]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Use global GOT type to determine GOT action
authorMatthew Malcomson <matthew.malcomson@arm.com>
Fri, 1 Jul 2022 10:48:56 +0000 (11:48 +0100)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Fri, 1 Jul 2022 10:48:56 +0000 (11:48 +0100)
morello-binutils: Use global GOT type to determine GOT action

In final_link_relocate we currently use whether the relocation we're
looking at is a Morello relocation to decide whether we should treat the
GOT entry as a Morello GOT entry or not.

This is problematic since we can have an AArch64 relocation against a
capability GOT entry (even if it isn't a very useful thing to have).

The current patch decides whether we need to emit a MORELLO RELATIVE
relocation in the GOT based on whether the GOT as a whole contains
capabilities rather than based on whether the first relocation against
this GOT is a Morello relocation.

Until now we did not see any problem from this.  Here we add a testcase
that triggers the problem.

bfd/elfnn-aarch64.c
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/emit-relocs-morello-10.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-morello-10.s [new file with mode: 0644]

index 68c88bce0b475a6af2097c3993f9a5753a774fdb..244b837f4458051fc0bce7e878a63a0b5278c26b 100644 (file)
@@ -7220,9 +7220,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
       base_got = globals->root.sgot;
 
       bfd_boolean is_dynamic = elf_hash_table (info)->dynamic_sections_created;
-      bfd_boolean c64_reloc =
-       (bfd_r_type == BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
-        || bfd_r_type == BFD_RELOC_MORELLO_ADR_GOT_PAGE);
 
       if (signed_addend != 0)
        {
@@ -7267,9 +7264,9 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
              BFD_ASSERT (!WILL_CALL_FINISH_DYNAMIC_SYMBOL
                            (is_dynamic, bfd_link_pic (info), h));
              relative_reloc = TRUE;
-             c64_needs_frag_fixup = c64_reloc ? TRUE : FALSE;
+             c64_needs_frag_fixup = globals->c64_rel ? TRUE : FALSE;
            }
-         else if (!c64_reloc || !c64_needs_relocation (info, h))
+         else if (!globals->c64_rel || !c64_needs_relocation (info, h))
            {
              /* Symbol references via GOT in C64 should always have
                 relocations of some kind unless they are undefined weak
@@ -7308,7 +7305,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
              c64_needs_frag_fixup = TRUE;
            }
 
-         if (c64_reloc
+         if (globals->c64_rel
              && c64_symbol_adjust (h, value, sym_sec, info, &frag_value))
            signed_addend = (value | h->target_internal) - frag_value;
          else
@@ -7354,7 +7351,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
          {
            bfd_vma frag_value;
 
-           if (c64_reloc
+           if (globals->c64_rel
                && c64_symbol_adjust (h, value, sym_sec, info, &frag_value))
              signed_addend = (value | sym->st_target_internal) - frag_value;
            else
@@ -7375,7 +7372,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
               dynamic relocations).  */
            if (bfd_link_pic (info)
                || (!bfd_link_pic (info) && bfd_link_executable (info)
-                   && c64_reloc))
+                   && globals->c64_rel))
              {
                /* We have not handled the case for weak undefined symbols in
                   this clause.  That is because we believe there can not be
@@ -7390,7 +7387,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
                   would not see it in this clause.  */
                BFD_ASSERT (!weak_undef_p);
                relative_reloc = TRUE;
-               c64_needs_frag_fixup = c64_reloc ? TRUE : FALSE;
+               c64_needs_frag_fixup = globals->c64_rel ? TRUE : FALSE;
              }
 
            symbol_got_offset_mark (input_bfd, h, r_symndx);
@@ -7410,7 +7407,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
       if (c64_needs_frag_fixup)
        {
-         BFD_ASSERT (c64_reloc);
+         BFD_ASSERT (globals->c64_rel);
          /* For a C64 relative relocation, also add size and permissions into
             the frag.  */
          bfd_reloc_status_type ret;
@@ -7433,7 +7430,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
          s = globals->root.srelgot;
 
-         if (c64_reloc)
+         if (globals->c64_rel)
            {
              rtype = MORELLO_R (RELATIVE);
 
index 95c0e1bfec10bfb3810d88c5ae27c279dcbbb3b5..5af3bbfa84151cbfca25dd5580407def9387fba0 100644 (file)
@@ -281,6 +281,7 @@ run_dump_test_lp64 "emit-relocs-morello-6b"
 run_dump_test_lp64 "emit-relocs-morello-7"
 run_dump_test_lp64 "emit-relocs-morello-8"
 run_dump_test_lp64 "emit-relocs-morello-9"
+run_dump_test_lp64 "emit-relocs-morello-10"
 run_dump_test_lp64 "emit-relocs-morello-hidden"
 run_dump_test_lp64 "emit-morello-reloc-markers-1"
 run_dump_test_lp64 "emit-morello-reloc-markers-2"
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-10.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-10.d
new file mode 100644 (file)
index 0000000..9f423e8
--- /dev/null
@@ -0,0 +1,12 @@
+# Checking that we have two RELATIVE relocations, indicating that both the
+# CAPINIT and the GOT entry were given a RELATIVE relocation.  As opposed to
+# before when the linker generated one RELATIVE relocation and an
+# R_AARCH64_NONE relocation.
+#as: -march=morello+c64
+#ld:
+#readelf: --relocs
+
+Relocation section '\.rela\.dyn' at offset .* contains 2 entries:
+  Offset          Info           Type           Sym\. Value    Sym\. Name \+ Addend
+[0-9a-f]+  [0-9a-f]+ R_MORELLO_RELATIV                    0
+[0-9a-f]+  [0-9a-f]+ R_MORELLO_RELATIV                    0
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-10.s b/ld/testsuite/ld-aarch64/emit-relocs-morello-10.s
new file mode 100644 (file)
index 0000000..b04bfe8
--- /dev/null
@@ -0,0 +1,21 @@
+       .data
+str:
+       .string "Hello there big bad world!"
+       .size str,.-str
+       .global ptr
+ptr:
+       .8byte str
+       .align 4
+       .type cap STT_OBJECT
+       .global cap
+cap:
+       .chericap str
+
+       .text
+       .globl _start
+       .type _start STT_FUNC
+_start:
+       ldr     x2, [x2, :got_lo12:cap]
+       adrp    c2, :got:cap
+       ldr     c2, [c2, :got_lo12:cap]
+       ldr     c2, [x2, :got_lo12:cap]