Add aarch64-w64-mingw32 target
authorMark Harmstone <mark@harmstone.com>
Thu, 5 Jan 2023 02:36:32 +0000 (02:36 +0000)
committerMark Harmstone <mark@harmstone.com>
Tue, 10 Jan 2023 23:30:49 +0000 (23:30 +0000)
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.

14 files changed:
bfd/config.bfd
bfd/peicode.h
binutils/configure
binutils/configure.ac
binutils/dlltool.c
binutils/rescoff.c
gas/configure.tgt
gas/testsuite/gas/pe/pe.exp
ld/configure.tgt
ld/emultempl/pep.em
ld/pe-dll.c
ld/testsuite/ld-pe/pe-aarch64.d
ld/testsuite/ld-pe/pe.exp
ld/testsuite/ld-scripts/weak.exp

index 800afa8105f88158b6bf80fe6d2b8c25ba78c905..0b0f7d50602859e095a4a3eee9e57a83c796e614 100644 (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"
     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
     ;;
index 06642c3db5a11ca7f7d08fd4f9661c32cd18a543..68ec3a37c89ded2302cedd2852c6e7f1b9e819e6 100644 (file)
@@ -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
index 20fd420dbaaa180a5a9571b58ec3877dd7e0360b..f27ee48be738421d3a17b3a6ffbb0a3515bfffe3 100755 (executable)
        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
index a217c81858fbb36651e5e3ef5c20da12aea6bfe4..dc93ac1f390712c9acccb6e6e09b994e57cd84f4 100644 (file)
@@ -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
index 7ca6906e2bd7361c51a17324fd529c4cd7d9b37f..31c864d7d5ce70273d42a6809b496cc0eb1366d2 100644 (file)
@@ -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 */
index 1fb6bf411058e50e885a0519c2f1abf3e76983f7..40a8f452a1fc57150d58e5d69ef347b4e12b72fb 100644 (file)
@@ -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))
index c210845d56755a908368028e9b9361734dc12f54..b7a1874781f0ec3e4831e92cc3dfd2b7239f4779 100644 (file)
@@ -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 ;;
index a1bb4bc6a11fdbbd1eb118e1036e6bbc2bf78f9e..172bc3caf6e02e77013e6f799fd43c65ca0d6ebb 100644 (file)
@@ -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"
 }
 
index aa74d2521bf5c21b0b7f32340899f30f36e84ab9..4f9a61f95ce8a6986cb0748aa756a4259248d329 100644 (file)
@@ -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
index 6ac70f9cfa46f515bc5d6306a66e704b239212e8..f0e678b84ed466374fd2d0f8f6fa5a1c70f736a9 100644 (file)
@@ -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
 
@@ -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 \
@@ -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)
@@ -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
@@ -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);
index de876ca509479d7c68401852f4e145fc2ec2d82e..a2584c39d0db55a28d879734aa852e97acc51610 100644 (file)
@@ -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 ();
index fac02b5fd87dc280d3e245d4409ffefe3a43e058..ab6370fb514bd4fe3d2b09f5974fa37748fe703d 100644 (file)
@@ -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
+       ...
index dae8c34066b37165f63afd31c0bac846b6f75acb..c4d48bb8c080e853efd68d1c1d67a17572317d44 100644 (file)
@@ -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 {
index 78d0616a0e19af57cfe81aeea5e746433582472f..bf6f8862571888d4ef00a0b8874cf3359e0d7217 100644 (file)
@@ -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