2006-04-27 19:11:45 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2008-05-02 00:08:37 +04:00
|
|
|
// $Id: extdb.cc,v 1.29 2008-05-01 20:08:37 sshwarts Exp $
|
2006-04-27 19:11:45 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-09-15 05:36:13 +04:00
|
|
|
#include "bochs.h"
|
|
|
|
#ifdef WIN32
|
2002-10-04 01:07:04 +04:00
|
|
|
// windows.h included in bochs.h
|
2002-09-15 05:36:13 +04:00
|
|
|
#else
|
2004-10-30 01:15:48 +04:00
|
|
|
# error "extdb.cc only supported in win32 environment"
|
2002-09-15 05:36:13 +04:00
|
|
|
#endif
|
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
#include "cpu.h"
|
2006-06-26 01:44:46 +04:00
|
|
|
#include "iodev/iodev.h"
|
2004-11-03 09:35:48 +03:00
|
|
|
#include "extdb.h"
|
|
|
|
|
2002-09-15 05:36:13 +04:00
|
|
|
TRegs regs;
|
|
|
|
|
|
|
|
char debug_loaded = 0;
|
|
|
|
|
|
|
|
void (*call_debugger)(TRegs *,Bit8u *, Bit32u);
|
|
|
|
|
|
|
|
void bx_external_debugger(BX_CPU_C *cpu)
|
|
|
|
{
|
|
|
|
switch (regs.debug_state) {
|
|
|
|
case debug_run:
|
|
|
|
return;
|
|
|
|
case debug_count:
|
|
|
|
if (--regs.debug_counter) return;
|
|
|
|
regs.debug_state = debug_step;
|
|
|
|
break;
|
|
|
|
case debug_skip:
|
2008-02-15 22:03:54 +03:00
|
|
|
if (cpu->get_instruction_pointer() != regs.debug_eip ||
|
|
|
|
cpu->sregs[BX_SEG_REG_CS].selector.value != regs.debug_cs) return;
|
2002-09-15 05:36:13 +04:00
|
|
|
regs.debug_state = debug_step;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2002-10-01 10:47:06 +04:00
|
|
|
#if BX_SUPPORT_X86_64
|
2002-09-15 05:36:13 +04:00
|
|
|
regs.rax = cpu->gen_reg[0].rrx;
|
|
|
|
regs.rcx = cpu->gen_reg[1].rrx;
|
|
|
|
regs.rdx = cpu->gen_reg[2].rrx;
|
|
|
|
regs.rbx = cpu->gen_reg[3].rrx;
|
|
|
|
regs.rsp = cpu->gen_reg[4].rrx;
|
|
|
|
regs.rbp = cpu->gen_reg[5].rrx;
|
|
|
|
regs.rsi = cpu->gen_reg[6].rrx;
|
|
|
|
regs.rdi = cpu->gen_reg[7].rrx;
|
|
|
|
regs.r8 = cpu->gen_reg[8].rrx;
|
|
|
|
regs.r9 = cpu->gen_reg[9].rrx;
|
|
|
|
regs.r10 = cpu->gen_reg[10].rrx;
|
|
|
|
regs.r11 = cpu->gen_reg[11].rrx;
|
|
|
|
regs.r12 = cpu->gen_reg[12].rrx;
|
|
|
|
regs.r13 = cpu->gen_reg[13].rrx;
|
|
|
|
regs.r14 = cpu->gen_reg[14].rrx;
|
|
|
|
regs.r15 = cpu->gen_reg[15].rrx;
|
2008-02-15 22:03:54 +03:00
|
|
|
regs.rip = cpu->get_instruction_pointer();
|
2002-10-01 10:47:06 +04:00
|
|
|
#else
|
|
|
|
regs.rax = cpu->gen_reg[0].dword.erx;
|
|
|
|
regs.rcx = cpu->gen_reg[1].dword.erx;
|
|
|
|
regs.rdx = cpu->gen_reg[2].dword.erx;
|
|
|
|
regs.rbx = cpu->gen_reg[3].dword.erx;
|
|
|
|
regs.rsp = cpu->gen_reg[4].dword.erx;
|
|
|
|
regs.rbp = cpu->gen_reg[5].dword.erx;
|
|
|
|
regs.rsi = cpu->gen_reg[6].dword.erx;
|
|
|
|
regs.rdi = cpu->gen_reg[7].dword.erx;
|
|
|
|
regs.r8 = 0;
|
|
|
|
regs.r9 = 0;
|
|
|
|
regs.r10 = 0;
|
|
|
|
regs.r11 = 0;
|
|
|
|
regs.r12 = 0;
|
|
|
|
regs.r13 = 0;
|
|
|
|
regs.r14 = 0;
|
|
|
|
regs.r15 = 0;
|
2008-02-15 22:03:54 +03:00
|
|
|
regs.rip = cpu->get_instruction_pointer();
|
2002-10-01 10:47:06 +04:00
|
|
|
#endif
|
2002-09-15 05:36:13 +04:00
|
|
|
regs.rflags = cpu->read_eflags();
|
2008-02-15 22:03:54 +03:00
|
|
|
regs.es = cpu->sregs[BX_SEG_REG_ES].selector.value;
|
|
|
|
regs.cs = cpu->sregs[BX_SEG_REG_CS].selector.value;
|
|
|
|
regs.ss = cpu->sregs[BX_SEG_REG_SS].selector.value;
|
|
|
|
regs.ds = cpu->sregs[BX_SEG_REG_DS].selector.value;
|
|
|
|
regs.fs = cpu->sregs[BX_SEG_REG_FS].selector.value;
|
|
|
|
regs.gs = cpu->sregs[BX_SEG_REG_GS].selector.value;
|
2002-09-15 05:36:13 +04:00
|
|
|
regs.gdt.base = cpu->gdtr.base;
|
|
|
|
regs.gdt.limit = cpu->gdtr.limit;
|
|
|
|
regs.idt.base = cpu->idtr.base;
|
|
|
|
regs.idt.limit = cpu->idtr.limit;
|
|
|
|
regs.ldt = cpu->ldtr.selector.value;
|
2008-04-01 00:56:27 +04:00
|
|
|
regs.cr0 = cpu->cr0.getRegister();
|
2002-09-15 05:36:13 +04:00
|
|
|
regs.cr1 = cpu->cr1;
|
|
|
|
regs.cr2 = cpu->cr2;
|
|
|
|
regs.cr3 = cpu->cr3;
|
2003-02-26 05:35:11 +03:00
|
|
|
#if BX_CPU_LEVEL >= 4
|
2002-09-15 18:01:16 +04:00
|
|
|
regs.cr4 = cpu->cr4.getRegister();
|
2003-02-26 05:35:11 +03:00
|
|
|
#endif
|
2005-03-01 20:49:34 +03:00
|
|
|
regs.fsbase = cpu->sregs[BX_SEG_REG_FS].cache.u.segment.base;
|
|
|
|
regs.gsbase = cpu->sregs[BX_SEG_REG_GS].cache.u.segment.base;
|
2002-10-01 10:47:06 +04:00
|
|
|
#if BX_SUPPORT_X86_64
|
2008-04-01 00:56:27 +04:00
|
|
|
regs.efer = cpu->efer.getRegister();
|
2002-10-01 10:47:06 +04:00
|
|
|
#else
|
2006-04-05 21:31:35 +04:00
|
|
|
regs.efer = 0;
|
2002-10-01 10:47:06 +04:00
|
|
|
#endif
|
2002-09-15 05:36:13 +04:00
|
|
|
|
|
|
|
if (debug_loaded == 0) {
|
|
|
|
HINSTANCE hdbg;
|
|
|
|
debug_loaded = 1;
|
|
|
|
hdbg = LoadLibrary("debug.dll");
|
|
|
|
call_debugger = (void (*)(TRegs *,Bit8u *, Bit32u)) GetProcAddress(hdbg,"call_debugger");
|
|
|
|
|
|
|
|
if (call_debugger != NULL) debug_loaded = 2;
|
|
|
|
}
|
|
|
|
if (debug_loaded == 2) {
|
2002-11-04 08:27:26 +03:00
|
|
|
DEV_vga_refresh();
|
2008-05-02 00:08:37 +04:00
|
|
|
call_debugger(®s,BX_MEM(0)->vector,BX_MEM(0)->get_memory_len());
|
2002-09-15 05:36:13 +04:00
|
|
|
}
|
|
|
|
}
|
2006-06-26 01:44:46 +04:00
|
|
|
|
2008-01-22 19:20:30 +03:00
|
|
|
void trap_debugger(bx_bool callnow, BX_CPU_C *cpu)
|
2006-06-26 01:44:46 +04:00
|
|
|
{
|
|
|
|
regs.debug_state = debug_step;
|
|
|
|
if (callnow) {
|
2008-01-22 19:20:30 +03:00
|
|
|
bx_external_debugger(cpu);
|
2006-06-26 01:44:46 +04:00
|
|
|
}
|
|
|
|
}
|