[PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
Jedidiah Thompson
wej22007@outlook.com
Wed Dec 29 21:29:42 GMT 2021
Here is a patch with LLP64 added:
>From df704f90aae1b41ccdd16270cd8287fa35c308e6 Mon Sep 17 00:00:00 2001
From: Jedidiah Thompson <wej22007@outlook.com>
Date: Wed, 29 Dec 2021 16:27:30 -0500
Subject: [PATCH 3/3] Add LLP64 ABI to AArch64 as and BFD
LLP64 only can be used on COFF targets currently; Windows is the only OS I know of that uses LLP64
---
bfd/archures.c | 1 +
bfd/bfd-in2.h | 1 +
bfd/cpu-aarch64.c | 27 +++++++++++++++++++++------
gas/config/tc-aarch64.c | 26 +++++++++++++++++++++-----
4 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/bfd/archures.c b/bfd/archures.c
index 441283b51a6..62ba16b9aae 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 7b7a329cd62..9b3b66a1359 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1907,6 +1907,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/cpu-aarch64.c b/bfd/cpu-aarch64.c
index d9d6c1b2f89..cbd764c9d75 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, \
+/* 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, false, NULL);
+ 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);
+ 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/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 818d260148d..83226aa5fd2 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -32,7 +32,6 @@
#include "elf/aarch64.h"
#endif
#include "dw2gencfi.h"
-
#include "dwarf2dbg.h"
/* Types of processor to assemble for. */
@@ -68,7 +67,8 @@ 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
@@ -76,7 +76,9 @@ enum aarch64_abi_type
#endif
/* DEFAULT_ARCH is initialized in gas/configure.tgt. */
+#ifdef OBJ_ELF
static const char *default_arch = DEFAULT_ARCH;
+#endif
/* AArch64 ABI for the output file. */
static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
@@ -86,6 +88,9 @@ 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)
+/* 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
{
@@ -8407,6 +8412,8 @@ aarch64_dwarf2_addr_size (void)
{
if (ilp32_p)
return 4;
+ else if (llp64_p)
+ return 8;
return bfd_arch_bits_per_address (stdoutput) / 8;
}
@@ -9125,7 +9132,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_AARCH64_LD_GOT_LO12_NC:
/* Should always be exported to object file, see
aarch64_force_relocation(). */
- fixP->fx_r_type = (ilp32_p
+ fixP->fx_r_type = ((ilp32_p || llp64_p)
? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
: BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
gas_assert (!fixP->fx_done);
@@ -9280,11 +9287,15 @@ aarch64_after_parse_args (void)
if (aarch64_abi != AARCH64_ABI_NONE)
return;
+#ifdef OBJ_COFF
+ aarch64_abi = AARCH64_ABI_LLP64;
+#elif defined (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;
+#endif
}
#ifdef OBJ_ELF
@@ -9631,7 +9642,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);
}
@@ -10201,7 +10217,7 @@ struct aarch64_option_abi_value_table
#ifdef OBJ_ELF
static const struct aarch64_option_abi_value_table aarch64_abis[] = {
{"ilp32", AARCH64_ABI_ILP32},
- {"lp64", AARCH64_ABI_LP64},
+ {"lp64", AARCH64_ABI_LP64}
};
static int
--
2.32.0
________________________________
From: Binutils <binutils-bounces+wej22007=outlook.com@sourceware.org> on behalf of Jedidiah Thompson via Binutils <binutils@sourceware.org>
Sent: Wednesday, December 29, 2021 1:36 PM
To: Tamar Christina <Tamar.Christina@arm.com>
Cc: binutils@sourceware.org <binutils@sourceware.org>
Subject: Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
This patch makes AArch64 on PE recognize the fact that varying ABIs exists (plus the small change in config.bfd)
Note that a new ABI like you suggested has not been added yet; I will work on that next
>From 5c82797beee422075b9dd55c231afe349447d293 Mon Sep 17 00:00:00 2001
From: Jedidiah Thompson <wej22007@outlook.com>
Date: Wed, 29 Dec 2021 13:34:26 -0500
Subject: [PATCH 2/2] Make aarch64 assember handle varying ABIs on PE
A new ABI should be created specially for Windows / PE, however, that is a larger task that will be handled seperatly
---
bfd/config.bfd | 5 ++--
gas/config/obj-coff.h | 3 ---
gas/config/tc-aarch64.c | 42 +++++++++++-------------------
gas/config/tc-aarch64.h | 57 ++++++++---------------------------------
4 files changed, 28 insertions(+), 79 deletions(-)
diff --git a/bfd/config.bfd b/bfd/config.bfd
index d2ec4c4a38b..e9188870f6d 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -253,9 +253,10 @@ case "${targ}" in
want64=true
;;
aarch64-*-pe)
- targ_defvec=aarch64_pei_le_vec
- targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
+ 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
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
index 5cb89f09d61..641db43ac6d 100644
--- a/gas/config/obj-coff.h
+++ b/gas/config/obj-coff.h
@@ -42,9 +42,6 @@
#ifdef TC_AARCH64
#include "coff/aarch64.h"
-#ifndef TARGET_FORMAT
-#define TARGET_FORMAT "pe-aarch64-little"
-#endif
#endif
#ifdef TC_PPC
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 811f3eedbaa..818d260148d 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -30,8 +30,8 @@
#ifdef OBJ_ELF
#include "elf/aarch64.h"
-#include "dw2gencfi.h"
#endif
+#include "dw2gencfi.h"
#include "dwarf2dbg.h"
@@ -61,6 +61,7 @@ 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
@@ -85,7 +86,6 @@ 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
enum vector_el_type
{
@@ -2028,8 +2028,6 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED)
input_line_pointer--;
demand_empty_rest_of_line ();
}
-
-#ifdef OBJ_ELF
static void
s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
{
@@ -2038,6 +2036,7 @@ s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
fde->pauth_key = AARCH64_PAUTH_KEY_B;
}
+#ifdef OBJ_ELF
/* Emit BFD_RELOC_AARCH64_TLSDESC_ADD on the next ADD instruction. */
static void
@@ -2111,8 +2110,8 @@ const pseudo_typeS md_pseudo_table[] = {
{"arch", s_aarch64_arch, 0},
{"arch_extension", s_aarch64_arch_extension, 0},
{"inst", s_aarch64_inst, 0},
-#ifdef OBJ_ELF
{"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
+#ifdef OBJ_ELF
{"tlsdescadd", s_tlsdescadd, 0},
{"tlsdesccall", s_tlsdesccall, 0},
{"tlsdescldr", s_tlsdescldr, 0},
@@ -8361,6 +8360,8 @@ aarch64_init_frag (fragS * fragP, int max_chars)
}
}
+#endif /* OBJ_ELF */
+
/* Initialize the DWARF-2 unwind information for this procedure. */
void
@@ -8368,7 +8369,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 +8405,8 @@ 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
return bfd_arch_bits_per_address (stdoutput) / 8;
}
@@ -9044,13 +9042,9 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
break;
case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC:
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
fixP->fx_r_type = (ilp32_p
? BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
: BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
-#else
- fixP->fx_r_type = BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
-#endif
S_SET_THREAD_LOCAL (fixP->fx_addsy);
/* Should always be exported to object file, see
aarch64_force_relocation(). */
@@ -9059,14 +9053,10 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
break;
case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC:
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
fixP->fx_r_type = (ilp32_p
? BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
: BFD_RELOC_AARCH64_TLSDESC_LD64_LO12);
-#else
- fixP->fx_r_type = BFD_RELOC_AARCH64_TLSDESC_LD64_LO12;
S_SET_THREAD_LOCAL (fixP->fx_addsy);
-#endif
/* Should always be exported to object file, see
aarch64_force_relocation(). */
gas_assert (!fixP->fx_done);
@@ -9135,13 +9125,9 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_AARCH64_LD_GOT_LO12_NC:
/* Should always be exported to object file, see
aarch64_force_relocation(). */
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
fixP->fx_r_type = (ilp32_p
? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
: BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
-#else
- fixP->fx_r_type = BFD_RELOC_AARCH64_LD64_GOT_LO12_NC;
-#endif
gas_assert (!fixP->fx_done);
gas_assert (seg->use_rela_p);
break;
@@ -9284,7 +9270,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. */
@@ -9302,6 +9287,7 @@ aarch64_after_parse_args (void)
aarch64_abi = AARCH64_ABI_LP64;
}
+#ifdef OBJ_ELF
const char *
elf64_aarch64_target_format (void)
{
@@ -9324,6 +9310,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. */
@@ -9639,11 +9631,7 @@ md_begin (void)
cpu_variant = *mcpu_cpu_opt;
/* Record the CPU type. */
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
mach = ilp32_p ? bfd_mach_aarch64_ilp32 : bfd_mach_aarch64;
-#else
- mach = bfd_mach_aarch64;
-#endif
bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
}
@@ -10204,13 +10192,13 @@ aarch64_parse_arch (const char *str)
}
/* ABIs. */
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
struct aarch64_option_abi_value_table
{
const char *name;
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},
@@ -10237,7 +10225,7 @@ aarch64_parse_abi (const char *str)
as_bad (_("unknown abi `%s'\n"), str);
return 0;
}
-#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
+#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 ccc4a4c3f0c..aae1b64588c 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)
@@ -202,17 +204,18 @@ struct aarch64_frag_type
extern int aarch64_dwarf2_addr_size (void);
#define DWARF2_ADDR_SIZE(bfd) aarch64_dwarf2_addr_size ()
-#ifdef OBJ_ELF
-# define obj_frob_symbol(sym, punt) aarch64elf_frob_symbol ((sym), & (punt))
+#ifdef TE_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
+#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
+#define TC_SEGMENT_INFO_TYPE struct aarch64_segment_info_type
/* This is not really an alignment operation, but it's something we
need to do at the same time: whenever we are figuring out the
alignment for data, we should check whether a $d symbol is
necessary. */
-# define md_cons_align(nbytes) mapping_state (MAP_DATA)
+#define md_cons_align(nbytes) mapping_state (MAP_DATA)
enum mstate
{
@@ -242,38 +245,6 @@ struct aarch64_segment_info_type
extern void aarch64_after_parse_args (void);
#define md_after_parse_args() aarch64_after_parse_args ()
-#elif defined(TE_PEP)
-# define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
-# define TC_SEGMENT_INFO_TYPE struct aarch64_segment_info_type
-
-/* This is not really an alignment operation, but it's something we
- need to do at the same time: whenever we are figuring out the
- alignment for data, we should check whether a $d symbol is
- necessary. */
-# define md_cons_align(nbytes) mapping_state (MAP_DATA)
-
-enum mstate
-{
- MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections. */
- MAP_DATA,
- MAP_INSN,
-};
-
-void mapping_state (enum mstate);
-
-struct aarch64_segment_info_type
-{
- const char *last_file;
- unsigned last_line;
- enum mstate mapstate;
- unsigned int marked_pr_dependency;
- aarch64_instr_sequence insn_sequence;
-};
-
-#else /* Not OBJ_ELF. */
-#define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
-#endif
-
#if defined OBJ_ELF || defined OBJ_COFF
# define EXTERN_FORCE_RELOC 1
@@ -287,6 +258,7 @@ struct aarch64_segment_info_type
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);
@@ -302,13 +274,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);
-#if 0
-
-#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
-
#endif /* TC_AARCH64 */
--
2.32.0
________________________________
From: Tamar Christina <Tamar.Christina@arm.com>
Sent: Wednesday, December 29, 2021 6:38 AM
To: Jedidiah Thompson <wej22007@outlook.com>
Cc: binutils@sourceware.org <binutils@sourceware.org>
Subject: RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
Hi Jedidiah,
Thanks for respinning the patch, a couple more comments below:
>
> From: Jedidiah Thompson <wej22007@outlook.com>
> Sent: Monday, December 27, 2021 5:07 PM
> To: Tamar Christina <Tamar.Christina@arm.com>
> Cc: binutils@sourceware.org
> Subject: Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
>
> Here is the updated patch:
>
> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -249,7 +249,12 @@ 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"
> + want64=true
> + ;;
> + aarch64-*-pe)
> + targ_defvec=aarch64_pei_le_vec
> + targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
> want64=true
64-bit PE is not an underscore platform, so you want targ_underscore=no here too.
Also you want the executable format not the image format as the default here. So
targ_defvec=aarch64_pe_le_vec instead of pei.
> ;;
> aarch64_be-*-elf)
> @@ -279,7 +284,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"
> want64=true
> ;;
> aarch64_be-*-linux* | aarch64_be-*-netbsd*)
> @@ -1534,3 +1539,9 @@ case "${targ_defvec} ${targ_selvecs}" in
> targ_archs="$targ_archs bfd_k1om_arch"
> ;;
> 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
> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index cc7725483aa..811f3eedbaa 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -1475,7 +1475,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),
> @@ -2029,6 +2029,7 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED)
> demand_empty_rest_of_line ();
> }
>
> +#ifdef OBJ_ELF
> static void
> s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
> {
> @@ -2037,7 +2038,6 @@ s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
> fde->pauth_key = AARCH64_PAUTH_KEY_B;
> }
>
> -#ifdef OBJ_ELF
> /* Emit BFD_RELOC_AARCH64_TLSDESC_ADD on the next ADD instruction. */
>
> static void
> @@ -2111,8 +2111,8 @@ const pseudo_typeS md_pseudo_table[] = {
> {"arch", s_aarch64_arch, 0},
> {"arch_extension", s_aarch64_arch_extension, 0},
> {"inst", s_aarch64_inst, 0},
> - {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
> #ifdef OBJ_ELF
> + {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
> {"tlsdescadd", s_tlsdescadd, 0},
> {"tlsdesccall", s_tlsdesccall, 0},
> {"tlsdescldr", s_tlsdescldr, 0},
> @@ -8302,7 +8302,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);
> @@ -9044,9 +9044,13 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
> break;
>
> case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC:
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> fixP->fx_r_type = (ilp32_p
> ? BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
> : BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
> +#else
> + fixP->fx_r_type = BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
> +#endif
not sure I understand why these changes are needed. ilp32_p is based on the ABI and since
-mabi isn't defined for aarch64-*pe you can't ever really set it. So all of these and the below
should already be correct without the ifdefs.
That said the default ABI looks wrong, The default ABI will be set to AARCH64_ABI_LP64.
Since PE/Windos is IL32P64 you'll want a new ABI, AARCH64_ABI_IL32P64 and make that the default in
aarch64_after_parse_args moving that ouf of the ifdef OBJ_ELF.
You'll also want to change TARGET_FORMAT to set the default format for the BFD target.
> S_SET_THREAD_LOCAL (fixP->fx_addsy);
> /* Should always be exported to object file, see
> aarch64_force_relocation(). */
> @@ -9055,10 +9059,14 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
> break;
>
> case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC:
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> fixP->fx_r_type = (ilp32_p
> ? BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
> : BFD_RELOC_AARCH64_TLSDESC_LD64_LO12);
> +#else
> + fixP->fx_r_type = BFD_RELOC_AARCH64_TLSDESC_LD64_LO12;
> S_SET_THREAD_LOCAL (fixP->fx_addsy);
> +#endif
> /* Should always be exported to object file, see
> aarch64_force_relocation(). */
> gas_assert (!fixP->fx_done);
> @@ -9127,9 +9135,13 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
> case BFD_RELOC_AARCH64_LD_GOT_LO12_NC:
> /* Should always be exported to object file, see
> aarch64_force_relocation(). */
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> fixP->fx_r_type = (ilp32_p
> ? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
> : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
> +#else
> + fixP->fx_r_type = BFD_RELOC_AARCH64_LD64_GOT_LO12_NC;
> +#endif
> gas_assert (!fixP->fx_done);
> gas_assert (seg->use_rela_p);
> break;
> @@ -9627,7 +9639,11 @@ md_begin (void)
> cpu_variant = *mcpu_cpu_opt;
>
> /* Record the CPU type. */
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> mach = ilp32_p ? bfd_mach_aarch64_ilp32 : bfd_mach_aarch64;
> +#else
> + mach = bfd_mach_aarch64;
> +#endif
>
> bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
> }
> @@ -10188,6 +10204,7 @@ aarch64_parse_arch (const char *str)
> }
>
> /* ABIs. */
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> struct aarch64_option_abi_value_table
> {
> const char *name;
> @@ -10220,6 +10237,7 @@ aarch64_parse_abi (const char *str)
> as_bad (_("unknown abi `%s'\n"), str);
> return 0;
> }
> +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
>
> 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 78bff0a1b56..ccc4a4c3f0c 100644
> --- a/gas/config/tc-aarch64.h
> +++ b/gas/config/tc-aarch64.h
> @@ -169,7 +169,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
> @@ -242,6 +242,34 @@ struct aarch64_segment_info_type
> extern void aarch64_after_parse_args (void);
> #define md_after_parse_args() aarch64_after_parse_args ()
>
> +#elif defined(TE_PEP)
> +# define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
> +# define TC_SEGMENT_INFO_TYPE struct aarch64_segment_info_type
> +
> +/* This is not really an alignment operation, but it's something we
> + need to do at the same time: whenever we are figuring out the
> + alignment for data, we should check whether a $d symbol is
> + necessary. */
> +# define md_cons_align(nbytes) mapping_state (MAP_DATA)
> +
> +enum mstate
> +{
> + MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections. */
> + MAP_DATA,
> + MAP_INSN,
> +};
> +
> +void mapping_state (enum mstate);
> +
> +struct aarch64_segment_info_type
> +{
> + const char *last_file;
> + unsigned last_line;
> + enum mstate mapstate;
> + unsigned int marked_pr_dependency;
> + aarch64_instr_sequence insn_sequence;
> +};
> +
Any reason you can't just remove the OBJ_ELF or include OBJ_COFF here?
This looks exactly the same code as the OBJ_ELF block and in principle
CFIs should be handled by BFD already.
> #else /* Not OBJ_ELF. */
> #define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
> #endif
> @@ -274,13 +302,13 @@ 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
> +#if 0
>
> #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
This looks like copied left over code from the Arm implementation, just delete the hunk.
Thanks,
Tamar
More information about the Binutils
mailing list