From 1f3f65b40ea01b93aa4b48c72671c7d84b504766 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Wed, 24 Apr 2024 20:39:52 +0400 Subject: [PATCH] fix(system): discard eh_frame sections if disabled in sdkconfig --- components/esp_system/ld/esp32/sections.ld.in | 17 ++++- .../esp_system/ld/esp32c2/sections.ld.in | 14 ++++ .../esp_system/ld/esp32c3/sections.ld.in | 14 ++++ .../esp_system/ld/esp32c6/sections.ld.in | 14 ++++ .../esp_system/ld/esp32h2/sections.ld.in | 14 ++++ .../esp_system/ld/esp32p4/sections.ld.in | 14 ++++ .../esp_system/ld/esp32s2/sections.ld.in | 16 ++++- .../esp_system/ld/esp32s3/sections.ld.in | 16 ++++- components/esp_system/ld/ld.cmake | 72 ++++++++++++------- 9 files changed, 158 insertions(+), 33 deletions(-) diff --git a/components/esp_system/ld/esp32/sections.ld.in b/components/esp_system/ld/esp32/sections.ld.in index 3f4da1a6e2..949f58ffc0 100644 --- a/components/esp_system/ld/esp32/sections.ld.in +++ b/components/esp_system/ld/esp32/sections.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /* Default entry point: */ ENTRY(call_start_cpu0); @@ -313,9 +316,11 @@ SECTIONS *(.gnu.linkonce.e.*) *(.gnu.version_r) . = (. + 3) & ~ 3; +#if CONFIG_COMPILER_CXX_EXCEPTIONS __eh_frame = ABSOLUTE(.); KEEP(*(.eh_frame)) . = (. + 7) & ~ 3; +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS /* C++ constructor and destructor tables Make a point of not including anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt @@ -459,12 +464,20 @@ SECTIONS */ .xt.prop 0 : { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) + KEEP (*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) } .xt.lit 0 : { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) + KEEP (*(.xt.lit .xt.lit.* .gnu.linkonce.p.*)) + } + + /DISCARD/ : + { + *(.eh_frame_hdr) +#if !CONFIG_COMPILER_CXX_EXCEPTIONS + *(.eh_frame) +#endif // !CONFIG_COMPILER_CXX_EXCEPTIONS } } diff --git a/components/esp_system/ld/esp32c2/sections.ld.in b/components/esp_system/ld/esp32c2/sections.ld.in index f42334f87b..f86383ef1f 100644 --- a/components/esp_system/ld/esp32c2/sections.ld.in +++ b/components/esp_system/ld/esp32c2/sections.ld.in @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" + /* Default entry point */ ENTRY(call_start_cpu0); @@ -241,9 +243,12 @@ SECTIONS *(.tbss) *(.tbss.*) _thread_local_end = ABSOLUTE(.); +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME . = ALIGN(ALIGNOF(.eh_frame)); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME } > default_rodata_seg +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* Keep this section shall be at least aligned on 4 */ .eh_frame : ALIGN(8) { @@ -263,6 +268,7 @@ SECTIONS KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); } > default_rodata_seg +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* This section is a place where we dump all the rodata which aren't used at runtime, @@ -330,6 +336,14 @@ SECTIONS . = ALIGN (16); _heap_start = ABSOLUTE(.); } > dram0_0_seg + + /DISCARD/ : + { +#if !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + *(.eh_frame_hdr) + *(.eh_frame) +#endif // !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + } } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in index 70e1e08377..ef0cd1395b 100644 --- a/components/esp_system/ld/esp32c3/sections.ld.in +++ b/components/esp_system/ld/esp32c3/sections.ld.in @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" + /* Default entry point */ ENTRY(call_start_cpu0); @@ -354,9 +356,12 @@ SECTIONS *(.tbss) *(.tbss.*) _thread_local_end = ABSOLUTE(.); +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME . = ALIGN(ALIGNOF(.eh_frame)); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME } > default_rodata_seg +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* Keep this section shall be at least aligned on 4 */ .eh_frame : ALIGN(8) { @@ -376,6 +381,7 @@ SECTIONS KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); } > default_rodata_seg +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* This section is a place where we dump all the rodata which aren't used at runtime, @@ -431,6 +437,14 @@ SECTIONS . = ALIGN (16); _heap_start = ABSOLUTE(.); } > dram0_0_seg + + /DISCARD/ : + { +#if !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + *(.eh_frame_hdr) + *(.eh_frame) +#endif // !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + } } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32c6/sections.ld.in b/components/esp_system/ld/esp32c6/sections.ld.in index db73f9021d..4498bb1d49 100644 --- a/components/esp_system/ld/esp32c6/sections.ld.in +++ b/components/esp_system/ld/esp32c6/sections.ld.in @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" + /* Default entry point */ ENTRY(call_start_cpu0); @@ -389,9 +391,12 @@ SECTIONS *(.tbss) *(.tbss.*) _thread_local_end = ABSOLUTE(.); +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME . = ALIGN(ALIGNOF(.eh_frame)); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME } > default_rodata_seg +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* Keep this section shall be at least aligned on 4 */ .eh_frame : ALIGN(8) { @@ -411,6 +416,7 @@ SECTIONS KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); } > default_rodata_seg +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* This section is a place where we dump all the rodata which aren't used at runtime, @@ -433,6 +439,14 @@ SECTIONS . = ALIGN (16); _heap_start = ABSOLUTE(.); } > dram0_0_seg + + /DISCARD/ : + { +#if !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + *(.eh_frame_hdr) + *(.eh_frame) +#endif // !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + } } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32h2/sections.ld.in b/components/esp_system/ld/esp32h2/sections.ld.in index de2f7eeb04..1ef035fb6e 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" + /* Default entry point */ ENTRY(call_start_cpu0); @@ -389,9 +391,12 @@ SECTIONS *(.tbss.*) _thread_local_end = ABSOLUTE(.); _rodata_reserved_end = ABSOLUTE(.); +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME . = ALIGN(ALIGNOF(.eh_frame)); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME } > default_rodata_seg +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* Keep this section shall be at least aligned on 4 */ .eh_frame : ALIGN(8) { @@ -411,6 +416,7 @@ SECTIONS KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); } > default_rodata_seg +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME .flash.rodata_noload (NOLOAD) : { @@ -424,6 +430,14 @@ SECTIONS . = ALIGN (16); _heap_start = ABSOLUTE(.); } > dram0_0_seg + + /DISCARD/ : + { +#if !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + *(.eh_frame_hdr) + *(.eh_frame) +#endif // !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + } } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32p4/sections.ld.in b/components/esp_system/ld/esp32p4/sections.ld.in index d029244f23..3e03ec85f9 100644 --- a/components/esp_system/ld/esp32p4/sections.ld.in +++ b/components/esp_system/ld/esp32p4/sections.ld.in @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" + /* Default entry point */ ENTRY(call_start_cpu0); @@ -410,9 +412,12 @@ SECTIONS *(.tbss) *(.tbss.*) _thread_local_end = ABSOLUTE(.); +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME . = ALIGN(ALIGNOF(.eh_frame)); +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME } > default_rodata_seg +#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* Keep this section shall be at least aligned on 4 */ .eh_frame : ALIGN(8) { @@ -432,6 +437,7 @@ SECTIONS KEEP (*(.eh_frame_hdr)) __eh_frame_hdr_end = ABSOLUTE(.); } > default_rodata_seg +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME /* This section is a place where we dump all the rodata which aren't used at runtime, @@ -454,6 +460,14 @@ SECTIONS . = ALIGN (16); _heap_start = ABSOLUTE(.); } > dram0_0_seg + + /DISCARD/ : + { +#if !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + *(.eh_frame_hdr) + *(.eh_frame) +#endif // !(CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME) + } } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index 681e686c85..298b7f856b 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" + /* Default entry point: */ ENTRY(call_start_cpu0); @@ -311,9 +313,11 @@ SECTIONS *(.gnu.linkonce.e.*) *(.gnu.version_r) . = (. + 3) & ~ 3; +#if CONFIG_COMPILER_CXX_EXCEPTIONS __eh_frame = ABSOLUTE(.); KEEP(*(.eh_frame)) . = (. + 7) & ~ 3; +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS /* C++ constructor and destructor tables Make a point of not including anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt @@ -434,12 +438,20 @@ SECTIONS */ .xt.prop 0 : { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) + KEEP (*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) } .xt.lit 0 : { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) + KEEP (*(.xt.lit .xt.lit.* .gnu.linkonce.p.*)) + } + + /DISCARD/ : + { + *(.eh_frame_hdr) +#if !CONFIG_COMPILER_CXX_EXCEPTIONS + *(.eh_frame) +#endif // !CONFIG_COMPILER_CXX_EXCEPTIONS } } diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index 850305ee69..18f0ebfff8 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" + /* Default entry point */ ENTRY(call_start_cpu0); @@ -340,9 +342,11 @@ SECTIONS *(.gnu.linkonce.e.*) *(.gnu.version_r) . = (. + 3) & ~ 3; +#if CONFIG_COMPILER_CXX_EXCEPTIONS __eh_frame = ABSOLUTE(.); KEEP(*(.eh_frame)) . = (. + 7) & ~ 3; +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS /* C++ constructor and destructor tables */ /* Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt */ __init_array_start = ABSOLUTE(.); @@ -473,12 +477,20 @@ SECTIONS */ .xt.prop 0 : { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) + KEEP (*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) } .xt.lit 0 : { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) + KEEP (*(.xt.lit .xt.lit.* .gnu.linkonce.p.*)) + } + + /DISCARD/ : + { + *(.eh_frame_hdr) +#if !CONFIG_COMPILER_CXX_EXCEPTIONS + *(.eh_frame) +#endif // !CONFIG_COMPILER_CXX_EXCEPTIONS } } diff --git a/components/esp_system/ld/ld.cmake b/components/esp_system/ld/ld.cmake index 5e80268da7..aa8c1b8121 100644 --- a/components/esp_system/ld/ld.cmake +++ b/components/esp_system/ld/ld.cmake @@ -1,33 +1,51 @@ -# For each supported target, a memory.ld.in and sections.ld.in is processed and dictate the -# memory layout of the app. -# -# memory.ld.in goes through the preprocessor -# sections.ld.in goes through linker script generator - idf_build_get_property(target IDF_TARGET) idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER) - -set(ld_input "${CMAKE_CURRENT_LIST_DIR}/${target}/memory.ld.in") -set(ld_output "${CMAKE_CURRENT_BINARY_DIR}/ld/memory.ld") -target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_output}") +idf_build_get_property(config_dir CONFIG_DIR) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ld") -# Process the template file through the linker script generation mechanism, and use the output for linking the -# final binary -target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/${target}/sections.ld.in" +# Cmake script that generates linker script from "*.ld.in" scripts using compiler preprocessor +set(linker_script_generator "${CMAKE_CURRENT_BINARY_DIR}/ld/linker_script_generator.cmake") +file(WRITE ${linker_script_generator} +[=[ +execute_process(COMMAND "${CC}" "-C" "-P" "-x" "c" "-E" "-I" "${CONFIG_DIR}" "-I" "${LD_DIR}" "${SOURCE}" + RESULT_VARIABLE RET_CODE + OUTPUT_VARIABLE PREPROCESSED_LINKER_SCRIPT + ERROR_VARIABLE ERROR_VAR) +if(RET_CODE AND NOT RET_CODE EQUAL 0) + message(FATAL_ERROR "Can't generate ${TARGET}\nRET_CODE: ${RET_CODE}\nERROR_MESSAGE: ${ERROR_VAR}") +endif() +string(REPLACE "\\n" "\n" TEXT "${PREPROCESSED_LINKER_SCRIPT}") +file(WRITE "${TARGET}" "${TEXT}") +]=]) + +function(preprocess_linker_file name_in name_out out_path) + set(script_in "${CMAKE_CURRENT_LIST_DIR}/${target}/${name_in}") + set(script_out "${CMAKE_CURRENT_BINARY_DIR}/ld/${name_out}") + set(${out_path} ${script_out} PARENT_SCOPE) + + add_custom_command( + OUTPUT ${script_out} + COMMAND ${CMAKE_COMMAND} + "-DCC=${CMAKE_C_COMPILER}" + "-DSOURCE=${script_in}" + "-DTARGET=${script_out}" + "-DCONFIG_DIR=${config_dir}" + "-DLD_DIR=${CMAKE_CURRENT_LIST_DIR}" + -P "${linker_script_generator}" + MAIN_DEPENDENCY ${script_in} + DEPENDS ${sdkconfig_header} + COMMENT "Generating ${script_out} linker script..." + VERBATIM) + add_custom_target("${name_out}" DEPENDS "${script_out}") + add_dependencies(${COMPONENT_LIB} "${name_out}") +endfunction() + +# Generage memory.ld +preprocess_linker_file("memory.ld.in" "memory.ld" ld_out_path) +target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_out_path}") + +# Generage sections.ld.in and pass it through linker script generator +preprocess_linker_file("sections.ld.in" "sections.ld.in" ld_out_path) +target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_out_path}" PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/sections.ld") - -idf_build_get_property(config_dir CONFIG_DIR) -# Preprocess memory.ld.in linker script to include configuration, becomes memory.ld -add_custom_command( - OUTPUT ${ld_output} - COMMAND "${CMAKE_C_COMPILER}" -C -P -x c -E -o ${ld_output} -I ${config_dir} - -I "${CMAKE_CURRENT_LIST_DIR}" ${ld_input} - MAIN_DEPENDENCY ${ld_input} - DEPENDS ${sdkconfig_header} - COMMENT "Generating memory.ld linker script..." - VERBATIM) - -add_custom_target(memory_ld DEPENDS ${ld_output}) -add_dependencies(${COMPONENT_LIB} memory_ld)