aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/.gitignore1
-rw-r--r--bfd/Makefile.am9
-rw-r--r--bfd/Makefile.in11
-rw-r--r--bfd/bfd.c1
-rw-r--r--bfd/coff-loongarch64.c165
-rw-r--r--bfd/coffcode.h19
-rw-r--r--bfd/config.bfd2
-rwxr-xr-xbfd/configure1
-rw-r--r--bfd/configure.ac1
-rw-r--r--bfd/libpei.h36
-rw-r--r--bfd/peXXigen.c49
-rw-r--r--bfd/pei-loongarch64.c75
-rw-r--r--bfd/peicode.h21
-rw-r--r--bfd/targets.c2
-rw-r--r--binutils/testsuite/binutils-all/loongarch64/loongarch64.exp30
-rw-r--r--binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.d15
-rw-r--r--binutils/testsuite/binutils-all/loongarch64/pei-loongarch64.s33
-rw-r--r--include/coff/loongarch64.h61
-rw-r--r--include/coff/pe.h1
19 files changed, 506 insertions, 27 deletions
diff --git a/bfd/.gitignore b/bfd/.gitignore
index 065ed99..e93eb65 100644
--- a/bfd/.gitignore
+++ b/bfd/.gitignore
@@ -11,6 +11,7 @@
/pepigen.c
/pex64igen.c
/pe-aarch64igen.c
+/pe-loongarch64igen.c
/stmp-bfd-h
/targmatch.h
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 670e059..2fa8df4 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -573,9 +573,11 @@ BFD64_BACKENDS = \
mach-o-x86-64.lo \
mmo.lo \
pe-aarch64igen.lo \
+ pe-loongarch64igen.lo \
pe-x86_64.lo \
pei-aarch64.lo \
pei-ia64.lo \
+ pei-loongarch64.lo \
pei-x86_64.lo \
pepigen.lo \
pex64igen.lo \
@@ -618,6 +620,7 @@ BFD64_BACKENDS_CFILES = \
pe-x86_64.c \
pei-aarch64.c \
pei-ia64.c \
+ pei-loongarch64.c \
pei-x86_64.c \
vms-alpha.c
@@ -677,7 +680,7 @@ BUILD_CFILES = \
elf32-ia64.c elf64-ia64.c \
elf32-loongarch.c elf64-loongarch.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)
@@ -894,6 +897,10 @@ pe-aarch64igen.c: peXXigen.c
$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
$(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
# The following program can be used to generate a simple config file
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 330096a..3547556 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1036,9 +1036,11 @@ BFD64_BACKENDS = \
mach-o-x86-64.lo \
mmo.lo \
pe-aarch64igen.lo \
+ pe-loongarch64igen.lo \
pe-x86_64.lo \
pei-aarch64.lo \
pei-ia64.lo \
+ pei-loongarch64.lo \
pei-x86_64.lo \
pepigen.lo \
pex64igen.lo \
@@ -1081,6 +1083,7 @@ BFD64_BACKENDS_CFILES = \
pe-x86_64.c \
pei-aarch64.c \
pei-ia64.c \
+ pei-loongarch64.c \
pei-x86_64.c \
vms-alpha.c
@@ -1139,7 +1142,7 @@ BUILD_CFILES = \
elf32-ia64.c elf64-ia64.c \
elf32-loongarch.c elf64-loongarch.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)
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.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-sh.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-i386.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-sh.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_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
# The following program can be used to generate a simple config file
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 5e5272b..5297177 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1743,6 +1743,7 @@ bfd_get_sign_extend_vma (bfd *abfd)
|| strcmp (name, "pei-aarch64-little") == 0
|| strcmp (name, "pe-arm-wince-little") == 0
|| strcmp (name, "pei-arm-wince-little") == 0
+ || strcmp (name, "pei-loongarch64") == 0
|| strcmp (name, "aixcoff-rs6000") == 0
|| strcmp (name, "aix5coff64-rs6000") == 0)
return 1;
diff --git a/bfd/coff-loongarch64.c b/bfd/coff-loongarch64.c
new file mode 100644
index 0000000..8013737
--- /dev/null
+++ b/bfd/coff-loongarch64.c
@@ -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
+};
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 798b9f2..67aaf15 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -2231,6 +2231,12 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
machine = internal_f->f_flags & F_AARCH64_ARCHITECTURE_MASK;
break;
#endif
+#ifdef LOONGARCH64MAGIC
+ case LOONGARCH64MAGIC:
+ arch = bfd_arch_loongarch;
+ machine = internal_f->f_flags & F_LOONGARCH64_ARCHITECTURE_MASK;
+ break;
+#endif
#ifdef Z80MAGIC
case Z80MAGIC:
arch = bfd_arch_z80;
@@ -2795,6 +2801,12 @@ coff_set_flags (bfd * abfd,
return true;
#endif
+#ifdef LOONGARCH64MAGIC
+ case bfd_arch_loongarch:
+ * magicp = LOONGARCH64MAGIC;
+ return true;
+#endif
+
#ifdef ARMMAGIC
case bfd_arch_arm:
#ifdef ARM_WINCE
@@ -3890,7 +3902,7 @@ coff_write_object_contents (bfd * abfd)
internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
#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
internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;
#else
@@ -3944,6 +3956,11 @@ coff_write_object_contents (bfd * abfd)
internal_a.magic = ZMAGIC;
#endif
+#if defined(LOONGARCH64)
+#define __A_MAGIC_SET__
+ internal_a.magic = ZMAGIC;
+#endif
+
#if defined MCORE_PE
#define __A_MAGIC_SET__
internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
diff --git a/bfd/config.bfd b/bfd/config.bfd
index a4c6c8e..c514479 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -1465,7 +1465,7 @@ case "${targ}" in
loongarch64-*)
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
;;
#endif
diff --git a/bfd/configure b/bfd/configure
index 9632f52..b5e44e6 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -13415,6 +13415,7 @@ do
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_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" ;;
m32r_elf32_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
m32r_elf32_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index 2d4f82e..fb8795b 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -494,6 +494,7 @@ do
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_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" ;;
m32r_elf32_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
m32r_elf32_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
diff --git a/bfd/libpei.h b/bfd/libpei.h
index 4aca024..dcf42f9 100644
--- a/bfd/libpei.h
+++ b/bfd/libpei.h
@@ -310,6 +310,41 @@
#define _bfd_XXi_write_codeview_record _bfd_peAArch64i_write_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 */
#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_pex64_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 *);
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 5ab0938..a7b8571 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,
+ 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"
@@ -86,6 +86,8 @@
# include "coff/ia64.h"
#elif defined COFF_WITH_peAArch64
# include "coff/aarch64.h"
+#elif defined COFF_WITH_peLoongArch64
+# include "coff/loongarch64.h"
#else
# include "coff/i386.h"
#endif
@@ -95,7 +97,7 @@
#include "libpei.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
# define AOUTSZ PEPAOUTSZ
# define PEAOUTHDR PEPAOUTHDR
@@ -472,7 +474,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) && !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! */
aouthdr_int->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)
{
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;
#endif
}
@@ -566,12 +568,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) && !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;
#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! */
if (aouthdr_int->dsize)
{
@@ -631,7 +633,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) && !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;
#endif
}
@@ -639,7 +641,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) && !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;
#endif
}
@@ -647,7 +649,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) && !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;
#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,
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! */
PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->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)
_bfd_error_handler (_("%pB:%.8s: section below image base"),
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))
_bfd_error_handler (_("%pB:%.8s: RVA truncated"), abfd, scnhdr_int->s_name);
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_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
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)
#else
# define PDATA_ROW_SIZE (5 * 4)
@@ -1840,7 +1847,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) && !defined(COFF_WITH_peAArch64)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
fprintf (file,
_(" vma:\t\t\tBegin Address End Address Unwind Info\n"));
#else
@@ -1877,7 +1884,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) || defined(COFF_WITH_peAArch64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
int em_data;
#endif
@@ -1895,7 +1902,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) || 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);
#endif
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, end_addr); fputc (' ', file);
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);
bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
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);
fprintf (file, "\nBaseOfCode\t\t");
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! */
fprintf (file, "\nBaseOfData\t\t");
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);
}
-#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
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
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) && !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;
#else
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
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");
diff --git a/bfd/pei-loongarch64.c b/bfd/pei-loongarch64.c
new file mode 100644
index 0000000..7221fe6
--- /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... */
+#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 02573c8..54a159f 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 BREAK 0. */
+ { LOONGARCH64MAGIC,
+ { 0x00, 0x00, 0x2a, 0x00 },
+ 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 3284bb8..8ad3ef3 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/testsuite/binutils-all/loongarch64/loongarch64.exp b/binutils/testsuite/binutils-all/loongarch64/loongarch64.exp
new file mode 100644
index 0000000..bd1d5eb
--- /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 0000000..574b3e5
--- /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 0000000..1e6710a
--- /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 0000000..b80ca42
--- /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 c1746500..da600e1 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