]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] Implement branch relocations
authorSiddhesh Poyarekar <siddesh.poyarekar@arm.com>
Fri, 11 Sep 2020 03:48:10 +0000 (09:18 +0530)
committerLuis Machado <luis.machado@linaro.org>
Tue, 20 Oct 2020 18:04:18 +0000 (15:04 -0300)
This implements the following static relocations:

- R_MORELLO_CALL26, R_MORELLO_JUMP26
- R_MORELLO_TSTBR14, R_MORELLO_CONDBR19

and the following dynamic relocations:

- R_MORELLO_JUMP_SLOT and R_MORELLO_IRELATIVE

Some notes on the implementation:

- The linker selects morello PLT stubs when it finds at least one
  static relocation that needs a capability GOT slot.

- It is assumed that C64 is not compatible with BTI/PAC, so the latter
  gets overridden.  To allow this, the call to setup_plt_values is
  delayed to take into account htab->c64_plt.

- If the caller is A64, the assembler emits R_AARCH64_JUMP_SLOT,
  otherwise it emits R_MORELLO_JUMP_SLOT.

- The PLT stub is A64-compatible, in that it should do the right thing
  when the execution state is A64.

- If the slots are 16-bytes (this happens when there is at least one
  Morello relocation on the GOT), the references in .plt.got and in
  .got are always capabilities; the dynamic linker will take care of
  that.  For PLT, the default trampoline is a capability.  This is
  true for A64 as well as C64.

- At present it is assumed that there is no interworking between A64
  and C64 functions.

bfd/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* elfnn-aarch64.c (elfNN_c64_small_plt0_entry,
elfNN_c64_small_plt_entry): New variables.
(elfNN_aarch64_howto_table): Add relocations.
(setup_plt_values): Choose C64 PLT when appropriate.
(bfd_elfNN_aarch64_set_options): Defer setup_plt_values
call...
(elfNN_aarch64_link_setup_gnu_properties) ... from here as
well...
(elfNN_aarch64_size_dynamic_sections): ... to here.
(elfNN_aarch64_final_link_relocate,
elfNN_aarch64_check_relocs, elfNN_aarch64_reloc_type_class):
Support new relocations.
(map_symbol_type): New member AARCH64_MAP_C64.
(elfNN_aarch64_output_arch_local_syms): Use it.
(aarch64_update_c64_plt_entry): New function.
(elfNN_aarch64_create_small_pltn_entry): Use it.
(elfNN_aarch64_init_small_plt0_entry): Emit C64 PLT when
appropriate.
* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend,
_bfd_aarch64_elf_resolve_relocation): Add new relocations.
* libbfd.h (bfd_reloc_code_real_names): Likewise.
* reloc.c: New relocations BFD_RELOC_MORELLO_TSTBR14,
BFD_RELOC_MORELLO_BRANCH19, BFD_RELOC_MORELLO_JUMP26,
BFD_RELOC_MORELLO_CALL26, BFD_RELOC_MORELLO_JUMP_SLOT and
BFD_RELOC_MORELLO_IRELATIVE.
* bfd-in2.h: Regenerate.

gas/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* config/tc-aarch64.c (parse_operands): Choose C64 branch
relocations when appropriate.
(md_apply_fix, aarch64_force_relocation,
aarch64_fix_adjustable): Support C64 branch relocations.

include/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* elf/aarch64.h: New relocations R_MORELLO_TSTBR14,
R_MORELLO_CONDBR19, R_MORELLO_JUMP26, R_MORELLO_CALL26,
R_MORELLO_JUMP_SLOT and R_MORELLO_IRELATIVE.

ld/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.
* testsuite/ld-aarch64/c64-ifunc-2-local.d: New file.
* testsuite/ld-aarch64/c64-ifunc-2.d: New file.
* testsuite/ld-aarch64/c64-ifunc-3a.d: New file.
* testsuite/ld-aarch64/c64-ifunc-3b.d: New file.
* testsuite/ld-aarch64/c64-ifunc-4.d: New file.
* testsuite/ld-aarch64/c64-ifunc-4a.d: New file.
* testsuite/ld-aarch64/ifunc-2-local.s: Support capabilities.
* testsuite/ld-aarch64/ifunc-2.s: Likewise.

opcodes/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* aarch64-dis.c (get_sym_code_type): Fix C64 PLT disassembly.

22 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elfnn-aarch64.c
bfd/elfxx-aarch64.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-aarch64.c
include/ChangeLog
include/elf/aarch64.h
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/c64-ifunc-2-local.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/c64-ifunc-2.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/c64-ifunc-3a.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/c64-ifunc-3b.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/c64-ifunc-4.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/c64-ifunc-4a.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/ifunc-2-local.s
ld/testsuite/ld-aarch64/ifunc-2.s
opcodes/ChangeLog
opcodes/aarch64-dis.c

