]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] Add Morello relocations for ADRP
authorSiddhesh Poyarekar <siddesh.poyarekar@arm.com>
Fri, 11 Sep 2020 03:48:09 +0000 (09:18 +0530)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 22:53:21 +0000 (15:53 -0700)
New relocations R_MORELLO_ADR_PREL_PG_HI20,
R_MORELLO_ADR_PREL_PG_HI20_NC and R_MORELLO_ADR_GOT_PAGE

bfd/ChangeLog:

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

* reloc.c: Add MORELLO_ADR_HI20_PCREL,
MORELLO_ADR_HI20_NC_PCREL and MORELLO_ADR_GOT_PAGE.
* elfnn-aarch64.c (elfNN_aarch64_howto_table): Likewise.
(aarch64_reloc_got_type): Add MORELLO_ADR_GOT_PAGE.
(_bfd_aarch64_erratum_843419_branch_to_stub): Add C64 argument
to _bfd_aarch64_reencode_adr_imm.
(elfNN_aarch64_final_link_relocate,
elfNN_aarch64_check_relocs): Add MORELLO_ADR_GOT_PAGE,
MORELLO_ADR_HI20_PCREL and MORELLO_ADR_HI20_NC_PCREL.
* elfxx-aarch64.c (_bfd_aarch64_reencode_adr_imm): Add C64
argument.
(_bfd_aarch64_elf_put_addend): Adjust callers.
* elfxx-aarch64.h (_bfd_aarch64_reencode_adr_imm): Add C64
argument.
* libbfd.h (bfd_reloc_code_real_names): Add
MORELLO_ADR_GOT_PAGE, MORELLO_ADR_HI20_PCREL and
MORELLO_ADR_HI20_NC_PCREL.
* bfd-in2.h: Regenerate.

gas/ChangeLog:

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

* config/tc-aarch64.c (reloc_table_entry): Add c64_adrp_type
field.
(reloc_table): Adjust.
(parse_adrp): Adjust users.
(md_apply_fix): Add MORELLO_ADR_GOT_PAGE,
MORELLO_ADR_HI20_PCREL and MORELLO_ADR_HI20_NC_PCREL.
* testsuite/gas/aarch64/morello_insn-c64.d: Adjust test.

include/ChangeLog:

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

* elf/aarch64.h: Add R_MORELLO_ADR_PREL_PG_HI20,
R_MORELLO_ADR_PREL_PG_HI20_NC and R_MORELLO_ADR_GOT_PAGE.

12 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elfnn-aarch64.c
bfd/elfxx-aarch64.c
bfd/elfxx-aarch64.h
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-aarch64.c
gas/testsuite/gas/aarch64/morello_insn-c64.d
include/ChangeLog
include/elf/aarch64.h

index 3c21dd46f348ff6fc9647cb59ce6e424871a7a02..43dcff00e01a594000c8b26130c69394582f2901 100644 (file)
@@ -1,3 +1,24 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * reloc.c: Add MORELLO_ADR_HI20_PCREL,
+       MORELLO_ADR_HI20_NC_PCREL and MORELLO_ADR_GOT_PAGE.
+       * elfnn-aarch64.c (elfNN_aarch64_howto_table): Likewise.
+       (aarch64_reloc_got_type): Add MORELLO_ADR_GOT_PAGE.
+       (_bfd_aarch64_erratum_843419_branch_to_stub): Add C64 argument
+       to _bfd_aarch64_reencode_adr_imm.
+       (elfNN_aarch64_final_link_relocate,
+       elfNN_aarch64_check_relocs): Add MORELLO_ADR_GOT_PAGE,
+       MORELLO_ADR_HI20_PCREL and MORELLO_ADR_HI20_NC_PCREL.
+       * elfxx-aarch64.c (_bfd_aarch64_reencode_adr_imm): Add C64
+       argument.
+       (_bfd_aarch64_elf_put_addend): Adjust callers.
+       * elfxx-aarch64.h (_bfd_aarch64_reencode_adr_imm): Add C64
+       argument.
+       * libbfd.h (bfd_reloc_code_real_names): Add
+       MORELLO_ADR_GOT_PAGE, MORELLO_ADR_HI20_PCREL and
+       MORELLO_ADR_HI20_NC_PCREL.
+       * bfd-in2.h: Regenerate.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * elfnn-aarch64.c (elfNN_aarch64_howto_table): Add
index 812bd07f0acaee37434984fc2996a7bf50485dab..5ef08cfa0792b629207f9bdcfd5612190a25bf1c 100644 (file)
@@ -5625,6 +5625,15 @@ offset.  The lowest two bits must be zero and are not stored in the
 instruction, giving a 21 bit signed byte offset.  */
   BFD_RELOC_AARCH64_LD_LO19_PCREL,
 
