void visit(SgNode* node) { SgAsmInterpretation *interp = isSgAsmInterpretation(node); if (interp) { const SgAsmGenericHeaderPtrList &headers = interp->get_headers()->get_headers(); bool only_x86 = true; for (size_t i=0; i<headers.size() && only_x86; ++i) only_x86 = 4==headers[i]->get_word_size(); if (only_x86) { ++ninterps; analyze_interp(interp); } } }
/* class method */ SgAsmGenericFile* BinaryLoader::createAsmAST(SgBinaryComposite* binaryFile, std::string filePath) { ASSERT_forbid(filePath.empty()); SgAsmGenericFile* file = SgAsmExecutableFileFormat::parseBinaryFormat(filePath.c_str()); ASSERT_not_null(file); // TODO do I need to attach here - or can I do after return binaryFile->get_genericFileList()->get_files().push_back(file); file->set_parent(binaryFile->get_genericFileList()); /* Add a new interpretation to the SgBinaryComposite object for each header of the newly parsed * SgAsmGenericFile for which a suitable interpretation does not already exist. */ const SgAsmGenericHeaderPtrList &headers = file->get_headers()->get_headers(); SgAsmInterpretationPtrList &interps = binaryFile->get_interpretations()->get_interpretations(); for (size_t i = 0; i < headers.size(); ++i) { SgAsmGenericHeader* header = headers[i]; SgAsmInterpretation* interp = NULL; for (size_t j = 0; j < interps.size(); ++j) { ASSERT_forbid(interps[j]->get_headers()->get_headers().empty()); SgAsmGenericHeader* interpHeader = interps[j]->get_headers()->get_headers().front(); if (isHeaderSimilar(header, interpHeader)) { interp = interps[j]; break; } } if (!interp) { interp = new SgAsmInterpretation(); interps.push_back(interp); interp->set_parent(binaryFile->get_interpretations()); if (const RegisterDictionary *registers = RegisterDictionary::dictionary_for_isa(header->get_isa())) interp->set_registers(registers); } interp->get_headers()->get_headers().push_back(header); } #if USE_ROSE_DWARF_SUPPORT /* Parse Dwarf info and add it to the SgAsmGenericFile. */ readDwarf(file); #endif return file; }
int main(int argc, char *argv[]) { SgProject *project = frontend(argc, argv); SgAsmInterpretation *interp = SageInterface::querySubTree<SgAsmInterpretation>(project).back(); AllInstructions insns(interp); SgAsmGenericHeader *header = interp->get_headers()->get_headers().front(); rose_addr_t start_va = header->get_base_va() + header->get_entry_rva(); #if SEMANTIC_API == OLD_API MyPolicy operators; X86InstructionSemantics<MyPolicy, MyValueType> dispatcher(operators); #else BaseSemantics::RiscOperatorsPtr operators = make_ops(); BaseSemantics::DispatcherPtr dispatcher = DispatcherX86::instance(operators); #endif struct sigaction sa; sa.sa_handler = alarm_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGALRM, &sa, NULL); alarm(timeout); struct timeval start_time; std::cout <<"test starting...\n"; gettimeofday(&start_time, NULL); size_t ninsns = 0; while (!had_alarm) { rose_addr_t va = start_va; while (SgAsmInstruction *insn = insns.fetch(va)) { //std::cerr <<unparseInstructionWithAddress(insn) <<"\n"; #if SEMANTIC_API == OLD_API dispatcher.processInstruction(isSgAsmx86Instruction(insn)); ++ninsns; #if SEMANTIC_DOMAIN == MULTI_DOMAIN // multi-semantics ValueType has no is_known() or get_known(). We need to invoke it on a specific subpolicy. PartialSymbolicSemantics::ValueType<32> ip = operators.readRegister<32>("eip") .get_subvalue(MyMultiSemanticsClass::SP0()); #else MyValueType<32> ip = operators.readRegister<32>("eip"); #endif if (!ip.is_known()) break; va = ip.known_value(); #else dispatcher->processInstruction(insn); ++ninsns; BaseSemantics::SValuePtr ip = operators->readRegister(dispatcher->findRegister("eip")); if (!ip->is_number()) break; va = ip->get_number(); #endif if (had_alarm) break; } } #if SEMANTIC_API == OLD_API MyValueType<32> eax = operators.readRegister<32>("eax"); std::cerr <<"eax = " <<eax <<"\n"; #else BaseSemantics::SValuePtr eax = operators->readRegister(dispatcher->findRegister("eax")); #if SEMANTIC_DOMAIN == MULTI_DOMAIN // This is entirely optional, but the output looks better if it has the names of the subdomains. std::cerr <<"eax = " <<(*eax + MultiSemantics::RiscOperators::promote(operators)->get_formatter()) <<"\n"; #else std::cerr <<"eax = " <<*eax <<"\n"; #endif #endif struct timeval stop_time; gettimeofday(&stop_time, NULL); double elapsed = ((double)stop_time.tv_sec-start_time.tv_sec) + 1e-6*((double)stop_time.tv_usec-start_time.tv_usec); if (elapsed < timeout/4.0) std::cout <<"warning: test did not run for a sufficiently long time; output may contain a high degree of error.\n"; std::cout <<"number of instructions: " <<ninsns <<"\n" <<"elapsed time: " <<elapsed <<" seconds\n" <<"semantic execution rate: " <<(ninsns/elapsed) <<" instructions/second\n"; return 0; }