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

* RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
  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
  0 siblings, 1 reply; 10+ messages in thread
From: Tamar Christina @ 2021-12-24 15:57 UTC (permalink / raw)
  To: Jedidiah Thompson; +Cc: binutils

Hi Jedidiah,

> +#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"

I don't understand the renaming from pei-aarch64-little to pei-aarch64.
The architecture supports both little and big endian so I would like the endianness to stay in the name.

Additionally this looks like it'll break efi support as the object mapping is now broken in objcopy, so please
undo the renaming and name the new object format with -little as we need to be able to tell from the name
which format it is.

Thanks,
Tamar


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

* Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
  2021-12-24 15:57 ` Tamar Christina
@ 2021-12-27 17:07   ` Jedidiah Thompson
  2021-12-29 11:38     ` Tamar Christina
  0 siblings, 1 reply; 10+ messages in thread
From: Jedidiah Thompson @ 2021-12-27 17:07 UTC (permalink / raw)
  To: Tamar Christina; +Cc: binutils

Here is the updated patch:

From cdc2d6fb12f287ae06b085f4d79b260b92ae3ad4 Mon Sep 17 00:00:00 2001
From: Jedidiah Thompson <wej22007@outlook.com>
Date: Mon, 27 Dec 2021 12:05:46 -0500
Subject: [PATCH] Add aarch64-pe support to GAS and LD; refine support in BFD

---
 bfd/Makefile.am            |  2 ++
 bfd/Makefile.in            |  4 +++
 bfd/bfd.c                  |  1 +
 bfd/coff-aarch64.c         |  4 +--
 bfd/config.bfd             | 15 ++++++--
 bfd/configure              | 33 ++++++++++++-----
 bfd/configure.ac           |  3 +-
 bfd/doc/Makefile.in        |  1 +
 bfd/pe-aarch64.c           | 74 ++++++++++++++++++++++++++++++++++++++
 bfd/pei-aarch64.c          |  2 +-
 bfd/peicode.h              |  2 ++
 bfd/pep-dll-x86_64.c       | 22 ++++++++++++
 bfd/targets.c              |  6 ++--
 gas/config/obj-coff.h      |  7 ++++
 gas/config/tc-aarch64.c    | 26 +++++++++++---
 gas/config/tc-aarch64.h    | 34 ++++++++++++++++--
 gas/configure.tgt          |  1 +
 ld/Makefile.am             |  1 +
 ld/Makefile.in             |  3 ++
 ld/configure               | 30 +++++++++++-----
 ld/configure.tgt           |  6 +++-
 ld/emulparams/aarch64pe.sh |  9 +++++
 ld/emultempl/pep.em        |  8 +++++
 ld/pe-dll.c                | 44 ++++++++++++++++++-----
 ld/pep-dll-aarch64.c       | 23 ++++++++++++
 ld/pep-dll.c               |  3 +-
 26 files changed, 320 insertions(+), 44 deletions(-)
 create mode 100644 bfd/pe-aarch64.c
 create mode 100644 bfd/pep-dll-x86_64.c
 create mode 100644 ld/emulparams/aarch64pe.sh
 create mode 100644 ld/pep-dll-aarch64.c

diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 4960cb500b1..4e51f2f9efe 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -575,6 +575,7 @@ BFD64_BACKENDS = \
   pe-aarch64igen.lo \
   pe-x86_64.lo \
   pei-aarch64.lo \
+  pe-aarch64.lo \
   pei-ia64.lo \
   pei-x86_64.lo \
   pepigen.lo \
@@ -616,6 +617,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..88cd46e341b 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@
@@ -1002,6 +1003,7 @@ BFD64_BACKENDS = \
   pe-aarch64igen.lo \
   pe-x86_64.lo \
   pei-aarch64.lo \
+  pe-aarch64.lo \
   pei-ia64.lo \
   pei-x86_64.lo \
   pepigen.lo \
@@ -1043,6 +1045,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 +1577,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..089c22c6fa0 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1739,6 +1739,7 @@ bfd_get_sign_extend_vma (bfd *abfd)
       || strcmp (name, "pe-x86-64") == 0
       || strcmp (name, "pei-x86-64") == 0
       || strcmp (name, "pei-aarch64-little") == 0
+    || strcmp (name, "pe-aarch64-little") == 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..9aa7d6a2280 100644
--- a/bfd/coff-aarch64.c
+++ b/bfd/coff-aarch64.c
@@ -89,13 +89,13 @@ const bfd_target
 #ifdef TARGET_SYM
   TARGET_SYM =
 #else
-  aarch64_pei_vec =
+# error "target symbol name not specified"
 #endif
 {
 #ifdef TARGET_NAME
   TARGET_NAME,
 #else
- "pei-aarch64-little",       /* Name.  */
+# error "target name not specified"
 #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..d2ec4c4a38b 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -249,7 +249,12 @@ case "${targ}" in
     ;;
   aarch64-*-elf | aarch64-*-rtems* | aarch64-*-genode*)
     targ_defvec=aarch64_elf64_le_vec
-    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
+    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
+    want64=true
+    ;;
+  aarch64-*-pe)
+    targ_defvec=aarch64_pei_le_vec
+    targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
     want64=true
     ;;
   aarch64_be-*-elf)
@@ -279,7 +284,7 @@ case "${targ}" in
     ;;
   aarch64-*-linux* | aarch64-*-netbsd*)
     targ_defvec=aarch64_elf64_le_vec
-    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
+    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
     want64=true
     ;;
   aarch64_be-*-linux* | aarch64_be-*-netbsd*)
@@ -1534,3 +1539,9 @@ case "${targ_defvec} ${targ_selvecs}" in
     targ_archs="$targ_archs bfd_k1om_arch"
     ;;
 esac
+
+if test x"$targ_defvec" = x"aarch64-pe"; then
+  # 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"
+fi
diff --git a/bfd/configure b/bfd/configure
index d4aa2178b29..3360cc89587 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];
@@ -13296,7 +13308,8 @@ do
     aarch64_elf64_le_vec)    tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     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_pei_le_vec)       tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
+    aarch64_pe_le_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..57c2123cb5e 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -437,7 +437,8 @@ do
     aarch64_elf64_le_vec)    tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     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_pei_le_vec)       tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
+    aarch64_pe_le_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/pe-aarch64.c b/bfd/pe-aarch64.c
new file mode 100644
index 00000000000..abbb9a91ed9
--- /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_le_vec
+#define TARGET_NAME            "pe-aarch64-little"
+#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"
\ No newline at end of file
diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c
index 99326d16126..308d740555a 100644
--- a/bfd/pei-aarch64.c
+++ b/bfd/pei-aarch64.c
@@ -21,7 +21,7 @@
 #include "sysdep.h"
 #include "bfd.h"

-#define TARGET_SYM     aarch64_pei_vec
+#define TARGET_SYM     aarch64_pei_le_vec
 #define TARGET_NAME    "pei-aarch64-little"
 #define TARGET_ARCHITECTURE  bfd_arch_aarch64
 #define TARGET_PAGESIZE      4096
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/pep-dll-x86_64.c b/bfd/pep-dll-x86_64.c
new file mode 100644
index 00000000000..7473892ad23
--- /dev/null
+++ b/bfd/pep-dll-x86_64.c
@@ -0,0 +1,22 @@
+/* Tiny wrapper over pep-dll.c
+   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   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"
\ No newline at end of file
diff --git a/bfd/targets.c b/bfd/targets.c
index 672dc2bb1a4..11a0b9bb55f 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -679,7 +679,8 @@ extern const bfd_target aarch64_elf64_be_cloudabi_vec;
 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_pei_le_vec;
+extern const bfd_target aarch64_pe_le_vec;
 extern const bfd_target alpha_ecoff_le_vec;
 extern const bfd_target alpha_elf64_vec;
 extern const bfd_target alpha_elf64_fbsd_vec;
@@ -994,7 +995,8 @@ static const bfd_target * const _bfd_target_vector[] =
   &aarch64_elf64_le_vec,
   &aarch64_elf64_le_cloudabi_vec,
   &aarch64_mach_o_vec,
-  &aarch64_pei_vec,
+  &aarch64_pei_le_vec,
+  &aarch64_pe_le_vec,
 #endif

 #ifdef BFD64
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
index 73c001e3edc..5cb89f09d61 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-little"
+#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..811f3eedbaa 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,10 +9059,14 @@ 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;
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
+#endif
       /* Should always be exported to object file, see
    aarch64_force_relocation().  */
       gas_assert (!fixP->fx_done);
@@ -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);
 }
@@ -10188,6 +10204,7 @@ aarch64_parse_arch (const char *str)
 }

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

 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..ccc4a4c3f0c 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..48aeb848184 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/Makefile.am b/ld/Makefile.am
index d27d9956af8..fd8daf48264 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..f659ffe2881 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 b/ld/configure
index c4ba49082cd..f9e98a52bea 100755
--- a/ld/configure
+++ b/ld/configure
@@ -791,6 +791,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -898,6 +899,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}'
@@ -1150,6 +1152,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=* \
@@ -1287,7 +1298,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.
@@ -1440,6 +1451,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]
@@ -11452,7 +11464,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11455 "configure"
+#line 11467 "configure"
 #include "confdefs.h"

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

 #if HAVE_DLFCN_H
@@ -14992,7 +15004,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];
@@ -15038,7 +15050,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];
@@ -15062,7 +15074,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];
@@ -15107,7 +15119,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];
@@ -15131,7 +15143,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];
@@ -16559,6 +16571,8 @@ main ()
     if (*(data + i) != *(data3 + i))
       return 14;
   close (fd);
+  free (data);
+  free (data3);
   return 0;
 }
 _ACEOF
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 925ce076179..8ee3c53645a 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -80,6 +80,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*)
+        targ_emul=aarch64pe
+        targ_extra_ofiles="deffilep.o pep-dll-aarch64.o"
+        ;;
 alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
         targ_emul=elf64alpha_fbsd
         targ_extra_emuls="elf64alpha alpha"
@@ -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..a72e1e04c55
--- /dev/null
+++ b/ld/emulparams/aarch64pe.sh
@@ -0,0 +1,9 @@
+ARCH="aarch64"
+SCRIPT_NAME=pep
+OUTPUT_FORMAT="pei-aarch64-little"
+RELOCATEABLE_OUTPUT_FORMAT="pe-aarch64-little"
+TEMPLATE_NAME=pep
+SUBSYSTEM=PE_DEF_SUBSYSTEM
+INITIAL_SYMBOL_CHAR=\"_\"
+TARGET_PAGE_SIZE=0x1000
+GENERATE_AUTO_IMPORT_SCRIPT=1
\ No newline at end of file
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 430351b6481..15c3cda9392 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 TARGET_IS_i386pep
 #include "coff/x86_64.h"
+#elif defined (TARGET_IS_aarch64pe)
+#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..b83b4f5d70b 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-little",
+    "pe-aarch64-little",
+    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..51fd2be5112
--- /dev/null
+++ b/ld/pep-dll-aarch64.c
@@ -0,0 +1,23 @@
+/* Tiny wrapper over pep-dll.c
+   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+
+   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"
\ No newline at end of file
diff --git a/ld/pep-dll.c b/ld/pep-dll.c
index 8564fb995b9..3b9aa5a59b3 100644
--- a/ld/pep-dll.c
+++ b/ld/pep-dll.c
@@ -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
@@ -59,6 +58,6 @@
                pep_output_file_set_long_section_names

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

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


________________________________
From: Tamar Christina <Tamar.Christina@arm.com>
Sent: Friday, December 24, 2021 10:57 AM
To: Jedidiah Thompson <wej22007@outlook.com>
Cc: binutils@sourceware.org <binutils@sourceware.org>
Subject: RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD

Hi Jedidiah,

> +#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"

I don't understand the renaming from pei-aarch64-little to pei-aarch64.
The architecture supports both little and big endian so I would like the endianness to stay in the name.

Additionally this looks like it'll break efi support as the object mapping is now broken in objcopy, so please
undo the renaming and name the new object format with -little as we need to be able to tell from the name
which format it is.

Thanks,
Tamar


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

* RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
  2021-12-27 17:07   ` Jedidiah Thompson
