From 1eb855e322d688ae57687094f5c47d9ab5122fe5 Mon Sep 17 00:00:00 2001 From: Alex Coplan Date: Mon, 17 Jan 2022 16:52:07 +0000 Subject: [PATCH] ld: Ignore TLS relocs against weak undef symbols 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 * 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 * 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. --- bfd/ChangeLog | 6 ++++ bfd/elfnn-aarch64.c | 32 ++++++++++++++++++- ld/ChangeLog | 7 +++++ ld/testsuite/ld-aarch64/aarch64-elf.exp | 1 + ld/testsuite/ld-aarch64/morello-weak-tls.d | 6 ++++ ld/testsuite/ld-aarch64/morello-weak-tls.s | 36 ++++++++++++++++++++++ ld/testsuite/ld-aarch64/weak-tls.d | 10 +++--- 7 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 ld/testsuite/ld-aarch64/morello-weak-tls.d create mode 100644 ld/testsuite/ld-aarch64/morello-weak-tls.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e4a674e4fc4..9d9224b285b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2022-01-17 Alex Coplan + + * elfnn-aarch64.c (elfNN_aarch64_relocate_section): Skip over TLS + relocations against weak undef symbols. + (elfNN_aarch64_check_relocs): Likewise, but also warn. + 2020-10-20 Siddhesh Poyarekar * elfnn-aarch64.c (IS_AARCH64_TLSDESC_RELOC): Add Morello diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 14b149a4007..902311e10dd 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -8142,6 +8142,14 @@ elfNN_aarch64_relocate_section (bfd *output_bfd, 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 @@ -8950,11 +8958,13 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, 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)) { @@ -8997,6 +9007,26 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, 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); diff --git a/ld/ChangeLog b/ld/ChangeLog index 72693ed03f0..d471efb85c1 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2022-01-17 Alex Coplan + + * 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 * testsuite/ld-aarch64/morello-tlsdesc.s: New file. diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 21fdfd26a0e..6c76f1d7878 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -457,4 +457,5 @@ run_dump_test "bti-pac-plt-2" run_dump_test "bti-warn" run_dump_test "weak-tls" +run_dump_test "morello-weak-tls" run_dump_test "undef-tls" diff --git a/ld/testsuite/ld-aarch64/morello-weak-tls.d b/ld/testsuite/ld-aarch64/morello-weak-tls.d new file mode 100644 index 00000000000..20f5cb1b889 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-weak-tls.d @@ -0,0 +1,6 @@ +#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 diff --git a/ld/testsuite/ld-aarch64/morello-weak-tls.s b/ld/testsuite/ld-aarch64/morello-weak-tls.s new file mode 100644 index 00000000000..a40d84b8546 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-weak-tls.s @@ -0,0 +1,36 @@ + .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 diff --git a/ld/testsuite/ld-aarch64/weak-tls.d b/ld/testsuite/ld-aarch64/weak-tls.d index a8269406892..60d7d9122c0 100644 --- a/ld/testsuite/ld-aarch64/weak-tls.d +++ b/ld/testsuite/ld-aarch64/weak-tls.d @@ -1,8 +1,6 @@ #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 -- 2.47.2