bfd: Add support for LoongArch64 EFI (efi-*-loongarch64).

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>
This commit is contained in:
Youling Tang 2022-08-06 14:49:43 +08:00 committed by liuzhensong
parent 4c3cb23cc0
commit 31f6009538
19 changed files with 506 additions and 27 deletions

1
bfd/.gitignore vendored
View File

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

View File

@ -573,9 +573,11 @@ BFD64_BACKENDS = \
mach-o-x86-64.lo \ mach-o-x86-64.lo \
mmo.lo \ mmo.lo \
pe-aarch64igen.lo \ pe-aarch64igen.lo \
pe-loongarch64igen.lo \
pe-x86_64.lo \ pe-x86_64.lo \
pei-aarch64.lo \ pei-aarch64.lo \
pei-ia64.lo \ pei-ia64.lo \
pei-loongarch64.lo \
pei-x86_64.lo \ pei-x86_64.lo \
pepigen.lo \ pepigen.lo \
pex64igen.lo \ pex64igen.lo \
@ -618,6 +620,7 @@ BFD64_BACKENDS_CFILES = \
pe-x86_64.c \ pe-x86_64.c \
pei-aarch64.c \ pei-aarch64.c \
pei-ia64.c \ pei-ia64.c \
pei-loongarch64.c \
pei-x86_64.c \ pei-x86_64.c \
vms-alpha.c vms-alpha.c
@ -677,7 +680,7 @@ BUILD_CFILES = \
elf32-ia64.c elf64-ia64.c \ elf32-ia64.c elf64-ia64.c \
elf32-loongarch.c elf64-loongarch.c \ elf32-loongarch.c elf64-loongarch.c \
elf32-riscv.c elf64-riscv.c \ elf32-riscv.c elf64-riscv.c \
peigen.c pepigen.c pex64igen.c pe-aarch64igen.c peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c
CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
@ -894,6 +897,10 @@ pe-aarch64igen.c: peXXigen.c
$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
$(AM_V_GEN)$(SED) -e s/XX/peAArch64/g < $< >> $@ $(AM_V_GEN)$(SED) -e s/XX/peAArch64/g < $< >> $@
pe-loongarch64igen.c: peXXigen.c
$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
$(AM_V_GEN)$(SED) -e s/XX/peLoongArch64/g < $< >> $@
host-aout.lo: Makefile host-aout.lo: Makefile
# The following program can be used to generate a simple config file # The following program can be used to generate a simple config file

View File

@ -1036,9 +1036,11 @@ BFD64_BACKENDS = \
mach-o-x86-64.lo \ mach-o-x86-64.lo \
mmo.lo \ mmo.lo \
pe-aarch64igen.lo \ pe-aarch64igen.lo \
pe-loongarch64igen.lo \
pe-x86_64.lo \ pe-x86_64.lo \
pei-aarch64.lo \ pei-aarch64.lo \
pei-ia64.lo \ pei-ia64.lo \
pei-loongarch64.lo \
pei-x86_64.lo \ pei-x86_64.lo \
pepigen.lo \ pepigen.lo \
pex64igen.lo \ pex64igen.lo \
@ -1081,6 +1083,7 @@ BFD64_BACKENDS_CFILES = \
pe-x86_64.c \ pe-x86_64.c \
pei-aarch64.c \ pei-aarch64.c \
pei-ia64.c \ pei-ia64.c \
pei-loongarch64.c \
pei-x86_64.c \ pei-x86_64.c \
vms-alpha.c vms-alpha.c
@ -1139,7 +1142,7 @@ BUILD_CFILES = \
elf32-ia64.c elf64-ia64.c \ elf32-ia64.c elf64-ia64.c \
elf32-loongarch.c elf64-loongarch.c \ elf32-loongarch.c elf64-loongarch.c \
elf32-riscv.c elf64-riscv.c \ elf32-riscv.c elf64-riscv.c \
peigen.c pepigen.c pex64igen.c pe-aarch64igen.c peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c
CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
SOURCE_HFILES = \ SOURCE_HFILES = \
@ -1690,6 +1693,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm-wince.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm-wince.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-i386.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-i386.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-loongarch64igen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-mcore.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-mcore.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-sh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-sh.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-x86_64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-x86_64.Plo@am__quote@
@ -1699,6 +1703,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-arm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-arm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-i386.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-i386.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-ia64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-ia64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-loongarch64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-mcore.Plo@am__quote@ @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-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-x86_64.Plo@am__quote@
@ -2401,6 +2406,10 @@ pe-aarch64igen.c: peXXigen.c
$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
$(AM_V_GEN)$(SED) -e s/XX/peAArch64/g < $< >> $@ $(AM_V_GEN)$(SED) -e s/XX/peAArch64/g < $< >> $@
pe-loongarch64igen.c: peXXigen.c
$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
$(AM_V_GEN)$(SED) -e s/XX/peLoongArch64/g < $< >> $@
host-aout.lo: Makefile host-aout.lo: Makefile
# The following program can be used to generate a simple config file # The following program can be used to generate a simple config file

