Some improvements on L4, and correcting a mistake made in revision 1361 (see mailing list).
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1377 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -97,7 +97,9 @@ void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_sp
|
|||||||
if(m_Regularity != 0 && ++m_Counter % m_Regularity == 0)
|
if(m_Regularity != 0 && ++m_Counter % m_Regularity == 0)
|
||||||
(*m_pDest) << "0x" << std::hex << instrPtr;
|
(*m_pDest) << "0x" << std::hex << instrPtr;
|
||||||
#endif
|
#endif
|
||||||
|
assert(context != NULL && "FATAL ERROR: Bochs internal member was NULL (not expected)!");
|
||||||
m_CPUContext = context;
|
m_CPUContext = context;
|
||||||
|
assert(cache_entry != NULL && "FATAL ERROR: Bochs internal member was NULL (not expected)!");
|
||||||
m_CacheEntry = cache_entry;
|
m_CacheEntry = cache_entry;
|
||||||
bool do_fire = false;
|
bool do_fire = false;
|
||||||
// Check for active breakpoint-events:
|
// Check for active breakpoint-events:
|
||||||
@ -228,13 +230,9 @@ void BochsController::onTimerTrigger(void* thisPtr)
|
|||||||
const std::string& BochsController::getMnemonic() const
|
const std::string& BochsController::getMnemonic() const
|
||||||
{
|
{
|
||||||
static std::string str;
|
static std::string str;
|
||||||
#if 0
|
bxInstruction_c* pInstr = getICacheEntry()->i;
|
||||||
bxICacheEntry_c* pEntry = BX_CPU(0)->getICacheEntry();
|
|
||||||
assert(pEntry != NULL && "FATAL ERROR: Bochs internal function returned NULL (not expected)!");
|
|
||||||
bxInstruction_c* pInstr = pEntry->i;
|
|
||||||
assert(pInstr != NULL && "FATAL ERROR: Bochs internal member was NULL (not expected)!");
|
assert(pInstr != NULL && "FATAL ERROR: Bochs internal member was NULL (not expected)!");
|
||||||
#endif
|
const char* pszName = get_bx_opcode_name(pInstr->getIaOpcode());
|
||||||
const char* pszName = get_bx_opcode_name(getICacheEntry()->i->getIaOpcode());
|
|
||||||
if (pszName != NULL)
|
if (pszName != NULL)
|
||||||
str = pszName;
|
str = pszName;
|
||||||
else
|
else
|
||||||
|
|||||||
@ -25,6 +25,7 @@ PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
|
|||||||
|
|
||||||
## Build library
|
## Build library
|
||||||
add_library(${EXPERIMENT_NAME} ${PROTO_SRCS} ${PROTO_HDRS} ${MY_CAMPAIGN_SRCS})
|
add_library(${EXPERIMENT_NAME} ${PROTO_SRCS} ${PROTO_HDRS} ${MY_CAMPAIGN_SRCS})
|
||||||
|
target_link_libraries(${EXPERIMENT_NAME} udis86)
|
||||||
|
|
||||||
## This is the example's campaign server distributing experiment parameters
|
## This is the example's campaign server distributing experiment parameters
|
||||||
add_executable(${EXPERIMENT_NAME}-server main.cc)
|
add_executable(${EXPERIMENT_NAME}-server main.cc)
|
||||||
|
|||||||
@ -50,7 +50,7 @@ bool L4SysCampaign::run() {
|
|||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
for (int i = 0; i < 3000; ++i) {
|
for (int i = 0; i < 3000; ++i) {
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
L4SysExperimentData *d = new L4SysExperimentData;
|
||||||
d->msg.set_exp_type(d->msg.IDCFLIP);
|
d->msg.set_exp_type(d->msg.RATFLIP);
|
||||||
d->msg.set_instr_offset(rand() % L4SYS_NUMINSTR);
|
d->msg.set_instr_offset(rand() % L4SYS_NUMINSTR);
|
||||||
// 15 bytes (120 bits) are the longest instruction Bochs still executes
|
// 15 bytes (120 bits) are the longest instruction Bochs still executes
|
||||||
int bit_offset = rand() % 120;
|
int bit_offset = rand() % 120;
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "experiment.hpp"
|
#include "experiment.hpp"
|
||||||
#include "experimentInfo.hpp"
|
#include "experimentInfo.hpp"
|
||||||
|
#include "UDIS86.hpp"
|
||||||
|
|
||||||
#include "sal/SALConfig.hpp"
|
#include "sal/SALConfig.hpp"
|
||||||
#include "sal/SALInst.hpp"
|
#include "sal/SALInst.hpp"
|
||||||
@ -93,8 +94,8 @@ const Bit8u *L4SysExperiment::calculateInstructionAddress() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bx_bool L4SysExperiment::fetchInstruction(BX_CPU_C *instance, const Bit8u *instr, bxInstruction_c *iStorage)
|
bx_bool L4SysExperiment::fetchInstruction(BX_CPU_C *instance,
|
||||||
{
|
const Bit8u *instr, bxInstruction_c *iStorage) {
|
||||||
unsigned remainingInPage = instance->eipPageWindowSize - eipBiased();
|
unsigned remainingInPage = instance->eipPageWindowSize - eipBiased();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -114,7 +115,8 @@ bx_bool L4SysExperiment::fetchInstruction(BX_CPU_C *instance, const Bit8u *instr
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void L4SysExperiment::logInjection(Logger &log, const L4SysExperimentData ¶m) {
|
void L4SysExperiment::logInjection(Logger &log,
|
||||||
|
const L4SysExperimentData ¶m) {
|
||||||
// explicit type assignment necessary before sending over output stream
|
// explicit type assignment necessary before sending over output stream
|
||||||
int id = param.getWorkloadID();
|
int id = param.getWorkloadID();
|
||||||
int instr_offset = param.msg.instr_offset();
|
int instr_offset = param.msg.instr_offset();
|
||||||
@ -123,41 +125,123 @@ void L4SysExperiment::logInjection(Logger &log, const L4SysExperimentData ¶m
|
|||||||
address_t injection_ip = param.msg.injection_ip();
|
address_t injection_ip = param.msg.injection_ip();
|
||||||
|
|
||||||
log << "job " << id << " exp_type " << exp_type << endl;
|
log << "job " << id << " exp_type " << exp_type << endl;
|
||||||
log << "inject @ ip " << injection_ip << " (offset " << dec
|
log << "inject @ ip " << injection_ip << " (offset " << dec << instr_offset
|
||||||
<< instr_offset << ")" << " bit " << bit_offset << endl;
|
<< ")" << " bit " << bit_offset << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool L4SysExperiment::isALUInstruction(unsigned opcode) {
|
bool L4SysExperiment::isALUInstruction(unsigned opcode) {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case BX_IA_INC_Eb: case BX_IA_INC_Ew: case BX_IA_INC_Ed: case BX_IA_INC_RX: case BX_IA_INC_ERX:
|
case BX_IA_INC_Eb:
|
||||||
case BX_IA_DEC_Eb: case BX_IA_DEC_Ew: case BX_IA_DEC_Ed: case BX_IA_DEC_RX: case BX_IA_DEC_ERX:
|
case BX_IA_INC_Ew:
|
||||||
case BX_IA_ADC_EbGb: case BX_IA_ADC_EdGd: case BX_IA_ADC_EwGw: case BX_IA_ADD_EbGb: case BX_IA_ADD_EdGd:
|
case BX_IA_INC_Ed:
|
||||||
case BX_IA_ADD_EwGw: case BX_IA_AND_EbGb: case BX_IA_AND_EdGd: case BX_IA_AND_EwGw: case BX_IA_CMP_EbGb:
|
case BX_IA_INC_RX:
|
||||||
case BX_IA_CMP_EdGd: case BX_IA_CMP_EwGw: case BX_IA_OR_EbGb: case BX_IA_OR_EdGd: case BX_IA_OR_EwGw:
|
case BX_IA_INC_ERX:
|
||||||
case BX_IA_SBB_EbGb: case BX_IA_SBB_EdGd: case BX_IA_SBB_EwGw: case BX_IA_SUB_EbGb: case BX_IA_SUB_EdGd:
|
case BX_IA_DEC_Eb:
|
||||||
case BX_IA_SUB_EwGw: case BX_IA_XOR_EbGb: case BX_IA_XOR_EdGd: case BX_IA_XOR_EwGw: case BX_IA_ADC_ALIb:
|
case BX_IA_DEC_Ew:
|
||||||
case BX_IA_ADC_AXIw: case BX_IA_ADC_EAXId: case BX_IA_ADD_EbIb: case BX_IA_OR_EbIb: case BX_IA_ADC_EbIb:
|
case BX_IA_DEC_Ed:
|
||||||
case BX_IA_SBB_EbIb: case BX_IA_AND_EbIb: case BX_IA_SUB_EbIb: case BX_IA_XOR_EbIb: case BX_IA_CMP_EbIb:
|
case BX_IA_DEC_RX:
|
||||||
case BX_IA_ADD_EwIw: case BX_IA_OR_EwIw: case BX_IA_ADC_EwIw: case BX_IA_SBB_EwIw: case BX_IA_AND_EwIw:
|
case BX_IA_DEC_ERX:
|
||||||
case BX_IA_SUB_EwIw: case BX_IA_XOR_EwIw: case BX_IA_CMP_EwIw: case BX_IA_ADD_EdId: case BX_IA_OR_EdId:
|
case BX_IA_ADC_EbGb:
|
||||||
case BX_IA_ADC_EdId: case BX_IA_SBB_EdId: case BX_IA_AND_EdId: case BX_IA_SUB_EdId: case BX_IA_XOR_EdId:
|
case BX_IA_ADC_EdGd:
|
||||||
case BX_IA_CMP_EdId: case BX_IA_ADC_GbEb: case BX_IA_ADC_GwEw: case BX_IA_ADC_GdEd: case BX_IA_ADD_ALIb:
|
case BX_IA_ADC_EwGw:
|
||||||
case BX_IA_ADD_AXIw: case BX_IA_ADD_EAXId: case BX_IA_ADD_GbEb: case BX_IA_ADD_GwEw: case BX_IA_ADD_GdEd:
|
case BX_IA_ADD_EbGb:
|
||||||
case BX_IA_AND_ALIb: case BX_IA_AND_AXIw: case BX_IA_AND_EAXId: case BX_IA_AND_GbEb: case BX_IA_AND_GwEw:
|
case BX_IA_ADD_EdGd:
|
||||||
case BX_IA_AND_GdEd: case BX_IA_ROL_Eb: case BX_IA_ROR_Eb: case BX_IA_RCL_Eb: case BX_IA_RCR_Eb:
|
case BX_IA_ADD_EwGw:
|
||||||
case BX_IA_SHL_Eb: case BX_IA_SHR_Eb: case BX_IA_SAR_Eb: case BX_IA_ROL_Ew: case BX_IA_ROR_Ew:
|
case BX_IA_AND_EbGb:
|
||||||
case BX_IA_RCL_Ew: case BX_IA_RCR_Ew: case BX_IA_SHL_Ew: case BX_IA_SHR_Ew: case BX_IA_SAR_Ew:
|
case BX_IA_AND_EdGd:
|
||||||
case BX_IA_ROL_Ed: case BX_IA_ROR_Ed: case BX_IA_RCL_Ed: case BX_IA_RCR_Ed: case BX_IA_SHL_Ed:
|
case BX_IA_AND_EwGw:
|
||||||
case BX_IA_SHR_Ed: case BX_IA_SAR_Ed: case BX_IA_NOT_Eb: case BX_IA_NEG_Eb: case BX_IA_NOT_Ew:
|
case BX_IA_CMP_EbGb:
|
||||||
case BX_IA_NEG_Ew: case BX_IA_NOT_Ed: case BX_IA_NEG_Ed:
|
case BX_IA_CMP_EdGd:
|
||||||
|
case BX_IA_CMP_EwGw:
|
||||||
|
case BX_IA_OR_EbGb:
|
||||||
|
case BX_IA_OR_EdGd:
|
||||||
|
case BX_IA_OR_EwGw:
|
||||||
|
case BX_IA_SBB_EbGb:
|
||||||
|
case BX_IA_SBB_EdGd:
|
||||||
|
case BX_IA_SBB_EwGw:
|
||||||
|
case BX_IA_SUB_EbGb:
|
||||||
|
case BX_IA_SUB_EdGd:
|
||||||
|
case BX_IA_SUB_EwGw:
|
||||||
|
case BX_IA_XOR_EbGb:
|
||||||
|
case BX_IA_XOR_EdGd:
|
||||||
|
case BX_IA_XOR_EwGw:
|
||||||
|
case BX_IA_ADC_ALIb:
|
||||||
|
case BX_IA_ADC_AXIw:
|
||||||
|
case BX_IA_ADC_EAXId:
|
||||||
|
case BX_IA_ADD_EbIb:
|
||||||
|
case BX_IA_OR_EbIb:
|
||||||
|
case BX_IA_ADC_EbIb:
|
||||||
|
case BX_IA_SBB_EbIb:
|
||||||
|
case BX_IA_AND_EbIb:
|
||||||
|
case BX_IA_SUB_EbIb:
|
||||||
|
case BX_IA_XOR_EbIb:
|
||||||
|
case BX_IA_CMP_EbIb:
|
||||||
|
case BX_IA_ADD_EwIw:
|
||||||
|
case BX_IA_OR_EwIw:
|
||||||
|
case BX_IA_ADC_EwIw:
|
||||||
|
case BX_IA_SBB_EwIw:
|
||||||
|
case BX_IA_AND_EwIw:
|
||||||
|
case BX_IA_SUB_EwIw:
|
||||||
|
case BX_IA_XOR_EwIw:
|
||||||
|
case BX_IA_CMP_EwIw:
|
||||||
|
case BX_IA_ADD_EdId:
|
||||||
|
case BX_IA_OR_EdId:
|
||||||
|
case BX_IA_ADC_EdId:
|
||||||
|
case BX_IA_SBB_EdId:
|
||||||
|
case BX_IA_AND_EdId:
|
||||||
|
case BX_IA_SUB_EdId:
|
||||||
|
case BX_IA_XOR_EdId:
|
||||||
|
case BX_IA_CMP_EdId:
|
||||||
|
case BX_IA_ADC_GbEb:
|
||||||
|
case BX_IA_ADC_GwEw:
|
||||||
|
case BX_IA_ADC_GdEd:
|
||||||
|
case BX_IA_ADD_ALIb:
|
||||||
|
case BX_IA_ADD_AXIw:
|
||||||
|
case BX_IA_ADD_EAXId:
|
||||||
|
case BX_IA_ADD_GbEb:
|
||||||
|
case BX_IA_ADD_GwEw:
|
||||||
|
case BX_IA_ADD_GdEd:
|
||||||
|
case BX_IA_AND_ALIb:
|
||||||
|
case BX_IA_AND_AXIw:
|
||||||
|
case BX_IA_AND_EAXId:
|
||||||
|
case BX_IA_AND_GbEb:
|
||||||
|
case BX_IA_AND_GwEw:
|
||||||
|
case BX_IA_AND_GdEd:
|
||||||
|
case BX_IA_ROL_Eb:
|
||||||
|
case BX_IA_ROR_Eb:
|
||||||
|
case BX_IA_RCL_Eb:
|
||||||
|
case BX_IA_RCR_Eb:
|
||||||
|
case BX_IA_SHL_Eb:
|
||||||
|
case BX_IA_SHR_Eb:
|
||||||
|
case BX_IA_SAR_Eb:
|
||||||
|
case BX_IA_ROL_Ew:
|
||||||
|
case BX_IA_ROR_Ew:
|
||||||
|
case BX_IA_RCL_Ew:
|
||||||
|
case BX_IA_RCR_Ew:
|
||||||
|
case BX_IA_SHL_Ew:
|
||||||
|
case BX_IA_SHR_Ew:
|
||||||
|
case BX_IA_SAR_Ew:
|
||||||
|
case BX_IA_ROL_Ed:
|
||||||
|
case BX_IA_ROR_Ed:
|
||||||
|
case BX_IA_RCL_Ed:
|
||||||
|
case BX_IA_RCR_Ed:
|
||||||
|
case BX_IA_SHL_Ed:
|
||||||
|
case BX_IA_SHR_Ed:
|
||||||
|
case BX_IA_SAR_Ed:
|
||||||
|
case BX_IA_NOT_Eb:
|
||||||
|
case BX_IA_NEG_Eb:
|
||||||
|
case BX_IA_NOT_Ew:
|
||||||
|
case BX_IA_NEG_Ew:
|
||||||
|
case BX_IA_NOT_Ed:
|
||||||
|
case BX_IA_NEG_Ed:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void L4SysExperiment::readFromFileToVector(std::ifstream &file, std::vector<trace_instr> &instr_list)
|
void L4SysExperiment::readFromFileToVector(std::ifstream &file,
|
||||||
{
|
std::vector<trace_instr> &instr_list) {
|
||||||
file >> hex;
|
file >> hex;
|
||||||
while (!file.eof()) {
|
while (!file.eof()) {
|
||||||
trace_instr curr_instr;
|
trace_instr curr_instr;
|
||||||
@ -167,7 +251,8 @@ void L4SysExperiment::readFromFileToVector(std::ifstream &file, std::vector<trac
|
|||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void L4SysExperiment::changeBochsInstruction(bxInstruction_c *dest, bxInstruction_c *src) {
|
void L4SysExperiment::changeBochsInstruction(bxInstruction_c *dest,
|
||||||
|
bxInstruction_c *src) {
|
||||||
// backup the current and insert the faulty instruction
|
// backup the current and insert the faulty instruction
|
||||||
bxInstruction_c old_instr;
|
bxInstruction_c old_instr;
|
||||||
memcpy(&old_instr, dest, sizeof(bxInstruction_c));
|
memcpy(&old_instr, dest, sizeof(bxInstruction_c));
|
||||||
@ -186,6 +271,7 @@ void L4SysExperiment::changeBochsInstruction(bxInstruction_c *dest, bxInstructio
|
|||||||
bool L4SysExperiment::run() {
|
bool L4SysExperiment::run() {
|
||||||
Logger log("L4Sys", false);
|
Logger log("L4Sys", false);
|
||||||
BPSingleEvent bp(0, L4SYS_ADDRESS_SPACE);
|
BPSingleEvent bp(0, L4SYS_ADDRESS_SPACE);
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
log << "startup" << endl;
|
log << "startup" << endl;
|
||||||
|
|
||||||
@ -364,8 +450,8 @@ bool L4SysExperiment::run() {
|
|||||||
|
|
||||||
// do the logging in case everything worked out
|
// do the logging in case everything worked out
|
||||||
logInjection(log, param);
|
logInjection(log, param);
|
||||||
log << "register data: 0x" << hex
|
log << "register data: 0x" << hex << ((int) data) << " -> 0x"
|
||||||
<< ((int) data) << " -> 0x" << ((int) newdata) << endl;
|
<< ((int) newdata) << endl;
|
||||||
} else if (exp_type == param.msg.IDCFLIP) {
|
} else if (exp_type == param.msg.IDCFLIP) {
|
||||||
// this is a twisted one
|
// this is a twisted one
|
||||||
|
|
||||||
@ -396,7 +482,8 @@ bool L4SysExperiment::run() {
|
|||||||
// decode the instruction
|
// decode the instruction
|
||||||
bxInstruction_c bochs_instr;
|
bxInstruction_c bochs_instr;
|
||||||
memset(&bochs_instr, 0, sizeof(bxInstruction_c));
|
memset(&bochs_instr, 0, sizeof(bxInstruction_c));
|
||||||
fetchInstruction(simulator.getCPUContext(), curr_instr_plain, &bochs_instr);
|
fetchInstruction(simulator.getCPUContext(), curr_instr_plain,
|
||||||
|
&bochs_instr);
|
||||||
|
|
||||||
// inject it
|
// inject it
|
||||||
changeBochsInstruction(cache_entry->i, &bochs_instr);
|
changeBochsInstruction(cache_entry->i, &bochs_instr);
|
||||||
@ -405,7 +492,105 @@ bool L4SysExperiment::run() {
|
|||||||
logInjection(log, param);
|
logInjection(log, param);
|
||||||
} else if (exp_type == param.msg.RATFLIP) {
|
} else if (exp_type == param.msg.RATFLIP) {
|
||||||
bxICacheEntry_c *cache_entry = simulator.getICacheEntry();
|
bxICacheEntry_c *cache_entry = simulator.getICacheEntry();
|
||||||
|
Udis86 udis(calculateInstructionAddress(), cache_entry->i->ilen());
|
||||||
|
if (udis.fetchNextInstruction()) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ud_type_t which;
|
||||||
|
unsigned rnd = random() % 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) */
|
||||||
|
|
||||||
|
if (which != UD_NONE) {
|
||||||
|
// 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);
|
||||||
|
int exchg_reg = -1;
|
||||||
|
RegisterManager &rm = simulator.getRegisterManager();
|
||||||
|
|
||||||
|
// first, decide if the fault hits a register bound to this thread
|
||||||
|
// (ten percent chance)
|
||||||
|
if (rand() % 10) {
|
||||||
|
// assure exchange of registers
|
||||||
|
exchg_reg = rand() % 7;
|
||||||
|
if (exchg_reg == bochs_reg)
|
||||||
|
exchg_reg++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare the fault
|
||||||
|
regdata_t data = rm.getRegister(bochs_reg)->getData();
|
||||||
|
if (rnd > 0) {
|
||||||
|
//input register - do the fault injection here
|
||||||
|
regdata_t newdata = 0;
|
||||||
|
if(exchg_reg >= 0) {
|
||||||
|
newdata = rm.getRegister(exchg_reg)->getData();
|
||||||
|
} else {
|
||||||
|
newdata = rand();
|
||||||
|
}
|
||||||
|
rm.getRegister(bochs_reg)->setData(newdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the instruction
|
||||||
|
BPSingleEvent execute_single_instr(ANY_INSTR, L4SYS_ADDRESS_SPACE);
|
||||||
|
simulator.addEvent(&execute_single_instr);
|
||||||
|
waitIOOrOther(false);
|
||||||
|
simulator.removeEvent(&execute_single_instr);
|
||||||
|
|
||||||
|
// restore
|
||||||
|
if (rnd > 0) {
|
||||||
|
// restore input register
|
||||||
|
rm.getRegister(bochs_reg)->setData(data);
|
||||||
|
} else if (rnd == 0) {
|
||||||
|
// output register - do the fault injection here
|
||||||
|
if(exchg_reg >= 0) {
|
||||||
|
// write the result into the wrong local register
|
||||||
|
regdata_t newdata = rm.getRegister(bochs_reg)->getData();
|
||||||
|
rm.getRegister(exchg_reg)->setData(newdata);
|
||||||
|
}
|
||||||
|
// restore the value of the actual output register
|
||||||
|
// in reality, it would never have been overwritten
|
||||||
|
rm.getRegister(bochs_reg)->setData(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// aftermath
|
// aftermath
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
message L4SysProtoMsg {
|
message L4SysProtoMsg {
|
||||||
// experiment types
|
// experiment types
|
||||||
enum ExperimentType {
|
enum ExperimentType {
|
||||||
GPRFLIP = 10;
|
GPRFLIP = 1;
|
||||||
RATFLIP = 15;
|
RATFLIP = 2;
|
||||||
IDCFLIP = 20;
|
IDCFLIP = 3;
|
||||||
ALUINSTR = 30;
|
ALUINSTR = 4;
|
||||||
}
|
}
|
||||||
// parameters
|
// parameters
|
||||||
required ExperimentType exp_type = 10;
|
required ExperimentType exp_type = 1;
|
||||||
required int32 instr_offset = 20;
|
required int32 instr_offset = 2;
|
||||||
required int32 bit_offset = 30;
|
required int32 bit_offset = 3;
|
||||||
|
|
||||||
// results
|
// results
|
||||||
// make these optional to reduce overhead for server->client communication
|
// make these optional to reduce overhead for server->client communication
|
||||||
@ -22,13 +22,13 @@ message L4SysProtoMsg {
|
|||||||
UNKNOWN = 6;
|
UNKNOWN = 6;
|
||||||
}
|
}
|
||||||
// instruction pointer where injection was done
|
// instruction pointer where injection was done
|
||||||
optional uint32 injection_ip = 40;
|
optional uint32 injection_ip = 4;
|
||||||
// result type, see above
|
// result type, see above
|
||||||
optional ResultType resulttype = 50;
|
optional ResultType resulttype = 5;
|
||||||
// result data, depending on resulttype (see source code)
|
// result data, depending on resulttype (see source code)
|
||||||
optional uint32 resultdata = 60;
|
optional uint32 resultdata = 6;
|
||||||
// generated output
|
// generated output
|
||||||
optional string output = 70;
|
optional string output = 7;
|
||||||
// optional textual description of what happened
|
// optional textual description of what happened
|
||||||
optional string details = 80;
|
optional string details = 8;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user