int RSIM_Simulator::exec(int argc, char **argv) { assert(argc>0); create_process(); SgAsmGenericHeader *fhdr = process->load(argv[0]); entry_va = fhdr->get_base_va() + fhdr->get_entry_rva(); RSIM_Thread *main_thread = process->get_thread(getpid()); assert(main_thread!=NULL); process->initialize_stack(fhdr, argc, argv); process->binary_trace_start(); if ((process->get_tracing_flags() & tracingFacilityBit(TRACE_MMAP))) { fprintf(process->get_tracing_file(), "memory map after program load:\n"); process->get_memory()->dump(process->get_tracing_file(), " "); } main_thread->tracing(TRACE_STATE)->mesg("Initial state:\n"); main_thread->policy.dump_registers(main_thread->tracing(TRACE_STATE)); return 0; }
std::string btorTranslate(BtorTranslationPolicy& policy, SgProject* proj, FILE* outfile, bool initialConditionsAreUnknown, bool bogusIpIsError) { std::vector<SgNode*> headers = NodeQuery::querySubTree(proj, V_SgAsmGenericHeader); ROSE_ASSERT (headers.size() == 1); SgAsmGenericHeader* header = isSgAsmGenericHeader(headers[0]); rose_addr_t entryPoint = header->get_entry_rva() + header->get_base_va(); X86InstructionSemantics<BtorTranslationPolicy, BtorWordType> t(policy); std::vector<SgNode*> instructions = NodeQuery::querySubTree(proj, V_SgAsmX86Instruction); for (size_t i = 0; i < instructions.size(); ++i) { SgAsmX86Instruction* insn = isSgAsmX86Instruction(instructions[i]); ROSE_ASSERT (insn); try { t.processInstruction(insn); } catch (const X86InstructionSemantics<BtorTranslationPolicy, BtorWordType>::Exception &e) { fprintf(stderr, "%s: %s\n", e.mesg.c_str(), unparseInstructionWithAddress(e.insn).c_str()); } } policy.setInitialState(entryPoint, initialConditionsAreUnknown); // Add "bogus IP" error policy.newRegisterMap.errorFlag[bmc_error_bogus_ip] = policy.invert(policy.isValidIp); for (size_t i = 0; i < numBmcErrors; ++i) { if (i == bmc_error_bogus_ip && !bogusIpIsError) continue; // For testing policy.problem.computations.push_back(policy.problem.build_op_root(policy.problem.build_op_and(policy.errorsEnabled, policy.newRegisterMap.errorFlag[i]))); } policy.addNexts(); return policy.problem.unparse(); }
BinaryLoader::MappingContribution BinaryLoader::align_values(SgAsmGenericSection *section, MemoryMap *map, rose_addr_t *malign_lo_p, rose_addr_t *malign_hi_p, rose_addr_t *va_p, rose_addr_t *mem_size_p, rose_addr_t *offset_p, rose_addr_t *file_size_p, bool *map_private_p, rose_addr_t *va_offset_p, bool *anon_lo_p, bool *anon_hi_p, ConflictResolution *resolve_p) { ASSERT_not_null(section); ASSERT_require2(section->is_mapped(), "section must be mapped to virtual memory"); SgAsmGenericHeader *header = isSgAsmGenericHeader(section); if (!header) header = section->get_header(); ASSERT_not_null(header); /* Initial guesses */ rose_addr_t malign_lo = std::max(section->get_mapped_alignment(), (rose_addr_t)1); rose_addr_t malign_hi = std::min(std::max(section->get_mapped_alignment(), (rose_addr_t)1), (rose_addr_t)4096); rose_addr_t va = header->get_base_va() + section->get_mapped_preferred_rva(); rose_addr_t mem_size = section->get_mapped_size(); rose_addr_t falign_lo = std::max(section->get_file_alignment(), (rose_addr_t)1); rose_addr_t offset = section->get_offset(); rose_addr_t file_size = section->get_size(); /* Align lower end of mapped region to satisfy both memory and file alignment constraints. */ rose_addr_t va_offset = bialign(va, malign_lo, offset, falign_lo); if (va_offset>va || va_offset>offset) { mlog[TRACE] <<" Adjustment " <<va_offset <<" exceeds va or offset (va=" <<va <<", offset=" <<offset <<")\n"; throw Exception("no solutions to memory/file alignment constraints"); } ASSERT_require((va - va_offset) % malign_lo == 0); ASSERT_require((offset - va_offset) % falign_lo == 0); va -= va_offset; mem_size += va_offset; offset -= va_offset; file_size += va_offset; /* Extend mapped region to satisfy high alignment; but do not extend the file region */ if ((va + mem_size) % malign_hi != 0) { uint64_t extend_by = alignUp(va+mem_size, malign_hi) - (va+mem_size); mem_size += extend_by; } /* Return values */ *malign_lo_p = malign_lo; *malign_hi_p = malign_hi; *va_p = va; *mem_size_p = mem_size; *offset_p = offset; *file_size_p = file_size; *map_private_p = false; *va_offset_p = va_offset; *anon_lo_p = true; *anon_hi_p = true; *resolve_p = RESOLVE_THROW; return CONTRIBUTE_ADD; }
/** Returns base virtual address for a section, or zero if the section is not associated with a header. */ rose_addr_t SgAsmGenericSection::get_base_va() const { ROSE_ASSERT(this != NULL); if (isSgAsmGenericHeader(this)) return isSgAsmGenericHeader(this)->get_base_va(); SgAsmGenericHeader *hdr = get_header(); return hdr ? hdr->get_base_va() : 0; }
/* This algorithm was implemented based on an e-mail from Cory Cohen at CERT and inspection of PE::ConvertRvaToFilePosition() * as defined in "PE.cpp 2738 2009-06-05 15:09:11Z murawski_dev". [RPM 2009-08-17] */ BinaryLoader::MappingContribution BinaryLoaderPe::align_values(SgAsmGenericSection *section, MemoryMap *map, rose_addr_t *malign_lo_p, rose_addr_t *malign_hi_p, rose_addr_t *va_p, rose_addr_t *mem_size_p, rose_addr_t *offset_p, rose_addr_t *file_size_p, bool *map_private_p, rose_addr_t *va_offset_p, bool *anon_lo_p, bool *anon_hi_p, ConflictResolution *resolve_p) { SgAsmGenericHeader *header = isSgAsmPEFileHeader(section); if (!header) header = section->get_header(); ROSE_ASSERT(header!=NULL); if (!section->is_mapped()) return CONTRIBUTE_NONE; /* File and memory alignment must be between 1 and 0x200 (512), inclusive */ rose_addr_t file_alignment = section->get_file_alignment(); if (file_alignment>0x200 || 0==file_alignment) file_alignment = 0x200; rose_addr_t mapped_alignment = section->get_mapped_alignment(); if (0==mapped_alignment) mapped_alignment = 0x200; /* Align file size upward even before we align the file offset downward. */ rose_addr_t file_size = ALIGN_UP(section->get_size(), file_alignment); /* Map the entire section's file content (aligned) or the requested map size, whichever is larger. */ rose_addr_t mapped_size = std::max(section->get_mapped_size(), file_size); /* Align file offset downward but do not adjust file size. */ rose_addr_t file_offset = ALIGN_DN(section->get_offset(), file_alignment); /* Align the preferred relative virtual address downward without regard for the base virtual address, and do not adjust * mapped size. */ rose_addr_t mapped_va = header->get_base_va() + ALIGN_DN(section->get_mapped_preferred_rva(), mapped_alignment); *malign_lo_p = mapped_alignment; *malign_hi_p = 1; *va_p = mapped_va; *mem_size_p = mapped_size; *offset_p = file_offset; *file_size_p = file_size; *map_private_p = false; *va_offset_p = 0; *anon_lo_p = *anon_hi_p = true; *resolve_p = RESOLVE_OVERMAP; return CONTRIBUTE_ADD; }
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; }