[PATCH] x86-64: Fix misleading R_X86_64_TPOFF32 error message

H.J. Lu hjl.tools@gmail.com
Tue Sep 9 20:38:36 GMT 2025


R_X86_64_TPOFF32 relocation of local-exec TLS model can only be used in
executable, not in a shared library, even if the source code is compiled
with -fPIC.  Change the linker error message from

relocation R_X86_64_TPOFF32 against symbol `foo' can not be used when making a shared object; recompile with -fPIC

to

relocation R_X86_64_TPOFF32 against symbol `foo' can not be used when making a shared object; replace local-exec with initial-exec TLS model

bfd/

	PR ld/33408
	* elf64-x86-64.c (elf_x86_64_need_pic): Suggest "replace
	local-exec with initial-exec TLS model" for R_X86_64_TPOFF32.
	(elf_x86_64_scan_relocs): Drop ABI_64_P check for
	R_X86_64_TPOFF32.

ld/

	PR ld/33408
	* testsuite/ld-x86-64/tls-le-pic-1-x32.d: New file.
	* testsuite/ld-x86-64/tls-le-pic-1.d: Likewise.
	* testsuite/ld-x86-64/tls-le-pic-1.s: Likewise.
	* testsuite/ld-x86-64/tls-le-pic-2-x32.d: Likewise.
	* testsuite/ld-x86-64/tls-le-pic-2.d: Likewise.
	* testsuite/ld-x86-64/tls-le-pic-2.s: Likewise.
	* testsuite/ld-x86-64/tls-le-pic-3-x32.d: Likewise.
	* testsuite/ld-x86-64/tls-le-pic-3.d: Likewise.
	* testsuite/ld-x86-64/tls-le-pic-3.s: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 bfd/elf64-x86-64.c                        |  6 ++++--
 ld/testsuite/ld-x86-64/tls-le-pic-1-x32.d |  4 ++++
 ld/testsuite/ld-x86-64/tls-le-pic-1.d     |  3 +++
 ld/testsuite/ld-x86-64/tls-le-pic-1.s     | 17 +++++++++++++++++
 ld/testsuite/ld-x86-64/tls-le-pic-2-x32.d |  4 ++++
 ld/testsuite/ld-x86-64/tls-le-pic-2.d     |  3 +++
 ld/testsuite/ld-x86-64/tls-le-pic-2.s     | 10 ++++++++++
 ld/testsuite/ld-x86-64/tls-le-pic-3-x32.d |  4 ++++
 ld/testsuite/ld-x86-64/tls-le-pic-3.d     |  3 +++
 ld/testsuite/ld-x86-64/tls-le-pic-3.s     | 16 ++++++++++++++++
 ld/testsuite/ld-x86-64/x86-64.exp         |  6 ++++++
 11 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-1-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-1.d
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-1.s
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-2-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-2.d
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-2.s
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-3-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-3.d
 create mode 100644 ld/testsuite/ld-x86-64/tls-le-pic-3.s

diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 00586455203..ad99cf6754e 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1717,7 +1717,9 @@ elf_x86_64_need_pic (struct bfd_link_info *info,
     {
       object = _("a shared object");
       if (!pic)
-	pic = _("; recompile with -fPIC");
+	pic = (howto->type == R_X86_64_TPOFF32
+	       ? _("; replace local-exec with initial-exec TLS model")
+	       : _("; recompile with -fPIC"));
     }
   else
     {
@@ -2684,7 +2686,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
 	  goto create_got;
 
 	case R_X86_64_TPOFF32:
-	  if (!bfd_link_executable (info) && ABI_64_P (abfd))
+	  if (!bfd_link_executable (info))
 	    {
 	      elf_x86_64_need_pic (info, abfd, sec, h, symtab_hdr, isym,
 				   &x86_64_elf_howto_table[r_type]);
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-1-x32.d b/ld/testsuite/ld-x86-64/tls-le-pic-1-x32.d
new file mode 100644
index 00000000000..b0824c4ae10
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-1-x32.d
@@ -0,0 +1,4 @@
+#source: tls-le-pic-1.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#error: .*: relocation R_X86_64_TPOFF32 against symbol `foo' can not be used when making a shared object; replace local-exec with initial-exec TLS model
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-1.d b/ld/testsuite/ld-x86-64/tls-le-pic-1.d
new file mode 100644
index 00000000000..6db5f029e75
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-1.d
@@ -0,0 +1,3 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#error: .*: relocation R_X86_64_TPOFF32 against symbol `foo' can not be used when making a shared object; replace local-exec with initial-exec TLS model
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-1.s b/ld/testsuite/ld-x86-64/tls-le-pic-1.s
new file mode 100644
index 00000000000..ffc8e63b3b4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-1.s
@@ -0,0 +1,17 @@
+	.text
+	.p2align 4
+	.globl	func
+	.type	func, @function
+func:
+	movq	%fs:0, %rax
+	addq	$foo@tpoff, %rax
+	ret
+	.size	func, .-func
+	.section	.tbss,"awT",@nobits
+	.align 4
+	.globl	foo
+	.type	foo, @object
+	.size	foo, 4
+foo:
+	.zero	4
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-2-x32.d b/ld/testsuite/ld-x86-64/tls-le-pic-2-x32.d
new file mode 100644
index 00000000000..e16395a5568
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-2-x32.d
@@ -0,0 +1,4 @@
+#source: tls-le-pic-2.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#error: .*: relocation R_X86_64_TPOFF32 against undefined symbol `foo' can not be used when making a shared object; replace local-exec with initial-exec TLS model
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-2.d b/ld/testsuite/ld-x86-64/tls-le-pic-2.d
new file mode 100644
index 00000000000..0e718e01ebc
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-2.d
@@ -0,0 +1,3 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#error: .*: relocation R_X86_64_TPOFF32 against undefined symbol `foo' can not be used when making a shared object; replace local-exec with initial-exec TLS model
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-2.s b/ld/testsuite/ld-x86-64/tls-le-pic-2.s
new file mode 100644
index 00000000000..ad930db1546
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-2.s
@@ -0,0 +1,10 @@
+	.text
+	.p2align 4
+	.globl	func
+	.type	func, @function
+func:
+	movq	%fs:0, %rax
+	addq	$foo@tpoff, %rax
+	ret
+	.size	func, .-func
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-3-x32.d b/ld/testsuite/ld-x86-64/tls-le-pic-3-x32.d
new file mode 100644
index 00000000000..f6731daa991
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-3-x32.d
@@ -0,0 +1,4 @@
+#source: tls-le-pic-3.s
+#as: --x32
+#ld: -shared -melf32_x86_64
+#error: .*: relocation R_X86_64_TPOFF32 against `foo' can not be used when making a shared object; replace local-exec with initial-exec TLS model
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-3.d b/ld/testsuite/ld-x86-64/tls-le-pic-3.d
new file mode 100644
index 00000000000..987e370ad17
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-3.d
@@ -0,0 +1,3 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#error: .*: relocation R_X86_64_TPOFF32 against `foo' can not be used when making a shared object; replace local-exec with initial-exec TLS model
diff --git a/ld/testsuite/ld-x86-64/tls-le-pic-3.s b/ld/testsuite/ld-x86-64/tls-le-pic-3.s
new file mode 100644
index 00000000000..6e213fd5b54
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/tls-le-pic-3.s
@@ -0,0 +1,16 @@
+	.text
+	.p2align 4
+	.globl	func
+	.type	func, @function
+func:
+	movq	%fs:0, %rax
+	addq	$foo@tpoff, %rax
+	ret
+	.size	func, .-func
+	.section	.tbss,"awT",@nobits
+	.align 4
+	.type	foo, @object
+	.size	foo, 4
+foo:
+	.zero	4
+	.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 23e0a98d1cd..f04ae923ebc 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -578,6 +578,12 @@ run_dump_test "pr33292"
 run_dump_test "pr33292-x32"
 run_dump_test "pr28387"
 run_dump_test "pr28387-x32"
+run_dump_test "tls-le-pic-1"
+run_dump_test "tls-le-pic-1-x32"
+run_dump_test "tls-le-pic-2"
+run_dump_test "tls-le-pic-2-x32"
+run_dump_test "tls-le-pic-3"
+run_dump_test "tls-le-pic-3-x32"
 
 if { ![skip_sframe_tests] } {
     run_dump_test "sframe-simple-1"
-- 
2.51.0



More information about the Binutils mailing list