]> 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)
committerAlex Coplan <alex.coplan@arm.com>
Mon, 17 Jan 2022 16:53:54 +0000 (16:53 +0000)
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 d4586cbd1ed91a8917930dba84e640a19aeae534..c5121d4366d576a52a013d38d984631e92be6c9b 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.
+
 2021-05-25  Luis Machado  <luis.machado@arm.com>
 
        * elf-bfd.h (elfcore_write_aarch_morello): New prototype.
index 55bf288a754383fa721e369df6891c3cf4e067ec..08d1141d4ddd986bff194a2dbc03c585dc282f8f 100644 (file)
@@ -8139,6 +8139,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
@@ -8947,11 +8955,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))
        {
@@ -8994,6 +9004,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 fce82ea83abc29623fe6c674a7ed82778c7e1899..54513a6926372d5832519ca18980f6548035e22b 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 228cfe224c57efc1cac6c694d304d8186e8749d6..893c869f1a313e6192d4585e46fc9c8b93d13b88 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