@ 2021-12-29 11:38     ` Tamar Christina
  2021-12-29 18:36       ` Jedidiah Thompson
  0 siblings, 1 reply; 10+ messages in thread
From: Tamar Christina @ 2021-12-29 11:38 UTC (permalink / raw)
  To: Jedidiah Thompson; +Cc: binutils


Hi Jedidiah,

Thanks for respinning the patch, a couple more comments below:

> 
> From: Jedidiah Thompson <wej22007@outlook.com> 
> Sent: Monday, December 27, 2021 5:07 PM
> To: Tamar Christina <Tamar.Christina@arm.com>
> Cc: binutils@sourceware.org
> Subject: Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
> 
> Here is the updated patch:
> 
> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -249,7 +249,12 @@ case "${targ}" in
>      ;;
>    aarch64-*-elf | aarch64-*-rtems* | aarch64-*-genode*)
>      targ_defvec=aarch64_elf64_le_vec
> -    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
> +    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
> +    want64=true
> +    ;;
> +  aarch64-*-pe)
> +    targ_defvec=aarch64_pei_le_vec
> +    targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
>      want64=true

64-bit PE is not an underscore platform, so you want targ_underscore=no here too.
Also you want the executable format not the image format as the default here. So
targ_defvec=aarch64_pe_le_vec instead of pei.

>      ;;
>    aarch64_be-*-elf)
> @@ -279,7 +284,7 @@ case "${targ}" in
>      ;;
>    aarch64-*-linux* | aarch64-*-netbsd*)
>      targ_defvec=aarch64_elf64_le_vec
> -    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
> +    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
>      want64=true
>      ;;
>    aarch64_be-*-linux* | aarch64_be-*-netbsd*)
> @@ -1534,3 +1539,9 @@ case "${targ_defvec} ${targ_selvecs}" in
>      targ_archs="$targ_archs bfd_k1om_arch"
>      ;;
>  esac
> +
> +if test x"$targ_defvec" = x"aarch64-pe"; then
> +  # 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"
> +fi

> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index cc7725483aa..811f3eedbaa 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

not sure I understand why these changes are needed. ilp32_p is based on the ABI and since
-mabi isn't defined for aarch64-*pe you can't ever really set it. So all of these and the below
should already be correct without the ifdefs.

That said the default ABI looks wrong, The default ABI will be set to AARCH64_ABI_LP64.
Since PE/Windos is IL32P64 you'll want a new ABI, AARCH64_ABI_IL32P64 and make that the default in
aarch64_after_parse_args moving that ouf of the ifdef OBJ_ELF.

You'll also want to change TARGET_FORMAT to set the default format for the BFD target.

>        S_SET_THREAD_LOCAL (fixP->fx_addsy);
>        /* Should always be exported to object file, see
>     aarch64_force_relocation().  */
> @@ -9055,10 +9059,14 @@ 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;
>        S_SET_THREAD_LOCAL (fixP->fx_addsy);
> +#endif
>        /* Should always be exported to object file, see
>     aarch64_force_relocation().  */
>        gas_assert (!fixP->fx_done);
> @@ -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);
>  }
> @@ -10188,6 +10204,7 @@ aarch64_parse_arch (const char *str)
>  }
>  
>  /* ABIs.  */
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
>  struct aarch64_option_abi_value_table
>  {
>    const char *name;
> @@ -10220,6 +10237,7 @@ aarch64_parse_abi (const char *str)
>    as_bad (_("unknown abi `%s'\n"), str);
>    return 0;
>  }
> +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
>  
>  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..ccc4a4c3f0c 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;
> +};
> +

Any reason you can't just remove the OBJ_ELF or include OBJ_COFF here?
This looks exactly the same code as the OBJ_ELF block and in principle
CFIs should be handled by BFD already.

>  #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

This looks like copied left over code from the Arm implementation, just delete the hunk.

Thanks,
Tamar


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

* Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
  2021-12-29 11:38     ` Tamar Christina
@ 2021-12-29 18:36       ` Jedidiah Thompson
  2021-12-29 21:29         ` Jedidiah Thompson
  2021-12-30 10:51         ` Tamar Christina
  0 siblings, 2 replies; 10+ messages in thread
From: Jedidiah Thompson @ 2021-12-29 18:36 UTC (permalink / raw)
  To: Tamar Christina; +Cc: binutils

This patch makes AArch64 on PE recognize the fact that varying ABIs exists (plus the small change in config.bfd)
Note that a new ABI like you suggested has not been added yet; I will work on that next

From 5c82797beee422075b9dd55c231afe349447d293 Mon Sep 17 00:00:00 2001
From: Jedidiah Thompson <wej22007@outlook.com>
Date: Wed, 29 Dec 2021 13:34:26 -0500
Subject: [PATCH 2/2] Make aarch64 assember handle varying ABIs on PE

A new ABI should be created specially for Windows / PE, however, that is a larger task that will be handled seperatly
---
 bfd/config.bfd          |  5 ++--
 gas/config/obj-coff.h   |  3 ---
 gas/config/tc-aarch64.c | 42 +++++++++++-------------------
 gas/config/tc-aarch64.h | 57 ++++++++---------------------------------
 4 files changed, 28 insertions(+), 79 deletions(-)

diff --git a/bfd/config.bfd b/bfd/config.bfd
index d2ec4c4a38b..e9188870f6d 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -253,9 +253,10 @@ case "${targ}" in
     want64=true
     ;;
   aarch64-*-pe)
