Files
fail/core/SAL/bochs/Jump.ah

140 lines
4.5 KiB
Plaintext

#ifndef __JUMP_AH__
#define __JUMP_AH__
#include "config/FailConfig.hpp"
#ifdef CONFIG_EVENT_JUMP
#include <iostream>
#include <cstdlib>
#include <string>
#include <ctime>
#include "../../../bochs/bochs.h"
#include "../SALInst.hpp"
// FIXME: This seems (partial) deprecated/incomplete as well...
aspect Jump {
// Note: Have a look at the Bochs-Code (cpu/cpu.h) and the Intel
// Architecture Software Developer's Manual - Instruction Set Reference
// p. 3-329 (PDF p. 369) for further information:
// http://www.intel.com/design/intarch/manuals/243191.htm
// Default conditional-jump instructions: they are evaluating the FLAGS,
// defined in ctrl_xfer[16 | 32 | 64].cc, Postfix: 16-Bit: w, 32-Bit: d, 64-Bit: q
pointcut defJumpInstructions() =
"% ...::bx_cpu_c::JO_J%(...)" ||
"% ...::bx_cpu_c::JNO_J%(...)" ||
"% ...::bx_cpu_c::JB_J%(...)" ||
"% ...::bx_cpu_c::JNB_J%(...)" ||
"% ...::bx_cpu_c::JZ_J%(...)" ||
"% ...::bx_cpu_c::JNZ_J%(...)" ||
"% ...::bx_cpu_c::JBE_J%(...)" ||
"% ...::bx_cpu_c::JNBE_J%(...)" ||
"% ...::bx_cpu_c::JS_J%(...)" ||
"% ...::bx_cpu_c::JNS_J%(...)" ||
"% ...::bx_cpu_c::JP_J%(...)" ||
"% ...::bx_cpu_c::JNP_J%(...)" ||
"% ...::bx_cpu_c::JL_J%(...)" ||
"% ...::bx_cpu_c::JNL_J%(...)" ||
"% ...::bx_cpu_c::JLE_J%(...)" ||
"% ...::bx_cpu_c::JNLE_J%(...)";
// Special cases: they are evaluating the content of the CX-/ECX-/RCX-registers
// (NOT the FLAGS):
pointcut regJumpInstructions() =
"% ...::bx_cpu_c::JCXZ_Jb(...)" || // ctrl_xfer16.cc
"% ...::bx_cpu_c::JECXZ_Jb(...)" || // ctrl_xfer32.cc
"% ...::bx_cpu_c::JRCXZ_Jb(...)"; // ctrl_xfer64.cc
/* TODO: Loop-Instructions needed? Example: "LOOPNE16_Jb"
pointcut loopInstructions() = ...;
*/
/* TODO: Conditional-Data-Moves needed? Example: "CMOVZ_GwEwR"
pointcut dataMoveInstructions() = ...;
*/
advice execution (defJumpInstructions()) : around()
{
bxInstruction_c* pInstr = *(tjp->arg<0>()); // bxInstruction_c-object
fail::simulator.onJumpEvent(true, pInstr->getIaOpcode());
/*
JoinPoint::That* pThis = tjp->that();
if(pThis == NULL)
pThis = BX_CPU(0);
assert(pThis != NULL && "FATAL ERROR: tjp->that() returned null ptr! (Maybe called on a static instance?)");
// According to the Intel-Spec (p. 3-329f), the following flags are relevant:
bool fZeroFlag = pThis->get_ZF();
bool fCarryFlag = pThis->get_CF();
bool fSignFlag = pThis->get_SF();
bool fOverflowFlag = pThis->get_OF();
bool fParityFlag = pThis->get_PF();
//
// Step-1: Modify one or more of the fxxxFlag according to the error you want to inject
// (using pThis->set_XX(new_val))
// Step-2: Call tjp->proceed();
// Step-3: Eventually, unwind the changes of Step-1
//
// Example:
if(g_fEnableInjection) // event fired?
{
g_fEnableInjection = false;
// Obviously, this advice matches *all* jump-instructions so that it is not clear
// which flag have to be modified in order to invert the jump. For simplification,
// we will invert *all* flags. This avoids a few case differentiations.
cout << ">>> Manipulating jump-destination (inverted)... \"" << tjp->signature() << "\" ";
pThis->set_ZF(!fZeroFlag);
pThis->set_SF(!fSignFlag);
pThis->set_CF(!fCarryFlag);
pThis->set_OF(!fOverflowFlag);
pThis->set_PF(!fParityFlag);
tjp->proceed();
pThis->set_ZF(fZeroFlag);
pThis->set_SF(fSignFlag);
pThis->set_CF(fCarryFlag);
pThis->set_OF(fOverflowFlag);
pThis->set_PF(fParityFlag);
cout << "finished (jump taken)!" << endl;
}
else
*/
tjp->proceed();
}
advice execution (regJumpInstructions()) : around ()
{
bxInstruction_c* pInstr = *(tjp->arg<0>()); // bxInstruction_c-object
fail::simulator.onJumpEvent(false, pInstr->getIaOpcode());
/*
JoinPoint::That* pThis = tjp->that();
assert(pThis != NULL && "Unexpected: tjp->that() returned null ptr! (Maybe called on a static instance?)");
// Note: Direct access to the registers using the bochs-macros (defined in
// bochs.h) is not possibly due to the fact that they are using the this-ptr.
Bit16u CX = (Bit16u)(pThis->gen_reg[1].word.rx);
Bit32u ECX = (Bit32u)(pThis->gen_reg[1].dword.erx);
#if BX_SUPPORT_X86_64
Bit64u RCX = (Bit64u)(pThis->gen_reg[1].rrx);
#endif
//
// Step-1: Modify CX, ECX or RCX according to the error you want to inject
// Step-2: Call tjp->proceed();
// Step-3: Eventually, unwind the changes of Step-1
//
*/
tjp->proceed();
}
};
#endif // CONFIG_EVENT_JUMP
#endif // __JUMP_AH__