[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