static std::vector<SgAsmFunction*> loadFunctions(const std::vector<std::string> &specimen, P2::Engine &engine) { engine.reset(); // clear all but config properties engine.doingPostAnalysis(false); // not needed for this tool SgAsmBlock *gblock = engine.buildAst(specimen); // parse, load, link, disassemble, partition, build AST return SageInterface::querySubTree<SgAsmFunction>(gblock); // return just the functions }
SgProject* buildAst(int argc, char *argv[], Settings &settings) { using namespace Sawyer::CommandLine; P2::Engine engine; // Parse the commane-line Parser p = engine.commandLineParser("transcode to LLVM", "Convert an ELF/PE specimen to LLVM assembly for testing."); SwitchGroup tool("Tool-specific switches"); tool.insert(Switch("llvm") .argument("version", anyParser(settings.llvmVersionString)) .doc("Version number for LLVM. The version number is a doublet or triplet of integers such as \"3.5\" or " "\"3.5.0\" and indicates which dialect of assembly should be emitted. The LLVM assembly syntax, being " "mostly an LLVM internal language, changes in incompatible ways between LLVM versions. This transcoder " "supports only certain versions (e.g., 3.5.0 and 3.7.0 as of December 2015).")); std::vector<std::string> specimen = p.with(tool).parse(argc, argv).apply().unreachedArgs(); if (specimen.empty()) { ::mlog[FATAL] <<"no binary specimen; see --help for usage\n"; exit(1); } // Parse the LLVM version number specified on the command-line if (!settings.llvmVersionString.empty()) { const char *s = settings.llvmVersionString.c_str(); char *rest = NULL; errno = 0; int a = strtol(s, &rest, 10), b = 0, c = 0; if ('.'==*rest && 0==errno) { b = strtol(rest+1, &rest, 10); if ('.'==*rest && 0==errno) c = strtol(rest+1, &rest, 10); } settings.llvmVersion = 1000000 * a + 1000 * b + c; } // Parse, load, disassemble, and partition the specimen. (void) engine.buildAst(specimen); SgProject *project = SageInterface::getProject(); if (!project) { ::mlog[FATAL] <<"This tool only supports ELF/PE specimens.\n"; exit(1); } return project; }