Some Bugfixes

ALUInstr should work now


git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1710 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
unzner
2012-10-03 15:02:22 +00:00
parent 4b8a417eda
commit 8a902d2b50
2 changed files with 162 additions and 12 deletions

View File

@ -0,0 +1,150 @@
#include "aluinstr.hpp"
#include <string.h>
#include <time.h>
#include "bochs.h"
#include "cpu/cpu.h"
#include "cpu/fetchdecode.h"
/**
* Forward declaration of the Bochs instruction decode table.
* This is necessary because, inconveniently, it is not declared in a header file.
*/
//extern bxIAOpcodeTable *BxOpcodesTable;
bxIAOpcodeTable MyBxOpcodesTable[] = {
#define bx_define_opcode(a, b, c, d, e) { b, c, e },
#include "cpu/ia_opcodes.h"
};
#undef bx_define_opcode
BochsALUInstructions::BochsALUInstructions(BochsALUInstr const *initial_array, size_t array_size)
{
allInstr = reinterpret_cast<BochsALUInstr*>(malloc(array_size));
memcpy(allInstr, initial_array, array_size);
allInstrSize = array_size / sizeof(BochsALUInstr);
srand(time(NULL));
buildEquivalenceClasses();
}
void BochsALUInstructions::buildEquivalenceClasses() {
for (size_t i = 0; i < allInstrSize; i++) {
InstrList &currVector = equivalenceClasses[allInstr[i].aluClass];
if (allInstr[i].opcodeRegisterOffset <= BochsALUInstr::REG_COUNT) {
// add an entry for each possible opcode
for (int j = 0; j < allInstr[i].opcodeRegisterOffset; j++) {
BochsALUInstr newInstr = { allInstr[i].bochs_operation,
allInstr[i].opcode + j,
allInstr[i].reg,
j,
allInstr[i].aluClass };
currVector.push_back(newInstr);
}
} else {
// normal case -- just add the instruction
currVector.push_back(allInstr[i]);
}
}
}
void BochsALUInstructions::bochsInstrToInstrStruct(bxInstruction_c const *src, BochsALUInstr *dest) const {
if (dest == NULL) return;
//Note: it may be necessary to introduce a solution for two-byte
//opcodes once they overlap with one-byte ones
for (size_t i = 0; i < allInstrSize; i++) {
// first, check the opcode
if (allInstr[i].opcodeRegisterOffset <= BochsALUInstr::REG_COUNT) {
// the opcode listed in allInstr is the starting value for a range
if (src->b1() < allInstr[i].opcode ||
src->b1() > allInstr[i].opcode + BochsALUInstr::REG_COUNT) {
continue;
}
} else if (src->b1() != allInstr[i].opcode) {
// normal case -- just compare the opcode
continue;
}
// second, check the opcode extension
if (allInstr[i].reg < BochsALUInstr::REG_COUNT &&
allInstr[i].reg != src->nnn()) {
continue;
}
// found it - now copy
if (allInstr[i].opcodeRegisterOffset <= BochsALUInstr::REG_COUNT) {
BochsALUInstr result = { allInstr[i].bochs_operation,
src->b1(),
allInstr[i].reg,
src->rm(),
allInstr[i].aluClass};
memcpy(dest, &result, sizeof(BochsALUInstr));
} else {
memcpy(dest, &allInstr[i], sizeof(BochsALUInstr));
}
return;
}
// not found - marking it undefined
dest->aluClass = ALU_UNDEF;
}
bool BochsALUInstructions::isALUInstruction(const bxInstruction_c *src) {
lastOrigInstr = src;
bochsInstrToInstrStruct(src, &lastInstr);
if (lastInstr.aluClass != ALU_UNDEF) {
return true;
}
return false;
}
bxInstruction_c BochsALUInstructions::randomEquivalent() const {
// find a random member of the same equivalence class
X86AluClass equClassID = lastInstr.aluClass;
if (equClassID == ALU_UNDEF) {
// something went wrong - just return the original instruction
return *lastOrigInstr;
}
InstrList const &destList = equivalenceClasses.at(equClassID);
BochsALUInstr dest;
// make sure the two are not equal by chance
do {
int index = rand() % destList.size();
dest = destList[index];
} while (!memcmp(&dest, &lastInstr, sizeof(BochsALUInstr)));
// first, copy everything
bxInstruction_c result;
memcpy(&result, lastOrigInstr, sizeof(bxInstruction_c));
// then change what has to be different
// execute functions
bxIAOpcodeTable entry = MyBxOpcodesTable[dest.bochs_operation];
if (result.execute2 == NULL) {
result.execute = entry.execute2;
} else {
result.execute = entry.execute1;
result.execute2 = entry.execute2;
}
// opcodes
result.metaInfo.ia_opcode = dest.bochs_operation;
result.setB1(dest.opcode);
if (dest.opcodeRegisterOffset < BochsALUInstr::REG_COUNT) {
result.setRm(dest.opcodeRegisterOffset);
}
// finally, return the result
return result;
}
#ifdef DEBUG
#include <iostream>
void BochsALUInstructions::printNestedMap() {
for (EquivClassMap::iterator it = equivalenceClasses.begin();
it != equivalenceClasses.end(); it++) {
std::cerr << it->first << ":" << std::endl;
for (InstrList::iterator jt = it->second.begin();
jt != it->second.end(); jt++) {
std::cerr << std::hex << " " << jt->bochs_operation
<< "," << (unsigned) jt->opcode << std::dec << "," << (unsigned) jt->reg
<< "," << (unsigned) jt->opcodeRegisterOffset << ","
<< jt->aluClass << std::endl;
}
}
}
#endif

