diff --git a/CMakeLists.txt b/CMakeLists.txt index b4abd30f0fd3..1be6a4e74c06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -700,14 +700,18 @@ if(CONFIG_GEN_ISR_TABLES) # isr_tables.c is generated from ${ZEPHYR_PREBUILT_EXECUTABLE} by # gen_isr_tables.py + set(obj_copy_cmd "") + bintools_objcopy( + RESULT_CMD_LIST obj_copy_cmd + TARGET_INPUT ${OUTPUT_FORMAT} + TARGET_OUTPUT "binary" + SECTION_ONLY ".intList" + FILE_INPUT $ + FILE_OUTPUT "isrList.bin" + ) add_custom_command( OUTPUT isr_tables.c - COMMAND ${CMAKE_OBJCOPY} - -I ${OUTPUT_FORMAT} - -O binary - --only-section=.intList - $ - isrList.bin + ${obj_copy_cmd} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/arch/common/gen_isr_tables.py --output-source isr_tables.c @@ -839,16 +843,22 @@ if(CONFIG_ARM AND CONFIG_USERSPACE) set(PRIV_STACKS_OUTPUT_OBJ_PATH ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/priv_stacks_output_lib.dir/${PRIV_STACKS_OUTPUT_OBJ}) + set(obj_copy_cmd "") + set(obj_copy_sections_rename + .bss=.priv_stacks.noinit + .data=.priv_stacks.data + .text=.priv_stacks.text + .rodata=.priv_stacks.rodata + ) + bintools_objcopy( + RESULT_CMD_LIST obj_copy_cmd + SECTION_RENAME ${obj_copy_sections_rename} + FILE_INPUT ${PRIV_STACKS_OUTPUT_OBJ_PATH} + FILE_OUTPUT ${PRIV_STACKS_OUTPUT_OBJ_RENAMED} + ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_OBJ_RENAMED} - COMMAND - ${CMAKE_OBJCOPY} - --rename-section .bss=.priv_stacks.noinit - --rename-section .data=.priv_stacks.data - --rename-section .text=.priv_stacks.text - --rename-section .rodata=.priv_stacks.rodata - ${PRIV_STACKS_OUTPUT_OBJ_PATH} - ${PRIV_STACKS_OUTPUT_OBJ_RENAMED} + ${obj_copy_cmd} DEPENDS priv_stacks_output_lib WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) @@ -964,15 +974,21 @@ if(CONFIG_USERSPACE) set(OUTPUT_OBJ_PATH ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/output_lib.dir/${OUTPUT_OBJ}) + set(obj_copy_cmd "") + set(obj_copy_sections_rename + .data=.kobject_data.data + .text=.kobject_data.text + .rodata=.kobject_data.rodata + ) + bintools_objcopy( + RESULT_CMD_LIST obj_copy_cmd + SECTION_RENAME ${obj_copy_sections_rename} + FILE_INPUT ${OUTPUT_OBJ_PATH} + FILE_OUTPUT ${OUTPUT_OBJ_RENAMED} + ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_OBJ_RENAMED} - COMMAND - ${CMAKE_OBJCOPY} - --rename-section .data=.kobject_data.data - --rename-section .text=.kobject_data.text - --rename-section .rodata=.kobject_data.rodata - ${OUTPUT_OBJ_PATH} - ${OUTPUT_OBJ_RENAMED} + ${obj_copy_cmd} DEPENDS output_lib WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) @@ -1216,7 +1232,7 @@ list(APPEND if(NOT CONFIG_BUILD_NO_GAP_FILL) # Use ';' as separator to get proper space in resulting command. - set(GAP_FILL "--gap-fill;0xff") + set(GAP_FILL "0xff") endif() if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE) @@ -1238,38 +1254,83 @@ if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE) endif() if(CONFIG_BUILD_OUTPUT_HEX) + set(out_hex_cmd "") + set(out_hex_byprod "") + set(out_hex_sections_remove + .comment + COMMON + .eh_frame + ) + bintools_objcopy( + RESULT_CMD_LIST out_hex_cmd + RESULT_BYPROD_LIST out_hex_byprod + STRIP_ALL + GAP_FILL ${GAP_FILL} + TARGET_OUTPUT "ihex" + SECTION_REMOVE ${out_hex_sections_remove} + FILE_INPUT ${KERNEL_ELF_NAME} + FILE_OUTPUT ${KERNEL_HEX_NAME} + ) list(APPEND post_build_commands - COMMAND - ${CMAKE_OBJCOPY} -S -Oihex ${GAP_FILL} -R .comment -R COMMON -R .eh_frame ${KERNEL_ELF_NAME} ${KERNEL_HEX_NAME} + ${out_hex_cmd} ) list(APPEND post_build_byproducts ${KERNEL_HEX_NAME} + ${out_hex_byprod} ) endif() if(CONFIG_BUILD_OUTPUT_BIN) + set(out_bin_cmd "") + set(out_bin_byprod "") + set(out_bin_sections_remove + .comment + COMMON + .eh_frame + ) + bintools_objcopy( + RESULT_CMD_LIST out_bin_cmd + RESULT_BYPROD_LIST out_bin_byprod + STRIP_ALL + GAP_FILL ${GAP_FILL} + TARGET_OUTPUT "binary" + SECTION_REMOVE ${out_bin_sections_remove} + FILE_INPUT ${KERNEL_ELF_NAME} + FILE_OUTPUT ${KERNEL_BIN_NAME} + ) list(APPEND post_build_commands - COMMAND - ${CMAKE_OBJCOPY} -S -Obinary ${GAP_FILL} -R .comment -R COMMON -R .eh_frame ${KERNEL_ELF_NAME} ${KERNEL_BIN_NAME} + ${out_bin_cmd} ) list(APPEND post_build_byproducts ${KERNEL_BIN_NAME} + ${out_bin_byprod} ) endif() if(CONFIG_BUILD_OUTPUT_S19) + set(out_S19_cmd "") + set(out_S19_byprod "") + bintools_objcopy( + RESULT_CMD_LIST out_S19_cmd + RESULT_BYPROD_LIST out_S19_byprod + GAP_FILL ${GAP_FILL} + TARGET_OUTPUT "srec" + SREC_LEN 1 + FILE_INPUT ${KERNEL_ELF_NAME} + FILE_OUTPUT ${KERNEL_S19_NAME} + ) list(APPEND post_build_commands - COMMAND - ${CMAKE_OBJCOPY} ${GAP_FILL} --srec-len 1 --output-target=srec ${KERNEL_ELF_NAME} ${KERNEL_S19_NAME} + ${out_S19_cmd} ) list(APPEND post_build_byproducts ${KERNEL_S19_NAME} + ${out_S19_byprod} ) endif() diff --git a/cmake/bintools/gnu/target.cmake b/cmake/bintools/gnu/target.cmake index 7359abcb1875..141c1e0a4322 100644 --- a/cmake/bintools/gnu/target.cmake +++ b/cmake/bintools/gnu/target.cmake @@ -15,3 +15,4 @@ find_program(CMAKE_GDB gdb-multiarch PATH ${TOOLCHAIN_HOME} # Include bin tool abstraction macros include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_memusage.cmake) +include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objcopy.cmake) diff --git a/cmake/bintools/gnu/target_objcopy.cmake b/cmake/bintools/gnu/target_objcopy.cmake new file mode 100644 index 000000000000..703e06806747 --- /dev/null +++ b/cmake/bintools/gnu/target_objcopy.cmake @@ -0,0 +1,126 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Construct a commandline suitable for calling the toolchain binary tools +# version of objcopy. +# +# Usage: +# bintools_objcopy( +# RESULT_CMD_LIST +# RESULT_BYPROD_LIST +# +# STRIP_ALL +# STRIP_DEBUG +# +# TARGET_INPUT +# TARGET_OUTPUT +# +# GAP_FILL +# SREC_LEN +# +# SECTION_ONLY +# SECTION_REMOVE +# SECTION_RENAME +# +# FILE_INPUT +# FILE_OUTPUT +# ) +function(bintools_objcopy) + cmake_parse_arguments( + # Prefix of output variables + BINTOOLS_OBJCOPY + # List of argument names without values, hence boolean + "STRIP_ALL;STRIP_DEBUG" + # List of argument names with one value + "RESULT_CMD_LIST;RESULT_BYPROD_LIST;TARGET_INPUT;TARGET_OUTPUT;GAP_FILL;SREC_LEN;FILE_INPUT;FILE_OUTPUT" + # List of argument names with multible values + "SECTION_ONLY;SECTION_RENAME;SECTION_REMOVE" + # Parser input + ${ARGN} + ) + + # Verify arguments + if(NOT DEFINED BINTOOLS_OBJCOPY_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_OBJCOPY_RESULT_CMD_LIST}) + message(FATAL_ERROR "RESULT_CMD_LIST is required.") + elseif(NOT DEFINED BINTOOLS_OBJCOPY_FILE_INPUT OR NOT DEFINED BINTOOLS_OBJCOPY_FILE_OUTPUT) + message(FATAL_ERROR "Both FILE_INPUT and FILE_OUTPUT is required.") + endif() + + # Handle stripping + set(obj_copy_strip "") + if(${BINTOOLS_OBJCOPY_STRIP_ALL}) + set(obj_copy_strip "-S") + elseif(${BINTOOLS_OBJCOPY_STRIP_DEBUG}) + set(obj_copy_strip "-g") + endif() + + # Handle gap filling + set(obj_copy_gap_fill "") + if(DEFINED BINTOOLS_OBJCOPY_GAP_FILL) + set(obj_copy_gap_fill "--gap-fill;${BINTOOLS_OBJCOPY_GAP_FILL}") + endif() + + # Handle srec len, but only if target output is srec + set(obj_copy_srec_len "") + if(DEFINED BINTOOLS_OBJCOPY_SREC_LEN) + if(NOT ${BINTOOLS_OBJCOPY_TARGET_OUTPUT} STREQUAL "srec") + message(WARNING "Ignoring srec len, for non srec target: ${BINTOOLS_OBJCOPY_TARGET_OUTPUT}") + else() + set(obj_copy_srec_len "--srec-len;${BINTOOLS_OBJCOPY_SREC_LEN}") + endif() + endif() + + # Handle Input and Output target types + set(obj_copy_target_input "") + if(DEFINED BINTOOLS_OBJCOPY_TARGET_INPUT) + set(obj_copy_target_input "--input-target=${BINTOOLS_OBJCOPY_TARGET_INPUT}") + endif() + set(obj_copy_target_output "") + if(DEFINED BINTOOLS_OBJCOPY_TARGET_OUTPUT) + set(obj_copy_target_output "--output-target=${BINTOOLS_OBJCOPY_TARGET_OUTPUT}") + endif() + + # Handle sections, if any + # 1. Section only selection(s) + set(obj_copy_sections_only "") + if(DEFINED BINTOOLS_OBJCOPY_SECTION_ONLY) + foreach(section_only ${BINTOOLS_OBJCOPY_SECTION_ONLY}) + list(APPEND obj_copy_sections_only "--only-section=${section_only}") + endforeach() + endif() + + # 2. Section rename selection(s) + set(obj_copy_sections_rename "") + if(DEFINED BINTOOLS_OBJCOPY_SECTION_RENAME) + foreach(section_rename ${BINTOOLS_OBJCOPY_SECTION_RENAME}) + if(NOT ${section_rename} MATCHES "^.*=.*$") + message(FATAL_ERROR "Malformed section renaming. Must be from=to, have ${section_rename}") + else() + list(APPEND obj_copy_sections_rename "--rename-section;${section_rename}") + endif() + endforeach() + endif() + + # 3. Section remove selection(s) + set(obj_copy_sections_remove "") + if(DEFINED BINTOOLS_OBJCOPY_SECTION_REMOVE) + foreach(section_remove ${BINTOOLS_OBJCOPY_SECTION_REMOVE}) + list(APPEND obj_copy_sections_remove "--remove-section=${section_remove}") + endforeach() + endif() + + # Construct the command + set(obj_copy_cmd + # Base command + COMMAND ${CMAKE_OBJCOPY} ${obj_copy_strip} ${obj_copy_gap_fill} ${obj_copy_srec_len} + # Input and Output target types + ${obj_copy_target_input} ${obj_copy_target_output} + # Sections + ${obj_copy_sections_only} ${obj_copy_sections_rename} ${obj_copy_sections_remove} + # Input and output files + ${BINTOOLS_OBJCOPY_FILE_INPUT} ${BINTOOLS_OBJCOPY_FILE_OUTPUT} + ) + + # Place command in the parent provided variable + set(${BINTOOLS_OBJCOPY_RESULT_CMD_LIST} ${obj_copy_cmd} PARENT_SCOPE) + +endfunction(bintools_objcopy) diff --git a/cmake/bintools/host-gnu/target.cmake b/cmake/bintools/host-gnu/target.cmake index 9f31b3923162..d802ddf83394 100644 --- a/cmake/bintools/host-gnu/target.cmake +++ b/cmake/bintools/host-gnu/target.cmake @@ -12,3 +12,4 @@ find_program(CMAKE_GDB gdb ) # Use the gnu binutil abstraction macros include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_memusage.cmake) +include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objcopy.cmake) diff --git a/cmake/bintools/llvm/target.cmake b/cmake/bintools/llvm/target.cmake index f973a6d02c17..4c547364de22 100644 --- a/cmake/bintools/llvm/target.cmake +++ b/cmake/bintools/llvm/target.cmake @@ -16,3 +16,4 @@ find_program(CMAKE_READELF readelf ${find_program_binutils_args}) # Use the gnu binutil abstraction macros include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_memusage.cmake) +include(${ZEPHYR_BASE}/cmake/bintools/gnu/target_objcopy.cmake)