]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] GOT Relocations
authorSiddhesh Poyarekar <siddesh.poyarekar@arm.com>
Fri, 11 Sep 2020 03:48:10 +0000 (09:18 +0530)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 22:53:21 +0000 (15:53 -0700)
- Implement R_MORELLO_LD128_GOT_LO12_NC and emit the correct
  relocation based on the target register size.
- Add R_MORELLO_GLOB_DAT and R_MORELLO_RELATIVE dynamic relocations for GOT
  entries
- Add support for capabilities in GOT

GOT slots for capabilities need to be 16 byte to accommodate
capabilities.  For this purpose, we delay initialising size and
alignment of the GOT sections until we have walked all relocs in
check_relocs.  If we encounter capability relocations during the walk,
set the GOT entry size and alignment to account for capabilities or
leave it pointer sized otherwise.

bfd/ChangeLog:

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

* elfnn-aarch64.c (GOT_ENTRY_SIZE): Adjust for C64
relocations.  Adjust callers.
(GOT_RESERVED_HEADER_SLOTS, GOT_CAP): New macros.
(elfNN_aarch64_howto_table): Add R_MORELLO_LD128_GOT_LO12_NC
and R_MORELLO_GLOB_DAT.
(elf_aarch64_link_hash_table): New member c64_rel.
(bfd_elfNN_aarch64_set_options): Initialise it.
(cap_meta, c64_get_capsize): New functions.
(aarch64_reloc_got_type): Use GOT_CAP.
(elfNN_aarch64_final_link_relocate): Add
R_MORELLO_LD128_GOT_LO12_NC and R_MORELLO_GLOB_DAT.
(aarch64_elf_create_got_section): Move section initialisation
into a...
(aarch64_elf_init_got_section): ... New function.
(elfNN_aarch64_size_dynamic_sections): Call it.
(elfNN_aarch64_check_relocs): Add R_MORELLO_LD128_GOT_LO12_NC
and R_MORELLO_GLOB_DAT.
(elfNN_aarch64_finish_dynamic_symbol): Emit C64 relocations
when appropriate.
(elfNN_aarch64_got_elt_size): New function.
(elfNN_aarch64_got_header_size): Return GOT entry size based
on c64_rel.
(elf_backend_got_elt_size): New macro.
* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend,
_bfd_aarch64_elf_resolve_relocation): Add
BFD_RELOC_MORELLO_LD128_GOT_LO12_NC.
* libbfd.h (bfd_reloc_code_real_names): Add
BFD_RELOC_MORELLO_GLOB_DAT and
BFD_RELOC_MORELLO_LD128_GOT_LO12_NC.
* reloc.c: Likewise.
* bfd-in2.h: Regenerate.

gas/ChangeLog:

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

* config/tc-aarch64.c (parse_operands): Emit C64 relocations
for got_lo12.  Move old relocation checks from...
(md_apply_fix): ... here.
* testsuite/gas/aarch64/morello-ldst-reloc.d: Add tests.
* testsuite/gas/aarch64/morello-ldst-reloc.s: Likewise.

include/ChangeLog:

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

* elf/aarch64.h: New relocations R_MORELLO_LD128_GOT_LO12_NC
and R_MORELLO_GLOB_DAT.

ld/ChangeLog:

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

* testsuite/ld-aarch64/emit-relocs-morello-1.d: New file.
* testsuite/ld-aarch64/emit-relocs-morello-1.s: New test file.
* testsuite/ld-aarch64/aarch64-elf.exp: Add it to test runner.

16 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
gas/testsuite/gas/aarch64/morello-ldst-reloc.d
gas/testsuite/gas/aarch64/morello-ldst-reloc.s
include/ChangeLog
include/elf/aarch64.h
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/emit-relocs-morello-1.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/emit-relocs-morello-1.s [new file with mode: 0644]

index 49550c9aedce585450bc44df4f128838bdfd60b6..259817fa8edee998f1f61c460ba5284e2771db07 100644 (file)
@@ -1,3 +1,37 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * elfnn-aarch64.c (GOT_ENTRY_SIZE): Adjust for C64
+       relocations.  Adjust callers.
+       (GOT_RESERVED_HEADER_SLOTS, GOT_CAP): New macros.
+       (elfNN_aarch64_howto_table): Add R_MORELLO_LD128_GOT_LO12_NC
+       and R_MORELLO_GLOB_DAT.
+       (elf_aarch64_link_hash_table): New member c64_rel.
+       (bfd_elfNN_aarch64_set_options): Initialise it.
+       (cap_meta, c64_get_capsize): New functions.
+       (aarch64_reloc_got_type): Use GOT_CAP.
+       (elfNN_aarch64_final_link_relocate): Add
+       R_MORELLO_LD128_GOT_LO12_NC and R_MORELLO_GLOB_DAT.
+       (aarch64_elf_create_got_section): Move section initialisation
+       into a...
+       (aarch64_elf_init_got_section): ... New function.
+       (elfNN_aarch64_size_dynamic_sections): Call it.
+       (elfNN_aarch64_check_relocs): Add R_MORELLO_LD128_GOT_LO12_NC
+       and R_MORELLO_GLOB_DAT.
+       (elfNN_aarch64_finish_dynamic_symbol): Emit C64 relocations
+       when appropriate.
+       (elfNN_aarch64_got_elt_size): New function.
+       (elfNN_aarch64_got_header_size): Return GOT entry size based
+       on c64_rel.
+       (elf_backend_got_elt_size): New macro.
+       * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend,
+       _bfd_aarch64_elf_resolve_relocation): Add
+       BFD_RELOC_MORELLO_LD128_GOT_LO12_NC.
+       * libbfd.h (bfd_reloc_code_real_names): Add
+       BFD_RELOC_MORELLO_GLOB_DAT and
+       BFD_RELOC_MORELLO_LD128_GOT_LO12_NC.
+       * reloc.c: Likewise.
+       * bfd-in2.h: Regenerate.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
            Tamar Christina  <tamar.christina@arm.com>
 
