int main() { LLVMInitializeNativeTarget(); LLVMInitializeNativeAsmPrinter(); LLVMInitializeNativeAsmParser(); LLVMContext &Context = getGlobalContext(); IRBuilder<> Builder(Context); std::unique_ptr<Module> Owner = make_unique<Module>("simple_module", Context); Module *M = Owner.get(); Function *F = Function::Create(TypeBuilder<int32_t(void), false>::get(Context), GlobalValue::ExternalLinkage, "scramble", M); BasicBlock *BB = BasicBlock::Create(Context, "entry", F); Builder.SetInsertPoint(BB); Builder.CreateRet(ConstantInt::get(Context, APInt(32, 24))); F = Function::Create(TypeBuilder<int32_t(void), false>::get(Context), GlobalValue::ExternalLinkage, "ooo1", M); BB = BasicBlock::Create(Context, "entry", F); Builder.SetInsertPoint(BB); Builder.CreateRet(ConstantInt::get(Context, APInt(32, 42))); M->dump(); ExecutionEngine *EE = EngineBuilder(std::move(Owner)).create(); assert(EE != NULL && "error creating MCJIT with EngineBuilder"); union { uint64_t raw; int (*usable)(); } functionPointer; functionPointer.raw = EE->getFunctionAddress("ooo1"); std::cout << functionPointer.usable() << std::endl; return 0; }
void LoadPlugin(const std::string& path, const std::string& name, MetaScriptRunner* msr) { SMDiagnostic error; std::unique_ptr<Module> Owner = parseIRFile(path, error, context); if(Owner == nullptr) { cout << "Load Error: " << path << endl; Owner->dump(); return; } initEE(std::move(Owner)); string func_name = name + "_elite_plugin_init"; uint64_t func_addr = EE->getFunctionAddress(func_name.c_str()); if (func_addr == 0) { printf("错误, 找不到函数: %s\n", func_name.c_str()); return; } func_type func = (func_type) func_addr; func(msr->getCodeGenContext()); }
int main() { ygt_print("Hello!\n"); InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); InitializeNativeTargetDisassembler(); ygt_print("Creating LLVM context and module...\n"); LLVMContext ctx; auto m = make_unique<Module>("the_module", ctx); ygt_print("Creating StackMapHelper...\n"); StackMapHelper smhelper; ygt_print("Declaring yg_stack_swap as an LLVM-level function...\n"); declare_ss(ctx, *m); ygt_print("Constructing bar, the ss leaf...\n"); Function *bar; smid_t bar_smid; tie(bar, bar_smid) = make_ss_leaf("barss", &main_stack, &coro_stack, smhelper, ctx, *m); verifyFunction(*bar); ygt_print("Constructing foo, the caller...\n"); Function *foo; smid_t foo_smid; tie(foo, foo_smid) = make_caller("foo", bar, smhelper, ctx, *m); verifyFunction(*foo); m->dump(); Function *ss_func = m->getFunction("yg_stack_swap"); ygt_print("Creating execution engine...\n"); ExecutionEngine *ee = EngineBuilder(move(m)).setEngineKind(EngineKind::JIT).create(); ygt_print("Execution engine created.\n"); StackMapSectionRecorder smsr; ygt_print("Registering JIT event listener...\n"); ee->RegisterJITEventListener(&smsr); EHFrameSectionRegisterer reg; ygt_print("Registering EHFrame registerer...\n"); ee->RegisterJITEventListener(®); ygt_print("Adding global mapping yg_stack_swap...\n"); ee->addGlobalMapping(ss_func, reinterpret_cast<void*>(yg_stack_swap)); ygt_print("JIT compiling...\n"); ee->finalizeObject(); ygt_print("Adding stack map sections...\n"); smhelper.add_stackmap_sections(smsr, *ee); ygt_print("Registering EH frames...\n"); reg.registerEHFrameSections(); uintptr_t yg_stack_swap_addr = ee->getFunctionAddress("yg_stack_swap"); ygt_print("yg_stack_swap_addr=%" PRIxPTR ", yg_stack_swap=%p\n", yg_stack_swap_addr, yg_stack_swap); assert(yg_stack_swap_addr == reinterpret_cast<uintptr_t>(yg_stack_swap)); ygt_print("Getting foo...\n"); void (*the_real_foo)(int32_t, int64_t, float, double) = (void(*)(int32_t, int64_t, float, double)) ee->getFunctionAddress("foo"); ygt_print("the_real_foo == %p\n", the_real_foo); ygt_print("Prepare corotine for introspection...\n"); coro_stack = YGStack::alloc(8*1024*1024); coro_stack.init(reinterpret_cast<uintptr_t>(coro)); MyCtx my_ctx = { foo_smid, bar_smid, &smhelper }; ygt_print("Swap-stack to prepare the coroutine...\n"); yg_stack_swap(&main_stack, &coro_stack, reinterpret_cast<uintptr_t>(&my_ctx)); ygt_print("Back from coro.\n"); ygt_print("Calling the_real_foo...\n"); the_real_foo(100, 200, 300.0f, 400.0); ygt_print("Returned from foo.\n"); return 0; }