Added far branch origin to bx_instr_far_branch instrumentation callback by user request
Updated instrumentation examples Fixed code duplication
This commit is contained in:
parent
fe49c73a6b
commit
3b237df41d
@ -1285,6 +1285,28 @@ public: // for now...
|
||||
bx_guard_found_t guard_found;
|
||||
#endif
|
||||
|
||||
#if BX_INSTRUMENTATION
|
||||
// store far branch CS:EIP pair for instrumentation purposes
|
||||
// unfortunatelly prev_rip CPU field cannot be used as is because it
|
||||
// could be overwritten by task switch which could happen as result
|
||||
// of the far branch
|
||||
struct {
|
||||
Bit16u prev_cs;
|
||||
bx_address prev_rip;
|
||||
} far_branch;
|
||||
|
||||
#define FAR_BRANCH_PREV_CS (BX_CPU_THIS_PTR far_branch.prev_cs)
|
||||
#define FAR_BRANCH_PREV_RIP (BX_CPU_THIS_PTR far_branch.prev_rip)
|
||||
|
||||
#define BX_INSTR_FAR_BRANCH_ORIGIN() { \
|
||||
BX_CPU_THIS_PTR far_branch.prev_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value; \
|
||||
BX_CPU_THIS_PTR far_branch.prev_rip = PREV_RIP; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define BX_INSTR_FAR_BRANCH_ORIGIN()
|
||||
#endif
|
||||
|
||||
// for paging
|
||||
struct {
|
||||
bx_TLB_entry entry[BX_TLB_SIZE] BX_CPP_AlignN(16);
|
||||
@ -4945,6 +4967,8 @@ public: // for now...
|
||||
BX_SMF bx_bool relocate_apic(Bit64u val_64);
|
||||
#endif
|
||||
|
||||
BX_SMF void call_far16(bxInstruction_c *i, Bit16u cs_raw, Bit16u disp16);
|
||||
BX_SMF void call_far32(bxInstruction_c *i, Bit16u cs_raw, Bit32u disp32);
|
||||
BX_SMF void task_gate(bxInstruction_c *i, bx_selector_t *selector, bx_descriptor_t *gate_descriptor, unsigned source);
|
||||
BX_SMF void jump_protected(bxInstruction_c *i, Bit16u cs, bx_address disp) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void jmp_call_gate(bx_selector_t *selector, bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(2);
|
||||
|
@ -43,6 +43,42 @@ BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near16(Bit16u new_IP)
|
||||
#endif
|
||||
}
|
||||
|
||||
void BX_CPU_C::call_far16(bxInstruction_c *i, Bit16u cs_raw, Bit16u disp16)
|
||||
{
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_call;
|
||||
#endif
|
||||
|
||||
RSP_SPECULATIVE;
|
||||
|
||||
if (protected_mode()) {
|
||||
call_protected(i, cs_raw, disp16);
|
||||
}
|
||||
else {
|
||||
// CS.LIMIT can't change when in real/v8086 mode
|
||||
if (disp16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_ERROR(("%s: instruction pointer not within code segment limits", i->getIaOpcodeNameShort()));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
push_16(IP);
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
EIP = (Bit32u) disp16;
|
||||
}
|
||||
|
||||
RSP_COMMIT;
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear16_Iw(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
|
||||
@ -108,6 +144,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar16_Iw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u ip, cs_raw;
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
@ -145,7 +183,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar16_Iw(bxInstruction_c *i)
|
||||
done:
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -175,39 +214,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL16_Ap(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_call;
|
||||
#endif
|
||||
|
||||
Bit16u disp16 = i->Iw();
|
||||
Bit16u cs_raw = i->Iw2();
|
||||
|
||||
RSP_SPECULATIVE;
|
||||
|
||||
if (protected_mode()) {
|
||||
call_protected(i, cs_raw, disp16);
|
||||
goto done;
|
||||
}
|
||||
|
||||
push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
push_16(IP);
|
||||
|
||||
// CS.LIMIT can't change when in real/v8086 mode
|
||||
if (disp16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_ERROR(("%s: instruction pointer not within code segment limits", i->getIaOpcodeNameShort()));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
EIP = (Bit32u) disp16;
|
||||
|
||||
done:
|
||||
RSP_COMMIT;
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
call_far16(i, cs_raw, disp16);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -236,44 +246,12 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EwR(bxInstruction_c *i)
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL16_Ep(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u cs_raw;
|
||||
Bit16u op1_16;
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_call;
|
||||
#endif
|
||||
|
||||
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
op1_16 = read_virtual_word(i->seg(), eaddr);
|
||||
cs_raw = read_virtual_word(i->seg(), (eaddr+2) & i->asize_mask());
|
||||
Bit16u op1_16 = read_virtual_word(i->seg(), eaddr);
|
||||
Bit16u cs_raw = read_virtual_word(i->seg(), (eaddr+2) & i->asize_mask());
|
||||
|
||||
RSP_SPECULATIVE;
|
||||
|
||||
if (protected_mode()) {
|
||||
call_protected(i, cs_raw, op1_16);
|
||||
goto done;
|
||||
}
|
||||
|
||||
push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
push_16(IP);
|
||||
|
||||
// CS.LIMIT can't change when in real/v8086 mode
|
||||
if (op1_16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_ERROR(("%s: instruction pointer not within code segment limits", i->getIaOpcodeNameShort()));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
EIP = op1_16;
|
||||
|
||||
done:
|
||||
RSP_COMMIT;
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL_INDIRECT,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
call_far16(i, cs_raw, op1_16);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -510,6 +488,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP16_Ep(bxInstruction_c *i)
|
||||
Bit16u cs_raw;
|
||||
Bit16u op1_16;
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
@ -535,13 +515,16 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP16_Ep(bxInstruction_c *i)
|
||||
done:
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP_INDIRECT,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET16(bxInstruction_c *i)
|
||||
{
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
@ -602,6 +585,7 @@ done:
|
||||
#endif
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
|
@ -45,6 +45,42 @@ BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near32(Bit32u new_EIP
|
||||
#endif
|
||||
}
|
||||
|
||||
void BX_CPU_C::call_far32(bxInstruction_c *i, Bit16u cs_raw, Bit32u disp32)
|
||||
{
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_call;
|
||||
#endif
|
||||
|
||||
RSP_SPECULATIVE;
|
||||
|
||||
if (protected_mode()) {
|
||||
call_protected(i, cs_raw, disp32);
|
||||
}
|
||||
else {
|
||||
// CS.LIMIT can't change when in real/v8086 mode
|
||||
if (disp32 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_ERROR(("%s: instruction pointer not within code segment limits", i->getIaOpcodeNameShort()));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
push_32(EIP);
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
EIP = disp32;
|
||||
}
|
||||
|
||||
RSP_COMMIT;
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear32_Iw(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
|
||||
@ -105,6 +141,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar32_Iw(bxInstruction_c *i)
|
||||
{
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_ret;
|
||||
#endif
|
||||
@ -142,7 +180,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar32_Iw(bxInstruction_c *i)
|
||||
done:
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -173,42 +212,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL32_Ap(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
|
||||
|
||||
Bit16u cs_raw;
|
||||
Bit32u disp32;
|
||||
Bit16u cs_raw = i->Iw2();
|
||||
Bit32u disp32 = i->Id();
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_call;
|
||||
#endif
|
||||
|
||||
disp32 = i->Id();
|
||||
cs_raw = i->Iw2();
|
||||
|
||||
RSP_SPECULATIVE;
|
||||
|
||||
if (protected_mode()) {
|
||||
call_protected(i, cs_raw, disp32);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// CS.LIMIT can't change when in real/v8086 mode
|
||||
if (disp32 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_ERROR(("%s: instruction pointer not within code segment limits", i->getIaOpcodeNameShort()));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
push_32(EIP);
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
EIP = disp32;
|
||||
|
||||
done:
|
||||
RSP_COMMIT;
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
call_far32(i, cs_raw, disp32);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -237,45 +244,12 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EdR(bxInstruction_c *i)
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL32_Ep(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u cs_raw;
|
||||
Bit32u op1_32;
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_call;
|
||||
#endif
|
||||
|
||||
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
/* pointer, segment address pair */
|
||||
op1_32 = read_virtual_dword(i->seg(), eaddr);
|
||||
cs_raw = read_virtual_word (i->seg(), (eaddr+4) & i->asize_mask());
|
||||
Bit32u op1_32 = read_virtual_dword(i->seg(), eaddr);
|
||||
Bit16u cs_raw = read_virtual_word (i->seg(), (eaddr+4) & i->asize_mask());
|
||||
|
||||
RSP_SPECULATIVE;
|
||||
|
||||
if (protected_mode()) {
|
||||
call_protected(i, cs_raw, op1_32);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// CS.LIMIT can't change when in real/v8086 mode
|
||||
if (op1_32 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
||||
BX_ERROR(("%s: instruction pointer not within code segment limits", i->getIaOpcodeNameShort()));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
push_32(EIP);
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
EIP = op1_32;
|
||||
|
||||
done:
|
||||
RSP_COMMIT;
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL_INDIRECT,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
call_far32(i, cs_raw, op1_32);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -506,6 +480,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_Ap(bxInstruction_c *i)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
if (i->os32L()) {
|
||||
disp32 = i->Id();
|
||||
}
|
||||
@ -531,7 +507,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_Ap(bxInstruction_c *i)
|
||||
|
||||
done:
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -553,6 +530,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP32_Ep(bxInstruction_c *i)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
/* pointer, segment address pair */
|
||||
@ -576,7 +555,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP32_Ep(bxInstruction_c *i)
|
||||
|
||||
done:
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP_INDIRECT,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -587,6 +567,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET32(bxInstruction_c *i)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_IRET)) Svm_Vmexit(SVM_VMEXIT_IRET);
|
||||
@ -645,6 +627,7 @@ done:
|
||||
#endif
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
|
@ -89,6 +89,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar64_Iw(bxInstruction_c *i)
|
||||
{
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_ret;
|
||||
#endif
|
||||
@ -99,6 +101,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar64_Iw(bxInstruction_c *i)
|
||||
return_protected(i, i->Iw());
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
@ -157,6 +160,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL64_Ep(bxInstruction_c *i)
|
||||
{
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_call;
|
||||
#endif
|
||||
@ -173,6 +178,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL64_Ep(bxInstruction_c *i)
|
||||
call_protected(i, cs_raw, op1_64);
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL_INDIRECT,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
@ -407,6 +413,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP64_Ep(bxInstruction_c *i)
|
||||
{
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
Bit64u op1_64 = read_linear_qword(i->seg(), get_laddr64(i->seg(), eaddr));
|
||||
@ -417,6 +425,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP64_Ep(bxInstruction_c *i)
|
||||
jump_protected(i, cs_raw, op1_64);
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP_INDIRECT,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
@ -426,6 +435,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET64(bxInstruction_c *i)
|
||||
{
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_IRET)) Svm_Vmexit(SVM_VMEXIT_IRET);
|
||||
@ -457,6 +468,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET64(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
|
@ -871,6 +871,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSENTER(bxInstruction_c *i)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
BX_CPU_THIS_PTR clear_VM(); // do this just like the book says to do
|
||||
BX_CPU_THIS_PTR clear_IF();
|
||||
BX_CPU_THIS_PTR clear_RF();
|
||||
@ -945,6 +947,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSENTER(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_SYSENTER,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
#endif
|
||||
|
||||
@ -965,6 +968,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSEXIT(bxInstruction_c *i)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->os64L()) {
|
||||
if (!IsCanonical(RDX)) {
|
||||
@ -1044,6 +1049,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSEXIT(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_SYSEXIT,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
#endif
|
||||
|
||||
@ -1063,6 +1069,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSCALL(bxInstruction_c *i)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long_mode())
|
||||
{
|
||||
@ -1174,6 +1182,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSCALL(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_SYSCALL,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
#endif
|
||||
|
||||
@ -1198,6 +1207,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSRET(bxInstruction_c *i)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
{
|
||||
@ -1305,6 +1316,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSRET(bxInstruction_c *i)
|
||||
RIP = temp_RIP;
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_SYSRET,
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
#endif
|
||||
|
||||
|
@ -62,6 +62,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BOUND_GdMa(bxInstruction_c *i)
|
||||
// is useful for an ICE system
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT1(bxInstruction_c *i)
|
||||
{
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
VMexit_Event(BX_PRIVILEGED_SOFTWARE_INTERRUPT, 1, 0, 0);
|
||||
#endif
|
||||
@ -82,14 +84,16 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT1(bxInstruction_c *i)
|
||||
interrupt(1, BX_PRIVILEGED_SOFTWARE_INTERRUPT, 0, 0);
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
|
||||
EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT3(bxInstruction_c *i)
|
||||
{
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
// INT 3 is not IOPL sensitive
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
@ -108,8 +112,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT3(bxInstruction_c *i)
|
||||
interrupt(3, BX_SOFTWARE_EXCEPTION, 0, 0);
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
|
||||
EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -119,6 +123,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT_Ib(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u vector = i->Ib();
|
||||
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
VMexit_Event(BX_SOFTWARE_INTERRUPT, vector, 0, 0);
|
||||
#endif
|
||||
@ -143,8 +149,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT_Ib(bxInstruction_c *i)
|
||||
interrupt(vector, BX_SOFTWARE_INTERRUPT, 0, 0);
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
|
||||
EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
@ -152,6 +158,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT_Ib(bxInstruction_c *i)
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INTO(bxInstruction_c *i)
|
||||
{
|
||||
if (get_OF()) {
|
||||
BX_INSTR_FAR_BRANCH_ORIGIN();
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
VMexit_Event(BX_SOFTWARE_EXCEPTION, 4, 0, 0);
|
||||
@ -169,8 +176,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INTO(bxInstruction_c *i)
|
||||
interrupt(4, BX_SOFTWARE_EXCEPTION, 0, 0);
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
|
||||
EIP);
|
||||
FAR_BRANCH_PREV_CS, FAR_BRANCH_PREV_RIP,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
}
|
||||
|
||||
BX_NEXT_TRACE(i);
|
||||
|
@ -172,7 +172,7 @@ void bx_instr_ucnear_branch(unsigned cpu, unsigned what, bx_address branch_eip,
|
||||
branch_taken(cpu, new_eip);
|
||||
}
|
||||
|
||||
void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u new_cs, bx_address new_eip)
|
||||
void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u prev_cs, bx_address prev_eip, Bit16u new_cs, bx_address new_eip)
|
||||
{
|
||||
branch_taken(cpu, new_eip);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ void bx_instr_reset(unsigned cpu, unsigned type);
|
||||
void bx_instr_cnear_branch_taken(unsigned cpu, bx_address branch_eip, bx_address new_eip);
|
||||
void bx_instr_cnear_branch_not_taken(unsigned cpu, bx_address branch_eip);
|
||||
void bx_instr_ucnear_branch(unsigned cpu, unsigned what, bx_address branch_eip, bx_address new_eip);
|
||||
void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u new_cs, bx_address new_eip);
|
||||
void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u prev_cs, bx_address prev_eip, Bit16u new_cs, bx_address new_eip);
|
||||
|
||||
void bx_instr_before_execution(unsigned cpu, bxInstruction_c *i);
|
||||
void bx_instr_after_execution(unsigned cpu, bxInstruction_c *i);
|
||||
@ -67,7 +67,8 @@ void bx_instr_lin_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsig
|
||||
#define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, branch_eip, new_eip) bx_instr_cnear_branch_taken(cpu_id, branch_eip, new_eip)
|
||||
#define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id, branch_eip) bx_instr_cnear_branch_not_taken(cpu_id, branch_eip)
|
||||
#define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, branch_eip, new_eip) bx_instr_ucnear_branch(cpu_id, what, branch_eip, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip) bx_instr_far_branch(cpu_id, what, new_cs, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, prev_cs, prev_eip, new_cs, new_eip) \
|
||||
bx_instr_far_branch(cpu_id, what, prev_cs, prev_eip, new_cs, new_eip)
|
||||
|
||||
/* decoding completed */
|
||||
#define BX_INSTR_OPCODE(cpu_id, i, opcode, len, is32, is64)
|
||||
@ -128,7 +129,7 @@ void bx_instr_lin_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsig
|
||||
#define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, branch_eip, new_eip)
|
||||
#define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id, branch_eip)
|
||||
#define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, branch_eip, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, prev_cs, prev_eip, new_cs, new_eip)
|
||||
|
||||
/* decoding completed */
|
||||
#define BX_INSTR_OPCODE(cpu_id, i, opcode, len, is32, is64)
|
||||
|
@ -142,7 +142,7 @@ void bxInstrumentation::bx_instr_ucnear_branch(unsigned what, bx_address branch_
|
||||
branch_taken(new_eip);
|
||||
}
|
||||
|
||||
void bxInstrumentation::bx_instr_far_branch(unsigned what, Bit16u new_cs, bx_address new_eip)
|
||||
void bxInstrumentation::bx_instr_far_branch(unsigned what, Bit16u prev_cs, bx_address prev_eip, Bit16u new_cs, bx_address new_eip)
|
||||
{
|
||||
branch_taken(new_eip);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
void bx_instr_cnear_branch_taken(bx_address branch_eip, bx_address new_eip);
|
||||
void bx_instr_cnear_branch_not_taken(bx_address branch_eip);
|
||||
void bx_instr_ucnear_branch(unsigned what, bx_address branch_eip, bx_address new_eip);
|
||||
void bx_instr_far_branch(unsigned what, Bit16u new_cs, bx_address new_eip);
|
||||
void bx_instr_far_branch(unsigned what, Bit16u prev_cs, bx_address prev_eip, Bit16u new_cs, bx_address new_eip);
|
||||
|
||||
void bx_instr_before_execution(bxInstruction_c *i);
|
||||
void bx_instr_after_execution(bxInstruction_c *i);
|
||||
@ -118,7 +118,7 @@ extern bxInstrumentation *icpu;
|
||||
#define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, branch_eip, new_eip) icpu[cpu_id].bx_instr_cnear_branch_taken(branch_eip, new_eip)
|
||||
#define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id, branch_eip) icpu[cpu_id].bx_instr_cnear_branch_not_taken(branch_eip)
|
||||
#define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, branch_eip, new_eip) icpu[cpu_id].bx_instr_ucnear_branch(what, branch_eip, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip) icpu[cpu_id].bx_instr_far_branch(what, new_cs, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, prev_cs, prev_eip, new_cs, new_eip) icpu[cpu_id].bx_instr_far_branch(what, prev_cs, prev_eip, new_cs, new_eip)
|
||||
|
||||
/* decoding completed */
|
||||
#define BX_INSTR_OPCODE(cpu_id, i, opcode, len, is32, is64)
|
||||
@ -179,7 +179,7 @@ extern bxInstrumentation *icpu;
|
||||
#define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, branch_eip, new_eip)
|
||||
#define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id, branch_eip)
|
||||
#define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, branch_eip, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, prev_cs, prev_eip, new_cs, new_eip)
|
||||
|
||||
/* decoding completed */
|
||||
#define BX_INSTR_OPCODE(cpu_id, i, opcode, len, is32, is64)
|
||||
|
@ -57,7 +57,7 @@ void bx_instr_before_execution(unsigned cpu, bxInstruction_c *i);
|
||||
#define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, branch_eip, new_eip)
|
||||
#define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id, branch_eip)
|
||||
#define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, branch_eip, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, prev_cs, prev_rip, new_cs, new_eip)
|
||||
|
||||
/* decoding completed */
|
||||
#define BX_INSTR_OPCODE(cpu_id, i, opcode, len, is32, is64)
|
||||
@ -120,7 +120,7 @@ void bx_instr_before_execution(unsigned cpu, bxInstruction_c *i);
|
||||
#define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, branch_eip, new_eip)
|
||||
#define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id, branch_eip)
|
||||
#define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, branch_eip, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip)
|
||||
#define BX_INSTR_FAR_BRANCH(cpu_id, what, prev_cs, prev_rip, new_cs, new_eip)
|
||||
|
||||
/* decoding completed */
|
||||
#define BX_INSTR_OPCODE(cpu_id, i, opcode, len, is32, is64)
|
||||
|
@ -66,25 +66,25 @@ state. The callback receives monitored memory range and MWAIT flags as a
|
||||
parameters.
|
||||
|
||||
|
||||
void bx_instr_cnear_branch_taken(unsigned cpu, bx_address branch_eip, bx_address new_eip);
|
||||
void bx_instr_cnear_branch_taken(unsigned cpu, bx_address branch_rip, bx_address new_rip);
|
||||
|
||||
The callback is called each time, when currently executed instruction is a
|
||||
conditional near branch and it is taken.
|
||||
|
||||
|
||||
void bx_instr_cnear_branch_not_taken(unsigned cpu, bx_address branch_eip);
|
||||
void bx_instr_cnear_branch_not_taken(unsigned cpu, bx_address branch_rip);
|
||||
|
||||
The callback is called each time, when currently executed instruction is a
|
||||
conditional near branch and it is not taken.
|
||||
|
||||
|
||||
void bx_instr_ucnear_branch(unsigned cpu, unsigned what, bx_address branch_eip, bx_address new_eip);
|
||||
void bx_instr_ucnear_branch(unsigned cpu, unsigned what, bx_address branch_rip, bx_address new_rip);
|
||||
|
||||
The callback is called each time, when currently executed instruction is an
|
||||
unconditional near branch (always taken).
|
||||
|
||||
|
||||
void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u new_cs, bx_address new_eip);
|
||||
void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u prev_cs, bx_address prev_rip, Bit16u new_cs, bx_address new_rip);
|
||||
|
||||
The callback is called each time, when currently executed instruction is an
|
||||
unconditional far branch (always taken).
|
||||
@ -130,7 +130,7 @@ The callback is called each time, when Bochs simulator executes an interrupt
|
||||
The callback is called each time, when Bochs simulator executes an exception.
|
||||
|
||||
|
||||
void bx_instr_hwinterrupt(unsigned cpu, unsigned vector, Bit16u cs, bx_address eip);
|
||||
void bx_instr_hwinterrupt(unsigned cpu, unsigned vector, Bit16u cs, bx_address rip);
|
||||
|
||||
The callback is called each time, when Bochs simulator executes a hardware
|
||||
interrupt.
|
||||
@ -248,7 +248,7 @@ Known problems:
|
||||
Feature requests:
|
||||
|
||||
1. BX_INSTR_CNEAR_BRANCH_NOT_TAKEN callback should have an additional
|
||||
'not taken' new_EIP parameter.
|
||||
'not taken' new_rip parameter.
|
||||
|
||||
2. BX_INSTR_SMI, BX_INSTR_NMI, BX_INSTR_SIPI and other external events
|
||||
callbacks
|
||||
|
Loading…
x
Reference in New Issue
Block a user