-    targ_defvec=aarch64_pei_le_vec
-    targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
+    targ_defvec=aarch64_pe_le_vec
+    targ_selvecs="aarch64_pei_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
     want64=true
+    targ_underscore=no
     ;;
   aarch64_be-*-elf)
     targ_defvec=aarch64_elf64_be_vec
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
index 5cb89f09d61..641db43ac6d 100644
--- a/gas/config/obj-coff.h
+++ b/gas/config/obj-coff.h
@@ -42,9 +42,6 @@

 #ifdef TC_AARCH64
 #include "coff/aarch64.h"
-#ifndef TARGET_FORMAT
-#define TARGET_FORMAT "pe-aarch64-little"
-#endif
 #endif

 #ifdef TC_PPC
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 811f3eedbaa..818d260148d 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -30,8 +30,8 @@

 #ifdef OBJ_ELF
 #include "elf/aarch64.h"
-#include "dw2gencfi.h"
 #endif
+#include "dw2gencfi.h"

 #include "dwarf2dbg.h"

@@ -61,6 +61,7 @@ static aarch64_instr_sequence *insn_sequence = NULL;
 #ifdef OBJ_ELF
 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"   */
 static symbolS *GOT_symbol;
+#endif

 /* Which ABI to use.  */
 enum aarch64_abi_type
@@ -85,7 +86,6 @@ static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
    64-bit model, in which the C int type is 32-bits but the C long type
    and all pointer types are 64-bit objects (LP64).  */
 #define ilp32_p     (aarch64_abi == AARCH64_ABI_ILP32)
-#endif

 enum vector_el_type
 {
@@ -2028,8 +2028,6 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED)
   input_line_pointer--;
   demand_empty_rest_of_line ();
 }
-
-#ifdef OBJ_ELF
 static void
 s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
 {
@@ -2038,6 +2036,7 @@ 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 +2110,8 @@ const pseudo_typeS md_pseudo_table[] = {
   {"arch", s_aarch64_arch, 0},
   {"arch_extension", s_aarch64_arch_extension, 0},
   {"inst", s_aarch64_inst, 0},
-#ifdef OBJ_ELF
   {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
+#ifdef OBJ_ELF
   {"tlsdescadd", s_tlsdescadd, 0},
   {"tlsdesccall", s_tlsdesccall, 0},
   {"tlsdescldr", s_tlsdescldr, 0},
@@ -8361,6 +8360,8 @@ aarch64_init_frag (fragS * fragP, int max_chars)
     }
 }

+#endif /* OBJ_ELF */
+
 /* Initialize the DWARF-2 unwind information for this procedure.  */

 void
@@ -8368,7 +8369,6 @@ tc_aarch64_frame_initial_instructions (void)
 {
   cfi_add_CFA_def_cfa (REG_SP, 0);
 }
-#endif /* OBJ_ELF */

 /* Convert REGNAME to a DWARF-2 register number.  */

@@ -8405,10 +8405,8 @@ tc_aarch64_regname_to_dw2regnum (char *regname)
 int
 aarch64_dwarf2_addr_size (void)
 {
-#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
   if (ilp32_p)
     return 4;
-#endif
   return bfd_arch_bits_per_address (stdoutput) / 8;
 }

@@ -9044,13 +9042,9 @@ 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().  */
@@ -9059,14 +9053,10 @@ 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;
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
-#endif
       /* Should always be exported to object file, see
    aarch64_force_relocation().  */
       gas_assert (!fixP->fx_done);
@@ -9135,13 +9125,9 @@ 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;
@@ -9284,7 +9270,6 @@ cons_fix_new_aarch64 (fragS * frag, int where, int size, expressionS * exp)
   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
 }

-#ifdef OBJ_ELF

 /* Implement md_after_parse_args.  This is the earliest time we need to decide
    ABI.  If no -mabi specified, the ABI will be decided by target triplet.  */
@@ -9302,6 +9287,7 @@ aarch64_after_parse_args (void)
     aarch64_abi = AARCH64_ABI_LP64;
 }

+#ifdef OBJ_ELF
 const char *
 elf64_aarch64_target_format (void)
 {
@@ -9324,6 +9310,12 @@ aarch64elf_frob_symbol (symbolS * symp, int *puntp)
 {
   elf_frob_symbol (symp, puntp);
 }
+#elif defined (OBJ_COFF)
+const char *
+coff_aarch64_target_format (void)
+{
+  return "pe-aarch64-little";
+}
 #endif

 /* MD interface: Finalization.  */
@@ -9639,11 +9631,7 @@ 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);
 }
@@ -10204,13 +10192,13 @@ aarch64_parse_arch (const char *str)
 }

 /* ABIs.  */
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 struct aarch64_option_abi_value_table
 {
   const char *name;
   enum aarch64_abi_type value;
 };

+#ifdef OBJ_ELF
 static const struct aarch64_option_abi_value_table aarch64_abis[] = {
   {"ilp32",      AARCH64_ABI_ILP32},
   {"lp64",    AARCH64_ABI_LP64},
@@ -10237,7 +10225,7 @@ aarch64_parse_abi (const char *str)
   as_bad (_("unknown abi `%s'\n"), str);
   return 0;
 }
-#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
+#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 ccc4a4c3f0c..aae1b64588c 100644
--- a/gas/config/tc-aarch64.h
+++ b/gas/config/tc-aarch64.h
@@ -59,9 +59,11 @@ struct aarch64_fix
   enum aarch64_opnd opnd;
 };

-#if defined OBJ_ELF
+#ifdef OBJ_ELF
 # define AARCH64_BI_ENDIAN
 # define TARGET_FORMAT elf64_aarch64_target_format ()
+#elif defined (OBJ_COFF)
+# define TARGET_FORMAT coff_aarch64_target_format ()
 #endif

 #define TC_FORCE_RELOCATION(FIX) aarch64_force_relocation (FIX)
@@ -202,17 +204,18 @@ struct aarch64_frag_type
 extern int aarch64_dwarf2_addr_size (void);
 #define DWARF2_ADDR_SIZE(bfd) aarch64_dwarf2_addr_size ()

-#ifdef OBJ_ELF
-# define obj_frob_symbol(sym, punt)   aarch64elf_frob_symbol ((sym), & (punt))
+#ifdef TE_ELF
+#define obj_frob_symbol(sym, punt) aarch64elf_frob_symbol ((sym), & (punt))
+#endif

-# define GLOBAL_OFFSET_TABLE_NAME  "_GLOBAL_OFFSET_TABLE_"
-# define TC_SEGMENT_INFO_TYPE      struct aarch64_segment_info_type
+#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)
+#define md_cons_align(nbytes)      mapping_state (MAP_DATA)

 enum mstate
 {
@@ -242,38 +245,6 @@ 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
-
 #if defined OBJ_ELF || defined OBJ_COFF

 # define EXTERN_FORCE_RELOC        1
@@ -287,6 +258,7 @@ struct aarch64_segment_info_type

 extern void aarch64_frag_align_code (int, int);
 extern const char * elf64_aarch64_target_format (void);
+extern const char * coff_aarch64_target_format (void);
 extern int aarch64_force_relocation (struct fix *);
 extern void aarch64_cleanup (void);
 extern void aarch64_start_line_hook (void);
@@ -302,13 +274,4 @@ extern void aarch64_handle_align (struct frag *);
 extern int tc_aarch64_regname_to_dw2regnum (char *regname);
 extern void tc_aarch64_frame_initial_instructions (void);

-#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
-
 #endif /* TC_AARCH64 */
--
2.32.0

________________________________
From: Tamar Christina <Tamar.Christina@arm.com>
Sent: Wednesday, December 29, 2021 6:38 AM
To: Jedidiah Thompson <wej22007@outlook.com>
Cc: binutils@sourceware.org <binutils@sourceware.org>
Subject: RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD


Hi Jedidiah,

Thanks for respinning the patch, a couple more comments below:

>
> From: Jedidiah Thompson <wej22007@outlook.com>
> Sent: Monday, December 27, 2021 5:07 PM
> To: Tamar Christina <Tamar.Christina@arm.com>
> Cc: binutils@sourceware.org
> Subject: Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
>
> Here is the updated patch:
>
> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -249,7 +249,12 @@ case "${targ}" in
>      ;;
>    aarch64-*-elf | aarch64-*-rtems* | aarch64-*-genode*)
>      targ_defvec=aarch64_elf64_le_vec
> -    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
> +    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
> +    want64=true
> +    ;;
> +  aarch64-*-pe)
> +    targ_defvec=aarch64_pei_le_vec
> +    targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
>      want64=true

