From 8a902d2b505d05bc6a78121faefb38cff1083052 Mon Sep 17 00:00:00 2001 From: unzner Date: Wed, 3 Oct 2012 15:02:22 +0000 Subject: [PATCH] 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 --- src/experiments/l4-sys/aluinstr.cc | 150 +++++++++++++++++++++++++++ src/experiments/l4-sys/experiment.cc | 24 ++--- 2 files changed, 162 insertions(+), 12 deletions(-) create mode 100644 src/experiments/l4-sys/aluinstr.cc diff --git a/src/experiments/l4-sys/aluinstr.cc b/src/experiments/l4-sys/aluinstr.cc new file mode 100644 index 00000000..d05c1ccb --- /dev/null +++ b/src/experiments/l4-sys/aluinstr.cc @@ -0,0 +1,150 @@ +#include "aluinstr.hpp" +#include +#include +#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(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 + +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 diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc index 1f303d5b..c86261cb 100644 --- a/src/experiments/l4-sys/experiment.cc +++ b/src/experiments/l4-sys/experiment.cc @@ -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(&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());