index f1d83b11de3bd8d4a22251b4fe7f184f7618ad44..5d501e7426cf9dd62a42c0bad5124afc40bb3ebb 100644 (file)
@@ -5712,6 +5712,11 @@ the GOT entry for this symbol.  Used in conjunction with
 BFD_RELOC_AARCH64_ADR_GOT_PAGE.  Valid in LP64 ABI only.  */
   BFD_RELOC_AARCH64_LD64_GOT_LO12_NC,
 
+/* Unsigned 12 bit byte offset for 128 bit load/store from the page of
+the GOT entry for this symbol.  Used in conjunction with
+BFD_RELOC_MORELLO_ADR_GOT_PAGE.  Valid in C64 ABI only.  */
+  BFD_RELOC_MORELLO_LD128_GOT_LO12_NC,
+
 /* Unsigned 12 bit byte offset for 32 bit load/store from the page of
 the GOT entry for this symbol.  Used in conjunction with
 BFD_RELOC_AARCH64_ADR_GOT_PAGE.  Valid in ILP32 ABI only.  */
@@ -5952,6 +5957,9 @@ instructions.  */
 /* Morello Capability initialization.  */
   BFD_RELOC_MORELLO_CAPINIT,
 
+/* Morello Capability global data.  */
+  BFD_RELOC_MORELLO_GLOB_DAT,
+
 /* Morello relative relocation for capabilities.  */
   BFD_RELOC_MORELLO_RELATIVE,
 
index e4c2bad6bc2610be2bcabd1dd88073caf9e678c8..c1897903f9bec2b6ff41c9f7218b50a601c3fd80 100644 (file)
    elf_aarch64_link_hash_entry.  */
 #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
 
-/* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32.  */
-#define GOT_ENTRY_SIZE                 (ARCH_SIZE / 8)
+/* GOT Entry size - 16 bytes in C64, 8 bytes in ELF64 and 4 bytes in ELF32.  */
+#define GOT_ENTRY_SIZE(htab) (ARCH_SIZE >> (3 - htab->c64_rel))
+#define GOT_RESERVED_HEADER_SLOTS      (3)
 #define PLT_ENTRY_SIZE                 (32)
 #define PLT_SMALL_ENTRY_SIZE           (16)
 #define PLT_TLSDESC_ENTRY_SIZE         (32)
 
 #define aarch64_compute_jump_table_size(htab)          \
   (((htab)->root.srelplt == NULL) ? 0                  \
-   : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
+   : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE (htab))
 
 /* The first entry in a procedure linkage table looks like this
    if the distance between the PLTGOT and the PLT is < 4GB use
@@ -1148,6 +1149,21 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0xff8,                 /* dst_mask */
         false),                /* pcrel_offset */
 
+  /* LD128: GOT offset G(S) & 0xff0  */
+  HOWTO64 (MORELLO_R (LD128_GOT_LO12_NC),      /* type */
+        4,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (LD128_GOT_LO12_NC),     /* name */
+        false,                 /* partial_inplace */
+        0xff0,                 /* src_mask */
+        0xff0,                 /* dst_mask */
+        false),                /* pcrel_offset */
+
   /* LD32: GOT offset G(S) & 0xffc  */
   HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC),       /* type */
         2,                     /* rightshift */
@@ -2227,7 +2243,21 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         ALL_ONES,              /* dst_mask */
         false),                /* pcrel_offset */
 