64-bit PE is not an underscore platform, so you want targ_underscore=no here too.
Also you want the executable format not the image format as the default here. So
targ_defvec=aarch64_pe_le_vec instead of pei.

>      ;;
>    aarch64_be-*-elf)
> @@ -279,7 +284,7 @@ case "${targ}" in
>      ;;
>    aarch64-*-linux* | aarch64-*-netbsd*)
>      targ_defvec=aarch64_elf64_le_vec
> -    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
> +    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
>      want64=true
>      ;;
>    aarch64_be-*-linux* | aarch64_be-*-netbsd*)
> @@ -1534,3 +1539,9 @@ case "${targ_defvec} ${targ_selvecs}" in
>      targ_archs="$targ_archs bfd_k1om_arch"
>      ;;
>  esac
> +
> +if test x"$targ_defvec" = x"aarch64-pe"; then
> +  # 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"
> +fi

> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index cc7725483aa..811f3eedbaa 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

not sure I understand why these changes are needed. ilp32_p is based on the ABI and since
-mabi isn't defined for aarch64-*pe you can't ever really set it. So all of these and the below
should already be correct without the ifdefs.

That said the default ABI looks wrong, The default ABI will be set to AARCH64_ABI_LP64.
Since PE/Windos is IL32P64 you'll want a new ABI, AARCH64_ABI_IL32P64 and make that the default in
aarch64_after_parse_args moving that ouf of the ifdef OBJ_ELF.

You'll also want to change TARGET_FORMAT to set the default format for the BFD target.

>        S_SET_THREAD_LOCAL (fixP->fx_addsy);
>        /* Should always be exported to object file, see
>     aarch64_force_relocation().  */
> @@ -9055,10 +9059,14 @@ 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;
>        S_SET_THREAD_LOCAL (fixP->fx_addsy);
> +#endif
>        /* Should always be exported to object file, see
>     aarch64_force_relocation().  */
>        gas_assert (!fixP->fx_done);
> @@ -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);
>  }
> @@ -10188,6 +10204,7 @@ aarch64_parse_arch (const char *str)
>  }
>
>  /* ABIs.  */
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
>  struct aarch64_option_abi_value_table
>  {
>    const char *name;
> @@ -10220,6 +10237,7 @@ aarch64_parse_abi (const char *str)
>    as_bad (_("unknown abi `%s'\n"), str);
>    return 0;
>  }
> +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
>
>  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..ccc4a4c3f0c 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;
> +};
> +

Any reason you can't just remove the OBJ_ELF or include OBJ_COFF here?
This looks exactly the same code as the OBJ_ELF block and in principle
CFIs should be handled by BFD already.

>  #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

This looks like copied left over code from the Arm implementation, just delete the hunk.

Thanks,
Tamar


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

* Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
  2021-12-29 18:36       ` Jedidiah Thompson
@ 2021-12-29 21:29         ` Jedidiah Thompson
  2021-12-30 11:00           ` Tamar Christina
  2021-12-30 10:51         ` Tamar Christina
  1 sibling, 1 reply; 10+ messages in thread
From: Jedidiah Thompson @ 2021-12-29 21:29 UTC (permalink / raw)
  To: Tamar Christina, Jedidiah Thompson; +Cc: binutils

Here is a patch with LLP64 added:

From df704f90aae1b41ccdd16270cd8287fa35c308e6 Mon Sep 17 00:00:00 2001
From: Jedidiah Thompson <wej22007@outlook.com>
Date: Wed, 29 Dec 2021 16:27:30 -0500
Subject: [PATCH 3/3] Add LLP64 ABI to AArch64 as and BFD

LLP64 only can be used on COFF targets currently; Windows is the only OS I know of that uses LLP64
---
 bfd/archures.c          |  1 +
 bfd/bfd-in2.h           |  1 +
 bfd/cpu-aarch64.c       | 27 +++++++++++++++++++++------
 gas/config/tc-aarch64.c | 26 +++++++++++++++++++++-----
 4 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/bfd/archures.c b/bfd/archures.c
index 441283b51a6..62ba16b9aae 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -533,6 +533,7 @@ DESCRIPTION
 .#define bfd_mach_aarch64 0
 .#define bfd_mach_aarch64_8R 1
 .#define bfd_mach_aarch64_ilp32  32
+.#define bfd_mach_aarch64_llp64 64
 .  bfd_arch_nios2,     {* Nios II.  *}
 .#define bfd_mach_nios2    0
 .#define bfd_mach_nios2r1  1
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 7b7a329cd62..9b3b66a1359 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1907,6 +1907,7 @@ enum bfd_architecture
 #define bfd_mach_aarch64 0
 #define bfd_mach_aarch64_8R    1
 #define bfd_mach_aarch64_ilp32 32
+#define bfd_mach_aarch64_llp64 64
   bfd_arch_nios2,     /* Nios II.  */
 #define bfd_mach_nios2         0
 #define bfd_mach_nios2r1       1
diff --git a/bfd/cpu-aarch64.c b/bfd/cpu-aarch64.c
index d9d6c1b2f89..cbd764c9d75 100644
--- a/bfd/cpu-aarch64.c
+++ b/bfd/cpu-aarch64.c
@@ -39,9 +39,11 @@ compatible (const bfd_arch_info_type * a, const bfd_arch_info_type * b)
   if (a->mach == b->mach)
     return a;

-  /* Don't allow mixing ilp32 with lp64.  */
+  /* Don't allow mixing data models  */
   if ((a->mach & bfd_mach_aarch64_ilp32) != (b->mach & bfd_mach_aarch64_ilp32))
     return NULL;
+  if ((a->mach & bfd_mach_aarch64_llp64) != (b->mach & bfd_mach_aarch64_llp64))
+    return NULL;

   /* Otherwise if either a or b is the 'default' machine
      then it can be polymorphed into the other.  */
@@ -102,20 +104,33 @@ scan (const struct bfd_arch_info *info, const char *string)
   return false;
 }

-#define N(NUMBER, PRINT, WORDSIZE, DEFAULT, NEXT)    \
-  { WORDSIZE, WORDSIZE, 8, bfd_arch_aarch64, NUMBER,   \
+/* Figure out if llp64 is default */
+#if DEFAULT_VECTOR == aarch64_pe_le_vec
+#define LLP64_DEFAULT true
+#define AARCH64_DEFAULT false
+#else
+#define LLP64_DEFAULT false
+#define AARCH64_DEFAULT true
+#endif
+
+#define N(NUMBER, PRINT, WORDSIZE, ADDRSIZE, DEFAULT, NEXT)    \
+  { WORDSIZE, ADDRSIZE, 8, bfd_arch_aarch64, NUMBER,   \
     "aarch64", PRINT, 4, DEFAULT, compatible, scan,    \
       bfd_arch_default_fill, NEXT, 0 }

 static const bfd_arch_info_type bfd_aarch64_arch_v8_r =
-  N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, false, NULL);
+  N (bfd_mach_aarch64_8R, "aarch64:armv8-r", 64, 64, false, NULL);

 static const bfd_arch_info_type bfd_aarch64_arch_ilp32 =
-  N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, false,
+  N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", 32, 32, false,
      &bfd_aarch64_arch_v8_r);

+static const bfd_arch_info_type bfd_aarch64_arch_llp64 =
+  N (bfd_mach_aarch64_llp64, "aarch64:llp64", 32, 64, LLP64_DEFAULT,
+     &bfd_aarch64_arch_ilp32);
+
 const bfd_arch_info_type bfd_aarch64_arch =
-  N (0, "aarch64", 64, true, &bfd_aarch64_arch_ilp32);
+  N (0, "aarch64", 64, 64, AARCH64_DEFAULT, &bfd_aarch64_arch_llp64);

 bool
 bfd_is_aarch64_special_symbol_name (const char *name, int type)
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 818d260148d..83226aa5fd2 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -32,7 +32,6 @@
 #include "elf/aarch64.h"
 #endif
 #include "dw2gencfi.h"
-
 #include "dwarf2dbg.h"

 /* Types of processor to assemble for.  */
@@ -68,7 +67,8 @@ enum aarch64_abi_type
 {
   AARCH64_ABI_NONE = 0,
   AARCH64_ABI_LP64 = 1,
-  AARCH64_ABI_ILP32 = 2
+  AARCH64_ABI_ILP32 = 2,
+  AARCH64_ABI_LLP64 = 3
 };

 #ifndef DEFAULT_ARCH
@@ -76,7 +76,9 @@ enum aarch64_abi_type
 #endif

 /* DEFAULT_ARCH is initialized in gas/configure.tgt.  */
+#ifdef OBJ_ELF
 static const char *default_arch = DEFAULT_ARCH;
+#endif

 /* AArch64 ABI for the output file.  */
 static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
