From c215048ddaac75969c22c018871295a5748a47e8 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 15 Sep 2024 10:54:04 +0100 Subject: [riscv] Add support for the RISC-V CPU architecture Add support for building iPXE as a 64-bit or 32-bit RISC-V binary, for either UEFI or Linux userspace platforms. For example: # RISC-V 64-bit UEFI make CROSS=riscv64-linux-gnu- bin-riscv64-efi/ipxe.efi # RISC-V 32-bit UEFI make CROSS=riscv64-linux-gnu- bin-riscv32-efi/ipxe.efi # RISC-V 64-bit Linux make CROSS=riscv64-linux-gnu- bin-riscv64-linux/tests.linux qemu-riscv64 -L /usr/riscv64-linux-gnu/sys-root \ ./bin-riscv64-linux/tests.linux # RISC-V 32-bit Linux make CROSS=riscv64-linux-gnu- SYSROOT=/usr/riscv32-linux-gnu/sys-root \ bin-riscv32-linux/tests.linux qemu-riscv32 -L /usr/riscv32-linux-gnu/sys-root \ ./bin-riscv32-linux/tests.linux Signed-off-by: Michael Brown --- src/util/elf2efi.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'src/util/elf2efi.c') diff --git a/src/util/elf2efi.c b/src/util/elf2efi.c index 4af587d87..5434e7040 100644 --- a/src/util/elf2efi.c +++ b/src/util/elf2efi.c @@ -83,6 +83,9 @@ #ifndef EM_AARCH64 #define EM_AARCH64 183 #endif +#ifndef EM_RISCV +#define EM_RISCV 243 +#endif #ifndef EM_LOONGARCH #define EM_LOONGARCH 258 #endif @@ -167,6 +170,45 @@ #ifndef R_LARCH_PCREL20_S2 #define R_LARCH_PCREL20_S2 103 #endif +#ifndef R_RISCV_NONE +#define R_RISCV_NONE 0 +#endif +#ifndef R_RISCV_32 +#define R_RISCV_32 1 +#endif +#ifndef R_RISCV_64 +#define R_RISCV_64 2 +#endif +#ifndef R_RISCV_BRANCH +#define R_RISCV_BRANCH 16 +#endif +#ifndef R_RISCV_JAL +#define R_RISCV_JAL 17 +#endif +#ifndef R_RISCV_PCREL_HI20 +#define R_RISCV_PCREL_HI20 23 +#endif +#ifndef R_RISCV_PCREL_LO12_I +#define R_RISCV_PCREL_LO12_I 24 +#endif +#ifndef R_RISCV_PCREL_LO12_S +#define R_RISCV_PCREL_LO12_S 25 +#endif +#ifndef R_RISCV_ADD32 +#define R_RISCV_ADD32 35 +#endif +#ifndef R_RISCV_SUB32 +#define R_RISCV_SUB32 39 +#endif +#ifndef R_RISCV_RVC_BRANCH +#define R_RISCV_RVC_BRANCH 44 +#endif +#ifndef R_RISCV_RVC_JUMP +#define R_RISCV_RVC_JUMP 45 +#endif +#ifndef R_RISCV_RELAX +#define R_RISCV_RELAX 51 +#endif #ifndef R_X86_64_GOTPCRELX #define R_X86_64_GOTPCRELX 41 #endif @@ -596,6 +638,11 @@ static void set_machine ( struct elf_file *elf, struct pe_header *pe_header ) { case EM_LOONGARCH: machine = EFI_IMAGE_MACHINE_LOONGARCH64; break; + case EM_RISCV: + machine = ( ( ELFCLASS == ELFCLASS64 ) ? + EFI_IMAGE_MACHINE_RISCV64 : + EFI_IMAGE_MACHINE_RISCV32 ); + break; default: eprintf ( "Unknown ELF architecture %d\n", ehdr->e_machine ); exit ( 1 ); @@ -828,16 +875,19 @@ static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr, case ELF_MREL ( EM_AARCH64, R_AARCH64_NONE ) : case ELF_MREL ( EM_AARCH64, R_AARCH64_NULL ) : case ELF_MREL ( EM_LOONGARCH, R_LARCH_NONE ) : + case ELF_MREL ( EM_RISCV, R_RISCV_NONE ) : /* Ignore dummy relocations used by REQUIRE_SYMBOL() */ break; case ELF_MREL ( EM_386, R_386_32 ) : case ELF_MREL ( EM_ARM, R_ARM_ABS32 ) : + case ELF_MREL ( EM_RISCV, R_RISCV_32 ) : /* Generate a 4-byte PE relocation */ generate_pe_reloc ( pe_reltab, offset, 4 ); break; case ELF_MREL ( EM_X86_64, R_X86_64_64 ) : case ELF_MREL ( EM_AARCH64, R_AARCH64_ABS64 ) : case ELF_MREL ( EM_LOONGARCH, R_LARCH_64 ) : + case ELF_MREL ( EM_RISCV, R_RISCV_64 ) : /* Generate an 8-byte PE relocation */ generate_pe_reloc ( pe_reltab, offset, 8 ); break; @@ -869,16 +919,31 @@ static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr, case ELF_MREL ( EM_LOONGARCH, R_LARCH_GOT_PC_HI20 ): case ELF_MREL ( EM_LOONGARCH, R_LARCH_GOT_PC_LO12 ): case ELF_MREL ( EM_LOONGARCH, R_LARCH_PCREL20_S2 ): + case ELF_MREL ( EM_RISCV, R_RISCV_BRANCH ) : + case ELF_MREL ( EM_RISCV, R_RISCV_JAL ) : + case ELF_MREL ( EM_RISCV, R_RISCV_PCREL_HI20 ) : + case ELF_MREL ( EM_RISCV, R_RISCV_PCREL_LO12_I ) : + case ELF_MREL ( EM_RISCV, R_RISCV_PCREL_LO12_S ) : + case ELF_MREL ( EM_RISCV, R_RISCV_RVC_BRANCH ) : + case ELF_MREL ( EM_RISCV, R_RISCV_RVC_JUMP ) : /* Skip PC-relative relocations; all relative * offsets remain unaltered when the object is * loaded. */ break; case ELF_MREL ( EM_LOONGARCH, R_LARCH_RELAX ): + case ELF_MREL ( EM_RISCV, R_RISCV_RELAX ) : /* Relocation can be relaxed (optimized out). * Ignore it for now. */ break; + case ELF_MREL ( EM_RISCV, R_RISCV_ADD32 ) : + case ELF_MREL ( EM_RISCV, R_RISCV_SUB32 ) : + /* Ignore label difference relocations since + * we do not perform any relocations that can + * result in altered label differences. + */ + break; case ELF_MREL ( EM_X86_64, R_X86_64_32 ) : /* Ignore 32-bit relocations in a hybrid * 32-bit BIOS and 64-bit UEFI binary, -- cgit v1.2.3-55-g7522