// new module. Create one that resolves symbols by looking back into the JIT.
auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
[&](const std::string &S) {
- return getMangledSymbolAddress(S);
- },
+ return findMangledSymbol(S).getAddress();
+ },
[](const std::string &S) { return 0; } );
return CompileLayer.addModuleSet(std::move(S), std::move(MM));
void removeModule(ModuleHandleT H) { CompileLayer.removeModuleSet(H); }
- uint64_t getMangledSymbolAddress(const std::string &Name) {
- return CompileLayer.getSymbolAddress(Name, false);
+ JITSymbol findMangledSymbol(const std::string &Name) {
+ return CompileLayer.findSymbol(Name, false);
}
- uint64_t getSymbolAddress(const std::string Name) {
+ JITSymbol findSymbol(const std::string Name) {
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
Mang.getNameWithPrefix(MangledNameStream, Name);
}
- return getMangledSymbolAddress(MangledName);
+ return findMangledSymbol(MangledName);
}
private:
auto H = J.addModule(C.takeM());
// Get the address of the JIT'd function in memory.
- uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr");
+ auto ExprSymbol = J.findSymbol("__anon_expr");
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr;
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
#ifdef MINIMAL_STDERR_OUTPUT
FP();
#else
// new module. Create one that resolves symbols by looking back into the JIT.
auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
[&](const std::string &S) {
- return getMangledSymbolAddress(S);
- },
+ return findMangledSymbol(S).getAddress();
+ },
[](const std::string &S) { return 0; } );
return LazyEmitLayer.addModuleSet(std::move(S), std::move(MM));
void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
- uint64_t getMangledSymbolAddress(const std::string &Name) {
- return LazyEmitLayer.getSymbolAddress(Name, false);
+ JITSymbol findMangledSymbol(const std::string &Name) {
+ return LazyEmitLayer.findSymbol(Name, false);
}
- uint64_t getSymbolAddress(const std::string Name) {
+ JITSymbol findSymbol(const std::string Name) {
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
Mang.getNameWithPrefix(MangledNameStream, Name);
}
- return getMangledSymbolAddress(MangledName);
+ return findMangledSymbol(MangledName);
}
private:
auto H = J.addModule(C.takeM());
// Get the address of the JIT'd function in memory.
- uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr");
+ auto ExprSymbol = J.findSymbol("__anon_expr");
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr;
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
#ifdef MINIMAL_STDERR_OUTPUT
FP();
#else
auto MM = createLookasideRTDyldMM<SectionMemoryManager>(
[&](const std::string &Name) -> uint64_t {
// First try to find 'Name' within the JIT.
- if (uint64_t Addr = getMangledSymbolAddress(Name))
- return Addr;
+ if (auto Symbol = findMangledSymbol(Name))
+ return Symbol.getAddress();
// If we don't find 'Name' in the JIT, see if we have some AST
// for it.
// finished with it.
Session.FunctionDefs.erase(DefI);
- return getMangledSymbolAddress(Name);
- },
+ return findMangledSymbol(Name).getAddress();
+ },
[](const std::string &S) { return 0; } );
return LazyEmitLayer.addModuleSet(std::move(S), std::move(MM));
void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
- uint64_t getMangledSymbolAddress(const std::string &Name) {
- return LazyEmitLayer.getSymbolAddress(Name, false);
+ JITSymbol findMangledSymbol(const std::string &Name) {
+ return LazyEmitLayer.findSymbol(Name, false);
}
- uint64_t getSymbolAddress(const std::string &Name) {
- return getMangledSymbolAddress(Mangle(Name));
+ JITSymbol findSymbol(const std::string &Name) {
+ return findMangledSymbol(Mangle(Name));
}
private:
auto H = J.addModule(C.takeM());
// Get the address of the JIT'd function in memory.
- uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr");
+ auto ExprSymbol = J.findSymbol("__anon_expr");
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr;
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
#ifdef MINIMAL_STDERR_OUTPUT
FP();
#else
void removeLogicalModule(LMHandle LMH) { Handles.erase(LMH); }
/// @brief Look up a symbol in this context.
- uint64_t lookup(LMHandle LMH, const std::string &Name) {
- if (uint64_t Addr = lookupOnlyIn(LMH, Name))
- return Addr;
+ JITSymbol findSymbol(LMHandle LMH, const std::string &Name) {
+ if (auto Symbol = findSymbolIn(LMH, Name))
+ return Symbol;
for (auto I = Handles.begin(), E = Handles.end(); I != E; ++I)
if (I != LMH)
- if (uint64_t Addr = lookupOnlyIn(I, Name))
- return Addr;
+ if (auto Symbol = findSymbolIn(I, Name))
+ return Symbol;
- return 0;
+ return nullptr;
}
private:
- uint64_t lookupOnlyIn(LMHandle LMH, const std::string &Name) {
+
+ JITSymbol findSymbolIn(LMHandle LMH, const std::string &Name) {
for (auto H : *LMH)
- if (uint64_t Addr = BaseLayer.lookupSymbolAddressIn(H, Name, false))
- return Addr;
- return 0;
+ if (auto Symbol = BaseLayer.findSymbolIn(H, Name, false))
+ return Symbol;
+ return nullptr;
}
BaseLayerT &BaseLayer;
MSI.JITResolveCallbackHandlers.push_back(
createCallbackHandlerFromJITIndirections(
Indirections, MSI.PersistentManglers.back(),
- [=](StringRef S) { return DylibLookup->lookup(LMH, S); }));
+ [=](StringRef S) {
+ return DylibLookup->findSymbol(LMH, S).getAddress();
+ }));
// Insert callback asm code into the first module.
InsertCallbackAsm(*ExplodedModules[0],
std::move(MSet),
createLookasideRTDyldMM<SectionMemoryManager>(
[=](const std::string &Name) {
- if (uint64_t Addr = DylibLookup->lookup(LMH, Name))
- return Addr;
- return getSymbolAddress(Name, true);
+ if (auto Symbol = DylibLookup->findSymbol(LMH, Name))
+ return Symbol.getAddress();
+ return findSymbol(Name, true).getAddress();
},
[=](const std::string &Name) {
- return DylibLookup->lookup(LMH, Name);
+ return DylibLookup->findSymbol(LMH, Name).getAddress();
}));
DylibLookup->addToLogicalModule(LMH, H);
MSI.BaseLayerModuleSetHandles.push_back(H);
initializeFuncAddrs(*MSI.JITResolveCallbackHandlers.back(), Indirections,
MSI.PersistentManglers.back(), [=](StringRef S) {
- return DylibLookup->lookup(LMH, S);
+ return DylibLookup->findSymbol(LMH, S).getAddress();
});
}
ModuleSetInfos.erase(H);
}
- /// @brief Get the address of a symbol provided by this layer, or some layer
- /// below this one.
- uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
- return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly);
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Get the address of a symbol provided by this layer, or some layer
/// below this one.
- uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
BaseLayerModuleSetHandleListT &BaseLayerHandles = H->second;
for (auto &BH : BaseLayerHandles) {
- if (uint64_t Addr =
- BaseLayer.lookupSymbolAddressIn(BH, Name, ExportedSymbolsOnly))
- return Addr;
+ if (auto Symbol = BaseLayer.findSymbolIn(BH, Name, ExportedSymbolsOnly))
+ return Symbol;
}
- return 0;
+ return nullptr;
}
private:
#ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
#define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
+#include "JITSymbol.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Object/ObjectFile.h"
/// @brief Remove the module set associated with the handle H.
void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
- /// @brief Get the address of a loaded symbol. This call is forwarded to the
- /// base layer's getSymbolAddress implementation.
- uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
- return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly);
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Get the address of the given symbol in the context of the set of
/// compiled modules represented by the handle H. This call is
/// forwarded to the base layer's implementation.
- uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
- return BaseLayer.lookupSymbolAddressIn(H, Name, ExportedSymbolsOnly);
+ /// @param H The handle for the module set to search in.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it is found in the
+ /// given module set.
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
private:
#ifndef LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
+#include "JITSymbol.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include <sstream>
///
/// This is expected to be called by code in the JIT process itself, in
/// order to resolve a function.
- virtual uint64_t resolve(StubIndex StubIdx) = 0;
+ virtual TargetAddress resolve(StubIndex StubIdx) = 0;
private:
FuncNameList FuncNames;
JITResolveCallbackHandlerImpl(LookupFtor Lookup, UpdateFtor Update)
: Lookup(std::move(Lookup)), Update(std::move(Update)) {}
- uint64_t resolve(StubIndex StubIdx) override {
+ TargetAddress resolve(StubIndex StubIdx) override {
const std::string &FuncName = getFuncName(StubIdx);
- uint64_t Addr = Lookup(FuncName);
+ TargetAddress Addr = Lookup(FuncName);
Update(FuncName, Addr);
return Addr;
}
[=](const std::string &S) {
return Lookup(NM.getMangledName(GetImplName(S)));
},
- [=](const std::string &S, uint64_t Addr) {
+ [=](const std::string &S, TargetAddress Addr) {
void *ImplPtr = reinterpret_cast<void *>(
Lookup(NM.getMangledName(GetAddrName(S))));
- memcpy(ImplPtr, &Addr, sizeof(uint64_t));
+ memcpy(ImplPtr, &Addr, sizeof(TargetAddress));
});
for (const auto &FuncName : Indirs.IndirectedNames)
// Now update indirects to point to the JIT resolve callback asm.
for (JITResolveCallbackHandler::StubIndex I = 0; I < J.getNumFuncs(); ++I) {
- uint64_t ResolveCallbackIdxAddr =
+ TargetAddress ResolveCallbackIdxAddr =
Lookup(getJITResolveCallbackIndexLabel(I));
void *AddrPtr = reinterpret_cast<void *>(
Lookup(NM.getMangledName(Indirs.GetAddrName(J.getFuncName(I)))));
assert(AddrPtr && "Can't find stub addr global to initialize.");
- memcpy(AddrPtr, &ResolveCallbackIdxAddr, sizeof(uint64_t));
+ memcpy(AddrPtr, &ResolveCallbackIdxAddr, sizeof(TargetAddress));
}
}
--- /dev/null
+//===----------- JITSymbol.h - JIT symbol abstraction -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Abstraction for target process addresses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
+#define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
+
+#include <functional>
+
+namespace llvm {
+
+/// @brief Represents an address in the target process's address space.
+typedef uint64_t TargetAddress;
+
+/// @brief Represents a symbol in the JIT.
+class JITSymbol {
+public:
+ typedef std::function<TargetAddress()> GetAddressFtor;
+
+ JITSymbol(std::nullptr_t) : CachedAddr(0) {}
+
+ JITSymbol(GetAddressFtor GetAddress)
+ : CachedAddr(0), GetAddress(std::move(GetAddress)) {}
+
+ /// @brief Returns true if the symbol exists, false otherwise.
+ explicit operator bool() const { return CachedAddr || GetAddress; }
+
+ /// @brief Get the address of the symbol in the target address space. Returns
+ /// '0' if the symbol does not exist.
+ TargetAddress getAddress() {
+ if (GetAddress) {
+ CachedAddr = GetAddress();
+ assert(CachedAddr && "Symbol could not be materialized.");
+ GetAddress = nullptr;
+ }
+ return CachedAddr;
+ }
+
+private:
+ TargetAddress CachedAddr;
+ GetAddressFtor GetAddress;
+};
+
+}
+
+#endif // LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
#ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
#define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
+#include "JITSymbol.h"
#include "LookasideRTDyldMM.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/IR/GlobalValue.h"
///
/// This layer accepts sets of LLVM IR Modules (via addModuleSet), but does
/// not immediately emit them the layer below. Instead, emissing to the base
-/// layer is deferred until some symbol in the module set is requested via
-/// getSymbolAddress.
+/// layer is deferred until the first time the client requests the address
+/// (via JITSymbol::getAddress) for a symbol contained in this layer.
template <typename BaseLayerT> class LazyEmittingLayer {
public:
typedef typename BaseLayerT::ModuleSetHandleT BaseLayerHandleT;
EmissionDeferredSet() : EmitState(NotEmitted) {}
virtual ~EmissionDeferredSet() {}
- uint64_t Search(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
+ JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
switch (EmitState) {
- case NotEmitted:
- if (Provides(Name, ExportedSymbolsOnly)) {
- EmitState = Emitting;
- Handle = Emit(B);
- EmitState = Emitted;
- } else
- return 0;
- break;
- case Emitting:
- // The module has been added to the base layer but we haven't gotten a
- // handle back yet so we can't use lookupSymbolAddressIn. Just return
- // '0' here - LazyEmittingLayer::getSymbolAddress will do a global
- // search in the base layer when it doesn't find the symbol here, so
- // we'll find it in the end.
- return 0;
- case Emitted:
- // Nothing to do. Go ahead and search the base layer.
- break;
+ case NotEmitted:
+ if (provides(Name, ExportedSymbolsOnly))
+ return JITSymbol(
+ [this,ExportedSymbolsOnly,Name,&B]() -> TargetAddress {
+ if (EmitState == Emitting)
+ return 0;
+ else if (EmitState != Emitted) {
+ EmitState = Emitting;
+ Handle = emit(B);
+ EmitState = Emitted;
+ }
+ return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly)
+ .getAddress();
+ });
+ else
+ return nullptr;
+ case Emitting:
+ // Calling "emit" can trigger external symbol lookup (e.g. to check for
+ // pre-existing definitions of common-symbol), but it will never find in
+ // this module that it would not have found already, so return null from
+ // here.
+ return nullptr;
+ case Emitted:
+ return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
}
-
- return B.lookupSymbolAddressIn(Handle, Name, ExportedSymbolsOnly);
+ llvm_unreachable("Invalid emit-state.");
}
- void RemoveModulesFromBaseLayer(BaseLayerT &BaseLayer) {
+ void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
if (EmitState != NotEmitted)
BaseLayer.removeModuleSet(Handle);
}
std::unique_ptr<RTDyldMemoryManager> MM);
protected:
- virtual bool Provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
- virtual BaseLayerHandleT Emit(BaseLayerT &BaseLayer) = 0;
+ virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
+ virtual BaseLayerHandleT emit(BaseLayerT &BaseLayer) = 0;
private:
enum { NotEmitted, Emitting, Emitted } EmitState;
: Ms(std::move(Ms)), MM(std::move(MM)) {}
protected:
- BaseLayerHandleT Emit(BaseLayerT &BaseLayer) override {
+ BaseLayerHandleT emit(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 {
+ bool provides(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.
LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
/// @brief Add the given set of modules to the lazy emitting layer.
- ///
- /// This method stores the set of modules in a side table, rather than
- /// immediately emitting them to the next layer of the JIT. When the address
- /// of a symbol provided by this set is requested (via getSymbolAddress) it
- /// triggers the emission of this set to the layer below (along with the given
- /// memory manager instance), and returns the address of the requested symbol.
template <typename ModuleSetT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
std::unique_ptr<RTDyldMemoryManager> MM) {
/// This method will free the memory associated with the given module set,
/// both in this layer, and the base layer.
void removeModuleSet(ModuleSetHandleT H) {
- (*H)->RemoveModulesFromBaseLayer(BaseLayer);
+ (*H)->removeModulesFromBaseLayer(BaseLayer);
ModuleSetList.erase(H);
}
- /// @brief Get the address of a symbol provided by this layer, or some layer
- /// below this one.
- ///
- /// When called for a symbol that has been added to this layer (via
- /// addModuleSet) but not yet emitted, this will trigger the emission of the
- /// module set containing the definiton of the symbol.
- uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
- // Look up symbol among existing definitions.
- if (uint64_t Addr = BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly))
- return Addr;
-
- // If not found then search the deferred sets. The call to 'Search' will
- // cause the set to be emitted to the next layer if it provides a definition
- // of 'Name'.
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
+ // Look for the symbol among existing definitions.
+ if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
+ return Symbol;
+
+ // If not found then search the deferred sets. If any of these contain a
+ // definition of 'Name' then they will return a JITSymbol that will emit
+ // the corresponding module when the symbol address is requested.
for (auto &DeferredSet : ModuleSetList)
- if (uint64_t Addr =
- DeferredSet->Search(Name, ExportedSymbolsOnly, BaseLayer))
- return Addr;
+ if (auto Symbol = DeferredSet->find(Name, ExportedSymbolsOnly, BaseLayer))
+ return Symbol;
- // If no definition found anywhere return 0.
- return 0;
+ // If no definition found anywhere return a null symbol.
+ return nullptr;
}
/// @brief Get the address of the given symbol in the context of the set of
- /// compiled modules represented by the handle H. This call is
- /// forwarded to the base layer's implementation.
- uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
- bool ExportedSymbolsOnly) {
- return (*H)->Search(Name, ExportedSymbolsOnly, BaseLayer);
+ /// compiled modules represented by the handle H.
+ JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
+ bool ExportedSymbolsOnly) {
+ return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer);
}
};
#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
+#include "JITSymbol.h"
#include "LookasideRTDyldMM.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
class ObjectLinkingLayerBase {
protected:
+
/// @brief Holds a set of objects to be allocated/linked as a unit in the JIT.
///
/// An instance of this class will be created for each set of objects added
return RTDyld->loadObject(Obj);
}
- uint64_t getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
+ TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
if (ExportedSymbolsOnly)
return RTDyld->getExportedSymbolLoadAddress(Name);
return RTDyld->getSymbolLoadAddress(Name);
State = Finalized;
}
- void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) {
+ void mapSectionAddress(const void *LocalAddress, TargetAddress TargetAddr) {
assert((State != Finalized) &&
"Attempting to remap sections for finalized objects.");
- RTDyld->mapSectionAddress(LocalAddress, TargetAddress);
+ RTDyld->mapSectionAddress(LocalAddress, TargetAddr);
}
void takeOwnershipOfBuffer(std::unique_ptr<MemoryBuffer> B) {
/// @brief Map section addresses for the objects associated with the handle H.
void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress,
- uint64_t TargetAddress) {
- H->mapSectionAddress(LocalAddress, TargetAddress);
+ TargetAddress TargetAddr) {
+ H->mapSectionAddress(LocalAddress, TargetAddr);
}
/// @brief Remove the set of objects associated with handle H.
LinkedObjSetList.erase(H);
}
- /// @brief Get the address of a loaded symbol.
- ///
- /// @return The address in the target process's address space of the named
- /// symbol. Null if no such symbol is known.
- ///
- /// This method will trigger the finalization of the linked object set
- /// containing the definition of the given symbol, if it is found.
- uint64_t getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
+ /// @brief Search for the given named symbol.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it exists.
+ JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
for (auto I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E;
++I)
- if (uint64_t Addr = lookupSymbolAddressIn(I, Name, ExportedSymbolsOnly))
- return Addr;
+ if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly))
+ return Symbol;
- return 0;
+ return nullptr;
}
- /// @brief Search for a given symbol in the context of the set of loaded
- /// objects represented by the handle H.
- ///
- /// @return The address in the target process's address space of the named
- /// symbol. Null if the given object set does not contain a definition
- /// of this symbol.
- ///
- /// This method will trigger the finalization of the linked object set
- /// represented by the handle H if that set contains the requested symbol.
- uint64_t lookupSymbolAddressIn(ObjSetHandleT H, StringRef Name,
- bool ExportedSymbolsOnly) {
- if (uint64_t Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
- if (H->NeedsFinalization()) {
- H->Finalize();
- if (NotifyFinalized)
- NotifyFinalized(H);
- }
- return Addr;
- }
- return 0;
+ /// @brief Search for the given named symbol in the context of the set of
+ /// loaded objects represented by the handle H.
+ /// @param H The handle for the object set to search in.
+ /// @param Name The name of the symbol to search for.
+ /// @param ExportedSymbolsOnly If true, search only for exported symbols.
+ /// @return A handle for the given named symbol, if it is found in the
+ /// given object set.
+ JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
+ bool ExportedSymbolsOnly) {
+ if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly))
+ return JITSymbol(
+ [this, Addr, H](){
+ if (H->NeedsFinalization()) {
+ H->Finalize();
+ if (NotifyFinalized)
+ NotifyFinalized(H);
+ }
+ return Addr;
+ });
+
+ return nullptr;
}
private:
private:
uint64_t getSymbolAddressWithoutMangling(StringRef Name) {
- if (uint64_t Addr = LazyEmitLayer.getSymbolAddress(Name, false))
+ if (uint64_t Addr = LazyEmitLayer.findSymbol(Name, false).getAddress())
return Addr;
if (uint64_t Addr = MM->getSymbolAddress(Name))
return Addr;
static_cast<object::ObjectFile *>(ChildBin.release())));
ObjectLayer.addObjectSet(
std::move(ObjSet), llvm::make_unique<ForwardingRTDyldMM>(*this));
- if (uint64_t Addr = ObjectLayer.getSymbolAddress(Name, true))
+ if (uint64_t Addr = ObjectLayer.findSymbol(Name, true).getAddress())
return Addr;
}
}