index 5e4d909d94184119ce3f4abb69c7c4321467b2a8..6648a26cc3e8dfb1d139eb3c9dde1b17b8e6c9a9 100644 (file)
@@ -1,3 +1,32 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * elfnn-aarch64.c (elfNN_c64_small_plt0_entry,
+       elfNN_c64_small_plt_entry): New variables.
+       (elfNN_aarch64_howto_table): Add relocations.
+       (setup_plt_values): Choose C64 PLT when appropriate.
+       (bfd_elfNN_aarch64_set_options): Defer setup_plt_values
+       call...
+       (elfNN_aarch64_link_setup_gnu_properties) ... from here as
+       well...
+       (elfNN_aarch64_size_dynamic_sections): ... to here.
+       (elfNN_aarch64_final_link_relocate,
+       elfNN_aarch64_check_relocs, elfNN_aarch64_reloc_type_class):
+       Support new relocations.
+       (map_symbol_type): New member AARCH64_MAP_C64.
+       (elfNN_aarch64_output_arch_local_syms): Use it.
+       (aarch64_update_c64_plt_entry): New function.
+       (elfNN_aarch64_create_small_pltn_entry): Use it.
+       (elfNN_aarch64_init_small_plt0_entry): Emit C64 PLT when
+       appropriate.
+       * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend,
+       _bfd_aarch64_elf_resolve_relocation): Add new relocations.
+       * libbfd.h (bfd_reloc_code_real_names): Likewise.
+       * reloc.c: New relocations BFD_RELOC_MORELLO_TSTBR14,
+       BFD_RELOC_MORELLO_BRANCH19, BFD_RELOC_MORELLO_JUMP26,
+       BFD_RELOC_MORELLO_CALL26, BFD_RELOC_MORELLO_JUMP_SLOT and
+       BFD_RELOC_MORELLO_IRELATIVE.
+       * bfd-in2.h: Regenerate.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Emit
index 5f44b187d56cadd9c6bde97556d1cfccbdcd2462..1b0cf5a8e7dae29e2e78eca942994f7a4e0fade4 100644 (file)
@@ -5664,6 +5664,26 @@ The lowest two bits must be zero and are not stored in the instruction,
 giving a 28 bit signed byte offset.  */
   BFD_RELOC_AARCH64_CALL26,
 
+/* A64C 14 bit pc-relative test bit and branch.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 16 bit signed byte offset.  */
+  BFD_RELOC_MORELLO_TSTBR14,
+
+/* A64C 19 bit pc-relative conditional branch and compare & branch.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 21 bit signed byte offset.  */
+  BFD_RELOC_MORELLO_BRANCH19,
+
+/* AArch64 26 bit pc-relative unconditional branch to capability.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 28 bit signed byte offset.  */
+  BFD_RELOC_MORELLO_JUMP26,
+
+/* AArch64 26 bit pc-relative unconditional branch and link to capability.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 28 bit signed byte offset.  */
+  BFD_RELOC_MORELLO_CALL26,
+
 /* AArch64 16-bit load/store instruction, holding bits 0 to 11 of the
 address.  Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.  */
   BFD_RELOC_AARCH64_LDST16_LO12,
@@ -5950,9 +5970,15 @@ instructions.  */
 /* Morello Capability global data.  */
   BFD_RELOC_MORELLO_GLOB_DAT,
 
+/* Morello Jump Slot.  */
+  BFD_RELOC_MORELLO_JUMP_SLOT,
+
 /* Morello relative relocation for capabilities.  */
   BFD_RELOC_MORELLO_RELATIVE,
 
+/* C64 support for STT_GNU_IFUNC.  */
+  BFD_RELOC_MORELLO_IRELATIVE,
+
 /* AArch64 pseudo relocation code to mark the end of the AArch64
 relocation enumerators that have direct mapping to ELF reloc codes.
 There are a few more enumerators after this one; those are mainly
index 897dc1c704a252249cc8a589ec46e4e9779fe80e..c926dba170bd1c3ce97dab89d5fed2954b9aa254 100644 (file)
@@ -325,6 +325,19 @@ static const bfd_byte elfNN_aarch64_small_plt0_bti_entry[PLT_ENTRY_SIZE] =
   0x1f, 0x20, 0x03, 0xd5,      /* nop */
 };
 
+/* The C64 PLT0.  */
+static const bfd_byte elfNN_c64_small_plt0_entry[PLT_ENTRY_SIZE] =
+{
+  0xf0, 0x7b, 0xbf, 0x62,      /* stp c16, c30, [csp, #-32]!  */
+  0x10, 0x00, 0x80, 0x90,      /* adrp c16, (GOT+16)  */
+  0x11, 0x0a, 0x40, 0xc2,      /* ldr c17, [c16, #PLT_GOT+0x10]  */
+  0x10, 0x02, 0x00, 0x02,      /* add c16, c16,#PLT_GOT+0x10   */
+  0x20, 0x12, 0xc2, 0xc2,      /* br c17  */
+  0x1f, 0x20, 0x03, 0xd5,      /* nop */
+  0x1f, 0x20, 0x03, 0xd5,      /* nop */
+  0x1f, 0x20, 0x03, 0xd5,      /* nop */
+};
+
 /* Per function entry in a procedure linkage table looks like this
    if the distance between the PLTGOT and the PLT is < 4GB use
    these PLT entries.  Use BTI versions of the PLTs when enabled.  */
@@ -341,6 +354,15 @@ static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
   0x20, 0x02, 0x1f, 0xd6,      /* br x17.  */
 };
 
+/* The C64 PLT.  */
+static const bfd_byte elfNN_c64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
+{
+  0x10, 0x00, 0x80, 0x90,      /* adrp c16, PLTGOT + offset  */
+  0x11, 0x02, 0x40, 0xc2,      /* ldr c17, [c16, PLTGOT + offset] */
+  0x10, 0x02, 0x00, 0x02,      /* add c16, c16, :lo12:PLTGOT + offset  */
+  0x20, 0x12, 0xc2, 0xc2,      /* br c17.  */
+};
+
 static const bfd_byte
 elfNN_aarch64_small_plt_bti_entry[PLT_BTI_SMALL_ENTRY_SIZE] =
 {
@@ -1026,6 +1048,66 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0x3ffffff,             /* dst_mask */
         TRUE),                 /* pcrel_offset */
 
