[llvm] r357947 - [RuntimeDyld] Decouple RuntimeDyldChecker from RuntimeDyld.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 8 14:50:49 PDT 2019
Author: lhames
Date: Mon Apr 8 14:50:48 2019
New Revision: 357947
URL: http://llvm.org/viewvc/llvm-project?rev=357947&view=rev
Log:
[RuntimeDyld] Decouple RuntimeDyldChecker from RuntimeDyld.
This will allow RuntimeDyldChecker (and rtdyld-check tests) to test a new JIT
linker: JITLink (https://reviews.llvm.org/D58704).
Modified:
llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=357947&r1=357946&r2=357947&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Mon Apr 8 14:50:48 2019
@@ -52,18 +52,20 @@ private:
std::string ErrMsg;
};
-class RuntimeDyldCheckerImpl;
class RuntimeDyldImpl;
class RuntimeDyld {
- friend class RuntimeDyldCheckerImpl;
-
protected:
// Change the address associated with a section when resolving relocations.
// Any relocations already associated with the symbol will be re-resolved.
void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
public:
+
+ using NotifyStubEmittedFunction =
+ std::function<void(StringRef FileName, StringRef SectionName,
+ StringRef SymbolName, uint32_t StubOffset)>;
+
/// Information about the loaded object.
class LoadedObjectInfo : public llvm::LoadedObjectInfo {
friend class RuntimeDyldImpl;
@@ -184,6 +186,9 @@ public:
/// and resolve relocatons based on where they put it).
void *getSymbolLocalAddress(StringRef Name) const;
+ /// Get the section ID for the section containing the given symbol.
+ unsigned getSymbolSectionID(StringRef Name) const;
+
/// Get the target address and flags for the named symbol.
/// This address is the one used for relocation.
JITEvaluatedSymbol getSymbol(StringRef Name) const;
@@ -204,6 +209,19 @@ public:
/// This is the address which will be used for relocation resolution.
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
+ /// Returns the section's working memory.
+ StringRef getSectionContent(unsigned SectionID) const;
+
+ /// If the section was loaded, return the section's load address,
+ /// otherwise return None.
+ uint64_t getSectionLoadAddress(unsigned SectionID) const;
+
+ /// Set the NotifyStubEmitted callback. This is used for debugging
+ /// purposes. A callback is made for each stub that is generated.
+ void setNotifyStubEmitted(NotifyStubEmittedFunction NotifyStubEmitted) {
+ this->NotifyStubEmitted = std::move(NotifyStubEmitted);
+ }
+
/// Register any EH frame sections that have been loaded but not previously
/// registered with the memory manager. Note, RuntimeDyld is responsible
/// for identifying the EH frame and calling the memory manager with the
@@ -265,7 +283,7 @@ private:
MemoryManager &MemMgr;
JITSymbolResolver &Resolver;
bool ProcessAllSections;
- RuntimeDyldCheckerImpl *Checker;
+ NotifyStubEmittedFunction NotifyStubEmitted;
};
// Asynchronous JIT link for ORC.
Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h?rev=357947&r1=357946&r2=357947&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyldChecker.h Mon Apr 8 14:50:48 2019
@@ -9,7 +9,10 @@
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/Support/Endian.h"
#include <cstdint>
#include <memory>
@@ -69,16 +72,34 @@ class raw_ostream;
///
class RuntimeDyldChecker {
public:
- RuntimeDyldChecker(RuntimeDyld &RTDyld, MCDisassembler *Disassembler,
+
+ using IsSymbolValidFunction = std::function<bool(StringRef Symbol)>;
+ using GetSymbolAddressFunction =
+ std::function<Expected<JITTargetAddress>(StringRef Symbol)>;
+ using GetSymbolContentFunction =
+ std::function<Expected<StringRef>(StringRef Symbol)>;
+ using GetSectionLoadAddressFunction =
+ std::function<Optional<JITTargetAddress>(StringRef FileName,
+ StringRef SectionName)>;
+ using GetSectionContentFunction =
+ std::function<Expected<StringRef>(StringRef FileName,
+ StringRef SectionName)>;
+ using GetStubOffsetInSectionFunction =
+ std::function<Expected<uint32_t>(StringRef FileName,
+ StringRef SectionName,
+ StringRef SymbolName)>;
+
+ RuntimeDyldChecker(IsSymbolValidFunction IsSymbolValid,
+ GetSymbolAddressFunction GetSymbolAddress,
+ GetSymbolContentFunction GetSymbolContent,
+ GetSectionLoadAddressFunction GetSectionLoadAddresss,
+ GetSectionContentFunction GetSectionContent,
+ GetStubOffsetInSectionFunction GetStubOffsetInSection,
+ support::endianness Endianness,
+ MCDisassembler *Disassembler,
MCInstPrinter *InstPrinter, raw_ostream &ErrStream);
~RuntimeDyldChecker();
- // Get the associated RTDyld instance.
- RuntimeDyld& getRTDyld();
-
- // Get the associated RTDyld instance.
- const RuntimeDyld& getRTDyld() const;
-
/// Check a single expression against the attached RuntimeDyld
/// instance.
bool check(StringRef CheckExpr) const;
@@ -99,7 +120,7 @@ public:
bool LocalAddress);
/// If there is a section at the given local address, return its load
- /// address, otherwise return none.
+ /// address, otherwise return none.
Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const;
private:
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=357947&r1=357946&r2=357947&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Mon Apr 8 14:50:48 2019
@@ -12,7 +12,6 @@
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "RuntimeDyldCOFF.h"
-#include "RuntimeDyldCheckerImpl.h"
#include "RuntimeDyldELF.h"
#include "RuntimeDyldImpl.h"
#include "RuntimeDyldMachO.h"
@@ -375,10 +374,34 @@ RuntimeDyldImpl::loadObjectImpl(const ob
else
return IOrErr.takeError();
- // If there is an attached checker, notify it about the stubs for this
- // section so that they can be verified.
- if (Checker)
- Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
+ // If there is a NotifyStubEmitted callback set, call it to register any
+ // stubs created for this section.
+ if (NotifyStubEmitted) {
+ StringRef FileName = Obj.getFileName();
+ StringRef SectionName = Sections[SectionID].getName();
+ for (auto &KV : Stubs) {
+
+ auto &VR = KV.first;
+ uint64_t StubAddr = KV.second;
+
+ // If this is a named stub, just call NotifyStubEmitted.
+ if (VR.SymbolName) {
+ NotifyStubEmitted(FileName, SectionName, VR.SymbolName, StubAddr);
+ continue;
+ }
+
+ // Otherwise we will have to try a reverse lookup on the globla symbol table.
+ for (auto &GSTMapEntry : GlobalSymbolTable) {
+ StringRef SymbolName = GSTMapEntry.first();
+ auto &GSTEntry = GSTMapEntry.second;
+ if (GSTEntry.getSectionID() == VR.SectionID &&
+ GSTEntry.getOffset() == VR.Offset) {
+ NotifyStubEmitted(FileName, SectionName, SymbolName, StubAddr);
+ break;
+ }
+ }
+ }
+ }
}
// Process remaining sections
@@ -721,9 +744,6 @@ Error RuntimeDyldImpl::emitCommonSymbols
Addr += Size;
}
- if (Checker)
- Checker->registerSection(Obj.getFileName(), SectionID);
-
return Error::success();
}
@@ -840,9 +860,6 @@ RuntimeDyldImpl::emitSection(const Objec
if (!IsRequired)
Sections.back().setLoadAddress(0);
- if (Checker)
- Checker->registerSection(Obj.getFileName(), SectionID);
-
return SectionID;
}
@@ -1225,42 +1242,43 @@ RuntimeDyld::RuntimeDyld(RuntimeDyld::Me
// permissions are applied.
Dyld = nullptr;
ProcessAllSections = false;
- Checker = nullptr;
}
RuntimeDyld::~RuntimeDyld() {}
static std::unique_ptr<RuntimeDyldCOFF>
-createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
- JITSymbolResolver &Resolver, bool ProcessAllSections,
- RuntimeDyldCheckerImpl *Checker) {
+createRuntimeDyldCOFF(
+ Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
+ JITSymbolResolver &Resolver, bool ProcessAllSections,
+ RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted) {
std::unique_ptr<RuntimeDyldCOFF> Dyld =
RuntimeDyldCOFF::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
- Dyld->setRuntimeDyldChecker(Checker);
+ Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));
return Dyld;
}
static std::unique_ptr<RuntimeDyldELF>
createRuntimeDyldELF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
JITSymbolResolver &Resolver, bool ProcessAllSections,
- RuntimeDyldCheckerImpl *Checker) {
+ RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted) {
std::unique_ptr<RuntimeDyldELF> Dyld =
RuntimeDyldELF::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
- Dyld->setRuntimeDyldChecker(Checker);
+ Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));
return Dyld;
}
static std::unique_ptr<RuntimeDyldMachO>
-createRuntimeDyldMachO(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
- JITSymbolResolver &Resolver,
- bool ProcessAllSections,
- RuntimeDyldCheckerImpl *Checker) {
+createRuntimeDyldMachO(
+ Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
+ JITSymbolResolver &Resolver,
+ bool ProcessAllSections,
+ RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted) {
std::unique_ptr<RuntimeDyldMachO> Dyld =
RuntimeDyldMachO::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
- Dyld->setRuntimeDyldChecker(Checker);
+ Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));
return Dyld;
}
@@ -1270,15 +1288,16 @@ RuntimeDyld::loadObject(const ObjectFile
if (Obj.isELF())
Dyld =
createRuntimeDyldELF(static_cast<Triple::ArchType>(Obj.getArch()),
- MemMgr, Resolver, ProcessAllSections, Checker);
+ MemMgr, Resolver, ProcessAllSections,
+ std::move(NotifyStubEmitted));
else if (Obj.isMachO())
Dyld = createRuntimeDyldMachO(
static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
- ProcessAllSections, Checker);
+ ProcessAllSections, std::move(NotifyStubEmitted));
else if (Obj.isCOFF())
Dyld = createRuntimeDyldCOFF(
static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
- ProcessAllSections, Checker);
+ ProcessAllSections, std::move(NotifyStubEmitted));
else
report_fatal_error("Incompatible object format!");
}
@@ -1297,6 +1316,11 @@ void *RuntimeDyld::getSymbolLocalAddress
return Dyld->getSymbolLocalAddress(Name);
}
+unsigned RuntimeDyld::getSymbolSectionID(StringRef Name) const {
+ assert(Dyld && "No RuntimeDyld instance attached");
+ return Dyld->getSymbolSectionID(Name);
+}
+
JITEvaluatedSymbol RuntimeDyld::getSymbol(StringRef Name) const {
if (!Dyld)
return nullptr;
@@ -1335,6 +1359,16 @@ void RuntimeDyld::finalizeWithMemoryMana
}
}
+StringRef RuntimeDyld::getSectionContent(unsigned SectionID) const {
+ assert(Dyld && "No Dyld instance attached");
+ return Dyld->getSectionContent(SectionID);
+}
+
+uint64_t RuntimeDyld::getSectionLoadAddress(unsigned SectionID) const {
+ assert(Dyld && "No Dyld instance attached");
+ return Dyld->getSectionLoadAddress(SectionID);
+}
+
void RuntimeDyld::registerEHFrames() {
if (Dyld)
Dyld->registerEHFrames();
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp?rev=357947&r1=357946&r2=357947&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp Mon Apr 8 14:50:48 2019
@@ -8,15 +8,14 @@
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
#include "RuntimeDyldCheckerImpl.h"
-#include "RuntimeDyldImpl.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
#include "llvm/Support/Path.h"
#include <cctype>
-#include <future>
#include <memory>
#include <utility>
@@ -665,25 +664,36 @@ private:
bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size) const {
MCDisassembler *Dis = Checker.Disassembler;
- StringRef SectionMem = Checker.getSubsectionStartingAt(Symbol);
- ArrayRef<uint8_t> SectionBytes(SectionMem.bytes_begin(), SectionMem.size());
+ StringRef SymbolMem = Checker.getSymbolContent(Symbol);
+ ArrayRef<uint8_t> SymbolBytes(SymbolMem.bytes_begin(), SymbolMem.size());
MCDisassembler::DecodeStatus S =
- Dis->getInstruction(Inst, Size, SectionBytes, 0, nulls(), nulls());
+ Dis->getInstruction(Inst, Size, SymbolBytes, 0, nulls(), nulls());
return (S == MCDisassembler::Success);
}
};
}
-RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld,
- MCDisassembler *Disassembler,
- MCInstPrinter *InstPrinter,
- raw_ostream &ErrStream)
- : RTDyld(RTDyld), Disassembler(Disassembler), InstPrinter(InstPrinter),
- ErrStream(ErrStream) {
- RTDyld.Checker = this;
-}
+RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl(
+ IsSymbolValidFunction IsSymbolValid,
+ GetSymbolAddressFunction GetSymbolAddress,
+ GetSymbolContentFunction GetSymbolContent,
+ GetSectionLoadAddressFunction GetSectionLoadAddress,
+ GetSectionContentFunction GetSectionContent,
+ GetStubOffsetInSectionFunction GetStubOffsetInSection,
+ support::endianness Endianness,
+ MCDisassembler *Disassembler,
+ MCInstPrinter *InstPrinter,
+ raw_ostream &ErrStream)
+ : IsSymbolValid(std::move(IsSymbolValid)),
+ GetSymbolAddress(std::move(GetSymbolAddress)),
+ GetSymbolContent(std::move(GetSymbolContent)),
+ GetSectionLoadAddress(std::move(GetSectionLoadAddress)),
+ GetSectionContent(std::move(GetSectionContent)),
+ GetStubOffsetInSection(std::move(GetStubOffsetInSection)),
+ Endianness(Endianness), Disassembler(Disassembler),
+ InstPrinter(InstPrinter), ErrStream(ErrStream) {}
bool RuntimeDyldCheckerImpl::check(StringRef CheckExpr) const {
CheckExpr = CheckExpr.trim();
@@ -728,243 +738,133 @@ bool RuntimeDyldCheckerImpl::checkAllRul
return DidAllTestsPass && (NumRules != 0);
}
-Expected<JITSymbolResolver::LookupResult> RuntimeDyldCheckerImpl::lookup(
- const JITSymbolResolver::LookupSet &Symbols) const {
-
-#ifdef _MSC_VER
- using ExpectedLookupResult = MSVCPExpected<JITSymbolResolver::LookupResult>;
-#else
- using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>;
-#endif
-
- auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>();
- auto ResultF = ResultP->get_future();
-
- getRTDyld().Resolver.lookup(
- Symbols, [=](Expected<JITSymbolResolver::LookupResult> Result) {
- ResultP->set_value(std::move(Result));
- });
- return ResultF.get();
-}
-
bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
- if (getRTDyld().getSymbol(Symbol))
- return true;
- auto Result = lookup({Symbol});
-
- if (!Result) {
- logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
- return false;
- }
-
- assert(Result->count(Symbol) && "Missing symbol result");
- return true;
+ return IsSymbolValid(Symbol);
}
uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
- return static_cast<uint64_t>(
- reinterpret_cast<uintptr_t>(getRTDyld().getSymbolLocalAddress(Symbol)));
+ auto Contents = GetSymbolContent(Symbol);
+ if (!Contents) {
+ logAllUnhandledErrors(Contents.takeError(), errs(), "RTDyldChecker: ");
+ return 0;
+ }
+ return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Contents->data()));
}
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
- if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
- return InternalSymbol.getAddress();
-
- auto Result = lookup({Symbol});
- if (!Result) {
- logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
+ auto Addr = GetSymbolAddress(Symbol);
+ if (!Addr) {
+ logAllUnhandledErrors(Addr.takeError(), errs(), "RTDyldChecker: ");
return 0;
}
- auto I = Result->find(Symbol);
- assert(I != Result->end() && "Missing symbol result");
- return I->second.getAddress();
+
+ return *Addr;
}
uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
unsigned Size) const {
uintptr_t PtrSizedAddr = static_cast<uintptr_t>(SrcAddr);
assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range.");
- uint8_t *Src = reinterpret_cast<uint8_t*>(PtrSizedAddr);
- return getRTDyld().readBytesUnaligned(Src, Size);
-}
-
-
-std::pair<const RuntimeDyldCheckerImpl::SectionAddressInfo*, std::string>
-RuntimeDyldCheckerImpl::findSectionAddrInfo(StringRef FileName,
- StringRef SectionName) const {
-
- auto SectionMapItr = Stubs.find(FileName);
- if (SectionMapItr == Stubs.end()) {
- std::string ErrorMsg = "File '";
- ErrorMsg += FileName;
- ErrorMsg += "' not found. ";
- if (Stubs.empty())
- ErrorMsg += "No stubs registered.";
- else {
- ErrorMsg += "Available files are:";
- for (const auto& StubEntry : Stubs) {
- ErrorMsg += " '";
- ErrorMsg += StubEntry.first;
- ErrorMsg += "'";
- }
- }
- ErrorMsg += "\n";
- return std::make_pair(nullptr, ErrorMsg);
- }
-
- auto SectionInfoItr = SectionMapItr->second.find(SectionName);
- if (SectionInfoItr == SectionMapItr->second.end())
- return std::make_pair(nullptr,
- ("Section '" + SectionName + "' not found in file '" +
- FileName + "'\n").str());
+ void *Ptr = reinterpret_cast<void*>(PtrSizedAddr);
- return std::make_pair(&SectionInfoItr->second, std::string(""));
+ switch (Size) {
+ case 1:
+ return support::endian::read<uint8_t>(Ptr, Endianness);
+ case 2:
+ return support::endian::read<uint16_t>(Ptr, Endianness);
+ case 4:
+ return support::endian::read<uint32_t>(Ptr, Endianness);
+ case 8:
+ return support::endian::read<uint64_t>(Ptr, Endianness);
+ }
+ llvm_unreachable("Unsupported read size");
+}
+
+StringRef RuntimeDyldCheckerImpl::getSymbolContent(StringRef Symbol) const {
+ auto Content = GetSymbolContent(Symbol);
+ if (!Content) {
+ logAllUnhandledErrors(Content.takeError(), errs(), "RTDyldChecker: ");
+ return StringRef();
+ }
+ return *Content;
}
std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
StringRef FileName, StringRef SectionName, bool IsInsideLoad) const {
- const SectionAddressInfo *SectionInfo = nullptr;
- {
- std::string ErrorMsg;
- std::tie(SectionInfo, ErrorMsg) =
- findSectionAddrInfo(FileName, SectionName);
- if (ErrorMsg != "")
- return std::make_pair(0, ErrorMsg);
+ uint64_t Addr = 0;
+ std::string ErrMsg;
+
+ // If this address is being looked up in "load" mode, return the content
+ // pointer.
+ if (IsInsideLoad) {
+ if (auto Content = GetSectionContent(FileName, SectionName))
+ Addr = pointerToJITTargetAddress(Content->data());
+ else {
+ raw_string_ostream ErrMsgStream(ErrMsg);
+ logAllUnhandledErrors(Content.takeError(), ErrMsgStream,
+ "RTDyldChecker: ");
+ }
+ return std::make_pair(Addr, std::move(ErrMsg));
}
- unsigned SectionID = SectionInfo->SectionID;
- uint64_t Addr;
- if (IsInsideLoad)
- Addr = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(
- getRTDyld().Sections[SectionID].getAddress()));
+ // ... otherwise return the target pointer.
+ if (auto LoadAddr = GetSectionLoadAddress(FileName, SectionName))
+ Addr = *LoadAddr;
else
- Addr = getRTDyld().Sections[SectionID].getLoadAddress();
+ return std::make_pair(Addr, ("Section (" + FileName + ", " +
+ SectionName + ") does not exist").str());
- return std::make_pair(Addr, std::string(""));
+ return std::make_pair(Addr, std::move(ErrMsg));
}
std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
StringRef FileName, StringRef SectionName, StringRef SymbolName,
bool IsInsideLoad) const {
- const SectionAddressInfo *SectionInfo = nullptr;
- {
- std::string ErrorMsg;
- std::tie(SectionInfo, ErrorMsg) =
- findSectionAddrInfo(FileName, SectionName);
- if (ErrorMsg != "")
- return std::make_pair(0, ErrorMsg);
- }
+ auto SectionAddr = getSectionAddr(FileName, SectionName, IsInsideLoad);
- unsigned SectionID = SectionInfo->SectionID;
- const StubOffsetsMap &SymbolStubs = SectionInfo->StubOffsets;
- auto StubOffsetItr = SymbolStubs.find(SymbolName);
- if (StubOffsetItr == SymbolStubs.end())
- return std::make_pair(0,
- ("Stub for symbol '" + SymbolName + "' not found. "
- "If '" + SymbolName + "' is an internal symbol this "
- "may indicate that the stub target offset is being "
- "computed incorrectly.\n").str());
+ if (!SectionAddr.second.empty())
+ return SectionAddr;
- uint64_t StubOffset = StubOffsetItr->second;
+ auto StubOffset = GetStubOffsetInSection(FileName, SectionName, SymbolName);
- uint64_t Addr;
- if (IsInsideLoad) {
- uintptr_t SectionBase = reinterpret_cast<uintptr_t>(
- getRTDyld().Sections[SectionID].getAddress());
- Addr = static_cast<uint64_t>(SectionBase) + StubOffset;
- } else {
- uint64_t SectionBase = getRTDyld().Sections[SectionID].getLoadAddress();
- Addr = SectionBase + StubOffset;
- }
-
- return std::make_pair(Addr, std::string(""));
-}
-
-StringRef
-RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const {
- RTDyldSymbolTable::const_iterator pos =
- getRTDyld().GlobalSymbolTable.find(Name);
- if (pos == getRTDyld().GlobalSymbolTable.end())
- return StringRef();
- const auto &SymInfo = pos->second;
- uint8_t *SectionAddr = getRTDyld().getSectionAddress(SymInfo.getSectionID());
- return StringRef(reinterpret_cast<const char *>(SectionAddr) +
- SymInfo.getOffset(),
- getRTDyld().Sections[SymInfo.getSectionID()].getSize() -
- SymInfo.getOffset());
-}
-
-Optional<uint64_t>
-RuntimeDyldCheckerImpl::getSectionLoadAddress(void *LocalAddress) const {
- for (auto &S : getRTDyld().Sections) {
- if (S.getAddress() == LocalAddress)
- return S.getLoadAddress();
+ if (!StubOffset) {
+ std::string ErrMsg;
+ {
+ raw_string_ostream ErrMsgStream(ErrMsg);
+ logAllUnhandledErrors(StubOffset.takeError(), ErrMsgStream,
+ "RTDyldChecker: ");
+ }
+ return std::make_pair((uint64_t)0, std::move(ErrMsg));
}
- return Optional<uint64_t>();
-}
-
-void RuntimeDyldCheckerImpl::registerSection(
- StringRef FilePath, unsigned SectionID) {
- StringRef FileName = sys::path::filename(FilePath);
- const SectionEntry &Section = getRTDyld().Sections[SectionID];
- StringRef SectionName = Section.getName();
- Stubs[FileName][SectionName].SectionID = SectionID;
+ return std::make_pair(SectionAddr.first + *StubOffset, "");
}
-void RuntimeDyldCheckerImpl::registerStubMap(
- StringRef FilePath, unsigned SectionID,
- const RuntimeDyldImpl::StubMap &RTDyldStubs) {
- StringRef FileName = sys::path::filename(FilePath);
- const SectionEntry &Section = getRTDyld().Sections[SectionID];
- StringRef SectionName = Section.getName();
-
- Stubs[FileName][SectionName].SectionID = SectionID;
-
- for (auto &StubMapEntry : RTDyldStubs) {
- std::string SymbolName = "";
-
- if (StubMapEntry.first.SymbolName)
- SymbolName = StubMapEntry.first.SymbolName;
- else {
- // If this is a (Section, Offset) pair, do a reverse lookup in the
- // global symbol table to find the name.
- for (auto &GSTEntry : getRTDyld().GlobalSymbolTable) {
- const auto &SymInfo = GSTEntry.second;
- if (SymInfo.getSectionID() == StubMapEntry.first.SectionID &&
- SymInfo.getOffset() ==
- static_cast<uint64_t>(StubMapEntry.first.Offset)) {
- SymbolName = GSTEntry.first();
- break;
- }
- }
- }
-
- if (SymbolName != "")
- Stubs[FileName][SectionName].StubOffsets[SymbolName] =
- StubMapEntry.second;
- }
-}
-
-RuntimeDyldChecker::RuntimeDyldChecker(RuntimeDyld &RTDyld,
- MCDisassembler *Disassembler,
- MCInstPrinter *InstPrinter,
- raw_ostream &ErrStream)
- : Impl(make_unique<RuntimeDyldCheckerImpl>(RTDyld, Disassembler,
- InstPrinter, ErrStream)) {}
+RuntimeDyldChecker::RuntimeDyldChecker(
+ IsSymbolValidFunction IsSymbolValid,
+ GetSymbolAddressFunction GetSymbolAddress,
+ GetSymbolContentFunction GetSymbolContent,
+ GetSectionLoadAddressFunction GetSectionLoadAddress,
+ GetSectionContentFunction GetSectionContent,
+ GetStubOffsetInSectionFunction GetStubOffsetInSection,
+ support::endianness Endianness,
+ MCDisassembler *Disassembler,
+ MCInstPrinter *InstPrinter,
+ raw_ostream &ErrStream)
+ : Impl(make_unique<RuntimeDyldCheckerImpl>(
+ std::move(IsSymbolValid),
+ std::move(GetSymbolAddress),
+ std::move(GetSymbolContent),
+ std::move(GetSectionLoadAddress),
+ std::move(GetSectionContent),
+ std::move(GetStubOffsetInSection),
+ Endianness, Disassembler,
+ InstPrinter, ErrStream)) {}
RuntimeDyldChecker::~RuntimeDyldChecker() {}
-RuntimeDyld& RuntimeDyldChecker::getRTDyld() {
- return Impl->RTDyld;
-}
-
-const RuntimeDyld& RuntimeDyldChecker::getRTDyld() const {
- return Impl->RTDyld;
-}
-
bool RuntimeDyldChecker::check(StringRef CheckExpr) const {
return Impl->check(CheckExpr);
}
@@ -979,8 +879,3 @@ RuntimeDyldChecker::getSectionAddr(Strin
bool LocalAddress) {
return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
}
-
-Optional<uint64_t>
-RuntimeDyldChecker::getSectionLoadAddress(void *LocalAddress) const {
- return Impl->getSectionLoadAddress(LocalAddress);
-}
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h?rev=357947&r1=357946&r2=357947&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h Mon Apr 8 14:50:48 2019
@@ -15,14 +15,35 @@ namespace llvm {
class RuntimeDyldCheckerImpl {
friend class RuntimeDyldChecker;
- friend class RuntimeDyldImpl;
friend class RuntimeDyldCheckerExprEval;
- friend class RuntimeDyldELF;
+
+ using IsSymbolValidFunction =
+ RuntimeDyldChecker::IsSymbolValidFunction;
+ using GetSymbolAddressFunction =
+ RuntimeDyldChecker::GetSymbolAddressFunction;
+ using GetSymbolContentFunction =
+ RuntimeDyldChecker::GetSymbolContentFunction;
+
+ using GetSectionLoadAddressFunction =
+ RuntimeDyldChecker::GetSectionLoadAddressFunction;
+ using GetSectionContentFunction =
+ RuntimeDyldChecker::GetSectionContentFunction;
+
+ using GetStubOffsetInSectionFunction =
+ RuntimeDyldChecker::GetStubOffsetInSectionFunction;
public:
- RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld, MCDisassembler *Disassembler,
- MCInstPrinter *InstPrinter,
- llvm::raw_ostream &ErrStream);
+ RuntimeDyldCheckerImpl(
+ IsSymbolValidFunction IsSymbolValid,
+ GetSymbolAddressFunction GetSymbolAddress,
+ GetSymbolContentFunction GetSymbolContent,
+ GetSectionLoadAddressFunction GetSectionLoadAddress,
+ GetSectionContentFunction GetSectionContent,
+ GetStubOffsetInSectionFunction GetStubOffsetInSection,
+ support::endianness Endianness,
+ MCDisassembler *Disassembler,
+ MCInstPrinter *InstPrinter,
+ llvm::raw_ostream &ErrStream);
bool check(StringRef CheckExpr) const;
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
@@ -30,15 +51,6 @@ public:
private:
// StubMap typedefs.
- typedef std::map<std::string, uint64_t> StubOffsetsMap;
- struct SectionAddressInfo {
- uint64_t SectionID;
- StubOffsetsMap StubOffsets;
- };
- typedef std::map<std::string, SectionAddressInfo> SectionMap;
- typedef std::map<std::string, SectionMap> StubMap;
-
- RuntimeDyldImpl &getRTDyld() const { return *RTDyld.Dyld; }
Expected<JITSymbolResolver::LookupResult>
lookup(const JITSymbolResolver::LookupSet &Symbols) const;
@@ -48,9 +60,7 @@ private:
uint64_t getSymbolRemoteAddr(StringRef Symbol) const;
uint64_t readMemoryAtAddr(uint64_t Addr, unsigned Size) const;
- std::pair<const SectionAddressInfo*, std::string> findSectionAddrInfo(
- StringRef FileName,
- StringRef SectionName) const;
+ StringRef getSymbolContent(StringRef Symbol) const;
std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
StringRef SectionName,
@@ -60,20 +70,19 @@ private:
StringRef SectionName,
StringRef Symbol,
bool IsInsideLoad) const;
- StringRef getSubsectionStartingAt(StringRef Name) const;
Optional<uint64_t> getSectionLoadAddress(void *LocalAddr) const;
- void registerSection(StringRef FilePath, unsigned SectionID);
- void registerStubMap(StringRef FilePath, unsigned SectionID,
- const RuntimeDyldImpl::StubMap &RTDyldStubs);
-
- RuntimeDyld &RTDyld;
+ IsSymbolValidFunction IsSymbolValid;
+ GetSymbolAddressFunction GetSymbolAddress;
+ GetSymbolContentFunction GetSymbolContent;
+ GetSectionLoadAddressFunction GetSectionLoadAddress;
+ GetSectionContentFunction GetSectionContent;
+ GetStubOffsetInSectionFunction GetStubOffsetInSection;
+ support::endianness Endianness;
MCDisassembler *Disassembler;
MCInstPrinter *InstPrinter;
llvm::raw_ostream &ErrStream;
-
- StubMap Stubs;
};
}
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=357947&r1=357946&r2=357947&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Mon Apr 8 14:50:48 2019
@@ -1856,9 +1856,6 @@ Error RuntimeDyldELF::finalizeLoad(const
Sections[GOTSectionID] =
SectionEntry(".got", Addr, TotalSize, TotalSize, 0);
- if (Checker)
- Checker->registerSection(Obj.getFileName(), GOTSectionID);
-
// For now, initialize all GOT entries to zero. We'll fill them in as
// needed when GOT-based relocations are applied.
memset(Addr, 0, TotalSize);
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=357947&r1=357946&r2=357947&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Mon Apr 8 14:50:48 2019
@@ -240,7 +240,6 @@ typedef StringMap<SymbolTableEntry> RTDy
class RuntimeDyldImpl {
friend class RuntimeDyld::LoadedObjectInfo;
- friend class RuntimeDyldCheckerImpl;
protected:
static const unsigned AbsoluteSymbolSection = ~0U;
@@ -250,9 +249,6 @@ protected:
// The symbol resolver to use for external symbols.
JITSymbolResolver &Resolver;
- // Attached RuntimeDyldChecker instance. Null if no instance attached.
- RuntimeDyldCheckerImpl *Checker;
-
// A list of all sections emitted by the dynamic linker. These sections are
// referenced in the code by means of their index in this list - SectionID.
typedef SmallVector<SectionEntry, 64> SectionList;
@@ -312,20 +308,16 @@ protected:
// the end of the list while the list is being processed.
sys::Mutex lock;
+ using NotifyStubEmittedFunction =
+ RuntimeDyld::NotifyStubEmittedFunction;
+ NotifyStubEmittedFunction NotifyStubEmitted;
+
virtual unsigned getMaxStubSize() = 0;
virtual unsigned getStubAlignment() = 0;
bool HasError;
std::string ErrorStr;
- uint64_t getSectionLoadAddress(unsigned SectionID) const {
- return Sections[SectionID].getLoadAddress();
- }
-
- uint8_t *getSectionAddress(unsigned SectionID) const {
- return Sections[SectionID].getAddress();
- }
-
void writeInt16BE(uint8_t *Addr, uint16_t Value) {
if (IsTargetLittleEndian)
sys::swapByteOrder(Value);
@@ -471,7 +463,7 @@ protected:
public:
RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr,
JITSymbolResolver &Resolver)
- : MemMgr(MemMgr), Resolver(Resolver), Checker(nullptr),
+ : MemMgr(MemMgr), Resolver(Resolver),
ProcessAllSections(false), HasError(false) {
}
@@ -481,13 +473,22 @@ public:
this->ProcessAllSections = ProcessAllSections;
}
- void setRuntimeDyldChecker(RuntimeDyldCheckerImpl *Checker) {
- this->Checker = Checker;
- }
-
virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
loadObject(const object::ObjectFile &Obj) = 0;
+ uint64_t getSectionLoadAddress(unsigned SectionID) const {
+ return Sections[SectionID].getLoadAddress();
+ }
+
+ uint8_t *getSectionAddress(unsigned SectionID) const {
+ return Sections[SectionID].getAddress();
+ }
+
+ StringRef getSectionContent(unsigned SectionID) const {
+ return StringRef(reinterpret_cast<char*>(Sections[SectionID].getAddress()),
+ Sections[SectionID].getSize());
+ }
+
uint8_t* getSymbolLocalAddress(StringRef Name) const {
// FIXME: Just look up as a function for now. Overly simple of course.
// Work in progress.
@@ -501,6 +502,13 @@ public:
return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
}
+ unsigned getSymbolSectionID(StringRef Name) const {
+ auto GSTItr = GlobalSymbolTable.find(Name);
+ if (GSTItr == GlobalSymbolTable.end())
+ return ~0U;
+ return GSTItr->second.getSectionID();
+ }
+
JITEvaluatedSymbol getSymbol(StringRef Name) const {
// FIXME: Just look up as a function for now. Overly simple of course.
// Work in progress.
@@ -559,6 +567,10 @@ public:
virtual bool isCompatibleFile(const ObjectFile &Obj) const = 0;
+ void setNotifyStubEmitted(NotifyStubEmittedFunction NotifyStubEmitted) {
+ this->NotifyStubEmitted = std::move(NotifyStubEmitted);
+ }
+
virtual void registerEHFrames();
void deregisterEHFrames();
Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=357947&r1=357946&r2=357947&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)
+++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Mon Apr 8 14:50:48 2019
@@ -29,9 +29,12 @@
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
+
+#include <future>
#include <list>
using namespace llvm;
@@ -137,14 +140,50 @@ PrintAllocationRequests("print-alloc-req
"manager by RuntimeDyld"),
cl::Hidden);
+ExitOnError ExitOnErr;
+
/* *** */
+using SectionIDMap = StringMap<unsigned>;
+using FileToSectionIDMap = StringMap<SectionIDMap>;
+
+void dumpFileToSectionIDMap(const FileToSectionIDMap &FileToSecIDMap) {
+ for (const auto &KV : FileToSecIDMap) {
+ llvm::dbgs() << "In " << KV.first() << "\n";
+ for (auto &KV2 : KV.second)
+ llvm::dbgs() << " \"" << KV2.first() << "\" -> " << KV2.second << "\n";
+ }
+}
+
+Expected<unsigned> getSectionId(const FileToSectionIDMap &FileToSecIDMap,
+ StringRef FileName, StringRef SectionName) {
+ auto I = FileToSecIDMap.find(FileName);
+ if (I == FileToSecIDMap.end())
+ return make_error<StringError>("No file named " + FileName,
+ inconvertibleErrorCode());
+ auto &SectionIDs = I->second;
+ auto J = SectionIDs.find(SectionName);
+ if (J == SectionIDs.end())
+ return make_error<StringError>("No section named \"" + SectionName +
+ "\" in file " + FileName,
+ inconvertibleErrorCode());
+ return J->second;
+}
+
// A trivial memory manager that doesn't do anything fancy, just uses the
// support library allocation routines directly.
class TrivialMemoryManager : public RTDyldMemoryManager {
public:
- SmallVector<sys::MemoryBlock, 16> FunctionMemory;
- SmallVector<sys::MemoryBlock, 16> DataMemory;
+ struct SectionInfo {
+ SectionInfo(StringRef Name, sys::MemoryBlock MB, unsigned SectionID)
+ : Name(Name), MB(std::move(MB)), SectionID(SectionID) {}
+ std::string Name;
+ sys::MemoryBlock MB;
+ unsigned SectionID = ~0U;
+ };
+
+ SmallVector<SectionInfo, 16> FunctionMemory;
+ SmallVector<SectionInfo, 16> DataMemory;
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID,
@@ -153,6 +192,11 @@ public:
unsigned SectionID, StringRef SectionName,
bool IsReadOnly) override;
+ /// If non null, records subsequent Name -> SectionID mappings.
+ void setSectionIDsMap(SectionIDMap *SecIDMap) {
+ this->SecIDMap = SecIDMap;
+ }
+
void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true) override {
return nullptr;
@@ -192,7 +236,8 @@ public:
SlabSize = Size;
}
- uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode) {
+ uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode,
+ StringRef SectionName, unsigned SectionID) {
Size = alignTo(Size, Alignment);
if (CurrentSlabOffset + Size > SlabSize)
report_fatal_error("Can't allocate enough memory. Tune --preallocate");
@@ -200,9 +245,9 @@ public:
uintptr_t OldSlabOffset = CurrentSlabOffset;
sys::MemoryBlock MB((void *)OldSlabOffset, Size);
if (isCode)
- FunctionMemory.push_back(MB);
+ FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID));
else
- DataMemory.push_back(MB);
+ DataMemory.push_back(SectionInfo(SectionName, MB, SectionID));
CurrentSlabOffset += Size;
return (uint8_t*)OldSlabOffset;
}
@@ -213,6 +258,7 @@ private:
bool UsePreallocation = false;
uintptr_t SlabSize = 0;
uintptr_t CurrentSlabOffset = 0;
+ SectionIDMap *SecIDMap = nullptr;
};
uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
@@ -223,8 +269,13 @@ uint8_t *TrivialMemoryManager::allocateC
outs() << "allocateCodeSection(Size = " << Size << ", Alignment = "
<< Alignment << ", SectionName = " << SectionName << ")\n";
+ dbgs() << " Registering code section \"" << SectionName << "\"\n";
+ if (SecIDMap)
+ (*SecIDMap)[SectionName] = SectionID;
+
if (UsePreallocation)
- return allocateFromSlab(Size, Alignment, true /* isCode */);
+ return allocateFromSlab(Size, Alignment, true /* isCode */,
+ SectionName, SectionID);
std::error_code EC;
sys::MemoryBlock MB =
@@ -234,7 +285,7 @@ uint8_t *TrivialMemoryManager::allocateC
EC);
if (!MB.base())
report_fatal_error("MemoryManager allocation failed: " + EC.message());
- FunctionMemory.push_back(MB);
+ FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID));
return (uint8_t*)MB.base();
}
@@ -247,8 +298,13 @@ uint8_t *TrivialMemoryManager::allocateD
outs() << "allocateDataSection(Size = " << Size << ", Alignment = "
<< Alignment << ", SectionName = " << SectionName << ")\n";
+ dbgs() << " Registering code section \"" << SectionName << "\"\n";
+ if (SecIDMap)
+ (*SecIDMap)[SectionName] = SectionID;
+
if (UsePreallocation)
- return allocateFromSlab(Size, Alignment, false /* isCode */);
+ return allocateFromSlab(Size, Alignment, false /* isCode */, SectionName,
+ SectionID);
std::error_code EC;
sys::MemoryBlock MB =
@@ -258,7 +314,7 @@ uint8_t *TrivialMemoryManager::allocateD
EC);
if (!MB.base())
report_fatal_error("MemoryManager allocation failed: " + EC.message());
- DataMemory.push_back(MB);
+ DataMemory.push_back(SectionInfo(SectionName, MB, SectionID));
return (uint8_t*)MB.base();
}
@@ -469,9 +525,11 @@ static int executeInput() {
// Invalidate the instruction cache for each loaded function.
for (auto &FM : MemMgr.FunctionMemory) {
+ auto &FM_MB = FM.MB;
+
// Make sure the memory is executable.
// setExecutable will call InvalidateInstructionCache.
- if (auto EC = sys::Memory::protectMappedMemory(FM,
+ if (auto EC = sys::Memory::protectMappedMemory(FM_MB,
sys::Memory::MF_READ |
sys::Memory::MF_EXEC))
ErrorAndExit("unable to mark function executable: '" + EC.message() +
@@ -505,10 +563,10 @@ static int checkAllExpressions(RuntimeDy
return 0;
}
-void applySpecificSectionMappings(RuntimeDyldChecker &Checker) {
+void applySpecificSectionMappings(RuntimeDyld &Dyld,
+ const FileToSectionIDMap &FileToSecIDMap) {
for (StringRef Mapping : SpecificSectionMappings) {
-
size_t EqualsIdx = Mapping.find_first_of("=");
std::string SectionIDStr = Mapping.substr(0, EqualsIdx);
size_t ComaIdx = Mapping.find_first_of(",");
@@ -519,17 +577,10 @@ void applySpecificSectionMappings(Runtim
std::string FileName = SectionIDStr.substr(0, ComaIdx);
std::string SectionName = SectionIDStr.substr(ComaIdx + 1);
+ unsigned SectionID =
+ ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName));
- uint64_t OldAddrInt;
- std::string ErrorMsg;
- std::tie(OldAddrInt, ErrorMsg) =
- Checker.getSectionAddr(FileName, SectionName, true);
-
- if (ErrorMsg != "")
- report_fatal_error(ErrorMsg);
-
- void* OldAddr = reinterpret_cast<void*>(static_cast<uintptr_t>(OldAddrInt));
-
+ auto* OldAddr = Dyld.getSectionContent(SectionID).data();
std::string NewAddrStr = Mapping.substr(EqualsIdx + 1);
uint64_t NewAddr;
@@ -537,7 +588,7 @@ void applySpecificSectionMappings(Runtim
report_fatal_error("Invalid section address in mapping '" + Mapping +
"'.");
- Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr);
+ Dyld.mapSectionAddress(OldAddr, NewAddr);
}
}
@@ -553,21 +604,17 @@ void applySpecificSectionMappings(Runtim
// (e.g. 1 << 32) to stress-test stubs, GOTs, etc.
//
static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
- TrivialMemoryManager &MemMgr,
- RuntimeDyldChecker &Checker) {
+ RuntimeDyld &Dyld,
+ TrivialMemoryManager &MemMgr) {
// Set up a work list (section addr/size pairs).
- typedef std::list<std::pair<void*, uint64_t>> WorklistT;
+ typedef std::list<const TrivialMemoryManager::SectionInfo*> WorklistT;
WorklistT Worklist;
for (const auto& CodeSection : MemMgr.FunctionMemory)
- Worklist.push_back(std::make_pair(CodeSection.base(), CodeSection.size()));
+ Worklist.push_back(&CodeSection);
for (const auto& DataSection : MemMgr.DataMemory)
- Worklist.push_back(std::make_pair(DataSection.base(), DataSection.size()));
-
- // Apply any section-specific mappings that were requested on the command
- // line.
- applySpecificSectionMappings(Checker);
+ Worklist.push_back(&DataSection);
// Keep an "already allocated" mapping of section target addresses to sizes.
// Sections whose address mappings aren't specified on the command line will
@@ -582,16 +629,16 @@ static void remapSectionsAndSymbols(cons
I != E;) {
WorklistT::iterator Tmp = I;
++I;
- auto LoadAddr = Checker.getSectionLoadAddress(Tmp->first);
- if (LoadAddr &&
- *LoadAddr != static_cast<uint64_t>(
- reinterpret_cast<uintptr_t>(Tmp->first))) {
+ auto LoadAddr = Dyld.getSectionLoadAddress((*Tmp)->SectionID);
+
+ if (LoadAddr != static_cast<uint64_t>(
+ reinterpret_cast<uintptr_t>((*Tmp)->MB.base()))) {
// A section will have a LoadAddr of 0 if it wasn't loaded for whatever
// reason (e.g. zero byte COFF sections). Don't include those sections in
// the allocation map.
- if (*LoadAddr != 0)
- AlreadyAllocated[*LoadAddr] = Tmp->second;
+ if (LoadAddr != 0)
+ AlreadyAllocated[LoadAddr] = (*Tmp)->MB.size();
Worklist.erase(Tmp);
}
}
@@ -609,19 +656,19 @@ static void remapSectionsAndSymbols(cons
// Process any elements remaining in the worklist.
while (!Worklist.empty()) {
- std::pair<void*, uint64_t> CurEntry = Worklist.front();
+ auto *CurEntry = Worklist.front();
Worklist.pop_front();
uint64_t NextSectionAddr = TargetAddrStart;
for (const auto &Alloc : AlreadyAllocated)
- if (NextSectionAddr + CurEntry.second + TargetSectionSep <= Alloc.first)
+ if (NextSectionAddr + CurEntry->MB.size() + TargetSectionSep <= Alloc.first)
break;
else
NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep;
- AlreadyAllocated[NextSectionAddr] = CurEntry.second;
- Checker.getRTDyld().mapSectionAddress(CurEntry.first, NextSectionAddr);
+ Dyld.mapSectionAddress(CurEntry->MB.base(), NextSectionAddr);
+ AlreadyAllocated[NextSectionAddr] = CurEntry->MB.size();
}
// Add dummy symbols to the memory manager.
@@ -693,18 +740,116 @@ static int linkAndVerify() {
// Instantiate a dynamic linker.
TrivialMemoryManager MemMgr;
doPreallocation(MemMgr);
+
+ using StubOffsets = StringMap<uint32_t>;
+ using SectionStubs = StringMap<StubOffsets>;
+ using FileStubs = StringMap<SectionStubs>;
+
+ FileStubs StubMap;
RuntimeDyld Dyld(MemMgr, MemMgr);
Dyld.setProcessAllSections(true);
- RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(),
- llvm::dbgs());
+
+ Dyld.setNotifyStubEmitted(
+ [&StubMap](StringRef FilePath, StringRef SectionName,
+ StringRef SymbolName, uint32_t StubOffset) {
+ StubMap[sys::path::filename(FilePath)][SectionName][SymbolName] =
+ StubOffset;
+ });
+
+ auto GetSymbolAddress =
+ [&Dyld, &MemMgr](StringRef Symbol) -> Expected<JITTargetAddress> {
+ if (auto InternalSymbol = Dyld.getSymbol(Symbol))
+ return InternalSymbol.getAddress();
+
+#ifdef _MSC_VER
+ using ExpectedLookupResult = MSVCPExpected<JITSymbolResolver::LookupResult>;
+#else
+ using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>;
+#endif
+
+ auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>();
+ auto ResultF = ResultP->get_future();
+
+ MemMgr.lookup(
+ JITSymbolResolver::LookupSet({Symbol}),
+ [=](Expected<JITSymbolResolver::LookupResult> Result) {
+ ResultP->set_value(std::move(Result));
+ });
+
+ auto Result = ResultF.get();
+ if (!Result)
+ return Result.takeError();
+
+ auto I = Result->find(Symbol);
+ assert(I != Result->end() &&
+ "Expected symbol address if no error occurred");
+ return I->second.getAddress();
+ };
+
+ auto IsSymbolValid =
+ [&Dyld, GetSymbolAddress](StringRef Symbol) {
+ if (Dyld.getSymbol(Symbol))
+ return true;
+ auto Addr = GetSymbolAddress(Symbol);
+ if (!Addr) {
+ logAllUnhandledErrors(Addr.takeError(), errs(), "RTDyldChecker: ");
+ return false;
+ }
+ return *Addr != 0;
+ };
+
+ FileToSectionIDMap FileToSecIDMap;
+
+ auto GetSectionAddress =
+ [&Dyld, &FileToSecIDMap](StringRef FileName, StringRef SectionName) {
+ unsigned SectionID =
+ ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName));
+ return Dyld.getSectionLoadAddress(SectionID);
+ };
+
+ auto GetSectionContent =
+ [&Dyld, &FileToSecIDMap](StringRef FileName, StringRef SectionName) {
+ unsigned SectionID =
+ ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName));
+ return Dyld.getSectionContent(SectionID);
+ };
+
+
+ auto GetSymbolContents =
+ [&Dyld](StringRef Symbol) {
+ auto *SymAddr = static_cast<char*>(Dyld.getSymbolLocalAddress(Symbol));
+ if (!SymAddr)
+ return StringRef();
+ unsigned SectionID = Dyld.getSymbolSectionID(Symbol);
+ if (SectionID == ~0U)
+ return StringRef();
+ StringRef SecContent = Dyld.getSectionContent(SectionID);
+ uint64_t SymSize = SecContent.size() - (SymAddr - SecContent.data());
+ return StringRef(SymAddr, SymSize);
+ };
+
+ auto GetStubOffset =
+ [&StubMap](StringRef FileName, StringRef SectionName, StringRef SymbolName) -> Expected<uint32_t> {
+ if (!StubMap.count(FileName))
+ return make_error<StringError>("File name not found", inconvertibleErrorCode());
+ if (!StubMap[FileName].count(SectionName))
+ return make_error<StringError>("Section name not found", inconvertibleErrorCode());
+ if (!StubMap[FileName][SectionName].count(SymbolName))
+ return make_error<StringError>("Symbol name not found", inconvertibleErrorCode());
+ return StubMap[FileName][SectionName][SymbolName];
+ };
+
+ // We will initialize this below once we have the first object file and can
+ // know the endianness.
+ std::unique_ptr<RuntimeDyldChecker> Checker;
// If we don't have any input files, read from stdin.
if (!InputFileList.size())
InputFileList.push_back("-");
- for (auto &Filename : InputFileList) {
+ for (auto &InputFile : InputFileList) {
// Load the input memory buffer.
ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
- MemoryBuffer::getFileOrSTDIN(Filename);
+ MemoryBuffer::getFileOrSTDIN(InputFile);
if (std::error_code EC = InputBuffer.getError())
ErrorAndExit("unable to read input: '" + EC.message() + "'");
@@ -722,6 +867,22 @@ static int linkAndVerify() {
ObjectFile &Obj = **MaybeObj;
+ if (!Checker)
+ Checker =
+ llvm::make_unique<RuntimeDyldChecker>(IsSymbolValid, GetSymbolAddress,
+ GetSymbolContents,
+ GetSectionAddress,
+ GetSectionContent, GetStubOffset,
+ Obj.isLittleEndian()
+ ? support::little
+ : support::big,
+ Disassembler.get(),
+ InstPrinter.get(), dbgs());
+
+ auto FileName = sys::path::filename(InputFile);
+ dbgs() << "In " << FileName << ":\n";
+ MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]);
+
// Load the object file
Dyld.loadObject(Obj);
if (Dyld.hasError()) {
@@ -731,7 +892,8 @@ static int linkAndVerify() {
// Re-map the section addresses into the phony target address space and add
// dummy symbols.
- remapSectionsAndSymbols(TheTriple, MemMgr, Checker);
+ applySpecificSectionMappings(Dyld, FileToSecIDMap);
+ remapSectionsAndSymbols(TheTriple, Dyld, MemMgr);
// Resolve all the relocations we can.
Dyld.resolveRelocations();
@@ -739,7 +901,7 @@ static int linkAndVerify() {
// Register EH frames.
Dyld.registerEHFrames();
- int ErrorCode = checkAllExpressions(Checker);
+ int ErrorCode = checkAllExpressions(*Checker);
if (Dyld.hasError())
ErrorAndExit("RTDyld reported an error applying relocations:\n " +
Dyld.getErrorString());
@@ -757,6 +919,8 @@ int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n");
+ ExitOnErr.setBanner(std::string(argv[0]) + ": ");
+
switch (Action) {
case AC_Execute:
return executeInput();
More information about the llvm-commits
mailing list