From 07b6275cbb655d53800df4b393fedcf299e2a451 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Thu, 17 Sep 2015 13:34:09 +0200 Subject: [PATCH] plugin/checkpoint: add possibility to cache data The checkpoint plugin is able to use dynamic values from within the target to calculate its ranges. If the experiment injects faults within those dynamic values, we will always get an digest error, even if it has no influence on the outcome of the experiment or the integrity of the data range. Therefore, the plugin now provides a possiblity to cache those dynamic values, before injecting them. This has to be done explicitly within the experiment. Change-Id: Ib2cbedd570ea9ab9c97efc152279e8eb79c573f4 --- src/plugins/checkpoint/Checkpoint.cc | 33 +++++++++++++++++++++++---- src/plugins/checkpoint/Checkpoint.hpp | 28 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) 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]);