mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[ORC] Re-apply r322913 with a fix for a read-after-free error.
ExternalSymbolMap now stores the string key (rather than using a StringRef), as the object file backing the key may be removed at any time. llvm-svn: 323001
This commit is contained in:
parent
7df5ea8f7b
commit
b99825f8cb
@ -137,17 +137,15 @@ protected:
|
||||
virtual char *getMemoryForGV(const GlobalVariable *GV);
|
||||
|
||||
static ExecutionEngine *(*MCJITCtor)(
|
||||
std::unique_ptr<Module> M,
|
||||
std::string *ErrorStr,
|
||||
std::shared_ptr<MCJITMemoryManager> MM,
|
||||
std::shared_ptr<JITSymbolResolver> SR,
|
||||
std::unique_ptr<TargetMachine> TM);
|
||||
std::unique_ptr<Module> M, std::string *ErrorStr,
|
||||
std::shared_ptr<MCJITMemoryManager> MM,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> SR,
|
||||
std::unique_ptr<TargetMachine> TM);
|
||||
|
||||
static ExecutionEngine *(*OrcMCJITReplacementCtor)(
|
||||
std::string *ErrorStr,
|
||||
std::shared_ptr<MCJITMemoryManager> MM,
|
||||
std::shared_ptr<JITSymbolResolver> SR,
|
||||
std::unique_ptr<TargetMachine> TM);
|
||||
std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MM,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> SR,
|
||||
std::unique_ptr<TargetMachine> TM);
|
||||
|
||||
static ExecutionEngine *(*InterpCtor)(std::unique_ptr<Module> M,
|
||||
std::string *ErrorStr);
|
||||
@ -532,7 +530,7 @@ private:
|
||||
std::string *ErrorStr;
|
||||
CodeGenOpt::Level OptLevel;
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr;
|
||||
std::shared_ptr<JITSymbolResolver> Resolver;
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver;
|
||||
TargetOptions Options;
|
||||
Optional<Reloc::Model> RelocModel;
|
||||
Optional<CodeModel::Model> CMModel;
|
||||
@ -571,8 +569,7 @@ public:
|
||||
EngineBuilder&
|
||||
setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM);
|
||||
|
||||
EngineBuilder&
|
||||
setSymbolResolver(std::unique_ptr<JITSymbolResolver> SR);
|
||||
EngineBuilder &setSymbolResolver(std::unique_ptr<LegacyJITSymbolResolver> SR);
|
||||
|
||||
/// setErrorStr - Set the error string to write to on error. This option
|
||||
/// defaults to NULL.
|
||||
|
@ -19,8 +19,11 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -269,11 +272,50 @@ private:
|
||||
JITSymbolFlags Flags;
|
||||
};
|
||||
|
||||
/// \brief Symbol resolution.
|
||||
/// @brief Symbol resolution interface.
|
||||
///
|
||||
/// Allows symbol flags and addresses to be looked up by name.
|
||||
/// Symbol queries are done in bulk (i.e. you request resolution of a set of
|
||||
/// symbols, rather than a single one) to reduce IPC overhead in the case of
|
||||
/// remote JITing, and expose opportunities for parallel compilation.
|
||||
class JITSymbolResolver {
|
||||
public:
|
||||
using SymbolNameSet = std::set<StringRef>;
|
||||
using LookupResult = std::map<StringRef, JITEvaluatedSymbol>;
|
||||
using LookupFlagsResult = std::map<StringRef, JITSymbolFlags>;
|
||||
|
||||
virtual ~JITSymbolResolver() = default;
|
||||
|
||||
/// @brief Returns the fully resolved address and flags for each of the given
|
||||
/// symbols.
|
||||
///
|
||||
/// This method will return an error if any of the given symbols can not be
|
||||
/// resolved, or if the resolution process itself triggers an error.
|
||||
virtual Expected<LookupResult> lookup(const SymbolNameSet &Symbols) = 0;
|
||||
|
||||
/// @brief Returns the symbol flags for each of the given symbols.
|
||||
///
|
||||
/// This method does NOT return an error if any of the given symbols is
|
||||
/// missing. Instead, that symbol will be left out of the result map.
|
||||
virtual Expected<LookupFlagsResult>
|
||||
lookupFlags(const SymbolNameSet &Symbols) = 0;
|
||||
|
||||
private:
|
||||
virtual void anchor();
|
||||
};
|
||||
|
||||
/// \brief Legacy symbol resolution interface.
|
||||
class LegacyJITSymbolResolver : public JITSymbolResolver {
|
||||
public:
|
||||
/// @brief Performs lookup by, for each symbol, first calling
|
||||
/// findSymbolInLogicalDylib and if that fails calling
|
||||
/// findSymbol.
|
||||
Expected<LookupResult> lookup(const SymbolNameSet &Symbols) final;
|
||||
|
||||
/// @brief Performs flags lookup by calling findSymbolInLogicalDylib and
|
||||
/// returning the flags value for that symbol.
|
||||
Expected<LookupFlagsResult> lookupFlags(const SymbolNameSet &Symbols) final;
|
||||
|
||||
/// This method returns the address of the specified symbol if it exists
|
||||
/// within the logical dynamic library represented by this JITSymbolResolver.
|
||||
/// Unlike findSymbol, queries through this interface should return addresses
|
||||
|
@ -183,7 +183,7 @@ private:
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
std::shared_ptr<JITSymbolResolver> ExternalSymbolResolver;
|
||||
std::shared_ptr<LegacyJITSymbolResolver> ExternalSymbolResolver;
|
||||
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
|
||||
StaticGlobalRenamer StaticRenamer;
|
||||
SourceModulesList SourceModules;
|
||||
@ -223,7 +223,7 @@ public:
|
||||
/// @brief Add a module to the compile-on-demand layer.
|
||||
Expected<ModuleHandleT>
|
||||
addModule(std::shared_ptr<Module> M,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver) {
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
|
||||
|
||||
LogicalDylibs.push_back(LogicalDylib());
|
||||
auto &LD = LogicalDylibs.back();
|
||||
|
@ -23,7 +23,7 @@ namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
|
||||
class LambdaResolver : public JITSymbolResolver {
|
||||
class LambdaResolver : public LegacyJITSymbolResolver {
|
||||
public:
|
||||
LambdaResolver(DylibLookupFtorT DylibLookupFtor,
|
||||
ExternalLookupFtorT ExternalLookupFtor)
|
||||
|
@ -22,7 +22,7 @@ namespace orc {
|
||||
|
||||
/// SymbolResolver impliementation that rejects all resolution requests.
|
||||
/// Useful for clients that have no cross-object fixups.
|
||||
class NullResolver : public JITSymbolResolver {
|
||||
class NullResolver : public LegacyJITSymbolResolver {
|
||||
public:
|
||||
JITSymbol findSymbol(const std::string &Name) final;
|
||||
|
||||
|
@ -328,7 +328,8 @@ public:
|
||||
/// @return A handle that can be used to refer to the loaded object (for
|
||||
/// symbol searching, finalization, freeing memory, etc.).
|
||||
Expected<ObjHandleT>
|
||||
addObject(ObjectPtr Object, std::shared_ptr<JITSymbolResolver> Resolver) {
|
||||
addObject(ObjectPtr Object,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
|
||||
StringRef ObjBuffer = Object->getBinary()->getData();
|
||||
if (auto HandleOrErr =
|
||||
this->Remote.template callB<AddObject>(ObjBuffer)) {
|
||||
@ -386,7 +387,8 @@ private:
|
||||
}
|
||||
|
||||
std::map<remote::ResourceIdMgr::ResourceId,
|
||||
std::shared_ptr<JITSymbolResolver>> Resolvers;
|
||||
std::shared_ptr<LegacyJITSymbolResolver>>
|
||||
Resolvers;
|
||||
};
|
||||
|
||||
/// RemoteObjectServerLayer acts as a server and handling RPC calls for the
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
// FIXME: As the RuntimeDyld fills out, additional routines will be needed
|
||||
// for the varying types of objects to be allocated.
|
||||
class RTDyldMemoryManager : public MCJITMemoryManager,
|
||||
public JITSymbolResolver {
|
||||
public LegacyJITSymbolResolver {
|
||||
public:
|
||||
RTDyldMemoryManager() = default;
|
||||
RTDyldMemoryManager(const RTDyldMemoryManager&) = delete;
|
||||
|
@ -49,14 +49,13 @@ STATISTIC(NumGlobals , "Number of global vars initialized");
|
||||
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
|
||||
std::unique_ptr<Module> M, std::string *ErrorStr,
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
|
||||
std::shared_ptr<JITSymbolResolver> Resolver,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
|
||||
std::unique_ptr<TargetMachine> TM) = nullptr;
|
||||
|
||||
ExecutionEngine *(*ExecutionEngine::OrcMCJITReplacementCtor)(
|
||||
std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver,
|
||||
std::unique_ptr<TargetMachine> TM) = nullptr;
|
||||
std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
|
||||
std::unique_ptr<TargetMachine> TM) = nullptr;
|
||||
|
||||
ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
|
||||
std::string *ErrorStr) =nullptr;
|
||||
@ -502,9 +501,9 @@ EngineBuilder::setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
EngineBuilder&
|
||||
EngineBuilder::setSymbolResolver(std::unique_ptr<JITSymbolResolver> SR) {
|
||||
Resolver = std::shared_ptr<JITSymbolResolver>(std::move(SR));
|
||||
EngineBuilder &
|
||||
EngineBuilder::setSymbolResolver(std::unique_ptr<LegacyJITSymbolResolver> SR) {
|
||||
Resolver = std::shared_ptr<LegacyJITSymbolResolver>(std::move(SR));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,10 @@ static struct RegisterJIT {
|
||||
extern "C" void LLVMLinkInMCJIT() {
|
||||
}
|
||||
|
||||
ExecutionEngine*
|
||||
MCJIT::createJIT(std::unique_ptr<Module> M,
|
||||
std::string *ErrorStr,
|
||||
ExecutionEngine *
|
||||
MCJIT::createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
|
||||
std::unique_ptr<TargetMachine> TM) {
|
||||
// Try to register the program as a source of symbols to resolve against.
|
||||
//
|
||||
@ -64,7 +63,7 @@ MCJIT::createJIT(std::unique_ptr<Module> M,
|
||||
|
||||
MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM,
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver)
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver)
|
||||
: ExecutionEngine(TM->createDataLayout(), std::move(M)), TM(std::move(TM)),
|
||||
Ctx(nullptr), MemMgr(std::move(MemMgr)),
|
||||
Resolver(*this, std::move(Resolver)), Dyld(*this->MemMgr, this->Resolver),
|
||||
|
@ -26,11 +26,11 @@ class MCJIT;
|
||||
// functions across modules that it owns. It aggregates the memory manager
|
||||
// that is passed in to the MCJIT constructor and defers most functionality
|
||||
// to that object.
|
||||
class LinkingSymbolResolver : public JITSymbolResolver {
|
||||
class LinkingSymbolResolver : public LegacyJITSymbolResolver {
|
||||
public:
|
||||
LinkingSymbolResolver(MCJIT &Parent,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver)
|
||||
: ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver)
|
||||
: ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
|
||||
|
||||
JITSymbol findSymbol(const std::string &Name) override;
|
||||
|
||||
@ -41,7 +41,7 @@ public:
|
||||
|
||||
private:
|
||||
MCJIT &ParentEngine;
|
||||
std::shared_ptr<JITSymbolResolver> ClientResolver;
|
||||
std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
|
||||
};
|
||||
|
||||
// About Module states: added->loaded->finalized.
|
||||
@ -67,7 +67,7 @@ private:
|
||||
class MCJIT : public ExecutionEngine {
|
||||
MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver);
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver);
|
||||
|
||||
typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;
|
||||
|
||||
@ -300,11 +300,10 @@ public:
|
||||
MCJITCtor = createJIT;
|
||||
}
|
||||
|
||||
static ExecutionEngine*
|
||||
createJIT(std::unique_ptr<Module> M,
|
||||
std::string *ErrorStr,
|
||||
static ExecutionEngine *
|
||||
createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
|
||||
std::unique_ptr<TargetMachine> TM);
|
||||
|
||||
// @}
|
||||
|
@ -196,7 +196,7 @@ public:
|
||||
return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
|
||||
}
|
||||
|
||||
std::shared_ptr<JITSymbolResolver>
|
||||
std::shared_ptr<LegacyJITSymbolResolver>
|
||||
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return orc::createLambdaResolver(
|
||||
|
@ -138,7 +138,7 @@ class OrcMCJITReplacement : public ExecutionEngine {
|
||||
std::shared_ptr<MCJITMemoryManager> ClientMM;
|
||||
};
|
||||
|
||||
class LinkingResolver : public JITSymbolResolver {
|
||||
class LinkingResolver : public LegacyJITSymbolResolver {
|
||||
public:
|
||||
LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
|
||||
|
||||
@ -160,20 +160,19 @@ private:
|
||||
static ExecutionEngine *
|
||||
createOrcMCJITReplacement(std::string *ErrorMsg,
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
|
||||
std::unique_ptr<TargetMachine> TM) {
|
||||
return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
|
||||
std::move(TM));
|
||||
}
|
||||
|
||||
public:
|
||||
OrcMCJITReplacement(
|
||||
std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<JITSymbolResolver> ClientResolver,
|
||||
std::unique_ptr<TargetMachine> TM)
|
||||
OrcMCJITReplacement(std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> ClientResolver,
|
||||
std::unique_ptr<TargetMachine> TM)
|
||||
: ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
|
||||
MemMgr(std::make_shared<MCJITReplacementMemMgr>(*this,
|
||||
std::move(MemMgr))),
|
||||
MemMgr(
|
||||
std::make_shared<MCJITReplacementMemMgr>(*this, std::move(MemMgr))),
|
||||
Resolver(std::make_shared<LinkingResolver>(*this)),
|
||||
ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
|
||||
NotifyFinalized(*this),
|
||||
@ -378,7 +377,7 @@ private:
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
std::shared_ptr<MCJITReplacementMemMgr> MemMgr;
|
||||
std::shared_ptr<LinkingResolver> Resolver;
|
||||
std::shared_ptr<JITSymbolResolver> ClientResolver;
|
||||
std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
|
||||
Mangler Mang;
|
||||
|
||||
// IMPORTANT: ShouldDelete *must* come before LocalModules: The shared_ptr
|
||||
|
@ -47,3 +47,53 @@ ARMJITSymbolFlags llvm::ARMJITSymbolFlags::fromObjectSymbol(
|
||||
Flags |= ARMJITSymbolFlags::Thumb;
|
||||
return Flags;
|
||||
}
|
||||
|
||||
/// @brief Performs lookup by, for each symbol, first calling
|
||||
/// findSymbolInLogicalDylib and if that fails calling
|
||||
/// findSymbol.
|
||||
Expected<JITSymbolResolver::LookupResult>
|
||||
LegacyJITSymbolResolver::lookup(const SymbolNameSet &Symbols) {
|
||||
JITSymbolResolver::LookupResult Result;
|
||||
for (auto &Symbol : Symbols) {
|
||||
std::string SymName = Symbol.str();
|
||||
if (auto Sym = findSymbolInLogicalDylib(SymName)) {
|
||||
if (auto AddrOrErr = Sym.getAddress())
|
||||
Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
|
||||
else
|
||||
return AddrOrErr.takeError();
|
||||
} else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
else {
|
||||
// findSymbolInLogicalDylib failed. Lets try findSymbol.
|
||||
if (auto Sym = findSymbol(SymName)) {
|
||||
if (auto AddrOrErr = Sym.getAddress())
|
||||
Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
|
||||
else
|
||||
return AddrOrErr.takeError();
|
||||
} else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
else
|
||||
return make_error<StringError>("Symbol not found: " + Symbol,
|
||||
inconvertibleErrorCode());
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(Result);
|
||||
}
|
||||
|
||||
/// @brief Performs flags lookup by calling findSymbolInLogicalDylib and
|
||||
/// returning the flags value for that symbol.
|
||||
Expected<JITSymbolResolver::LookupFlagsResult>
|
||||
LegacyJITSymbolResolver::lookupFlags(const SymbolNameSet &Symbols) {
|
||||
JITSymbolResolver::LookupFlagsResult Result;
|
||||
|
||||
for (auto &Symbol : Symbols) {
|
||||
std::string SymName = Symbol.str();
|
||||
if (auto Sym = findSymbolInLogicalDylib(SymName))
|
||||
Result[Symbol] = Sym.getFlags();
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
}
|
||||
|
||||
return std::move(Result);
|
||||
}
|
||||
|
@ -202,7 +202,33 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
|
||||
ObjSectionToIDMap LocalSections;
|
||||
|
||||
// Common symbols requiring allocation, with their sizes and alignments
|
||||
CommonSymbolList CommonSymbols;
|
||||
CommonSymbolList CommonSymbolsToAllocate;
|
||||
|
||||
uint64_t CommonSize = 0;
|
||||
uint32_t CommonAlign = 0;
|
||||
|
||||
// First, collect all weak and common symbols. We need to know if stronger
|
||||
// definitions occur elsewhere.
|
||||
JITSymbolResolver::LookupFlagsResult SymbolFlags;
|
||||
{
|
||||
JITSymbolResolver::SymbolNameSet Symbols;
|
||||
for (auto &Sym : Obj.symbols()) {
|
||||
uint32_t Flags = Sym.getFlags();
|
||||
if ((Flags & SymbolRef::SF_Common) || (Flags & SymbolRef::SF_Weak)) {
|
||||
// Get symbol name.
|
||||
StringRef Name;
|
||||
if (auto NameOrErr = Sym.getName())
|
||||
Symbols.insert(*NameOrErr);
|
||||
else
|
||||
return NameOrErr.takeError();
|
||||
}
|
||||
}
|
||||
|
||||
if (auto FlagsResultOrErr = Resolver.lookupFlags(Symbols))
|
||||
SymbolFlags = std::move(*FlagsResultOrErr);
|
||||
else
|
||||
return FlagsResultOrErr.takeError();
|
||||
}
|
||||
|
||||
// Parse symbols
|
||||
DEBUG(dbgs() << "Parse symbols:\n");
|
||||
@ -214,102 +240,108 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
|
||||
if (Flags & SymbolRef::SF_Undefined)
|
||||
continue;
|
||||
|
||||
if (Flags & SymbolRef::SF_Common)
|
||||
CommonSymbols.push_back(*I);
|
||||
else {
|
||||
// Get the symbol type.
|
||||
object::SymbolRef::Type SymType;
|
||||
if (auto SymTypeOrErr = I->getType())
|
||||
SymType = *SymTypeOrErr;
|
||||
else
|
||||
return SymTypeOrErr.takeError();
|
||||
|
||||
// Get the symbol type.
|
||||
object::SymbolRef::Type SymType;
|
||||
if (auto SymTypeOrErr = I->getType())
|
||||
SymType = *SymTypeOrErr;
|
||||
// Get symbol name.
|
||||
StringRef Name;
|
||||
if (auto NameOrErr = I->getName())
|
||||
Name = *NameOrErr;
|
||||
else
|
||||
return NameOrErr.takeError();
|
||||
|
||||
// Compute JIT symbol flags.
|
||||
JITSymbolFlags JITSymFlags = getJITSymbolFlags(*I);
|
||||
|
||||
// If this is a weak definition, check to see if there's a strong one.
|
||||
// If there is, skip this symbol (we won't be providing it: the strong
|
||||
// definition will). If there's no strong definition, make this definition
|
||||
// strong.
|
||||
if (JITSymFlags.isWeak() || JITSymFlags.isCommon()) {
|
||||
// First check whether there's already a definition in this instance.
|
||||
// FIXME: Override existing weak definitions with strong ones.
|
||||
if (GlobalSymbolTable.count(Name))
|
||||
continue;
|
||||
|
||||
// Then check whether we found flags for an existing symbol during the
|
||||
// flags lookup earlier.
|
||||
auto FlagsI = SymbolFlags.find(Name);
|
||||
if (FlagsI == SymbolFlags.end() ||
|
||||
(JITSymFlags.isWeak() && !FlagsI->second.isStrong()) ||
|
||||
(JITSymFlags.isCommon() && FlagsI->second.isCommon())) {
|
||||
if (JITSymFlags.isWeak())
|
||||
JITSymFlags &= ~JITSymbolFlags::Weak;
|
||||
if (JITSymFlags.isCommon()) {
|
||||
JITSymFlags &= ~JITSymbolFlags::Common;
|
||||
uint32_t Align = I->getAlignment();
|
||||
uint64_t Size = I->getCommonSize();
|
||||
if (!CommonAlign)
|
||||
CommonAlign = Align;
|
||||
CommonSize += alignTo(CommonSize, Align) + Size;
|
||||
CommonSymbolsToAllocate.push_back(*I);
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Flags & SymbolRef::SF_Absolute &&
|
||||
SymType != object::SymbolRef::ST_File) {
|
||||
uint64_t Addr = 0;
|
||||
if (auto AddrOrErr = I->getAddress())
|
||||
Addr = *AddrOrErr;
|
||||
else
|
||||
return SymTypeOrErr.takeError();
|
||||
return AddrOrErr.takeError();
|
||||
|
||||
// Get symbol name.
|
||||
StringRef Name;
|
||||
if (auto NameOrErr = I->getName())
|
||||
Name = *NameOrErr;
|
||||
unsigned SectionID = AbsoluteSymbolSection;
|
||||
|
||||
DEBUG(dbgs() << "\tType: " << SymType << " (absolute) Name: " << Name
|
||||
<< " SID: " << SectionID
|
||||
<< " Offset: " << format("%p", (uintptr_t)Addr)
|
||||
<< " flags: " << Flags << "\n");
|
||||
GlobalSymbolTable[Name] = SymbolTableEntry(SectionID, Addr, JITSymFlags);
|
||||
} else if (SymType == object::SymbolRef::ST_Function ||
|
||||
SymType == object::SymbolRef::ST_Data ||
|
||||
SymType == object::SymbolRef::ST_Unknown ||
|
||||
SymType == object::SymbolRef::ST_Other) {
|
||||
|
||||
section_iterator SI = Obj.section_end();
|
||||
if (auto SIOrErr = I->getSection())
|
||||
SI = *SIOrErr;
|
||||
else
|
||||
return NameOrErr.takeError();
|
||||
return SIOrErr.takeError();
|
||||
|
||||
// Compute JIT symbol flags.
|
||||
JITSymbolFlags JITSymFlags = getJITSymbolFlags(*I);
|
||||
if (SI == Obj.section_end())
|
||||
continue;
|
||||
|
||||
// If this is a weak definition, check to see if there's a strong one.
|
||||
// If there is, skip this symbol (we won't be providing it: the strong
|
||||
// definition will). If there's no strong definition, make this definition
|
||||
// strong.
|
||||
if (JITSymFlags.isWeak()) {
|
||||
// First check whether there's already a definition in this instance.
|
||||
// FIXME: Override existing weak definitions with strong ones.
|
||||
if (GlobalSymbolTable.count(Name))
|
||||
continue;
|
||||
// Then check the symbol resolver to see if there's a definition
|
||||
// elsewhere in this logical dylib.
|
||||
if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) {
|
||||
if (Sym.getFlags().isStrong())
|
||||
continue;
|
||||
} else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
// else
|
||||
JITSymFlags &= ~JITSymbolFlags::Weak;
|
||||
}
|
||||
// Get symbol offset.
|
||||
uint64_t SectOffset;
|
||||
if (auto Err = getOffset(*I, *SI, SectOffset))
|
||||
return std::move(Err);
|
||||
|
||||
if (Flags & SymbolRef::SF_Absolute &&
|
||||
SymType != object::SymbolRef::ST_File) {
|
||||
uint64_t Addr = 0;
|
||||
if (auto AddrOrErr = I->getAddress())
|
||||
Addr = *AddrOrErr;
|
||||
else
|
||||
return AddrOrErr.takeError();
|
||||
bool IsCode = SI->isText();
|
||||
unsigned SectionID;
|
||||
if (auto SectionIDOrErr =
|
||||
findOrEmitSection(Obj, *SI, IsCode, LocalSections))
|
||||
SectionID = *SectionIDOrErr;
|
||||
else
|
||||
return SectionIDOrErr.takeError();
|
||||
|
||||
unsigned SectionID = AbsoluteSymbolSection;
|
||||
|
||||
DEBUG(dbgs() << "\tType: " << SymType << " (absolute) Name: " << Name
|
||||
<< " SID: " << SectionID << " Offset: "
|
||||
<< format("%p", (uintptr_t)Addr)
|
||||
<< " flags: " << Flags << "\n");
|
||||
GlobalSymbolTable[Name] =
|
||||
SymbolTableEntry(SectionID, Addr, JITSymFlags);
|
||||
} else if (SymType == object::SymbolRef::ST_Function ||
|
||||
SymType == object::SymbolRef::ST_Data ||
|
||||
SymType == object::SymbolRef::ST_Unknown ||
|
||||
SymType == object::SymbolRef::ST_Other) {
|
||||
|
||||
section_iterator SI = Obj.section_end();
|
||||
if (auto SIOrErr = I->getSection())
|
||||
SI = *SIOrErr;
|
||||
else
|
||||
return SIOrErr.takeError();
|
||||
|
||||
if (SI == Obj.section_end())
|
||||
continue;
|
||||
|
||||
// Get symbol offset.
|
||||
uint64_t SectOffset;
|
||||
if (auto Err = getOffset(*I, *SI, SectOffset))
|
||||
return std::move(Err);
|
||||
|
||||
bool IsCode = SI->isText();
|
||||
unsigned SectionID;
|
||||
if (auto SectionIDOrErr = findOrEmitSection(Obj, *SI, IsCode,
|
||||
LocalSections))
|
||||
SectionID = *SectionIDOrErr;
|
||||
else
|
||||
return SectionIDOrErr.takeError();
|
||||
|
||||
DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name
|
||||
<< " SID: " << SectionID << " Offset: "
|
||||
<< format("%p", (uintptr_t)SectOffset)
|
||||
<< " flags: " << Flags << "\n");
|
||||
GlobalSymbolTable[Name] =
|
||||
DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name
|
||||
<< " SID: " << SectionID
|
||||
<< " Offset: " << format("%p", (uintptr_t)SectOffset)
|
||||
<< " flags: " << Flags << "\n");
|
||||
GlobalSymbolTable[Name] =
|
||||
SymbolTableEntry(SectionID, SectOffset, JITSymFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate common symbols
|
||||
if (auto Err = emitCommonSymbols(Obj, CommonSymbols))
|
||||
if (auto Err = emitCommonSymbols(Obj, CommonSymbolsToAllocate, CommonSize,
|
||||
CommonAlign))
|
||||
return std::move(Err);
|
||||
|
||||
// Parse and process relocations
|
||||
@ -621,45 +653,12 @@ JITSymbolFlags RuntimeDyldImpl::getJITSymbolFlags(const BasicSymbolRef &SR) {
|
||||
}
|
||||
|
||||
Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
|
||||
CommonSymbolList &CommonSymbols) {
|
||||
if (CommonSymbols.empty())
|
||||
CommonSymbolList &SymbolsToAllocate,
|
||||
uint64_t CommonSize,
|
||||
uint32_t CommonAlign) {
|
||||
if (SymbolsToAllocate.empty())
|
||||
return Error::success();
|
||||
|
||||
uint64_t CommonSize = 0;
|
||||
uint32_t CommonAlign = CommonSymbols.begin()->getAlignment();
|
||||
CommonSymbolList SymbolsToAllocate;
|
||||
|
||||
DEBUG(dbgs() << "Processing common symbols...\n");
|
||||
|
||||
for (const auto &Sym : CommonSymbols) {
|
||||
StringRef Name;
|
||||
if (auto NameOrErr = Sym.getName())
|
||||
Name = *NameOrErr;
|
||||
else
|
||||
return NameOrErr.takeError();
|
||||
|
||||
// Skip common symbols already elsewhere.
|
||||
if (GlobalSymbolTable.count(Name)) {
|
||||
DEBUG(dbgs() << "\tSkipping already emitted common symbol '" << Name
|
||||
<< "'\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) {
|
||||
if (!Sym.getFlags().isCommon()) {
|
||||
DEBUG(dbgs() << "\tSkipping common symbol '" << Name
|
||||
<< "' in favor of stronger definition.\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
uint32_t Align = Sym.getAlignment();
|
||||
uint64_t Size = Sym.getCommonSize();
|
||||
|
||||
CommonSize = alignTo(CommonSize, Align) + Size;
|
||||
|
||||
SymbolsToAllocate.push_back(Sym);
|
||||
}
|
||||
|
||||
// Allocate memory for the section
|
||||
unsigned SectionID = Sections.size();
|
||||
uint8_t *Addr = MemMgr.allocateDataSection(CommonSize, CommonAlign, SectionID,
|
||||
@ -997,7 +996,40 @@ void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
|
||||
}
|
||||
|
||||
Error RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
StringMap<JITEvaluatedSymbol> ExternalSymbolMap;
|
||||
|
||||
// Resolution can trigger emission of more symbols, so iterate until
|
||||
// we've resolved *everything*.
|
||||
{
|
||||
JITSymbolResolver::SymbolNameSet ResolvedSymbols;
|
||||
|
||||
while (true) {
|
||||
JITSymbolResolver::SymbolNameSet NewSymbols;
|
||||
|
||||
for (auto &RelocKV : ExternalSymbolRelocations) {
|
||||
StringRef Name = RelocKV.first();
|
||||
if (!Name.empty() && !GlobalSymbolTable.count(Name) &&
|
||||
!ResolvedSymbols.count(Name))
|
||||
NewSymbols.insert(Name);
|
||||
}
|
||||
|
||||
if (NewSymbols.empty())
|
||||
break;
|
||||
|
||||
auto NewResolverResults = Resolver.lookup(NewSymbols);
|
||||
if (!NewResolverResults)
|
||||
return NewResolverResults.takeError();
|
||||
|
||||
for (auto &RRKV : *NewResolverResults) {
|
||||
assert(!ResolvedSymbols.count(RRKV.first) && "Redundant resolution?");
|
||||
ExternalSymbolMap.insert(RRKV);
|
||||
ResolvedSymbols.insert(RRKV.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!ExternalSymbolRelocations.empty()) {
|
||||
|
||||
StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin();
|
||||
|
||||
StringRef Name = i->first();
|
||||
@ -1012,29 +1044,10 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
JITSymbolFlags Flags;
|
||||
RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(Name);
|
||||
if (Loc == GlobalSymbolTable.end()) {
|
||||
// This is an external symbol, try to get its address from the symbol
|
||||
// resolver.
|
||||
// First search for the symbol in this logical dylib.
|
||||
if (auto Sym = Resolver.findSymbolInLogicalDylib(Name.data())) {
|
||||
if (auto AddrOrErr = Sym.getAddress()) {
|
||||
Addr = *AddrOrErr;
|
||||
Flags = Sym.getFlags();
|
||||
} else
|
||||
return AddrOrErr.takeError();
|
||||
} else if (auto Err = Sym.takeError())
|
||||
return Err;
|
||||
|
||||
// If that fails, try searching for an external symbol.
|
||||
if (!Addr) {
|
||||
if (auto Sym = Resolver.findSymbol(Name.data())) {
|
||||
if (auto AddrOrErr = Sym.getAddress()) {
|
||||
Addr = *AddrOrErr;
|
||||
Flags = Sym.getFlags();
|
||||
} else
|
||||
return AddrOrErr.takeError();
|
||||
} else if (auto Err = Sym.takeError())
|
||||
return Err;
|
||||
}
|
||||
auto RRI = ExternalSymbolMap.find(Name);
|
||||
assert(RRI != ExternalSymbolMap.end() && "No result for symbol");
|
||||
Addr = RRI->second.getAddress();
|
||||
Flags = RRI->second.getFlags();
|
||||
// The call to getSymbolAddress may have caused additional modules to
|
||||
// be loaded, which may have added new entries to the
|
||||
// ExternalSymbolRelocations map. Consquently, we need to update our
|
||||
@ -1095,6 +1108,7 @@ uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress(
|
||||
|
||||
void RuntimeDyld::MemoryManager::anchor() {}
|
||||
void JITSymbolResolver::anchor() {}
|
||||
void LegacyJITSymbolResolver::anchor() {}
|
||||
|
||||
RuntimeDyld::RuntimeDyld(RuntimeDyld::MemoryManager &MemMgr,
|
||||
JITSymbolResolver &Resolver)
|
||||
|
@ -731,7 +731,14 @@ bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
|
||||
bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
|
||||
if (getRTDyld().getSymbol(Symbol))
|
||||
return true;
|
||||
return !!getRTDyld().Resolver.findSymbol(Symbol);
|
||||
JITSymbolResolver::SymbolNameSet Symbols({Symbol});
|
||||
auto Result = getRTDyld().Resolver.lookup(Symbols);
|
||||
if (!Result) {
|
||||
logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
|
||||
return false;
|
||||
}
|
||||
assert(Result->count(Symbol) && "Missing symbol result");
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
|
||||
@ -742,7 +749,16 @@ uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
|
||||
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
|
||||
if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
|
||||
return InternalSymbol.getAddress();
|
||||
return cantFail(getRTDyld().Resolver.findSymbol(Symbol).getAddress());
|
||||
|
||||
JITSymbolResolver::SymbolNameSet Symbols({Symbol});
|
||||
auto Result = getRTDyld().Resolver.lookup(Symbols);
|
||||
if (!Result) {
|
||||
logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
|
||||
return 0;
|
||||
}
|
||||
auto I = Result->find(Symbol);
|
||||
assert(I != Result->end() && "Missing symbol result");
|
||||
return I->second.getAddress();
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
|
||||
|
@ -385,7 +385,8 @@ protected:
|
||||
/// new section for them and update the symbol mappings in the object and
|
||||
/// symbol table.
|
||||
Error emitCommonSymbols(const ObjectFile &Obj,
|
||||
CommonSymbolList &CommonSymbols);
|
||||
CommonSymbolList &CommonSymbols, uint64_t CommonSize,
|
||||
uint32_t CommonAlign);
|
||||
|
||||
/// \brief Emits section data from the object file to the MemoryManager.
|
||||
/// \param IsCode if it's true then allocateCodeSection() will be
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
this->MemMgr = std::move(MemMgr);
|
||||
}
|
||||
|
||||
void setResolver(std::shared_ptr<JITSymbolResolver> Resolver) {
|
||||
void setResolver(std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
|
||||
this->Resolver = std::move(Resolver);
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ public:
|
||||
|
||||
private:
|
||||
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr;
|
||||
std::shared_ptr<JITSymbolResolver> Resolver;
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver;
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user