[haiku-commits] haiku: hrev54914 - in src/system: kernel/arch/riscv64 boot/loader

  • From: Alex von Gluck IV <kallisti5@xxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 25 Jan 2021 17:10:27 +0000 (UTC)

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;
 }


Other related posts:

  • » [haiku-commits] haiku: hrev54914 - in src/system: kernel/arch/riscv64 boot/loader - Alex von Gluck IV