View File

@ -1743,6 +1743,7 @@ bfd_get_sign_extend_vma (bfd *abfd)
|| strcmp (name, "pei-aarch64-little") == 0 || strcmp (name, "pei-aarch64-little") == 0
|| strcmp (name, "pe-arm-wince-little") == 0 || strcmp (name, "pe-arm-wince-little") == 0
|| strcmp (name, "pei-arm-wince-little") == 0 || strcmp (name, "pei-arm-wince-little") == 0
|| strcmp (name, "pei-loongarch64") == 0
|| strcmp (name, "aixcoff-rs6000") == 0 || strcmp (name, "aixcoff-rs6000") == 0
|| strcmp (name, "aix5coff64-rs6000") == 0) || strcmp (name, "aix5coff64-rs6000") == 0)
return 1; return 1;

165
bfd/coff-loongarch64.c Normal file
View File

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

View File

@ -2231,6 +2231,12 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
machine = internal_f->f_flags & F_AARCH64_ARCHITECTURE_MASK; machine = internal_f->f_flags & F_AARCH64_ARCHITECTURE_MASK;
break; break;
#endif #endif
#ifdef LOONGARCH64MAGIC
case LOONGARCH64MAGIC:
arch = bfd_arch_loongarch;
machine = internal_f->f_flags & F_LOONGARCH64_ARCHITECTURE_MASK;
break;
#endif
#ifdef Z80MAGIC #ifdef Z80MAGIC
case Z80MAGIC: case Z80MAGIC:
arch = bfd_arch_z80; arch = bfd_arch_z80;
@ -2795,6 +2801,12 @@ coff_set_flags (bfd * abfd,
return true; return true;
#endif #endif
#ifdef LOONGARCH64MAGIC
case bfd_arch_loongarch:
* magicp = LOONGARCH64MAGIC;
return true;
#endif
#ifdef ARMMAGIC #ifdef ARMMAGIC
case bfd_arch_arm: case bfd_arch_arm:
#ifdef ARM_WINCE #ifdef ARM_WINCE
@ -3890,7 +3902,7 @@ coff_write_object_contents (bfd * abfd)
internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE; internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
#endif #endif
#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
#ifdef COFF_WITH_PE #ifdef COFF_WITH_PE
internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE; internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;
#else #else
@ -3944,6 +3956,11 @@ coff_write_object_contents (bfd * abfd)
internal_a.magic = ZMAGIC; internal_a.magic = ZMAGIC;
#endif #endif
#if defined(LOONGARCH64)
#define __A_MAGIC_SET__
internal_a.magic = ZMAGIC;
#endif
#if defined MCORE_PE #if defined MCORE_PE
#define __A_MAGIC_SET__ #define __A_MAGIC_SET__
internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;

View File

@ -1465,7 +1465,7 @@ case "${targ}" in
loongarch64-*) loongarch64-*)
targ_defvec=loongarch_elf64_vec targ_defvec=loongarch_elf64_vec
targ_selvecs="loongarch_elf32_vec loongarch_elf64_vec" targ_selvecs="loongarch_elf32_vec loongarch_elf64_vec loongarch64_pei_vec"
want64=true want64=true
;; ;;
#endif #endif

1
bfd/configure vendored
View File