+  /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
+  HOWTO64 (MORELLO_R (TSTBR14),        /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        14,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed,      /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (TSTBR14),       /* name */
+        FALSE,                 /* partial_inplace */
+        0x3fff,                /* src_mask */
+        0x3fff,                /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
+  HOWTO64 (MORELLO_R (CONDBR19),       /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        19,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed,      /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (CONDBR19),      /* name */
+        FALSE,                 /* partial_inplace */
+        0x7ffff,               /* src_mask */
+        0x7ffff,               /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* B:      ((S+A-P) >> 2) & 0x3ffffff */
+  HOWTO64 (MORELLO_R (JUMP26), /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        26,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed,      /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (JUMP26),        /* name */
+        FALSE,                 /* partial_inplace */
+        0x3ffffff,             /* src_mask */
+        0x3ffffff,             /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* BL:     ((S+A-P) >> 2) & 0x3ffffff */
+  HOWTO64 (MORELLO_R (CALL26), /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        26,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed,      /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (CALL26),        /* name */
+        FALSE,                 /* partial_inplace */
+        0x3ffffff,             /* src_mask */
+        0x3ffffff,             /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
   /* LD/ST16:  (S+A) & 0xffe */
   HOWTO (AARCH64_R (LDST16_ABS_LO12_NC),       /* type */
         1,                     /* rightshift */
@@ -2257,7 +2339,21 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  HOWTO64 (MORELLO_R (RELATIVE),/* type */
+  HOWTO64 (MORELLO_R (JUMP_SLOT),      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,    /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (JUMP_SLOT),     /* name */
+        TRUE,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO64 (MORELLO_R (RELATIVE),       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         64,                    /* bitsize */
@@ -2271,6 +2367,20 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         ALL_ONES,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  HOWTO64 (MORELLO_R (IRELATIVE),      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,    /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (IRELATIVE),     /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ALL_ONES,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
   EMPTY_HOWTO (0),
 };
 
@@ -4951,6 +5061,21 @@ setup_plt_values (struct bfd_link_info *link_info,
   struct elf_aarch64_link_hash_table *globals;
   globals = elf_aarch64_hash_table (link_info);
 
+  /* Set up plt stubs in case we need C64 PLT.  Override BTI/PAC since they're
+     not compatible.  PLT stub sizes are the same as the default ones.  */
+  if (globals->c64_rel)
+    {
+      if (plt_type != PLT_NORMAL)
+       _bfd_error_handler
+         (_("ignoring C64-incompatible extensions: %s"),
+          (plt_type == PLT_BTI_PAC ? "BTI, PAC"
+           : plt_type == PLT_BTI ? "BTI" : "PAC"));
+
+      globals->plt0_entry = elfNN_c64_small_plt0_entry;
+      globals->plt_entry = elfNN_c64_small_plt_entry;
+      return;
+    }
+
   if (plt_type == PLT_BTI_PAC)
     {
       globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry;
@@ -5024,7 +5149,6 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
       break;
     }
   elf_aarch64_tdata (output_bfd)->plt_type = bp_info.plt_type;
-  setup_plt_values (link_info, bp_info.plt_type);
   elf_aarch64_tdata (output_bfd)->secmaps_initialised = FALSE;
 }
 
@@ -5957,7 +6081,10 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
                  || bfd_link_executable (info))
                {
                  /* This symbol is resolved locally.  */
-                 outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
+                 outrel.r_info = (elf_aarch64_hash_entry (h)->got_type
+                                  == GOT_CAP
+                                  ? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE))
+                                  : ELFNN_R_INFO (0, AARCH64_R (IRELATIVE)));
                  outrel.r_addend = (h->root.u.def.value
                                     + h->root.u.def.section->output_section->vma
                                     + h->root.u.def.section->output_offset);
@@ -5979,6 +6106,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
              return bfd_reloc_ok;
            }
          /* FALLTHROUGH */
+       case BFD_RELOC_MORELLO_CALL26:
+       case BFD_RELOC_MORELLO_JUMP26:
        case BFD_RELOC_AARCH64_CALL26:
        case BFD_RELOC_AARCH64_JUMP26:
          value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
@@ -6192,6 +6321,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
        value += signed_addend;
       break;
 
+    case BFD_RELOC_MORELLO_CALL26:
+    case BFD_RELOC_MORELLO_JUMP26:
     case BFD_RELOC_AARCH64_CALL26:
     case BFD_RELOC_AARCH64_JUMP26:
       {
@@ -6291,6 +6422,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
        value |= 1;
       break;
 
+    case BFD_RELOC_MORELLO_BRANCH19:
+    case BFD_RELOC_MORELLO_TSTBR14:
     case BFD_RELOC_AARCH64_BRANCH19:
     case BFD_RELOC_AARCH64_TSTBR14:
       if (h && h->root.type == bfd_link_hash_undefined)
@@ -8206,6 +8339,14 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            default:
              break;
 
+           case BFD_RELOC_MORELLO_CALL26:
+           case BFD_RELOC_MORELLO_JUMP26:
+             /* For dynamic symbols record caller information so that we can
+                decide what kind of PLT stubs to emit.  */
+             if (h != NULL)
+               elf_aarch64_hash_entry (h)->got_type = GOT_CAP;
+             /* Fall through.  */
+
            case BFD_RELOC_AARCH64_ADD_LO12:
            case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
            case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
@@ -8519,6 +8660,13 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            break;
          }
 
+       case BFD_RELOC_MORELLO_CALL26:
+       case BFD_RELOC_MORELLO_JUMP26:
+         htab->c64_rel = 1;
+         if (h != NULL)
+           elf_aarch64_hash_entry (h)->got_type = GOT_CAP;
+
+         /* Fall through.  */
        case BFD_RELOC_AARCH64_CALL26:
        case BFD_RELOC_AARCH64_JUMP26:
          if (h == NULL)
@@ -8698,10 +8846,13 @@ elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSE
   switch ((int) ELFNN_R_TYPE (rela->r_info))
     {
     case AARCH64_R (IRELATIVE):
+    case MORELLO_R (IRELATIVE):
       return reloc_class_ifunc;
     case AARCH64_R (RELATIVE):
+    case MORELLO_R (RELATIVE):
       return reloc_class_relative;
     case AARCH64_R (JUMP_SLOT):
+    case MORELLO_R (JUMP_SLOT):
       return reloc_class_plt;
     case AARCH64_R (COPY):
       return reloc_class_copy;
@@ -8752,7 +8903,8 @@ typedef struct
 enum map_symbol_type
 {
   AARCH64_MAP_INSN,
-  AARCH64_MAP_DATA
+  AARCH64_MAP_DATA,
+  AARCH64_MAP_C64,
 };
 
 
@@ -8914,7 +9066,8 @@ elfNN_aarch64_output_arch_local_syms (bfd *output_bfd,
     (output_bfd, htab->root.splt->output_section);
   osi.sec = htab->root.splt;
 
-  elfNN_aarch64_output_map_sym (&osi, AARCH64_MAP_INSN, 0);
+  elfNN_aarch64_output_map_sym (&osi, (htab->c64_rel ? AARCH64_MAP_C64
+                                      : AARCH64_MAP_INSN), 0);
 
   return TRUE;
 
@@ -9355,6 +9508,8 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd,
 
   aarch64_elf_init_got_section (output_bfd, info);
 
+  setup_plt_values (info, elf_aarch64_tdata (output_bfd)->plt_type);
+
   /* Set up .got offsets for local syms, and space for local dynamic
      relocs.  */
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
@@ -9626,6 +9781,26 @@ elf_aarch64_update_plt_entry (bfd *output_bfd,
   (void) _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
 }
 
+static void
+aarch64_update_c64_plt_entry (bfd *output_bfd, bfd_byte *plt_entry,
+                             bfd_vma plt_base, bfd_vma plt_got_ent)
+{
+  /* Fill in the top 20 bits for this: ADRP c16, PLT_GOT + n * 16.
+     ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0xfffff */
+  elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_MORELLO_ADR_HI20_PCREL,
+                               plt_entry,
+                               PG (plt_got_ent) - PG (plt_base));
+
+  elf_aarch64_update_plt_entry (output_bfd,
+                               BFD_RELOC_AARCH64_LDST128_LO12,
+                               plt_entry + 4,
+                               PG_OFFSET (plt_got_ent));
+
+  elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
+                               plt_entry + 8,
+                               PG_OFFSET (plt_got_ent));
+}
+
 static void
 elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
                                       struct elf_aarch64_link_hash_table
@@ -9687,33 +9862,42 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
   /* Copy in the boiler-plate for the PLTn entry.  */
   memcpy (plt_entry, htab->plt_entry, htab->plt_entry_size);
 
-  /* First instruction in BTI enabled PLT stub is a BTI
-     instruction so skip it.  */
-  if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI
-      && elf_elfheader (output_bfd)->e_type == ET_EXEC)
-    plt_entry = plt_entry + 4;
+  if (htab->c64_rel)
+    aarch64_update_c64_plt_entry (output_bfd, plt_entry, plt_entry_address,
+                                 gotplt_entry_address);
+  else
+    {
 
-  /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
-     ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
-  elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
-                               plt_entry,
-                               PG (gotplt_entry_address) -
-                               PG (plt_entry_address));
+      /* First instruction in BTI enabled PLT stub is a BTI
+        instruction so skip it.  */
+      if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI
+         && elf_elfheader (output_bfd)->e_type == ET_EXEC)
+       plt_entry = plt_entry + 4;
 
-  /* Fill in the lo12 bits for the load from the pltgot.  */
-  elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
-                               plt_entry + 4,
-                               PG_OFFSET (gotplt_entry_address));
+      /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
+        ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
+      elf_aarch64_update_plt_entry (output_bfd,
+                                   BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+                                   plt_entry,
+                                   PG (gotplt_entry_address) -
+                                   PG (plt_entry_address));
 
-  /* Fill in the lo12 bits for the add from the pltgot entry.  */
-  elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
-                               plt_entry + 8,
-                               PG_OFFSET (gotplt_entry_address));
+      /* Fill in the lo12 bits for the load from the pltgot.  */
+      elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
+                                   plt_entry + 4,
+                                   PG_OFFSET (gotplt_entry_address));
 
