[PATCH] ld: Account for .tbss size on ARM EABI targets
Torbjörn SVENSSON
torbjorn.svensson@foss.st.com
Tue Aug 18 09:32:05 GMT 2026
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
--
2.43.0
More information about the Binutils
mailing list