@@ -86,6 +88,9 @@ static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
    64-bit model, in which the C int type is 32-bits but the C long type
    and all pointer types are 64-bit objects (LP64).  */
 #define ilp32_p    (aarch64_abi == AARCH64_ABI_ILP32)
+/* When non zero, C types int and long are 32 bit,
+   pointers, however are 64 bit */
+#define llp64_p (aarch64_abi == AARCH64_ABI_LLP64)

 enum vector_el_type
 {
@@ -8407,6 +8412,8 @@ aarch64_dwarf2_addr_size (void)
 {
   if (ilp32_p)
     return 4;
+  else if (llp64_p)
+    return 8;
   return bfd_arch_bits_per_address (stdoutput) / 8;
 }

@@ -9125,7 +9132,7 @@ 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().  */
-      fixP->fx_r_type = (ilp32_p
+      fixP->fx_r_type = ((ilp32_p || llp64_p)
       ? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
       : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
       gas_assert (!fixP->fx_done);
@@ -9280,11 +9287,15 @@ aarch64_after_parse_args (void)
   if (aarch64_abi != AARCH64_ABI_NONE)
     return;

+#ifdef OBJ_COFF
+  aarch64_abi = AARCH64_ABI_LLP64;
+#elif defined (OBJ_ELF)
   /* DEFAULT_ARCH will have ":32" extension if it's configured for ILP32.  */
   if (strlen (default_arch) > 7 && strcmp (default_arch + 7, ":32") == 0)
     aarch64_abi = AARCH64_ABI_ILP32;
   else
     aarch64_abi = AARCH64_ABI_LP64;
+#endif
 }

 #ifdef OBJ_ELF
@@ -9631,7 +9642,12 @@ md_begin (void)
   cpu_variant = *mcpu_cpu_opt;

   /* Record the CPU type.  */
-  mach = ilp32_p ? bfd_mach_aarch64_ilp32 : bfd_mach_aarch64;
+  if(ilp32_p)
+    mach = bfd_mach_aarch64_ilp32;
+  else if (llp64_p)
+    mach = bfd_mach_aarch64_llp64;
+  else
+    mach = bfd_mach_aarch64;

   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
 }
@@ -10201,7 +10217,7 @@ struct aarch64_option_abi_value_table
 #ifdef OBJ_ELF
 static const struct aarch64_option_abi_value_table aarch64_abis[] = {
   {"ilp32",    AARCH64_ABI_ILP32},
-  {"lp64",   AARCH64_ABI_LP64},
+  {"lp64",   AARCH64_ABI_LP64}
 };

 static int
--
2.32.0


________________________________
From: Binutils <binutils-bounces+wej22007=outlook.com@sourceware.org> on behalf of Jedidiah Thompson via Binutils <binutils@sourceware.org>
Sent: Wednesday, December 29, 2021 1:36 PM
To: Tamar Christina <Tamar.Christina@arm.com>
Cc: binutils@sourceware.org <binutils@sourceware.org>
Subject: Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD

This patch makes AArch64 on PE recognize the fact that varying ABIs exists (plus the small change in config.bfd)
Note that a new ABI like you suggested has not been added yet; I will work on that next

From 5c82797beee422075b9dd55c231afe349447d293 Mon Sep 17 00:00:00 2001
From: Jedidiah Thompson <wej22007@outlook.com>
Date: Wed, 29 Dec 2021 13:34:26 -0500
Subject: [PATCH 2/2] Make aarch64 assember handle varying ABIs on PE

A new ABI should be created specially for Windows / PE, however, that is a larger task that will be handled seperatly
---
 bfd/config.bfd          |  5 ++--
 gas/config/obj-coff.h   |  3 ---
 gas/config/tc-aarch64.c | 42 +++++++++++-------------------
 gas/config/tc-aarch64.h | 57 ++++++++---------------------------------
 4 files changed, 28 insertions(+), 79 deletions(-)

diff --git a/bfd/config.bfd b/bfd/config.bfd
index d2ec4c4a38b..e9188870f6d 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -253,9 +253,10 @@ case "${targ}" in
     want64=true
     ;;
   aarch64-*-pe)
-    targ_defvec=aarch64_pei_le_vec
-    targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
+    targ_defvec=aarch64_pe_le_vec
+    targ_selvecs="aarch64_pei_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
     want64=true
+    targ_underscore=no
     ;;
   aarch64_be-*-elf)
     targ_defvec=aarch64_elf64_be_vec
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
index 5cb89f09d61..641db43ac6d 100644
--- a/gas/config/obj-coff.h
+++ b/gas/config/obj-coff.h
@@ -42,9 +42,6 @@

 #ifdef TC_AARCH64
 #include "coff/aarch64.h"
-#ifndef TARGET_FORMAT
-#define TARGET_FORMAT "pe-aarch64-little"
-#endif
 #endif

 #ifdef TC_PPC
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 811f3eedbaa..818d260148d 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -30,8 +30,8 @@

 #ifdef OBJ_ELF
 #include "elf/aarch64.h"
-#include "dw2gencfi.h"
 #endif
+#include "dw2gencfi.h"

 #include "dwarf2dbg.h"

@@ -61,6 +61,7 @@ static aarch64_instr_sequence *insn_sequence = NULL;
 #ifdef OBJ_ELF
 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"   */
 static symbolS *GOT_symbol;
+#endif

 /* Which ABI to use.  */
 enum aarch64_abi_type
@@ -85,7 +86,6 @@ static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
    64-bit model, in which the C int type is 32-bits but the C long type
    and all pointer types are 64-bit objects (LP64).  */
 #define ilp32_p     (aarch64_abi == AARCH64_ABI_ILP32)
-#endif

 enum vector_el_type
 {
@@ -2028,8 +2028,6 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED)
   input_line_pointer--;
   demand_empty_rest_of_line ();
 }
-
-#ifdef OBJ_ELF
 static void
 s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
 {
@@ -2038,6 +2036,7 @@ 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 +2110,8 @@ const pseudo_typeS md_pseudo_table[] = {
   {"arch", s_aarch64_arch, 0},
   {"arch_extension", s_aarch64_arch_extension, 0},
   {"inst", s_aarch64_inst, 0},
-#ifdef OBJ_ELF
   {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
+#ifdef OBJ_ELF
   {"tlsdescadd", s_tlsdescadd, 0},
   {"tlsdesccall", s_tlsdesccall, 0},
   {"tlsdescldr", s_tlsdescldr, 0},
@@ -8361,6 +8360,8 @@ aarch64_init_frag (fragS * fragP, int max_chars)
     }
 }

+#endif /* OBJ_ELF */
+
 /* Initialize the DWARF-2 unwind information for this procedure.  */

 void
@@ -8368,7 +8369,6 @@ tc_aarch64_frame_initial_instructions (void)
 {
   cfi_add_CFA_def_cfa (REG_SP, 0);
 }
-#endif /* OBJ_ELF */

 /* Convert REGNAME to a DWARF-2 register number.  */

@@ -8405,10 +8405,8 @@ tc_aarch64_regname_to_dw2regnum (char *regname)
 int
 aarch64_dwarf2_addr_size (void)
 {
-#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
   if (ilp32_p)
     return 4;
-#endif
   return bfd_arch_bits_per_address (stdoutput) / 8;
 }

@@ -9044,13 +9042,9 @@ 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().  */
@@ -9059,14 +9053,10 @@ 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;
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
-#endif
       /* Should always be exported to object file, see
    aarch64_force_relocation().  */
       gas_assert (!fixP->fx_done);
@@ -9135,13 +9125,9 @@ 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;
@@ -9284,7 +9270,6 @@ cons_fix_new_aarch64 (fragS * frag, int where, int size, expressionS * exp)
   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
 }

-#ifdef OBJ_ELF

 /* Implement md_after_parse_args.  This is the earliest time we need to decide
    ABI.  If no -mabi specified, the ABI will be decided by target triplet.  */
@@ -9302,6 +9287,7 @@ aarch64_after_parse_args (void)
     aarch64_abi = AARCH64_ABI_LP64;
 }

+#ifdef OBJ_ELF
 const char *
 elf64_aarch64_target_format (void)
 {
@@ -9324,6 +9310,12 @@ aarch64elf_frob_symbol (symbolS * symp, int *puntp)
 {
   elf_frob_symbol (symp, puntp);
 }
+#elif defined (OBJ_COFF)
+const char *
+coff_aarch64_target_format (void)
+{
+  return "pe-aarch64-little";
+}
 #endif

 /* MD interface: Finalization.  */
@@ -9639,11 +9631,7 @@ 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);
 }
@@ -10204,13 +10192,13 @@ aarch64_parse_arch (const char *str)
 }

 /* ABIs.  */
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 struct aarch64_option_abi_value_table
 {
   const char *name;
   enum aarch64_abi_type value;
 };

