[llvm] [JITLink] fix i686 R_386_32 relocation value (PR #111091)
Jameson Nash via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 4 10:11:44 PDT 2024
https://github.com/vtjnash updated https://github.com/llvm/llvm-project/pull/111091
>From 0d56a9f39f17c85c0bcad448dfecf6cacc0a3c3f Mon Sep 17 00:00:00 2001
From: Jameson Nash <vtjnash at gmail.com>
Date: Thu, 3 Oct 2024 21:24:44 +0000
Subject: [PATCH] [JITLink] fix most i686 relocations to include addend
Most relocations involve adding the value at the location with a value
taken from elsewhere. Most of them were hard coded instead. Assume
signed, since the math is the same either way after truncation, but this
seems more likely to give reasonable looking intermediate results.
---
.../llvm/ExecutionEngine/JITLink/i386.h | 33 +++++--------------
llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp | 20 +++++++++--
.../i386/ELF_i386_absolute_relocations_16.s | 10 +++++-
.../i386/ELF_i386_absolute_relocations_32.s | 16 ++++++---
.../ELF_i386_pc_relative_relocations_32.s | 7 ++--
.../i386/ELF_i386_small_pic_relocations_got.s | 12 +++----
.../i386/ELF_i386_small_pic_relocations_plt.s | 6 ++--
7 files changed, 60 insertions(+), 44 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/i386.h b/llvm/include/llvm/ExecutionEngine/JITLink/i386.h
index f8d24d8bf31ca0..efe8182934dd76 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/i386.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/i386.h
@@ -39,12 +39,8 @@ enum EdgeKind_i386 : Edge::Kind {
/// Represents a data/control flow instruction using PC-relative addressing
/// to a target.
///
- /// The fixup expression for this kind includes an implicit offset to account
- /// for the PC (unlike the Delta edges) so that a PCRel32 with a target
- /// T and addend zero is a call/branch to the start (offset zero) of T.
- ///
/// Fixup expression:
- /// Fixup <- Target - (Fixup + 4) + Addend : int32
+ /// Fixup <- Target - Fixup + Addend : int32
///
/// Errors:
/// - The result of the fixup expression must fit into an int32, otherwise
@@ -68,12 +64,8 @@ enum EdgeKind_i386 : Edge::Kind {
/// Represents a data/control flow instruction using PC-relative addressing
/// to a target.
///
- /// The fixup expression for this kind includes an implicit offset to account
- /// for the PC (unlike the Delta edges) so that a PCRel16 with a target
- /// T and addend zero is a call/branch to the start (offset zero) of T.
- ///
/// Fixup expression:
- /// Fixup <- Target - (Fixup + 4) + Addend : int16
+ /// Fixup <- Target - Fixup + Addend : int16
///
/// Errors:
/// - The result of the fixup expression must fit into an int16, otherwise
@@ -86,7 +78,7 @@ enum EdgeKind_i386 : Edge::Kind {
/// Delta from the fixup to the target.
///
/// Fixup expression:
- /// Fixup <- Target - Fixup + Addend : int64
+ /// Fixup <- Target - Fixup + Addend : int32
///
/// Errors:
/// - The result of the fixup expression must fit into an int32, otherwise
@@ -130,12 +122,8 @@ enum EdgeKind_i386 : Edge::Kind {
/// Represents a PC-relative call or branch to a target. This can be used to
/// identify, record, and/or patch call sites.
///
- /// The fixup expression for this kind includes an implicit offset to account
- /// for the PC (unlike the Delta edges) so that a Branch32PCRel with a target
- /// T and addend zero is a call/branch to the start (offset zero) of T.
- ///
/// Fixup expression:
- /// Fixup <- Target - (Fixup + 4) + Addend : int32
+ /// Fixup <- Target - Fixup + Addend : int32
///
/// Errors:
/// - The result of the fixup expression must fit into an int32, otherwise
@@ -164,7 +152,7 @@ enum EdgeKind_i386 : Edge::Kind {
/// target may be recorded to allow manipulation at runtime.
///
/// Fixup expression:
- /// Fixup <- Target - Fixup + Addend - 4 : int32
+ /// Fixup <- Target - Fixup + Addend : int32
///
/// Errors:
/// - The result of the fixup expression must fit into an int32, otherwise
@@ -180,7 +168,7 @@ enum EdgeKind_i386 : Edge::Kind {
/// is within range of the fixup location.
///
/// Fixup expression:
- /// Fixup <- Target - Fixup + Addend - 4: int32
+ /// Fixup <- Target - Fixup + Addend : int32
///
/// Errors:
/// - The result of the fixup expression must fit into an int32, otherwise
@@ -215,8 +203,7 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
}
case i386::PCRel32: {
- int32_t Value =
- E.getTarget().getAddress() - (FixupAddress + 4) + E.getAddend();
+ int32_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
*(little32_t *)FixupPtr = Value;
break;
}
@@ -231,8 +218,7 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
}
case i386::PCRel16: {
- int32_t Value =
- E.getTarget().getAddress() - (FixupAddress + 4) + E.getAddend();
+ int32_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
if (LLVM_LIKELY(isInt<16>(Value)))
*(little16_t *)FixupPtr = Value;
else
@@ -257,8 +243,7 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
case i386::BranchPCRel32:
case i386::BranchPCRel32ToPtrJumpStub:
case i386::BranchPCRel32ToPtrJumpStubBypassable: {
- int32_t Value =
- E.getTarget().getAddress() - (FixupAddress + 4) + E.getAddend();
+ int32_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
*(little32_t *)FixupPtr = Value;
break;
}
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp
index 860165365a7e4f..2d5f28cad1cc6d 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp
@@ -186,15 +186,29 @@ class ELFLinkGraphBuilder_i386 : public ELFLinkGraphBuilder<ELFT> {
int64_t Addend = 0;
switch (*Kind) {
- case i386::EdgeKind_i386::Delta32: {
+ case i386::EdgeKind_i386::None:
+ break;
+ case i386::EdgeKind_i386::Pointer32:
+ case i386::EdgeKind_i386::PCRel32:
+ case i386::EdgeKind_i386::RequestGOTAndTransformToDelta32FromGOT:
+ case i386::EdgeKind_i386::Delta32:
+ case i386::EdgeKind_i386::Delta32FromGOT:
+ case i386::EdgeKind_i386::BranchPCRel32:
+ case i386::EdgeKind_i386::BranchPCRel32ToPtrJumpStub:
+ case i386::EdgeKind_i386::BranchPCRel32ToPtrJumpStubBypassable: {
const char *FixupContent = BlockToFix.getContent().data() +
(FixupAddress - BlockToFix.getAddress());
- Addend = *(const support::ulittle32_t *)FixupContent;
+ Addend = *(const support::little32_t *)FixupContent;
break;
}
- default:
+ case i386::EdgeKind_i386::Pointer16:
+ case i386::EdgeKind_i386::PCRel16: {
+ const char *FixupContent = BlockToFix.getContent().data() +
+ (FixupAddress - BlockToFix.getAddress());
+ Addend = *(const support::little16_t *)FixupContent;
break;
}
+ }
Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
Edge GE(*Kind, Offset, *GraphSymbol, Addend);
diff --git a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_absolute_relocations_16.s b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_absolute_relocations_16.s
index 47142c4be3c09e..092f7d753c7eae 100644
--- a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_absolute_relocations_16.s
+++ b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_absolute_relocations_16.s
@@ -22,4 +22,12 @@ main:
.type bar, at function
bar:
retw $external_data
- .size bar, .-bar
\ No newline at end of file
+ .size bar, .-bar
+
+# jitlink-check: decode_operand(baz, 0) = external_data + 23
+ .globl baz
+ .align 2, 0x90
+ .type baz, at function
+baz:
+ retw $external_data+23
+ .size baz, .-baz
diff --git a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_absolute_relocations_32.s b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_absolute_relocations_32.s
index e4b02a794bbc4a..a66ad8e7cda677 100644
--- a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_absolute_relocations_32.s
+++ b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_absolute_relocations_32.s
@@ -7,17 +7,25 @@
# Test ELF 32 bit absolute relocations
.text
- .globl main
+ .globl main
.p2align 4, 0x90
.type main, at function
-main:
+main:
retl
.size main, .-main
# jitlink-check: decode_operand(foo, 0) = external_data
- .globl foo
+ .globl foo
.p2align 4, 0x90
.type foo, at function
foo:
movl external_data, %eax
- .size foo, .-foo
\ No newline at end of file
+ .size foo, .-foo
+
+# jitlink-check: decode_operand(bar, 0) = external_data + 4000
+ .globl bar
+ .p2align 4, 0x90
+ .type bar, at function
+bar:
+ movl external_data + 4000, %eax
+ .size bar, .-bar
diff --git a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_pc_relative_relocations_32.s b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_pc_relative_relocations_32.s
index df74c7bb39324a..0717c8f434d537 100644
--- a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_pc_relative_relocations_32.s
+++ b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_pc_relative_relocations_32.s
@@ -33,11 +33,12 @@ foo:
# Tests PC relative relocation for negative offset from PC
-# jitlink-check: decode_operand(baz, 0) = fooz - next_pc(baz)
+# jitlink-check: decode_operand(baz, 0) = fooz - next_pc(baz) + 1
.globl fooz
.p2align 4
.type fooz, at function
fooz:
+ nop
retl
.size fooz, .-fooz
@@ -45,5 +46,5 @@ fooz:
.p2align 4
.type baz, at function
baz:
- calll fooz
- .size baz, .-baz
\ No newline at end of file
+ calll fooz+1
+ .size baz, .-baz
diff --git a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_small_pic_relocations_got.s b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_small_pic_relocations_got.s
index 91049a8a87a551..080341ac3bfede 100644
--- a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_small_pic_relocations_got.s
+++ b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_small_pic_relocations_got.s
@@ -19,29 +19,29 @@ main:
# Test GOT32 handling.
#
# We want to check both the offset to the GOT entry and its contents.
-# jitlink-check: decode_operand(test_got, 4) = got_addr(elf_sm_pic_reloc_got.o, named_data1) - _GLOBAL_OFFSET_TABLE_
+# jitlink-check: decode_operand(test_got, 4) = got_addr(elf_sm_pic_reloc_got.o, named_data1) - _GLOBAL_OFFSET_TABLE_ + 42
# jitlink-check: *{4}(got_addr(elf_sm_pic_reloc_got.o, named_data1)) = named_data1
#
-# jitlink-check: decode_operand(test_got+6, 4) = got_addr(elf_sm_pic_reloc_got.o, named_data2) - _GLOBAL_OFFSET_TABLE_
+# jitlink-check: decode_operand(test_got+6, 4) = got_addr(elf_sm_pic_reloc_got.o, named_data2) - _GLOBAL_OFFSET_TABLE_ + 5
# jitlink-check: *{4}(got_addr(elf_sm_pic_reloc_got.o, named_data2)) = named_data2
.globl test_got
.p2align 4, 0x90
.type test_got, at function
test_got:
- leal named_data1 at GOT, %eax
- leal named_data2 at GOT, %eax
+ leal named_data1 at GOT+42, %eax
+ leal named_data2 at GOT+5, %eax
.size test_got, .-test_got
# Test GOTOFF64 handling.
-# jitlink-check: decode_operand(test_gotoff, 1) = named_func - _GLOBAL_OFFSET_TABLE_
+# jitlink-check: decode_operand(test_gotoff, 1) = named_func - _GLOBAL_OFFSET_TABLE_ + 99
.globl test_gotoff
.p2align 4, 0x90
.type test_gotoff, at function
test_gotoff:
- mov $named_func at GOTOFF, %eax
+ mov $named_func at GOTOFF+99, %eax
.size test_gotoff, .-test_gotoff
diff --git a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_small_pic_relocations_plt.s b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_small_pic_relocations_plt.s
index e5725a2b52c30d..ce565ca2fcdda7 100644
--- a/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_small_pic_relocations_plt.s
+++ b/llvm/test/ExecutionEngine/JITLink/i386/ELF_i386_small_pic_relocations_plt.s
@@ -27,12 +27,12 @@ main:
# for position independent code, first, as there may be future use-cases
# where we would want to disable the optimization.
#
-# jitlink-check: decode_operand(test_call_extern_plt, 0) = external_func - next_pc(test_call_extern_plt)
+# jitlink-check: decode_operand(test_call_extern_plt, 0) = external_func - next_pc(test_call_extern_plt) + 53
# jitlink-check: *{4}(got_addr(elf_sm_pic_reloc_plt.o, external_func))= external_func
.globl test_call_extern_plt
.p2align 4, 0x90
.type test_call_extern_plt, at function
test_call_extern_plt:
- call external_func at plt
+ call external_func at plt + 53
- .size test_call_extern_plt, .-test_call_extern_plt
\ No newline at end of file
+ .size test_call_extern_plt, .-test_call_extern_plt
More information about the llvm-commits
mailing list