]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld: Ignore TLS relocs against weak undef symbols
authorAlex Coplan <alex.coplan@arm.com>
Mon, 17 Jan 2022 16:52:07 +0000 (16:52 +0000)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 22:59:24 +0000 (15:59 -0700)
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.

bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/morello-weak-tls.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-weak-tls.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/weak-tls.d

index e4a674e4fc45287a99d943cc0eda3dba4289ccdb..9d9224b285b072438a1d7dad4c417d18116f9569 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * elfnn-aarch64.c (IS_AARCH64_TLSDESC_RELOC): Add Morello
index 14b149a400780d7fd8ca6230c577eb52c4834deb..902311e10dd01b11b763aea53b1f1444c976a748 100644 (file)
@@ -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);
 
index 72693ed03f02cf9c18aafb33fe8289788f38c1fa..d471efb85c1e50a754cf05dc638f34e5c7ec7679 100644 (file)
@@ -1,3 +1,10 @@
+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.
index 21fdfd26a0ec1f948f88124a82f65a81e8738848..6c76f1d78780718707a3295f28c350290d542848 100644 (file)
@@ -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 (file)
index 0000000..20f5cb1
--- /dev/null
@@ -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 (file)
index 0000000..a40d84b
--- /dev/null
@@ -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
index a8269406892fc7e9d94a528a799398171ff53a85..60d7d9122c02045034a02ba147bd82d1bf97d9e2 100644 (file)
@@ -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