public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Add basic support for RISC-V 64-bit EFI objects
@ 2023-08-08 14:18 Andreas Schwab
  2023-08-09  1:54 ` Palmer Dabbelt
  2023-09-06 20:01 ` Peter Jones
  0 siblings, 2 replies; 11+ messages in thread
From: Andreas Schwab @ 2023-08-08 14:18 UTC (permalink / raw)
  To: binutils

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/loongarch64/pei-riscv64.d: New.
	* testsuite/binutils-all/loongarch64/pei-riscv64.s: New.

include:
	* coff/riscv64.h: New file.
	* coff/pe.h (IMAGE_FILE_MACHINE_RISCV32)
	(IMAGE_FILE_MACHINE_RISCV64): Define.
---
 bfd/.gitignore                                |   1 +
 bfd/Makefile.am                               |  10 +-
 bfd/Makefile.in                               |  12 +-
 bfd/bfd.c                                     |   1 +
 bfd/coff-riscv64.c                            | 130 ++++++++++++++++++
 bfd/coffcode.h                                |  19 ++-
 bfd/config.bfd                                |   8 +-
 bfd/configure                                 |   1 +
 bfd/configure.ac                              |   1 +
 bfd/libpei.h                                  |  36 +++++
 bfd/peXXigen.c                                |  44 +++---
 bfd/pei-riscv64.c                             |  74 ++++++++++
 bfd/peicode.h                                 |  20 ++-
 bfd/targets.c                                 |   2 +
 .../binutils-all/riscv/pei-riscv64.d          |  16 +++
 .../binutils-all/riscv/pei-riscv64.s          |  31 +++++
 include/coff/pe.h                             |   2 +
 include/coff/riscv64.h                        |  64 +++++++++
 18 files changed, 442 insertions(+), 30 deletions(-)
 create mode 100644 bfd/coff-riscv64.c
 create mode 100644 bfd/pei-riscv64.c
 create mode 100644 binutils/testsuite/binutils-all/riscv/pei-riscv64.d
 create mode 100644 binutils/testsuite/binutils-all/riscv/pei-riscv64.s
 create mode 100644 include/coff/riscv64.h

diff --git a/bfd/.gitignore b/bfd/.gitignore
index 9eb73b14864..ba2aea70156 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 5c5fdefd3b8..5f16aab4b93 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -580,11 +580,13 @@ BFD64_BACKENDS = \
 	mmo.lo \
 	pe-aarch64igen.lo \
 	pe-loongarch64igen.lo \
+	pe-riscv64igen.lo \
 	pe-x86_64.lo \
 	pei-aarch64.lo \
 	pe-aarch64.lo \
 	pei-ia64.lo \
 	pei-loongarch64.lo \
+	pei-riscv64.lo \
 	pei-x86_64.lo \
 	pepigen.lo \
 	pex64igen.lo \
@@ -629,6 +631,7 @@ BFD64_BACKENDS_CFILES = \
 	pei-aarch64.c \
 	pei-ia64.c \
 	pei-loongarch64.c \
+	pei-riscv64.c \
 	pei-x86_64.c \
 	vms-alpha.c
 
@@ -684,7 +687,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)
 
@@ -886,6 +890,10 @@ pe-loongarch64igen.c: peXXigen.c
 	$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
 	$(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 4edfedee924..ca62f23185f 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1037,11 +1037,13 @@ BFD64_BACKENDS = \
 	mmo.lo \
 	pe-aarch64igen.lo \
 	pe-loongarch64igen.lo \
+	pe-riscv64igen.lo \
 	pe-x86_64.lo \
 	pei-aarch64.lo \
 	pe-aarch64.lo \
 	pei-ia64.lo \
 	pei-loongarch64.lo \
+	pei-riscv64.lo \
 	pei-x86_64.lo \
 	pepigen.lo \
 	pex64igen.lo \
@@ -1086,6 +1088,7 @@ BFD64_BACKENDS_CFILES = \
 	pei-aarch64.c \
 	pei-ia64.c \
 	pei-loongarch64.c \
+	pei-riscv64.c \
 	pei-x86_64.c \
 	vms-alpha.c
 
@@ -1140,7 +1143,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 = \
@@ -1683,6 +1687,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@
@@ -1693,6 +1698,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@
@@ -2384,6 +2390,10 @@ pe-loongarch64igen.c: peXXigen.c
 	$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
 	$(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/bfd.c b/bfd/bfd.c
index e43a388ac72..c6901e99b29 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1948,6 +1948,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 00000000000..0502be431a8
--- /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 6c8080c841e..4c900e88401 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -2182,6 +2182,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;
@@ -2753,6 +2759,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
@@ -3938,7 +3950,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
@@ -3997,6 +4009,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 3b39ff36c00..98ceed98794 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -1214,22 +1214,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 3d6ec5721f1..69eaeffd9cf 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -14019,6 +14019,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 f044616f4d9..f6534781f84 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -586,6 +586,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 9837d4628dd..e8f2931dd96 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 cdd89f80330..3fc1d3c9340 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);
@@ -933,7 +935,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);
@@ -1834,7 +1836,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)
@@ -1862,7 +1864,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
@@ -1899,7 +1901,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
 
