[llvm] 4b17c81 - [jitlink/rtdydl][checker] Add TargetFlag dependent disassembler switching support

Stefan Gränitz via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 8 00:07:22 PDT 2023


Author: Eymen Ünay
Date: 2023-09-08T09:06:15+02:00
New Revision: 4b17c81d5a5d3e0f514026c2b7f9b623d901cc04

URL: https://github.com/llvm/llvm-project/commit/4b17c81d5a5d3e0f514026c2b7f9b623d901cc04
DIFF: https://github.com/llvm/llvm-project/commit/4b17c81d5a5d3e0f514026c2b7f9b623d901cc04.diff

LOG: [jitlink/rtdydl][checker] Add TargetFlag dependent disassembler switching support

Some targets such as AArch32 make use of TargetFlags to indicate ISA mode. Depending
on the TargetFlag, MCDisassembler and similar target specific objects should be
reinitialized with the correct Target Triple. Backends with similar needs can
easily extend this implementation for their usecase.

The drivers llvm-rtdyld and llvm-jitlink have their SymbolInfo's extended to take
TargetFlag into account. RuntimeDyldChecker can now create necessary TargetInfo
to reinitialize MCDisassembler and MCInstPrinter. The required triple is obtained
from the new getTripleFromTargetFlag function by checking the TargetFlag.

In addition, breaking changes for RuntimeDyld COFF Thumb tests are fixed by making
the backend emit a TargetFlag.

Reviewed By: lhames, sgraenitz

Differential Revision: https://reviews.llvm.org/D158280

Added: 
    

Modified: 
    llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
    llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
    llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
    llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
    llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
    llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
    llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
    llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
    llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s
    llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s
    llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp
    llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
    llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
    llvm/tools/llvm-jitlink/llvm-jitlink.cpp
    llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index 48268aa9f6899b9..ab4441fbec4606d 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -623,10 +623,8 @@ class Symbol {
     this->S = static_cast<uint8_t>(S);
   }
 