-  HOWTO64 (MORELLO_R (RELATIVE),       /* type */
+  HOWTO64 (MORELLO_R (GLOB_DAT),/* 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 (GLOB_DAT),      /* 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 */
@@ -2732,6 +2762,7 @@ elfNN_aarch64_mkobject (bfd *abfd)
 #define GOT_TLS_GD     2
 #define GOT_TLS_IE     4
 #define GOT_TLSDESC_GD 8
+#define GOT_CAP        16
 
 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
 
@@ -2858,6 +2889,7 @@ struct elf_aarch64_link_hash_table
 
   /* Used for capability relocations.  */
   asection *srelcaps;
+  int c64_rel;
 };
 
 /* Create an entry in an AArch64 ELF linker hash table.  */
@@ -4974,6 +5006,7 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
      workaround.  */
   globals->fix_erratum_843419 = fix_erratum_843419;
   globals->no_apply_dynamic_relocs = no_apply_dynamic_relocs;
+  globals->c64_rel = 0;
 
   BFD_ASSERT (is_aarch64_elf (output_bfd));
   elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
@@ -5141,7 +5174,6 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
   switch (r_type)
     {
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
-    case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
     case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
@@ -5152,6 +5184,10 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
     case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
       return GOT_NORMAL;
 
+    case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
+    case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
+      return GOT_CAP;
+
     case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
@@ -5964,6 +6000,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
        case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
        case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+       case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
          base_got = globals->root.sgot;
          off = h->got.offset;
 
@@ -5982,13 +6019,13 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
                {
                  plt_index = ((h->plt.offset - globals->plt_header_size) /
                               globals->plt_entry_size);
-                 off = (plt_index + 3) * GOT_ENTRY_SIZE;
+                 off = (plt_index + 3) * GOT_ENTRY_SIZE (globals);
                  base_got = globals->root.sgotplt;
                }
              else
                {
                  plt_index = h->plt.offset / globals->plt_entry_size;
-                 off = plt_index * GOT_ENTRY_SIZE;
+                 off = plt_index * GOT_ENTRY_SIZE (globals);
                  base_got = globals->root.igotplt;
                }
 
@@ -6306,6 +6343,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+    case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
     case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
     case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
@@ -6336,7 +6374,11 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
          /* Record the GOT entry address which will be used when generating
             RELATIVE relocation.  */
          if (relative_reloc)
-           got_entry_addr = value;
+           {
+             got_entry_addr = value;
+             base_got = globals->root.sgot;
+             off = h->got.offset & ~1;
+           }
 
          if (aarch64_relocation_aginst_gp_p (bfd_r_type))
            addend = (globals->root.sgot->output_section->vma
@@ -6344,6 +6386,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
          value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
                                                       place, value,
                                                       addend, weak_undef_p);
+       value |= h->target_internal;
        }
       else
       {
@@ -6392,6 +6435,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
        value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
                                                     place, value,
                                                     addend, weak_undef_p);
+
+       value |= sym->st_target_internal;
       }
 
       if (relative_reloc)
@@ -6399,13 +6444,34 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
          asection *s;
          Elf_Internal_Rela outrel;
 
+         enum elf_aarch64_reloc_type rtype = AARCH64_R (RELATIVE);
+
+         /* For a C64 relative relocation, also add size and permissions into
+            the frag.  */
+         if (bfd_r_type == BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
+             || bfd_r_type == BFD_RELOC_MORELLO_ADR_GOT_PAGE)
+           {
+             bfd_reloc_status_type ret;
+
+             ret = c64_fixup_frag (input_bfd, info, bfd_r_type, sym, h,
+                                   sym_sec, base_got->contents + off + 8,
+                                   orig_value, 0);
+
+             if (ret != bfd_reloc_continue)
+               return ret;
+
+             rtype = MORELLO_R (RELATIVE);
+             outrel.r_addend = 0;
+           }
+         else
+           outrel.r_addend = orig_value;
+
          s = globals->root.srelgot;
          if (s == NULL)
            abort ();
 
          outrel.r_offset = got_entry_addr;
-         outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
-         outrel.r_addend = orig_value;
+         outrel.r_info = ELFNN_R_INFO (0, rtype);
          elf_append_rela (output_bfd, s, &outrel);
        }
       break;
@@ -7347,14 +7413,14 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                         base address when invoke runtime TLS resolver.  */
                      bfd_put_NN (output_bfd, 0,
                                  globals->root.sgot->contents + off
-                                 + GOT_ENTRY_SIZE);
+                                 + GOT_ENTRY_SIZE (globals));
                    }
                  else if (indx == 0)
                    {
                      bfd_put_NN (output_bfd,
                                  relocation - dtpoff_base (info),
                                  globals->root.sgot->contents + off
-                                 + GOT_ENTRY_SIZE);
+                                 + GOT_ENTRY_SIZE (globals));
                    }
                  else
                    {
@@ -7367,7 +7433,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                      rela.r_offset =
                        (globals->root.sgot->output_section->vma
                         + globals->root.sgot->output_offset + off
-                        + GOT_ENTRY_SIZE);
+                        + GOT_ENTRY_SIZE (globals));
 
                      loc = globals->root.srelgot->contents;
                      loc += globals->root.srelgot->reloc_count++
@@ -7375,7 +7441,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                      bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
                      bfd_put_NN (output_bfd, (bfd_vma) 0,
                                  globals->root.sgot->contents + off
-                                 + GOT_ENTRY_SIZE);
+                                 + GOT_ENTRY_SIZE (globals));
                    }
                }
              else
@@ -7385,7 +7451,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                  bfd_put_NN (output_bfd,
                              relocation - dtpoff_base (info),
                              globals->root.sgot->contents + off
-                             + GOT_ENTRY_SIZE);
+                             + GOT_ENTRY_SIZE (globals));
                }
 
              symbol_got_offset_mark (input_bfd, h, r_symndx);