-  /* All the GOTPLT Entries are essentially initialized to PLT0.  */
-  bfd_put_NN (output_bfd,
-             plt->output_section->vma + plt->output_offset,
-             gotplt->contents + got_offset);
+      /* Fill in the lo12 bits for the add from the pltgot entry.  */
+      elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
+                                   plt_entry + 8,
+                                   PG_OFFSET (gotplt_entry_address));
+    }
+
+  /* All the GOTPLT Entries are essentially initialized to PLT0.  Set LSB if
+     the PLT is C64.  */
+  bfd_vma plt0 = ((plt->output_section->vma + plt->output_offset)
+                 | htab->c64_rel);
+  bfd_put_NN (output_bfd, plt0, gotplt->contents + got_offset);
 
   rela.r_offset = gotplt_entry_address;
 
@@ -9725,7 +9909,9 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
     {
       /* If an STT_GNU_IFUNC symbol is locally defined, generate
         R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT.  */
-      rela.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
+      rela.r_info = (elf_aarch64_hash_entry (h)->got_type == GOT_CAP
+                    ? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE))
+                    : ELFNN_R_INFO (0, AARCH64_R (IRELATIVE)));
       rela.r_addend = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
                       + h->root.u.def.section->output_offset);
@@ -9733,7 +9919,9 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
   else
     {
       /* Fill in the entry in the .rela.plt section.  */
-      rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
+      rela.r_info = (elf_aarch64_hash_entry (h)->got_type == GOT_CAP
+                    ? ELFNN_R_INFO (h->dynindx, MORELLO_R (JUMP_SLOT))
+                    : ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT)));
       rela.r_addend = 0;
     }
 