+/* Morello ADRP instruction, with bits 12 to 31 of a pc-relative page
+offset, giving a 4KB aligned page base address.  */
+  BFD_RELOC_MORELLO_ADR_HI20_PCREL,
+
+/* Morello ADRP instruction, with bits 12 to 31 of a pc-relative page
+offset, giving a 4KB aligned page base address, but with no overflow
+checking.  */
+  BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL,
+
 /* AArch64 ADR instruction, holding a simple 21 bit pc-relative byte offset.  */
   BFD_RELOC_AARCH64_ADR_LO21_PCREL,
 
@@ -5693,6 +5702,11 @@ part of an ADRP instruction using a 21 bit PC relative value.Used in
 conjunction with BFD_RELOC_AARCH64_LD64_GOT_LO12_NC.  */
   BFD_RELOC_AARCH64_ADR_GOT_PAGE,
 
+/* Get to the page base of the global offset table entry for a symbol as
+part of an ADRP instruction using a 20 bit PC relative value.Used in
+conjunction with BFD_RELOC_MORELLO_LD128_GOT_LO12_NC.  */
+  BFD_RELOC_MORELLO_ADR_GOT_PAGE,
+
 /* 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.  */
index 52b80334079cd4b397b359c6ea12ad048dfb479c..9e195ffb3236576dc1f7c737cabd61ca6a2507b1 100644 (file)
@@ -858,6 +858,36 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0x7ffff,               /* dst_mask */
         true),                 /* pcrel_offset */
 
+  /* C64 ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0xfffff */
+  HOWTO64 (MORELLO_R (ADR_PREL_PG_HI20),       /* type */
+        12,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        20,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed,      /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (ADR_PREL_PG_HI20),      /* name */
+        false,                 /* partial_inplace */
+        0xfffff,               /* src_mask */
+        0xfffff,               /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* C64 ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0xfffff [no overflow check] */
+  HOWTO64 (MORELLO_R (ADR_PREL_PG_HI20_NC),    /* type */
+        12,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        20,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (ADR_PREL_PG_HI20_NC),   /* name */
+        false,                 /* partial_inplace */
+        0xfffff,               /* src_mask */
+        0xfffff,               /* dst_mask */
+        true),                 /* pcrel_offset */
+
   /* ADR:    (S+A-P) & 0x1fffff */
   HOWTO (AARCH64_R (ADR_PREL_LO21),    /* type */
         0,                     /* rightshift */
@@ -1087,6 +1117,22 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0x1fffff,              /* dst_mask */
         true),                 /* pcrel_offset */
 
+  /* Get to the page for the GOT entry for the symbol
+     (G(S) - P) using a C64 ADRP instruction.  */
+  HOWTO64 (MORELLO_R (ADR_GOT_PAGE),   /* type */
+        12,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        20,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (ADR_GOT_PAGE),  /* name */
+        false,                 /* partial_inplace */
+        0xfffff,               /* src_mask */
+        0xfffff,               /* dst_mask */
+        true),                 /* pcrel_offset */
+
   /* LD64: GOT offset G(S) & 0xff8  */
   HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC),       /* type */
         3,                     /* rightshift */
