Exemple #1
0
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;
}
Exemple #2
0
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;
  }

  
}