@@ -1917,7 +1919,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;
@@ -1928,7 +1930,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);
@@ -2827,7 +2829,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);
@@ -3143,7 +3145,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)
 {
@@ -4559,7 +4561,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;
@@ -4568,7 +4570,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 00000000000..1a80015b67f
--- /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 e2e2be65b5d..3a467b7e509 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
     }
@@ -777,6 +777,16 @@ static const jump_table jtab[] =
     4, 0
   },
 
+#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 }
@@ -936,7 +946,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;
@@ -1255,6 +1265,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 3dbcd088966..39cfb2b4786 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -861,6 +861,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;
@@ -1253,6 +1254,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,
 
diff --git a/binutils/testsuite/binutils-all/riscv/pei-riscv64.d b/binutils/testsuite/binutils-all/riscv/pei-riscv64.d
new file mode 100644
index 00000000000..189b0162ba5
--- /dev/null
+++ b/binutils/testsuite/binutils-all/riscv/pei-riscv64.d
@@ -0,0 +1,16 @@
+#as: -march=rv64gc -mabi=lp64d
+#ld: -m elf64lriscv -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-riscv64-little
+#objdump: -h -f
+#name: Check if efi app format is recognized
+
+.*:     file format pei-riscv64-little
+architecture: riscv:rv64, flags 0x00000132:
+EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
+start address 0x0000000000000000
+
+Sections:
+Idx Name          Size      VMA               LMA               File off  Algn
+  0 \.text         00000010  0[^ ]+  0[^ ]+  0[^ ]+  2\*\*2
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
diff --git a/binutils/testsuite/binutils-all/riscv/pei-riscv64.s b/binutils/testsuite/binutils-all/riscv/pei-riscv64.s
new file mode 100644
index 00000000000..68c0e5bfa31
--- /dev/null
+++ b/binutils/testsuite/binutils-all/riscv/pei-riscv64.s
@@ -0,0 +1,31 @@
+	.file	"test_pei.c"
+	.option nopic
+	.attribute arch, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0"
+	.attribute unaligned_access, 0
+	.attribute stack_align, 16
+	.text
+	.align	1
+	.globl	main
+	.type	main, @function
+main:
+.LFB0:
+	.cfi_startproc
+	addi	sp,sp,-16
+	.cfi_def_cfa_offset 16
+	sd	s0,8(sp)
+	.cfi_offset 8, -8
+	addi	s0,sp,16
+	.cfi_def_cfa 8, 0
+	li	a5,0
+	mv	a0,a5
+	ld	s0,8(sp)
+	.cfi_restore 8
+	.cfi_def_cfa 2, 16
+	addi	sp,sp,16
+	.cfi_def_cfa_offset 0
+	jr	ra
+	.cfi_endproc
+.LFE0:
+	.size	main, .-main
+	.ident	"GCC: (SUSE Linux) 13.1.1 20230720 [revision 9aac37ab8a7b919a89c6d64bc7107a8436996e93]"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/include/coff/pe.h b/include/coff/pe.h
index 6b26d533218..dd4cf547a77 100644
--- a/include/coff/pe.h
+++ b/include/coff/pe.h
@@ -156,6 +156,8 @@
 #define IMAGE_FILE_MACHINE_R10000            0x0168
 #define IMAGE_FILE_MACHINE_R3000             0x0162
 #define IMAGE_FILE_MACHINE_R4000             0x0166
+#define IMAGE_FILE_MACHINE_RISCV32           0x5032
+#define IMAGE_FILE_MACHINE_RISCV64           0x5064
 #define IMAGE_FILE_MACHINE_SH3               0x01a2
 #define IMAGE_FILE_MACHINE_SH3DSP            0x01a3
 #define IMAGE_FILE_MACHINE_SH3E              0x01a4
