diff --git a/CMakeLists.txt b/CMakeLists.txt index 62ca601c07..90b9f451a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -416,8 +416,8 @@ if(CONFIG_BUILD_PROTECTED) nuttx_add_library_internal(nuttx_user) endif() -if(CONFIG_ALLSYMS) - include(nuttx_allsyms) +if(CONFIG_ALLSYMS OR CONFIG_MM_KASAN_GLOBAL) + include(nuttx_multiple_link) endif() add_dependencies(nuttx nuttx_context) diff --git a/cmake/nuttx_allsyms.cmake b/cmake/nuttx_allsyms.cmake deleted file mode 100644 index d87d5a64ea..0000000000 --- a/cmake/nuttx_allsyms.cmake +++ /dev/null @@ -1,126 +0,0 @@ -# ############################################################################## -# cmake/nuttx_allsyms.cmake -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed to the Apache Software Foundation (ASF) under one or more contributor -# license agreements. See the NOTICE file distributed with this work for -# additional information regarding copyright ownership. The ASF licenses this -# file to you under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. -# -# ############################################################################## - -# ~~~ -# define_allsyms_link_target -# -# Description: -# Wrapper of cmake declaration of nuttx executable -# in order to implement ALLSYMS. -# -# When declaring the target to be `nuttx`, -# create an empty allsyms source file for it; -# When the target is declared as something else, -# the link behavior of the `nuttx` target is cloned -# and added to actually generate the allsyms file. -# -# Parameters: -# inter_target : declaration of target -# dep_target : targets which depends on -# allsyms_file : generated allsyms file name -# ~~~ - -# create an empty allsyms source file for `nuttx` -set(ALLSYMS_SOURCE ${CMAKE_BINARY_DIR}/allsyms_empty.c) - -add_custom_command( - OUTPUT ${ALLSYMS_SOURCE} - COMMAND ${NUTTX_DIR}/tools/mkallsyms.py nuttx.empty ${ALLSYMS_SOURCE} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating allsyms_empty.c") -add_custom_target(generate_empty_allsyms DEPENDS ${ALLSYMS_SOURCE}) -add_dependencies(nuttx generate_empty_allsyms) - -target_sources(nuttx PRIVATE ${ALLSYMS_SOURCE}) -set(ALLSYMS_INCDIR ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include) -set_source_files_properties(${ALLSYMS_SOURCE} PROPERTIES INCLUDE_DIRECTORIES - "${ALLSYMS_INCDIR}") - -macro(define_allsyms_link_target inter_target dep_target allsyms_file) - # generate `g_allsyms` file - add_custom_command( - OUTPUT ${allsyms_file}.c POST_BUILD - COMMAND ${NUTTX_DIR}/tools/mkallsyms.py ${CMAKE_BINARY_DIR}/${dep_target} - ${allsyms_file}.c - DEPENDS ${dep_target} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMAND_EXPAND_LISTS) - - # relink target with allsysm.c which generated by the elf of the previous - # phase - add_executable( - ${inter_target} ${allsyms_file}.c - $,EXCLUDE,allsyms_empty>) - - # relink target and nuttx have exactly the same configuration - target_include_directories( - ${inter_target} SYSTEM PUBLIC ${CMAKE_SOURCE_DIR}/include - ${CMAKE_BINARY_DIR}/include) - target_compile_definitions( - ${inter_target} PRIVATE $) - target_compile_options( - ${inter_target} - PRIVATE $) - target_link_options(${inter_target} PRIVATE - $) - target_link_libraries( - ${inter_target} - PRIVATE $>) -endmacro() - -# allsyms link phase 1 with generated allsyms source file -define_allsyms_link_target(allsyms_inter nuttx allsyms_first_link) -# allsyms link phase 2 since the table offset may changed -define_allsyms_link_target(allsyms_nuttx allsyms_inter allsyms_final_link) -# fixing timing dependencies -add_dependencies(nuttx_post allsyms_nuttx) -# finally use allsyms_nuttx to overwrite the already generated nuttx -add_custom_command( - TARGET allsyms_nuttx - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different allsyms_nuttx nuttx DEPENDS - allsyms_nuttx - COMMENT "Overwrite nuttx with allsyms_nuttx") - -# regenerate binary outputs in different formats (.bin, .hex, etc) -if(CONFIG_INTELHEX_BINARY) - add_custom_command( - TARGET allsyms_nuttx - POST_BUILD - COMMAND ${CMAKE_OBJCOPY} -O ihex allsyms_nuttx nuttx.hex DEPENDS nuttx-hex - COMMENT "Regenerate nuttx.hex") - -endif() -if(CONFIG_MOTOROLA_SREC) - add_custom_command( - TARGET allsyms_nuttx - POST_BUILD - COMMAND ${CMAKE_OBJCOPY} -O srec allsyms_nuttx nuttx.srec DEPENDS nuttx-srec - COMMENT "Regenerate nuttx.srec") -endif() -if(CONFIG_RAW_BINARY) - add_custom_command( - TARGET allsyms_nuttx - POST_BUILD - COMMAND ${CMAKE_OBJCOPY} -O binary allsyms_nuttx nuttx.bin DEPENDS nuttx-bin - COMMENT "Regenerate nuttx.bin") -endif() diff --git a/cmake/nuttx_multiple_link.cmake b/cmake/nuttx_multiple_link.cmake new file mode 100644 index 0000000000..fef695f52d --- /dev/null +++ b/cmake/nuttx_multiple_link.cmake @@ -0,0 +1,167 @@ +# ############################################################################## +# cmake/nuttx_multiple_link.cmake +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +# create an empty allsyms source file for `nuttx` +if(CONFIG_ALLSYMS) + set(ALLSYMS_SOURCE ${CMAKE_BINARY_DIR}/allsyms_empty.c) + add_custom_command( + OUTPUT ${ALLSYMS_SOURCE} + COMMAND ${NUTTX_DIR}/tools/mkallsyms.py nuttx.empty ${ALLSYMS_SOURCE} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating allsyms_empty.c") + add_custom_target(generate_empty_allsyms DEPENDS ${ALLSYMS_SOURCE}) + add_dependencies(nuttx generate_empty_allsyms) + + target_sources(nuttx PRIVATE ${ALLSYMS_SOURCE}) + set(ALLSYMS_INCDIR ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include) + set_source_files_properties(${ALLSYMS_SOURCE} PROPERTIES INCLUDE_DIRECTORIES + "${ALLSYMS_INCDIR}") +endif() + +if(CONFIG_MM_KASAN_GLOBAL) + set(KASAN_GLOBAL_SOURCE ${CMAKE_BINARY_DIR}/kasan_global.c) + add_custom_command( + OUTPUT ${KASAN_GLOBAL_SOURCE} + COMMAND ${NUTTX_DIR}/tools/kasan_global.py -e nuttx.empty -o + ${KASAN_GLOBAL_SOURCE} -a ${CONFIG_MM_KASAN_GLOBAL_ALIGN} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating kasan_global.c") + add_custom_target(generate_empty_kasan_global DEPENDS ${KASAN_GLOBAL_SOURCE}) + add_dependencies(nuttx generate_empty_kasan_global) + + target_sources(nuttx PRIVATE ${KASAN_GLOBAL_SOURCE}) + set(KASAN_GLOBAL_INCDIR ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include) + set_source_files_properties( + ${KASAN_GLOBAL_SOURCE} PROPERTIES INCLUDE_DIRECTORIES + "${KASAN_GLOBAL_INCDIR}") +endif() + +# ~~~ +# define_multiple_link_target +# +# Description: +# Wrapper of cmake declaration of nuttx executable +# in order to implement ALLSYMS. +# +# When declaring the target to be `nuttx`, +# create an empty allsyms source file for it; +# When the target is declared as something else, +# the link behavior of the `nuttx` target is cloned +# and added to actually generate the allsyms file. +# +# Parameters: +# inter_target : declaration of target +# dep_target : targets which depends on +# linktimes : link times of the target +# ~~~ + +macro(define_multiple_link_target inter_target dep_target linktimes) + set(MULTIPLE_LINK_SOURCES_${linktimes}) + if(CONFIG_ALLSYMS) + set(LINK_ALLSYMS_SOURCE allsyms_${linktimes}.c) + list(APPEND MULTIPLE_LINK_SOURCES_${linktimes} ${LINK_ALLSYMS_SOURCE}) + add_custom_command( + OUTPUT ${LINK_ALLSYMS_SOURCE} POST_BUILD + COMMAND ${NUTTX_DIR}/tools/mkallsyms.py ${CMAKE_BINARY_DIR}/${dep_target} + ${LINK_ALLSYMS_SOURCE} + DEPENDS ${dep_target} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMAND_EXPAND_LISTS) + endif() + + if(CONFIG_MM_KASAN_GLOBAL) + set(LINK_KASAN_GLOBAL_SOURCE kasan_global_${linktimes}.c) + list(APPEND MULTIPLE_LINK_SOURCES_${linktimes} ${LINK_KASAN_GLOBAL_SOURCE}) + add_custom_command( + OUTPUT ${LINK_KASAN_GLOBAL_SOURCE} POST_BUILD + COMMAND + ${NUTTX_DIR}/tools/kasan_global.py -e ${CMAKE_BINARY_DIR}/${dep_target} + -o ${LINK_KASAN_GLOBAL_SOURCE} -a ${CONFIG_MM_KASAN_GLOBAL_ALIGN} + DEPENDS ${dep_target} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMAND_EXPAND_LISTS) + endif() + + # relink target with allsysm.c which generated by the elf of the previous + # phase + add_executable( + ${inter_target} + ${MULTIPLE_LINK_SOURCES_${linktimes}} + $,EXCLUDE,allsyms_empty|kasan_global>) + + # relink target and nuttx have exactly the same configuration + target_include_directories( + ${inter_target} SYSTEM PUBLIC ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include) + target_compile_definitions( + ${inter_target} PRIVATE $) + target_compile_options( + ${inter_target} + PRIVATE $) + target_link_options(${inter_target} PRIVATE + $) + target_link_libraries( + ${inter_target} + PRIVATE $>) +endmacro() + +# allsyms link phase 1 with generated allsyms source file +define_multiple_link_target(first_link nuttx first) +# allsyms link phase 2 since the table offset may changed +define_multiple_link_target(second_link first_link second) +# allsyms link phase 3 since the table offset may changed +define_multiple_link_target(final_nuttx second_link final) + +# fixing timing dependencies +add_dependencies(nuttx_post final_nuttx) +# finally use final_nuttx to overwrite the already generated nuttx +add_custom_command( + TARGET final_nuttx + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different final_nuttx nuttx DEPENDS + final_nuttx + COMMENT "Overwrite nuttx with final_nuttx") + +# regenerate binary outputs in different formats (.bin, .hex, etc) +if(CONFIG_INTELHEX_BINARY) + add_custom_command( + TARGET final_nuttx + POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O ihex final_nuttx nuttx.hex DEPENDS nuttx-hex + COMMENT "Regenerate nuttx.hex") + +endif() +if(CONFIG_MOTOROLA_SREC) + add_custom_command( + TARGET final_nuttx + POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O srec final_nuttx nuttx.srec DEPENDS nuttx-srec + COMMENT "Regenerate nuttx.srec") +endif() +if(CONFIG_RAW_BINARY) + add_custom_command( + TARGET final_nuttx + POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary final_nuttx nuttx.bin DEPENDS nuttx-bin + COMMENT "Regenerate nuttx.bin") +endif()