void doPrintModule(NativeModulePtr m) { string pathBase = "./"; list<NativeFunctionPtr> mod_funcs = m->get_funcs(); list<NativeFunctionPtr>::iterator it = mod_funcs.begin(); for(; it != mod_funcs.end(); ++it) { NativeFunctionPtr f = *it; string n = pathBase+to_string<uint64_t>(f->get_start(), hex) + ".dot"; ofstream out(n.c_str()); block_label_writer bgl(f); CFG g = f->get_cfg(); write_graphviz(out, g, bgl); } return; }
static bool InsertFunctionIntoModule(NativeModulePtr mod, NativeFunctionPtr func, llvm::Module *M) { auto &C = M->getContext(); auto F = M->getFunction(func->get_name()); if (!F) { throw TErr(__LINE__, __FILE__, "Could not get func " + func->get_name()); } if (!F->empty()) { std::cout << "WARNING: Asking to re-insert function: " << func->get_name() << std::endl << "\tReturning current function instead" << std::endl; return true; } auto entryBlock = llvm::BasicBlock::Create(F->getContext(), "entry", F); ArchAllocRegisterVars(entryBlock); TranslationContext ctx; ctx.natM = mod; ctx.natF = func; ctx.natI = nullptr; ctx.M = M; ctx.F = F; // Create basic blocks for each basic block in the original function. for (auto block_info : func->get_blocks()) { ctx.va_to_bb[block_info.first] = llvm::BasicBlock::Create( C, block_info.second->get_name(), F); } // Create a branch from the end of the entry block to the first block llvm::BranchInst::Create(ctx.va_to_bb[func->get_start()], entryBlock); try { // Lift every basic block into the functions. auto error = false; for (auto block_info : func->get_blocks()) { ctx.natB = block_info.second; error = LiftBlockIntoFunction(ctx) || error; ctx.natB = nullptr; } // For ease of debugging generated code, don't allow lifted functions to // be inlined. This will make lifted and native call graphs one-to-one. F->addFnAttr(llvm::Attribute::NoInline); //we should be done, having inserted every block into the module return !error; } catch (std::exception &e) { std::cerr << "error: " << std::endl << e.what() << std::endl << "in function " << std::hex << ctx.natF->get_start() << std::endl; if (ctx.natB) { std::cerr << "in block " << std::hex << ctx.natB->get_base() << std::endl; if (ctx.natI) { std::cerr << "in inst " << std::hex << ctx.natI->get_loc() << std::endl; } } return false; } }