diff --git a/include/coff/riscv64.h b/include/coff/riscv64.h
new file mode 100644
index 00000000000..614d74347ae
--- /dev/null
+++ b/include/coff/riscv64.h
@@ -0,0 +1,64 @@
+/* RISC-V 64-bit COFF support for BFD.
+   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.  */
+
+#ifndef COFF_RISCV64_H
+#define COFF_RISCV64_H
+
+#define COFFRISCV64 1
+
+#define L_LNNO_SIZE 2
+#define INCLUDE_COMDAT_FIELDS_IN_AUXENT
+#include "coff/external.h"
+
+#define	RISCV64MAGIC	0x5064  /* From Microsoft specification. */
+
+#undef  BADMAG
+#define BADMAG(x) ((x).f_magic != RISCV64MAGIC)
+#define RISCV64         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
+
+#endif /* COFF_RISCV64_H */
-- 
2.41.0


-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Add basic support for RISC-V 64-bit EFI objects
  2023-08-08 14:18 [PATCH] Add basic support for RISC-V 64-bit EFI objects Andreas Schwab
@ 2023-08-09  1:54 ` Palmer Dabbelt
  2023-08-09  8:10   ` Andreas Schwab
  2023-09-06 20:01 ` Peter Jones
  1 sibling, 1 reply; 11+ messages in thread
From: Palmer Dabbelt @ 2023-08-09  1:54 UTC (permalink / raw)
  To: binutils

On Tue, 08 Aug 2023 07:18:39 PDT (-0700), binutils@sourceware.org wrote:
> This adds a new PEI target pei-riscv64-little.  Only objdump and objcopy
> are supported.

So the idea is to just objcopy an ELF into a PE for EFI?  IIUC that's 
generally the way to go for this sort of thing.  In Linux we just have a 
PE header manually embedded in a flat binary, but presumably EFI folks 
want to have objcopy support for some reason?

Is the idea that anyone who wants EFI also wants 64-bit?  It's kind of 
nice to keep rv32 and rv64 as similar as possible, but I guess having 
one less binary format is kind of nice.

> 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/loongarch64/pei-riscv64.d: New.
> 	* testsuite/binutils-all/loongarch64/pei-riscv64.s: New.

I think those paths are wrong?

> include:
> 	* coff/riscv64.h: New file.
> 	* coff/pe.h (IMAGE_FILE_MACHINE_RISCV32)
> 	(IMAGE_FILE_MACHINE_RISCV64): Define.
> ---
>  bfd/.gitignore                                |   1 +
>  bfd/Makefile.am                               |  10 +-
>  bfd/Makefile.in                               |  12 +-
>  bfd/bfd.c                                     |   1 +
>  bfd/coff-riscv64.c                            | 130 ++++++++++++++++++
>  bfd/coffcode.h                                |  19 ++-
>  bfd/config.bfd                                |   8 +-
>  bfd/configure                                 |   1 +
>  bfd/configure.ac                              |   1 +
>  bfd/libpei.h                                  |  36 +++++
>  bfd/peXXigen.c                                |  44 +++---
>  bfd/pei-riscv64.c                             |  74 ++++++++++
>  bfd/peicode.h                                 |  20 ++-
>  bfd/targets.c                                 |   2 +
>  .../binutils-all/riscv/pei-riscv64.d          |  16 +++
>  .../binutils-all/riscv/pei-riscv64.s          |  31 +++++
>  include/coff/pe.h                             |   2 +
>  include/coff/riscv64.h                        |  64 +++++++++
>  18 files changed, 442 insertions(+), 30 deletions(-)
>  create mode 100644 bfd/coff-riscv64.c
>  create mode 100644 bfd/pei-riscv64.c
>  create mode 100644 binutils/testsuite/binutils-all/riscv/pei-riscv64.d
>  create mode 100644 binutils/testsuite/binutils-all/riscv/pei-riscv64.s
>  create mode 100644 include/coff/riscv64.h
>
> diff --git a/bfd/.gitignore b/bfd/.gitignore
> index 9eb73b14864..ba2aea70156 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 5c5fdefd3b8..5f16aab4b93 100644
> --- a/bfd/Makefile.am
> +++ b/bfd/Makefile.am
> @@ -580,11 +580,13 @@ BFD64_BACKENDS = \
>  	mmo.lo \
>  	pe-aarch64igen.lo \
>  	pe-loongarch64igen.lo \
> +	pe-riscv64igen.lo \
>  	pe-x86_64.lo \
>  	pei-aarch64.lo \
>  	pe-aarch64.lo \
>  	pei-ia64.lo \
>  	pei-loongarch64.lo \
> +	pei-riscv64.lo \
>  	pei-x86_64.lo \
>  	pepigen.lo \
>  	pex64igen.lo \
> @@ -629,6 +631,7 @@ BFD64_BACKENDS_CFILES = \
>  	pei-aarch64.c \
>  	pei-ia64.c \
>  	pei-loongarch64.c \
> +	pei-riscv64.c \
>  	pei-x86_64.c \
>  	vms-alpha.c
>
> @@ -684,7 +687,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)
>
> @@ -886,6 +890,10 @@ pe-loongarch64igen.c: peXXigen.c
>  	$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
>  	$(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 4edfedee924..ca62f23185f 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -1037,11 +1037,13 @@ BFD64_BACKENDS = \
>  	mmo.lo \
>  	pe-aarch64igen.lo \
>  	pe-loongarch64igen.lo \
> +	pe-riscv64igen.lo \
>  	pe-x86_64.lo \
>  	pei-aarch64.lo \
>  	pe-aarch64.lo \
>  	pei-ia64.lo \
>  	pei-loongarch64.lo \
> +	pei-riscv64.lo \
>  	pei-x86_64.lo \
>  	pepigen.lo \
>  	pex64igen.lo \
> @@ -1086,6 +1088,7 @@ BFD64_BACKENDS_CFILES = \
>  	pei-aarch64.c \
>  	pei-ia64.c \
>  	pei-loongarch64.c \
> +	pei-riscv64.c \
>  	pei-x86_64.c \
>  	vms-alpha.c
>
> @@ -1140,7 +1143,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 = \
> @@ -1683,6 +1687,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@
> @@ -1693,6 +1698,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@
> @@ -2384,6 +2390,10 @@ pe-loongarch64igen.c: peXXigen.c
>  	$(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@
>  	$(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/bfd.c b/bfd/bfd.c
> index e43a388ac72..c6901e99b29 100644
> --- a/bfd/bfd.c
> +++ b/bfd/bfd.c
> @@ -1948,6 +1948,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 00000000000..0502be431a8
> --- /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 6c8080c841e..4c900e88401 100644
> --- a/bfd/coffcode.h
> +++ b/bfd/coffcode.h
> @@ -2182,6 +2182,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;
> @@ -2753,6 +2759,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
> @@ -3938,7 +3950,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
> @@ -3997,6 +4009,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 3b39ff36c00..98ceed98794 100644
> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -1214,22 +1214,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 3d6ec5721f1..69eaeffd9cf 100755
> --- a/bfd/configure
> +++ b/bfd/configure
> @@ -14019,6 +14019,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 f044616f4d9..f6534781f84 100644
> --- a/bfd/configure.ac
> +++ b/bfd/configure.ac
> @@ -586,6 +586,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 9837d4628dd..e8f2931dd96 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 cdd89f80330..3fc1d3c9340 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);
> @@ -933,7 +935,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);
> @@ -1834,7 +1836,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)
> @@ -1862,7 +1864,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
> @@ -1899,7 +1901,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
>
> @@ -1917,7 +1919,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;
> @@ -1928,7 +1930,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);
> @@ -2827,7 +2829,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);
> @@ -3143,7 +3145,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)
>  {
> @@ -4559,7 +4561,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;
> @@ -4568,7 +4570,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 00000000000..1a80015b67f
> --- /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 e2e2be65b5d..3a467b7e509 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
>      }
> @@ -777,6 +777,16 @@ static const jump_table jtab[] =
>      4, 0
>    },
>
> +#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 }
> @@ -936,7 +946,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;
> @@ -1255,6 +1265,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 3dbcd088966..39cfb2b4786 100644
> --- a/bfd/targets.c
> +++ b/bfd/targets.c
> @@ -861,6 +861,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;
> @@ -1253,6 +1254,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,
>
> diff --git a/binutils/testsuite/binutils-all/riscv/pei-riscv64.d b/binutils/testsuite/binutils-all/riscv/pei-riscv64.d
> new file mode 100644
> index 00000000000..189b0162ba5
> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/riscv/pei-riscv64.d
> @@ -0,0 +1,16 @@
> +#as: -march=rv64gc -mabi=lp64d
> +#ld: -m elf64lriscv -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-riscv64-little
> +#objdump: -h -f
> +#name: Check if efi app format is recognized
> +
> +.*:     file format pei-riscv64-little
> +architecture: riscv:rv64, flags 0x00000132:
> +EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
> +start address 0x0000000000000000
> +
> +Sections:
> +Idx Name          Size      VMA               LMA               File off  Algn
> +  0 \.text         00000010  0[^ ]+  0[^ ]+  0[^ ]+  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> diff --git a/binutils/testsuite/binutils-all/riscv/pei-riscv64.s b/binutils/testsuite/binutils-all/riscv/pei-riscv64.s
> new file mode 100644
> index 00000000000..68c0e5bfa31
> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/riscv/pei-riscv64.s
> @@ -0,0 +1,31 @@
> +	.file	"test_pei.c"
> +	.option nopic
> +	.attribute arch, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0"
> +	.attribute unaligned_access, 0
> +	.attribute stack_align, 16
> +	.text
> +	.align	1
> +	.globl	main
> +	.type	main, @function
> +main:
> +.LFB0:
> +	.cfi_startproc
> +	addi	sp,sp,-16
> +	.cfi_def_cfa_offset 16
> +	sd	s0,8(sp)
> +	.cfi_offset 8, -8
> +	addi	s0,sp,16
> +	.cfi_def_cfa 8, 0
> +	li	a5,0
> +	mv	a0,a5
> +	ld	s0,8(sp)
> +	.cfi_restore 8
> +	.cfi_def_cfa 2, 16
> +	addi	sp,sp,16
> +	.cfi_def_cfa_offset 0
> +	jr	ra
> +	.cfi_endproc
> +.LFE0:
> +	.size	main, .-main
> +	.ident	"GCC: (SUSE Linux) 13.1.1 20230720 [revision 9aac37ab8a7b919a89c6d64bc7107a8436996e93]"
> +	.section	.note.GNU-stack,"",@progbits
> diff --git a/include/coff/pe.h b/include/coff/pe.h
> index 6b26d533218..dd4cf547a77 100644
> --- a/include/coff/pe.h
> +++ b/include/coff/pe.h
> @@ -156,6 +156,8 @@
>  #define IMAGE_FILE_MACHINE_R10000            0x0168
>  #define IMAGE_FILE_MACHINE_R3000             0x0162
>  #define IMAGE_FILE_MACHINE_R4000             0x0166
> +#define IMAGE_FILE_MACHINE_RISCV32           0x5032
> +#define IMAGE_FILE_MACHINE_RISCV64           0x5064

The spec has rv128 as well, but I guess nothing's supporting that so it 
doesn't really matter?

>  #define IMAGE_FILE_MACHINE_SH3               0x01a2
>  #define IMAGE_FILE_MACHINE_SH3DSP            0x01a3
>  #define IMAGE_FILE_MACHINE_SH3E              0x01a4
> diff --git a/include/coff/riscv64.h b/include/coff/riscv64.h
> new file mode 100644
> index 00000000000..614d74347ae
> --- /dev/null
> +++ b/include/coff/riscv64.h
> @@ -0,0 +1,64 @@
> +/* RISC-V 64-bit COFF support for BFD.
> +   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.  */
> +
> +#ifndef COFF_RISCV64_H
> +#define COFF_RISCV64_H
> +
> +#define COFFRISCV64 1
> +
> +#define L_LNNO_SIZE 2
> +#define INCLUDE_COMDAT_FIELDS_IN_AUXENT
> +#include "coff/external.h"
> +
> +#define	RISCV64MAGIC	0x5064  /* From Microsoft specification. */

Which is the same as IMAGE_FILE_MACHINE_RISCV64, not sure if we can use 
that here though?

> +
> +#undef  BADMAG
> +#define BADMAG(x) ((x).f_magic != RISCV64MAGIC)
> +#define RISCV64         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"

Is that a PE-ism?  It's ".rodata" elsewhere in RISC-V.  It looks like the 
other PE/COFF ports are ".rdata", though.

> +
> +/********************** 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
> +
> +#endif /* COFF_RISCV64_H */

Nothing's really jumping out as wrong to me, so

Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>

Nelson said he'd take a look too.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Add basic support for RISC-V 64-bit EFI objects
  2023-08-09  1:54 ` Palmer Dabbelt
