From 62cd4e62b71db4598f92656d4b98134961aa6564 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] alpha: Handle local weak undefined symbol value separately
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.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
bfd/elf64-alpha.c | 46 ++++++++++++++++------
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 +++++++++++
12 files changed, 180 insertions(+), 12 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
@@ -4104,6 +4104,17 @@ elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED,
return ret_val;
}
+/* Return true if H is local weak undefined. */
+
+static bool
+elf64_alpha_local_undefweak_p (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info)
+{
+ return (h != NULL
+ && h->root.type == bfd_link_hash_undefweak
+ && _bfd_elf_symbol_refs_local_p (h, info, false));
+}
+
/* Relocate an Alpha ELF section. */
static int
@@ -4644,8 +4655,13 @@ 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;
+ else if (elf64_alpha_local_undefweak_p (&h->root, info))
+ value = 0;
+ else
+ {
+ 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);
goto default_reloc;
@@ -4665,18 +4681,24 @@ 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))
- value -= tp_base;
+ if (elf64_alpha_local_undefweak_p (&h->root, info))
+ value = 0;
else
{
- elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
- gotent->got_offset, 0,
- R_ALPHA_TPREL64,
- value - dtp_base);
- value = 0;
+ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+ if (r_type == R_ALPHA_GOTDTPREL)
+ value -= dtp_base;
+ else if (bfd_link_executable (info))
+ value -= tp_base;
+ else
+ {
+ elf64_alpha_emit_dynrel (output_bfd, info,
+ sgot, srelgot,
+ gotent->got_offset, 0,
+ R_ALPHA_TPREL64,
+ value - dtp_base);
+ value = 0;
+ }
}
}
bfd_put_64 (output_bfd, value,
@@ -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]
+}
new file mode 100644
@@ -0,0 +1,2 @@
+#ld:
+#error: .*: undefined reference to `x'
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -0,0 +1,2 @@
+#ld: -shared
+#error: .*: undefined reference to `x'
new file mode 100644
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
--
2.54.0