From 32efc604e79c426ef84b8deee976b51a84954aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20D=C3=B6bel?= Date: Wed, 11 Sep 2013 09:06:54 +0200 Subject: [PATCH 1/8] use MEM FI type Change-Id: If149c4fdeaaf6fef96a99d6fe2a424d8ad0f2916 --- src/experiments/l4-sys/campaign.cc | 3 ++- src/experiments/l4-sys/l4sys.proto | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/experiments/l4-sys/campaign.cc b/src/experiments/l4-sys/campaign.cc index e6a62a1a..3b55e84c 100644 --- a/src/experiments/l4-sys/campaign.cc +++ b/src/experiments/l4-sys/campaign.cc @@ -158,6 +158,7 @@ void L4SysCampaign::cb_send_pilot(DatabaseCampaignMessage p) #endif L4SysExperimentData *d = new L4SysExperimentData; d->msg.mutable_fsppilot()->CopyFrom(p); - d->msg.set_exp_type(d->msg.GPRFLIP); + //d->msg.set_exp_type(d->msg.GPRFLIP); + d->msg.set_exp_type(d->msg.MEM); campaignmanager.addParam(d); } diff --git a/src/experiments/l4-sys/l4sys.proto b/src/experiments/l4-sys/l4sys.proto index 3f39af05..83cf3685 100644 --- a/src/experiments/l4-sys/l4sys.proto +++ b/src/experiments/l4-sys/l4sys.proto @@ -8,6 +8,7 @@ message L4SysProtoMsg { RATFLIP = 2; IDCFLIP = 3; ALUINSTR = 4; + MEM = 5; } // registers From 20a9904032ea4b42a53b84f609311bda9b959493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20D=C3=B6bel?= Date: Wed, 11 Sep 2013 09:07:44 +0200 Subject: [PATCH 2/8] start memory experiment Change-Id: Ice7921a02f899c7381d15ead10b27e21df7019fb --- src/experiments/l4-sys/experiment.cc | 38 ++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc index 09aa6f41..a2738e6c 100644 --- a/src/experiments/l4-sys/experiment.cc +++ b/src/experiments/l4-sys/experiment.cc @@ -67,7 +67,8 @@ BaseListener* L4SysExperiment::waitIOOrOther(bool clear_output) { while (true) { simulator.addListener(&ev_ioport); ev = simulator.resume(); - simulator.removeListener(&ev_ioport); + //log << "hello " << simulator.getListenerCount() << std::endl; + //simulator.removeListener(&ev_ioport); if (ev == &ev_ioport) { currentOutput += ev_ioport.getData(); } else { @@ -252,8 +253,6 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) } size_t count = 0, inst_accepted = 0, mem = 0, mem_valid = 0; - simtime_t prevtime = 0, currtime; - simtime_diff_t deltatime; map times_called_map; bool injecting = false; @@ -278,9 +277,6 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) ++count; } - currtime = simulator.getTimerTicks(); - deltatime = currtime - prevtime; - unsigned times_called = times_called_map[curr_addr]; ++times_called; times_called_map[curr_addr] = times_called; @@ -309,7 +305,7 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) ++mem_valid; Trace_Event te; - if (deltatime != 0) { te.set_time_delta(deltatime); }; + te.set_time_delta(1); te.set_ip(curr_addr); te.set_memaddr(ML.getTriggerAddress()); te.set_accesstype( (ML.getTriggerAccessType() & MemAccessEvent::MEM_READ) ? te.READ : te.WRITE ); @@ -336,7 +332,7 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) // the generic *-trace tools // XXX: need to log CR3 if we want multiple binaries here Trace_Event e; - if (deltatime != 0) { e.set_time_delta(deltatime); }; + e.set_time_delta(1); e.set_ip(curr_addr); os_instr->writeMessage(&e); } else { @@ -455,6 +451,32 @@ bool L4SysExperiment::run() { int instr_offset = param->msg.fsppilot().injection_instr(); int regData = param->msg.fsppilot().data_address(); + + if (exp_type == param->msg.MEM) { + currentOutput.clear(); + currentOutput.reserve(teststruct.st_size); + simulator.clearListeners(); + + log << "Memory fault injection at instruction " << std::hex << instr_offset + << ", ip " << param->msg.fsppilot().injection_instr_absolute() << ", address " + << regData << std::endl; + bp.setWatchInstructionPointer( + param->msg.fsppilot().injection_instr_absolute() & 0xFFFFFFFF); + bp.setCounter(1); + log << bp.getWatchInstructionPointer() << " - " << bp.getCounter() << std::endl; + + simulator.restore(L4SYS_STATE_FOLDER); + + simtime_t now = simulator.getTimerTicks(); + simulator.addListener(&bp); + //and log the output + waitIOOrOther(true); + log << "Hit BP. Start time " << now << ", new time " << simulator.getTimerTicks() + << ", diff = " << simulator.getTimerTicks() - now << std::endl; + //assert(ev == &bp); + exit(1); + } + int reg, width, offset; reg = ((regData >> 8) & 0xF) + 1; // regs start at 1 width = (regData >> 4) & 0xF; From 0b2ab41c2f67f603a95250a5db83a6f0b541f2f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20D=C3=B6bel?= Date: Wed, 11 Sep 2013 11:01:00 +0200 Subject: [PATCH 3/8] first working mem experiment Change-Id: I928ee0c38f12f6dfe3f661ee60cccad11f35ad6a --- src/experiments/l4-sys/experiment.cc | 70 +++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc index a2738e6c..e0c1cf13 100644 --- a/src/experiments/l4-sys/experiment.cc +++ b/src/experiments/l4-sys/experiment.cc @@ -474,7 +474,73 @@ bool L4SysExperiment::run() { log << "Hit BP. Start time " << now << ", new time " << simulator.getTimerTicks() << ", diff = " << simulator.getTimerTicks() - now << std::endl; //assert(ev == &bp); - exit(1); + for (unsigned bit_offset = 0; bit_offset < 8; ++bit_offset) { + currentOutput.clear(); + currentOutput.reserve(teststruct.st_size); + simulator.clearListeners(); + + log << "restoring state" << endl; + simulator.restore(L4SYS_STATE_FOLDER); + log << simulator.getCPU(0).getInstructionPointer() + << " injecting bit " << bit_offset << std::endl; + + L4SysProtoMsg_Result *result = param->msg.add_result(); + result->set_instr_offset(instr_offset); + result->set_bit_offset(bit_offset); + + MemoryManager& mm = simulator.getMemoryManager(); + byte_t data = mm.getByte(regData); + byte_t newdata = data ^ (1 << bit_offset); + mm.setByte(regData, newdata); + log << (int)data << " -> " << (int)newdata << std::endl; + + BPSingleListener ev_done(L4SYS_FUNC_EXIT, L4SYS_ADDRESS_SPACE); + simulator.addListener(&ev_done); + + unsigned instr_left = L4SYS_TOTINSTR - instr_offset; // XXX offset is in NUMINSTR, TOTINSTR is higher + BPSingleListener ev_incomplete(ANY_ADDR, L4SYS_ADDRESS_SPACE); + ev_incomplete.setCounter(static_cast(instr_left * 1.1)); + simulator.addListener(&ev_incomplete); + + TimerListener ev_timeout(calculateTimeout(instr_left)); + simulator.addListener(&ev_timeout); + + //do not discard output recorded so far + BaseListener *ev = waitIOOrOther(false); + + /* copying a string object that contains control sequences + * unfortunately does not work with the library I am using, + * which is why output is passed on as C string and + * the string compare is done on C strings + */ + if (ev == &ev_done) { + if (strcmp(currentOutput.c_str(), golden_run.c_str()) == 0) { + log << "Result DONE" << endl; + result->set_resulttype(param->msg.DONE); + } else { + log << "Result WRONG" << endl; + result->set_resulttype(param->msg.WRONG); + result->set_output(sanitised(currentOutput.c_str())); + } + } else if (ev == &ev_incomplete) { + log << "Result INCOMPLETE" << endl; + result->set_resulttype(param->msg.INCOMPLETE); + result->set_resultdata(simulator.getCPU(0).getInstructionPointer()); + result->set_output(sanitised(currentOutput.c_str())); + } else if (ev == &ev_timeout) { + log << "Result TIMEOUT" << endl; + result->set_resulttype(param->msg.TIMEOUT); + result->set_resultdata(simulator.getCPU(0).getInstructionPointer()); + result->set_output(sanitised(currentOutput.c_str())); + } else { + log << "Result WTF?" << endl; + stringstream ss; + ss << "eventid " << ev; + terminateWithError(ss.str(), 50); + } + } + m_jc.sendResult(*param); + terminate(0); } int reg, width, offset; @@ -496,7 +562,7 @@ bool L4SysExperiment::run() { L4SysProtoMsg_Result *result = param->msg.add_result(); result->set_instr_offset(instr_offset); - result->set_bit_offset(bit_offset + 8 * offset); + result->set_bit_offset(bit_offset); result->set_register_offset(static_cast(reg)); // restore experiment state From 8caa63397a1685005e1b7f2d3b3fedc00caa6ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20D=C3=B6bel?= Date: Wed, 11 Sep 2013 16:17:12 +0200 Subject: [PATCH 4/8] L4Sys: refactoring * more more stuff into functions * try to have generic experiment code only once Change-Id: I4f037bd972243665a10941fcc3607f015b0bb1f9 --- src/experiments/l4-sys/experiment.cc | 556 ++++++++++++-------------- src/experiments/l4-sys/experiment.hpp | 15 +- 2 files changed, 273 insertions(+), 298 deletions(-) diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc index e0c1cf13..91ed6fb9 100644 --- a/src/experiments/l4-sys/experiment.cc +++ b/src/experiments/l4-sys/experiment.cc @@ -215,21 +215,22 @@ void L4SysExperiment::terminateWithError(string details, int reason) { } -void L4SysExperiment::startAndSaveInitState(fail::BPSingleListener& bp) +void L4SysExperiment::startAndSaveInitState(fail::BPSingleListener* bp) { - bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY); - simulator.addListenerAndResume(&bp); + bp->setWatchInstructionPointer(L4SYS_FUNC_ENTRY); + simulator.addListenerAndResume(bp); log << "test function entry reached, saving state" << endl; - log << "EIP: expected " << hex << bp.getTriggerInstructionPointer() + log << "EIP: expected " << hex << bp->getTriggerInstructionPointer() << " and actually got " << simulator.getCPU(0).getInstructionPointer() << endl; log << "check the source code if the two instruction pointers are not equal" << endl; simulator.save(L4SYS_STATE_FOLDER); + delete bp; } -void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) +void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener* bp) { log << "restoring state" << endl; simulator.restore(L4SYS_STATE_FOLDER); @@ -240,14 +241,14 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) #ifdef L4SYS_FILTER_INSTRUCTIONS ofstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary); RangeSetInstructionFilter filtering(L4SYS_FILTER); - bp.setWatchInstructionPointer(ANY_ADDR); + bp->setWatchInstructionPointer(ANY_ADDR); fail::MemAccessListener ML(ANY_ADDR, MemAccessEvent::MEM_READWRITE); if (!simulator.addListener(&ML)) { log << "did not add memory listener..." << std::endl; exit(1); } - if (!simulator.addListener(&bp)) { + if (!simulator.addListener(bp)) { log << "did not add breakpoint listener..." << std::endl; exit(1); } @@ -256,12 +257,10 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) map times_called_map; bool injecting = false; - ogzstream out_instr("trace_inst.pb"); - ogzstream out_mem("trace_mem.pb"); - ProtoOStream *os_instr = new ProtoOStream(&out_instr); - ProtoOStream *os_mem = new ProtoOStream(&out_mem); + ogzstream out("trace.pb"); + ProtoOStream *os = new ProtoOStream(&out); - while (bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) { + while (bp->getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) { fail::BaseListener *res = simulator.resume(); address_t curr_addr = 0; @@ -270,16 +269,17 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) curr_addr = ML.getTriggerInstructionPointer(); simulator.addListener(&ML); ++mem; - } else if (res == &bp) { - curr_addr = bp.getTriggerInstructionPointer(); + } else if (res == bp) { + curr_addr = bp->getTriggerInstructionPointer(); assert(curr_addr == simulator.getCPU(0).getInstructionPointer()); - simulator.addListener(&bp); + simulator.addListener(bp); ++count; } - unsigned times_called = times_called_map[curr_addr]; - ++times_called; - times_called_map[curr_addr] = times_called; + simtime_t prevtime = 0, currtime; + simtime_diff_t deltatime; + currtime = simulator.getTimerTicks(); + deltatime = currtime - prevtime; if (curr_addr == L4SYS_FILTER_ENTRY) { injecting = true; @@ -305,13 +305,17 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) ++mem_valid; Trace_Event te; - te.set_time_delta(1); + 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_mem->writeMessage(&te); - } else if (res == &bp) { + os->writeMessage(&te); + } else if (res == bp) { + unsigned times_called = times_called_map[curr_addr]; + ++times_called; + times_called_map[curr_addr] = times_called; + //log << "breakpoint event" << std::endl; // now check if we want to add the instruction for fault injection ++inst_accepted; @@ -332,12 +336,13 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) // the generic *-trace tools // XXX: need to log CR3 if we want multiple binaries here Trace_Event e; - e.set_time_delta(1); + if (deltatime != 0) { e.set_time_delta(deltatime); }; e.set_ip(curr_addr); - os_instr->writeMessage(&e); + os->writeMessage(&e); } else { printf("Unknown res? %p\n", res); } + prevtime = currtime; //short sanity check //log << "continue..." << std::endl; @@ -365,9 +370,10 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp) << dec << count << " instructions; " << "ul: " << ul << ", kernel: " << kernel << endl; #endif + delete bp; } -void L4SysExperiment::goldenRun(fail::BPSingleListener& bp) +void L4SysExperiment::goldenRun(fail::BPSingleListener* bp) { log << "restoring state" << endl; simulator.restore(L4SYS_STATE_FOLDER); @@ -377,10 +383,10 @@ void L4SysExperiment::goldenRun(fail::BPSingleListener& bp) std::string golden_run; ofstream golden_run_file(L4SYS_CORRECT_OUTPUT); - bp.setWatchInstructionPointer(L4SYS_FUNC_EXIT); - simulator.addListener(&bp); + bp->setWatchInstructionPointer(L4SYS_FUNC_EXIT); + simulator.addListener(bp); BaseListener* ev = waitIOOrOther(true); - if (ev == &bp) { + if (ev == bp) { golden_run.assign(currentOutput.c_str()); golden_run_file << currentOutput.c_str(); log << "Output successfully logged!" << endl; @@ -395,50 +401,12 @@ void L4SysExperiment::goldenRun(fail::BPSingleListener& bp) log << "saving output generated during normal execution" << endl; golden_run_file.close(); + delete bp; } -bool L4SysExperiment::run() { - BPSingleListener bp(0, L4SYS_ADDRESS_SPACE); - srand(time(NULL)); - - log << "startup" << endl; - -#if PREPARATION_STEP == 1 - // STEP 1: run until interesting function starts, and save state - startAndSaveInitState(bp); -#elif PREPARATION_STEP == 2 - // STEP 2: determine instructions executed - collectInstructionTrace(bp); - -#elif PREPARATION_STEP == 3 - // STEP 3: determine the output of a "golden run" - goldenRun(bp); - -#elif PREPARATION_STEP == 0 - // LAST STEP: The actual experiment. - struct stat teststruct; - if (stat(L4SYS_STATE_FOLDER, &teststruct) == -1 || - stat(L4SYS_CORRECT_OUTPUT, &teststruct) == -1) { - log << "Important data missing - call \"prepare\" first." << endl; - terminate(10); - } - - // Read the golden run output for validation purposes - std::string golden_run; - ifstream golden_run_file(L4SYS_CORRECT_OUTPUT); - - if (!golden_run_file.good()) { - log << "Could not open file " << L4SYS_CORRECT_OUTPUT << endl; - terminate(20); - } - golden_run.reserve(teststruct.st_size); - - golden_run.assign((istreambuf_iterator(golden_run_file)), - istreambuf_iterator()); - - golden_run_file.close(); - +void L4SysExperiment::getJobParameters() +{ // get the experiment parameters log << "asking job server for experiment parameters" << endl; if (!m_jc.getParam(*param)) { @@ -446,203 +414,250 @@ bool L4SysExperiment::run() { // communicate that we were told to die terminate(1); } +} + + +void L4SysExperiment::validatePrerequisites() +{ + struct stat teststruct; + if (stat(L4SYS_STATE_FOLDER, &teststruct) == -1 || + stat(L4SYS_CORRECT_OUTPUT, &teststruct) == -1) { + log << "Important data missing - call \"prepare\" first." << endl; + terminate(10); + } +} + + +void L4SysExperiment::readGoldenRun(std::string& target) +{ + ifstream golden_run_file(L4SYS_CORRECT_OUTPUT); + + if (!golden_run_file.good()) { + log << "Could not open file " << L4SYS_CORRECT_OUTPUT << endl; + terminate(20); + } + + target.assign((istreambuf_iterator(golden_run_file)), + istreambuf_iterator()); + + golden_run_file.close(); +} + + +fail::BPSingleListener* +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); + + if (!instr_list_file.good()) { + log << "Missing instruction trace" << endl; + terminate(21); + } + + TraceInstr curr_instr; + instr_list_file.seekg(offset * sizeof(TraceInstr)); + log << instr_list_file.eof() << " " << instr_list_file.bad() << " " + << instr_list_file.fail() << endl; + if (instr_list_file.eof()) { + log << "Job parameters indicate position outside the traced instruction list." << endl; + terminate(1); + } + instr_list_file.read(reinterpret_cast(&curr_instr), sizeof(TraceInstr)); + instr_list_file.close(); + + log << "setting watchpoint at " << hex << curr_instr.trigger_addr << endl; + bp->setWatchInstructionPointer(curr_instr.trigger_addr); + log << "setting bp counter " << hex << curr_instr.bp_counter << endl; + bp->setCounter(curr_instr.bp_counter); +#else + bp->setWatchInstructionPointer(ANY_ADDR); + bp->setCounter(instr_offset); +#endif + return bp; +} + + +void L4SysExperiment::doMemoryInjection(int address, int bit) +{ + MemoryManager& mm = simulator.getMemoryManager(); + byte_t data = mm.getByte(address); + byte_t newdata = data ^ (1 << bit); + mm.setByte(address, newdata); + log << "[" << std::hex << address << "] " << (int)data + << " -> " << (int)newdata << std::endl; +} + + +void L4SysExperiment::doRegisterInjection(int regDesc, int bit) +{ + int reg, width, offset; + reg = ((regDesc >> 8) & 0xF) + 1; // regs start at 1 + width = (regDesc >> 4) & 0xF; + offset = regDesc & 0xF; + + ConcreteCPU& cpu = simulator.getCPU(0); + Register *reg_target = cpu.getRegister(reg - 1); + regdata_t data = cpu.getRegisterContent(reg_target); + regdata_t newdata = data ^ (1 << (bit + 8 * offset)); + cpu.setRegisterContent(reg_target, newdata); + log << "Reg[" << reg << "]: " << std::hex << data << " -> " + << newdata << std::endl; +} + + +bool L4SysExperiment::run() +{ + BPSingleListener *bp = 0; + srand(time(NULL)); + + log << "Starting L4Sys Experiment, phase " << PREPARATION_STEP << endl; + +#if PREPARATION_STEP == 1 + // STEP 1: run until interesting function starts, and save state + startAndSaveInitState(new BPSingleListener(0, L4SYS_ADDRESS_SPACE)); +#elif PREPARATION_STEP == 2 + // STEP 2: determine instructions executed + collectInstructionTrace(new BPSingleListener(0, L4SYS_ADDRESS_SPACE)); + +#elif PREPARATION_STEP == 3 + // STEP 3: determine the output of a "golden run" + goldenRun(new BPSingleListener(0, L4SYS_ADDRESS_SPACE)); + +#elif PREPARATION_STEP == 0 + // LAST STEP: The actual experiment. + validatePrerequisites(); + + // Read the golden run output for validation purposes + std::string golden_run; + readGoldenRun(golden_run); + + getJobParameters(); int exp_type = param->msg.exp_type(); int instr_offset = param->msg.fsppilot().injection_instr(); int regData = param->msg.fsppilot().data_address(); - if (exp_type == param->msg.MEM) { - currentOutput.clear(); - currentOutput.reserve(teststruct.st_size); - simulator.clearListeners(); - - log << "Memory fault injection at instruction " << std::hex << instr_offset - << ", ip " << param->msg.fsppilot().injection_instr_absolute() << ", address " - << regData << std::endl; - bp.setWatchInstructionPointer( - param->msg.fsppilot().injection_instr_absolute() & 0xFFFFFFFF); - bp.setCounter(1); - log << bp.getWatchInstructionPointer() << " - " << bp.getCounter() << std::endl; - - simulator.restore(L4SYS_STATE_FOLDER); - - simtime_t now = simulator.getTimerTicks(); - simulator.addListener(&bp); - //and log the output - waitIOOrOther(true); - log << "Hit BP. Start time " << now << ", new time " << simulator.getTimerTicks() - << ", diff = " << simulator.getTimerTicks() - now << std::endl; - //assert(ev == &bp); - for (unsigned bit_offset = 0; bit_offset < 8; ++bit_offset) { - currentOutput.clear(); - currentOutput.reserve(teststruct.st_size); - simulator.clearListeners(); - - log << "restoring state" << endl; - simulator.restore(L4SYS_STATE_FOLDER); - log << simulator.getCPU(0).getInstructionPointer() - << " injecting bit " << bit_offset << std::endl; - - L4SysProtoMsg_Result *result = param->msg.add_result(); - result->set_instr_offset(instr_offset); - result->set_bit_offset(bit_offset); - - MemoryManager& mm = simulator.getMemoryManager(); - byte_t data = mm.getByte(regData); - byte_t newdata = data ^ (1 << bit_offset); - mm.setByte(regData, newdata); - log << (int)data << " -> " << (int)newdata << std::endl; - - BPSingleListener ev_done(L4SYS_FUNC_EXIT, L4SYS_ADDRESS_SPACE); - simulator.addListener(&ev_done); - - unsigned instr_left = L4SYS_TOTINSTR - instr_offset; // XXX offset is in NUMINSTR, TOTINSTR is higher - BPSingleListener ev_incomplete(ANY_ADDR, L4SYS_ADDRESS_SPACE); - ev_incomplete.setCounter(static_cast(instr_left * 1.1)); - simulator.addListener(&ev_incomplete); - - TimerListener ev_timeout(calculateTimeout(instr_left)); - simulator.addListener(&ev_timeout); - - //do not discard output recorded so far - BaseListener *ev = waitIOOrOther(false); - - /* copying a string object that contains control sequences - * unfortunately does not work with the library I am using, - * which is why output is passed on as C string and - * the string compare is done on C strings - */ - if (ev == &ev_done) { - if (strcmp(currentOutput.c_str(), golden_run.c_str()) == 0) { - log << "Result DONE" << endl; - result->set_resulttype(param->msg.DONE); - } else { - log << "Result WRONG" << endl; - result->set_resulttype(param->msg.WRONG); - result->set_output(sanitised(currentOutput.c_str())); - } - } else if (ev == &ev_incomplete) { - log << "Result INCOMPLETE" << endl; - result->set_resulttype(param->msg.INCOMPLETE); - result->set_resultdata(simulator.getCPU(0).getInstructionPointer()); - result->set_output(sanitised(currentOutput.c_str())); - } else if (ev == &ev_timeout) { - log << "Result TIMEOUT" << endl; - result->set_resulttype(param->msg.TIMEOUT); - result->set_resultdata(simulator.getCPU(0).getInstructionPointer()); - result->set_output(sanitised(currentOutput.c_str())); - } else { - log << "Result WTF?" << endl; - stringstream ss; - ss << "eventid " << ev; - terminateWithError(ss.str(), 50); - } - } - m_jc.sendResult(*param); - terminate(0); + bp = prepareMemoryExperiment(param->msg.fsppilot().injection_instr_absolute(), + param->msg.fsppilot().injection_instr(), + param->msg.fsppilot().data_address()); + } else if (exp_type == param->msg.GPRFLIP) { + bp = prepareRegisterExperiment(param->msg.fsppilot().injection_instr_absolute(), + param->msg.fsppilot().injection_instr(), + param->msg.fsppilot().data_address()); + } else { + log << "Unsupported experiment type: " << exp_type << std::endl; + terminate(1); } - int reg, width, offset; - reg = ((regData >> 8) & 0xF) + 1; // regs start at 1 - width = (regData >> 4) & 0xF; - offset = regData & 0xF; + assert(bp); - log << "Inject type " << exp_type << " at instr. offset " << instr_offset - << " reg data (" << reg << ", " << width << ", " - << offset << ")" << std::endl; - - /* Each experiment message stands for 8 bits to be tested */ - for (unsigned bit_offset = 0; bit_offset < 8; ++bit_offset) { - - //the generated output probably has a similar length - currentOutput.clear(); - currentOutput.reserve(teststruct.st_size); - simulator.clearListeners(); + for (unsigned bit = 0; bit < 8; ++bit) { L4SysProtoMsg_Result *result = param->msg.add_result(); result->set_instr_offset(instr_offset); - result->set_bit_offset(bit_offset); - result->set_register_offset(static_cast(reg)); - // restore experiment state - log << "restoring state" << endl; - simulator.restore(L4SYS_STATE_FOLDER); - log << "EIP = " << hex << simulator.getCPU(0).getInstructionPointer() << endl; + simulator.clearListeners(); -#ifdef L4SYS_FILTER_INSTRUCTIONS - // XXX still needed??? - ifstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary); + log << "Bit " << bit << ", restoring state." << endl; + simulator.restore(L4SYS_STATE_FOLDER); + log << " ... EIP = " << std::hex << simulator.getCPU(0).getInstructionPointer() << std::endl; + + simulator.addListener(bp); + + simtime_t now = simulator.getTimerTicks(); + fail::BaseListener *go = waitIOOrOther(true); + assert(go == bp); + + log << "Hit BP. Start time " << now << ", new time " << simulator.getTimerTicks() + << ", diff = " << simulator.getTimerTicks() - now << std::endl; - if (!instr_list_file.good()) { - log << "Missing instruction trace" << endl; - terminate(21); - } + assert(bp->getTriggerInstructionPointer() == bp->getWatchInstructionPointer()); + result->set_injection_ip(bp->getTriggerInstructionPointer()); + + if (exp_type == param->msg.MEM) { + result->set_bit_offset(bit); + doMemoryInjection(param->msg.fsppilot().data_address(), bit); + } else if (exp_type == param->msg.GPRFLIP) { + result->set_bit_offset(bit + 8 * (param->msg.fsppilot().data_address() & 0xF)); + doRegisterInjection(param->msg.fsppilot().data_address(), bit); + } else { + log << "doing nothing for experiment type " << exp_type << std::endl; + } + + BPSingleListener ev_done(L4SYS_FUNC_EXIT, L4SYS_ADDRESS_SPACE); + simulator.addListener(&ev_done); - TraceInstr curr_instr; - instr_list_file.seekg(instr_offset * sizeof(TraceInstr)); - log << instr_list_file.eof() << " " << instr_list_file.bad() << " " - << instr_list_file.fail() << endl; - if (instr_list_file.eof()) { - log << "Job parameters indicate position outside the traced instruction list." << endl; - terminate(1); - } - instr_list_file.read(reinterpret_cast(&curr_instr), sizeof(TraceInstr)); - instr_list_file.close(); + unsigned instr_left = L4SYS_TOTINSTR - instr_offset; // XXX offset is in NUMINSTR, TOTINSTR is higher + BPSingleListener ev_incomplete(ANY_ADDR, L4SYS_ADDRESS_SPACE); + ev_incomplete.setCounter(static_cast(instr_left * 1.1)); + simulator.addListener(&ev_incomplete); - log << "setting watchpoint at " << hex << curr_instr.trigger_addr << endl; - bp.setWatchInstructionPointer(curr_instr.trigger_addr); - log << "setting bp counter " << hex << curr_instr.bp_counter << endl; - bp.setCounter(curr_instr.bp_counter); -#else - bp.setWatchInstructionPointer(ANY_ADDR); - bp.setCounter(instr_offset); -#endif - simulator.addListener(&bp); - //and log the output - waitIOOrOther(true); + TimerListener ev_timeout(calculateTimeout(instr_left)); + simulator.addListener(&ev_timeout); - // note at what IP we will do the injection - address_t testIP = param->msg.fsppilot().injection_instr_absolute() & 0xFFFFFFFF; - address_t injection_ip = - simulator.getCPU(0).getInstructionPointer(); - result->set_injection_ip(injection_ip); - log << std::hex << "testIP " << testIP << " <-> " << injection_ip - << " inject_ip_abs" << std::endl; - if (testIP != injection_ip) { - stringstream ss; - ss << std::hex << "Test IP " << testIP << " does not match injection IP " - << injection_ip << std::endl; - terminateWithError(ss.str(), 19); - } + //do not discard output recorded so far + BaseListener *ev = waitIOOrOther(false); -#ifdef L4SYS_FILTER_INSTRUCTIONS - // only works if we filter instructions - // sanity check (only works if we're working with an instruction trace) - if (injection_ip != curr_instr.trigger_addr) { - stringstream ss; - ss << "SANITY CHECK FAILED: " << injection_ip << " != " - << curr_instr.trigger_addr; - log << ss.str() << endl; - terminateWithError(ss.str(), 20); - } -#endif + /* copying a string object that contains control sequences + * unfortunately does not work with the library I am using, + * which is why output is passed on as C string and + * the string compare is done on C strings + */ + if (ev == &ev_done) { + if (strcmp(currentOutput.c_str(), golden_run.c_str()) == 0) { + log << "Result DONE" << endl; + result->set_resulttype(param->msg.DONE); + } else { + log << "Result WRONG" << endl; + result->set_resulttype(param->msg.WRONG); + result->set_output(sanitised(currentOutput.c_str())); + } + } else if (ev == &ev_incomplete) { + log << "Result INCOMPLETE" << endl; + result->set_resulttype(param->msg.INCOMPLETE); + result->set_resultdata(simulator.getCPU(0).getInstructionPointer()); + result->set_output(sanitised(currentOutput.c_str())); + } else if (ev == &ev_timeout) { + log << "Result TIMEOUT" << endl; + result->set_resulttype(param->msg.TIMEOUT); + result->set_resultdata(simulator.getCPU(0).getInstructionPointer()); + result->set_output(sanitised(currentOutput.c_str())); + } else { + log << "Result WTF?" << endl; + stringstream ss; + ss << "eventid " << ev; + terminateWithError(ss.str(), 50); + } + } + + m_jc.sendResult(*param); - // inject - if (exp_type == param->msg.GPRFLIP) { - int reg_offset = reg; // XXX redundant - ConcreteCPU& cpu = simulator.getCPU(0); - Register *reg_target = cpu.getRegister(reg_offset - 1); - regdata_t data = cpu.getRegisterContent(reg_target); - regdata_t newdata = data ^ (1 << (bit_offset + 8 * offset)); - cpu.setRegisterContent(reg_target, newdata); - - // do the logging in case everything worked out - logInjection(); - log << "IP " << hex << simulator.getCPU(0).getInstructionPointer() - << " register data: 0x" << hex << ((int) data) << " -> 0x" - << ((int) newdata) << endl; - } // XXX: Fixme to work with database campaign! #if 0 else if (exp_type == param->msg.IDCFLIP) { @@ -857,58 +872,9 @@ bool L4SysExperiment::run() { } #endif - // aftermath - BPSingleListener ev_done(L4SYS_FUNC_EXIT, L4SYS_ADDRESS_SPACE); - simulator.addListener(&ev_done); - - unsigned instr_left = L4SYS_TOTINSTR - instr_offset; // XXX offset is in NUMINSTR, TOTINSTR is higher - BPSingleListener ev_incomplete(ANY_ADDR, L4SYS_ADDRESS_SPACE); - ev_incomplete.setCounter(static_cast(instr_left * 1.1)); - simulator.addListener(&ev_incomplete); - - TimerListener ev_timeout(calculateTimeout(instr_left)); - simulator.addListener(&ev_timeout); - - //do not discard output recorded so far - BaseListener *ev = waitIOOrOther(false); - - /* copying a string object that contains control sequences - * unfortunately does not work with the library I am using, - * which is why output is passed on as C string and - * the string compare is done on C strings - */ - if (ev == &ev_done) { - if (strcmp(currentOutput.c_str(), golden_run.c_str()) == 0) { - log << "Result DONE" << endl; - result->set_resulttype(param->msg.DONE); - } else { - log << "Result WRONG" << endl; - result->set_resulttype(param->msg.WRONG); - result->set_output(sanitised(currentOutput.c_str())); - } - } else if (ev == &ev_incomplete) { - log << "Result INCOMPLETE" << endl; - result->set_resulttype(param->msg.INCOMPLETE); - result->set_resultdata(simulator.getCPU(0).getInstructionPointer()); - result->set_output(sanitised(currentOutput.c_str())); - } else if (ev == &ev_timeout) { - log << "Result TIMEOUT" << endl; - result->set_resulttype(param->msg.TIMEOUT); - result->set_resultdata(simulator.getCPU(0).getInstructionPointer()); - result->set_output(sanitised(currentOutput.c_str())); - } else { - log << "Result WTF?" << endl; - stringstream ss; - ss << "eventid " << ev; - terminateWithError(ss.str(), 50); - } - } - - m_jc.sendResult(*param); #endif - terminate(0); - + terminate(0); // experiment successfully conducted return true; } diff --git a/src/experiments/l4-sys/experiment.hpp b/src/experiments/l4-sys/experiment.hpp index edc01b2e..0a6d696d 100644 --- a/src/experiments/l4-sys/experiment.hpp +++ b/src/experiments/l4-sys/experiment.hpp @@ -112,16 +112,25 @@ private: * Run until L4SYS_FUNC_ENTRY and save state (experiment preparation, * phase 1) */ - void startAndSaveInitState(fail::BPSingleListener& bp); + void startAndSaveInitState(fail::BPSingleListener* bp); /** * Collect list of executed instructions, considering instruction * filtering if configured (experiment preparation, phase 2). */ - void collectInstructionTrace(fail::BPSingleListener& bp); + void collectInstructionTrace(fail::BPSingleListener* bp); /** * Perform the golden run (experiment preparation, phase 3) */ - void goldenRun(fail::BPSingleListener& bp); + void goldenRun(fail::BPSingleListener* bp); + + void validatePrerequisites(); + void getJobParameters(); + void readGoldenRun(std::string& target); + + fail::BPSingleListener* prepareMemoryExperiment(int ip, int offset, int dataAddress); + fail::BPSingleListener* prepareRegisterExperiment(int ip, int offset, int dataAddress); + void doMemoryInjection(int address, int bit); + void doRegisterInjection(int regDesc, int bit); }; #endif // __L4SYS_EXPERIMENT_HPP__ From 1a09d301278ca7f7b970a787bb064c343e9c7d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20D=C3=B6bel?= Date: Wed, 11 Sep 2013 16:18:44 +0200 Subject: [PATCH 5/8] L4Sys: prepare script supports mem/reg experiments Change-Id: Ibcbc9e99b063d4b019b4d68401c77fc964253da8 --- scripts/l4sys/l4sys-prepare.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/l4sys/l4sys-prepare.sh b/scripts/l4sys/l4sys-prepare.sh index dc7c8372..2d94acb2 100755 --- a/scripts/l4sys/l4sys-prepare.sh +++ b/scripts/l4sys/l4sys-prepare.sh @@ -15,6 +15,20 @@ BAK=experimentInfo.hpp.bak CFG=experimentInfo.hpp FAIL_CMD="fail-client -q" # -rc bochs-dbg.rc" FAILDIR=/home/doebel/src/fail +DBNAME=fiasco + +if [ -n "$1" ] ; then + if [ "$1" = "mem" ]; then + IMPORTER=MemoryImporter; + fi +fi + +if [ "$IMPORTER" = "MemoryImporter" ]; then + echo "Preparing memory injection experiment." +else + IMPORTER=RegisterImporter; + echo "Preparing register injection experiment." +fi function buildfail { echo -e "\033[33mCompiling....\033[0m" @@ -39,6 +53,7 @@ BuildNRun -f bochsrc-bd echo -e "\033[35;1m[$(date)] ================== Step 2: Get Instruction Count ===============\033[0m" cat $BAK | sed -e 's/PREPARATION_STEP.*/PREPARATION_STEP 2/' >$CFG buildfail + echo -e "\033[32mRunning...\033[0m" values=`$FAIL_CMD 2>/dev/null | grep instructions\; | sed -e 's/.*after \(.*\) instructions;\(.*\) accepted/\1 \2/'` echo $values @@ -58,8 +73,8 @@ rm $BAK $BAK.2 $BAK.3 buildfail echo -e "\033[35;1m[$(date)] ================== Step 5: Trace Import/Prune ==============\033[0m" -import-trace --importer RegisterImporter -e fiasco.image -d fail -prune-trace -d fail +import-trace --importer $IMPORTER -e fiasco.image -d $DBNAME -t trace.pb +prune-trace -d $DBNAME echo -e "\033[32;1m==========================================================================================" echo "[$(date)] Preparations are finished. Happy injecting...." From 560860cb99cef49325c4e16d2dbb8b4e796181bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20D=C3=B6bel?= Date: Wed, 11 Sep 2013 17:55:37 +0200 Subject: [PATCH 6/8] L4Sys: consult instruction list for breakpoints Change-Id: Ic8163cc84bad9b0074a9d6489127d0ef09eb3c21 --- src/experiments/l4-sys/experiment.cc | 79 ++++++++++++++++----------- src/experiments/l4-sys/experiment.hpp | 32 +++++++++++ 2 files changed, 79 insertions(+), 32 deletions(-) diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc index 91ed6fb9..c16828db 100644 --- a/src/experiments/l4-sys/experiment.cc +++ b/src/experiments/l4-sys/experiment.cc @@ -71,6 +71,7 @@ BaseListener* L4SysExperiment::waitIOOrOther(bool clear_output) { //simulator.removeListener(&ev_ioport); if (ev == &ev_ioport) { currentOutput += ev_ioport.getData(); + //log << currentOutput << std::endl; } else { break; } @@ -444,34 +445,8 @@ void L4SysExperiment::readGoldenRun(std::string& target) } -fail::BPSingleListener* -L4SysExperiment::prepareMemoryExperiment(int ip, int offset, int dataAddress) +void L4SysExperiment::setupFilteredBreakpoint(fail::BPSingleListener* bp, int instOffset) { - 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); if (!instr_list_file.good()) { @@ -480,7 +455,7 @@ L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress) } 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() << " " << instr_list_file.fail() << endl; if (instr_list_file.eof()) { @@ -494,6 +469,44 @@ L4SysExperiment::prepareRegisterExperiment(int ip, int offset, int dataAddress) bp->setWatchInstructionPointer(curr_instr.trigger_addr); log << "setting bp counter " << hex << curr_instr.bp_counter << endl; 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 bp->setWatchInstructionPointer(ANY_ADDR); bp->setCounter(instr_offset); @@ -515,9 +528,8 @@ void L4SysExperiment::doMemoryInjection(int address, int bit) void L4SysExperiment::doRegisterInjection(int regDesc, int bit) { - int reg, width, offset; - reg = ((regDesc >> 8) & 0xF) + 1; // regs start at 1 - width = (regDesc >> 4) & 0xF; + int reg, offset; + reg = (regDesc >> 4) + 1; // regs start at 1 offset = regDesc & 0xF; 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 BPSingleListener ev_incomplete(ANY_ADDR, L4SYS_ADDRESS_SPACE); - ev_incomplete.setCounter(static_cast(instr_left * 1.1)); + ev_incomplete.setCounter(instr_left); simulator.addListener(&ev_incomplete); TimerListener ev_timeout(calculateTimeout(instr_left)); simulator.addListener(&ev_timeout); + log << "continue... (" << simulator.getListenerCount() + << " breakpoints, timeout @ " << ev_timeout.getTimeout() + << std::endl; //do not discard output recorded so far BaseListener *ev = waitIOOrOther(false); diff --git a/src/experiments/l4-sys/experiment.hpp b/src/experiments/l4-sys/experiment.hpp index 0a6d696d..451f54f9 100644 --- a/src/experiments/l4-sys/experiment.hpp +++ b/src/experiments/l4-sys/experiment.hpp @@ -123,14 +123,46 @@ private: */ void goldenRun(fail::BPSingleListener* bp); + /** + * Check that all required setup has been done before an experiment run. + */ void validatePrerequisites(); + + /** + * Load job parameters for an experiment. + */ void getJobParameters(); + + /** + * Read the golden run output into the target string. + */ 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); + + /* + * Prepare register experiment. Creates a breakpoint to run until the + * injection location. + */ fail::BPSingleListener* prepareRegisterExperiment(int ip, int offset, int dataAddress); + + /** + * Perform memory bit flip at (address, bit). + */ void doMemoryInjection(int address, int bit); + + /** + * Perform register bit flip in the specified (register, bit) + * combination. + */ void doRegisterInjection(int regDesc, int bit); + + + void setupFilteredBreakpoint(fail::BPSingleListener* bp, int instOffset); }; #endif // __L4SYS_EXPERIMENT_HPP__ From b7d03f64d4516929190b53b779524636b3bd0b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20D=C3=B6bel?= Date: Wed, 11 Sep 2013 18:00:44 +0200 Subject: [PATCH 7/8] docs Change-Id: Ic46dfc6c59c7bee796c2e3e8e97376859391b342 --- src/experiments/l4-sys/experiment.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc index c16828db..719ae7d4 100644 --- a/src/experiments/l4-sys/experiment.cc +++ b/src/experiments/l4-sys/experiment.cc @@ -447,6 +447,22 @@ void L4SysExperiment::readGoldenRun(std::string& target) void L4SysExperiment::setupFilteredBreakpoint(fail::BPSingleListener* bp, int instOffset) { + /* + * The L4Sys experiment uses instruction filtering to restrict the range + * of fault injection to only e.g., kernel instructions. + * + * To speed up injection, L4Sys furthermore does not use per-instruction + * breakpoints but only places a breakpoint on the actually interesting + * instruction (e.g., the injection EIP). Hence, we also do not count + * instructions from the beginning of the experiment, but we count how + * often a certain EIP was hit before the injection. + * + * To achieve these properties, we use an additional trace file that + * provides us with a 'hit counter' of each injection candidate. We use + * the global instruction ID (DataBaseCampaign: instruction_offset) to + * index into this trace file and determine the value for the breakpoint + * counter. + */ ifstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary); if (!instr_list_file.good()) { From 37eda9097114229b6b045b571ea0a4c3a4f8ddf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20D=C3=B6bel?= Date: Wed, 11 Sep 2013 18:01:04 +0200 Subject: [PATCH 8/8] L4Sys campaign: GPRFLIP and MEM injections Change-Id: I0c4a6bf6b80d6620c035595c11663121f504f4d5 --- src/experiments/l4-sys/campaign.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/experiments/l4-sys/campaign.cc b/src/experiments/l4-sys/campaign.cc index 3b55e84c..5815ec33 100644 --- a/src/experiments/l4-sys/campaign.cc +++ b/src/experiments/l4-sys/campaign.cc @@ -158,7 +158,7 @@ void L4SysCampaign::cb_send_pilot(DatabaseCampaignMessage p) #endif L4SysExperimentData *d = new L4SysExperimentData; d->msg.mutable_fsppilot()->CopyFrom(p); - //d->msg.set_exp_type(d->msg.GPRFLIP); - d->msg.set_exp_type(d->msg.MEM); + d->msg.set_exp_type(d->msg.GPRFLIP); + //d->msg.set_exp_type(d->msg.MEM); campaignmanager.addParam(d); }