Browse Source

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.
users/ahajkova/try-frob
Mark Harmstone 4 years ago
parent
commit
b152649d51
  1. 674
      bfd/coff-aarch64.c
  2. 6
      bfd/config.bfd
  3. 24
      gas/config/tc-aarch64.c
  4. 230
      gas/testsuite/gas/pe/pe-aarch64.d
  5. 162
      gas/testsuite/gas/pe/pe-aarch64.s
  6. 158
      ld/testsuite/ld-pe/aarch64.d
  7. 159
      ld/testsuite/ld-pe/aarch64a.s
  8. 8
      ld/testsuite/ld-pe/aarch64b.s
  9. 10
      ld/testsuite/ld-pe/pe.exp

674
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),

6
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*)

24
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,11 +2124,13 @@ 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'},
@ -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"),

230
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

162
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

158
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
...

159
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

8
ld/testsuite/ld-pe/aarch64b.s

@ -0,0 +1,8 @@
.text
.long 0
# 2220
.global bar
bar:
.dword 0x123456789abcdef0

10
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"

Loading…
Cancel
Save