summaryrefslogtreecommitdiff
path: root/bfd/peXXigen.c
diff options
context:
space:
mode:
authorYouling Tang <tangyouling@loongson.cn>2022-08-06 14:49:43 +0800
committerliuzhensong <liuzhensong@loongson.cn>2022-08-10 09:26:25 +0800
commit31f6009538b75c22a4b3f99216846973283f0c6d (patch)
tree593e7e73578a9e614611adb395193ddc1d590d7b /bfd/peXXigen.c
parent4c3cb23cc00025fe7105254203ec58679051cf94 (diff)
downloadbinutils-gdb-31f6009538b75c22a4b3f99216846973283f0c6d.tar.gz
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>
Diffstat (limited to 'bfd/peXXigen.c')
-rw-r--r--bfd/peXXigen.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 5ab09387e72..a7b85713023 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");