From 3af7bbca4a0ef64de64b8bb38d3b167673ec60f0 Mon Sep 17 00:00:00 2001 From: fourdim Date: Thu, 17 Feb 2022 23:00:55 +0800 Subject: [PATCH] [JITLink][RISCV] fix the extractBits behavior and add R_RISCV_JAL relocation. This patch supports the R_RISCV_JAL relocation. Moreover, it will fix the extractBits function's behavior as it extracts Size + 1 bits. In the test ELF_jal.s: Before: ``` Hi: 4294836480 extractBits(Hi, 12, 8): 480 ``` After: ``` Hi: 4294836480 extractBits(Hi, 12, 8): 224 ``` Reviewed By: StephenFan Differential Revision: https://reviews.llvm.org/D117975 --- llvm/include/llvm/ExecutionEngine/JITLink/riscv.h | 7 +++++ llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp | 16 ++++++++++ llvm/lib/ExecutionEngine/JITLink/riscv.cpp | 2 ++ llvm/test/ExecutionEngine/JITLink/RISCV/ELF_jal.s | 37 +++++++++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 llvm/test/ExecutionEngine/JITLink/RISCV/ELF_jal.s diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h b/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h index d0d3a37..2d32a74 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h @@ -44,6 +44,13 @@ enum EdgeKind_riscv : Edge::Kind { /// R_RISCV_BRANCH, + /// High 20 bits of PC-relative jump pointer value relocation + /// + /// Fixup expression: + /// Fixup <- Target - Fixup + Addend + /// + R_RISCV_JAL, + /// High 20 bits of 32-bit pointer value relocation /// /// Fixup expression diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp index 90f3a38..469a81d 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -220,6 +220,20 @@ private: *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7; break; } + case R_RISCV_JAL: { + int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; + Error AlignmentIssue = checkAlignment(FixupAddress, Value, 2, E); + if (AlignmentIssue) { + return AlignmentIssue; + } + uint32_t Imm20 = extractBits(Value, 20, 1) << 31; + uint32_t Imm10_1 = extractBits(Value, 1, 10) << 21; + uint32_t Imm11 = extractBits(Value, 11, 1) << 20; + uint32_t Imm19_12 = extractBits(Value, 12, 8) << 12; + uint32_t RawInstr = *(little32_t *)FixupPtr; + *(little32_t *)FixupPtr = RawInstr | Imm20 | Imm10_1 | Imm11 | Imm19_12; + break; + } case R_RISCV_HI20: { int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); int64_t Hi = Value + 0x800; @@ -409,6 +423,8 @@ private: return EdgeKind_riscv::R_RISCV_64; case ELF::R_RISCV_BRANCH: return EdgeKind_riscv::R_RISCV_BRANCH; + case ELF::R_RISCV_JAL: + return EdgeKind_riscv::R_RISCV_JAL; case ELF::R_RISCV_HI20: return EdgeKind_riscv::R_RISCV_HI20; case ELF::R_RISCV_LO12_I: diff --git a/llvm/lib/ExecutionEngine/JITLink/riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/riscv.cpp index 3ce2cf1..0bd57b6 100644 --- a/llvm/lib/ExecutionEngine/JITLink/riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/riscv.cpp @@ -26,6 +26,8 @@ const char *getEdgeKindName(Edge::Kind K) { return "R_RISCV_64"; case R_RISCV_BRANCH: return "R_RISCV_BRANCH"; + case R_RISCV_JAL: + return "R_RISCV_JAL"; case R_RISCV_HI20: return "R_RISCV_HI20"; case R_RISCV_LO12_I: diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_jal.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_jal.s new file mode 100644 index 0000000..82f1235 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_jal.s @@ -0,0 +1,37 @@ +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc -triple=riscv64 -filetype=obj \ +# RUN: -o %t/elf_riscv64_jal.o %s +# RUN: llvm-mc -triple=riscv32 -filetype=obj \ +# RUN: -o %t/elf_riscv32_jal.o %s +# RUN: llvm-jitlink -noexec \ +# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \ +# RUN: -define-abs external_func=0x1fe000fe \ +# RUN: -check %s %t/elf_riscv64_jal.o +# RUN: llvm-jitlink -noexec \ +# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \ +# RUN: -define-abs external_func=0x1fe000fe \ +# RUN: -check %s %t/elf_riscv32_jal.o +# + + .text + .file "testcase.c" + +# Empty main entry point. + .globl main + .p2align 1 + .type main,@function +main: + ret + + .size main, .-main + +# Test R_RISCV_JAL + +# jitlink-check: decode_operand(test_jal, 1)[31:12] = (external_func - test_jal)[31:12] + .globl test_jal + .p2align 1 + .type test_jal,@function +test_jal: + jal x0, external_func + + .size test_jal, .-test_jal -- 2.7.4