@ 2023-08-09  8:10   ` Andreas Schwab
  2023-08-25  2:15     ` Nelson Chu
  0 siblings, 1 reply; 11+ messages in thread
From: Andreas Schwab @ 2023-08-09  8:10 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils

On Aug 08 2023, Palmer Dabbelt wrote:

> So the idea is to just objcopy an ELF into a PE for EFI?  IIUC that's
> generally the way to go for this sort of thing.  In Linux we just have a
> PE header manually embedded in a flat binary, but presumably EFI folks
> want to have objcopy support for some reason?

My main intention is to let BFD recognize EFI objects so that I can
objdump them easily.  The support for objcopy comes in naturally, and
some packages do use objcopy to create EFI objects from ELF (on archs
where BFD supports it).

> Is the idea that anyone who wants EFI also wants 64-bit?

That's not my intention.  It's just that I have no 32-bit setup for
testing.

>> binutils:
>> 	* testsuite/binutils-all/loongarch64/pei-riscv64.d: New.
>> 	* testsuite/binutils-all/loongarch64/pei-riscv64.s: New.
>
> I think those paths are wrong?

Yes, that reveals where I copied the whole thing from. ;-)

>> diff --git a/include/coff/pe.h b/include/coff/pe.h
>> index 6b26d533218..dd4cf547a77 100644
>> --- a/include/coff/pe.h
>> +++ b/include/coff/pe.h
>> @@ -156,6 +156,8 @@
>>  #define IMAGE_FILE_MACHINE_R10000            0x0168
>>  #define IMAGE_FILE_MACHINE_R3000             0x0162
>>  #define IMAGE_FILE_MACHINE_R4000             0x0166
>> +#define IMAGE_FILE_MACHINE_RISCV32           0x5032
>> +#define IMAGE_FILE_MACHINE_RISCV64           0x5064
>
> The spec has rv128 as well, but I guess nothing's supporting that so it
> doesn't really matter?

