[llvm] 209ceed - [JITLink][ELF/x86-64] Add Delta32, NegDelta32, NegDelta64 support.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 21 20:19:26 PDT 2021
Author: Lang Hames
Date: 2021-03-21T20:15:40-07:00
New Revision: 209ceed745253cfcf3d05c72b9bdc76b439bc1fb
URL: https://github.com/llvm/llvm-project/commit/209ceed745253cfcf3d05c72b9bdc76b439bc1fb
DIFF: https://github.com/llvm/llvm-project/commit/209ceed745253cfcf3d05c72b9bdc76b439bc1fb.diff
LOG: [JITLink][ELF/x86-64] Add Delta32, NegDelta32, NegDelta64 support.
These were missing, but are used in eh-frame section support.
Added:
Modified:
llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
index 2503577ea36b..868a53552b97 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
@@ -15,6 +15,8 @@
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include <limits>
+
namespace llvm {
namespace jitlink {
namespace x86_64 {
@@ -244,6 +246,17 @@ enum EdgeKind_x86_64 : Edge::Kind {
/// only.
const char *getEdgeKindName(Edge::Kind K);
+/// Returns true if the given uint64_t value is in range for a uint32_t.
+inline bool isInRangeForImmU32(uint64_t Value) {
+ return Value <= std::numeric_limits<uint32_t>::max();
+}
+
+/// Returns true if the given int64_t value is in range for an int32_t.
+inline bool isInRangeForImmS32(int64_t Value) {
+ return (Value >= std::numeric_limits<int32_t>::min() &&
+ Value <= std::numeric_limits<int32_t>::max());
+}
+
/// Apply fixup expression for edge to block content.
inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
char *BlockWorkingMem) {
@@ -262,9 +275,10 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
case Pointer32: {
uint64_t Value = E.getTarget().getAddress() + E.getAddend();
- if (Value > std::numeric_limits<uint32_t>::max())
+ if (LLVM_LIKELY(isInRangeForImmU32(Value)))
+ *(ulittle32_t *)FixupPtr = Value;
+ else
return makeTargetOutOfRangeError(G, B, E);
- *(ulittle32_t *)FixupPtr = Value;
break;
}
@@ -275,10 +289,10 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
case PCRel32TLVPLoadRelaxable: {
int64_t Value =
E.getTarget().getAddress() - (FixupAddress + 4) + E.getAddend();
- if (Value < std::numeric_limits<int32_t>::min() ||
- Value > std::numeric_limits<int32_t>::max())
+ if (LLVM_LIKELY(isInRangeForImmS32(Value)))
+ *(little32_t *)FixupPtr = Value;
+ else
return makeTargetOutOfRangeError(G, B, E);
- *(little32_t *)FixupPtr = Value;
break;
}
@@ -290,10 +304,10 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
case Delta32: {
int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
- if (Value < std::numeric_limits<int32_t>::min() ||
- Value > std::numeric_limits<int32_t>::max())
+ if (LLVM_LIKELY(isInRangeForImmS32(Value)))
+ *(little32_t *)FixupPtr = Value;
+ else
return makeTargetOutOfRangeError(G, B, E);
- *(little32_t *)FixupPtr = Value;
break;
}
@@ -305,10 +319,10 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
case NegDelta32: {
int64_t Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
- if (Value < std::numeric_limits<int32_t>::min() ||
- Value > std::numeric_limits<int32_t>::max())
+ if (LLVM_LIKELY(isInRangeForImmS32(Value)))
+ *(little32_t *)FixupPtr = Value;
+ else
return makeTargetOutOfRangeError(G, B, E);
- *(little32_t *)FixupPtr = Value;
break;
}
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
index 50d30c7d2058..3532665cae53 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
@@ -12,6 +12,7 @@
#include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/ExecutionEngine/JITLink/x86_64.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Endian.h"
@@ -707,10 +708,10 @@ class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> {
case ELFX86RelocationKind::PCRel32:
case ELFX86RelocationKind::PCRel32GOTLoad: {
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
- if (Value < std::numeric_limits<int32_t>::min() ||
- Value > std::numeric_limits<int32_t>::max())
+ if (LLVM_LIKELY(x86_64::isInRangeForImmS32(Value)))
+ *(little32_t *)FixupPtr = Value;
+ else
return makeTargetOutOfRangeError(G, B, E);
- *(little32_t *)FixupPtr = Value;
break;
}
case ELFX86RelocationKind::Pointer64: {
@@ -718,11 +719,38 @@ class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> {
*(ulittle64_t *)FixupPtr = Value;
break;
}
+ case ELFX86RelocationKind::Delta32: {
+ int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
+ if (LLVM_LIKELY(x86_64::isInRangeForImmS32(Value)))
+ *(little32_t *)FixupPtr = Value;
+ else
+ return makeTargetOutOfRangeError(G, B, E);
+ break;
+ }
case ELFX86RelocationKind::Delta64: {
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
*(little64_t *)FixupPtr = Value;
break;
}
+ case ELFX86RelocationKind::NegDelta32: {
+ int64_t Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
+ if (LLVM_LIKELY(x86_64::isInRangeForImmS32(Value)))
+ *(little32_t *)FixupPtr = Value;
+ else
+ return makeTargetOutOfRangeError(G, B, E);
+ break;
+ }
+ case ELFX86RelocationKind::NegDelta64: {
+ int64_t Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
+ *(little64_t *)FixupPtr = Value;
+ break;
+ }
+ default:
+ LLVM_DEBUG({
+ dbgs() << "Bad edge: " << getELFX86RelocationKindName(E.getKind())
+ << "\n";
+ });
+ llvm_unreachable("Unsupported relocation");
}
return Error::success();
}
@@ -780,16 +808,46 @@ void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
}
const char *getELFX86RelocationKindName(Edge::Kind R) {
switch (R) {
- case PCRel32:
- return "PCRel32";
- case Pointer64:
- return "Pointer64";
- case PCRel32GOTLoad:
- return "PCRel32GOTLoad";
case Branch32:
return "Branch32";
case Branch32ToStub:
return "Branch32ToStub";
+ case Pointer32:
+ return "Pointer32";
+ case Pointer64:
+ return "Pointer64";
+ case Pointer64Anon:
+ return "Pointer64Anon";
+ case PCRel32:
+ return "PCRel32";
+ case PCRel32Minus1:
+ return "PCRel32Minus1";
+ case PCRel32Minus2:
+ return "PCRel32Minus2";
+ case PCRel32Minus4:
+ return "PCRel32Minus4";
+ case PCRel32Anon:
+ return "PCRel32Anon";
+ case PCRel32Minus1Anon:
+ return "PCRel32Minus1Anon";
+ case PCRel32Minus2Anon:
+ return "PCRel32Minus2Anon";
+ case PCRel32Minus4Anon:
+ return "PCRel32Minus4Anon";
+ case PCRel32GOTLoad:
+ return "PCRel32GOTLoad";
+ case PCRel32GOT:
+ return "PCRel32GOT";
+ case PCRel32TLV:
+ return "PCRel32TLV";
+ case Delta32:
+ return "Delta32";
+ case Delta64:
+ return "Delta64";
+ case NegDelta32:
+ return "NegDelta32";
+ case NegDelta64:
+ return "NegDelta64";
}
return getGenericEdgeKindName(static_cast<Edge::Kind>(R));
}
More information about the llvm-commits
mailing list