L4Sys Experiment: more on address space tracing
* introduce L4SYS_ADDRESS_SPACE_TRACE to indicate that we want to trace instructions in a different AS from the one we are starting the experiment in * add CR3Run() to determine address space ID Change-Id: I7bdaf1e858a6dd369af5175bd56e1b4e2d5f05ef
This commit is contained in:
@ -22,8 +22,7 @@
|
|||||||
#include "util/ProtoStream.hpp"
|
#include "util/ProtoStream.hpp"
|
||||||
#include "TracePlugin.pb.h"
|
#include "TracePlugin.pb.h"
|
||||||
#include "util/gzstream/gzstream.h"
|
#include "util/gzstream/gzstream.h"
|
||||||
|
#include <sal/bochs/BochsMemory.hpp>
|
||||||
#include "l4sys.pb.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace fail;
|
using namespace fail;
|
||||||
@ -204,8 +203,15 @@ void L4SysExperiment::terminate(int reason) {
|
|||||||
simulator.terminate(reason);
|
simulator.terminate(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void L4SysExperiment::terminateWithError(string details, int reason) {
|
void L4SysExperiment::terminateWithError(string details, int reason,
|
||||||
L4SysProtoMsg_Result *result = param->msg.add_result();
|
L4SysProtoMsg_Result *r = 0) {
|
||||||
|
L4SysProtoMsg_Result *result;
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
result = r;
|
||||||
|
else
|
||||||
|
result = param->msg.add_result();
|
||||||
|
|
||||||
result->set_resulttype(param->msg.UNKNOWN);
|
result->set_resulttype(param->msg.UNKNOWN);
|
||||||
result->set_resultdata(simulator.getCPU(0).getInstructionPointer());
|
result->set_resultdata(simulator.getCPU(0).getInstructionPointer());
|
||||||
result->set_output(sanitised(currentOutput.c_str()));
|
result->set_output(sanitised(currentOutput.c_str()));
|
||||||
@ -230,21 +236,37 @@ void L4SysExperiment::startAndSaveInitState(fail::BPSingleListener* bp)
|
|||||||
simulator.save(L4SYS_STATE_FOLDER);
|
simulator.save(L4SYS_STATE_FOLDER);
|
||||||
delete bp;
|
delete bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void L4SysExperiment::CR3run(fail::BPSingleListener *bp)
|
||||||
|
{
|
||||||
|
bp->setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
|
||||||
|
simulator.addListenerAndResume(bp);
|
||||||
|
log << "Reached entry point @ " << hex << bp->getTriggerInstructionPointer()
|
||||||
|
<< " == " << simulator.getCPU(0).getInstructionPointer()
|
||||||
|
<< endl;
|
||||||
|
log << "CR3 = " << hex << BX_CPU(0)->cr3 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener* bp)
|
void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener* bp)
|
||||||
{
|
{
|
||||||
|
fail::MemAccessListener ML(ANY_ADDR, MemAccessEvent::MEM_READWRITE);
|
||||||
|
ogzstream out("trace.pb");
|
||||||
|
ProtoOStream *os = new ProtoOStream(&out);
|
||||||
|
|
||||||
|
size_t count = 0, inst_accepted = 0, mem = 0, mem_valid = 0;
|
||||||
|
simtime_t prevtime = 0, currtime;
|
||||||
|
simtime_diff_t deltatime;
|
||||||
|
|
||||||
log << "restoring state" << endl;
|
log << "restoring state" << endl;
|
||||||
simulator.restore(L4SYS_STATE_FOLDER);
|
simulator.restore(L4SYS_STATE_FOLDER);
|
||||||
|
currtime = simulator.getTimerTicks();
|
||||||
|
|
||||||
log << "EIP = " << hex
|
log << "EIP = " << hex
|
||||||
<< simulator.getCPU(0).getInstructionPointer()
|
<< simulator.getCPU(0).getInstructionPointer()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
#ifdef L4SYS_FILTER_INSTRUCTIONS
|
|
||||||
ofstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary);
|
|
||||||
RangeSetInstructionFilter filtering(L4SYS_FILTER);
|
|
||||||
bp->setWatchInstructionPointer(ANY_ADDR);
|
|
||||||
|
|
||||||
fail::MemAccessListener ML(ANY_ADDR, MemAccessEvent::MEM_READWRITE);
|
|
||||||
if (!simulator.addListener(&ML)) {
|
if (!simulator.addListener(&ML)) {
|
||||||
log << "did not add memory listener..." << std::endl;
|
log << "did not add memory listener..." << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -254,16 +276,14 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener* bp)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t count = 0, inst_accepted = 0, mem = 0, mem_valid = 0;
|
#if L4SYS_FILTER_INSTRUCTIONS
|
||||||
|
ofstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary);
|
||||||
|
RangeSetInstructionFilter filtering(L4SYS_FILTER);
|
||||||
|
bp->setWatchInstructionPointer(ANY_ADDR);
|
||||||
|
|
||||||
map<address_t, unsigned> times_called_map;
|
map<address_t, unsigned> times_called_map;
|
||||||
bool injecting = false;
|
bool injecting = false;
|
||||||
|
|
||||||
ogzstream out("trace.pb");
|
|
||||||
ProtoOStream *os = new ProtoOStream(&out);
|
|
||||||
|
|
||||||
simtime_t prevtime = 0, currtime;
|
|
||||||
simtime_diff_t deltatime;
|
|
||||||
|
|
||||||
while (bp->getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) {
|
while (bp->getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) {
|
||||||
fail::BaseListener *res = simulator.resume();
|
fail::BaseListener *res = simulator.resume();
|
||||||
address_t curr_addr = 0;
|
address_t curr_addr = 0;
|
||||||
@ -272,10 +292,10 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener* bp)
|
|||||||
if (res == &ML) {
|
if (res == &ML) {
|
||||||
curr_addr = ML.getTriggerInstructionPointer();
|
curr_addr = ML.getTriggerInstructionPointer();
|
||||||
simulator.addListener(&ML);
|
simulator.addListener(&ML);
|
||||||
++mem;
|
if ((L4SYS_ADDRESS_SPACE_TRACE != ANY_ADDR) && (BX_CPU(0)->cr3 != L4SYS_ADDRESS_SPACE_TRACE)) {
|
||||||
if (BX_CPU(0)->cr3 != L4SYS_ADDRESS_SPACE) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
++mem;
|
||||||
} else if (res == bp) {
|
} else if (res == bp) {
|
||||||
curr_addr = bp->getTriggerInstructionPointer();
|
curr_addr = bp->getTriggerInstructionPointer();
|
||||||
assert(curr_addr == simulator.getCPU(0).getInstructionPointer());
|
assert(curr_addr == simulator.getCPU(0).getInstructionPointer());
|
||||||
@ -294,8 +314,15 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener* bp)
|
|||||||
injecting = false;
|
injecting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only trace if:
|
||||||
|
// 1) we are between FILTER_ENTRY and FILTER_EXIT, and
|
||||||
|
// 2) we have a valid instruction according to filter rules, and
|
||||||
|
// 3) we are in the TRACE address space
|
||||||
if (!injecting or
|
if (!injecting or
|
||||||
!filtering.isValidInstr(curr_addr, reinterpret_cast<char const*>(calculateInstructionAddress()))) {
|
!filtering.isValidInstr(curr_addr, reinterpret_cast<char const*>(calculateInstructionAddress()))
|
||||||
|
or
|
||||||
|
(BX_CPU(0)->cr3 != L4SYS_ADDRESS_SPACE_TRACE)
|
||||||
|
) {
|
||||||
//log << "connt..." << std::endl;
|
//log << "connt..." << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -358,22 +385,62 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener* bp)
|
|||||||
<< dec << count << " instructions; " << inst_accepted << " accepted" << endl;
|
<< dec << count << " instructions; " << inst_accepted << " accepted" << endl;
|
||||||
log << "mem accesses: " << mem << ", valid: " << mem_valid << std::endl;
|
log << "mem accesses: " << mem << ", valid: " << mem_valid << std::endl;
|
||||||
#else
|
#else
|
||||||
int count = 0;
|
bp->setWatchInstructionPointer(ANY_ADDR);
|
||||||
int ul = 0, kernel = 0;
|
while(bp->getTriggerInstructionPointer() != L4SYS_FUNC_EXIT)
|
||||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
{
|
||||||
for (; bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT; ++count) {
|
fail::BaseListener *res = simulator.resume();
|
||||||
simulator.addListenerAndResume(&bp);
|
address_t curr_addr = 0;
|
||||||
if (bp.getTriggerInstructionPointer() < 0xC0000000) {
|
|
||||||
ul++;
|
// XXX: See the API problem below!
|
||||||
} else {
|
if (res == &ML) {
|
||||||
kernel++;
|
curr_addr = ML.getTriggerInstructionPointer();
|
||||||
}
|
simulator.addListener(&ML);
|
||||||
|
if ((L4SYS_ADDRESS_SPACE_TRACE != ANY_ADDR) && (BX_CPU(0)->cr3 != L4SYS_ADDRESS_SPACE_TRACE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++mem;
|
||||||
|
} else if (res == bp) {
|
||||||
|
curr_addr = bp->getTriggerInstructionPointer();
|
||||||
|
assert(curr_addr == simulator.getCPU(0).getInstructionPointer());
|
||||||
|
simulator.addListener(bp);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr_addr < 0xC0000000) // XXX filter for kernel-only experiment
|
||||||
|
continue;
|
||||||
|
|
||||||
|
currtime = simulator.getTimerTicks();
|
||||||
|
deltatime = currtime - prevtime;
|
||||||
|
|
||||||
|
if (res == &ML) {
|
||||||
|
#if 0
|
||||||
|
log << "Memory event IP " << std::hex << ML.getTriggerInstructionPointer()
|
||||||
|
<< " @ " << ML.getTriggerAddress() << "("
|
||||||
|
<< ML.getTriggerAccessType() << "," << ML.getTriggerWidth()
|
||||||
|
<< ")" << std::endl;
|
||||||
|
#endif
|
||||||
|
++mem_valid;
|
||||||
|
|
||||||
|
Trace_Event te;
|
||||||
|
if (deltatime != 0) { te.set_time_delta(deltatime); };
|
||||||
|
te.set_ip(curr_addr);
|
||||||
|
te.set_memaddr(ML.getTriggerAddress());
|
||||||
|
te.set_accesstype( (ML.getTriggerAccessType() & MemAccessEvent::MEM_READ) ? te.READ : te.WRITE );
|
||||||
|
te.set_width(ML.getTriggerWidth());
|
||||||
|
os->writeMessage(&te);
|
||||||
|
} else if (res == bp) {
|
||||||
|
Trace_Event e;
|
||||||
|
if (deltatime != 0) { e.set_time_delta(deltatime); };
|
||||||
|
e.set_ip(curr_addr);
|
||||||
|
os->writeMessage(&e);
|
||||||
|
} else {
|
||||||
|
printf("Unknown res? %p\n", res);
|
||||||
|
}
|
||||||
|
prevtime = currtime;
|
||||||
}
|
}
|
||||||
log << "EIP = " << hex
|
|
||||||
<< simulator.getCPU(0).getInstructionPointer() << endl;
|
|
||||||
log << "test function calculation position reached after "
|
log << "test function calculation position reached after "
|
||||||
<< dec << count << " instructions; "
|
<< dec << count << " instructions; " << count << " accepted" << endl;
|
||||||
<< "ul: " << ul << ", kernel: " << kernel << endl;
|
log << "mem accesses: " << mem << ", valid: " << mem_valid << std::endl;
|
||||||
#endif
|
#endif
|
||||||
delete bp;
|
delete bp;
|
||||||
}
|
}
|
||||||
@ -495,16 +562,16 @@ void L4SysExperiment::setupFilteredBreakpoint(fail::BPSingleListener* bp, int in
|
|||||||
fail::BPSingleListener*
|
fail::BPSingleListener*
|
||||||
L4SysExperiment::prepareMemoryExperiment(int ip, int offset, int dataAddress)
|
L4SysExperiment::prepareMemoryExperiment(int ip, int offset, int dataAddress)
|
||||||
{
|
{
|
||||||
fail::BPSingleListener *bp = new BPSingleListener(0, L4SYS_ADDRESS_SPACE);
|
fail::BPSingleListener *bp = new BPSingleListener(0, L4SYS_ADDRESS_SPACE_TRACE);
|
||||||
log << "\033[34;1mMemory fault injection\033[0m at instruction " << std::hex << offset
|
log << "\033[34;1mMemory fault injection\033[0m at instruction " << std::hex << offset
|
||||||
<< ", ip " << ip << ", address " << dataAddress << std::endl;
|
<< ", ip " << ip << ", address " << dataAddress << std::endl;
|
||||||
|
|
||||||
#ifdef L4SYS_FILTER_INSTRUCTIONS
|
#if L4SYS_FILTER_INSTRUCTIONS
|
||||||
setupFilteredBreakpoint(bp, offset);
|
setupFilteredBreakpoint(bp, offset-1);
|
||||||
assert(bp->getWatchInstructionPointer() == (address_t)(ip & 0xFFFFFFFF));
|
assert(bp->getWatchInstructionPointer() == (address_t)(ip & 0xFFFFFFFF));
|
||||||
#else
|
#else
|
||||||
bp->setWatchInstructionPointer(ANY_ADDR);
|
bp->setWatchInstructionPointer(ANY_ADDR);
|
||||||
bp->setCounter(instr_offset);
|
bp->setCounter(offset);
|
||||||
#endif
|
#endif
|
||||||
return bp;
|
return bp;
|
||||||
}
|
}
|
||||||
@ -513,7 +580,7 @@ L4SysExperiment::prepareMemoryExperiment(int ip, int offset, int dataAddress)
|
|||||||
fail::BPSingleListener*
|
fail::BPSingleListener*
|
||||||
L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress)
|
L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress)
|
||||||
{
|
{
|
||||||
fail::BPSingleListener *bp = new BPSingleListener(0, L4SYS_ADDRESS_SPACE);
|
fail::BPSingleListener *bp = new BPSingleListener(0, L4SYS_ADDRESS_SPACE_TRACE);
|
||||||
|
|
||||||
int reg, regOffset;
|
int reg, regOffset;
|
||||||
reg = ((dataAddress >> 4) & 0xF) + 1; // regs start at 1
|
reg = ((dataAddress >> 4) & 0xF) + 1; // regs start at 1
|
||||||
@ -523,26 +590,36 @@ L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress)
|
|||||||
<< " reg data (" << reg << ", "
|
<< " reg data (" << reg << ", "
|
||||||
<< regOffset << ")" << std::endl;
|
<< regOffset << ")" << std::endl;
|
||||||
|
|
||||||
#ifdef L4SYS_FILTER_INSTRUCTIONS
|
#if L4SYS_FILTER_INSTRUCTIONS
|
||||||
setupFilteredBreakpoint(bp, offset);
|
setupFilteredBreakpoint(bp, offset-1);
|
||||||
|
log << bp->getWatchInstructionPointer() << std::endl;
|
||||||
|
log << ip << std::endl;
|
||||||
assert(bp->getWatchInstructionPointer() == (address_t)(ip & 0xFFFFFFFF));
|
assert(bp->getWatchInstructionPointer() == (address_t)(ip & 0xFFFFFFFF));
|
||||||
log << bp->getCounter() << std::endl;
|
log << bp->getCounter() << std::endl;
|
||||||
#else
|
#else
|
||||||
|
log << "Exp offset: " << offset << std::endl;
|
||||||
bp->setWatchInstructionPointer(ANY_ADDR);
|
bp->setWatchInstructionPointer(ANY_ADDR);
|
||||||
bp->setCounter(instr_offset);
|
bp->setCounter(offset);
|
||||||
#endif
|
#endif
|
||||||
return bp;
|
return bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void L4SysExperiment::doMemoryInjection(int address, int bit)
|
bool L4SysExperiment::doMemoryInjection(int address, int bit)
|
||||||
{
|
{
|
||||||
MemoryManager& mm = simulator.getMemoryManager();
|
MemoryManager& mm = simulator.getMemoryManager();
|
||||||
|
|
||||||
|
// XXX: evil, but I need to bail out if memory access is invalid
|
||||||
|
host_address_t addr = reinterpret_cast<BochsMemoryManager*>(&mm)->guestToHost(address);
|
||||||
|
if (addr == (host_address_t)ADDR_INV)
|
||||||
|
return false;
|
||||||
|
|
||||||
byte_t data = mm.getByte(address);
|
byte_t data = mm.getByte(address);
|
||||||
byte_t newdata = data ^ (1 << bit);
|
byte_t newdata = data ^ (1 << bit);
|
||||||
mm.setByte(address, newdata);
|
mm.setByte(address, newdata);
|
||||||
log << "[" << std::hex << address << "] " << (int)data
|
log << "[" << std::hex << address << "] " << (int)data
|
||||||
<< " -> " << (int)newdata << std::endl;
|
<< " -> " << (int)newdata << std::endl;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -571,15 +648,21 @@ bool L4SysExperiment::run()
|
|||||||
|
|
||||||
#if PREPARATION_STEP == 1
|
#if PREPARATION_STEP == 1
|
||||||
// STEP 1: run until interesting function starts, and save state
|
// STEP 1: run until interesting function starts, and save state
|
||||||
|
// -> needs L4SYS_ADDRESS_SPACE, because it runs until L4SYS_FUNC_ENTRY
|
||||||
startAndSaveInitState(new BPSingleListener(0, L4SYS_ADDRESS_SPACE));
|
startAndSaveInitState(new BPSingleListener(0, L4SYS_ADDRESS_SPACE));
|
||||||
#elif PREPARATION_STEP == 2
|
#elif PREPARATION_STEP == 2
|
||||||
// STEP 2: determine instructions executed
|
// STEP 2: determine instructions executed
|
||||||
collectInstructionTrace(new BPSingleListener(0, L4SYS_ADDRESS_SPACE));
|
collectInstructionTrace(new BPSingleListener(0, ANY_ADDR));
|
||||||
|
|
||||||
#elif PREPARATION_STEP == 3
|
#elif PREPARATION_STEP == 3
|
||||||
// STEP 3: determine the output of a "golden run"
|
// STEP 3: determine the output of a "golden run"
|
||||||
|
// -> golden run needs L4SYS_ADDRESS_SPACE as it breaks on
|
||||||
|
// L4SYS_FUNC_EXIT
|
||||||
goldenRun(new BPSingleListener(0, L4SYS_ADDRESS_SPACE));
|
goldenRun(new BPSingleListener(0, L4SYS_ADDRESS_SPACE));
|
||||||
|
|
||||||
|
#elif PREPARATION_STEP == 4
|
||||||
|
CR3run(new BPSingleListener(0));
|
||||||
|
|
||||||
#elif PREPARATION_STEP == 0
|
#elif PREPARATION_STEP == 0
|
||||||
// LAST STEP: The actual experiment.
|
// LAST STEP: The actual experiment.
|
||||||
validatePrerequisites();
|
validatePrerequisites();
|
||||||
@ -626,15 +709,25 @@ bool L4SysExperiment::run()
|
|||||||
fail::BaseListener *go = waitIOOrOther(true);
|
fail::BaseListener *go = waitIOOrOther(true);
|
||||||
assert(go == bp);
|
assert(go == bp);
|
||||||
|
|
||||||
log << "Hit BP. Start time " << now << ", new time " << simulator.getTimerTicks()
|
log << "Hit BP @ " << hex << bp->getTriggerInstructionPointer() << " " << bp->getWatchInstructionPointer()
|
||||||
|
<< " Start time " << now << ", new time " << simulator.getTimerTicks()
|
||||||
<< ", diff = " << simulator.getTimerTicks() - now << std::endl;
|
<< ", diff = " << simulator.getTimerTicks() - now << std::endl;
|
||||||
|
|
||||||
|
#if L4SYS_FILTER_INSTRUCTIONS
|
||||||
assert(bp->getTriggerInstructionPointer() == bp->getWatchInstructionPointer());
|
assert(bp->getTriggerInstructionPointer() == bp->getWatchInstructionPointer());
|
||||||
|
#endif
|
||||||
result->set_injection_ip(bp->getTriggerInstructionPointer());
|
result->set_injection_ip(bp->getTriggerInstructionPointer());
|
||||||
|
|
||||||
if (exp_type == param->msg.MEM) {
|
if (exp_type == param->msg.MEM) {
|
||||||
result->set_bit_offset(bit);
|
result->set_bit_offset(bit);
|
||||||
doMemoryInjection(param->msg.fsppilot().data_address(), bit);
|
log << "injection addr: "
|
||||||
|
<< std::hex << param->msg.fsppilot().data_address()
|
||||||
|
<< std::endl;
|
||||||
|
result->set_injection_address(param->msg.fsppilot().data_address());
|
||||||
|
if (!doMemoryInjection(param->msg.fsppilot().data_address(), bit))
|
||||||
|
{
|
||||||
|
terminateWithError("invalid mem access", 51, result);
|
||||||
|
}
|
||||||
} else if (exp_type == param->msg.GPRFLIP) {
|
} else if (exp_type == param->msg.GPRFLIP) {
|
||||||
int reg = (param->msg.fsppilot().data_address() >> 4) + 1;
|
int reg = (param->msg.fsppilot().data_address() >> 4) + 1;
|
||||||
result->set_register_offset(static_cast<L4SysProtoMsg_RegisterType>(reg));
|
result->set_register_offset(static_cast<L4SysProtoMsg_RegisterType>(reg));
|
||||||
@ -649,9 +742,18 @@ 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(instr_left);
|
/*
|
||||||
|
* Use hard-coded value for incomplete counter. We are currently looking at short-running pieces
|
||||||
|
* of code. This means that in the error case, where a lot of data is still to be printed to serial
|
||||||
|
* line, the benchmark does not complete this within <short-time> * <1.x> cycles. Instead, we use
|
||||||
|
* a frame large enough to catch some more output even at the end of a run.
|
||||||
|
*/
|
||||||
|
ev_incomplete.setCounter(2000000);
|
||||||
simulator.addListener(&ev_incomplete);
|
simulator.addListener(&ev_incomplete);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This timeout will always be at least one second - see calculateTimeout()
|
||||||
|
*/
|
||||||
TimerListener ev_timeout(calculateTimeout(instr_left));
|
TimerListener ev_timeout(calculateTimeout(instr_left));
|
||||||
simulator.addListener(&ev_timeout);
|
simulator.addListener(&ev_timeout);
|
||||||
log << "continue... (" << simulator.getListenerCount()
|
log << "continue... (" << simulator.getListenerCount()
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
#include "util/Logger.hpp"
|
#include "util/Logger.hpp"
|
||||||
#include "sal/Listener.hpp"
|
#include "sal/Listener.hpp"
|
||||||
|
|
||||||
|
#include "l4sys.pb.h"
|
||||||
|
|
||||||
class L4SysExperimentData;
|
class L4SysExperimentData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,12 +109,13 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Send back the experiment parameter set with a description of the error.
|
* Send back the experiment parameter set with a description of the error.
|
||||||
*/
|
*/
|
||||||
void terminateWithError(std::string details, int reason);
|
void terminateWithError(std::string details, int reason, L4SysProtoMsg_Result*);
|
||||||
/**
|
/**
|
||||||
* Run until L4SYS_FUNC_ENTRY and save state (experiment preparation,
|
* Run until L4SYS_FUNC_ENTRY and save state (experiment preparation,
|
||||||
* phase 1)
|
* phase 1)
|
||||||
*/
|
*/
|
||||||
void startAndSaveInitState(fail::BPSingleListener* bp);
|
void startAndSaveInitState(fail::BPSingleListener* bp);
|
||||||
|
void CR3run(fail::BPSingleListener *bp);
|
||||||
/**
|
/**
|
||||||
* Collect list of executed instructions, considering instruction
|
* Collect list of executed instructions, considering instruction
|
||||||
* filtering if configured (experiment preparation, phase 2).
|
* filtering if configured (experiment preparation, phase 2).
|
||||||
@ -153,7 +156,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Perform memory bit flip at (address, bit).
|
* Perform memory bit flip at (address, bit).
|
||||||
*/
|
*/
|
||||||
void doMemoryInjection(int address, int bit);
|
bool doMemoryInjection(int address, int bit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform register bit flip in the specified (register, bit)
|
* Perform register bit flip in the specified (register, bit)
|
||||||
|
|||||||
@ -5,17 +5,24 @@
|
|||||||
#define MAX_INSTR_BYTES 15
|
#define MAX_INSTR_BYTES 15
|
||||||
|
|
||||||
// the bounds of the program (space, instructions and time)
|
// the bounds of the program (space, instructions and time)
|
||||||
#define L4SYS_ADDRESS_SPACE 0x1fd4c000
|
// client
|
||||||
|
#define L4SYS_ADDRESS_SPACE 0x1fd4c000
|
||||||
|
// master
|
||||||
|
//#define L4SYS_ADDRESS_SPACE_TRACE 0x1fd4c000
|
||||||
|
// vcpu task
|
||||||
|
#define L4SYS_ADDRESS_SPACE_TRACE 0x1fd5a000
|
||||||
|
//#define L4SYS_ADDRESS_SPACE_TRACE L4SYS_ADDRESS_SPACE
|
||||||
|
|
||||||
// FUNC_{ENTRY,EXIT} specifies the range that needs to
|
// FUNC_{ENTRY,EXIT} specifies the range that needs to
|
||||||
// be captured to log program output properly
|
// be captured to log program output properly
|
||||||
#define L4SYS_FUNC_ENTRY 0x01000350
|
#define L4SYS_FUNC_ENTRY 0x60002052
|
||||||
#define L4SYS_FUNC_EXIT 0x010004bd
|
//#define L4SYS_FUNC_ENTRY 0x10000
|
||||||
|
#define L4SYS_FUNC_EXIT 0x600020ae
|
||||||
// FILTER_{ENTRY,EXIT} specifies the range that injections
|
// FILTER_{ENTRY,EXIT} specifies the range that injections
|
||||||
// should be carried out on (should be a subset of the above)
|
// should be carried out on (should be a subset of the above)
|
||||||
// and only works with FILTER_INSTRUCTIONS turned on
|
// and only works with FILTER_INSTRUCTIONS turned on
|
||||||
#define L4SYS_FILTER_ENTRY 0x0100042e
|
#define L4SYS_FILTER_ENTRY 0x60002067
|
||||||
#define L4SYS_FILTER_EXIT 0x01000434
|
#define L4SYS_FILTER_EXIT 0x60002075
|
||||||
|
|
||||||
// select instruction filtering
|
// select instruction filtering
|
||||||
// XXX: this should be always on and the code should be
|
// XXX: this should be always on and the code should be
|
||||||
@ -24,8 +31,8 @@
|
|||||||
#define L4SYS_FILTER_INSTRUCTIONS 1
|
#define L4SYS_FILTER_INSTRUCTIONS 1
|
||||||
|
|
||||||
// kernel: 2377547, userland: 79405472
|
// kernel: 2377547, userland: 79405472
|
||||||
#define L4SYS_NUMINSTR 2988
|
#define L4SYS_NUMINSTR 141
|
||||||
#define L4SYS_TOTINSTR 67811
|
#define L4SYS_TOTINSTR 154205
|
||||||
#define L4SYS_BOCHS_IPS 5000000
|
#define L4SYS_BOCHS_IPS 5000000
|
||||||
|
|
||||||
// several file names used
|
// several file names used
|
||||||
@ -38,6 +45,6 @@
|
|||||||
// flags
|
// flags
|
||||||
// 0 - preparation complete
|
// 0 - preparation complete
|
||||||
// >0 - next step to execute
|
// >0 - next step to execute
|
||||||
#define PREPARATION_STEP 2
|
#define PREPARATION_STEP 0
|
||||||
|
|
||||||
#endif // __L4SYS_EXPERIMENT_INFO_HPP__
|
#endif // __L4SYS_EXPERIMENT_INFO_HPP__
|
||||||
|
|||||||
Reference in New Issue
Block a user