[llvm] [RuntimeDyldChecker][AArch32] Add a PC offset to next_PC for ARM targets (PR #91746)
Eymen Ünay via llvm-commits
llvm-commits at lists.llvm.org
Sun May 12 03:55:30 PDT 2024
https://github.com/eymay updated https://github.com/llvm/llvm-project/pull/91746
>From df8308894fbe40d28af4625164c28e1e314c394a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Fri, 10 May 2024 16:42:57 +0300
Subject: [PATCH 1/3] [RuntimeDyldChecker][AArch32] Add a PC offset to next_PC
for ARM targets
In ARM mode, the Program Counter (PC) points to the current instruction's
address + 8 instead of + 4. This offset is added to RuntimeDyldChecker to
use `next_pc` expression in JITLink tests.
---
.../RuntimeDyld/RuntimeDyldChecker.cpp | 14 +++++++++++++-
.../JITLink/AArch32/ELF_relocations_arm.s | 6 ++----
.../JITLink/AArch32/ELF_relocations_thumbv6m.s | 2 +-
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index 11fb21a9c1c0a..dcbe3f1712db5 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -369,7 +369,19 @@ class RuntimeDyldCheckerExprEval {
uint64_t SymbolAddr = PCtx.IsInsideLoad
? Checker.getSymbolLocalAddr(Symbol)
: Checker.getSymbolRemoteAddr(Symbol);
- uint64_t NextPC = SymbolAddr + InstSize;
+
+ uint64_t PCOffset = 0;
+ auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));
+ switch (TT.getArch()) {
+ case Triple::ArchType::arm:
+ // ARM mode adds an offset of 4 bytes to PC
+ PCOffset = 4;
+ break;
+ default:
+ PCOffset = 0;
+ }
+
+ uint64_t NextPC = SymbolAddr + InstSize + PCOffset;
return std::make_pair(EvalResult(NextPC), RemainingExpr);
}
diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_arm.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_arm.s
index 3dec8c96f5cd5..4d12b84d48c91 100644
--- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_arm.s
+++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_arm.s
@@ -28,9 +28,7 @@
# CHECK-INSTR: 4: ebfffffe bl
# CHECK-INSTR: 0000000c <call_target_arm>
# CHECK-INSTR: 00000010 <call_target_thumb>
-# ARM branch offset is 8, because it accounts for an additional prefetch
-# instruction that increments PC even though it is implicit
-# jitlink-check: decode_operand(call_site + 0, 0) = call_target_arm - (call_site + 8)
+# jitlink-check: decode_operand(call_site + 0, 0) = call_target_arm - next_pc(call_site)
# jitlink-check: decode_operand(call_site + 4, 0) = call_target_thumb - (call_site + 12)
.globl call_site
.type call_site,%function
@@ -62,7 +60,7 @@ call_target_thumb:
# CHECK-INSTR: 00000014 <jump24_site>:
# CHECK-INSTR: 14: eafffffe b
# CHECK-INSTR: 00000018 <jump24_target>
-# jitlink-check: decode_operand(jump24_site, 0) = jump24_target - (jump24_site + 8)
+# jitlink-check: decode_operand(jump24_site, 0) = jump24_target - next_pc(jump24_site)
.globl jump24_site
.type jump24_site,%function
.p2align 2
diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_thumbv6m.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_thumbv6m.s
index e0a224d9c7106..9f46ff0ed3922 100644
--- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_thumbv6m.s
+++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_thumbv6m.s
@@ -30,7 +30,7 @@
# CHECK-INSTR: f7ff fffe bl
# We decode the operand with index 2, because bl generates two leading implicit
# predicate operands that we have to skip in order to decode the call_target operand
-# jitlink-check: decode_operand(call_site, 2) = call_target_thumb - (call_site + 4)
+# jitlink-check: decode_operand(call_site, 2) = call_target_thumb - next_pc(call_site)
.globl call_site
.type call_site,%function
.p2align 1
>From 0eecc0ab808b592ccd41aadc32b91a55d9f177d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Sun, 12 May 2024 12:52:14 +0300
Subject: [PATCH 2/3] Simplify the PC offset declaration
---
.../RuntimeDyld/RuntimeDyldChecker.cpp | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index dcbe3f1712db5..14c8577aab9d7 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -370,16 +370,9 @@ class RuntimeDyldCheckerExprEval {
? Checker.getSymbolLocalAddr(Symbol)
: Checker.getSymbolRemoteAddr(Symbol);
- uint64_t PCOffset = 0;
+ // ARM mode adds an offset of 4 bytes to PC
auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));
- switch (TT.getArch()) {
- case Triple::ArchType::arm:
- // ARM mode adds an offset of 4 bytes to PC
- PCOffset = 4;
- break;
- default:
- PCOffset = 0;
- }
+ uint64_t PCOffset = TT.getArch() == Triple::ArchType::arm ? 4 : 0;
uint64_t NextPC = SymbolAddr + InstSize + PCOffset;
>From e66c24a66baae2fcb3ce1b17747ba85a35fb64a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Sun, 12 May 2024 13:54:36 +0300
Subject: [PATCH 3/3] Teach evalNextPC to decode addition expression with a
symbol
---
.../RuntimeDyld/RuntimeDyldChecker.cpp | 28 ++++++++++++++++---
.../JITLink/AArch32/ELF_relocations_arm.s | 2 +-
.../JITLink/AArch32/ELF_stubs_arm.s | 4 +--
.../JITLink/AArch32/ELF_stubs_multi.s | 4 +--
4 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index 14c8577aab9d7..25b3caffd49c0 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -354,6 +354,26 @@ class RuntimeDyldCheckerExprEval {
EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),
"");
+ // if there is an offset number expr
+ int64_t SymbolOffset = 0;
+ BinOpToken BinOp;
+ std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
+ switch (BinOp) {
+ case BinOpToken::Add: {
+ EvalResult Number;
+ std::tie(Number, RemainingExpr) = evalNumberExpr(RemainingExpr);
+ SymbolOffset = Number.getValue();
+ break;
+ }
+ case BinOpToken::Invalid:
+ break;
+ default:
+ return std::make_pair(
+ unexpectedToken(RemainingExpr, RemainingExpr,
+ "expected '+' for offset or ')' if no offset"),
+ "");
+ }
+
if (!RemainingExpr.starts_with(")"))
return std::make_pair(
unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");
@@ -361,14 +381,14 @@ class RuntimeDyldCheckerExprEval {
MCInst Inst;
uint64_t InstSize;
- if (!decodeInst(Symbol, Inst, InstSize, 0))
+ if (!decodeInst(Symbol, Inst, InstSize, SymbolOffset))
return std::make_pair(
EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),
"");
- uint64_t SymbolAddr = PCtx.IsInsideLoad
- ? Checker.getSymbolLocalAddr(Symbol)
- : Checker.getSymbolRemoteAddr(Symbol);
+ uint64_t SymbolAddr =
+ PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
+ : Checker.getSymbolRemoteAddr(Symbol) + SymbolOffset;
// ARM mode adds an offset of 4 bytes to PC
auto TT = Checker.getTripleForSymbol(Checker.getTargetFlag(Symbol));
diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_arm.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_arm.s
index 4d12b84d48c91..a0a28b702bc76 100644
--- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_arm.s
+++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_arm.s
@@ -29,7 +29,7 @@
# CHECK-INSTR: 0000000c <call_target_arm>
# CHECK-INSTR: 00000010 <call_target_thumb>
# jitlink-check: decode_operand(call_site + 0, 0) = call_target_arm - next_pc(call_site)
-# jitlink-check: decode_operand(call_site + 4, 0) = call_target_thumb - (call_site + 12)
+# jitlink-check: decode_operand(call_site + 4, 0) = call_target_thumb - next_pc(call_site + 4)
.globl call_site
.type call_site,%function
.p2align 2
diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_stubs_arm.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_stubs_arm.s
index d3a596c811ec4..3476b185914f3 100644
--- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_stubs_arm.s
+++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_stubs_arm.s
@@ -27,7 +27,7 @@
# hard-code it in the immediate field.
# The external function ext will return to the caller directly.
-# jitlink-check: decode_operand(test_arm_jump, 0) = stub_addr(out.o, ext) - (test_arm_jump + 8)
+# jitlink-check: decode_operand(test_arm_jump, 0) = stub_addr(out.o, ext) - next_pc(test_arm_jump)
.globl test_arm_jump
.type test_arm_jump,%function
.p2align 2
@@ -38,7 +38,7 @@ test_arm_jump:
# The branch-with-link sets the LR register so that the external function ext
# returns to us. We have to save the register (push) and return to main manually
# (pop). This adds the +4 offset for the bl instruction we decode:
-# jitlink-check: decode_operand(test_arm_call + 4, 0) = stub_addr(out.o, ext) - (test_arm_call + 8) - 4
+# jitlink-check: decode_operand(test_arm_call + 4, 0) = stub_addr(out.o, ext) - next_pc(test_arm_call) - 4
.globl test_arm_call
.type test_arm_call,%function
.p2align 2
diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_stubs_multi.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_stubs_multi.s
index d575f114dcba1..51aced157ad51 100644
--- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_stubs_multi.s
+++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_stubs_multi.s
@@ -13,7 +13,7 @@
# ascending size (because the default memory manager lays out blocks by size).
# Thumb relocation site emits thumb stub
-# jitlink-check: decode_operand(test_stub_thumb, 0) = stub_addr(out.o, ext, thumb) - (test_stub_thumb + 4)
+# jitlink-check: decode_operand(test_stub_thumb, 0) = stub_addr(out.o, ext, thumb) - next_pc(test_stub_thumb)
.globl test_stub_thumb
.type test_stub_thumb,%function
.p2align 1
@@ -24,7 +24,7 @@ test_stub_thumb:
.size test_stub_thumb, .-test_stub_thumb
# Arm relocation site emits arm stub
-# jitlink-check: decode_operand(test_stub_arm, 0) = stub_addr(out.o, ext, arm) - (test_stub_arm + 8)
+# jitlink-check: decode_operand(test_stub_arm, 0) = stub_addr(out.o, ext, arm) - next_pc(test_stub_arm)
.globl test_stub_arm
.type test_stub_arm,%function
.p2align 2
More information about the llvm-commits
mailing list