[llvm] [JITLink] Add support for R_X86_64_SIZE* relocations. (PR #110081)
Xing Guo via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 26 00:53:32 PDT 2024
https://github.com/higuoxing updated https://github.com/llvm/llvm-project/pull/110081
>From f1f0e9cdbb7da601774185dac6af50f677b73654 Mon Sep 17 00:00:00 2001
From: Xing Guo <higuoxing at gmail.com>
Date: Thu, 26 Sep 2024 07:52:07 +0800
Subject: [PATCH] [JITLink] Add support for R_X86_64_SIZE* relocations.
This patch adds support for R_X86_64_SIZE32/R_X86_64_SIZE64 relocation
types by introducing edge kinds x86_64::Size32/x86_64::Size64. The
calculation for these relocations is: Z + A, where:
Z - Represents the size of the symbol whose index resides in the
relocation entry.
A - Represents the addend used to compute the value of the relocation
field.
Ref: [System V Application Binary Interface x86-64](https://gitlab.com/x86-psABIs/x86-64-ABI/-/jobs/artifacts/master/raw/x86-64-ABI/abi.pdf?job=build)
---
.../llvm/ExecutionEngine/JITLink/x86_64.h | 34 +++++++++++++++++++
.../ExecutionEngine/JITLink/ELF_x86_64.cpp | 6 ++++
llvm/lib/ExecutionEngine/JITLink/x86_64.cpp | 4 +++
.../JITLink/x86-64/ELF_R_X86_64_SIZE.s | 27 +++++++++++++++
4 files changed, 71 insertions(+)
create mode 100644 llvm/test/ExecutionEngine/JITLink/x86-64/ELF_R_X86_64_SIZE.s
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
index 24cf982fc3ab0f..0d7e0fdb5820b5 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
@@ -142,6 +142,24 @@ enum EdgeKind_x86_64 : Edge::Kind {
/// an out-of-range error will be returned.
NegDelta32,
+ /// A 64-bit size relocation.
+ ///
+ /// Fixup expression:
+ /// Fixup <- Size + Addend : uint64
+ ///
+ Size64,
+
+ /// A 32-bit size relocation.
+ ///
+ /// Fixup expression:
+ /// Fixup <- Size + Addend : uint32
+ ///
+ /// Errors:
+ /// - The result of the fixup expression must fit into an uint32, otherwise
+ /// an out-of-range error will be returned.
+ ///
+ Size32,
+
/// A 64-bit GOT delta.
///
/// Delta from the global offset table to the target
@@ -531,6 +549,22 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
return makeTargetOutOfRangeError(G, B, E);
break;
}
+
+ case Size64: {
+ uint64_t Value = E.getTarget().getSize() + E.getAddend();
+ *(ulittle64_t *)FixupPtr = Value;
+ break;
+ }
+
+ case Size32: {
+ uint64_t Value = E.getTarget().getSize() + E.getAddend();
+ if (LLVM_LIKELY(isUInt<32>(Value)))
+ *(ulittle32_t *)FixupPtr = Value;
+ else
+ return makeTargetOutOfRangeError(G, B, E);
+ break;
+ }
+
case Delta64FromGOT: {
assert(GOTSymbol && "No GOT section symbol");
int64_t Value =
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
index 6a32ccc3776510..44122726fb5c08 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
@@ -182,6 +182,12 @@ class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder<object::ELF64LE> {
case ELF::R_X86_64_64:
Kind = x86_64::Pointer64;
break;
+ case ELF::R_X86_64_SIZE32:
+ Kind = x86_64::Size32;
+ break;
+ case ELF::R_X86_64_SIZE64:
+ Kind = x86_64::Size64;
+ break;
case ELF::R_X86_64_GOTPCREL:
Kind = x86_64::RequestGOTAndTransformToDelta32;
break;
diff --git a/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp
index cca4358a377660..e5b48d2c3fab0e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp
@@ -42,6 +42,10 @@ const char *getEdgeKindName(Edge::Kind K) {
return "NegDelta64";
case NegDelta32:
return "NegDelta32";
+ case Size64:
+ return "Size64";
+ case Size32:
+ return "Size32";
case Delta64FromGOT:
return "Delta64FromGOT";
case PCRel32:
diff --git a/llvm/test/ExecutionEngine/JITLink/x86-64/ELF_R_X86_64_SIZE.s b/llvm/test/ExecutionEngine/JITLink/x86-64/ELF_R_X86_64_SIZE.s
new file mode 100644
index 00000000000000..abde122f76e237
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/x86-64/ELF_R_X86_64_SIZE.s
@@ -0,0 +1,27 @@
+# Checks that JITLink is able to handle R_X86_64_SIZE32/R_X86_64_SIZE64 relocations.
+# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent \
+# RUN: -filetype=obj -o %t.1.o %s
+# RUN: llvm-jitlink -noexec %t.1.o
+
+# Checks that JITLink emits an error message when the fixup cannot fit into a 32-bit value.
+# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent --defsym=OVERFLOW=1 \
+# RUN: -filetype=obj -o %t.2.o %s
+# RUN: not llvm-jitlink -noexec %t.2.o 2>&1 | FileCheck %s
+# CHECK: llvm-jitlink error: In graph {{.*}}, section .text: relocation target "main" at address {{.*}} is out of range of Size32 fixup at {{.*}} (main, {{.*}})
+
+ .text
+ .globl main
+ .type main, at function
+main:
+ xorl %eax, %eax
+ movq main at SIZE + 2, %rbx # Generate R_X86_64_SIZE32 relocation.
+.ifndef OVERFLOW
+ movl main at SIZE + 1, %ebx # Generate R_X86_64_SIZE32 relocation.
+.else
+ movl main at SIZE - 32, %ebx # Generate R_X86_64_SIZE32 relocation whose fixup overflows.
+.endif
+ retq
+ .size main, .-main
+
+ .data
+ .quad main at SIZE + 1 # Generate R_X86_64_SIZE64 relocation.
More information about the llvm-commits
mailing list