Exemplo n.º 1
0
int main(int argc, char *argv[]) {
  llvm::cl::SetVersionPrinter(PrintVersion);
  llvm::cl::ParseCommandLineOptions(argc, argv, "CFG to LLVM");


  if (InputFilename.empty() || OutputFilename.empty()) {
    std::cerr
        << "Must specify an input and output file";
    return EXIT_FAILURE;
  }

  auto context = new llvm::LLVMContext;

  if (!InitArch(context, OS, Arch)) {
    std::cerr
        << "Cannot initialize for arch " << Arch
        << " and OS " << OS << std::endl;
    return EXIT_FAILURE;
  }

  auto M = CreateModule(context);
  if (!M) {
    return EXIT_FAILURE;
  }

  auto triple = M->getTargetTriple();

  //reproduce NativeModule from CFG input argument
  try {
    auto mod = ReadProtoBuf(InputFilename);
    if (!mod) {
      std::cerr << "Unable to read module from CFG" << std::endl;
      return EXIT_FAILURE;
    }

    //now, convert it to an LLVM module
    ArchInitAttachDetach(M);

    if (!LiftCodeIntoModule(mod, M)) {
      std::cerr << "Failure to convert to LLVM module!" << std::endl;
      return EXIT_FAILURE;
    }

    std::set<VA> entry_point_pcs;
    for (const auto &entry_point_name : EntryPoints) {
      auto entry_pc = FindSymbolInModule(mod, entry_point_name);
      if (entry_pc != static_cast<VA>( -1)) {
        std::cerr << "Adding entry point: " << entry_point_name << std::endl
                  << entry_point_name << " is implemented by sub_" << std::hex
                  << entry_pc << std::endl;

        if ( !ArchAddEntryPointDriver(M, entry_point_name, entry_pc)) {
          return EXIT_FAILURE;
        }

        entry_point_pcs.insert(entry_pc);
      } else {
        std::cerr << "Could not find entry point: " << entry_point_name
                  << "; aborting" << std::endl;
        return EXIT_FAILURE;
      }
    }

    RenameLiftedFunctions(mod, M, entry_point_pcs);

    // will abort if verification fails
    if (llvm::verifyModule( *M, &llvm::errs())) {
      std::cerr << "Could not verify module!" << std::endl;
      return EXIT_FAILURE;
    }

    std::error_code ec;
    llvm::tool_output_file Out(OutputFilename.c_str(), ec,
                               llvm::sys::fs::F_None);
    llvm::WriteBitcodeToFile(M, Out.os());
    Out.keep();

  } catch (std::exception &e) {
    std::cerr << "error: " << std::endl << e.what() << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
Exemplo n.º 2
0
int main(int argc, char *argv[]) {
  llvm::cl::SetVersionPrinter(PrintVersion);
  llvm::cl::ParseCommandLineOptions(argc, argv, "CFG to LLVM");

  auto context = llvm::make_unique<llvm::LLVMContext>();

  if (OS.empty()) {
    if (ListSupported || ListUnsupported) {
      OS = "linux"; // just need something
    }
    else {
      std::cerr << "-os must be specified" << std::endl;
      return EXIT_FAILURE;
    }
  }

  if (!(ListSupported || ListUnsupported || ListCFGFunctions) && EntryPoints.empty()) {
    std::cerr
        << "-entrypoint must be specified" << std::endl;
        return EXIT_FAILURE;
  }

  if (!InitArch(context.get(), OS, Arch)) {
    std::cerr
        << "Cannot initialize for arch " << Arch
        << " and OS " << OS << std::endl;
    return EXIT_FAILURE;
  }

  auto M = CreateModule(context.get());
  if (!M) {
    return EXIT_FAILURE;
  }

  auto triple = M->getTargetTriple();

  if (ListSupported || ListUnsupported) {
    ListArchSupportedInstructions(triple, llvm::outs(), ListSupported, ListUnsupported);
    return EXIT_SUCCESS;
  }

  if (InputFilename.empty()) {
    std::cerr
        << "Must specify an input file." << std::endl;
    return EXIT_FAILURE;
  }

  //reproduce NativeModule from CFG input argument
  try {
    std::unique_ptr<NativeModule> mod(ReadProtoBuf(InputFilename));
    if (!mod) {
      std::cerr << "Unable to read module from CFG" << std::endl;
      return EXIT_FAILURE;
    }

    if (ListCFGFunctions) {
      PrintCFGFunctionList(mod.get(), Arch);
      return EXIT_SUCCESS;
    }

    //make sure the entry point list is correct before we start lifting the code
    const std::vector<NativeEntrySymbol> &module_entry_points = mod->getEntryPoints();

    for (const auto &entry_point : EntryPoints) {
      auto it = std::find_if(
        module_entry_points.begin(),
        module_entry_points.end(),

        [&entry_point](const NativeEntrySymbol &symbol) -> bool {
          return (symbol.getName() == entry_point);
        }
      );

      if (it == module_entry_points.end()) {
          std::cerr << "The following entry point could not be found: \"" << entry_point << "\". Aborting..." << std::endl;
          return EXIT_FAILURE;
      }
    }

    //now, convert it to an LLVM module
    ArchInitAttachDetach(M);

    if (!LiftCodeIntoModule(mod.get(), M)) {
      std::cerr << "Failure to convert to LLVM module!" << std::endl;
      return EXIT_FAILURE;
    }

    std::set<VA> entry_point_pcs;
    for (const auto &entry_point_name : EntryPoints) {
      auto entry_pc = FindSymbolInModule(mod.get(), entry_point_name);
      assert(entry_pc != static_cast<VA>( -1));

      std::cerr << "Adding entry point: " << entry_point_name << std::endl
                << entry_point_name << " is implemented by sub_" << std::hex
                << entry_pc << std::endl;

      if ( !ArchAddEntryPointDriver(M, entry_point_name, entry_pc)) {
        return EXIT_FAILURE;
      }

      entry_point_pcs.insert(entry_pc);
    }

    RenameLiftedFunctions(mod.get(), M, entry_point_pcs);

    // will abort if verification fails
    if (llvm::verifyModule( *M, &llvm::errs())) {
      std::cerr << "Could not verify module!" << std::endl;
      return EXIT_FAILURE;
    }

    std::error_code ec;
    llvm::tool_output_file Out(OutputFilename.c_str(), ec,
                               llvm::sys::fs::F_None);
    llvm::WriteBitcodeToFile(M, Out.os());
    Out.keep();

  } catch (std::exception &e) {
    std::cerr << "error: " << std::endl << e.what() << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}