Skip to content

Commit

Permalink
Add aarch64-w64-mingw32 target
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
maharmstone committed Jan 10, 2023
1 parent 528e4f4 commit 16fea92
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 24 deletions.
4 changes: 2 additions & 2 deletions bfd/config.bfd
Original file line number Diff line number Diff line change
Expand Up @@ -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
;;
Expand Down
2 changes: 1 addition & 1 deletion bfd/peicode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions binutils/configure
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions binutils/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
57 changes: 53 additions & 4 deletions binutils/dlltool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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 }
};

Expand Down Expand Up @@ -864,6 +886,7 @@ rvaafter (int mach)
case MMCORE_ELF:
case MMCORE_ELF_LE:
case MARM_WINCE:
case MAARCH64:
break;
default:
/* xgettext:c-format */
Expand All @@ -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 */
Expand All @@ -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:
Expand Down Expand Up @@ -2474,14 +2499,21 @@ 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);

/* 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;

Expand All @@ -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);
Expand All @@ -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;

Expand Down Expand Up @@ -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"));
Expand Down Expand Up @@ -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 */
Expand Down
3 changes: 3 additions & 0 deletions binutils/rescoff.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion gas/configure.tgt
Original file line number Diff line number Diff line change
Expand Up @@ -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 ;;
Expand Down
2 changes: 1 addition & 1 deletion gas/testsuite/gas/pe/pe.exp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}

Expand Down
4 changes: 2 additions & 2 deletions ld/configure.tgt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions ld/emultempl/pep.em
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fragment <<EOF
#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

Expand All @@ -130,7 +130,7 @@ fragment <<EOF
| 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 \
Expand Down Expand Up @@ -1222,6 +1222,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)
Expand Down Expand Up @@ -1577,14 +1578,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
Expand Down Expand Up @@ -1880,6 +1881,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);
Expand Down
12 changes: 6 additions & 6 deletions ld/pe-dll.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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 ();
Expand Down
13 changes: 11 additions & 2 deletions ld/testsuite/ld-pe/pe-aarch64.d
Original file line number Diff line number Diff line change
Expand Up @@ -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
...
2 changes: 1 addition & 1 deletion ld/testsuite/ld-pe/pe.exp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions ld/testsuite/ld-scripts/weak.exp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 16fea92

Please sign in to comment.