public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
@ 2021-12-23 13:07 Jedidiah Thompson
  2021-12-24 15:57 ` Tamar Christina
  0 siblings, 1 reply; 10+ messages in thread
From: Jedidiah Thompson @ 2021-12-23 13:07 UTC (permalink / raw)
  To: binutils

In case sending an attachment wasn't correct, here is the patch in a non attached form


---
 bfd/ChangeLog              | 14 ++++++++
 bfd/Makefile.am            |  1 +
 bfd/Makefile.in            |  3 ++
 bfd/bfd.c                  |  2 +-
 bfd/coff-aarch64.c         |  2 +-
 bfd/config.bfd             |  8 +++++
 bfd/configure              | 31 +++++++++++-----
 bfd/configure.ac           |  1 +
 bfd/doc/Makefile.in        |  1 +
 bfd/libpei.h               | 70 ++++++++++++++++++------------------
 bfd/pe-aarch64.c           | 74 ++++++++++++++++++++++++++++++++++++++
 bfd/pei-aarch64.c          |  2 +-
 bfd/peicode.h              |  2 ++
 bfd/targets.c              |  2 ++
 gas/ChangeLog              |  6 ++++
 gas/config/obj-coff.h      |  7 ++++
 gas/config/tc-aarch64.c    | 26 +++++++++++---
 gas/config/tc-aarch64.h    | 34 ++++++++++++++++--
 gas/configure.tgt          |  1 +
 ld/ChangeLog               | 11 ++++++
 ld/Makefile.am             |  1 +
 ld/Makefile.in             |  3 ++
 ld/configure.tgt           |  6 +++-
 ld/emulparams/aarch64pe.sh |  9 +++++
 ld/emultempl/pep.em        |  8 +++++
 ld/pe-dll.c                | 44 ++++++++++++++++++-----
 ld/pep-dll-aarch64.c       | 24 +++++++++++++
 ld/pep-dll-x86_64.c        | 24 +++++++++++++
 ld/pep-dll.c               |  7 ++--
 29 files changed, 357 insertions(+), 67 deletions(-)
 create mode 100644 bfd/pe-aarch64.c
 create mode 100644 ld/emulparams/aarch64pe.sh
 create mode 100644 ld/pep-dll-aarch64.c
 create mode 100644 ld/pep-dll-x86_64.c

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 24311710088..fd81fb5bc0d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,17 @@
+2021-12-22 Jedidiah Thompson <wej22007 [at] outlook [com]>
+
+       doc/Makefile.in: regenerate
+       bfd.c: change pe-aarch64-little to pe-aarch64
+       coff-aarch64.c: change pe-aarch64-little to pe-aarch64
+       config.bfd: add aarch64-pe target
+       configure: regenerate
+       configure.ac: add aarch64_pe vector
+       Makefile.am: add pe-aarch64.c
+       Makefile.in: regenerate
+       pe-aarch64.c: create
+       peicode.h: add COFF_WITH_peAArch64 case coff_swap_filehdr_out
+       targets.c: add aarch64_pe vector
+
 2021-12-15  Nikita Popov  <npv1310@gmail.com>

        PR 28687
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 4960cb500b1..44cfabc185e 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -616,6 +616,7 @@ BFD64_BACKENDS_CFILES = \
        mmo.c \
        pe-x86_64.c \
        pei-aarch64.c \
+       pe-aarch64.c \
        pei-ia64.c \
        pei-x86_64.c \
        vms-alpha.c
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index a838262bc78..8e398d2cbc6 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -439,6 +439,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -1043,6 +1044,7 @@ BFD64_BACKENDS_CFILES = \
        mmo.c \
        pe-x86_64.c \
        pei-aarch64.c \
+       pe-aarch64.c \
        pei-ia64.c \
        pei-x86_64.c \
        vms-alpha.c
@@ -1574,6 +1576,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osf-core.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pc532-mach.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdp11.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-aarch64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-aarch64igen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm-wince.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm.Plo@am__quote@
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 2eff8150023..e98d0195d32 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1738,7 +1738,7 @@ bfd_get_sign_extend_vma (bfd *abfd)
       || strcmp (name, "pei-i386") == 0
       || strcmp (name, "pe-x86-64") == 0
       || strcmp (name, "pei-x86-64") == 0
-      || strcmp (name, "pei-aarch64-little") == 0
+      || strcmp (name, "pei-aarch64") == 0
       || strcmp (name, "pe-arm-wince-little") == 0
       || strcmp (name, "pei-arm-wince-little") == 0
       || strcmp (name, "aixcoff-rs6000") == 0
diff --git a/bfd/coff-aarch64.c b/bfd/coff-aarch64.c
index a9bc417fae8..a31b72b807d 100644
--- a/bfd/coff-aarch64.c
+++ b/bfd/coff-aarch64.c
@@ -95,7 +95,7 @@ const bfd_target
 #ifdef TARGET_NAME
   TARGET_NAME,
 #else
- "pei-aarch64-little",                 /* Name.  */
+ "pei-aarch64",                        /* Name.  */
 #endif
   bfd_target_coff_flavour,
   BFD_ENDIAN_LITTLE,           /* Data byte order is little.  */
diff --git a/bfd/config.bfd b/bfd/config.bfd
index c062ef8b44c..d8be9e16ae6 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -257,6 +257,14 @@ case "${targ}" in
     targ_selvecs="aarch64_elf64_le_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_be_vec arm_elf32_le_vec"
     want64=true
     ;;
+  aarch64-*-pe)
+    # Not currently complete (and probably not stable), warn user
+    echo "*** WARNING BFD aarch64-pe support not complete nor stable"
+    echo "*** Do not rely on this for production purposes"
+    targ_defvec=aarch64_pei_vec
+    targ_selvecs="aarch64_pe_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
+    want64=true
+    ;;
   aarch64-*-freebsd*)
     targ_defvec=aarch64_elf64_le_vec
     targ_selvecs="aarch64_elf64_be_vec arm_elf32_le_vec arm_elf32_be_vec"
diff --git a/bfd/configure b/bfd/configure
index d4aa2178b29..4550e32a2f5 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -794,6 +794,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -891,6 +892,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1143,6 +1145,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;

+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1280,7 +1291,7 @@ fi
 for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+               libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1433,6 +1444,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -11084,7 +11096,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11087 "configure"
+#line 11099 "configure"
 #include "confdefs.h"

 #if HAVE_DLFCN_H
@@ -11190,7 +11202,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11193 "configure"
+#line 11205 "configure"
 #include "confdefs.h"

 #if HAVE_DLFCN_H
@@ -11620,7 +11632,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -11666,7 +11678,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -11690,7 +11702,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -11735,7 +11747,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -11759,7 +11771,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -13297,6 +13309,7 @@ do
     aarch64_elf64_le_cloudabi_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     aarch64_mach_o_vec)                 tb="$tb mach-o-aarch64.lo"; target_size=64 ;;
     aarch64_pei_vec)            tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
+    aarch64_pe_vec)     tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
     alpha_ecoff_le_vec)                 tb="$tb coff-alpha.lo ecoff.lo $ecoff"; target_size=64 ;;
     alpha_elf64_vec)            tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
     alpha_elf64_fbsd_vec)       tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
@@ -14993,6 +15006,8 @@ main ()
     if (*(data + i) != *(data3 + i))
       return 14;
   close (fd);
+  free (data);
+  free (data3);
   return 0;
 }
 _ACEOF
diff --git a/bfd/configure.ac b/bfd/configure.ac
index a578c3a019e..7eef17067b2 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -438,6 +438,7 @@ do
     aarch64_elf64_le_cloudabi_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     aarch64_mach_o_vec)                 tb="$tb mach-o-aarch64.lo"; target_size=64 ;;
     aarch64_pei_vec)            tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
+    aarch64_pe_vec)     tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
     alpha_ecoff_le_vec)                 tb="$tb coff-alpha.lo ecoff.lo $ecoff"; target_size=64 ;;
     alpha_elf64_vec)            tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
     alpha_elf64_fbsd_vec)       tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
index c070dd8c458..27e44971e85 100644
--- a/bfd/doc/Makefile.in
+++ b/bfd/doc/Makefile.in
@@ -376,6 +376,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/bfd/libpei.h b/bfd/libpei.h
index 26589e8e520..272ae0485a3 100644
--- a/bfd/libpei.h
+++ b/bfd/libpei.h
@@ -240,41 +240,6 @@
 #define _bfd_XXi_write_codeview_record                 _bfd_pex64i_write_codeview_record
 #define _bfd_XXi_slurp_codeview_record                 _bfd_pex64i_slurp_codeview_record

-#elif defined COFF_WITH_pep
-
-#define GET_OPTHDR_IMAGE_BASE H_GET_64
-#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
-#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64
-#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64
-#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64
-#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64
-#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64
-#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64
-#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64
-#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64
-#define GET_PDATA_ENTRY bfd_get_64
-
-#define _bfd_XX_bfd_copy_private_bfd_data_common       _bfd_pep_bfd_copy_private_bfd_data_common
-#define _bfd_XX_bfd_copy_private_section_data          _bfd_pep_bfd_copy_private_section_data
-#define _bfd_XX_get_symbol_info                                _bfd_pep_get_symbol_info
-#define _bfd_XX_only_swap_filehdr_out                  _bfd_pep_only_swap_filehdr_out
-#define _bfd_XX_print_private_bfd_data_common          _bfd_pep_print_private_bfd_data_common
-#define _bfd_XXi_final_link_postscript                 _bfd_pepi_final_link_postscript
-#define _bfd_XXi_only_swap_filehdr_out                 _bfd_pepi_only_swap_filehdr_out
-#define _bfd_XXi_swap_aouthdr_in                       _bfd_pepi_swap_aouthdr_in
-#define _bfd_XXi_swap_aouthdr_out                      _bfd_pepi_swap_aouthdr_out
-#define _bfd_XXi_swap_aux_in                           _bfd_pepi_swap_aux_in
-#define _bfd_XXi_swap_aux_out                          _bfd_pepi_swap_aux_out
-#define _bfd_XXi_swap_lineno_in                                _bfd_pepi_swap_lineno_in
-#define _bfd_XXi_swap_lineno_out                       _bfd_pepi_swap_lineno_out
-#define _bfd_XXi_swap_scnhdr_out                       _bfd_pepi_swap_scnhdr_out
-#define _bfd_XXi_swap_sym_in                           _bfd_pepi_swap_sym_in
-#define _bfd_XXi_swap_sym_out                          _bfd_pepi_swap_sym_out
-#define _bfd_XXi_swap_debugdir_in                      _bfd_pepi_swap_debugdir_in
-#define _bfd_XXi_swap_debugdir_out                     _bfd_pepi_swap_debugdir_out
-#define _bfd_XXi_write_codeview_record                 _bfd_pepi_write_codeview_record
-#define _bfd_XXi_slurp_codeview_record                 _bfd_pepi_slurp_codeview_record
-
 #elif defined COFF_WITH_peAArch64

 #define GET_OPTHDR_IMAGE_BASE           H_GET_64
@@ -310,6 +275,41 @@
 #define _bfd_XXi_write_codeview_record                 _bfd_peAArch64i_write_codeview_record
 #define _bfd_XXi_slurp_codeview_record                 _bfd_peAArch64i_slurp_codeview_record

+#elif defined COFF_WITH_pep
+
+#define GET_OPTHDR_IMAGE_BASE H_GET_64
+#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64
+#define GET_PDATA_ENTRY bfd_get_64
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common       _bfd_pep_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data          _bfd_pep_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info                                _bfd_pep_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out                  _bfd_pep_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common          _bfd_pep_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript                 _bfd_pepi_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out                 _bfd_pepi_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in                       _bfd_pepi_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out                      _bfd_pepi_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in                           _bfd_pepi_swap_aux_in
+#define _bfd_XXi_swap_aux_out                          _bfd_pepi_swap_aux_out
+#define _bfd_XXi_swap_lineno_in                                _bfd_pepi_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out                       _bfd_pepi_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out                       _bfd_pepi_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in                           _bfd_pepi_swap_sym_in
+#define _bfd_XXi_swap_sym_out                          _bfd_pepi_swap_sym_out
+#define _bfd_XXi_swap_debugdir_in                      _bfd_pepi_swap_debugdir_in
+#define _bfd_XXi_swap_debugdir_out                     _bfd_pepi_swap_debugdir_out
+#define _bfd_XXi_write_codeview_record                 _bfd_pepi_write_codeview_record
+#define _bfd_XXi_slurp_codeview_record                 _bfd_pepi_slurp_codeview_record
+
 #else /* !COFF_WITH_pep */

 #define GET_OPTHDR_IMAGE_BASE H_GET_32
diff --git a/bfd/pe-aarch64.c b/bfd/pe-aarch64.c
new file mode 100644
index 00000000000..242d4605c2e
--- /dev/null
+++ b/bfd/pe-aarch64.c
@@ -0,0 +1,74 @@
+/* BFD back-end for AArch64 PE IMAGE COFF files.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM             aarch64_pe_vec
+#define TARGET_NAME            "pe-aarch64"
+#define TARGET_ARCHITECTURE    bfd_arch_aarch64
+#define TARGET_PAGESIZE                4096
+#define TARGET_BIG_ENDIAN      0
+#define TARGET_ARCHIVE         0
+#define TARGET_PRIORITY                0
+
+/* Rename the above into.. */
+#define COFF_WITH_peAArch64
+#define COFF_WITH_PE
+#define PCRELOFFSET       true
+
+/* Long section names not allowed in executable images, only object files.  */
+#define COFF_LONG_SECTION_NAMES 0
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#define PEI_HEADERS
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/aarch64.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+#include "libpei.h"
+#include "libiberty.h"
+
+/* Make sure we're setting a 64-bit format.  */
+#undef AOUTSZ
+#define AOUTSZ          PEPAOUTSZ
+#define PEAOUTHDR       PEPAOUTHDR
+
+#include "coff-aarch64.c"
diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c
index 99326d16126..a0f926e31ce 100644
--- a/bfd/pei-aarch64.c
+++ b/bfd/pei-aarch64.c
@@ -22,7 +22,7 @@
 #include "bfd.h"

 #define TARGET_SYM             aarch64_pei_vec
-#define TARGET_NAME            "pei-aarch64-little"
+#define TARGET_NAME            "pei-aarch64"
 #define TARGET_ARCHITECTURE    bfd_arch_aarch64
 #define TARGET_PAGESIZE                4096
 #define TARGET_BIG_ENDIAN      0
diff --git a/bfd/peicode.h b/bfd/peicode.h
index 1e8ed803edc..3306ef92a8a 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -191,6 +191,8 @@ coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)

 #ifdef COFF_IMAGE_WITH_PE
 # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
+#elif defined COFF_WITH_peAArch64
+# define coff_swap_filehdr_out _bfd_XX_only_swap_filehdr_out
 #elif defined COFF_WITH_pex64
 # define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
 #elif defined COFF_WITH_pep
diff --git a/bfd/targets.c b/bfd/targets.c
index 672dc2bb1a4..bf3c2d383a4 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -680,6 +680,7 @@ extern const bfd_target aarch64_elf64_le_vec;
 extern const bfd_target aarch64_elf64_le_cloudabi_vec;
 extern const bfd_target aarch64_mach_o_vec;
 extern const bfd_target aarch64_pei_vec;
+extern const bfd_target aarch64_pe_vec;
 extern const bfd_target alpha_ecoff_le_vec;
 extern const bfd_target alpha_elf64_vec;
 extern const bfd_target alpha_elf64_fbsd_vec;
@@ -995,6 +996,7 @@ static const bfd_target * const _bfd_target_vector[] =
        &aarch64_elf64_le_cloudabi_vec,
        &aarch64_mach_o_vec,
        &aarch64_pei_vec,
+       &aarch64_pe_vec,
 #endif

 #ifdef BFD64
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 77888663077..3beb269f7ba 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2021-12-22 Jedidiah Thompson <wej22007 [at] outlook [com]>
+
+       * config/tc-aarch64.c: add AArch64 COFF / PE support to GAS
+       * config/tc-aarch64.h: add AArch64 COFF / PE support
+       * configure.tgt: add AArch64 COFF / PE
+
 2021-12-16  Nick Clifton  <nickc@redhat.com>

        PR 28686
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
index 73c001e3edc..dc94884f831 100644
--- a/gas/config/obj-coff.h
+++ b/gas/config/obj-coff.h
@@ -40,6 +40,13 @@
 #endif
 #endif

+#ifdef TC_AARCH64
+#include "coff/aarch64.h"
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "pe-aarch64"
+#endif
+#endif
+
 #ifdef TC_PPC
 #include "coff/rs6000.h"
 #endif
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index cc7725483aa..7b5c77d60d9 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -1475,7 +1475,7 @@ s_unreq (int a ATTRIBUTE_UNUSED)

 /* Directives: Instruction set selection.  */

-#ifdef OBJ_ELF
+#if defined (OBJ_ELF) || defined (OBJ_COFF)
 /* This code is to handle mapping symbols as defined in the ARM AArch64 ELF
    spec.  (See "Mapping symbols", section 4.5.4, ARM AAELF64 version 0.05).
    Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
@@ -2029,6 +2029,7 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }

+#ifdef OBJ_ELF
 static void
 s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
 {
@@ -2037,7 +2038,6 @@ s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
   fde->pauth_key = AARCH64_PAUTH_KEY_B;
 }

-#ifdef OBJ_ELF
 /* Emit BFD_RELOC_AARCH64_TLSDESC_ADD on the next ADD instruction.  */

 static void
@@ -2111,8 +2111,8 @@ const pseudo_typeS md_pseudo_table[] = {
   {"arch", s_aarch64_arch, 0},
   {"arch_extension", s_aarch64_arch_extension, 0},
   {"inst", s_aarch64_inst, 0},
-  {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
 #ifdef OBJ_ELF
+  {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
   {"tlsdescadd", s_tlsdescadd, 0},
   {"tlsdesccall", s_tlsdesccall, 0},
   {"tlsdescldr", s_tlsdescldr, 0},
@@ -8302,7 +8302,7 @@ aarch64_handle_align (fragS * fragP)
   fix = bytes & (noop_size - 1);
   if (fix)
     {
-#ifdef OBJ_ELF
+#if defined(OBJ_ELF) || defined(OBJ_COFF)
       insert_data_mapping_symbol (MAP_INSN, fragP->fr_fix, fragP, fix);
 #endif
       memset (p, 0, fix);
@@ -9044,9 +9044,13 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
       break;

     case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC:
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       fixP->fx_r_type = (ilp32_p
                         ? BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
                         : BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
+#else
+      fixP->fx_r_type = BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
+#endif
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
       /* Should always be exported to object file, see
         aarch64_force_relocation().  */
@@ -9055,9 +9059,13 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
       break;

     case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC:
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       fixP->fx_r_type = (ilp32_p
                         ? BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
                         : BFD_RELOC_AARCH64_TLSDESC_LD64_LO12);
+#else
+      fixP->fx_r_type = BFD_RELOC_AARCH64_TLSDESC_LD64_LO12;
+#endif
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
       /* Should always be exported to object file, see
         aarch64_force_relocation().  */
@@ -9127,9 +9135,13 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
     case BFD_RELOC_AARCH64_LD_GOT_LO12_NC:
       /* Should always be exported to object file, see
         aarch64_force_relocation().  */
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       fixP->fx_r_type = (ilp32_p
                         ? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
                         : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
+#else
+      fixP->fx_r_type = BFD_RELOC_AARCH64_LD64_GOT_LO12_NC;
+#endif
       gas_assert (!fixP->fx_done);
       gas_assert (seg->use_rela_p);
       break;
@@ -9627,7 +9639,11 @@ md_begin (void)
   cpu_variant = *mcpu_cpu_opt;

   /* Record the CPU type.  */
+#if defined(OBJ_ELF) || defined(OBJ_MAYBE_ELF)
   mach = ilp32_p ? bfd_mach_aarch64_ilp32 : bfd_mach_aarch64;
+#else
+  mach = bfd_mach_aarch64;
+#endif

   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
 }
@@ -10187,6 +10203,7 @@ aarch64_parse_arch (const char *str)
   return 0;
 }

+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 /* ABIs.  */
 struct aarch64_option_abi_value_table
 {
@@ -10220,6 +10237,7 @@ aarch64_parse_abi (const char *str)
   as_bad (_("unknown abi `%s'\n"), str);
   return 0;
 }
