#ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
#include "JITSymbol.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include <vector>
namespace llvm {
class ConstantArray;
class GlobalVariable;
class Function;
class Module;
class Value;
namespace orc {
class CtorDtorIterator {
public:
struct Element {
Element(unsigned Priority, const Function *Func, const Value *Data)
: Priority(Priority), Func(Func), Data(Data) {}
unsigned Priority;
const Function *Func;
const Value *Data;
};
CtorDtorIterator(const GlobalVariable *GV, bool End);
bool operator==(const CtorDtorIterator &Other) const;
bool operator!=(const CtorDtorIterator &Other) const;
CtorDtorIterator& operator++();
CtorDtorIterator operator++(int);
Element operator*() const;
private:
const ConstantArray *InitList;
unsigned I;
};
iterator_range<CtorDtorIterator> getConstructors(const Module &M);
iterator_range<CtorDtorIterator> getDestructors(const Module &M);
template <typename JITLayerT>
class CtorDtorRunner {
public:
CtorDtorRunner(std::vector<std::string> CtorDtorNames,
typename JITLayerT::ModuleSetHandleT H)
: CtorDtorNames(std::move(CtorDtorNames)), H(H) {}
bool runViaLayer(JITLayerT &JITLayer) const {
typedef void (*CtorDtorTy)();
bool Error = false;
for (const auto &CtorDtorName : CtorDtorNames)
if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
CtorDtorTy CtorDtor =
reinterpret_cast<CtorDtorTy>(
static_cast<uintptr_t>(CtorDtorSym.getAddress()));
CtorDtor();
} else
Error = true;
return !Error;
}
private:
std::vector<std::string> CtorDtorNames;
typename JITLayerT::ModuleSetHandleT H;
};
class LocalCXXRuntimeOverrides {
public:
template <typename MangleFtorT>
LocalCXXRuntimeOverrides(const MangleFtorT &Mangle) {
addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride));
addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride));
}
RuntimeDyld::SymbolInfo searchOverrides(const std::string &Name) {
auto I = CXXRuntimeOverrides.find(Name);
if (I != CXXRuntimeOverrides.end())
return RuntimeDyld::SymbolInfo(I->second, JITSymbolFlags::Exported);
return nullptr;
}
void runDestructors();
private:
template <typename PtrTy>
TargetAddress toTargetAddress(PtrTy* P) {
return static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(P));
}
void addOverride(const std::string &Name, TargetAddress Addr) {
CXXRuntimeOverrides.insert(std::make_pair(Name, Addr));
}
StringMap<TargetAddress> CXXRuntimeOverrides;
typedef void (*DestructorPtr)(void*);
typedef std::pair<DestructorPtr, void*> CXXDestructorDataPair;
typedef std::vector<CXXDestructorDataPair> CXXDestructorDataPairList;
CXXDestructorDataPairList DSOHandleOverride;
static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
void *DSOHandle);
};
} }
#endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H