@ -13415,6 +13415,7 @@ do
lm32_elf32_fdpic_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;; lm32_elf32_fdpic_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
loongarch_elf32_vec) tb="$tb elf32-loongarch.lo elfxx-loongarch.lo elf32.lo elf-ifunc.lo $elf" ;; loongarch_elf32_vec) tb="$tb elf32-loongarch.lo elfxx-loongarch.lo elf32.lo elf-ifunc.lo $elf" ;;
loongarch_elf64_vec) tb="$tb elf64-loongarch.lo elf64.lo elfxx-loongarch.lo elf32.lo elf-ifunc.lo $elf"; target_size=64 ;; loongarch_elf64_vec) tb="$tb elf64-loongarch.lo elf64.lo elfxx-loongarch.lo elf32.lo elf-ifunc.lo $elf"; target_size=64 ;;
loongarch64_pei_vec) tb="$tb pei-loongarch64.lo pe-loongarch64igen.lo $coff"; target_size=64 ;;
m32c_elf32_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;; m32c_elf32_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
m32r_elf32_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;; m32r_elf32_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
m32r_elf32_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;; m32r_elf32_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;

View File

@ -494,6 +494,7 @@ do
lm32_elf32_fdpic_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;; lm32_elf32_fdpic_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
loongarch_elf32_vec) tb="$tb elf32-loongarch.lo elfxx-loongarch.lo elf32.lo elf-ifunc.lo $elf" ;; loongarch_elf32_vec) tb="$tb elf32-loongarch.lo elfxx-loongarch.lo elf32.lo elf-ifunc.lo $elf" ;;
loongarch_elf64_vec) tb="$tb elf64-loongarch.lo elf64.lo elfxx-loongarch.lo elf32.lo elf-ifunc.lo $elf"; target_size=64 ;; loongarch_elf64_vec) tb="$tb elf64-loongarch.lo elf64.lo elfxx-loongarch.lo elf32.lo elf-ifunc.lo $elf"; target_size=64 ;;
loongarch64_pei_vec) tb="$tb pei-loongarch64.lo pe-loongarch64igen.lo $coff"; target_size=64 ;;
m32c_elf32_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;; m32c_elf32_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
m32r_elf32_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;; m32r_elf32_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
m32r_elf32_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;; m32r_elf32_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;

View File

@ -310,6 +310,41 @@
#define _bfd_XXi_write_codeview_record _bfd_peAArch64i_write_codeview_record #define _bfd_XXi_write_codeview_record _bfd_peAArch64i_write_codeview_record
#define _bfd_XXi_slurp_codeview_record _bfd_peAArch64i_slurp_codeview_record #define _bfd_XXi_slurp_codeview_record _bfd_peAArch64i_slurp_codeview_record
#elif defined COFF_WITH_peLoongArch64
#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_peLoongArch64_bfd_copy_private_bfd_data_common
#define _bfd_XX_bfd_copy_private_section_data _bfd_peLoongArch64_bfd_copy_private_section_data
#define _bfd_XX_get_symbol_info _bfd_peLoongArch64_get_symbol_info
#define _bfd_XX_only_swap_filehdr_out _bfd_peLoongArch64_only_swap_filehdr_out
#define _bfd_XX_print_private_bfd_data_common _bfd_peLoongArch64_print_private_bfd_data_common
#define _bfd_XXi_final_link_postscript _bfd_peLoongArch64i_final_link_postscript
#define _bfd_XXi_only_swap_filehdr_out _bfd_peLoongArch64i_only_swap_filehdr_out
#define _bfd_XXi_swap_aouthdr_in _bfd_peLoongArch64i_swap_aouthdr_in
#define _bfd_XXi_swap_aouthdr_out _bfd_peLoongArch64i_swap_aouthdr_out
#define _bfd_XXi_swap_aux_in _bfd_peLoongArch64i_swap_aux_in
#define _bfd_XXi_swap_aux_out _bfd_peLoongArch64i_swap_aux_out
#define _bfd_XXi_swap_lineno_in _bfd_peLoongArch64i_swap_lineno_in
#define _bfd_XXi_swap_lineno_out _bfd_peLoongArch64i_swap_lineno_out
#define _bfd_XXi_swap_scnhdr_out _bfd_peLoongArch64i_swap_scnhdr_out
#define _bfd_XXi_swap_sym_in _bfd_peLoongArch64i_swap_sym_in
#define _bfd_XXi_swap_sym_out _bfd_peLoongArch64i_swap_sym_out
#define _bfd_XXi_swap_debugdir_in _bfd_peLoongArch64i_swap_debugdir_in
#define _bfd_XXi_swap_debugdir_out _bfd_peLoongArch64i_swap_debugdir_out
#define _bfd_XXi_write_codeview_record _bfd_peLoongArch64i_write_codeview_record
#define _bfd_XXi_slurp_codeview_record _bfd_peLoongArch64i_slurp_codeview_record
#else /* !COFF_WITH_pep */ #else /* !COFF_WITH_pep */
#define GET_OPTHDR_IMAGE_BASE H_GET_32 #define GET_OPTHDR_IMAGE_BASE H_GET_32
@ -405,5 +440,6 @@ bool _bfd_pe_print_ce_compressed_pdata (bfd *, void *);
bool _bfd_pe64_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_pex64_print_ce_compressed_pdata (bfd *, void *);
bool _bfd_peAArch64_print_ce_compressed_pdata (bfd *, void *); bool _bfd_peAArch64_print_ce_compressed_pdata (bfd *, void *);
bool _bfd_peLoongArch64_print_ce_compressed_pdata (bfd *, void *);
bool _bfd_pep_print_ce_compressed_pdata (bfd *, void *); bool _bfd_pep_print_ce_compressed_pdata (bfd *, void *);

