diff --git a/components/esp_system/ld/esp32/memory.ld.in b/components/esp_system/ld/esp32/memory.ld.in index df13722b0ce..66071e3d133 100644 --- a/components/esp_system/ld/esp32/memory.ld.in +++ b/components/esp_system/ld/esp32/memory.ld.in @@ -141,9 +141,6 @@ _heap_end = ALIGN(0x40000000 - _sram1_iram_len - 3, 4); _heap_end = 0x40000000 - CONFIG_ESP32_TRACEMEM_RESERVE_DRAM; #endif - -_data_seg_org = ORIGIN(rtc_data_seg); - /* The lines below define location alias for .rtc.data section based on Kconfig option. When the option is not defined then use slow memory segment else the data will be placed in fast memory segment */ diff --git a/components/esp_system/ld/esp32/sections.ld.in b/components/esp_system/ld/esp32/sections.ld.in index fd13d6afd88..5dfa4c37fb8 100644 --- a/components/esp_system/ld/esp32/sections.ld.in +++ b/components/esp_system/ld/esp32/sections.ld.in @@ -19,7 +19,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_text_start) - mapping[rtc_text] + SECTION_MAPPINGS(rtc_text) *rtc_wake_stub*.*(.literal .text .literal.* .text.*) @@ -49,7 +49,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_force_fast_start) - mapping[rtc_force_fast] + SECTION_MAPPINGS(rtc_force_fast) *(.rtc.force_fast .rtc.force_fast.*) @@ -68,7 +68,7 @@ SECTIONS { _rtc_data_start = ABSOLUTE(.); - mapping[rtc_data] + SECTION_MAPPINGS(rtc_data) *rtc_wake_stub*.*(.data .rodata .data.* .rodata.*) @@ -83,7 +83,7 @@ SECTIONS *rtc_wake_stub*.*(.bss .bss.*) *rtc_wake_stub*.*(COMMON) - mapping[rtc_bss] + SECTION_MAPPINGS(rtc_bss) _rtc_bss_end = ABSOLUTE(.); } > rtc_data_location @@ -100,6 +100,8 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_noinit_start) + SECTION_MAPPINGS(rtc_noinit) + *(.rtc_noinit .rtc_noinit.*) ALIGNED_SYMBOL(4, _rtc_noinit_end) @@ -222,8 +224,7 @@ SECTIONS /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); - mapping[iram0_text] - + SECTION_MAPPINGS(iram0_text) } > iram0_0_seg .dram0.data : @@ -237,7 +238,7 @@ SECTIONS *(.gnu.linkonce.s2.*) *(.jcr) - mapping[dram0_data] + SECTION_MAPPINGS(dram0_data) _data_end = ABSOLUTE(.); } > dram0_0_seg @@ -250,6 +251,7 @@ SECTIONS { _ext_ram_noinit_start = ABSOLUTE(.); + SECTION_MAPPINGS(extram_noinit) *(.ext_ram_noinit*) ALIGNED_SYMBOL(4, _ext_ram_noinit_end) @@ -275,7 +277,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _ext_ram_bss_start) - mapping[extern_ram] + SECTION_MAPPINGS(extern_ram) ALIGNED_SYMBOL(4, _ext_ram_bss_end) } > extern_ram_seg @@ -285,11 +287,7 @@ SECTIONS { ALIGNED_SYMBOL(8, _bss_start) - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] + SECTION_MAPPINGS(dram0_bss) ALIGNED_SYMBOL(8, _bss_end) } > dram0_0_seg @@ -326,7 +324,7 @@ SECTIONS { _flash_rodata_start = ABSOLUTE(.); - mapping[flash_rodata] + SECTION_MAPPINGS(flash_rodata) *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) @@ -344,16 +342,6 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) -#if EH_FRAME_LINKING_ENABLED - ALIGNED_SYMBOL(4, __eh_frame) - KEEP(*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); -#endif // EH_FRAME_LINKING_ENABLED - /** * C++ constructor tables. * @@ -381,9 +369,37 @@ SECTIONS *(.lit4.*) *(.gnu.linkonce.lit4.*) _lit4_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); + } > default_rodata_seg + ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - /* TLS data. */ - ALIGNED_SYMBOL(4, _thread_local_start) +#if EH_FRAME_LINKING_ENABLED + .eh_frame : + { + ALIGNED_SYMBOL(4, __eh_frame) + + KEEP (*(.eh_frame)) + /** + * As we are not linking with crtend.o, which includes the CIE terminator + * (see __FRAME_END__ in libgcc sources), it is manually provided here. + */ + LONG(0); + + __eh_frame_end = ABSOLUTE(.); + + . = ALIGN(ALIGNOF(.flash.tdata)); + } > default_rodata_seg +#endif // EH_FRAME_LINKING_ENABLED + + .flash.tdata : + { + /* Keep tdata and tbss sections contiguous (no gaps between them). + * The TLS runtime code calculates offsets assuming these sections are + * adjacent. Gaps would cause incorrect address calculations, leading + * to accessing wrong memory. + */ + /* tdata sections */ + _thread_local_data_start = ABSOLUTE(.); #if CONFIG_LIBC_PICOLIBC _picolibc_reent_stub_start = ABSOLUTE(.); KEEP(*(.tdata.errno)) @@ -395,15 +411,18 @@ SECTIONS #endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY _picolibc_reent_stub_end = ABSOLUTE(.); #endif // CONFIG_LIBC_PICOLIBC - *(.tdata) - *(.tdata.*) - *(.tbss) - *(.tbss.*) - _thread_local_end = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _thread_local_data_end = ABSOLUTE(.); + /* tbss sections */ + _thread_local_bss_start = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + _thread_local_bss_end = ABSOLUTE(.); } > default_rodata_seg + _tls_section_alignment = ALIGNOF(.flash.tdata); ASSERT_PICOLIBC_REENT_STUB() - - _flash_rodata_align = ALIGNOF(.flash.rodata); + ASSERT(_thread_local_data_end == _thread_local_bss_start, + "tdata and tbss must be contiguous.") /** * This section contains all the rodata that is not used @@ -418,7 +437,7 @@ SECTIONS */ _rodata_reserved_end = ABSOLUTE(.); - mapping[rodata_noload] + SECTION_MAPPINGS(rodata_noload) } > default_rodata_seg .flash.text : @@ -431,7 +450,7 @@ SECTIONS _instruction_reserved_start = ABSOLUTE(.); _text_start = ABSOLUTE(.); - mapping[flash_text] + SECTION_MAPPINGS(flash_text) *(.stub) *(.gnu.warning) @@ -472,7 +491,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _iram_data_start) - mapping[iram0_data] + SECTION_MAPPINGS(iram0_data) _iram_data_end = ABSOLUTE(.); } > iram0_0_seg @@ -481,7 +500,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _iram_bss_start) - mapping[iram0_bss] + SECTION_MAPPINGS(iram0_bss) _iram_bss_end = ABSOLUTE(.); ALIGNED_SYMBOL(4, _iram_end) @@ -494,7 +513,8 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_start) } > dram0_0_seg -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32s2/memory.ld.in b/components/esp_system/ld/esp32s2/memory.ld.in index 82fa95625c6..55214e7ca90 100644 --- a/components/esp_system/ld/esp32s2/memory.ld.in +++ b/components/esp_system/ld/esp32s2/memory.ld.in @@ -109,8 +109,6 @@ _heap_start = _heap_low_start; _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - /* The lines below define location alias for .rtc.data section based on Kconfig option. When the option is not defined then use slow memory segment else the data will be placed in fast memory segment */ diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index f73da102338..41fa979c920 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -28,7 +28,7 @@ SECTIONS HIDDEN(_rtc_code_start = .); - mapping[rtc_text] + SECTION_MAPPINGS(rtc_text) *rtc_wake_stub*.*(.literal .text .literal.* .text.*) @@ -63,7 +63,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_force_fast_start) - mapping[rtc_force_fast] + SECTION_MAPPINGS(rtc_force_fast) *(.rtc.force_fast .rtc.force_fast.*) @@ -82,7 +82,7 @@ SECTIONS { _rtc_data_start = ABSOLUTE(.); - mapping[rtc_data] + SECTION_MAPPINGS(rtc_data) *rtc_wake_stub*.*(.data .rodata .data.* .rodata.*) @@ -97,7 +97,7 @@ SECTIONS *rtc_wake_stub*.*(.bss .bss.*) *rtc_wake_stub*.*(COMMON) - mapping[rtc_bss] + SECTION_MAPPINGS(rtc_bss) _rtc_bss_end = ABSOLUTE(.); } > rtc_data_location @@ -114,6 +114,8 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_noinit_start) + SECTION_MAPPINGS(rtc_noinit) + *(.rtc_noinit .rtc_noinit.*) ALIGNED_SYMBOL(4, _rtc_noinit_end) @@ -211,7 +213,7 @@ SECTIONS /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); - mapping[iram0_text] + SECTION_MAPPINGS(iram0_text) /* Padding for possible CPU prefetch + alignment for PMS split lines */ . += _esp_memprot_prefetch_pad_size; @@ -239,7 +241,7 @@ SECTIONS *(.gnu.linkonce.s2.*) *(.jcr) - mapping[dram0_data] + SECTION_MAPPINGS(dram0_data) _data_end = ABSOLUTE(.); } > dram0_0_seg @@ -265,7 +267,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _ext_ram_bss_start) - mapping[extern_ram] + SECTION_MAPPINGS(extern_ram) ALIGNED_SYMBOL(4, _ext_ram_bss_end) } > extern_ram_seg @@ -280,6 +282,7 @@ SECTIONS { _ext_ram_noinit_start = ABSOLUTE(.); + SECTION_MAPPINGS(extram_noinit) *(.ext_ram_noinit*) ALIGNED_SYMBOL(4, _ext_ram_noinit_end) @@ -291,11 +294,7 @@ SECTIONS { ALIGNED_SYMBOL(8, _bss_start) - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] + SECTION_MAPPINGS(dram0_bss) ALIGNED_SYMBOL(8, _bss_end) } > dram0_0_seg @@ -329,7 +328,7 @@ SECTIONS { _flash_rodata_start = ABSOLUTE(.); - mapping[flash_rodata] + SECTION_MAPPINGS(flash_rodata) *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) @@ -347,16 +346,6 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) -#if EH_FRAME_LINKING_ENABLED - ALIGNED_SYMBOL(4, __eh_frame) - KEEP(*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); -#endif // EH_FRAME_LINKING_ENABLED - /** * C++ constructor tables. * @@ -384,9 +373,37 @@ SECTIONS *(.lit4.*) *(.gnu.linkonce.lit4.*) _lit4_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); + } > default_rodata_seg + ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - /* TLS data. */ - ALIGNED_SYMBOL(4, _thread_local_start) +#if EH_FRAME_LINKING_ENABLED + .eh_frame : + { + ALIGNED_SYMBOL(4, __eh_frame) + + KEEP (*(.eh_frame)) + /** + * As we are not linking with crtend.o, which includes the CIE terminator + * (see __FRAME_END__ in libgcc sources), it is manually provided here. + */ + LONG(0); + + __eh_frame_end = ABSOLUTE(.); + + . = ALIGN(ALIGNOF(.flash.tdata)); + } > default_rodata_seg +#endif // EH_FRAME_LINKING_ENABLED + + .flash.tdata : + { + /* Keep tdata and tbss sections contiguous (no gaps between them). + * The TLS runtime code calculates offsets assuming these sections are + * adjacent. Gaps would cause incorrect address calculations, leading + * to accessing wrong memory. + */ + /* tdata sections */ + _thread_local_data_start = ABSOLUTE(.); #if CONFIG_LIBC_PICOLIBC _picolibc_reent_stub_start = ABSOLUTE(.); KEEP(*(.tdata.errno)) @@ -398,15 +415,18 @@ SECTIONS #endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY _picolibc_reent_stub_end = ABSOLUTE(.); #endif // CONFIG_LIBC_PICOLIBC - *(.tdata) - *(.tdata.*) - *(.tbss) - *(.tbss.*) - _thread_local_end = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _thread_local_data_end = ABSOLUTE(.); + /* tbss sections */ + _thread_local_bss_start = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + _thread_local_bss_end = ABSOLUTE(.); } > default_rodata_seg + _tls_section_alignment = ALIGNOF(.flash.tdata); ASSERT_PICOLIBC_REENT_STUB() - - _flash_rodata_align = ALIGNOF(.flash.rodata); + ASSERT(_thread_local_data_end == _thread_local_bss_start, + "tdata and tbss must be contiguous.") /** * This section contains all the rodata that is not used @@ -421,7 +441,8 @@ SECTIONS */ _rodata_reserved_end = ABSOLUTE(.); - mapping[rodata_noload] + SECTION_MAPPINGS(rodata_noload) + } > default_rodata_seg .flash.text : @@ -434,7 +455,7 @@ SECTIONS _instruction_reserved_start = ABSOLUTE(.); _text_start = ABSOLUTE(.); - mapping[flash_text] + SECTION_MAPPINGS(flash_text) *(.stub) *(.gnu.warning) @@ -478,7 +499,8 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_start) } > dram0_0_seg -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/esp32s3/memory.ld.in b/components/esp_system/ld/esp32s3/memory.ld.in index ba229c649b9..400efc22dff 100644 --- a/components/esp_system/ld/esp32s3/memory.ld.in +++ b/components/esp_system/ld/esp32s3/memory.ld.in @@ -130,9 +130,6 @@ _heap_start = _heap_low_start; /* Heap ends at top of dram0_0_seg */ _heap_end = 0x40000000; -_data_seg_org = ORIGIN(rtc_data_seg); - - /* RTC fast memory shares the same range for both data and instructions */ REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index bf71a95412a..7a12ddb7bbf 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -24,7 +24,7 @@ SECTIONS *(.rtc.entry.literal .rtc.entry.text) - mapping[rtc_text] + SECTION_MAPPINGS(rtc_text) *rtc_wake_stub*.*(.literal .text .literal.* .text.*) *(.rtc_text_end_test) @@ -47,7 +47,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_force_fast_start) - mapping[rtc_force_fast] + SECTION_MAPPINGS(rtc_force_fast) *(.rtc.force_fast .rtc.force_fast.*) @@ -66,7 +66,7 @@ SECTIONS { _rtc_data_start = ABSOLUTE(.); - mapping[rtc_data] + SECTION_MAPPINGS(rtc_data) *rtc_wake_stub*.*(.data .rodata .data.* .rodata.*) @@ -81,7 +81,7 @@ SECTIONS *rtc_wake_stub*.*(.bss .bss.*) *rtc_wake_stub*.*(COMMON) - mapping[rtc_bss] + SECTION_MAPPINGS(rtc_bss) _rtc_bss_end = ABSOLUTE(.); } > rtc_data_location @@ -98,6 +98,8 @@ SECTIONS { ALIGNED_SYMBOL(4, _rtc_noinit_start) + SECTION_MAPPINGS(rtc_noinit) + *(.rtc_noinit .rtc_noinit.*) ALIGNED_SYMBOL(4, _rtc_noinit_end) @@ -195,8 +197,7 @@ SECTIONS /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); - mapping[iram0_text] - + SECTION_MAPPINGS(iram0_text) } > iram0_0_seg /** @@ -205,8 +206,7 @@ SECTIONS */ .dram0.dummy (NOLOAD): { - /* MAX() uses unsigned long arithmetic. Add offset to prevent underflow when _iram_end < _diram_i_start */ - . = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start + (_diram_i_start - ORIGIN(iram0_0_seg)), (_diram_i_start - ORIGIN(iram0_0_seg))) - (_diram_i_start - ORIGIN(iram0_0_seg)); + . = ORIGIN(dram0_0_seg) + ((_iram_end > _diram_i_start) ? (_iram_end - _diram_i_start) : 0); } > dram0_0_seg .dram0.data : @@ -220,7 +220,7 @@ SECTIONS *(.gnu.linkonce.s2.*) *(.jcr) - mapping[dram0_data] + SECTION_MAPPINGS(dram0_data) _data_end = ABSOLUTE(.); } > dram0_0_seg @@ -245,11 +245,7 @@ SECTIONS { ALIGNED_SYMBOL(8, _bss_start) - /** - * ldgen places all bss-related data to mapping[dram0_bss] - * (See components/esp_system/app.lf). - */ - mapping[dram0_bss] + SECTION_MAPPINGS(dram0_bss) ALIGNED_SYMBOL(8, _bss_end) } > dram0_0_seg @@ -267,7 +263,7 @@ SECTIONS _instruction_reserved_start = ABSOLUTE(.); _text_start = ABSOLUTE(.); - mapping[flash_text] + SECTION_MAPPINGS(flash_text) *(.stub) *(.gnu.warning) @@ -341,7 +337,7 @@ SECTIONS { _flash_rodata_start = ABSOLUTE(.); - mapping[flash_rodata] + SECTION_MAPPINGS(flash_rodata) *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) @@ -359,16 +355,6 @@ SECTIONS __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); *(.xt_except_desc_end) -#if EH_FRAME_LINKING_ENABLED - ALIGNED_SYMBOL(4, __eh_frame) - KEEP(*(.eh_frame)) - /** - * As we are not linking with crtend.o, which includes the CIE terminator - * (see __FRAME_END__ in libgcc sources), it is manually provided here. - */ - LONG(0); -#endif // EH_FRAME_LINKING_ENABLED - /** * C++ constructor tables. * @@ -396,9 +382,37 @@ SECTIONS *(.lit4.*) *(.gnu.linkonce.lit4.*) _lit4_end = ABSOLUTE(.); + . = ALIGN(ALIGNOF(SECTION_AFTER_FLASH_RODATA)); + } > default_rodata_seg + ASSERT_SECTIONS_GAP(.flash.rodata, SECTION_AFTER_FLASH_RODATA) - /* TLS data. */ - ALIGNED_SYMBOL(4, _thread_local_start) +#if EH_FRAME_LINKING_ENABLED + .eh_frame : + { + ALIGNED_SYMBOL(4, __eh_frame) + + KEEP (*(.eh_frame)) + /** + * As we are not linking with crtend.o, which includes the CIE terminator + * (see __FRAME_END__ in libgcc sources), it is manually provided here. + */ + LONG(0); + + __eh_frame_end = ABSOLUTE(.); + + . = ALIGN(ALIGNOF(.flash.tdata)); + } > default_rodata_seg +#endif // EH_FRAME_LINKING_ENABLED + + .flash.tdata : + { + /* Keep tdata and tbss sections contiguous (no gaps between them). + * The TLS runtime code calculates offsets assuming these sections are + * adjacent. Gaps would cause incorrect address calculations, leading + * to accessing wrong memory. + */ + /* tdata sections */ + _thread_local_data_start = ABSOLUTE(.); #if CONFIG_LIBC_PICOLIBC _picolibc_reent_stub_start = ABSOLUTE(.); KEEP(*(.tdata.errno)) @@ -410,15 +424,18 @@ SECTIONS #endif // CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY _picolibc_reent_stub_end = ABSOLUTE(.); #endif // CONFIG_LIBC_PICOLIBC - *(.tdata) - *(.tdata.*) - *(.tbss) - *(.tbss.*) - _thread_local_end = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _thread_local_data_end = ABSOLUTE(.); + /* tbss sections */ + _thread_local_bss_start = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + _thread_local_bss_end = ABSOLUTE(.); } > default_rodata_seg + _tls_section_alignment = ALIGNOF(.flash.tdata); ASSERT_PICOLIBC_REENT_STUB() - - _flash_rodata_align = ALIGNOF(.flash.rodata); + ASSERT(_thread_local_data_end == _thread_local_bss_start, + "tdata and tbss must be contiguous.") /** * This section contains all the rodata that is not used @@ -433,7 +450,7 @@ SECTIONS */ _rodata_reserved_end = ABSOLUTE(.); - mapping[rodata_noload] + SECTION_MAPPINGS(rodata_noload) } > default_rodata_seg /** @@ -453,7 +470,7 @@ SECTIONS { _ext_ram_bss_start = ABSOLUTE(.); - mapping[extern_ram] + SECTION_MAPPINGS(extern_ram) ALIGNED_SYMBOL(4, _ext_ram_bss_end) } > extern_ram_seg @@ -468,6 +485,7 @@ SECTIONS { _ext_ram_noinit_start = ABSOLUTE(.); + SECTION_MAPPINGS(extram_noinit) *(.ext_ram_noinit*) ALIGNED_SYMBOL(4, _ext_ram_noinit_end) @@ -491,7 +509,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _iram_data_start) - mapping[iram0_data] + SECTION_MAPPINGS(iram0_data) ALIGNED_SYMBOL(4, _iram_data_end) } > iram0_0_seg @@ -500,7 +518,7 @@ SECTIONS { ALIGNED_SYMBOL(4, _iram_bss_start) - mapping[iram0_bss] + SECTION_MAPPINGS(iram0_bss) _iram_bss_end = ABSOLUTE(.); ALIGNED_SYMBOL(4, _iram_end) @@ -513,7 +531,8 @@ SECTIONS ALIGNED_SYMBOL(8, _heap_low_start) } > dram0_0_seg -#include "elf_misc.ld.in" +#include "ld.debug.sections" +#include "ld.discard.sections" } ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), diff --git a/components/esp_system/ld/ld.common b/components/esp_system/ld/ld.common index 4c39566ae2b..51e2d3f2eba 100644 --- a/components/esp_system/ld/ld.common +++ b/components/esp_system/ld/ld.common @@ -105,7 +105,12 @@ ASSERT((ADDR(NEXT_SECTION) == ADDR(PREV_SECTION) + SIZEOF(PREV_SECTION)), \ #endif #if EH_FRAME_LINKING_ENABLED +#if CONFIG_IDF_TARGET_ARCH_RISCV #define SECTION_AFTER_FLASH_RODATA .eh_frame_hdr +#endif +#if CONFIG_IDF_TARGET_ARCH_XTENSA +#define SECTION_AFTER_FLASH_RODATA .eh_frame +#endif #else #define SECTION_AFTER_FLASH_RODATA .flash.tdata #endif diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index a26a41c7074..7e799a9d674 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -450,30 +450,36 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u LOW ADDRESS |---------------------------| Linker Symbols | Section | -------------- - | .flash.rodata | - 0x0|---------------------------| <- _flash_rodata_start - ^ | Other Data | - | |---------------------------| <- _thread_local_start - | | .tbss | ^ - V | | | - 0xNNN | int example; | | tls_area_size - | | | - | .tdata | V - |---------------------------| <- _thread_local_end + | .flash.tdata | + 0x0|---------------------------| <- _thread_local_data_start ^ + | .flash.tdata | | + | int var_1 = 1; | | + | | <- _thread_local_data_end | + | | <- _thread_local_bss_start | tls_area_size + | | | + | .flash.tbss (NOLOAD) | | + | int var_2; | | + |---------------------------| <- _thread_local_bss_end V | Other data | | ... | |---------------------------| HIGH ADDRESS */ // Calculate the TLS area's size (rounded up to multiple of 16 bytes). - extern int _thread_local_start, _thread_local_end, _flash_rodata_start, _flash_rodata_align; - const uint32_t tls_area_size = ALIGNUP(16, (uint32_t)&_thread_local_end - (uint32_t)&_thread_local_start); + extern int _tls_section_alignment; + extern char _thread_local_data_start, _thread_local_data_end; + extern char _thread_local_bss_start, _thread_local_bss_end; + const uint32_t tls_data_size = (uint32_t)&_thread_local_data_end - (uint32_t)&_thread_local_data_start; + const uint32_t tls_bss_size = (uint32_t)&_thread_local_bss_end - (uint32_t)&_thread_local_bss_start; + const uint32_t tls_area_size = ALIGNUP(16, tls_data_size + tls_bss_size); // TODO: check that TLS area fits the stack // Allocate space for the TLS area on the stack. The area must be allocated at a 16-byte aligned address uxStackPointer = STACKPTR_ALIGN_DOWN(16, uxStackPointer - (UBaseType_t)tls_area_size); - // Initialize the TLS area with the initialization values of each TLS variable - memcpy((void *)uxStackPointer, &_thread_local_start, tls_area_size); + // Initialize the TLS data with the initialization values of each TLS variable + memcpy((void *)uxStackPointer, &_thread_local_data_start, tls_data_size); + // Initialize the TLS bss with zeroes + memset((void *)(uxStackPointer + tls_data_size), 0, tls_bss_size); /* Calculate the THREADPTR register's initialization value based on the link-time offset and the TLS area allocated on @@ -500,10 +506,10 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u - "offset = address - tls_section_vma + align_up(TCB_SIZE, tls_section_alignment)" - TCB_SIZE is hardcoded to 8 */ - const uint32_t tls_section_align = (uint32_t)&_flash_rodata_align; // ALIGN value of .flash.rodata section + const uint32_t tls_section_align = (uint32_t)&_tls_section_alignment; // ALIGN value of .flash.tdata section #define TCB_SIZE 8 const uint32_t base = ALIGNUP(tls_section_align, TCB_SIZE); - *ret_threadptr_reg_init = (uint32_t)uxStackPointer - ((uint32_t)&_thread_local_start - (uint32_t)&_flash_rodata_start) - base; + *ret_threadptr_reg_init = (uint32_t)uxStackPointer - base; return uxStackPointer; } diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index 2b5f5aadb0b..4364d28f56f 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -8,7 +8,7 @@ * * SPDX-License-Identifier: MIT * - * SPDX-FileContributor: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2023-2026 Espressif Systems (Shanghai) CO LTD * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -220,30 +220,36 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u LOW ADDRESS |---------------------------| Linker Symbols | Section | -------------- - | .flash.rodata | - 0x0|---------------------------| <- _flash_rodata_start - ^ | Other Data | - | |---------------------------| <- _thread_local_start - | | .tbss | ^ - V | | | - 0xNNN | int example; | | tls_area_size - | | | - | .tdata | V - |---------------------------| <- _thread_local_end + | .flash.tdata | + 0x0|---------------------------| <- _thread_local_data_start ^ + | .flash.tdata | | + | int var_1 = 1; | | + | | <- _thread_local_data_end | + | | <- _thread_local_bss_start | tls_area_size + | | | + | .flash.tbss (NOLOAD) | | + | int var_2; | | + |---------------------------| <- _thread_local_bss_end V | Other data | | ... | |---------------------------| HIGH ADDRESS */ // Calculate the TLS area's size (rounded up to multiple of 16 bytes). - extern int _thread_local_start, _thread_local_end, _flash_rodata_start, _flash_rodata_align; - const uint32_t tls_area_size = ALIGNUP(16, (uint32_t)&_thread_local_end - (uint32_t)&_thread_local_start); + extern int _tls_section_alignment; + extern char _thread_local_data_start, _thread_local_data_end; + extern char _thread_local_bss_start, _thread_local_bss_end; + const uint32_t tls_data_size = (uint32_t)&_thread_local_data_end - (uint32_t)&_thread_local_data_start; + const uint32_t tls_bss_size = (uint32_t)&_thread_local_bss_end - (uint32_t)&_thread_local_bss_start; + const uint32_t tls_area_size = ALIGNUP(16, tls_data_size + tls_bss_size); // TODO: check that TLS area fits the stack // Allocate space for the TLS area on the stack. The area must be allocated at a 16-byte aligned address uxStackPointer = STACKPTR_ALIGN_DOWN(16, uxStackPointer - (UBaseType_t)tls_area_size); - // Initialize the TLS area with the initialization values of each TLS variable - memcpy((void *)uxStackPointer, &_thread_local_start, tls_area_size); + // Initialize the TLS data with the initialization values of each TLS variable + memcpy((void *)uxStackPointer, &_thread_local_data_start, tls_data_size); + // Initialize the TLS bss with zeroes + memset((void *)(uxStackPointer + tls_data_size), 0, tls_bss_size); /* Calculate the THREADPTR register's initialization value based on the link-time offset and the TLS area allocated on @@ -270,10 +276,10 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u - "offset = address - tls_section_vma + align_up(TCB_SIZE, tls_section_alignment)" - TCB_SIZE is hardcoded to 8 */ - const uint32_t tls_section_align = (uint32_t)&_flash_rodata_align; // ALIGN value of .flash.rodata section + const uint32_t tls_section_align = (uint32_t)&_tls_section_alignment; // ALIGN value of .flash.tdata section #define TCB_SIZE 8 const uint32_t base = ALIGNUP(tls_section_align, TCB_SIZE); - *ret_threadptr_reg_init = (uint32_t)uxStackPointer - ((uint32_t)&_thread_local_start - (uint32_t)&_flash_rodata_start) - base; + *ret_threadptr_reg_init = (uint32_t)uxStackPointer - base; return uxStackPointer; }