aboutsummaryrefslogtreecommitdiff
path: root/ld/testsuite
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2025-07-04 08:39:03 +0800
committerH.J. Lu <hjl.tools@gmail.com>2025-08-20 13:53:32 -0700
commit0d1e88f8bfb0e62f37bf8a89172cd91373ace5e6 (patch)
tree48053196a0e72a9cf2402883f5ac5f42bd4742e7 /ld/testsuite
parentcf03cf4e8879bbfe6b90160ff3fda63feb2a898f (diff)
downloadbinutils-0d1e88f8bfb0e62f37bf8a89172cd91373ace5e6.zip
binutils-0d1e88f8bfb0e62f37bf8a89172cd91373ace5e6.tar.gz
binutils-0d1e88f8bfb0e62f37bf8a89172cd91373ace5e6.tar.bz2
x86: Add GLIBC_ABI_GNU2_TLS version dependency
On Linux/x86, programs and shared libraries compiled with -mtls-dialect=gnu2 may fail silently at run-time against glibc without the GNU2 TLS run-time fixes for: https://sourceware.org/bugzilla/show_bug.cgi?id=31501 https://sourceware.org/bugzilla/show_bug.cgi?id=31372 A version tag, GLIBC_ABI_GNU2_TLS, has been added to glibc to indicate that glibc has the working GNU2 TLS run-time. Add the --gnu2-tls-tag option to i386/x86-64 ELF linker to add the GLIBC_ABI_GNU2_TLS version dependency in output programs and shared libraries when linking against glibc if input relocatable object files have R_386_TLS_DESC_CALL or R_X86_64_TLSDESC_CALL relocation. The output will fail to load and run at run-time against glibc which doesn't define the GLIBC_ABI_GNU2_TLS version. Add the --enable-gnu2-tls-tag configure option to enable --gnu2-tls-tag by default. If unspecified, linker will add the GLIBC_ABI_GNU2_TLS version dependency if input object files have R_386_TLS_DESC_CALL or R_X86_64_TLSDESC_CALL relocation and libc.so defines the GLIBC_ABI_GNU2_TLS version. Update elf_link_add_glibc_verneed to properly add the GLIBC_2.36 version dependency when -z mark-plt -z nopack-relative-relocs passed to x86-64 ELF linker. bfd/ PR ld/33130 * elf-bfd.h (_bfd_elf_link_add_glibc_version_dependency): Add a pointer to bool argument. * elf-linker-x86.h (elf_linker_x86_params): Add gnu2_tls_version_tag. * elf32-i386.c (elf_i386_scan_relocs): Set has_tls_desc_call to 1 for R_386_TLS_DESC_CALL. (elf_i386_add_glibc_version_dependency): New. Undef before FreeBSD support. * elf64-x86-64.c (elf_x86_64_scan_relocs): Set has_tls_desc_call to 1 for R_X86_64_TLSDESC_CALL. (elf_x86_64_add_glibc_version_dependency): Add GLIBC_ABI_GNU2_TLS version dependency if GLIBC_ABI_GNU2_TLS dependency isn't disabled and has_tlsdesc_call isn't 0. (elf_backend_add_glibc_version_dependency): Undef before FreeBSD support and redefine for elf32-x86-64. * elflink.c (elf_link_add_glibc_verneed): Changed to return bool. Remove the pointer to elf_find_verdep_info argument. Add a pointer to bool argument, auto_version. Return true if linked against glibc. Otherwise return false. If the version dependency is added, set *auto_version to true. If *auto_version is true, add the version dependency only if libc.so defines the version. (_bfd_elf_link_add_glibc_version_dependency): Add a pointer to bool argument and pass it to elf_link_add_glibc_verneed. (_bfd_elf_link_add_dt_relr_dependency): Pass NULL to _bfd_elf_link_add_glibc_version_dependency. * elfxx-x86.h (elf_x86_link_hash_table): Add has_tls_desc_call. ld/ PR ld/33130 * NEWS: Mention --gnu2-tls-tag, --no-gnu2-tls-tag and --enable-gnu2-tls-tag. * config.in: Regenerated. * configure: Likewise. * configure.ac: Add --enable-gnu2-tls-tag. * ld.texi: Document --gnu2-tls-tag/--no-gnu2-tls-tag. * ldlex.h (option_values): Add OPTION_GNU2_TLS_VERSION_TAG and OPTION_NO_GNU2_TLS_VERSION_TAG. * emulparams/elf32_x86_64.sh (EXTRA_EM_FILE): Changed to "elf-x86-64-glibc". * emulparams/elf_i386.sh (EXTRA_EM_FILE): Set to "elf-i386-glibc". * emulparams/elf_i386_fbsd.sh (EXTRA_EM_FILE): New. Set to "elf-x86". * emulparams/elf_i386_haiku.sh (EXTRA_EM_FILE): Likewise. * emulparams/elf_x86_64.sh (EXTRA_EM_FILE): Likewise. * emulparams/elf_x86_64_fbsd.sh (EXTRA_EM_FILE): New. Set to "elf-x86-64". * emulparams/elf_x86_64_haiku.sh (EXTRA_EM_FILE): Likewise. * (EXTRA_EM_FILE): Likewise. * (EXTRA_EM_FILE): Likewise. * emultempl/elf-i386-glibc.em: New file. * emultempl/elf-x86-64-glibc.em: Likewise. * emultempl/elf-x86-64.em: Likewise. * emultempl/elf-x86-glibc.em: Likewise. * emultempl/elf-x86.em (elf_x86_64_before_parse): Removed. (LDEMUL_BEFORE_PARSE): Likewise. (elf_x86_64_before_allocation): Likewise. (LDEMUL_BEFORE_ALLOCATION): Likewise. * emultempl/solaris2-x86-64.em: New file. * testsuite/ld-i386/gnu2-tls-1.s: Likewise. * testsuite/ld-i386/gnu2-tls-1a.rd: Likewise. * testsuite/ld-i386/gnu2-tls-1b.rd: Likewise. * testsuite/ld-x86-64/gnu2-tls-1.s: Likewise. * testsuite/ld-x86-64/gnu2-tls-1a.rd: Likewise. * testsuite/ld-x86-64/gnu2-tls-1b.rd: Likewise. * testsuite/ld-x86-64/mark-plt-2.rd: Likewise. * testsuite/ld-x86-64/mark-plt-2.s: Likewise. * testsuite/ld-i386/i386.exp: Run GLIBC_ABI_GNU2_TLS tests. * testsuite/ld-x86-64/x86-64.exp: Likewise. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Diffstat (limited to 'ld/testsuite')
-rw-r--r--ld/testsuite/ld-i386/gnu2-tls-1.s11
-rw-r--r--ld/testsuite/ld-i386/gnu2-tls-1a.rd7
-rw-r--r--ld/testsuite/ld-i386/gnu2-tls-1b.rd4
-rw-r--r--ld/testsuite/ld-i386/i386.exp23
-rw-r--r--ld/testsuite/ld-x86-64/gnu2-tls-1.s11
-rw-r--r--ld/testsuite/ld-x86-64/gnu2-tls-1a.rd7
-rw-r--r--ld/testsuite/ld-x86-64/gnu2-tls-1b.rd4
-rw-r--r--ld/testsuite/ld-x86-64/mark-plt-2.rd7
-rw-r--r--ld/testsuite/ld-x86-64/mark-plt-2.s13
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp26
10 files changed, 112 insertions, 1 deletions
diff --git a/ld/testsuite/ld-i386/gnu2-tls-1.s b/ld/testsuite/ld-i386/gnu2-tls-1.s
new file mode 100644
index 0000000..e3841c7
--- /dev/null
+++ b/ld/testsuite/ld-i386/gnu2-tls-1.s
@@ -0,0 +1,11 @@
+ .section .text.startup,"ax",@progbits
+ .p2align 4
+ .globl main
+ .type main, @function
+main:
+ leal ld@TLSDESC(%ebx), %eax
+ call *ld@TLSCALL(%eax)
+ addl %gs:0, %eax
+ ret
+ .size main, .-main
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/gnu2-tls-1a.rd b/ld/testsuite/ld-i386/gnu2-tls-1a.rd
new file mode 100644
index 0000000..3eb926a
--- /dev/null
+++ b/ld/testsuite/ld-i386/gnu2-tls-1a.rd
@@ -0,0 +1,7 @@
+#...
+Version needs section '.gnu.version_r' contains 1 entry:
+ Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\)
+ +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+
+#...
+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU2_TLS Flags: none Version: [0-9]+
+#pass
diff --git a/ld/testsuite/ld-i386/gnu2-tls-1b.rd b/ld/testsuite/ld-i386/gnu2-tls-1b.rd
new file mode 100644
index 0000000..33ef8ac
--- /dev/null
+++ b/ld/testsuite/ld-i386/gnu2-tls-1b.rd
@@ -0,0 +1,4 @@
+#failif
+#...
+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU2_TLS Flags: none Version: [0-9]+
+#...
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 8633a66..622c06e 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -1519,6 +1519,29 @@ run_ld_link_tests [list \
] \
]
+# The musl C library does not support --gnu2-tls-tag.
+if { ![istarget *-*-musl]
+ && [check_compiler_available] } {
+ run_cc_link_tests [list \
+ [list \
+ "Build gnu2-tls-1a.so" \
+ "-shared -Wl,--no-as-needed,--gnu2-tls-tag" \
+ "-fPIC" \
+ { gnu2-tls-1.s } \
+ {{readelf {-W --version-info} gnu2-tls-1a.rd}} \
+ "gnu2-tls-1a.so" \
+ ] \
+ [list \
+ "Build gnu2-tls-1b.so" \
+ "-shared -Wl,--no-as-needed,--no-gnu2-tls-tag" \
+ "-fPIC" \
+ { gnu2-tls-1.s } \
+ {{readelf {-W --version-info} gnu2-tls-1b.rd}} \
+ "gnu2-tls-1b.so" \
+ ] \
+ ]
+}
+
# Linux only tests
run_dump_test "pltgot-1"
run_dump_test "pltgot-2"
diff --git a/ld/testsuite/ld-x86-64/gnu2-tls-1.s b/ld/testsuite/ld-x86-64/gnu2-tls-1.s
new file mode 100644
index 0000000..eca788c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/gnu2-tls-1.s
@@ -0,0 +1,11 @@
+ .section .text.startup,"ax",@progbits
+ .p2align 4
+ .globl main
+ .type main, @function
+main:
+ leaq foo@TLSDESC(%rip), %rax
+ call *foo@TLSCALL(%rax)
+ movl %fs:(%rax), %eax
+ ret
+ .size main, .-main
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/gnu2-tls-1a.rd b/ld/testsuite/ld-x86-64/gnu2-tls-1a.rd
new file mode 100644
index 0000000..3eb926a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/gnu2-tls-1a.rd
@@ -0,0 +1,7 @@
+#...
+Version needs section '.gnu.version_r' contains 1 entry:
+ Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\)
+ +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+
+#...
+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU2_TLS Flags: none Version: [0-9]+
+#pass
diff --git a/ld/testsuite/ld-x86-64/gnu2-tls-1b.rd b/ld/testsuite/ld-x86-64/gnu2-tls-1b.rd
new file mode 100644
index 0000000..33ef8ac
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/gnu2-tls-1b.rd
@@ -0,0 +1,4 @@
+#failif
+#...
+ 0x[a-f0-9]+: Name: GLIBC_ABI_GNU2_TLS Flags: none Version: [0-9]+
+#...
diff --git a/ld/testsuite/ld-x86-64/mark-plt-2.rd b/ld/testsuite/ld-x86-64/mark-plt-2.rd
new file mode 100644
index 0000000..b0ed702
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-2.rd
@@ -0,0 +1,7 @@
+#...
+Version needs section '.gnu.version_r' contains 1 entry:
+ Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\)
+ +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+
+#...
+ 0x[a-f0-9]+: Name: (GLIBC_2.36|GLIBC_ABI_DT_X86_64_PLT) Flags: none Version: [0-9]+
+#pass
diff --git a/ld/testsuite/ld-x86-64/mark-plt-2.s b/ld/testsuite/ld-x86-64/mark-plt-2.s
new file mode 100644
index 0000000..c816567
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-2.s
@@ -0,0 +1,13 @@
+ .text
+ .globl foo
+ .type foo, @function
+foo:
+ subq $8, %rsp
+ leaq xxx@TLSDESC(%rip), %rax
+ .nops 10
+ call *xxx@TLSCALL(%rax)
+ movl %fs:(%rax), %eax
+ addq $8, %rsp
+ call bar
+ ret
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 9d97531..63cf1e4 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -2360,7 +2360,7 @@ run_dump_test "ibt-plt-3b-x32"
run_dump_test "ibt-plt-3c-x32"
run_dump_test "ibt-plt-3d-x32"
-# Skip -z mark-plt tests on MUSL.
+# Skip -z mark-plt and --gnu2-tls-tag tests on MUSL.
if { [istarget "x86_64-*-musl*"]} {
set ASFLAGS "$saved_ASFLAGS"
return
@@ -2386,6 +2386,30 @@ if { [check_compiler_available] } {
{readelf {-W --version-info} mark-plt-1b.rd}} \
"mark-plt-1.so" \
] \
+ [list \
+ "Build mark-plt-2.so" \
+ "-shared -Wl,--no-as-needed,-z,mark-plt,-z,nopack-relative-relocs" \
+ "-fPIC" \
+ { mark-plt-2.s } \
+ {{readelf {-W --version-info} mark-plt-2.rd}} \
+ "mark-plt-2.so" \
+ ] \
+ [list \
+ "Build gnu2-tls-1a.so" \
+ "-shared -Wl,--no-as-needed,--gnu2-tls-tag" \
+ "-fPIC" \
+ { gnu2-tls-1.s } \
+ {{readelf {-W --version-info} gnu2-tls-1a.rd}} \
+ "gnu2-tls-1a.so" \
+ ] \
+ [list \
+ "Build gnu2-tls-1b.so" \
+ "-shared -Wl,--no-as-needed,--no-gnu2-tls-tag" \
+ "-fPIC" \
+ { gnu2-tls-1.s } \
+ {{readelf {-W --version-info} gnu2-tls-1b.rd}} \
+ "gnu2-tls-1b.so" \
+ ] \
]
}