diff options
-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 | 169 | ||||
-rw-r--r-- | bfd/coffcode.h | 19 | ||||
-rw-r--r-- | bfd/config.bfd | 2 | ||||
-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 | ||||
-rw-r--r-- | binutils/objcopy.c | 7 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.d | 16 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/aarch64/pei-aarch64-little.s | 42 | ||||
-rw-r--r-- | include/coff/aarch64.h | 63 | ||||
-rw-r--r-- | include/coff/pe.h | 1 |
19 files changed, 494 insertions, 26 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 ed2f701..a4c13c1 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -570,8 +570,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 = \ @@ -609,6 +611,7 @@ BFD64_BACKENDS_CFILES = \ pe-x86_64.c \ pei-ia64.c \ pei-x86_64.c \ + pei-aarch64.c \ vms-alpha.c OPTIONAL_BACKENDS = \ @@ -666,7 +669,7 @@ BUILD_CFILES = \ elf32-aarch64.c elf64-aarch64.c \ elf32-ia64.c elf64-ia64.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) @@ -862,6 +865,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 12807d9..e78091f 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -997,8 +997,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 = \ @@ -1036,6 +1038,7 @@ BFD64_BACKENDS_CFILES = \ pe-x86_64.c \ pei-ia64.c \ pei-x86_64.c \ + pei-aarch64.c \ vms-alpha.c OPTIONAL_BACKENDS = \ @@ -1092,7 +1095,7 @@ BUILD_CFILES = \ elf32-aarch64.c elf64-aarch64.c \ elf32-ia64.c elf64-ia64.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 = \ @@ -1551,9 +1554,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@ @@ -1991,6 +1996,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..b4dcc81 --- /dev/null +++ b/bfd/coff-aarch64.c @@ -0,0 +1,169 @@ +/* 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 = \ + (dst)->r_type < NUM_RELOCS \ + ? pe_aarch64_std_reloc_howto + (dst)->r_type \ + : 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 d5d9153..86e9561 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 ab51257..7546a73 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -247,7 +247,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) diff --git a/bfd/configure b/bfd/configure index cae69d4..21bc018 100755 --- a/bfd/configure +++ b/bfd/configure @@ -13256,6 +13256,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 9ff303a..24b5fd1 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 c41c329..1bfd6c8 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 c84b135..9374e23 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 89b49e7..ae6075b 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; @@ -991,6 +992,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/objcopy.c b/binutils/objcopy.c index a6c2e0d..fe3ea29 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -4987,6 +4987,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 0000000..0957c98 --- /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 0000000..dafc5fa --- /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 0000000..2c21f0d --- /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 9e1ea4b..558cf0e 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 |