hrev54914 adds 1 changeset to branch 'master'
old head: 08e58a41e5bb332f6f91fe82cba6c890eb30c194
new head: 170aff0a14f32085a607341b95a23de56872a43d
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=170aff0a14f3+%5E08e58a41e5bb
----------------------------------------------------------------------------
170aff0a14f3: kernel/arch/riscv64: Fix elf image loading / add basic relocations
Change-Id: I0f24ef2585ae9f83a8cff8c145276d54298d1c6b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3677
Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>
[ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54914
Commit: 170aff0a14f32085a607341b95a23de56872a43d
URL: https://git.haiku-os.org/haiku/commit/?id=170aff0a14f3
Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date: Sun Jan 24 01:50:09 2021 UTC
Committer: Alex von Gluck IV <kallisti5@xxxxxxxxxxx>
Commit-Date: Mon Jan 25 17:10:24 2021 UTC
----------------------------------------------------------------------------
2 files changed, 86 insertions(+), 60 deletions(-)
src/system/boot/loader/Jamfile | 7 +-
src/system/kernel/arch/riscv64/arch_elf.cpp | 139 ++++++++++++++----------
----------------------------------------------------------------------------
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 <pulkomandy@xxxxxxxxxxxxx>
- * Copyright 2010, Ithamar R. Adema <ithamar.adema@xxxxxxxxxxxxxxxx>
- * Copyright 2009, Johannes Wischert, johanneswi@xxxxxxxxx.
- * Copyright 2005, Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx>.
- * 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 <boot/arch.h>
+#endif
+
#include <KernelExport.h>
#include <elf_priv.h>
@@ -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)
-{
- // 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)
+ struct elf_image_info *resolveImage, Elf64_Rel *rel, int relLength)
+#endif
{
- // 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;
}