ErrorOr<unique_ptr<Module>> generateAnnotatedModule(Executable& executable, const string& moduleName = "fcd-out") { x86_config config64 = { x86_isa64, 8, X86_REG_RIP, X86_REG_RSP, X86_REG_RBP }; TranslationContext transl(llvm, config64, moduleName); unordered_map<uint64_t, SymbolInfo> toVisit; for (uint64_t address : executable.getVisibleEntryPoints()) { auto symbolInfo = executable.getInfo(address); // Entry points are always considered when naming symbols, but only used in full disassembly mode. // Otherwise, we expect symbols to be specified with the command line. if (isFullDisassembly()) { assert(symbolInfo != nullptr); toVisit.insert({symbolInfo->virtualAddress, *symbolInfo}); } } unordered_set<uint64_t> entryPoints(additionalEntryPoints.begin(), additionalEntryPoints.end()); for (uint64_t address : entryPoints) { if (auto symbolInfo = executable.getInfo(address)) { toVisit.insert({symbolInfo->virtualAddress, *symbolInfo}); } else { return make_error_code(FcdError::Main_EntryPointOutOfMappedMemory); } } if (toVisit.size() == 0) { return make_error_code(FcdError::Main_NoEntryPoint); } size_t iterations = 0; do { while (toVisit.size() > 0) { auto iter = toVisit.begin(); auto functionInfo = iter->second; toVisit.erase(iter); if (functionInfo.name.size() > 0) { transl.setFunctionName(functionInfo.virtualAddress, functionInfo.name); } Function* fn = transl.createFunction(executable, functionInfo.virtualAddress); // Couldn't decompile, abort if (fn == nullptr) { return make_error_code(FcdError::Main_DecompilationError); } } iterations++; } while (refillEntryPoints(transl, executable, toVisit, iterations)); // Perform early optimizations to make the module suitable for analysis auto module = transl.take(); legacy::PassManager phaseOne = createBasePassManager(); phaseOne.add(createExternalAAWrapperPass(&Main::aliasAnalysisHooks)); phaseOne.add(createDeadCodeEliminationPass()); phaseOne.add(createCFGSimplificationPass()); phaseOne.add(createInstructionCombiningPass()); phaseOne.add(createRegisterPointerPromotionPass()); phaseOne.add(createGVNPass()); phaseOne.add(createDeadStoreEliminationPass()); phaseOne.add(createInstructionCombiningPass()); phaseOne.add(createCFGSimplificationPass()); phaseOne.add(createGlobalDCEPass()); phaseOne.run(*module); // Annotate stubs before returning module annotateStubs(executable, *module); return move(module); }