Browse Source
This adds support for efi-loongarch64 by virtue of adding a new PEI target
pei-loongarch64. 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 loongarch64 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.
We should't limit addresses to 32-bits for 64-bit vma, otherwise there will be
"RVA truncated" error when using objcopy on loongarch64.
With these changes the resulting file is recognized as an efi image.
Any magic number is based on the Microsoft PE specification [1].
The test results are as follows:
$ make check-binutils RUNTESTFLAGS='loongarch64.exp'
PASS: Check if efi app format is recognized
$ objdump -h -f tmpdir/loongarch64copy.o
tmpdir/loongarch64copy.o: file format pei-loongarch64
architecture: Loongarch64, flags 0x00000132:
EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x0000000000000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000003c 00000000200000b0 00000000200000b0 00000200 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
[1] https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
bfd:
* .gitignore (pe-loongarch64igen.c): New.
* Makefile.am (pei-loongarch64.lo, pe-loongarch64igen.lo, pei-loongarch64.c,
pe-loongarch64igen.c): Add support.
* Makefile.in: Likewise.
* bfd.c (bfd_get_sign_extend_vma): Add pei-loongarch64.
* coff-loongarch64.c: New file.
* coffcode.h (coff_set_arch_mach_hook, coff_set_flags,
coff_write_object_contents) Add loongarch64 (loongarch64_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_peLoongArch64_bfd_copy_private_bfd_data_common,
_bfd_peLoongArch64_bfd_copy_private_section_data,
_bfd_peLoongArch64_get_symbol_info, _bfd_peLoongArch64_only_swap_filehdr_out,
_bfd_peLoongArch64_print_private_bfd_data_common,
_bfd_peLoongArch64i_final_link_postscript,
_bfd_peLoongArch64i_only_swap_filehdr_out, _bfd_peLoongArch64i_swap_aouthdr_in,
_bfd_peLoongArch64i_swap_aouthdr_out, _bfd_peLoongArch64i_swap_aux_in,
_bfd_peLoongArch64i_swap_aux_out, _bfd_peLoongArch64i_swap_lineno_in,
_bfd_peLoongArch64i_swap_lineno_out, _bfd_peLoongArch64i_swap_scnhdr_out,
_bfd_peLoongArch64i_swap_sym_in, _bfd_peLoongArch64i_swap_sym_out,
_bfd_peLoongArch64i_swap_debugdir_in, _bfd_peLoongArch64i_swap_debugdir_out,
_bfd_peLoongArch64i_write_codeview_record,
_bfd_peLoongArch64i_slurp_codeview_record,
_bfd_peLoongArch64_print_ce_compressed_pdata): New.
* peXXigen.c (_bfd_XXi_swap_aouthdr_in, _bfd_XXi_swap_aouthdr_out,
_bfd_XXi_swap_scnhdr_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_peLoongArch64,
* pei-loongarch64.c: New file.
* peicode.h (coff_swap_scnhdr_in, pe_ILF_build_a_bfd, pe_ILF_object_p):
Support COFF_WITH_peLoongArch64.
(jtab): Add dummy entry that traps.
* targets.c (loongarch64_pei_vec): New.
binutils
* testsuite/binutils-all/loongarch64/loongarch64.exp: New file.
* testsuite/binutils-all/loongarch64/pei-loongarch64.d: New test.
* testsuite/binutils-all/loongarch64/pei-loongarch64.s: New test.
include
* coff/loongarch64.h: New file.
* coff/pe.h (IMAGE_FILE_MACHINE_LOONGARCH64): New.
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
users/aburgess/try-mips-disasm-styling
committed by
liuzhensong
19 changed files with 506 additions and 27 deletions
@ -0,0 +1,165 @@ |
|||
/* BFD back-end for LoongArch64 COFF files.
|
|||
Copyright (C) 2022 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_peLoongArch64 |
|||
#define COFF_WITH_peLoongArch64 |
|||
#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/loongarch64.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 0x4000 |
|||
|
|||
/* 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_loongarch64_std_reloc_howto[] = |
|||
{ |
|||
|
|||
}; |
|||
|
|||
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2 |
|||
|
|||
#ifndef NUM_ELEM |
|||
#define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0])) |
|||
#endif |
|||
|
|||
#define NUM_RELOCS NUM_ELEM (pe_loongarch64_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 |
|||
loongarch64_pei_vec = |
|||
#endif |
|||
{ |
|||
#ifdef TARGET_NAME |
|||
TARGET_NAME, |
|||
#else |
|||
"pei-loongarch64", /* 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 |
|||
}; |
|||
@ -0,0 +1,75 @@ |
|||
/* BFD back-end for LoongArch64 PE IMAGE COFF files.
|
|||
Copyright (C) 2022 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 loongarch64_pei_vec |
|||
#define TARGET_NAME "pei-loongarch64" |
|||
#define TARGET_ARCHITECTURE bfd_arch_loongarch |
|||
#define TARGET_PAGESIZE 0x4000 |
|||
#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_peLoongArch64 |
|||
#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/loongarch64.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-loongarch64.c" |
|||
@ -0,0 +1,30 @@ |
|||
# Copyright (C) 2022 Free Software Foundation, Inc. |
|||
|
|||
# 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. |
|||
|
|||
if {![istarget "loongarch64*-*-*"] |
|||
|| ![is_elf_format]} then { |
|||
return |
|||
} |
|||
|
|||
set tempfile tmpdir/loongarch64temp.o |
|||
set copyfile tmpdir/loongarch64copy |
|||
|
|||
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] |
|||
foreach t $test_list { |
|||
# We need to strip the ".d", but can leave the dirname. |
|||
verbose [file rootname $t] |
|||
run_dump_test [file rootname $t] |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
#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=pei-loongarch64 |
|||
#objdump: -h -f |
|||
#name: Check if efi app format is recognized |
|||
|
|||
.*: file format pei-loongarch64 |
|||
architecture: Loongarch64, flags 0x00000132: |
|||
EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED |
|||
start address 0x0000000000000000 |
|||
|
|||
Sections: |
|||
Idx Name Size VMA LMA File off Algn |
|||
0 \.text 0000003c 0[^ ]+ 0[^ ]+ 0[^ ]+ 2\*\*2 |
|||
CONTENTS, ALLOC, LOAD, READONLY, CODE |
|||
@ -0,0 +1,33 @@ |
|||
.file "test_pei.c" |
|||
.text |
|||
.align 2 |
|||
.globl main |
|||
.type main, @function |
|||
main: |
|||
.LFB0 = . |
|||
.cfi_startproc |
|||
addi.d $r3,$r3,-32 |
|||
.cfi_def_cfa_offset 32 |
|||
st.d $r22,$r3,24 |
|||
.cfi_offset 22, -8 |
|||
addi.d $r22,$r3,32 |
|||
.cfi_def_cfa 22, 0 |
|||
addi.w $r12,$r0,1 # 0x1 |
|||
st.w $r12,$r22,-20 |
|||
addi.w $r12,$r0,2 # 0x2 |
|||
st.w $r12,$r22,-24 |
|||
ld.w $r13,$r22,-20 |
|||
ld.w $r12,$r22,-24 |
|||
mul.w $r12,$r13,$r12 |
|||
slli.w $r12,$r12,0 |
|||
or $r4,$r12,$r0 |
|||
ld.d $r22,$r3,24 |
|||
.cfi_restore 22 |
|||
addi.d $r3,$r3,32 |
|||
.cfi_def_cfa_register 3 |
|||
jr $r1 |
|||
.cfi_endproc |
|||
.LFE0: |
|||
.size main, .-main |
|||
.ident "GCC: (GNU) 12.1.0" |
|||
.section .note.GNU-stack,"",@progbits |
|||
@ -0,0 +1,61 @@ |
|||
/* LoongArch64 COFF support for BFD.
|
|||
Copyright (C) 2022 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 COFFLOONGARCH64 1 |
|||
|
|||
#define L_LNNO_SIZE 2 |
|||
#define INCLUDE_COMDAT_FIELDS_IN_AUXENT |
|||
#include "coff/external.h" |
|||
|
|||
#define F_LOONGARCH64_ARCHITECTURE_MASK (0x4000) |
|||
|
|||
#define LOONGARCH64MAGIC 0x6264 /* From Microsoft specification. */ |
|||
|
|||
#undef BADMAG |
|||
#define BADMAG(x) ((x).f_magic != LOONGARCH64MAGIC) |
|||
#define LOONGARCH64 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 |
|||
Loading…
Reference in new issue