@@ -10043,9 +10231,17 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
   plt_base = htab->root.splt->output_section->vma +
     htab->root.splt->output_offset;
 
+  bfd_byte *plt0_entry = htab->root.splt->contents;
+
+  if (htab->c64_rel)
+    {
+      aarch64_update_c64_plt_entry (output_bfd, plt0_entry + 4,
+                                   plt_base + 4, plt_got_2nd_ent);
+      return;
+    }
+
   /* First instruction in BTI enabled PLT stub is a BTI
      instruction so skip it.  */
-  bfd_byte *plt0_entry = htab->root.splt->contents;
   if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI)
     plt0_entry = plt0_entry + 4;
 
@@ -10389,7 +10585,6 @@ elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info *info)
   elf_aarch64_tdata (info->output_bfd)->gnu_and_prop = prop;
   elf_aarch64_tdata (info->output_bfd)->plt_type
     |= (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ? PLT_BTI : 0;
-  setup_plt_values (info, elf_aarch64_tdata (info->output_bfd)->plt_type);
   return pbfd;
 }
 
index cc58c17419696891ccec8efdc8e97219ee32cd62..3163c99831571db778263c03113fadd41111ee59 100644 (file)
@@ -230,16 +230,20 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
 
   switch (r_type)
     {
+    case BFD_RELOC_MORELLO_CALL26:
+    case BFD_RELOC_MORELLO_JUMP26:
     case BFD_RELOC_AARCH64_CALL26:
     case BFD_RELOC_AARCH64_JUMP26:
       contents = reencode_branch_ofs_26 (contents, addend);
       break;
 
     case BFD_RELOC_AARCH64_BRANCH19:
+    case BFD_RELOC_MORELLO_BRANCH19:
       contents = reencode_cond_branch_ofs_19 (contents, addend);
       break;
 
     case BFD_RELOC_AARCH64_TSTBR14:
+    case BFD_RELOC_MORELLO_TSTBR14:
       contents = reencode_tst_branch_ofs_14 (contents, addend);
       break;
 
@@ -451,6 +455,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd,
     case BFD_RELOC_AARCH64_64_PCREL:
     case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
     case BFD_RELOC_AARCH64_BRANCH19:
+    case BFD_RELOC_MORELLO_BRANCH19:
     case BFD_RELOC_AARCH64_LD_LO19_PCREL:
     case BFD_RELOC_AARCH64_MOVW_PREL_G0:
     case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC:
@@ -465,11 +470,14 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd,
     case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
     case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
     case BFD_RELOC_AARCH64_TSTBR14:
+    case BFD_RELOC_MORELLO_TSTBR14:
       if (weak_undef_p)
        value = place;
       value = value + addend - place;
       break;
 
+    case BFD_RELOC_MORELLO_CALL26:
+    case BFD_RELOC_MORELLO_JUMP26:
     case BFD_RELOC_AARCH64_CALL26:
     case BFD_RELOC_AARCH64_JUMP26:
       value = value + addend - place;
index c106292175dd7eff5937d5866615b4f4618eae4e..1180071c119d45d5902cad0a2f34ac5b646743b3 100644 (file)
@@ -3027,6 +3027,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_BRANCH19",
   "BFD_RELOC_AARCH64_JUMP26",
   "BFD_RELOC_AARCH64_CALL26",
+  "BFD_RELOC_MORELLO_TSTBR14",
+  "BFD_RELOC_MORELLO_BRANCH19",
+  "BFD_RELOC_MORELLO_JUMP26",
+  "BFD_RELOC_MORELLO_CALL26",
   "BFD_RELOC_AARCH64_LDST16_LO12",
   "BFD_RELOC_AARCH64_LDST32_LO12",
   "BFD_RELOC_AARCH64_LDST64_LO12",
@@ -3110,7 +3114,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_IRELATIVE",
   "BFD_RELOC_MORELLO_CAPINIT",
   "BFD_RELOC_MORELLO_GLOB_DAT",
+  "BFD_RELOC_MORELLO_JUMP_SLOT",
   "BFD_RELOC_MORELLO_RELATIVE",
+  "BFD_RELOC_MORELLO_IRELATIVE",
   "BFD_RELOC_AARCH64_RELOC_END",
   "BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP",
   "BFD_RELOC_AARCH64_LDST_LO12",
index a5f64c177ad8e0b21b57bdee134fc8070b00e42a..fc9e9bef720bcc0fad4b49528e35a7a62018fa47 100644 (file)
@@ -7174,6 +7174,30 @@ ENUMDOC
   AArch64 26 bit pc-relative unconditional branch and link.
   The lowest two bits must be zero and are not stored in the instruction,
   giving a 28 bit signed byte offset.
+ENUM
+  BFD_RELOC_MORELLO_TSTBR14
+ENUMDOC
+  A64C 14 bit pc-relative test bit and branch.
+  The lowest two bits must be zero and are not stored in the instruction,
+  giving a 16 bit signed byte offset.
+ENUM
+  BFD_RELOC_MORELLO_BRANCH19
+ENUMDOC
+  A64C 19 bit pc-relative conditional branch and compare & branch.
+  The lowest two bits must be zero and are not stored in the instruction,
+  giving a 21 bit signed byte offset.
+ENUM
+  BFD_RELOC_MORELLO_JUMP26
+ENUMDOC
+  AArch64 26 bit pc-relative unconditional branch to capability.
+  The lowest two bits must be zero and are not stored in the instruction,
+  giving a 28 bit signed byte offset.
+ENUM
+  BFD_RELOC_MORELLO_CALL26
+ENUMDOC
+  AArch64 26 bit pc-relative unconditional branch and link to capability.
+  The lowest two bits must be zero and are not stored in the instruction,
+  giving a 28 bit signed byte offset.
 ENUM
   BFD_RELOC_AARCH64_LDST16_LO12
 ENUMDOC
@@ -7543,10 +7567,18 @@ ENUM
   BFD_RELOC_MORELLO_GLOB_DAT
 ENUMDOC
   Morello Capability global data.
+ENUM
+  BFD_RELOC_MORELLO_JUMP_SLOT
+ENUMDOC
+  Morello Jump Slot.
 ENUM
   BFD_RELOC_MORELLO_RELATIVE
 ENUMDOC
   Morello relative relocation for capabilities.
+ENUM
+  BFD_RELOC_MORELLO_IRELATIVE
+ENUMDOC
+  C64 support for STT_GNU_IFUNC.
 ENUM
   BFD_RELOC_AARCH64_RELOC_END
 ENUMDOC
index d0ae46139ca927cb90714f2fcea9dab242bc840b..dd8fd72b837d5c9d3d9bf4dede041175ae492155 100644 (file)
@@ -1,3 +1,10 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * config/tc-aarch64.c (parse_operands): Choose C64 branch
+       relocations when appropriate.
+       (md_apply_fix, aarch64_force_relocation,
+       aarch64_fix_adjustable): Support C64 branch relocations.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * config/tc-aarch64.c (parse_operands): Emit C64 relocations
index 715ac2d2e9b50a5a6d50a7778ab88a4a91f0078d..4e63ce1594c02dbf32258b9e06af95615c1267fb 100644 (file)
@@ -6623,19 +6623,29 @@ bad_adrdp:
                  case condbranch:
                    /* e.g. CBZ or B.COND  */
                    gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19);