I don't think we will see any 128-bit CPU of any kind any time soon.

>> +#define	RISCV64MAGIC	0x5064  /* From Microsoft specification. */
>
> Which is the same as IMAGE_FILE_MACHINE_RISCV64, not sure if we can use
> that here though?

I think the intention is to separate the PE stuff from the COFF base.

>> +/* We use the .rdata section to hold read only data.  */
>> +#define _LIT	".rdata"
>
> Is that a PE-ism?  It's ".rodata" elsewhere in RISC-V.  It looks like the
> other PE/COFF ports are ".rdata", though.

.rdata seems to be a normal PE/COFF thing.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Add basic support for RISC-V 64-bit EFI objects
  2023-08-09  8:10   ` Andreas Schwab
@ 2023-08-25  2:15     ` Nelson Chu
  2023-08-25 13:26       ` Palmer Dabbelt
  0 siblings, 1 reply; 11+ messages in thread
From: Nelson Chu @ 2023-08-25  2:15 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Palmer Dabbelt, binutils

[-- Attachment #1: Type: text/plain, Size: 980 bytes --]

On Wed, Aug 9, 2023 at 4:11 PM Andreas Schwab via Binutils <
binutils@sourceware.org> wrote:

> On Aug 08 2023, Palmer Dabbelt wrote:
>
> > So the idea is to just objcopy an ELF into a PE for EFI?  IIUC that's
> > generally the way to go for this sort of thing.  In Linux we just have a
> > PE header manually embedded in a flat binary, but presumably EFI folks
> > want to have objcopy support for some reason?
>
> My main intention is to let BFD recognize EFI objects so that I can
> objdump them easily.  The support for objcopy comes in naturally, and
> some packages do use objcopy to create EFI objects from ELF (on archs
> where BFD supports it).
>

Passed the binutils regression, and the pei-riscv64 testcase is also
passed.  I don't familiar with the COFF stuff, but at least the support of
objdump and objcopy seems to be working, that's what I can check the most
currently.  Hope this helps before any expert comments appear ;)

Thanks
Nelson

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Add basic support for RISC-V 64-bit EFI objects
  2023-08-25  2:15     ` Nelson Chu
