diff options
author | Andreas Schwab <schwab@suse.de> | 2023-08-03 17:22:42 +0200 |
---|---|---|
committer | Andreas Schwab <schwab@suse.de> | 2023-12-05 13:20:27 +0100 |
commit | 1b183017aa2fbb73785dc24b4cff32daae942c9c (patch) | |
tree | a38cc647f52a6a83f7c496ef7c36cbe04892f579 /bfd | |
parent | db4ab410dec3554bf38f69879de2306ce5e25b7e (diff) | |
download | binutils-1b183017aa2fbb73785dc24b4cff32daae942c9c.zip binutils-1b183017aa2fbb73785dc24b4cff32daae942c9c.tar.gz binutils-1b183017aa2fbb73785dc24b4cff32daae942c9c.tar.bz2 |
Add basic support for RISC-V 64-bit EFI objects
This adds a new PEI target pei-riscv64-little. Only objdump and objcopy
are supported.
bfd:
* .gitignore: Add pe-riscv64igen.c.
* Makefile.am (BFD64_BACKENDS): Add pei-riscv64.lo,
pe-riscv64igen.lo.
(BFD64_BACKENDS_CFILES): Add pei-riscv64.c.
(BUILD_CFILES): Add pe-riscv64igen.c.
(pe-riscv64igen.c): New rule.
* Makefile.in: Regenerate.
* bfd.c (bfd_get_sign_extend_vma): Add pei-riscv64-little.
* coff-riscv64.c: New file.
* coffcode.h (coff_set_arch_mach_hook, coff_set_flags)
(coff_write_object_contents): Add riscv64 (riscv64_pei_vec)
support.
* config.bfd (targ_selvecs): Add riscv64_pei_vec to all riscv*
targets.
* configure.ac: Handle riscv64_pei_vec.
* configure: Regenerate.
* 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_XX_bfd_copy_private_bfd_data_common)
(_bfd_XX_bfd_copy_private_section_data)
(_bfd_XX_get_symbol_info, _bfd_XX_only_swap_filehdr_out)
(_bfd_XX_print_private_bfd_data_common)
(_bfd_XXi_final_link_postscript, _bfd_XXi_only_swap_filehdr_out)
(_bfd_XXi_swap_aouthdr_in, _bfd_XXi_swap_aouthdr_out)
(_bfd_XXi_swap_aux_in, _bfd_XXi_swap_aux_out)
(_bfd_XXi_swap_lineno_in, _bfd_XXi_swap_lineno_out)
(_bfd_XXi_swap_scnhdr_out, _bfd_XXi_swap_sym_in)
(_bfd_XXi_swap_sym_out, _bfd_XXi_swap_debugdir_in)
(_bfd_XXi_swap_debugdir_out, _bfd_XXi_write_codeview_record)
(_bfd_XXi_slurp_codeview_record) [COFF_WITH_peRiscV64]: Define.
(_bfd_peRiscV64_print_ce_compressed_pdata): Declare.
* 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_peRiscV64.
* pei-riscv64.c: New file.
* peicode.h (coff_swap_scnhdr_in, pe_ILF_build_a_bfd)
(pe_ILF_object_p): Support COFF_WITH_peRiscV64.
(jtab): Add dummy entry that traps.
* targets.c (_bfd_target_vector): Add riscv64_pei_vec.
binutils:
* testsuite/binutils-all/riscv/pei-riscv64.d: New.
* testsuite/binutils-all/riscv/pei-riscv64.s: New.
include:
* coff/riscv64.h: New file.
* coff/pe.h (IMAGE_FILE_MACHINE_RISCV32)
(IMAGE_FILE_MACHINE_RISCV64): Define.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/.gitignore | 1 | ||||
-rw-r--r-- | bfd/Makefile.am | 10 | ||||
-rw-r--r-- | bfd/Makefile.in | 12 | ||||
-rw-r--r-- | bfd/bfd.c | 1 | ||||
-rw-r--r-- | bfd/coff-riscv64.c | 130 | ||||
-rw-r--r-- | bfd/coffcode.h | 19 | ||||
-rw-r--r-- | bfd/config.bfd | 8 | ||||
-rwxr-xr-x | bfd/configure | 1 | ||||
-rw-r--r-- | bfd/configure.ac | 1 | ||||
-rw-r--r-- | bfd/libpei.h | 36 | ||||
-rw-r--r-- | bfd/peXXigen.c | 44 | ||||
-rw-r--r-- | bfd/pei-riscv64.c | 74 | ||||
-rw-r--r-- | bfd/peicode.h | 20 | ||||
-rw-r--r-- | bfd/targets.c | 2 |
14 files changed, 329 insertions, 30 deletions
diff --git a/bfd/.gitignore b/bfd/.gitignore index 9eb73b1..ba2aea7 100644 --- a/bfd/.gitignore +++ b/bfd/.gitignore @@ -12,6 +12,7 @@ /pex64igen.c /pe-aarch64igen.c /pe-loongarch64igen.c +/pe-riscv64igen.c /stmp-bfd-h /targmatch.h diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 378c131..7f4b543 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -586,10 +586,12 @@ BFD64_BACKENDS = \ pe-aarch64.lo \ pe-aarch64igen.lo \ pe-loongarch64igen.lo \ + pe-riscv64igen.lo \ pe-x86_64.lo \ pei-aarch64.lo \ pei-ia64.lo \ pei-loongarch64.lo \ + pei-riscv64.lo \ pei-x86_64.lo \ pepigen.lo \ pex64igen.lo \ @@ -635,6 +637,7 @@ BFD64_BACKENDS_CFILES = \ pei-aarch64.c \ pei-ia64.c \ pei-loongarch64.c \ + pei-riscv64.c \ pei-x86_64.c \ vms-alpha.c @@ -691,7 +694,8 @@ 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 pe-loongarch64igen.c + peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c \ + pe-riscv64igen.c CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) @@ -901,6 +905,10 @@ pe-loongarch64igen.c: peXXigen.c $(AM_V_at)echo "#line 1 \"$<\"" > $@ $(AM_V_GEN)$(SED) -e s/XX/peLoongArch64/g < $< >> $@ +pe-riscv64igen.c: peXXigen.c + $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/XX/peRiscV64/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 bac78f4..480894f 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -1054,10 +1054,12 @@ BFD64_BACKENDS = \ pe-aarch64.lo \ pe-aarch64igen.lo \ pe-loongarch64igen.lo \ + pe-riscv64igen.lo \ pe-x86_64.lo \ pei-aarch64.lo \ pei-ia64.lo \ pei-loongarch64.lo \ + pei-riscv64.lo \ pei-x86_64.lo \ pepigen.lo \ pex64igen.lo \ @@ -1103,6 +1105,7 @@ BFD64_BACKENDS_CFILES = \ pei-aarch64.c \ pei-ia64.c \ pei-loongarch64.c \ + pei-riscv64.c \ pei-x86_64.c \ vms-alpha.c @@ -1158,7 +1161,8 @@ 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 pe-loongarch64igen.c + peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c \ + pe-riscv64igen.c CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) SOURCE_HFILES = \ @@ -1705,6 +1709,7 @@ distclean-compile: @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-riscv64igen.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)/pef.Plo@am__quote@ @@ -1715,6 +1720,7 @@ distclean-compile: @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-riscv64.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)/peigen.Plo@am__quote@ @@ -2414,6 +2420,10 @@ pe-loongarch64igen.c: peXXigen.c $(AM_V_at)echo "#line 1 \"$<\"" > $@ $(AM_V_GEN)$(SED) -e s/XX/peLoongArch64/g < $< >> $@ +pe-riscv64igen.c: peXXigen.c + $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/XX/peRiscV64/g < $< >> $@ + host-aout.lo: Makefile # The following program can be used to generate a simple config file @@ -2111,6 +2111,7 @@ bfd_get_sign_extend_vma (bfd *abfd) || strcmp (name, "pe-arm-wince-little") == 0 || strcmp (name, "pei-arm-wince-little") == 0 || strcmp (name, "pei-loongarch64") == 0 + || strcmp (name, "pei-riscv64-little") == 0 || strcmp (name, "aixcoff-rs6000") == 0 || strcmp (name, "aix5coff64-rs6000") == 0) return 1; diff --git a/bfd/coff-riscv64.c b/bfd/coff-riscv64.c new file mode 100644 index 0000000..0502be43 --- /dev/null +++ b/bfd/coff-riscv64.c @@ -0,0 +1,130 @@ +/* BFD back-end for RISC-V 64-bit COFF files. + Copyright (C) 2023 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" +#include "libbfd.h" +#include "coff/riscv64.h" +#include "coff/internal.h" +#include "coff/pe.h" +#include "libcoff.h" +#include "libiberty.h" + +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2 + +#ifndef bfd_pe_print_pdata +#define bfd_pe_print_pdata NULL +#endif + +#define RTYPE2HOWTO(cache_ptr, dst) \ + (cache_ptr)->howto = NULL + +/* 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 + riscv64_coff_vec = +#endif +{ +#ifdef TARGET_NAME + TARGET_NAME, +#else + "coff-riscv64-little", /* 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 0487555..a368ed1 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -2235,6 +2235,12 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) machine = internal_f->f_flags & F_LOONGARCH64_ARCHITECTURE_MASK; break; #endif +#ifdef RISCV64MAGIC + case RISCV64MAGIC: + arch = bfd_arch_riscv; + machine = bfd_mach_riscv64; + break; +#endif #ifdef Z80MAGIC case Z80MAGIC: arch = bfd_arch_z80; @@ -2806,6 +2812,12 @@ coff_set_flags (bfd * abfd, return true; #endif +#ifdef RISCV64MAGIC + case bfd_arch_riscv: + * magicp = RISCV64MAGIC; + return true; +#endif + #ifdef ARMMAGIC case bfd_arch_arm: #ifdef ARM_WINCE @@ -4002,7 +4014,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) #ifdef COFF_WITH_PE internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE; #else @@ -4061,6 +4073,11 @@ coff_write_object_contents (bfd * abfd) internal_a.magic = ZMAGIC; #endif +#if defined(RISCV64) +#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 8c9637a..4106924 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -1229,22 +1229,22 @@ case "${targ}" in #ifdef BFD64 riscvbe-*-* | riscv32be*-*-*) targ_defvec=riscv_elf32_be_vec - targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec" + targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec riscv64_pei_vec" want64=true ;; riscv-*-* | riscv32*-*-*) targ_defvec=riscv_elf32_vec - targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec" + targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec riscv64_pei_vec" want64=true ;; riscv64be*-*-*) targ_defvec=riscv_elf64_be_vec - targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec" + targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec riscv64_pei_vec" want64=true ;; riscv64*-*-*) targ_defvec=riscv_elf64_vec - targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec" + targ_selvecs="riscv_elf32_vec riscv_elf64_vec riscv_elf32_be_vec riscv_elf64_be_vec riscv64_pei_vec" want64=true ;; #endif diff --git a/bfd/configure b/bfd/configure index 0513cb5..6c56ffe 100755 --- a/bfd/configure +++ b/bfd/configure @@ -16005,6 +16005,7 @@ do riscv_elf64_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;; riscv_elf32_be_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;; riscv_elf64_be_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;; + riscv64_pei_vec) tb="$tb pei-riscv64.lo pe-riscv64igen.lo $coff"; target_size=64 ;; rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;; rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;; rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;; diff --git a/bfd/configure.ac b/bfd/configure.ac index ed6e773..9331165 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -590,6 +590,7 @@ do riscv_elf64_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;; riscv_elf32_be_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf" ;; riscv_elf64_be_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;; + riscv64_pei_vec) tb="$tb pei-riscv64.lo pe-riscv64igen.lo $coff"; target_size=64 ;; rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;; rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;; rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo aix5ppc-core.lo $xcoff"; target_size=64 ;; diff --git a/bfd/libpei.h b/bfd/libpei.h index 9837d46..e8f2931 100644 --- a/bfd/libpei.h +++ b/bfd/libpei.h @@ -347,6 +347,41 @@ #define _bfd_XXi_write_codeview_record _bfd_peLoongArch64i_write_codeview_record #define _bfd_XXi_slurp_codeview_record _bfd_peLoongArch64i_slurp_codeview_record +#elif defined COFF_WITH_peRiscV64 + +#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_peRiscV64_bfd_copy_private_bfd_data_common +#define _bfd_XX_bfd_copy_private_section_data _bfd_peRiscV64_bfd_copy_private_section_data +#define _bfd_XX_get_symbol_info _bfd_peRiscV64_get_symbol_info +#define _bfd_XX_only_swap_filehdr_out _bfd_peRiscV64_only_swap_filehdr_out +#define _bfd_XX_print_private_bfd_data_common _bfd_peRiscV64_print_private_bfd_data_common +#define _bfd_XXi_final_link_postscript _bfd_peRiscV64i_final_link_postscript +#define _bfd_XXi_only_swap_filehdr_out _bfd_peRiscV64i_only_swap_filehdr_out +#define _bfd_XXi_swap_aouthdr_in _bfd_peRiscV64i_swap_aouthdr_in +#define _bfd_XXi_swap_aouthdr_out _bfd_peRiscV64i_swap_aouthdr_out +#define _bfd_XXi_swap_aux_in _bfd_peRiscV64i_swap_aux_in +#define _bfd_XXi_swap_aux_out _bfd_peRiscV64i_swap_aux_out +#define _bfd_XXi_swap_lineno_in _bfd_peRiscV64i_swap_lineno_in +#define _bfd_XXi_swap_lineno_out _bfd_peRiscV64i_swap_lineno_out +#define _bfd_XXi_swap_scnhdr_out _bfd_peRiscV64i_swap_scnhdr_out +#define _bfd_XXi_swap_sym_in _bfd_peRiscV64i_swap_sym_in +#define _bfd_XXi_swap_sym_out _bfd_peRiscV64i_swap_sym_out +#define _bfd_XXi_swap_debugdir_in _bfd_peRiscV64i_swap_debugdir_in +#define _bfd_XXi_swap_debugdir_out _bfd_peRiscV64i_swap_debugdir_out +#define _bfd_XXi_write_codeview_record _bfd_peRiscV64i_write_codeview_record +#define _bfd_XXi_slurp_codeview_record _bfd_peRiscV64i_slurp_codeview_record + #else /* !COFF_WITH_pep */ #define GET_OPTHDR_IMAGE_BASE H_GET_32 @@ -445,6 +480,7 @@ 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_peRiscV64_print_ce_compressed_pdata (bfd *, void *); bool _bfd_pep_print_ce_compressed_pdata (bfd *, void *); #endif /* _LIBPEI_H */ diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index 641c259..6c8f498 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -61,8 +61,8 @@ wasting too much time. */ /* 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+. */ + COFF_WITH_peAArch64 or COFF_WITH_peLoongArch64 or COFF_WITH_peRiscV64 + depending on whether we're compiling for straight PE or PE+. */ #define COFF_WITH_XX #include "sysdep.h" @@ -88,6 +88,8 @@ # include "coff/aarch64.h" #elif defined COFF_WITH_peLoongArch64 # include "coff/loongarch64.h" +#elif defined COFF_WITH_peRiscV64 +# include "coff/riscv64.h" #else # include "coff/i386.h" #endif @@ -97,7 +99,7 @@ #include "libpei.h" #include "safe-ctype.h" -#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64 +#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64 || defined COFF_WITH_peRiscV64 # undef AOUTSZ # define AOUTSZ PEPAOUTSZ # define PEAOUTHDR PEPAOUTHDR @@ -464,7 +466,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) /* PE32+ does not have data_start member! */ aouthdr_int->data_start = GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start); @@ -531,7 +533,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) aouthdr_int->entry &= 0xffffffff; #endif } @@ -539,12 +541,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) aouthdr_int->text_start &= 0xffffffff; #endif } -#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) /* PE32+ does not have data_start member! */ if (aouthdr_int->dsize) { @@ -604,7 +606,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) aouthdr_in->text_start &= 0xffffffff; #endif } @@ -612,7 +614,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) aouthdr_in->data_start &= 0xffffffff; #endif } @@ -620,7 +622,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) aouthdr_in->entry &= 0xffffffff; #endif } @@ -734,7 +736,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) /* PE32+ does not have data_start member! */ PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, aouthdr_out->standard.data_start); @@ -922,7 +924,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out) _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) +#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) 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); @@ -1823,7 +1825,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) && !defined(COFF_WITH_peLoongArch64) +#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) # define PDATA_ROW_SIZE (3 * 8) #else # define PDATA_ROW_SIZE (5 * 4) @@ -1851,7 +1853,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) && !defined(COFF_WITH_peLoongArch64) +#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) fprintf (file, _(" vma:\t\t\tBegin Address End Address Unwind Info\n")); #else @@ -1888,7 +1890,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) || defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64) int em_data; #endif @@ -1906,7 +1908,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) || defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64) em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3); #endif eh_handler &= ~(bfd_vma) 0x3; @@ -1917,7 +1919,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) || defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64) fputc (' ', file); bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file); bfd_fprintf_vma (abfd, file, prolog_end_addr); @@ -2816,7 +2818,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) /* PE32+ does not have BaseOfData member! */ fprintf (file, "\nBaseOfData\t\t"); bfd_fprintf_vma (abfd, file, i->BaseOfData); @@ -3132,7 +3134,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) || defined(COFF_WITH_peLoongArch64)) +#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)) static int sort_x64_pdata (const void *l, const void *r) { @@ -4548,7 +4550,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64) pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18; #else pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28; @@ -4557,7 +4559,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) || defined(COFF_WITH_peLoongArch64)) +#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)) { asection *sec = bfd_get_section_by_name (abfd, ".pdata"); diff --git a/bfd/pei-riscv64.c b/bfd/pei-riscv64.c new file mode 100644 index 0000000..1a80015 --- /dev/null +++ b/bfd/pei-riscv64.c @@ -0,0 +1,74 @@ +/* BFD back-end for RISC-V 64-bit PE IMAGE COFF files. + Copyright (C) 2023 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 riscv64_pei_vec +#define TARGET_NAME "pei-riscv64-little" +#define TARGET_ARCHITECTURE bfd_arch_riscv +#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_peRiscV64 +#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 } + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "coff/riscv64.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-riscv64.c" diff --git a/bfd/peicode.h b/bfd/peicode.h index 72adce1..e16bfc2 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -233,7 +233,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) && !defined(COFF_WITH_peLoongArch64) +#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peRiscV64) scnhdr_int->s_vaddr &= 0xffffffff; #endif } @@ -767,6 +767,16 @@ static const jump_table jtab[] = #endif +#ifdef RISCV64MAGIC + /* We don't currently support jumping to DLLs, so if + someone does try emit a runtime trap. Through EBREAK. */ + { RISCV64MAGIC, + { 0x73, 0x00, 0x10, 0x00 }, + 4, 0 + }, + +#endif + { 0, { 0 }, 0, 0 } }; @@ -924,7 +934,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) || defined(COFF_WITH_peLoongArch64) +#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64) ((unsigned int *) id4->contents)[0] = ordinal; ((unsigned int *) id4->contents)[1] = 0x80000000; ((unsigned int *) id5->contents)[0] = ordinal; @@ -1245,6 +1255,12 @@ pe_ILF_object_p (bfd * abfd) #endif break; + case IMAGE_FILE_MACHINE_RISCV64: +#ifdef RISCV64MAGIC + magic = RISCV64MAGIC; +#endif + break; + case IMAGE_FILE_MACHINE_THUMB: #ifdef THUMBPEMAGIC { diff --git a/bfd/targets.c b/bfd/targets.c index 63b3abb..132d135 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -863,6 +863,7 @@ extern const bfd_target riscv_elf32_vec; extern const bfd_target riscv_elf64_vec; extern const bfd_target riscv_elf32_be_vec; extern const bfd_target riscv_elf64_be_vec; +extern const bfd_target riscv64_pei_vec; extern const bfd_target rl78_elf32_vec; extern const bfd_target rs6000_xcoff64_vec; extern const bfd_target rs6000_xcoff64_aix_vec; @@ -1260,6 +1261,7 @@ static const bfd_target * const _bfd_target_vector[] = &riscv_elf64_vec, &riscv_elf32_be_vec, &riscv_elf64_be_vec, + &riscv64_pei_vec, #endif &rl78_elf32_vec, |