-                   inst.reloc.type = BFD_RELOC_AARCH64_BRANCH19;
+                   inst.reloc.type = (c64 ? BFD_RELOC_MORELLO_BRANCH19
+                                      : BFD_RELOC_AARCH64_BRANCH19);
                    break;
                  case testbranch:
                    /* e.g. TBZ  */
                    gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL14);
-                   inst.reloc.type = BFD_RELOC_AARCH64_TSTBR14;
+                   inst.reloc.type = (c64 ? BFD_RELOC_MORELLO_TSTBR14
+                                      : BFD_RELOC_AARCH64_TSTBR14);
                    break;
                  case branch_imm:
                    /* e.g. B or BL  */
-                   gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL26);
-                   inst.reloc.type =
-                     (opcode->op == OP_BL) ? BFD_RELOC_AARCH64_CALL26
-                        : BFD_RELOC_AARCH64_JUMP26;
+                     {
+                       enum aarch64_opnd jump, call;
+
+                       gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL26);
+
+                       jump = (c64 ? BFD_RELOC_MORELLO_JUMP26
+                               : BFD_RELOC_AARCH64_JUMP26);
+                       call = (c64 ? BFD_RELOC_MORELLO_CALL26
+                               : BFD_RELOC_AARCH64_CALL26);
+
+                       inst.reloc.type = opcode->op == OP_BL ? call : jump;
+                     }
                    break;
                  case loadlit:
                    gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19
@@ -8516,6 +8526,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
       break;
 
     case BFD_RELOC_AARCH64_BRANCH19:
+    case BFD_RELOC_MORELLO_BRANCH19:
       if (fixP->fx_done || !seg->use_rela_p)
        {
          if (value & 3)
@@ -8530,6 +8541,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
        }
       break;
 
+    case BFD_RELOC_MORELLO_TSTBR14:
     case BFD_RELOC_AARCH64_TSTBR14:
       if (fixP->fx_done || !seg->use_rela_p)
        {
@@ -8545,6 +8557,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
        }
       break;
 
+    case BFD_RELOC_MORELLO_CALL26:
+    case BFD_RELOC_MORELLO_JUMP26:
     case BFD_RELOC_AARCH64_CALL26:
     case BFD_RELOC_AARCH64_JUMP26:
       if (fixP->fx_done || !seg->use_rela_p)
@@ -8997,8 +9011,12 @@ aarch64_force_relocation (struct fix *fixp)
       return 1;
 
     case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
