Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

riscv: Prepare EFI header for relocatable kernels

ld does not handle relocations correctly as explained here [1],
a fix for that was proposed by Nelson there but we have to support older
toolchains and then provide this fix.

Note that llvm does not need this fix and is then excluded.

[1] https://sourceware.org/pipermail/binutils/2023-March/126690.html

Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Link: https://lore.kernel.org/r/20230329045329.64565-2-alexghiti@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

authored by

Alexandre Ghiti and committed by
Palmer Dabbelt
55de1e4a fe15c26e

+21 -6
+3
arch/riscv/include/asm/set_memory.h
··· 56 56 #define SECTION_ALIGN L1_CACHE_BYTES 57 57 #endif /* CONFIG_STRICT_KERNEL_RWX */ 58 58 59 + #define PECOFF_SECTION_ALIGNMENT 0x1000 60 + #define PECOFF_FILE_ALIGNMENT 0x200 61 + 59 62 #endif /* _ASM_RISCV_SET_MEMORY_H */
+16 -3
arch/riscv/kernel/efi-header.S
··· 6 6 7 7 #include <linux/pe.h> 8 8 #include <linux/sizes.h> 9 + #include <asm/set_memory.h> 9 10 10 11 .macro __EFI_PE_HEADER 11 12 .long PE_MAGIC ··· 34 33 .byte 0x02 // MajorLinkerVersion 35 34 .byte 0x14 // MinorLinkerVersion 36 35 .long __pecoff_text_end - efi_header_end // SizeOfCode 37 - .long __pecoff_data_virt_size // SizeOfInitializedData 36 + #ifdef __clang__ 37 + .long __pecoff_data_virt_size // SizeOfInitializedData 38 + #else 39 + .long __pecoff_data_virt_end - __pecoff_text_end // SizeOfInitializedData 40 + #endif 38 41 .long 0 // SizeOfUninitializedData 39 42 .long __efistub_efi_pe_entry - _start // AddressOfEntryPoint 40 43 .long efi_header_end - _start // BaseOfCode ··· 96 91 IMAGE_SCN_MEM_EXECUTE // Characteristics 97 92 98 93 .ascii ".data\0\0\0" 99 - .long __pecoff_data_virt_size // VirtualSize 94 + #ifdef __clang__ 95 + .long __pecoff_data_virt_size // VirtualSize 96 + #else 97 + .long __pecoff_data_virt_end - __pecoff_text_end // VirtualSize 98 + #endif 100 99 .long __pecoff_text_end - _start // VirtualAddress 101 - .long __pecoff_data_raw_size // SizeOfRawData 100 + #ifdef __clang__ 101 + .long __pecoff_data_raw_size // SizeOfRawData 102 + #else 103 + .long __pecoff_data_raw_end - __pecoff_text_end // SizeOfRawData 104 + #endif 102 105 .long __pecoff_text_end - _start // PointerToRawData 103 106 104 107 .long 0 // PointerToRelocations
+2 -3
arch/riscv/kernel/vmlinux.lds.S
··· 27 27 28 28 jiffies = jiffies_64; 29 29 30 - PECOFF_SECTION_ALIGNMENT = 0x1000; 31 - PECOFF_FILE_ALIGNMENT = 0x200; 32 - 33 30 SECTIONS 34 31 { 35 32 /* Beginning of code and text segment */ ··· 129 132 #ifdef CONFIG_EFI 130 133 .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); } 131 134 __pecoff_data_raw_size = ABSOLUTE(. - __pecoff_text_end); 135 + __pecoff_data_raw_end = ABSOLUTE(.); 132 136 #endif 133 137 134 138 /* End of data section */ ··· 140 142 #ifdef CONFIG_EFI 141 143 . = ALIGN(PECOFF_SECTION_ALIGNMENT); 142 144 __pecoff_data_virt_size = ABSOLUTE(. - __pecoff_text_end); 145 + __pecoff_data_virt_end = ABSOLUTE(.); 143 146 #endif 144 147 _end = .; 145 148