+#ifdef OBJ_ELF
 static const struct aarch64_option_abi_value_table aarch64_abis[] = {
   {"ilp32",      AARCH64_ABI_ILP32},
   {"lp64",    AARCH64_ABI_LP64},
@@ -10237,7 +10225,7 @@ aarch64_parse_abi (const char *str)
   as_bad (_("unknown abi `%s'\n"), str);
   return 0;
 }
-#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
+#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 ccc4a4c3f0c..aae1b64588c 100644
--- a/gas/config/tc-aarch64.h
+++ b/gas/config/tc-aarch64.h
@@ -59,9 +59,11 @@ struct aarch64_fix
   enum aarch64_opnd opnd;
 };

-#if defined OBJ_ELF
+#ifdef OBJ_ELF
 # define AARCH64_BI_ENDIAN
 # define TARGET_FORMAT elf64_aarch64_target_format ()
+#elif defined (OBJ_COFF)
+# define TARGET_FORMAT coff_aarch64_target_format ()
 #endif

 #define TC_FORCE_RELOCATION(FIX) aarch64_force_relocation (FIX)
@@ -202,17 +204,18 @@ struct aarch64_frag_type
 extern int aarch64_dwarf2_addr_size (void);
 #define DWARF2_ADDR_SIZE(bfd) aarch64_dwarf2_addr_size ()

-#ifdef OBJ_ELF
-# define obj_frob_symbol(sym, punt)   aarch64elf_frob_symbol ((sym), & (punt))
+#ifdef TE_ELF
+#define obj_frob_symbol(sym, punt) aarch64elf_frob_symbol ((sym), & (punt))
+#endif

-# define GLOBAL_OFFSET_TABLE_NAME  "_GLOBAL_OFFSET_TABLE_"
-# define TC_SEGMENT_INFO_TYPE      struct aarch64_segment_info_type
+#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)
+#define md_cons_align(nbytes)      mapping_state (MAP_DATA)

 enum mstate
 {
@@ -242,38 +245,6 @@ 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
-
 #if defined OBJ_ELF || defined OBJ_COFF

 # define EXTERN_FORCE_RELOC        1
@@ -287,6 +258,7 @@ struct aarch64_segment_info_type

 extern void aarch64_frag_align_code (int, int);
 extern const char * elf64_aarch64_target_format (void);
+extern const char * coff_aarch64_target_format (void);
 extern int aarch64_force_relocation (struct fix *);
 extern void aarch64_cleanup (void);
 extern void aarch64_start_line_hook (void);
@@ -302,13 +274,4 @@ extern void aarch64_handle_align (struct frag *);
 extern int tc_aarch64_regname_to_dw2regnum (char *regname);
 extern void tc_aarch64_frame_initial_instructions (void);

-#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
-
 #endif /* TC_AARCH64 */
--
2.32.0

________________________________
From: Tamar Christina <Tamar.Christina@arm.com>
Sent: Wednesday, December 29, 2021 6:38 AM
To: Jedidiah Thompson <wej22007@outlook.com>
Cc: binutils@sourceware.org <binutils@sourceware.org>
Subject: RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD


Hi Jedidiah,

Thanks for respinning the patch, a couple more comments below:

>
> From: Jedidiah Thompson <wej22007@outlook.com>
> Sent: Monday, December 27, 2021 5:07 PM
> To: Tamar Christina <Tamar.Christina@arm.com>
> Cc: binutils@sourceware.org
> Subject: Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
>
> Here is the updated patch:
>
> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -249,7 +249,12 @@ case "${targ}" in
>      ;;
>    aarch64-*-elf | aarch64-*-rtems* | aarch64-*-genode*)
>      targ_defvec=aarch64_elf64_le_vec
> -    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
> +    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
> +    want64=true
> +    ;;
> +  aarch64-*-pe)
> +    targ_defvec=aarch64_pei_le_vec
> +    targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
>      want64=true

64-bit PE is not an underscore platform, so you want targ_underscore=no here too.
Also you want the executable format not the image format as the default here. So
targ_defvec=aarch64_pe_le_vec instead of pei.

>      ;;
>    aarch64_be-*-elf)
> @@ -279,7 +284,7 @@ case "${targ}" in
>      ;;
>    aarch64-*-linux* | aarch64-*-netbsd*)
>      targ_defvec=aarch64_elf64_le_vec
> -    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
> +    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
>      want64=true
>      ;;
>    aarch64_be-*-linux* | aarch64_be-*-netbsd*)
> @@ -1534,3 +1539,9 @@ case "${targ_defvec} ${targ_selvecs}" in
>      targ_archs="$targ_archs bfd_k1om_arch"
>      ;;
>  esac
> +
> +if test x"$targ_defvec" = x"aarch64-pe"; then
> +  # 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"
> +fi

> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index cc7725483aa..811f3eedbaa 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

not sure I understand why these changes are needed. ilp32_p is based on the ABI and since
-mabi isn't defined for aarch64-*pe you can't ever really set it. So all of these and the below
should already be correct without the ifdefs.

That said the default ABI looks wrong, The default ABI will be set to AARCH64_ABI_LP64.
Since PE/Windos is IL32P64 you'll want a new ABI, AARCH64_ABI_IL32P64 and make that the default in
aarch64_after_parse_args moving that ouf of the ifdef OBJ_ELF.

You'll also want to change TARGET_FORMAT to set the default format for the BFD target.

>        S_SET_THREAD_LOCAL (fixP->fx_addsy);
>        /* Should always be exported to object file, see
>     aarch64_force_relocation().  */
> @@ -9055,10 +9059,14 @@ 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;
>        S_SET_THREAD_LOCAL (fixP->fx_addsy);
> +#endif
>        /* Should always be exported to object file, see
>     aarch64_force_relocation().  */
>        gas_assert (!fixP->fx_done);
> @@ -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);
>  }
> @@ -10188,6 +10204,7 @@ aarch64_parse_arch (const char *str)
>  }
>
>  /* ABIs.  */
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
>  struct aarch64_option_abi_value_table
>  {
>    const char *name;
> @@ -10220,6 +10237,7 @@ aarch64_parse_abi (const char *str)
>    as_bad (_("unknown abi `%s'\n"), str);
>    return 0;
>  }
> +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
>
>  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..ccc4a4c3f0c 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;
> +};
> +

Any reason you can't just remove the OBJ_ELF or include OBJ_COFF here?
This looks exactly the same code as the OBJ_ELF block and in principle
CFIs should be handled by BFD already.

>  #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

This looks like copied left over code from the Arm implementation, just delete the hunk.

Thanks,
Tamar


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

* RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
  2021-12-29 18:36       ` Jedidiah Thompson
  2021-12-29 21:29         ` Jedidiah Thompson