View File

@ -195,7 +195,7 @@ bool L4SysExperiment::run() {
bp.setWatchInstructionPointer(ANY_ADDR);
for (; bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT; ++count) {
simulator.addListenerAndResume(&bp);
if(bp.getTriggerInstructionPointer() < 0xC0000000) {
if (bp.getTriggerInstructionPointer() < 0xC0000000) {
ul++;
} else {
kernel++;
@ -277,7 +277,7 @@ bool L4SysExperiment::run() {
bxInstruction_c instr;
fetchInstruction(simulator.getCPUContext(), calculateInstructionAddress(), &instr);
// add it to a second list if it is an ALU instruction
if(isALUInstruction(instr.getIaOpcode())) {
if (isALUInstruction(instr.getIaOpcode())) {
alu_instr_list.push_back(new_instr);
alu_instr_file.write(reinterpret_cast<char*>(&new_instr), sizeof(trace_instr));
}
@ -302,7 +302,7 @@ bool L4SysExperiment::run() {
}
ifstream golden_run_file(L4SYS_CORRECT_OUTPUT);
if(!golden_run_file.good()) {
if (!golden_run_file.good()) {
log << "Could not open file " << L4SYS_CORRECT_OUTPUT << endl;
simulator.terminate(20);
}
@ -362,7 +362,7 @@ bool L4SysExperiment::run() {
// inject
if (exp_type == param.msg.GPRFLIP) {
if(!param.msg.has_register_offset()) {
if (!param.msg.has_register_offset()) {
param.msg.set_resulttype(param.msg.UNKNOWN);
param.msg.set_resultdata(
simulator.getRegisterManager().getInstructionPointer());
@ -459,7 +459,7 @@ bool L4SysExperiment::run() {
ud_type_t which;
unsigned rnd;
if(opcount == 0)
if (opcount == 0)
rnd = 0;
else
rnd = rand() % opcount;
@ -496,7 +496,7 @@ bool L4SysExperiment::run() {
if (rnd > 0) {
//input register - do the fault injection here
regdata_t newdata = 0;
if(exchg_reg >= 0) {
if (exchg_reg >= 0) {
newdata = rm.getRegister(exchg_reg)->getData();
} else {
newdata = rand();
@ -510,7 +510,7 @@ bool L4SysExperiment::run() {
// restore
if (rnd == 0) {
// output register - do the fault injection here
if(exchg_reg >= 0) {
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);
@ -529,14 +529,14 @@ bool L4SysExperiment::run() {
BochsALUInstructions aluInstrObject(aluInstructions, aluInstructionsSize);
// find the closest ALU instruction after the current IP
bxInstruction_c *currInstr = simulator.getCurrentInstruction();
while(!aluInstrObject.isALUInstruction(currInstr)) {
bxInstruction_c *currInstr;
while (!aluInstrObject.isALUInstruction(
currInstr = simulator.getCurrentInstruction())) {
singleStep();
currInstr = simulator.getCurrentInstruction();
}
// now exchange it with a random equivalent
bxInstruction_c newInstr = aluInstrObject.randomEquivalent();
if(!memcmp(&newInstr, currInstr, sizeof(bxInstruction_c))) {
if (!memcmp(&newInstr, currInstr, sizeof(bxInstruction_c))) {
// something went wrong - exit experiment
param.msg.set_resulttype(param.msg.UNKNOWN);
param.msg.set_resultdata(
@ -588,7 +588,7 @@ bool L4SysExperiment::run() {
simulator.getRegisterManager().getInstructionPointer());
param.msg.set_output(sanitised(output.c_str()));
} else if (ev == &ev_timeout) {
log << hex << "Result TIMEOUT; Last INT #:" << endl;
log << hex << "Result TIMEOUT" << endl;
param.msg.set_resulttype(param.msg.TIMEOUT);
param.msg.set_resultdata(
simulator.getRegisterManager().getInstructionPointer());