public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-aarch64).
@ 2021-10-29 11:05 Tamar Christina
  2021-11-05 17:39 ` Tamar Christina
  2021-11-18  8:04 ` Nick Clifton
  0 siblings, 2 replies; 4+ messages in thread
From: Tamar Christina @ 2021-10-29 11:05 UTC (permalink / raw)
  To: binutils; +Cc: nd, Richard.Earnshaw, marcus.shawcroft

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

Hi All,

This adds support for efi-*-aarch64 by virtue of adding a new PEI target
pei-aarch64-little.  This is not a full target and only exists to support EFI
at this time.

This means that this target does not support relocation processing and is mostly
a container format.  This format has been added to elf based aarch64 targets
such that efi images can be made natively on Linux.

However this target is not valid for use with gas but only with objcopy.

With these changes the resulting file is recognized as an efi image by
third party tools:

>  pecli info hello.efi

Metadata
================================================================================
MD5:            598c32a778b0f0deebe977fef8578c4e
SHA1:           4580121edd5cb4dc40f51b28f171fd15250df84c
SHA256:         3154bd7cf42433d1c957f6bf55a17ad8c57ed41b29df2d485703349fd6ff1d5c
Imphash:
Size:           47561 bytes
Type:           PE32+ executable (EFI application) (stripped to external PDB), for MS Windows
Compile Time:   2021-10-29 00:00:00 (UTC - 0x0       )
Entry point:    0x2000 (section .text)

Sections
================================================================================
Name      RWX  VirtSize   VirtAddr   RawAddr   RawSize   Entropy  md5
.text     R-X  0x5bb0     0x2000     0x400     0x5c00      6.39 551fbc264256a3f387de8a891500ae0d
.reloc    R--  0xc        0x8000     0x6000    0x200       0.02 0c45f6d812d079821c1d54c09ab89e1d
.data     RW-  0x1d88     0x9000     0x6200    0x1e00      4.18 5d1137c09f01289dc62bf754f7290db3
.dynamic  RW-  0xf0       0xb000     0x8000    0x200       0.34 5c94ed3206f05a277e6f04fbf131f131
.rela     R--  0xe58      0xc000     0x8200    0x1000      1.87 8b5c6bc30f3acb7ca7bf2e6789d68519
.dynsym   R--  0x138      0xd000     0x9200    0x200       0.96 bdcf5101da51aadc663ca8859f88138c


Imports
================================================================================

Any magic number is based on the Microsoft PE specification [1].

[1] https://docs.microsoft.com/en-us/windows/win32/debug/pe-format

build on native hardware and regtested on
  aarch64-none-elf, aarch64-none-elf (32 bit host),
  aarch64-none-linux-gnu, aarch64-none-linux-gnu (32 bit host)

Cross-compiled and regtested on
  aarch64-none-linux-gnu, aarch64_be-none-linux-gnu

and no issues.

Ok for master?

Thanks,
Tamar

bfd/ChangeLog:

2021-10-29  Tamar Christina  <tamar.christina@arm.com>

	PR binutils/26206
	* .gitignore (pe-aarch64igen.c): New.
	* Makefile.am (pei-aarch64.lo, pe-aarch64igen.lo, pei-aarch64.c,
	pe-aarch64igen.c): Add support.
	* Makefile.in: Likewise.
	* bfd.c (bfd_get_sign_extend_vma): Add pei-aarch64-little.
	* coff-aarch64.c: New file.
	* coffcode.h (coff_set_arch_mach_hook, coff_set_flags,
	coff_write_object_contents) Add aarch64 (aarch64_pei_vec) support.
	* config.bfd: Likewise.
	* configure: Likewise.
	* configure.ac: Likewise.
	* libpei.h (GET_OPTHDR_IMAGE_BASE, PUT_OPTHDR_IMAGE_BASE,
	GET_OPTHDR_SIZE_OF_STACK_RESERVE, PUT_OPTHDR_SIZE_OF_STACK_RESERVE,
	GET_OPTHDR_SIZE_OF_STACK_COMMIT, PUT_OPTHDR_SIZE_OF_STACK_COMMIT,
	GET_OPTHDR_SIZE_OF_HEAP_RESERVE, PUT_OPTHDR_SIZE_OF_HEAP_RESERVE,
	GET_OPTHDR_SIZE_OF_HEAP_COMMIT, PUT_OPTHDR_SIZE_OF_HEAP_COMMIT,
	GET_PDATA_ENTRY, _bfd_peAArch64_bfd_copy_private_bfd_data_common,
	_bfd_peAArch64_bfd_copy_private_section_data,
	_bfd_peAArch64_get_symbol_info, _bfd_peAArch64_only_swap_filehdr_out,
	_bfd_peAArch64_print_private_bfd_data_common,
	_bfd_peAArch64i_final_link_postscript,
	_bfd_peAArch64i_only_swap_filehdr_out, _bfd_peAArch64i_swap_aouthdr_in,
	_bfd_peAArch64i_swap_aouthdr_out, _bfd_peAArch64i_swap_aux_in,
	_bfd_peAArch64i_swap_aux_out, _bfd_peAArch64i_swap_lineno_in,
	_bfd_peAArch64i_swap_lineno_out, _bfd_peAArch64i_swap_scnhdr_out,
	_bfd_peAArch64i_swap_sym_in, _bfd_peAArch64i_swap_sym_out,
	_bfd_peAArch64i_swap_debugdir_in, _bfd_peAArch64i_swap_debugdir_out,
	_bfd_peAArch64i_write_codeview_record,
	_bfd_peAArch64i_slurp_codeview_record,
	_bfd_peAArch64_print_ce_compressed_pdata): New.
	* peXXigen.c (_bfd_XXi_swap_aouthdr_in, _bfd_XXi_swap_aouthdr_out,
	pe_print_pdata, _bfd_XX_print_private_bfd_data_common, 
	_bfd_XX_bfd_copy_private_section_data, _bfd_XXi_final_link_postscript):
	Support COFF_WITH_peAArch64,
	* pei-aarch64.c: New file.
	* peicode.h (coff_swap_scnhdr_in, pe_ILF_build_a_bfd, pe_ILF_object_p):
	Support COFF_WITH_peAArch64.
	(jtab): Add dummy entry that traps.
	* targets.c (aarch64_pei_vec): New.

binutils/ChangeLog:

2021-10-29  Tamar Christina  <tamar.christina@arm.com>

	PR binutils/26206
	* NEWS: Add new support.
	* objcopy.c (convert_efi_target): Add efi-*-aarch64 support.
	* testsuite/binutils-all/aarch64/pei-aarch64-little.d: New test.
	* testsuite/binutils-all/aarch64/pei-aarch64-little.s: New test.

include/ChangeLog:

2021-10-29  Tamar Christina  <tamar.christina@arm.com>

	PR binutils/26206
	* coff/aarch64.h: New file.
	* coff/pe.h (IMAGE_FILE_MACHINE_ARM64): New.

--- inline copy of patch -- 
diff --git a/bfd/.gitignore b/bfd/.gitignore
index 0a5530d128a7204d4619ea9e95430ae37d532a81..d4f7423111e5be6009abc685539af0c2e58e9045 100644
--- a/bfd/.gitignore
+++ b/bfd/.gitignore
@@ -10,6 +10,7 @@
 /peigen.c
 /pepigen.c
 /pex64igen.c
+/pe-aarch64igen.c
 /stmp-bfd-h
 /targmatch.h
 
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 097177bae5c36c734a50884ca6550cd38877b4fa..7777f733702c09b441bc591daa5b8c3d9ab2abd7 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -575,8 +575,10 @@ BFD64_BACKENDS = \
 	pe-x86_64.lo \
 	pei-ia64.lo \
 	pei-x86_64.lo \
+	pei-aarch64lo \
 	pepigen.lo \
 	pex64igen.lo \
+	pe-aarch64igen.lo \
 	vms-alpha.lo
 
 BFD64_BACKENDS_CFILES = \
@@ -615,6 +617,7 @@ BFD64_BACKENDS_CFILES = \
 	pe-x86_64.c \
 	pei-ia64.c \
 	pei-x86_64.c \
+	pei-aarch64.c \
 	vms-alpha.c
 
 OPTIONAL_BACKENDS = \
@@ -673,7 +676,7 @@ BUILD_CFILES = \
 	elf32-ia64.c elf64-ia64.c \
 	elf32-loongarch.c elf64-loongarch.c \
 	elf32-riscv.c elf64-riscv.c \
-	peigen.c pepigen.c pex64igen.c
+	peigen.c pepigen.c pex64igen.c pe-aarch64igen.c
 
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 
@@ -877,6 +880,10 @@ pex64igen.c: peXXigen.c
 	echo "#line 1 \"peXXigen.c\"" > $@
 	$(SED) -e s/XX/pex64/g < $< >> $@
 
+pe-aarch64igen.c: peXXigen.c
+	echo "#line 1 \"peXXigen.c\"" > $@
+	$(SED) -e s/XX/peAArch64/g < $< >> $@
+
 BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/diagnostics.h
 LOCAL_H_DEPS= libbfd.h sysdep.h config.h
 $(BFD32_LIBS) \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index a76b653247fd5b7d1fc8991ac5f8ad7fbb5eaba3..b243151fea350032c6cb90f1ec1f359bdba589f5 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1002,8 +1002,10 @@ BFD64_BACKENDS = \
 	pe-x86_64.lo \
 	pei-ia64.lo \
 	pei-x86_64.lo \
+	pei-aarch64.lo \
 	pepigen.lo \
 	pex64igen.lo \
+	pe-aarch64igen.lo \
 	vms-alpha.lo
 
 BFD64_BACKENDS_CFILES = \
@@ -1042,6 +1044,7 @@ BFD64_BACKENDS_CFILES = \
 	pe-x86_64.c \
 	pei-ia64.c \
 	pei-x86_64.c \
+	pei-aarch64.c \
 	vms-alpha.c
 
 OPTIONAL_BACKENDS = \
@@ -1099,7 +1102,7 @@ BUILD_CFILES = \
 	elf32-ia64.c elf64-ia64.c \
 	elf32-loongarch.c elf64-loongarch.c \
 	elf32-riscv.c elf64-riscv.c \
-	peigen.c pepigen.c pex64igen.c
+	peigen.c pepigen.c pex64igen.c pe-aarch64igen.c
 
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
@@ -1562,9 +1565,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-mcore.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-sh.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-x86_64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-aarch64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peigen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pepigen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pex64igen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-aarch64igen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppcboot.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reloc.Plo@am__quote@
@@ -2010,6 +2015,11 @@ pepigen.c : peXXigen.c
 pex64igen.c: peXXigen.c
 	echo "#line 1 \"peXXigen.c\"" > $@
 	$(SED) -e s/XX/pex64/g < $< >> $@
+
+pe-aarch64igen.c: peXXigen.c
+	echo "#line 1 \"peXXigen.c\"" > $@
+	$(SED) -e s/XX/peAArch64/g < $< >> $@
+
 $(BFD32_LIBS) \
  $(BFD64_LIBS) \
  $(ALL_MACHINES) \
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 421f4f19fd60daefe38ded6424b67749c33cda21..5c3797de3052b5715c6cb222599dbf5b2bd2e8f9 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1738,6 +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, "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
new file mode 100644
index 0000000000000000000000000000000000000000..a9bc417fae8b7c353f1127cf8ec17978079d4ff2
--- /dev/null
+++ b/bfd/coff-aarch64.c
@@ -0,0 +1,166 @@
+/* BFD back-end for AArch64 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.  */
+
+
+#ifndef COFF_WITH_peAArch64
+#define COFF_WITH_peAArch64
+#endif
+
+/* Note we have to make sure not to include headers twice.
+   Not all headers are wrapped in #ifdef guards, so we define
+   PEI_HEADERS to prevent double including here.  */
+#ifndef 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 "libiberty.h"
+#endif
+
+#include "libcoff.h"
+
+/* The page size is a guess based on ELF.  */
+
+#define COFF_PAGE_SIZE 0x1000
+
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET true
+#endif
+
+/* Currently we don't handle any relocations.  */
+static reloc_howto_type pe_aarch64_std_reloc_howto[] =
+  {
+
+  };
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER  2
+#define COFF_PAGE_SIZE			      0x1000
+
+#ifndef NUM_ELEM
+#define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
+#endif
+
+#define NUM_RELOCS NUM_ELEM (pe_aarch64_std_reloc_howto)
+
+#define RTYPE2HOWTO(cache_ptr, dst)             \
+  (cache_ptr)->howto = NULL
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata      NULL
+#endif
+
+/* Return TRUE if this relocation should
+   appear in the output .reloc section.  */
+
+static bool
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
+            reloc_howto_type * howto)
+{
+  return !howto->pc_relative;
+}
+
+#include "coffcode.h"
+
+/* Target vectors.  */
+const bfd_target
+#ifdef TARGET_SYM
+  TARGET_SYM =
+#else
+  aarch64_pei_vec =
+#endif
+{
+#ifdef TARGET_NAME
+  TARGET_NAME,
+#else
+ "pei-aarch64-little",			/* Name.  */
+#endif
+  bfd_target_coff_flavour,
+  BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */
+  BFD_ENDIAN_LITTLE,		/* Header byte order is little.  */
+
+  (HAS_RELOC | EXEC_P		/* Object flags.  */
+   | HAS_LINENO | HAS_DEBUG
+   | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
+
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
+#if defined(COFF_WITH_PE)
+   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
+#endif
+   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
+
+#ifdef TARGET_UNDERSCORE
+  TARGET_UNDERSCORE,		/* Leading underscore.  */
+#else
+  0,				/* Leading underscore.  */
+#endif
+  '/',				/* Ar_pad_char.  */
+  15,				/* Ar_max_namelen.  */
+  0,				/* match priority.  */
+  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
+
+     /* Data conversion functions.  */
+     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
+     /* Header conversion functions.  */
+     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
+
+  /* Note that we allow an object file to be treated as a core file as well.  */
+  {				/* bfd_check_format.  */
+    _bfd_dummy_target,
+    coff_object_p,
+    bfd_generic_archive_p,
+    coff_object_p
+  },
+  {				/* bfd_set_format.  */
+    _bfd_bool_bfd_false_error,
+    coff_mkobject,
+    _bfd_generic_mkarchive,
+    _bfd_bool_bfd_false_error
+  },
+  {				/* bfd_write_contents.  */
+    _bfd_bool_bfd_false_error,
+    coff_write_object_contents,
+    _bfd_write_archive_contents,
+    _bfd_bool_bfd_false_error
+  },
+
+  BFD_JUMP_TABLE_GENERIC (coff),
+  BFD_JUMP_TABLE_COPY (coff),
+  BFD_JUMP_TABLE_CORE (_bfd_nocore),
+  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+  BFD_JUMP_TABLE_SYMBOLS (coff),
+  BFD_JUMP_TABLE_RELOCS (coff),
+  BFD_JUMP_TABLE_WRITE (coff),
+  BFD_JUMP_TABLE_LINK (coff),
+  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+  NULL,
+
+  COFF_SWAP_TABLE
+};
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 7967cedf918b086a129c1c918af6520b29ab2034..86688d31cdb0a4809b7fc01079d16e87573dd56f 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -2221,6 +2221,12 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
 	}
       break;
 #endif
+#ifdef AARCH64MAGIC
+    case AARCH64MAGIC:
+      arch = bfd_arch_aarch64;
+      machine = internal_f->f_flags & F_AARCH64_ARCHITECTURE_MASK;
+      break;
+#endif
 #ifdef Z80MAGIC
     case Z80MAGIC:
       arch = bfd_arch_z80;
@@ -2777,6 +2783,12 @@ coff_set_flags (bfd * abfd,
       return true;
 #endif
 
+#ifdef AARCH64MAGIC
+    case bfd_arch_aarch64:
+      * magicp = AARCH64MAGIC;
+      return true;
+#endif
+
 #ifdef ARMMAGIC
     case bfd_arch_arm:
 #ifdef ARM_WINCE
@@ -3872,7 +3884,7 @@ coff_write_object_contents (bfd * abfd)
     internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
 #endif
 
-#ifndef COFF_WITH_pex64
+#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
 #ifdef COFF_WITH_PE
   internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;
 #else
@@ -3921,6 +3933,11 @@ coff_write_object_contents (bfd * abfd)
     internal_a.magic = ZMAGIC;
 #endif
 
+#if defined(AARCH64)
+#define __A_MAGIC_SET__
+    internal_a.magic = ZMAGIC;
+#endif
+
 #if defined MCORE_PE
 #define __A_MAGIC_SET__
     internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 3cf322713334cfdeaebc671f48fd321558a4f279..776918253ef11140df94042b379789e6f7b1e598 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -248,7 +248,7 @@ 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"
+    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"
     want64=true
     ;;
   aarch64_be-*-elf)
@@ -278,7 +278,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"
+    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"
     want64=true
     ;;
   aarch64_be-*-linux* | aarch64_be-*-netbsd*)
diff --git a/bfd/configure b/bfd/configure
index 58449ee8a608e3f3ac1d4ad376992d41f87f404e..5741e039a4fed386d826ad4910e1fd029bd37f23 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -13257,6 +13257,7 @@ 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 ;;
     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/configure.ac b/bfd/configure.ac
index 50ba391fff3988717a7760489508ec0d388459b5..1fadfd7d91ed7ead6b04be2173d6c596fb4af221 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -436,6 +436,7 @@ 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 ;;
     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/libpei.h b/bfd/libpei.h
index 4de0c9fd048ac1dc9cf6e4ce0075bc95e610cbd6..26589e8e520f8ee9ab752822e76964a8f0e2979c 100644
--- a/bfd/libpei.h
+++ b/bfd/libpei.h
@@ -275,6 +275,41 @@
 #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