+#endif

 static struct aarch64_long_option_table aarch64_long_opts[] = {
 #ifdef OBJ_ELF
diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h
index 78bff0a1b56..a508f27d513 100644
--- a/gas/config/tc-aarch64.h
+++ b/gas/config/tc-aarch64.h
@@ -169,7 +169,7 @@ void aarch64_elf_copy_symbol_attributes (symbolS *, symbolS *);
 struct aarch64_frag_type
 {
   int recorded;
-#ifdef OBJ_ELF
+#if defined (OBJ_ELF) || defined (OBJ_COFF)
   /* If there is a mapping symbol at offset 0 in this frag,
      it will be saved in FIRST_MAP.  If there are any mapping
      symbols in this frag, the last one will be saved in
@@ -242,6 +242,34 @@ struct aarch64_segment_info_type
 extern void aarch64_after_parse_args (void);
 #define md_after_parse_args() aarch64_after_parse_args ()

+#elif defined(TE_PEP)
+# define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
+# define TC_SEGMENT_INFO_TYPE          struct aarch64_segment_info_type
+
+/* This is not really an alignment operation, but it's something we
+   need to do at the same time: whenever we are figuring out the
+   alignment for data, we should check whether a $d symbol is
+   necessary.  */
+# define md_cons_align(nbytes)         mapping_state (MAP_DATA)
+
+enum mstate
+{
+  MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections.  */
+  MAP_DATA,
+  MAP_INSN,
+};
+
+void mapping_state (enum mstate);
+
+struct aarch64_segment_info_type
+{
+  const char *last_file;
+  unsigned last_line;
+  enum mstate mapstate;
+  unsigned int marked_pr_dependency;
+  aarch64_instr_sequence insn_sequence;
+};
+
 #else /* Not OBJ_ELF.  */
 #define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
 #endif
@@ -274,13 +302,13 @@ extern void aarch64_handle_align (struct frag *);
 extern int tc_aarch64_regname_to_dw2regnum (char *regname);
 extern void tc_aarch64_frame_initial_instructions (void);

-#ifdef TE_PE
+#if 0

 #define O_secrel O_md1

 #define TC_DWARF2_EMIT_OFFSET  tc_pe_dwarf2_emit_offset
 void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);

-#endif /* TE_PE */
+#endif

 #endif /* TC_AARCH64 */
diff --git a/gas/configure.tgt b/gas/configure.tgt
index d3db3aa9e88..bb6d543e893 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -134,6 +134,7 @@ case ${generic_target} in
       aarch64*-linux-gnu_ilp32)                arch=aarch64:32 ;;
     esac ;;
   aarch64*-*-netbsd*)                  fmt=elf em=nbsd;;
