added ability to modify sregs from bochs debugger
This commit is contained in:
parent
cccbac3bb7
commit
d779842da3
@ -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;
|
||||
|
@ -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
@ -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); }
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user