The behaviour of weak undef thread-local variables is not well defined.
TLS relocations against weak undef symbols are not handled properly by
the linker, and in some cases cause the linker to crash (notably when
linking glibc for purecap Morello). This patch simply ignores these and
emits a warning to that effect. This is a compromise to enable progress
for Morello.
bfd/ChangeLog:
2022-01-17 Alex Coplan <alex.coplan@arm.com>
* elfnn-aarch64.c (elfNN_aarch64_relocate_section): Skip over TLS
relocations against weak undef symbols.
(elfNN_aarch64_check_relocs): Likewise, but also warn.
ld/ChangeLog:
2022-01-17 Alex Coplan <alex.coplan@arm.com>
* testsuite/ld-aarch64/aarch64-elf.exp: Add morello-weak-tls test.
* testsuite/ld-aarch64/morello-weak-tls.d: New test.
* testsuite/ld-aarch64/morello-weak-tls.s: New test.
* testsuite/ld-aarch64/weak-tls.d: Update test wrt new behaviour.
+2022-01-17 Alex Coplan <alex.coplan@arm.com>
+
+ * elfnn-aarch64.c (elfNN_aarch64_relocate_section): Skip over TLS
+ relocations against weak undef symbols.
+ (elfNN_aarch64_check_relocs): Likewise, but also warn.
+
2021-05-25 Luis Machado <luis.machado@arm.com>
* elf-bfd.h (elfcore_write_aarch_morello): New prototype.
input_section, (uint64_t) rel->r_offset, howto->name, name);
}
+ if (r_symndx
+ && h
+ && IS_AARCH64_TLS_RELOC (bfd_r_type)
+ && h->root.type == bfd_link_hash_undefweak)
+ /* We have already warned about these in aarch64_check_relocs,
+ so just skip over them. */
+ continue;
+
/* We relax only if we can see that there can be a valid transition
from a reloc type to another.
We call elfNN_aarch64_final_link_relocate unless we're completely
for (rel = relocs; rel < rel_end; rel++)
{
struct elf_link_hash_entry *h;
- unsigned int r_symndx;
+ unsigned int r_symndx, r_type;
bfd_reloc_code_real_type bfd_r_type;
Elf_Internal_Sym *isym;
r_symndx = ELFNN_R_SYM (rel->r_info);
+ r_type = ELFNN_R_TYPE (rel->r_info);
+ bfd_r_type = elfNN_aarch64_bfd_reloc_from_type (abfd, r_type);
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
h = (struct elf_link_hash_entry *) h->root.u.i.link;
}
+ /* Ignore TLS relocations against weak undef symbols and warn about them.
+ The behaviour of weak TLS variables is not well defined. Since making
+ these well behaved is not a priority for Morello, we simply ignore
+ TLS relocations against such symbols here to avoid the linker crashing
+ on these and to enable making progress in other areas. */
+ if (r_symndx
+ && h
+ && IS_AARCH64_TLS_RELOC (bfd_r_type)
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
+ _bfd_error_handler (_("%pB(%pA+%#" PRIx64 "): ignoring TLS relocation "
+ "%s against undef weak symbol %s"),
+ abfd, sec,
+ (uint64_t) rel->r_offset,
+ elfNN_aarch64_howto_table[howto_index].name,
+ h->root.root.string);
+ continue;
+ }
+
/* Could be done earlier, if h were already available. */
bfd_r_type = aarch64_tls_transition (abfd, info, rel, h, r_symndx);
+2022-01-17 Alex Coplan <alex.coplan@arm.com>
+
+ * testsuite/ld-aarch64/aarch64-elf.exp: Add morello-weak-tls test.
+ * testsuite/ld-aarch64/morello-weak-tls.d: New test.
+ * testsuite/ld-aarch64/morello-weak-tls.s: New test.
+ * testsuite/ld-aarch64/weak-tls.d: Update test wrt new behaviour.
+
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* testsuite/ld-aarch64/morello-tlsdesc.s: New file.
run_dump_test "bti-warn"
run_dump_test "weak-tls"
+run_dump_test "morello-weak-tls"
run_dump_test "undef-tls"
--- /dev/null
+#source: morello-weak-tls.s
+#ld:
+#warning:.*: ignoring TLS relocation R_MORELLO_TLSDESC_ADR_PAGE20 against undef weak symbol x
+#warning:.*: ignoring TLS relocation R_MORELLO_TLSDESC_LD128_LO12 against undef weak symbol x
+#warning:.*: ignoring TLS relocation R_AARCH64_TLSDESC_ADD_LO12 against undef weak symbol x
+#warning:.*: ignoring TLS relocation R_MORELLO_TLSDESC_CALL against undef weak symbol x
--- /dev/null
+ .arch morello+crc+c64
+ .file "t.c"
+ .text
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+.LFB0:
+ .cfi_startproc
+ stp c29, c30, [csp, -32]!
+ .cfi_def_cfa_offset 32
+ .cfi_offset 29, -32
+ .cfi_offset 30, -16
+ mov c29, csp
+ mrs c2, ctpidr_el0
+ nop
+ adrp c0, :tlsdesc:x
+ ldr c1, [c0, #:tlsdesc_lo12:x]
+ add c0, c0, :tlsdesc_lo12:x
+ .tlsdesccall x
+ blr c1
+ scbnds c0, c0, x1
+ mov w1, 1
+ str w1, [c0]
+ nop
+ ldp c29, c30, [csp], 32
+ .cfi_restore 30
+ .cfi_restore 29
+ .cfi_def_cfa_offset 0
+ ret
+ .cfi_endproc
+.LFE0:
+ .size _start, .-_start
+ .weak x
+ .ident "GCC: (GNU) 11.0.0 20200826 (experimental)"
+ .section .note.GNU-stack,"",@progbits
#source: weak-tls.s
#ld: -e0 --emit-relocs
-#objdump: -dr
-#...
-#error:.*: warning: Weak TLS is implementation defined and may not work as expected.*
-#error:.*: warning: Weak TLS is implementation defined and may not work as expected.*
-#error:.*: in function `get':.*
-#error:.*: relocation truncated to fit: R_AARCH64_TLSLD_ADD_DTPREL_LO12 against undefined symbol `dtl'.*
+#warning:.*: ignoring TLS relocation .* against undef weak symbol tls
+#warning:.*: ignoring TLS relocation .* against undef weak symbol tls
+#warning:.*: ignoring TLS relocation .* against undef weak symbol dtl
+#warning:.*: ignoring TLS relocation .* against undef weak symbol dtl