Example #1
0
static void llvm_init(){
    ExecutionEngine *ee = tcg_llvm_ctx->getExecutionEngine();
    FunctionPassManager *fpm = tcg_llvm_ctx->getFunctionPassManager();
    Module *mod = tcg_llvm_ctx->getModule();
    LLVMContext &ctx = mod->getContext();

    // Link logging function in with JIT
    Function *logFunc;
    std::vector<Type*> argTypes;
    // DynValBuffer*
    argTypes.push_back(IntegerType::get(ctx, 8*sizeof(uintptr_t)));
    // DynValEntryType
    argTypes.push_back(IntegerType::get(ctx, 8*sizeof(DynValEntryType)));
    // LogOp
    argTypes.push_back(IntegerType::get(ctx, 8*sizeof(LogOp)));
    // Dynamic value
    argTypes.push_back(IntegerType::get(ctx, 8*sizeof(uintptr_t)));
    logFunc = Function::Create(
            FunctionType::get(Type::getVoidTy(ctx), argTypes, false),
            Function::ExternalLinkage, "log_dynval", mod);
    logFunc->addFnAttr(Attribute::AlwaysInline);
    ee->addGlobalMapping(logFunc, (void*) &log_dynval);
    
    // Create instrumentation pass and add to function pass manager
    llvm::FunctionPass *instfp = createPandaInstrFunctionPass(mod);
    fpm->add(instfp);
    PIFP = static_cast<PandaInstrFunctionPass*>(instfp);
}
int main()
{
    // Module Construction
    LLVMContext &context = llvm::getGlobalContext();
    Module *module = new Module("test", context);

    //declare 'value' and 'foo' in module 'test'
    GlobalVariable *v = cast<GlobalVariable>(module->getOrInsertGlobal("value", Type::getInt32Ty(context)));
    // prototype of foo is: int foo(int x)
    Function *f = cast<Function>(module->getOrInsertFunction("foo", Type::getInt32Ty(context),
                                   Type::getInt32Ty(context), NULL));

    //create a LLVM function 'bar'
    Function* bar = cast<Function>(module->getOrInsertFunction("bar", Type::getInt32Ty(context),NULL));

    //basic block construction
    BasicBlock* entry = BasicBlock::Create(context, "entry", bar);
    IRBuilder<> builder(entry);

    //read 'value'
    Value * v_IR = builder.CreateLoad(v);
    //call foo(value)
    Value * ret = builder.CreateCall(f, v_IR);
    //return return value of 'foo'
    builder.CreateRet(ret);

    //now bind global value and global function
    //create execution engine first
    InitializeNativeTarget();
    ExecutionEngine *ee = EngineBuilder(module).setEngineKind(EngineKind::JIT).create();

    //map global variable
    ee->addGlobalMapping(v, &value);

    //map global function
    ee->addGlobalMapping(f, (void *)foo);

    // JIT and run
    void *barAddr = ee->getPointerToFunction(bar);
    typedef int (*FuncType)();
    FuncType barFunc = (FuncType)barAddr;

    std::cout << barFunc() << std::endl;
    return 0;
}
Example #3
0
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(&reg);

    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;
}
Example #4
0
int main() {
    InitializeNativeTarget();
    LLVMContext& Context = getGlobalContext();
    Module *M = new Module("test C++ exception handling ", Context);


    StructType* MyStructType = StructType::create(Context, "struct.MyStruct");
    Type* MyStructFields[] = {
        Type::getInt32Ty(Context),
        Type::getInt32Ty(Context)
    };
    MyStructType->setBody(MyStructFields);

    GlobalValue* throwFunc = cast<GlobalValue>(M->getOrInsertFunction("throwMyStruct", Type::getVoidTy(Context), NULL));
    GlobalValue* MyStructTypeInfo = cast<GlobalValue>(M->getOrInsertGlobal("MyStructTypeInfo", Type::getInt8Ty(Context)));

    Function* gxx_personality = Function::Create(FunctionType::get(Type::getInt32Ty(Context), true), Function::ExternalLinkage, "__gxx_personality_v0", M);
    Function* begin_catch     = Function::Create(FunctionType::get(Type::getInt8PtrTy(Context), Type::getInt8PtrTy(Context), false), Function::ExternalLinkage, "__cxa_begin_catch", M);
    Function* end_catch       = Function::Create(FunctionType::get(Type::getVoidTy(Context), false), Function::ExternalLinkage, "__cxa_end_catch", M);

    Function* testExceptions = cast<Function>(M->getOrInsertFunction("testExceptions", Type::getInt32Ty(Context), NULL));

    BasicBlock* entryBB   = BasicBlock::Create(Context, "", testExceptions);
    BasicBlock* landPadBB = BasicBlock::Create(Context, "landPad", testExceptions);
    BasicBlock* noErrorBB = BasicBlock::Create(Context, "noError", testExceptions);


    IRBuilder<> builder(entryBB);

    Value* invokeThrow = builder.CreateInvoke(throwFunc, noErrorBB, landPadBB);

    builder.SetInsertPoint(noErrorBB);
    builder.CreateRet( builder.getInt32(666) ); // should never happen

    //writing landingpad! <<<<<<<

    builder.SetInsertPoint(landPadBB);

    Value* gxx_personality_i8 = builder.CreateBitCast(gxx_personality, Type::getInt8PtrTy(Context));
    Type* caughtType = StructType::get(builder.getInt8PtrTy(), builder.getInt32Ty(), NULL);

    LandingPadInst* caughtResult = builder.CreateLandingPad(caughtType, gxx_personality_i8, 1);

    // we can catch any C++ exception we want
    // but now we are catching MyStruct
    caughtResult->addClause(MyStructTypeInfo);

    //we are sure to catch MyStruct so no other checks are needed
    //if throwMyStruct() throws anything but MyStruct it won't pass to the current landingpad BB

    Value* thrownExctn  = builder.CreateExtractValue(caughtResult, 0);
    Value* thrownObject = builder.CreateCall(begin_catch, thrownExctn);
    Value* object       = builder.CreateBitCast(thrownObject, MyStructType->getPointerTo());
    Value* resultPtr    = builder.CreateStructGEP(object, 1);
    Value* result       = builder.CreateLoad(resultPtr);

    builder.CreateCall(end_catch);

    builder.CreateRet( result ); // << z.y

    TargetOptions Opts;
    Opts.JITExceptionHandling = true; // DO NOT FORGET THIS OPTION !!!!!!11


    ExecutionEngine* EE = EngineBuilder(M)
                        .setEngineKind(EngineKind::JIT)
                        .setTargetOptions(Opts)
                        .create();

    EE->addGlobalMapping(throwFunc, reinterpret_cast<void*>(&throwMyStruct));
    EE->addGlobalMapping(MyStructTypeInfo, MyStruct::getTypeInfo());

    verifyFunction(*testExceptions);
    outs() << *testExceptions;

    std::vector<GenericValue> noArgs;
    GenericValue gv = EE->runFunction(testExceptions, noArgs);

    outs() << "\ntestExceptions result: " << gv.IntVal << "\n";

    delete EE;
    llvm_shutdown();
    return 0;
}