Add aarch64-w64-mingw32 target

This adds a mingw target for aarch64, including windres and dlltool.

Note that the old value of jmp_aarch64_bytes was wrong, and this does
the same thing as MSVC does.
This commit is contained in:
Mark Harmstone
2023-01-05 02:36:32 +00:00
parent 528e4f463f
commit 16fea92ccd
14 changed files with 109 additions and 24 deletions

View File

@ -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" 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 want64=true
;; ;;
aarch64-*-pe*) aarch64-*-pe* | aarch64-*-mingw*)
targ_defvec=aarch64_pe_le_vec 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 want64=true
targ_underscore=no targ_underscore=no
;; ;;

View File

@ -444,7 +444,7 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
#define SIZEOF_IDATA2 (5 * 4) #define SIZEOF_IDATA2 (5 * 4)
/* For PEx64 idata4 & 5 have thumb size of 8 bytes. */ /* 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_IDATA4 (2 * 4)
#define SIZEOF_IDATA5 (2 * 4) #define SIZEOF_IDATA5 (2 * 4)
#else #else

10
binutils/configure vendored
View File

@ -14578,6 +14578,16 @@ do
esac esac
case $targ in 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*) arm-wince-pe* | arm-*-wince | arm*-*-cegcc* | arm*-*-mingw32ce*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
if test -z "$DLLTOOL_DEFAULT"; then if test -z "$DLLTOOL_DEFAULT"; then

View File

@ -355,6 +355,16 @@ do
esac esac
case $targ in 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*) arm-wince-pe* | arm-*-wince | arm*-*-cegcc* | arm*-*-mingw32ce*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
if test -z "$DLLTOOL_DEFAULT"; then if test -z "$DLLTOOL_DEFAULT"; then

View File

@ -442,6 +442,11 @@ static const char *mname = "arm";
static const char *mname = "arm-wince"; static const char *mname = "arm-wince";
#endif #endif
#ifdef DLLTOOL_DEFAULT_AARCH64
/* arm64 rather than aarch64 to match llvm-dlltool */
static const char *mname = "arm64";
#endif
#ifdef DLLTOOL_DEFAULT_I386 #ifdef DLLTOOL_DEFAULT_I386
static const char *mname = "i386"; static const char *mname = "i386";
#endif #endif
@ -560,6 +565,14 @@ static const unsigned char mcore_le_jtab[] =
0x00, 0x00, 0x00, 0x00 /* <address> */ 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[] = static const char i386_trampoline[] =
"\tpushl %%ecx\n" "\tpushl %%ecx\n"
"\tpushl %%edx\n" "\tpushl %%edx\n"
@ -717,6 +730,15 @@ mtable[] =
i386_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, true, i386_x64_trampoline 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 } { 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:
case MMCORE_ELF_LE: case MMCORE_ELF_LE:
case MARM_WINCE: case MARM_WINCE:
case MAARCH64:
break; break;
default: default:
/* xgettext:c-format */ /* xgettext:c-format */
@ -888,6 +911,7 @@ rvabefore (int mach)
case MMCORE_ELF: case MMCORE_ELF:
case MMCORE_ELF_LE: case MMCORE_ELF_LE:
case MARM_WINCE: case MARM_WINCE:
case MAARCH64:
return ".rva\t"; return ".rva\t";
default: default:
/* xgettext:c-format */ /* xgettext:c-format */
@ -910,6 +934,7 @@ asm_prefix (int mach, const char *name)
case MMCORE_ELF: case MMCORE_ELF:
case MMCORE_ELF_LE: case MMCORE_ELF_LE:
case MARM_WINCE: case MARM_WINCE:
case MAARCH64:
break; break;
case M386: case M386:
case MX86: case MX86:
@ -2474,6 +2499,8 @@ make_one_lib_file (export_type *exp, int i, int delay)
case TEXT: case TEXT:
if (! exp->data) if (! exp->data)
{ {
unsigned int rpp_len;
si->size = HOW_JTAB_SIZE; si->size = HOW_JTAB_SIZE;
si->data = xmalloc (HOW_JTAB_SIZE); si->data = xmalloc (HOW_JTAB_SIZE);
memcpy (si->data, HOW_JTAB, 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. */ /* Add the reloc into idata$5. */
rel = xmalloc (sizeof (arelent)); 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[0] = rel;
rpp[1] = 0; rpp[1] = 0;
@ -2507,6 +2539,22 @@ make_one_lib_file (export_type *exp, int i, int delay)
BFD_RELOC_32_PCREL); BFD_RELOC_32_PCREL);
rel->sym_ptr_ptr = iname_pp; 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 else
{ {
rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 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->orelocation = rpp;
sec->reloc_count = delay ? 3 : 1; sec->reloc_count = rpp_len - 1;
} }
break; break;
@ -3674,7 +3722,7 @@ usage (FILE *file, int status)
fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name); fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
/* xgetext:c-format */ /* xgetext:c-format */
fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname); 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, _(" -e --output-exp <outname> Generate an export file.\n"));
fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n")); fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
fprintf (file, _(" -y --output-delaylib <outname> Create a delay-import 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; machine = i;
/* Check if we generated PE+. */ /* 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 */ /* Check the default underscore */

View File

@ -463,6 +463,9 @@ write_coff_file (const char *filename, const char *target,
#elif defined DLLTOOL_ARM #elif defined DLLTOOL_ARM
if (! bfd_set_arch_mach (abfd, bfd_arch_arm, 0)) if (! bfd_set_arch_mach (abfd, bfd_arch_arm, 0))
bfd_fatal ("bfd_set_arch_mach(arm)"); 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 #else
/* FIXME: This is obviously i386 specific. */ /* FIXME: This is obviously i386 specific. */
if (! bfd_set_arch_mach (abfd, bfd_arch_i386, 0)) if (! bfd_set_arch_mach (abfd, bfd_arch_i386, 0))

View File

@ -135,7 +135,7 @@ case ${generic_target} in
esac ;; esac ;;
aarch64*-*-netbsd*) fmt=elf em=nbsd;; aarch64*-*-netbsd*) fmt=elf em=nbsd;;
aarch64*-*-openbsd*) fmt=elf;; aarch64*-*-openbsd*) fmt=elf;;
aarch64*-*-pe*) fmt=coff em=pepaarch64 ;; aarch64*-*-pe* | aarch64*-*-mingw*) fmt=coff em=pepaarch64 ;;
alpha-*-*vms*) fmt=evax ;; alpha-*-*vms*) fmt=evax ;;
alpha-*-osf*) fmt=ecoff ;; alpha-*-osf*) fmt=ecoff ;;
alpha-*-linux*ecoff*) fmt=ecoff ;; alpha-*-linux*ecoff*) fmt=ecoff ;;

