Compare commits

...

1 Commits

Author SHA1 Message Date
Tamar Christina
981118a8b7 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 tagret 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.

As such it's not valid for use with gas but only with objcopy.

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/26218
	* .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/26218
	* 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/26218
	* coff/aarch64.h: New file.
	* coff/pe.h (IMAGE_FILE_MACHINE_ARM64): New.
2021-10-21 16:53:27 +01:00
19 changed files with 494 additions and 26 deletions

1
bfd/.gitignore vendored
View File

@@ -10,6 +10,7 @@
/peigen.c
/pepigen.c
/pex64igen.c
/pe-aarch64igen.c
/stmp-bfd-h
/targmatch.h

View File

@@ -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) \

View File

@@ -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) \

View File

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

169
bfd/coff-aarch64.c Normal file
View File

@@ -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
};

View File

@@ -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;

View File

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

1
bfd/configure vendored
View File

@@ -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 ;;

View File

@@ -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 ;;

View File

@@ -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 *);

View File

@@ -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");

75
bfd/pei-aarch64.c Normal file
View File

@@ -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"

View File

@@ -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
{

View File

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

View File

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

View File

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

View File

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

63
include/coff/aarch64.h Normal file
View File

@@ -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"

View File

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