aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Harmstone <mark@harmstone.com>2022-12-14 00:54:34 +0000
committerMark Harmstone <mark@harmstone.com>2023-01-10 23:30:44 +0000
commitb152649d51b52e4e82176fb835b8b91a9ca08ad4 (patch)
tree635d2ed5c44c70a897110aa4855a5dcf10ed1f63
parent5093b5a5e7e3e51116207eb2dec81846140fc604 (diff)
downloadgdb-b152649d51b52e4e82176fb835b8b91a9ca08ad4.zip
gdb-b152649d51b52e4e82176fb835b8b91a9ca08ad4.tar.gz
gdb-b152649d51b52e4e82176fb835b8b91a9ca08ad4.tar.bz2
Add pe-aarch64 relocations
This adds the remaining pe-aarch64 relocations, and gets them working. It also brings in the constant directives from ELF, as otherwise .word would be 2 rather than 4 bytes, and .xword and .dword wouldn't be defined.
-rw-r--r--bfd/coff-aarch64.c674
-rw-r--r--bfd/config.bfd6
-rw-r--r--gas/config/tc-aarch64.c24
-rw-r--r--gas/testsuite/gas/pe/pe-aarch64.d230
-rw-r--r--gas/testsuite/gas/pe/pe-aarch64.s162
-rw-r--r--ld/testsuite/ld-pe/aarch64.d158
-rw-r--r--ld/testsuite/ld-pe/aarch64a.s159
-rw-r--r--ld/testsuite/ld-pe/aarch64b.s8
-rw-r--r--ld/testsuite/ld-pe/pe.exp10
9 files changed, 1388 insertions, 43 deletions
diff --git a/bfd/coff-aarch64.c b/bfd/coff-aarch64.c
index 236cbb7..d6c48eb 100644
--- a/bfd/coff-aarch64.c
+++ b/bfd/coff-aarch64.c
@@ -39,59 +39,310 @@
#include "libcoff.h"
+static bfd_reloc_status_type
+coff_aarch64_addr64_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint64_t val = reloc_entry->addend;
+
+ bfd_putl64 (val, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+coff_aarch64_addr32_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint64_t val;
+
+ if ((int64_t) reloc_entry->addend > 0x7fffffff
+ || (int64_t) reloc_entry->addend < -0x7fffffff)
+ return bfd_reloc_overflow;
+
+ val = reloc_entry->addend;
+
+ bfd_putl32 ((uint32_t) val, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+coff_aarch64_branch26_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint32_t op;
+ int32_t param;
+
+ op = bfd_getl32 (data + reloc_entry->address);
+ param = reloc_entry->addend;
+
+ if (param > 0x7ffffff || param < -0x8000000)
+ return bfd_reloc_overflow;
+
+ op &= 0xfc000000;
+ op |= (param >> 2) & 0x3ffffff;
+
+ bfd_putl32 (op, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+coff_aarch64_rel21_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint32_t op;
+ int32_t param;
+
+ op = bfd_getl32 (data + reloc_entry->address);
+ param = reloc_entry->addend;
+
+ if (param > 0xfffff || param < -0x100000)
+ return bfd_reloc_overflow;
+
+ op &= 0x9f00001f;
+ op |= (param & 0x1ffffc) << 3;
+ op |= (param & 0x3) << 29;
+
+ bfd_putl32 (op, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+coff_aarch64_po12l_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint32_t op;
+ int32_t param;
+ uint8_t shift;
+
+ op = bfd_getl32 (data + reloc_entry->address);
+ param = reloc_entry->addend & 0xfff;
+
+ if ((op & 0xff800000) == 0x3d800000)
+ {
+ /* LDR / STR with q register */
+ shift = 4;
+ }
+ else
+ {
+ /* top two bits represent how much addend should be shifted */
+ shift = op >> 30;
+ }
+
+ if (param & ((1 << shift) - 1))
+ return bfd_reloc_overflow;
+
+ param >>= shift;
+
+ op &= 0xffc003ff;
+ op |= param << 10;
+
+ bfd_putl32 (op, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+coff_aarch64_branch19_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint32_t op;
+ int32_t param;
+
+ op = bfd_getl32 (data + reloc_entry->address);
+ param = reloc_entry->addend;
+
+ if (param > 0xfffff || param < -0x100000)
+ return bfd_reloc_overflow;
+
+ op &= 0xff00001f;
+ op |= ((param >> 2) & 0x7ffff) << 5;
+
+ bfd_putl32 (op, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+coff_aarch64_branch14_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint32_t op;
+ int32_t param;
+
+ op = bfd_getl32 (data + reloc_entry->address);
+ param = reloc_entry->addend;
+
+ if (param > 0x7fff || param < -0x8000)
+ return bfd_reloc_overflow;
+
+ op &= 0xfff8001f;
+ op |= ((param >> 2) & 0x3fff) << 5;
+
+ bfd_putl32 (op, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+coff_aarch64_po12a_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint32_t op;
+ int32_t param;
+
+ op = bfd_getl32 (data + reloc_entry->address);
+ param = reloc_entry->addend;
+
+ op &= 0xffc003ff;
+ op |= (param & 0xfff) << 10;
+
+ bfd_putl32 (op, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+coff_aarch64_addr32nb_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ uint64_t val;
+
+ if ((int64_t) reloc_entry->addend > 0x7fffffff
+ || (int64_t) reloc_entry->addend < -0x7fffffff)
+ return bfd_reloc_overflow;
+
+ val = reloc_entry->addend;
+
+ bfd_putl32 ((uint32_t) val, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
#define MINUS_ONE (~ (bfd_vma) 0)
+static const reloc_howto_type arm64_reloc_howto_abs = HOWTO(IMAGE_REL_ARM64_ABSOLUTE, 0, 1, 0, false, 0,
+ complain_overflow_dont,
+ NULL, "IMAGE_REL_ARM64_ABSOLUTE",
+ false, 0, 0, false);
+
static const reloc_howto_type arm64_reloc_howto_64 = HOWTO(IMAGE_REL_ARM64_ADDR64, 0, 8, 64, false, 0,
complain_overflow_bitfield,
- NULL, "64",
+ coff_aarch64_addr64_reloc, "IMAGE_REL_ARM64_ADDR64",
false, MINUS_ONE, MINUS_ONE, false);
static const reloc_howto_type arm64_reloc_howto_32 = HOWTO (IMAGE_REL_ARM64_ADDR32, 0, 4, 32, false, 0,
complain_overflow_bitfield,
- NULL, "32",
+ coff_aarch64_addr32_reloc, "IMAGE_REL_ARM64_ADDR32",
false, 0xffffffff, 0xffffffff, false);
static const reloc_howto_type arm64_reloc_howto_32_pcrel = HOWTO (IMAGE_REL_ARM64_REL32, 0, 4, 32, true, 0,
complain_overflow_bitfield,
- NULL, "DISP32",
+ NULL, "IMAGE_REL_ARM64_REL32",
false, 0xffffffff, 0xffffffff, true);
static const reloc_howto_type arm64_reloc_howto_branch26 = HOWTO (IMAGE_REL_ARM64_BRANCH26, 0, 4, 26, true, 0,
complain_overflow_bitfield,
- NULL, "BRANCH26",
+ coff_aarch64_branch26_reloc, "IMAGE_REL_ARM64_BRANCH26",
false, 0x03ffffff, 0x03ffffff, true);
static const reloc_howto_type arm64_reloc_howto_page21 = HOWTO (IMAGE_REL_ARM64_PAGEBASE_REL21, 12, 4, 21, true, 0,
complain_overflow_signed,
- NULL, "PAGE21",
+ coff_aarch64_rel21_reloc, "IMAGE_REL_ARM64_PAGEBASE_REL21",
false, 0x1fffff, 0x1fffff, false);
static const reloc_howto_type arm64_reloc_howto_lo21 = HOWTO (IMAGE_REL_ARM64_REL21, 0, 4, 21, true, 0,
complain_overflow_signed,
- NULL, "LO21",
+ coff_aarch64_rel21_reloc, "IMAGE_REL_ARM64_REL21",
false, 0x1fffff, 0x1fffff, true);
-static const reloc_howto_type arm64_reloc_howto_pgoff12 = HOWTO (IMAGE_REL_ARM64_PAGEOFFSET_12L, 1, 4, 12, true, 0,
+static const reloc_howto_type arm64_reloc_howto_pgoff12l = HOWTO (IMAGE_REL_ARM64_PAGEOFFSET_12L, 1, 4, 12, true, 0,
complain_overflow_signed,
- NULL, "PGOFF12",
+ coff_aarch64_po12l_reloc, "IMAGE_REL_ARM64_PAGEOFFSET_12L",
false, 0xffe, 0xffe, true);
static const reloc_howto_type arm64_reloc_howto_branch19 = HOWTO (IMAGE_REL_ARM64_BRANCH19, 2, 4, 19, true, 0,
complain_overflow_signed,
- NULL, "BRANCH19",
+ coff_aarch64_branch19_reloc, "IMAGE_REL_ARM64_BRANCH19",
false, 0x7ffff, 0x7ffff, true);
+static const reloc_howto_type arm64_reloc_howto_branch14 = HOWTO (IMAGE_REL_ARM64_BRANCH14, 2, 4, 14, true, 0,
+ complain_overflow_signed,
+ coff_aarch64_branch14_reloc, "IMAGE_REL_ARM64_BRANCH14",
+ false, 0x3fff, 0x3fff, true);
+
+static const reloc_howto_type arm64_reloc_howto_pgoff12a = HOWTO (IMAGE_REL_ARM64_PAGEOFFSET_12A, 2, 4, 12, true, 10,
+ complain_overflow_dont,
+ coff_aarch64_po12a_reloc, "IMAGE_REL_ARM64_PAGEOFFSET_12A",
+ false, 0x3ffc00, 0x3ffc00, false);
+
+static const reloc_howto_type arm64_reloc_howto_32nb = HOWTO (IMAGE_REL_ARM64_ADDR32NB, 0, 4, 32, false, 0,
+ complain_overflow_bitfield,
+ coff_aarch64_addr32nb_reloc, "IMAGE_REL_ARM64_ADDR32NB",
+ false, 0xffffffff, 0xffffffff, false);
static const reloc_howto_type* const arm64_howto_table[] = {
+ &arm64_reloc_howto_abs,
&arm64_reloc_howto_64,
&arm64_reloc_howto_32,
&arm64_reloc_howto_32_pcrel,
&arm64_reloc_howto_branch26,
&arm64_reloc_howto_page21,
&arm64_reloc_howto_lo21,
- &arm64_reloc_howto_pgoff12,
- &arm64_reloc_howto_branch19
+ &arm64_reloc_howto_pgoff12l,
+ &arm64_reloc_howto_branch19,
+ &arm64_reloc_howto_branch14,
+ &arm64_reloc_howto_pgoff12a,
+ &arm64_reloc_howto_32nb
};
#ifndef NUM_ELEM
@@ -118,13 +369,24 @@ coff_aarch64_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real
case BFD_RELOC_AARCH64_JUMP26:
return &arm64_reloc_howto_branch26;
case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
return &arm64_reloc_howto_page21;
+ case BFD_RELOC_AARCH64_TSTBR14:
+ return &arm64_reloc_howto_branch14;
case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
return &arm64_reloc_howto_lo21;
+ case BFD_RELOC_AARCH64_ADD_LO12:
+ return &arm64_reloc_howto_pgoff12a;
+ case BFD_RELOC_AARCH64_LDST8_LO12:
case BFD_RELOC_AARCH64_LDST16_LO12:
- return &arm64_reloc_howto_pgoff12;
+ case BFD_RELOC_AARCH64_LDST32_LO12:
+ case BFD_RELOC_AARCH64_LDST64_LO12:
+ case BFD_RELOC_AARCH64_LDST128_LO12:
+ return &arm64_reloc_howto_pgoff12l;
case BFD_RELOC_AARCH64_BRANCH19:
return &arm64_reloc_howto_branch19;
+ case BFD_RELOC_RVA:
+ return &arm64_reloc_howto_32nb;
default:
BFD_FAIL ();
return NULL;
@@ -155,6 +417,8 @@ coff_aarch64_rtype_lookup (unsigned int code)
{
switch (code)
{
+ case IMAGE_REL_ARM64_ABSOLUTE:
+ return &arm64_reloc_howto_abs;
case IMAGE_REL_ARM64_ADDR64:
return &arm64_reloc_howto_64;
case IMAGE_REL_ARM64_ADDR32:
@@ -168,9 +432,15 @@ coff_aarch64_rtype_lookup (unsigned int code)
case IMAGE_REL_ARM64_REL21:
return &arm64_reloc_howto_lo21;
case IMAGE_REL_ARM64_PAGEOFFSET_12L:
- return &arm64_reloc_howto_pgoff12;
+ return &arm64_reloc_howto_pgoff12l;
case IMAGE_REL_ARM64_BRANCH19:
return &arm64_reloc_howto_branch19;
+ case IMAGE_REL_ARM64_BRANCH14:
+ return &arm64_reloc_howto_branch14;
+ case IMAGE_REL_ARM64_PAGEOFFSET_12A:
+ return &arm64_reloc_howto_pgoff12a;
+ case IMAGE_REL_ARM64_ADDR32NB:
+ return &arm64_reloc_howto_32nb;
default:
BFD_FAIL ();
return NULL;
@@ -188,6 +458,7 @@ coff_aarch64_rtype_lookup (unsigned int code)
#define bfd_pe_print_pdata NULL
#endif
+#ifdef COFF_WITH_PE
/* Return TRUE if this relocation should
appear in the output .reloc section. */
@@ -197,9 +468,384 @@ in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
{
return !howto->pc_relative;
}
+#endif
+
+static bool
+coff_pe_aarch64_relocate_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ struct internal_reloc *relocs,
+ struct internal_syment *syms,
+ asection **sections)
+{
+ struct internal_reloc *rel;
+ struct internal_reloc *relend;
+
+ if (bfd_link_relocatable (info))
+ return true;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+
+ /* The addend for a relocation is stored in the immediate bits of each
+ opcode. So for each relocation, we need to extract the immediate value,
+ use this to calculate what it should be for the symbol, and rewrite the
+ opcode into the section stream. */
+
+ for (; rel < relend; rel++)
+ {
+ long symndx;
+ struct coff_link_hash_entry *h;
+ bfd_vma sym_value;
+ asection *sec = NULL;
+ uint64_t dest_vma;
+
+ /* skip trivial relocations */
+ if (rel->r_type == IMAGE_REL_ARM64_ADDR32
+ || rel->r_type == IMAGE_REL_ARM64_ADDR64
+ || rel->r_type == IMAGE_REL_ARM64_ABSOLUTE)
+ continue;
+
+ symndx = rel->r_symndx;
+ sym_value = syms[symndx].n_value;
+
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+
+ if (h && h->root.type == bfd_link_hash_defined)
+ {
+ sec = h->root.u.def.section;
+ sym_value = h->root.u.def.value;
+ }
+ else
+ {
+ sec = sections[symndx];
+ }
+
+ if (!sec)
+ continue;
+
+ if (bfd_is_und_section (sec))
+ continue;
+
+ if (discarded_section (sec))
+ continue;
+
+ dest_vma = sec->output_section->vma + sec->output_offset + sym_value;
+
+ if (symndx < 0
+ || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
+ continue;
+
+ switch (rel->r_type)
+ {
+ case IMAGE_REL_ARM64_ADDR32NB:
+ {
+ uint64_t val;
+ int32_t addend;
+
+ addend = bfd_getl32 (contents + rel->r_vaddr);
+
+ dest_vma += addend;
+
+ val = dest_vma;
+ val -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+
+ if (val > 0xffffffff)
+ (*info->callbacks->reloc_overflow)
+ (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
+ "IMAGE_REL_ARM64_ADDR32NB", addend, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
+
+ bfd_putl32 (val, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
+ case IMAGE_REL_ARM64_BRANCH26:
+ {
+ uint64_t cur_vma;
+ uint32_t opcode;
+ int64_t addend, val;
+
+ opcode = bfd_getl32 (contents + rel->r_vaddr);
+
+ addend = (opcode & 0x3ffffff) << 2;
+
+ if (addend & 0x8000000)
+ addend |= 0xfffffffff0000000;
+
+ dest_vma += addend;
+ cur_vma = input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_vaddr;
+
+ val = (dest_vma >> 2) - (cur_vma >> 2);
+
+ if (val > 0x1ffffff || val < -0x2000000)
+ (*info->callbacks->reloc_overflow)
+ (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
+ "IMAGE_REL_ARM64_BRANCH26", addend, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
+
+ opcode &= 0xfc000000;
+ opcode |= val & 0x3ffffff;
+
+ bfd_putl32 (opcode, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
+ case IMAGE_REL_ARM64_BRANCH19:
+ {
+ uint64_t cur_vma;
+ uint32_t opcode;
+ int64_t addend, val;
+
+ opcode = bfd_getl32 (contents + rel->r_vaddr);
+
+ addend = (opcode & 0xffffe0) >> 3;
+
+ if (addend & 0x100000)
+ addend |= 0xffffffffffe00000;
+
+ dest_vma += addend;
+ cur_vma = input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_vaddr;
+
+ val = (dest_vma >> 2) - (cur_vma >> 2);
+
+ if (val > 0x3ffff || val < -0x40000)
+ (*info->callbacks->reloc_overflow)
+ (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
+ "IMAGE_REL_ARM64_BRANCH19", addend, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
+
+ opcode &= 0xff00001f;
+ opcode |= (val & 0x7ffff) << 5;
+
+ bfd_putl32 (opcode, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
+ case IMAGE_REL_ARM64_BRANCH14:
+ {
+ uint64_t cur_vma;
+ uint32_t opcode;
+ int64_t addend, val;
+
+ opcode = bfd_getl32 (contents + rel->r_vaddr);
+
+ addend = (opcode & 0x7ffe0) >> 3;
+
+ if (addend & 0x8000)
+ addend |= 0xffffffffffff0000;
+
+ dest_vma += addend;
+ cur_vma = input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_vaddr;
+
+ val = (dest_vma >> 2) - (cur_vma >> 2);
+
+ if (val > 0x1fff || val < -0x2000)
+ (*info->callbacks->reloc_overflow)
+ (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
+ "IMAGE_REL_ARM64_BRANCH14", addend, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
+
+ opcode &= 0xfff8001f;
+ opcode |= (val & 0x3fff) << 5;
+
+ bfd_putl32 (opcode, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
+ case IMAGE_REL_ARM64_PAGEBASE_REL21:
+ {
+ uint64_t cur_vma;
+ uint32_t opcode;
+ int64_t addend, val;
+
+ opcode = bfd_getl32 (contents + rel->r_vaddr);
+
+ addend = ((opcode & 0xffffe0) >> 3)
+ | ((opcode & 0x60000000) >> 29);
+
+ if (addend & 0x100000)
+ addend |= 0xffffffffffe00000;
+
+ dest_vma += addend;
+ cur_vma = input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_vaddr;
+
+ val = (dest_vma >> 12) - (cur_vma >> 12);
+
+ if (val > 0xfffff || val < -0x100000)
+ (*info->callbacks->reloc_overflow)
+ (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
+ "IMAGE_REL_ARM64_PAGEBASE_REL21", addend, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
+
+ opcode &= 0x9f00001f;
+ opcode |= (val & 0x3) << 29;
+ opcode |= (val & 0x1ffffc) << 3;
+
+ bfd_putl32 (opcode, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
+ case IMAGE_REL_ARM64_REL21:
+ {
+ uint64_t cur_vma;
+ uint32_t opcode;
+ int64_t addend, val;
+
+ opcode = bfd_getl32 (contents + rel->r_vaddr);
+
+ addend = ((opcode & 0xffffe0) >> 3)
+ | ((opcode & 0x60000000) >> 29);
+
+ if (addend & 0x100000)
+ addend |= 0xffffffffffe00000;
+
+ dest_vma += addend;
+ cur_vma = input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_vaddr;
+
+ val = dest_vma - cur_vma;
+
+ if (val > 0xfffff || val < -0x100000)
+ (*info->callbacks->reloc_overflow)
+ (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
+ "IMAGE_REL_ARM64_REL21", addend, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
+
+ opcode &= 0x9f00001f;
+ opcode |= (val & 0x3) << 29;
+ opcode |= (val & 0x1ffffc) << 3;
+
+ bfd_putl32 (opcode, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
+ case IMAGE_REL_ARM64_PAGEOFFSET_12L:
+ {
+ uint32_t opcode, val;
+ uint8_t shift;
+ int32_t addend;
+
+ opcode = bfd_getl32 (contents + rel->r_vaddr);
+
+ addend = (opcode & 0x3ffc00) >> 10;
+
+ if ((opcode & 0xff800000) == 0x3d800000)
+ {
+ /* LDR / STR with q register */
+ shift = 4;
+ }
+ else
+ {
+ /* top two bits represent how much addend should be shifted */
+ shift = opcode >> 30;
+ }
+
+ addend <<= shift;
+
+ dest_vma += addend;
+
+ /* only interested in bottom 12 bits */
+ val = dest_vma & 0xfff;
+
+ if (val & ((1 << shift) - 1))
+ (*info->callbacks->reloc_overflow)
+ (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
+ "IMAGE_REL_ARM64_PAGEOFFSET_12L", addend, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
+
+ val >>= shift;
+
+ opcode &= 0xffc003ff;
+ opcode |= val << 10;
+
+ bfd_putl32 (opcode, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
+ case IMAGE_REL_ARM64_PAGEOFFSET_12A:
+ {
+ uint32_t opcode, val;
+ int32_t addend;
+
+ opcode = bfd_getl32 (contents + rel->r_vaddr);
+
+ addend = (opcode & 0x3ffc00) >> 10;
+
+ dest_vma += addend;
+
+ /* only interested in bottom 12 bits */
+ val = dest_vma & 0xfff;
+
+ opcode &= 0xffc003ff;
+ opcode |= val << 10;
+
+ bfd_putl32 (opcode, contents + rel->r_vaddr);
+ rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
+
+ break;
+ }
+
+ default:
+ info->callbacks->einfo (_("%F%P: Unhandled relocation type %u\n"),
+ rel->r_type);
+ BFD_FAIL ();
+ return false;
+ }
+ }
+
+ return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
+ input_section, contents,
+ relocs, syms, sections);
+}
+
+#define coff_relocate_section coff_pe_aarch64_relocate_section
#include "coffcode.h"
+/* Prevent assertion in md_apply_fix by forcing use_rela_p on for new
+ sections. */
+static bool
+coff_aarch64_new_section_hook (bfd *abfd, asection *section)
+{
+ if (!coff_new_section_hook (abfd, section))
+ return false;
+
+ section->use_rela_p = 1;
+
+ return true;
+}
+
+#define coff_aarch64_close_and_cleanup coff_close_and_cleanup
+#define coff_aarch64_bfd_free_cached_info coff_bfd_free_cached_info
+#define coff_aarch64_get_section_contents coff_get_section_contents
+#define coff_aarch64_get_section_contents_in_window coff_get_section_contents_in_window
+
/* Target vectors. */
const bfd_target
#ifdef TARGET_SYM
@@ -266,7 +912,7 @@ const bfd_target
_bfd_bool_bfd_false_error
},
- BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_GENERIC (coff_aarch64),
BFD_JUMP_TABLE_COPY (coff),
BFD_JUMP_TABLE_CORE (_bfd_nocore),
BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 3672b6a..800afa8 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -1493,12 +1493,6 @@ case "${targ}" in
;;
esac
-if test x"$targ_defvec" = x"aarch64-pe"; then
- # Not currently complete (and probably not stable), warn user
- echo "*** WARNING BFD aarch64-pe support not complete nor stable"
- echo "*** Do not rely on this for production purposes"
-fi
-
# All MIPS ELF targets need a 64-bit bfd_vma.
case "${targ_defvec} ${targ_selvecs}" in
*mips_elf*)
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 132f8db..25e7943 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -1889,10 +1889,9 @@ s_ltorg (int ignored ATTRIBUTE_UNUSED)
}
}
-#ifdef OBJ_ELF
+#if defined(OBJ_ELF) || defined(OBJ_COFF)
/* Forward declarations for functions below, in the MD interface
section. */
-static fixS *fix_new_aarch64 (fragS *, int, short, expressionS *, int, int);
static struct reloc_table_entry * find_reloc_table_entry (char **);
/* Directives: Data. */
@@ -1900,7 +1899,7 @@ static struct reloc_table_entry * find_reloc_table_entry (char **);
implemented properly. */
static void
-s_aarch64_elf_cons (int nbytes)
+s_aarch64_cons (int nbytes)
{
expressionS exp;
@@ -1950,6 +1949,12 @@ s_aarch64_elf_cons (int nbytes)
input_line_pointer--;
demand_empty_rest_of_line ();
}
+#endif
+
+#ifdef OBJ_ELF
+/* Forward declarations for functions below, in the MD interface
+ section. */
+ static fixS *fix_new_aarch64 (fragS *, int, short, expressionS *, int, int);
/* Mark symbol that it follows a variant PCS convention. */
@@ -2119,12 +2124,14 @@ const pseudo_typeS md_pseudo_table[] = {
{"tlsdescadd", s_tlsdescadd, 0},
{"tlsdesccall", s_tlsdesccall, 0},
{"tlsdescldr", s_tlsdescldr, 0},
- {"word", s_aarch64_elf_cons, 4},
- {"long", s_aarch64_elf_cons, 4},
- {"xword", s_aarch64_elf_cons, 8},
- {"dword", s_aarch64_elf_cons, 8},
{"variant_pcs", s_variant_pcs, 0},
#endif
+#if defined(OBJ_ELF) || defined(OBJ_COFF)
+ {"word", s_aarch64_cons, 4},
+ {"long", s_aarch64_cons, 4},
+ {"xword", s_aarch64_cons, 8},
+ {"dword", s_aarch64_cons, 8},
+#endif
{"float16", float_cons, 'h'},
{"bfloat16", float_cons, 'b'},
{0, 0, 0}
@@ -9260,6 +9267,9 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
/* An error will already have been reported. */
break;
+ case BFD_RELOC_RVA:
+ break;
+
default:
as_bad_where (fixP->fx_file, fixP->fx_line,
_("unexpected %s fixup"),
diff --git a/gas/testsuite/gas/pe/pe-aarch64.d b/gas/testsuite/gas/pe/pe-aarch64.d
index 0b8009d..eb61103 100644
--- a/gas/testsuite/gas/pe/pe-aarch64.d
+++ b/gas/testsuite/gas/pe/pe-aarch64.d
@@ -1,14 +1,232 @@
#as:
-#objdump: -d
+#objdump: -dr
.*: file format pe-aarch64-little
Disassembly of section .text:
-0000000000000000 <_start>:
- 0: d2800281 mov x1, #0x14 // #20
- 4: 14000001 b 8 <foo>
+0000000000000000 <.text>:
+ ...
-0000000000000008 <foo>:
- 8: d65f03c0 ret
+0000000000000010 <foo>:
+ 10: 12345678 and w24, w19, #0xfffff003
+ 14: 12345678 and w24, w19, #0xfffff003
+ 18: 00000010 udf #16
+ 18: IMAGE_REL_ARM64_ADDR32 .text
+ 1c: 00000010 udf #16
+ 1c: IMAGE_REL_ARM64_ADDR32 .text
+ ...
+ 20: IMAGE_REL_ARM64_ADDR32 bar
+ 24: IMAGE_REL_ARM64_ADDR32 bar
+ 28: 00000011 udf #17
+ 28: IMAGE_REL_ARM64_ADDR32 .text
+ 2c: 00000011 udf #17
+ 2c: IMAGE_REL_ARM64_ADDR32 .text
+ 30: 00000001 udf #1
+ 30: IMAGE_REL_ARM64_ADDR32 bar
+ 34: 00000001 udf #1
+ 34: IMAGE_REL_ARM64_ADDR32 bar
+ 38: 0000000f udf #15
+ 38: IMAGE_REL_ARM64_ADDR32 .text
+ 3c: 0000000f udf #15
+ 3c: IMAGE_REL_ARM64_ADDR32 .text
+ 40: ffffffff .inst 0xffffffff ; undefined
+ 40: IMAGE_REL_ARM64_ADDR32 bar
+ 44: ffffffff .inst 0xffffffff ; undefined
+ 44: IMAGE_REL_ARM64_ADDR32 bar
+ 48: 9abcdef0 .inst 0x9abcdef0 ; undefined
+ 4c: 12345678 and w24, w19, #0xfffff003
+ 50: 9abcdef0 .inst 0x9abcdef0 ; undefined
+ 54: 12345678 and w24, w19, #0xfffff003
+ 58: 00000010 udf #16
+ 58: IMAGE_REL_ARM64_ADDR64 .text
+ 5c: 00000000 udf #0
+ 60: 00000010 udf #16
+ 60: IMAGE_REL_ARM64_ADDR64 .text
+ ...
+ 68: IMAGE_REL_ARM64_ADDR64 bar
+ 70: IMAGE_REL_ARM64_ADDR64 bar
+ 78: 00000011 udf #17
+ 78: IMAGE_REL_ARM64_ADDR64 .text
+ 7c: 00000000 udf #0
+ 80: 00000011 udf #17
+ 80: IMAGE_REL_ARM64_ADDR64 .text
+ 84: 00000000 udf #0
+ 88: 00000001 udf #1
+ 88: IMAGE_REL_ARM64_ADDR64 bar
+ 8c: 00000000 udf #0
+ 90: 00000001 udf #1
+ 90: IMAGE_REL_ARM64_ADDR64 bar
+ 94: 00000000 udf #0
+ 98: 0000000f udf #15
+ 98: IMAGE_REL_ARM64_ADDR64 .text
+ 9c: 00000000 udf #0
+ a0: 0000000f udf #15
+ a0: IMAGE_REL_ARM64_ADDR64 .text
+ a4: 00000000 udf #0
+ a8: ffffffff .inst 0xffffffff ; undefined
+ a8: IMAGE_REL_ARM64_ADDR64 bar
+ ac: ffffffff .inst 0xffffffff ; undefined
+ b0: ffffffff .inst 0xffffffff ; undefined
+ b0: IMAGE_REL_ARM64_ADDR64 bar
+ b4: ffffffff .inst 0xffffffff ; undefined
+ b8: 00000010 udf #16
+ b8: IMAGE_REL_ARM64_ADDR32NB .text
+ bc: 00000000 udf #0
+ bc: IMAGE_REL_ARM64_ADDR32NB bar
+ c0: 00000011 udf #17
+ c0: IMAGE_REL_ARM64_ADDR32NB .text
+ c4: 00000001 udf #1
+ c4: IMAGE_REL_ARM64_ADDR32NB bar
+ c8: 0000000f udf #15
+ c8: IMAGE_REL_ARM64_ADDR32NB .text
+ cc: ffffffff .inst 0xffffffff ; undefined
+ cc: IMAGE_REL_ARM64_ADDR32NB bar
+ d0: 17ffffd0 b 10 <foo>
+ d4: 17ffffd0 b 14 <foo\+0x4>
+ d8: 17ffffcd b c <.text\+0xc>
+ dc: 14000000 b 0 <bar>
+ dc: IMAGE_REL_ARM64_BRANCH26 bar
+ e0: 14000001 b 4 <bar\+0x4>
+ e0: IMAGE_REL_ARM64_BRANCH26 bar
+ e4: 17ffffff b fffffffffffffffc <bar\+0xfffffffffffffffc>
+ e4: IMAGE_REL_ARM64_BRANCH26 bar
+ e8: 97ffffca bl 10 <foo>
+ ec: 97ffffca bl 14 <foo\+0x4>
+ f0: 97ffffc7 bl c <.text\+0xc>
+ f4: 94000000 bl 0 <bar>
+ f4: IMAGE_REL_ARM64_BRANCH26 bar
+ f8: 94000001 bl 4 <bar\+0x4>
+ f8: IMAGE_REL_ARM64_BRANCH26 bar
+ fc: 97ffffff bl fffffffffffffffc <bar\+0xfffffffffffffffc>
+ fc: IMAGE_REL_ARM64_BRANCH26 bar
+ 100: 97ffffbf bl fffffffffffffffc <foo\+0xffffffffffffffec>
+ 104: b4fff860 cbz x0, 10 <foo>
+ 108: b4fff860 cbz x0, 14 <foo\+0x4>
+ 10c: b4fff800 cbz x0, c <.text\+0xc>
+ 110: b4000000 cbz x0, 0 <bar>
+ 110: IMAGE_REL_ARM64_BRANCH19 bar
+ 114: b4000020 cbz x0, 4 <bar\+0x4>
+ 114: IMAGE_REL_ARM64_BRANCH19 bar
+ 118: b4ffffe0 cbz x0, fffffffffffffffc <bar\+0xfffffffffffffffc>
+ 118: IMAGE_REL_ARM64_BRANCH19 bar
+ 11c: b4fff700 cbz x0, fffffffffffffffc <foo\+0xffffffffffffffec>
+ 120: 3607f780 tbz w0, #0, 10 <foo>
+ 124: 3607f780 tbz w0, #0, 14 <foo\+0x4>
+ 128: 3607f720 tbz w0, #0, c <.text\+0xc>
+ 12c: 36000000 tbz w0, #0, 0 <bar>
+ 12c: IMAGE_REL_ARM64_BRANCH14 bar
+ 130: 36000020 tbz w0, #0, 4 <bar\+0x4>
+ 130: IMAGE_REL_ARM64_BRANCH14 bar
+ 134: 3607ffe0 tbz w0, #0, fffffffffffffffc <bar\+0xfffffffffffffffc>
+ 134: IMAGE_REL_ARM64_BRANCH14 bar
+ 138: 3607f620 tbz w0, #0, fffffffffffffffc <foo\+0xffffffffffffffec>
+ 13c: 90000080 adrp x0, 10000 <foo\+0xfff0>
+ 13c: IMAGE_REL_ARM64_PAGEBASE_REL21 .text
+ 140: b0000080 adrp x0, 11000 <foo\+0x10ff0>
+ 140: IMAGE_REL_ARM64_PAGEBASE_REL21 .text
+ 144: f0000060 adrp x0, f000 <foo\+0xeff0>
+ 144: IMAGE_REL_ARM64_PAGEBASE_REL21 .text
+ 148: 90000000 adrp x0, 0 <bar>
+ 148: IMAGE_REL_ARM64_PAGEBASE_REL21 bar
+ 14c: b0000000 adrp x0, 1000 <bar\+0x1000>
+ 14c: IMAGE_REL_ARM64_PAGEBASE_REL21 bar
+ 150: f0ffffe0 adrp x0, fffffffffffff000 <bar\+0xfffffffffffff000>
+ 150: IMAGE_REL_ARM64_PAGEBASE_REL21 bar
+ 154: 90ffffe0 adrp x0, ffffffffffffc000 <foo\+0xffffffffffffbff0>
+ 154: IMAGE_REL_ARM64_PAGEBASE_REL21 .text
+ 158: 10fff5c0 adr x0, 10 <foo>
+ 15c: 30fff5a0 adr x0, 11 <foo\+0x1>
+ 160: 70fff560 adr x0, f <.text\+0xf>
+ 164: 10000000 adr x0, 0 <bar>
+ 164: IMAGE_REL_ARM64_REL21 bar
+ 168: 30000000 adr x0, 1 <bar\+0x1>
+ 168: IMAGE_REL_ARM64_REL21 bar
+ 16c: 70ffffe0 adr x0, ffffffffffffffff <bar\+0xffffffffffffffff>
+ 16c: IMAGE_REL_ARM64_REL21 bar
+ 170: 70fff460 adr x0, ffffffffffffffff <foo\+0xffffffffffffffef>
+ 174: 39004000 strb w0, \[x0, #16\]
+ 174: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 178: 39005000 strb w0, \[x0, #20\]
+ 178: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 17c: 39003000 strb w0, \[x0, #12\]
+ 17c: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 180: 39000000 strb w0, \[x0\]
+ 180: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 184: 39001000 strb w0, \[x0, #4\]
+ 184: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 188: 393ff000 strb w0, \[x0, #4092\]
+ 188: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 18c: 393ff000 strb w0, \[x0, #4092\]
+ 18c: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 190: 79002000 strh w0, \[x0, #16\]
+ 190: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 194: 79002800 strh w0, \[x0, #20\]
+ 194: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 198: 79001800 strh w0, \[x0, #12\]
+ 198: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 19c: 79000000 strh w0, \[x0\]
+ 19c: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1a0: 79000800 strh w0, \[x0, #4\]
+ 1a0: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1a4: 791ff800 strh w0, \[x0, #4092\]
+ 1a4: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1a8: 791ff800 strh w0, \[x0, #4092\]
+ 1a8: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1ac: b9001000 str w0, \[x0, #16\]
+ 1ac: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1b0: b9001400 str w0, \[x0, #20\]
+ 1b0: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1b4: b9000c00 str w0, \[x0, #12\]
+ 1b4: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1b8: b9000000 str w0, \[x0\]
+ 1b8: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1bc: b9000400 str w0, \[x0, #4\]
+ 1bc: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1c0: b90ffc00 str w0, \[x0, #4092\]
+ 1c0: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1c4: b90ffc00 str w0, \[x0, #4092\]
+ 1c4: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1c8: f9000800 str x0, \[x0, #16\]
+ 1c8: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1cc: f9000c00 str x0, \[x0, #24\]
+ 1cc: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1d0: f9000400 str x0, \[x0, #8\]
+ 1d0: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1d4: f9000000 str x0, \[x0\]
+ 1d4: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1d8: f9000400 str x0, \[x0, #8\]
+ 1d8: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1dc: f907fc00 str x0, \[x0, #4088\]
+ 1dc: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1e0: f907fc00 str x0, \[x0, #4088\]
+ 1e0: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1e4: 3d800400 str q0, \[x0, #16\]
+ 1e4: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1e8: 3d800800 str q0, \[x0, #32\]
+ 1e8: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1ec: 3d800000 str q0, \[x0\]
+ 1ec: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 1f0: 3d800000 str q0, \[x0\]
+ 1f0: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1f4: 3d800400 str q0, \[x0, #16\]
+ 1f4: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1f8: 3d83fc00 str q0, \[x0, #4080\]
+ 1f8: IMAGE_REL_ARM64_PAGEOFFSET_12L bar
+ 1fc: 3d83fc00 str q0, \[x0, #4080\]
+ 1fc: IMAGE_REL_ARM64_PAGEOFFSET_12L .text
+ 200: 91004000 add x0, x0, #0x10
+ 200: IMAGE_REL_ARM64_PAGEOFFSET_12A .text
+ 204: 91004400 add x0, x0, #0x11
+ 204: IMAGE_REL_ARM64_PAGEOFFSET_12A .text
+ 208: 91003c00 add x0, x0, #0xf
+ 208: IMAGE_REL_ARM64_PAGEOFFSET_12A .text
+ 20c: 91000000 add x0, x0, #0x0
+ 20c: IMAGE_REL_ARM64_PAGEOFFSET_12A bar
+ 210: 91000400 add x0, x0, #0x1
+ 210: IMAGE_REL_ARM64_PAGEOFFSET_12A bar
+ 214: 913ffc00 add x0, x0, #0xfff
+ 214: IMAGE_REL_ARM64_PAGEOFFSET_12A bar
+ 218: 913ffc00 add x0, x0, #0xfff
+ 218: IMAGE_REL_ARM64_PAGEOFFSET_12A .text
diff --git a/gas/testsuite/gas/pe/pe-aarch64.s b/gas/testsuite/gas/pe/pe-aarch64.s
index 546d55f..2a02d2d 100644
--- a/gas/testsuite/gas/pe/pe-aarch64.s
+++ b/gas/testsuite/gas/pe/pe-aarch64.s
@@ -1,11 +1,157 @@
-# A little test to ensure pe-aarch64 is working in GAS.
-# Currently, the poor pe-aarch64 implementation in binutils
-# couldn't do anything useful, hence, this test is rather short
+.text
-.section .text
+.dword 0
+.dword 0
-_start:
- mov x1, 20
- b foo
foo:
- ret
+
+# 4-byte literal
+.long 0x12345678
+.word 0x12345678
+
+# IMAGE_REL_ARM64_ADDR32 (BFD_RELOC_32)
+.long foo
+.word foo
+.long bar
+.word bar
+.long foo + 1
+.word foo + 1
+.long bar + 1
+.word bar + 1
+.long foo - 1
+.word foo - 1
+.long bar - 1
+.word bar - 1
+
+# 8-byte literal
+.dword 0x123456789abcdef0
+.xword 0x123456789abcdef0
+
+# IMAGE_REL_ARM64_ADDR64 (BFD_RELOC_64)
+.dword foo
+.xword foo
+.dword bar
+.xword bar
+.dword foo + 1
+.xword foo + 1
+.dword bar + 1
+.xword bar + 1
+.dword foo - 1
+.xword foo - 1
+.dword bar - 1
+.xword bar - 1
+
+# IMAGE_REL_ARM64_ADDR32NB (BFD_RELOC_RVA)
+.rva foo
+.rva bar
+.rva foo + 1
+.rva bar + 1
+.rva foo - 1
+.rva bar - 1
+
+# IMAGE_REL_ARM64_BRANCH26 (BFD_RELOC_AARCH64_JUMP26)
+b foo
+b foo + 4
+b foo - 4
+b bar
+b bar + 4
+b bar - 4
+
+# IMAGE_REL_ARM64_BRANCH26 (BFD_RELOC_AARCH64_CALL26)
+bl foo
+bl foo + 4
+bl foo - 4
+bl bar
+bl bar + 4
+bl bar - 4
+bl .text - 4
+
+# IMAGE_REL_ARM64_BRANCH19 (BFD_RELOC_AARCH64_BRANCH19)
+cbz x0, foo
+cbz x0, foo + 4
+cbz x0, foo - 4
+cbz x0, bar
+cbz x0, bar + 4
+cbz x0, bar - 4
+cbz x0, .text - 4
+
+# IMAGE_REL_ARM64_BRANCH14 (BFD_RELOC_AARCH64_TSTBR14)
+tbz x0, 0, foo
+tbz x0, 0, foo + 4
+tbz x0, 0, foo - 4
+tbz x0, 0, bar
+tbz x0, 0, bar + 4
+tbz x0, 0, bar - 4
+tbz x0, 0, .text - 4
+
+# IMAGE_REL_ARM64_PAGEBASE_REL21 (BFD_RELOC_AARCH64_ADR_HI21_PCREL)
+adrp x0, foo
+adrp x0, foo + 1
+adrp x0, foo - 1
+adrp x0, bar
+adrp x0, bar + 1
+adrp x0, bar - 1
+adrp x0, .text - 4
+
+# IMAGE_REL_ARM64_REL21 (BFD_RELOC_AARCH64_ADR_LO21_PCREL)
+adr x0, foo
+adr x0, foo + 1
+adr x0, foo - 1
+adr x0, bar
+adr x0, bar + 1
+adr x0, bar - 1
+adr x0, .text - 1
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST8_LO12)
+strb w0, [x0,:lo12:foo]
+strb w0, [x0,:lo12:foo + 4]
+strb w0, [x0,:lo12:foo - 4]
+strb w0, [x0,:lo12:bar]
+strb w0, [x0,:lo12:bar + 4]
+strb w0, [x0,:lo12:bar - 4]
+strb w0, [x0,:lo12:.text - 4]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST16_LO12)
+strh w0, [x0,:lo12:foo]
+strh w0, [x0,:lo12:foo + 4]
+strh w0, [x0,:lo12:foo - 4]
+strh w0, [x0,:lo12:bar]
+strh w0, [x0,:lo12:bar + 4]
+strh w0, [x0,:lo12:bar - 4]
+strh w0, [x0,:lo12:.text - 4]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST32_LO12)
+str w0, [x0,:lo12:foo]
+str w0, [x0,:lo12:foo + 4]
+str w0, [x0,:lo12:foo - 4]
+str w0, [x0,:lo12:bar]
+str w0, [x0,:lo12:bar + 4]
+str w0, [x0,:lo12:bar - 4]
+str w0, [x0,:lo12:.text - 4]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST64_LO12)
+str x0, [x0,:lo12:foo]
+str x0, [x0,:lo12:foo + 8]
+str x0, [x0,:lo12:foo - 8]
+str x0, [x0,:lo12:bar]
+str x0, [x0,:lo12:bar + 8]
+str x0, [x0,:lo12:bar - 8]
+str x0, [x0,:lo12:.text - 8]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST128_LO12)
+str q0, [x0,:lo12:foo]
+str q0, [x0,:lo12:foo + 16]
+str q0, [x0,:lo12:foo - 16]
+str q0, [x0,:lo12:bar]
+str q0, [x0,:lo12:bar + 16]
+str q0, [x0,:lo12:bar - 16]
+str q0, [x0,:lo12:.text - 16]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12A (BFD_RELOC_AARCH64_ADD_LO12)
+add x0, x0, #:lo12:foo
+add x0, x0, #:lo12:foo + 1
+add x0, x0, #:lo12:foo - 1
+add x0, x0, #:lo12:bar
+add x0, x0, #:lo12:bar + 1
+add x0, x0, #:lo12:bar - 1
+add x0, x0, #:lo12:.text - 1
diff --git a/ld/testsuite/ld-pe/aarch64.d b/ld/testsuite/ld-pe/aarch64.d
new file mode 100644
index 0000000..cc3daf9
--- /dev/null
+++ b/ld/testsuite/ld-pe/aarch64.d
@@ -0,0 +1,158 @@
+
+tmpdir/aarch64.x: file format pei-aarch64-little
+
+
+Disassembly of section .text:
+
+0000000000002000 <__rt_psrelocs_end>:
+ ...
+
+0000000000002010 <foo>:
+ 2010: 12345678 and w24, w19, #0xfffff003
+ 2014: 12345678 and w24, w19, #0xfffff003
+ 2018: 00002000 udf #8192
+ 201c: 00002000 udf #8192
+ 2020: 00002220 udf #8736
+ 2024: 00002220 udf #8736
+ 2028: 00002001 udf #8193
+ 202c: 00002001 udf #8193
+ 2030: 00002221 udf #8737
+ 2034: 00002221 udf #8737
+ 2038: 00001fff udf #8191
+ 203c: 00001fff udf #8191
+ 2040: 0000221f udf #8735
+ 2044: 0000221f udf #8735
+ 2048: 9abcdef0 .inst 0x9abcdef0 ; undefined
+ 204c: 12345678 and w24, w19, #0xfffff003
+ 2050: 9abcdef0 .inst 0x9abcdef0 ; undefined
+ 2054: 12345678 and w24, w19, #0xfffff003
+ 2058: 00002000 udf #8192
+ 205c: 00000000 udf #0
+ 2060: 00002000 udf #8192
+ 2064: 00000000 udf #0
+ 2068: 00002220 udf #8736
+ 206c: 00000000 udf #0
+ 2070: 00002220 udf #8736
+ 2074: 00000000 udf #0
+ 2078: 00002001 udf #8193
+ 207c: 00000000 udf #0
+ 2080: 00002001 udf #8193
+ 2084: 00000000 udf #0
+ 2088: 00002221 udf #8737
+ 208c: 00000000 udf #0
+ 2090: 00002221 udf #8737
+ 2094: 00000000 udf #0
+ 2098: 00001fff udf #8191
+ 209c: 00000000 udf #0
+ 20a0: 00001fff udf #8191
+ 20a4: 00000000 udf #0
+ 20a8: 0000221f udf #8735
+ 20ac: 00000000 udf #0
+ 20b0: 0000221f udf #8735
+ 20b4: 00000000 udf #0
+ 20b8: 00001010 udf #4112
+ 20bc: 00001220 udf #4640
+ 20c0: 00001011 udf #4113
+ 20c4: 00001221 udf #4641
+ 20c8: 0000100f udf #4111
+ 20cc: 0000121f udf #4639
+ 20d0: 17ffffd0 b 2010 <foo>
+ 20d4: 17ffffd0 b 2014 <foo\+0x4>
+ 20d8: 17ffffcd b 200c <__rt_psrelocs_end\+0xc>
+ 20dc: 14000051 b 2220 <bar>
+ 20e0: 14000051 b 2224 <bar\+0x4>
+ 20e4: 1400004e b 221c <.text>
+ 20e8: 97ffffca bl 2010 <foo>
+ 20ec: 97ffffca bl 2014 <foo\+0x4>
+ 20f0: 97ffffc7 bl 200c <__rt_psrelocs_end\+0xc>
+ 20f4: 9400004b bl 2220 <bar>
+ 20f8: 9400004b bl 2224 <bar\+0x4>
+ 20fc: 94000048 bl 221c <.text>
+ 2100: 97ffffbf bl 1ffc <__ImageBase\+0xffc>
+ 2104: b4fff860 cbz x0, 2010 <foo>
+ 2108: b4fff860 cbz x0, 2014 <foo\+0x4>
+ 210c: b4fff800 cbz x0, 200c <__rt_psrelocs_end\+0xc>
+ 2110: b4000880 cbz x0, 2220 <bar>
+ 2114: b4000880 cbz x0, 2224 <bar\+0x4>
+ 2118: b4000820 cbz x0, 221c <.text>
+ 211c: b4fff700 cbz x0, 1ffc <__ImageBase\+0xffc>
+ 2120: 3607f780 tbz w0, #0, 2010 <foo>
+ 2124: 3607f780 tbz w0, #0, 2014 <foo\+0x4>
+ 2128: 3607f720 tbz w0, #0, 200c <__rt_psrelocs_end\+0xc>
+ 212c: 360007a0 tbz w0, #0, 2220 <bar>
+ 2130: 360007a0 tbz w0, #0, 2224 <bar\+0x4>
+ 2134: 36000740 tbz w0, #0, 221c <.text>
+ 2138: 3607f620 tbz w0, #0, 1ffc <__ImageBase\+0xffc>
+ 213c: 90000000 adrp x0, 2000 <__rt_psrelocs_end>
+ 2140: 90000000 adrp x0, 2000 <__rt_psrelocs_end>
+ 2144: 90000000 adrp x0, 2000 <__rt_psrelocs_end>
+ 2148: 90000000 adrp x0, 2000 <__rt_psrelocs_end>
+ 214c: 90000000 adrp x0, 2000 <__rt_psrelocs_end>
+ 2150: 90000000 adrp x0, 2000 <__rt_psrelocs_end>
+ 2154: f0ffffe0 adrp x0, 1000 <__ImageBase>
+ 2158: 10fff5c0 adr x0, 2010 <foo>
+ 215c: 30fff5a0 adr x0, 2011 <foo\+0x1>
+ 2160: 70fff560 adr x0, 200f <__rt_psrelocs_end\+0xf>
+ 2164: 100005e0 adr x0, 2220 <bar>
+ 2168: 300005c0 adr x0, 2221 <bar\+0x1>
+ 216c: 70000580 adr x0, 221f <.text\+0x3>
+ 2170: 70fff460 adr x0, 1fff <__ImageBase\+0xfff>
+ 2174: 39004000 strb w0, \[x0, #16\]
+ 2178: 39005000 strb w0, \[x0, #20\]
+ 217c: 39003000 strb w0, \[x0, #12\]
+ 2180: 39088000 strb w0, \[x0, #544\]
+ 2184: 39089000 strb w0, \[x0, #548\]
+ 2188: 39087000 strb w0, \[x0, #540\]
+ 218c: 393ff000 strb w0, \[x0, #4092\]
+ 2190: 79002000 strh w0, \[x0, #16\]
+ 2194: 79002800 strh w0, \[x0, #20\]
+ 2198: 79001800 strh w0, \[x0, #12\]
+ 219c: 79044000 strh w0, \[x0, #544\]
+ 21a0: 79044800 strh w0, \[x0, #548\]
+ 21a4: 79043800 strh w0, \[x0, #540\]
+ 21a8: 791ff800 strh w0, \[x0, #4092\]
+ 21ac: b9001000 str w0, \[x0, #16\]
+ 21b0: b9001400 str w0, \[x0, #20\]
+ 21b4: b9000c00 str w0, \[x0, #12\]
+ 21b8: b9022000 str w0, \[x0, #544\]
+ 21bc: b9022400 str w0, \[x0, #548\]
+ 21c0: b9021c00 str w0, \[x0, #540\]
+ 21c4: b90ffc00 str w0, \[x0, #4092\]
+ 21c8: f9000800 str x0, \[x0, #16\]
+ 21cc: f9000c00 str x0, \[x0, #24\]
+ 21d0: f9000400 str x0, \[x0, #8\]
+ 21d4: f9011000 str x0, \[x0, #544\]
+ 21d8: f9011400 str x0, \[x0, #552\]
+ 21dc: f9010c00 str x0, \[x0, #536\]
+ 21e0: f907fc00 str x0, \[x0, #4088\]
+ 21e4: 3d800400 str q0, \[x0, #16\]
+ 21e8: 3d800800 str q0, \[x0, #32\]
+ 21ec: 3d800000 str q0, \[x0\]
+ 21f0: 3d808800 str q0, \[x0, #544\]
+ 21f4: 3d808c00 str q0, \[x0, #560\]
+ 21f8: 3d808400 str q0, \[x0, #528\]
+ 21fc: 3d83fc00 str q0, \[x0, #4080\]
+ 2200: 91004000 add x0, x0, #0x10
+ 2204: 91004400 add x0, x0, #0x11
+ 2208: 91003c00 add x0, x0, #0xf
+ 220c: 91088000 add x0, x0, #0x220
+ 2210: 91088400 add x0, x0, #0x221
+ 2214: 91087c00 add x0, x0, #0x21f
+ 2218: 913ffc00 add x0, x0, #0xfff
+
+000000000000221c <.text>:
+ 221c: 00000000 udf #0
+
+0000000000002220 <bar>:
+ 2220: 9abcdef0 .inst 0x9abcdef0 ; undefined
+ 2224: 12345678 and w24, w19, #0xfffff003
+
+0000000000002228 <__CTOR_LIST__>:
+ 2228: ffffffff .inst 0xffffffff ; undefined
+ 222c: ffffffff .inst 0xffffffff ; undefined
+ ...
+
+0000000000002238 <__DTOR_LIST__>:
+ 2238: ffffffff .inst 0xffffffff ; undefined
+ 223c: ffffffff .inst 0xffffffff ; undefined
+ ...
diff --git a/ld/testsuite/ld-pe/aarch64a.s b/ld/testsuite/ld-pe/aarch64a.s
new file mode 100644
index 0000000..58b8f5a
--- /dev/null
+++ b/ld/testsuite/ld-pe/aarch64a.s
@@ -0,0 +1,159 @@
+.text
+
+.dword 0
+.dword 0
+
+# 2010
+.global foo
+foo:
+
+# 4-byte literal
+.long 0x12345678
+.word 0x12345678
+
+# IMAGE_REL_ARM64_ADDR32 (BFD_RELOC_32)
+.long foo
+.word foo
+.long bar
+.word bar
+.long foo + 1
+.word foo + 1
+.long bar + 1
+.word bar + 1
+.long foo - 1
+.word foo - 1
+.long bar - 1
+.word bar - 1
+
+# 8-byte literal
+.dword 0x123456789abcdef0
+.xword 0x123456789abcdef0
+
+# IMAGE_REL_ARM64_ADDR64 (BFD_RELOC_64)
+.dword foo
+.xword foo
+.dword bar
+.xword bar
+.dword foo + 1
+.xword foo + 1
+.dword bar + 1
+.xword bar + 1
+.dword foo - 1
+.xword foo - 1
+.dword bar - 1
+.xword bar - 1
+
+# IMAGE_REL_ARM64_ADDR32NB (BFD_RELOC_RVA)
+.rva foo
+.rva bar
+.rva foo + 1
+.rva bar + 1
+.rva foo - 1
+.rva bar - 1
+
+# IMAGE_REL_ARM64_BRANCH26 (BFD_RELOC_AARCH64_JUMP26)
+b foo
+b foo + 4
+b foo - 4
+b bar
+b bar + 4
+b bar - 4
+
+# IMAGE_REL_ARM64_BRANCH26 (BFD_RELOC_AARCH64_CALL26)
+bl foo
+bl foo + 4
+bl foo - 4
+bl bar
+bl bar + 4
+bl bar - 4
+bl .text - 4
+
+# IMAGE_REL_ARM64_BRANCH19 (BFD_RELOC_AARCH64_BRANCH19)
+cbz x0, foo
+cbz x0, foo + 4
+cbz x0, foo - 4
+cbz x0, bar
+cbz x0, bar + 4
+cbz x0, bar - 4
+cbz x0, .text - 4
+
+# IMAGE_REL_ARM64_BRANCH14 (BFD_RELOC_AARCH64_TSTBR14)
+tbz x0, 0, foo
+tbz x0, 0, foo + 4
+tbz x0, 0, foo - 4
+tbz x0, 0, bar
+tbz x0, 0, bar + 4
+tbz x0, 0, bar - 4
+tbz x0, 0, .text - 4
+
+# IMAGE_REL_ARM64_PAGEBASE_REL21 (BFD_RELOC_AARCH64_ADR_HI21_PCREL)
+adrp x0, foo
+adrp x0, foo + 1
+adrp x0, foo - 1
+adrp x0, bar
+adrp x0, bar + 1
+adrp x0, bar - 1
+adrp x0, .text - 4
+
+# IMAGE_REL_ARM64_REL21 (BFD_RELOC_AARCH64_ADR_LO21_PCREL)
+adr x0, foo
+adr x0, foo + 1
+adr x0, foo - 1
+adr x0, bar
+adr x0, bar + 1
+adr x0, bar - 1
+adr x0, .text - 1
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST8_LO12)
+strb w0, [x0,:lo12:foo]
+strb w0, [x0,:lo12:foo + 4]
+strb w0, [x0,:lo12:foo - 4]
+strb w0, [x0,:lo12:bar]
+strb w0, [x0,:lo12:bar + 4]
+strb w0, [x0,:lo12:bar - 4]
+strb w0, [x0,:lo12:.text - 4]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST16_LO12)
+strh w0, [x0,:lo12:foo]
+strh w0, [x0,:lo12:foo + 4]
+strh w0, [x0,:lo12:foo - 4]
+strh w0, [x0,:lo12:bar]
+strh w0, [x0,:lo12:bar + 4]
+strh w0, [x0,:lo12:bar - 4]
+strh w0, [x0,:lo12:.text - 4]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST32_LO12)
+str w0, [x0,:lo12:foo]
+str w0, [x0,:lo12:foo + 4]
+str w0, [x0,:lo12:foo - 4]
+str w0, [x0,:lo12:bar]
+str w0, [x0,:lo12:bar + 4]
+str w0, [x0,:lo12:bar - 4]
+str w0, [x0,:lo12:.text - 4]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST64_LO12)
+str x0, [x0,:lo12:foo]
+str x0, [x0,:lo12:foo + 8]
+str x0, [x0,:lo12:foo - 8]
+str x0, [x0,:lo12:bar]
+str x0, [x0,:lo12:bar + 8]
+str x0, [x0,:lo12:bar - 8]
+str x0, [x0,:lo12:.text - 8]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST128_LO12)
+str q0, [x0,:lo12:foo]
+str q0, [x0,:lo12:foo + 16]
+str q0, [x0,:lo12:foo - 16]
+str q0, [x0,:lo12:bar]
+str q0, [x0,:lo12:bar + 16]
+str q0, [x0,:lo12:bar - 16]
+str q0, [x0,:lo12:.text - 16]
+
+# IMAGE_REL_ARM64_PAGEOFFSET_12A (BFD_RELOC_AARCH64_ADD_LO12)
+add x0, x0, #:lo12:foo
+add x0, x0, #:lo12:foo + 1
+add x0, x0, #:lo12:foo - 1
+add x0, x0, #:lo12:bar
+add x0, x0, #:lo12:bar + 1
+add x0, x0, #:lo12:bar - 1
+add x0, x0, #:lo12:.text - 1
diff --git a/ld/testsuite/ld-pe/aarch64b.s b/ld/testsuite/ld-pe/aarch64b.s
new file mode 100644
index 0000000..3f4ec48
--- /dev/null
+++ b/ld/testsuite/ld-pe/aarch64b.s
@@ -0,0 +1,8 @@
+.text
+
+.long 0
+
+# 2220
+.global bar
+bar:
+.dword 0x123456789abcdef0
diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp
index 613635f..c22c6d4 100644
--- a/ld/testsuite/ld-pe/pe.exp
+++ b/ld/testsuite/ld-pe/pe.exp
@@ -79,9 +79,15 @@ if {[istarget i*86-*-cygwin*]
}
if {[istarget "aarch64-*-pe*"]} {
- run_dump_test "pe-aarch64"
-}
+ run_dump_test "pe-aarch64"
+
+ set pe_tests {
+ {"aarch64" "--image-base 0x1000" "" "" {aarch64a.s aarch64b.s}
+ {{objdump -dr aarch64.d}} "aarch64.x"}
+ }
+ run_ld_link_tests $pe_tests
+}
run_dump_test "image_size"
run_dump_test "export_dynamic_warning"