//! [basicReadTest] static void basicReadTest(const P2::Partitioner &partitioner) { std::cout <<"\n" <<std::string(40, '=') <<"\nbasicReadTest\n" <<std::string(40, '=') <<"\n"; SymbolicSemantics::Formatter fmt; fmt.set_line_prefix(" "); // Create the RiscOperators and the initial state. const RegisterDictionary *regdict = partitioner.instructionProvider().registerDictionary(); const RegisterDescriptor REG = partitioner.instructionProvider().stackPointerRegister(); const std::string REG_NAME = RegisterNames(regdict)(REG); BaseSemantics::RiscOperatorsPtr ops = SymbolicSemantics::RiscOperators::instance(regdict); ops->currentState()->memoryState()->set_byteOrder(partitioner.instructionProvider().defaultByteOrder()); BaseSemantics::StatePtr initialState = ops->currentState()->clone(); ops->initialState(initialState); // lazily evaluated initial state std::cout <<"Initial state before reading:\n" <<(*initialState+fmt); // Read some memory and a register, which should cause them to spring into existence in both the current state and the // initial state. BaseSemantics::SValuePtr addr1 = ops->number_(32, 0); BaseSemantics::SValuePtr dflt1m = ops->number_(32, 0x11223344); BaseSemantics::SValuePtr read1m = ops->readMemory(RegisterDescriptor(), addr1, dflt1m, ops->boolean_(true)); BaseSemantics::SValuePtr dflt1r = ops->undefined_(REG.get_nbits()); BaseSemantics::SValuePtr read1r = ops->readRegister(REG, dflt1r); std::cout <<"Initial state after reading " <<*read1m <<" from address " <<*addr1 <<"\n" <<"and " <<*read1r <<" from " <<REG_NAME <<"\n" <<(*initialState+fmt); ASSERT_always_require(read1m->must_equal(dflt1m)); ASSERT_always_require(read1r->must_equal(dflt1r)); // Create a new current state and read again. We should get the same value even though the current state is empty. BaseSemantics::StatePtr curState = ops->currentState()->clone(); curState->clear(); ops->currentState(curState); BaseSemantics::SValuePtr dflt2m = ops->number_(32, 0x55667788); BaseSemantics::SValuePtr read2m = ops->readMemory(RegisterDescriptor(), addr1, dflt2m, ops->boolean_(true)); BaseSemantics::SValuePtr dflt2r = ops->undefined_(REG.get_nbits()); BaseSemantics::SValuePtr read2r = ops->readRegister(REG, dflt2r); std::cout <<"Initial state after reading " <<*read2m <<" from address " <<*addr1 <<"\n" <<"and " <<*read2r <<" from " <<REG_NAME <<"\n" <<(*initialState+fmt); ASSERT_always_require(read1m->must_equal(read2m)); ASSERT_always_require(read1r->must_equal(read2r)); // Disable the initial state. If we re-read the same address we'll still get the same result because it's now present in // the current state also. ops->initialState(BaseSemantics::StatePtr()); BaseSemantics::SValuePtr dflt3m = ops->number_(32, 0x99aabbcc); BaseSemantics::SValuePtr read3m = ops->readMemory(RegisterDescriptor(), addr1, dflt3m, ops->boolean_(true)); BaseSemantics::SValuePtr dflt3r = ops->undefined_(REG.get_nbits()); BaseSemantics::SValuePtr read3r = ops->readRegister(REG, dflt3r); ASSERT_always_require(read1m->must_equal(read3m)); ASSERT_always_require(read1r->must_equal(read3r)); }
void reset(const MemoryMap::Ptr &map) { BOOST_FOREACH (MemoryMap::Segment &segment, map->segments()) segment.buffer()->copyOnWrite(true); // prevent the VM from changing the real map BaseSemantics::StatePtr state = ops_->currentState()->clone(); state->clear(); ConcreteSemantics::MemoryStatePtr memState = ConcreteSemantics::MemoryState::promote(state->memoryState()); memState->memoryMap(map); ops_->currentState(state); BaseSemantics::SValuePtr sp = ops_->number_(wordSize_, stackVa_); ops_->writeRegister(regSp_, sp); ops_->writeMemory(regSs_, sp, ops_->number_(wordSize_, returnMarker_), ops_->boolean_(true)); }
BaseSemantics::StatePtr NoOperation::initialState(SgAsmInstruction *insn) const { ASSERT_not_null(insn); ASSERT_not_null(cpu_); BaseSemantics::StatePtr state; if (normalizer_) { state = normalizer_->initialState(cpu_, insn); } else { state = cpu_->currentState()->clone(); state->clear(); RegisterDescriptor IP = cpu_->instructionPointerRegister(); state->writeRegister(IP, cpu_->number_(IP.get_nbits(), insn->get_address()), cpu_->get_operators().get()); } // Set the stack pointer to a concrete value if (initialSp_) { const RegisterDescriptor regSp = cpu_->stackPointerRegister(); BaseSemantics::RiscOperatorsPtr ops = cpu_->get_operators(); state->writeRegister(regSp, ops->number_(regSp.get_nbits(), *initialSp_), ops.get()); } return state; }
std::string NoOperation::StateNormalizer::toString(const BaseSemantics::DispatcherPtr &cpu, const BaseSemantics::StatePtr &state_) { BaseSemantics::StatePtr state = state_; BaseSemantics::RiscOperatorsPtr ops = cpu->get_operators(); if (!state) return ""; bool isCloned = false; // do we have our own copy of the state? // If possible and appropriate, remove the instruction pointer register const RegisterDescriptor regIp = cpu->instructionPointerRegister(); BaseSemantics::RegisterStateGenericPtr rstate = BaseSemantics::RegisterStateGeneric::promote(state->registerState()); if (rstate && rstate->is_partly_stored(regIp)) { BaseSemantics::SValuePtr ip = ops->readRegister(cpu->instructionPointerRegister()); if (ip->is_number()) { state = state->clone(); isCloned = true; rstate = BaseSemantics::RegisterStateGeneric::promote(state->registerState()); rstate->erase_register(regIp, ops.get()); } } // Get the memory state, cloning the state if not done so above. BaseSemantics::MemoryCellStatePtr mem = boost::dynamic_pointer_cast<BaseSemantics::MemoryCellState>(state->memoryState()); if (mem && !isCloned) { state = state->clone(); isCloned = true; mem = BaseSemantics::MemoryCellState::promote(state->memoryState()); } // Erase memory that has never been written (i.e., cells that sprang into existence by reading an address) of which appears // to have been recently popped from the stack. CellErasurePredicate predicate(ops, ops->readRegister(cpu->stackPointerRegister()), ignorePoppedMemory_); if (mem) mem->eraseMatchingCells(predicate); BaseSemantics::Formatter fmt; fmt.set_show_latest_writers(false); fmt.set_show_properties(false); std::ostringstream ss; ss <<(*state+fmt); return ss.str(); }