Rework instruction filtering

Add a new instruction filter that allows filtering a list of
ranges read from a file. This allows us to specify multiple
ranges, e.g., to leave out instructions or to focus on multiple
functions

Change-Id: Iba13cda00d0a73edaef270b3cd9100afe3e4668b
This commit is contained in:
Björn Döbel
2013-08-27 11:26:27 +02:00
parent 1fefef06b0
commit 10420938d2
4 changed files with 83 additions and 19 deletions

View File

@ -1,4 +1,44 @@
#include "InstructionFilter.hpp"
#include "util/Logger.hpp"
#include <fstream>
// 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);
}
}

View File

@ -3,6 +3,7 @@
#include "sal/SALConfig.hpp"
#include "cpu/instr.h"
#include <vector>
using namespace fail;
@ -54,4 +55,34 @@ private:
address_t endAddress; //<! the end of the address range
};
/**
* \class RangeSetInstructionFilter
*
* Collects a list of filter ranges from an input file.
*/
class RangeSetInstructionFilter : public InstructionFilter {
private:
std::vector<RangeInstructionFilter> _filters;
public:
RangeSetInstructionFilter(char const *filename);
~RangeSetInstructionFilter() {}
bool isValidInstr(address_t ip, char const *instr) const
{
std::vector<RangeInstructionFilter>::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__ */

View File

@ -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<address_t, unsigned> 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<char const*>(calculateInstructionAddress()))) {
if (rsif.isValidInstr(curr_addr,
reinterpret_cast<char const*>(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<char*>(&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 "

View File

@ -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__