@@ -5064,6 +5110,7 @@ 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:
@@ -5394,7 +5441,7 @@ _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry *gen_entry,
   if ((htab->fix_erratum_843419 & ERRAT_ADR)
       && (imm >= AARCH64_MIN_ADRP_IMM  && imm <= AARCH64_MAX_ADRP_IMM))
     {
-      insn = (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP, imm)
+      insn = (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP, imm, 0)
              | AARCH64_RT (insn));
       bfd_putl32 (insn, contents + stub_entry->adrp_offset);
       /* Stub is not needed, don't map it out.  */
@@ -5694,6 +5741,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
          return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
                                              howto, value);
        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:
@@ -5771,6 +5819,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
          return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
        case BFD_RELOC_AARCH64_ADD_LO12:
        case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+       case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
          break;
        }
     }
@@ -5955,6 +6004,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_64_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+    case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL:
+    case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
     case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
     case BFD_RELOC_AARCH64_LD_LO19_PCREL:
     case BFD_RELOC_MORELLO_LD_LO17_PCREL:
@@ -6035,6 +6086,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
       break;
 
     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:
@@ -7778,7 +7830,9 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
            case BFD_RELOC_AARCH64_ADD_LO12:
            case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+           case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
            case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+           case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
            case BFD_RELOC_AARCH64_CALL26:
            case BFD_RELOC_AARCH64_GOT_LD_PREL19:
            case BFD_RELOC_AARCH64_JUMP26:
@@ -7856,6 +7910,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case BFD_RELOC_AARCH64_ADD_LO12:
        case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
        case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+       case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL:
+       case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
        case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
        case BFD_RELOC_AARCH64_LDST128_LO12:
        case BFD_RELOC_AARCH64_LDST16_LO12:
@@ -7981,6 +8037,7 @@ 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_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
index 3e57a97683dada5772df8ad479bc4e4be728e7e1..0b60ea1b4d15dc9c9b77c67a063abed094b2ab3e 100644 (file)
@@ -57,10 +57,10 @@ reencode_add_imm (uint32_t insn, uint32_t imm)
 /* Reencode the IMM field of ADR.  */
 
 uint32_t
-_bfd_aarch64_reencode_adr_imm (uint32_t insn, uint32_t imm)
+_bfd_aarch64_reencode_adr_imm (uint32_t insn, uint32_t imm, uint32_t c64)
 {
-  return (insn & ~((MASK (2) << 29) | (MASK (19) << 5)))
-    | ((imm & MASK (2)) << 29) | ((imm & (MASK (19) << 2)) << 3);
+  return (insn & ~((MASK (2) << 29) | (MASK (19 - c64) << 5)))
+    | ((imm & MASK (2)) << 29) | ((imm & (MASK (19 - c64) << 2)) << 3);
 }
 
 /* Reencode the imm field of ld/st pos immediate.  */
@@ -247,6 +247,12 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
       break;
 
+    case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
+    case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL:
+    case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
+      contents = _bfd_aarch64_reencode_adr_imm (contents, addend, 1);
+      break;
+
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
@@ -258,7 +264,7 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
     case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
-      contents = _bfd_aarch64_reencode_adr_imm (contents, addend);
+      contents = _bfd_aarch64_reencode_adr_imm (contents, addend, 0);
       break;
 
     case BFD_RELOC_AARCH64_ADD_LO12:
@@ -496,6 +502,8 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd,
       value = value + addend;
       break;
 
+    case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL:
+    case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
       if (weak_undef_p)
@@ -507,6 +515,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd,
       value = value + addend - place;
       break;
 
+    case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
index a2c8b3e54f5b2aa3f9bfbe395b26bd827a9f5aa0..1026b8fcc233c7de7b96efe2a138f9296104d91e 100644 (file)
@@ -111,7 +111,7 @@ extern uint32_t
 _bfd_aarch64_decode_adrp_imm (uint32_t);
 
 extern uint32_t