+  aarch64*-*-pe*)      fmt=coff em=pep ;;

   alpha-*-*vms*)                       fmt=evax ;;
   alpha-*-osf*)                                fmt=ecoff ;;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index a0ab861bb4a..50a0947c425 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,14 @@
+2021-12-22 Jedidiah Thompson <wej22007 [at] outlook [com]>
+
+       emulparams/aarch64pe.sh: create
+       emultempl/pep.em: remove x86_64 assumptions and add AArch64 support
+       configure.tgt: add aarch64-pe target
+       Makefile.am: add aarch64pe emulation
+       Makefile.in: regenerate
+       pe-dll.c: add aarch64 support, genralize for non x86_64
+       pep-dll-aarch64.c: create
+       pep-dll-x86_64.c: create
+
 2021-12-16  Nick Clifton  <nickc@redhat.com>

        PR 28686
diff --git a/ld/Makefile.am b/ld/Makefile.am
index d27d9956af8..f6db936e71f 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -391,6 +391,7 @@ ALL_64_EMULATION_SOURCES = \
        eaarch64linux32.c \
        eaarch64linux32b.c \
        eaarch64linuxb.c \
+       eaarch64pe.c    \
        eelf32_x86_64.c \
        eelf32b4300.c \
        eelf32bmip.c \
diff --git a/ld/Makefile.in b/ld/Makefile.in
index d159f14823f..f6f24d76077 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -522,6 +522,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -880,6 +881,7 @@ ALL_64_EMULATION_SOURCES = \
        eaarch64linux32.c \
        eaarch64linux32b.c \
        eaarch64linuxb.c \
+       eaarch64pe.c    \
        eelf32_x86_64.c \
        eelf32b4300.c \
        eelf32bmip.c \
@@ -1255,6 +1257,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32b.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linuxb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64pe.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5ppc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5rs6.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixppc.Po@am__quote@
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 925ce076179..717b40affc2 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -50,6 +50,10 @@ aarch64-*-elf | aarch64-*-rtems* | aarch64-*-genode*)
                        targ_emul=aarch64elf
                        targ_extra_emuls="aarch64elf32 aarch64elf32b aarch64elfb armelf armelfb"
                        ;;
+aarch64-*-pe)
+                       targ_emul=aarch64pe
+                       targ_extra_ofiles="deffilep.o pep-dll-aarch64.o"
+                       ;;
 aarch64-*-cloudabi*)   targ_emul=aarch64cloudabi
                        targ_extra_emuls=aarch64cloudabib
                        ;;
@@ -1005,7 +1009,7 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
                        ;;
 x86_64-*-pe | x86_64-*-pep) targ_emul=i386pep ;
                        targ_extra_emuls=i386pe ;
-                       targ_extra_ofiles="deffilep.o pep-dll.o pe-dll.o"
+                       targ_extra_ofiles="deffilep.o pep-dll-x86_64.o pe-dll.o"
                        ;;
 x86_64-*-cygwin)       targ_emul=i386pep ;
                        targ_extra_emuls=i386pe
