diff --git a/src/experiments/l4-sys/InstructionFilter.cc b/src/experiments/l4-sys/InstructionFilter.cc index b3d339c3..dac5ae61 100644 --- a/src/experiments/l4-sys/InstructionFilter.cc +++ b/src/experiments/l4-sys/InstructionFilter.cc @@ -1,4 +1,44 @@ #include "InstructionFilter.hpp" +#include "util/Logger.hpp" +#include // for more complex filters yet to come +/** + * Determine how many bytes are left in this file. + */ +static inline unsigned +getFileBytesLeft(std::ifstream& f) +{ + // get pos, seek to end, return difference + std::streampos pos = f.tellg(); + f.seekg(0, std::ios::end); + std::streampos end = f.tellg(); + + // and don't forget to reset the seek pos + f.seekg(pos, std::ios::beg); + + return end - pos; +} + + +RangeSetInstructionFilter::RangeSetInstructionFilter(char const *filename) + : _filters() +{ + fail::Logger log("RangeSet", false); + + std::ifstream filterFile(filename, std::ios::in); + if (!filterFile.is_open()) { + log << filename << " not found" << std::endl; + return; + } + + while (getFileBytesLeft(filterFile) > 1) { + address_t start, end; + filterFile >> std::hex >> start; + filterFile >> std::hex >> end; + log << "new filter range: " << std::hex + << start << " - " << end << std::endl; + addFilter(start, end); + } +} diff --git a/src/experiments/l4-sys/InstructionFilter.hpp b/src/experiments/l4-sys/InstructionFilter.hpp index 40e03615..f8a0645e 100644 --- a/src/experiments/l4-sys/InstructionFilter.hpp +++ b/src/experiments/l4-sys/InstructionFilter.hpp @@ -3,6 +3,7 @@ #include "sal/SALConfig.hpp" #include "cpu/instr.h" +#include using namespace fail; @@ -54,4 +55,34 @@ private: address_t endAddress; // _filters; + +public: + RangeSetInstructionFilter(char const *filename); + ~RangeSetInstructionFilter() {} + + bool isValidInstr(address_t ip, char const *instr) const + { + std::vector::const_iterator it; + for (it = _filters.begin(); it != _filters.end(); ++it) { + if (it->isValidInstr(ip, instr)) + return true; + } + return false; + } + + void addFilter(address_t startAddr, address_t endAddr) + { + _filters.push_back(RangeInstructionFilter(startAddr, endAddr)); + } +}; + #endif /* __L4SYS_INSTRUCTIONFILTER_HPP__ */ diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc index a547d8a4..0dd7d695 100644 --- a/src/experiments/l4-sys/experiment.cc +++ b/src/experiments/l4-sys/experiment.cc @@ -228,14 +228,12 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) #ifdef L4SYS_FILTER_INSTRUCTIONS ofstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary); + RangeSetInstructionFilter rsif(L4SYS_FILTER); bp.setWatchInstructionPointer(ANY_ADDR); size_t count = 0, accepted = 0; map times_called_map; - InstructionFilter *instrFilter = NULL; -#if defined(L4SYS_ADDRESS_LBOUND) && defined(L4SYS_ADDRESS_UBOUND) - instrFilter = new RangeInstructionFilter(L4SYS_ADDRESS_LBOUND, L4SYS_ADDRESS_UBOUND); -#endif + while (bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) { simulator.addListenerAndResume(&bp); count++; @@ -249,9 +247,8 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) times_called_map[curr_addr] = times_called; // now check if we want to add the instruction for fault injection - if (instrFilter != NULL && - instrFilter->isValidInstr(curr_addr, - reinterpret_cast(calculateInstructionAddress()))) { + if (rsif.isValidInstr(curr_addr, + reinterpret_cast(calculateInstructionAddress()))) { accepted++; TraceInstr new_instr; log << "writing IP " << hex << curr_addr << " counter " @@ -262,7 +259,6 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) instr_list_file.write(reinterpret_cast(&new_instr), sizeof(TraceInstr)); } } - delete instrFilter; log << "saving instructions triggered during normal execution" << endl; instr_list_file.close(); log << "test function calculation position reached after " diff --git a/src/experiments/l4-sys/experimentInfo.hpp b/src/experiments/l4-sys/experimentInfo.hpp index eb378acc..a1724dda 100644 --- a/src/experiments/l4-sys/experimentInfo.hpp +++ b/src/experiments/l4-sys/experimentInfo.hpp @@ -5,20 +5,16 @@ #define MAX_INSTR_BYTES 15 // the bounds of the program (space, instructions and time) -#define L4SYS_ADDRESS_SPACE 0x1fd6e000 -#define L4SYS_FUNC_ENTRY 0x01000200 -#define L4SYS_FUNC_EXIT 0x01000245 +#define L4SYS_ADDRESS_SPACE 0x1fd4c000 +#define L4SYS_FUNC_ENTRY 0x010002a0 +#define L4SYS_FUNC_EXIT 0x01000380 -// Instruction filtering: Allows to specify a range within -// which to perform injection experiments. If in doubt, set -// to the whole user-addressable area (0, 0xC0000000) +// select instruction filtering #define L4SYS_FILTER_INSTRUCTIONS 1 -#define L4SYS_ADDRESS_LBOUND 0 -#define L4SYS_ADDRESS_UBOUND 0xC0000000 // kernel: 2377547, userland: 79405472 -#define L4SYS_NUMINSTR 3281 -#define L4SYS_TOTINSTR 228218 +#define L4SYS_NUMINSTR 15099 +#define L4SYS_TOTINSTR 60214 #define L4SYS_BOCHS_IPS 5000000 // several file names used @@ -26,10 +22,11 @@ #define L4SYS_INSTRUCTION_LIST "ip.list" #define L4SYS_ALU_INSTRUCTIONS "alu.list" #define L4SYS_CORRECT_OUTPUT "golden.out" +#define L4SYS_FILTER "filter.list" // flags // 0 - preparation complete // >0 - next step to execute -#define PREPARATION_STEP 0 +#define PREPARATION_STEP 2 #endif // __L4SYS_EXPERIMENT_INFO_HPP__