diff options
author | Jedidiah Thompson <wej22007@outlook.com> | 2022-10-19 10:57:12 +0200 |
---|---|---|
committer | Zac Walker <zac.walker@linaro.org> | 2022-10-19 10:57:12 +0200 |
commit | c60b3806799abf1d7f6cf5108a1b0e733a950b13 (patch) | |
tree | a203af8ed31ff48618e57a76a668faea3673fb0e /gas | |
parent | 740a19d914a83423122fe81eec9508fa1dbb0559 (diff) | |
download | gdb-c60b3806799abf1d7f6cf5108a1b0e733a950b13.zip gdb-c60b3806799abf1d7f6cf5108a1b0e733a950b13.tar.gz gdb-c60b3806799abf1d7f6cf5108a1b0e733a950b13.tar.bz2 |
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>
Diffstat (limited to 'gas')
-rw-r--r-- | gas/config/obj-coff.h | 4 | ||||
-rw-r--r-- | gas/config/tc-aarch64.c | 49 | ||||
-rw-r--r-- | gas/config/tc-aarch64.h | 18 | ||||
-rw-r--r-- | gas/config/te-pepaarch64.h | 29 | ||||
-rw-r--r-- | gas/configure.tgt | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/pe/pe-aarch64.d | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/pe/pe-aarch64.s | 11 | ||||
-rw-r--r-- | gas/testsuite/gas/pe/pe.exp | 6 |
8 files changed, 108 insertions, 25 deletions
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index 1dbd38a..f79c737 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 98a7ca5..f6fa158 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 { @@ -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>"), diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h index f5c1752..2d514ff 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 0000000..4774e94 --- /dev/null +++ b/gas/config/te-pepaarch64.h @@ -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" diff --git a/gas/configure.tgt b/gas/configure.tgt index 9f2b672..82f2d44 100644 --- a/gas/configure.tgt +++ b/gas/configure.tgt @@ -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 ;; diff --git a/gas/testsuite/gas/pe/pe-aarch64.d b/gas/testsuite/gas/pe/pe-aarch64.d new file mode 100644 index 0000000..0b8009d --- /dev/null +++ b/gas/testsuite/gas/pe/pe-aarch64.d @@ -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 diff --git a/gas/testsuite/gas/pe/pe-aarch64.s b/gas/testsuite/gas/pe/pe-aarch64.s new file mode 100644 index 0000000..546d55f --- /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 3568ff7..8df750f 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 |