diff --git a/ld/emulparams/aarch64pe.sh b/ld/emulparams/aarch64pe.sh
new file mode 100644
index 00000000000..3b1c161692e
--- /dev/null
+++ b/ld/emulparams/aarch64pe.sh
@@ -0,0 +1,9 @@
+ARCH="aarch64"
+SCRIPT_NAME=pep
+OUTPUT_FORMAT="pei-aarch64"
+RELOCATEABLE_OUTPUT_FORMAT="pe-aarch64"
+TEMPLATE_NAME=pep
+SUBSYSTEM=PE_DEF_SUBSYSTEM
+INITIAL_SYMBOL_CHAR=\"_\"
+TARGET_PAGE_SIZE=0x1000
+GENERATE_AUTO_IMPORT_SCRIPT=1
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 430351b6481..af7e1ff07d1 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -48,7 +48,11 @@ fragment <<EOF

 #define COFF_IMAGE_WITH_PE
 #define COFF_WITH_PE
+#ifdef TARGET_IS_aarch64pe
+#define COFF_WITH_peAArch64
+#elif defined TARGET_IS_i386pep
 #define COFF_WITH_pex64
+#endif

 #include "sysdep.h"
 #include "bfd.h"
@@ -72,7 +76,11 @@ fragment <<EOF

 /* FIXME: See bfd/peXXigen.c for why we include an architecture specific
    header in generic PE code.  */
+#ifdef COFF_WITH_pex64
 #include "coff/x86_64.h"
+#elif defined COFF_WITH_peAArch64
+#include "coff/aarch64.h"
+#endif
 #include "coff/pe.h"

 /* FIXME: These are BFD internal header files, and we should not be
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index e7b82ba6ffa..43c052d723b 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -42,7 +42,7 @@
 #include "../bfd/libcoff.h"
 #include "deffile.h"

-#ifdef pe_use_x86_64
+#ifdef pe_use_plus

 #define PE_IDATA4_SIZE 8
 #define PE_IDATA5_SIZE 8
@@ -209,7 +209,7 @@ static const autofilter_entry_type autofilter_symbollist_i386[] =
   { STRING_COMMA_LEN ("_NULL_IMPORT_DESCRIPTOR") },
   /* Entry point symbols, and entry hooks.  */
   { STRING_COMMA_LEN ("cygwin_crt0") },
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
   { STRING_COMMA_LEN ("DllMain") },
   { STRING_COMMA_LEN ("DllEntryPoint") },
   { STRING_COMMA_LEN ("DllMainCRTStartup") },
@@ -246,13 +246,14 @@ static const autofilter_entry_type autofilter_symbollist_i386[] =
 #define PE_ARCH_mips    3
 #define PE_ARCH_arm     4
 #define PE_ARCH_arm_wince 5
+#define PE_ARCH_aarch64   6

 /* Don't make it constant as underscore mode gets possibly overriden
    by target or -(no-)leading-underscore option.  */
 static pe_details_type pe_detail_list[] =
 {
   {
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
     "pei-x86-64",
     "pe-x86-64",
     3 /* R_IMAGEBASE */,
@@ -263,14 +264,14 @@ static pe_details_type pe_detail_list[] =
 #endif
     PE_ARCH_i386,
     bfd_arch_i386,
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
     false,
 #else
     true,
 #endif
     autofilter_symbollist_i386
   },
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
   {
     "pei-x86-64",
     "pe-bigobj-x86-64",
@@ -327,6 +328,15 @@ static pe_details_type pe_detail_list[] =
     false,
     autofilter_symbollist_generic
   },
+  {
+    "pei-aarch64",
+    "pe-aarch64",
+    2,  /* ARM64_RVA32 */
+    PE_ARCH_aarch64,
+    bfd_arch_aarch64,
+    false,
+    autofilter_symbollist_generic
+  },
   { NULL, NULL, 0, 0, 0, false, NULL }
 };

@@ -1641,7 +1651,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
                  switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
                                         relocs[i]->howto->rightshift)
                    {
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
                    case BITS_AND_SHIFT (64, 0):
                      reloc_data[total_relocs].type = 10;
                      total_relocs++;
@@ -2278,6 +2288,15 @@ static const unsigned char jmp_arm_bytes[] =
   0,    0,    0,    0
 };

+/* _function:
+  b <__imp_function>
+  nop */
+static const unsigned char jmp_aarch64_bytes[] =
+{
+  0x00, 0x00, 0x00, 0x14,
+  0x1f, 0x20, 0x03, 0xD5
+};
+

 static bfd *
 make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
@@ -2317,6 +2336,10 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
          jmp_bytes = jmp_arm_bytes;
          jmp_byte_count = sizeof (jmp_arm_bytes);
          break;
+  case PE_ARCH_aarch64:
+    jmp_bytes = jmp_aarch64_bytes;
+    jmp_byte_count = sizeof (jmp_aarch64_bytes);
+    break;
        default:
          abort ();
        }
@@ -2382,7 +2405,7 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
       switch (pe_details->pe_arch)
        {
        case PE_ARCH_i386:
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
          quick_reloc (abfd, 2, BFD_RELOC_32_PCREL, 2);
 #else
          /* Mark this object as SAFESEH compatible.  */
@@ -2403,6 +2426,9 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
        case PE_ARCH_arm_wince:
          quick_reloc (abfd, 8, BFD_RELOC_32, 2);
          break;
+  case PE_ARCH_aarch64:
+    quick_reloc (abfd, 0, BFD_RELOC_32_PCREL, 2);
+    break;
        default:
          abort ();
        }
@@ -3374,7 +3400,7 @@ pe_implied_import_dll (const char *filename)
   /* Get pe_header, optional header and numbers of directory entries.  */
   pe_header_offset = pe_get32 (dll, 0x3c);
   opthdr_ofs = pe_header_offset + 4 + 20;
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
   num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /*  & NumberOfRvaAndSizes.  */
 #else
   num_entries = pe_get32 (dll, opthdr_ofs + 92);
@@ -3384,7 +3410,7 @@ pe_implied_import_dll (const char *filename)
   if (num_entries < 1)
     return false;

-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
   export_rva  = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
   export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
 #else
diff --git a/ld/pep-dll-aarch64.c b/ld/pep-dll-aarch64.c
new file mode 100644
index 00000000000..b57fd03ebfa
--- /dev/null
+++ b/ld/pep-dll-aarch64.c
@@ -0,0 +1,24 @@
+/* Tiny wrapper over pep-dll.c
+   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   Written by Kai Tietz, OneVision Software GmbH&CoKg.
+
+   This file is part of the GNU Binutils.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define COFF_WITH_peAArch64
+
+#include "pep-dll.c"
diff --git a/ld/pep-dll-x86_64.c b/ld/pep-dll-x86_64.c
new file mode 100644
index 00000000000..858e1a876ff
--- /dev/null
+++ b/ld/pep-dll-x86_64.c
@@ -0,0 +1,24 @@
+/* Tiny wrapper over pep-dll.c
+   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   Written by Kai Tietz, OneVision Software GmbH&CoKg.
+
+   This file is part of the GNU Binutils.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define COFF_WITH_pex64
+
+#include "pep-dll.c"
diff --git a/ld/pep-dll.c b/ld/pep-dll.c
index 8564fb995b9..6760bcdefcb 100644
--- a/ld/pep-dll.c
+++ b/ld/pep-dll.c
@@ -1,4 +1,4 @@
-/* Routines to help build PEPI-format DLLs (Win64 etc)
+/* Routines to help build PEPI-format DLLs on x86_64 (Win64 etc)
    Copyright (C) 2006-2021 Free Software Foundation, Inc.
    Written by Kai Tietz, OneVision Software GmbH&CoKg.

@@ -21,7 +21,6 @@

 #define COFF_IMAGE_WITH_PE
 #define COFF_WITH_PE
-#define COFF_WITH_pex64

 /* Local defined globals.  */
 #define pe_def_file                pep_def_file
@@ -58,7 +57,7 @@
 #define pe_output_file_set_long_section_names \
                                    pep_output_file_set_long_section_names

-/* Uses x86_64 PE+.  */
-#define pe_use_x86_64
+/* Use PE+.  */
+#define pe_use_plus

 #include "pe-dll.c"
--
2.32.0


^ permalink raw reply	[flat|nested] 10+ messages in thread
* [PATCH] Add aarch64-pe support to LD and GAS; refine support in BFD
@ 2021-12-22 23:19 Jedidiah Thompson
  0 siblings, 0 replies; 10+ messages in thread
From: Jedidiah Thompson @ 2021-12-22 23:19 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 114 bytes --]

This adds support for aarch64-pe in LD and GAS, plus adds non image vectors in BFD (and fixes a couple bugs)



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-aarch64-pe-support-to-LD-and-GAS-refine-support-.patch --]
[-- Type: text/x-patch; name="0001-Add-aarch64-pe-support-to-LD-and-GAS-refine-support-.patch", Size: 39758 bytes --]

