nanojpeg: campaign's fault-space pruning works now
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1795 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -84,6 +84,20 @@ bool NanoJPEGCampaign::run()
|
||||
Udis86Helper udis_helper;
|
||||
Udis86Helper::UDRegisterSet in_regs, out_regs;
|
||||
|
||||
// register cascade for equivalence class generation
|
||||
// map: register -> list of latest accesses (front = newest access)
|
||||
// list: latest accesses (instr offset | bit mask)
|
||||
map<GPRegisterId, std::list<std::pair<unsigned, uint64_t> > > reg_cascade;
|
||||
// open up an equivalence class for all bits in all GPRs
|
||||
reg_cascade[RID_EAX].push_front(std::pair<unsigned, uint64_t>(0, 0xffffffffffffffffULL));
|
||||
reg_cascade[RID_EBX].push_front(std::pair<unsigned, uint64_t>(0, 0xffffffffffffffffULL));
|
||||
reg_cascade[RID_ECX].push_front(std::pair<unsigned, uint64_t>(0, 0xffffffffffffffffULL));
|
||||
reg_cascade[RID_EDX].push_front(std::pair<unsigned, uint64_t>(0, 0xffffffffffffffffULL));
|
||||
reg_cascade[RID_ESP].push_front(std::pair<unsigned, uint64_t>(0, 0xffffffffffffffffULL));
|
||||
reg_cascade[RID_EBP].push_front(std::pair<unsigned, uint64_t>(0, 0xffffffffffffffffULL));
|
||||
reg_cascade[RID_ESI].push_front(std::pair<unsigned, uint64_t>(0, 0xffffffffffffffffULL));
|
||||
reg_cascade[RID_EDI].push_front(std::pair<unsigned, uint64_t>(0, 0xffffffffffffffffULL));
|
||||
|
||||
// load trace
|
||||
ifstream tracef(NANOJPEG_TRACE);
|
||||
if (tracef.fail()) {
|
||||
@ -124,13 +138,15 @@ bool NanoJPEGCampaign::run()
|
||||
ud_t& ud = udis.getCurrentState();
|
||||
udis_helper.setUd(&ud);
|
||||
|
||||
// for now: debug output
|
||||
m_log << "0x" << hex << ev.ip() << " " << ::ud_insn_asm(&ud) << endl;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
cout << udis_helper.operandTypeToChar(ud.operand[i].type) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
//m_log << "0x" << hex << ev.ip() << " " << ::ud_insn_asm(&ud) << endl;
|
||||
//for (int i = 0; i < 3; ++i) {
|
||||
// cout << udis_helper.operandTypeToChar(ud.operand[i].type) << " ";
|
||||
//}
|
||||
//cout << endl;
|
||||
|
||||
// determine input/output registers
|
||||
udis_helper.inOutRegisters(in_regs, out_regs);
|
||||
#if 0
|
||||
cout << "IN: ";
|
||||
for (Udis86Helper::UDRegisterSet::const_iterator it = in_regs.begin();
|
||||
it != in_regs.end(); ++it) {
|
||||
@ -142,7 +158,64 @@ bool NanoJPEGCampaign::run()
|
||||
cout << udis_helper.typeToString(*it) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
#endif
|
||||
|
||||
// all IN registers close an equivalence class and generate experiments
|
||||
for (Udis86Helper::UDRegisterSet::const_iterator it = in_regs.begin();
|
||||
it != in_regs.end(); ++it) {
|
||||
// determine Fail* register ID and bitmask
|
||||
uint64_t access_mask;
|
||||
fail::GPRegisterId reg = udis_helper.udisGPRToFailBochsGPR(*it, access_mask);
|
||||
uint64_t remaining_access_mask = access_mask;
|
||||
|
||||
// iterate over latest accesses to register, newest to oldest
|
||||
for (std::list<std::pair<unsigned, uint64_t> >::iterator acc = reg_cascade[reg].begin();
|
||||
acc != reg_cascade[reg].end() && remaining_access_mask; ) {
|
||||
uint64_t curr_mask = acc->second;
|
||||
uint64_t common_mask = curr_mask & remaining_access_mask;
|
||||
if (!common_mask) {
|
||||
++acc;
|
||||
continue;
|
||||
}
|
||||
|
||||
remaining_access_mask &= ~common_mask;
|
||||
acc->second &= ~common_mask;
|
||||
|
||||
// new EC with experiments: acc->first -- instr, common_mask
|
||||
count += add_experiment_ec(acc->first, instr, 0 /*todo*/, reg, common_mask);
|
||||
|
||||
// new memory access EC in access cascade
|
||||
reg_cascade[reg].push_front(std::pair<unsigned, uint64_t>(instr + 1, common_mask));
|
||||
|
||||
// old access completely shadowed by newer accesses?
|
||||
if (acc->second == 0) {
|
||||
acc = reg_cascade[reg].erase(acc);
|
||||
} else {
|
||||
++acc;
|
||||
}
|
||||
}
|
||||
assert(remaining_access_mask == 0);
|
||||
}
|
||||
|
||||
// all OUT registers close an equivalence class and generate known results
|
||||
// TODO
|
||||
// special case: empty EC!
|
||||
}
|
||||
cout << "experiments planned: " << dec << count << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int NanoJPEGCampaign::add_experiment_ec(unsigned instr_ecstart, unsigned instr_offset,
|
||||
unsigned instr_address, fail::GPRegisterId register_id, uint64_t bitmask)
|
||||
{
|
||||
uint64_t v = bitmask; // count the number of bits set in v
|
||||
int c; // c accumulates the total bits set in v
|
||||
|
||||
for (c = 0; v; v >>= 1) {
|
||||
c += v & 1;
|
||||
}
|
||||
|
||||
// TODO really enqueue jobs
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "cpn/Campaign.hpp"
|
||||
#include "comm/ExperimentData.hpp"
|
||||
#include "util/Logger.hpp"
|
||||
#include "sal/bochs/BochsRegisterIDs.hpp"
|
||||
#include "nanojpeg.pb.h"
|
||||
|
||||
class NanoJPEGExperimentData : public fail::ExperimentData {
|
||||
@ -14,6 +15,8 @@ public:
|
||||
|
||||
class NanoJPEGCampaign : public fail::Campaign {
|
||||
fail::Logger m_log;
|
||||
int add_experiment_ec(unsigned instr_ecstart, unsigned instr_offset,
|
||||
unsigned instr_address, fail::GPRegisterId register_id, uint64_t bitmask);
|
||||
public:
|
||||
NanoJPEGCampaign() : m_log("nJPEG Campaign") {}
|
||||
virtual bool run();
|
||||
|
||||
@ -2,16 +2,16 @@ message NanoJPEGProtoMsg {
|
||||
// Input: experiment parameters
|
||||
// (client executes one experiment for every specified bit in the target register)
|
||||
|
||||
// equivalence class start
|
||||
required int32 instr_ecstart = 1;
|
||||
// FI at #instructions from experiment start
|
||||
required int32 instr_offset = 1;
|
||||
required int32 instr_offset = 2;
|
||||
// the exact IP value at this point in time (from golden run)
|
||||
optional int32 instr_address = 2; // for sanity checks
|
||||
optional int32 instr_address = 3; // for sanity checks
|
||||
// ID of the register to inject faults into
|
||||
required int32 register_id = 3;
|
||||
// first bit to inject a flip into
|
||||
required int32 bit_start = 4;
|
||||
// last bit to inject a flip into (inclusive)
|
||||
required int32 bit_end = 5;
|
||||
required int32 register_id = 4;
|
||||
// bits to inject a bit flip into
|
||||
required int64 bitmask = 5;
|
||||
// timeout in ms
|
||||
required int32 timeout = 6;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user