@ 2023-08-25 13:26       ` Palmer Dabbelt
  2023-08-28  2:03         ` Nelson Chu
  0 siblings, 1 reply; 11+ messages in thread
From: Palmer Dabbelt @ 2023-08-25 13:26 UTC (permalink / raw)
  To: nelson; +Cc: schwab, binutils

On Thu, 24 Aug 2023 19:15:32 PDT (-0700), nelson@rivosinc.com wrote:
> On Wed, Aug 9, 2023 at 4:11 PM Andreas Schwab via Binutils <
> binutils@sourceware.org> wrote:
>
>> On Aug 08 2023, Palmer Dabbelt wrote:
>>
>> > So the idea is to just objcopy an ELF into a PE for EFI?  IIUC that's
>> > generally the way to go for this sort of thing.  In Linux we just have a
>> > PE header manually embedded in a flat binary, but presumably EFI folks
>> > want to have objcopy support for some reason?
>>
>> My main intention is to let BFD recognize EFI objects so that I can
>> objdump them easily.  The support for objcopy comes in naturally, and
>> some packages do use objcopy to create EFI objects from ELF (on archs
>> where BFD supports it).

OK, that makes sense to me.

> Passed the binutils regression, and the pei-riscv64 testcase is also
> passed.  I don't familiar with the COFF stuff, but at least the support of
> objdump and objcopy seems to be working, that's what I can check the most
> currently.  Hope this helps before any expert comments appear ;)

So you think it's ready to merge, or did you want to look closer?