From 60d508a22af8ebd94b054a62c93efad352c58087 Mon Sep 17 00:00:00 2001
From: Jedidiah Thompson <wej22007@outlook.com>
Date: Wed, 22 Dec 2021 18:14:27 -0500
Subject: [PATCH] Add aarch64-pe support to LD and GAS; refine support in BFD

---
 bfd/ChangeLog              | 14 ++++++++
 bfd/Makefile.am            |  1 +
 bfd/Makefile.in            |  3 ++
 bfd/bfd.c                  |  2 +-
 bfd/coff-aarch64.c         |  2 +-
 bfd/config.bfd             |  8 +++++
 bfd/configure              | 31 +++++++++++-----
 bfd/configure.ac           |  1 +
 bfd/doc/Makefile.in        |  1 +
 bfd/libpei.h               | 70 ++++++++++++++++++------------------
 bfd/pe-aarch64.c           | 74 ++++++++++++++++++++++++++++++++++++++
 bfd/pei-aarch64.c          |  2 +-
 bfd/peicode.h              |  2 ++
 bfd/targets.c              |  2 ++
 gas/ChangeLog              |  6 ++++
 gas/config/obj-coff.h      |  7 ++++
 gas/config/tc-aarch64.c    | 26 +++++++++++---
 gas/config/tc-aarch64.h    | 34 ++++++++++++++++--
 gas/configure.tgt          |  1 +
 ld/ChangeLog               | 11 ++++++
 ld/Makefile.am             |  1 +
 ld/Makefile.in             |  3 ++
 ld/configure.tgt           |  6 +++-
 ld/emulparams/aarch64pe.sh |  9 +++++
 ld/emultempl/pep.em        |  8 +++++
 ld/pe-dll.c                | 44 ++++++++++++++++++-----
 ld/pep-dll-aarch64.c       | 24 +++++++++++++
 ld/pep-dll-x86_64.c        | 24 +++++++++++++
 ld/pep-dll.c               |  7 ++--
 29 files changed, 357 insertions(+), 67 deletions(-)
 create mode 100644 bfd/pe-aarch64.c
 create mode 100644 ld/emulparams/aarch64pe.sh
 create mode 100644 ld/pep-dll-aarch64.c
 create mode 100644 ld/pep-dll-x86_64.c

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 24311710088..fd81fb5bc0d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,17 @@
+2021-12-22 Jedidiah Thompson <wej22007 [at] outlook [com]>
+
+	doc/Makefile.in: regenerate
+	bfd.c: change pe-aarch64-little to pe-aarch64
+	coff-aarch64.c: change pe-aarch64-little to pe-aarch64
+	config.bfd: add aarch64-pe target
+	configure: regenerate
+	configure.ac: add aarch64_pe vector
+	Makefile.am: add pe-aarch64.c
+	Makefile.in: regenerate
+	pe-aarch64.c: create
+	peicode.h: add COFF_WITH_peAArch64 case coff_swap_filehdr_out
+	targets.c: add aarch64_pe vector
+
 2021-12-15  Nikita Popov  <npv1310@gmail.com>
 
 	PR 28687
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 4960cb500b1..44cfabc185e 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -616,6 +616,7 @@ BFD64_BACKENDS_CFILES = \
 	mmo.c \
 	pe-x86_64.c \
 	pei-aarch64.c \
+	pe-aarch64.c \
 	pei-ia64.c \
 	pei-x86_64.c \
 	vms-alpha.c
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index a838262bc78..8e398d2cbc6 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -439,6 +439,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -1043,6 +1044,7 @@ BFD64_BACKENDS_CFILES = \
 	mmo.c \
 	pe-x86_64.c \
 	pei-aarch64.c \
+	pe-aarch64.c \
 	pei-ia64.c \
 	pei-x86_64.c \
 	vms-alpha.c
@@ -1574,6 +1576,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osf-core.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pc532-mach.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdp11.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-aarch64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-aarch64igen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm-wince.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm.Plo@am__quote@
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 2eff8150023..e98d0195d32 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1738,7 +1738,7 @@ bfd_get_sign_extend_vma (bfd *abfd)
       || strcmp (name, "pei-i386") == 0
       || strcmp (name, "pe-x86-64") == 0
       || strcmp (name, "pei-x86-64") == 0
-      || strcmp (name, "pei-aarch64-little") == 0
+      || strcmp (name, "pei-aarch64") == 0
       || strcmp (name, "pe-arm-wince-little") == 0
       || strcmp (name, "pei-arm-wince-little") == 0
       || strcmp (name, "aixcoff-rs6000") == 0
diff --git a/bfd/coff-aarch64.c b/bfd/coff-aarch64.c
index a9bc417fae8..a31b72b807d 100644
--- a/bfd/coff-aarch64.c
+++ b/bfd/coff-aarch64.c
@@ -95,7 +95,7 @@ const bfd_target
 #ifdef TARGET_NAME
   TARGET_NAME,
 #else
- "pei-aarch64-little",			/* Name.  */
+ "pei-aarch64",			/* Name.  */
 #endif
   bfd_target_coff_flavour,
   BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */
diff --git a/bfd/config.bfd b/bfd/config.bfd
index c062ef8b44c..d8be9e16ae6 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -257,6 +257,14 @@ case "${targ}" in
     targ_selvecs="aarch64_elf64_le_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_be_vec arm_elf32_le_vec"
     want64=true
     ;;
+  aarch64-*-pe)
+    # Not currently complete (and probably not stable), warn user
+    echo "*** WARNING BFD aarch64-pe support not complete nor stable"
+    echo "*** Do not rely on this for production purposes"
+    targ_defvec=aarch64_pei_vec
+    targ_selvecs="aarch64_pe_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
+    want64=true
+    ;;
   aarch64-*-freebsd*)
     targ_defvec=aarch64_elf64_le_vec
     targ_selvecs="aarch64_elf64_be_vec arm_elf32_le_vec arm_elf32_be_vec"
diff --git a/bfd/configure b/bfd/configure
index d4aa2178b29..4550e32a2f5 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -794,6 +794,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -891,6 +892,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1143,6 +1145,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1280,7 +1291,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1433,6 +1444,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -11084,7 +11096,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11087 "configure"
+#line 11099 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11190,7 +11202,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11193 "configure"
+#line 11205 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11620,7 +11632,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -11666,7 +11678,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -11690,7 +11702,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -11735,7 +11747,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -11759,7 +11771,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -13297,6 +13309,7 @@ do
     aarch64_elf64_le_cloudabi_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     aarch64_mach_o_vec)		 tb="$tb mach-o-aarch64.lo"; target_size=64 ;;
     aarch64_pei_vec)		 tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
+    aarch64_pe_vec)     tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
     alpha_ecoff_le_vec)		 tb="$tb coff-alpha.lo ecoff.lo $ecoff"; target_size=64 ;;
     alpha_elf64_vec)		 tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
     alpha_elf64_fbsd_vec)	 tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
@@ -14993,6 +15006,8 @@ main ()
     if (*(data + i) != *(data3 + i))
       return 14;
   close (fd);
+  free (data);
+  free (data3);
   return 0;
 }
 _ACEOF
diff --git a/bfd/configure.ac b/bfd/configure.ac
index a578c3a019e..7eef17067b2 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -438,6 +438,7 @@ do
     aarch64_elf64_le_cloudabi_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     aarch64_mach_o_vec)		 tb="$tb mach-o-aarch64.lo"; target_size=64 ;;
     aarch64_pei_vec)		 tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
+    aarch64_pe_vec)     tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
     alpha_ecoff_le_vec)		 tb="$tb coff-alpha.lo ecoff.lo $ecoff"; target_size=64 ;;
     alpha_elf64_vec)		 tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
     alpha_elf64_fbsd_vec)	 tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
index c070dd8c458..27e44971e85 100644
--- a/bfd/doc/Makefile.in
+++ b/bfd/doc/Makefile.in
@@ -376,6 +376,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/bfd/libpei.h b/bfd/libpei.h
index 26589e8e520..272ae0485a3 100644
--- a/bfd/libpei.h
+++ b/bfd/libpei.h
@@ -240,41 +240,6 @@
 #define _bfd_XXi_write_codeview_record			_bfd_pex64i_write_codeview_record
 #define _bfd_XXi_slurp_codeview_record			_bfd_pex64i_slurp_codeview_record
 
