mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
aarch64-pe support for LD, GAS and BFD
Allows aarch64-pe to be targeted natively, not having to use objcopy to convert it from ELF to PE. Based on initial work by Jedidiah Thompson Co-authored-by: Jedidiah Thompson <wej22007@outlook.com> Co-authored-by: Zac Walker <zac.walker@linaro.org>
This commit is contained in:
parent
740a19d914
commit
c60b380679
@ -578,6 +578,7 @@ BFD64_BACKENDS = \
|
||||
pe-loongarch64igen.lo \
|
||||
pe-x86_64.lo \
|
||||
pei-aarch64.lo \
|
||||
pe-aarch64.lo \
|
||||
pei-ia64.lo \
|
||||
pei-loongarch64.lo \
|
||||
pei-x86_64.lo \
|
||||
@ -619,6 +620,7 @@ BFD64_BACKENDS_CFILES = \
|
||||
mach-o-aarch64.c \
|
||||
mach-o-x86-64.c \
|
||||
mmo.c \
|
||||
pe-aarch64.c \
|
||||
pe-x86_64.c \
|
||||
pei-aarch64.c \
|
||||
pei-ia64.c \
|
||||
|
@ -1089,6 +1089,7 @@ BFD64_BACKENDS_CFILES = \
|
||||
mach-o-aarch64.c \
|
||||
mach-o-x86-64.c \
|
||||
mmo.c \
|
||||
pe-aarch64.c \
|
||||
pe-x86_64.c \
|
||||
pei-aarch64.c \
|
||||
pei-ia64.c \
|
||||
|
@ -523,6 +523,7 @@ DESCRIPTION
|
||||
.#define bfd_mach_aarch64 0
|
||||
.#define bfd_mach_aarch64_8R 1
|
||||
.#define bfd_mach_aarch64_ilp32 32
|
||||
.#define bfd_mach_aarch64_llp64 64
|
||||
. bfd_arch_nios2, {* Nios II. *}
|
||||
.#define bfd_mach_nios2 0
|
||||
.#define bfd_mach_nios2r1 1
|
||||
|
@ -1857,6 +1857,7 @@ enum bfd_architecture
|
||||
#define bfd_mach_aarch64 0
|
||||
#define bfd_mach_aarch64_8R 1
|
||||
#define bfd_mach_aarch64_ilp32 32
|
||||
#define bfd_mach_aarch64_llp64 64
|
||||
bfd_arch_nios2, /* Nios II. */
|
||||
#define bfd_mach_nios2 0
|
||||
#define bfd_mach_nios2r1 1
|
||||
|
@ -1743,6 +1743,7 @@ bfd_get_sign_extend_vma (bfd *abfd)
|
||||
|| strcmp (name, "pei-i386") == 0
|
||||
|| strcmp (name, "pe-x86-64") == 0
|
||||
|| strcmp (name, "pei-x86-64") == 0
|
||||
|| strcmp (name, "pe-aarch64-little") == 0
|
||||
|| strcmp (name, "pei-aarch64-little") == 0
|
||||
|| strcmp (name, "pe-arm-wince-little") == 0
|
||||
|| strcmp (name, "pei-arm-wince-little") == 0
|
||||
|
@ -39,34 +39,150 @@
|
||||
|
||||
#include "libcoff.h"
|
||||
|
||||
/* The page size is a guess based on ELF. */
|
||||
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
|
||||
#define MINUS_ONE (~ (bfd_vma) 0)
|
||||
|
||||
#define COFF_PAGE_SIZE 0x1000
|
||||
static const reloc_howto_type arm64_reloc_howto_64 = HOWTO(IMAGE_REL_ARM64_ADDR64, 0, 8, 64, false, 0,
|
||||
complain_overflow_bitfield,
|
||||
NULL, "64",
|
||||
false, MINUS_ONE, MINUS_ONE, false);
|
||||
|
||||
/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
|
||||
#define OCTETS_PER_BYTE(ABFD, SEC) 1
|
||||
static const reloc_howto_type arm64_reloc_howto_32 = HOWTO (IMAGE_REL_ARM64_ADDR32, 0, 4, 32, false, 0,
|
||||
complain_overflow_bitfield,
|
||||
NULL, "32",
|
||||
false, 0xffffffff, 0xffffffff, false);
|
||||
|
||||
#ifndef PCRELOFFSET
|
||||
#define PCRELOFFSET true
|
||||
#endif
|
||||
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",
|
||||
false, 0xffffffff, 0xffffffff, true);
|
||||
|
||||
/* Currently we don't handle any relocations. */
|
||||
static reloc_howto_type pe_aarch64_std_reloc_howto[] =
|
||||
{
|
||||
static const reloc_howto_type arm64_reloc_howto_branch26 = HOWTO (IMAGE_REL_ARM64_BRANCH26, 0, 4, 26, true, 0,
|
||||
complain_overflow_bitfield,
|
||||
NULL, "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",
|
||||
false, 0x1fffff, 0x1fffff, false);
|
||||
|
||||
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
|
||||
#define COFF_PAGE_SIZE 0x1000
|
||||
static const reloc_howto_type arm64_reloc_howto_lo21 = HOWTO (IMAGE_REL_ARM64_REL21, 0, 4, 21, true, 0,
|
||||
complain_overflow_signed,
|
||||
NULL, "LO21",
|
||||
false, 0x1fffff, 0x1fffff, true);
|
||||
|
||||
static const reloc_howto_type arm64_reloc_howto_pgoff12 = HOWTO (IMAGE_REL_ARM64_PAGEOFFSET_12L, 1, 4, 12, true, 0,
|
||||
complain_overflow_signed,
|
||||
NULL, "PGOFF12",
|
||||
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",
|
||||
false, 0x7ffff, 0x7ffff, true);
|
||||
|
||||
|
||||
static const reloc_howto_type* const arm64_howto_table[] = {
|
||||
&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
|
||||
};
|
||||
|
||||
#ifndef NUM_ELEM
|
||||
#define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
|
||||
#endif
|
||||
|
||||
#define NUM_RELOCS NUM_ELEM (pe_aarch64_std_reloc_howto)
|
||||
#define NUM_RELOCS NUM_ELEM (arm64_howto_table)
|
||||
|
||||
#define RTYPE2HOWTO(cache_ptr, dst) \
|
||||
(cache_ptr)->howto = NULL
|
||||
#define coff_bfd_reloc_type_lookup coff_aarch64_reloc_type_lookup
|
||||
#define coff_bfd_reloc_name_lookup coff_aarch64_reloc_name_lookup
|
||||
|
||||
static reloc_howto_type *
|
||||
coff_aarch64_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case BFD_RELOC_64:
|
||||
return &arm64_reloc_howto_64;
|
||||
case BFD_RELOC_32:
|
||||
return &arm64_reloc_howto_32;
|
||||
case BFD_RELOC_32_PCREL:
|
||||
return &arm64_reloc_howto_32_pcrel;
|
||||
case BFD_RELOC_AARCH64_CALL26:
|
||||
case BFD_RELOC_AARCH64_JUMP26:
|
||||
return &arm64_reloc_howto_branch26;
|
||||
case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
|
||||
return &arm64_reloc_howto_page21;
|
||||
case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
|
||||
return &arm64_reloc_howto_lo21;
|
||||
case BFD_RELOC_AARCH64_LDST16_LO12:
|
||||
return &arm64_reloc_howto_pgoff12;
|
||||
case BFD_RELOC_AARCH64_BRANCH19:
|
||||
return &arm64_reloc_howto_branch19;
|
||||
default:
|
||||
BFD_FAIL ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static reloc_howto_type *
|
||||
coff_aarch64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
const char *r_name)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NUM_RELOCS; i++)
|
||||
if (arm64_howto_table[i]->name != NULL
|
||||
&& strcasecmp (arm64_howto_table[i]->name, r_name) == 0)
|
||||
return arm64_howto_table[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
|
||||
#define COFF_PAGE_SIZE 0x1000
|
||||
|
||||
static reloc_howto_type *
|
||||
coff_aarch64_rtype_lookup (unsigned int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case IMAGE_REL_ARM64_ADDR64:
|
||||
return &arm64_reloc_howto_64;
|
||||
case IMAGE_REL_ARM64_ADDR32:
|
||||
return &arm64_reloc_howto_32;
|
||||
case IMAGE_REL_ARM64_REL32:
|
||||
return &arm64_reloc_howto_32_pcrel;
|
||||
case IMAGE_REL_ARM64_BRANCH26:
|
||||
return &arm64_reloc_howto_branch26;
|
||||
case IMAGE_REL_ARM64_PAGEBASE_REL21:
|
||||
return &arm64_reloc_howto_page21;
|
||||
case IMAGE_REL_ARM64_REL21:
|
||||
return &arm64_reloc_howto_lo21;
|
||||
case IMAGE_REL_ARM64_PAGEOFFSET_12L:
|
||||
return &arm64_reloc_howto_pgoff12;
|
||||
case IMAGE_REL_ARM64_BRANCH19:
|
||||
return &arm64_reloc_howto_branch19;
|
||||
default:
|
||||
BFD_FAIL ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define RTYPE2HOWTO(cache_ptr, dst) \
|
||||
((cache_ptr)->howto = coff_aarch64_rtype_lookup((dst)->r_type))
|
||||
|
||||
#define SELECT_RELOC(x,howto) { (x).r_type = (howto)->type; }
|
||||
|
||||
#ifndef bfd_pe_print_pdata
|
||||
#define bfd_pe_print_pdata NULL
|
||||
@ -93,13 +209,13 @@ const bfd_target
|
||||
#ifdef TARGET_SYM
|
||||
TARGET_SYM =
|
||||
#else
|
||||
aarch64_pei_vec =
|
||||
# error "target symbol name not specified"
|
||||
#endif
|
||||
{
|
||||
#ifdef TARGET_NAME
|
||||
TARGET_NAME,
|
||||
#else
|
||||
"pei-aarch64-little", /* Name. */
|
||||
# error "target name not specified"
|
||||
#endif
|
||||
bfd_target_coff_flavour,
|
||||
BFD_ENDIAN_LITTLE, /* Data byte order is little. */
|
||||
@ -125,14 +241,14 @@ const bfd_target
|
||||
0, /* match priority. */
|
||||
TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
|
||||
|
||||
/* Data conversion functions. */
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
|
||||
/* Header conversion functions. */
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
|
||||
/* Data conversion functions. */
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
|
||||
/* Header conversion functions. */
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
|
||||
|
||||
/* Note that we allow an object file to be treated as a core file as well. */
|
||||
{ /* bfd_check_format. */
|
||||
|
@ -245,9 +245,15 @@ case "${targ}" in
|
||||
;;
|
||||
aarch64-*-elf | aarch64-*-rtems* | aarch64-*-genode*)
|
||||
targ_defvec=aarch64_elf64_le_vec
|
||||
targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
|
||||
targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec aarch64_pe_le_vec"
|
||||
want64=true
|
||||
;;
|
||||
aarch64-*-pe*)
|
||||
targ_defvec=aarch64_pe_le_vec
|
||||
targ_selvecs="aarch64_pe_le_vec aarch64_pei_le_vec"
|
||||
want64=true
|
||||
targ_underscore=no
|
||||
;;
|
||||
aarch64_be-*-elf)
|
||||
targ_defvec=aarch64_elf64_be_vec
|
||||
targ_selvecs="aarch64_elf64_le_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_be_vec arm_elf32_le_vec"
|
||||
@ -280,7 +286,7 @@ case "${targ}" in
|
||||
;;
|
||||
aarch64-*-linux* | aarch64-*-netbsd*)
|
||||
targ_defvec=aarch64_elf64_le_vec
|
||||
targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
|
||||
targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec aarch64_pe_le_vec"
|
||||
want64=true
|
||||
;;
|
||||
aarch64_be-*-linux* | aarch64_be-*-netbsd*)
|
||||
@ -1488,6 +1494,12 @@ 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*)
|
||||
|
3
bfd/configure
vendored
3
bfd/configure
vendored
@ -13603,7 +13603,8 @@ do
|
||||
aarch64_elf64_le_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
|
||||
aarch64_elf64_le_cloudabi_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
|
||||
aarch64_mach_o_vec) tb="$tb mach-o-aarch64.lo"; target_size=64 ;;
|
||||
aarch64_pei_vec) tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
|
||||
aarch64_pei_le_vec) tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
|
||||
aarch64_pe_le_vec) tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
|
||||
alpha_ecoff_le_vec) tb="$tb coff-alpha.lo ecoff.lo $ecoff"; target_size=64 ;;
|
||||
alpha_elf64_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
|
||||
alpha_elf64_fbsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
|
||||
|
@ -404,7 +404,8 @@ do
|
||||
aarch64_elf64_le_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
|
||||
aarch64_elf64_le_cloudabi_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
|
||||
aarch64_mach_o_vec) tb="$tb mach-o-aarch64.lo"; target_size=64 ;;
|
||||
aarch64_pei_vec) tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
|
||||
aarch64_pei_le_vec) tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
|
||||
aarch64_pe_le_vec) tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
|
||||
alpha_ecoff_le_vec) tb="$tb coff-alpha.lo ecoff.lo $ecoff"; target_size=64 ;;
|
||||
alpha_elf64_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
|
||||
alpha_elf64_fbsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
|
||||
|
@ -39,8 +39,8 @@ compatible (const bfd_arch_info_type * a, const bfd_arch_info_type * b)
|
||||
if (a->mach == b->mach)
|
||||
return a;
|
||||
|
||||
/* Don't allow mixing ilp32 with lp64. */
|
||||
if ((a->mach & bfd_mach_aarch64_ilp32) != (b->mach & bfd_mach_aarch64_ilp32))
|
||||
/* Don't allow mixing data models. */
|
||||
if ((a->mach ^ b->mach) & (bfd_mach_aarch64_ilp32 | bfd_mach_aarch64_llp64))
|
||||
return NULL;
|
||||
|
||||
/* Otherwise if either a or b is the 'default' machine
|
||||
@ -102,20 +102,33 @@ scan (const struct bfd_arch_info *info, const char *string)
|
||||
return false;
|
||||
}
|
||||
|
||||
#define N(NUMBER, PRINT, WORDSIZE, DEFAULT, NEXT) \
|
||||
{ WORDSIZE, WORDSIZE, 8, bfd_arch_aarch64, NUMBER, \
|
||||
"aarch64", PRINT, 4, DEFAULT, compatible, scan, \
|
||||
bfd_arch_default_fill, NEXT, 0 }
|
||||
/* Figure out if llp64 is default */
|
||||
#if DEFAULT_VECTOR == aarch64_pe_le_vec
|
||||
#define LLP64_DEFAULT true
|
||||
#define AARCH64_DEFAULT false
|
||||
#else
|
||||
#define LLP64_DEFAULT false
|
||||
#define AARCH64_DEFAULT true
|
||||
#endif
|
||||
|
||||
static const bfd_arch_info_type bfd_aarch64_arch_v8_r =
|
||||
N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, false, NULL);
|
||||
#define N(NUMBER, PRINT, WORDSIZE, ADDRSIZE, DEFAULT, NEXT) \
|
||||
{ WORDSIZE, ADDRSIZE, 8, bfd_arch_aarch64, NUMBER, \
|
||||
"aarch64", PRINT, 4, DEFAULT, compatible, scan, \
|
||||
bfd_arch_default_fill, NEXT, 0 }
|
||||
|
||||
static const bfd_arch_info_type bfd_aarch64_arch_v8_r =
|
||||
N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, 64, false, NULL);
|
||||
|
||||
static const bfd_arch_info_type bfd_aarch64_arch_ilp32 =
|
||||
N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, false,
|
||||
N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, 32, false,
|
||||
&bfd_aarch64_arch_v8_r);
|
||||
|
||||
const bfd_arch_info_type bfd_aarch64_arch =
|
||||
N (0, "aarch64", 64, true, &bfd_aarch64_arch_ilp32);
|
||||
static const bfd_arch_info_type bfd_aarch64_arch_llp64 =
|
||||
N (bfd_mach_aarch64_llp64, "aarch64:llp64", 32, 64, LLP64_DEFAULT,
|
||||
&bfd_aarch64_arch_ilp32);
|
||||
|
||||
const bfd_arch_info_type bfd_aarch64_arch =
|
||||
N (0, "aarch64", 64, 64, AARCH64_DEFAULT, &bfd_aarch64_arch_llp64);
|
||||
|
||||
bool
|
||||
bfd_is_aarch64_special_symbol_name (const char *name, int type)
|
||||
|
74
bfd/pe-aarch64.c
Normal file
74
bfd/pe-aarch64.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* BFD back-end for AArch64 PE IMAGE COFF files.
|
||||
Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "bfd.h"
|
||||
|
||||
#define TARGET_SYM aarch64_pe_le_vec
|
||||
#define TARGET_NAME "pe-aarch64-little"
|
||||
#define TARGET_ARCHITECTURE bfd_arch_aarch64
|
||||
#define TARGET_PAGESIZE 4096
|
||||
#define TARGET_BIG_ENDIAN 0
|
||||
#define TARGET_ARCHIVE 0
|
||||
#define TARGET_PRIORITY 0
|
||||
|
||||
/* Rename the above into.. */
|
||||
#define COFF_WITH_peAArch64
|
||||
#define COFF_WITH_PE
|
||||
#define PCRELOFFSET true
|
||||
|
||||
/* Long section names not allowed in executable images, only object files. */
|
||||
#define COFF_LONG_SECTION_NAMES 1
|
||||
|
||||
#define COFF_SECTION_ALIGNMENT_ENTRIES \
|
||||
{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
|
||||
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
|
||||
{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
|
||||
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
|
||||
{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
|
||||
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
|
||||
{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
|
||||
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
|
||||
{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
|
||||
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
|
||||
{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
|
||||
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
|
||||
{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
|
||||
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
|
||||
{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
|
||||
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
|
||||
|
||||
#define PEI_HEADERS
|
||||
#include "sysdep.h"
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
||||
#include "coff/aarch64.h"
|
||||
#include "coff/internal.h"
|
||||
#include "coff/pe.h"
|
||||
#include "libcoff.h"
|
||||
#include "libpei.h"
|
||||
#include "libiberty.h"
|
||||
|
||||
/* Make sure we're setting a 64-bit format. */
|
||||
#undef AOUTSZ
|
||||
#define AOUTSZ PEPAOUTSZ
|
||||
#define PEAOUTHDR PEPAOUTHDR
|
||||
|
||||
#include "coff-aarch64.c"
|
@ -21,7 +21,7 @@
|
||||
#include "sysdep.h"
|
||||
#include "bfd.h"
|
||||
|
||||
#define TARGET_SYM aarch64_pei_vec
|
||||
#define TARGET_SYM aarch64_pei_le_vec
|
||||
#define TARGET_NAME "pei-aarch64-little"
|
||||
#define TARGET_ARCHITECTURE bfd_arch_aarch64
|
||||
#define TARGET_PAGESIZE 4096
|
||||
|
@ -191,6 +191,8 @@ coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
|
||||
|
||||
#ifdef COFF_IMAGE_WITH_PE
|
||||
# define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
|
||||
#elif defined COFF_WITH_peAArch64
|
||||
# define coff_swap_filehdr_out _bfd_XX_only_swap_filehdr_out
|
||||
#elif defined COFF_WITH_pex64
|
||||
# define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
|
||||
#elif defined COFF_WITH_pep
|
||||
|
@ -313,6 +313,7 @@ osf-core.c
|
||||
pc532-mach.c
|
||||
pdb.c
|
||||
pdp11.c
|
||||
pe-aarch64.c
|
||||
pe-arm-wince.c
|
||||
pe-arm.c
|
||||
pe-i386.c
|
||||
|
@ -686,7 +686,8 @@ extern const bfd_target aarch64_elf64_be_cloudabi_vec;
|
||||
extern const bfd_target aarch64_elf64_le_vec;
|
||||
extern const bfd_target aarch64_elf64_le_cloudabi_vec;
|
||||
extern const bfd_target aarch64_mach_o_vec;
|
||||
extern const bfd_target aarch64_pei_vec;
|
||||
extern const bfd_target aarch64_pei_le_vec;
|
||||
extern const bfd_target aarch64_pe_le_vec;
|
||||
extern const bfd_target alpha_ecoff_le_vec;
|
||||
extern const bfd_target alpha_elf64_vec;
|
||||
extern const bfd_target alpha_elf64_fbsd_vec;
|
||||
@ -999,7 +1000,8 @@ static const bfd_target * const _bfd_target_vector[] =
|
||||
&aarch64_elf64_le_vec,
|
||||
&aarch64_elf64_le_cloudabi_vec,
|
||||
&aarch64_mach_o_vec,
|
||||
&aarch64_pei_vec,
|
||||
&aarch64_pe_le_vec,
|
||||
&aarch64_pei_le_vec,
|
||||
#endif
|
||||
|
||||
#ifdef BFD64
|
||||
|
@ -40,6 +40,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef TC_AARCH64
|
||||
#include "coff/aarch64.h"
|
||||
#endif
|
||||
|
||||
#ifdef TC_PPC
|
||||
#include "coff/rs6000.h"
|
||||
#endif
|
||||
|
@ -30,9 +30,9 @@
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
#include "elf/aarch64.h"
|
||||
#include "dw2gencfi.h"
|
||||
#endif
|
||||
|
||||
#include "dw2gencfi.h"
|
||||
#include "dwarf2dbg.h"
|
||||
|
||||
/* Types of processor to assemble for. */
|
||||
@ -61,21 +61,25 @@ static aarch64_instr_sequence *insn_sequence = NULL;
|
||||
#ifdef OBJ_ELF
|
||||
/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
|
||||
static symbolS *GOT_symbol;
|
||||
#endif
|
||||
|
||||
/* Which ABI to use. */
|
||||
enum aarch64_abi_type
|
||||
{
|
||||
AARCH64_ABI_NONE = 0,
|
||||
AARCH64_ABI_LP64 = 1,
|
||||
AARCH64_ABI_ILP32 = 2
|
||||
AARCH64_ABI_ILP32 = 2,
|
||||
AARCH64_ABI_LLP64 = 3
|
||||
};
|
||||
|
||||
#ifndef DEFAULT_ARCH
|
||||
#define DEFAULT_ARCH "aarch64"
|
||||
#endif
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
/* DEFAULT_ARCH is initialized in gas/configure.tgt. */
|
||||
static const char *default_arch = DEFAULT_ARCH;
|
||||
#endif
|
||||
|
||||
/* AArch64 ABI for the output file. */
|
||||
static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
|
||||
@ -85,7 +89,10 @@ static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
|
||||
64-bit model, in which the C int type is 32-bits but the C long type
|
||||
and all pointer types are 64-bit objects (LP64). */
|
||||
#define ilp32_p (aarch64_abi == AARCH64_ABI_ILP32)
|
||||
#endif
|
||||
|
||||
/* When non zero, C types int and long are 32 bit,
|
||||
pointers, however are 64 bit */
|
||||
#define llp64_p (aarch64_abi == AARCH64_ABI_LLP64)
|
||||
|
||||
enum vector_el_type
|
||||
{
|
||||
@ -1459,7 +1466,7 @@ s_unreq (int a ATTRIBUTE_UNUSED)
|
||||
|
||||
/* Directives: Instruction set selection. */
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
#if defined OBJ_ELF || defined OBJ_COFF
|
||||
/* This code is to handle mapping symbols as defined in the ARM AArch64 ELF
|
||||
spec. (See "Mapping symbols", section 4.5.4, ARM AAELF64 version 0.05).
|
||||
Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
|
||||
@ -8336,7 +8343,7 @@ aarch64_handle_align (fragS * fragP)
|
||||
fix = bytes & (noop_size - 1);
|
||||
if (fix)
|
||||
{
|
||||
#ifdef OBJ_ELF
|
||||
#if defined OBJ_ELF || defined OBJ_COFF
|
||||
insert_data_mapping_symbol (MAP_INSN, fragP->fr_fix, fragP, fix);
|
||||
#endif
|
||||
memset (p, 0, fix);
|
||||
@ -8394,6 +8401,7 @@ aarch64_init_frag (fragS * fragP, int max_chars)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
/* Initialize the DWARF-2 unwind information for this procedure. */
|
||||
|
||||
@ -8402,7 +8410,6 @@ tc_aarch64_frame_initial_instructions (void)
|
||||
{
|
||||
cfi_add_CFA_def_cfa (REG_SP, 0);
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
/* Convert REGNAME to a DWARF-2 register number. */
|
||||
|
||||
@ -8439,10 +8446,10 @@ tc_aarch64_regname_to_dw2regnum (char *regname)
|
||||
int
|
||||
aarch64_dwarf2_addr_size (void)
|
||||
{
|
||||
#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
|
||||
if (ilp32_p)
|
||||
return 4;
|
||||
#endif
|
||||
else if (llp64_p)
|
||||
return 8;
|
||||
return bfd_arch_bits_per_address (stdoutput) / 8;
|
||||
}
|
||||
|
||||
@ -9307,8 +9314,6 @@ cons_fix_new_aarch64 (fragS * frag, int where, int size, expressionS * exp)
|
||||
fix_new_exp (frag, where, (int) size, exp, pcrel, type);
|
||||
}
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
|
||||
/* Implement md_after_parse_args. This is the earliest time we need to decide
|
||||
ABI. If no -mabi specified, the ABI will be decided by target triplet. */
|
||||
|
||||
@ -9318,13 +9323,18 @@ aarch64_after_parse_args (void)
|
||||
if (aarch64_abi != AARCH64_ABI_NONE)
|
||||
return;
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
/* DEFAULT_ARCH will have ":32" extension if it's configured for ILP32. */
|
||||
if (strlen (default_arch) > 7 && strcmp (default_arch + 7, ":32") == 0)
|
||||
aarch64_abi = AARCH64_ABI_ILP32;
|
||||
else
|
||||
aarch64_abi = AARCH64_ABI_LP64;
|
||||
#else
|
||||
aarch64_abi = AARCH64_ABI_LLP64;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
const char *
|
||||
elf64_aarch64_target_format (void)
|
||||
{
|
||||
@ -9347,6 +9357,12 @@ aarch64elf_frob_symbol (symbolS * symp, int *puntp)
|
||||
{
|
||||
elf_frob_symbol (symp, puntp);
|
||||
}
|
||||
#elif defined OBJ_COFF
|
||||
const char *
|
||||
coff_aarch64_target_format (void)
|
||||
{
|
||||
return "pe-aarch64-little";
|
||||
}
|
||||
#endif
|
||||
|
||||
/* MD interface: Finalization. */
|
||||
@ -9662,7 +9678,12 @@ md_begin (void)
|
||||
cpu_variant = *mcpu_cpu_opt;
|
||||
|
||||
/* Record the CPU type. */
|
||||
mach = ilp32_p ? bfd_mach_aarch64_ilp32 : bfd_mach_aarch64;
|
||||
if(ilp32_p)
|
||||
mach = bfd_mach_aarch64_ilp32;
|
||||
else if (llp64_p)
|
||||
mach = bfd_mach_aarch64_llp64;
|
||||
else
|
||||
mach = bfd_mach_aarch64;
|
||||
|
||||
bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
|
||||
}
|
||||
@ -10230,8 +10251,12 @@ struct aarch64_option_abi_value_table
|
||||
};
|
||||
|
||||
static const struct aarch64_option_abi_value_table aarch64_abis[] = {
|
||||
#ifdef OBJ_ELF
|
||||
{"ilp32", AARCH64_ABI_ILP32},
|
||||
{"lp64", AARCH64_ABI_LP64},
|
||||
#else
|
||||
{"llp64", AARCH64_ABI_LLP64},
|
||||
#endif
|
||||
};
|
||||
|
||||
static int
|
||||
@ -10257,10 +10282,8 @@ aarch64_parse_abi (const char *str)
|
||||
}
|
||||
|
||||
static struct aarch64_long_option_table aarch64_long_opts[] = {
|
||||
#ifdef OBJ_ELF
|
||||
{"mabi=", N_("<abi name>\t specify for ABI <abi name>"),
|
||||
aarch64_parse_abi, NULL},
|
||||
#endif /* OBJ_ELF */
|
||||
{"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
|
||||
aarch64_parse_cpu, NULL},
|
||||
{"march=", N_("<arch name>\t assemble for architecture <arch name>"),
|
||||
|
@ -59,9 +59,11 @@ struct aarch64_fix
|
||||
enum aarch64_opnd opnd;
|
||||
};
|
||||
|
||||
#if defined OBJ_ELF
|
||||
#ifdef OBJ_ELF
|
||||
# define AARCH64_BI_ENDIAN
|
||||
# define TARGET_FORMAT elf64_aarch64_target_format ()
|
||||
#elif defined (OBJ_COFF)
|
||||
# define TARGET_FORMAT coff_aarch64_target_format ()
|
||||
#endif
|
||||
|
||||
#define TC_FORCE_RELOCATION(FIX) aarch64_force_relocation (FIX)
|
||||
@ -169,7 +171,7 @@ void aarch64_elf_copy_symbol_attributes (symbolS *, symbolS *);
|
||||
struct aarch64_frag_type
|
||||
{
|
||||
int recorded;
|
||||
#ifdef OBJ_ELF
|
||||
#if defined OBJ_ELF || defined OBJ_COFF
|
||||
/* If there is a mapping symbol at offset 0 in this frag,
|
||||
it will be saved in FIRST_MAP. If there are any mapping
|
||||
symbols in this frag, the last one will be saved in
|
||||
@ -202,8 +204,10 @@ struct aarch64_frag_type
|
||||
extern int aarch64_dwarf2_addr_size (void);
|
||||
#define DWARF2_ADDR_SIZE(bfd) aarch64_dwarf2_addr_size ()
|
||||
|
||||
#if defined OBJ_ELF || defined OBJ_COFF
|
||||
#ifdef OBJ_ELF
|
||||
# define obj_frob_symbol(sym, punt) aarch64elf_frob_symbol ((sym), & (punt))
|
||||
#endif
|
||||
|
||||
# define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
|
||||
# define TC_SEGMENT_INFO_TYPE struct aarch64_segment_info_type
|
||||
@ -259,6 +263,7 @@ extern void aarch64_after_parse_args (void);
|
||||
|
||||
extern void aarch64_frag_align_code (int, int);
|
||||
extern const char * elf64_aarch64_target_format (void);
|
||||
extern const char * coff_aarch64_target_format (void);
|
||||
extern int aarch64_force_relocation (struct fix *);
|
||||
extern void aarch64_cleanup (void);
|
||||
extern void aarch64_start_line_hook (void);
|
||||
@ -274,13 +279,4 @@ extern void aarch64_handle_align (struct frag *);
|
||||
extern int tc_aarch64_regname_to_dw2regnum (char *regname);
|
||||
extern void tc_aarch64_frame_initial_instructions (void);
|
||||
|
||||
#ifdef TE_PE
|
||||
|
||||
#define O_secrel O_md1
|
||||
|
||||
#define TC_DWARF2_EMIT_OFFSET tc_pe_dwarf2_emit_offset
|
||||
void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
|
||||
|
||||
#endif /* TE_PE */
|
||||
|
||||
#endif /* TC_AARCH64 */
|
||||
|
29
gas/config/te-pepaarch64.h
Normal file
29
gas/config/te-pepaarch64.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copyright (C) 2006-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
GAS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 3,
|
||||
or (at your option) any later version.
|
||||
|
||||
GAS is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GAS; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#define TE_PEP
|
||||
#define COFF_WITH_peAArch64
|
||||
|
||||
#define TE_PE
|
||||
#define LEX_AT (LEX_BEGIN_NAME | LEX_NAME) /* Can have @'s inside labels. */
|
||||
|
||||
/* The PE format supports long section names. */
|
||||
#define COFF_LONG_SECTION_NAMES
|
||||
|
||||
#include "obj-format.h"
|
@ -135,7 +135,7 @@ case ${generic_target} in
|
||||
esac ;;
|
||||
aarch64*-*-netbsd*) fmt=elf em=nbsd;;
|
||||
aarch64*-*-openbsd*) fmt=elf;;
|
||||
|
||||
aarch64*-*-pe*) fmt=coff em=pepaarch64 ;;
|
||||
alpha-*-*vms*) fmt=evax ;;
|
||||
alpha-*-osf*) fmt=ecoff ;;
|
||||
alpha-*-linux*ecoff*) fmt=ecoff ;;
|
||||
|
14
gas/testsuite/gas/pe/pe-aarch64.d
Normal file
14
gas/testsuite/gas/pe/pe-aarch64.d
Normal file
@ -0,0 +1,14 @@
|
||||
#as:
|
||||
#objdump: -d
|
||||
|
||||
.*: file format pe-aarch64-little
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0000000000000000 <_start>:
|
||||
0: d2800281 mov x1, #0x14 // #20
|
||||
4: 14000001 b 8 <foo>
|
||||
|
||||
0000000000000008 <foo>:
|
||||
8: d65f03c0 ret
|
11
gas/testsuite/gas/pe/pe-aarch64.s
Normal file
11
gas/testsuite/gas/pe/pe-aarch64.s
Normal file
@ -0,0 +1,11 @@
|
||||
# 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
|
||||
|
||||
.section .text
|
||||
|
||||
_start:
|
||||
mov x1, 20
|
||||
b foo
|
||||
foo:
|
||||
ret
|
@ -52,6 +52,12 @@ if ([istarget "x86_64-*-mingw*"]) then {
|
||||
run_dump_test "peseh-x64-6"
|
||||
}
|
||||
|
||||
|
||||
# This test is only for AArch64
|
||||
if ([istarget "aarch64-*-pe*"]) {
|
||||
run_dump_test "pe-aarch64"
|
||||
}
|
||||
|
||||
# Big obj
|
||||
|
||||
|
||||
|
@ -331,7 +331,9 @@ read_pe_exported_syms (minimal_symbol_reader &reader,
|
||||
section_data[PE_SECTION_INDEX_BSS].section_name = ".bss";
|
||||
|
||||
is_pe64 = (strcmp (target, "pe-x86-64") == 0
|
||||
|| strcmp (target, "pei-x86-64") == 0);
|
||||
|| strcmp (target, "pei-x86-64") == 0
|
||||
|| strcmp (target, "pe-aarch64") == 0
|
||||
|| strcmp (target, "pei-aarch64") == 0);
|
||||
is_pe32 = (strcmp (target, "pe-i386") == 0
|
||||
|| strcmp (target, "pei-i386") == 0
|
||||
|| strcmp (target, "pe-arm-wince-little") == 0
|
||||
@ -610,7 +612,9 @@ pe_text_section_offset (struct bfd *abfd)
|
||||
target = bfd_get_target (abfd);
|
||||
|
||||
is_pe64 = (strcmp (target, "pe-x86-64") == 0
|
||||
|| strcmp (target, "pei-x86-64") == 0);
|
||||
|| strcmp (target, "pei-x86-64") == 0
|
||||
|| strcmp (target, "pe-aarch64") == 0
|
||||
|| strcmp (target, "pei-aarch64") == 0);
|
||||
is_pe32 = (strcmp (target, "pe-i386") == 0
|
||||
|| strcmp (target, "pei-i386") == 0
|
||||
|| strcmp (target, "pe-arm-wince-little") == 0
|
||||
|
@ -60,4 +60,26 @@ struct external_reloc
|
||||
#define RELOC struct external_reloc
|
||||
#define RELSZ 14
|
||||
|
||||
/* ARM64 relocations types. */
|
||||
|
||||
|
||||
#define IMAGE_REL_ARM64_ABSOLUTE 0x0000 /* No relocation required */
|
||||
#define IMAGE_REL_ARM64_ADDR32 0x0001 /* The 32-bit VA of the target. */
|
||||
#define IMAGE_REL_ARM64_ADDR32NB 0x0002 /* The 32-bit RVA of the target. */
|
||||
#define IMAGE_REL_ARM64_BRANCH26 0x0003 /* The 26-bit relative displacement to the target, for B and BL instructions. */
|
||||
#define IMAGE_REL_ARM64_PAGEBASE_REL21 0x0004 /* The page base of the target, for ADRP instruction. */
|
||||
#define IMAGE_REL_ARM64_REL21 0x0005 /* The 12-bit relative displacement to the target, for instruction ADR */
|
||||
#define IMAGE_REL_ARM64_PAGEOFFSET_12A 0x0006 /* The 12-bit page offset of the target, for instructions ADD/ADDS (immediate) with zero shift. */
|
||||
#define IMAGE_REL_ARM64_PAGEOFFSET_12L 0x0007 /* The 12-bit page offset of the target, for instruction LDR (indexed, unsigned immediate). */
|
||||
#define IMAGE_REL_ARM64_SECREL 0x0008 /* The 32-bit offset of the target from the beginning of its section. This is used to support debugging information and static thread local storage. */
|
||||
#define IMAGE_REL_ARM64_SECREL_LOW12A 0x0009 /* Bit 0:11 of section offset of the target, for instructions ADD/ADDS (immediate) with zero shift. */
|
||||
#define IMAGE_REL_ARM64_SECREL_HIGH12A 0x000A /* Bit 12:23 of section offset of the target, for instructions ADD/ADDS (immediate) with zero shift. */
|
||||
#define IMAGE_REL_ARM64_SECREL_LOW12L 0x000B /* Bit 0:11 of section offset of the target, for instruction LDR (indexed, unsigned immediate). */
|
||||
#define IMAGE_REL_ARM64_TOKEN 0x000C /* CLR token */
|
||||
#define IMAGE_REL_ARM64_SECTION 0x000D /* The 16-bit section index of the section that contains the target. This is used to support debugging information. */
|
||||
#define IMAGE_REL_ARM64_ADDR64 0x000E /* The 64-bit VA of the relocation target. */
|
||||
#define IMAGE_REL_ARM64_BRANCH19 0x000F /* 19 bit offset << 2 & sign ext. for conditional B */
|
||||
#define IMAGE_REL_ARM64_BRANCH14 0x0010 /* The 14-bit offset to the relocation target, for instructions TBZ and TBNZ. */
|
||||
#define IMAGE_REL_ARM64_REL32 0x0011 /* The 32-bit relative address from the byte following the relocation. */
|
||||
|
||||
#define ARM_NOTE_SECTION ".note"
|
||||
|
@ -377,6 +377,7 @@ ALL_EMULATIONS = $(ALL_EMULATION_SOURCES:.c=.@OBJEXT@)
|
||||
ALL_64_EMULATION_SOURCES = \
|
||||
eaarch64cloudabi.c \
|
||||
eaarch64cloudabib.c \
|
||||
eaarch64pe.c \
|
||||
eaarch64elf.c \
|
||||
eaarch64elf32.c \
|
||||
eaarch64elf32b.c \
|
||||
|
@ -887,6 +887,7 @@ ALL_64_EMULATION_SOURCES = \
|
||||
eaarch64linux32.c \
|
||||
eaarch64linux32b.c \
|
||||
eaarch64linuxb.c \
|
||||
eaarch64pe.c \
|
||||
eelf32_x86_64.c \
|
||||
eelf32b4300.c \
|
||||
eelf32bmip.c \
|
||||
|
@ -117,6 +117,10 @@ aarch64-*-linux*) targ_emul=aarch64linux
|
||||
aarch64-*-haiku*) targ_emul=aarch64haiku
|
||||
targ_extra_emuls="aarch64elf aarch64elf32 aarch64elf32b aarch64elfb armelf armelfb armelf_haiku $targ_extra_libpath"
|
||||
;;
|
||||
aarch64-*-pe*)
|
||||
targ_emul=aarch64pe
|
||||
targ_extra_ofiles="deffilep.o pep-dll-aarch64.o"
|
||||
;;
|
||||
alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
|
||||
targ_emul=elf64alpha_fbsd
|
||||
targ_extra_emuls="elf64alpha alpha"
|
||||
@ -1042,7 +1046,7 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
|
||||
;;
|
||||
x86_64-*-pe | x86_64-*-pep) targ_emul=i386pep ;
|
||||
targ_extra_emuls=i386pe ;
|
||||
targ_extra_ofiles="deffilep.o pep-dll.o pe-dll.o"
|
||||
targ_extra_ofiles="deffilep.o pep-dll-x86_64.o pe-dll.o"
|
||||
;;
|
||||
x86_64-*-cygwin) targ_emul=i386pep ;
|
||||
targ_extra_emuls=i386pe
|
||||
|
9
ld/emulparams/aarch64pe.sh
Normal file
9
ld/emulparams/aarch64pe.sh
Normal file
@ -0,0 +1,9 @@
|
||||
ARCH="aarch64"
|
||||
SCRIPT_NAME=pep
|
||||
OUTPUT_FORMAT="pei-aarch64-little"
|
||||
RELOCATEABLE_OUTPUT_FORMAT="pe-aarch64-little"
|
||||
TEMPLATE_NAME=pep
|
||||
SUBSYSTEM=PE_DEF_SUBSYSTEM
|
||||
INITIAL_SYMBOL_CHAR=\"_\"
|
||||
TARGET_PAGE_SIZE=0x1000
|
||||
GENERATE_AUTO_IMPORT_SCRIPT=1
|
@ -48,7 +48,11 @@ fragment <<EOF
|
||||
|
||||
#define COFF_IMAGE_WITH_PE
|
||||
#define COFF_WITH_PE
|
||||
#ifdef TARGET_IS_aarch64pe
|
||||
#define COFF_WITH_peAArch64
|
||||
#elif defined (TARGET_IS_i386pep)
|
||||
#define COFF_WITH_pex64
|
||||
#endif
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "bfd.h"
|
||||
@ -72,7 +76,11 @@ fragment <<EOF
|
||||
|
||||
/* FIXME: See bfd/peXXigen.c for why we include an architecture specific
|
||||
header in generic PE code. */
|
||||
#include "coff/x86_64.h"
|
||||
#ifdef TARGET_IS_i386pep
|
||||
# include "coff/x86_64.h"
|
||||
#elif defined TARGET_IS_aarch64pe
|
||||
# include "coff/aarch64.h"
|
||||
#endif
|
||||
#include "coff/pe.h"
|
||||
|
||||
/* FIXME: These are BFD internal header files, and we should not be
|
||||
|
44
ld/pe-dll.c
44
ld/pe-dll.c
@ -42,7 +42,7 @@
|
||||
#include "../bfd/libcoff.h"
|
||||
#include "deffile.h"
|
||||
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
|
||||
#define PE_IDATA4_SIZE 8
|
||||
#define PE_IDATA5_SIZE 8
|
||||
@ -209,7 +209,7 @@ static const autofilter_entry_type autofilter_symbollist_i386[] =
|
||||
{ STRING_COMMA_LEN ("_NULL_IMPORT_DESCRIPTOR") },
|
||||
/* Entry point symbols, and entry hooks. */
|
||||
{ STRING_COMMA_LEN ("cygwin_crt0") },
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
{ STRING_COMMA_LEN ("DllMain") },
|
||||
{ STRING_COMMA_LEN ("DllEntryPoint") },
|
||||
{ STRING_COMMA_LEN ("DllMainCRTStartup") },
|
||||
@ -246,13 +246,14 @@ static const autofilter_entry_type autofilter_symbollist_i386[] =
|
||||
#define PE_ARCH_mips 3
|
||||
#define PE_ARCH_arm 4
|
||||
#define PE_ARCH_arm_wince 5
|
||||
#define PE_ARCH_aarch64 6
|
||||
|
||||
/* Don't make it constant as underscore mode gets possibly overriden
|
||||
by target or -(no-)leading-underscore option. */
|
||||
static pe_details_type pe_detail_list[] =
|
||||
{
|
||||
{
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
"pei-x86-64",
|
||||
"pe-x86-64",
|
||||
3 /* R_IMAGEBASE */,
|
||||
@ -263,14 +264,14 @@ static pe_details_type pe_detail_list[] =
|
||||
#endif
|
||||
PE_ARCH_i386,
|
||||
bfd_arch_i386,
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
false,
|
||||
#else
|
||||
true,
|
||||
#endif
|
||||
autofilter_symbollist_i386
|
||||
},
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
{
|
||||
"pei-x86-64",
|
||||
"pe-bigobj-x86-64",
|
||||
@ -327,6 +328,15 @@ static pe_details_type pe_detail_list[] =
|
||||
false,
|
||||
autofilter_symbollist_generic
|
||||
},
|
||||
{
|
||||
"pei-aarch64-little",
|
||||
"pe-aarch64-little",
|
||||
2, /* ARM64_RVA32 */
|
||||
PE_ARCH_aarch64,
|
||||
bfd_arch_aarch64,
|
||||
false,
|
||||
autofilter_symbollist_generic
|
||||
},
|
||||
{ NULL, NULL, 0, 0, 0, false, NULL }
|
||||
};
|
||||
|
||||
@ -1638,7 +1648,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
|
||||
switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
|
||||
relocs[i]->howto->rightshift)
|
||||
{
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
case BITS_AND_SHIFT (64, 0):
|
||||
reloc_data[total_relocs].type = IMAGE_REL_BASED_DIR64;
|
||||
total_relocs++;
|
||||
@ -2247,6 +2257,15 @@ static const unsigned char jmp_ix86_bytes[] =
|
||||
0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
|
||||
};
|
||||
|
||||
/* _function:
|
||||
b <__imp_function>
|
||||
nop */
|
||||
static const unsigned char jmp_aarch64_bytes[] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x14,
|
||||
0x1f, 0x20, 0x03, 0xD5
|
||||
};
|
||||
|
||||
/* _function:
|
||||
mov.l ip+8,r0
|
||||
mov.l @r0,r0
|
||||
@ -2317,6 +2336,10 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
|
||||
jmp_bytes = jmp_arm_bytes;
|
||||
jmp_byte_count = sizeof (jmp_arm_bytes);
|
||||
break;
|
||||
case PE_ARCH_aarch64:
|
||||
jmp_bytes = jmp_aarch64_bytes;
|
||||
jmp_byte_count = sizeof (jmp_aarch64_bytes);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
@ -2386,7 +2409,7 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
|
||||
switch (pe_details->pe_arch)
|
||||
{
|
||||
case PE_ARCH_i386:
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
quick_reloc (abfd, 2, BFD_RELOC_32_PCREL, 2);
|
||||
#else
|
||||
/* Mark this object as SAFESEH compatible. */
|
||||
@ -2407,6 +2430,9 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
|
||||
case PE_ARCH_arm_wince:
|
||||
quick_reloc (abfd, 8, BFD_RELOC_32, 2);
|
||||
break;
|
||||
case PE_ARCH_aarch64:
|
||||
quick_reloc (abfd, 0, BFD_RELOC_AARCH64_JUMP26, 2);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
@ -3406,7 +3432,7 @@ pe_implied_import_dll (const char *filename)
|
||||
/* Get pe_header, optional header and numbers of directory entries. */
|
||||
pe_header_offset = pe_get32 (dll, 0x3c);
|
||||
opthdr_ofs = pe_header_offset + 4 + 20;
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /* & NumberOfRvaAndSizes. */
|
||||
#else
|
||||
num_entries = pe_get32 (dll, opthdr_ofs + 92);
|
||||
@ -3416,7 +3442,7 @@ pe_implied_import_dll (const char *filename)
|
||||
if (num_entries < 1)
|
||||
return false;
|
||||
|
||||
#ifdef pe_use_x86_64
|
||||
#ifdef pe_use_plus
|
||||
export_rva = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
|
||||
export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
|
||||
#else
|
||||
|
23
ld/pep-dll-aarch64.c
Normal file
23
ld/pep-dll-aarch64.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* Tiny wrapper over pep-dll.c
|
||||
Copyright (C) 2006-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#define COFF_WITH_peAArch64
|
||||
|
||||
#include "pep-dll.c"
|
22
ld/pep-dll-x86_64.c
Normal file
22
ld/pep-dll-x86_64.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* Tiny wrapper over pep-dll.c
|
||||
Copyright (C) 2006-2022 Free Software Foundation, Inc.
|
||||
This file is part of the GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#define COFF_WITH_pex64
|
||||
|
||||
#include "pep-dll.c"
|
@ -21,7 +21,6 @@
|
||||
|
||||
#define COFF_IMAGE_WITH_PE
|
||||
#define COFF_WITH_PE
|
||||
#define COFF_WITH_pex64
|
||||
|
||||
/* Local defined globals. */
|
||||
#define pe_def_file pep_def_file
|
||||
@ -58,7 +57,7 @@
|
||||
#define pe_output_file_set_long_section_names \
|
||||
pep_output_file_set_long_section_names
|
||||
|
||||
/* Uses x86_64 PE+. */
|
||||
#define pe_use_x86_64
|
||||
/* Uses PE+. */
|
||||
#define pe_use_plus
|
||||
|
||||
#include "pe-dll.c"
|
||||
|
16
ld/testsuite/ld-pe/pe-aarch64.d
Normal file
16
ld/testsuite/ld-pe/pe-aarch64.d
Normal file
@ -0,0 +1,16 @@
|
||||
#ld:
|
||||
#objdump: -d
|
||||
|
||||
.*: file format pei-aarch64-little
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0000000140001000 <__rt_psrelocs_end>:
|
||||
140001000: d2800281 mov x1, #0x14 // #20
|
||||
140001004: 14000001 b 140001008 <foo>
|
||||
|
||||
0000000140001008 <foo>:
|
||||
140001008: d65f03c0 ret
|
||||
14000100c: 00000000 udf #0
|
||||
#...
|
11
ld/testsuite/ld-pe/pe-aarch64.s
Normal file
11
ld/testsuite/ld-pe/pe-aarch64.s
Normal file
@ -0,0 +1,11 @@
|
||||
# A little test to ensure pe-aarch64 is working in LD.
|
||||
# Currently, the poor pe-aarch64 implementation in binutils
|
||||
# couldn't do anything useful, hence, this test is rather short
|
||||
|
||||
.section .text
|
||||
|
||||
_start:
|
||||
mov x1, 20
|
||||
b foo
|
||||
foo:
|
||||
ret
|
@ -78,6 +78,11 @@ if {[istarget i*86-*-cygwin*]
|
||||
run_ld_link_tests $pe_tests
|
||||
}
|
||||
|
||||
if {[istarget "aarch64-*-pe*"]} {
|
||||
run_dump_test "pe-aarch64"
|
||||
}
|
||||
|
||||
|
||||
run_dump_test "image_size"
|
||||
run_dump_test "export_dynamic_warning"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user