-  /// Check whether the given target flags are set for this Symbol.
-  bool hasTargetFlags(TargetFlagsType Flags) const {
-    return static_cast<TargetFlagsType>(TargetFlags) & Flags;
-  }
+  /// Get the target flags of this Symbol.
+  TargetFlagsType getTargetFlags() const { return TargetFlags; }
 
   /// Set the target flags for this Symbol.
   void setTargetFlags(TargetFlagsType Flags) {

diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index b21c9e2a1cd8260..d1d54c0ca633362 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -23,6 +23,9 @@ namespace llvm {
 namespace jitlink {
 namespace aarch32 {
 
+/// Check whether the given target flags are set for this Symbol.
+bool hasTargetFlags(Symbol &Sym, TargetFlagsType Flags);
+
 /// JITLink-internal AArch32 fixup kinds
 enum EdgeKind_aarch32 : Edge::Kind {
 

diff  --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
index 5904250c9a72208..ae6764c1a3ac3b3 100644
--- a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
+++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -12,6 +12,8 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/Support/Endian.h"
+#include "llvm/TargetParser/SubtargetFeature.h"
+#include "llvm/TargetParser/Triple.h"
 #include <optional>
 
 #include <cstdint>
@@ -29,6 +31,9 @@ class RuntimeDyld;
 class RuntimeDyldCheckerImpl;
 class raw_ostream;
 
+/// Holds target-specific properties for a symbol.
+using TargetFlagsType = uint8_t;
+
 /// RuntimeDyld invariant checker for verifying that RuntimeDyld has
 ///        correctly applied relocations.
 ///
@@ -78,10 +83,11 @@ class RuntimeDyldChecker {
   public:
     MemoryRegionInfo() = default;
 
-    /// Constructor for symbols/sections with content.
-    MemoryRegionInfo(ArrayRef<char> Content, JITTargetAddress TargetAddress)
+    /// Constructor for symbols/sections with content and TargetFlag.
+    MemoryRegionInfo(ArrayRef<char> Content, JITTargetAddress TargetAddress,
+                     TargetFlagsType TargetFlags)
         : ContentPtr(Content.data()), Size(Content.size()),
-          TargetAddress(TargetAddress) {}
+          TargetAddress(TargetAddress), TargetFlags(TargetFlags) {}
 
     /// Constructor for zero-fill symbols/sections.
     MemoryRegionInfo(uint64_t Size, JITTargetAddress TargetAddress)
@@ -127,10 +133,20 @@ class RuntimeDyldChecker {
     /// Return the target address for this region.
     JITTargetAddress getTargetAddress() const { return TargetAddress; }
 
+    /// Get the target flags for this Symbol.
+    TargetFlagsType getTargetFlags() const { return TargetFlags; }
+
+    /// Set the target flags for this Symbol.
+    void setTargetFlags(TargetFlagsType Flags) {
+      assert(Flags <= 1 && "Add more bits to store more than one flag");
+      TargetFlags = Flags;
+    }
+
   private:
     const char *ContentPtr = nullptr;
     uint64_t Size = 0;
     JITTargetAddress TargetAddress = 0;
+    TargetFlagsType TargetFlags = 0;
   };
 
   using IsSymbolValidFunction = std::function<bool(StringRef Symbol)>;
@@ -148,9 +164,8 @@ class RuntimeDyldChecker {
                      GetSectionInfoFunction GetSectionInfo,
                      GetStubInfoFunction GetStubInfo,
                      GetGOTInfoFunction GetGOTInfo,
-                     support::endianness Endianness,
-                     MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
-                     raw_ostream &ErrStream);
+                     support::endianness Endianness, Triple TT,
+                     SubtargetFeatures TF, raw_ostream &ErrStream);
   ~RuntimeDyldChecker();
 
   /// Check a single expression against the attached RuntimeDyld

diff  --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index e9221a898ff63da..01c9e8b4fd9d18e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -25,6 +25,11 @@ namespace llvm {
 namespace jitlink {
 namespace aarch32 {
 
+/// Check whether the given target flags are set for this Symbol.
+bool hasTargetFlags(Symbol &Sym, TargetFlagsType Flags) {
+  return static_cast<TargetFlagsType>(Sym.getTargetFlags()) & Flags;
+}
+
 /// Encode 22-bit immediate value for branch instructions without J1J2 range
 /// extension (formats B T4, BL T1 and BLX T2).
 ///
@@ -287,7 +292,7 @@ Error applyFixupData(LinkGraph &G, Block &B, const Edge &E) {
   int64_t Addend = E.getAddend();
   Symbol &TargetSymbol = E.getTarget();
   uint64_t TargetAddress = TargetSymbol.getAddress().getValue();
-  assert(!TargetSymbol.hasTargetFlags(ThumbSymbol));
+  assert(!hasTargetFlags(TargetSymbol, ThumbSymbol));
 
   // Regular data relocations have size 4, alignment 1 and write the full 32-bit
   // result to the place; no need for overflow checking. There are three
@@ -341,14 +346,14 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
   int64_t Addend = E.getAddend();
   Symbol &TargetSymbol = E.getTarget();
   uint64_t TargetAddress = TargetSymbol.getAddress().getValue();
-  if (TargetSymbol.hasTargetFlags(ThumbSymbol))
+  if (hasTargetFlags(TargetSymbol, ThumbSymbol))
     TargetAddress |= 0x01;
 
   switch (Kind) {
   case Thumb_Jump24: {
     if (!checkOpcode<Thumb_Jump24>(R))
       return makeUnexpectedOpcodeError(G, R, Kind);
-    if (!(TargetSymbol.hasTargetFlags(ThumbSymbol)))
+    if (!hasTargetFlags(TargetSymbol, ThumbSymbol))
       return make_error<JITLinkError>("Branch relocation needs interworking "
                                       "stub when bridging to ARM: " +
                                       StringRef(G.getEdgeKindName(Kind)));
@@ -375,7 +380,7 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
 
     // The call instruction itself is Thumb. The call destination can either be
     // Thumb or Arm. We use BL to stay in Thumb and BLX to change to Arm.
-    bool TargetIsArm = !TargetSymbol.hasTargetFlags(ThumbSymbol);
+    bool TargetIsArm = !hasTargetFlags(TargetSymbol, ThumbSymbol);
     bool InstrIsBlx = (R.Lo & FixupInfo<Thumb_Call>::LoBitNoBlx) == 0;
     if (TargetIsArm != InstrIsBlx) {
       if (LLVM_LIKELY(TargetIsArm)) {

diff  --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
index a29f3d1c3aec8da..3d77f82e65696a8 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
@@ -46,7 +46,7 @@ ExecutorAddr getJITSymbolPtrForSymbol(Symbol &Sym, const Triple &TT) {
   case Triple::armeb:
   case Triple::thumb:
   case Triple::thumbeb:
-    if (Sym.hasTargetFlags(aarch32::ThumbSymbol)) {
+    if (hasTargetFlags(Sym, aarch32::ThumbSymbol)) {
       // Set LSB to indicate thumb target
       assert(Sym.isCallable() && "Only callable symbols can have thumb flag");
       assert((Sym.getAddress().getValue() & 0x01) == 0 && "LSB is clear");

diff  --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index ab561ecd0057984..b4f0a718fda6d26 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -10,9 +10,16 @@
 #include "RuntimeDyldCheckerImpl.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
 #include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/MSVCErrorWorkarounds.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -25,6 +32,19 @@
 
 using namespace llvm;
 
+namespace {
+struct TargetInfo {
+  const Target *TheTarget;
+  std::unique_ptr<MCSubtargetInfo> STI;
+  std::unique_ptr<MCRegisterInfo> MRI;
+  std::unique_ptr<MCAsmInfo> MAI;
+  std::unique_ptr<MCContext> Ctx;
+  std::unique_ptr<MCDisassembler> Disassembler;
+  std::unique_ptr<MCInstrInfo> MII;
+  std::unique_ptr<MCInstPrinter> InstPrinter;
+};
+} // anonymous namespace
+
 namespace llvm {
 
 // Helper class that implements the language evaluated by RuntimeDyldChecker.
@@ -276,6 +296,20 @@ class RuntimeDyldCheckerExprEval {
           "");
 
     unsigned OpIdx = OpIdxExpr.getValue();
+
+    auto printInst = [this](StringRef Symbol, MCInst Inst,
+                            raw_string_ostream &ErrMsgStream) {
+      auto TI = getTargetInfo(
+          Checker.getTripleFromTargetFlag(Checker.getTargetFlag(Symbol)));
+      if (auto E = TI.takeError()) {
+        errs() << "Error obtaining instruction printer: "
+               << toString(std::move(E)) << "\n";
+        return std::make_pair(EvalResult(ErrMsgStream.str()), "");
+      }
+      Inst.dump_pretty(ErrMsgStream, TI->InstPrinter.get());
+      return std::make_pair(EvalResult(ErrMsgStream.str()), "");
+    };
+
     if (OpIdx >= Inst.getNumOperands()) {
       std::string ErrMsg;
       raw_string_ostream ErrMsgStream(ErrMsg);
@@ -284,8 +318,8 @@ class RuntimeDyldCheckerExprEval {
                    << "'. Instruction has only "
                    << format("%i", Inst.getNumOperands())
                    << " operands.\nInstruction is:\n  ";
-      Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
-      return std::make_pair(EvalResult(ErrMsgStream.str()), "");
+
+      return printInst(Symbol, Inst, ErrMsgStream);
     }
 
     const MCOperand &Op = Inst.getOperand(OpIdx);
@@ -294,9 +328,8 @@ class RuntimeDyldCheckerExprEval {
       raw_string_ostream ErrMsgStream(ErrMsg);
       ErrMsgStream << "Operand '" << format("%i", OpIdx) << "' of instruction '"
                    << Symbol << "' is not an immediate.\nInstruction is:\n  ";
-      Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
 
-      return std::make_pair(EvalResult(ErrMsgStream.str()), "");
+      return printInst(Symbol, Inst, ErrMsgStream);
     }
 
     return std::make_pair(EvalResult(Op.getImm()), RemainingExpr);
@@ -687,31 +720,101 @@ class RuntimeDyldCheckerExprEval {
 
   bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size,
                   int64_t Offset) const {
-    MCDisassembler *Dis = Checker.Disassembler;
+    auto TI = getTargetInfo(
+        Checker.getTripleFromTargetFlag(Checker.getTargetFlag(Symbol)));
+
+    if (auto E = TI.takeError()) {
+      errs() << "Error obtaining disassembler: " << toString(std::move(E))
+             << "\n";
+      return false;
+    }
+
     StringRef SymbolMem = Checker.getSymbolContent(Symbol);
     ArrayRef<uint8_t> SymbolBytes(SymbolMem.bytes_begin() + Offset,
                                   SymbolMem.size() - Offset);
 
     MCDisassembler::DecodeStatus S =
-        Dis->getInstruction(Inst, Size, SymbolBytes, 0, nulls());
+        TI->Disassembler->getInstruction(Inst, Size, SymbolBytes, 0, nulls());
 
     return (S == MCDisassembler::Success);
   }
+
+  Expected<TargetInfo>
+  getTargetInfo(const Triple &TT,
+                const SubtargetFeatures &TF = SubtargetFeatures()) const {
+
+    auto TripleName = TT.str();
+    std::string ErrorStr;
+    const Target *TheTarget =
+        TargetRegistry::lookupTarget(TripleName, ErrorStr);
+    if (!TheTarget)
+      return make_error<StringError>("Error accessing target '" + TripleName +
+                                         "': " + ErrorStr,
+                                     inconvertibleErrorCode());
+
+    std::unique_ptr<MCSubtargetInfo> STI(
+        TheTarget->createMCSubtargetInfo(TripleName, "", TF.getString()));
+    if (!STI)
+      return make_error<StringError>("Unable to create subtarget for " +
+                                         TripleName,
+                                     inconvertibleErrorCode());
+
+    std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
+    if (!MRI)
+      return make_error<StringError>("Unable to create target register info "
+                                     "for " +
+                                         TripleName,
+                                     inconvertibleErrorCode());
+
+    MCTargetOptions MCOptions;
+    std::unique_ptr<MCAsmInfo> MAI(
+        TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
+    if (!MAI)
+      return make_error<StringError>("Unable to create target asm info " +
+                                         TripleName,
+                                     inconvertibleErrorCode());
+
+    auto Ctx = std::make_unique<MCContext>(Triple(TripleName), MAI.get(),
+                                           MRI.get(), STI.get());
+
+    std::unique_ptr<MCDisassembler> Disassembler(
+        TheTarget->createMCDisassembler(*STI, *Ctx));
+    if (!Disassembler)
+      return make_error<StringError>("Unable to create disassembler for " +
+                                         TripleName,
+                                     inconvertibleErrorCode());
+
+    std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
+    if (!MII)
+      return make_error<StringError>("Unable to create instruction info for" +
+                                         TripleName,
+                                     inconvertibleErrorCode());
+
+    std::unique_ptr<MCInstPrinter> InstPrinter(TheTarget->createMCInstPrinter(
+        Triple(TripleName), 0, *MAI, *MII, *MRI));
+    if (!InstPrinter)
+      return make_error<StringError>(
+          "Unable to create instruction printer for" + TripleName,
+          inconvertibleErrorCode());
+
+    return TargetInfo({TheTarget, std::move(STI), std::move(MRI),
+                       std::move(MAI), std::move(Ctx), std::move(Disassembler),
+                       std::move(MII), std::move(InstPrinter)});
+  }
 };
 } // namespace llvm
 
 RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl(
     IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
     GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
-    GetGOTInfoFunction GetGOTInfo, support::endianness Endianness,
-    MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
-    raw_ostream &ErrStream)
+    GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, Triple TT,
+    SubtargetFeatures TF, raw_ostream &ErrStream)
     : IsSymbolValid(std::move(IsSymbolValid)),
       GetSymbolInfo(std::move(GetSymbolInfo)),
       GetSectionInfo(std::move(GetSectionInfo)),
       GetStubInfo(std::move(GetStubInfo)), GetGOTInfo(std::move(GetGOTInfo)),
-      Endianness(Endianness), Disassembler(Disassembler),
-      InstPrinter(InstPrinter), ErrStream(ErrStream) {}
+      Endianness(Endianness), TT(std::move(TT)), TF(std::move(TF)),
+      ErrStream(ErrStream) {}
 
 bool RuntimeDyldCheckerImpl::check(StringRef CheckExpr) const {
   CheckExpr = CheckExpr.trim();
@@ -822,6 +925,36 @@ StringRef RuntimeDyldCheckerImpl::getSymbolContent(StringRef Symbol) const {
   return {SymInfo->getContent().data(), SymInfo->getContent().size()};
 }
 
+TargetFlagsType RuntimeDyldCheckerImpl::getTargetFlag(StringRef Symbol) const {
+  auto SymInfo = GetSymbolInfo(Symbol);
+  if (!SymInfo) {
+    logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
+    return TargetFlagsType{};
+  }
+  return SymInfo->getTargetFlags();
+}
+
+Triple
+RuntimeDyldCheckerImpl::getTripleFromTargetFlag(TargetFlagsType Flag) const {
+  Triple TheTriple = TT;
+
+  switch (TT.getArch()) {
+  case Triple::ArchType::arm:
+    if (~Flag & 0x1)
+      return TT;
+    TheTriple.setArchName((Twine("thumb") + TT.getArchName().substr(3)).str());
+    return TheTriple;
+  case Triple::ArchType::thumb:
+    if (Flag & 0x1)
+      return TT;
+    TheTriple.setArchName((Twine("arm") + TT.getArchName().substr(5)).str());
+    return TheTriple;
+
+  default:
+    return TT;
+  }
+}
+
 std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
     StringRef FileName, StringRef SectionName, bool IsInsideLoad) const {
 
@@ -884,13 +1017,12 @@ std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor(
 RuntimeDyldChecker::RuntimeDyldChecker(
     IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
     GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
-    GetGOTInfoFunction GetGOTInfo, support::endianness Endianness,
-    MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
-    raw_ostream &ErrStream)
+    GetGOTInfoFunction GetGOTInfo, support::endianness Endianness, Triple TT,
+    SubtargetFeatures TF, raw_ostream &ErrStream)
     : Impl(::std::make_unique<RuntimeDyldCheckerImpl>(
           std::move(IsSymbolValid), std::move(GetSymbolInfo),
           std::move(GetSectionInfo), std::move(GetStubInfo),
-          std::move(GetGOTInfo), Endianness, Disassembler, InstPrinter,
+          std::move(GetGOTInfo), Endianness, std::move(TT), std::move(TF),
           ErrStream)) {}
 
 RuntimeDyldChecker::~RuntimeDyldChecker() = default;

diff  --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
index f564b0035bffdec..8596b3372b69358 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
@@ -13,6 +13,9 @@
 
 namespace llvm {
 
+/// Holds target-specific properties for a symbol.
+using TargetFlagsType = uint8_t;
+
 class RuntimeDyldCheckerImpl {
   friend class RuntimeDyldChecker;
   friend class RuntimeDyldCheckerExprEval;
@@ -25,12 +28,13 @@ class RuntimeDyldCheckerImpl {
   using GetGOTInfoFunction = RuntimeDyldChecker::GetGOTInfoFunction;
 
 public:
-  RuntimeDyldCheckerImpl(
-      IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
-      GetSectionInfoFunction GetSectionInfo, GetStubInfoFunction GetStubInfo,
-      GetGOTInfoFunction GetGOTInfo, support::endianness Endianness,
-      MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
-      llvm::raw_ostream &ErrStream);
+  RuntimeDyldCheckerImpl(IsSymbolValidFunction IsSymbolValid,
+                         GetSymbolInfoFunction GetSymbolInfo,
+                         GetSectionInfoFunction GetSectionInfo,
+                         GetStubInfoFunction GetStubInfo,
+                         GetGOTInfoFunction GetGOTInfo,
+                         support::endianness Endianness, Triple TT,
+                         SubtargetFeatures TF, llvm::raw_ostream &ErrStream);
 
   bool check(StringRef CheckExpr) const;
   bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
@@ -49,6 +53,9 @@ class RuntimeDyldCheckerImpl {
 
   StringRef getSymbolContent(StringRef Symbol) const;
 
+  TargetFlagsType getTargetFlag(StringRef Symbol) const;
+  Triple getTripleFromTargetFlag(TargetFlagsType Flag) const;
+
   std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
                                                   StringRef SectionName,
                                                   bool IsInsideLoad) const;
@@ -65,8 +72,8 @@ class RuntimeDyldCheckerImpl {
   GetStubInfoFunction GetStubInfo;
   GetGOTInfoFunction GetGOTInfo;
   support::endianness Endianness;
-  MCDisassembler *Disassembler;
-  MCInstPrinter *InstPrinter;
+  Triple TT;
+  SubtargetFeatures TF;
   llvm::raw_ostream &ErrStream;
 };
 }

diff  --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
index 22f1cf33158c8be..a3e66c6bc0ecdf8 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
@@ -54,6 +54,28 @@ class RuntimeDyldCOFFThumb : public RuntimeDyldCOFF {
     return 16; // 8-byte load instructions, 4-byte jump, 4-byte padding
   }
 
+  Expected<JITSymbolFlags> getJITSymbolFlags(const SymbolRef &SR) override {
+
+    auto Flags = RuntimeDyldImpl::getJITSymbolFlags(SR);
+
+    if (!Flags) {
+      return Flags.takeError();
+    }
+    auto SectionIterOrErr = SR.getSection();
+    if (!SectionIterOrErr) {
+      return SectionIterOrErr.takeError();
+    }
+    SectionRef Sec = *SectionIterOrErr.get();
+    const object::COFFObjectFile *COFFObjPtr =
+        cast<object::COFFObjectFile>(Sec.getObject());
+    const coff_section *CoffSec = COFFObjPtr->getCOFFSection(Sec);
+    bool isThumb = CoffSec->Characteristics & COFF::IMAGE_SCN_MEM_16BIT;
+
+    Flags->getTargetFlags() = isThumb;
+
+    return Flags;
+  }
+
   Align getStubAlignment() override { return Align(1); }
 
   Expected<object::relocation_iterator>

diff  --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s
index 76c5f5807f7b86c..b0d6db045efd216 100644
--- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s
+++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s
@@ -4,8 +4,6 @@
 # RUN: llvm-jitlink -noexec -slab-address 0x76ff0000 -slab-allocate 10Kb \
 # RUN:              -slab-page-size 4096 -show-entry-es -check %s %t.o
 
-# This test requires the RuntimeDyldChecker fix from review D158280
-# XFAIL: *
 
 	.text
 	.syntax unified

diff  --git a/llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s b/llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s
index aec4fdad4c58868..b4946880ff15523 100644
--- a/llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s
+++ b/llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s
@@ -101,7 +101,7 @@ rel11:
 	bx r0
 	trap
 
-	.data
+	.text
 
 	.p2align 2
 

diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp
index 415aee76b186345..283e655205d7809 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp
@@ -118,7 +118,8 @@ Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
         if (Sym->getSize() != 0) {
           if (auto TS = getCOFFGOTTarget(G, Sym->getBlock()))
             FileInfo.GOTEntryInfos[TS->getName()] = {
-                Sym->getSymbolContent(), Sym->getAddress().getValue()};
+                Sym->getSymbolContent(), Sym->getAddress().getValue(),
+                Sym->getTargetFlags()};
           else
             return TS.takeError();
         }
@@ -130,7 +131,8 @@ Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
 
         if (auto TS = getCOFFStubTarget(G, Sym->getBlock()))
           FileInfo.StubInfos[TS->getName()] = {Sym->getSymbolContent(),
-                                               Sym->getAddress().getValue()};
+                                               Sym->getAddress().getValue(),
+                                               Sym->getTargetFlags()};
         else
           return TS.takeError();
         SectionContainsContent = true;
@@ -143,7 +145,8 @@ Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
           SectionContainsZeroFill = true;
         } else {
           S.SymbolInfos[Sym->getName()] = {Sym->getSymbolContent(),
-                                           Sym->getAddress().getValue()};
+                                           Sym->getAddress().getValue(),
+                                           Sym->getTargetFlags()};
           SectionContainsContent = true;
         }
       }
@@ -164,7 +167,7 @@ Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
     else
       FileInfo.SectionInfos[Sec.getName()] = {
           ArrayRef<char>(FirstSym->getBlock().getContent().data(), SecSize),
-          SecAddr.getValue()};
+          SecAddr.getValue(), FirstSym->getTargetFlags()};
   }
 
   return Error::success();

diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
index 5200dbcf9036619..7881660d1a73851 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
@@ -120,7 +120,8 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
         if (Sym->getSize() != 0) {
           if (auto TS = getELFGOTTarget(G, Sym->getBlock()))
             FileInfo.GOTEntryInfos[TS->getName()] = {
-                Sym->getSymbolContent(), Sym->getAddress().getValue()};
+                Sym->getSymbolContent(), Sym->getAddress().getValue(),
+                Sym->getTargetFlags()};
           else
             return TS.takeError();
         }
@@ -132,7 +133,8 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
 
         if (auto TS = getELFStubTarget(G, Sym->getBlock()))
           FileInfo.StubInfos[TS->getName()] = {Sym->getSymbolContent(),
-                                               Sym->getAddress().getValue()};
+                                               Sym->getAddress().getValue(),
+                                               Sym->getTargetFlags()};
         else
           return TS.takeError();
         SectionContainsContent = true;
@@ -145,7 +147,8 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
           SectionContainsZeroFill = true;
         } else {
           S.SymbolInfos[Sym->getName()] = {Sym->getSymbolContent(),
-                                           Sym->getAddress().getValue()};
+                                           Sym->getAddress().getValue(),
+                                           Sym->getTargetFlags()};
           SectionContainsContent = true;
         }
       }
@@ -170,7 +173,7 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
     else
       FileInfo.SectionInfos[Sec.getName()] = {
           ArrayRef<char>(FirstSym->getBlock().getContent().data(), SecSize),
-          SecAddr.getValue()};
+          SecAddr.getValue(), FirstSym->getTargetFlags()};
   }
 
   return Error::success();

diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
index bcb2f251ece1c0c..7dcadd94c2365a4 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
@@ -117,8 +117,9 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
                                          inconvertibleErrorCode());
 
         if (auto TS = getMachOGOTTarget(G, Sym->getBlock()))
-          FileInfo.GOTEntryInfos[TS->getName()] = {
-              Sym->getSymbolContent(), Sym->getAddress().getValue()};
+          FileInfo.GOTEntryInfos[TS->getName()] = {Sym->getSymbolContent(),
+                                                   Sym->getAddress().getValue(),
+                                                   Sym->getTargetFlags()};
         else
           return TS.takeError();
         SectionContainsContent = true;
@@ -129,7 +130,8 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
 
         if (auto TS = getMachOStubTarget(G, Sym->getBlock()))
           FileInfo.StubInfos[TS->getName()] = {Sym->getSymbolContent(),
-                                               Sym->getAddress().getValue()};
+                                               Sym->getAddress().getValue(),
+                                               Sym->getTargetFlags()};
         else
           return TS.takeError();
         SectionContainsContent = true;
@@ -140,7 +142,8 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
           SectionContainsZeroFill = true;
         } else {
           S.SymbolInfos[Sym->getName()] = {Sym->getSymbolContent(),
-                                           Sym->getAddress().getValue()};
+                                           Sym->getAddress().getValue(),
+                                           Sym->getTargetFlags()};
           SectionContainsContent = true;
         }
       }
