[PATCH 6/7] Add aarch64-w64-mingw32 target
Mark Harmstone
mark@harmstone.com
Fri Jan 6 01:25:08 GMT 2023
---
bfd/config.bfd | 4 +--
bfd/peicode.h | 2 +-
binutils/configure | 10 ++++++
binutils/configure.ac | 10 ++++++
binutils/dlltool.c | 57 +++++++++++++++++++++++++++++---
binutils/rescoff.c | 3 ++
gas/configure.tgt | 2 +-
gas/testsuite/gas/pe/pe.exp | 2 +-
ld/configure.tgt | 4 +--
ld/emultempl/pep.em | 11 +++---
ld/pe-dll.c | 12 +++----
ld/testsuite/ld-pe/pe-aarch64.d | 13 ++++++--
ld/testsuite/ld-pe/pe.exp | 2 +-
ld/testsuite/ld-scripts/weak.exp | 1 +
14 files changed, 109 insertions(+), 24 deletions(-)
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 800afa8105f..0b0f7d50602 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -247,9 +247,9 @@ case "${targ}" in
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*)
+ aarch64-*-pe* | aarch64-*-mingw*)
targ_defvec=aarch64_pe_le_vec
- targ_selvecs="aarch64_pe_le_vec aarch64_pei_le_vec"
+ targ_selvecs="aarch64_pe_le_vec aarch64_pei_le_vec aarch64_elf64_le_vec aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec pdb_vec"
want64=true
targ_underscore=no
;;
diff --git a/bfd/peicode.h b/bfd/peicode.h
index 6b71f204826..3613b44b48b 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -440,7 +440,7 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
#define SIZEOF_IDATA2 (5 * 4)
/* For PEx64 idata4 & 5 have thumb size of 8 bytes. */
-#ifdef COFF_WITH_pex64
+#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
#define SIZEOF_IDATA4 (2 * 4)
#define SIZEOF_IDATA5 (2 * 4)
#else
diff --git a/binutils/configure b/binutils/configure
index 20fd420dbaa..f27ee48be73 100755
--- a/binutils/configure
+++ b/binutils/configure
@@ -14578,6 +14578,16 @@ do
esac
case $targ in
+ aarch64-*-mingw*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ if test -z "$DLLTOOL_DEFAULT"; then
+ DLLTOOL_DEFAULT="-DDLLTOOL_DEFAULT_AARCH64"
+ fi
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_AARCH64"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
+ BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
+ ;;
arm-wince-pe* | arm-*-wince | arm*-*-cegcc* | arm*-*-mingw32ce*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
if test -z "$DLLTOOL_DEFAULT"; then
diff --git a/binutils/configure.ac b/binutils/configure.ac
index a217c81858f..dc93ac1f390 100644
--- a/binutils/configure.ac
+++ b/binutils/configure.ac
@@ -355,6 +355,16 @@ do
esac
case $targ in
+ aarch64-*-mingw*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ if test -z "$DLLTOOL_DEFAULT"; then
+ DLLTOOL_DEFAULT="-DDLLTOOL_DEFAULT_AARCH64"
+ fi
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_AARCH64"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
+ BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
+ ;;
arm-wince-pe* | arm-*-wince | arm*-*-cegcc* | arm*-*-mingw32ce*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
if test -z "$DLLTOOL_DEFAULT"; then
diff --git a/binutils/dlltool.c b/binutils/dlltool.c
index 7ca6906e2bd..31c864d7d5c 100644
--- a/binutils/dlltool.c
+++ b/binutils/dlltool.c
@@ -442,6 +442,11 @@ static const char *mname = "arm";
static const char *mname = "arm-wince";
#endif
+#ifdef DLLTOOL_DEFAULT_AARCH64
+/* arm64 rather than aarch64 to match llvm-dlltool */
+static const char *mname = "arm64";
+#endif
+
#ifdef DLLTOOL_DEFAULT_I386
static const char *mname = "i386";
#endif
@@ -560,6 +565,14 @@ static const unsigned char mcore_le_jtab[] =
0x00, 0x00, 0x00, 0x00 /* <address> */
};
+static const unsigned char aarch64_jtab[] =
+{
+ 0x10, 0x00, 0x00, 0x90, /* adrp x16, 0 */
+ 0x10, 0x02, 0x00, 0x91, /* add x16, x16, #0x0 */
+ 0x10, 0x02, 0x40, 0xf9, /* ldr x16, [x16] */
+ 0x00, 0x02, 0x1f, 0xd6 /* br x16 */
+};
+
static const char i386_trampoline[] =
"\tpushl %%ecx\n"
"\tpushl %%edx\n"
@@ -717,6 +730,15 @@ mtable[] =
i386_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, true, i386_x64_trampoline
}
,
+ {
+#define MAARCH64 10
+ "arm64", ".byte", ".short", ".long", ".asciz", "//",
+ "bl ", ".global", ".space", ".balign\t2", ".balign\t4", "",
+ "pe-aarch64-little", bfd_arch_aarch64,
+ aarch64_jtab, sizeof (aarch64_jtab), 0,
+ 0, 0, 0, 0, 0, false, 0
+ }
+ ,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
@@ -864,6 +886,7 @@ rvaafter (int mach)
case MMCORE_ELF:
case MMCORE_ELF_LE:
case MARM_WINCE:
+ case MAARCH64:
break;
default:
/* xgettext:c-format */
@@ -888,6 +911,7 @@ rvabefore (int mach)
case MMCORE_ELF:
case MMCORE_ELF_LE:
case MARM_WINCE:
+ case MAARCH64:
return ".rva\t";
default:
/* xgettext:c-format */
@@ -910,6 +934,7 @@ asm_prefix (int mach, const char *name)
case MMCORE_ELF:
case MMCORE_ELF_LE:
case MARM_WINCE:
+ case MAARCH64:
break;
case M386:
case MX86:
@@ -2474,6 +2499,8 @@ make_one_lib_file (export_type *exp, int i, int delay)
case TEXT:
if (! exp->data)
{
+ unsigned int rpp_len;
+
si->size = HOW_JTAB_SIZE;
si->data = xmalloc (HOW_JTAB_SIZE);
memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
@@ -2481,7 +2508,12 @@ make_one_lib_file (export_type *exp, int i, int delay)
/* Add the reloc into idata$5. */
rel = xmalloc (sizeof (arelent));
- rpp = xmalloc (sizeof (arelent *) * (delay ? 4 : 2));
+ rpp_len = delay ? 4 : 2;
+
+ if (machine == MAARCH64)
+ rpp_len++;
+
+ rpp = xmalloc (sizeof (arelent *) * rpp_len);
rpp[0] = rel;
rpp[1] = 0;
@@ -2507,6 +2539,22 @@ make_one_lib_file (export_type *exp, int i, int delay)
BFD_RELOC_32_PCREL);
rel->sym_ptr_ptr = iname_pp;
}
+ else if (machine == MAARCH64)
+ {
+ arelent *rel_add;
+
+ rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL);
+ rel->sym_ptr_ptr = secdata[IDATA5].sympp;
+
+ rel_add = xmalloc (sizeof (arelent));
+ rel_add->address = 4;
+ rel_add->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_AARCH64_ADD_LO12);
+ rel_add->sym_ptr_ptr = secdata[IDATA5].sympp;
+ rel_add->addend = 0;
+
+ rpp[rpp_len - 2] = rel_add;
+ rpp[rpp_len - 1] = 0;
+ }
else
{
rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
@@ -2527,7 +2575,7 @@ make_one_lib_file (export_type *exp, int i, int delay)
}
sec->orelocation = rpp;
- sec->reloc_count = delay ? 3 : 1;
+ sec->reloc_count = rpp_len - 1;
}
break;
@@ -3674,7 +3722,7 @@ usage (FILE *file, int status)
fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
/* xgetext:c-format */
fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname);
- fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, thumb\n"));
+ fprintf (file, _(" possible <machine>: arm[_interwork], arm64, i386, mcore[-elf]{-le|-be}, thumb\n"));
fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
fprintf (file, _(" -y --output-delaylib <outname> Create a delay-import library.\n"));
@@ -3967,7 +4015,8 @@ main (int ac, char **av)
machine = i;
/* Check if we generated PE+. */
- create_for_pep = strcmp (mname, "i386:x86-64") == 0;
+ create_for_pep = strcmp (mname, "i386:x86-64") == 0 ||
+ strcmp (mname, "arm64") == 0;
{
/* Check the default underscore */
diff --git a/binutils/rescoff.c b/binutils/rescoff.c
index 1fb6bf41105..40a8f452a1f 100644
--- a/binutils/rescoff.c
+++ b/binutils/rescoff.c
@@ -463,6 +463,9 @@ write_coff_file (const char *filename, const char *target,
#elif defined DLLTOOL_ARM
if (! bfd_set_arch_mach (abfd, bfd_arch_arm, 0))
bfd_fatal ("bfd_set_arch_mach(arm)");
+#elif defined DLLTOOL_AARCH64
+ if (! bfd_set_arch_mach (abfd, bfd_arch_aarch64, 0))
+ bfd_fatal ("bfd_set_arch_mach(aarch64)");
#else
/* FIXME: This is obviously i386 specific. */
if (! bfd_set_arch_mach (abfd, bfd_arch_i386, 0))
diff --git a/gas/configure.tgt b/gas/configure.tgt
index c210845d567..b7a1874781f 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 ;;
+ aarch64*-*-pe* | aarch64*-*-mingw*) 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.exp b/gas/testsuite/gas/pe/pe.exp
index a1bb4bc6a11..172bc3caf6e 100644
--- a/gas/testsuite/gas/pe/pe.exp
+++ b/gas/testsuite/gas/pe/pe.exp
@@ -54,7 +54,7 @@ if ([istarget "x86_64-*-mingw*"]) then {
# This test is only for AArch64
-if ([istarget "aarch64-*-pe*"]) {
+if {[istarget "aarch64-*-pe*"] || [istarget "aarch64-*-mingw*"]} {
run_dump_test "pe-aarch64"
}
diff --git a/ld/configure.tgt b/ld/configure.tgt
index aa74d2521bf..4f9a61f95ce 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -118,10 +118,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*)
+aarch64-*-pe* | aarch64-*-mingw*)
targ_emul=aarch64pe
targ_extra_emuls="arm64pe"
- targ_extra_ofiles="deffilep.o pep-dll-aarch64.o"
+ targ_extra_ofiles="deffilep.o pep-dll-aarch64.o pe-dll.o"
;;
alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
targ_emul=elf64alpha_fbsd
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index d61cab86d75..d900e384d51 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -117,7 +117,7 @@ ${pdb_support+#include \"pdb.h\"}
#define PE_DEF_SECTION_ALIGNMENT ${OVERRIDE_SECTION_ALIGNMENT}
#endif
-#ifdef TARGET_IS_i386pep
+#if defined(TARGET_IS_i386pep) || defined(COFF_WITH_peAArch64)
#define DLL_SUPPORT
#endif
@@ -126,7 +126,7 @@ ${pdb_support+#include \"pdb.h\"}
| IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA \
| IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
-#if defined(TARGET_IS_i386pep) || ! defined(DLL_SUPPORT)
+#if defined(TARGET_IS_i386pep) || defined(COFF_WITH_peAArch64) || ! defined(DLL_SUPPORT)
#define PE_DEF_SUBSYSTEM 3
#undef NT_EXE_IMAGE_BASE
#define NT_EXE_IMAGE_BASE \
@@ -1218,6 +1218,7 @@ make_import_fixup (arelent *rel, asection *s, char *name, const char *symname)
else if (suc)
_addend = bfd_get_16 (s->owner, addend);
break;
+ case 26:
case 32:
suc = bfd_get_section_contents (s->owner, s, addend, rel->address, 4);
if (suc && rel->howto->pc_relative)
@@ -1573,14 +1574,14 @@ gld${EMULATION_NAME}_after_open (void)
if (pep_enable_stdcall_fixup) /* -1=warn or 1=enable */
pep_fixup_stdcalls ();
-#ifndef TARGET_IS_i386pep
+#if !defined(TARGET_IS_i386pep) && !defined(COFF_WITH_peAArch64)
if (bfd_link_pic (&link_info))
#else
if (!bfd_link_relocatable (&link_info))
#endif
pep_dll_build_sections (link_info.output_bfd, &link_info);
-#ifndef TARGET_IS_i386pep
+#if !defined(TARGET_IS_i386pep) && !defined(COFF_WITH_peAArch64)
else
pep_exe_build_sections (link_info.output_bfd, &link_info);
#endif
@@ -1876,6 +1877,8 @@ gld${EMULATION_NAME}_recognized_file (lang_input_statement_type *entry ATTRIBUTE
#ifdef DLL_SUPPORT
#ifdef TARGET_IS_i386pep
pep_dll_id_target ("pei-x86-64");
+#elif defined(COFF_WITH_peAArch64)
+ pep_dll_id_target ("pei-aarch64-little");
#endif
if (pep_bfd_is_dll (entry->the_bfd))
return pep_implied_import_dll (entry->filename);
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index de876ca5094..a2584c39d0d 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -2257,13 +2257,12 @@ 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
+ 0x10, 0x00, 0x00, 0x90, /* adrp x16, 0 */
+ 0x10, 0x02, 0x00, 0x91, /* add x16, x16, #0x0 */
+ 0x10, 0x02, 0x40, 0xf9, /* ldr x16, [x16] */
+ 0x00, 0x02, 0x1f, 0xd6 /* br x16 */
};
/* _function:
@@ -2431,7 +2430,8 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
quick_reloc (abfd, 8, BFD_RELOC_32, 2);
break;
case PE_ARCH_aarch64:
- quick_reloc (abfd, 0, BFD_RELOC_AARCH64_JUMP26, 2);
+ quick_reloc (abfd, 0, BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL, 2);
+ quick_reloc (abfd, 4, BFD_RELOC_AARCH64_ADD_LO12, 2);
break;
default:
abort ();
diff --git a/ld/testsuite/ld-pe/pe-aarch64.d b/ld/testsuite/ld-pe/pe-aarch64.d
index fac02b5fd87..ab6370fb514 100644
--- a/ld/testsuite/ld-pe/pe-aarch64.d
+++ b/ld/testsuite/ld-pe/pe-aarch64.d
@@ -6,11 +6,20 @@
Disassembly of section .text:
-0000000140001000 <__rt_psrelocs_end>:
+0000000140001000 <___crt_xc_end__>:
140001000: d2800281 mov x1, #0x14 // #20
140001004: 14000001 b 140001008 <foo>
0000000140001008 <foo>:
140001008: d65f03c0 ret
14000100c: 00000000 udf #0
-#...
+
+0000000140001010 <__CTOR_LIST__>:
+ 140001010: ffffffff .inst 0xffffffff ; undefined
+ 140001014: ffffffff .inst 0xffffffff ; undefined
+ ...
+
+0000000140001020 <__DTOR_LIST__>:
+ 140001020: ffffffff .inst 0xffffffff ; undefined
+ 140001024: ffffffff .inst 0xffffffff ; undefined
+ ...
diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp
index dae8c34066b..c4d48bb8c08 100644
--- a/ld/testsuite/ld-pe/pe.exp
+++ b/ld/testsuite/ld-pe/pe.exp
@@ -78,7 +78,7 @@ if {[istarget i*86-*-cygwin*]
run_ld_link_tests $pe_tests
}
-if {[istarget "aarch64-*-pe*"]} {
+if {[istarget "aarch64-*-pe*"] || [istarget "aarch64-*-mingw*"]} {
run_dump_test "pe-aarch64"
set pe_tests {
diff --git a/ld/testsuite/ld-scripts/weak.exp b/ld/testsuite/ld-scripts/weak.exp
index 78d0616a0e1..bf6f8862571 100644
--- a/ld/testsuite/ld-scripts/weak.exp
+++ b/ld/testsuite/ld-scripts/weak.exp
@@ -31,6 +31,7 @@ if {! [is_elf_format] && ! [is_pecoff_format]} {
# Weak symbols are broken for most PE targets.
if {! [istarget i?86-*-*] && ! [istarget sh-*-*]} {
setup_xfail *-*-pe*
+ setup_xfail *-*-mingw*
}
# hppa64 is incredibly broken
--
2.37.4
More information about the Binutils
mailing list