소스 검색

LibELF+readelf: Add support for RISC-V dynamic relocation types

Sönke Holz 1 년 전
부모
커밋
0b0ea19d12

+ 2 - 0
Userland/Libraries/LibELF/Arch/GenericDynamicRelocationType.h

@@ -10,6 +10,8 @@
 
 #if ARCH(AARCH64)
 #    include <Userland/Libraries/LibELF/Arch/aarch64/GenericDynamicRelocationType.h>
+#elif ARCH(RISCV64)
+#    include <Userland/Libraries/LibELF/Arch/riscv64/GenericDynamicRelocationType.h>
 #elif ARCH(X86_64)
 #    include <Userland/Libraries/LibELF/Arch/x86_64/GenericDynamicRelocationType.h>
 #else

+ 30 - 0
Userland/Libraries/LibELF/Arch/riscv64/GenericDynamicRelocationType.h

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024, Sönke Holz <sholz8530@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <Userland/Libraries/LibELF/ELFABI.h>
+
+#include <AK/Platform.h>
+VALIDATE_IS_RISCV64()
+
+namespace ELF {
+
+enum class GenericDynamicRelocationType : unsigned {
+    NONE = R_RISCV_NONE,
+    ABSOLUTE = R_RISCV_64,
+    COPY = R_RISCV_COPY,
+    // there is no R_RISCV_GLOB_DAT
+    JUMP_SLOT = R_RISCV_JUMP_SLOT,
+    RELATIVE = R_RISCV_RELATIVE,
+    TLS_DTPMOD = R_RISCV_TLS_DTPMOD64,
+    TLS_DTPREL = R_RISCV_TLS_DTPREL64,
+    TLS_TPREL = R_RISCV_TLS_TPREL64,
+    TLSDESC = R_RISCV_TLSDESC,
+    IRELATIVE = R_RISCV_IRELATIVE,
+};
+
+}

+ 3 - 1
Userland/Libraries/LibELF/DynamicLoader.cpp

@@ -536,7 +536,7 @@ void DynamicLoader::load_program_headers()
 
 DynamicLoader::RelocationResult DynamicLoader::do_direct_relocation(DynamicObject::Relocation const& relocation,
     Optional<DynamicLoader::CachedLookupResult>& cached_result,
-    ShouldInitializeWeak should_initialize_weak,
+    [[maybe_unused]] ShouldInitializeWeak should_initialize_weak,
     ShouldCallIfuncResolver should_call_ifunc_resolver)
 {
     FlatPtr* patch_ptr = nullptr;
@@ -603,6 +603,7 @@ DynamicLoader::RelocationResult DynamicLoader::do_direct_relocation(DynamicObjec
             *patch_ptr = call_ifunc_resolver(VirtualAddress { *patch_ptr }).get();
         break;
     }
+#if !ARCH(RISCV64)
     case GLOB_DAT: {
         auto symbol = relocation.symbol();
         auto res = lookup_symbol(symbol);
@@ -633,6 +634,7 @@ DynamicLoader::RelocationResult DynamicLoader::do_direct_relocation(DynamicObjec
         *patch_ptr = symbol_location.get();
         break;
     }
+#endif
     case RELATIVE: {
         if (!image().is_dynamic())
             break;

+ 24 - 0
Userland/Libraries/LibELF/ELFABI.h

@@ -882,3 +882,27 @@ struct elf_args {
     R(R_AARCH64_TLS_TPREL)                    \
     R(R_AARCH64_TLSDESC)                      \
     R(R_AARCH64_IRELATIVE)
+
+/* https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/v1.0/riscv-elf.adoc#relocations */
+#define R_RISCV_NONE 0
+#define R_RISCV_64 2
+#define R_RISCV_RELATIVE 3
+#define R_RISCV_COPY 4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD64 7
+#define R_RISCV_TLS_DTPREL64 9
+#define R_RISCV_TLS_TPREL64 11
+#define R_RISCV_TLSDESC 12
+#define R_RISCV_IRELATIVE 58
+
+#define __ENUMERATE_RISCV_DYNAMIC_RELOCS(R) \
+    R(R_RISCV_NONE)                         \
+    R(R_RISCV_64)                           \
+    R(R_RISCV_RELATIVE)                     \
+    R(R_RISCV_COPY)                         \
+    R(R_RISCV_JUMP_SLOT)                    \
+    R(R_RISCV_TLS_DTPMOD64)                 \
+    R(R_RISCV_TLS_DTPREL64)                 \
+    R(R_RISCV_TLS_TPREL64)                  \
+    R(R_RISCV_TLSDESC)                      \
+    R(R_RISCV_IRELATIVE)

+ 4 - 0
Userland/Utilities/readelf.cpp

@@ -197,6 +197,10 @@ static char const* object_relocation_type_to_string(Elf_Half machine, Elf_Word t
         switch (type) {
             __ENUMERATE_AARCH64_DYNAMIC_RELOCS(ENUMERATE_RELOCATION)
         }
+    } else if (machine == EM_RISCV) {
+        switch (type) {
+            __ENUMERATE_RISCV_DYNAMIC_RELOCS(ENUMERATE_RELOCATION)
+        }
     }
 #undef ENUMERATE_RELOCATION
     return "(?)";