From dda116bc3d9c126b3c962563fc80ae332d42801d Mon Sep 17 00:00:00 2001 From: luxufan <932494295@qq.com> Date: Sun, 22 Aug 2021 16:43:02 +0800 Subject: [PATCH] [JITLink] Add support of R_X86_64_32S relocation This patch supported the R_X86_64_32S relocation and add the Pointer32Signed generic edge kind. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D108446 --- .../llvm/ExecutionEngine/JITLink/ELF_x86_64.h | 1 + llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h | 18 +++++++++++ llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp | 7 +++++ llvm/lib/ExecutionEngine/JITLink/x86_64.cpp | 2 ++ .../JITLink/X86/ELF_x86_64_absolute_relocations.s | 35 ++++++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 llvm/test/ExecutionEngine/JITLink/X86/ELF_x86_64_absolute_relocations.s diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h index 36e346c59325..611d58b97449 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h @@ -21,6 +21,7 @@ namespace jitlink { namespace ELF_x86_64_Edges { enum ELFX86RelocationKind : Edge::Kind { Branch32 = Edge::FirstRelocation, + Pointer32Signed, Pointer64, PCRel32, PCRel32GOTLoad, diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h index fdf804047db7..a11174a7f34e 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h @@ -42,6 +42,16 @@ enum EdgeKind_x86_64 : Edge::Kind { /// Pointer32, + /// A signed 32-bit pointer value relocation + /// + /// Fixup expression: + /// Fixup <- Target + Addend : int32 + /// + /// Errors: + /// - The target must reside in the signed 32-bits([-2**31, 2**32 - 1]) of + /// the address space, otherwise an out-of-range error will be returned. + Pointer32Signed, + /// A 64-bit delta. /// /// Delta from the fixup to the target. @@ -380,6 +390,14 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E, return makeTargetOutOfRangeError(G, B, E); break; } + case Pointer32Signed: { + int64_t Value = E.getTarget().getAddress() + E.getAddend(); + if (LLVM_LIKELY(isInRangeForImmS32(Value))) + *(little32_t *)FixupPtr = Value; + else + return makeTargetOutOfRangeError(G, B, E); + break; + } case BranchPCRel32: case BranchPCRel32ToPtrJumpStub: diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp index 736bcada9c8f..e65af56a2f24 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp @@ -176,6 +176,8 @@ private: static Expected getRelocationKind(const uint32_t Type) { switch (Type) { + case ELF::R_X86_64_32S: + return ELF_x86_64_Edges::ELFX86RelocationKind::Pointer32Signed; case ELF::R_X86_64_PC32: return ELF_x86_64_Edges::ELFX86RelocationKind::PCRel32; case ELF::R_X86_64_PC64: @@ -298,6 +300,9 @@ private: case Delta64: Kind = x86_64::Delta64; break; + case Pointer32Signed: + Kind = x86_64::Pointer32Signed; + break; case Pointer64: Kind = x86_64::Pointer64; break; @@ -497,6 +502,8 @@ const char *getELFX86RelocationKindName(Edge::Kind R) { switch (R) { case Branch32: return "Branch32"; + case Pointer32Signed: + return "Pointer32Signed"; case Pointer64: return "Pointer64"; case PCRel32: diff --git a/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp index c2e25c6c685e..4c107cbf4192 100644 --- a/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp @@ -24,6 +24,8 @@ const char *getEdgeKindName(Edge::Kind K) { return "Pointer64"; case Pointer32: return "Pointer32"; + case Pointer32Signed: + return "Pointer32Signed"; case Delta64: return "Delta64"; case Delta32: diff --git a/llvm/test/ExecutionEngine/JITLink/X86/ELF_x86_64_absolute_relocations.s b/llvm/test/ExecutionEngine/JITLink/X86/ELF_x86_64_absolute_relocations.s new file mode 100644 index 000000000000..56dc1e0eca20 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/X86/ELF_x86_64_absolute_relocations.s @@ -0,0 +1,35 @@ +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent -filetype=obj \ +# RUN: -o %t/elf_abs_reloc.o %s +# RUN: llvm-jitlink -noexec -slab-allocate 100Kb -slab-address 0xfff00000 \ +# RUN: -define-abs external_data_low=0x1 \ +# RUN: -define-abs external_data_high=0xffffffff80000000 \ +# RUN: -check %s %t/elf_abs_reloc.o +# +# Test ELF absolute relocations. + + + .text + .file "testcase.c" + +# Empty main entry point. + .globl main + .p2align 4, 0x90 + .type main,@function +main: + retq + + .size main, .-main + +# R_X86_64_32S handling +# Test the target value is in range of signed 32-bits imm +# jitlink-check: decode_operand(test_abs_32S, 4) = external_data_low +# jitlink-check: decode_operand(test_abs_32S+7, 4)[31:0] = external_data_high[31:0] + .globl test_abs_32S + .p2align 4, 0x90 + .type test_abs_32S,@function +test_abs_32S: + movl external_data_low, %eax + movl external_data_high, %esi + + .size test_abs_32S, .-test_abs_32S -- 2.11.4.GIT