@@ -7500,7 +7566,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                  bfd_put_NN (output_bfd, (bfd_vma) 0,
                              globals->root.sgotplt->contents + off +
                              globals->sgotplt_jump_table_size +
-                             GOT_ENTRY_SIZE);
+                             GOT_ENTRY_SIZE (globals));
                }
 
              symbol_tlsdesc_got_offset_mark (input_bfd, h, r_symndx);
@@ -7928,6 +7994,40 @@ elfNN_aarch64_allocate_local_symbols (bfd *abfd, unsigned number)
   return true;
 }
 
+/* Initialise the .got section to hold the global offset table.  */
+
+static void
+aarch64_elf_init_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  asection *s;
+  struct elf_aarch64_link_hash_table *globals = elf_aarch64_hash_table (info);
+  unsigned int align = bed->s->log_file_align + globals->c64_rel;
+
+  if (globals->root.sgot != NULL)
+    {
+      bfd_set_section_alignment (globals->root.srelgot,
+                                bed->s->log_file_align);
+      bfd_set_section_alignment (globals->root.sgot, align);
+      globals->root.sgot->size += GOT_ENTRY_SIZE (globals);
+    }
+
+  if (globals->root.igotplt != NULL)
+    bfd_set_section_alignment (globals->root.igotplt, align);
+
+  s = globals->root.sgot;
+
+  if (globals->root.sgotplt != NULL)
+    {
+      bfd_set_section_alignment (globals->root.sgotplt, align);
+      s = globals->root.sgotplt;
+    }
+
+  /* The first bit of the global offset table is the header.  */
+  if (s != NULL)
+    s->size += bed->got_header_size (info);
+}
+
 /* Create the .got section to hold the global offset table.  */
 
 static bool
@@ -7950,17 +8050,14 @@ aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
                                           ? ".rela.got" : ".rel.got"),
                                          (bed->dynamic_sec_flags
                                           | SEC_READONLY));
-  if (s == NULL
-      || !bfd_set_section_alignment (s, bed->s->log_file_align))
+  if (s == NULL)
     return false;
   htab->srelgot = s;
 
   s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
-  if (s == NULL
-      || !bfd_set_section_alignment (s, bed->s->log_file_align))
+  if (s == NULL)
     return false;
   htab->sgot = s;
-  htab->sgot->size += GOT_ENTRY_SIZE;
 
   if (bed->want_got_sym)
     {
@@ -7978,15 +8075,11 @@ aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
   if (bed->want_got_plt)
     {
       s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
-      if (s == NULL
-         || !bfd_set_section_alignment (s, bed->s->log_file_align))
+      if (s == NULL)
        return false;
       htab->sgotplt = s;
     }
 
-  /* The first bit of the global offset table is the header.  */
-  s->size += bed->got_header_size (info);
-
   return true;
 }
 
@@ -8113,6 +8206,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
            case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
            case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+           case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
            case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
            case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
            case BFD_RELOC_AARCH64_NN:
@@ -8308,8 +8402,12 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
          /* RR: We probably want to keep a consistency check that
             there are no dangling GOT_PAGE relocs.  */
-       case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
+       case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
+         htab->c64_rel = 1;
+         /* Fall through.  */
+
+       case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
@@ -8374,7 +8472,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
               is a TLS/non-TLS mismatch, based on the symbol type.
               So just combine any TLS types needed.  */
            if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
-               && got_type != GOT_NORMAL)
+               && got_type != GOT_NORMAL && old_got_type != GOT_CAP
+               && got_type != GOT_CAP)
              got_type |= old_got_type;
 
            /* If the symbol is accessed by both IE and GD methods, we
@@ -8384,7 +8483,10 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
              got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
 
-           if (old_got_type != got_type)
+           /* GOT_CAP has higher precedence due to higher alignment and size
+              requirements, so do not overwrite it.  XXX This should be
+              revisited when we add TLS relocations.  */
+           if (old_got_type != got_type && old_got_type != GOT_CAP)
              {
                if (h != NULL)
                  elf_aarch64_hash_entry (h)->got_type = got_type;
@@ -9007,7 +9109,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
          /* We also need to make an entry in the .got.plt section, which
             will be placed in the .got section by the linker script.  */
-         htab->root.sgotplt->size += GOT_ENTRY_SIZE;
+         htab->root.sgotplt->size += GOT_ENTRY_SIZE (htab);
 
          /* We also need to make an entry in the .rela.plt section.  */
          htab->root.srelplt->size += RELOC_SIZE (htab);
@@ -9069,10 +9171,11 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       if (got_type == GOT_UNKNOWN)
        {
        }
-      else if (got_type == GOT_NORMAL)
+      else if (got_type == GOT_NORMAL
+              || got_type == GOT_CAP)
        {
          h->got.offset = htab->root.sgot->size;
-         htab->root.sgot->size += GOT_ENTRY_SIZE;
+         htab->root.sgot->size += GOT_ENTRY_SIZE (htab);
          if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
               || h->root.type != bfd_link_hash_undefweak)
              && (bfd_link_pic (info)
@@ -9092,20 +9195,20 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
              eh->tlsdesc_got_jump_table_offset =
                (htab->root.sgotplt->size
                 - aarch64_compute_jump_table_size (htab));
-             htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
+             htab->root.sgotplt->size += GOT_ENTRY_SIZE (htab) * 2;
              h->got.offset = (bfd_vma) - 2;
            }
 
          if (got_type & GOT_TLS_GD)
            {
              h->got.offset = htab->root.sgot->size;
-             htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
+             htab->root.sgot->size += GOT_ENTRY_SIZE (htab) * 2;
            }
 
          if (got_type & GOT_TLS_IE)
            {
              h->got.offset = htab->root.sgot->size;
-             htab->root.sgot->size += GOT_ENTRY_SIZE;
+             htab->root.sgot->size += GOT_ENTRY_SIZE (htab);
            }
 
          indx = h && h->dynindx != -1 ? h->dynindx : 0;
@@ -9272,7 +9375,7 @@ elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
                                               &h->dyn_relocs,
                                               htab->plt_entry_size,
                                               htab->plt_header_size,
-                                              GOT_ENTRY_SIZE,
+                                              GOT_ENTRY_SIZE (htab),
                                               false);
   return true;
 }