-#elif defined COFF_WITH_pep
-
-#define GET_OPTHDR_IMAGE_BASE H_GET_64
-#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
-#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64
-#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64
-#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64
-#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64
-#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64
-#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64
-#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64
-#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64
-#define GET_PDATA_ENTRY bfd_get_64
-
-#define _bfd_XX_bfd_copy_private_bfd_data_common	_bfd_pep_bfd_copy_private_bfd_data_common
-#define _bfd_XX_bfd_copy_private_section_data		_bfd_pep_bfd_copy_private_section_data
-#define _bfd_XX_get_symbol_info				_bfd_pep_get_symbol_info
-#define _bfd_XX_only_swap_filehdr_out			_bfd_pep_only_swap_filehdr_out
-#define _bfd_XX_print_private_bfd_data_common		_bfd_pep_print_private_bfd_data_common
-#define _bfd_XXi_final_link_postscript			_bfd_pepi_final_link_postscript
-#define _bfd_XXi_only_swap_filehdr_out			_bfd_pepi_only_swap_filehdr_out
-#define _bfd_XXi_swap_aouthdr_in			_bfd_pepi_swap_aouthdr_in
-#define _bfd_XXi_swap_aouthdr_out			_bfd_pepi_swap_aouthdr_out
-#define _bfd_XXi_swap_aux_in				_bfd_pepi_swap_aux_in
-#define _bfd_XXi_swap_aux_out				_bfd_pepi_swap_aux_out
-#define _bfd_XXi_swap_lineno_in				_bfd_pepi_swap_lineno_in
-#define _bfd_XXi_swap_lineno_out			_bfd_pepi_swap_lineno_out
-#define _bfd_XXi_swap_scnhdr_out			_bfd_pepi_swap_scnhdr_out
-#define _bfd_XXi_swap_sym_in				_bfd_pepi_swap_sym_in
-#define _bfd_XXi_swap_sym_out				_bfd_pepi_swap_sym_out
-#define _bfd_XXi_swap_debugdir_in			_bfd_pepi_swap_debugdir_in
-#define _bfd_XXi_swap_debugdir_out			_bfd_pepi_swap_debugdir_out
-#define _bfd_XXi_write_codeview_record			_bfd_pepi_write_codeview_record
-#define _bfd_XXi_slurp_codeview_record			_bfd_pepi_slurp_codeview_record
-
 #elif defined COFF_WITH_peAArch64
 
 #define GET_OPTHDR_IMAGE_BASE		 H_GET_64
@@ -310,6 +275,41 @@
 #define _bfd_XXi_write_codeview_record			_bfd_peAArch64i_write_codeview_record
 #define _bfd_XXi_slurp_codeview_record			_bfd_peAArch64i_slurp_codeview_record
 
+#elif defined COFF_WITH_pep
+
+#define GET_OPTHDR_IMAGE_BASE H_GET_64
+#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64
+#define GET_PDATA_ENTRY bfd_get_64
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common	_bfd_pep_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data		_bfd_pep_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info				_bfd_pep_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out			_bfd_pep_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common		_bfd_pep_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript			_bfd_pepi_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out			_bfd_pepi_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in			_bfd_pepi_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out			_bfd_pepi_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in				_bfd_pepi_swap_aux_in
+#define _bfd_XXi_swap_aux_out				_bfd_pepi_swap_aux_out
+#define _bfd_XXi_swap_lineno_in				_bfd_pepi_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out			_bfd_pepi_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out			_bfd_pepi_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in				_bfd_pepi_swap_sym_in
+#define _bfd_XXi_swap_sym_out				_bfd_pepi_swap_sym_out
+#define _bfd_XXi_swap_debugdir_in			_bfd_pepi_swap_debugdir_in
+#define _bfd_XXi_swap_debugdir_out			_bfd_pepi_swap_debugdir_out
+#define _bfd_XXi_write_codeview_record			_bfd_pepi_write_codeview_record
+#define _bfd_XXi_slurp_codeview_record			_bfd_pepi_slurp_codeview_record
+
 #else /* !COFF_WITH_pep */
 
 #define GET_OPTHDR_IMAGE_BASE H_GET_32
diff --git a/bfd/pe-aarch64.c b/bfd/pe-aarch64.c
new file mode 100644
index 00000000000..242d4605c2e
--- /dev/null
+++ b/bfd/pe-aarch64.c
@@ -0,0 +1,74 @@
+/* BFD back-end for AArch64 PE IMAGE COFF files.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM		aarch64_pe_vec
+#define TARGET_NAME		"pe-aarch64"
+#define TARGET_ARCHITECTURE	bfd_arch_aarch64
+#define TARGET_PAGESIZE		4096
+#define TARGET_BIG_ENDIAN	0
+#define TARGET_ARCHIVE		0
+#define TARGET_PRIORITY		0
+
+/* Rename the above into.. */
+#define COFF_WITH_peAArch64
+#define COFF_WITH_PE
+#define PCRELOFFSET	   true
+
+/* Long section names not allowed in executable images, only object files.  */
+#define COFF_LONG_SECTION_NAMES 0
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#define PEI_HEADERS
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/aarch64.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+#include "libpei.h"
+#include "libiberty.h"
+
+/* Make sure we're setting a 64-bit format.  */
+#undef AOUTSZ
+#define AOUTSZ          PEPAOUTSZ
+#define PEAOUTHDR       PEPAOUTHDR
+
+#include "coff-aarch64.c"
diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c
index 99326d16126..a0f926e31ce 100644
--- a/bfd/pei-aarch64.c
+++ b/bfd/pei-aarch64.c
@@ -22,7 +22,7 @@
 #include "bfd.h"
 
 #define TARGET_SYM		aarch64_pei_vec
-#define TARGET_NAME		"pei-aarch64-little"
+#define TARGET_NAME		"pei-aarch64"
 #define TARGET_ARCHITECTURE	bfd_arch_aarch64
 #define TARGET_PAGESIZE		4096
 #define TARGET_BIG_ENDIAN	0
diff --git a/bfd/peicode.h b/bfd/peicode.h
index 1e8ed803edc..3306ef92a8a 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -191,6 +191,8 @@ coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
 
 #ifdef COFF_IMAGE_WITH_PE
 # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
+#elif defined COFF_WITH_peAArch64
+# define coff_swap_filehdr_out _bfd_XX_only_swap_filehdr_out
 #elif defined COFF_WITH_pex64
 # define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
 #elif defined COFF_WITH_pep
diff --git a/bfd/targets.c b/bfd/targets.c
index 672dc2bb1a4..bf3c2d383a4 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -680,6 +680,7 @@ extern const bfd_target aarch64_elf64_le_vec;
 extern const bfd_target aarch64_elf64_le_cloudabi_vec;
 extern const bfd_target aarch64_mach_o_vec;
 extern const bfd_target aarch64_pei_vec;
+extern const bfd_target aarch64_pe_vec;
 extern const bfd_target alpha_ecoff_le_vec;
 extern const bfd_target alpha_elf64_vec;
 extern const bfd_target alpha_elf64_fbsd_vec;
@@ -995,6 +996,7 @@ static const bfd_target * const _bfd_target_vector[] =
 	&aarch64_elf64_le_cloudabi_vec,
 	&aarch64_mach_o_vec,
 	&aarch64_pei_vec,
+	&aarch64_pe_vec,
 #endif
 
 #ifdef BFD64
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 77888663077..3beb269f7ba 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2021-12-22 Jedidiah Thompson <wej22007 [at] outlook [com]>
+
+	* config/tc-aarch64.c: add AArch64 COFF / PE support to GAS
+	* config/tc-aarch64.h: add AArch64 COFF / PE support
+	* configure.tgt: add AArch64 COFF / PE
+
 2021-12-16  Nick Clifton  <nickc@redhat.com>
 
 	PR 28686
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
index 73c001e3edc..dc94884f831 100644
--- a/gas/config/obj-coff.h
+++ b/gas/config/obj-coff.h
@@ -40,6 +40,13 @@
 #endif
 #endif
 
+#ifdef TC_AARCH64
+#include "coff/aarch64.h"
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "pe-aarch64"
+#endif
+#endif
+
 #ifdef TC_PPC
 #include "coff/rs6000.h"
 #endif
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index cc7725483aa..7b5c77d60d9 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -1475,7 +1475,7 @@ s_unreq (int a ATTRIBUTE_UNUSED)
 
 /* Directives: Instruction set selection.  */
 
-#ifdef OBJ_ELF
+#if defined (OBJ_ELF) || defined (OBJ_COFF)
 /* This code is to handle mapping symbols as defined in the ARM AArch64 ELF
    spec.  (See "Mapping symbols", section 4.5.4, ARM AAELF64 version 0.05).
    Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
@@ -2029,6 +2029,7 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
+#ifdef OBJ_ELF
 static void
 s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
 {
@@ -2037,7 +2038,6 @@ s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
   fde->pauth_key = AARCH64_PAUTH_KEY_B;
 }
 
-#ifdef OBJ_ELF
 /* Emit BFD_RELOC_AARCH64_TLSDESC_ADD on the next ADD instruction.  */
 
 static void
