forked from OSchip/llvm-project
[Orc][MCJIT][RuntimeDyld] Add symbol flags to symbols in RuntimeDyld. Thread the
new types through MCJIT and Orc. In particular, add a 'weak' flag. When plumbed through RTDyldMemoryManager, this will allow us to distinguish between weak and strong definitions and find the right ones during symbol resolution. llvm-svn: 231724
This commit is contained in:
parent
fa79110cc7
commit
3197fb4a89
|
@ -14,6 +14,7 @@
|
|||
#ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
|
||||
|
||||
#include "llvm/ExecutionEngine/JITSymbolFlags.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
|
@ -25,17 +26,19 @@ namespace orc {
|
|||
typedef uint64_t TargetAddress;
|
||||
|
||||
/// @brief Represents a symbol in the JIT.
|
||||
class JITSymbol {
|
||||
public:
|
||||
class JITSymbol : public JITSymbolBase {
|
||||
public:
|
||||
|
||||
typedef std::function<TargetAddress()> GetAddressFtor;
|
||||
|
||||
/// @brief Create a 'null' symbol that represents failure to find a symbol
|
||||
/// definition.
|
||||
JITSymbol(std::nullptr_t) : CachedAddr(0) {}
|
||||
JITSymbol(std::nullptr_t)
|
||||
: JITSymbolBase(JITSymbolFlags::None), CachedAddr(0) {}
|
||||
|
||||
/// @brief Create a symbol for a definition with a known address.
|
||||
JITSymbol(TargetAddress Addr)
|
||||
: CachedAddr(Addr) {}
|
||||
JITSymbol(TargetAddress Addr, JITSymbolFlags Flags)
|
||||
: JITSymbolBase(Flags), CachedAddr(Addr) {}
|
||||
|
||||
/// @brief Create a symbol for a definition that doesn't have a known address
|
||||
/// yet.
|
||||
|
@ -46,8 +49,8 @@ public:
|
|||
/// definition without actually materializing the definition up front. The
|
||||
/// user can materialize the definition at any time by calling the getAddress
|
||||
/// method.
|
||||
JITSymbol(GetAddressFtor GetAddress)
|
||||
: CachedAddr(0), GetAddress(std::move(GetAddress)) {}
|
||||
JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
|
||||
: JITSymbolBase(Flags), GetAddress(std::move(GetAddress)), CachedAddr(0) {}
|
||||
|
||||
/// @brief Returns true if the symbol exists, false otherwise.
|
||||
explicit operator bool() const { return CachedAddr || GetAddress; }
|
||||
|
@ -64,8 +67,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
TargetAddress CachedAddr;
|
||||
GetAddressFtor GetAddress;
|
||||
TargetAddress CachedAddr;
|
||||
};
|
||||
|
||||
} // End namespace orc.
|
||||
|
|
|
@ -45,23 +45,25 @@ private:
|
|||
JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
|
||||
switch (EmitState) {
|
||||
case NotEmitted:
|
||||
if (provides(Name, ExportedSymbolsOnly)) {
|
||||
if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
|
||||
// Create a std::string version of Name to capture here - the argument
|
||||
// (a StringRef) may go away before the lambda is executed.
|
||||
// FIXME: Use capture-init when we move to C++14.
|
||||
std::string PName = Name;
|
||||
return JITSymbol(
|
||||
[this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
|
||||
if (this->EmitState == Emitting)
|
||||
return 0;
|
||||
else if (this->EmitState == NotEmitted) {
|
||||
this->EmitState = Emitting;
|
||||
Handle = this->emitToBaseLayer(B);
|
||||
this->EmitState = Emitted;
|
||||
}
|
||||
return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly)
|
||||
.getAddress();
|
||||
});
|
||||
auto PName = Name;
|
||||
JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV);
|
||||
auto GetAddress =
|
||||
[this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
|
||||
if (this->EmitState == Emitting)
|
||||
return 0;
|
||||
else if (this->EmitState == NotEmitted) {
|
||||
this->EmitState = Emitting;
|
||||
Handle = this->emitToBaseLayer(B);
|
||||
this->EmitState = Emitted;
|
||||
}
|
||||
auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly);
|
||||
return Sym.getAddress();
|
||||
};
|
||||
return JITSymbol(std::move(GetAddress), Flags);
|
||||
} else
|
||||
return nullptr;
|
||||
case Emitting:
|
||||
|
@ -98,7 +100,8 @@ private:
|
|||
std::unique_ptr<RTDyldMemoryManager> MM);
|
||||
|
||||
protected:
|
||||
virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
|
||||
virtual const GlobalValue* searchGVs(StringRef Name,
|
||||
bool ExportedSymbolsOnly) const = 0;
|
||||
virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
|
||||
|
||||
private:
|
||||
|
@ -115,46 +118,48 @@ private:
|
|||
|
||||
protected:
|
||||
|
||||
BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
|
||||
// We don't need the mangled names set any more: Once we've emitted this
|
||||
// to the base layer we'll just look for symbols there.
|
||||
MangledNames.reset();
|
||||
return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
|
||||
}
|
||||
|
||||
bool provides(StringRef Name, bool ExportedSymbolsOnly) const override {
|
||||
const GlobalValue* searchGVs(StringRef Name,
|
||||
bool ExportedSymbolsOnly) const override {
|
||||
// FIXME: We could clean all this up if we had a way to reliably demangle
|
||||
// names: We could just demangle name and search, rather than
|
||||
// mangling everything else.
|
||||
|
||||
// If we have already built the mangled name set then just search it.
|
||||
if (MangledNames) {
|
||||
auto VI = MangledNames->find(Name);
|
||||
if (VI == MangledNames->end())
|
||||
return false;
|
||||
return !ExportedSymbolsOnly || VI->second;
|
||||
if (MangledSymbols) {
|
||||
auto VI = MangledSymbols->find(Name);
|
||||
if (VI == MangledSymbols->end())
|
||||
return nullptr;
|
||||
auto GV = VI->second;
|
||||
if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
|
||||
return GV;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If we haven't built the mangled name set yet, try to build it. As an
|
||||
// optimization this will leave MangledNames set to nullptr if we find
|
||||
// Name in the process of building the set.
|
||||
buildMangledNames(Name, ExportedSymbolsOnly);
|
||||
if (!MangledNames)
|
||||
return true;
|
||||
return false;
|
||||
return buildMangledSymbols(Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
|
||||
// We don't need the mangled names set any more: Once we've emitted this
|
||||
// to the base layer we'll just look for symbols there.
|
||||
MangledSymbols.reset();
|
||||
return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
|
||||
}
|
||||
|
||||
private:
|
||||
// If the mangled name of the given GlobalValue matches the given search
|
||||
// name (and its visibility conforms to the ExportedSymbolsOnly flag) then
|
||||
// just return 'true'. Otherwise, add the mangled name to the Names map and
|
||||
// return 'false'.
|
||||
bool addGlobalValue(StringMap<bool> &Names, const GlobalValue &GV,
|
||||
const Mangler &Mang, StringRef SearchName,
|
||||
bool ExportedSymbolsOnly) const {
|
||||
// return the symbol. Otherwise, add the mangled name to the Names map and
|
||||
// return nullptr.
|
||||
const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
|
||||
const GlobalValue &GV,
|
||||
const Mangler &Mang, StringRef SearchName,
|
||||
bool ExportedSymbolsOnly) const {
|
||||
// Modules don't "provide" decls or common symbols.
|
||||
if (GV.isDeclaration() || GV.hasCommonLinkage())
|
||||
return false;
|
||||
return nullptr;
|
||||
|
||||
// Mangle the GV name.
|
||||
std::string MangledName;
|
||||
|
@ -167,39 +172,42 @@ private:
|
|||
// bail out early.
|
||||
if (MangledName == SearchName)
|
||||
if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
|
||||
return true;
|
||||
return &GV;
|
||||
|
||||
// Otherwise add this to the map for later.
|
||||
Names[MangledName] = GV.hasDefaultVisibility();
|
||||
return false;
|
||||
Names[MangledName] = &GV;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Build the MangledNames map. Bails out early (with MangledNames left set
|
||||
// Build the MangledSymbols map. Bails out early (with MangledSymbols left set
|
||||
// to nullptr) if the given SearchName is found while building the map.
|
||||
void buildMangledNames(StringRef SearchName,
|
||||
bool ExportedSymbolsOnly) const {
|
||||
assert(!MangledNames && "Mangled names map already exists?");
|
||||
const GlobalValue* buildMangledSymbols(StringRef SearchName,
|
||||
bool ExportedSymbolsOnly) const {
|
||||
assert(!MangledSymbols && "Mangled symbols map already exists?");
|
||||
|
||||
auto Names = llvm::make_unique<StringMap<bool>>();
|
||||
auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
|
||||
|
||||
for (const auto &M : Ms) {
|
||||
Mangler Mang(&M->getDataLayout());
|
||||
|
||||
for (const auto &GV : M->globals())
|
||||
if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly))
|
||||
return;
|
||||
for (const auto &V : M->globals())
|
||||
if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName,
|
||||
ExportedSymbolsOnly))
|
||||
return GV;
|
||||
|
||||
for (const auto &F : *M)
|
||||
if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly))
|
||||
return;
|
||||
if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName,
|
||||
ExportedSymbolsOnly))
|
||||
return GV;
|
||||
}
|
||||
|
||||
MangledNames = std::move(Names);
|
||||
MangledSymbols = std::move(Symbols);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModuleSetT Ms;
|
||||
std::unique_ptr<RTDyldMemoryManager> MM;
|
||||
mutable std::unique_ptr<StringMap<bool>> MangledNames;
|
||||
mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
|
||||
};
|
||||
|
||||
typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;
|
||||
|
|
|
@ -51,10 +51,8 @@ protected:
|
|||
return RTDyld->loadObject(Obj);
|
||||
}
|
||||
|
||||
TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
|
||||
if (ExportedSymbolsOnly)
|
||||
return RTDyld->getExportedSymbolLoadAddress(Name);
|
||||
return RTDyld->getSymbolLoadAddress(Name);
|
||||
RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
|
||||
return RTDyld->getSymbol(Name);
|
||||
}
|
||||
|
||||
bool NeedsFinalization() const { return (State == Raw); }
|
||||
|
@ -214,28 +212,32 @@ public:
|
|||
/// given object set.
|
||||
JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
|
||||
if (!H->NeedsFinalization()) {
|
||||
// If this instance has already been finalized then we can just return
|
||||
// the address.
|
||||
return JITSymbol(Addr);
|
||||
} else {
|
||||
// If this instance needs finalization return a functor that will do it.
|
||||
// The functor still needs to double-check whether finalization is
|
||||
// required, in case someone else finalizes this set before the functor
|
||||
// is called.
|
||||
return JITSymbol(
|
||||
[this, Addr, H]() {
|
||||
if (H->NeedsFinalization()) {
|
||||
H->Finalize();
|
||||
if (NotifyFinalized)
|
||||
NotifyFinalized(H);
|
||||
}
|
||||
return Addr;
|
||||
});
|
||||
if (auto Sym = H->getSymbol(Name)) {
|
||||
if (Sym.isExported() || !ExportedSymbolsOnly) {
|
||||
auto Addr = Sym.getAddress();
|
||||
auto Flags = Sym.getFlags();
|
||||
if (!H->NeedsFinalization()) {
|
||||
// If this instance has already been finalized then we can just return
|
||||
// the address.
|
||||
return JITSymbol(Addr, Flags);
|
||||
} else {
|
||||
// If this instance needs finalization return a functor that will do
|
||||
// it. The functor still needs to double-check whether finalization is
|
||||
// required, in case someone else finalizes this set before the
|
||||
// functor is called.
|
||||
auto GetAddress =
|
||||
[this, Addr, H]() {
|
||||
if (H->NeedsFinalization()) {
|
||||
H->Finalize();
|
||||
if (NotifyFinalized)
|
||||
NotifyFinalized(H);
|
||||
}
|
||||
return Addr;
|
||||
};
|
||||
return JITSymbol(std::move(GetAddress), Flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
|
||||
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
|
||||
|
||||
#include "JITSymbolFlags.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/Support/Memory.h"
|
||||
|
@ -28,7 +29,7 @@ namespace object {
|
|||
|
||||
class RuntimeDyldImpl;
|
||||
class RuntimeDyldCheckerImpl;
|
||||
|
||||
|
||||
class RuntimeDyld {
|
||||
friend class RuntimeDyldCheckerImpl;
|
||||
|
||||
|
@ -47,6 +48,18 @@ protected:
|
|||
void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
|
||||
public:
|
||||
|
||||
/// \brief Information about a named symbol.
|
||||
class SymbolInfo : public JITSymbolBase {
|
||||
public:
|
||||
SymbolInfo(std::nullptr_t) : JITSymbolBase(JITSymbolFlags::None), Address(0) {}
|
||||
SymbolInfo(uint64_t Address, JITSymbolFlags Flags)
|
||||
: JITSymbolBase(Flags), Address(Address) {}
|
||||
explicit operator bool() const { return Address != 0; }
|
||||
uint64_t getAddress() const { return Address; }
|
||||
private:
|
||||
uint64_t Address;
|
||||
};
|
||||
|
||||
/// \brief Information about the loaded object.
|
||||
class LoadedObjectInfo {
|
||||
friend class RuntimeDyldImpl;
|
||||
|
@ -79,15 +92,11 @@ public:
|
|||
/// Get the address of our local copy of the symbol. This may or may not
|
||||
/// be the address used for relocation (clients can copy the data around
|
||||
/// and resolve relocatons based on where they put it).
|
||||
void *getSymbolAddress(StringRef Name) const;
|
||||
void *getSymbolLocalAddress(StringRef Name) const;
|
||||
|
||||
/// Get the address of the target copy of the symbol (works for both exported
|
||||
/// and non-exported symbols). This is the address used for relocation.
|
||||
uint64_t getSymbolLoadAddress(StringRef Name) const;
|
||||
|
||||
/// Get the address of the target copy of the symbol (works for exported
|
||||
/// symbols only). This is the address used for relocation.
|
||||
uint64_t getExportedSymbolLoadAddress(StringRef Name) const;
|
||||
/// Get the target address and flags for the named symbol.
|
||||
/// This address is the one used for relocation.
|
||||
SymbolInfo getSymbol(StringRef Name) const;
|
||||
|
||||
/// Resolve the relocations for all symbols we currently know about.
|
||||
void resolveRelocations();
|
||||
|
|
|
@ -86,12 +86,12 @@ public:
|
|||
/// \brief Returns the address of the requested section (or an error message
|
||||
/// in the second element of the pair if the address cannot be found).
|
||||
///
|
||||
/// if 'LinkerAddress' is true, this returns the address of the section
|
||||
/// within the linker's memory. If 'LinkerAddress' is false it returns the
|
||||
/// if 'LocalAddress' is true, this returns the address of the section
|
||||
/// within the linker's memory. If 'LocalAddress' is false it returns the
|
||||
/// address within the target process (i.e. the load address).
|
||||
std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
|
||||
StringRef SectionName,
|
||||
bool LinkerAddress);
|
||||
bool LocalAddress);
|
||||
|
||||
private:
|
||||
std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
|
||||
|
|
|
@ -257,7 +257,7 @@ uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
|
|||
Mangler Mang(TM->getDataLayout());
|
||||
SmallString<128> FullName;
|
||||
Mang.getNameWithPrefix(FullName, Name);
|
||||
return Dyld.getSymbolLoadAddress(FullName);
|
||||
return Dyld.getSymbol(FullName).getAddress();
|
||||
}
|
||||
|
||||
Module *MCJIT::findModuleForSymbol(const std::string &Name,
|
||||
|
@ -383,7 +383,7 @@ void *MCJIT::getPointerToFunction(Function *F) {
|
|||
//
|
||||
// This is the accessor for the target address, so make sure to check the
|
||||
// load address of the symbol, not the local address.
|
||||
return (void*)Dyld.getSymbolLoadAddress(Name);
|
||||
return (void*)Dyld.getSymbol(Name).getAddress();
|
||||
}
|
||||
|
||||
void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
|
||||
|
|
|
@ -197,10 +197,13 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
|
|||
<< " SID: " << SectionID << " Offset: "
|
||||
<< format("%p", (uintptr_t)SectOffset)
|
||||
<< " flags: " << Flags << "\n");
|
||||
SymbolInfo::Visibility Vis =
|
||||
(Flags & SymbolRef::SF_Exported) ?
|
||||
SymbolInfo::Default : SymbolInfo::Hidden;
|
||||
GlobalSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
|
||||
JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
|
||||
if (Flags & SymbolRef::SF_Weak)
|
||||
RTDyldSymFlags |= JITSymbolFlags::Weak;
|
||||
if (Flags & SymbolRef::SF_Exported)
|
||||
RTDyldSymFlags |= JITSymbolFlags::Exported;
|
||||
GlobalSymbolTable[Name] =
|
||||
SymbolTableEntry(SectionID, SectOffset, RTDyldSymFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -525,12 +528,15 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
|
|||
Offset += AlignOffset;
|
||||
}
|
||||
uint32_t Flags = Sym.getFlags();
|
||||
SymbolInfo::Visibility Vis =
|
||||
(Flags & SymbolRef::SF_Exported) ?
|
||||
SymbolInfo::Default : SymbolInfo::Hidden;
|
||||
JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
|
||||
if (Flags & SymbolRef::SF_Weak)
|
||||
RTDyldSymFlags |= JITSymbolFlags::Weak;
|
||||
if (Flags & SymbolRef::SF_Exported)
|
||||
RTDyldSymFlags |= JITSymbolFlags::Exported;
|
||||
DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
|
||||
<< format("%p", Addr) << "\n");
|
||||
GlobalSymbolTable[Name] = SymbolInfo(SectionID, Offset, Vis);
|
||||
GlobalSymbolTable[Name] =
|
||||
SymbolTableEntry(SectionID, Offset, RTDyldSymFlags);
|
||||
Offset += Size;
|
||||
Addr += Size;
|
||||
}
|
||||
|
@ -894,22 +900,16 @@ RuntimeDyld::loadObject(const ObjectFile &Obj) {
|
|||
return Dyld->loadObject(Obj);
|
||||
}
|
||||
|
||||
void *RuntimeDyld::getSymbolAddress(StringRef Name) const {
|
||||
void *RuntimeDyld::getSymbolLocalAddress(StringRef Name) const {
|
||||
if (!Dyld)
|
||||
return nullptr;
|
||||
return Dyld->getSymbolAddress(Name);
|
||||
return Dyld->getSymbolLocalAddress(Name);
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) const {
|
||||
RuntimeDyld::SymbolInfo RuntimeDyld::getSymbol(StringRef Name) const {
|
||||
if (!Dyld)
|
||||
return 0;
|
||||
return Dyld->getSymbolLoadAddress(Name);
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyld::getExportedSymbolLoadAddress(StringRef Name) const {
|
||||
if (!Dyld)
|
||||
return 0;
|
||||
return Dyld->getExportedSymbolLoadAddress(Name);
|
||||
return nullptr;
|
||||
return Dyld->getSymbol(Name);
|
||||
}
|
||||
|
||||
void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); }
|
||||
|
|
|
@ -310,7 +310,7 @@ private:
|
|||
"");
|
||||
|
||||
uint64_t SymbolAddr = PCtx.IsInsideLoad
|
||||
? Checker.getSymbolLinkerAddr(Symbol)
|
||||
? Checker.getSymbolLocalAddr(Symbol)
|
||||
: Checker.getSymbolRemoteAddr(Symbol);
|
||||
uint64_t NextPC = SymbolAddr + InstSize;
|
||||
|
||||
|
@ -437,7 +437,7 @@ private:
|
|||
// The value for the symbol depends on the context we're evaluating in:
|
||||
// Inside a load this is the address in the linker's memory, outside a
|
||||
// load it's the address in the target processes memory.
|
||||
uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLinkerAddr(Symbol)
|
||||
uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
|
||||
: Checker.getSymbolRemoteAddr(Symbol);
|
||||
|
||||
// Looks like a plain symbol reference.
|
||||
|
@ -727,17 +727,17 @@ bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
|
|||
}
|
||||
|
||||
bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
|
||||
return getRTDyld().getSymbolAddress(Symbol) != nullptr;
|
||||
return getRTDyld().getSymbolLocalAddress(Symbol) != nullptr;
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyldCheckerImpl::getSymbolLinkerAddr(StringRef Symbol) const {
|
||||
uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
|
||||
return static_cast<uint64_t>(
|
||||
reinterpret_cast<uintptr_t>(getRTDyld().getSymbolAddress(Symbol)));
|
||||
reinterpret_cast<uintptr_t>(getRTDyld().getSymbolLocalAddress(Symbol)));
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
|
||||
if (uint64_t InternalSymbolAddr = getRTDyld().getSymbolLoadAddress(Symbol))
|
||||
return InternalSymbolAddr;
|
||||
if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
|
||||
return InternalSymbol.getAddress();
|
||||
return getRTDyld().MemMgr->getSymbolAddress(Symbol);
|
||||
}
|
||||
|
||||
|
@ -929,6 +929,6 @@ bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix,
|
|||
|
||||
std::pair<uint64_t, std::string>
|
||||
RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
|
||||
bool LinkerAddress) {
|
||||
return Impl->getSectionAddr(FileName, SectionName, LinkerAddress);
|
||||
bool LocalAddress) {
|
||||
return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ private:
|
|||
RuntimeDyldImpl &getRTDyld() const { return *RTDyld.Dyld; }
|
||||
|
||||
bool isSymbolValid(StringRef Symbol) const;
|
||||
uint64_t getSymbolLinkerAddr(StringRef Symbol) const;
|
||||
uint64_t getSymbolLocalAddr(StringRef Symbol) const;
|
||||
uint64_t getSymbolRemoteAddr(StringRef Symbol) const;
|
||||
uint64_t readMemoryAtAddr(uint64_t Addr, unsigned Size) const;
|
||||
|
||||
|
|
|
@ -164,27 +164,24 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// @brief Symbol info for RuntimeDyld.
|
||||
class SymbolInfo {
|
||||
/// @brief Symbol info for RuntimeDyld.
|
||||
class SymbolTableEntry : public JITSymbolBase {
|
||||
public:
|
||||
typedef enum { Hidden = 0, Default = 1 } Visibility;
|
||||
SymbolTableEntry()
|
||||
: JITSymbolBase(JITSymbolFlags::None), Offset(0), SectionID(0) {}
|
||||
|
||||
SymbolInfo() : Offset(0), SectionID(0), Vis(Hidden) {}
|
||||
|
||||
SymbolInfo(unsigned SectionID, uint64_t Offset, Visibility Vis)
|
||||
: Offset(Offset), SectionID(SectionID), Vis(Vis) {}
|
||||
SymbolTableEntry(unsigned SectionID, uint64_t Offset, JITSymbolFlags Flags)
|
||||
: JITSymbolBase(Flags), Offset(Offset), SectionID(SectionID) {}
|
||||
|
||||
unsigned getSectionID() const { return SectionID; }
|
||||
uint64_t getOffset() const { return Offset; }
|
||||
Visibility getVisibility() const { return Vis; }
|
||||
|
||||
private:
|
||||
uint64_t Offset;
|
||||
unsigned SectionID : 31;
|
||||
Visibility Vis : 1;
|
||||
unsigned SectionID;
|
||||
};
|
||||
|
||||
typedef StringMap<SymbolInfo> RTDyldSymbolTable;
|
||||
typedef StringMap<SymbolTableEntry> RTDyldSymbolTable;
|
||||
|
||||
class RuntimeDyldImpl {
|
||||
friend class RuntimeDyld::LoadedObjectInfo;
|
||||
|
@ -394,7 +391,7 @@ public:
|
|||
virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
|
||||
loadObject(const object::ObjectFile &Obj) = 0;
|
||||
|
||||
uint8_t* getSymbolAddress(StringRef Name) const {
|
||||
uint8_t* getSymbolLocalAddress(StringRef Name) const {
|
||||
// FIXME: Just look up as a function for now. Overly simple of course.
|
||||
// Work in progress.
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
|
@ -404,24 +401,16 @@ public:
|
|||
return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
}
|
||||
|
||||
uint64_t getSymbolLoadAddress(StringRef Name) const {
|
||||
RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
|
||||
// FIXME: Just look up as a function for now. Overly simple of course.
|
||||
// Work in progress.
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
if (pos == GlobalSymbolTable.end())
|
||||
return 0;
|
||||
const auto &SymInfo = pos->second;
|
||||
return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
}
|
||||
|
||||
uint64_t getExportedSymbolLoadAddress(StringRef Name) const {
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
if (pos == GlobalSymbolTable.end())
|
||||
return 0;
|
||||
const auto &SymInfo = pos->second;
|
||||
if (SymInfo.getVisibility() == SymbolInfo::Hidden)
|
||||
return 0;
|
||||
return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
return nullptr;
|
||||
const auto &SymEntry = pos->second;
|
||||
uint64_t TargetAddr =
|
||||
getSectionLoadAddress(SymEntry.getSectionID()) + SymEntry.getOffset();
|
||||
return RuntimeDyld::SymbolInfo(TargetAddr, SymEntry.getFlags());
|
||||
}
|
||||
|
||||
void resolveRelocations();
|
||||
|
|
|
@ -298,7 +298,7 @@ static int executeInput() {
|
|||
// FIXME: Error out if there are unresolved relocations.
|
||||
|
||||
// Get the address of the entry point (_main by default).
|
||||
void *MainAddress = Dyld.getSymbolAddress(EntryPoint);
|
||||
void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint);
|
||||
if (!MainAddress)
|
||||
return Error("no definition for '" + EntryPoint + "'");
|
||||
|
||||
|
|
Loading…
Reference in New Issue