diff options
author | Tamar Christina <tamar.christina@arm.com> | 2021-11-23 09:36:39 +0000 |
---|---|---|
committer | Tamar Christina <tamar.christina@arm.com> | 2021-11-23 09:36:39 +0000 |
commit | b69c9d41e89498442cb5af5287f378b3583dd445 (patch) | |
tree | 2e7a9d40deb5b1b17bd16b6556f73bd33db3f0a9 /bfd | |
parent | 0c3e266dc283a45a23185be3bb49e4d33987a892 (diff) | |
download | gdb-b69c9d41e89498442cb5af5287f378b3583dd445.zip gdb-b69c9d41e89498442cb5af5287f378b3583dd445.tar.gz gdb-b69c9d41e89498442cb5af5287f378b3583dd445.tar.bz2 |
AArch64: Add support for AArch64 EFI (efi-*-aarch64).
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: 1970-01-01 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
bfd/ChangeLog:
2021-10-21 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-21 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-21 Tamar Christina <tamar.christina@arm.com>
PR binutils/26206
* coff/aarch64.h: New file.
* coff/pe.h (IMAGE_FILE_MACHINE_ARM64): New.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/.gitignore | 1 | ||||
-rw-r--r-- | bfd/Makefile.am | 9 | ||||
-rw-r--r-- | bfd/Makefile.in | 12 | ||||
-rw-r--r-- | bfd/bfd.c | 1 | ||||
-rw-r--r-- | bfd/coff-aarch64.c | 166 | ||||
-rw-r--r-- | bfd/coffcode.h | 19 | ||||
-rw-r--r-- | bfd/config.bfd | 4 | ||||
-rwxr-xr-x | bfd/configure | 1 | ||||
-rw-r--r-- | bfd/configure.ac | 1 | ||||
-rw-r--r-- | bfd/libpei.h | 36 | ||||
-rw-r--r-- | bfd/peXXigen.c | 43 | ||||
-rw-r--r-- | bfd/pei-aarch64.c | 75 | ||||
-rw-r--r-- | bfd/peicode.h | 20 | ||||
-rw-r--r-- | bfd/targets.c | 2 |
14 files changed, 363 insertions, 27 deletions
diff --git a/bfd/.gitignore b/bfd/.gitignore index 0a5530d..d4f7423 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 097177b..d0798c3 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -572,7 +572,9 @@ BFD64_BACKENDS = \ mach-o-aarch64.lo \ mach-o-x86-64.lo \ mmo.lo \ + pe-aarch64igen.lo \ pe-x86_64.lo \ + pei-aarch64lo \ pei-ia64.lo \ pei-x86_64.lo \ pepigen.lo \ @@ -613,6 +615,7 @@ BFD64_BACKENDS_CFILES = \ mach-o-x86-64.c \ mmo.c \ pe-x86_64.c \ + pei-aarch64.c \ pei-ia64.c \ pei-x86_64.c \ vms-alpha.c @@ -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 a76b653..b946643 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -999,7 +999,9 @@ BFD64_BACKENDS = \ mach-o-aarch64.lo \ mach-o-x86-64.lo \ mmo.lo \ + pe-aarch64igen.lo \ pe-x86_64.lo \ + pei-aarch64.lo \ pei-ia64.lo \ pei-x86_64.lo \ pepigen.lo \ @@ -1040,6 +1042,7 @@ BFD64_BACKENDS_CFILES = \ mach-o-x86-64.c \ mmo.c \ pe-x86_64.c \ + pei-aarch64.c \ pei-ia64.c \ pei-x86_64.c \ vms-alpha.c @@ -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) \ @@ -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 0000000..a9bc417 --- /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 f0b73a9..e2b2566 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -2225,6 +2225,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; @@ -2781,6 +2787,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 @@ -3876,7 +3888,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 @@ -3925,6 +3937,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 3cf3227..7769182 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 b55e98e..eb782e7 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 fc38571..aa16d92 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 4de0c9f..26589e8 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 e2a9cbb..5f977ea 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 0000000..99326d1 --- /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 4195597..1e8ed80 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 8f5abb1..672dc2b 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 |