>
> Thanks
> Nelson

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Add basic support for RISC-V 64-bit EFI objects
  2023-08-25 13:26       ` Palmer Dabbelt
@ 2023-08-28  2:03         ` Nelson Chu
  2023-09-06 15:40           ` Palmer Dabbelt
  0 siblings, 1 reply; 11+ messages in thread
From: Nelson Chu @ 2023-08-28  2:03 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: schwab, binutils

[-- Attachment #1: Type: text/plain, Size: 713 bytes --]

On Fri, Aug 25, 2023 at 9:26 PM Palmer Dabbelt <palmer@dabbelt.com> wrote:

> On Thu, 24 Aug 2023 19:15:32 PDT (-0700), nelson@rivosinc.com wrote:
> > Passed the binutils regression, and the pei-riscv64 testcase is also
> > passed.  I don't familiar with the COFF stuff, but at least the support
> of
> > objdump and objcopy seems to be working, that's what I can check the most
> > currently.  Hope this helps before any expert comments appear ;)
>
> So you think it's ready to merge, or did you want to look closer?
>

At least it should be safe to merge since regressions are passed, and
current features shouldn't be affected.  So if no one objected after a
while, it should merge.

Nelson

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Add basic support for RISC-V 64-bit EFI objects
  2023-08-28  2:03         ` Nelson Chu
@ 2023-09-06 15:40           ` Palmer Dabbelt
  0 siblings, 0 replies; 11+ messages in thread
From: Palmer Dabbelt @ 2023-09-06 15:40 UTC (permalink / raw)
  To: nelson; +Cc: schwab, binutils

On Sun, 27 Aug 2023 19:03:49 PDT (-0700), nelson@rivosinc.com wrote:
> On Fri, Aug 25, 2023 at 9:26 PM Palmer Dabbelt <palmer@dabbelt.com> wrote:
>
>> On Thu, 24 Aug 2023 19:15:32 PDT (-0700), nelson@rivosinc.com wrote:
>> > Passed the binutils regression, and the pei-riscv64 testcase is also
>> > passed.  I don't familiar with the COFF stuff, but at least the support
>> of
>> > objdump and objcopy seems to be working, that's what I can check the most
>> > currently.  Hope this helps before any expert comments appear ;)
>>
>> So you think it's ready to merge, or did you want to look closer?
>>
>
> At least it should be safe to merge since regressions are passed, and
> current features shouldn't be affected.  So if no one objected after a
> while, it should merge.

OK, let's merge it, then?

> Nelson

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Add basic support for RISC-V 64-bit EFI objects
  2023-08-08 14:18 [PATCH] Add basic support for RISC-V 64-bit EFI objects Andreas Schwab
  2023-08-09  1:54 ` Palmer Dabbelt
@ 2023-09-06 20:01 ` Peter Jones
  2023-09-06 20:01   ` [PATCH] Handle "efi-app-riscv64" and similar targets in objcopy Peter Jones
  1 sibling, 1 reply; 11+ messages in thread
From: Peter Jones @ 2023-09-06 20:01 UTC (permalink / raw)
  To: binutils; +Cc: Andreas Schwab

Hi,
This looks good to me, but it seems to be missing the bit to make
objcopy work to make /EFI/ binaries (as opposed to e.g. windows PE
binaries), which is something we definitely want.  I'll follow up with a
patch.

--
	Peter



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] Handle "efi-app-riscv64" and similar targets in objcopy.
  2023-09-06 20:01 ` Peter Jones
@ 2023-09-06 20:01   ` Peter Jones
  2023-12-04 17:16     ` Palmer Dabbelt
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Jones @ 2023-09-06 20:01 UTC (permalink / raw)
  To: binutils; +Cc: Andreas Schwab, Peter Jones

This adds the efi target name handling for riscv64 to objcopy.

binutils:
	* binutils/objcopy.c: add riscv64 handling to
	  convert_efi_target()

Signed-off-by: Peter Jones <pjones@redhat.com>
---
 binutils/objcopy.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 2ce1b07bf7c..b64cbee3dd7 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -5129,6 +5129,11 @@ convert_efi_target (char **targ)
       /* Change aarch64 to aarch64-little.  */
       memcpy (pei + 4 + sizeof ("aarch64") - 1, "-little", sizeof ("-little"));
     }
+  else if (strcmp (efi + 4, "riscv64") == 0)
+    {
+      /* Change riscv64 to riscv64-little.  */
+      memcpy (pei + 4 + sizeof ("riscv64") - 1, "-little", sizeof ("-little"));
+    }
   *targ = pei;
   return subsys;
 }
-- 
2.40.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Handle "efi-app-riscv64" and similar targets in objcopy.
  2023-09-06 20:01   ` [PATCH] Handle "efi-app-riscv64" and similar targets in objcopy Peter Jones
