|
From d2cb3362e75692f77c2f4166c1b1065cad65e986 Mon Sep 17 00:00:00 2001 |
|
From: Jedidiah Thompson <wej22007@outlook.com> |
|
Date: Fri, 1 Apr 2022 17:50:03 -0400 |
|
Subject: [PATCH] Refine support for aarch64-pe in GAS, LD, BFD |
|
|
|
This allows aarch64-pe to be targetted natively, not having to use objcopy to convert it from ELF to PE. Note that support is very limited, |
|
there is a bug in GAS or BFD that needs to be fixed, plus relocations need to be supported. Also, there probably should be more testing done. |
|
GAS and LD's testsuites also need some work; GAS has a lot of ELF specific tests that need to be seperated, plus relocation support is needed |
|
for others. LD's tests also need some work as well. This commit also adds a new LLP64 ABI to AArch64. This cannot be selected from ELF targets, |
|
and only can be used be PE targets. |
|
--- |
|
bfd/Makefile.am | 2 + |
|
bfd/archures.c | 1 + |
|
bfd/bfd-in2.h | 1 + |
|
bfd/bfd.c | 1 + |
|
bfd/coff-aarch64.c | 4 +- |
|
bfd/config.bfd | 16 ++++++- |
|
bfd/configure.ac | 3 +- |
|
bfd/cpu-aarch64.c | 39 +++++++++++----- |
|
bfd/pe-aarch64.c | 74 +++++++++++++++++++++++++++++++ |
|
bfd/pei-aarch64.c | 2 +- |
|
bfd/peicode.h | 2 + |
|
bfd/targets.c | 6 ++- |
|
binutils/dlltool.c | 3 ++ |
|
gas/config/obj-coff.h | 4 ++ |
|
gas/config/tc-aarch64.c | 45 ++++++++++++++----- |
|
gas/config/tc-aarch64.h | 18 +++----- |
|
gas/config/te-pepaarch64.h | 29 ++++++++++++ |
|
gas/configure.tgt | 1 + |
|
gas/testsuite/gas/pe/pe-aarch64.d | 15 +++++++ |
|
gas/testsuite/gas/pe/pe-aarch64.s | 11 +++++ |
|
gas/testsuite/gas/pe/pe.exp | 6 +++ |
|
gdb/coff-pe-read.c | 8 +++- |
|
ld/Makefile.am | 1 + |
|
ld/configure.tgt | 6 ++- |
|
ld/emulparams/aarch64pe.sh | 9 ++++ |
|
ld/emultempl/pep.em | 10 ++++- |
|
ld/pe-dll.c | 45 +++++++++++++++---- |
|
ld/pep-dll-aarch64.c | 23 ++++++++++ |
|
ld/pep-dll-x86_64.c | 22 +++++++++ |
|
ld/pep-dll.c | 5 +-- |
|
ld/testsuite/ld-pe/pe-aarch64.d | 16 +++++++ |
|
ld/testsuite/ld-pe/pe-aarch64.s | 12 +++++ |
|
ld/testsuite/ld-pe/pe.exp | 5 +++ |
|
33 files changed, 387 insertions(+), 58 deletions(-) |
|
create mode 100644 bfd/pe-aarch64.c |
|
create mode 100644 gas/config/te-pepaarch64.h |
|
create mode 100644 gas/testsuite/gas/pe/pe-aarch64.d |
|
create mode 100644 gas/testsuite/gas/pe/pe-aarch64.s |
|
create mode 100644 ld/emulparams/aarch64pe.sh |
|
create mode 100644 ld/pep-dll-aarch64.c |
|
create mode 100644 ld/pep-dll-x86_64.c |
|
create mode 100644 ld/testsuite/ld-pe/pe-aarch64.d |
|
create mode 100644 ld/testsuite/ld-pe/pe-aarch64.s |
|
|
|
diff --git a/bfd/Makefile.am b/bfd/Makefile.am |
|
index b9a3f8207ac..296b94bae9c 100644 |
|
--- a/bfd/Makefile.am |
|
+++ b/bfd/Makefile.am |
|
@@ -583,6 +583,7 @@ BFD64_BACKENDS = \ |
|
pe-aarch64igen.lo \ |
|
pe-x86_64.lo \ |
|
pei-aarch64.lo \ |
|
+ pe-aarch64.lo \ |
|
pei-ia64.lo \ |
|
pei-x86_64.lo \ |
|
pepigen.lo \ |
|
@@ -624,6 +625,7 @@ BFD64_BACKENDS_CFILES = \ |
|
mach-o-x86-64.c \ |
|
mmo.c \ |
|
pe-x86_64.c \ |
|
+ pe-aarch64.c \ |
|
pei-aarch64.c \ |
|
pei-ia64.c \ |
|
pei-x86_64.c \ |
|
diff --git a/bfd/archures.c b/bfd/archures.c |
|
index fac9fe82a08..dc964e02192 100644 |
|
--- a/bfd/archures.c |
|
+++ b/bfd/archures.c |
|
@@ -533,6 +533,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 |
|
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h |
|
index c0b563aec02..a0161a263c6 100644 |
|
--- a/bfd/bfd-in2.h |
|
+++ b/bfd/bfd-in2.h |
|
@@ -1912,6 +1912,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 |
|
diff --git a/bfd/bfd.c b/bfd/bfd.c |
|
index 913ce2d6abe..bf7f442425e 100644 |
|
--- a/bfd/bfd.c |
|
+++ b/bfd/bfd.c |
|
@@ -1738,6 +1738,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 |
|
diff --git a/bfd/coff-aarch64.c b/bfd/coff-aarch64.c |
|
index e22ef3c4795..7b09834b7bd 100644 |
|
--- a/bfd/coff-aarch64.c |
|
+++ b/bfd/coff-aarch64.c |
|
@@ -89,13 +89,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. */ |
|
diff --git a/bfd/config.bfd b/bfd/config.bfd |
|
index 872685cfb72..e2a0be9a2c2 100644 |
|
--- a/bfd/config.bfd |
|
+++ b/bfd/config.bfd |
|
@@ -250,9 +250,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_pei_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_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*) |
|
@@ -1493,6 +1499,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*) |
|
diff --git a/bfd/configure.ac b/bfd/configure.ac |
|
index 9e873736792..437b1b35683 100644 |
|
--- a/bfd/configure.ac |
|
+++ b/bfd/configure.ac |
|
@@ -436,7 +436,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 ;; |
|
diff --git a/bfd/cpu-aarch64.c b/bfd/cpu-aarch64.c |
|
index e1bd8fc4789..b94eaeb54b4 100644 |
|
--- a/bfd/cpu-aarch64.c |
|
+++ b/bfd/cpu-aarch64.c |
|
@@ -39,9 +39,11 @@ 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. */ |
|
+ /* Don't allow mixing data models. */ |
|
if ((a->mach & bfd_mach_aarch64_ilp32) != (b->mach & bfd_mach_aarch64_ilp32)) |
|
return NULL; |
|
+ if ((a->mach & bfd_mach_aarch64_llp64) != (b->mach & bfd_mach_aarch64_llp64)) |
|
+ return NULL; |
|
|
|
/* Otherwise if either a or b is the 'default' machine |
|
then it can be polymorphed into the other. */ |
|
@@ -102,20 +104,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 } |
|
- |
|
-static const bfd_arch_info_type bfd_aarch64_arch_v8_r = |
|
- N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, false, NULL); |
|
- |
|
+/* 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 |
|
+ |
|
+#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); |
|
+ |
|
+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, true, &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) |
|
diff --git a/bfd/pe-aarch64.c b/bfd/pe-aarch64.c |
|
new file mode 100644 |
|
index 00000000000..c0e2eb6b9cc |
|
--- /dev/null |
|
+++ b/bfd/pe-aarch64.c |
|
@@ -0,0 +1,74 @@ |
|
+/* BFD back-end for AArch64 PE IMAGE COFF files. |
|
+ Copyright (C) 2021 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" |
|
diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c |
|
index c447690793d..7b6c681b4be 100644 |
|
--- a/bfd/pei-aarch64.c |
|
+++ b/bfd/pei-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 |
|
diff --git a/bfd/peicode.h b/bfd/peicode.h |
|
index 0346bc2174e..e6cb11f0ad8 100644 |
|
--- a/bfd/peicode.h |
|
+++ b/bfd/peicode.h |
|
@@ -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 |
|
diff --git a/bfd/targets.c b/bfd/targets.c |
|
index 417743efc0e..d68ce831ef7 100644 |
|
--- a/bfd/targets.c |
|
+++ b/bfd/targets.c |
|
@@ -679,7 +679,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; |
|
@@ -995,7 +996,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_pei_le_vec, |
|
+ &aarch64_pe_le_vec, |
|
#endif |
|
|
|
#ifdef BFD64 |
|
diff --git a/binutils/dlltool.c b/binutils/dlltool.c |
|
index 89871510b45..43dc48b41df 100644 |
|
--- a/binutils/dlltool.c |
|
+++ b/binutils/dlltool.c |
|
@@ -255,6 +255,9 @@ |
|
#ifdef DLLTOOL_DEFAULT_I386 |
|
#include "coff/i386.h" |
|
#endif |
|
+#ifdef DLLTOOL_DEFAULT_AARCH64 |
|
+#include "coff/aarch64.h" |
|
+#endif |
|
|
|
#ifndef COFF_PAGE_SIZE |
|
#define COFF_PAGE_SIZE ((bfd_vma) 4096) |
|
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h |
|
index 1892b8a3f3f..bc21763f2ac 100644 |
|
--- a/gas/config/obj-coff.h |
|
+++ b/gas/config/obj-coff.h |
|
@@ -40,6 +40,10 @@ |
|
#endif |
|
#endif |
|
|
|
+#ifdef TC_AARCH64 |
|
+#include "coff/aarch64.h" |
|
+#endif |
|
+ |
|
#ifdef TC_PPC |
|
#include "coff/rs6000.h" |
|
#endif |
|
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c |
|
index a4ef65274e4..3b965692493 100644 |
|
--- a/gas/config/tc-aarch64.c |
|
+++ b/gas/config/tc-aarch64.c |
|
@@ -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 |
|
{ |
|
@@ -1475,7 +1482,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), |
|
@@ -8302,7 +8309,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); |
|
@@ -8360,6 +8367,7 @@ aarch64_init_frag (fragS * fragP, int max_chars) |
|
break; |
|
} |
|
} |
|
+#endif /* OBJ_ELF */ |
|
|
|
/* Initialize the DWARF-2 unwind information for this procedure. */ |
|
|
|
@@ -8368,7 +8376,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. */ |
|
|
|
@@ -8405,10 +8412,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; |
|
} |
|
|
|
@@ -9272,8 +9279,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. */ |
|
|
|
@@ -9283,13 +9288,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) |
|
{ |
|
@@ -9312,6 +9322,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. */ |
|
@@ -9627,7 +9643,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); |
|
} |
|
@@ -10194,6 +10215,7 @@ struct aarch64_option_abi_value_table |
|
enum aarch64_abi_type value; |
|
}; |
|
|
|
+#ifdef OBJ_ELF |
|
static const struct aarch64_option_abi_value_table aarch64_abis[] = { |
|
{"ilp32", AARCH64_ABI_ILP32}, |
|
{"lp64", AARCH64_ABI_LP64}, |
|
@@ -10220,6 +10242,7 @@ aarch64_parse_abi (const char *str) |
|
as_bad (_("unknown abi `%s'\n"), str); |
|
return 0; |
|
} |
|
+#endif |
|
|
|
static struct aarch64_long_option_table aarch64_long_opts[] = { |
|
#ifdef OBJ_ELF |
|
diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h |
|
index f5c17523796..2d514ff610a 100644 |
|
--- a/gas/config/tc-aarch64.h |
|
+++ b/gas/config/tc-aarch64.h |
|
@@ -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 */ |
|
diff --git a/gas/config/te-pepaarch64.h b/gas/config/te-pepaarch64.h |
|
new file mode 100644 |
|
index 00000000000..5983c7642cc |
|
--- /dev/null |
|
+++ b/gas/config/te-pepaarch64.h |
|
@@ -0,0 +1,29 @@ |
|
+/* Copyright (C) 2006-2021 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" |
|
diff --git a/gas/configure.tgt b/gas/configure.tgt |
|
index 62f806bdfe8..dd48ba684df 100644 |
|
--- a/gas/configure.tgt |
|
+++ b/gas/configure.tgt |
|
@@ -134,6 +134,7 @@ case ${generic_target} in |
|
aarch64*-linux-gnu_ilp32) arch=aarch64:32 ;; |
|
esac ;; |
|
aarch64*-*-netbsd*) fmt=elf em=nbsd;; |
|
+ aarch64*-*-pe*) fmt=coff em=pepaarch64 ;; |
|
|
|
alpha-*-*vms*) fmt=evax ;; |
|
alpha-*-osf*) fmt=ecoff ;; |
|
diff --git a/gas/testsuite/gas/pe/pe-aarch64.d b/gas/testsuite/gas/pe/pe-aarch64.d |
|
new file mode 100644 |
|
index 00000000000..8ddc5849535 |
|
--- /dev/null |
|
+++ b/gas/testsuite/gas/pe/pe-aarch64.d |
|
@@ -0,0 +1,15 @@ |
|
+#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 |
|
+ |
|
diff --git a/gas/testsuite/gas/pe/pe-aarch64.s b/gas/testsuite/gas/pe/pe-aarch64.s |
|
new file mode 100644 |
|
index 00000000000..546d55fc361 |
|
--- /dev/null |
|
+++ b/gas/testsuite/gas/pe/pe-aarch64.s |
|
@@ -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 |
|
diff --git a/gas/testsuite/gas/pe/pe.exp b/gas/testsuite/gas/pe/pe.exp |
|
index 3568ff7b02f..8df750f9dd0 100644 |
|
--- a/gas/testsuite/gas/pe/pe.exp |
|
+++ b/gas/testsuite/gas/pe/pe.exp |
|
@@ -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 |
|
|
|
|
|
diff --git a/gdb/coff-pe-read.c b/gdb/coff-pe-read.c |
|
index 16c1e044794..192a3c7d306 100644 |
|
--- a/gdb/coff-pe-read.c |
|
+++ b/gdb/coff-pe-read.c |
|
@@ -371,7 +371,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 |
|
@@ -643,7 +645,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 |
|
diff --git a/ld/Makefile.am b/ld/Makefile.am |
|
index e53bef13bb8..dc56a18488b 100644 |
|
--- a/ld/Makefile.am |
|
+++ b/ld/Makefile.am |
|
@@ -380,6 +380,7 @@ ALL_EMULATIONS = $(ALL_EMULATION_SOURCES:.c=.@OBJEXT@) |
|
ALL_64_EMULATION_SOURCES = \ |
|
eaarch64cloudabi.c \ |
|
eaarch64cloudabib.c \ |
|
+ eaarch64pe.c \ |
|
eaarch64elf.c \ |
|
eaarch64elf32.c \ |
|
eaarch64elf32b.c \ |
|
diff --git a/ld/configure.tgt b/ld/configure.tgt |
|
index 89f4a99c66e..ddf24570825 100644 |
|
--- a/ld/configure.tgt |
|
+++ b/ld/configure.tgt |
|
@@ -80,6 +80,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" |
|
@@ -1005,7 +1009,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 |
|
diff --git a/ld/emulparams/aarch64pe.sh b/ld/emulparams/aarch64pe.sh |
|
new file mode 100644 |
|
index 00000000000..02bf02cd963 |
|
--- /dev/null |
|
+++ b/ld/emulparams/aarch64pe.sh |
|
@@ -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 |
|
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em |
|
index e68d1e69f17..aedd5b0381a 100644 |
|
--- a/ld/emultempl/pep.em |
|
+++ b/ld/emultempl/pep.em |
|
@@ -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 |
|
diff --git a/ld/pe-dll.c b/ld/pe-dll.c |
|
index 95de94b8474..a523975076d 100644 |
|
--- a/ld/pe-dll.c |
|
+++ b/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 } |
|
}; |
|
|
|
@@ -1642,7 +1652,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 = 10; |
|
total_relocs++; |
|
@@ -2249,6 +2259,16 @@ 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 |
|
@@ -2319,6 +2339,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 (); |
|
} |
|
@@ -2384,7 +2408,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. */ |
|
@@ -2405,6 +2429,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_32_PCREL, 2); |
|
+ break; |
|
default: |
|
abort (); |
|
} |
|
@@ -3378,7 +3405,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); |
|
@@ -3388,7 +3415,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 |
|
diff --git a/ld/pep-dll-aarch64.c b/ld/pep-dll-aarch64.c |
|
new file mode 100644 |
|
index 00000000000..551fdcb1511 |
|
--- /dev/null |
|
+++ b/ld/pep-dll-aarch64.c |
|
@@ -0,0 +1,23 @@ |
|
+/* Tiny wrapper over pep-dll.c |
|
+ Copyright (C) 2006-2021 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" |
|
diff --git a/ld/pep-dll-x86_64.c b/ld/pep-dll-x86_64.c |
|
new file mode 100644 |
|
index 00000000000..9a9baca7819 |
|
--- /dev/null |
|
+++ b/ld/pep-dll-x86_64.c |
|
@@ -0,0 +1,22 @@ |
|
+/* Tiny wrapper over pep-dll.c |
|
+ Copyright (C) 2006-2021 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" |
|
diff --git a/ld/pep-dll.c b/ld/pep-dll.c |
|
index 3049a024e17..1cfed490337 100644 |
|
--- a/ld/pep-dll.c |
|
+++ b/ld/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" |
|
diff --git a/ld/testsuite/ld-pe/pe-aarch64.d b/ld/testsuite/ld-pe/pe-aarch64.d |
|
new file mode 100644 |
|
index 00000000000..fac02b5fd87 |
|
--- /dev/null |
|
+++ b/ld/testsuite/ld-pe/pe-aarch64.d |
|
@@ -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 |
|
+#... |
|
diff --git a/ld/testsuite/ld-pe/pe-aarch64.s b/ld/testsuite/ld-pe/pe-aarch64.s |
|
new file mode 100644 |
|
index 00000000000..df114a8acfa |
|
--- /dev/null |
|
+++ b/ld/testsuite/ld-pe/pe-aarch64.s |
|
@@ -0,0 +1,12 @@ |
|
+# 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 |
|
+ |
|
diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp |
|
index f47c7eb2370..502ccd7e02b 100644 |
|
--- a/ld/testsuite/ld-pe/pe.exp |
|
+++ b/ld/testsuite/ld-pe/pe.exp |
|
@@ -63,6 +63,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" |
|
|
|
-- |
|
2.32.0 |
|
|