diff --git a/src/core/sal/bochs/BochsListener.ah b/src/core/sal/bochs/BochsListener.ah index 54c4b58e..ea290a5e 100644 --- a/src/core/sal/bochs/BochsListener.ah +++ b/src/core/sal/bochs/BochsListener.ah @@ -37,8 +37,10 @@ aspect BochsListener { { assert(pev != NULL && "FATAL ERROR: TimerListener object ptr cannot be NULL!"); return static_cast( - bx_pc_system.register_timer(pev, fail::onTimerTrigger, pev->getTimeout(), - false, 1/*start immediately*/, "Fail*: BochsController"/*name*/)); + bx_pc_system.register_timer(pev, fail::onTimerTrigger, + pev->getTimeout() * 1000 /*timeout in microseconds*/, + false /*non-continuous*/, + true /*start immediately*/, "Fail*: BochsController"/*name*/)); } bool m_unregisterTimer(TimerListener* pev) { diff --git a/src/core/sal/bochs/BochsListener.cc b/src/core/sal/bochs/BochsListener.cc index 46c71f47..42ac45e4 100644 --- a/src/core/sal/bochs/BochsListener.cc +++ b/src/core/sal/bochs/BochsListener.cc @@ -1,3 +1,4 @@ +#include "../SALInst.hpp" #include "BochsListener.hpp" #include "../SALInst.hpp" diff --git a/src/experiments/l4-sys/aluinstr.cc b/src/experiments/l4-sys/aluinstr.cc index d05c1ccb..5e465074 100644 --- a/src/experiments/l4-sys/aluinstr.cc +++ b/src/experiments/l4-sys/aluinstr.cc @@ -45,47 +45,45 @@ void BochsALUInstructions::buildEquivalenceClasses() { } } -void BochsALUInstructions::bochsInstrToInstrStruct(bxInstruction_c const *src, BochsALUInstr *dest) const { - if (dest == NULL) return; +void BochsALUInstructions::bochsInstrToInstrStruct(bxInstruction_c const &src, BochsALUInstr &dest) const { //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) { + if (src.b1() < allInstr[i].opcode || + src.b1() > allInstr[i].opcode + BochsALUInstr::REG_COUNT) { continue; } - } else if (src->b1() != allInstr[i].opcode) { + } 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()) { + 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)); + dest.bochs_operation = allInstr[i].bochs_operation; + dest.opcode = src.b1(); + dest.reg = allInstr[i].reg; + dest.opcodeRegisterOffset = src.rm(); + dest.aluClass = allInstr[i].aluClass; } else { - memcpy(dest, &allInstr[i], sizeof(BochsALUInstr)); + dest = allInstr[i]; } return; } // not found - marking it undefined - dest->aluClass = ALU_UNDEF; + dest.aluClass = ALU_UNDEF; } -bool BochsALUInstructions::isALUInstruction(const bxInstruction_c *src) { - lastOrigInstr = src; - bochsInstrToInstrStruct(src, &lastInstr); +bool BochsALUInstructions::isALUInstruction(bxInstruction_c const *src) { + memcpy(&lastOrigInstr, src, sizeof(bxInstruction_c)); + bochsInstrToInstrStruct(lastOrigInstr, lastInstr); if (lastInstr.aluClass != ALU_UNDEF) { return true; } @@ -97,7 +95,7 @@ bxInstruction_c BochsALUInstructions::randomEquivalent() const { X86AluClass equClassID = lastInstr.aluClass; if (equClassID == ALU_UNDEF) { // something went wrong - just return the original instruction - return *lastOrigInstr; + return lastOrigInstr; } InstrList const &destList = equivalenceClasses.at(equClassID); @@ -106,11 +104,10 @@ bxInstruction_c BochsALUInstructions::randomEquivalent() const { do { int index = rand() % destList.size(); dest = destList[index]; - } while (!memcmp(&dest, &lastInstr, sizeof(BochsALUInstr))); + } while (memcmp(&dest, &lastInstr, sizeof(BochsALUInstr)) == 0); // first, copy everything - bxInstruction_c result; - memcpy(&result, lastOrigInstr, sizeof(bxInstruction_c)); + bxInstruction_c result = lastOrigInstr; // then change what has to be different // execute functions diff --git a/src/experiments/l4-sys/aluinstr.hpp b/src/experiments/l4-sys/aluinstr.hpp index 7b7be32f..b85db913 100644 --- a/src/experiments/l4-sys/aluinstr.hpp +++ b/src/experiments/l4-sys/aluinstr.hpp @@ -8,12 +8,16 @@ #include "cpu/instr.h" /** - * Trying to order X86 ALU instructions. + * \enum X86AluClass + * + * \brief An attempt to order X86 ALU instructions. + * + * An attempt to order X86 ALU instructions. * Each instruction class contains instructions * of roughly equal length and operands, so that * all the bxInstruction_c structures residing within * one class contain the same member fields (except for - * b1, rm and the execute pointers). + * b1, rm and the execute function pointers). */ enum X86AluClass { ALU_UNDEF = 0, @@ -32,6 +36,8 @@ enum X86AluClass { }; /** + * \struct BochsALUInstr + * * A struct describing a specific x86 * ALU instruction in terms of Bochs. */ @@ -73,11 +79,9 @@ struct BochsALUInstr { /** - * Array containing most (all?) Bochs ALU commands. - * Attention: here, \a reg and \a opcodeRegisterOffset, if less than 8, - * define the maximum value possible in this field, - * according to the Bochs instruction decoder function. - * (see the BxOpcodeInfoG... arrays in cpu/fetchdecode.h) + * \var aluInstructions + * + * Array containing the Bochs IA-32 Integer ALU commands. */ const BochsALUInstr aluInstructions [] = { // Now is a great time to open Volume 2 of Intel's IA-32 documentation. @@ -266,33 +270,81 @@ const BochsALUInstr aluInstructions [] = { /* --- \\\ BINARY OPERATIONS /// --- */ }; -const size_t aluInstructionsSize = sizeof(aluInstructions); +/** + * \var aluInstructionsSize + * + * the size of aluInstructions, in bytes + */ +size_t const aluInstructionsSize = sizeof(aluInstructions); +/** + * \class BochsALUInstructions + * + * \brfief This class handles Bochs ALU instructions. + * + * This class analyses a given bxInstruction_c object: + * if it belongs to the instructions listed in + * \a allInstr, the user can request a random + * ALU instruction with an equivalent addressing mode. + */ class BochsALUInstructions { public: /** - * + * A list of Bochs instructions */ typedef std::vector InstrList; + /** + * This data structure assigns lists of instructions on their ALU equivalence + * class. + * + * \see X86AluClass + */ typedef std::map EquivClassMap; /** - * + * Creates a new BochsALUInstructions object. + * @param initial_array initialises \a allInstr + * @param array_size the size of initial_array */ BochsALUInstructions(const BochsALUInstr *initial_array, size_t array_size); + /** + * Destroys the BochsALUInstructions object. + */ ~BochsALUInstructions() { free(allInstr); } + /** + * Determines if a given Bochs instruction is an ALU instruction. + * @param src the instruction to examine. It is stored internally + * to be reused with \a randomEquivalent + * @returns \c true if the given instruction is an ALU instruction, + * \c false otherwise + */ bool isALUInstruction(const bxInstruction_c *src); + /** + * Determines a new bxInstruction_c object with an equivalent + * addressing mode. + * @returns a bxInstruction_c object as described above + */ bxInstruction_c randomEquivalent() const; protected: - void bochsInstrToInstrStruct(const bxInstruction_c *src, BochsALUInstr *dest) const; + /** + * Convert a bxInstruction_c object into its matching BochsALUInstr object. + * @params src the Bochs instruction to examine + * @params dest the resulting BochsALUInstr object. Its \a aluClass field + * is set to \c ALU_UNDEF in case no matching ALU instruction + * could be found. In this case, all other fields of dest are invalid. + */ + void bochsInstrToInstrStruct(bxInstruction_c const &src, BochsALUInstr &dest) const; private: - BochsALUInstr *allInstr; - BochsALUInstr lastInstr; - const bxInstruction_c *lastOrigInstr; - size_t allInstrSize; - EquivClassMap equivalenceClasses; + BochsALUInstr *allInstr; //(L4SYS_NUMINSTR * 1.1)); simulator.addListener(&ev_incomplete); + log << calculateTimeout() << endl; TimerListener ev_timeout(calculateTimeout()); simulator.addListener(&ev_timeout);