First steps to integrate the fourth experiment type, still debugging

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1587 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
unzner
2012-09-02 17:17:39 +00:00
parent f992f53d5d
commit ea1c9f5716
6 changed files with 138 additions and 156 deletions

View File

@ -10,6 +10,7 @@ set(MY_PROTOS
)
set(MY_CAMPAIGN_SRCS
aluinstr.hpp
experiment.hpp
experiment.cc
campaign.hpp

View File

@ -1,12 +1,14 @@
#ifndef __L4SYS_ALUINSTR_HPP__
#define __L4SYS_ALUINSTR_HPP__
#if 0
/**
* Forward declaration of the Bochs instruction decode table.
* This is necessary because, inconveniently, it is not declared in a header file.
*/
#include "cpu/fetchdecode.h"
static const BxOpcodeInfo_t *BxOpcodeInfo32;
#endif
/**
* Trying to order X86 ALU instructions.
@ -54,7 +56,10 @@ struct BochsALUInstr {
Bit8u opcode;
/**
* the reg part of the modr/m field (known as nnn in bxInstruction_c)
* A value of 8 or higher marks this field unused.
* it is used to
* a) further subdivide the functionality of a given opcode
* b) specify a register the instruction is supposed to use
* In this class, a value of 8 or higher marks this field unused.
*/
Bit8u reg;
/**
@ -63,7 +68,7 @@ struct BochsALUInstr {
* to their opcode. It is necessary to store this separately for
* several reasons, one being the ability to separate
* ALU input latch faults from ALU instruction latch faults.
* A value of 8 or higher marks this field unused.
* In this class, a value of 8 or higher marks this field unused.
*/
Bit8u opcodeRegisterOffset;
/**
@ -141,90 +146,77 @@ const BochsALUInstr aluInstructions [] = {
#undef SHIFTOPS
/* --- \\\ SHIFT OPERATIONS /// --- */
/**
*
* The remaining instructions, roughly ordered,
* in the form of a (probably obsolete) experiment method
* /**
* Assigns a given opcode a class of ALU instructions
* @param opcode the opcode to examine
* @returns an enum AluClass object
/* --- /// BINARY OPERATIONS \\\ --- */
X86AluClass isALUInstruction(unsigned opcode);
*
* X86AluClass L4SysExperiment::isALUInstruction(unsigned opcode) {
switch (opcode) {
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_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_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:
default:
return ALU_UNDEF;
}
}
*
*/
// reg, immediate
// a macro to reduce copy-paste overhead
#define BINOPS(IACODE, OPCODE8, OPCODE16) \
{ BX_IA_##IACODE##_ALIb, OPCODE8, 8, 8, ALU_IMM8_REG }, \
{ BX_IA_##IACODE##_AXIw, OPCODE16, 8, 8, ALU_IMM16_REG }, \
{ BX_IA_##IACODE##_EAXId, OPCODE16, 8, 8, ALU_IMM32_REG }
// register ax, immediate
BINOPS(ADC, 0x14, 0x15),
BINOPS(ADD, 0x04, 0x05),
BINOPS(AND, 0x24, 0x25),
BINOPS(CMP, 0x3C, 0x3D),
BINOPS(OR, 0x0C, 0x0D),
BINOPS(SBB, 0x1C, 0x1D),
BINOPS(SUB, 0x2C, 0x2D),
BINOPS(XOR, 0x34, 0x35),
#undef BINOPS
// a macro to reduce copy-paste overhead
#define BINOPS(IACODE, OPCODE8, OPCODE16) \
{ BX_IA_##IACODE##_EbGb, OPCODE8, 7, 8, ALU_IMM8_RM8 }, \
{ BX_IA_##IACODE##_EwGw, OPCODE16, 7, 8, ALU_IMM16_RM16 }, \
{ BX_IA_##IACODE##_EdGd, OPCODE16, 7, 8, ALU_IMM32_RM32 }
// r/m, arbitrary register
BINOPS(ADC, 0x10, 0x11),
BINOPS(ADD, 0x00, 0x01),
BINOPS(AND, 0x20, 0x21),
BINOPS(CMP, 0x38, 0x39),
BINOPS(OR, 0x08, 0x09),
BINOPS(SBB, 0x18, 0x19),
BINOPS(SUB, 0x28, 0x29),
BINOPS(XOR, 0x30, 0x31),
#undef BINOPS
#define BINOPS(IACODE, OPCODE8, OPCODE16) \
{ BX_IA_##IACODE##_GbEb, OPCODE8, 7, 8, ALU_IMM8_RM8 }, \
{ BX_IA_##IACODE##_GwEw, OPCODE16, 7, 8, ALU_IMM16_RM16 }, \
{ BX_IA_##IACODE##_GdEd, OPCODE16, 7, 8, ALU_IMM32_RM32 }
// arbitrary register, r/m
BINOPS(ADC, 0x12, 0x13),
BINOPS(ADD, 0x02, 0x03),
BINOPS(AND, 0x22, 0x23),
BINOPS(CMP, 0x3a, 0x3b),
BINOPS(OR, 0x0a, 0x0b),
BINOPS(SBB, 0x1a, 0x1b),
BINOPS(SUB, 0x2a, 0x2b),
BINOPS(XOR, 0x32, 0x33),
#undef BINOPS
// a macro to reduce copy-paste overhead
#define BINOPS(OPCODE, WDE, WDI, CLASS) \
{ BX_IA_ADC_E##WDE##I##WDI, OPCODE, 2, 8, CLASS }, \
{ BX_IA_ADD_E##WDE##I##WDI, OPCODE, 0, 8, CLASS }, \
{ BX_IA_AND_E##WDE##I##WDI, OPCODE, 4, 8, CLASS }, \
{ BX_IA_CMP_E##WDE##I##WDI, OPCODE, 7, 8, CLASS }, \
{ BX_IA_OR_E##WDE##I##WDI, OPCODE, 1, 8, CLASS }, \
{ BX_IA_SBB_E##WDE##I##WDI, OPCODE, 3, 8, CLASS }, \
{ BX_IA_SUB_E##WDE##I##WDI, OPCODE, 5, 8, CLASS }, \
{ BX_IA_XOR_E##WDE##I##WDI, OPCODE, 6, 8, CLASS }
BINOPS(80, b, b, ALU_IMM8_RM8),
BINOPS(81, w, w, ALU_IMM16_RM16),
BINOPS(81, d, d, ALU_IMM32_RM32),
BINOPS(83, w, w, ALU_IMM8_RM16),
BINOPS(83, d, d, ALU_IMM8_RM32),
#undef BINOPS
/* --- \\\ BINARY OPERATIONS /// --- */
};
#endif // __L4SYS_ALUINSTR_HPP__

View File

@ -63,7 +63,7 @@ bool L4SysCampaign::run() {
srand(time(NULL));
for (int i = 0; i < 25; ++i) {
L4SysExperimentData *d = new L4SysExperimentData;
d->msg.set_exp_type(d->msg.GPRFLIP);
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);

View File

@ -20,10 +20,6 @@
#include "l4sys.pb.h"
// FIXME libudis86 test -- remove me
#include <udis86.h>
void foo() { ud_t x; ud_init(&x); }
using namespace std;
using namespace fail;
@ -160,34 +156,24 @@ bool L4SysExperiment::run() {
log << "startup" << endl;
struct stat teststruct;
#if PREPARATION_STEP == 1
// STEP 1: run until interesting function starts, and save state
if (stat(L4SYS_STATE_FOLDER, &teststruct) == -1) {
bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
simulator.addListenerAndResume(&bp);
log << "test function entry reached, saving state" << endl;
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or "
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
simulator.save(L4SYS_STATE_FOLDER);
}
bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
simulator.addListenerAndResume(&bp);
log << "test function entry reached, saving state" << endl;
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or "
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
simulator.save(L4SYS_STATE_FOLDER);
#elif PREPARATION_STEP == 2
// STEP 2: determine instructions executed
#ifdef PREPARE_EXPERIMENT
log << "restoring state" << endl;
simulator.restore(L4SYS_STATE_FOLDER);
log << "EIP = " << hex
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
// make sure the timer interrupt doesn't disturb us
simulator.addSuppressedInterrupt(0);
int count;
int ul = 0, kernel = 0;
// count the first instruction which has already been executed
int count = 1;
int ul = 1, kernel = 0;
bp.setWatchInstructionPointer(ANY_ADDR);
for (count = 0; bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT; ++count) {
for (; bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT; ++count) {
simulator.addListenerAndResume(&bp);
if(bp.getTriggerInstructionPointer() < 0xC0000000) {
ul++;
@ -198,7 +184,35 @@ bool L4SysExperiment::run() {
}
log << "test function calculation position reached after " << dec << count << " instructions; "
<< "ul: " << ul << ", kernel: " << kernel << endl;
#else
#elif PREPARATION_STEP == 3
// STEP 3: determine the output of a "golden run"
log << "restoring state" << endl;
simulator.restore(L4SYS_STATE_FOLDER);
log << "EIP = " << hex
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
ofstream golden_run_file(L4SYS_CORRECT_OUTPUT);
bp.setWatchInstructionPointer(L4SYS_FUNC_EXIT);
bp.setCounter(L4SYS_ITERATION_COUNT);
simulator.addListener(&bp);
BaseListener* ev = waitIOOrOther(true);
if (ev == &bp) {
golden_run.assign(output.c_str());
golden_run_file << output.c_str();
log << "Output successfully logged!" << endl;
} else {
log
<< "Obviously, there is some trouble with the events registered - aborting simulation!"
<< endl;
golden_run_file.close();
simulator.terminate(10);
}
simulator.clearListeners();
bp.setCounter(1);
log << "saving output generated during normal execution" << endl;
golden_run_file.close();
#if 0
// the files currently get too big.
/* I do not really have a clever idea to solve this.
@ -260,38 +274,13 @@ bool L4SysExperiment::run() {
}
#endif
// STEP 3: determine the output of a "golden run"
if (stat(L4SYS_CORRECT_OUTPUT, &teststruct) == -1) {
log << "restoring state" << endl;
simulator.restore(L4SYS_STATE_FOLDER);
log << "EIP = " << hex
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
// make sure the timer interrupt doesn't disturb us
simulator.addSuppressedInterrupt(0);
ofstream golden_run_file(L4SYS_CORRECT_OUTPUT);
bp.setWatchInstructionPointer(L4SYS_FUNC_EXIT);
bp.setCounter(L4SYS_ITERATION_COUNT);
simulator.addListener(&bp);
BaseListener* ev = waitIOOrOther(true);
if (ev == &bp) {
golden_run.assign(output.c_str());
golden_run_file << output.c_str();
log << "Output successfully logged!" << endl;
} else {
log
<< "Obviously, there is some trouble with the events registered - aborting simulation!"
<< endl;
golden_run_file.close();
simulator.terminate(10);
}
simulator.clearListeners();
bp.setCounter(1);
log << "saving output generated during normal execution" << endl;
golden_run_file.close();
} else {
#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;
simulator.terminate(1);
}
ifstream golden_run_file(L4SYS_CORRECT_OUTPUT);
golden_run.reserve(teststruct.st_size);
@ -303,9 +292,7 @@ bool L4SysExperiment::run() {
//the generated output probably has a similar length
output.reserve(teststruct.st_size);
}
// STEP 4: The actual experiment.
log << "restoring state" << endl;
simulator.restore(L4SYS_STATE_FOLDER);
@ -366,7 +353,7 @@ bool L4SysExperiment::run() {
// this is a twisted one
// initial definitions
bxICacheEntry_c *cache_entry = simulator.getCPUContext()->getICacheEntry();
bxICacheEntry_c *cache_entry = simulator.getICacheEntry();
unsigned length_in_bits = cache_entry->i->ilen() << 3;
// get the instruction in plain text in inject the error there

View File

@ -6,8 +6,7 @@
#include "efw/ExperimentFlow.hpp"
#include "efw/JobClient.hpp"
#include "util/Logger.hpp"
// not implemented yet
// #include "aluinstr.hpp"
#include "aluinstr.hpp"
class L4SysExperimentData;

View File

@ -6,9 +6,10 @@
// the bounds of the program
#define L4SYS_ADDRESS_SPACE 0x203d000
#define L4SYS_FUNC_ENTRY 0x1000400
#define L4SYS_FUNC_EXIT 0x10005b0
#define L4SYS_NUMINSTR 56052774
#define L4SYS_FUNC_ENTRY 0x10025ca
#define L4SYS_FUNC_EXIT 0x1002810
#define L4SYS_NUMINSTR 83084798
// kernel: 3599694, userland: 79485104
#define L4SYS_ITERATION_COUNT 1
@ -20,6 +21,8 @@
// flags
#define HEADLESS_EXPERIMENT
//#define PREPARE_EXPERIMENT
// 0 - preparation complete
// >0 - next step to execute
#define PREPARATION_STEP 3
#endif // __EXPERIMENT_INFO_HPP__