riscv-non-isa / riscv-uefi

https://jira.riscv.org/browse/RVG-49
Creative Commons Attribution 4.0 International
23 stars 5 forks source link

COFF relocation types #12

Open maharmstone opened 2 years ago

maharmstone commented 2 years ago

I'm not sure if this is the best place for this, but I can't see where else it would go...

UEFI executables use the PE format, which as per the specs is defined at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format. I've been looking into adding support for RISC-V EFI images to binutils, but this would also need details of the relocation types for COFF object files, which aren't specified for RISC-V on Microsoft's page.

Do you know if these have been decided upon yet?

vlsunil commented 2 years ago

I am not an expert here. But I believe IMAGE_FILE_RELOCS_STRIPPED is set for RISC-V EFI images and no COFF relocations are added to MS spec.

Copying Heinrich and Atish to see whether they have any information. @xypron @atishp04

vlsunil commented 2 years ago

Here is what I see for Linux kernel EFI image.

file     linux/arch/riscv/boot/Image
size     0x12e3000
humansz  18.9M
mode     r-x
format   pe64
iorw     false
block    0x100
type     EXEC (Executable file)
arch     riscv
baddr    0x10000
binsz    19804160
bintype  pe
bits     64
canary   true
retguard false
class    PE32+
cmp.csum 0x012f039f
compiled Thu Jan  1 05:30:00 1970
crypto   false
endian   little
havecode true
hdr.csum 0x00000000
laddr    0x0
lang     c
linenum  true
lsyms    false
machine  RISC-V 64-bit
nx       false
os       efi
overlay  false
cc       ms
pic      false
relocs   false
signed   false
sanitize false
static   true
stripped true
subsys   EFI Application
va       true
xypron commented 2 years ago

https://docs.microsoft.com/en-us/windows/win32/debug/pe-format describes relocations in UEFI files. These have to be handled by the UEFI firmware. Binutil's objcopy will have to care about translating relocations that exist in ELF files. The ELF relocations are described in https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#relocations.

There are two ways that objcopy could handle relocations:

An example of relocation handling in the start code can be found in

Here only a single relocation type had to be supported due to the specific compiler flags used by gnu-efi.

maharmstone commented 2 years ago

Sorry, I might not have made myself clear...

If I want to create an EFI image for amd64, I can use the normal Windows cross-compiler x86_64-w64-mingw32-gcc. GCC creates COFF object files, and ld links them together into a PE file. The only thing to watch out for is that you need to tell ld to use a different subsytem value.

If I want to create a RISC-V EFI image, AIUI the only way is to create an ELF image using a Linux RISC-V cross-compiler, then mess about using objcopy etc. to hand-craft a PE file. This is what e.g. Pete Batard does at https://github.com/pbatard/efifs/.

It'd be much easier if there were a proper cross-compiler for RISC-V EFI, as there is for amd64, x86, and (with LLVM) ARM. However, there would need to be a specificiation for the relocation types within the object files (i.e. the equivalent of IMAGE_REL_ARM64_PAGEOFFSET_12A etc. in the Microsoft document). If I were to add "coff-riscv" support to binutils, I could make up my own constants, or copy those of the ELF specs, but that'd run the risk of someone else choosing different values later on.

xypron commented 2 years ago

gcc creates ELF object files. It would be desirable that binutils' linker ld could take these and produce a RISC-V UEFI binary.

Windows tools for x86_64 and aarch64 use COFF object files. But why should this file format concern binutils' linker on RISC-V?

vlsunil commented 2 years ago

Hi @maharmstone , it looks like this issue belongs to toolchain. Could you close this here and continue the discussion if required in toolchain repo/ML?