@ 2023-12-04 17:16     ` Palmer Dabbelt
  2023-12-05  6:45       ` Nelson Chu
  0 siblings, 1 reply; 11+ messages in thread
From: Palmer Dabbelt @ 2023-12-04 17:16 UTC (permalink / raw)
  To: pjones; +Cc: binutils, schwab, pjones

On Wed, 06 Sep 2023 13:01:34 PDT (-0700), pjones@redhat.com wrote:
> This adds the efi target name handling for riscv64 to objcopy.
>
> binutils:
> 	* binutils/objcopy.c: add riscv64 handling to
> 	  convert_efi_target()
>
> Signed-off-by: Peter Jones <pjones@redhat.com>
> ---
>  binutils/objcopy.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/binutils/objcopy.c b/binutils/objcopy.c
> index 2ce1b07bf7c..b64cbee3dd7 100644
> --- a/binutils/objcopy.c
> +++ b/binutils/objcopy.c
> @@ -5129,6 +5129,11 @@ convert_efi_target (char **targ)
>        /* Change aarch64 to aarch64-little.  */
>        memcpy (pei + 4 + sizeof ("aarch64") - 1, "-little", sizeof ("-little"));
>      }
> +  else if (strcmp (efi + 4, "riscv64") == 0)
> +    {
> +      /* Change riscv64 to riscv64-little.  */
> +      memcpy (pei + 4 + sizeof ("riscv64") - 1, "-little", sizeof ("-little"));
> +    }
>    *targ = pei;
>    return subsys;
>  }

Sorry I missed this, David just poked me.

Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
Acked-by: Palmer Dabbelt <palmer@rivosinc.com>

Thanks!

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Handle "efi-app-riscv64" and similar targets in objcopy.
  2023-12-04 17:16     ` Palmer Dabbelt
@ 2023-12-05  6:45       ` Nelson Chu
  0 siblings, 0 replies; 11+ messages in thread
From: Nelson Chu @ 2023-12-05  6:45 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: pjones, binutils, schwab

[-- Attachment #1: Type: text/plain, Size: 1372 bytes --]

Committed since passed the regressions of riscv-gnu-toolchain.

Thanks
Nelson

On Tue, Dec 5, 2023 at 1:16 AM Palmer Dabbelt <palmer@dabbelt.com> wrote:

> On Wed, 06 Sep 2023 13:01:34 PDT (-0700), pjones@redhat.com wrote:
> > This adds the efi target name handling for riscv64 to objcopy.
> >
> > binutils:
> >       * binutils/objcopy.c: add riscv64 handling to
> >         convert_efi_target()
> >
> > Signed-off-by: Peter Jones <pjones@redhat.com>
> > ---
> >  binutils/objcopy.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/binutils/objcopy.c b/binutils/objcopy.c
> > index 2ce1b07bf7c..b64cbee3dd7 100644
> > --- a/binutils/objcopy.c
> > +++ b/binutils/objcopy.c
> > @@ -5129,6 +5129,11 @@ convert_efi_target (char **targ)
> >        /* Change aarch64 to aarch64-little.  */
> >        memcpy (pei + 4 + sizeof ("aarch64") - 1, "-little", sizeof
> ("-little"));
> >      }
> > +  else if (strcmp (efi + 4, "riscv64") == 0)
> > +    {
> > +      /* Change riscv64 to riscv64-little.  */
> > +      memcpy (pei + 4 + sizeof ("riscv64") - 1, "-little", sizeof
> ("-little"));
> > +    }
> >    *targ = pei;
> >    return subsys;
> >  }
>
> Sorry I missed this, David just poked me.
>
> Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
> Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
>
> Thanks!
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-12-05  6:45 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-08 14:18 [PATCH] Add basic support for RISC-V 64-bit EFI objects Andreas Schwab
2023-08-09  1:54 ` Palmer Dabbelt
2023-08-09  8:10   ` Andreas Schwab
2023-08-25  2:15     ` Nelson Chu
2023-08-25 13:26       ` Palmer Dabbelt
2023-08-28  2:03         ` Nelson Chu
2023-09-06 15:40           ` Palmer Dabbelt
2023-09-06 20:01 ` Peter Jones
2023-09-06 20:01   ` [PATCH] Handle "efi-app-riscv64" and similar targets in objcopy Peter Jones
2023-12-04 17:16     ` Palmer Dabbelt
2023-12-05  6:45       ` Nelson Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).