+#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_32
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common	_bfd_peAArch64_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data		_bfd_peAArch64_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info				_bfd_peAArch64_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out			_bfd_peAArch64_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common		_bfd_peAArch64_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript			_bfd_peAArch64i_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out			_bfd_peAArch64i_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in			_bfd_peAArch64i_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out			_bfd_peAArch64i_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in				_bfd_peAArch64i_swap_aux_in
+#define _bfd_XXi_swap_aux_out				_bfd_peAArch64i_swap_aux_out
+#define _bfd_XXi_swap_lineno_in				_bfd_peAArch64i_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out			_bfd_peAArch64i_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out			_bfd_peAArch64i_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in				_bfd_peAArch64i_swap_sym_in
+#define _bfd_XXi_swap_sym_out				_bfd_peAArch64i_swap_sym_out
+#define _bfd_XXi_swap_debugdir_in			_bfd_peAArch64i_swap_debugdir_in
+#define _bfd_XXi_swap_debugdir_out			_bfd_peAArch64i_swap_debugdir_out
+#define _bfd_XXi_write_codeview_record			_bfd_peAArch64i_write_codeview_record
+#define _bfd_XXi_slurp_codeview_record			_bfd_peAArch64i_slurp_codeview_record
+
 #else /* !COFF_WITH_pep */
 
 #define GET_OPTHDR_IMAGE_BASE H_GET_32
@@ -369,5 +404,6 @@ bool _bfd_XX_bfd_copy_private_section_data
 bool _bfd_pe_print_ce_compressed_pdata (bfd *, void *);
 bool _bfd_pe64_print_ce_compressed_pdata (bfd *, void *);
 bool _bfd_pex64_print_ce_compressed_pdata (bfd *, void *);
+bool _bfd_peAArch64_print_ce_compressed_pdata (bfd *, void *);
 bool _bfd_pep_print_ce_compressed_pdata (bfd *, void *);
 
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index c41c3299277846875ee7eca9ca00e530b2683d61..1bfd6c89f1943fe0cf4155111d55b511be3dcc7b 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -60,8 +60,9 @@
    on this code has a chance of getting something accomplished without
    wasting too much time.  */
 
-/* This expands into COFF_WITH_pe, COFF_WITH_pep, or COFF_WITH_pex64
-   depending on whether we're compiling for straight PE or PE+.  */
+/* This expands into COFF_WITH_pe, COFF_WITH_pep, COFF_WITH_pex64 or
+   COFF_WITH_peAArch64 depending on whether we're compiling for straight
+   PE or PE+.  */
 #define COFF_WITH_XX
 
 #include "sysdep.h"
@@ -83,6 +84,8 @@
 # include "coff/x86_64.h"
 #elif defined COFF_WITH_pep
 # include "coff/ia64.h"
+#elif defined COFF_WITH_peAArch64
+# include "coff/aarch64.h"
 #else
 # include "coff/i386.h"
 #endif
@@ -92,7 +95,7 @@
 #include "libpei.h"
 #include "safe-ctype.h"
 
-#if defined COFF_WITH_pep || defined COFF_WITH_pex64
+#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64
 # undef AOUTSZ
 # define AOUTSZ		PEPAOUTSZ
 # define PEAOUTHDR	PEPAOUTHDR
@@ -469,7 +472,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   aouthdr_int->text_start =
     GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   /* PE32+ does not have data_start member!  */
   aouthdr_int->data_start =
     GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
@@ -555,7 +558,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   if (aouthdr_int->entry)
     {
       aouthdr_int->entry += a->ImageBase;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_int->entry &= 0xffffffff;
 #endif
     }
@@ -563,12 +566,12 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   if (aouthdr_int->tsize)
     {
       aouthdr_int->text_start += a->ImageBase;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_int->text_start &= 0xffffffff;
 #endif
     }
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   /* PE32+ does not have data_start member!  */
   if (aouthdr_int->dsize)
     {
@@ -628,7 +631,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->tsize)
     {
       aouthdr_in->text_start -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_in->text_start &= 0xffffffff;
 #endif
     }
@@ -636,7 +639,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->dsize)
     {
       aouthdr_in->data_start -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_in->data_start &= 0xffffffff;
 #endif
     }
@@ -644,7 +647,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->entry)
     {
       aouthdr_in->entry -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_in->entry &= 0xffffffff;
 #endif
     }
@@ -748,7 +751,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
 			  aouthdr_out->standard.text_start);
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   /* PE32+ does not have data_start member!  */
   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
 			  aouthdr_out->standard.data_start);
@@ -1800,7 +1803,7 @@ pe_print_edata (bfd * abfd, void * vfile)
 static bool
 pe_print_pdata (bfd * abfd, void * vfile)
 {
-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
 # define PDATA_ROW_SIZE	(3 * 8)
 #else
 # define PDATA_ROW_SIZE	(5 * 4)
@@ -1827,7 +1830,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
 
   fprintf (file,
 	   _("\nThe Function Table (interpreted .pdata section contents)\n"));
-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   fprintf (file,
 	   _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
 #else
@@ -1864,7 +1867,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
       bfd_vma eh_handler;
       bfd_vma eh_data;
       bfd_vma prolog_end_addr;
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       int em_data;
 #endif
 
@@ -1882,7 +1885,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
 	/* We are probably into the padding of the section now.  */
 	break;
 
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
 #endif
       eh_handler &= ~(bfd_vma) 0x3;
@@ -1893,7 +1896,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
       bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, eh_handler);
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       fputc (' ', file);
       bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, prolog_end_addr);
@@ -2784,7 +2787,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
   fprintf (file, "\nBaseOfCode\t\t");
   bfd_fprintf_vma (abfd, file, i->BaseOfCode);
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   /* PE32+ does not have BaseOfData member!  */
   fprintf (file, "\nBaseOfData\t\t");
   bfd_fprintf_vma (abfd, file, i->BaseOfData);
@@ -3085,7 +3088,7 @@ _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
   coff_get_symbol_info (abfd, symbol, ret);
 }
 
-#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64) && defined(COFF_WITH_peAArch64)
 static int
 sort_x64_pdata (const void *l, const void *r)
 {
@@ -4504,7 +4507,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 	the TLS data directory consists of 4 pointers, followed
 	by two 4-byte integer. This implies that the total size
 	is different for 32-bit and 64-bit executables.  */
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
 #else
       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
@@ -4513,7 +4516,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 
 /* If there is a .pdata section and we have linked pdata finally, we
      need to sort the entries ascending.  */
-#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64) && defined(COFF_WITH_peAArch64)
   {
     asection *sec = bfd_get_section_by_name (abfd, ".pdata");
 
diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c
new file mode 100644
index 0000000000000000000000000000000000000000..99326d1612655408f1b5ceea7a013e1768083498
--- /dev/null
+++ b/bfd/pei-aarch64.c
@@ -0,0 +1,75 @@
+/* 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_pei_vec
+#define TARGET_NAME		"pei-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
+
+#define COFF_IMAGE_WITH_PE
+/* 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/peicode.h b/bfd/peicode.h
index 41955975cdc621df3f53165a934a0d999140f09e..1e8ed803edc6e269eb84c08007eb0ce568d75a16 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -231,7 +231,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
     {
       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
       /* Do not cut upper 32-bits for 64-bit vma.  */
-#ifndef COFF_WITH_pex64
+#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       scnhdr_int->s_vaddr &= 0xffffffff;
 #endif
     }
@@ -738,6 +738,16 @@ static const jump_table jtab[] =
   },
 #endif
 
+#ifdef AARCH64MAGIC
+/* We don't currently support jumping to DLLs, so if
+   someone does try emit a runtime trap.  Through UDF #0.  */
+  { AARCH64MAGIC,
+    { 0x00, 0x00, 0x00, 0x00 },
+    4, 0
+  },
+
+#endif
+
 #ifdef  ARMPEMAGIC
   { ARMPEMAGIC,
     { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
@@ -910,7 +920,7 @@ pe_ILF_build_a_bfd (bfd *	    abfd,
 	/* See PR 20907 for a reproducer.  */
 	goto error_return;
 
-#ifdef COFF_WITH_pex64
+#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       ((unsigned int *) id4->contents)[0] = ordinal;
       ((unsigned int *) id4->contents)[1] = 0x80000000;
       ((unsigned int *) id5->contents)[0] = ordinal;
@@ -1206,6 +1216,12 @@ pe_ILF_object_p (bfd * abfd)
 #endif
       break;
 
+    case IMAGE_FILE_MACHINE_ARM64:
+#ifdef AARCH64MAGIC
+      magic = AARCH64MAGIC;
+#endif
+      break;
+
     case IMAGE_FILE_MACHINE_THUMB:
 #ifdef THUMBPEMAGIC
       {
diff --git a/bfd/targets.c b/bfd/targets.c
index 8f5abb174e2dfecad62008b68f381d89b423576d..672dc2bb1a4d5643f84577d81d4c9cebc14429d9 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -679,6 +679,7 @@ 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 alpha_ecoff_le_vec;
 extern const bfd_target alpha_elf64_vec;
 extern const bfd_target alpha_elf64_fbsd_vec;
@@ -993,6 +994,7 @@ static const bfd_target * const _bfd_target_vector[] =
 	&aarch64_elf64_le_vec,
 	&aarch64_elf64_le_cloudabi_vec,
 	&aarch64_mach_o_vec,
+	&aarch64_pei_vec,
 #endif
 
 #ifdef BFD64
diff --git a/binutils/NEWS b/binutils/NEWS
index e6977b650db6c70cce6efeba43fce7435519099e..994546330f95ccc3b859ffb17388b2cc5ec6a653 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -2,6 +2,9 @@
 
 * Add support for the LoongArch instruction set.
 
+* Support for efi-app-aarch64, efi-rtdrv-aarch64 and efi-bsdrv-aarch64 has been
+  added to objcopy in order to enable UEFI development using binutils.
+
 Changes in 2.37:
 
 * The readelf tool has a new command line option which can be used to specify
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 0e7400fe4cb7046fa704f207816616e623de65af..458a6d96cccbeb154f95e5ba54734b956d14f879 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -4996,6 +4996,13 @@ convert_efi_target (char *efi)
       /* Change x86_64 to x86-64.  */
       efi[7] = '-';
     }
+  else if (strcmp (efi + 4, "aarch64") == 0)
+    {
+      /* Change aarch64 to aarch64-little.  */
+      efi = (char *) xrealloc (efi, strlen (efi) + 7);
+      char *t = "aarch64-little";
+      strcpy (efi + 4, t);
+    }
 }
 
 /* Allocate and return a pointer to a struct section_add, initializing the
diff --git a/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
new file mode 100644
index 0000000000000000000000000000000000000000..0957c985359c049adb4f085a94ddc4ff03c91794
--- /dev/null
+++ b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
@@ -0,0 +1,16 @@
+#skip: aarch64_be-*-*
+#ld: -e0
+#PROG: objcopy
+#objcopy: -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* -j .reloc --target=efi-app-aarch64
+#objdump: -h -f
+#name: Check if efi app format is recognized
+
+.*:     file format pei-aarch64-little
+architecture: aarch64, flags 0x00000132:
+EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
+start address 0x0000000000000000
+
+Sections:
+Idx Name          Size      VMA               LMA               File off  Algn
+  0 \.text         00000030  0000000000400000  0000000000400000  00000200  2\*\*2
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
diff --git a/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
new file mode 100644
index 0000000000000000000000000000000000000000..dafc5fa47f9713b541a8d252748f9621affce5fc
--- /dev/null
+++ b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
@@ -0,0 +1,42 @@
+	.arch armv8-a
+	.text
+	.align	2
+	.global	foo
+	.type	foo, %function
+foo:
+.LFB0:
+	.cfi_startproc
+	sub	sp, sp, #16
+	.cfi_def_cfa_offset 16
+	str	w0, [sp, 12]
+	ldr	w0, [sp, 12]
+	mul	w0, w0, w0
+	add	sp, sp, 16
+	.cfi_def_cfa_offset 0
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+	.align	2
+	.global	main
+	.type	main, %function
+main:
+.LFB1:
+	.cfi_startproc
+	stp	x29, x30, [sp, -16]!
+	.cfi_def_cfa_offset 16
+	.cfi_offset 29, -16
+	.cfi_offset 30, -8
+	mov	x29, sp
+	mov	w0, 5
+	bl	foo
+	ldp	x29, x30, [sp], 16
+	.cfi_restore 30
+	.cfi_restore 29
+	.cfi_def_cfa_offset 0
+	ret
+	.cfi_endproc
+.LFE1:
+	.size	main, .-main
+	.ident	"GCC: (fsf-trunk.2870) 12.0.0 20210930 (experimental)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/include/coff/aarch64.h b/include/coff/aarch64.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c21f0d6cfdac4cb0debbee60030226fa70106d2
--- /dev/null
+++ b/include/coff/aarch64.h
@@ -0,0 +1,63 @@
+/* AArch64 COFF support for BFD.
+   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.  */
+
+#define COFFAARCH64 1
+
+#define L_LNNO_SIZE 2
+#define INCLUDE_COMDAT_FIELDS_IN_AUXENT
+#include "coff/external.h"
+
+#define F_AARCH64_ARCHITECTURE_MASK	(0x4000)
+
+#define	AARCH64MAGIC	0xaa64  /* From Microsoft specification. */
+
+#undef  BADMAG
+#define BADMAG(x) ((x).f_magic != AARCH64MAGIC)
+#define AARCH64         1                 /* Customize coffcode.h.  */
+
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
+
+#define OMAGIC          0404    /* Object files, eg as output.  */
+#define ZMAGIC          IMAGE_NT_OPTIONAL_HDR64_MAGIC    /* Demand load format, eg normal ld output 0x10b.  */
+#define STMAGIC		0401	/* Target shlib.  */
+#define SHMAGIC		0443	/* Host   shlib.  */
+
+/* define some NT default values */
+/*  #define NT_IMAGE_BASE        0x400000 moved to internal.h */
+#define NT_SECTION_ALIGNMENT 0x1000
+#define NT_FILE_ALIGNMENT    0x200
+#define NT_DEF_RESERVE       0x100000
+#define NT_DEF_COMMIT        0x1000
+
+/* We use the .rdata section to hold read only data.  */
+#define _LIT	".rdata"
+
+/********************** RELOCATION DIRECTIVES **********************/
+struct external_reloc
+{
+  char r_vaddr[4];
+  char r_symndx[4];
+  char r_type[2];
+  char r_offset[4];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 14
+
+#define ARM_NOTE_SECTION ".note"
diff --git a/include/coff/pe.h b/include/coff/pe.h
index 9e1ea4b5aa47b8278a0e7a88fad2db5dd8bc9fc5..558cf0e1b86f008f613d107bc72368b3811143ee 100644
--- a/include/coff/pe.h
+++ b/include/coff/pe.h
@@ -137,6 +137,7 @@
 #define IMAGE_FILE_MACHINE_AM33              0x01d3
 #define IMAGE_FILE_MACHINE_AMD64             0x8664
 #define IMAGE_FILE_MACHINE_ARM               0x01c0
+#define IMAGE_FILE_MACHINE_ARM64             0xaa64
 #define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
 #define IMAGE_FILE_MACHINE_CEE               0xc0ee
 #define IMAGE_FILE_MACHINE_CEF               0x0cef


-- 

[-- Attachment #2: rb14950.patch --]
[-- Type: text/x-diff, Size: 35488 bytes --]

diff --git a/bfd/.gitignore b/bfd/.gitignore
index 0a5530d128a7204d4619ea9e95430ae37d532a81..d4f7423111e5be6009abc685539af0c2e58e9045 100644
--- a/bfd/.gitignore
+++ b/bfd/.gitignore
@@ -10,6 +10,7 @@
 /peigen.c
 /pepigen.c
 /pex64igen.c
+/pe-aarch64igen.c
 /stmp-bfd-h
 /targmatch.h
 
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 097177bae5c36c734a50884ca6550cd38877b4fa..7777f733702c09b441bc591daa5b8c3d9ab2abd7 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -575,8 +575,10 @@ BFD64_BACKENDS = \
 	pe-x86_64.lo \
 	pei-ia64.lo \
 	pei-x86_64.lo \
+	pei-aarch64lo \
 	pepigen.lo \
 	pex64igen.lo \
+	pe-aarch64igen.lo \
 	vms-alpha.lo
 
 BFD64_BACKENDS_CFILES = \
@@ -615,6 +617,7 @@ BFD64_BACKENDS_CFILES = \
 	pe-x86_64.c \
 	pei-ia64.c \
 	pei-x86_64.c \
+	pei-aarch64.c \
 	vms-alpha.c
 
 OPTIONAL_BACKENDS = \
@@ -673,7 +676,7 @@ BUILD_CFILES = \
 	elf32-ia64.c elf64-ia64.c \
 	elf32-loongarch.c elf64-loongarch.c \
 	elf32-riscv.c elf64-riscv.c \
-	peigen.c pepigen.c pex64igen.c
+	peigen.c pepigen.c pex64igen.c pe-aarch64igen.c
 
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 
@@ -877,6 +880,10 @@ pex64igen.c: peXXigen.c
 	echo "#line 1 \"peXXigen.c\"" > $@
 	$(SED) -e s/XX/pex64/g < $< >> $@
 
+pe-aarch64igen.c: peXXigen.c
+	echo "#line 1 \"peXXigen.c\"" > $@
+	$(SED) -e s/XX/peAArch64/g < $< >> $@
+
 BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/diagnostics.h
 LOCAL_H_DEPS= libbfd.h sysdep.h config.h
 $(BFD32_LIBS) \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index a76b653247fd5b7d1fc8991ac5f8ad7fbb5eaba3..b243151fea350032c6cb90f1ec1f359bdba589f5 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1002,8 +1002,10 @@ BFD64_BACKENDS = \
 	pe-x86_64.lo \
 	pei-ia64.lo \
 	pei-x86_64.lo \
+	pei-aarch64.lo \
 	pepigen.lo \
 	pex64igen.lo \
+	pe-aarch64igen.lo \
 	vms-alpha.lo
 
 BFD64_BACKENDS_CFILES = \
@@ -1042,6 +1044,7 @@ BFD64_BACKENDS_CFILES = \
 	pe-x86_64.c \
 	pei-ia64.c \
 	pei-x86_64.c \
+	pei-aarch64.c \
 	vms-alpha.c
 
 OPTIONAL_BACKENDS = \
@@ -1099,7 +1102,7 @@ BUILD_CFILES = \
 	elf32-ia64.c elf64-ia64.c \
 	elf32-loongarch.c elf64-loongarch.c \
 	elf32-riscv.c elf64-riscv.c \
-	peigen.c pepigen.c pex64igen.c
+	peigen.c pepigen.c pex64igen.c pe-aarch64igen.c
 
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
@@ -1562,9 +1565,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-mcore.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-sh.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-x86_64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-aarch64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peigen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pepigen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pex64igen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-aarch64igen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppcboot.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reloc.Plo@am__quote@
@@ -2010,6 +2015,11 @@ pepigen.c : peXXigen.c
 pex64igen.c: peXXigen.c
 	echo "#line 1 \"peXXigen.c\"" > $@
 	$(SED) -e s/XX/pex64/g < $< >> $@
+
+pe-aarch64igen.c: peXXigen.c
+	echo "#line 1 \"peXXigen.c\"" > $@
+	$(SED) -e s/XX/peAArch64/g < $< >> $@
+
 $(BFD32_LIBS) \
  $(BFD64_LIBS) \
  $(ALL_MACHINES) \
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 421f4f19fd60daefe38ded6424b67749c33cda21..5c3797de3052b5715c6cb222599dbf5b2bd2e8f9 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1738,6 +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, "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
new file mode 100644
index 0000000000000000000000000000000000000000..a9bc417fae8b7c353f1127cf8ec17978079d4ff2
--- /dev/null
+++ b/bfd/coff-aarch64.c
@@ -0,0 +1,166 @@
+/* BFD back-end for AArch64 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.  */
+
+
+#ifndef COFF_WITH_peAArch64
+#define COFF_WITH_peAArch64
+#endif
+
+/* Note we have to make sure not to include headers twice.
+   Not all headers are wrapped in #ifdef guards, so we define
+   PEI_HEADERS to prevent double including here.  */
+#ifndef 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 "libiberty.h"
+#endif
+
+#include "libcoff.h"
+
+/* The page size is a guess based on ELF.  */
+
+#define COFF_PAGE_SIZE 0x1000
+
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET true
+#endif
+
+/* Currently we don't handle any relocations.  */
+static reloc_howto_type pe_aarch64_std_reloc_howto[] =
+  {
+
+  };
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER  2
+#define COFF_PAGE_SIZE			      0x1000
+
+#ifndef NUM_ELEM
+#define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
+#endif
+
+#define NUM_RELOCS NUM_ELEM (pe_aarch64_std_reloc_howto)
+
+#define RTYPE2HOWTO(cache_ptr, dst)             \
+  (cache_ptr)->howto = NULL
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata      NULL
+#endif
+
+/* Return TRUE if this relocation should
+   appear in the output .reloc section.  */
+
+static bool
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
+            reloc_howto_type * howto)
+{
+  return !howto->pc_relative;
+}
+
+#include "coffcode.h"
+
+/* Target vectors.  */
+const bfd_target
+#ifdef TARGET_SYM
+  TARGET_SYM =
+#else
+  aarch64_pei_vec =
+#endif
+{
+#ifdef TARGET_NAME
+  TARGET_NAME,
+#else
+ "pei-aarch64-little",			/* Name.  */
+#endif
+  bfd_target_coff_flavour,
+  BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */
+  BFD_ENDIAN_LITTLE,		/* Header byte order is little.  */
+
+  (HAS_RELOC | EXEC_P		/* Object flags.  */
+   | HAS_LINENO | HAS_DEBUG
+   | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
+
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
+#if defined(COFF_WITH_PE)
+   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
+#endif
+   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
+
+#ifdef TARGET_UNDERSCORE
+  TARGET_UNDERSCORE,		/* Leading underscore.  */
+#else
+  0,				/* Leading underscore.  */
+#endif
+  '/',				/* Ar_pad_char.  */
+  15,				/* Ar_max_namelen.  */
+  0,				/* match priority.  */
+  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
+
+     /* Data conversion functions.  */
+     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
+     /* Header conversion functions.  */
+     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
+
+  /* Note that we allow an object file to be treated as a core file as well.  */
+  {				/* bfd_check_format.  */
+    _bfd_dummy_target,
+    coff_object_p,
+    bfd_generic_archive_p,
+    coff_object_p
+  },
+  {				/* bfd_set_format.  */
+    _bfd_bool_bfd_false_error,
+    coff_mkobject,
+    _bfd_generic_mkarchive,
+    _bfd_bool_bfd_false_error
+  },
+  {				/* bfd_write_contents.  */
+    _bfd_bool_bfd_false_error,
+    coff_write_object_contents,
+    _bfd_write_archive_contents,
+    _bfd_bool_bfd_false_error
+  },
+
+  BFD_JUMP_TABLE_GENERIC (coff),
+  BFD_JUMP_TABLE_COPY (coff),
+  BFD_JUMP_TABLE_CORE (_bfd_nocore),
+  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+  BFD_JUMP_TABLE_SYMBOLS (coff),
+  BFD_JUMP_TABLE_RELOCS (coff),
+  BFD_JUMP_TABLE_WRITE (coff),
+  BFD_JUMP_TABLE_LINK (coff),
+  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+  NULL,
+
+  COFF_SWAP_TABLE
+};
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 7967cedf918b086a129c1c918af6520b29ab2034..86688d31cdb0a4809b7fc01079d16e87573dd56f 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -2221,6 +2221,12 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
 	}
       break;
 #endif
+#ifdef AARCH64MAGIC
+    case AARCH64MAGIC:
+      arch = bfd_arch_aarch64;
+      machine = internal_f->f_flags & F_AARCH64_ARCHITECTURE_MASK;
+      break;
+#endif
 #ifdef Z80MAGIC
     case Z80MAGIC:
       arch = bfd_arch_z80;
@@ -2777,6 +2783,12 @@ coff_set_flags (bfd * abfd,
       return true;
 #endif
 
+#ifdef AARCH64MAGIC
+    case bfd_arch_aarch64:
+      * magicp = AARCH64MAGIC;
+      return true;
+#endif
+
 #ifdef ARMMAGIC
     case bfd_arch_arm:
 #ifdef ARM_WINCE
@@ -3872,7 +3884,7 @@ coff_write_object_contents (bfd * abfd)
     internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
 #endif
 
-#ifndef COFF_WITH_pex64
+#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
 #ifdef COFF_WITH_PE
   internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;
 #else
@@ -3921,6 +3933,11 @@ coff_write_object_contents (bfd * abfd)
     internal_a.magic = ZMAGIC;
 #endif
 
+#if defined(AARCH64)
+#define __A_MAGIC_SET__
+    internal_a.magic = ZMAGIC;
+#endif
+
 #if defined MCORE_PE
 #define __A_MAGIC_SET__
     internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 3cf322713334cfdeaebc671f48fd321558a4f279..776918253ef11140df94042b379789e6f7b1e598 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -248,7 +248,7 @@ 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"
+    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"
     want64=true
     ;;
   aarch64_be-*-elf)
@@ -278,7 +278,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"
+    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"
     want64=true
     ;;
   aarch64_be-*-linux* | aarch64_be-*-netbsd*)
diff --git a/bfd/configure b/bfd/configure
index 58449ee8a608e3f3ac1d4ad376992d41f87f404e..5741e039a4fed386d826ad4910e1fd029bd37f23 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -13257,6 +13257,7 @@ 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 ;;
     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/configure.ac b/bfd/configure.ac
index 50ba391fff3988717a7760489508ec0d388459b5..1fadfd7d91ed7ead6b04be2173d6c596fb4af221 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -436,6 +436,7 @@ 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 ;;
     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/libpei.h b/bfd/libpei.h
index 4de0c9fd048ac1dc9cf6e4ce0075bc95e610cbd6..26589e8e520f8ee9ab752822e76964a8f0e2979c 100644
--- a/bfd/libpei.h
+++ b/bfd/libpei.h
@@ -275,6 +275,41 @@
 #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
+#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_32
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common	_bfd_peAArch64_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data		_bfd_peAArch64_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info				_bfd_peAArch64_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out			_bfd_peAArch64_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common		_bfd_peAArch64_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript			_bfd_peAArch64i_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out			_bfd_peAArch64i_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in			_bfd_peAArch64i_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out			_bfd_peAArch64i_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in				_bfd_peAArch64i_swap_aux_in
+#define _bfd_XXi_swap_aux_out				_bfd_peAArch64i_swap_aux_out
+#define _bfd_XXi_swap_lineno_in				_bfd_peAArch64i_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out			_bfd_peAArch64i_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out			_bfd_peAArch64i_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in				_bfd_peAArch64i_swap_sym_in
+#define _bfd_XXi_swap_sym_out				_bfd_peAArch64i_swap_sym_out
+#define _bfd_XXi_swap_debugdir_in			_bfd_peAArch64i_swap_debugdir_in
+#define _bfd_XXi_swap_debugdir_out			_bfd_peAArch64i_swap_debugdir_out
+#define _bfd_XXi_write_codeview_record			_bfd_peAArch64i_write_codeview_record
+#define _bfd_XXi_slurp_codeview_record			_bfd_peAArch64i_slurp_codeview_record
+
 #else /* !COFF_WITH_pep */
 
 #define GET_OPTHDR_IMAGE_BASE H_GET_32
@@ -369,5 +404,6 @@ bool _bfd_XX_bfd_copy_private_section_data
 bool _bfd_pe_print_ce_compressed_pdata (bfd *, void *);
 bool _bfd_pe64_print_ce_compressed_pdata (bfd *, void *);
 bool _bfd_pex64_print_ce_compressed_pdata (bfd *, void *);
+bool _bfd_peAArch64_print_ce_compressed_pdata (bfd *, void *);
 bool _bfd_pep_print_ce_compressed_pdata (bfd *, void *);
 
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index c41c3299277846875ee7eca9ca00e530b2683d61..1bfd6c89f1943fe0cf4155111d55b511be3dcc7b 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -60,8 +60,9 @@
    on this code has a chance of getting something accomplished without
    wasting too much time.  */
 
-/* This expands into COFF_WITH_pe, COFF_WITH_pep, or COFF_WITH_pex64
-   depending on whether we're compiling for straight PE or PE+.  */
+/* This expands into COFF_WITH_pe, COFF_WITH_pep, COFF_WITH_pex64 or
+   COFF_WITH_peAArch64 depending on whether we're compiling for straight
+   PE or PE+.  */
 #define COFF_WITH_XX
 
 #include "sysdep.h"
@@ -83,6 +84,8 @@
 # include "coff/x86_64.h"
 #elif defined COFF_WITH_pep
 # include "coff/ia64.h"
+#elif defined COFF_WITH_peAArch64
+# include "coff/aarch64.h"
 #else
 # include "coff/i386.h"
 #endif
@@ -92,7 +95,7 @@
 #include "libpei.h"
 #include "safe-ctype.h"
 
-#if defined COFF_WITH_pep || defined COFF_WITH_pex64
+#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64
 # undef AOUTSZ
 # define AOUTSZ		PEPAOUTSZ
 # define PEAOUTHDR	PEPAOUTHDR
@@ -469,7 +472,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   aouthdr_int->text_start =
     GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   /* PE32+ does not have data_start member!  */
   aouthdr_int->data_start =
     GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
@@ -555,7 +558,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   if (aouthdr_int->entry)
     {
       aouthdr_int->entry += a->ImageBase;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_int->entry &= 0xffffffff;
 #endif
     }
@@ -563,12 +566,12 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   if (aouthdr_int->tsize)
     {
       aouthdr_int->text_start += a->ImageBase;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_int->text_start &= 0xffffffff;
 #endif
     }
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   /* PE32+ does not have data_start member!  */
   if (aouthdr_int->dsize)
     {
@@ -628,7 +631,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->tsize)
     {
       aouthdr_in->text_start -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_in->text_start &= 0xffffffff;
 #endif
     }
@@ -636,7 +639,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->dsize)
     {
       aouthdr_in->data_start -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_in->data_start &= 0xffffffff;
 #endif
     }
@@ -644,7 +647,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->entry)
     {
       aouthdr_in->entry -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       aouthdr_in->entry &= 0xffffffff;
 #endif
     }