-_bfd_aarch64_reencode_adr_imm (uint32_t, uint32_t);
+_bfd_aarch64_reencode_adr_imm (uint32_t, uint32_t, uint32_t);
 
 extern bfd_reloc_status_type
 _bfd_aarch64_elf_put_addend (bfd *, bfd_byte *, bfd_reloc_code_real_type,
index a6adcad23b1d82438952e70191af76776867b7be..4b1282d78db336181972827ca363fe37cf35cefc 100644 (file)
@@ -3037,6 +3037,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_MOVW_PREL_G3",
   "BFD_RELOC_MORELLO_LD_LO17_PCREL",
   "BFD_RELOC_AARCH64_LD_LO19_PCREL",
+  "BFD_RELOC_MORELLO_ADR_HI20_PCREL",
+  "BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL",
   "BFD_RELOC_AARCH64_ADR_LO21_PCREL",
   "BFD_RELOC_AARCH64_ADR_HI21_PCREL",
   "BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL",
@@ -3052,6 +3054,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_LDST128_LO12",
   "BFD_RELOC_AARCH64_GOT_LD_PREL19",
   "BFD_RELOC_AARCH64_ADR_GOT_PAGE",
+  "BFD_RELOC_MORELLO_ADR_GOT_PAGE",
   "BFD_RELOC_AARCH64_LD64_GOT_LO12_NC",
   "BFD_RELOC_AARCH64_LD32_GOT_LO12_NC",
   "BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC",
index f2a9f0d436e482342590c67def969a333fb6713f..221c446afc007ab1f26fc2bc4eb0a5e041f6bfef 100644 (file)
@@ -7127,6 +7127,17 @@ ENUMDOC
   AArch64 Load Literal instruction, holding a 19 bit pc-relative word
   offset.  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_ADR_HI20_PCREL
+ENUMDOC
+  Morello ADRP instruction, with bits 12 to 31 of a pc-relative page
+  offset, giving a 4KB aligned page base address.
+ENUM
+  BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL
+ENUMDOC
+  Morello ADRP instruction, with bits 12 to 31 of a pc-relative page
+  offset, giving a 4KB aligned page base address, but with no overflow
+  checking.
 ENUM
   BFD_RELOC_AARCH64_ADR_LO21_PCREL
 ENUMDOC
@@ -7210,6 +7221,12 @@ ENUMDOC
   Get to the page base of the global offset table entry for a symbol as
   part of an ADRP instruction using a 21 bit PC relative value.Used in
   conjunction with BFD_RELOC_AARCH64_LD64_GOT_LO12_NC.
+ENUM
+  BFD_RELOC_MORELLO_ADR_GOT_PAGE
+ENUMDOC
+  Get to the page base of the global offset table entry for a symbol as
+  part of an ADRP instruction using a 20 bit PC relative value.Used in
+  conjunction with BFD_RELOC_MORELLO_LD128_GOT_LO12_NC.
 ENUM
   BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
 ENUMDOC
index b0b480cef3a5dfea513b9d13570f6c247554523c..0313285c40ab69ec5d93dd486bb6ad857696172f 100644 (file)
@@ -1,3 +1,13 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * config/tc-aarch64.c (reloc_table_entry): Add c64_adrp_type
+       field.
+       (reloc_table): Adjust.
+       (parse_adrp): Adjust users.
+       (md_apply_fix): Add MORELLO_ADR_GOT_PAGE,
+       MORELLO_ADR_HI20_PCREL and MORELLO_ADR_HI20_NC_PCREL.
+       * testsuite/gas/aarch64/morello_insn-c64.d: Adjust test.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * config/tc-aarch64.c (process_omitted_operand,
index 8d0f9c6d7b02b94c5987dead20a7b40e7d8d284c..dc8aba1271f5470bd63f1adfa04cef806f401c15 100644 (file)
@@ -2539,6 +2539,7 @@ struct reloc_table_entry
   int pc_rel;
   bfd_reloc_code_real_type adr_type;
   bfd_reloc_code_real_type adrp_type;
+  bfd_reloc_code_real_type c64_adrp_type;
   bfd_reloc_code_real_type movw_type;
   bfd_reloc_code_real_type add_type;
   bfd_reloc_code_real_type ldst_type;
@@ -2552,6 +2553,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_ADD_LO12,
    BFD_RELOC_AARCH64_LDST_LO12,
    0},
@@ -2560,15 +2562,18 @@ static struct reloc_table_entry reloc_table[] =
   {"pg_hi21", 1,
    0,                          /* adr_type */
    BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+   BFD_RELOC_MORELLO_ADR_HI20_PCREL,
    0,
    0,
    0,
    0},
 
-  /* Higher 21 bits of pc-relative page offset: ADRP, no check */
+  /* Higher 21 bits (20 bits for C64) of pc-relative page offset: ADRP, no
+     check */
   {"pg_hi21_nc", 1,
    0,                          /* adr_type */
    BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL,
+   BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL,
    0,
    0,
    0,
@@ -2578,6 +2583,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g0", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G0,
    0,
    0,
@@ -2587,6 +2593,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g0_s", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G0_S,
    0,
    0,
@@ -2596,6 +2603,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g0_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G0_NC,
    0,
    0,
@@ -2605,6 +2613,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g1", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G1,
    0,
    0,
@@ -2614,6 +2623,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g1_s", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G1_S,
    0,
    0,
@@ -2623,6 +2633,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g1_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G1_NC,
    0,
    0,
@@ -2632,6 +2643,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g2", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G2,
    0,
    0,
@@ -2641,6 +2653,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g2_s", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G2_S,
    0,
    0,
@@ -2650,6 +2663,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g2_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G2_NC,
    0,
    0,
@@ -2659,6 +2673,7 @@ static struct reloc_table_entry reloc_table[] =
   {"abs_g3", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_G3,
    0,
    0,
@@ -2668,6 +2683,7 @@ static struct reloc_table_entry reloc_table[] =
   {"prel_g0", 1,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_PREL_G0,
    0,
    0,
@@ -2677,6 +2693,7 @@ static struct reloc_table_entry reloc_table[] =
   {"prel_g0_nc", 1,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_PREL_G0_NC,
    0,
    0,
@@ -2686,6 +2703,7 @@ static struct reloc_table_entry reloc_table[] =
   {"prel_g1", 1,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_PREL_G1,
    0,
    0,
@@ -2695,6 +2713,7 @@ static struct reloc_table_entry reloc_table[] =
   {"prel_g1_nc", 1,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_PREL_G1_NC,
    0,
    0,
@@ -2704,6 +2723,7 @@ static struct reloc_table_entry reloc_table[] =
   {"prel_g2", 1,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_PREL_G2,
    0,
    0,
@@ -2713,6 +2733,7 @@ static struct reloc_table_entry reloc_table[] =
   {"prel_g2_nc", 1,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_PREL_G2_NC,
    0,
    0,
@@ -2722,6 +2743,7 @@ static struct reloc_table_entry reloc_table[] =
   {"prel_g3", 1,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_PREL_G3,
    0,
    0,
@@ -2731,6 +2753,7 @@ static struct reloc_table_entry reloc_table[] =
   {"got", 1,
    0,                          /* adr_type */
    BFD_RELOC_AARCH64_ADR_GOT_PAGE,
+   BFD_RELOC_MORELLO_ADR_GOT_PAGE,
    0,
    0,
    0,
@@ -2742,6 +2765,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_LD_GOT_LO12_NC,
    0},
 
@@ -2749,6 +2773,7 @@ static struct reloc_table_entry reloc_table[] =
   {"gotoff_g0_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC,
    0,
    0,
@@ -2758,6 +2783,7 @@ static struct reloc_table_entry reloc_table[] =
   {"gotoff_g1", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_MOVW_GOTOFF_G1,
    0,
    0,
@@ -2769,6 +2795,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_LD64_GOTOFF_LO15,
    0},
 
@@ -2776,6 +2803,7 @@ static struct reloc_table_entry reloc_table[] =
   {"gottprel_g0_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC,
    0,
    0,
@@ -2785,6 +2813,7 @@ static struct reloc_table_entry reloc_table[] =
   {"gottprel_g1", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1,
    0,
    0,
@@ -2797,6 +2826,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    0},
 
   /* 12 bit offset into the page containing GOT TLS entry for a symbol */
@@ -2804,6 +2834,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC,
    0,
    0},
@@ -2812,6 +2843,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tlsgd_g0_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC,
    0,
    0,
@@ -2821,6 +2853,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tlsgd_g1", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSGD_MOVW_G1,
    0,
    0,
@@ -2833,6 +2866,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSDESC_LD_PREL19},
 
   /* 12 bit offset into the page containing GOT TLS entry for a symbol */
@@ -2840,6 +2874,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSDESC_ADD_LO12,
    BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC,
    0},
@@ -2855,6 +2890,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    0},
 
   /* 12 bit offset into the page containing GOT TLS entry for a symbol */
@@ -2862,6 +2898,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC,
    0,
    0},
@@ -2871,6 +2908,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12,
    BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12,
    0},
@@ -2880,6 +2918,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC,
    BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC,
    0},
@@ -2889,6 +2928,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12,
    0,
    0},
@@ -2897,6 +2937,7 @@ static struct reloc_table_entry reloc_table[] =
   {"dtprel_g0", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0,
    0,
    0,
@@ -2906,6 +2947,7 @@ static struct reloc_table_entry reloc_table[] =
   {"dtprel_g0_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC,
    0,
    0,
@@ -2915,6 +2957,7 @@ static struct reloc_table_entry reloc_table[] =
   {"dtprel_g1", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1,
    0,
    0,
@@ -2924,6 +2967,7 @@ static struct reloc_table_entry reloc_table[] =
   {"dtprel_g1_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC,
    0,
    0,
@@ -2933,6 +2977,7 @@ static struct reloc_table_entry reloc_table[] =
   {"dtprel_g2", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2,
    0,
    0,
@@ -2942,6 +2987,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tlsdesc_off_g0_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC,
    0,
    0,
@@ -2951,6 +2997,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tlsdesc_off_g1", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSDESC_OFF_G1,
    0,
    0,
@@ -2963,6 +3010,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19},
 
   /* 12 bit offset into the page containing GOT TLS entry for a symbol */
@@ -2971,6 +3019,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC,
    0},
 
@@ -2979,6 +3028,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12,
    0,
    0},
@@ -2988,6 +3038,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12,
    BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12,
    0},
@@ -2997,6 +3048,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12,
    0,
    0},
@@ -3006,6 +3058,7 @@ static struct reloc_table_entry reloc_table[] =
    0,                          /* adr_type */
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC,
    BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC,
    0},
@@ -3014,6 +3067,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tprel_g2", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2,
    0,
    0,
@@ -3023,6 +3077,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tprel_g1", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1,
    0,
    0,
@@ -3032,6 +3087,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tprel_g1_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC,
    0,
    0,
@@ -3041,6 +3097,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tprel_g0", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0,
    0,
    0,
@@ -3050,6 +3107,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tprel_g0_nc", 0,
    0,                          /* adr_type */
    0,
+   0,
    BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC,
    0,
    0,
@@ -3061,6 +3119,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15,
    0},
 
@@ -3070,6 +3129,7 @@ static struct reloc_table_entry reloc_table[] =
    0,
    0,
    0,
+   0,
    BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14,
    0},
 };