@@ -2111,8 +2111,8 @@ const pseudo_typeS md_pseudo_table[] = {
   {"arch", s_aarch64_arch, 0},
   {"arch_extension", s_aarch64_arch_extension, 0},
   {"inst", s_aarch64_inst, 0},
-  {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
 #ifdef OBJ_ELF
+  {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
   {"tlsdescadd", s_tlsdescadd, 0},
   {"tlsdesccall", s_tlsdesccall, 0},
   {"tlsdescldr", s_tlsdescldr, 0},
@@ -8302,7 +8302,7 @@ aarch64_handle_align (fragS * fragP)
   fix = bytes & (noop_size - 1);
   if (fix)
     {
-#ifdef OBJ_ELF
+#if defined(OBJ_ELF) || defined(OBJ_COFF)
       insert_data_mapping_symbol (MAP_INSN, fragP->fr_fix, fragP, fix);
 #endif
       memset (p, 0, fix);
@@ -9044,9 +9044,13 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
       break;
 
     case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC:
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       fixP->fx_r_type = (ilp32_p
 			 ? BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
 			 : BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
+#else
+      fixP->fx_r_type = BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
+#endif
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
       /* Should always be exported to object file, see
 	 aarch64_force_relocation().  */
@@ -9055,9 +9059,13 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
       break;
 
     case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC:
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       fixP->fx_r_type = (ilp32_p
 			 ? BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
 			 : BFD_RELOC_AARCH64_TLSDESC_LD64_LO12);
+#else
+      fixP->fx_r_type = BFD_RELOC_AARCH64_TLSDESC_LD64_LO12;
+#endif
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
       /* Should always be exported to object file, see
 	 aarch64_force_relocation().  */
@@ -9127,9 +9135,13 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
     case BFD_RELOC_AARCH64_LD_GOT_LO12_NC:
       /* Should always be exported to object file, see
 	 aarch64_force_relocation().  */
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
       fixP->fx_r_type = (ilp32_p
 			 ? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
 			 : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
+#else
+      fixP->fx_r_type = BFD_RELOC_AARCH64_LD64_GOT_LO12_NC;
+#endif
       gas_assert (!fixP->fx_done);
       gas_assert (seg->use_rela_p);
       break;
@@ -9627,7 +9639,11 @@ md_begin (void)
   cpu_variant = *mcpu_cpu_opt;
 
   /* Record the CPU type.  */
+#if defined(OBJ_ELF) || defined(OBJ_MAYBE_ELF)
   mach = ilp32_p ? bfd_mach_aarch64_ilp32 : bfd_mach_aarch64;
+#else
+  mach = bfd_mach_aarch64;
+#endif
 
   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
 }
@@ -10187,6 +10203,7 @@ aarch64_parse_arch (const char *str)
   return 0;
 }
 
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 /* ABIs.  */
 struct aarch64_option_abi_value_table
 {
@@ -10220,6 +10237,7 @@ aarch64_parse_abi (const char *str)
   as_bad (_("unknown abi `%s'\n"), str);
   return 0;
 }
+#endif
 
 static struct aarch64_long_option_table aarch64_long_opts[] = {
 #ifdef OBJ_ELF
diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h
index 78bff0a1b56..a508f27d513 100644
--- a/gas/config/tc-aarch64.h
+++ b/gas/config/tc-aarch64.h
@@ -169,7 +169,7 @@ void aarch64_elf_copy_symbol_attributes (symbolS *, symbolS *);
 struct aarch64_frag_type
 {
   int recorded;
-#ifdef OBJ_ELF
+#if defined (OBJ_ELF) || defined (OBJ_COFF)
   /* If there is a mapping symbol at offset 0 in this frag,
      it will be saved in FIRST_MAP.  If there are any mapping
      symbols in this frag, the last one will be saved in
@@ -242,6 +242,34 @@ struct aarch64_segment_info_type
 extern void aarch64_after_parse_args (void);
 #define md_after_parse_args() aarch64_after_parse_args ()
 
+#elif defined(TE_PEP)
+# define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
+# define TC_SEGMENT_INFO_TYPE		struct aarch64_segment_info_type
+
+/* This is not really an alignment operation, but it's something we
+   need to do at the same time: whenever we are figuring out the
+   alignment for data, we should check whether a $d symbol is
+   necessary.  */
+# define md_cons_align(nbytes)		mapping_state (MAP_DATA)
+
+enum mstate
+{
+  MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections.  */
+  MAP_DATA,
+  MAP_INSN,
+};
+
+void mapping_state (enum mstate);
+
+struct aarch64_segment_info_type
+{
+  const char *last_file;
+  unsigned last_line;
+  enum mstate mapstate;
+  unsigned int marked_pr_dependency;
+  aarch64_instr_sequence insn_sequence;
+};
+
 #else /* Not OBJ_ELF.  */
 #define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
 #endif
@@ -274,13 +302,13 @@ extern void aarch64_handle_align (struct frag *);
 extern int tc_aarch64_regname_to_dw2regnum (char *regname);
 extern void tc_aarch64_frame_initial_instructions (void);
 
-#ifdef TE_PE
+#if 0
 
 #define O_secrel O_md1
 
 #define TC_DWARF2_EMIT_OFFSET  tc_pe_dwarf2_emit_offset
 void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
 
-#endif /* TE_PE */
+#endif
 
 #endif /* TC_AARCH64 */
diff --git a/gas/configure.tgt b/gas/configure.tgt
index d3db3aa9e88..bb6d543e893 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -134,6 +134,7 @@ case ${generic_target} in
       aarch64*-linux-gnu_ilp32)		arch=aarch64:32 ;;
     esac ;;
   aarch64*-*-netbsd*)			fmt=elf em=nbsd;;
+  aarch64*-*-pe*)      fmt=coff em=pep ;;
 
   alpha-*-*vms*)			fmt=evax ;;
   alpha-*-osf*)				fmt=ecoff ;;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index a0ab861bb4a..50a0947c425 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,14 @@
+2021-12-22 Jedidiah Thompson <wej22007 [at] outlook [com]>
+
+	emulparams/aarch64pe.sh: create
+	emultempl/pep.em: remove x86_64 assumptions and add AArch64 support
+	configure.tgt: add aarch64-pe target
+	Makefile.am: add aarch64pe emulation
+	Makefile.in: regenerate
+	pe-dll.c: add aarch64 support, genralize for non x86_64
+	pep-dll-aarch64.c: create
+	pep-dll-x86_64.c: create
+
 2021-12-16  Nick Clifton  <nickc@redhat.com>
 
 	PR 28686
diff --git a/ld/Makefile.am b/ld/Makefile.am
index d27d9956af8..f6db936e71f 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -391,6 +391,7 @@ ALL_64_EMULATION_SOURCES = \
 	eaarch64linux32.c \
 	eaarch64linux32b.c \
 	eaarch64linuxb.c \
+	eaarch64pe.c	\
 	eelf32_x86_64.c \
 	eelf32b4300.c \
 	eelf32bmip.c \
diff --git a/ld/Makefile.in b/ld/Makefile.in
index d159f14823f..f6f24d76077 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -522,6 +522,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -880,6 +881,7 @@ ALL_64_EMULATION_SOURCES = \
 	eaarch64linux32.c \
 	eaarch64linux32b.c \
 	eaarch64linuxb.c \
+	eaarch64pe.c	\
 	eelf32_x86_64.c \
 	eelf32b4300.c \
 	eelf32bmip.c \
@@ -1255,6 +1257,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32b.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linuxb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64pe.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5ppc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5rs6.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixppc.Po@am__quote@
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 925ce076179..717b40affc2 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -50,6 +50,10 @@ aarch64-*-elf | aarch64-*-rtems* | aarch64-*-genode*)
 			targ_emul=aarch64elf
 			targ_extra_emuls="aarch64elf32 aarch64elf32b aarch64elfb armelf armelfb"
 			;;
+aarch64-*-pe)
+			targ_emul=aarch64pe
+			targ_extra_ofiles="deffilep.o pep-dll-aarch64.o"
+			;;
 aarch64-*-cloudabi*)	targ_emul=aarch64cloudabi
 			targ_extra_emuls=aarch64cloudabib
 			;;
@@ -1005,7 +1009,7 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
 			;;
 x86_64-*-pe | x86_64-*-pep) targ_emul=i386pep ;
 			targ_extra_emuls=i386pe ;
-			targ_extra_ofiles="deffilep.o pep-dll.o pe-dll.o"
+			targ_extra_ofiles="deffilep.o pep-dll-x86_64.o pe-dll.o"
 			;;
 x86_64-*-cygwin)	targ_emul=i386pep ;
 			targ_extra_emuls=i386pe
