L4Sys: consult instruction list for breakpoints
Change-Id: Ic8163cc84bad9b0074a9d6489127d0ef09eb3c21
This commit is contained in:
@ -71,6 +71,7 @@ BaseListener* L4SysExperiment::waitIOOrOther(bool clear_output) {
|
|||||||
//simulator.removeListener(&ev_ioport);
|
//simulator.removeListener(&ev_ioport);
|
||||||
if (ev == &ev_ioport) {
|
if (ev == &ev_ioport) {
|
||||||
currentOutput += ev_ioport.getData();
|
currentOutput += ev_ioport.getData();
|
||||||
|
//log << currentOutput << std::endl;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -444,34 +445,8 @@ void L4SysExperiment::readGoldenRun(std::string& target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fail::BPSingleListener*
|
void L4SysExperiment::setupFilteredBreakpoint(fail::BPSingleListener* bp, int instOffset)
|
||||||
L4SysExperiment::prepareMemoryExperiment(int ip, int offset, int dataAddress)
|
|
||||||
{
|
{
|
||||||
fail::BPSingleListener *bp = new BPSingleListener(0, L4SYS_ADDRESS_SPACE);
|
|
||||||
log << "Memory fault injection at instruction " << std::hex << offset
|
|
||||||
<< ", ip " << ip << ", address " << dataAddress << std::endl;
|
|
||||||
bp->setWatchInstructionPointer(ip & 0xFFFFFFFF);
|
|
||||||
bp->setCounter(offset);
|
|
||||||
return bp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fail::BPSingleListener*
|
|
||||||
L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress)
|
|
||||||
{
|
|
||||||
fail::BPSingleListener *bp = new BPSingleListener(0, L4SYS_ADDRESS_SPACE);
|
|
||||||
|
|
||||||
int reg, width, regOffset;
|
|
||||||
reg = ((dataAddress >> 8) & 0xF) + 1; // regs start at 1
|
|
||||||
width = (dataAddress >> 4) & 0xF;
|
|
||||||
regOffset = dataAddress & 0xF;
|
|
||||||
|
|
||||||
log << "GPR bitflip at instr. offset " << offset
|
|
||||||
<< " reg data (" << reg << ", " << width << ", "
|
|
||||||
<< regOffset << ")" << std::endl;
|
|
||||||
|
|
||||||
#ifdef L4SYS_FILTER_INSTRUCTIONS
|
|
||||||
// XXX still needed???
|
|
||||||
ifstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary);
|
ifstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary);
|
||||||
|
|
||||||
if (!instr_list_file.good()) {
|
if (!instr_list_file.good()) {
|
||||||
@ -480,7 +455,7 @@ L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TraceInstr curr_instr;
|
TraceInstr curr_instr;
|
||||||
instr_list_file.seekg(offset * sizeof(TraceInstr));
|
instr_list_file.seekg(instOffset * sizeof(TraceInstr));
|
||||||
log << instr_list_file.eof() << " " << instr_list_file.bad() << " "
|
log << instr_list_file.eof() << " " << instr_list_file.bad() << " "
|
||||||
<< instr_list_file.fail() << endl;
|
<< instr_list_file.fail() << endl;
|
||||||
if (instr_list_file.eof()) {
|
if (instr_list_file.eof()) {
|
||||||
@ -494,6 +469,44 @@ L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress)
|
|||||||
bp->setWatchInstructionPointer(curr_instr.trigger_addr);
|
bp->setWatchInstructionPointer(curr_instr.trigger_addr);
|
||||||
log << "setting bp counter " << hex << curr_instr.bp_counter << endl;
|
log << "setting bp counter " << hex << curr_instr.bp_counter << endl;
|
||||||
bp->setCounter(curr_instr.bp_counter);
|
bp->setCounter(curr_instr.bp_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fail::BPSingleListener*
|
||||||
|
L4SysExperiment::prepareMemoryExperiment(int ip, int offset, int dataAddress)
|
||||||
|
{
|
||||||
|
fail::BPSingleListener *bp = new BPSingleListener(0, L4SYS_ADDRESS_SPACE);
|
||||||
|
log << "\033[34;1mMemory fault injection\033[0m at instruction " << std::hex << offset
|
||||||
|
<< ", ip " << ip << ", address " << dataAddress << std::endl;
|
||||||
|
|
||||||
|
#ifdef L4SYS_FILTER_INSTRUCTIONS
|
||||||
|
setupFilteredBreakpoint(bp, offset);
|
||||||
|
assert(bp->getWatchInstructionPointer() == (address_t)(ip & 0xFFFFFFFF));
|
||||||
|
#else
|
||||||
|
bp->setWatchInstructionPointer(ANY_ADDR);
|
||||||
|
bp->setCounter(instr_offset);
|
||||||
|
#endif
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fail::BPSingleListener*
|
||||||
|
L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress)
|
||||||
|
{
|
||||||
|
fail::BPSingleListener *bp = new BPSingleListener(0, L4SYS_ADDRESS_SPACE);
|
||||||
|
|
||||||
|
int reg, regOffset;
|
||||||
|
reg = ((dataAddress >> 4) & 0xF) + 1; // regs start at 1
|
||||||
|
regOffset = dataAddress & 0xF;
|
||||||
|
|
||||||
|
log << "\033[32;1mGPR bitflip\033[0m at instr. offset " << offset
|
||||||
|
<< " reg data (" << reg << ", "
|
||||||
|
<< regOffset << ")" << std::endl;
|
||||||
|
|
||||||
|
#ifdef L4SYS_FILTER_INSTRUCTIONS
|
||||||
|
setupFilteredBreakpoint(bp, offset);
|
||||||
|
assert(bp->getWatchInstructionPointer() == (address_t)(ip & 0xFFFFFFFF));
|
||||||
|
log << bp->getCounter() << std::endl;
|
||||||
#else
|
#else
|
||||||
bp->setWatchInstructionPointer(ANY_ADDR);
|
bp->setWatchInstructionPointer(ANY_ADDR);
|
||||||
bp->setCounter(instr_offset);
|
bp->setCounter(instr_offset);
|
||||||
@ -515,9 +528,8 @@ void L4SysExperiment::doMemoryInjection(int address, int bit)
|
|||||||
|
|
||||||
void L4SysExperiment::doRegisterInjection(int regDesc, int bit)
|
void L4SysExperiment::doRegisterInjection(int regDesc, int bit)
|
||||||
{
|
{
|
||||||
int reg, width, offset;
|
int reg, offset;
|
||||||
reg = ((regDesc >> 8) & 0xF) + 1; // regs start at 1
|
reg = (regDesc >> 4) + 1; // regs start at 1
|
||||||
width = (regDesc >> 4) & 0xF;
|
|
||||||
offset = regDesc & 0xF;
|
offset = regDesc & 0xF;
|
||||||
|
|
||||||
ConcreteCPU& cpu = simulator.getCPU(0);
|
ConcreteCPU& cpu = simulator.getCPU(0);
|
||||||
@ -615,11 +627,14 @@ bool L4SysExperiment::run()
|
|||||||
|
|
||||||
unsigned instr_left = L4SYS_TOTINSTR - instr_offset; // XXX offset is in NUMINSTR, TOTINSTR is higher
|
unsigned instr_left = L4SYS_TOTINSTR - instr_offset; // XXX offset is in NUMINSTR, TOTINSTR is higher
|
||||||
BPSingleListener ev_incomplete(ANY_ADDR, L4SYS_ADDRESS_SPACE);
|
BPSingleListener ev_incomplete(ANY_ADDR, L4SYS_ADDRESS_SPACE);
|
||||||
ev_incomplete.setCounter(static_cast<unsigned>(instr_left * 1.1));
|
ev_incomplete.setCounter(instr_left);
|
||||||
simulator.addListener(&ev_incomplete);
|
simulator.addListener(&ev_incomplete);
|
||||||
|
|
||||||
TimerListener ev_timeout(calculateTimeout(instr_left));
|
TimerListener ev_timeout(calculateTimeout(instr_left));
|
||||||
simulator.addListener(&ev_timeout);
|
simulator.addListener(&ev_timeout);
|
||||||
|
log << "continue... (" << simulator.getListenerCount()
|
||||||
|
<< " breakpoints, timeout @ " << ev_timeout.getTimeout()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
//do not discard output recorded so far
|
//do not discard output recorded so far
|
||||||
BaseListener *ev = waitIOOrOther(false);
|
BaseListener *ev = waitIOOrOther(false);
|
||||||
|
|||||||
@ -123,14 +123,46 @@ private:
|
|||||||
*/
|
*/
|
||||||
void goldenRun(fail::BPSingleListener* bp);
|
void goldenRun(fail::BPSingleListener* bp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that all required setup has been done before an experiment run.
|
||||||
|
*/
|
||||||
void validatePrerequisites();
|
void validatePrerequisites();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load job parameters for an experiment.
|
||||||
|
*/
|
||||||
void getJobParameters();
|
void getJobParameters();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the golden run output into the target string.
|
||||||
|
*/
|
||||||
void readGoldenRun(std::string& target);
|
void readGoldenRun(std::string& target);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare memory experiment. Creates a breakpoint to run until the
|
||||||
|
* injection location.
|
||||||
|
*/
|
||||||
fail::BPSingleListener* prepareMemoryExperiment(int ip, int offset, int dataAddress);
|
fail::BPSingleListener* prepareMemoryExperiment(int ip, int offset, int dataAddress);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare register experiment. Creates a breakpoint to run until the
|
||||||
|
* injection location.
|
||||||
|
*/
|
||||||
fail::BPSingleListener* prepareRegisterExperiment(int ip, int offset, int dataAddress);
|
fail::BPSingleListener* prepareRegisterExperiment(int ip, int offset, int dataAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform memory bit flip at (address, bit).
|
||||||
|
*/
|
||||||
void doMemoryInjection(int address, int bit);
|
void doMemoryInjection(int address, int bit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform register bit flip in the specified (register, bit)
|
||||||
|
* combination.
|
||||||
|
*/
|
||||||
void doRegisterInjection(int regDesc, int bit);
|
void doRegisterInjection(int regDesc, int bit);
|
||||||
|
|
||||||
|
|
||||||
|
void setupFilteredBreakpoint(fail::BPSingleListener* bp, int instOffset);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __L4SYS_EXPERIMENT_HPP__
|
#endif // __L4SYS_EXPERIMENT_HPP__
|
||||||
|
|||||||
Reference in New Issue
Block a user