@@ -9300,7 +9403,7 @@ elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
    though !  */
 
 static bool
-elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+elfNN_aarch64_size_dynamic_sections (bfd *output_bfd,
                                     struct bfd_link_info *info)
 {
   struct elf_aarch64_link_hash_table *htab;
@@ -9326,6 +9429,8 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        }
     }
 
+  aarch64_elf_init_got_section (output_bfd, info);
+
   /* Set up .got offsets for local syms, and space for local dynamic
      relocs.  */
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
@@ -9381,21 +9486,22 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                  locals[i].tlsdesc_got_jump_table_offset =
                    (htab->root.sgotplt->size
                     - aarch64_compute_jump_table_size (htab));
-                 htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
+                 htab->root.sgotplt->size += GOT_ENTRY_SIZE (htab) * 2;
                  locals[i].got_offset = (bfd_vma) - 2;
                }
 
              if (got_type & GOT_TLS_GD)
                {
                  locals[i].got_offset = htab->root.sgot->size;
-                 htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
+                 htab->root.sgot->size += GOT_ENTRY_SIZE (htab) * 2;
                }
 
              if (got_type & GOT_TLS_IE
-                 || got_type & GOT_NORMAL)
+                 || got_type & GOT_NORMAL
+                 || got_type & GOT_CAP)
                {
                  locals[i].got_offset = htab->root.sgot->size;
-                 htab->root.sgot->size += GOT_ENTRY_SIZE;
+                 htab->root.sgot->size += GOT_ENTRY_SIZE (htab);
                }
 
              if (got_type == GOT_UNKNOWN)
@@ -9415,7 +9521,8 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                    htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
 
                  if (got_type & GOT_TLS_IE
-                     || got_type & GOT_NORMAL)
+                     || got_type & GOT_NORMAL
+                     || got_type & GOT_CAP)
                    htab->root.srelgot->size += RELOC_SIZE (htab);
                }
            }
@@ -9466,7 +9573,7 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          htab->root.splt->size += htab->tlsdesc_plt_entry_size;
 
          htab->root.tlsdesc_got = htab->root.sgot->size;
-         htab->root.sgot->size += GOT_ENTRY_SIZE;
+         htab->root.sgot->size += GOT_ENTRY_SIZE (htab);
        }
     }
 
@@ -9636,12 +9743,12 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
   if (plt == htab->root.splt)
     {
       plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
-      got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
+      got_offset = (plt_index + 3) * GOT_ENTRY_SIZE (htab);
     }
   else
     {
       plt_index = h->plt.offset / htab->plt_entry_size;
-      got_offset = plt_index * GOT_ENTRY_SIZE;
+      got_offset = plt_index * GOT_ENTRY_SIZE (htab);
     }
 
   plt_entry = plt->contents + h->plt.offset;
@@ -9817,8 +9924,11 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
        }
     }
 
+  bool is_c64 = elf_aarch64_hash_entry (h)->got_type == GOT_CAP;
+
   if (h->got.offset != (bfd_vma) - 1
-      && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL
+      && (elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL
+         || elf_aarch64_hash_entry (h)->got_type == GOT_CAP)
       /* Undefined weak symbol in static PIE resolves to 0 without
         any dynamic relocations.  */
       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
@@ -9868,10 +9978,18 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
            return false;
 
          BFD_ASSERT ((h->got.offset & 1) != 0);
-         rela.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
-         rela.r_addend = (h->root.u.def.value
-                          + h->root.u.def.section->output_section->vma
-                          + h->root.u.def.section->output_offset);
+         if (is_c64)
+           {
+             rela.r_info = ELFNN_R_INFO (0, MORELLO_R (RELATIVE));
+             rela.r_addend = 0;
+           }
+         else
+           {
+             rela.r_info = ELFNN_R_INFO (0, AARCH64_R (RELATIVE));
+             rela.r_addend = (h->root.u.def.value
+                              + h->root.u.def.section->output_section->vma
+                              + h->root.u.def.section->output_offset);
+           }
        }
       else
        {
@@ -9879,7 +9997,9 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
          BFD_ASSERT ((h->got.offset & 1) == 0);
          bfd_put_NN (output_bfd, (bfd_vma) 0,
                      htab->root.sgot->contents + h->got.offset);
-         rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (GLOB_DAT));
+         rela.r_info = ELFNN_R_INFO (h->dynindx,
+                                     (is_c64 ? MORELLO_R (GLOB_DAT)
+                                      : AARCH64_R (GLOB_DAT)));
          rela.r_addend = 0;
        }
 
