Code cleanup
This commit is contained in:
@ -20,8 +20,6 @@ set(MY_CAMPAIGN_SRCS
|
|||||||
UDIS86.cc
|
UDIS86.cc
|
||||||
InstructionFilter.hpp
|
InstructionFilter.hpp
|
||||||
InstructionFilter.cc
|
InstructionFilter.cc
|
||||||
conversion.hpp
|
|
||||||
conversion.cc
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#### PROTOBUFS ####
|
#### PROTOBUFS ####
|
||||||
|
|||||||
@ -1,164 +1,12 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "campaign.hpp"
|
#include "campaign.hpp"
|
||||||
#include "experimentInfo.hpp"
|
#include "experiment.hpp"
|
||||||
#include "conversion.hpp"
|
|
||||||
#include "comm/DatabaseCampaignMessage.pb.h"
|
|
||||||
#include "cpn/CampaignManager.hpp"
|
#include "cpn/CampaignManager.hpp"
|
||||||
#include "util/Logger.hpp"
|
|
||||||
#include "sal/SALConfig.hpp"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace fail;
|
|
||||||
|
|
||||||
char const * const results_csv = "l4sys.csv";
|
|
||||||
|
|
||||||
extern L4SysConversion l4sysResultConversion;
|
|
||||||
extern L4SysConversion l4sysExperimentConversion;
|
|
||||||
extern L4SysConversion l4sysRegisterConversion;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
bool L4SysCampaign::run() {
|
|
||||||
Logger log("L4SysCampaign");
|
|
||||||
|
|
||||||
ifstream test(results_csv);
|
|
||||||
if (test.is_open()) {
|
|
||||||
log << results_csv << " already exists" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ofstream results(results_csv);
|
|
||||||
if (!results.is_open()) {
|
|
||||||
log << "failed to open " << results_csv << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
log << "startup" << endl;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
srand(time(NULL));
|
|
||||||
|
|
||||||
for (int i = 0; i < L4SYS_NUMINSTR; ++i) {
|
|
||||||
for (int r = 1; r < 9; ++r) {
|
|
||||||
for (int b = 0; b < 32; ++b) {
|
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
|
||||||
d->msg.set_exp_type(d->msg.GPRFLIP);
|
|
||||||
d->msg.set_register_offset(static_cast<L4SysProtoMsg_RegisterType>(r));
|
|
||||||
d->msg.set_instr_offset(i);
|
|
||||||
d->msg.set_bit_offset(b);
|
|
||||||
campaignmanager.addParam(d);
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 20000; ++i) {
|
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
|
||||||
d->msg.set_exp_type(d->msg.GPRFLIP);
|
|
||||||
// affect a random register
|
|
||||||
int reg_offset = rand() % 8 + 1;
|
|
||||||
d->msg.set_register_offset(
|
|
||||||
static_cast<L4SysProtoMsg_RegisterType>(reg_offset));
|
|
||||||
// modify for a random instruction
|
|
||||||
int instr_offset = rand() % L4SYS_NUMINSTR;
|
|
||||||
d->msg.set_instr_offset(instr_offset);
|
|
||||||
// modify a random bit
|
|
||||||
int bit_offset = rand() % 32;
|
|
||||||
d->msg.set_bit_offset(bit_offset);
|
|
||||||
|
|
||||||
campaignmanager.addParam(d);
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 20000; ++i) {
|
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
|
||||||
d->msg.set_exp_type(d->msg.ALUINSTR);
|
|
||||||
// modify for a random instruction
|
|
||||||
int instr_offset = rand() % L4SYS_NUMINSTR;
|
|
||||||
d->msg.set_instr_offset(instr_offset);
|
|
||||||
// this value is not required for this experiment, so set it to an arbitrary value
|
|
||||||
d->msg.set_bit_offset(0);
|
|
||||||
|
|
||||||
campaignmanager.addParam(d);
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 20000; ++i) {
|
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
|
||||||
d->msg.set_exp_type(d->msg.IDCFLIP);
|
|
||||||
// modify for a random instruction
|
|
||||||
int instr_offset = rand() % L4SYS_NUMINSTR;
|
|
||||||
d->msg.set_instr_offset(instr_offset);
|
|
||||||
// modify a random bit - Bochs supports at most 15 bytes of instruction
|
|
||||||
int bit_offset = rand() % 125;
|
|
||||||
d->msg.set_bit_offset(bit_offset);
|
|
||||||
|
|
||||||
campaignmanager.addParam(d);
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 20000; ++i) {
|
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
|
||||||
d->msg.set_exp_type(d->msg.RATFLIP);
|
|
||||||
// modify for a random instruction
|
|
||||||
int instr_offset = rand() % L4SYS_NUMINSTR;
|
|
||||||
d->msg.set_instr_offset(instr_offset);
|
|
||||||
// this value is not required for this experiment, so set it to an arbitrary value
|
|
||||||
d->msg.set_bit_offset(0);
|
|
||||||
|
|
||||||
campaignmanager.addParam(d);
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
campaignmanager.noMoreParameters();
|
|
||||||
log << "done enqueueing parameter sets (" << count << ")." << endl;
|
|
||||||
|
|
||||||
// collect results
|
|
||||||
L4SysExperimentData *res;
|
|
||||||
int rescount = 0;
|
|
||||||
results
|
|
||||||
<< "exp_type,injection_ip,register,instr_offset,injection_bit,resulttype,resultdata,output,details"
|
|
||||||
<< endl;
|
|
||||||
while ((res = static_cast<L4SysExperimentData *>(campaignmanager.getDone()))) {
|
|
||||||
rescount++;
|
|
||||||
|
|
||||||
results << l4sysExperimentConversion.output(res->msg.exp_type())
|
|
||||||
<< "," << hex << res->msg.injection_ip() << dec << ",";
|
|
||||||
if (res->msg.has_register_offset())
|
|
||||||
results << l4sysRegisterConversion.output(res->msg.register_offset());
|
|
||||||
else
|
|
||||||
results << "None";
|
|
||||||
results << "," << res->msg.instr_offset() << "," << res->msg.bit_offset()
|
|
||||||
<< ","
|
|
||||||
<< l4sysResultConversion.output(res->msg.resulttype()) << ","
|
|
||||||
<< res->msg.resultdata();
|
|
||||||
if (res->msg.has_output())
|
|
||||||
results << "," << res->msg.output();
|
|
||||||
if (res->msg.has_details())
|
|
||||||
results << "," << res->msg.details();
|
|
||||||
results << endl;
|
|
||||||
delete res;
|
|
||||||
}
|
|
||||||
|
|
||||||
log << "done. sent " << count << " received " << rescount << endl;
|
|
||||||
results.close();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace google::protobuf;
|
|
||||||
|
|
||||||
void L4SysCampaign::cb_send_pilot(DatabaseCampaignMessage p)
|
void L4SysCampaign::cb_send_pilot(DatabaseCampaignMessage p)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
int inj_instr = p.injection_instr();
|
|
||||||
int data_addr = p.data_address();
|
|
||||||
int reg = (data_addr >> 8) & 0xF;
|
|
||||||
int width = (data_addr >> 4) & 0xF;
|
|
||||||
int offs = data_addr & 0xF;
|
|
||||||
#endif
|
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
L4SysExperimentData *d = new L4SysExperimentData;
|
||||||
d->msg.mutable_fsppilot()->CopyFrom(p);
|
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);
|
d->msg.set_exp_type(d->msg.MEM);
|
||||||
campaignmanager.addParam(d);
|
fail::campaignmanager.addParam(d);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,15 +13,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class L4SysCampaign : public fail::DatabaseCampaign {
|
class L4SysCampaign : public fail::DatabaseCampaign {
|
||||||
#if 0
|
|
||||||
public:
|
|
||||||
virtual bool run();
|
|
||||||
#else
|
|
||||||
virtual const google::protobuf::Descriptor * cb_result_message()
|
virtual const google::protobuf::Descriptor * cb_result_message()
|
||||||
{ return google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName("L4SysProtoMsg"); }
|
{ return google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName("L4SysProtoMsg"); }
|
||||||
|
|
||||||
virtual void cb_send_pilot(DatabaseCampaignMessage pilot);
|
virtual void cb_send_pilot(DatabaseCampaignMessage pilot);
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __L4SYS_CAMPAIGN_HPP__
|
#endif // __L4SYS_CAMPAIGN_HPP__
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
#include "conversion.hpp"
|
|
||||||
|
|
||||||
char const *l4sys_output_result_strings[] = { "Unknown", "No effect", "Incomplete execution", "Crash", "Silent data corruption", "Error" };
|
|
||||||
char const *l4sys_output_experiment_strings[] = { "Unknown", "GPR Flip", "RAT Flip", "IDC Flip", "ALU Instr Flip" };
|
|
||||||
char const *l4sys_output_register_strings[] = { "Unknown", "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" };
|
|
||||||
|
|
||||||
L4SysConversion l4sysResultConversion(
|
|
||||||
l4sys_output_result_strings,
|
|
||||||
sizeof(l4sys_output_result_strings));
|
|
||||||
L4SysConversion l4sysExperimentConversion(
|
|
||||||
l4sys_output_experiment_strings,
|
|
||||||
sizeof(l4sys_output_experiment_strings));
|
|
||||||
L4SysConversion l4sysRegisterConversion(
|
|
||||||
l4sys_output_register_strings,
|
|
||||||
sizeof(l4sys_output_register_strings));
|
|
||||||
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
#ifndef __L4SYS_CONVERSION_HPP__
|
|
||||||
#define __L4SYS_CONVERSION_HPP__
|
|
||||||
|
|
||||||
#include "l4sys.pb.h"
|
|
||||||
|
|
||||||
class L4SysConversion {
|
|
||||||
public:
|
|
||||||
L4SysConversion(char const **strings, size_t array_size)
|
|
||||||
: m_Strings(strings)
|
|
||||||
{
|
|
||||||
m_ElementCount = array_size / sizeof(char*);
|
|
||||||
}
|
|
||||||
char const * output(unsigned int res) {
|
|
||||||
if (res == 0 || res >= m_ElementCount) {
|
|
||||||
return m_Strings[0];
|
|
||||||
} else {
|
|
||||||
return m_Strings[res];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
char const **m_Strings;
|
|
||||||
size_t m_ElementCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __L4SYS_CONVERSION_HPP__
|
|
||||||
@ -36,9 +36,6 @@ using namespace fail;
|
|||||||
save, and restore. Enable these in the configuration.
|
save, and restore. Enable these in the configuration.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//string golden_run;
|
|
||||||
extern L4SysConversion l4sysRegisterConversion;
|
|
||||||
|
|
||||||
string L4SysExperiment::sanitised(const string &in_str) {
|
string L4SysExperiment::sanitised(const string &in_str) {
|
||||||
string result;
|
string result;
|
||||||
int in_str_size = in_str.size();
|
int in_str_size = in_str.size();
|
||||||
@ -474,8 +471,7 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener* bp)
|
|||||||
#if 0
|
#if 0
|
||||||
if (curr_addr < 0xC0000000) // XXX filter for kernel-only experiment
|
if (curr_addr < 0xC0000000) // XXX filter for kernel-only experiment
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
currtime = simulator.getTimerTicks();
|
currtime = simulator.getTimerTicks();
|
||||||
deltatime = currtime - prevtime;
|
deltatime = currtime - prevtime;
|
||||||
|
|
||||||
@ -816,7 +812,7 @@ bool L4SysExperiment::run()
|
|||||||
BPSingleListener ev_longjmp(L4SYS_BREAK_LONGJMP);
|
BPSingleListener ev_longjmp(L4SYS_BREAK_LONGJMP);
|
||||||
simulator.addListener(&ev_longjmp);
|
simulator.addListener(&ev_longjmp);
|
||||||
|
|
||||||
//If we come to our own exit function, we can stop
|
//If we come to our own exit function, we can stop
|
||||||
BPSingleListener ev_exit(L4SYS_BREAK_EXIT);
|
BPSingleListener ev_exit(L4SYS_BREAK_EXIT);
|
||||||
simulator.addListener(&ev_exit);
|
simulator.addListener(&ev_exit);
|
||||||
|
|
||||||
@ -844,10 +840,6 @@ bool L4SysExperiment::run()
|
|||||||
<< (void*)&ev_incomplete << endl;
|
<< (void*)&ev_incomplete << endl;
|
||||||
BaseListener *ev = afterInjection(result);
|
BaseListener *ev = afterInjection(result);
|
||||||
log << "afterInj: res.devstep = " << result->deviate_steps() << endl;
|
log << "afterInj: res.devstep = " << result->deviate_steps() << endl;
|
||||||
#if 0
|
|
||||||
//do not discard output recorded so far
|
|
||||||
BaseListener *ev = waitIOOrOther(false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* copying a string object that contains control sequences
|
/* copying a string object that contains control sequences
|
||||||
* unfortunately does not work with the library I am using,
|
* unfortunately does not work with the library I am using,
|
||||||
@ -875,11 +867,11 @@ bool L4SysExperiment::run()
|
|||||||
result->set_resulttype(param->msg.TIMEOUT);
|
result->set_resulttype(param->msg.TIMEOUT);
|
||||||
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()));
|
||||||
} else if (ev == &ev_exit) {
|
} else if (ev == &ev_exit) {
|
||||||
log << "Result FAILSTOP" << endl;
|
log << "Result FAILSTOP" << endl;
|
||||||
result->set_resulttype(param->msg.FAILSTOP);
|
result->set_resulttype(param->msg.FAILSTOP);
|
||||||
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()));
|
||||||
} else {
|
} else {
|
||||||
log << "Result WTF?" << endl;
|
log << "Result WTF?" << endl;
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
@ -890,220 +882,6 @@ bool L4SysExperiment::run()
|
|||||||
|
|
||||||
m_jc.sendResult(*param);
|
m_jc.sendResult(*param);
|
||||||
|
|
||||||
// XXX: Fixme to work with database campaign!
|
|
||||||
#if 0
|
|
||||||
else if (exp_type == param->msg.IDCFLIP) {
|
|
||||||
// this is a twisted one
|
|
||||||
|
|
||||||
// initial definitions
|
|
||||||
bxInstruction_c *currInstr = simulator.getCurrentInstruction();
|
|
||||||
unsigned length_in_bits = currInstr->ilen() << 3;
|
|
||||||
|
|
||||||
// get the instruction in plain text and inject the error there
|
|
||||||
// Note: we need to fetch some extra bytes into the array
|
|
||||||
// in case the faulty instruction is interpreted to be longer
|
|
||||||
// than the original one
|
|
||||||
Bit8u curr_instr_plain[MAX_INSTR_BYTES];
|
|
||||||
const Bit8u *addr = calculateInstructionAddress();
|
|
||||||
memcpy(curr_instr_plain, addr, MAX_INSTR_BYTES);
|
|
||||||
|
|
||||||
// CampaignManager has no idea of the instruction length
|
|
||||||
// (neither do we), therefore this small adaption
|
|
||||||
bit_offset %= length_in_bits;
|
|
||||||
param->msg.set_bit_offset(bit_offset);
|
|
||||||
|
|
||||||
// do some access calculation
|
|
||||||
int byte_index = bit_offset >> 3;
|
|
||||||
Bit8u bit_index = bit_offset & 7;
|
|
||||||
|
|
||||||
// apply the fault
|
|
||||||
curr_instr_plain[byte_index] ^= 0x80 >> bit_index;
|
|
||||||
|
|
||||||
// decode the instruction
|
|
||||||
bxInstruction_c bochs_instr;
|
|
||||||
memset(&bochs_instr, 0, sizeof(bxInstruction_c));
|
|
||||||
fetchInstruction(simulator.getCPUContext(), curr_instr_plain,
|
|
||||||
&bochs_instr);
|
|
||||||
|
|
||||||
// inject it
|
|
||||||
injectInstruction(currInstr, &bochs_instr);
|
|
||||||
|
|
||||||
// do the logging
|
|
||||||
logInjection();
|
|
||||||
} else if (exp_type == param->msg.RATFLIP) {
|
|
||||||
ud_type_t which = UD_NONE;
|
|
||||||
unsigned rnd = 0;
|
|
||||||
Udis86 udis(injection_ip);
|
|
||||||
do {
|
|
||||||
bxInstruction_c *currInstr = simulator.getCurrentInstruction();
|
|
||||||
udis.setInputBuffer(calculateInstructionAddress(), currInstr->ilen());
|
|
||||||
if (!udis.fetchNextInstruction()) {
|
|
||||||
terminateWithError(
|
|
||||||
"Could not decode instruction using UDIS86", 32);
|
|
||||||
}
|
|
||||||
ud_t _ud = udis.getCurrentState();
|
|
||||||
|
|
||||||
/* start Bjoern Doebel's code (slightly modified) */
|
|
||||||
/* ============================================== */
|
|
||||||
unsigned opcount = 0;
|
|
||||||
unsigned operands[4] = { ~0U, ~0U, ~0U, ~0U };
|
|
||||||
enum {
|
|
||||||
RAT_IDX_MASK = 0x0FF,
|
|
||||||
RAT_IDX_OFFSET = 0x100
|
|
||||||
};
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 3; ++i) {
|
|
||||||
/*
|
|
||||||
* Case 1: operand is a register
|
|
||||||
*/
|
|
||||||
if (_ud.operand[i].type == UD_OP_REG) {
|
|
||||||
operands[opcount++] = i;
|
|
||||||
} else if (_ud.operand[i].type == UD_OP_MEM) {
|
|
||||||
/*
|
|
||||||
* Case 2: operand is memory op.
|
|
||||||
*
|
|
||||||
* In this case, we may have 2 registers involved for the
|
|
||||||
* index-scale address calculation.
|
|
||||||
*/
|
|
||||||
if (_ud.operand[i].base != 0) // 0 if hard-wired mem operand
|
|
||||||
operands[opcount++] = i;
|
|
||||||
if (_ud.operand[i].index != 0)
|
|
||||||
operands[opcount++] = i + RAT_IDX_OFFSET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opcount == 0) {
|
|
||||||
// try the next instruction
|
|
||||||
singleStep(true);
|
|
||||||
} else {
|
|
||||||
// assign the necessary variables
|
|
||||||
rnd = rand() % opcount;
|
|
||||||
|
|
||||||
if (operands[rnd] > RAT_IDX_OFFSET) {
|
|
||||||
which = _ud.operand[operands[rnd] - RAT_IDX_OFFSET].index;
|
|
||||||
} else {
|
|
||||||
which = _ud.operand[operands[rnd]].base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* ============================================ */
|
|
||||||
/* end Bjoern Doebel's code (slightly modified) */
|
|
||||||
|
|
||||||
} while (which == UD_NONE &&
|
|
||||||
simulator.getCPU(0).getInstructionPointer() != L4SYS_FUNC_EXIT);
|
|
||||||
|
|
||||||
if (simulator.getCPU(0).getInstructionPointer() == L4SYS_FUNC_EXIT) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "Reached the end of the experiment ";
|
|
||||||
ss << "without finding an appropriate instruction";
|
|
||||||
|
|
||||||
terminateWithError(ss.str(), 33);
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the real injection point
|
|
||||||
param->msg.set_injection_ip(simulator.getCPU(0).getInstructionPointer());
|
|
||||||
|
|
||||||
// so we are able to flip the associated registers
|
|
||||||
// for details on the algorithm, see Bjoern Doebel's SWIFI/RATFlip class
|
|
||||||
|
|
||||||
// some declarations
|
|
||||||
GPRegisterId bochs_reg = Udis86::udisGPRToFailBochsGPR(which);
|
|
||||||
param->msg.set_register_offset(static_cast<L4SysProtoMsg_RegisterType>(bochs_reg + 1));
|
|
||||||
ConcreteCPU &cpu = simulator.getCPU(0);
|
|
||||||
Register *bochsRegister = cpu.getRegister(bochs_reg);
|
|
||||||
Register *exchangeRegister = NULL;
|
|
||||||
|
|
||||||
// first, decide if the fault hits a register bound to this thread
|
|
||||||
// (ten percent chance)
|
|
||||||
if (rand() % 10 == 0) {
|
|
||||||
// assure exchange of registers
|
|
||||||
unsigned int exchg_reg = rand() % 7;
|
|
||||||
if (exchg_reg == bochs_reg)
|
|
||||||
exchg_reg++;
|
|
||||||
exchangeRegister = cpu.getRegister(exchg_reg);
|
|
||||||
param->msg.set_details(l4sysRegisterConversion.output(exchg_reg + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare the fault
|
|
||||||
regdata_t data = cpu.getRegisterContent(bochsRegister);
|
|
||||||
if (rnd > 0) {
|
|
||||||
//input register - do the fault injection here
|
|
||||||
regdata_t newdata = 0;
|
|
||||||
if (exchangeRegister != NULL) {
|
|
||||||
// the data is taken from a process register chosen before
|
|
||||||
newdata = cpu.getRegisterContent(exchangeRegister);
|
|
||||||
} else {
|
|
||||||
// the data comes from an uninitialised register
|
|
||||||
newdata = rand();
|
|
||||||
stringstream ss;
|
|
||||||
ss << "0x" << hex << newdata;
|
|
||||||
param->msg.set_details(ss.str());
|
|
||||||
}
|
|
||||||
cpu.setRegisterContent(bochsRegister, newdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute the instruction
|
|
||||||
singleStep(true);
|
|
||||||
|
|
||||||
// restore the register if we are still in the thread
|
|
||||||
if (rnd == 0) {
|
|
||||||
// output register - do the fault injection here
|
|
||||||
if (exchangeRegister != NULL) {
|
|
||||||
// write the result into the wrong local register
|
|
||||||
regdata_t newdata = cpu.getRegisterContent(bochsRegister);
|
|
||||||
cpu.setRegisterContent(exchangeRegister, newdata);
|
|
||||||
}
|
|
||||||
// otherwise, just assume it is stored in an unused register
|
|
||||||
}
|
|
||||||
// restore the actual value of the register
|
|
||||||
// in reality, it would never have been overwritten
|
|
||||||
cpu.setRegisterContent(bochsRegister, data);
|
|
||||||
|
|
||||||
// log the injection
|
|
||||||
logInjection();
|
|
||||||
|
|
||||||
} else if (exp_type == param->msg.ALUINSTR) {
|
|
||||||
static BochsALUInstructions aluInstrObject(aluInstructions, aluInstructionsSize);
|
|
||||||
// find the closest ALU instruction after the current IP
|
|
||||||
|
|
||||||
bxInstruction_c *currInstr;
|
|
||||||
while (!aluInstrObject.isALUInstruction(
|
|
||||||
currInstr = simulator.getCurrentInstruction()) &&
|
|
||||||
simulator.getCPU(0).getInstructionPointer() != L4SYS_FUNC_EXIT) {
|
|
||||||
singleStep(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (simulator.getCPU(0).getInstructionPointer() == L4SYS_FUNC_EXIT) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "Reached the end of the experiment ";
|
|
||||||
ss << "without finding an appropriate instruction";
|
|
||||||
|
|
||||||
terminateWithError(ss.str(), 34);
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the real injection point
|
|
||||||
param->msg.set_injection_ip(simulator.getCPU(0).getInstructionPointer());
|
|
||||||
|
|
||||||
// now exchange it with a random equivalent
|
|
||||||
bxInstruction_c newInstr;
|
|
||||||
string details;
|
|
||||||
aluInstrObject.randomEquivalent(newInstr, details);
|
|
||||||
if (memcmp(&newInstr, currInstr, sizeof(bxInstruction_c)) == 0) {
|
|
||||||
// something went wrong - exit experiment
|
|
||||||
terminateWithError(
|
|
||||||
"Did not hit an ALU instruction - correct the source code please!",
|
|
||||||
40);
|
|
||||||
}
|
|
||||||
// record information on the new instruction
|
|
||||||
param->msg.set_details(details);
|
|
||||||
|
|
||||||
// inject it
|
|
||||||
injectInstruction(currInstr, &newInstr);
|
|
||||||
|
|
||||||
// do the logging
|
|
||||||
logInjection();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
terminate(0);
|
terminate(0);
|
||||||
|
|||||||
@ -6,23 +6,29 @@
|
|||||||
|
|
||||||
// the bounds of the program (space, instructions and time)
|
// the bounds of the program (space, instructions and time)
|
||||||
// client
|
// client
|
||||||
#define L4SYS_ADDRESS_SPACE 0x1fd4c000
|
#define L4SYS_ADDRESS_SPACE 0x1fd77000
|
||||||
// server
|
// server
|
||||||
#define L4SYS_ADDRESS_SPACE_TRACE L4SYS_ADDRESS_SPACE
|
#define L4SYS_ADDRESS_SPACE_TRACE L4SYS_ADDRESS_SPACE
|
||||||
//#define L4SYS_ADDRESS_SPACE_TRACE 0x1fd4c000
|
//#define L4SYS_ADDRESS_SPACE_TRACE 0x1fd4c000
|
||||||
|
|
||||||
|
#define L4SYS_exp_start 0x20000216
|
||||||
|
#define L4SYS_exp_end 0x2000029c
|
||||||
|
#define L4SYS_inj_start 0x2000022f
|
||||||
|
#define L4SYS_inj_end 0x20000252
|
||||||
|
|
||||||
// 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 0x20000220
|
#define L4SYS_FUNC_ENTRY L4SYS_exp_start
|
||||||
#define L4SYS_FUNC_EXIT 0x20000216
|
#define L4SYS_FUNC_EXIT L4SYS_exp_end
|
||||||
// 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 0x200002ba
|
#define L4SYS_FILTER_ENTRY L4SYS_inj_start
|
||||||
#define L4SYS_FILTER_EXIT 0x20000444
|
#define L4SYS_FILTER_EXIT L4SYS_inj_end
|
||||||
|
|
||||||
#define L4SYS_BREAK_BLINK 0xf004b800
|
#define L4SYS_BREAK_BLINK 0x0
|
||||||
#define L4SYS_BREAK_LONGJMP 0xf004c88e
|
#define L4SYS_BREAK_LONGJMP 0x0
|
||||||
|
#define L4SYS_BREAK_EXIT 0x0
|
||||||
|
|
||||||
// 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
|
||||||
@ -31,12 +37,12 @@
|
|||||||
#define L4SYS_FILTER_INSTRUCTIONS 1
|
#define L4SYS_FILTER_INSTRUCTIONS 1
|
||||||
|
|
||||||
// kernel: 2377547, userland: 79405472
|
// kernel: 2377547, userland: 79405472
|
||||||
#define L4SYS_NUMINSTR 27025
|
#define L4SYS_NUMINSTR 16
|
||||||
#define L4SYS_TOTINSTR 189122
|
#define L4SYS_TOTINSTR 58401
|
||||||
#define L4SYS_BOCHS_IPS 5000000
|
#define L4SYS_BOCHS_IPS 5000000
|
||||||
|
|
||||||
// several file names used
|
// several file names used
|
||||||
#define L4SYS_STATE_FOLDER "l4sys.state"
|
#define L4SYS_STATE_FOLDER "l4sys.state"
|
||||||
#define L4SYS_INSTRUCTION_LIST "ip.list"
|
#define L4SYS_INSTRUCTION_LIST "ip.list"
|
||||||
#define L4SYS_ALU_INSTRUCTIONS "alu.list"
|
#define L4SYS_ALU_INSTRUCTIONS "alu.list"
|
||||||
#define L4SYS_CORRECT_OUTPUT "golden.out"
|
#define L4SYS_CORRECT_OUTPUT "golden.out"
|
||||||
|
|||||||
Reference in New Issue
Block a user