[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