@@ -9972,7 +10092,7 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma
                  + htab->root.sgotplt->output_offset
-                 + GOT_ENTRY_SIZE * 2);
+                 + GOT_ENTRY_SIZE (htab) * 2);
 
   plt_base = htab->root.splt->output_section->vma +
     htab->root.splt->output_offset;
@@ -10164,10 +10284,11 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
          /* Write GOT[1] and GOT[2], needed for the dynamic linker.  */
          bfd_put_NN (output_bfd,
                      (bfd_vma) 0,
-                     htab->root.sgotplt->contents + GOT_ENTRY_SIZE);
+                     htab->root.sgotplt->contents + GOT_ENTRY_SIZE (htab));
          bfd_put_NN (output_bfd,
                      (bfd_vma) 0,
-                     htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2);
+                     (htab->root.sgotplt->contents
+                      + GOT_ENTRY_SIZE (htab) * 2));
        }
 
       if (htab->root.sgot)
@@ -10181,12 +10302,12 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
        }
 
       elf_section_data (htab->root.sgotplt->output_section)->
-       this_hdr.sh_entsize = GOT_ENTRY_SIZE;
+       this_hdr.sh_entsize = GOT_ENTRY_SIZE (htab);
     }
 
   if (htab->root.sgot && htab->root.sgot->size > 0)
     elf_section_data (htab->root.sgot->output_section)->this_hdr.sh_entsize