@@ -748,7 +751,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
 			  aouthdr_out->standard.text_start);
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   /* PE32+ does not have data_start member!  */
   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
 			  aouthdr_out->standard.data_start);
@@ -1800,7 +1803,7 @@ pe_print_edata (bfd * abfd, void * vfile)
 static bool
 pe_print_pdata (bfd * abfd, void * vfile)
 {
-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
 # define PDATA_ROW_SIZE	(3 * 8)
 #else
 # define PDATA_ROW_SIZE	(5 * 4)
@@ -1827,7 +1830,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
 
   fprintf (file,
 	   _("\nThe Function Table (interpreted .pdata section contents)\n"));
-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   fprintf (file,
 	   _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
 #else
@@ -1864,7 +1867,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
       bfd_vma eh_handler;
       bfd_vma eh_data;
       bfd_vma prolog_end_addr;
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       int em_data;
 #endif
 
@@ -1882,7 +1885,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
 	/* We are probably into the padding of the section now.  */
 	break;
 
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
 #endif
       eh_handler &= ~(bfd_vma) 0x3;
@@ -1893,7 +1896,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
       bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, eh_handler);
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       fputc (' ', file);
       bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, prolog_end_addr);
@@ -2784,7 +2787,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
   fprintf (file, "\nBaseOfCode\t\t");
   bfd_fprintf_vma (abfd, file, i->BaseOfCode);
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
   /* PE32+ does not have BaseOfData member!  */
   fprintf (file, "\nBaseOfData\t\t");
   bfd_fprintf_vma (abfd, file, i->BaseOfData);
@@ -3085,7 +3088,7 @@ _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
   coff_get_symbol_info (abfd, symbol, ret);
 }
 
-#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64) && defined(COFF_WITH_peAArch64)
 static int
 sort_x64_pdata (const void *l, const void *r)
 {
@@ -4504,7 +4507,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 	the TLS data directory consists of 4 pointers, followed
 	by two 4-byte integer. This implies that the total size
 	is different for 32-bit and 64-bit executables.  */
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
 #else
       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
@@ -4513,7 +4516,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 
 /* If there is a .pdata section and we have linked pdata finally, we
      need to sort the entries ascending.  */
-#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64) && defined(COFF_WITH_peAArch64)
   {
     asection *sec = bfd_get_section_by_name (abfd, ".pdata");
 
diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c
new file mode 100644
index 0000000000000000000000000000000000000000..99326d1612655408f1b5ceea7a013e1768083498
--- /dev/null
+++ b/bfd/pei-aarch64.c
@@ -0,0 +1,75 @@
+/* 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_pei_vec
+#define TARGET_NAME		"pei-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
+
+#define COFF_IMAGE_WITH_PE
+/* 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/peicode.h b/bfd/peicode.h
index 41955975cdc621df3f53165a934a0d999140f09e..1e8ed803edc6e269eb84c08007eb0ce568d75a16 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -231,7 +231,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
     {
       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
       /* Do not cut upper 32-bits for 64-bit vma.  */
-#ifndef COFF_WITH_pex64
+#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
       scnhdr_int->s_vaddr &= 0xffffffff;
 #endif
     }
@@ -738,6 +738,16 @@ static const jump_table jtab[] =
   },
 #endif
 
