aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorEymen Ünay <eymenunay@outlook.com>2023-09-08 09:05:14 +0200
committerStefan Gränitz <stefan.graenitz@gmail.com>2023-09-08 09:06:15 +0200
commit4b17c81d5a5d3e0f514026c2b7f9b623d901cc04 (patch)
treebb9dc0e4f48382f7907221bf7ca6e26a1d30072d /llvm
parentb0ea2790c41db65b3c283f78a5f534bc26fc6f8f (diff)
downloadllvm-4b17c81d5a5d3e0f514026c2b7f9b623d901cc04.zip
llvm-4b17c81d5a5d3e0f514026c2b7f9b623d901cc04.tar.gz
llvm-4b17c81d5a5d3e0f514026c2b7f9b623d901cc04.tar.bz2
[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
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h6
-rw-r--r--llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h3
-rw-r--r--llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h27
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/aarch32.cpp13
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp162
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h23
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h22
-rw-r--r--llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s2
-rw-r--r--llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s2
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp11
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp11
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp13
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink.cpp14
-rw-r--r--llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp5
15 files changed, 253 insertions, 63 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index 48268aa9..ab4441f 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -623,10 +623,8 @@ public:
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 b21c9e2..d1d54c0 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 5904250..ae6764c1 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 @@ public:
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 @@ public:
/// 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 @@ public:
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 e9221a8..01c9e8b 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 a29f3d1..3d77f82 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 ab561ec..b4f0a71 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 @@ private:
"");
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 @@ private:
<< "'. 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 @@ private:
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 @@ private:
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 f564b00..8596b33 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 @@ private:
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 @@ private:
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 22f1cf3..a3e66c6 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
@@ -54,6 +54,28 @@ public:
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 76c5f58..b0d6db0 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 aec4fda..b494688 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 415aee7..283e655 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 5200dbc..7881660 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 bcb2f25..7dcadd9 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 00dd520..a8f056e 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 df82fb0..7e621cb 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]);