diff --git a/src/experiments/vezs-example/experiment.cc b/src/experiments/vezs-example/experiment.cc index 716c069564e56a6ba2be5db8c70ec989f86b97b3..681c69aa8dc1fb0e4c9b40fae243f15821b8a02d 100644 --- a/src/experiments/vezs-example/experiment.cc +++ b/src/experiments/vezs-example/experiment.cc @@ -25,63 +25,56 @@ using namespace fail; #error This experiment needs: breakpoints, traps, save, and restore. Enable these in the configuration. #endif -bool ChecksumOOStuBSExperiment::run() +bool VEZSExperiment::run() { Logger log("VEZS-Example", false); - BPSingleEvent bp; log << "startup" << endl; + BPSingleEvent bp; +#if 1 + // STEP 1: run until interesting function starts, and save state + bp.setWatchInstructionPointer(OOSTUBS_FUNC_ENTRY); + simulator.addEventAndWait(&bp); + log << "test function entry reached, saving state" << endl; + log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or " << simulator.getRegisterManager().getInstructionPointer() << endl; + simulator.save("vezs.state"); +#endif +#if 0 - bp.setWatchInstructionPointer(ANY_ADDR); - bp.setCounter(OOSTUBS_NUMINSTR); - - //simulator.addEvent(&bp); - // BPSingleEvent ev_count(ANY_ADDR); - // simulator.addEvent(&ev_count); - - for (int i = 0; i < 400; ++i) { // more than 400 will be very slow (500 is max) + int bit_offset = 2; + for (int instr_offset = 0; instr_offset < OOSTUBS_NUMINSTR; ++instr_offset) { - // XXX debug - int instr_offset = 1000; + // STEP 3: The actual experiment. + log << "restoring state" << endl; + simulator.restore("vezs.state"); - // reaching finish() could happen before OR after FI - BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH); - simulator.addEvent(&func_finish); - bool finish_reached = false; + log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl; bp.setWatchInstructionPointer(ANY_ADDR); - bp.setCounter(instr_offset); - simulator.addEvent(&bp); - - // finish() before FI? - if (simulator.waitAny() == &func_finish) { - finish_reached = true; - log << "experiment reached finish() before FI" << endl; - - // wait for bp - simulator.waitAny(); + for (int count = 0; count < instr_offset; ++count) { + simulator.addEventAndWait(&bp); } - - - // --- fault injection --- - //byte_t newdata = data ^ (1 << bit_offset); - //mm.setByte(mem_addr, newdata); - // note at what IP we did it + + + int32_t data = simulator.getRegisterManager().getRegister(RID_CAX)->getData(); + // The INJECTION: + int32_t newdata = data ^ (1<<bit_offset); + simulator.getRegisterManager().getRegister(RID_CAX)->setData(newdata); + int32_t injection_ip = simulator.getRegisterManager().getInstructionPointer(); - log << "fault injected @ ip " << injection_ip << endl; - + log << "inject @ ip " << injection_ip + << " (offset " << dec << instr_offset << ")" + << " bit " << bit_offset << ": 0x" + << hex << ((int)data) << " -> 0x" << ((int)newdata) << endl; + // --- aftermath --- // possible outcomes: // - trap, "crash" // - jump outside text segment - // - (XXX unaligned jump inside text segment) - // - (XXX weird instructions?) - // - (XXX results displayed?) // - reaches THE END // - error detected, stop // additional info: // - #loop iterations before/after FI - // - (XXX "sane" display?) // catch traps as "extraordinary" ending TrapEvent ev_trap(ANY_TRAP); @@ -98,23 +91,14 @@ bool ChecksumOOStuBSExperiment::run() // remaining instructions until "normal" ending BPSingleEvent ev_end(ANY_ADDR); - ev_end.setCounter(OOSTUBS_NUMINSTR + OOSTUBS_RECOVERYINSTR - instr_offset); + ev_end.setCounter(OOSTUBS_NUMINSTR - instr_offset); simulator.addEvent(&ev_end); // Start simulator and wait for any result BaseEvent* ev = simulator.waitAny(); - // Do we reach finish() while waiting for ev_trap/ev_done? - if (ev == &func_finish) { - finish_reached = true; - log << "experiment reached finish()" << endl; - - // wait for ev_trap/ev_done - ev = simulator.waitAny(); - } - // record latest IP regardless of result - //simulator.getRegisterManager().getInstructionPointer(); + injection_ip = simulator.getRegisterManager().getInstructionPointer(); if (ev == &ev_end) { @@ -128,11 +112,13 @@ bool ChecksumOOStuBSExperiment::run() } else { log << "Result WTF?" << endl; } + log << "@ ip 0x" << hex << injection_ip << endl; // explicitly remove all events before we leave their scope // FIXME event destructors should remove them from the queues simulator.clearEvents(); - } +} +#endif // Explicitly terminate, or the simulator will continue to run. simulator.terminate(); } diff --git a/src/experiments/vezs-example/experiment.hpp b/src/experiments/vezs-example/experiment.hpp index a0ab7a9845f963211d3475c67a3c3a70a1d5bbf7..701770465e040632ce609309b4945deabaa170a2 100644 --- a/src/experiments/vezs-example/experiment.hpp +++ b/src/experiments/vezs-example/experiment.hpp @@ -4,10 +4,10 @@ #include "efw/ExperimentFlow.hpp" #include "efw/JobClient.hpp" -class ChecksumOOStuBSExperiment : public fail::ExperimentFlow { +class VEZSExperiment : public fail::ExperimentFlow { fail::JobClient m_jc; public: - ChecksumOOStuBSExperiment() : m_jc("ios.cs.tu-dortmund.de") {} + VEZSExperiment() : m_jc("ios.cs.tu-dortmund.de") {} bool run(); }; diff --git a/src/experiments/vezs-example/experimentInfo.hpp b/src/experiments/vezs-example/experimentInfo.hpp index 80a6e166398a2e91ce8b1b9d0dbd82ae720d64c5..bcc57e18352502d0c5d545000103e7d2fb5e1bd8 100644 --- a/src/experiments/vezs-example/experimentInfo.hpp +++ b/src/experiments/vezs-example/experimentInfo.hpp @@ -3,48 +3,22 @@ // FIXME autogenerate this -#if 1 // with ECC // the task function's entry address: // nm -C ecc.elf|fgrep main -#define OOSTUBS_FUNC_ENTRY 0x00101eaa +#define OOSTUBS_FUNC_ENTRY 0x001009d0 // empty function that is called explicitly when the experiment finished // nm -C ecc.elf|fgrep "finished()" -#define OOSTUBS_FUNC_FINISH 0x00106da4 +#define OOSTUBS_FUNC_FINISH 0x001009d6 // function executing HLT with no chance for further progress (after panic()) // nm -C ecc.elf|fgrep cpu_halt #define OOSTUBS_FUNC_CPU_HALT 0x001009f7 // nm -C ecc.elf | fgrep "_TEXT_" #define OOSTUBS_TEXT_START 0x00100000 -#define OOSTUBS_TEXT_END 0x00107cbf +#define OOSTUBS_TEXT_END 0x00100a1b -// number of instructions the target executes under non-error conditions from ENTRY to DONE: -// (result of experiment's step #2) -#define OOSTUBS_NUMINSTR 0x4B16E6 -// number of instructions that are executed additionally for error corrections -// (this is a rough guess ... TODO) -#define OOSTUBS_RECOVERYINSTR 0x2000 -// the variable that's increased if ECC corrects an error: -// nm -C ecc.elf|fgrep errors_corrected -#define OOSTUBS_ERROR_CORRECTED 0x0010baf0 -// -// nm -C ecc.elf|fgrep results -#define OOSTUBS_RESULTS_ADDR 0x0010ae6c -#define OOSTUBS_RESULTS_BYTES 12 -#define OOSTUBS_RESULT0 0xab3566a9 -#define OOSTUBS_RESULT1 0x44889112 -#define OOSTUBS_RESULT2 0x10420844 +#define OOSTUBS_NUMINSTR 5 -#else // without ECC - -#define COOL_ECC_FUNC_ENTRY 0x00200a90 -#define COOL_ECC_CALCDONE 0x00200ab7 -#define COOL_ECC_NUMINSTR 97 -#define COOL_ECC_OBJUNDERTEST 0x0021263c -#define COOL_ECC_OBJUNDERTEST_SIZE 10 -#define COOL_ECC_ERROR_CORRECTED 0x002127b0 // dummy - -#endif #endif // __EXPERIMENT_INFO_HPP__