+    case BFD_RELOC_MORELLO_BRANCH19:
+    case BFD_RELOC_MORELLO_TSTBR14:
     case BFD_RELOC_AARCH64_BRANCH19:
     case BFD_RELOC_AARCH64_TSTBR14:
+    case BFD_RELOC_MORELLO_CALL26:
+    case BFD_RELOC_MORELLO_JUMP26:
     case BFD_RELOC_AARCH64_CALL26:
     case BFD_RELOC_AARCH64_JUMP26:
       gas_assert (fixp->fx_addsy != NULL);
@@ -9175,6 +9193,10 @@ aarch64_fix_adjustable (struct fix *fixP)
     case BFD_RELOC_AARCH64_TSTBR14:
     case BFD_RELOC_AARCH64_JUMP26:
     case BFD_RELOC_AARCH64_CALL26:
+    case BFD_RELOC_MORELLO_BRANCH19:
+    case BFD_RELOC_MORELLO_TSTBR14:
+    case BFD_RELOC_MORELLO_JUMP26:
+    case BFD_RELOC_MORELLO_CALL26:
       if (fixP->tc_fix_data.c64 || AARCH64_IS_C64 (fixP->fx_addsy))
        return FALSE;
       break;
index d50893b0e2b4a1d64178173ba1837d3b16b3116f..232c640915a55a3bbbf093fd4c854c65af8b5d4f 100644 (file)
@@ -1,3 +1,9 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * elf/aarch64.h: New relocations R_MORELLO_TSTBR14,
+       R_MORELLO_CONDBR19, R_MORELLO_JUMP26, R_MORELLO_CALL26,
+       R_MORELLO_JUMP_SLOT and R_MORELLO_IRELATIVE.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * elf/aarch64.h: New relocations R_MORELLO_LD128_GOT_LO12_NC
index 3aa27712aa9e9472d94362f84a1831bacc4a7539..ff91177d4e374ed3b7dd933faec8f16b95691e90 100644 (file)
@@ -444,6 +444,18 @@ RELOC_NUMBER (R_AARCH64_IRELATIVE, 1032)
 
 /* Morello Relocations.  */
 
+/* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff.  */
+RELOC_NUMBER (R_MORELLO_TSTBR14, 57344)
+
+/* B.cond: ((S+A-P) >> 2) & 0x7ffff.  */
+RELOC_NUMBER (R_MORELLO_CONDBR19, 57345)
+
+/* B:      ((S+A-P) >> 2) & 0x3ffffff.  */
+RELOC_NUMBER (R_MORELLO_JUMP26, 57346)
+
+/* BL:     ((S+A-P) >> 2) & 0x3ffffff.  */
+RELOC_NUMBER (R_MORELLO_CALL26, 57347)
+
 /* A64C LD-lit: ((S+A-P) >> 4) & 0x1ffff */
 RELOC_NUMBER (R_MORELLO_LD_PREL_LO17, 57348)
 
@@ -461,7 +473,9 @@ RELOC_NUMBER (R_MORELLO_LD128_GOT_LO12_NC, 57352)
 
 RELOC_NUMBER (R_MORELLO_CAPINIT, 59392)
 RELOC_NUMBER (R_MORELLO_GLOB_DAT, 59393)
+RELOC_NUMBER (R_MORELLO_JUMP_SLOT, 59394)
 RELOC_NUMBER (R_MORELLO_RELATIVE, 59395)
+RELOC_NUMBER (R_MORELLO_IRELATIVE, 59396)
 
 END_RELOC_NUMBERS (R_AARCH64_end)
 
index 13e55a71d51a5f23aaa6f6699c699c5bc79ff166..269b09d2d2999fce787ddc6a636e0f4467251637 100644 (file)
@@ -1,3 +1,15 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.
+       * testsuite/ld-aarch64/c64-ifunc-2-local.d: New file.
+       * testsuite/ld-aarch64/c64-ifunc-2.d: New file.
+       * testsuite/ld-aarch64/c64-ifunc-3a.d: New file.
+       * testsuite/ld-aarch64/c64-ifunc-3b.d: New file.
+       * testsuite/ld-aarch64/c64-ifunc-4.d: New file.
+       * testsuite/ld-aarch64/c64-ifunc-4a.d: New file.
+       * testsuite/ld-aarch64/ifunc-2-local.s: Support capabilities.
+       * testsuite/ld-aarch64/ifunc-2.s: Likewise.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * testsuite/ld-aarch64/emit-relocs-morello-2-a64c.d: New test.
index 7604061506e9a4eccd533b6ca0310d0678984fde..1d56179505528ebc60e1f2dc634a7e7389e252e8 100644 (file)
@@ -382,6 +382,13 @@ run_dump_test_lp64 "ifunc-20"
 run_dump_test_lp64 "ifunc-21"
 run_dump_test_lp64 "ifunc-22"
 
+run_dump_test_lp64 "c64-ifunc-2"
+run_dump_test_lp64 "c64-ifunc-2-local"
+run_dump_test_lp64 "c64-ifunc-3a"
+run_dump_test_lp64 "c64-ifunc-3b"
+run_dump_test_lp64 "c64-ifunc-4"
+run_dump_test_lp64 "c64-ifunc-4a"
+
 run_dump_test "relasz"
 run_dump_test_lp64 "relocs-1027-symbolic-func"
 
diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d b/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d
new file mode 100644 (file)
index 0000000..8c7fe03
--- /dev/null
@@ -0,0 +1,13 @@
+#target: [check_shared_lib_support]
+#as: -march=morello+c64 --defsym C64MODE=1
+#ld: -shared --hash-style=sysv
+#objdump: -dw
+#source: ifunc-2-local.s
+
+#...
+0+(110|180|1a0) <__GI_foo>:
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0x(110|180|1a0)@plt>
+[ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+c0, 0 <.*>
+[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+c0, c0, #0x(101|171|191)
+#pass
diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-2.d b/ld/testsuite/ld-aarch64/c64-ifunc-2.d
new file mode 100644 (file)
index 0000000..64a8b80
--- /dev/null
@@ -0,0 +1,13 @@
+#target: [check_shared_lib_support]
+#as: -march=morello+c64 --defsym C64MODE=1
+#ld: -shared --hash-style=sysv
+#objdump: -dw
+#source: ifunc-2.s
+
+#...
+0+(130|1a0|1c8) <foo>:
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0x(130|1a0|1c8)@plt>
+[ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+c0, 0 <.*>
+[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+c0, c0, #0x(120|190|1b8)
+#pass
diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-3a.d b/ld/testsuite/ld-aarch64/c64-ifunc-3a.d
new file mode 100644 (file)
index 0000000..d680cde
--- /dev/null
@@ -0,0 +1,11 @@
+#source: ifunc-3.s
+#target: [check_shared_lib_support]
+#as: -march=morello+c64
+#ld: -shared --hash-style=sysv
+#objdump: -dw
+
+#...
+0+(150|1d0|1e8) <__GI_foo>:
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0x(150|1d0|1e8)@plt>
+#pass
diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-3b.d b/ld/testsuite/ld-aarch64/c64-ifunc-3b.d
new file mode 100644 (file)
index 0000000..99929ed
--- /dev/null
@@ -0,0 +1,9 @@
+#source: ifunc-3.s
+#target: [check_shared_lib_support]
+#as: -march=morello+c64
+#ld: -shared
+#readelf: -r --wide
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_MORELLO_IRELATIVE[ ]*[0-9a-f]*
+#pass
diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-4.d b/ld/testsuite/ld-aarch64/c64-ifunc-4.d
new file mode 100644 (file)
index 0000000..ec9411a
--- /dev/null
@@ -0,0 +1,9 @@
+#source: ifunc-4.s
+#as: -march=morello+c64
+#ld:
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_MORELLO_IRELATIVE[ ]*[0-9a-f]*
+#pass
diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-4a.d b/ld/testsuite/ld-aarch64/c64-ifunc-4a.d
new file mode 100644 (file)
index 0000000..3c240e3
--- /dev/null
@@ -0,0 +1,9 @@
+#as: -march=morello+c64
+#ld: -s
+#readelf: -r --wide
+#target: aarch64*-*-*
+#source: ifunc-4.s
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_MORELLO_IRELATIVE[ ]*[0-9a-f]*
+#pass
index 632c31f456067809c0fb03eacfd9cc0b58c6b1ce..5354ad485072a8513caf82ead5af9fef20d54a39 100644 (file)
@@ -1,3 +1,9 @@
+       .ifdef C64MODE
+               REG .req c0
+       .else
+               REG .req x0
+       .endif
+
        .type foo, %gnu_indirect_function
        .set __GI_foo, foo
        .text
@@ -9,7 +15,7 @@ foo:
        .type   bar, @function
 bar:
        bl      __GI_foo
-        adrp    x0, __GI_foo
-        add     x0, x0, :lo12:__GI_foo
+        adrp    REG, __GI_foo
+        add     REG, REG, :lo12:__GI_foo
        ret
        .size   bar, .-bar
index da350df63158ae75b58b6d46df78470fc37fe0cf..bd65b2305c9247546a8f04bb6496b39ac5f5c9a1 100644 (file)
@@ -1,3 +1,9 @@
+       .ifdef C64MODE
+               REG .req c0
+       .else
+               REG .req x0
+       .endif
+
        .type foo, %gnu_indirect_function
        .global __GI_foo
        .hidden __GI_foo
@@ -12,7 +18,7 @@ foo:
        .type   bar, @function
 bar:
        bl      __GI_foo
-        adrp    x0, __GI_foo
-        add     x0, x0, :lo12:__GI_foo
+        adrp    REG, __GI_foo
+        add     REG, REG, :lo12:__GI_foo
        ret
        .size   bar, .-bar
index 49a7786b3d58a1c0f63daf9d74752e2a1b28585d..58df5c059d1229a1876488b2132ea978b146c391 100644 (file)
@@ -1,3 +1,7 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * aarch64-dis.c (get_sym_code_type): Fix C64 PLT disassembly.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * aarch64-opc.c (operand_general_constraint_met_p): Expect
index 062458a018933cc56cab5efe3a3b6bbcb45ce53f..24dea397e83f9b9098316d866751141b4a766a2b 100644 (file)
@@ -3547,8 +3547,9 @@ get_sym_code_type (struct disassemble_info *info, int n,
 
   type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
 
-  /* ST_TARGET_INTERNAL is set for C64.  */
-  if (type == STT_FUNC)
+  /* ST_TARGET_INTERNAL is set for C64.  For PLT stubs, depend only on the
+     mapping symbol that the linker generated for it.  */
+  if (type == STT_FUNC && !(es->symbol.flags & BSF_SYNTHETIC))
     {
       *map_type = (es->internal_elf_sym.st_target_internal & ST_BRANCH_TO_C64
                   ? MAP_C64 : MAP_INSN);