@@ -160,7 +163,7 @@ Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
     else
       FileInfo.SectionInfos[Sec.getName()] = {
           ArrayRef<char>(FirstSym->getBlock().getContent().data(), SecSize),
-          SecAddr.getValue()};
+          SecAddr.getValue(), FirstSym->getTargetFlags()};
   }
 
   return Error::success();

diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 00dd5206d75a756..a8f056eab674ec0 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -1388,7 +1388,8 @@ static Error addAbsoluteSymbols(Session &S,
       return Err;
 
     // Register the absolute symbol with the session symbol infos.
-    S.SymbolInfos[Name] = {ArrayRef<char>(), Addr};
+    S.SymbolInfos[Name] = {ArrayRef<char>(), Addr,
+                           AbsDef.getFlags().getTargetFlags()};
   }
 
   return Error::success();
@@ -1856,15 +1857,12 @@ getTargetInfo(const Triple &TT,
           std::move(MAI), std::move(Ctx), std::move(Disassembler),
           std::move(MII), std::move(MIA), std::move(InstPrinter)};
 }
-
-static Error runChecks(Session &S) {
+static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
   if (CheckFiles.empty())
     return Error::success();
 
   LLVM_DEBUG(dbgs() << "Running checks...\n");
 
-  auto TI = getTargetInfo(S.ES.getTargetTriple(), S.Features);
-
   auto IsSymbolValid = [&S](StringRef Symbol) {
     return S.isSymbolRegistered(Symbol);
   };
@@ -1888,7 +1886,7 @@ static Error runChecks(Session &S) {
   RuntimeDyldChecker Checker(
       IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo,
       S.ES.getTargetTriple().isLittleEndian() ? support::little : support::big,
-      TI.Disassembler.get(), TI.InstPrinter.get(), dbgs());
+      TT, Features, dbgs());
 
   std::string CheckLineStart = "# " + CheckName + ":";
   for (auto &CheckFile : CheckFiles) {
@@ -2000,7 +1998,7 @@ int main(int argc, char *argv[]) {
   auto [TT, Features] = getFirstFileTripleAndFeatures();
   ExitOnErr(sanitizeArguments(TT, argv[0]));
 
-  auto S = ExitOnErr(Session::Create(std::move(TT), std::move(Features)));
+  auto S = ExitOnErr(Session::Create(TT, Features));
 
   enableStatistics(*S, !OrcRuntime.empty());
 
@@ -2036,7 +2034,7 @@ int main(int argc, char *argv[]) {
     exit(1);
   }
 
-  ExitOnErr(runChecks(*S));
+  ExitOnErr(runChecks(*S, std::move(TT), std::move(Features)));
 
   int Result = 0;
   if (!NoExec) {

diff  --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
index df82fb04e8e680c..7e621cba1871b32 100644
--- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -892,6 +892,8 @@ static int linkAndVerify() {
         StringRef SecContent = Dyld.getSectionContent(SectionID);
         uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data());
         SymInfo.setContent(ArrayRef<char>(CSymAddr, SymSize));
+        SymInfo.setTargetFlags(
+            Dyld.getSymbol(Symbol).getFlags().getTargetFlags());
       }
     }
     return SymInfo;
@@ -973,11 +975,12 @@ static int linkAndVerify() {
 
     ObjectFile &Obj = **MaybeObj;
 
+    SubtargetFeatures Features = SubtargetFeatures();
     if (!Checker)
       Checker = std::make_unique<RuntimeDyldChecker>(
           IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo,
           GetStubInfo, Obj.isLittleEndian() ? support::little : support::big,
-          Disassembler.get(), InstPrinter.get(), dbgs());
+          TheTriple, Features, dbgs());
 
     auto FileName = sys::path::filename(InputFile);
     MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]);


        


More information about the llvm-commits mailing list