View File

@ -60,9 +60,9 @@
on this code has a chance of getting something accomplished without on this code has a chance of getting something accomplished without
wasting too much time. */ wasting too much time. */
/* This expands into COFF_WITH_pe, COFF_WITH_pep, COFF_WITH_pex64 or /* This expands into COFF_WITH_pe, COFF_WITH_pep, COFF_WITH_pex64,
COFF_WITH_peAArch64 depending on whether we're compiling for straight COFF_WITH_peAArch64 or COFF_WITH_peLoongArch64 depending on whether we're
PE or PE+. */ compiling for straight PE or PE+. */
#define COFF_WITH_XX #define COFF_WITH_XX
#include "sysdep.h" #include "sysdep.h"
@ -86,6 +86,8 @@
# include "coff/ia64.h" # include "coff/ia64.h"
#elif defined COFF_WITH_peAArch64 #elif defined COFF_WITH_peAArch64
# include "coff/aarch64.h" # include "coff/aarch64.h"
#elif defined COFF_WITH_peLoongArch64
# include "coff/loongarch64.h"
#else #else
# include "coff/i386.h" # include "coff/i386.h"
#endif #endif
@ -95,7 +97,7 @@
#include "libpei.h" #include "libpei.h"
#include "safe-ctype.h" #include "safe-ctype.h"
#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64 #if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64
# undef AOUTSZ # undef AOUTSZ
# define AOUTSZ PEPAOUTSZ # define AOUTSZ PEPAOUTSZ
# define PEAOUTHDR PEPAOUTHDR # define PEAOUTHDR PEPAOUTHDR
@ -472,7 +474,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
aouthdr_int->text_start = aouthdr_int->text_start =
GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start); GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
/* PE32+ does not have data_start member! */ /* PE32+ does not have data_start member! */
aouthdr_int->data_start = aouthdr_int->data_start =
GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start); GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
@ -558,7 +560,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
if (aouthdr_int->entry) if (aouthdr_int->entry)
{ {
aouthdr_int->entry += a->ImageBase; aouthdr_int->entry += a->ImageBase;
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
aouthdr_int->entry &= 0xffffffff; aouthdr_int->entry &= 0xffffffff;
#endif #endif
} }
@ -566,12 +568,12 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
if (aouthdr_int->tsize) if (aouthdr_int->tsize)
{ {
aouthdr_int->text_start += a->ImageBase; aouthdr_int->text_start += a->ImageBase;
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
aouthdr_int->text_start &= 0xffffffff; aouthdr_int->text_start &= 0xffffffff;
#endif #endif
} }
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
/* PE32+ does not have data_start member! */ /* PE32+ does not have data_start member! */
if (aouthdr_int->dsize) if (aouthdr_int->dsize)
{ {
@ -631,7 +633,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
if (aouthdr_in->tsize) if (aouthdr_in->tsize)
{ {
aouthdr_in->text_start -= ib; aouthdr_in->text_start -= ib;
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
aouthdr_in->text_start &= 0xffffffff; aouthdr_in->text_start &= 0xffffffff;
#endif #endif
} }
@ -639,7 +641,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
if (aouthdr_in->dsize) if (aouthdr_in->dsize)
{ {
aouthdr_in->data_start -= ib; aouthdr_in->data_start -= ib;
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
aouthdr_in->data_start &= 0xffffffff; aouthdr_in->data_start &= 0xffffffff;
#endif #endif
} }
@ -647,7 +649,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
if (aouthdr_in->entry) if (aouthdr_in->entry)
{ {
aouthdr_in->entry -= ib; aouthdr_in->entry -= ib;
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
aouthdr_in->entry &= 0xffffffff; aouthdr_in->entry &= 0xffffffff;
#endif #endif
} }
@ -761,7 +763,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start, PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
aouthdr_out->standard.text_start); aouthdr_out->standard.text_start);
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
/* PE32+ does not have data_start member! */ /* PE32+ does not have data_start member! */
PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
aouthdr_out->standard.data_start); aouthdr_out->standard.data_start);
@ -946,9 +948,14 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
if (scnhdr_int->s_vaddr < pe_data (abfd)->pe_opthdr.ImageBase) if (scnhdr_int->s_vaddr < pe_data (abfd)->pe_opthdr.ImageBase)
_bfd_error_handler (_("%pB:%.8s: section below image base"), _bfd_error_handler (_("%pB:%.8s: section below image base"),
abfd, scnhdr_int->s_name); abfd, scnhdr_int->s_name);
/* Do not compare lower 32-bits for 64-bit vma. */
#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
else if(ss != (ss & 0xffffffff)) else if(ss != (ss & 0xffffffff))
_bfd_error_handler (_("%pB:%.8s: RVA truncated"), abfd, scnhdr_int->s_name); _bfd_error_handler (_("%pB:%.8s: RVA truncated"), abfd, scnhdr_int->s_name);
PUT_SCNHDR_VADDR (abfd, ss & 0xffffffff, scnhdr_ext->s_vaddr); PUT_SCNHDR_VADDR (abfd, ss & 0xffffffff, scnhdr_ext->s_vaddr);
#else
PUT_SCNHDR_VADDR (abfd, ss, scnhdr_ext->s_vaddr);
#endif
/* NT wants the size data to be rounded up to the next /* NT wants the size data to be rounded up to the next
NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss, NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
@ -1813,7 +1820,7 @@ pe_print_edata (bfd * abfd, void * vfile)
static bool static bool
pe_print_pdata (bfd * abfd, void * vfile) pe_print_pdata (bfd * abfd, void * vfile)
{ {
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
# define PDATA_ROW_SIZE (3 * 8) # define PDATA_ROW_SIZE (3 * 8)
#else #else
# define PDATA_ROW_SIZE (5 * 4) # define PDATA_ROW_SIZE (5 * 4)
@ -1840,7 +1847,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
fprintf (file, fprintf (file,
_("\nThe Function Table (interpreted .pdata section contents)\n")); _("\nThe Function Table (interpreted .pdata section contents)\n"));
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
fprintf (file, fprintf (file,
_(" vma:\t\t\tBegin Address End Address Unwind Info\n")); _(" vma:\t\t\tBegin Address End Address Unwind Info\n"));
#else #else
@ -1877,7 +1884,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
bfd_vma eh_handler; bfd_vma eh_handler;
bfd_vma eh_data; bfd_vma eh_data;
bfd_vma prolog_end_addr; bfd_vma prolog_end_addr;
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
int em_data; int em_data;
#endif #endif
@ -1895,7 +1902,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
/* We are probably into the padding of the section now. */ /* We are probably into the padding of the section now. */
break; break;
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3); em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
#endif #endif
eh_handler &= ~(bfd_vma) 0x3; eh_handler &= ~(bfd_vma) 0x3;
@ -1906,7 +1913,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file); bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file); bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
bfd_fprintf_vma (abfd, file, eh_handler); bfd_fprintf_vma (abfd, file, eh_handler);
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
fputc (' ', file); fputc (' ', file);
bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file); bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
bfd_fprintf_vma (abfd, file, prolog_end_addr); bfd_fprintf_vma (abfd, file, prolog_end_addr);
@ -2797,7 +2804,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint); bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
fprintf (file, "\nBaseOfCode\t\t"); fprintf (file, "\nBaseOfCode\t\t");
bfd_fprintf_vma (abfd, file, i->BaseOfCode); bfd_fprintf_vma (abfd, file, i->BaseOfCode);
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
/* PE32+ does not have BaseOfData member! */ /* PE32+ does not have BaseOfData member! */
fprintf (file, "\nBaseOfData\t\t"); fprintf (file, "\nBaseOfData\t\t");
bfd_fprintf_vma (abfd, file, i->BaseOfData); bfd_fprintf_vma (abfd, file, i->BaseOfData);
@ -3112,7 +3119,7 @@ _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
coff_get_symbol_info (abfd, symbol, ret); coff_get_symbol_info (abfd, symbol, ret);
} }
#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)) #if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64))
static int static int
sort_x64_pdata (const void *l, const void *r) sort_x64_pdata (const void *l, const void *r)
{ {
@ -4531,7 +4538,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
the TLS data directory consists of 4 pointers, followed the TLS data directory consists of 4 pointers, followed
by two 4-byte integer. This implies that the total size by two 4-byte integer. This implies that the total size
is different for 32-bit and 64-bit executables. */ is different for 32-bit and 64-bit executables. */
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) #if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18; pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
#else #else
pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28; pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
@ -4540,7 +4547,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 /* If there is a .pdata section and we have linked pdata finally, we
need to sort the entries ascending. */ need to sort the entries ascending. */
#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)) #if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64))
{ {
asection *sec = bfd_get_section_by_name (abfd, ".pdata"); asection *sec = bfd_get_section_by_name (abfd, ".pdata");

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

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

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; scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
/* Do not cut upper 32-bits for 64-bit vma. */ /* 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; scnhdr_int->s_vaddr &= 0xffffffff;
#endif #endif
} }
@ -763,6 +763,17 @@ static const jump_table jtab[] =
16, 12 16, 12
}, },
#endif #endif
#ifdef LOONGARCH64MAGIC
/* We don't currently support jumping to DLLs, so if
someone does try emit a runtime trap. Through BREAK 0. */
{ LOONGARCH64MAGIC,
{ 0x00, 0x00, 0x2a, 0x00 },
4, 0
},
#endif
{ 0, { 0 }, 0, 0 } { 0, { 0 }, 0, 0 }
}; };
@ -920,7 +931,7 @@ pe_ILF_build_a_bfd (bfd * abfd,
/* See PR 20907 for a reproducer. */ /* See PR 20907 for a reproducer. */
goto error_return; 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)[0] = ordinal;
((unsigned int *) id4->contents)[1] = 0x80000000; ((unsigned int *) id4->contents)[1] = 0x80000000;
((unsigned int *) id5->contents)[0] = ordinal; ((unsigned int *) id5->contents)[0] = ordinal;
@ -1222,6 +1233,12 @@ pe_ILF_object_p (bfd * abfd)
#endif #endif
break; break;
case IMAGE_FILE_MACHINE_LOONGARCH64:
#ifdef LOONGARCH64MAGIC
magic = LOONGARCH64MAGIC;
#endif
break;
case IMAGE_FILE_MACHINE_THUMB: case IMAGE_FILE_MACHINE_THUMB:
#ifdef THUMBPEMAGIC #ifdef THUMBPEMAGIC
{ {

View File

@ -768,6 +768,7 @@ extern const bfd_target lm32_elf32_vec;
extern const bfd_target lm32_elf32_fdpic_vec; extern const bfd_target lm32_elf32_fdpic_vec;
extern const bfd_target loongarch_elf64_vec; extern const bfd_target loongarch_elf64_vec;
extern const bfd_target loongarch_elf32_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 m32c_elf32_vec;
extern const bfd_target m32r_elf32_vec; extern const bfd_target m32r_elf32_vec;
extern const bfd_target m32r_elf32_le_vec; extern const bfd_target m32r_elf32_le_vec;
@ -1358,6 +1359,7 @@ static const bfd_target * const _bfd_target_vector[] =
#ifdef BFD64 #ifdef BFD64
&loongarch_elf32_vec, &loongarch_elf32_vec,
&loongarch_elf64_vec, &loongarch_elf64_vec,
&loongarch64_pei_vec,
#endif #endif
#endif /* not SELECT_VECS */ #endif /* not SELECT_VECS */

View File

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

View File

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

View File

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

View File

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

View File

@ -163,6 +163,7 @@
#define IMAGE_FILE_MACHINE_TRICORE 0x0520 #define IMAGE_FILE_MACHINE_TRICORE 0x0520
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 #define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
#define IMAGE_FILE_MACHINE_AMD64 0x8664 #define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264
#define IMAGE_SUBSYSTEM_UNKNOWN 0 #define IMAGE_SUBSYSTEM_UNKNOWN 0
#define IMAGE_SUBSYSTEM_NATIVE 1 #define IMAGE_SUBSYSTEM_NATIVE 1