View File

@ -54,7 +54,7 @@ if ([istarget "x86_64-*-mingw*"]) then {
# This test is only for AArch64 # This test is only for AArch64
if ([istarget "aarch64-*-pe*"]) { if {[istarget "aarch64-*-pe*"] || [istarget "aarch64-*-mingw*"]} {
run_dump_test "pe-aarch64" run_dump_test "pe-aarch64"
} }

View File

@ -118,10 +118,10 @@ aarch64-*-linux*) targ_emul=aarch64linux
aarch64-*-haiku*) targ_emul=aarch64haiku aarch64-*-haiku*) targ_emul=aarch64haiku
targ_extra_emuls="aarch64elf aarch64elf32 aarch64elf32b aarch64elfb armelf armelfb armelf_haiku $targ_extra_libpath" targ_extra_emuls="aarch64elf aarch64elf32 aarch64elf32b aarch64elfb armelf armelfb armelf_haiku $targ_extra_libpath"
;; ;;
aarch64-*-pe*) aarch64-*-pe* | aarch64-*-mingw*)
targ_emul=aarch64pe targ_emul=aarch64pe
targ_extra_emuls="arm64pe" 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) alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
targ_emul=elf64alpha_fbsd targ_emul=elf64alpha_fbsd

View File

@ -121,7 +121,7 @@ fragment <<EOF
#define PE_DEF_SECTION_ALIGNMENT ${OVERRIDE_SECTION_ALIGNMENT} #define PE_DEF_SECTION_ALIGNMENT ${OVERRIDE_SECTION_ALIGNMENT}
#endif #endif
#ifdef TARGET_IS_i386pep #if defined(TARGET_IS_i386pep) || defined(COFF_WITH_peAArch64)
#define DLL_SUPPORT #define DLL_SUPPORT
#endif #endif
@ -130,7 +130,7 @@ fragment <<EOF
| IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA \ | IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA \
| IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) | 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 #define PE_DEF_SUBSYSTEM 3
#undef NT_EXE_IMAGE_BASE #undef NT_EXE_IMAGE_BASE
#define NT_EXE_IMAGE_BASE \ #define NT_EXE_IMAGE_BASE \
@ -1222,6 +1222,7 @@ make_import_fixup (arelent *rel, asection *s, char *name, const char *symname)
else if (suc) else if (suc)
_addend = bfd_get_16 (s->owner, addend); _addend = bfd_get_16 (s->owner, addend);
break; break;
case 26:
case 32: case 32:
suc = bfd_get_section_contents (s->owner, s, addend, rel->address, 4); suc = bfd_get_section_contents (s->owner, s, addend, rel->address, 4);
if (suc && rel->howto->pc_relative) if (suc && rel->howto->pc_relative)
@ -1577,14 +1578,14 @@ gld${EMULATION_NAME}_after_open (void)
if (pep_enable_stdcall_fixup) /* -1=warn or 1=enable */ if (pep_enable_stdcall_fixup) /* -1=warn or 1=enable */
pep_fixup_stdcalls (); pep_fixup_stdcalls ();
#ifndef TARGET_IS_i386pep #if !defined(TARGET_IS_i386pep) && !defined(COFF_WITH_peAArch64)
if (bfd_link_pic (&link_info)) if (bfd_link_pic (&link_info))
#else #else
if (!bfd_link_relocatable (&link_info)) if (!bfd_link_relocatable (&link_info))
#endif #endif
pep_dll_build_sections (link_info.output_bfd, &link_info); pep_dll_build_sections (link_info.output_bfd, &link_info);
#ifndef TARGET_IS_i386pep #if !defined(TARGET_IS_i386pep) && !defined(COFF_WITH_peAArch64)
else else
pep_exe_build_sections (link_info.output_bfd, &link_info); pep_exe_build_sections (link_info.output_bfd, &link_info);
#endif #endif
@ -1880,6 +1881,8 @@ gld${EMULATION_NAME}_recognized_file (lang_input_statement_type *entry ATTRIBUTE
#ifdef DLL_SUPPORT #ifdef DLL_SUPPORT
#ifdef TARGET_IS_i386pep #ifdef TARGET_IS_i386pep
pep_dll_id_target ("pei-x86-64"); pep_dll_id_target ("pei-x86-64");
#elif defined(COFF_WITH_peAArch64)
pep_dll_id_target ("pei-aarch64-little");
#endif #endif
if (pep_bfd_is_dll (entry->the_bfd)) if (pep_bfd_is_dll (entry->the_bfd))
return pep_implied_import_dll (entry->filename); return pep_implied_import_dll (entry->filename);

View File

@ -2257,13 +2257,12 @@ static const unsigned char jmp_ix86_bytes[] =
0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
}; };
/* _function:
b <__imp_function>
nop */
static const unsigned char jmp_aarch64_bytes[] = static const unsigned char jmp_aarch64_bytes[] =
{ {
0x00, 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x90, /* adrp x16, 0 */
0x1f, 0x20, 0x03, 0xD5 0x10, 0x02, 0x00, 0x91, /* add x16, x16, #0x0 */
0x10, 0x02, 0x40, 0xf9, /* ldr x16, [x16] */
0x00, 0x02, 0x1f, 0xd6 /* br x16 */
}; };
/* _function: /* _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); quick_reloc (abfd, 8, BFD_RELOC_32, 2);
break; break;
case PE_ARCH_aarch64: 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; break;
default: default:
abort (); abort ();

View File

@ -6,11 +6,20 @@
Disassembly of section .text: Disassembly of section .text:
0000000140001000 <__rt_psrelocs_end>: 0000000140001000 <___crt_xc_end__>:
140001000: d2800281 mov x1, #0x14 // #20 140001000: d2800281 mov x1, #0x14 // #20
140001004: 14000001 b 140001008 <foo> 140001004: 14000001 b 140001008 <foo>
0000000140001008 <foo>: 0000000140001008 <foo>:
140001008: d65f03c0 ret 140001008: d65f03c0 ret
14000100c: 00000000 udf #0 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
...

View File

@ -78,7 +78,7 @@ if {[istarget i*86-*-cygwin*]
run_ld_link_tests $pe_tests run_ld_link_tests $pe_tests
} }
if {[istarget "aarch64-*-pe*"]} { if {[istarget "aarch64-*-pe*"] || [istarget "aarch64-*-mingw*"]} {
run_dump_test "pe-aarch64" run_dump_test "pe-aarch64"
set pe_tests { set pe_tests {

View File

@ -31,6 +31,7 @@ if {! [is_elf_format] && ! [is_pecoff_format]} {
# Weak symbols are broken for most PE targets. # Weak symbols are broken for most PE targets.
if {! [istarget i?86-*-*] && ! [istarget sh-*-*]} { if {! [istarget i?86-*-*] && ! [istarget sh-*-*]} {
setup_xfail *-*-pe* setup_xfail *-*-pe*
setup_xfail *-*-mingw*
} }
# hppa64 is incredibly broken # hppa64 is incredibly broken