fix(esp_system): xtensa: refactor linker scripts and reduce binary size for C++ apps

This commit is contained in:
Alexey Lapshin
2026-01-28 18:57:27 +07:00
committed by BOT
parent 6bd63cc577
commit dfafd6fc2a
9 changed files with 225 additions and 155 deletions
@@ -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 */
+58 -38
View File
@@ -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)),
@@ -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 */
+57 -35
View File
@@ -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)),
@@ -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 );
+59 -40
View File
@@ -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)),
+5
View File
@@ -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
@@ -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;
}
@@ -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;
}