[PATCH] bfd: Add support for LoongArch64 EFI (efi-*-loongarch64).
WANG Xuerui
i.swmail@xen0n.name
Fri Aug 5 09:41:57 GMT 2022
On 2022/8/5 10:26, Youling Tang wrote:
> 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
> * NEWS: Add new support.
> * 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>
> ---
> bfd/.gitignore | 1 +
> bfd/Makefile.am | 9 +-
> bfd/Makefile.in | 11 +-
> bfd/bfd.c | 1 +
> bfd/coff-loongarch64.c | 165 ++++++++++++++++++
> bfd/coffcode.h | 19 +-
> bfd/config.bfd | 2 +-
> bfd/configure | 1 +
> bfd/configure.ac | 1 +
> bfd/libpei.h | 36 ++++
> bfd/peXXigen.c | 49 +++---
> bfd/pei-loongarch64.c | 75 ++++++++
> bfd/peicode.h | 21 ++-
> bfd/targets.c | 2 +
> binutils/NEWS | 3 +
> .../binutils-all/loongarch64/loongarch64.exp | 30 ++++
> .../loongarch64/pei-loongarch64.d | 15 ++
> .../loongarch64/pei-loongarch64.s | 33 ++++
> include/coff/loongarch64.h | 61 +++++++
> include/coff/pe.h | 1 +
> 20 files changed, 509 insertions(+), 27 deletions(-)
> create mode 100644 bfd/coff-loongarch64.c
> create mode 100644 bfd/pei-loongarch64.c
> create mode 100644 binutils/testsuite/binutils-all/loongarch64/loongarch64.exp
> create mode 100644 binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.d
> create mode 100644 binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.s
> create mode 100644 include/coff/loongarch64.h
>
> <snip>
>
> diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
> index 5ab09387e72..ba12cf8cba0 100644
> --- a/bfd/peXXigen.c
> +++ b/bfd/peXXigen.c
> @@ -60,9 +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, COFF_WITH_pex64 or
> - COFF_WITH_peAArch64 depending on whether we're compiling for straight
> - PE or PE+. */
> +/* This expands into COFF_WITH_pe, COFF_WITH_pep, COFF_WITH_pex64 ,
Nit: extra space before the comma.
> + COFF_WITH_peAArch64 or COFF_WITH_peLoongArch64 depending on whether we're
> + compiling for straight PE or PE+. */
> #define COFF_WITH_XX
>
> #include "sysdep.h"
>
> <snip>
>
> diff --git a/bfd/pei-loongarch64.c b/bfd/pei-loongarch64.c
> new file mode 100644
> index 00000000000..28220074157
> --- /dev/null
> +++ b/bfd/pei-loongarch64.c
> @@ -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.. */
I know this is copied from bfd/pei-aarch64.c, but you could reformat it
a little by adding an additional period and space, for style consistency.
> +#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"
> diff --git a/bfd/peicode.h b/bfd/peicode.h
> index 02573c84694..a337493994c 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. */
> -#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
> +#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
> scnhdr_int->s_vaddr &= 0xffffffff;
> #endif
> }
> @@ -763,6 +763,17 @@ static const jump_table jtab[] =
> 16, 12
> },
> #endif
> +
> +#ifdef LOONGARCH64MAGIC
> +/* We don't currently support jumping to DLLs, so if
> + someone does try emit a runtime trap. Through UDF #0. */
> + { LOONGARCH64MAGIC,
> + { 0x00, 0x00, 0x00, 0x00 },
I think "UDF #0" is an ARM instruction. Here I think we could use a
"BREAK 0" or something like that instead... The instruction word for
BREAK 0 is 0x002a0000, FYI.
> + 4, 0
> + },
> +
> +#endif
> +
> { 0, { 0 }, 0, 0 }
> };
>
> @@ -920,7 +931,7 @@ pe_ILF_build_a_bfd (bfd * abfd,
> /* See PR 20907 for a reproducer. */
> goto error_return;
>
> -#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
> +#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
> ((unsigned int *) id4->contents)[0] = ordinal;
> ((unsigned int *) id4->contents)[1] = 0x80000000;
> ((unsigned int *) id5->contents)[0] = ordinal;
> @@ -1222,6 +1233,12 @@ pe_ILF_object_p (bfd * abfd)
> #endif
> break;
>
> + case IMAGE_FILE_MACHINE_LOONGARCH64:
> +#ifdef LOONGARCH64MAGIC
> + magic = LOONGARCH64MAGIC;
> +#endif
> + break;
> +
> case IMAGE_FILE_MACHINE_THUMB:
> #ifdef THUMBPEMAGIC
> {
> diff --git a/bfd/targets.c b/bfd/targets.c
> index 3284bb88aa8..8ad3ef366ce 100644
> --- a/bfd/targets.c
> +++ b/bfd/targets.c
> @@ -768,6 +768,7 @@ extern const bfd_target lm32_elf32_vec;
> extern const bfd_target lm32_elf32_fdpic_vec;
> extern const bfd_target loongarch_elf64_vec;
> extern const bfd_target loongarch_elf32_vec;
> +extern const bfd_target loongarch64_pei_vec;
> extern const bfd_target m32c_elf32_vec;
> extern const bfd_target m32r_elf32_vec;
> extern const bfd_target m32r_elf32_le_vec;
> @@ -1358,6 +1359,7 @@ static const bfd_target * const _bfd_target_vector[] =
> #ifdef BFD64
> &loongarch_elf32_vec,
> &loongarch_elf64_vec,
> + &loongarch64_pei_vec,
> #endif
>
> #endif /* not SELECT_VECS */
> diff --git a/binutils/NEWS b/binutils/NEWS
> index 4fdf1c3b4e8..3b5a96b9819 100644
> --- a/binutils/NEWS
> +++ b/binutils/NEWS
> @@ -14,6 +14,9 @@ Changes in 2.39:
> architectures. Use the --disassembler-color=MODE command line flag, with
> mode being either off, color, or extended-color.
>
> +* Support for pei-loongarch64 has been added to objcopy in order to enable
> + UEFI development using binutils.
> +
Isn't binutils 2.39 already frozen?
> Changes in 2.38:
>
> * elfedit: Add --output-abiversion option to update ABIVERSION.
> diff --git a/binutils/testsuite/binutils-all/loongarch64/loongarch64.exp b/binutils/testsuite/binutils-all/loongarch64/loongarch64.exp
> new file mode 100644
> index 00000000000..bd1d5eba036
> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/loongarch64/loongarch64.exp
> @@ -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]
> +}
> diff --git a/binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.d b/binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.d
> new file mode 100644
> index 00000000000..574b3e5448d
> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.d
> @@ -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
> diff --git a/binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.s b/binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.s
> new file mode 100644
> index 00000000000..1e6710ac2c2
> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.s
> @@ -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
> diff --git a/include/coff/loongarch64.h b/include/coff/loongarch64.h
> new file mode 100644
> index 00000000000..b80ca42a12d
> --- /dev/null
> +++ b/include/coff/loongarch64.h
> @@ -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
> diff --git a/include/coff/pe.h b/include/coff/pe.h
> index c17465000dc..da600e1c781 100644
> --- a/include/coff/pe.h
> +++ b/include/coff/pe.h
> @@ -163,6 +163,7 @@
> #define IMAGE_FILE_MACHINE_TRICORE 0x0520
> #define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
> #define IMAGE_FILE_MACHINE_AMD64 0x8664
> +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264
>
> #define IMAGE_SUBSYSTEM_UNKNOWN 0
> #define IMAGE_SUBSYSTEM_NATIVE 1
More information about the Binutils
mailing list