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 06642c3db5a..68ec3a37c89 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -444,7 +444,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 /*
*/
};
+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