]> 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)
committerLuis Machado <luis.machado@linaro.org>
Tue, 20 Oct 2020 18:04:10 +0000 (15:04 -0300)
- 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 2b03b838951f5d990fd95e0e4d686ffdef88665d..1a7dd20a5c332622c107da254ec44ad381856574 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 ed065af3c7b336272c1adba6a4f0b51f758eaf95..5f44b187d56cadd9c6bde97556d1cfccbdcd2462 100644 (file)
@@ -5702,6 +5702,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.  */
@@ -5942,6 +5947,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 9d53ca71b59d118f7c5609a0a6353bdca948ea27..547b6074d2476e0d73e8c115e466dd99e336d137 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:
@@ -5961,6 +5997,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;
 
@@ -5979,13 +6016,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;
                }
 
@@ -6303,6 +6340,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:
@@ -6333,7 +6371,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
@@ -6341,6 +6383,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
       {
@@ -6389,6 +6432,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)
@@ -6396,13 +6441,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;
@@ -7344,14 +7410,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
                    {
@@ -7364,7 +7430,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++
@@ -7372,7 +7438,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
@@ -7382,7 +7448,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);
@@ -7497,7 +7563,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);
@@ -7925,6 +7991,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 bfd_boolean
@@ -7947,17 +8047,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)
     {
@@ -7975,15 +8072,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;
 }
 
@@ -8110,6 +8203,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:
@@ -8305,8 +8399,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:
@@ -8371,7 +8469,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
@@ -8381,7 +8480,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;
@@ -8913,7 +9015,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);
@@ -8975,10 +9077,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)
@@ -8998,20 +9101,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;
@@ -9178,7 +9281,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;
 }
@@ -9206,7 +9309,7 @@ elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
    though !  */
 
 static bfd_boolean
-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;
@@ -9232,6 +9335,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)
@@ -9287,21 +9392,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)
@@ -9321,7 +9427,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);
                }
            }
@@ -9372,7 +9479,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);
        }
     }
 
@@ -9542,12 +9649,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;
@@ -9723,8 +9830,11 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
        }
     }
 
+  bfd_boolean 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))
@@ -9774,10 +9884,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
        {
@@ -9785,7 +9903,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;
        }
 
@@ -9878,7 +9998,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;
@@ -10070,10 +10190,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)
@@ -10087,12 +10208,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,
@@ -10315,13 +10436,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
@@ -10471,6 +10608,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 6a905b9290091f75355cf98796eba592201e0105..cc58c17419696891ccec8efdc8e97219ee32cd62 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 877a6d677c2bffbbd61c827a74353eded4572c8e..c106292175dd7eff5937d5866615b4f4618eae4e 100644 (file)
@@ -3035,6 +3035,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",
@@ -3108,6 +3109,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 674d6c4e5f070f84c6c42cb1570d55b8920cedc4..a5f64c177ad8e0b21b57bdee134fc8070b00e42a 100644 (file)
@@ -7220,6 +7220,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
@@ -7533,6 +7539,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 86b92bb467af3690a39c2c8a4f5e0b58f5cdc950..d0ae46139ca927cb90714f2fcea9dab242bc840b 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 55e0358bc110bd9a6b6bc3d1e7943d575f5d2a00..715ac2d2e9b50a5a6d50a7778ab88a4a91f0078d 100644 (file)
@@ -6882,6 +6882,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;
@@ -8747,9 +8750,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;
@@ -8772,6 +8778,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);
@@ -8926,6 +8933,7 @@ aarch64_force_relocation (struct fix *fixp)
     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:
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 fe301b86158342dbdfc0c2432d6f6d697cc86e06..d50893b0e2b4a1d64178173ba1837d3b16b3116f 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 cbead77370c4a7d68bbb215b75cb2bedfb084a77..3aa27712aa9e9472d94362f84a1831bacc4a7539 100644 (file)
@@ -455,9 +455,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 803808a88216841119d2f00c174a3467d53bea2e..b952f416e0c6fa1f2f473f2c78ba35e8888cc023 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 bd2590a721c932803b55a57ec3810189c7704e0f..ac0a998df90b0e3b381c209c52614bba7727d585 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]