@ 2021-12-30 10:51         ` Tamar Christina
  1 sibling, 0 replies; 10+ messages in thread
From: Tamar Christina @ 2021-12-30 10:51 UTC (permalink / raw)
  To: Jedidiah Thompson; +Cc: binutils

Hi Jedidiah,

Thanks this looks good, but I can't approve it, you'll need a maintainer to but they're all away till early next year.

It looks like patch 2 is just undoing some changes made in patch 1 no? can you squash those two.

Lastly you'll also need to add some tests in the testsuite for this and add a NEWS entry.

When you reply with your squashed patch + test also CC the maintainers as listed here https://github.com/bminor/binutils-gdb/blob/master/binutils/MAINTAINERS#L60

Thanks!
Tamar

From: Jedidiah Thompson <wej22007@outlook.com>
Sent: Wednesday, December 29, 2021 6:37 PM
To: Tamar Christina <Tamar.Christina@arm.com>
Cc: binutils@sourceware.org
Subject: Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD

This patch makes AArch64 on PE recognize the fact that varying ABIs exists (plus the small change in config.bfd)
Note that a new ABI like you suggested has not been added yet; I will work on that next

From 5c82797beee422075b9dd55c231afe349447d293 Mon Sep 17 00:00:00 2001
From: Jedidiah Thompson <wej22007@outlook.com<mailto:wej22007@outlook.com>>
Date: Wed, 29 Dec 2021 13:34:26 -0500
Subject: [PATCH 2/2] Make aarch64 assember handle varying ABIs on PE

A new ABI should be created specially for Windows / PE, however, that is a larger task that will be handled seperatly
---
 bfd/config.bfd          |  5 ++--
 gas/config/obj-coff.h   |  3 ---
 gas/config/tc-aarch64.c | 42 +++++++++++-------------------
 gas/config/tc-aarch64.h | 57 ++++++++---------------------------------
 4 files changed, 28 insertions(+), 79 deletions(-)

diff --git a/bfd/config.bfd b/bfd/config.bfd
index d2ec4c4a38b..e9188870f6d 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -253,9 +253,10 @@ case "${targ}" in
     want64=true
     ;;
   aarch64-*-pe)
-    targ_defvec=aarch64_pei_le_vec
-    targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
+    targ_defvec=aarch64_pe_le_vec
+    targ_selvecs="aarch64_pei_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
     want64=true
+    targ_underscore=no
     ;;
   aarch64_be-*-elf)
     targ_defvec=aarch64_elf64_be_vec
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
index 5cb89f09d61..641db43ac6d 100644
--- a/gas/config/obj-coff.h
+++ b/gas/config/obj-coff.h
@@ -42,9 +42,6 @@

 #ifdef TC_AARCH64
 #include "coff/aarch64.h"
-#ifndef TARGET_FORMAT
-#define TARGET_FORMAT "pe-aarch64-little"
-#endif
 #endif

 #ifdef TC_PPC
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 811f3eedbaa..818d260148d 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -30,8 +30,8 @@

 #ifdef OBJ_ELF
 #include "elf/aarch64.h"
-#include "dw2gencfi.h"
 #endif
+#include "dw2gencfi.h"

 #include "dwarf2dbg.h"

@@ -61,6 +61,7 @@ static aarch64_instr_sequence *insn_sequence = NULL;
 #ifdef OBJ_ELF
 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"   */
 static symbolS *GOT_symbol;
+#endif

 /* Which ABI to use.  */
 enum aarch64_abi_type
@@ -85,7 +86,6 @@ static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
    64-bit model, in which the C int type is 32-bits but the C long type
    and all pointer types are 64-bit objects (LP64).  */
 #define ilp32_p     (aarch64_abi == AARCH64_ABI_ILP32)
-#endif

 enum vector_el_type
 {
@@ -2028,8 +2028,6 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED)
   input_line_pointer--;
   demand_empty_rest_of_line ();
 }
-
-#ifdef OBJ_ELF
 static void
 s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED)
 {
@@ -2038,6 +2036,7 @@ 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 +2110,8 @@ const pseudo_typeS md_pseudo_table[] = {
   {"arch", s_aarch64_arch, 0},
   {"arch_extension", s_aarch64_arch_extension, 0},
   {"inst", s_aarch64_inst, 0},
-#ifdef OBJ_ELF
   {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0},
+#ifdef OBJ_ELF
   {"tlsdescadd", s_tlsdescadd, 0},
   {"tlsdesccall", s_tlsdesccall, 0},
   {"tlsdescldr", s_tlsdescldr, 0},
@@ -8361,6 +8360,8 @@ aarch64_init_frag (fragS * fragP, int max_chars)
     }
 }

+#endif /* OBJ_ELF */
+
 /* Initialize the DWARF-2 unwind information for this procedure.  */

 void
@@ -8368,7 +8369,6 @@ tc_aarch64_frame_initial_instructions (void)
 {
   cfi_add_CFA_def_cfa (REG_SP, 0);
 }
-#endif /* OBJ_ELF */

 /* Convert REGNAME to a DWARF-2 register number.  */

@@ -8405,10 +8405,8 @@ tc_aarch64_regname_to_dw2regnum (char *regname)
 int
 aarch64_dwarf2_addr_size (void)
 {
-#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
   if (ilp32_p)
     return 4;
-#endif
   return bfd_arch_bits_per_address (stdoutput) / 8;
 }

@@ -9044,13 +9042,9 @@ 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().  */
@@ -9059,14 +9053,10 @@ 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;
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
-#endif
       /* Should always be exported to object file, see
    aarch64_force_relocation().  */
       gas_assert (!fixP->fx_done);
@@ -9135,13 +9125,9 @@ 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;
@@ -9284,7 +9270,6 @@ cons_fix_new_aarch64 (fragS * frag, int where, int size, expressionS * exp)
   fix_new_exp (frag, where, (int) size, exp, pcrel, type);
 }

-#ifdef OBJ_ELF

 /* Implement md_after_parse_args.  This is the earliest time we need to decide
    ABI.  If no -mabi specified, the ABI will be decided by target triplet.  */
@@ -9302,6 +9287,7 @@ aarch64_after_parse_args (void)
     aarch64_abi = AARCH64_ABI_LP64;
 }

+#ifdef OBJ_ELF
 const char *
 elf64_aarch64_target_format (void)
 {
@@ -9324,6 +9310,12 @@ aarch64elf_frob_symbol (symbolS * symp, int *puntp)
 {
   elf_frob_symbol (symp, puntp);
 }
+#elif defined (OBJ_COFF)
+const char *
+coff_aarch64_target_format (void)
+{
+  return "pe-aarch64-little";
+}
 #endif

 /* MD interface: Finalization.  */
@@ -9639,11 +9631,7 @@ 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);
 }
@@ -10204,13 +10192,13 @@ aarch64_parse_arch (const char *str)
 }

 /* ABIs.  */
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 struct aarch64_option_abi_value_table
 {
   const char *name;
   enum aarch64_abi_type value;
 };

+#ifdef OBJ_ELF
 static const struct aarch64_option_abi_value_table aarch64_abis[] = {
   {"ilp32",      AARCH64_ABI_ILP32},
   {"lp64",    AARCH64_ABI_LP64},
@@ -10237,7 +10225,7 @@ aarch64_parse_abi (const char *str)
   as_bad (_("unknown abi `%s'\n"), str);
   return 0;
 }
-#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
+#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 ccc4a4c3f0c..aae1b64588c 100644
--- a/gas/config/tc-aarch64.h
+++ b/gas/config/tc-aarch64.h
@@ -59,9 +59,11 @@ struct aarch64_fix
   enum aarch64_opnd opnd;
 };

-#if defined OBJ_ELF
+#ifdef OBJ_ELF
 # define AARCH64_BI_ENDIAN
 # define TARGET_FORMAT elf64_aarch64_target_format ()
+#elif defined (OBJ_COFF)
+# define TARGET_FORMAT coff_aarch64_target_format ()
 #endif

 #define TC_FORCE_RELOCATION(FIX) aarch64_force_relocation (FIX)
@@ -202,17 +204,18 @@ struct aarch64_frag_type
 extern int aarch64_dwarf2_addr_size (void);
 #define DWARF2_ADDR_SIZE(bfd) aarch64_dwarf2_addr_size ()

-#ifdef OBJ_ELF
-# define obj_frob_symbol(sym, punt)   aarch64elf_frob_symbol ((sym), & (punt))
+#ifdef TE_ELF
+#define obj_frob_symbol(sym, punt) aarch64elf_frob_symbol ((sym), & (punt))
+#endif

-# define GLOBAL_OFFSET_TABLE_NAME  "_GLOBAL_OFFSET_TABLE_"
-# define TC_SEGMENT_INFO_TYPE      struct aarch64_segment_info_type
+#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)
+#define md_cons_align(nbytes)      mapping_state (MAP_DATA)

 enum mstate
 {
@@ -242,38 +245,6 @@ 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
-
 #if defined OBJ_ELF || defined OBJ_COFF

 # define EXTERN_FORCE_RELOC        1
@@ -287,6 +258,7 @@ struct aarch64_segment_info_type

 extern void aarch64_frag_align_code (int, int);
 extern const char * elf64_aarch64_target_format (void);
+extern const char * coff_aarch64_target_format (void);
 extern int aarch64_force_relocation (struct fix *);
 extern void aarch64_cleanup (void);
 extern void aarch64_start_line_hook (void);
@@ -302,13 +274,4 @@ extern void aarch64_handle_align (struct frag *);
 extern int tc_aarch64_regname_to_dw2regnum (char *regname);
 extern void tc_aarch64_frame_initial_instructions (void);

-#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
-
 #endif /* TC_AARCH64 */
--
2.32.0

________________________________
From: Tamar Christina <Tamar.Christina@arm.com<mailto:Tamar.Christina@arm.com>>
Sent: Wednesday, December 29, 2021 6:38 AM
To: Jedidiah Thompson <wej22007@outlook.com<mailto:wej22007@outlook.com>>
Cc: binutils@sourceware.org<mailto:binutils@sourceware.org> <binutils@sourceware.org<mailto:binutils@sourceware.org>>
Subject: RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD


Hi Jedidiah,

Thanks for respinning the patch, a couple more comments below:

>
> From: Jedidiah Thompson <wej22007@outlook.com<mailto:wej22007@outlook.com>>
> Sent: Monday, December 27, 2021 5:07 PM
> To: Tamar Christina <Tamar.Christina@arm.com<mailto:Tamar.Christina@arm.com>>
> Cc: binutils@sourceware.org<mailto:binutils@sourceware.org>
> Subject: Re: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
>
> Here is the updated patch:
>
> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -249,7 +249,12 @@ case "${targ}" in
>      ;;
>    aarch64-*-elf | aarch64-*-rtems* | aarch64-*-genode*)
>      targ_defvec=aarch64_elf64_le_vec
> -    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
> +    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
> +    want64=true
> +    ;;
> +  aarch64-*-pe)
> +    targ_defvec=aarch64_pei_le_vec
> +    targ_selvecs="aarch64_pe_le_vec aarch64_elf64_le_vec arm_pe_le_vec arm_pei_le_vec"
>      want64=true

