Skip to content

Commit 210140a

Browse files
authored
[JITLink] Add support for R_X86_64_SIZE* relocations. (#110081)
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)
1 parent 69f7758 commit 210140a

File tree

4 files changed

+71
-0
lines changed

4 files changed

+71
-0
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,24 @@ enum EdgeKind_x86_64 : Edge::Kind {
142142
/// an out-of-range error will be returned.
143143
NegDelta32,
144144

145+
/// A 64-bit size relocation.
146+
///
147+
/// Fixup expression:
148+
/// Fixup <- Size + Addend : uint64
149+
///
150+
Size64,
151+
152+
/// A 32-bit size relocation.
153+
///
154+
/// Fixup expression:
155+
/// Fixup <- Size + Addend : uint32
156+
///
157+
/// Errors:
158+
/// - The result of the fixup expression must fit into an uint32, otherwise
159+
/// an out-of-range error will be returned.
160+
///
161+
Size32,
162+
145163
/// A 64-bit GOT delta.
146164
///
147165
/// Delta from the global offset table to the target
@@ -531,6 +549,22 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
531549
return makeTargetOutOfRangeError(G, B, E);
532550
break;
533551
}
552+
553+
case Size64: {
554+
uint64_t Value = E.getTarget().getSize() + E.getAddend();
555+
*(ulittle64_t *)FixupPtr = Value;
556+
break;
557+
}
558+
559+
case Size32: {
560+
uint64_t Value = E.getTarget().getSize() + E.getAddend();
561+
if (LLVM_LIKELY(isUInt<32>(Value)))
562+
*(ulittle32_t *)FixupPtr = Value;
563+
else
564+
return makeTargetOutOfRangeError(G, B, E);
565+
break;
566+
}
567+
534568
case Delta64FromGOT: {
535569
assert(GOTSymbol && "No GOT section symbol");
536570
int64_t Value =

llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder<object::ELF64LE> {
182182
case ELF::R_X86_64_64:
183183
Kind = x86_64::Pointer64;
184184
break;
185+
case ELF::R_X86_64_SIZE32:
186+
Kind = x86_64::Size32;
187+
break;
188+
case ELF::R_X86_64_SIZE64:
189+
Kind = x86_64::Size64;
190+
break;
185191
case ELF::R_X86_64_GOTPCREL:
186192
Kind = x86_64::RequestGOTAndTransformToDelta32;
187193
break;

llvm/lib/ExecutionEngine/JITLink/x86_64.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ const char *getEdgeKindName(Edge::Kind K) {
4242
return "NegDelta64";
4343
case NegDelta32:
4444
return "NegDelta32";
45+
case Size64:
46+
return "Size64";
47+
case Size32:
48+
return "Size32";
4549
case Delta64FromGOT:
4650
return "Delta64FromGOT";
4751
case PCRel32:
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Checks that JITLink is able to handle R_X86_64_SIZE32/R_X86_64_SIZE64 relocations.
2+
# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent \
3+
# RUN: -filetype=obj -o %t.1.o %s
4+
# RUN: llvm-jitlink -noexec %t.1.o
5+
6+
# Checks that JITLink emits an error message when the fixup cannot fit into a 32-bit value.
7+
# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent --defsym=OVERFLOW=1 \
8+
# RUN: -filetype=obj -o %t.2.o %s
9+
# RUN: not llvm-jitlink -noexec %t.2.o 2>&1 | FileCheck %s
10+
# CHECK: llvm-jitlink error: In graph {{.*}}, section .text: relocation target "main" at address {{.*}} is out of range of Size32 fixup at {{.*}} (main, {{.*}})
11+
12+
.text
13+
.globl main
14+
.type main,@function
15+
main:
16+
xorl %eax, %eax
17+
movq main@SIZE + 2, %rbx # Generate R_X86_64_SIZE32 relocation.
18+
.ifndef OVERFLOW
19+
movl main@SIZE + 1, %ebx # Generate R_X86_64_SIZE32 relocation.
20+
.else
21+
movl main@SIZE - 32, %ebx # Generate R_X86_64_SIZE32 relocation whose fixup overflows.
22+
.endif
23+
retq
24+
.size main, .-main
25+
26+
.data
27+
.quad main@SIZE + 1 # Generate R_X86_64_SIZE64 relocation.

0 commit comments

Comments
 (0)