@@ -3122,6 +3182,9 @@ aarch64_force_reloc (unsigned int type)
 
     case BFD_RELOC_AARCH64_ADD_LO12:
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+    case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
+    case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL:
+    case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
@@ -4083,6 +4146,7 @@ parse_adrp (char **str)
   if (*p == ':')
     {
       struct reloc_table_entry *entry;
+      bfd_reloc_code_real_type adrp_type;
 
       /* Try to parse a relocation.  Anything else is an error.  */
       ++p;
@@ -4092,17 +4156,23 @@ parse_adrp (char **str)
          return false;
        }
 
-      if (entry->adrp_type == 0)
+      adrp_type = (AARCH64_CPU_HAS_FEATURE (cpu_variant, AARCH64_FEATURE_C64)
+                  ? entry->c64_adrp_type : entry->adrp_type);
+
+      if (adrp_type == 0)
        {
          set_syntax_error
            (_("this relocation modifier is not allowed on this instruction"));
          return false;
        }
 
-      inst.reloc.type = entry->adrp_type;
+      inst.reloc.type = adrp_type;
     }
   else
-    inst.reloc.type = BFD_RELOC_AARCH64_ADR_HI21_PCREL;
+    inst.reloc.type = (AARCH64_CPU_HAS_FEATURE (cpu_variant,
+                                               AARCH64_FEATURE_C64)
+                      ? BFD_RELOC_MORELLO_ADR_HI20_PCREL
+                      : BFD_RELOC_AARCH64_ADR_HI21_PCREL);
 
   inst.reloc.pc_rel = 1;
   if (! aarch64_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, REJECT_ABSENT,
@@ -9575,6 +9645,9 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
 
     case BFD_RELOC_AARCH64_ADD_LO12:
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+    case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
+    case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL:
+    case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
     case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
index 02884ac5988dd084304a57d241a6ba8fd2f7c4ee..a73ad9cf18450a2c1ed3e6e3f7a9e977e15e41ef 100644 (file)
@@ -76,7 +76,7 @@ Disassembly of section \.text:
 .* <Label>:
 .*:    10000000        adr     c0, .* <Label>
 .*:    90800000        adrp    c0, .* <.*>
-                       .*: R_AARCH64_ADR_PREL_PG_HI21  .*
+                       .*: R_MORELLO_ADR_PREL_PG_HI20  .*
 .*:    b0000000        adrdp   c0, #0x1000
 .*:    023fc135        add     c21, c9, #0xff0
 .*:    023ffd35        add     c21, c9, #0xfff
index 50faf73b11a8de31b3af477710f33f02416d3735..f87591b1d0a4ccb9802c36d953db29dd5bbbe158 100644 (file)
@@ -1,3 +1,8 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * elf/aarch64.h: Add R_MORELLO_ADR_PREL_PG_HI20,
+       R_MORELLO_ADR_PREL_PG_HI20_NC and R_MORELLO_ADR_GOT_PAGE.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * opcode/aarch64.h (aarch64_opnd): New operand Cat_SYS.
index b29a1c8161d13edbf74b4cd004cd1d0f5395d238..57d92b56995bc8644dc819683fa6adab1db769dd 100644 (file)
@@ -450,6 +450,14 @@ RELOC_NUMBER (R_AARCH64_IRELATIVE, 1032)
 /* A64C LD-lit: ((S+A-P) >> 4) & 0x1ffff */
 RELOC_NUMBER (R_MORELLO_LD_PREL_LO17, 57348)
 
+/* ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0xfffff */
+RELOC_NUMBER (R_MORELLO_ADR_PREL_PG_HI20, 57349)
+
+/* ADRP:   ((PG(S+A)-PG(P)) >> 12) & 0xfffff */
+RELOC_NUMBER (R_MORELLO_ADR_PREL_PG_HI20_NC, 57350)
+
+RELOC_NUMBER (R_MORELLO_ADR_GOT_PAGE, 57351)
+
 END_RELOC_NUMBERS (R_AARCH64_end)
 
 enum aarch64_st_branch_type