64-bit PE is not an underscore platform, so you want targ_underscore=no here too.
Also you want the executable format not the image format as the default here. So
targ_defvec=aarch64_pe_le_vec instead of pei.

>      ;;
>    aarch64_be-*-elf)
> @@ -279,7 +284,7 @@ case "${targ}" in
>      ;;
>    aarch64-*-linux* | aarch64-*-netbsd*)
>      targ_defvec=aarch64_elf64_le_vec
> -    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_vec"
> +    targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec"
>      want64=true
>      ;;
>    aarch64_be-*-linux* | aarch64_be-*-netbsd*)
> @@ -1534,3 +1539,9 @@ case "${targ_defvec} ${targ_selvecs}" in
>      targ_archs="$targ_archs bfd_k1om_arch"
>      ;;
>  esac
> +
> +if test x"$targ_defvec" = x"aarch64-pe"; then
> +  # 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"
> +fi

> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index cc7725483aa..811f3eedbaa 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

not sure I understand why these changes are needed. ilp32_p is based on the ABI and since
-mabi isn't defined for aarch64-*pe you can't ever really set it. So all of these and the below
should already be correct without the ifdefs.

That said the default ABI looks wrong, The default ABI will be set to AARCH64_ABI_LP64.
Since PE/Windos is IL32P64 you'll want a new ABI, AARCH64_ABI_IL32P64 and make that the default in
aarch64_after_parse_args moving that ouf of the ifdef OBJ_ELF.

You'll also want to change TARGET_FORMAT to set the default format for the BFD target.

>        S_SET_THREAD_LOCAL (fixP->fx_addsy);
>        /* Should always be exported to object file, see
>     aarch64_force_relocation().  */
> @@ -9055,10 +9059,14 @@ 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;
>        S_SET_THREAD_LOCAL (fixP->fx_addsy);
> +#endif
>        /* Should always be exported to object file, see
>     aarch64_force_relocation().  */
>        gas_assert (!fixP->fx_done);
> @@ -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);
>  }
> @@ -10188,6 +10204,7 @@ aarch64_parse_arch (const char *str)
>  }
>
>  /* ABIs.  */
> +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
>  struct aarch64_option_abi_value_table
>  {
>    const char *name;
> @@ -10220,6 +10237,7 @@ aarch64_parse_abi (const char *str)
>    as_bad (_("unknown abi `%s'\n"), str);
>    return 0;
>  }
> +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
>
>  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..ccc4a4c3f0c 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;
> +};
> +

Any reason you can't just remove the OBJ_ELF or include OBJ_COFF here?
This looks exactly the same code as the OBJ_ELF block and in principle
CFIs should be handled by BFD already.

>  #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

This looks like copied left over code from the Arm implementation, just delete the hunk.

Thanks,
Tamar

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

* RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
  2021-12-29 21:29         ` Jedidiah Thompson
@ 2021-12-30 11:00           ` Tamar Christina
  2021-12-30 13:54             ` Jedidiah Thompson
  0 siblings, 1 reply; 10+ messages in thread
From: Tamar Christina @ 2021-12-30 11:00 UTC (permalink / raw)
  To: Jedidiah Thompson; +Cc: binutils

Hi Jedidiah,

> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index 818d260148d..83226aa5fd2 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -32,7 +32,6 @@
>  #include "elf/aarch64.h"
>  #endif
>  #include "dw2gencfi.h"
> -
>  #include "dwarf2dbg.h"
>  
>  /* Types of processor to assemble for.  */
> @@ -68,7 +67,8 @@ enum aarch64_abi_type
>  {
>    AARCH64_ABI_NONE = 0,
>    AARCH64_ABI_LP64 = 1,
> -  AARCH64_ABI_ILP32 = 2
> +  AARCH64_ABI_ILP32 = 2,
> +  AARCH64_ABI_LLP64 = 3
>  };
>  
>  #ifndef DEFAULT_ARCH
> @@ -76,7 +76,9 @@ enum aarch64_abi_type
>  #endif
>  
>  /* DEFAULT_ARCH is initialized in gas/configure.tgt.  */
> +#ifdef OBJ_ELF
>  static const char *default_arch = DEFAULT_ARCH;
> +#endif
>  
>  /* AArch64 ABI for the output file.  */
>  static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
> @@ -86,6 +88,9 @@ static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
>     64-bit model, in which the C int type is 32-bits but the C long type
>     and all pointer types are 64-bit objects (LP64).  */
>  #define ilp32_p    (aarch64_abi == AARCH64_ABI_ILP32)
> +/* When non zero, C types int and long are 32 bit, 
> +   pointers, however are 64 bit */
> +#define llp64_p (aarch64_abi == AARCH64_ABI_LLP64)
>  
>  enum vector_el_type
>  {
> @@ -8407,6 +8412,8 @@ aarch64_dwarf2_addr_size (void)
>  {
>    if (ilp32_p)
>      return 4;
> +  else if (llp64_p)
> +    return 8;
>    return bfd_arch_bits_per_address (stdoutput) / 8;
>  }
>  
> @@ -9125,7 +9132,7 @@ 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().  */
> -      fixP->fx_r_type = (ilp32_p
> +      fixP->fx_r_type = ((ilp32_p || llp64_p)
>        ? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
>        : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
>        gas_assert (!fixP->fx_done);

Is this right? you still have full 64-bit addressing with llp64.

Thanks,
Tamar

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

* RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD
  2021-12-30 11:00           ` Tamar Christina
@ 2021-12-30 13:54             ` Jedidiah Thompson
  0 siblings, 0 replies; 10+ messages in thread
From: Jedidiah Thompson @ 2021-12-30 13:54 UTC (permalink / raw)
  To: Tamar Christina; +Cc: binutils

Probably not, I’ll correct it when I get to my computer.

Once that’s done, I’ll get all the patches in a form that is ready to be contributed!
From: Tamar Christina<mailto:Tamar.Christina@arm.com>
Sent: Thursday, December 30, 2021 6:01 AM
To: Jedidiah Thompson<mailto:wej22007@outlook.com>
Cc: binutils@sourceware.org<mailto:binutils@sourceware.org>
Subject: RE: [PATCH} Add aarch64-pe support to LD and GAS; refine support in BFD

Hi Jedidiah,

> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index 818d260148d..83226aa5fd2 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -32,7 +32,6 @@
>  #include "elf/aarch64.h"
>  #endif
>  #include "dw2gencfi.h"
> -
>  #include "dwarf2dbg.h"
>
>  /* Types of processor to assemble for.  */
> @@ -68,7 +67,8 @@ enum aarch64_abi_type
>  {
>    AARCH64_ABI_NONE = 0,
>    AARCH64_ABI_LP64 = 1,
> -  AARCH64_ABI_ILP32 = 2
> +  AARCH64_ABI_ILP32 = 2,
> +  AARCH64_ABI_LLP64 = 3
>  };
>
>  #ifndef DEFAULT_ARCH
> @@ -76,7 +76,9 @@ enum aarch64_abi_type
>  #endif
>
>  /* DEFAULT_ARCH is initialized in gas/configure.tgt.  */
> +#ifdef OBJ_ELF
>  static const char *default_arch = DEFAULT_ARCH;
> +#endif
>
>  /* AArch64 ABI for the output file.  */
>  static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
> @@ -86,6 +88,9 @@ static enum aarch64_abi_type aarch64_abi = AARCH64_ABI_NONE;
>     64-bit model, in which the C int type is 32-bits but the C long type
>     and all pointer types are 64-bit objects (LP64).  */
>  #define ilp32_p    (aarch64_abi == AARCH64_ABI_ILP32)
> +/* When non zero, C types int and long are 32 bit,
> +   pointers, however are 64 bit */
> +#define llp64_p (aarch64_abi == AARCH64_ABI_LLP64)
>
>  enum vector_el_type
>  {
> @@ -8407,6 +8412,8 @@ aarch64_dwarf2_addr_size (void)
>  {
>    if (ilp32_p)
>      return 4;
> +  else if (llp64_p)
> +    return 8;
>    return bfd_arch_bits_per_address (stdoutput) / 8;
>  }
>
> @@ -9125,7 +9132,7 @@ 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().  */
> -      fixP->fx_r_type = (ilp32_p
> +      fixP->fx_r_type = ((ilp32_p || llp64_p)
>        ? BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
>        : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC);
>        gas_assert (!fixP->fx_done);

Is this right? you still have full 64-bit addressing with llp64.

Thanks,
Tamar


^ 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).