[v3] alpha: Don't assert elf_hash_table (info)->tls_sec != NULL

Message ID CAMe9rOrrdf611L9cYF2Zg+CdH1t8_N-nnCUp-YoFs7icsRZPPA@mail.gmail.com
State New
Headers
Series [v3] alpha: Don't assert elf_hash_table (info)->tls_sec != NULL |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 fail Test failed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

H.J. Lu May 23, 2026, 11:24 p.m. UTC
  On Sat, May 23, 2026 at 11:45 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Sat, May 23, 2026 at 7:52 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > Since local weak undefined symbol value is always 0, handle TLS
> > relocations against local weak undefined symbols separately.
> >
> > bfd/
> >
> > PR ld/34165
> > * elf64-alpha.c (elf64_alpha_local_undefweak_p): New function.
> > (elf64_alpha_relocate_section): Handle TLS relocations against
> > local weak undefined symbol value separately.
> >
> > ld/testsuite/
> >
> > PR ld/34165
> > * ld-alpha/alpha.exp: Run $srcdir/$subdir/*.d.
> > * ld-alpha/tlsbin-undef.d: New file.
> > * ld-alpha/tlsbin-undef.s: Likewise.
> > * ld-alpha/tlsbin-weak-undef1.d: Likewise.
> > * ld-alpha/tlsbin-weak-undef1.s: Likewise.
> > * ld-alpha/tlsbin-weak-undef2.d: Likewise.
> > * ld-alpha/tlsbin-weak-undef2.s: Likewise.
> > * ld-alpha/tlspic-undef.d: Likewise.
> > * ld-alpha/tlspic-undef.s: Likewise.
> > * ld-alpha/tlspic-weak-undef1.d: Likewise.
> > * ld-alpha/tlspic-weak-undef1.s: Likewise.
> >
>
> Move elf64_alpha_local_undefweak_p to elf-bfd.h (elf_link_local_undefweak_p)
>
>
> --
> H.J.
> ---
> Since local weak undefined symbol value is always 0, handle TLS
> relocations against local weak undefined symbols separately.
>
> bfd/
>
> PR ld/34165
> * elf-bfd.h (elf_link_local_undefweak_p): New function.
> * elf64-alpha.c (elf64_alpha_relocate_section): Handle TLS
> relocations against local weak undefined symbol value separately.
>
> ld/testsuite/
>
> PR ld/34165
> * ld-alpha/alpha.exp: Run $srcdir/$subdir/*.d.
> * ld-alpha/tlsbin-undef.d: New file.
> * ld-alpha/tlsbin-undef.s: Likewise.
> * ld-alpha/tlsbin-weak-undef1.d: Likewise.
> * ld-alpha/tlsbin-weak-undef1.s: Likewise.
> * ld-alpha/tlsbin-weak-undef2.d: Likewise.
> * ld-alpha/tlsbin-weak-undef2.s: Likewise.
> * ld-alpha/tlspic-undef.d: Likewise.
> * ld-alpha/tlspic-undef.s: Likewise.
> * ld-alpha/tlspic-weak-undef1.d: Likewise.
> * ld-alpha/tlspic-weak-undef1.s: Likewise.

Don't assert elf_hash_table (info)->tls_sec != NULL since the
undefined TLS symbol address isn't usable.
  

Comments

Alan Modra May 24, 2026, 3:55 a.m. UTC | #1
On Sun, May 24, 2026 at 07:24:46AM +0800, H.J. Lu wrote:
> When processing TLS relocations, elf_hash_table (info)->tls_sec can be
> NULL if all TLS symbols are weak, hidden and undefined.  Don't assert
> elf_hash_table (info)->tls_sec != NULL.  Since the undefined TLS symbol
> address doesn't map to any TLS storage, it isn't usable.  Also set
> dtp_base and tp_base to 0 if elf_hash_table (info)->tls_sec == NULL.
> 
> bfd/
> 
> 	PR ld/34165
> 	* elf64-alpha.c (elf64_alpha_relax_got_load): Set dtp_base and
> 	tp_base to 0 if elf_hash_table (info)->tls_sec == NULL.
> 	(elf64_alpha_relocate_section): Don't assert
> 	elf_hash_table (info)->tls_sec != NULL.
> 
> ld/
> 
> 	PR ld/34165
> 	* testsuite/ld-alpha/alpha.exp: Run $srcdir/$subdir/*.d.
> 	* testsuite/ld-alpha/tlsbin-undef.d: New file.
> 	* testsuite/ld-alpha/tlsbin-undef.s: Likewise.
> 	* testsuite/ld-alpha/tlsbin-weak-undef1.d: Likewise.
> 	* testsuite/ld-alpha/tlsbin-weak-undef1.s: Likewise.
> 	* testsuite/ld-alpha/tlsbin-weak-undef2.d: Likewise.
> 	* testsuite/ld-alpha/tlsbin-weak-undef2.s: Likewise.
> 	* testsuite/ld-alpha/tlspic-undef.d: Likewise.
> 	* testsuite/ld-alpha/tlspic-undef.s: Likewise.
> 	* testsuite/ld-alpha/tlspic-weak-undef1.d: Likewise.
> 	* testsuite/ld-alpha/tlspic-weak-undef1.s: Likewise.
> 	* testsuite/ld-elf/pr34165.c: Likewise.
> 	* testsuite/ld-elf/tls.exp: Run PR ld/34165 test.

Thanks, this is good.  aarch64-linux and ia64-linux fail the pr34165
test, exposing similary problems in those backends.
  

Patch

From 474f78f8a553fc86008117b4fc685126fa2642c6 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sat, 23 May 2026 05:12:10 +0800
Subject: [PATCH v3] alpha: Don't assert elf_hash_table (info)->tls_sec != NULL

When processing TLS relocations, elf_hash_table (info)->tls_sec can be
NULL if all TLS symbols are weak, hidden and undefined.  Don't assert
elf_hash_table (info)->tls_sec != NULL.  Since the undefined TLS symbol
address doesn't map to any TLS storage, it isn't usable.  Also set
dtp_base and tp_base to 0 if elf_hash_table (info)->tls_sec == NULL.

bfd/

	PR ld/34165
	* elf64-alpha.c (elf64_alpha_relax_got_load): Set dtp_base and
	tp_base to 0 if elf_hash_table (info)->tls_sec == NULL.
	(elf64_alpha_relocate_section): Don't assert
	elf_hash_table (info)->tls_sec != NULL.

ld/

	PR ld/34165
	* testsuite/ld-alpha/alpha.exp: Run $srcdir/$subdir/*.d.
	* testsuite/ld-alpha/tlsbin-undef.d: New file.
	* testsuite/ld-alpha/tlsbin-undef.s: Likewise.
	* testsuite/ld-alpha/tlsbin-weak-undef1.d: Likewise.
	* testsuite/ld-alpha/tlsbin-weak-undef1.s: Likewise.
	* testsuite/ld-alpha/tlsbin-weak-undef2.d: Likewise.
	* testsuite/ld-alpha/tlsbin-weak-undef2.s: Likewise.
	* testsuite/ld-alpha/tlspic-undef.d: Likewise.
	* testsuite/ld-alpha/tlspic-undef.s: Likewise.
	* testsuite/ld-alpha/tlspic-weak-undef1.d: Likewise.
	* testsuite/ld-alpha/tlspic-weak-undef1.s: Likewise.
	* testsuite/ld-elf/pr34165.c: Likewise.
	* testsuite/ld-elf/tls.exp: Run PR ld/34165 test.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 bfd/elf64-alpha.c                          | 12 +++++++-----
 ld/testsuite/ld-alpha/alpha.exp            |  7 +++++++
 ld/testsuite/ld-alpha/tlsbin-undef.d       |  2 ++
 ld/testsuite/ld-alpha/tlsbin-undef.s       | 16 ++++++++++++++++
 ld/testsuite/ld-alpha/tlsbin-weak-undef1.d | 14 ++++++++++++++
 ld/testsuite/ld-alpha/tlsbin-weak-undef1.s | 22 ++++++++++++++++++++++
 ld/testsuite/ld-alpha/tlsbin-weak-undef2.d | 14 ++++++++++++++
 ld/testsuite/ld-alpha/tlsbin-weak-undef2.s | 17 +++++++++++++++++
 ld/testsuite/ld-alpha/tlspic-undef.d       |  2 ++
 ld/testsuite/ld-alpha/tlspic-undef.s       | 16 ++++++++++++++++
 ld/testsuite/ld-alpha/tlspic-weak-undef1.d | 14 ++++++++++++++
 ld/testsuite/ld-alpha/tlspic-weak-undef1.s | 22 ++++++++++++++++++++++
 ld/testsuite/ld-elf/pr34165.c              | 14 ++++++++++++++
 ld/testsuite/ld-elf/tls.exp                | 11 +++++++++++
 14 files changed, 178 insertions(+), 5 deletions(-)
 create mode 100644 ld/testsuite/ld-alpha/tlsbin-undef.d
 create mode 100644 ld/testsuite/ld-alpha/tlsbin-undef.s
 create mode 100644 ld/testsuite/ld-alpha/tlsbin-weak-undef1.d
 create mode 100644 ld/testsuite/ld-alpha/tlsbin-weak-undef1.s
 create mode 100644 ld/testsuite/ld-alpha/tlsbin-weak-undef2.d
 create mode 100644 ld/testsuite/ld-alpha/tlsbin-weak-undef2.s
 create mode 100644 ld/testsuite/ld-alpha/tlspic-undef.d
 create mode 100644 ld/testsuite/ld-alpha/tlspic-undef.s
 create mode 100644 ld/testsuite/ld-alpha/tlspic-weak-undef1.d
 create mode 100644 ld/testsuite/ld-alpha/tlspic-weak-undef1.s
 create mode 100644 ld/testsuite/ld-elf/pr34165.c

diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index 91cc7bcaec8..d4dc86d0ef5 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -3018,9 +3018,13 @@  elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
     {
       bfd_vma dtp_base, tp_base;
 
-      BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
-      dtp_base = alpha_get_dtprel_base (info->link_info);
-      tp_base = alpha_get_tprel_base (info->link_info);
+      if (elf_hash_table (info->link_info)->tls_sec != NULL)
+	{
+	  dtp_base = alpha_get_dtprel_base (info->link_info);
+	  tp_base = alpha_get_tprel_base (info->link_info);
+	}
+      else
+	dtp_base = tp_base = 0;
       disp = symval - (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
 
       insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
@@ -4644,7 +4648,6 @@  elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 		 input_bfd, h->root.root.root.string);
 	      ret_val = false;
 	    }
-	  BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
 	  value -= tp_base;
 	  if (r_type == R_ALPHA_TPRELHI)
 	    value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
@@ -4665,7 +4668,6 @@  elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 		value = 0;
 	      else
 		{
-		  BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
 		  if (r_type == R_ALPHA_GOTDTPREL)
 		    value -= dtp_base;
 		  else if (bfd_link_executable (info))
diff --git a/ld/testsuite/ld-alpha/alpha.exp b/ld/testsuite/ld-alpha/alpha.exp
index 540580f3e19..f6b16918927 100644
--- a/ld/testsuite/ld-alpha/alpha.exp
+++ b/ld/testsuite/ld-alpha/alpha.exp
@@ -69,3 +69,10 @@  set alphatests {
 #    {{objdump -sj.debug_foobar tlsg.sd}} "tlsg"}
 
 run_ld_link_tests $alphatests
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+foreach t $test_list {
+    # We need to strip the ".d", but can leave the dirname.
+    verbose [file rootname $t]
+    run_dump_test [file rootname $t]
+}
diff --git a/ld/testsuite/ld-alpha/tlsbin-undef.d b/ld/testsuite/ld-alpha/tlsbin-undef.d
new file mode 100644
index 00000000000..203d0c424e8
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlsbin-undef.d
@@ -0,0 +1,2 @@ 
+#ld:
+#error: .*: undefined reference to `x'
diff --git a/ld/testsuite/ld-alpha/tlsbin-undef.s b/ld/testsuite/ld-alpha/tlsbin-undef.s
new file mode 100644
index 00000000000..b95f48afd69
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlsbin-undef.s
@@ -0,0 +1,16 @@ 
+	.set noreorder
+	.set volatile
+	.set noat
+	.set nomacro
+	.arch ev4
+	.text
+	.align 4
+	.globl _start
+	.ent _start
+_start:
+	ldq $1,x($29)		!gottprel
+	addq $0,$1,$0
+	ret
+	.end _start
+	.hidden x
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-alpha/tlsbin-weak-undef1.d b/ld/testsuite/ld-alpha/tlsbin-weak-undef1.d
new file mode 100644
index 00000000000..a234b5e4ad1
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlsbin-weak-undef1.d
@@ -0,0 +1,14 @@ 
+#ld: -z norelro -z nomemory-seal
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+ +[a-f0-9]+:	00 80 3d a4 	ldq	t0,-32768\(gp\)
+ +[a-f0-9]+:	00 04 01 40 	addq	v0,t0,v0
+ +[a-f0-9]+:	01 80 fa 6b 	ret
+ +[a-f0-9]+:	00 00 fe 2f 	unop	
+#pass
diff --git a/ld/testsuite/ld-alpha/tlsbin-weak-undef1.s b/ld/testsuite/ld-alpha/tlsbin-weak-undef1.s
new file mode 100644
index 00000000000..c0a5c0a5808
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlsbin-weak-undef1.s
@@ -0,0 +1,22 @@ 
+	.set noreorder
+	.set volatile
+	.set noat
+	.set nomacro
+	.arch ev4
+	.text
+	.align 4
+	.globl _start
+	.ent _start
+_start:
+	ldq $1,x($29)		!gottprel
+	addq $0,$1,$0
+	ret
+	.end _start
+	.section .tbss,"awT",@nobits
+	.type	y, @object
+	.size	y, 4
+y:
+	.zero	4
+	.weak x
+	.hidden x
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-alpha/tlsbin-weak-undef2.d b/ld/testsuite/ld-alpha/tlsbin-weak-undef2.d
new file mode 100644
index 00000000000..47fb7336674
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlsbin-weak-undef2.d
@@ -0,0 +1,14 @@ 
+#ld: -z norelro -z nomemory-seal
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+ +[a-f0-9]+:	00 00 00 24 	ldah	v0,0\(v0\)
+ +[a-f0-9]+:	00 00 20 a0 	ldl	t0,0\(v0\)
+ +[a-f0-9]+:	01 80 fa 6b 	ret
+ +[a-f0-9]+:	00 00 fe 2f 	unop	
+#pass
diff --git a/ld/testsuite/ld-alpha/tlsbin-weak-undef2.s b/ld/testsuite/ld-alpha/tlsbin-weak-undef2.s
new file mode 100644
index 00000000000..bf05205bb59
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlsbin-weak-undef2.s
@@ -0,0 +1,17 @@ 
+	.set noreorder
+	.set volatile
+	.set noat
+	.set nomacro
+	.arch ev4
+	.text
+	.align 4
+	.globl _start
+	.ent _start
+_start:
+	ldah $0,x($0)		!tprelhi
+	ldl $1,x($0)		!tprello
+	ret
+	.end _start
+	.weak x
+	.hidden x
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-alpha/tlspic-undef.d b/ld/testsuite/ld-alpha/tlspic-undef.d
new file mode 100644
index 00000000000..e6907997ada
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlspic-undef.d
@@ -0,0 +1,2 @@ 
+#ld: -shared
+#error: .*: undefined reference to `x'
diff --git a/ld/testsuite/ld-alpha/tlspic-undef.s b/ld/testsuite/ld-alpha/tlspic-undef.s
new file mode 100644
index 00000000000..c4b091fc834
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlspic-undef.s
@@ -0,0 +1,16 @@ 
+	.set noreorder
+	.set volatile
+	.set noat
+	.set nomacro
+	.arch ev4
+	.text
+	.align 4
+	.globl _start
+	.ent _start
+_start:
+	ldq $1,x($29)		!gotdtprel
+	addq $0,$1,$1
+	ret
+	.end _start
+	.hidden x
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-alpha/tlspic-weak-undef1.d b/ld/testsuite/ld-alpha/tlspic-weak-undef1.d
new file mode 100644
index 00000000000..626da576d66
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlspic-weak-undef1.d
@@ -0,0 +1,14 @@ 
+#ld: -shared -z norelro -z nomemory-seal
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+ +[a-f0-9]+:	00 80 3d a4 	ldq	t0,-32768\(gp\)
+ +[a-f0-9]+:	01 04 01 40 	addq	v0,t0,t0
+ +[a-f0-9]+:	01 80 fa 6b 	ret
+ +[a-f0-9]+:	00 00 fe 2f 	unop	
+#pass
diff --git a/ld/testsuite/ld-alpha/tlspic-weak-undef1.s b/ld/testsuite/ld-alpha/tlspic-weak-undef1.s
new file mode 100644
index 00000000000..bcbe5a173b3
--- /dev/null
+++ b/ld/testsuite/ld-alpha/tlspic-weak-undef1.s
@@ -0,0 +1,22 @@ 
+	.set noreorder
+	.set volatile
+	.set noat
+	.set nomacro
+	.arch ev4
+	.text
+	.align 4
+	.globl _start
+	.ent _start
+_start:
+	ldq $1,x($29)		!gotdtprel
+	addq $0,$1,$1
+	ret
+	.end _start
+	.section .tbss,"awT",@nobits
+	.type	y, @object
+	.size	y, 4
+y:
+	.zero	4
+	.weak x
+	.hidden x
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-elf/pr34165.c b/ld/testsuite/ld-elf/pr34165.c
new file mode 100644
index 00000000000..3793dda4403
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr34165.c
@@ -0,0 +1,14 @@ 
+extern __thread int x
+__attribute__((visibility("hidden")))
+__attribute__((weak));
+extern __thread int x_used
+__attribute__((visibility("hidden")))
+__attribute__((weak));
+
+int
+main (void)
+{
+  if (!x_used)
+    x++;
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/tls.exp b/ld/testsuite/ld-elf/tls.exp
index 515824b7f12..d149c3a41df 100644
--- a/ld/testsuite/ld-elf/tls.exp
+++ b/ld/testsuite/ld-elf/tls.exp
@@ -62,6 +62,17 @@  run_ld_link_tests [list \
     ] \
 ]
 
+run_cc_link_tests [list \
+    [list \
+	"pr34165" \
+	"" \
+	"-O2 $NOSANITIZE_CFLAGS" \
+	{ pr34165.c } \
+	{} \
+	"pr34165" \
+    ] \
+]
+
 if [file exists tmpdir/pr22263-1] {
     run_ld_link_tests [list \
 	[list \
-- 
2.54.0