Decoding functionality for Bochs disassembler.

Fixed 'step over' debugger command using bx_dbg_read_linear method.
Small debugger fix in cpu.cc
This commit is contained in:
Stanislav Shwartsman 2006-02-05 19:48:29 +00:00
parent f2de4e5d70
commit 5a65e1065e
4 changed files with 81 additions and 76 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dbg_main.cc,v 1.48 2006-02-02 22:33:32 sshwarts Exp $
// $Id: dbg_main.cc,v 1.49 2006-02-05 19:48:26 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -577,31 +577,31 @@ void bx_dbg_timebp_command(bx_bool absolute, Bit64u time)
}
if (timebp_timer >= 0) {
if (timebp_queue_size == 0 || abs_time < timebp_queue[0]) {
/* first in queue */
for (int i = timebp_queue_size; i >= 0; i--)
timebp_queue[i+1] = timebp_queue[i];
timebp_queue[0] = abs_time;
timebp_queue_size++;
bx_pc_system.activate_timer_ticks(timebp_timer, diff, 1);
} else {
/* not first, insert at suitable place */
for (int i = 1; i < timebp_queue_size; i++) {
if (timebp_queue[i] == abs_time) {
dbg_printf("Time breakpoint not inserted (duplicate)\n");
return;
} else if (abs_time < timebp_queue[i]) {
for (int j = timebp_queue_size; j >= i; j++)
timebp_queue[j+1] = timebp_queue[j];
timebp_queue[i] = abs_time;
goto inserted;
if (timebp_queue_size == 0 || abs_time < timebp_queue[0]) {
/* first in queue */
for (int i = timebp_queue_size; i >= 0; i--)
timebp_queue[i+1] = timebp_queue[i];
timebp_queue[0] = abs_time;
timebp_queue_size++;
bx_pc_system.activate_timer_ticks(timebp_timer, diff, 1);
} else {
/* not first, insert at suitable place */
for (int i = 1; i < timebp_queue_size; i++) {
if (timebp_queue[i] == abs_time) {
dbg_printf("Time breakpoint not inserted (duplicate)\n");
return;
} else if (abs_time < timebp_queue[i]) {
for (int j = timebp_queue_size; j >= i; j++)
timebp_queue[j+1] = timebp_queue[j];
timebp_queue[i] = abs_time;
goto inserted;
}
}
}
/* last */
timebp_queue[timebp_queue_size] = abs_time;
/* last */
timebp_queue[timebp_queue_size] = abs_time;
inserted:
timebp_queue_size++;
}
timebp_queue_size++;
}
} else {
timebp_queue_size = 1;
timebp_queue[0] = abs_time;
@ -2614,8 +2614,8 @@ void bx_dbg_print_descriptor (unsigned char desc[8], int verbose)
dbg_printf("P=present=%d\n", present);
#endif
/* brief output */
// 32-bit trap gate, target=0010:c0108ec4, DPL=0, present=1
// code segment, base=0000:00cfffff, length=0xffff
// 32-bit trap gate, target=0010:c0108ec4, DPL=0, present=1
// code segment, base=0000:00cfffff, length=0xffff
if (s) {
// either a code or a data segment. bit 11 (type file MSB) then says
// 0=data segment, 1=code seg
@ -3417,30 +3417,19 @@ Bit32u bx_dbg_get_laddr(Bit16u sel, Bit32u ofs)
void bx_dbg_step_over_command ()
{
Bit8u *fetchPtr;
bxInstruction_c iStorage BX_CPP_AlignN (32);
bxInstruction_c *i = &iStorage;
bx_address Laddr = BX_CPU (dbg_cpu)->get_segment_base(BX_SEG_REG_CS) +
BX_CPU (dbg_cpu)->get_ip ();
Bit32u Paddr;
bx_bool paddr_valid;
unsigned remainingInPage;
bx_address Laddr = BX_CPU(which_cpu)->guard_found.laddr;
BX_CPU (dbg_cpu)->dbg_xlate_linear2phy (Laddr, &Paddr, &paddr_valid);
if(!paddr_valid) {
dbg_printf("bx_dbg_step_over_command:: Invalid physical address\n");
if (! bx_dbg_read_linear(dbg_cpu, Laddr, 16, bx_disasm_ibuf))
{
return;
}
fetchPtr = BX_CPU (dbg_cpu)->mem->getHostMemAddr (BX_CPU(dbg_cpu), Paddr, BX_READ);
unsigned ret = BX_CPU (dbg_cpu)->fetchDecode (fetchPtr, i, 15);
remainingInPage = BX_CPU(dbg_cpu)->eipPageWindowSize -
(BX_CPU(dbg_cpu)->dword.eip + BX_CPU(dbg_cpu)->eipPageBias);
if (ret == 0)
BX_CPU (dbg_cpu)->boundaryFetch (fetchPtr, remainingInPage, i);
x86_insn insn = bx_disassemble.decode(BX_CPU(which_cpu)->guard_found.is_32bit_code,
BX_CPU(which_cpu)->guard_found.is_64bit_code,
BX_CPU(which_cpu)->get_segment_base(BX_SEG_REG_CS),
BX_CPU(which_cpu)->guard_found.eip, bx_disasm_ibuf, bx_disasm_tbuf);
unsigned b1 = i->b1 ();
unsigned b1 = insn.b1;
switch(b1) {
// Jcc short
@ -3503,7 +3492,7 @@ void bx_dbg_step_over_command ()
return;
// jmp absolute indirect
case 0xFF:
switch (i->nnn ()) {
switch (insn.nnn) {
// near
case 4:
// far
@ -3514,7 +3503,7 @@ void bx_dbg_step_over_command ()
}
// calls, ints, loops and so on
int BpId = bx_dbg_lbreakpoint_command (bkStepOver, Laddr + i->ilen ());
int BpId = bx_dbg_lbreakpoint_command (bkStepOver, Laddr + insn.ilen);
if (BpId == -1) {
dbg_printf("bx_dbg_step_over_command:: Failed to set lbreakpoint !\n");
return;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.127 2006-02-01 18:12:08 sshwarts Exp $
// $Id: cpu.cc,v 1.128 2006-02-05 19:48:28 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -995,6 +995,7 @@ bx_bool BX_CPU_C::dbg_is_end_instr_bpoint(Bit16u cs, bx_address eip, bx_address
BX_CPU_THIS_PTR guard_found.eip = eip;
BX_CPU_THIS_PTR guard_found.laddr = laddr;
BX_CPU_THIS_PTR guard_found.is_32bit_code = is_32;
BX_CPU_THIS_PTR guard_found.is_64bit_code = is_64;
BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_ICOUNT;
return(1);
}

View File

@ -49,27 +49,17 @@ static const unsigned char instruction_has_modrm[512] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
unsigned disassembler::disasm16(bx_address base, bx_address ip, Bit8u *instr, char *disbuf)
unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{
return disasm(0, 0, base, ip, instr, disbuf);
x86_insn insn = decode(is_32, is_64, base, ip, instr, disbuf);
return insn.ilen;
}
unsigned disassembler::disasm32(bx_address base, bx_address ip, Bit8u *instr, char *disbuf)
{
return disasm(1, 0, base, ip, instr, disbuf);
}
unsigned disassembler::disasm64(bx_address base, bx_address ip, Bit8u *instr, char *disbuf)
{
return disasm(1, 1, base, ip, instr, disbuf);
}
unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, Bit8u *instr, char *disbuf)
x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{
x86_insn insn(is_32, is_64);
Bit8u *instruction_begin = instruction = instr;
const Bit8u *instruction_begin = instruction = instr;
resolve_modrm = NULL;
unsigned n_prefixes = 0;
db_eip = ip;
db_base = base; // cs linear base (base for PM & cs<<4 for RM & VM)
@ -86,7 +76,7 @@ unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_
for(;;)
{
insn.b1 = fetch_byte();
n_prefixes++;
insn.prefixes++;
switch(insn.b1) {
case 0xf3: // rep
@ -166,7 +156,7 @@ unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_
break;
}
n_prefixes--;
insn.prefixes--;
break;
}
@ -208,11 +198,14 @@ unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_
case _GRPSSE:
{
if(sse_prefix) n_prefixes--;
if(sse_prefix) insn.prefixes--;
/* For SSE opcodes, look into another 4 entries table
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3) */
int op = sse_prefix_index[sse_prefix];
if (op < 0) return 0;
if (op < 0) {
printf("disassembler panic - too many sse prefixes !\n");
return x86_insn(is_32, is_64);
}
entry = &(OPCODE_TABLE(entry)[op]);
}
break;
@ -241,7 +234,7 @@ unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_
default:
printf("Internal disassembler error - unknown attribute !\n");
return 0;
return x86_insn(is_32, is_64);
}
/* get additional attributes from group table */
@ -254,7 +247,7 @@ unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_
unsigned branch_hint = 0;
// print prefixes
for(unsigned i=0;i<n_prefixes;i++)
for(unsigned i=0;i<insn.prefixes;i++)
{
Bit8u prefix_byte = *(instr+i);
@ -294,7 +287,9 @@ unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_
dis_sprintf(", taken");
}
return(instruction - instruction_begin);
insn.ilen = (unsigned)(instruction - instruction_begin);
return insn;
}
void disassembler::dis_sprintf(char *fmt, ...)

View File

@ -121,7 +121,8 @@ public:
Bit8u extend8b;
Bit8u rex_r, rex_x, rex_b;
Bit8u seg_override;
unsigned b1;
unsigned b1, prefixes;
unsigned ilen;
Bit8u modrm, mod, nnn, rm;
Bit8u sib, scale, index, base;
@ -152,6 +153,8 @@ BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
extend8b = 0;
rex_r = rex_b = rex_x = 0;
seg_override = NO_SEG_OVERRIDE;
prefixes = 0;
ilen = 0;
b1 = 0;
modrm = mod = nnn = rm = 0;
@ -162,11 +165,28 @@ BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
class disassembler {
public:
disassembler() { set_syntax_intel(); }
unsigned disasm16(bx_address base, bx_address ip, Bit8u *instr, char *disbuf);
unsigned disasm32(bx_address base, bx_address ip, Bit8u *instr, char *disbuf);
unsigned disasm64(bx_address base, bx_address ip, Bit8u *instr, char *disbuf);
unsigned disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, Bit8u *instr, char *disbuf);
unsigned disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf);
unsigned disasm16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return disasm(0, 0, base, ip, instr, disbuf); }
unsigned disasm32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return disasm(1, 0, base, ip, instr, disbuf); }
unsigned disasm64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return disasm(1, 1, base, ip, instr, disbuf); }
x86_insn decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf);
x86_insn decode16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return decode(0, 0, base, ip, instr, disbuf); }
x86_insn decode32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return decode(1, 0, base, ip, instr, disbuf); }
x86_insn decode64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
{ return decode(1, 1, base, ip, instr, disbuf); }
void set_syntax_intel();
void set_syntax_att ();
@ -195,7 +215,7 @@ private:
bx_address db_eip, db_base;
Bit8u *instruction; // for fetching of next byte of instruction
const Bit8u *instruction; // for fetching of next byte of instruction
char *disbufptr;