13#if LLVM_VERSION_CODE < LLVM_VERSION(8, 0)
14#include "llvm/IR/CallSite.h"
16#include "llvm/IR/Constants.h"
17#include "llvm/IR/DerivedTypes.h"
18#include "llvm/IR/IRBuilder.h"
19#include "llvm/IR/Instructions.h"
20#include "llvm/IR/LLVMContext.h"
21#include "llvm/IR/Module.h"
22#include "llvm/ExecutionEngine/GenericValue.h"
23#include "llvm/ExecutionEngine/MCJIT.h"
24#include "llvm/Support/DynamicLibrary.h"
25#include "llvm/Support/raw_ostream.h"
26#include "llvm/Support/TargetSelect.h"
49 typedef std::map<const llvm::Instruction *, llvm::Function *>
dispatchers_ty;
52 llvm::Module *module);
65 bool executeCall(llvm::Function *function, llvm::Instruction *i,
76 static uint64_t counter = 0;
77 std::string underlyingString;
78 llvm::raw_string_ostream ss(underlyingString);
79 ss <<
"ExternalDispatcherModule_" << counter;
88 const char *str = name.c_str();
98 void *addr = sys::DynamicLibrary::SearchForAddressOfSymbol(str);
104 if (name[0] == 1 && str[0] ==
'_') {
106 addr = sys::DynamicLibrary::SearchForAddressOfSymbol(str);
113 : ctx(ctx), lastErrno(0) {
123 .setEngineKind(EngineKind::JIT)
127 llvm::errs() <<
"unable to make jit: " << error <<
"\n";
133 llvm::InitializeNativeTarget();
134 llvm::InitializeNativeTargetAsmParser();
135 llvm::InitializeNativeTargetAsmPrinter();
141 sys::DynamicLibrary::LoadLibraryPermanently(0);
168 Function *dispatcher;
170 std::map<std::string, void *>::iterator it2 =
182 Module *dispatchModule = NULL;
196 auto dispatchModuleUniq = std::unique_ptr<Module>(dispatchModule);
198 std::move(dispatchModuleUniq));
203 assert(fnAddr &&
"failed to get function address");
207 delete dispatchModule;
215 struct sigaction segvAction, segvActionOld;
221 std::vector<GenericValue> gvArgs;
224 segvAction.sa_handler =
nullptr;
225 sigemptyset(&(segvAction.sa_mask));
226 sigaddset(&(segvAction.sa_mask), SIGSEGV);
227 segvAction.sa_flags = SA_SIGINFO;
229 sigaction(SIGSEGV, &segvAction, &segvActionOld);
241 sigaction(SIGSEGV, &segvActionOld,
nullptr);
261#if LLVM_VERSION_CODE >= LLVM_VERSION(8, 0)
262 const CallBase &cs = cast<CallBase>(*inst);
264 const CallSite cs(inst->getOpcode() == Instruction::Call
265 ? CallSite(cast<CallInst>(inst))
266 : CallSite(cast<InvokeInst>(inst)));
269 Value **args =
new Value *[cs.arg_size()];
271 std::vector<Type *> nullary;
277 "dispatcher_" + target->getName().str() + module->getModuleIdentifier();
278 Function *dispatcher =
279 Function::Create(FunctionType::get(Type::getVoidTy(
ctx), nullary,
false),
280 GlobalVariable::ExternalLinkage, fnName, module);
282 BasicBlock *dBB = BasicBlock::Create(
ctx,
"entry", dispatcher);
284 llvm::IRBuilder<> Builder(dBB);
286 auto argI64sp = Builder.CreateIntToPtr(
287 ConstantInt::get(Type::getInt64Ty(
ctx), (uintptr_t)(
void *)&
gTheArgsP),
288 PointerType::getUnqual(PointerType::getUnqual(Type::getInt64Ty(
ctx))),
290 auto argI64s = Builder.CreateLoad(
291 argI64sp->getType()->getPointerElementType(), argI64sp,
"args");
294 FunctionType *FTy = cast<FunctionType>(
295 cast<PointerType>(target->getType())->getElementType());
298 unsigned i = 0, idx = 2;
299 for (
auto ai = cs.arg_begin(), ae = cs.arg_end(); ai != ae; ++ai, ++i) {
304 (i < FTy->getNumParams() ? FTy->getParamType(i) : (*ai)->getType());
307 if (argTy->isX86_FP80Ty() && idx & 0x01)
311 Builder.CreateGEP(argI64s->getType()->getPointerElementType(), argI64s,
312 ConstantInt::get(Type::getInt32Ty(
ctx), idx));
314 auto argp = Builder.CreateBitCast(argI64p, PointerType::getUnqual(argTy));
316 Builder.CreateLoad(argp->getType()->getPointerElementType(), argp);
318 unsigned argSize = argTy->getPrimitiveSizeInBits();
319 idx += ((!!argSize ? argSize : 64) + 63) / 64;
322 auto dispatchTarget = module->getOrInsertFunction(target->getName(), FTy,
323 target->getAttributes());
324 auto result = Builder.CreateCall(dispatchTarget,
325 llvm::ArrayRef<Value *>(args, args + i));
326 if (result->getType() != Type::getVoidTy(
ctx)) {
327 auto resp = Builder.CreateBitCast(
328 argI64s, PointerType::getUnqual(result->getType()));
329 Builder.CreateStore(result, resp);
332 Builder.CreateRetVoid();
350 llvm::Instruction *i, uint64_t *args) {
static void sigsegv_handler(int signal, siginfo_t *info, void *context)
static sigjmp_buf escapeCallJmpBuf
bool runProtectedCall(llvm::Function *f, uint64_t *args)
bool executeCall(llvm::Function *function, llvm::Instruction *i, uint64_t *args)
std::vector< std::string > moduleIDs
ExternalDispatcherImpl(llvm::LLVMContext &ctx)
void * resolveSymbol(const std::string &name)
std::map< std::string, void * > preboundFunctions
dispatchers_ty dispatchers
llvm::ExecutionEngine * executionEngine
std::string & getFreshModuleID()
void setLastErrno(int newErrno)
std::map< const llvm::Instruction *, llvm::Function * > dispatchers_ty
llvm::Function * createDispatcher(llvm::Function *f, llvm::Instruction *i, llvm::Module *module)
llvm::Module * singleDispatchModule
~ExternalDispatcherImpl()
void * resolveSymbol(const std::string &name)
bool executeCall(llvm::Function *function, llvm::Instruction *i, uint64_t *args)
void setLastErrno(int newErrno)
ExternalDispatcher(llvm::LLVMContext &ctx)
ExternalDispatcherImpl * impl
static uint64_t * gTheArgsP