diff --git a/src/plugins/checkpoint/Checkpoint.cc b/src/plugins/checkpoint/Checkpoint.cc index 472445e4..48c334db 100644 --- a/src/plugins/checkpoint/Checkpoint.cc +++ b/src/plugins/checkpoint/Checkpoint.cc @@ -53,10 +53,16 @@ address_t Checkpoint::resolve_address(const indirectable_address_t &addr) { const address_t paddr = addr.first; address_t value = 0; - MemoryManager& mm = simulator.getMemoryManager(); + std::map::iterator it = cached_stackpointer_variables.find(paddr); + if (it != cached_stackpointer_variables.end()) { + m_log << "Use Cached Value! " << std::hex << it->first << "=" << it->second << std::dec << endl; + value = it->second; + } else { + MemoryManager& mm = simulator.getMemoryManager(); - if(mm.isMapped(paddr) && mm.isMapped(paddr+1) && mm.isMapped(paddr+2) && mm.isMapped(paddr+3)) { - simulator.getMemoryManager().getBytes(paddr, 4, &value); + if(mm.isMapped(paddr) && mm.isMapped(paddr+1) && mm.isMapped(paddr+2) && mm.isMapped(paddr+3)) { + simulator.getMemoryManager().getBytes(paddr, 4, &value); + } } // HACK/WORKAROUND for dOSEK, which uses bit 31 for parity! @@ -68,6 +74,24 @@ address_t Checkpoint::resolve_address(const indirectable_address_t &addr) { } } +bool Checkpoint::in_range(fail::address_t addr) +{ + // iterate memory regions + std::vector::const_iterator it = m_check_ranges.begin(); + for( ; it != m_check_ranges.end(); ++it) { + fail::address_t start = resolve_address(it->first); + fail::address_t end = resolve_address(it->second); + if((start == 0) || (end == 0)) { + m_log << std::hex << "invalid checksum range pointer" << std::endl; + continue; + } + if (start <= addr && addr < end) { + return true; + } + } + return false; +} + void Checkpoint::checksum(uint8_t (&Message_Digest)[20]) { SHA1Context sha; @@ -97,7 +121,8 @@ void Checkpoint::checksum(uint8_t (&Message_Digest)[20]) continue; } - //m_log << std::hex << "checksumming 0x" << start << " - 0x" << end << std::endl; + // if (start != end) + // m_log << std::hex << "checksumming 0x" << start << " - 0x" << end << std::endl; for(fail::address_t addr = start; addr < end; addr++) { if(mm.isMapped(addr)) { diff --git a/src/plugins/checkpoint/Checkpoint.hpp b/src/plugins/checkpoint/Checkpoint.hpp index 7cd2aa79..ace5bfba 100644 --- a/src/plugins/checkpoint/Checkpoint.hpp +++ b/src/plugins/checkpoint/Checkpoint.hpp @@ -41,6 +41,11 @@ private: std::ifstream m_istream; //!< inputfile stream unsigned m_count; + // In this map, we save the contents of stackpointer-variables to + // beginning/end of region markers. We allow this to make those + // stackpointer-variables injectable. + std::map cached_stackpointer_variables; + public: /** * Construct Checkpoint Logger in tracing (output) mode. @@ -97,6 +102,29 @@ public: */ check_result check(const fail::ElfSymbol symbol, fail::address_t ip); + /** + * Checks whether the given address is currently (according to the + * machine state) within the checked ranges. + * + * @param addr address to check + * @return addr is in checked ranges + */ + bool in_range(fail::address_t addr); + + /** + * Cache a memory address, which is to be dereferenced by the checkpoint plugin. + * + * @param address of the stackpointer variable + * @param value of the stackpointer variable + */ + void cache_stackpointer_variable(fail::address_t addr, fail::address_t value) { + cached_stackpointer_variables[addr] = value; + } + + void uncache_stackpointer_variable(fail::address_t addr) { + cached_stackpointer_variables.erase(addr); + } + private: //! calulate checksum over memory regions void checksum(uint8_t (&Message_Digest)[20]);