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:
Stanislav Shwartsman 2015-01-11 20:45:39 +00:00
parent fe49c73a6b
commit 3b237df41d
12 changed files with 188 additions and 165 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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)

View File

@ -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)

View File

@ -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