+#ifdef AARCH64MAGIC
+/* We don't currently support jumping to DLLs, so if
+   someone does try emit a runtime trap.  Through UDF #0.  */
+  { AARCH64MAGIC,
+    { 0x00, 0x00, 0x00, 0x00 },
+    4, 0
+  },
+
+#endif
+
 #ifdef  ARMPEMAGIC
   { ARMPEMAGIC,
     { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
@@ -910,7 +920,7 @@ pe_ILF_build_a_bfd (bfd *	    abfd,
 	/* See PR 20907 for a reproducer.  */
 	goto error_return;
 
-#ifdef COFF_WITH_pex64
+#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
       ((unsigned int *) id4->contents)[0] = ordinal;
       ((unsigned int *) id4->contents)[1] = 0x80000000;
       ((unsigned int *) id5->contents)[0] = ordinal;
@@ -1206,6 +1216,12 @@ pe_ILF_object_p (bfd * abfd)
 #endif
       break;
 
+    case IMAGE_FILE_MACHINE_ARM64:
+#ifdef AARCH64MAGIC
+      magic = AARCH64MAGIC;
+#endif
+      break;
+
     case IMAGE_FILE_MACHINE_THUMB:
 #ifdef THUMBPEMAGIC
       {
diff --git a/bfd/targets.c b/bfd/targets.c
index 8f5abb174e2dfecad62008b68f381d89b423576d..672dc2bb1a4d5643f84577d81d4c9cebc14429d9 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -679,6 +679,7 @@ 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 alpha_ecoff_le_vec;
 extern const bfd_target alpha_elf64_vec;
 extern const bfd_target alpha_elf64_fbsd_vec;
@@ -993,6 +994,7 @@ static const bfd_target * const _bfd_target_vector[] =
 	&aarch64_elf64_le_vec,
 	&aarch64_elf64_le_cloudabi_vec,
 	&aarch64_mach_o_vec,
+	&aarch64_pei_vec,
 #endif
 
 #ifdef BFD64
diff --git a/binutils/NEWS b/binutils/NEWS
index e6977b650db6c70cce6efeba43fce7435519099e..994546330f95ccc3b859ffb17388b2cc5ec6a653 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -2,6 +2,9 @@
 
 * Add support for the LoongArch instruction set.
 
+* Support for efi-app-aarch64, efi-rtdrv-aarch64 and efi-bsdrv-aarch64 has been
+  added to objcopy in order to enable UEFI development using binutils.
+
 Changes in 2.37:
 
 * The readelf tool has a new command line option which can be used to specify
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 0e7400fe4cb7046fa704f207816616e623de65af..458a6d96cccbeb154f95e5ba54734b956d14f879 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -4996,6 +4996,13 @@ convert_efi_target (char *efi)
       /* Change x86_64 to x86-64.  */
       efi[7] = '-';
     }
+  else if (strcmp (efi + 4, "aarch64") == 0)
+    {
+      /* Change aarch64 to aarch64-little.  */
+      efi = (char *) xrealloc (efi, strlen (efi) + 7);
+      char *t = "aarch64-little";
+      strcpy (efi + 4, t);
+    }
 }
 
 /* Allocate and return a pointer to a struct section_add, initializing the
diff --git a/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
new file mode 100644
index 0000000000000000000000000000000000000000..0957c985359c049adb4f085a94ddc4ff03c91794
--- /dev/null
+++ b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
@@ -0,0 +1,16 @@
+#skip: aarch64_be-*-*
+#ld: -e0
+#PROG: objcopy
+#objcopy: -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* -j .reloc --target=efi-app-aarch64
+#objdump: -h -f
+#name: Check if efi app format is recognized
+
+.*:     file format pei-aarch64-little
+architecture: aarch64, flags 0x00000132:
+EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
+start address 0x0000000000000000
+
+Sections:
+Idx Name          Size      VMA               LMA               File off  Algn
+  0 \.text         00000030  0000000000400000  0000000000400000  00000200  2\*\*2
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
diff --git a/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
new file mode 100644
index 0000000000000000000000000000000000000000..dafc5fa47f9713b541a8d252748f9621affce5fc
--- /dev/null
+++ b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
@@ -0,0 +1,42 @@
+	.arch armv8-a
+	.text
+	.align	2
+	.global	foo
+	.type	foo, %function
+foo:
+.LFB0:
+	.cfi_startproc
+	sub	sp, sp, #16
+	.cfi_def_cfa_offset 16
+	str	w0, [sp, 12]
+	ldr	w0, [sp, 12]
+	mul	w0, w0, w0
+	add	sp, sp, 16
+	.cfi_def_cfa_offset 0
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+	.align	2
+	.global	main
+	.type	main, %function
+main:
+.LFB1:
+	.cfi_startproc
+	stp	x29, x30, [sp, -16]!
+	.cfi_def_cfa_offset 16
+	.cfi_offset 29, -16
+	.cfi_offset 30, -8
+	mov	x29, sp
+	mov	w0, 5
+	bl	foo
+	ldp	x29, x30, [sp], 16
+	.cfi_restore 30
+	.cfi_restore 29
+	.cfi_def_cfa_offset 0
+	ret
+	.cfi_endproc
+.LFE1:
+	.size	main, .-main
+	.ident	"GCC: (fsf-trunk.2870) 12.0.0 20210930 (experimental)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/include/coff/aarch64.h b/include/coff/aarch64.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c21f0d6cfdac4cb0debbee60030226fa70106d2
--- /dev/null
+++ b/include/coff/aarch64.h
@@ -0,0 +1,63 @@
+/* AArch64 COFF support for BFD.
+   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.  */
+
+#define COFFAARCH64 1
+
+#define L_LNNO_SIZE 2
+#define INCLUDE_COMDAT_FIELDS_IN_AUXENT
+#include "coff/external.h"
+
+#define F_AARCH64_ARCHITECTURE_MASK	(0x4000)
+
+#define	AARCH64MAGIC	0xaa64  /* From Microsoft specification. */
+
+#undef  BADMAG
+#define BADMAG(x) ((x).f_magic != AARCH64MAGIC)
+#define AARCH64         1                 /* Customize coffcode.h.  */
+
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
+
+#define OMAGIC          0404    /* Object files, eg as output.  */
+#define ZMAGIC          IMAGE_NT_OPTIONAL_HDR64_MAGIC    /* Demand load format, eg normal ld output 0x10b.  */
+#define STMAGIC		0401	/* Target shlib.  */
+#define SHMAGIC		0443	/* Host   shlib.  */
+
+/* define some NT default values */
+/*  #define NT_IMAGE_BASE        0x400000 moved to internal.h */
+#define NT_SECTION_ALIGNMENT 0x1000
+#define NT_FILE_ALIGNMENT    0x200
+#define NT_DEF_RESERVE       0x100000
+#define NT_DEF_COMMIT        0x1000
+
+/* We use the .rdata section to hold read only data.  */
+#define _LIT	".rdata"
+
+/********************** RELOCATION DIRECTIVES **********************/
+struct external_reloc
+{
+  char r_vaddr[4];
+  char r_symndx[4];
+  char r_type[2];
+  char r_offset[4];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 14
+
+#define ARM_NOTE_SECTION ".note"
diff --git a/include/coff/pe.h b/include/coff/pe.h
index 9e1ea4b5aa47b8278a0e7a88fad2db5dd8bc9fc5..558cf0e1b86f008f613d107bc72368b3811143ee 100644
--- a/include/coff/pe.h
+++ b/include/coff/pe.h
@@ -137,6 +137,7 @@
 #define IMAGE_FILE_MACHINE_AM33              0x01d3
 #define IMAGE_FILE_MACHINE_AMD64             0x8664
 #define IMAGE_FILE_MACHINE_ARM               0x01c0
+#define IMAGE_FILE_MACHINE_ARM64             0xaa64
 #define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
 #define IMAGE_FILE_MACHINE_CEE               0xc0ee
 #define IMAGE_FILE_MACHINE_CEF               0x0cef


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

* RE: [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-aarch64).
  2021-10-29 11:05 [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-aarch64) Tamar Christina
@ 2021-11-05 17:39 ` Tamar Christina
  2021-11-12  6:10   ` Tamar Christina
  2021-11-18  8:04 ` Nick Clifton
  1 sibling, 1 reply; 4+ messages in thread
From: Tamar Christina @ 2021-11-05 17:39 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, nd, Marcus Shawcroft

Ping (adding mailing list back in)

> -----Original Message-----
> From: Binutils <binutils-bounces+tamar.christina=arm.com@sourceware.org>
> On Behalf Of Tamar Christina via Binutils
> Sent: Friday, October 29, 2021 12:05 PM
> To: binutils@sourceware.org
> Cc: Richard Earnshaw <Richard.Earnshaw@arm.com>; nd <nd@arm.com>;
> Marcus Shawcroft <Marcus.Shawcroft@arm.com>
> Subject: [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-
> aarch64).
> 
> Hi All,
> 
> This adds support for efi-*-aarch64 by virtue of adding a new PEI target pei-
> aarch64-little.  This is not a full target and only exists to support EFI at this
> time.
> 
> This means that this target does not support relocation processing and is
> mostly a container format.  This format has been added to elf based aarch64
> targets such that efi images can be made natively on Linux.
> 
> However this target is not valid for use with gas but only with objcopy.
> 
> With these changes the resulting file is recognized as an efi image by third
> party tools:
> 
> >  pecli info hello.efi
> 
> Metadata
> ==========================================================
> ======================
> MD5:            598c32a778b0f0deebe977fef8578c4e
> SHA1:           4580121edd5cb4dc40f51b28f171fd15250df84c
> SHA256:
> 3154bd7cf42433d1c957f6bf55a17ad8c57ed41b29df2d485703349fd6ff1d5c
> Imphash:
> Size:           47561 bytes
> Type:           PE32+ executable (EFI application) (stripped to external PDB), for
> MS Windows
> Compile Time:   2021-10-29 00:00:00 (UTC - 0x0       )
> Entry point:    0x2000 (section .text)
> 
> Sections
> ==========================================================
> ======================
> Name      RWX  VirtSize   VirtAddr   RawAddr   RawSize   Entropy  md5
> .text     R-X  0x5bb0     0x2000     0x400     0x5c00      6.39
> 551fbc264256a3f387de8a891500ae0d
> .reloc    R--  0xc        0x8000     0x6000    0x200       0.02
> 0c45f6d812d079821c1d54c09ab89e1d
> .data     RW-  0x1d88     0x9000     0x6200    0x1e00      4.18
> 5d1137c09f01289dc62bf754f7290db3
> .dynamic  RW-  0xf0       0xb000     0x8000    0x200       0.34
> 5c94ed3206f05a277e6f04fbf131f131
> .rela     R--  0xe58      0xc000     0x8200    0x1000      1.87
> 8b5c6bc30f3acb7ca7bf2e6789d68519
> .dynsym   R--  0x138      0xd000     0x9200    0x200       0.96
> bdcf5101da51aadc663ca8859f88138c
> 
> 
> Imports
> ==========================================================
> ======================
> 
> Any magic number is based on the Microsoft PE specification [1].
> 
> [1] https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
> 
> build on native hardware and regtested on
>   aarch64-none-elf, aarch64-none-elf (32 bit host),
>   aarch64-none-linux-gnu, aarch64-none-linux-gnu (32 bit host)
> 
> Cross-compiled and regtested on
>   aarch64-none-linux-gnu, aarch64_be-none-linux-gnu
> 
> and no issues.
> 
> Ok for master?
> 
> Thanks,
> Tamar
> 
> bfd/ChangeLog:
> 
> 2021-10-29  Tamar Christina  <tamar.christina@arm.com>
> 
> 	PR binutils/26206
> 	* .gitignore (pe-aarch64igen.c): New.
> 	* Makefile.am (pei-aarch64.lo, pe-aarch64igen.lo, pei-aarch64.c,
> 	pe-aarch64igen.c): Add support.
> 	* Makefile.in: Likewise.
> 	* bfd.c (bfd_get_sign_extend_vma): Add pei-aarch64-little.
> 	* coff-aarch64.c: New file.
> 	* coffcode.h (coff_set_arch_mach_hook, coff_set_flags,
> 	coff_write_object_contents) Add aarch64 (aarch64_pei_vec)
> support.
> 	* config.bfd: Likewise.
> 	* configure: Likewise.
> 	* configure.ac: Likewise.
> 	* libpei.h (GET_OPTHDR_IMAGE_BASE, PUT_OPTHDR_IMAGE_BASE,
> 	GET_OPTHDR_SIZE_OF_STACK_RESERVE,
> PUT_OPTHDR_SIZE_OF_STACK_RESERVE,
> 	GET_OPTHDR_SIZE_OF_STACK_COMMIT,
> PUT_OPTHDR_SIZE_OF_STACK_COMMIT,
> 	GET_OPTHDR_SIZE_OF_HEAP_RESERVE,
> PUT_OPTHDR_SIZE_OF_HEAP_RESERVE,
> 	GET_OPTHDR_SIZE_OF_HEAP_COMMIT,
> PUT_OPTHDR_SIZE_OF_HEAP_COMMIT,
> 	GET_PDATA_ENTRY,
> _bfd_peAArch64_bfd_copy_private_bfd_data_common,
> 	_bfd_peAArch64_bfd_copy_private_section_data,
> 	_bfd_peAArch64_get_symbol_info,
> _bfd_peAArch64_only_swap_filehdr_out,
> 	_bfd_peAArch64_print_private_bfd_data_common,
> 	_bfd_peAArch64i_final_link_postscript,
> 	_bfd_peAArch64i_only_swap_filehdr_out,
> _bfd_peAArch64i_swap_aouthdr_in,
> 	_bfd_peAArch64i_swap_aouthdr_out,
> _bfd_peAArch64i_swap_aux_in,
> 	_bfd_peAArch64i_swap_aux_out,
> _bfd_peAArch64i_swap_lineno_in,
> 	_bfd_peAArch64i_swap_lineno_out,
> _bfd_peAArch64i_swap_scnhdr_out,
> 	_bfd_peAArch64i_swap_sym_in, _bfd_peAArch64i_swap_sym_out,
> 	_bfd_peAArch64i_swap_debugdir_in,
> _bfd_peAArch64i_swap_debugdir_out,
> 	_bfd_peAArch64i_write_codeview_record,
> 	_bfd_peAArch64i_slurp_codeview_record,
> 	_bfd_peAArch64_print_ce_compressed_pdata): New.
> 	* peXXigen.c (_bfd_XXi_swap_aouthdr_in,
> _bfd_XXi_swap_aouthdr_out,
> 	pe_print_pdata, _bfd_XX_print_private_bfd_data_common,
> 	_bfd_XX_bfd_copy_private_section_data,
> _bfd_XXi_final_link_postscript):
> 	Support COFF_WITH_peAArch64,
> 	* pei-aarch64.c: New file.
> 	* peicode.h (coff_swap_scnhdr_in, pe_ILF_build_a_bfd,
> pe_ILF_object_p):
> 	Support COFF_WITH_peAArch64.
> 	(jtab): Add dummy entry that traps.
> 	* targets.c (aarch64_pei_vec): New.
> 
> binutils/ChangeLog:
> 
> 2021-10-29  Tamar Christina  <tamar.christina@arm.com>
> 
> 	PR binutils/26206
> 	* NEWS: Add new support.
> 	* objcopy.c (convert_efi_target): Add efi-*-aarch64 support.
> 	* testsuite/binutils-all/aarch64/pei-aarch64-little.d: New test.
> 	* testsuite/binutils-all/aarch64/pei-aarch64-little.s: New test.
> 
> include/ChangeLog:
> 
> 2021-10-29  Tamar Christina  <tamar.christina@arm.com>
> 
> 	PR binutils/26206
> 	* coff/aarch64.h: New file.
> 	* coff/pe.h (IMAGE_FILE_MACHINE_ARM64): New.
> 
> --- inline copy of patch --
> diff --git a/bfd/.gitignore b/bfd/.gitignore index
> 0a5530d128a7204d4619ea9e95430ae37d532a81..d4f7423111e5be6009abc685
> 539af0c2e58e9045 100644
> --- a/bfd/.gitignore
> +++ b/bfd/.gitignore
> @@ -10,6 +10,7 @@
>  /peigen.c
>  /pepigen.c
>  /pex64igen.c
> +/pe-aarch64igen.c
>  /stmp-bfd-h
>  /targmatch.h
> 
> diff --git a/bfd/Makefile.am b/bfd/Makefile.am index
> 097177bae5c36c734a50884ca6550cd38877b4fa..7777f733702c09b441bc591daa
> 5b8c3d9ab2abd7 100644
> --- a/bfd/Makefile.am
> +++ b/bfd/Makefile.am
> @@ -575,8 +575,10 @@ BFD64_BACKENDS = \
>  	pe-x86_64.lo \
>  	pei-ia64.lo \
>  	pei-x86_64.lo \
> +	pei-aarch64lo \
>  	pepigen.lo \
>  	pex64igen.lo \
> +	pe-aarch64igen.lo \
>  	vms-alpha.lo
> 
>  BFD64_BACKENDS_CFILES = \
> @@ -615,6 +617,7 @@ BFD64_BACKENDS_CFILES = \
>  	pe-x86_64.c \
>  	pei-ia64.c \
>  	pei-x86_64.c \
> +	pei-aarch64.c \
>  	vms-alpha.c
> 
>  OPTIONAL_BACKENDS = \
> @@ -673,7 +676,7 @@ BUILD_CFILES = \
>  	elf32-ia64.c elf64-ia64.c \
>  	elf32-loongarch.c elf64-loongarch.c \
>  	elf32-riscv.c elf64-riscv.c \
> -	peigen.c pepigen.c pex64igen.c
> +	peigen.c pepigen.c pex64igen.c pe-aarch64igen.c
> 
>  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
> 
> @@ -877,6 +880,10 @@ pex64igen.c: peXXigen.c
>  	echo "#line 1 \"peXXigen.c\"" > $@
>  	$(SED) -e s/XX/pex64/g < $< >> $@
> 
> +pe-aarch64igen.c: peXXigen.c
> +	echo "#line 1 \"peXXigen.c\"" > $@
> +	$(SED) -e s/XX/peAArch64/g < $< >> $@
> +
>  BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
> $(INCDIR)/diagnostics.h  LOCAL_H_DEPS= libbfd.h sysdep.h config.h
>  $(BFD32_LIBS) \
> diff --git a/bfd/Makefile.in b/bfd/Makefile.in index
> a76b653247fd5b7d1fc8991ac5f8ad7fbb5eaba3..b243151fea350032c6cb90f1ec
> 1f359bdba589f5 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -1002,8 +1002,10 @@ BFD64_BACKENDS = \
>  	pe-x86_64.lo \
>  	pei-ia64.lo \
>  	pei-x86_64.lo \
> +	pei-aarch64.lo \
>  	pepigen.lo \
>  	pex64igen.lo \
> +	pe-aarch64igen.lo \
>  	vms-alpha.lo
> 
>  BFD64_BACKENDS_CFILES = \
> @@ -1042,6 +1044,7 @@ BFD64_BACKENDS_CFILES = \
>  	pe-x86_64.c \
>  	pei-ia64.c \
>  	pei-x86_64.c \
> +	pei-aarch64.c \
>  	vms-alpha.c
> 
>  OPTIONAL_BACKENDS = \
> @@ -1099,7 +1102,7 @@ BUILD_CFILES = \
>  	elf32-ia64.c elf64-ia64.c \
>  	elf32-loongarch.c elf64-loongarch.c \
>  	elf32-riscv.c elf64-riscv.c \
> -	peigen.c pepigen.c pex64igen.c
> +	peigen.c pepigen.c pex64igen.c pe-aarch64igen.c
> 
>  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)  SOURCE_HFILES = \ @@ -
> 1562,9 +1565,11 @@ distclean-compile:
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-
> mcore.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-
> sh.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-
> x86_64.Plo@am__quote@
> +@AMDEP_TRUE@@am__include@
> +@am__quote@./$(DEPDIR)/pei-aarch64.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@
> @am__quote@./$(DEPDIR)/peigen.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@
> @am__quote@./$(DEPDIR)/pepigen.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@
> @am__quote@./$(DEPDIR)/pex64igen.Plo@am__quote@
> +@AMDEP_TRUE@@am__include@
> +@am__quote@./$(DEPDIR)/pe-aarch64igen.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@
> @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@
> @am__quote@./$(DEPDIR)/ppcboot.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@
> @am__quote@./$(DEPDIR)/reloc.Plo@am__quote@
> @@ -2010,6 +2015,11 @@ pepigen.c : peXXigen.c
>  pex64igen.c: peXXigen.c
>  	echo "#line 1 \"peXXigen.c\"" > $@
>  	$(SED) -e s/XX/pex64/g < $< >> $@
> +
> +pe-aarch64igen.c: peXXigen.c
> +	echo "#line 1 \"peXXigen.c\"" > $@
> +	$(SED) -e s/XX/peAArch64/g < $< >> $@
> +
>  $(BFD32_LIBS) \
>   $(BFD64_LIBS) \
>   $(ALL_MACHINES) \
> diff --git a/bfd/bfd.c b/bfd/bfd.c
> index
> 421f4f19fd60daefe38ded6424b67749c33cda21..5c3797de3052b5715c6cb22259
> 9dbf5b2bd2e8f9 100644
> --- a/bfd/bfd.c
> +++ b/bfd/bfd.c
> @@ -1738,6 +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, "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 new file mode 100644 index
> 0000000000000000000000000000000000000000..a9bc417fae8b7c353f1127cf8e
> c17978079d4ff2
> --- /dev/null
> +++ b/bfd/coff-aarch64.c
> @@ -0,0 +1,166 @@
> +/* BFD back-end for AArch64 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.  */
> +
> +
> +#ifndef COFF_WITH_peAArch64
> +#define COFF_WITH_peAArch64
> +#endif
> +
> +/* Note we have to make sure not to include headers twice.
> +   Not all headers are wrapped in #ifdef guards, so we define
> +   PEI_HEADERS to prevent double including here.  */ #ifndef
> +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 "libiberty.h"
> +#endif
> +
> +#include "libcoff.h"
> +
> +/* The page size is a guess based on ELF.  */
> +
> +#define COFF_PAGE_SIZE 0x1000
> +
> +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.
> +*/ #define OCTETS_PER_BYTE(ABFD, SEC) 1
> +
> +#ifndef PCRELOFFSET
> +#define PCRELOFFSET true
> +#endif
> +
> +/* Currently we don't handle any relocations.  */ static
> +reloc_howto_type pe_aarch64_std_reloc_howto[] =
> +  {
> +
> +  };
> +
> +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER  2
> +#define COFF_PAGE_SIZE			      0x1000
> +
> +#ifndef NUM_ELEM
> +#define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0])) #endif
> +
> +#define NUM_RELOCS NUM_ELEM (pe_aarch64_std_reloc_howto)
> +
> +#define RTYPE2HOWTO(cache_ptr, dst)             \
> +  (cache_ptr)->howto = NULL
> +
> +#ifndef bfd_pe_print_pdata
> +#define bfd_pe_print_pdata      NULL
> +#endif
> +
> +/* Return TRUE if this relocation should
> +   appear in the output .reloc section.  */
> +
> +static bool
> +in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
> +            reloc_howto_type * howto)
> +{
> +  return !howto->pc_relative;
> +}
> +
> +#include "coffcode.h"
> +
> +/* Target vectors.  */
> +const bfd_target
> +#ifdef TARGET_SYM
> +  TARGET_SYM =
> +#else
> +  aarch64_pei_vec =
> +#endif
> +{
> +#ifdef TARGET_NAME
> +  TARGET_NAME,
> +#else
> + "pei-aarch64-little",			/* Name.  */
> +#endif
> +  bfd_target_coff_flavour,
> +  BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */
> +  BFD_ENDIAN_LITTLE,		/* Header byte order is little.  */
> +
> +  (HAS_RELOC | EXEC_P		/* Object flags.  */
> +   | HAS_LINENO | HAS_DEBUG
> +   | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS |
> + BFD_DECOMPRESS),
> +
> +  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section
> +flags.  */ #if defined(COFF_WITH_PE)
> +   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY |
> SEC_DEBUGGING
> +#endif
> +   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
> +
> +#ifdef TARGET_UNDERSCORE
> +  TARGET_UNDERSCORE,		/* Leading underscore.  */
> +#else
> +  0,				/* Leading underscore.  */
> +#endif
> +  '/',				/* Ar_pad_char.  */
> +  15,				/* Ar_max_namelen.  */
> +  0,				/* match priority.  */
> +  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section
> symbols.
> +*/
> +
> +     /* Data conversion functions.  */
> +     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
> +     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
> +     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
> +     /* Header conversion functions.  */
> +     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
> +     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
> +     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
> +
> +  /* Note that we allow an object file to be treated as a core file as well.  */
> +  {				/* bfd_check_format.  */
> +    _bfd_dummy_target,
> +    coff_object_p,
> +    bfd_generic_archive_p,
> +    coff_object_p
> +  },
> +  {				/* bfd_set_format.  */
> +    _bfd_bool_bfd_false_error,
> +    coff_mkobject,
> +    _bfd_generic_mkarchive,
> +    _bfd_bool_bfd_false_error
> +  },
> +  {				/* bfd_write_contents.  */
> +    _bfd_bool_bfd_false_error,
> +    coff_write_object_contents,
> +    _bfd_write_archive_contents,
> +    _bfd_bool_bfd_false_error
> +  },
> +
> +  BFD_JUMP_TABLE_GENERIC (coff),
> +  BFD_JUMP_TABLE_COPY (coff),
> +  BFD_JUMP_TABLE_CORE (_bfd_nocore),
> +  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
> BFD_JUMP_TABLE_SYMBOLS
> + (coff),  BFD_JUMP_TABLE_RELOCS (coff),  BFD_JUMP_TABLE_WRITE (coff),
> + BFD_JUMP_TABLE_LINK (coff),  BFD_JUMP_TABLE_DYNAMIC
> (_bfd_nodynamic),
> +
> +  NULL,
> +
> +  COFF_SWAP_TABLE
> +};
> diff --git a/bfd/coffcode.h b/bfd/coffcode.h index
> 7967cedf918b086a129c1c918af6520b29ab2034..86688d31cdb0a4809b7fc01079
> d16e87573dd56f 100644
> --- a/bfd/coffcode.h
> +++ b/bfd/coffcode.h
> @@ -2221,6 +2221,12 @@ coff_set_arch_mach_hook (bfd *abfd, void *
> filehdr)
>  	}
>        break;
>  #endif
> +#ifdef AARCH64MAGIC
> +    case AARCH64MAGIC:
> +      arch = bfd_arch_aarch64;
> +      machine = internal_f->f_flags & F_AARCH64_ARCHITECTURE_MASK;
> +      break;
> +#endif
>  #ifdef Z80MAGIC
>      case Z80MAGIC:
>        arch = bfd_arch_z80;
> @@ -2777,6 +2783,12 @@ coff_set_flags (bfd * abfd,
>        return true;
>  #endif
> 
> +#ifdef AARCH64MAGIC
> +    case bfd_arch_aarch64:
> +      * magicp = AARCH64MAGIC;
> +      return true;
> +#endif
> +
>  #ifdef ARMMAGIC
>      case bfd_arch_arm:
>  #ifdef ARM_WINCE
> @@ -3872,7 +3884,7 @@ coff_write_object_contents (bfd * abfd)
>      internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;  #endif
> 
> -#ifndef COFF_WITH_pex64
> +#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
>  #ifdef COFF_WITH_PE
>    internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;  #else @@ -3921,6
> +3933,11 @@ coff_write_object_contents (bfd * abfd)
>      internal_a.magic = ZMAGIC;
>  #endif
> 
> +#if defined(AARCH64)
> +#define __A_MAGIC_SET__
> +    internal_a.magic = ZMAGIC;
> +#endif
> +
>  #if defined MCORE_PE
>  #define __A_MAGIC_SET__
>      internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; diff --git
> a/bfd/config.bfd b/bfd/config.bfd index
> 3cf322713334cfdeaebc671f48fd321558a4f279..776918253ef11140df94042b379
> 789e6f7b1e598 100644
> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -248,7 +248,7 @@ 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"
> +    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"
>      want64=true
>      ;;
>    aarch64_be-*-elf)
> @@ -278,7 +278,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"
> +    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"
>      want64=true
>      ;;
>    aarch64_be-*-linux* | aarch64_be-*-netbsd*) diff --git a/bfd/configure
> b/bfd/configure index
> 58449ee8a608e3f3ac1d4ad376992d41f87f404e..5741e039a4fed386d826ad491
> 0e1fd029bd37f23 100755
> --- a/bfd/configure
> +++ b/bfd/configure
> @@ -13257,6 +13257,7 @@ 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 ;;
>      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/configure.ac b/bfd/configure.ac index
> 50ba391fff3988717a7760489508ec0d388459b5..1fadfd7d91ed7ead6b04be217
> 3d6c596fb4af221 100644
> --- a/bfd/configure.ac
> +++ b/bfd/configure.ac
> @@ -436,6 +436,7 @@ 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 ;;
>      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/libpei.h b/bfd/libpei.h index
> 4de0c9fd048ac1dc9cf6e4ce0075bc95e610cbd6..26589e8e520f8ee9ab752822e
> 76964a8f0e2979c 100644
> --- a/bfd/libpei.h
> +++ b/bfd/libpei.h
> @@ -275,6 +275,41 @@
>  #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
> +#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_32
> +
> +#define _bfd_XX_bfd_copy_private_bfd_data_common
> 	_bfd_peAArch64_bfd_copy_private_bfd_data_common
> +#define _bfd_XX_bfd_copy_private_section_data
> 	_bfd_peAArch64_bfd_copy_private_section_data
> +#define _bfd_XX_get_symbol_info
> 	_bfd_peAArch64_get_symbol_info
> +#define _bfd_XX_only_swap_filehdr_out
> 	_bfd_peAArch64_only_swap_filehdr_out
> +#define _bfd_XX_print_private_bfd_data_common
> 	_bfd_peAArch64_print_private_bfd_data_common
> +#define _bfd_XXi_final_link_postscript
> 	_bfd_peAArch64i_final_link_postscript
> +#define _bfd_XXi_only_swap_filehdr_out
> 	_bfd_peAArch64i_only_swap_filehdr_out
> +#define _bfd_XXi_swap_aouthdr_in
> 	_bfd_peAArch64i_swap_aouthdr_in
> +#define _bfd_XXi_swap_aouthdr_out
> 	_bfd_peAArch64i_swap_aouthdr_out
> +#define _bfd_XXi_swap_aux_in
> 	_bfd_peAArch64i_swap_aux_in
> +#define _bfd_XXi_swap_aux_out
> 	_bfd_peAArch64i_swap_aux_out
> +#define _bfd_XXi_swap_lineno_in
> 	_bfd_peAArch64i_swap_lineno_in
> +#define _bfd_XXi_swap_lineno_out
> 	_bfd_peAArch64i_swap_lineno_out
> +#define _bfd_XXi_swap_scnhdr_out
> 	_bfd_peAArch64i_swap_scnhdr_out
> +#define _bfd_XXi_swap_sym_in
> 	_bfd_peAArch64i_swap_sym_in
> +#define _bfd_XXi_swap_sym_out
> 	_bfd_peAArch64i_swap_sym_out
> +#define _bfd_XXi_swap_debugdir_in
> 	_bfd_peAArch64i_swap_debugdir_in
> +#define _bfd_XXi_swap_debugdir_out
> 	_bfd_peAArch64i_swap_debugdir_out
> +#define _bfd_XXi_write_codeview_record
> 	_bfd_peAArch64i_write_codeview_record
> +#define _bfd_XXi_slurp_codeview_record
> 	_bfd_peAArch64i_slurp_codeview_record
> +
>  #else /* !COFF_WITH_pep */
> 
>  #define GET_OPTHDR_IMAGE_BASE H_GET_32
> @@ -369,5 +404,6 @@ bool _bfd_XX_bfd_copy_private_section_data
>  bool _bfd_pe_print_ce_compressed_pdata (bfd *, void *);  bool
> _bfd_pe64_print_ce_compressed_pdata (bfd *, void *);  bool
> _bfd_pex64_print_ce_compressed_pdata (bfd *, void *);
> +bool _bfd_peAArch64_print_ce_compressed_pdata (bfd *, void *);
>  bool _bfd_pep_print_ce_compressed_pdata (bfd *, void *);
> 
> diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index
> c41c3299277846875ee7eca9ca00e530b2683d61..1bfd6c89f1943fe0cf4155111d
> 55b511be3dcc7b 100644
> --- a/bfd/peXXigen.c
> +++ b/bfd/peXXigen.c
> @@ -60,8 +60,9 @@
>     on this code has a chance of getting something accomplished without
>     wasting too much time.  */
> 
> -/* This expands into COFF_WITH_pe, COFF_WITH_pep, or
> COFF_WITH_pex64
> -   depending on whether we're compiling for straight PE or PE+.  */
> +/* This expands into COFF_WITH_pe, COFF_WITH_pep, COFF_WITH_pex64
> or
> +   COFF_WITH_peAArch64 depending on whether we're compiling for
> straight
> +   PE or PE+.  */
>  #define COFF_WITH_XX
> 
>  #include "sysdep.h"
> @@ -83,6 +84,8 @@
>  # include "coff/x86_64.h"
>  #elif defined COFF_WITH_pep
>  # include "coff/ia64.h"
> +#elif defined COFF_WITH_peAArch64
> +# include "coff/aarch64.h"
>  #else
>  # include "coff/i386.h"
>  #endif
> @@ -92,7 +95,7 @@
>  #include "libpei.h"
>  #include "safe-ctype.h"
> 
> -#if defined COFF_WITH_pep || defined COFF_WITH_pex64
> +#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined
> +COFF_WITH_peAArch64
>  # undef AOUTSZ
>  # define AOUTSZ		PEPAOUTSZ
>  # define PEAOUTHDR	PEPAOUTHDR
> @@ -469,7 +472,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
>    aouthdr_int->text_start =
>      GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
> 
> -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>    /* PE32+ does not have data_start member!  */
>    aouthdr_int->data_start =
>      GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start); @@ -
> 555,7 +558,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
>    if (aouthdr_int->entry)
>      {
>        aouthdr_int->entry += a->ImageBase; -#if !defined(COFF_WITH_pep)
> && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>        aouthdr_int->entry &= 0xffffffff;  #endif
>      }
> @@ -563,12 +566,12 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
>    if (aouthdr_int->tsize)
>      {
>        aouthdr_int->text_start += a->ImageBase; -
> #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>        aouthdr_int->text_start &= 0xffffffff;  #endif
>      }
> 
> -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>    /* PE32+ does not have data_start member!  */
>    if (aouthdr_int->dsize)
>      {
> @@ -628,7 +631,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in,
> void * out)
>    if (aouthdr_in->tsize)
>      {
>        aouthdr_in->text_start -= ib;
> -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>        aouthdr_in->text_start &= 0xffffffff;  #endif
>      }
> @@ -636,7 +639,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in,
> void * out)
>    if (aouthdr_in->dsize)
>      {
>        aouthdr_in->data_start -= ib;
> -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>        aouthdr_in->data_start &= 0xffffffff;  #endif
>      }
> @@ -644,7 +647,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in,
> void * out)
>    if (aouthdr_in->entry)
>      {
>        aouthdr_in->entry -= ib;
> -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>        aouthdr_in->entry &= 0xffffffff;
>  #endif
>      }
> @@ -748,7 +751,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in,
> void * out)
>    PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
>  			  aouthdr_out->standard.text_start);
> 
> -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>    /* PE32+ does not have data_start member!  */
>    PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
>  			  aouthdr_out->standard.data_start);
> @@ -1800,7 +1803,7 @@ pe_print_edata (bfd * abfd, void * vfile)  static bool
> pe_print_pdata (bfd * abfd, void * vfile)  { -#if defined(COFF_WITH_pep)
> && !defined(COFF_WITH_pex64)
> +#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>  # define PDATA_ROW_SIZE	(3 * 8)
>  #else
>  # define PDATA_ROW_SIZE	(5 * 4)
> @@ -1827,7 +1830,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
> 
>    fprintf (file,
>  	   _("\nThe Function Table (interpreted .pdata section contents)\n"));
> -#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>    fprintf (file,
>  	   _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
>  #else
> @@ -1864,7 +1867,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
>        bfd_vma eh_handler;
>        bfd_vma eh_data;
>        bfd_vma prolog_end_addr;
> -#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) ||
> +defined(COFF_WITH_peAArch64)
>        int em_data;
>  #endif
> 
> @@ -1882,7 +1885,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
>  	/* We are probably into the padding of the section now.  */
>  	break;
> 
> -#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) ||
> +defined(COFF_WITH_peAArch64)
>        em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);  #endif
>        eh_handler &= ~(bfd_vma) 0x3;
> @@ -1893,7 +1896,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
>        bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
>        bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
>        bfd_fprintf_vma (abfd, file, eh_handler); -#if !defined(COFF_WITH_pep)
> || defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) ||
> +defined(COFF_WITH_peAArch64)
>        fputc (' ', file);
>        bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
>        bfd_fprintf_vma (abfd, file, prolog_end_addr); @@ -2784,7 +2787,7 @@
> _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
>    bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
>    fprintf (file, "\nBaseOfCode\t\t");
>    bfd_fprintf_vma (abfd, file, i->BaseOfCode); -
> #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>    /* PE32+ does not have BaseOfData member!  */
>    fprintf (file, "\nBaseOfData\t\t");
>    bfd_fprintf_vma (abfd, file, i->BaseOfData); @@ -3085,7 +3088,7 @@
> _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
>    coff_get_symbol_info (abfd, symbol, ret);  }
> 
> -#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64) &&
> +defined(COFF_WITH_peAArch64)
>  static int
>  sort_x64_pdata (const void *l, const void *r)  { @@ -4504,7 +4507,7 @@
> _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
>  	the TLS data directory consists of 4 pointers, followed
>  	by two 4-byte integer. This implies that the total size
>  	is different for 32-bit and 64-bit executables.  */ -
> #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> +!defined(COFF_WITH_peAArch64)
>        pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
> #else
>        pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
> @@ -4513,7 +4516,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct
> coff_final_link_info *pfinfo)
> 
>  /* If there is a .pdata section and we have linked pdata finally, we
>       need to sort the entries ascending.  */ -#if !defined(COFF_WITH_pep) &&
> defined(COFF_WITH_pex64)
> +#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64) &&
> +defined(COFF_WITH_peAArch64)
>    {
>      asection *sec = bfd_get_section_by_name (abfd, ".pdata");
> 
> diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c new file mode 100644
> index
> 0000000000000000000000000000000000000000..99326d1612655408f1b5ceea7
> a013e1768083498
> --- /dev/null
> +++ b/bfd/pei-aarch64.c
> @@ -0,0 +1,75 @@
> +/* 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_pei_vec
> +#define TARGET_NAME		"pei-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
> +
> +#define COFF_IMAGE_WITH_PE
> +/* 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/peicode.h b/bfd/peicode.h index
> 41955975cdc621df3f53165a934a0d999140f09e..1e8ed803edc6e269eb84c0800
> 7eb0ce568d75a16 100644
> --- a/bfd/peicode.h
> +++ b/bfd/peicode.h
> @@ -231,7 +231,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
>      {
>        scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
>        /* Do not cut upper 32-bits for 64-bit vma.  */ -#ifndef
> COFF_WITH_pex64
> +#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
>        scnhdr_int->s_vaddr &= 0xffffffff;  #endif
>      }
> @@ -738,6 +738,16 @@ static const jump_table jtab[] =
>    },
>  #endif
> 
> +#ifdef AARCH64MAGIC
> +/* We don't currently support jumping to DLLs, so if
> +   someone does try emit a runtime trap.  Through UDF #0.  */
> +  { AARCH64MAGIC,
> +    { 0x00, 0x00, 0x00, 0x00 },
> +    4, 0
> +  },
> +
> +#endif
> +
>  #ifdef  ARMPEMAGIC
>    { ARMPEMAGIC,
>      { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
> @@ -910,7 +920,7 @@ pe_ILF_build_a_bfd (bfd *	    abfd,
>  	/* See PR 20907 for a reproducer.  */
>  	goto error_return;
> 
> -#ifdef COFF_WITH_pex64
> +#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
>        ((unsigned int *) id4->contents)[0] = ordinal;
>        ((unsigned int *) id4->contents)[1] = 0x80000000;
>        ((unsigned int *) id5->contents)[0] = ordinal; @@ -1206,6 +1216,12 @@
> pe_ILF_object_p (bfd * abfd)  #endif
>        break;
> 
> +    case IMAGE_FILE_MACHINE_ARM64:
> +#ifdef AARCH64MAGIC
> +      magic = AARCH64MAGIC;
> +#endif
> +      break;
> +
>      case IMAGE_FILE_MACHINE_THUMB:
>  #ifdef THUMBPEMAGIC
>        {
> diff --git a/bfd/targets.c b/bfd/targets.c index
> 8f5abb174e2dfecad62008b68f381d89b423576d..672dc2bb1a4d5643f84577d81
> d4c9cebc14429d9 100644
> --- a/bfd/targets.c
> +++ b/bfd/targets.c
> @@ -679,6 +679,7 @@ 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 alpha_ecoff_le_vec;  extern const bfd_target
> alpha_elf64_vec;  extern const bfd_target alpha_elf64_fbsd_vec; @@ -993,6
> +994,7 @@ static const bfd_target * const _bfd_target_vector[] =
>  	&aarch64_elf64_le_vec,
>  	&aarch64_elf64_le_cloudabi_vec,
>  	&aarch64_mach_o_vec,
> +	&aarch64_pei_vec,
>  #endif
> 
>  #ifdef BFD64
> diff --git a/binutils/NEWS b/binutils/NEWS index
> e6977b650db6c70cce6efeba43fce7435519099e..994546330f95ccc3b859ffb173
> 88b2cc5ec6a653 100644
> --- a/binutils/NEWS
> +++ b/binutils/NEWS
> @@ -2,6 +2,9 @@
> 
>  * Add support for the LoongArch instruction set.
> 
> +* Support for efi-app-aarch64, efi-rtdrv-aarch64 and efi-bsdrv-aarch64
> +has been
> +  added to objcopy in order to enable UEFI development using binutils.
> +
>  Changes in 2.37:
> 
>  * The readelf tool has a new command line option which can be used to
> specify diff --git a/binutils/objcopy.c b/binutils/objcopy.c index
> 0e7400fe4cb7046fa704f207816616e623de65af..458a6d96cccbeb154f95e5ba54
> 734b956d14f879 100644
> --- a/binutils/objcopy.c
> +++ b/binutils/objcopy.c
> @@ -4996,6 +4996,13 @@ convert_efi_target (char *efi)
>        /* Change x86_64 to x86-64.  */
>        efi[7] = '-';
>      }
> +  else if (strcmp (efi + 4, "aarch64") == 0)
> +    {
> +      /* Change aarch64 to aarch64-little.  */
> +      efi = (char *) xrealloc (efi, strlen (efi) + 7);
> +      char *t = "aarch64-little";
> +      strcpy (efi + 4, t);
> +    }
>  }
> 
>  /* Allocate and return a pointer to a struct section_add, initializing the diff --
> git a/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
> b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..0957c985359c049adb4f085a94
> ddc4ff03c91794
> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
> @@ -0,0 +1,16 @@
> +#skip: aarch64_be-*-*
> +#ld: -e0
> +#PROG: objcopy
> +#objcopy: -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j
> +.rela -j .rel.* -j .rela.* -j .rel* -j .rela* -j .reloc
> +--target=efi-app-aarch64
> +#objdump: -h -f
> +#name: Check if efi app format is recognized
> +
> +.*:     file format pei-aarch64-little
> +architecture: aarch64, flags 0x00000132:
> +EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
> +start address 0x0000000000000000
> +
> +Sections:
> +Idx Name          Size      VMA               LMA               File off  Algn
> +  0 \.text         00000030  0000000000400000  0000000000400000  00000200
> 2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> diff --git a/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
> b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..dafc5fa47f9713b541a8d25274
> 8f9621affce5fc
> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
> @@ -0,0 +1,42 @@
> +	.arch armv8-a
> +	.text
> +	.align	2
> +	.global	foo
> +	.type	foo, %function
> +foo:
> +.LFB0:
> +	.cfi_startproc
> +	sub	sp, sp, #16
> +	.cfi_def_cfa_offset 16
> +	str	w0, [sp, 12]
> +	ldr	w0, [sp, 12]
> +	mul	w0, w0, w0
> +	add	sp, sp, 16
> +	.cfi_def_cfa_offset 0
> +	ret
> +	.cfi_endproc
> +.LFE0:
> +	.size	foo, .-foo
> +	.align	2
> +	.global	main
> +	.type	main, %function
> +main:
> +.LFB1:
> +	.cfi_startproc
> +	stp	x29, x30, [sp, -16]!
> +	.cfi_def_cfa_offset 16
> +	.cfi_offset 29, -16
> +	.cfi_offset 30, -8
> +	mov	x29, sp
> +	mov	w0, 5
> +	bl	foo
> +	ldp	x29, x30, [sp], 16
> +	.cfi_restore 30
> +	.cfi_restore 29
> +	.cfi_def_cfa_offset 0
> +	ret
> +	.cfi_endproc
> +.LFE1:
> +	.size	main, .-main
> +	.ident	"GCC: (fsf-trunk.2870) 12.0.0 20210930 (experimental)"
> +	.section	.note.GNU-stack,"",@progbits
> diff --git a/include/coff/aarch64.h b/include/coff/aarch64.h new file mode
> 100644 index
> 0000000000000000000000000000000000000000..2c21f0d6cfdac4cb0debbee60
> 030226fa70106d2
> --- /dev/null
> +++ b/include/coff/aarch64.h
> @@ -0,0 +1,63 @@
> +/* AArch64 COFF support for BFD.
> +   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.
> + */
> +
> +#define COFFAARCH64 1
> +
> +#define L_LNNO_SIZE 2
> +#define INCLUDE_COMDAT_FIELDS_IN_AUXENT #include "coff/external.h"
> +
> +#define F_AARCH64_ARCHITECTURE_MASK	(0x4000)
> +
> +#define	AARCH64MAGIC	0xaa64  /* From Microsoft
> specification. */
> +
> +#undef  BADMAG
> +#define BADMAG(x) ((x).f_magic != AARCH64MAGIC)
> +#define AARCH64         1                 /* Customize coffcode.h.  */
> +
> +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
> +
> +#define OMAGIC          0404    /* Object files, eg as output.  */
> +#define ZMAGIC          IMAGE_NT_OPTIONAL_HDR64_MAGIC    /* Demand
> load format, eg normal ld output 0x10b.  */
> +#define STMAGIC		0401	/* Target shlib.  */
> +#define SHMAGIC		0443	/* Host   shlib.  */
> +
> +/* define some NT default values */
> +/*  #define NT_IMAGE_BASE        0x400000 moved to internal.h */
> +#define NT_SECTION_ALIGNMENT 0x1000
> +#define NT_FILE_ALIGNMENT    0x200
> +#define NT_DEF_RESERVE       0x100000
> +#define NT_DEF_COMMIT        0x1000
> +
> +/* We use the .rdata section to hold read only data.  */
> +#define _LIT	".rdata"
> +
> +/********************** RELOCATION DIRECTIVES
> **********************/
> +struct external_reloc {
> +  char r_vaddr[4];
> +  char r_symndx[4];
> +  char r_type[2];
> +  char r_offset[4];
> +};
> +
> +#define RELOC struct external_reloc
> +#define RELSZ 14
> +
> +#define ARM_NOTE_SECTION ".note"
> diff --git a/include/coff/pe.h b/include/coff/pe.h index
> 9e1ea4b5aa47b8278a0e7a88fad2db5dd8bc9fc5..558cf0e1b86f008f613d107bc
> 72368b3811143ee 100644
> --- a/include/coff/pe.h
> +++ b/include/coff/pe.h
> @@ -137,6 +137,7 @@
>  #define IMAGE_FILE_MACHINE_AM33              0x01d3
>  #define IMAGE_FILE_MACHINE_AMD64             0x8664
>  #define IMAGE_FILE_MACHINE_ARM               0x01c0
> +#define IMAGE_FILE_MACHINE_ARM64             0xaa64
>  #define IMAGE_FILE_MACHINE_AXP64
> IMAGE_FILE_MACHINE_ALPHA64
>  #define IMAGE_FILE_MACHINE_CEE               0xc0ee
>  #define IMAGE_FILE_MACHINE_CEF               0x0cef
> 
> 
> --

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

* RE: [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-aarch64).
  2021-11-05 17:39 ` Tamar Christina
@ 2021-11-12  6:10   ` Tamar Christina
  0 siblings, 0 replies; 4+ messages in thread
From: Tamar Christina @ 2021-11-12  6:10 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw, nd, Marcus Shawcroft

Ping x2

> -----Original Message-----
> From: Binutils <binutils-bounces+tamar.christina=arm.com@sourceware.org>
> On Behalf Of Tamar Christina via Binutils
> Sent: Friday, November 5, 2021 6:40 PM
> To: binutils@sourceware.org
> Cc: Richard Earnshaw <Richard.Earnshaw@arm.com>; nd <nd@arm.com>;
> Marcus Shawcroft <Marcus.Shawcroft@arm.com>
> Subject: RE: [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-
> aarch64).
> 
> Ping (adding mailing list back in)
> 
> > -----Original Message-----
> > From: Binutils
> > <binutils-bounces+tamar.christina=arm.com@sourceware.org>
> > On Behalf Of Tamar Christina via Binutils
> > Sent: Friday, October 29, 2021 12:05 PM
> > To: binutils@sourceware.org
> > Cc: Richard Earnshaw <Richard.Earnshaw@arm.com>; nd <nd@arm.com>;
> > Marcus Shawcroft <Marcus.Shawcroft@arm.com>
> > Subject: [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-
> > aarch64).
> >
> > Hi All,
> >
> > This adds support for efi-*-aarch64 by virtue of adding a new PEI
> > target pei- aarch64-little.  This is not a full target and only exists
> > to support EFI at this time.
> >
> > This means that this target does not support relocation processing and
> > is mostly a container format.  This format has been added to elf based
> > aarch64 targets such that efi images can be made natively on Linux.
> >
> > However this target is not valid for use with gas but only with objcopy.
> >
> > With these changes the resulting file is recognized as an efi image by
> > third party tools:
> >
> > >  pecli info hello.efi
> >
> > Metadata
> >
> ==========================================================
> > ======================
> > MD5:            598c32a778b0f0deebe977fef8578c4e
> > SHA1:           4580121edd5cb4dc40f51b28f171fd15250df84c
> > SHA256:
> > 3154bd7cf42433d1c957f6bf55a17ad8c57ed41b29df2d485703349fd6ff1d5c
> > Imphash:
> > Size:           47561 bytes
> > Type:           PE32+ executable (EFI application) (stripped to external PDB),
> for
> > MS Windows
> > Compile Time:   2021-10-29 00:00:00 (UTC - 0x0       )
> > Entry point:    0x2000 (section .text)
> >
> > Sections
> >
> ==========================================================
> > ======================
> > Name      RWX  VirtSize   VirtAddr   RawAddr   RawSize   Entropy  md5
> > .text     R-X  0x5bb0     0x2000     0x400     0x5c00      6.39
> > 551fbc264256a3f387de8a891500ae0d
> > .reloc    R--  0xc        0x8000     0x6000    0x200       0.02
> > 0c45f6d812d079821c1d54c09ab89e1d
> > .data     RW-  0x1d88     0x9000     0x6200    0x1e00      4.18
> > 5d1137c09f01289dc62bf754f7290db3
> > .dynamic  RW-  0xf0       0xb000     0x8000    0x200       0.34
> > 5c94ed3206f05a277e6f04fbf131f131
> > .rela     R--  0xe58      0xc000     0x8200    0x1000      1.87
> > 8b5c6bc30f3acb7ca7bf2e6789d68519
> > .dynsym   R--  0x138      0xd000     0x9200    0x200       0.96
> > bdcf5101da51aadc663ca8859f88138c
> >
> >
> > Imports
> >
> ==========================================================
> > ======================
> >
> > Any magic number is based on the Microsoft PE specification [1].
> >
> > [1] https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
> >
> > build on native hardware and regtested on
> >   aarch64-none-elf, aarch64-none-elf (32 bit host),
> >   aarch64-none-linux-gnu, aarch64-none-linux-gnu (32 bit host)
> >
> > Cross-compiled and regtested on
> >   aarch64-none-linux-gnu, aarch64_be-none-linux-gnu
> >
> > and no issues.
> >
> > Ok for master?
> >
> > Thanks,
> > Tamar
> >
> > bfd/ChangeLog:
> >
> > 2021-10-29  Tamar Christina  <tamar.christina@arm.com>
> >
> > 	PR binutils/26206
> > 	* .gitignore (pe-aarch64igen.c): New.
> > 	* Makefile.am (pei-aarch64.lo, pe-aarch64igen.lo, pei-aarch64.c,
> > 	pe-aarch64igen.c): Add support.
> > 	* Makefile.in: Likewise.
> > 	* bfd.c (bfd_get_sign_extend_vma): Add pei-aarch64-little.
> > 	* coff-aarch64.c: New file.
> > 	* coffcode.h (coff_set_arch_mach_hook, coff_set_flags,
> > 	coff_write_object_contents) Add aarch64 (aarch64_pei_vec)
> support.
> > 	* config.bfd: Likewise.
> > 	* configure: Likewise.
> > 	* configure.ac: Likewise.
> > 	* libpei.h (GET_OPTHDR_IMAGE_BASE, PUT_OPTHDR_IMAGE_BASE,
> > 	GET_OPTHDR_SIZE_OF_STACK_RESERVE,
> > PUT_OPTHDR_SIZE_OF_STACK_RESERVE,
> > 	GET_OPTHDR_SIZE_OF_STACK_COMMIT,
> > PUT_OPTHDR_SIZE_OF_STACK_COMMIT,
> > 	GET_OPTHDR_SIZE_OF_HEAP_RESERVE,
> > PUT_OPTHDR_SIZE_OF_HEAP_RESERVE,
> > 	GET_OPTHDR_SIZE_OF_HEAP_COMMIT,
> > PUT_OPTHDR_SIZE_OF_HEAP_COMMIT,
> > 	GET_PDATA_ENTRY,
> > _bfd_peAArch64_bfd_copy_private_bfd_data_common,
> > 	_bfd_peAArch64_bfd_copy_private_section_data,
> > 	_bfd_peAArch64_get_symbol_info,
> > _bfd_peAArch64_only_swap_filehdr_out,
> > 	_bfd_peAArch64_print_private_bfd_data_common,
> > 	_bfd_peAArch64i_final_link_postscript,
> > 	_bfd_peAArch64i_only_swap_filehdr_out,
> > _bfd_peAArch64i_swap_aouthdr_in,
> > 	_bfd_peAArch64i_swap_aouthdr_out,
> > _bfd_peAArch64i_swap_aux_in,
> > 	_bfd_peAArch64i_swap_aux_out,
> > _bfd_peAArch64i_swap_lineno_in,
> > 	_bfd_peAArch64i_swap_lineno_out,
> > _bfd_peAArch64i_swap_scnhdr_out,
> > 	_bfd_peAArch64i_swap_sym_in, _bfd_peAArch64i_swap_sym_out,
> > 	_bfd_peAArch64i_swap_debugdir_in,
> > _bfd_peAArch64i_swap_debugdir_out,
> > 	_bfd_peAArch64i_write_codeview_record,
> > 	_bfd_peAArch64i_slurp_codeview_record,
> > 	_bfd_peAArch64_print_ce_compressed_pdata): New.
> > 	* peXXigen.c (_bfd_XXi_swap_aouthdr_in,
> _bfd_XXi_swap_aouthdr_out,
> > 	pe_print_pdata, _bfd_XX_print_private_bfd_data_common,
> > 	_bfd_XX_bfd_copy_private_section_data,
> > _bfd_XXi_final_link_postscript):
> > 	Support COFF_WITH_peAArch64,
> > 	* pei-aarch64.c: New file.
> > 	* peicode.h (coff_swap_scnhdr_in, pe_ILF_build_a_bfd,
> > pe_ILF_object_p):
> > 	Support COFF_WITH_peAArch64.
> > 	(jtab): Add dummy entry that traps.
> > 	* targets.c (aarch64_pei_vec): New.
> >
> > binutils/ChangeLog:
> >
> > 2021-10-29  Tamar Christina  <tamar.christina@arm.com>
> >
> > 	PR binutils/26206
> > 	* NEWS: Add new support.
> > 	* objcopy.c (convert_efi_target): Add efi-*-aarch64 support.
> > 	* testsuite/binutils-all/aarch64/pei-aarch64-little.d: New test.
> > 	* testsuite/binutils-all/aarch64/pei-aarch64-little.s: New test.
> >
> > include/ChangeLog:
> >
> > 2021-10-29  Tamar Christina  <tamar.christina@arm.com>
> >
> > 	PR binutils/26206
> > 	* coff/aarch64.h: New file.
> > 	* coff/pe.h (IMAGE_FILE_MACHINE_ARM64): New.
> >
> > --- inline copy of patch --
> > diff --git a/bfd/.gitignore b/bfd/.gitignore index
> >
> 0a5530d128a7204d4619ea9e95430ae37d532a81..d4f7423111e5be6009abc685
> > 539af0c2e58e9045 100644
> > --- a/bfd/.gitignore
> > +++ b/bfd/.gitignore
> > @@ -10,6 +10,7 @@
> >  /peigen.c
> >  /pepigen.c
> >  /pex64igen.c
> > +/pe-aarch64igen.c
> >  /stmp-bfd-h
> >  /targmatch.h
> >
> > diff --git a/bfd/Makefile.am b/bfd/Makefile.am index
> >
> 097177bae5c36c734a50884ca6550cd38877b4fa..7777f733702c09b441bc591daa
> > 5b8c3d9ab2abd7 100644
> > --- a/bfd/Makefile.am
> > +++ b/bfd/Makefile.am
> > @@ -575,8 +575,10 @@ BFD64_BACKENDS = \
> >  	pe-x86_64.lo \
> >  	pei-ia64.lo \
> >  	pei-x86_64.lo \
> > +	pei-aarch64lo \
> >  	pepigen.lo \
> >  	pex64igen.lo \
> > +	pe-aarch64igen.lo \
> >  	vms-alpha.lo
> >
> >  BFD64_BACKENDS_CFILES = \
> > @@ -615,6 +617,7 @@ BFD64_BACKENDS_CFILES = \
> >  	pe-x86_64.c \
> >  	pei-ia64.c \
> >  	pei-x86_64.c \
> > +	pei-aarch64.c \
> >  	vms-alpha.c
> >
> >  OPTIONAL_BACKENDS = \
> > @@ -673,7 +676,7 @@ BUILD_CFILES = \
> >  	elf32-ia64.c elf64-ia64.c \
> >  	elf32-loongarch.c elf64-loongarch.c \
> >  	elf32-riscv.c elf64-riscv.c \
> > -	peigen.c pepigen.c pex64igen.c
> > +	peigen.c pepigen.c pex64igen.c pe-aarch64igen.c
> >
> >  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
> >
> > @@ -877,6 +880,10 @@ pex64igen.c: peXXigen.c
> >  	echo "#line 1 \"peXXigen.c\"" > $@
> >  	$(SED) -e s/XX/pex64/g < $< >> $@
> >
> > +pe-aarch64igen.c: peXXigen.c
> > +	echo "#line 1 \"peXXigen.c\"" > $@
> > +	$(SED) -e s/XX/peAArch64/g < $< >> $@
> > +
> >  BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
> > $(INCDIR)/diagnostics.h  LOCAL_H_DEPS= libbfd.h sysdep.h config.h
> >  $(BFD32_LIBS) \
> > diff --git a/bfd/Makefile.in b/bfd/Makefile.in index
> >
> a76b653247fd5b7d1fc8991ac5f8ad7fbb5eaba3..b243151fea350032c6cb90f1ec
> > 1f359bdba589f5 100644
> > --- a/bfd/Makefile.in
> > +++ b/bfd/Makefile.in
> > @@ -1002,8 +1002,10 @@ BFD64_BACKENDS = \
> >  	pe-x86_64.lo \
> >  	pei-ia64.lo \
> >  	pei-x86_64.lo \
> > +	pei-aarch64.lo \
> >  	pepigen.lo \
> >  	pex64igen.lo \
> > +	pe-aarch64igen.lo \
> >  	vms-alpha.lo
> >
> >  BFD64_BACKENDS_CFILES = \
> > @@ -1042,6 +1044,7 @@ BFD64_BACKENDS_CFILES = \
> >  	pe-x86_64.c \
> >  	pei-ia64.c \
> >  	pei-x86_64.c \
> > +	pei-aarch64.c \
> >  	vms-alpha.c
> >
> >  OPTIONAL_BACKENDS = \
> > @@ -1099,7 +1102,7 @@ BUILD_CFILES = \
> >  	elf32-ia64.c elf64-ia64.c \
> >  	elf32-loongarch.c elf64-loongarch.c \
> >  	elf32-riscv.c elf64-riscv.c \
> > -	peigen.c pepigen.c pex64igen.c
> > +	peigen.c pepigen.c pex64igen.c pe-aarch64igen.c
> >
> >  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)  SOURCE_HFILES = \ @@ -
> > 1562,9 +1565,11 @@ distclean-compile:
> >  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-
> > mcore.Plo@am__quote@  @AMDEP_TRUE@@am__include@
> > @am__quote@./$(DEPDIR)/pei- sh.Plo@am__quote@
> > @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-
> > x86_64.Plo@am__quote@
> > +@AMDEP_TRUE@@am__include@
> > +@am__quote@./$(DEPDIR)/pei-aarch64.Plo@am__quote@
> >  @AMDEP_TRUE@@am__include@
> > @am__quote@./$(DEPDIR)/peigen.Plo@am__quote@
> >  @AMDEP_TRUE@@am__include@
> > @am__quote@./$(DEPDIR)/pepigen.Plo@am__quote@
> >  @AMDEP_TRUE@@am__include@
> > @am__quote@./$(DEPDIR)/pex64igen.Plo@am__quote@
> > +@AMDEP_TRUE@@am__include@
> > +@am__quote@./$(DEPDIR)/pe-aarch64igen.Plo@am__quote@
> >  @AMDEP_TRUE@@am__include@
> > @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@
> >  @AMDEP_TRUE@@am__include@
> > @am__quote@./$(DEPDIR)/ppcboot.Plo@am__quote@
> >  @AMDEP_TRUE@@am__include@
> > @am__quote@./$(DEPDIR)/reloc.Plo@am__quote@
> > @@ -2010,6 +2015,11 @@ pepigen.c : peXXigen.c
> >  pex64igen.c: peXXigen.c
> >  	echo "#line 1 \"peXXigen.c\"" > $@
> >  	$(SED) -e s/XX/pex64/g < $< >> $@
> > +
> > +pe-aarch64igen.c: peXXigen.c
> > +	echo "#line 1 \"peXXigen.c\"" > $@
> > +	$(SED) -e s/XX/peAArch64/g < $< >> $@
> > +
> >  $(BFD32_LIBS) \
> >   $(BFD64_LIBS) \
> >   $(ALL_MACHINES) \
> > diff --git a/bfd/bfd.c b/bfd/bfd.c
> > index
> >
> 421f4f19fd60daefe38ded6424b67749c33cda21..5c3797de3052b5715c6cb22259
> > 9dbf5b2bd2e8f9 100644
> > --- a/bfd/bfd.c
> > +++ b/bfd/bfd.c
> > @@ -1738,6 +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, "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 new file mode 100644 index
> >
> 0000000000000000000000000000000000000000..a9bc417fae8b7c353f1127cf8e
> > c17978079d4ff2
> > --- /dev/null
> > +++ b/bfd/coff-aarch64.c
> > @@ -0,0 +1,166 @@
> > +/* BFD back-end for AArch64 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.  */
> > +
> > +
> > +#ifndef COFF_WITH_peAArch64
> > +#define COFF_WITH_peAArch64
> > +#endif
> > +
> > +/* Note we have to make sure not to include headers twice.
> > +   Not all headers are wrapped in #ifdef guards, so we define
> > +   PEI_HEADERS to prevent double including here.  */ #ifndef
> > +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 "libiberty.h"
> > +#endif
> > +
> > +#include "libcoff.h"
> > +
> > +/* The page size is a guess based on ELF.  */
> > +
> > +#define COFF_PAGE_SIZE 0x1000
> > +
> > +/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.
> > +*/ #define OCTETS_PER_BYTE(ABFD, SEC) 1
> > +
> > +#ifndef PCRELOFFSET
> > +#define PCRELOFFSET true
> > +#endif
> > +
> > +/* Currently we don't handle any relocations.  */ static
> > +reloc_howto_type pe_aarch64_std_reloc_howto[] =
> > +  {
> > +
> > +  };
> > +
> > +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER  2
> > +#define COFF_PAGE_SIZE			      0x1000
> > +
> > +#ifndef NUM_ELEM
> > +#define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0])) #endif
> > +
> > +#define NUM_RELOCS NUM_ELEM (pe_aarch64_std_reloc_howto)
> > +
> > +#define RTYPE2HOWTO(cache_ptr, dst)             \
> > +  (cache_ptr)->howto = NULL
> > +
> > +#ifndef bfd_pe_print_pdata
> > +#define bfd_pe_print_pdata      NULL
> > +#endif
> > +
> > +/* Return TRUE if this relocation should
> > +   appear in the output .reloc section.  */
> > +
> > +static bool
> > +in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
> > +            reloc_howto_type * howto) {
> > +  return !howto->pc_relative;
> > +}
> > +
> > +#include "coffcode.h"
> > +
> > +/* Target vectors.  */
> > +const bfd_target
> > +#ifdef TARGET_SYM
> > +  TARGET_SYM =
> > +#else
> > +  aarch64_pei_vec =
> > +#endif
> > +{
> > +#ifdef TARGET_NAME
> > +  TARGET_NAME,
> > +#else
> > + "pei-aarch64-little",			/* Name.  */
> > +#endif
> > +  bfd_target_coff_flavour,
> > +  BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */
> > +  BFD_ENDIAN_LITTLE,		/* Header byte order is little.  */
> > +
> > +  (HAS_RELOC | EXEC_P		/* Object flags.  */
> > +   | HAS_LINENO | HAS_DEBUG
> > +   | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS |
> > + BFD_DECOMPRESS),
> > +
> > +  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section
> > +flags.  */ #if defined(COFF_WITH_PE)
> > +   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY |
> > SEC_DEBUGGING
> > +#endif
> > +   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
> > +
> > +#ifdef TARGET_UNDERSCORE
> > +  TARGET_UNDERSCORE,		/* Leading underscore.  */
> > +#else
> > +  0,				/* Leading underscore.  */
> > +#endif
> > +  '/',				/* Ar_pad_char.  */
> > +  15,				/* Ar_max_namelen.  */
> > +  0,				/* match priority.  */
> > +  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section
> > symbols.
> > +*/
> > +
> > +     /* Data conversion functions.  */
> > +     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
> > +     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
> > +     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
> > +     /* Header conversion functions.  */
> > +     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
> > +     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
> > +     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
> > +
> > +  /* Note that we allow an object file to be treated as a core file as well.  */
> > +  {				/* bfd_check_format.  */
> > +    _bfd_dummy_target,
> > +    coff_object_p,
> > +    bfd_generic_archive_p,
> > +    coff_object_p
> > +  },
> > +  {				/* bfd_set_format.  */
> > +    _bfd_bool_bfd_false_error,
> > +    coff_mkobject,
> > +    _bfd_generic_mkarchive,
> > +    _bfd_bool_bfd_false_error
> > +  },
> > +  {				/* bfd_write_contents.  */
> > +    _bfd_bool_bfd_false_error,
> > +    coff_write_object_contents,
> > +    _bfd_write_archive_contents,
> > +    _bfd_bool_bfd_false_error
> > +  },
> > +
> > +  BFD_JUMP_TABLE_GENERIC (coff),
> > +  BFD_JUMP_TABLE_COPY (coff),
> > +  BFD_JUMP_TABLE_CORE (_bfd_nocore),
> > +  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
> > BFD_JUMP_TABLE_SYMBOLS
> > + (coff),  BFD_JUMP_TABLE_RELOCS (coff),  BFD_JUMP_TABLE_WRITE
> (coff),
> > + BFD_JUMP_TABLE_LINK (coff),  BFD_JUMP_TABLE_DYNAMIC
> > (_bfd_nodynamic),
> > +
> > +  NULL,
> > +
> > +  COFF_SWAP_TABLE
> > +};
> > diff --git a/bfd/coffcode.h b/bfd/coffcode.h index
> >
> 7967cedf918b086a129c1c918af6520b29ab2034..86688d31cdb0a4809b7fc01079
> > d16e87573dd56f 100644
> > --- a/bfd/coffcode.h
> > +++ b/bfd/coffcode.h
> > @@ -2221,6 +2221,12 @@ coff_set_arch_mach_hook (bfd *abfd, void *
> > filehdr)
> >  	}
> >        break;
> >  #endif
> > +#ifdef AARCH64MAGIC
> > +    case AARCH64MAGIC:
> > +      arch = bfd_arch_aarch64;
> > +      machine = internal_f->f_flags & F_AARCH64_ARCHITECTURE_MASK;
> > +      break;
> > +#endif
> >  #ifdef Z80MAGIC
> >      case Z80MAGIC:
> >        arch = bfd_arch_z80;
> > @@ -2777,6 +2783,12 @@ coff_set_flags (bfd * abfd,
> >        return true;
> >  #endif
> >
> > +#ifdef AARCH64MAGIC
> > +    case bfd_arch_aarch64:
> > +      * magicp = AARCH64MAGIC;
> > +      return true;
> > +#endif
> > +
> >  #ifdef ARMMAGIC
> >      case bfd_arch_arm:
> >  #ifdef ARM_WINCE
> > @@ -3872,7 +3884,7 @@ coff_write_object_contents (bfd * abfd)
> >      internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;  #endif
> >
> > -#ifndef COFF_WITH_pex64
> > +#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
> >  #ifdef COFF_WITH_PE
> >    internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;  #else @@ -3921,6
> > +3933,11 @@ coff_write_object_contents (bfd * abfd)
> >      internal_a.magic = ZMAGIC;
> >  #endif
> >
> > +#if defined(AARCH64)
> > +#define __A_MAGIC_SET__
> > +    internal_a.magic = ZMAGIC;
> > +#endif
> > +
> >  #if defined MCORE_PE
> >  #define __A_MAGIC_SET__
> >      internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; diff --git
> > a/bfd/config.bfd b/bfd/config.bfd index
> >
> 3cf322713334cfdeaebc671f48fd321558a4f279..776918253ef11140df94042b379
> > 789e6f7b1e598 100644
> > --- a/bfd/config.bfd
> > +++ b/bfd/config.bfd
> > @@ -248,7 +248,7 @@ 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"
> > +    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"
> >      want64=true
> >      ;;
> >    aarch64_be-*-elf)
> > @@ -278,7 +278,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"
> > +    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"
> >      want64=true
> >      ;;
> >    aarch64_be-*-linux* | aarch64_be-*-netbsd*) diff --git
> > a/bfd/configure b/bfd/configure index
> >
> 58449ee8a608e3f3ac1d4ad376992d41f87f404e..5741e039a4fed386d826ad491
> > 0e1fd029bd37f23 100755
> > --- a/bfd/configure
> > +++ b/bfd/configure
> > @@ -13257,6 +13257,7 @@ 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 ;;
> >      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/configure.ac b/bfd/configure.ac index
> >
> 50ba391fff3988717a7760489508ec0d388459b5..1fadfd7d91ed7ead6b04be217
> > 3d6c596fb4af221 100644
> > --- a/bfd/configure.ac
> > +++ b/bfd/configure.ac
> > @@ -436,6 +436,7 @@ 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 ;;
> >      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/libpei.h b/bfd/libpei.h index
> >
> 4de0c9fd048ac1dc9cf6e4ce0075bc95e610cbd6..26589e8e520f8ee9ab752822e
> > 76964a8f0e2979c 100644
> > --- a/bfd/libpei.h
> > +++ b/bfd/libpei.h
> > @@ -275,6 +275,41 @@
> >  #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
> > +#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_32
> > +
> > +#define _bfd_XX_bfd_copy_private_bfd_data_common
> > 	_bfd_peAArch64_bfd_copy_private_bfd_data_common
> > +#define _bfd_XX_bfd_copy_private_section_data
> > 	_bfd_peAArch64_bfd_copy_private_section_data
> > +#define _bfd_XX_get_symbol_info
> > 	_bfd_peAArch64_get_symbol_info
> > +#define _bfd_XX_only_swap_filehdr_out
> > 	_bfd_peAArch64_only_swap_filehdr_out
> > +#define _bfd_XX_print_private_bfd_data_common
> > 	_bfd_peAArch64_print_private_bfd_data_common
> > +#define _bfd_XXi_final_link_postscript
> > 	_bfd_peAArch64i_final_link_postscript
> > +#define _bfd_XXi_only_swap_filehdr_out
> > 	_bfd_peAArch64i_only_swap_filehdr_out
> > +#define _bfd_XXi_swap_aouthdr_in
> > 	_bfd_peAArch64i_swap_aouthdr_in
> > +#define _bfd_XXi_swap_aouthdr_out
> > 	_bfd_peAArch64i_swap_aouthdr_out
> > +#define _bfd_XXi_swap_aux_in
> > 	_bfd_peAArch64i_swap_aux_in
> > +#define _bfd_XXi_swap_aux_out
> > 	_bfd_peAArch64i_swap_aux_out
> > +#define _bfd_XXi_swap_lineno_in
> > 	_bfd_peAArch64i_swap_lineno_in
> > +#define _bfd_XXi_swap_lineno_out
> > 	_bfd_peAArch64i_swap_lineno_out
> > +#define _bfd_XXi_swap_scnhdr_out
> > 	_bfd_peAArch64i_swap_scnhdr_out
> > +#define _bfd_XXi_swap_sym_in
> > 	_bfd_peAArch64i_swap_sym_in
> > +#define _bfd_XXi_swap_sym_out
> > 	_bfd_peAArch64i_swap_sym_out
> > +#define _bfd_XXi_swap_debugdir_in
> > 	_bfd_peAArch64i_swap_debugdir_in
> > +#define _bfd_XXi_swap_debugdir_out
> > 	_bfd_peAArch64i_swap_debugdir_out
> > +#define _bfd_XXi_write_codeview_record
> > 	_bfd_peAArch64i_write_codeview_record
> > +#define _bfd_XXi_slurp_codeview_record
> > 	_bfd_peAArch64i_slurp_codeview_record
> > +
> >  #else /* !COFF_WITH_pep */
> >
> >  #define GET_OPTHDR_IMAGE_BASE H_GET_32 @@ -369,5 +404,6 @@
> bool
> > _bfd_XX_bfd_copy_private_section_data
> >  bool _bfd_pe_print_ce_compressed_pdata (bfd *, void *);  bool
> > _bfd_pe64_print_ce_compressed_pdata (bfd *, void *);  bool
> > _bfd_pex64_print_ce_compressed_pdata (bfd *, void *);
> > +bool _bfd_peAArch64_print_ce_compressed_pdata (bfd *, void *);
> >  bool _bfd_pep_print_ce_compressed_pdata (bfd *, void *);
> >
> > diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index
> >
> c41c3299277846875ee7eca9ca00e530b2683d61..1bfd6c89f1943fe0cf4155111d
> > 55b511be3dcc7b 100644
> > --- a/bfd/peXXigen.c
> > +++ b/bfd/peXXigen.c
> > @@ -60,8 +60,9 @@
> >     on this code has a chance of getting something accomplished without
> >     wasting too much time.  */
> >
> > -/* This expands into COFF_WITH_pe, COFF_WITH_pep, or
> > COFF_WITH_pex64
> > -   depending on whether we're compiling for straight PE or PE+.  */
> > +/* This expands into COFF_WITH_pe, COFF_WITH_pep,
> COFF_WITH_pex64
> > or
> > +   COFF_WITH_peAArch64 depending on whether we're compiling for
> > straight
> > +   PE or PE+.  */
> >  #define COFF_WITH_XX
> >
> >  #include "sysdep.h"
> > @@ -83,6 +84,8 @@
> >  # include "coff/x86_64.h"
> >  #elif defined COFF_WITH_pep
> >  # include "coff/ia64.h"
> > +#elif defined COFF_WITH_peAArch64
> > +# include "coff/aarch64.h"
> >  #else
> >  # include "coff/i386.h"
> >  #endif
> > @@ -92,7 +95,7 @@
> >  #include "libpei.h"
> >  #include "safe-ctype.h"
> >
> > -#if defined COFF_WITH_pep || defined COFF_WITH_pex64
> > +#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined
> > +COFF_WITH_peAArch64
> >  # undef AOUTSZ
> >  # define AOUTSZ		PEPAOUTSZ
> >  # define PEAOUTHDR	PEPAOUTHDR
> > @@ -469,7 +472,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
> >    aouthdr_int->text_start =
> >      GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
> >
> > -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >    /* PE32+ does not have data_start member!  */
> >    aouthdr_int->data_start =
> >      GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start); @@ -
> > 555,7 +558,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
> >    if (aouthdr_int->entry)
> >      {
> >        aouthdr_int->entry += a->ImageBase; -#if
> > !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >        aouthdr_int->entry &= 0xffffffff;  #endif
> >      }
> > @@ -563,12 +566,12 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
> >    if (aouthdr_int->tsize)
> >      {
> >        aouthdr_int->text_start += a->ImageBase; - #if
> > !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >        aouthdr_int->text_start &= 0xffffffff;  #endif
> >      }
> >
> > -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >    /* PE32+ does not have data_start member!  */
> >    if (aouthdr_int->dsize)
> >      {
> > @@ -628,7 +631,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in,
> > void * out)
> >    if (aouthdr_in->tsize)
> >      {
> >        aouthdr_in->text_start -= ib;
> > -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >        aouthdr_in->text_start &= 0xffffffff;  #endif
> >      }
> > @@ -636,7 +639,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in,
> > void * out)
> >    if (aouthdr_in->dsize)
> >      {
> >        aouthdr_in->data_start -= ib;
> > -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >        aouthdr_in->data_start &= 0xffffffff;  #endif
> >      }
> > @@ -644,7 +647,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in,
> > void * out)
> >    if (aouthdr_in->entry)
> >      {
> >        aouthdr_in->entry -= ib;
> > -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >        aouthdr_in->entry &= 0xffffffff;  #endif
> >      }
> > @@ -748,7 +751,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in,
> > void * out)
> >    PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
> >  			  aouthdr_out->standard.text_start);
> >
> > -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >    /* PE32+ does not have data_start member!  */
> >    PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
> >  			  aouthdr_out->standard.data_start);
> > @@ -1800,7 +1803,7 @@ pe_print_edata (bfd * abfd, void * vfile)
> > static bool pe_print_pdata (bfd * abfd, void * vfile)  { -#if
> > defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >  # define PDATA_ROW_SIZE	(3 * 8)
> >  #else
> >  # define PDATA_ROW_SIZE	(5 * 4)
> > @@ -1827,7 +1830,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
> >
> >    fprintf (file,
> >  	   _("\nThe Function Table (interpreted .pdata section
> > contents)\n")); -#if defined(COFF_WITH_pep) &&
> > !defined(COFF_WITH_pex64)
> > +#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >    fprintf (file,
> >  	   _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
> >  #else
> > @@ -1864,7 +1867,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
> >        bfd_vma eh_handler;
> >        bfd_vma eh_data;
> >        bfd_vma prolog_end_addr;
> > -#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) ||
> > +defined(COFF_WITH_peAArch64)
> >        int em_data;
> >  #endif
> >
> > @@ -1882,7 +1885,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
> >  	/* We are probably into the padding of the section now.  */
> >  	break;
> >
> > -#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) ||
> > +defined(COFF_WITH_peAArch64)
> >        em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
> #endif
> >        eh_handler &= ~(bfd_vma) 0x3;
> > @@ -1893,7 +1896,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
> >        bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
> >        bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
> >        bfd_fprintf_vma (abfd, file, eh_handler); -#if
> > !defined(COFF_WITH_pep)
> > || defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) ||
> > +defined(COFF_WITH_peAArch64)
> >        fputc (' ', file);
> >        bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
> >        bfd_fprintf_vma (abfd, file, prolog_end_addr); @@ -2784,7
> > +2787,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void
> * vfile)
> >    bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
> >    fprintf (file, "\nBaseOfCode\t\t");
> >    bfd_fprintf_vma (abfd, file, i->BaseOfCode); - #if
> > !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >    /* PE32+ does not have BaseOfData member!  */
> >    fprintf (file, "\nBaseOfData\t\t");
> >    bfd_fprintf_vma (abfd, file, i->BaseOfData); @@ -3085,7 +3088,7 @@
> > _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info
> *ret)
> >    coff_get_symbol_info (abfd, symbol, ret);  }
> >
> > -#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64) &&
> > +defined(COFF_WITH_peAArch64)
> >  static int
> >  sort_x64_pdata (const void *l, const void *r)  { @@ -4504,7 +4507,7
> > @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info
> *pfinfo)
> >  	the TLS data directory consists of 4 pointers, followed
> >  	by two 4-byte integer. This implies that the total size
> >  	is different for 32-bit and 64-bit executables.  */ - #if
> > !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) &&
> > +!defined(COFF_WITH_peAArch64)
> >        pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size =
> > 0x18; #else
> >        pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size =
> > 0x28; @@ -4513,7 +4516,7 @@ _bfd_XXi_final_link_postscript (bfd *
> > abfd, struct coff_final_link_info *pfinfo)
> >
> >  /* If there is a .pdata section and we have linked pdata finally, we
> >       need to sort the entries ascending.  */ -#if
> > !defined(COFF_WITH_pep) &&
> > defined(COFF_WITH_pex64)
> > +#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64) &&
> > +defined(COFF_WITH_peAArch64)
> >    {
> >      asection *sec = bfd_get_section_by_name (abfd, ".pdata");
> >
> > diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c new file mode
> > 100644 index
> >
> 0000000000000000000000000000000000000000..99326d1612655408f1b5ceea7
> > a013e1768083498
> > --- /dev/null
> > +++ b/bfd/pei-aarch64.c
> > @@ -0,0 +1,75 @@
> > +/* 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_pei_vec
> > +#define TARGET_NAME		"pei-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
> > +
> > +#define COFF_IMAGE_WITH_PE
> > +/* 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/peicode.h b/bfd/peicode.h index
> >
> 41955975cdc621df3f53165a934a0d999140f09e..1e8ed803edc6e269eb84c0800
> > 7eb0ce568d75a16 100644
> > --- a/bfd/peicode.h
> > +++ b/bfd/peicode.h
> > @@ -231,7 +231,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void *
> in)
> >      {
> >        scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
> >        /* Do not cut upper 32-bits for 64-bit vma.  */ -#ifndef
> > COFF_WITH_pex64
> > +#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
> >        scnhdr_int->s_vaddr &= 0xffffffff;  #endif
> >      }
> > @@ -738,6 +738,16 @@ static const jump_table jtab[] =
> >    },
> >  #endif
> >
> > +#ifdef AARCH64MAGIC
> > +/* We don't currently support jumping to DLLs, so if
> > +   someone does try emit a runtime trap.  Through UDF #0.  */
> > +  { AARCH64MAGIC,
> > +    { 0x00, 0x00, 0x00, 0x00 },
> > +    4, 0
> > +  },
> > +
> > +#endif
> > +
> >  #ifdef  ARMPEMAGIC
> >    { ARMPEMAGIC,
> >      { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
> > @@ -910,7 +920,7 @@ pe_ILF_build_a_bfd (bfd *	    abfd,
> >  	/* See PR 20907 for a reproducer.  */
> >  	goto error_return;
> >
> > -#ifdef COFF_WITH_pex64
> > +#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
> >        ((unsigned int *) id4->contents)[0] = ordinal;
> >        ((unsigned int *) id4->contents)[1] = 0x80000000;
> >        ((unsigned int *) id5->contents)[0] = ordinal; @@ -1206,6
> > +1216,12 @@ pe_ILF_object_p (bfd * abfd)  #endif
> >        break;
> >
> > +    case IMAGE_FILE_MACHINE_ARM64:
> > +#ifdef AARCH64MAGIC
> > +      magic = AARCH64MAGIC;
> > +#endif
> > +      break;
> > +
> >      case IMAGE_FILE_MACHINE_THUMB:
> >  #ifdef THUMBPEMAGIC
> >        {
> > diff --git a/bfd/targets.c b/bfd/targets.c index
> >
> 8f5abb174e2dfecad62008b68f381d89b423576d..672dc2bb1a4d5643f84577d81
> > d4c9cebc14429d9 100644
> > --- a/bfd/targets.c
> > +++ b/bfd/targets.c
> > @@ -679,6 +679,7 @@ 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 alpha_ecoff_le_vec;  extern const bfd_target
> > alpha_elf64_vec;  extern const bfd_target alpha_elf64_fbsd_vec; @@
> > -993,6
> > +994,7 @@ static const bfd_target * const _bfd_target_vector[] =
> >  	&aarch64_elf64_le_vec,
> >  	&aarch64_elf64_le_cloudabi_vec,
> >  	&aarch64_mach_o_vec,
> > +	&aarch64_pei_vec,
> >  #endif
> >
> >  #ifdef BFD64
> > diff --git a/binutils/NEWS b/binutils/NEWS index
> >
> e6977b650db6c70cce6efeba43fce7435519099e..994546330f95ccc3b859ffb173
> > 88b2cc5ec6a653 100644
> > --- a/binutils/NEWS
> > +++ b/binutils/NEWS
> > @@ -2,6 +2,9 @@
> >
> >  * Add support for the LoongArch instruction set.
> >
> > +* Support for efi-app-aarch64, efi-rtdrv-aarch64 and
> > +efi-bsdrv-aarch64 has been
> > +  added to objcopy in order to enable UEFI development using binutils.
> > +
> >  Changes in 2.37:
> >
> >  * The readelf tool has a new command line option which can be used to
> > specify diff --git a/binutils/objcopy.c b/binutils/objcopy.c index
> >
> 0e7400fe4cb7046fa704f207816616e623de65af..458a6d96cccbeb154f95e5ba54
> > 734b956d14f879 100644
> > --- a/binutils/objcopy.c
> > +++ b/binutils/objcopy.c
> > @@ -4996,6 +4996,13 @@ convert_efi_target (char *efi)
> >        /* Change x86_64 to x86-64.  */
> >        efi[7] = '-';
> >      }
> > +  else if (strcmp (efi + 4, "aarch64") == 0)
> > +    {
> > +      /* Change aarch64 to aarch64-little.  */
> > +      efi = (char *) xrealloc (efi, strlen (efi) + 7);
> > +      char *t = "aarch64-little";
> > +      strcpy (efi + 4, t);
> > +    }
> >  }
> >
> >  /* Allocate and return a pointer to a struct section_add,
> > initializing the diff -- git
> > a/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
> > b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
> > new file mode 100644
> > index
> >
> 0000000000000000000000000000000000000000..0957c985359c049adb4f085a94
> > ddc4ff03c91794
> > --- /dev/null
> > +++ b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d
> > @@ -0,0 +1,16 @@
> > +#skip: aarch64_be-*-*
> > +#ld: -e0
> > +#PROG: objcopy
> > +#objcopy: -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel
> > +-j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* -j .reloc
> > +--target=efi-app-aarch64
> > +#objdump: -h -f
> > +#name: Check if efi app format is recognized
> > +
> > +.*:     file format pei-aarch64-little
> > +architecture: aarch64, flags 0x00000132:
> > +EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED start address
> > +0x0000000000000000
> > +
> > +Sections:
> > +Idx Name          Size      VMA               LMA               File off  Algn
> > +  0 \.text         00000030  0000000000400000  0000000000400000  00000200
> > 2\*\*2
> > +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> > diff --git
> > a/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
> > b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
> > new file mode 100644
> > index
> >
> 0000000000000000000000000000000000000000..dafc5fa47f9713b541a8d25274
> > 8f9621affce5fc
> > --- /dev/null
> > +++ b/binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s
> > @@ -0,0 +1,42 @@
> > +	.arch armv8-a
> > +	.text
> > +	.align	2
> > +	.global	foo
> > +	.type	foo, %function
> > +foo:
> > +.LFB0:
> > +	.cfi_startproc
> > +	sub	sp, sp, #16
> > +	.cfi_def_cfa_offset 16
> > +	str	w0, [sp, 12]
> > +	ldr	w0, [sp, 12]
> > +	mul	w0, w0, w0
> > +	add	sp, sp, 16
> > +	.cfi_def_cfa_offset 0
> > +	ret
> > +	.cfi_endproc
> > +.LFE0:
> > +	.size	foo, .-foo
> > +	.align	2
> > +	.global	main
> > +	.type	main, %function
> > +main:
> > +.LFB1:
> > +	.cfi_startproc
> > +	stp	x29, x30, [sp, -16]!
> > +	.cfi_def_cfa_offset 16
> > +	.cfi_offset 29, -16
> > +	.cfi_offset 30, -8
> > +	mov	x29, sp
> > +	mov	w0, 5
> > +	bl	foo
> > +	ldp	x29, x30, [sp], 16
> > +	.cfi_restore 30
> > +	.cfi_restore 29
> > +	.cfi_def_cfa_offset 0
> > +	ret
> > +	.cfi_endproc
> > +.LFE1:
> > +	.size	main, .-main
> > +	.ident	"GCC: (fsf-trunk.2870) 12.0.0 20210930 (experimental)"
> > +	.section	.note.GNU-stack,"",@progbits
> > diff --git a/include/coff/aarch64.h b/include/coff/aarch64.h new file
> > mode
> > 100644 index
> >
> 0000000000000000000000000000000000000000..2c21f0d6cfdac4cb0debbee60
> > 030226fa70106d2
> > --- /dev/null
> > +++ b/include/coff/aarch64.h
> > @@ -0,0 +1,63 @@
> > +/* AArch64 COFF support for BFD.
> > +   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.
> > + */
> > +
> > +#define COFFAARCH64 1
> > +
> > +#define L_LNNO_SIZE 2
> > +#define INCLUDE_COMDAT_FIELDS_IN_AUXENT #include
> "coff/external.h"
> > +
> > +#define F_AARCH64_ARCHITECTURE_MASK	(0x4000)
> > +
> > +#define	AARCH64MAGIC	0xaa64  /* From Microsoft
> > specification. */
> > +
> > +#undef  BADMAG
> > +#define BADMAG(x) ((x).f_magic != AARCH64MAGIC)
> > +#define AARCH64         1                 /* Customize coffcode.h.  */
> > +
> > +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
> > +
> > +#define OMAGIC          0404    /* Object files, eg as output.  */
> > +#define ZMAGIC          IMAGE_NT_OPTIONAL_HDR64_MAGIC    /*
> Demand
> > load format, eg normal ld output 0x10b.  */
> > +#define STMAGIC		0401	/* Target shlib.  */
> > +#define SHMAGIC		0443	/* Host   shlib.  */
> > +
> > +/* define some NT default values */
> > +/*  #define NT_IMAGE_BASE        0x400000 moved to internal.h */
> > +#define NT_SECTION_ALIGNMENT 0x1000
> > +#define NT_FILE_ALIGNMENT    0x200
> > +#define NT_DEF_RESERVE       0x100000
> > +#define NT_DEF_COMMIT        0x1000
> > +
> > +/* We use the .rdata section to hold read only data.  */
> > +#define _LIT	".rdata"
> > +
> > +/********************** RELOCATION DIRECTIVES
> > **********************/
> > +struct external_reloc {
> > +  char r_vaddr[4];
> > +  char r_symndx[4];
> > +  char r_type[2];
> > +  char r_offset[4];
> > +};
> > +
> > +#define RELOC struct external_reloc
> > +#define RELSZ 14
> > +
> > +#define ARM_NOTE_SECTION ".note"
> > diff --git a/include/coff/pe.h b/include/coff/pe.h index
> >
> 9e1ea4b5aa47b8278a0e7a88fad2db5dd8bc9fc5..558cf0e1b86f008f613d107bc
> > 72368b3811143ee 100644
> > --- a/include/coff/pe.h
> > +++ b/include/coff/pe.h
> > @@ -137,6 +137,7 @@
> >  #define IMAGE_FILE_MACHINE_AM33              0x01d3
> >  #define IMAGE_FILE_MACHINE_AMD64             0x8664
> >  #define IMAGE_FILE_MACHINE_ARM               0x01c0
> > +#define IMAGE_FILE_MACHINE_ARM64             0xaa64
> >  #define IMAGE_FILE_MACHINE_AXP64
> > IMAGE_FILE_MACHINE_ALPHA64
> >  #define IMAGE_FILE_MACHINE_CEE               0xc0ee
> >  #define IMAGE_FILE_MACHINE_CEF               0x0cef
> >
> >
> > --

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

* Re: [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-aarch64).
  2021-10-29 11:05 [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-aarch64) Tamar Christina
  2021-11-05 17:39 ` Tamar Christina
@ 2021-11-18  8:04 ` Nick Clifton
  1 sibling, 0 replies; 4+ messages in thread
From: Nick Clifton @ 2021-11-18  8:04 UTC (permalink / raw)
  To: Tamar Christina, binutils; +Cc: Richard.Earnshaw, nd, marcus.shawcroft

Hi Tamar,

> This adds support for efi-*-aarch64 by virtue of adding a new PEI target
> pei-aarch64-little.  This is not a full target and only exists to support EFI
> at this time.
  Sorry for the very late review of this patch.

The code itself looks fine, but I did encounter one new binutils testsuite failure.
This was for an aarch64-linux-gnu toolchain and the failure was:

   regexp_diff match failure
   regexp "^  0 \.text         00000030  0000000000400000  0000000000400000  00000200  2\*\*2$"
   line   "  0 .text         00000030  00000000004000b0  00000000004000b0  000002b0  2**2"
   FAIL: Check if efi app format is recognized

So your patch is approved provided that you make a small update to the regexp for
this particular test.

Cheers
   Nick


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

end of thread, other threads:[~2021-11-18  8:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-29 11:05 [PATCH][Binutils]AArch64 Add support for AArch64 EFI (efi-*-aarch64) Tamar Christina
2021-11-05 17:39 ` Tamar Christina
2021-11-12  6:10   ` Tamar Christina
2021-11-18  8:04 ` Nick Clifton

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