[PING]: [PATCH] ld: Account for .tbss size on ARM EABI targets
Torbjorn SVENSSON
torbjorn.svensson@foss.st.com
Fri Aug 28 13:10:09 GMT 2026
Gentle ping! :)
Kind regards,
Torbjörn
On 2026-08-18 11:32, Torbjörn SVENSSON wrote:
> Ok for master?
>
> --
>
> Bare-metal ARM EABI programs allocate TLS storage directly, so if .tdata
> consumses VMA, then .tbss must also do so. Otherwise, a following
> section such as .bss can overlap it.
>
> Keep the existing behavior for non-EABI targets, and add tests for
> static, executable, PIE, and dynamic links.
>
> This change aligns with LLVM lld behavior for .tbss.
>
> ld/
>
> * ld.h: New build-time property tls_nobits_occupies_vma.
> * ldlang.c: Make .tbss occupy VMA when tls_nobits_occupies_vma
> is true.
> * emultempl/armelf.em: Set tls_nobits_occupies_vma to true for
> arm*-*-eabi* targets.
> * testsuite/ld-arm/arm-elf.exp: Add new tests.
> * testsuite/ld-arm/tls-app-eabi.d: New test.
> * testsuite/ld-arm/tls-nobits-vma.s: New source.
> * testsuite/ld-arm/tls-nobits-vma-dynamic.d: New test.
> * testsuite/ld-arm/tls-nobits-vma-exec.d: New test.
> * testsuite/ld-arm/tls-nobits-vma-pie.d: New test.
> * testsuite/ld-arm/tls-nobits-vma-static.d: New test.
> * testsuite/ld-arm/tls-nobits-vma.ld: New test.
>
> Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
> ---
> ld/emultempl/armelf.em | 1 +
> ld/ld.h | 4 +++
> ld/ldlang.c | 15 ++++++-----
> ld/testsuite/ld-arm/arm-elf.exp | 18 ++++++++++---
> ld/testsuite/ld-arm/tls-app-eabi.d | 18 +++++++++++++
> ld/testsuite/ld-arm/tls-nobits-vma-dynamic.d | 27 +++++++++++++++++++
> ld/testsuite/ld-arm/tls-nobits-vma-exec.d | 22 +++++++++++++++
> ld/testsuite/ld-arm/tls-nobits-vma-pie.d | 28 ++++++++++++++++++++
> ld/testsuite/ld-arm/tls-nobits-vma-static.d | 22 +++++++++++++++
> ld/testsuite/ld-arm/tls-nobits-vma.ld | 13 +++++++++
> ld/testsuite/ld-arm/tls-nobits-vma.s | 11 ++++++++
> 11 files changed, 170 insertions(+), 9 deletions(-)
> create mode 100644 ld/testsuite/ld-arm/tls-app-eabi.d
> create mode 100644 ld/testsuite/ld-arm/tls-nobits-vma-dynamic.d
> create mode 100644 ld/testsuite/ld-arm/tls-nobits-vma-exec.d
> create mode 100644 ld/testsuite/ld-arm/tls-nobits-vma-pie.d
> create mode 100644 ld/testsuite/ld-arm/tls-nobits-vma-static.d
> create mode 100644 ld/testsuite/ld-arm/tls-nobits-vma.ld
> create mode 100644 ld/testsuite/ld-arm/tls-nobits-vma.s
>
> diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
> index f70bcf34b8b..9e59f7ceb94 100644
> --- a/ld/emultempl/armelf.em
> +++ b/ld/emultempl/armelf.em
> @@ -58,6 +58,7 @@ gld${EMULATION_NAME}_before_parse (void)
> #endif /* not TARGET_ */
> input_flags.dynamic = ${DYNAMIC_LINK-true};
> config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`;
> + config.tls_nobits_occupies_vma = `case ${target} in arm*-*-eabi*) echo true ;; *) echo false ;; esac`;
> config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo true ; else echo false ; fi`;
> EOF
> if test -n "$COMMONPAGESIZE"; then
> diff --git a/ld/ld.h b/ld/ld.h
> index 76825e4253c..8f83a9da4d1 100644
> --- a/ld/ld.h
> +++ b/ld/ld.h
> @@ -236,6 +236,10 @@ typedef struct
> parameter. */
> bool has_shared;
>
> + /* If TRUE, TLS NOBITS sections consume VMA like other allocated
> + sections. */
> + bool tls_nobits_occupies_vma;
> +
> /* If TRUE, build constructors. */
> bool build_constructors;
>
> diff --git a/ld/ldlang.c b/ld/ldlang.c
> index 65494acca00..35b884bd98a 100644
> --- a/ld/ldlang.c
> +++ b/ld/ldlang.c
> @@ -5890,8 +5890,11 @@ sort_sections_by_vma (const void *arg1, const void *arg2)
> #define IS_TBSS(s) \
> ((s->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == SEC_THREAD_LOCAL)
>
> +#define TBSS_EFFECTIVELY_ZERO(s) \
> + (IS_TBSS (s) && !config.tls_nobits_occupies_vma)
> +
> #define IGNORE_SECTION(s) \
> - ((s->flags & SEC_ALLOC) == 0 || IS_TBSS (s))
> + ((s->flags & SEC_ALLOC) == 0 || TBSS_EFFECTIVELY_ZERO (s))
>
> /* Check to see if any allocated sections overlap with other allocated
> sections. This can happen if a linker script specifies the output
> @@ -6433,8 +6436,8 @@ lang_size_sections_1
> if (bfd_is_abs_section (os->bfd_section) || os->ignored)
> break;
>
> - /* .tbss sections effectively have zero size. */
> - if (!IS_TBSS (os->bfd_section)
> + /* Hosted .tbss sections effectively have zero size. */
> + if (!TBSS_EFFECTIVELY_ZERO (os->bfd_section)
> || bfd_link_relocatable (&link_info))
> dotdelta = TO_ADDR (os->bfd_section->size);
> else
> @@ -6813,7 +6816,7 @@ lang_size_relro_segment_1 (void)
> bfd_vma start, end, bump;
>
> end = start = sec->vma;
> - if (!IS_TBSS (sec))
> + if (!TBSS_EFFECTIVELY_ZERO (sec))
> end += TO_ADDR (sec->size);
> bump = desired_end - end;
> /* We'd like to increase START by BUMP, but we must heed
> @@ -6936,8 +6939,8 @@ lang_do_assignments_1 (lang_statement_union_type *s,
> {
> newdot = os->bfd_section->vma;
>
> - /* .tbss sections effectively have zero size. */
> - if (!IS_TBSS (os->bfd_section)
> + /* Hosted .tbss sections effectively have zero size. */
> + if (!TBSS_EFFECTIVELY_ZERO (os->bfd_section)
> || bfd_link_relocatable (&link_info))
> newdot += TO_ADDR (os->bfd_section->size);
>
> diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
> index ad27c1f86c9..5b5906e10ee 100644
> --- a/ld/testsuite/ld-arm/arm-elf.exp
> +++ b/ld/testsuite/ld-arm/arm-elf.exp
> @@ -120,20 +120,25 @@ set tmp {
> "arm-call"}
> }
> append armelftests_common $tmp
> -set tmp {
> +if {[istarget "arm*-*-eabi*"]} {
> + set tls_app_dump tls-app-eabi.d
> +} else {
> + set tls_app_dump tls-app.d
> +}
> +set tmp [subst -nocommands -nobackslashes {
> {"TLS shared library" "-shared -T arm-lib.ld --hash-style=sysv" ""
> "" {tls-lib.s}
> {{objdump -fdw tls-lib.d} {objdump -Rw tls-lib.r}}
> "tls-lib.so"}
> {"TLS dynamic application"
> "-T arm-dyn.ld --hash-style=sysv tmpdir/tls-lib.so" "" "" {tls-app.s}
> - {{objdump -fdw tls-app.d} {objdump -Rw tls-app.r}}
> + {{objdump -fdw $tls_app_dump} {objdump -Rw tls-app.r}}
> "tls-app"}
> {"TLS gnu shared library got"
> "-shared -T arm-dyn.ld --hash-style=sysv" "" "" {tls-gdesc-got.s}
> {{objdump "-fDR -j .got" tls-gdesc-got.d}}
> "tls-lib2-got.so"}
> -}
> +}]
> if [check_shared_lib_support] { append armelftests_common $tmp }
> set tmp {
> {"TLS gnu GD to IE relaxation"
> @@ -432,6 +437,13 @@ run_dump_test "rel32-reject"
> run_dump_test "rel32-reject-pie"
> run_dump_test "pie-bind-locally"
>
> +if {[istarget "arm*-*-eabi*"]} {
> + run_dump_test "tls-nobits-vma-static"
> + run_dump_test "tls-nobits-vma-exec"
> + run_dump_test "tls-nobits-vma-pie"
> + run_dump_test "tls-nobits-vma-dynamic"
> +}
> +
> # Exclude non-ARM-EABI targets.
>
> if { [istarget "arm*-*-netbsd*"] } {
> diff --git a/ld/testsuite/ld-arm/tls-app-eabi.d b/ld/testsuite/ld-arm/tls-app-eabi.d
> new file mode 100644
> index 00000000000..d240a0ecbaa
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/tls-app-eabi.d
> @@ -0,0 +1,18 @@
> +
> +.*: file format elf32-.*arm.*
> +architecture: arm.*, flags 0x00000112:
> +EXEC_P, HAS_SYMS, D_PAGED
> +start address 0x00008[0-9a-f]+
> +
> +Disassembly of section .text:
> +
> +00008[0-9a-f]+ <foo>:
> + 8[0-9a-f]+: e1a00000 nop @ \(mov r0, r0\)
> + 8[0-9a-f]+: e1a00000 nop @ \(mov r0, r0\)
> + 8[0-9a-f]+: e1a0f00e mov pc, lr
> + 8[0-9a-f]+: 000080c4 .word 0x000080c4
> + 8[0-9a-f]+: 000080bc .word 0x000080bc
> + 8[0-9a-f]+: 000080b4 .word 0x000080b4
> + 8[0-9a-f]+: 00000004 .word 0x00000004
> + 8[0-9a-f]+: 000080cc .word 0x000080cc
> + 8[0-9a-f]+: 00000014 .word 0x00000014
> diff --git a/ld/testsuite/ld-arm/tls-nobits-vma-dynamic.d b/ld/testsuite/ld-arm/tls-nobits-vma-dynamic.d
> new file mode 100644
> index 00000000000..3c8e8930656
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/tls-nobits-vma-dynamic.d
> @@ -0,0 +1,27 @@
> +#source: tls-nobits-vma.s
> +#ld: -shared -T tls-nobits-vma.ld
> +#readelf: -hSW
> +
> +ELF Header:
> +#...
> + Type: +DYN \(Shared object file\)
> +#...
> +
> +Section Headers:
> + \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
> + \[ 0\] +NULL +0+ +0+ +0+ +0+ +0 +0 +0
> + \[ 1\] .dynsym +DYNSYM +00008000 +[0-9a-f]+ +000010 +10 +A +2 +1 +4
> + \[ 2\] .dynstr +STRTAB +00008010 +[0-9a-f]+ +000001 +00 +A +0 +0 +1
> + \[ 3\] .hash +HASH +00008014 +[0-9a-f]+ +000010 +04 +A +1 +0 +4
> + \[ 4\] .data +PROGBITS +00001000 +[0-9a-f]+ +000004 +00 +WA +0 +0 +4
> + \[ 5\] .dynamic +DYNAMIC +00001004 +[0-9a-f]+ +000058 +08 +WA +2 +0 +4
> + \[ 6\] .got.plt +PROGBITS +0000105c +[0-9a-f]+ +00000c +04 +WA +0 +0 +4
> + \[ 7\] .tdata +PROGBITS +00001068 +[0-9a-f]+ +000004 +00 WAT +0 +0 +4
> + \[ 8\] .tbss +NOBITS +0000106c +[0-9a-f]+ +000004 +00 WAT +0 +0 +4
> + \[ 9\] .bss +NOBITS +00001070 +[0-9a-f]+ +000008 +00 +WA +0 +0 +4
> + \[10\] .ARM.attributes +ARM_ATTRIBUTES +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> + \[11\] .symtab +SYMTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +10 +12 +[0-9]+ +4
> + \[12\] .strtab +STRTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> + \[13\] .shstrtab +STRTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> +Key to Flags:
> +#...
> diff --git a/ld/testsuite/ld-arm/tls-nobits-vma-exec.d b/ld/testsuite/ld-arm/tls-nobits-vma-exec.d
> new file mode 100644
> index 00000000000..adf00663084
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/tls-nobits-vma-exec.d
> @@ -0,0 +1,22 @@
> +#source: tls-nobits-vma.s
> +#ld: -T tls-nobits-vma.ld
> +#readelf: -hSW
> +
> +ELF Header:
> +#...
> + Type: +EXEC \(Executable file\)
> +#...
> +
> +Section Headers:
> + \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
> + \[ 0\] +NULL +0+ +0+ +0+ +0+ +0 +0 +0
> + \[ 1\] .data +PROGBITS +00001000 +[0-9a-f]+ +000004 +00 +WA +0 +0 +4
> + \[ 2\] .tdata +PROGBITS +00001004 +[0-9a-f]+ +000004 +00 WAT +0 +0 +4
> + \[ 3\] .tbss +NOBITS +00001008 +[0-9a-f]+ +000004 +00 WAT +0 +0 +4
> + \[ 4\] .bss +NOBITS +0000100c +[0-9a-f]+ +000008 +00 +WA +0 +0 +4
> + \[ 5\] .ARM.attributes +ARM_ATTRIBUTES +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> + \[ 6\] .symtab +SYMTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +10 +7 +[0-9]+ +4
> + \[ 7\] .strtab +STRTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> + \[ 8\] .shstrtab +STRTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> +Key to Flags:
> +#...
> diff --git a/ld/testsuite/ld-arm/tls-nobits-vma-pie.d b/ld/testsuite/ld-arm/tls-nobits-vma-pie.d
> new file mode 100644
> index 00000000000..9fbcde5b491
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/tls-nobits-vma-pie.d
> @@ -0,0 +1,28 @@
> +#source: tls-nobits-vma.s
> +#ld: -pie -T tls-nobits-vma.ld
> +#readelf: -hSW
> +
> +ELF Header:
> +#...
> + Type: +EXEC \(Executable file\)
> +#...
> +
> +Section Headers:
> + \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
> + \[ 0\] +NULL +0+ +0+ +0+ +0+ +0 +0 +0
> + \[ 1\] .interp +PROGBITS +00008000 +[0-9a-f]+ +000011 +00 +A +0 +0 +1
> + \[ 2\] .dynsym +DYNSYM +00008014 +[0-9a-f]+ +000010 +10 +A +3 +1 +4
> + \[ 3\] .dynstr +STRTAB +00008024 +[0-9a-f]+ +000001 +00 +A +0 +0 +1
> + \[ 4\] .hash +HASH +00008028 +[0-9a-f]+ +000010 +04 +A +2 +0 +4
> + \[ 5\] .data +PROGBITS +00001000 +[0-9a-f]+ +000004 +00 +WA +0 +0 +4
> + \[ 6\] .dynamic +DYNAMIC +00001004 +[0-9a-f]+ +000068 +08 +WA +3 +0 +4
> + \[ 7\] .got.plt +PROGBITS +0000106c +[0-9a-f]+ +00000c +04 +WA +0 +0 +4
> + \[ 8\] .tdata +PROGBITS +00001078 +[0-9a-f]+ +000004 +00 WAT +0 +0 +4
> + \[ 9\] .tbss +NOBITS +0000107c +[0-9a-f]+ +000004 +00 WAT +0 +0 +4
> + \[10\] .bss +NOBITS +00001080 +[0-9a-f]+ +000008 +00 +WA +0 +0 +4
> + \[11\] .ARM.attributes +ARM_ATTRIBUTES +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> + \[12\] .symtab +SYMTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +10 +13 +[0-9]+ +4
> + \[13\] .strtab +STRTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> + \[14\] .shstrtab +STRTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> +Key to Flags:
> +#...
> diff --git a/ld/testsuite/ld-arm/tls-nobits-vma-static.d b/ld/testsuite/ld-arm/tls-nobits-vma-static.d
> new file mode 100644
> index 00000000000..7e3cdb9159d
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/tls-nobits-vma-static.d
> @@ -0,0 +1,22 @@
> +#source: tls-nobits-vma.s
> +#ld: -static -T tls-nobits-vma.ld
> +#readelf: -hSW
> +
> +ELF Header:
> +#...
> + Type: +EXEC \(Executable file\)
> +#...
> +
> +Section Headers:
> + \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
> + \[ 0\] +NULL +0+ +0+ +0+ +0+ +0 +0 +0
> + \[ 1\] .data +PROGBITS +00001000 +[0-9a-f]+ +000004 +00 +WA +0 +0 +4
> + \[ 2\] .tdata +PROGBITS +00001004 +[0-9a-f]+ +000004 +00 WAT +0 +0 +4
> + \[ 3\] .tbss +NOBITS +00001008 +[0-9a-f]+ +000004 +00 WAT +0 +0 +4
> + \[ 4\] .bss +NOBITS +0000100c +[0-9a-f]+ +000008 +00 +WA +0 +0 +4
> + \[ 5\] .ARM.attributes +ARM_ATTRIBUTES +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> + \[ 6\] .symtab +SYMTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +10 +7 +[0-9]+ +4
> + \[ 7\] .strtab +STRTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> + \[ 8\] .shstrtab +STRTAB +0+ +[0-9a-f]+ +[0-9a-f]+ +00 +0 +0 +1
> +Key to Flags:
> +#...
> diff --git a/ld/testsuite/ld-arm/tls-nobits-vma.ld b/ld/testsuite/ld-arm/tls-nobits-vma.ld
> new file mode 100644
> index 00000000000..14c1527e401
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/tls-nobits-vma.ld
> @@ -0,0 +1,13 @@
> +MEMORY
> +{
> + FLASH (rx) : ORIGIN = 0x8000, LENGTH = 0x1000
> + RAM (rw) : ORIGIN = 0x1000, LENGTH = 0x1000
> +}
> +
> +SECTIONS
> +{
> + .data : ALIGN(4) { *(.data) } >RAM AT>FLASH
> + .tdata : ALIGN(4) { *(.tdata) } >RAM AT>FLASH
> + .tbss (NOLOAD) : ALIGN(4) { *(.tbss) } >RAM
> + .bss (NOLOAD) : ALIGN(4) { *(.bss) } >RAM
> +}
> diff --git a/ld/testsuite/ld-arm/tls-nobits-vma.s b/ld/testsuite/ld-arm/tls-nobits-vma.s
> new file mode 100644
> index 00000000000..df2607251b1
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/tls-nobits-vma.s
> @@ -0,0 +1,11 @@
> + .section .data,"aw",%progbits
> + .word 1
> +
> + .section .tdata,"awT",%progbits
> + .word 2
> +
> + .section .tbss,"awT",%nobits
> + .space 4
> +
> + .section .bss,"aw",%nobits
> + .space 8
More information about the Binutils
mailing list