-      = GOT_ENTRY_SIZE;
+      = GOT_ENTRY_SIZE (htab);
 
   /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
   htab_traverse (htab->loc_hash_table,
@@ -10411,13 +10532,29 @@ aarch64_elfNN_swap_symbol_out (bfd *abfd,
   bfd_elfNN_swap_symbol_out (abfd, &newsym, cdst, shndx);
 }
 
+/* Define the size of a GOT element for the generic mid-end.  */
+
+static bfd_vma
+elfNN_aarch64_got_elt_size (bfd *abfd ATTRIBUTE_UNUSED,
+                           struct bfd_link_info *info,
+                           struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
+                           bfd *ibfd ATTRIBUTE_UNUSED,
+                           unsigned long symndx ATTRIBUTE_UNUSED)
+{
+  struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
+
+  return GOT_ENTRY_SIZE (htab);
+}
+
 /* Define the size of a GOT header, which is the minimum size of the GOT section
    when one is needed.  */
 
 static bfd_vma
-elfNN_aarch64_got_header_size (struct bfd_link_info *info ATTRIBUTE_UNUSED)
+elfNN_aarch64_got_header_size (struct bfd_link_info *info)
 {
-  return GOT_ENTRY_SIZE * 3;
+  struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
+
+  return GOT_ENTRY_SIZE (htab) * GOT_RESERVED_HEADER_SLOTS;
 }
 
 /* We use this so we can override certain functions
@@ -10572,6 +10709,9 @@ const struct elf_size_info elfNN_aarch64_size_info =
 #define elf_backend_got_header_size            \
   elfNN_aarch64_got_header_size
 
+#define elf_backend_got_elt_size               \
+  elfNN_aarch64_got_elt_size
+
 #define elf_backend_can_refcount       1
 #define elf_backend_can_gc_sections    1
 #define elf_backend_plt_readonly       1
index bc5771b5eaaa13a1899cd9c1464e8b5826b52610..f142a91312343a200cb4017dfe6ab72336a4f300 100644 (file)
@@ -303,6 +303,7 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
     case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
     case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+    case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LDST128_LO12:
     case BFD_RELOC_AARCH64_LDST16_LO12:
     case BFD_RELOC_AARCH64_LDST32_LO12:
@@ -556,6 +557,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd,
     case BFD_RELOC_AARCH64_ADD_LO12:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+    case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LDST128_LO12:
     case BFD_RELOC_AARCH64_LDST16_LO12:
     case BFD_RELOC_AARCH64_LDST32_LO12:
index 435c26ef29f50204cb3874cfa882ae9230bde30b..a70a972c77c2b57216506de3a7afc3bf25b9847a 100644 (file)
@@ -3056,6 +3056,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_ADR_GOT_PAGE",
   "BFD_RELOC_MORELLO_ADR_GOT_PAGE",
   "BFD_RELOC_AARCH64_LD64_GOT_LO12_NC",
+  "BFD_RELOC_MORELLO_LD128_GOT_LO12_NC",
   "BFD_RELOC_AARCH64_LD32_GOT_LO12_NC",
   "BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC",
   "BFD_RELOC_AARCH64_MOVW_GOTOFF_G1",
@@ -3129,6 +3130,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_TLSDESC",
   "BFD_RELOC_AARCH64_IRELATIVE",
   "BFD_RELOC_MORELLO_CAPINIT",
+  "BFD_RELOC_MORELLO_GLOB_DAT",
   "BFD_RELOC_MORELLO_RELATIVE",
   "BFD_RELOC_AARCH64_RELOC_END",
   "BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP",
index 19c4b9666099f1aebc6884bee24b202cc2772d2f..d6983537da6096db5263eaf53a16b215792a23fa 100644 (file)
@@ -7233,6 +7233,12 @@ ENUMDOC
   Unsigned 12 bit byte offset for 64 bit load/store from the page of
   the GOT entry for this symbol.  Used in conjunction with
   BFD_RELOC_AARCH64_ADR_GOT_PAGE.  Valid in LP64 ABI only.
+ENUM
+  BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
+ENUMDOC
+  Unsigned 12 bit byte offset for 128 bit load/store from the page of
+  the GOT entry for this symbol.  Used in conjunction with
+  BFD_RELOC_MORELLO_ADR_GOT_PAGE.  Valid in C64 ABI only.
 ENUM
   BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
 ENUMDOC
@@ -7546,6 +7552,10 @@ ENUM
   BFD_RELOC_MORELLO_CAPINIT
 ENUMDOC
   Morello Capability initialization.
+ENUM
+  BFD_RELOC_MORELLO_GLOB_DAT
+ENUMDOC
+  Morello Capability global data.
 ENUM
   BFD_RELOC_MORELLO_RELATIVE
 ENUMDOC
index af7c54cf45944d8e7d8ba80636c93d388d2a76bc..244cb662ce0950742736b4303aa3f4b8a8890091 100644 (file)
@@ -1,3 +1,11 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * config/tc-aarch64.c (parse_operands): Emit C64 relocations
+       for got_lo12.  Move old relocation checks from...
+       (md_apply_fix): ... here.
+       * testsuite/gas/aarch64/morello-ldst-reloc.d: Add tests.
+       * testsuite/gas/aarch64/morello-ldst-reloc.s: Likewise.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * config/tc-aarch64.c (ldst_lo12_determine_real_reloc_type):
index 88ec2a4c06f88f52c4ba9e900297c8df2e2c92f5..1ac0162d0694fcc87c67656c62a62dd024af082f 100644 (file)
@@ -3213,6 +3213,7 @@ aarch64_force_reloc (unsigned int type)
     case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15:
     case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+    case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LDST128_LO12:
     case BFD_RELOC_AARCH64_LDST16_LO12:
     case BFD_RELOC_AARCH64_LDST32_LO12:
@@ -7586,6 +7587,9 @@ addr_uimm:
 
              inst.reloc.type = ldst_lo12_determine_real_reloc_type ();
            }
+         else if (inst.reloc.type == BFD_RELOC_AARCH64_LD_GOT_LO12_NC
+                  && inst.base.operands[0].qualifier == AARCH64_OPND_QLF_CA)
+           inst.reloc.flags = FIXUP_F_C64;
 
          /* Leave qualifier to be determined by libopcodes.  */
          break;
@@ -9663,9 +9667,12 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
     case BFD_RELOC_AARCH64_LD_GOT_LO12_NC:
       /* Should always be exported to object file, see
         aarch64_force_relocation().  */
-      fixP->fx_r_type = (ilp32_p
-                        ? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
-                        : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
+      if (fixP->tc_fix_data.c64)
+       fixP->fx_r_type = BFD_RELOC_MORELLO_LD128_GOT_LO12_NC;
+      else if (ilp32_p)
+       fixP->fx_r_type = BFD_RELOC_AARCH64_LD32_GOT_LO12_NC;
+      else
+       fixP->fx_r_type = BFD_RELOC_AARCH64_LD64_GOT_LO12_NC;
       gas_assert (!fixP->fx_done);
       gas_assert (seg->use_rela_p);
       break;
@@ -9688,6 +9695,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
     case BFD_RELOC_AARCH64_LDST32_LO12:
     case BFD_RELOC_AARCH64_LDST64_LO12:
     case BFD_RELOC_AARCH64_LDST8_LO12:
+    case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
       /* Should always be exported to object file, see
         aarch64_force_relocation().  */
       gas_assert (!fixP->fx_done);
index 7e4fcf4f07967679f092c18bf1d295aebd08fce2..d2fb08ec9d13c28e6fa70f12c8f49f88fc37f34f 100644 (file)
@@ -19,3 +19,15 @@ Disassembly of section \.text:
 .* <add>:
 .*:    02000000        add     c0, c0, #0x0
                        .*: R_AARCH64_ADD_ABS_LO12_NC   ptr
+
+.* <f1>:
+  .*:  90800002        adrp    c2, 0 <_start>
+                       .*: R_MORELLO_ADR_GOT_PAGE      \.data\+0x10
+  .*:  c2400042        ldr     c2, \[c2\]
+                       .*: R_MORELLO_LD128_GOT_LO12_NC \.data\+0x10
+  .*:  82600042        ldr     c2, \[x2\]
+                       .*: R_MORELLO_LD128_GOT_LO12_NC \.data\+0x20
+  .*:  f9400042        ldr     x2, \[c2\]
+                       .*: R_AARCH64_LD64_GOT_LO12_NC  \.data\+0x20
+  .*:  82600c42        ldr     x2, \[x2\]
+                       .*: R_AARCH64_LD64_GOT_LO12_NC  \.data\+0x20
index 2aa4bbe3ec7eddf5bccc7a3b9b033e26e9d402fc..513c760576aa8d07b5d4162ebad8beb588e9a25c 100644 (file)
@@ -6,6 +6,8 @@ cap:
        .capinit pad
        .8byte 0x0
        .8byte 0x0
+ptr:
+       .8byte pad
 
 .text
 .globl _start
@@ -18,3 +20,10 @@ _start:
 
 add:
        add     c0, c0, :lo12:ptr
+
+f1:
+       adrp    c2, :got:cap
+       ldr     c2, [c2, :got_lo12:cap]
+       ldr     c2, [x2, :got_lo12:ptr]
+       ldr     x2, [c2, :got_lo12:ptr]
+       ldr     x2, [x2, :got_lo12:ptr]
index 407c493925de96cf0cbd43c21d6dc5a7d6493f9e..333d352af3c074ea88885cfdae98c29719eef921 100644 (file)
@@ -1,3 +1,8 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * elf/aarch64.h: New relocations R_MORELLO_LD128_GOT_LO12_NC
+       and R_MORELLO_GLOB_DAT.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * elf/aarch64.h (R_MORELLO_CAPINIT, R_MORELLO_RELATIVE): New
index fd4b7bcce346fa08bc855cc9c46a1333f0a78322..18a497d52b92e55db4451e7a0ee7169acf7028f6 100644 (file)
@@ -458,9 +458,12 @@ RELOC_NUMBER (R_MORELLO_ADR_PREL_PG_HI20_NC, 57350)
 
 RELOC_NUMBER (R_MORELLO_ADR_GOT_PAGE, 57351)
 
+RELOC_NUMBER (R_MORELLO_LD128_GOT_LO12_NC, 57352)
+
 /* Morello dynamic relocations.  */
 
 RELOC_NUMBER (R_MORELLO_CAPINIT, 59392)
+RELOC_NUMBER (R_MORELLO_GLOB_DAT, 59393)
 RELOC_NUMBER (R_MORELLO_RELATIVE, 59395)
 
 END_RELOC_NUMBERS (R_AARCH64_end)
index 0e21377a3ce7227b4f655eea86b5c5040403d1a1..2df4550023775bfa82fbb95d1a31dcefce8195c5 100644 (file)
@@ -1,3 +1,9 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * testsuite/ld-aarch64/emit-relocs-morello-1.d: New file.
+       * testsuite/ld-aarch64/emit-relocs-morello-1.s: New test file.
+       * testsuite/ld-aarch64/aarch64-elf.exp: Add it to test runner.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * testsuite/ld-aarch64/aarch64-elf.exp: Add test.
index 135ea328be35a2689ff5a6b27bd3e1d697053588..5c3eea1ef6dcd87a4fbf70ab62f02282cfdbac82 100644 (file)
@@ -237,6 +237,7 @@ run_dump_test_lp64 "emit-relocs-558"
 run_dump_test_lp64 "emit-relocs-558-overflow"
 run_dump_test_lp64 "emit-relocs-559"
 run_dump_test_lp64 "emit-relocs-560"
+run_dump_test_lp64 "emit-relocs-morello-1"
 
 run_dump_test_lp64 "morello-capinit"
 
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-1.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-1.d
new file mode 100644 (file)
index 0000000..ee27215
--- /dev/null
@@ -0,0 +1,36 @@
+#source: emit-relocs-morello-1.s
+#as: -march=morello+c64
+#ld: -pie -static
+#objdump: -DR -j .got -j .data -j .text
+
+.*:     file format .*
+
+
+Disassembly of section .text:
+
+.* <_start>:
+ .*:   c240.800        ldr     c0, \[c0, #[0-9af]+\]
+
+Disassembly of section .got:
+
+.* <.got>:
+   .*: [0-9a-f]+       .*
+       ...
+   .*: [0-9a-f]+       .*
+                       .*: R_MORELLO_RELATIVE  \*ABS\*
+   .*: 00000000        .*
+   .*: 00000302        .*
+   .*: 00000000        .*
+
+Disassembly of section .data:
+
+.* <val>:
+   .*: 00424242        .*
+       ...
+
+.* <cap>:
+   .*: [0-9a-f]+       .*
+                       .*: R_MORELLO_RELATIVE  \*ABS\*
+   .*: 00000000        .*
+   .*: 00000302        .*
+   .*: 00000000        .*
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-1.s b/ld/testsuite/ld-aarch64/emit-relocs-morello-1.s
new file mode 100644 (file)
index 0000000..eba7bc1
--- /dev/null
@@ -0,0 +1,20 @@
+.data
+.global val
+val:
+       .byte 0x42
+       .byte 0x42
+       .byte 0x42
+       .size val, .-val
+
+.align 4
+.global cap
+cap:
+       .capinit val
+       .8byte 0
+       .8byte 0
+       .size cap, .-cap
+
+.text
+.global _start
+_start:
+       ldr     c0, [c0, :got_lo12:val]