added ability to modify sregs from bochs debugger

This commit is contained in:
Stanislav Shwartsman 2009-12-27 16:38:09 +00:00
parent cccbac3bb7
commit d779842da3
8 changed files with 1053 additions and 959 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dbg_main.cc,v 1.221 2009-12-04 16:53:11 sshwarts Exp $
// $Id: dbg_main.cc,v 1.222 2009-12-27 16:38:09 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2009 The Bochs Project
@ -3561,67 +3561,121 @@ bx_address bx_dbg_get_instruction_pointer(void)
return BX_CPU(dbg_cpu)->get_instruction_pointer();
}
bx_bool bx_dbg_read_pmode_descriptor(Bit16u sel, bx_descriptor_t *descriptor)
{
bx_selector_t selector;
Bit32u dword1, dword2;
bx_address desc_base;
/* if selector is NULL, error */
if ((sel & 0xfffc) == 0) {
dbg_printf("bx_dbg_read_pmode_descriptor: Dereferencing a NULL selector!\n");
return 0;
}
/* parse fields in selector */
parse_selector(sel, &selector);
if (selector.ti) {
// LDT
if (((Bit32u)selector.index*8 + 7) > BX_CPU(dbg_cpu)->ldtr.cache.u.segment.limit_scaled) {
dbg_printf("bx_dbg_read_pmode_descriptor: selector (0x%04x) > LDT size limit\n", selector.index*8);
return 0;
}
desc_base = BX_CPU(dbg_cpu)->ldtr.cache.u.segment.base;
}
else {
// GDT
if (((Bit32u)selector.index*8 + 7) > BX_CPU(dbg_cpu)->gdtr.limit) {
dbg_printf("bx_dbg_read_pmode_descriptor: selector (0x%04x) > GDT size limit\n", selector.index*8);
return 0;
}
desc_base = BX_CPU(dbg_cpu)->gdtr.base;
}
if (! bx_dbg_read_linear(dbg_cpu, desc_base + selector.index * 8, 4, (Bit8u*) &dword1)) {
dbg_printf("bx_dbg_read_pmode_descriptor: cannot read selector 0x%04x (index=0x%04x)\n", sel, selector.index);
return 0;
}
if (! bx_dbg_read_linear(dbg_cpu, desc_base + selector.index * 8 + 4, 4, (Bit8u*) &dword2)) {
dbg_printf("bx_dbg_read_pmode_descriptor: cannot read selector 0x%04x (index=0x%04x)\n", sel, selector.index);
return 0;
}
memset (descriptor, 0, sizeof (descriptor));
BX_CPU(dbg_cpu)->parse_descriptor(dword1, dword2, descriptor);
if (!descriptor->segment) {
dbg_printf("bx_dbg_read_pmode_descriptor: selector 0x%04x points to a system descriptor and is not supported!\n", sel);
return 0;
}
/* #NP(selector) if descriptor is not present */
if (descriptor->p==0) {
dbg_printf("bx_dbg_read_pmode_descriptor: descriptor 0x%04x not present!\n", sel);
return 0;
}
return 1;
}
void bx_dbg_load_segreg(unsigned seg_no, unsigned value)
{
bx_segment_reg_t sreg;
if (seg_no > 6) {
dbg_printf("bx_dbg_load_segreg: unknown segment register !");
return;
}
if (value > 0xffff) {
dbg_printf("bx_dbg_load_segreg: segment selector out of limits !");
return;
}
unsigned cpu_mode = BX_CPU(dbg_cpu)->get_cpu_mode();
if (cpu_mode == BX_MODE_LONG_64) {
dbg_printf("bx_dbg_load_segreg: not supported in long64 mode !");
return;
}
if (! BX_CPU(dbg_cpu)->protected_mode()) {
parse_selector(value, &sreg.selector);
sreg.cache.valid = SegValidCache;
sreg.cache.p = 1;
sreg.cache.dpl = (cpu_mode == BX_MODE_IA32_V8086);
sreg.cache.segment = 1;
sreg.cache.type = BX_DATA_READ_WRITE_ACCESSED;
sreg.cache.u.segment.base = sreg.selector.value << 4;
sreg.cache.u.segment.limit_scaled = 0xffff;
sreg.cache.u.segment.g = 0;
sreg.cache.u.segment.d_b = 0;
sreg.cache.u.segment.avl = 0;
sreg.selector.rpl = (cpu_mode == BX_MODE_IA32_V8086);
BX_CPU(dbg_cpu)->dbg_set_sreg(seg_no, &sreg);
}
else {
parse_selector(value, &sreg.selector);
if (bx_dbg_read_pmode_descriptor(value, &sreg.cache)) {
BX_CPU(dbg_cpu)->dbg_set_sreg(seg_no, &sreg);
}
}
}
bx_address bx_dbg_get_laddr(Bit16u sel, bx_address ofs)
{
bx_address laddr;
if (BX_CPU(dbg_cpu)->protected_mode()) {
bx_descriptor_t descriptor;
bx_selector_t selector;
Bit32u dword1, dword2;
/* if selector is NULL, error */
if ((sel & 0xfffc) == 0) {
dbg_printf("ERROR: Dereferencing a NULL selector!\n");
return 0;
}
/* parse fields in selector */
BX_CPU(dbg_cpu)->parse_selector(sel, &selector);
bx_address desc_base;
if (selector.ti) {
// LDT
if (((Bit32u)selector.index*8 + 7) > BX_CPU(dbg_cpu)->ldtr.cache.u.segment.limit_scaled) {
dbg_printf("ERROR: selector (%04x) > LDT size limit\n", selector.index*8);
return 0;
}
desc_base = BX_CPU(dbg_cpu)->ldtr.cache.u.segment.base;
}
else {
// GDT
if (((Bit32u)selector.index*8 + 7) > BX_CPU(dbg_cpu)->gdtr.limit) {
dbg_printf("ERROR: selector (%04x) > GDT size limit\n", selector.index*8);
return 0;
}
desc_base = BX_CPU(dbg_cpu)->gdtr.base;
}
if (! bx_dbg_read_linear(dbg_cpu, desc_base + selector.index * 8, 4, (Bit8u*) &dword1)) {
dbg_printf("ERROR: cannot read selector (0x%04x)\n", selector.index);
return 0;
}
if (! bx_dbg_read_linear(dbg_cpu, desc_base + selector.index * 8 + 4, 4, (Bit8u*) &dword2)) {
dbg_printf("ERROR: cannot read selector (0x%04x)\n", selector.index);
return 0;
}
memset (&descriptor, 0, sizeof (descriptor));
BX_CPU(dbg_cpu)->parse_descriptor(dword1, dword2, &descriptor);
if (!descriptor.segment) {
dbg_printf("ERROR: selector %04x points to a system descriptor and is not supported!\n", sel);
return 0;
}
/* #NP(selector) if descriptor is not present */
if (descriptor.p==0) {
dbg_printf("ERROR: descriptor %04x not present!\n", sel);
return 0;
}
Bit32u lowaddr, highaddr;
if (! bx_dbg_read_pmode_descriptor(sel, &descriptor))
return 0;
// expand-down
if (IS_DATA_SEGMENT(descriptor.type) && IS_DATA_SEGMENT_EXPAND_DOWN(descriptor.type)) {
lowaddr = descriptor.u.segment.limit_scaled;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: debug.h,v 1.62 2009-12-04 16:53:11 sshwarts Exp $
// $Id: debug.h,v 1.63 2009-12-27 16:38:09 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2009 The Bochs Project
@ -214,6 +214,7 @@ void bx_dbg_set_reg8h_value(unsigned reg, Bit8u value);
void bx_dbg_set_reg16_value(unsigned reg, Bit16u value);
void bx_dbg_set_reg32_value(unsigned reg, Bit32u value);
void bx_dbg_set_reg64_value(unsigned reg, Bit64u value);
void bx_dbg_load_segreg(unsigned reg, unsigned value);
bx_address bx_dbg_get_laddr(Bit16u sel, bx_address ofs);
void bx_dbg_step_over_command(void);
void bx_dbg_trace_command(bx_bool enable);

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: parser.y,v 1.41 2009-11-20 12:15:21 sshwarts Exp $
// $Id: parser.y,v 1.42 2009-12-27 16:38:09 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
%{
@ -488,6 +488,10 @@ set_command:
{
bx_dbg_set_reg64_value($2, $4);
}
| BX_TOKEN_SET BX_TOKEN_SEGREG '=' expression '\n'
{
bx_dbg_load_segreg($2, $4);
}
;
breakpoint_command:
@ -1173,6 +1177,7 @@ BX_TOKEN_NONSEG_REG:
/* Arithmetic expression for vbreak command */
vexpression:
BX_TOKEN_NUMERIC { $$ = $1; }
| BX_TOKEN_STRING { $$ = bx_dbg_get_symbol_value($1); free($1);}
| BX_TOKEN_8BL_REG { $$ = bx_dbg_get_reg8l_value($1); }
| BX_TOKEN_8BH_REG { $$ = bx_dbg_get_reg8h_value($1); }
| BX_TOKEN_16B_REG { $$ = bx_dbg_get_reg16_value($1); }

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.631 2009-12-22 12:11:09 sshwarts Exp $
// $Id: cpu.h,v 1.632 2009-12-27 16:38:09 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2009 The Bochs Project
@ -2758,6 +2758,7 @@ public: // for now...
BX_SMF void dbg_take_dma(void);
BX_SMF bx_bool dbg_set_reg(unsigned reg, Bit32u val);
BX_SMF bx_bool dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no);
BX_SMF bx_bool dbg_set_sreg(unsigned sreg_no, bx_segment_reg_t *sreg);
BX_SMF void dbg_get_tr(bx_dbg_sreg_t *sreg);
BX_SMF void dbg_get_ldtr(bx_dbg_sreg_t *sreg);
BX_SMF void dbg_get_gdtr(bx_dbg_global_sreg_t *sreg);
@ -3165,7 +3166,6 @@ public: // for now...
BX_SMF Bit32u read_eflags(void) { return BX_CPU_THIS_PTR force_flags(); }
BX_SMF bx_bool allow_io(bxInstruction_c *i, Bit16u addr, unsigned len) BX_CPP_AttrRegparmN(3);
BX_SMF void parse_selector(Bit16u raw_selector, bx_selector_t *selector) BX_CPP_AttrRegparmN(2);
BX_SMF void parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp) BX_CPP_AttrRegparmN(3);
BX_SMF Bit8u get_ar_byte(const bx_descriptor_t *d) BX_CPP_AttrRegparmN(1);
BX_SMF void set_ar_byte(bx_descriptor_t *d, Bit8u ar_byte) BX_CPP_AttrRegparmN(2);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: debugstuff.cc,v 1.109 2009-12-04 16:53:12 sshwarts Exp $
// $Id: debugstuff.cc,v 1.110 2009-12-27 16:38:09 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2009 The Bochs Project
@ -333,6 +333,19 @@ bx_bool BX_CPU_C::dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no)
return(1);
}
bx_bool BX_CPU_C::dbg_set_sreg(unsigned sreg_no, bx_segment_reg_t *sreg)
{
if (sreg_no < 6) {
BX_CPU_THIS_PTR sregs[sreg_no] = *sreg;
if (sreg_no == BX_SEG_REG_CS)
invalidate_prefetch_q();
return 1;
}
return 0;
}
void BX_CPU_C::dbg_get_tr(bx_dbg_sreg_t *sreg)
{
sreg->valid = BX_CPU_THIS_PTR tr.cache.valid;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: descriptor.h,v 1.32 2009-10-14 20:45:29 sshwarts Exp $
// $Id: descriptor.h,v 1.33 2009-12-27 16:38:09 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2009 Stanislav Shwartsman
@ -183,13 +183,11 @@ typedef struct {
bx_descriptor_t cache;
} bx_segment_reg_t;
#if BX_CPU_LEVEL < 2
/* no GDTR or IDTR register in an 8086 */
#else
typedef struct {
bx_address base; /* base address: 24bits=286,32bits=386,64bits=x86-64 */
Bit16u limit; /* limit, 16bits */
} bx_global_segment_reg_t;
#endif
void parse_selector(Bit16u raw_selector, bx_selector_t *selector);
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: segment_ctrl_pro.cc,v 1.123 2009-12-04 16:53:12 sshwarts Exp $
// $Id: segment_ctrl_pro.cc,v 1.124 2009-12-27 16:38:09 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2009 The Bochs Project
@ -284,8 +284,7 @@ void BX_CPU_C::validate_seg_regs(void)
validate_seg_reg(BX_SEG_REG_GS);
}
void BX_CPP_AttrRegparmN(2)
BX_CPU_C::parse_selector(Bit16u raw_selector, bx_selector_t *selector)
void parse_selector(Bit16u raw_selector, bx_selector_t *selector)
{
selector->value = raw_selector;
selector->index = raw_selector >> 3;