diff --git a/src/system/boot/loader/Jamfile b/src/system/boot/loader/Jamfile index 66b255cf96..81d06d3113 100644 --- a/src/system/boot/loader/Jamfile +++ b/src/system/boot/loader/Jamfile @@ -70,11 +70,16 @@ for platform in [ MultiBootSubDirSetup ] { BOOT_SUPPORT_ELF64 ; } - case "risc-v" : + case "riscv64" : { DEFINES += BOOT_SUPPORT_ELF64 ; + if $(TARGET_BOOT_PLATFORM) = efi { + DEFINES += + _BOOT_PLATFORM_EFI + ; + } } case "m68k" : { diff --git a/src/system/kernel/arch/riscv64/arch_elf.cpp b/src/system/kernel/arch/riscv64/arch_elf.cpp index e34c185241..763d6a1d03 100644 --- a/src/system/kernel/arch/riscv64/arch_elf.cpp +++ b/src/system/kernel/arch/riscv64/arch_elf.cpp @@ -1,13 +1,15 @@ /* - * Copyright 2019, Adrien Destugues - * Copyright 2010, Ithamar R. Adema - * Copyright 2009, Johannes Wischert, johanneswi@gmail.com. - * Copyright 2005, Ingo Weinhold . - * Copyright 2002, Travis Geiselbrecht. All rights reserved. + * Copyright 2004-2018 Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. + * Copyright 2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. */ +#ifdef _BOOT_MODE +# include +#endif + #include #include @@ -17,10 +19,8 @@ //#define TRACE_ARCH_ELF #ifdef TRACE_ARCH_ELF # define TRACE(x) dprintf x -# define CHATTY 1 #else # define TRACE(x) ; -# define CHATTY 0 #endif @@ -29,71 +29,92 @@ static bool is_in_image(struct elf_image_info *image, addr_t address) { return (address >= image->text_region.start - && address < image->text_region.start + image->text_region.size) + && address < image->text_region.start + + image->text_region.size) || (address >= image->data_region.start - && address < image->data_region.start + image->data_region.size); + && address < image->data_region.start + + image->data_region.size); } #endif // !_BOOT_MODE +#ifdef _BOOT_MODE +status_t +boot_arch_elf_relocate_rel(preloaded_elf64_image* image, Elf64_Rel* rel, + int relLength) +#else int arch_elf_relocate_rel(struct elf_image_info *image, - struct elf_image_info *resolve_image, Elf64_Rel *rel, int rel_len) + struct elf_image_info *resolveImage, Elf64_Rel *rel, int relLength) +#endif { - // TODO: rel entries in RISCV64 elf - return B_NO_ERROR; -} - - -static inline void -write_32(addr_t P, Elf32_Word value) -{ - *(Elf32_Word*)P = value; -} - - -static inline void -write_16(addr_t P, Elf32_Word value) -{ - // bits 16:29 - *(Elf32_Half*)P = (Elf32_Half)value; -} - - -static inline bool -write_16_check(addr_t P, Elf32_Word value) -{ - // bits 15:0 - if ((value & 0xffff0000) && (~value & 0xffff8000)) - return false; - *(Elf32_Half*)P = (Elf32_Half)value; - return true; -} - - -static inline bool -write_8(addr_t P, Elf32_Word value) -{ - // bits 7:0 - *(uint8 *)P = (uint8)value; - return true; -} - - -static inline bool -write_8_check(addr_t P, Elf32_Word value) -{ - // bits 7:0 - if ((value & 0xffffff00) && (~value & 0xffffff80)) - return false; - *(uint8 *)P = (uint8)value; - return true; + dprintf("arch_elf_relocate_rel: not supported on riscv64\n"); + return B_ERROR; } +#ifdef _BOOT_MODE +status_t +boot_arch_elf_relocate_rela(preloaded_elf64_image* image, Elf64_Rela* rel, + int relLength) +#else int arch_elf_relocate_rela(struct elf_image_info *image, - struct elf_image_info *resolve_image, Elf64_Rela *rel, int rel_len) + struct elf_image_info *resolveImage, Elf64_Rela *rel, int relLength) +#endif { + for (int i = 0; i < relLength / (int)sizeof(Elf64_Rela); i++) { + int type = ELF64_R_TYPE(rel[i].r_info); + int symIndex = ELF64_R_SYM(rel[i].r_info); + Elf64_Addr symAddr = 0; + + // Resolve the symbol, if any. + if (symIndex != 0) { + Elf64_Sym* symbol = SYMBOL(image, symIndex); + + status_t status; +#ifdef _BOOT_MODE + status = boot_elf_resolve_symbol(image, symbol, + &symAddr); +#else + status = elf_resolve_symbol(image, symbol, resolveImage, + &symAddr); +#endif + if (status < B_OK) + return status; + } + + // Address of the relocation. + Elf64_Addr relocAddr = image->text_region.delta + + rel[i].r_offset; + + // Calculate the relocation value. + Elf64_Addr relocValue; + switch (type) { + case R_RISCV_NONE: + continue; + case R_RISCV_64: + relocValue = symAddr + rel[i].r_addend; + break; + case R_RISCV_RELATIVE: + relocValue = image->text_region.delta + + rel[i].r_addend; + break; + default: + dprintf("arch_elf_relocate_rela: unhandled" + "relocation type %d\n", type); + return B_BAD_DATA; + } +#ifdef _BOOT_MODE + boot_elf64_set_relocation(relocAddr, relocValue); +#else + if (!is_in_image(image, relocAddr)) { + dprintf("arch_elf_relocate_rela: invalid offset %#lx\n", + rel[i].r_offset); + return B_BAD_ADDRESS; + } +#endif + } + return B_OK; }