aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJedidiah Thompson <wej22007@outlook.com>2022-10-19 10:57:12 +0200
committerZac Walker <zac.walker@linaro.org>2022-10-19 10:57:12 +0200
commitc60b3806799abf1d7f6cf5108a1b0e733a950b13 (patch)
treea203af8ed31ff48618e57a76a668faea3673fb0e /gas
parent740a19d914a83423122fe81eec9508fa1dbb0559 (diff)
downloadgdb-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.h4
-rw-r--r--gas/config/tc-aarch64.c49
-rw-r--r--gas/config/tc-aarch64.h18
-rw-r--r--gas/config/te-pepaarch64.h29
-rw-r--r--gas/configure.tgt2
-rw-r--r--gas/testsuite/gas/pe/pe-aarch64.d14
-rw-r--r--gas/testsuite/gas/pe/pe-aarch64.s11
-rw-r--r--gas/testsuite/gas/pe/pe.exp6
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