diff --git a/ld/emulparams/aarch64pe.sh b/ld/emulparams/aarch64pe.sh
new file mode 100644
index 00000000000..3b1c161692e
--- /dev/null
+++ b/ld/emulparams/aarch64pe.sh
@@ -0,0 +1,9 @@
+ARCH="aarch64"
+SCRIPT_NAME=pep
+OUTPUT_FORMAT="pei-aarch64"
+RELOCATEABLE_OUTPUT_FORMAT="pe-aarch64"
+TEMPLATE_NAME=pep
+SUBSYSTEM=PE_DEF_SUBSYSTEM
+INITIAL_SYMBOL_CHAR=\"_\"
+TARGET_PAGE_SIZE=0x1000
+GENERATE_AUTO_IMPORT_SCRIPT=1
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 430351b6481..af7e1ff07d1 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -48,7 +48,11 @@ fragment <<EOF
 
 #define COFF_IMAGE_WITH_PE
 #define COFF_WITH_PE
+#ifdef TARGET_IS_aarch64pe
+#define COFF_WITH_peAArch64
+#elif defined TARGET_IS_i386pep
 #define COFF_WITH_pex64
+#endif
 
 #include "sysdep.h"
 #include "bfd.h"
@@ -72,7 +76,11 @@ fragment <<EOF
 
 /* FIXME: See bfd/peXXigen.c for why we include an architecture specific
    header in generic PE code.  */
+#ifdef COFF_WITH_pex64
 #include "coff/x86_64.h"
+#elif defined COFF_WITH_peAArch64
+#include "coff/aarch64.h"
+#endif
 #include "coff/pe.h"
 
 /* FIXME: These are BFD internal header files, and we should not be
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index e7b82ba6ffa..43c052d723b 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -42,7 +42,7 @@
 #include "../bfd/libcoff.h"
 #include "deffile.h"
 
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
 
 #define PE_IDATA4_SIZE	8
 #define PE_IDATA5_SIZE	8
@@ -209,7 +209,7 @@ static const autofilter_entry_type autofilter_symbollist_i386[] =
   { STRING_COMMA_LEN ("_NULL_IMPORT_DESCRIPTOR") },
   /* Entry point symbols, and entry hooks.  */
   { STRING_COMMA_LEN ("cygwin_crt0") },
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
   { STRING_COMMA_LEN ("DllMain") },
   { STRING_COMMA_LEN ("DllEntryPoint") },
   { STRING_COMMA_LEN ("DllMainCRTStartup") },
@@ -246,13 +246,14 @@ static const autofilter_entry_type autofilter_symbollist_i386[] =
 #define PE_ARCH_mips	 3
 #define PE_ARCH_arm	 4
 #define PE_ARCH_arm_wince 5
+#define PE_ARCH_aarch64   6
 
 /* Don't make it constant as underscore mode gets possibly overriden
    by target or -(no-)leading-underscore option.  */
 static pe_details_type pe_detail_list[] =
 {
   {
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
     "pei-x86-64",
     "pe-x86-64",
     3 /* R_IMAGEBASE */,
@@ -263,14 +264,14 @@ static pe_details_type pe_detail_list[] =
 #endif
     PE_ARCH_i386,
     bfd_arch_i386,
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
     false,
 #else
     true,
 #endif
     autofilter_symbollist_i386
   },
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
   {
     "pei-x86-64",
     "pe-bigobj-x86-64",
@@ -327,6 +328,15 @@ static pe_details_type pe_detail_list[] =
     false,
     autofilter_symbollist_generic
   },
+  {
+    "pei-aarch64",
+    "pe-aarch64",
+    2,  /* ARM64_RVA32 */
+    PE_ARCH_aarch64,
+    bfd_arch_aarch64,
+    false,
+    autofilter_symbollist_generic
+  },
   { NULL, NULL, 0, 0, 0, false, NULL }
 };
 
@@ -1641,7 +1651,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
 		  switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
 					 relocs[i]->howto->rightshift)
 		    {
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
 		    case BITS_AND_SHIFT (64, 0):
 		      reloc_data[total_relocs].type = 10;
 		      total_relocs++;
@@ -2278,6 +2288,15 @@ static const unsigned char jmp_arm_bytes[] =
   0,    0,    0,    0
 };
 
+/* _function:
+  b <__imp_function>
+  nop */
+static const unsigned char jmp_aarch64_bytes[] =
+{
+  0x00, 0x00, 0x00, 0x14,
+  0x1f, 0x20, 0x03, 0xD5
+};
+
 
 static bfd *
 make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
@@ -2317,6 +2336,10 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
 	  jmp_bytes = jmp_arm_bytes;
 	  jmp_byte_count = sizeof (jmp_arm_bytes);
 	  break;
+  case PE_ARCH_aarch64:
+    jmp_bytes = jmp_aarch64_bytes;
+    jmp_byte_count = sizeof (jmp_aarch64_bytes);
+    break;
 	default:
 	  abort ();
 	}
@@ -2382,7 +2405,7 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
       switch (pe_details->pe_arch)
 	{
 	case PE_ARCH_i386:
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
 	  quick_reloc (abfd, 2, BFD_RELOC_32_PCREL, 2);
 #else
 	  /* Mark this object as SAFESEH compatible.  */
@@ -2403,6 +2426,9 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
 	case PE_ARCH_arm_wince:
 	  quick_reloc (abfd, 8, BFD_RELOC_32, 2);
 	  break;
+  case PE_ARCH_aarch64:
+    quick_reloc (abfd, 0, BFD_RELOC_32_PCREL, 2);
+    break;
 	default:
 	  abort ();
 	}
@@ -3374,7 +3400,7 @@ pe_implied_import_dll (const char *filename)
   /* Get pe_header, optional header and numbers of directory entries.  */
   pe_header_offset = pe_get32 (dll, 0x3c);
   opthdr_ofs = pe_header_offset + 4 + 20;
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
   num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /*  & NumberOfRvaAndSizes.  */
 #else
   num_entries = pe_get32 (dll, opthdr_ofs + 92);
@@ -3384,7 +3410,7 @@ pe_implied_import_dll (const char *filename)
   if (num_entries < 1)
     return false;
 
-#ifdef pe_use_x86_64
+#ifdef pe_use_plus
   export_rva  = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
   export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
 #else
diff --git a/ld/pep-dll-aarch64.c b/ld/pep-dll-aarch64.c
new file mode 100644
index 00000000000..b57fd03ebfa
--- /dev/null
+++ b/ld/pep-dll-aarch64.c
@@ -0,0 +1,24 @@
+/* Tiny wrapper over pep-dll.c
+   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   Written by Kai Tietz, OneVision Software GmbH&CoKg.
+
+   This file is part of the GNU Binutils.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define COFF_WITH_peAArch64
+
+#include "pep-dll.c"
diff --git a/ld/pep-dll-x86_64.c b/ld/pep-dll-x86_64.c
new file mode 100644
index 00000000000..858e1a876ff
--- /dev/null
+++ b/ld/pep-dll-x86_64.c
@@ -0,0 +1,24 @@
+/* Tiny wrapper over pep-dll.c
+   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   Written by Kai Tietz, OneVision Software GmbH&CoKg.
+
+   This file is part of the GNU Binutils.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define COFF_WITH_pex64
+
+#include "pep-dll.c"
diff --git a/ld/pep-dll.c b/ld/pep-dll.c
index 8564fb995b9..6760bcdefcb 100644
--- a/ld/pep-dll.c
+++ b/ld/pep-dll.c
@@ -1,4 +1,4 @@
-/* Routines to help build PEPI-format DLLs (Win64 etc)
+/* Routines to help build PEPI-format DLLs on x86_64 (Win64 etc)
    Copyright (C) 2006-2021 Free Software Foundation, Inc.
    Written by Kai Tietz, OneVision Software GmbH&CoKg.
 
@@ -21,7 +21,6 @@
 
 #define COFF_IMAGE_WITH_PE
 #define COFF_WITH_PE
-#define COFF_WITH_pex64
 
 /* Local defined globals.  */
 #define pe_def_file	            pep_def_file
@@ -58,7 +57,7 @@
 #define pe_output_file_set_long_section_names \
 				    pep_output_file_set_long_section_names
 
-/* Uses x86_64 PE+.  */
-#define pe_use_x86_64
+/* Use PE+.  */
+#define pe_use_plus
 
 #include "pe-dll.c"
-- 
2.32.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-12-30 13:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-23 13:07 [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD Jedidiah Thompson
2021-12-24 15:57 ` Tamar Christina
2021-12-27 17:07   ` Jedidiah Thompson
2021-12-29 11:38     ` Tamar Christina
2021-12-29 18:36       ` Jedidiah Thompson
2021-12-29 21:29         ` Jedidiah Thompson
2021-12-30 11:00           ` Tamar Christina
2021-12-30 13:54             ` Jedidiah Thompson
2021-12-30 10:51         ` Tamar Christina
  -- strict thread matches above, loose matches on Subject: below --
2021-12-22 23:19 [PATCH] " Jedidiah Thompson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).