Improved support for vm86 mode.

This commit is contained in:
Alexandre Julliard 2000-09-24 03:15:50 +00:00
parent b59627c89f
commit 954a413c47
11 changed files with 147 additions and 127 deletions

View File

@ -274,18 +274,18 @@ static int DEBUG_InitXPoint(int type, DBG_ADDR* addr)
breakpoints[num].type = type; breakpoints[num].type = type;
breakpoints[num].skipcount = 0; breakpoints[num].skipcount = 0;
breakpoints[num].addr = *addr; breakpoints[num].addr = *addr;
breakpoints[num].is32 = 1;
#ifdef __i386__
if (addr->seg)
{
switch (DEBUG_GetSelectorType( addr->seg )) switch (DEBUG_GetSelectorType( addr->seg ))
{ {
case 32: break; case MODE_32:
case 16: breakpoints[num].is32 = 0; break; breakpoints[num].is32 = 1;
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break;
case MODE_VM86:
case MODE_16:
breakpoints[num].is32 = 0;
break;
default:
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
} }
}
#endif
return num; return num;
} }
} }
@ -360,7 +360,7 @@ void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) )
breakpoints[num].u.b.func = func; breakpoints[num].u.b.func = func;
DEBUG_Printf( DBG_CHN_MESG, "Breakpoint %d at ", num ); DEBUG_Printf( DBG_CHN_MESG, "Breakpoint %d at ", num );
DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32 : 16, DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? MODE_32 : MODE_16,
TRUE ); TRUE );
DEBUG_Printf( DBG_CHN_MESG, "\n" ); DEBUG_Printf( DBG_CHN_MESG, "\n" );
} }
@ -472,7 +472,7 @@ void DEBUG_AddWatchpoint( const DBG_VALUE *_value, BOOL is_write )
breakpoints[reg].u.w.reg = reg; breakpoints[reg].u.w.reg = reg;
DEBUG_Printf( DBG_CHN_MESG, "Watchpoint %d at ", num ); DEBUG_Printf( DBG_CHN_MESG, "Watchpoint %d at ", num );
DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32:16, TRUE ); DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? MODE_32 : MODE_16, TRUE );
DEBUG_Printf( DBG_CHN_MESG, "\n" ); DEBUG_Printf( DBG_CHN_MESG, "\n" );
} }
} }
@ -623,7 +623,7 @@ void DEBUG_InfoBreakpoints(void)
{ {
DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n'); DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
DEBUG_PrintAddress( &breakpoints[i].addr, DEBUG_PrintAddress( &breakpoints[i].addr,
breakpoints[i].is32 ? 32 : 16, TRUE); breakpoints[i].is32 ? MODE_32 : MODE_16, TRUE);
DEBUG_Printf( DBG_CHN_MESG, " (%u)\n", breakpoints[i].refcount ); DEBUG_Printf( DBG_CHN_MESG, " (%u)\n", breakpoints[i].refcount );
if( breakpoints[i].condition != NULL ) if( breakpoints[i].condition != NULL )
{ {
@ -640,7 +640,7 @@ void DEBUG_InfoBreakpoints(void)
{ {
DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n'); DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
DEBUG_PrintAddress( &breakpoints[i].addr, DEBUG_PrintAddress( &breakpoints[i].addr,
breakpoints[i].is32 ? 32 : 16, TRUE); breakpoints[i].is32 ? MODE_32 : MODE_16, TRUE);
DEBUG_Printf( DBG_CHN_MESG, " on %d byte%s (%c)\n", DEBUG_Printf( DBG_CHN_MESG, " on %d byte%s (%c)\n",
breakpoints[i].u.w.len + 1, breakpoints[i].u.w.len + 1,
breakpoints[i].u.w.len > 0 ? "s" : "", breakpoints[i].u.w.len > 0 ? "s" : "",
@ -702,7 +702,7 @@ BOOL DEBUG_ShouldContinue( DBG_ADDR *addr, DWORD code, enum exec_mode mode, int
int bpnum; int bpnum;
DWORD oldval; DWORD oldval;
int wpnum; int wpnum;
int addrlen = 32; enum dbg_mode addr_mode;
struct symbol_info syminfo; struct symbol_info syminfo;
#ifdef __i386__ #ifdef __i386__
@ -723,7 +723,7 @@ BOOL DEBUG_ShouldContinue( DBG_ADDR *addr, DWORD code, enum exec_mode mode, int
DEBUG_Printf( DBG_CHN_MESG, "Stopped on breakpoint %d at ", bpnum ); DEBUG_Printf( DBG_CHN_MESG, "Stopped on breakpoint %d at ", bpnum );
syminfo = DEBUG_PrintAddress( &breakpoints[bpnum].addr, syminfo = DEBUG_PrintAddress( &breakpoints[bpnum].addr,
breakpoints[bpnum].is32 ? 32 : 16, TRUE ); breakpoints[bpnum].is32 ? MODE_32 : MODE_16, TRUE );
DEBUG_Printf( DBG_CHN_MESG, "\n" ); DEBUG_Printf( DBG_CHN_MESG, "\n" );
if( syminfo.list.sourcefile != NULL ) if( syminfo.list.sourcefile != NULL )
@ -744,11 +744,9 @@ BOOL DEBUG_ShouldContinue( DBG_ADDR *addr, DWORD code, enum exec_mode mode, int
} }
if (!DEBUG_ShallBreak(wpnum)) return TRUE; if (!DEBUG_ShallBreak(wpnum)) return TRUE;
#ifdef __i386__ addr_mode = DEBUG_GetSelectorType( addr->seg );
if (addr->seg) addrlen = DEBUG_GetSelectorType( addr->seg );
#endif
DEBUG_Printf(DBG_CHN_MESG, "Stopped on watchpoint %d at ", wpnum); DEBUG_Printf(DBG_CHN_MESG, "Stopped on watchpoint %d at ", wpnum);
syminfo = DEBUG_PrintAddress( addr, addrlen, TRUE ); syminfo = DEBUG_PrintAddress( addr, addr_mode, TRUE );
DEBUG_Printf(DBG_CHN_MESG, " values: old=%lu new=%lu\n", DEBUG_Printf(DBG_CHN_MESG, " values: old=%lu new=%lu\n",
oldval, breakpoints[wpnum].u.w.oldval); oldval, breakpoints[wpnum].u.w.oldval);

View File

@ -1033,7 +1033,7 @@ static void db_task_printsym(unsigned int addr, int size)
address.seg = 0; address.seg = 0;
address.off = addr; address.off = addr;
DEBUG_PrintAddress( &address, db_disasm_16 ? 16 : 32, TRUE ); DEBUG_PrintAddress( &address, db_disasm_16 ? MODE_16 : MODE_32, TRUE );
} }
void db_print_address(char *seg, int size, struct i_addr *addrp, int byref) void db_print_address(char *seg, int size, struct i_addr *addrp, int byref)
@ -1189,10 +1189,12 @@ void DEBUG_Disasm( DBG_ADDR *addr, int display )
* Set this so we get can supress the printout if we need to. * Set this so we get can supress the printout if we need to.
*/ */
db_display = display; db_display = display;
switch (DEBUG_GetSelectorType(addr->seg)) { switch (DEBUG_GetSelectorType(addr->seg))
case 16: db_disasm_16 = 1; break; {
case 32: db_disasm_16 = 0; break; case MODE_VM86:
default: DEBUG_Printf(DBG_CHN_MESG, "Bad selector %ld\n", addr->seg); return; case MODE_16: db_disasm_16 = 1; break;
case MODE_32: db_disasm_16 = 0; break;
default: DEBUG_Printf(DBG_CHN_MESG, "Bad selector %lx\n", addr->seg); return;
} }
get_value_inc( inst, addr, 1, FALSE ); get_value_inc( inst, addr, 1, FALSE );
@ -1625,8 +1627,7 @@ void DEBUG_Disasm( DBG_ADDR *addr, int display )
2, FALSE ); 2, FALSE );
if( db_display ) if( db_display )
{ {
DEBUG_PrintAddress( &address, short_addr ? 16 : 32, DEBUG_PrintAddress( &address, short_addr ? MODE_16 : MODE_32, TRUE );
TRUE );
} }
} }

View File

@ -40,7 +40,7 @@ int yyerror(char *);
} }
%token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN %token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN
%token tENABLE tDISABLE tBREAK tWATCH tDELETE tSET tMODE tPRINT tEXAM tABORT %token tENABLE tDISABLE tBREAK tWATCH tDELETE tSET tMODE tPRINT tEXAM tABORT tVM86
%token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL %token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL
%token tPROCESS tTHREAD tMODREF tEOL %token tPROCESS tTHREAD tMODREF tEOL
%token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE %token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE
@ -117,6 +117,7 @@ command:
DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return TRUE; } DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return TRUE; }
| tABORT tEOL { kill(getpid(), SIGABRT); } | tABORT tEOL { kill(getpid(), SIGABRT); }
| tMODE tNUM tEOL { mode_command($2); } | tMODE tNUM tEOL { mode_command($2); }
| tMODE tVM86 tEOL { DEBUG_CurrThread->dbg_mode = MODE_VM86; }
| tENABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, TRUE ); } | tENABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, TRUE ); }
| tDISABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, FALSE ); } | tDISABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, FALSE ); }
| tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); } | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); }
@ -346,8 +347,12 @@ static void issue_prompt(void)
static void mode_command(int newmode) static void mode_command(int newmode)
{ {
if ((newmode == 16) || (newmode == 32)) DEBUG_CurrThread->dbg_mode = newmode; switch(newmode)
else DEBUG_Printf(DBG_CHN_MESG,"Invalid mode (use 16 or 32)\n"); {
case 16: DEBUG_CurrThread->dbg_mode = MODE_16; break;
case 32: DEBUG_CurrThread->dbg_mode = MODE_32; break;
default: DEBUG_Printf(DBG_CHN_MESG,"Invalid mode (use 16, 32 or vm86)\n");
}
} }
void DEBUG_Exit(DWORD ec) void DEBUG_Exit(DWORD ec)

View File

@ -41,6 +41,7 @@ STRING \"[^\n"]+\"
%s DEL_CMD %s DEL_CMD
%s WALK_CMD %s WALK_CMD
%s SHOW_CMD %s SHOW_CMD
%s MODE_CMD
%s NOCMD %s NOCMD
%x ASTRING_EXPECTED %x ASTRING_EXPECTED
@ -111,7 +112,7 @@ STRING \"[^\n"]+\"
<INITIAL>abort|abor|abo { BEGIN(NOCMD); return tABORT; } <INITIAL>abort|abor|abo { BEGIN(NOCMD); return tABORT; }
<INITIAL>print|prin|pri|pr|p { BEGIN(FORMAT_EXPECTED); return tPRINT; } <INITIAL>print|prin|pri|pr|p { BEGIN(FORMAT_EXPECTED); return tPRINT; }
<INITIAL>mode { BEGIN(NOCMD); return tMODE; } <INITIAL>mode { BEGIN(MODE_CMD); return tMODE; }
<INITIAL>show|sho|sh { BEGIN(SHOW_CMD); return tSHOW; } <INITIAL>show|sho|sh { BEGIN(SHOW_CMD); return tSHOW; }
<INITIAL>symbolfile|symbols|symbol|sf { BEGIN(PATH_EXPECTED); return tSYMBOLFILE; } <INITIAL>symbolfile|symbols|symbol|sf { BEGIN(PATH_EXPECTED); return tSYMBOLFILE; }
@ -134,6 +135,7 @@ STRING \"[^\n"]+\"
<INFO_CMD>maps|map { return tMAPS; } <INFO_CMD>maps|map { return tMAPS; }
<INFO_CMD,WALK_CMD>window|windo|wind|win|wnd { return tWND; } <INFO_CMD,WALK_CMD>window|windo|wind|win|wnd { return tWND; }
<HELP_CMD>info|inf|in { return tINFO; } <HELP_CMD>info|inf|in { return tINFO; }
<MODE_CMD>vm86 { return tVM86; }
<INITIAL,SHOW_CMD>directories|directorie|directori|director|directo|direct|direc|direc|dir { <INITIAL,SHOW_CMD>directories|directorie|directori|director|directo|direct|direc|direc|dir {
BEGIN(PATH_EXPECTED); return tDIR; } BEGIN(PATH_EXPECTED); return tDIR; }

View File

@ -144,6 +144,11 @@ typedef struct
struct expr * condition; struct expr * condition;
} DBG_BREAKPOINT; } DBG_BREAKPOINT;
enum dbg_mode
{
MODE_INVALID, MODE_16, MODE_32, MODE_VM86
};
typedef struct tagDBG_THREAD { typedef struct tagDBG_THREAD {
struct tagDBG_PROCESS* process; struct tagDBG_PROCESS* process;
HANDLE handle; HANDLE handle;
@ -151,7 +156,7 @@ typedef struct tagDBG_THREAD {
LPVOID start; LPVOID start;
LPVOID teb; LPVOID teb;
int wait_for_first_exception; int wait_for_first_exception;
int dbg_mode; enum dbg_mode dbg_mode;
enum exec_mode dbg_exec_mode; enum exec_mode dbg_exec_mode;
int dbg_exec_count; int dbg_exec_count;
DBG_BREAKPOINT stepOverBP; DBG_BREAKPOINT stepOverBP;
@ -326,12 +331,11 @@ extern BOOL DEBUG_Normalize(struct name_hash * nh );
/* debugger/info.c */ /* debugger/info.c */
extern void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format ); extern void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format );
extern struct symbol_info DEBUG_PrintAddress( const DBG_ADDR *addr, extern struct symbol_info DEBUG_PrintAddress( const DBG_ADDR *addr, enum dbg_mode mode, int flag );
int addrlen, int flag );
extern void DEBUG_Help(void); extern void DEBUG_Help(void);
extern void DEBUG_HelpInfo(void); extern void DEBUG_HelpInfo(void);
extern struct symbol_info DEBUG_PrintAddressAndArgs( const DBG_ADDR *addr, extern struct symbol_info DEBUG_PrintAddressAndArgs( const DBG_ADDR *addr,
int addrlen, enum dbg_mode mode,
unsigned int ebp, unsigned int ebp,
int flag ); int flag );
extern void DEBUG_InfoClass(const char* clsName); extern void DEBUG_InfoClass(const char* clsName);
@ -357,10 +361,9 @@ extern void DEBUG_InvalLinAddr( void* addr );
extern DWORD DEBUG_ToLinear( const DBG_ADDR *address ); extern DWORD DEBUG_ToLinear( const DBG_ADDR *address );
extern void DEBUG_GetCurrentAddress( DBG_ADDR * ); extern void DEBUG_GetCurrentAddress( DBG_ADDR * );
extern BOOL DEBUG_GrabAddress( DBG_VALUE* value, BOOL fromCode ); extern BOOL DEBUG_GrabAddress( DBG_VALUE* value, BOOL fromCode );
extern enum dbg_mode DEBUG_GetSelectorType( WORD sel );
#ifdef __i386__ #ifdef __i386__
extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def ); extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def );
extern BOOL DEBUG_FixSegment( DBG_ADDR* addr );
extern int DEBUG_GetSelectorType( WORD sel );
extern int DEBUG_IsSelectorSystem( WORD sel ); extern int DEBUG_IsSelectorSystem( WORD sel );
#endif #endif

View File

@ -513,9 +513,6 @@ DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
rtn.type = NULL; rtn.type = NULL;
rtn.addr.seg = VAL(exp1); rtn.addr.seg = VAL(exp1);
rtn.addr.off = VAL(exp2); rtn.addr.off = VAL(exp2);
#ifdef __i386__
DEBUG_FixSegment(&rtn.addr);
#endif
break; break;
case EXP_OP_LOR: case EXP_OP_LOR:
exp->un.binop.result = (VAL(exp1) || VAL(exp2)); exp->un.binop.result = (VAL(exp1) || VAL(exp2));

View File

@ -120,7 +120,7 @@ void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format )
* Print an 16- or 32-bit address, with the nearest symbol if any. * Print an 16- or 32-bit address, with the nearest symbol if any.
*/ */
struct symbol_info struct symbol_info
DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen, int flag ) DEBUG_PrintAddress( const DBG_ADDR *addr, enum dbg_mode mode, int flag )
{ {
struct symbol_info rtn; struct symbol_info rtn;
@ -128,7 +128,7 @@ DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen, int flag )
&rtn.list ); &rtn.list );
if (addr->seg) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx:", addr->seg&0xFFFF ); if (addr->seg) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx:", addr->seg&0xFFFF );
if (addrlen == 16) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", addr->off ); if (mode != MODE_32) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", addr->off );
else DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", addr->off ); else DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", addr->off );
if (name) DEBUG_Printf( DBG_CHN_MESG, " (%s)", name ); if (name) DEBUG_Printf( DBG_CHN_MESG, " (%s)", name );
return rtn; return rtn;
@ -141,7 +141,7 @@ DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen, int flag )
* each function (if known). This is useful in a backtrace. * each function (if known). This is useful in a backtrace.
*/ */
struct symbol_info struct symbol_info
DEBUG_PrintAddressAndArgs( const DBG_ADDR *addr, int addrlen, DEBUG_PrintAddressAndArgs( const DBG_ADDR *addr, enum dbg_mode mode,
unsigned int ebp, int flag ) unsigned int ebp, int flag )
{ {
struct symbol_info rtn; struct symbol_info rtn;
@ -150,7 +150,7 @@ DEBUG_PrintAddressAndArgs( const DBG_ADDR *addr, int addrlen,
&rtn.list ); &rtn.list );
if (addr->seg) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx:", addr->seg ); if (addr->seg) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx:", addr->seg );
if (addrlen == 16) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", addr->off ); if (mode != MODE_32) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", addr->off );
else DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", addr->off ); else DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", addr->off );
if (name) DEBUG_Printf( DBG_CHN_MESG, " (%s)", name ); if (name) DEBUG_Printf( DBG_CHN_MESG, " (%s)", name );
@ -186,7 +186,7 @@ void DEBUG_Help(void)
" show dir dir <path>", " show dir dir <path>",
" display <expr> undisplay <disnum>", " display <expr> undisplay <disnum>",
" delete display <disnum> debugmsg <class>[-+]<type>\n", " delete display <disnum> debugmsg <class>[-+]<type>\n",
" mode [16,32] walk [wnd,class,queue,module,", " mode [16,32,vm86] walk [wnd,class,queue,module,",
" whatis process,modref <pid>]", " whatis process,modref <pid>]",
" info (see 'help info' for options)\n", " info (see 'help info' for options)\n",

View File

@ -15,10 +15,7 @@
#include "winbase.h" #include "winbase.h"
#ifdef __i386__ #ifdef __i386__
#include "wine/winbase16.h" #define IS_VM86_MODE() (DEBUG_context.EFlags & V86_FLAG)
#define DBG_V86_MODULE(seg) ((seg)>>16)
#define IS_SELECTOR_V86(seg) DBG_V86_MODULE(seg)
#endif #endif
static void DEBUG_Die(const char* msg) static void DEBUG_Die(const char* msg)
@ -52,41 +49,33 @@ char* DEBUG_XStrDup(const char *str)
return res; return res;
} }
enum dbg_mode DEBUG_GetSelectorType( WORD sel )
{
#ifdef __i386__
LDT_ENTRY le;
if (IS_VM86_MODE()) return MODE_VM86;
if (sel == 0) return MODE_32;
if (GetThreadSelectorEntry( DEBUG_CurrThread->handle, sel, &le))
return le.HighWord.Bits.Default_Big ? MODE_32 : MODE_16;
/* selector doesn't exist */
return MODE_INVALID;
#else
return MODE_32;
#endif
}
#ifdef __i386__ #ifdef __i386__
void DEBUG_FixAddress( DBG_ADDR *addr, DWORD def) void DEBUG_FixAddress( DBG_ADDR *addr, DWORD def)
{ {
if (addr->seg == 0xffffffff) addr->seg = def; if (addr->seg == 0xffffffff) addr->seg = def;
if (!IS_SELECTOR_V86(addr->seg) && DEBUG_IsSelectorSystem(addr->seg)) addr->seg = 0; if (DEBUG_IsSelectorSystem(addr->seg)) addr->seg = 0;
}
BOOL DEBUG_FixSegment( DBG_ADDR* addr )
{
/* V86 mode ? */
if (DEBUG_context.EFlags & V86_FLAG) {
addr->seg |= (DWORD)(GetExePtr(GetCurrentTask())) << 16;
return TRUE;
}
return FALSE;
}
int DEBUG_GetSelectorType( WORD sel )
{
LDT_ENTRY le;
if (sel == 0)
return 32;
if (IS_SELECTOR_V86(sel))
return 16;
if (GetThreadSelectorEntry( DEBUG_CurrThread->handle, sel, &le))
return le.HighWord.Bits.Default_Big ? 32 : 16;
/* selector doesn't exist */
return 0;
} }
/* Determine if sel is a system selector (i.e. not managed by Wine) */ /* Determine if sel is a system selector (i.e. not managed by Wine) */
BOOL DEBUG_IsSelectorSystem(WORD sel) BOOL DEBUG_IsSelectorSystem(WORD sel)
{ {
return !(sel & 4) || (((sel & 0xFFFF) >> 3) < 17); if (IS_VM86_MODE()) return FALSE; /* no system selectors in vm86 mode */
return !(sel & 4) || ((sel >> 3) < 17);
} }
#endif /* __i386__ */ #endif /* __i386__ */
@ -95,10 +84,8 @@ DWORD DEBUG_ToLinear( const DBG_ADDR *addr )
#ifdef __i386__ #ifdef __i386__
LDT_ENTRY le; LDT_ENTRY le;
#if 0 if (IS_VM86_MODE()) return (DWORD)(LOWORD(addr->seg) << 4) + addr->off;
if (IS_SELECTOR_V86(addr->seg))
return (DWORD) DOSMEM_MemoryBase(DBG_V86_MODULE(addr->seg)) + (((addr->seg)&0xFFFF)<<4) + addr->off;
#endif
if (DEBUG_IsSelectorSystem(addr->seg)) if (DEBUG_IsSelectorSystem(addr->seg))
return addr->off; return addr->off;
@ -116,7 +103,7 @@ void DEBUG_GetCurrentAddress( DBG_ADDR *addr )
#ifdef __i386__ #ifdef __i386__
addr->seg = DEBUG_context.SegCs; addr->seg = DEBUG_context.SegCs;
if (!DEBUG_FixSegment( addr ) && DEBUG_IsSelectorSystem(addr->seg)) if (DEBUG_IsSelectorSystem(addr->seg))
addr->seg = 0; addr->seg = 0;
addr->off = DEBUG_context.Eip; addr->off = DEBUG_context.Eip;
#elif defined(__sparc__) #elif defined(__sparc__)

View File

@ -82,7 +82,7 @@ void DEBUG_InfoRegisters(void)
(WORD)DEBUG_context.SegCs, (WORD)DEBUG_context.SegSs, (WORD)DEBUG_context.SegCs, (WORD)DEBUG_context.SegSs,
(WORD)DEBUG_context.SegDs, (WORD)DEBUG_context.SegEs, (WORD)DEBUG_context.SegDs, (WORD)DEBUG_context.SegEs,
(WORD)DEBUG_context.SegFs, (WORD)DEBUG_context.SegGs ); (WORD)DEBUG_context.SegFs, (WORD)DEBUG_context.SegGs );
if (DEBUG_CurrThread->dbg_mode == 16) if (DEBUG_CurrThread->dbg_mode != MODE_32)
{ {
char flag[33]; char flag[33];

View File

@ -63,11 +63,13 @@ void DEBUG_InfoStack(void)
value.addr.off = DEBUG_context.Esp; value.addr.off = DEBUG_context.Esp;
DEBUG_Printf(DBG_CHN_MESG,"Stack dump:\n"); DEBUG_Printf(DBG_CHN_MESG,"Stack dump:\n");
switch (DEBUG_GetSelectorType(value.addr.seg)) { switch (DEBUG_GetSelectorType(value.addr.seg))
case 32: /* 32-bit mode */ {
case MODE_32: /* 32-bit mode */
DEBUG_ExamineMemory( &value, 24, 'x' ); DEBUG_ExamineMemory( &value, 24, 'x' );
break; break;
case 16: /* 16-bit mode */ case MODE_16: /* 16-bit mode */
case MODE_VM86:
value.addr.off &= 0xffff; value.addr.off &= 0xffff;
DEBUG_ExamineMemory( &value, 24, 'w' ); DEBUG_ExamineMemory( &value, 24, 'w' );
break; break;
@ -79,7 +81,8 @@ void DEBUG_InfoStack(void)
} }
#ifdef __i386__ #ifdef __i386__
static void DEBUG_ForceFrame(DBG_ADDR *stack, DBG_ADDR *code, int frameno, int bits, int noisy, const char *caveat) static void DEBUG_ForceFrame(DBG_ADDR *stack, DBG_ADDR *code, int frameno, enum dbg_mode mode,
int noisy, const char *caveat)
{ {
int theframe = nframe++; int theframe = nframe++;
frames = (struct bt_info *)DBG_realloc(frames, frames = (struct bt_info *)DBG_realloc(frames,
@ -90,8 +93,7 @@ static void DEBUG_ForceFrame(DBG_ADDR *stack, DBG_ADDR *code, int frameno, int b
frames[theframe].cs = code->seg; frames[theframe].cs = code->seg;
frames[theframe].eip = code->off; frames[theframe].eip = code->off;
if (noisy) if (noisy)
frames[theframe].frame = DEBUG_PrintAddressAndArgs( code, bits, frames[theframe].frame = DEBUG_PrintAddressAndArgs( code, mode, stack->off, TRUE );
stack->off, TRUE );
else else
DEBUG_FindNearestSymbol( code, TRUE, DEBUG_FindNearestSymbol( code, TRUE,
&frames[theframe].frame.sym, stack->off, &frames[theframe].frame.sym, stack->off,
@ -99,7 +101,8 @@ static void DEBUG_ForceFrame(DBG_ADDR *stack, DBG_ADDR *code, int frameno, int b
frames[theframe].ss = stack->seg; frames[theframe].ss = stack->seg;
frames[theframe].ebp = stack->off; frames[theframe].ebp = stack->off;
if (noisy) { if (noisy) {
DEBUG_Printf( DBG_CHN_MESG, (bits == 16) ? " (bp=%04lx%s)\n" : " (ebp=%08lx%s)\n", stack->off, caveat?caveat:"" ); DEBUG_Printf( DBG_CHN_MESG, (mode != MODE_32) ? " (bp=%04lx%s)\n" : " (ebp=%08lx%s)\n",
stack->off, caveat?caveat:"" );
} }
} }
@ -136,7 +139,8 @@ static BOOL DEBUG_Frame16(DBG_ADDR *addr, unsigned int *cs, int frameno, int noi
code.seg = *cs; code.seg = *cs;
code.off = frame.ip; code.off = frame.ip;
addr->off = frame.bp & ~1; addr->off = frame.bp & ~1;
DEBUG_ForceFrame(addr, &code, frameno, 16, noisy, possible_cs ? ", far call assumed" : NULL ); DEBUG_ForceFrame(addr, &code, frameno, MODE_16, noisy,
possible_cs ? ", far call assumed" : NULL );
return TRUE; return TRUE;
} }
@ -158,7 +162,7 @@ static BOOL DEBUG_Frame32(DBG_ADDR *addr, unsigned int *cs, int frameno, int noi
code.seg = *cs; code.seg = *cs;
code.off = frame.ip; code.off = frame.ip;
addr->off = frame.bp; addr->off = frame.bp;
DEBUG_ForceFrame(addr, &code, frameno, 32, noisy, NULL); DEBUG_ForceFrame(addr, &code, frameno, MODE_32, noisy, NULL);
if (addr->off == old_bp) return FALSE; if (addr->off == old_bp) return FALSE;
return TRUE; return TRUE;
} }
@ -195,12 +199,12 @@ void DEBUG_BackTrace(BOOL noisy)
/* first stack frame from registers */ /* first stack frame from registers */
switch (DEBUG_GetSelectorType(ss)) switch (DEBUG_GetSelectorType(ss))
{ {
case 32: case MODE_32:
code.seg = cs; code.seg = cs;
code.off = DEBUG_context.Eip; code.off = DEBUG_context.Eip;
addr.seg = ss; addr.seg = ss;
addr.off = DEBUG_context.Ebp; addr.off = DEBUG_context.Ebp;
DEBUG_ForceFrame( &addr, &code, frameno, 32, noisy, NULL ); DEBUG_ForceFrame( &addr, &code, frameno, MODE_32, noisy, NULL );
if (!(code.seg || code.off)) { if (!(code.seg || code.off)) {
/* trying to execute a null pointer... yuck... /* trying to execute a null pointer... yuck...
* if it was a call to null, the return EIP should be * if it was a call to null, the return EIP should be
@ -208,21 +212,22 @@ void DEBUG_BackTrace(BOOL noisy)
tmp.seg = ss; tmp.seg = ss;
tmp.off = DEBUG_context.Esp; tmp.off = DEBUG_context.Esp;
if (DEBUG_READ_MEM((void *)DEBUG_ToLinear(&tmp), &code.off, sizeof(code.off))) { if (DEBUG_READ_MEM((void *)DEBUG_ToLinear(&tmp), &code.off, sizeof(code.off))) {
DEBUG_ForceFrame( &addr, &code, ++frameno, 32, noisy, ", null call assumed" ); DEBUG_ForceFrame( &addr, &code, ++frameno, MODE_32, noisy, ", null call assumed" );
} }
} }
is16 = FALSE; is16 = FALSE;
break; break;
case 16: case MODE_16:
case MODE_VM86:
code.seg = cs; code.seg = cs;
code.off = LOWORD(DEBUG_context.Eip); code.off = LOWORD(DEBUG_context.Eip);
addr.seg = ss; addr.seg = ss;
addr.off = LOWORD(DEBUG_context.Ebp); addr.off = LOWORD(DEBUG_context.Ebp);
DEBUG_ForceFrame( &addr, &code, frameno, 16, noisy, NULL ); DEBUG_ForceFrame( &addr, &code, frameno, MODE_16, noisy, NULL );
is16 = TRUE; is16 = TRUE;
break; break;
default: default:
if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad segment '%u'\n", ss); if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad segment '%x'\n", ss);
return; return;
} }
@ -282,7 +287,7 @@ void DEBUG_BackTrace(BOOL noisy)
cs = 0; cs = 0;
addr.seg = 0; addr.seg = 0;
addr.off = frame32.ebp; addr.off = frame32.ebp;
DEBUG_ForceFrame( &addr, &code, ++frameno, 32, noisy, NULL ); DEBUG_ForceFrame( &addr, &code, ++frameno, MODE_32, noisy, NULL );
next_switch = cur_switch; next_switch = cur_switch;
tmp.seg = SELECTOROF(next_switch); tmp.seg = SELECTOROF(next_switch);
@ -316,7 +321,7 @@ void DEBUG_BackTrace(BOOL noisy)
cs = frame16.cs; cs = frame16.cs;
addr.seg = SELECTOROF(next_switch); addr.seg = SELECTOROF(next_switch);
addr.off = frame16.bp; addr.off = frame16.bp;
DEBUG_ForceFrame( &addr, &code, ++frameno, 16, noisy, NULL ); DEBUG_ForceFrame( &addr, &code, ++frameno, MODE_16, noisy, NULL );
next_switch = cur_switch; next_switch = cur_switch;
if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) { if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) {

View File

@ -282,15 +282,24 @@ static BOOL DEBUG_ExceptionProlog(BOOL is_debug, BOOL force, DWORD code)
DEBUG_SuspendExecution(); DEBUG_SuspendExecution();
if (!is_debug) { if (!is_debug) {
#ifdef __i386__ if (!addr.seg)
if (DEBUG_IsSelectorSystem(DEBUG_context.SegCs))
DEBUG_Printf(DBG_CHN_MESG, " in 32-bit code (0x%08lx).\n", addr.off); DEBUG_Printf(DBG_CHN_MESG, " in 32-bit code (0x%08lx).\n", addr.off);
else else
DEBUG_Printf(DBG_CHN_MESG, " in 16-bit code (%04x:%04lx).\n", switch(DEBUG_GetSelectorType(addr.seg))
LOWORD(addr.seg), addr.off); {
#else case MODE_32:
DEBUG_Printf(DBG_CHN_MESG, " (0x%08lx).\n", addr.off); DEBUG_Printf(DBG_CHN_MESG, " in 32-bit code (%04lx:%08lx).\n", addr.seg, addr.off);
#endif break;
case MODE_16:
DEBUG_Printf(DBG_CHN_MESG, " in 16-bit code (%04lx:%04lx).\n", addr.seg, addr.off);
break;
case MODE_VM86:
DEBUG_Printf(DBG_CHN_MESG, " in vm86 code (%04lx:%04lx).\n", addr.seg, addr.off);
break;
case MODE_INVALID:
DEBUG_Printf(DBG_CHN_MESG, "bad CS (%lx)\n", addr.seg);
break;
}
} }
DEBUG_LoadEntryPoints("Loading new modules symbols:\n"); DEBUG_LoadEntryPoints("Loading new modules symbols:\n");
@ -302,16 +311,13 @@ static BOOL DEBUG_ExceptionProlog(BOOL is_debug, BOOL force, DWORD code)
&DEBUG_CurrThread->dbg_exec_count)) &DEBUG_CurrThread->dbg_exec_count))
return FALSE; return FALSE;
#ifdef __i386__ if ((newmode = DEBUG_GetSelectorType(addr.seg)) == MODE_INVALID) newmode = MODE_32;
switch (newmode = DEBUG_GetSelectorType(addr.seg)) {
case 16: case 32: break;
default: DEBUG_Printf(DBG_CHN_MESG, "Bad CS (%ld)\n", addr.seg); newmode = 32;
}
#else
newmode = 32;
#endif
if (newmode != DEBUG_CurrThread->dbg_mode) if (newmode != DEBUG_CurrThread->dbg_mode)
DEBUG_Printf(DBG_CHN_MESG,"In %d bit mode.\n", DEBUG_CurrThread->dbg_mode = newmode); {
static const char * const names[] = { "???", "16-bit", "32-bit", "vm86" };
DEBUG_Printf(DBG_CHN_MESG,"In %s mode.\n", names[newmode] );
DEBUG_CurrThread->dbg_mode = newmode;
}
DEBUG_DoDisplay(); DEBUG_DoDisplay();
@ -326,7 +332,7 @@ static BOOL DEBUG_ExceptionProlog(BOOL is_debug, BOOL force, DWORD code)
DEBUG_InfoRegisters(); DEBUG_InfoRegisters();
DEBUG_InfoStack(); DEBUG_InfoStack();
#ifdef __i386__ #ifdef __i386__
if (DEBUG_CurrThread->dbg_mode == 16) { if (DEBUG_CurrThread->dbg_mode == MODE_16) {
DEBUG_InfoSegments(DEBUG_context.SegDs >> 3, 1); DEBUG_InfoSegments(DEBUG_context.SegDs >> 3, 1);
if (DEBUG_context.SegEs != DEBUG_context.SegDs) if (DEBUG_context.SegEs != DEBUG_context.SegDs)
DEBUG_InfoSegments(DEBUG_context.SegEs >> 3, 1); DEBUG_InfoSegments(DEBUG_context.SegEs >> 3, 1);
@ -374,7 +380,6 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL
BOOL ret = TRUE; BOOL ret = TRUE;
*cont = DBG_CONTINUE; *cont = DBG_CONTINUE;
if (first_chance && !force && !DBG_IVAR(BreakOnFirstChance)) return TRUE;
switch (rec->ExceptionCode) switch (rec->ExceptionCode)
{ {
@ -384,6 +389,13 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL
break; break;
} }
if (first_chance && !force && !DBG_IVAR(BreakOnFirstChance))
{
/* pass exception to program except for debug exceptions */
*cont = is_debug ? DBG_CONTINUE : DBG_EXCEPTION_NOT_HANDLED;
return TRUE;
}
if (!is_debug) if (!is_debug)
{ {
/* print some infos */ /* print some infos */
@ -432,6 +444,16 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL
return TRUE; return TRUE;
} }
break; break;
case EXCEPTION_VM86_INTx:
DEBUG_Printf(DBG_CHN_MESG, "interrupt %02lx in vm86 mode",
rec->ExceptionInformation[0]);
break;
case EXCEPTION_VM86_STI:
DEBUG_Printf(DBG_CHN_MESG, "sti in vm86 mode");
break;
case EXCEPTION_VM86_PICRETURN:
DEBUG_Printf(DBG_CHN_MESG, "PIC return in vm86 mode");
break;
default: default:
DEBUG_Printf(DBG_CHN_MESG, "%08lx", rec->ExceptionCode); DEBUG_Printf(DBG_CHN_MESG, "%08lx", rec->ExceptionCode);
break; break;
@ -728,7 +750,7 @@ static DWORD DEBUG_MainLoop(void)
DWORD cont; DWORD cont;
BOOL ret; BOOL ret;
DEBUG_Printf(DBG_CHN_MESG, " on pid %ld\n", DEBUG_CurrPid); DEBUG_Printf(DBG_CHN_MESG, " on pid %lx\n", DEBUG_CurrPid);
for (ret = TRUE; ret; ) { for (ret = TRUE; ret; ) {
/* wait until we get at least one loaded process */ /* wait until we get at least one loaded process */
@ -741,7 +763,7 @@ static DWORD DEBUG_MainLoop(void)
} }
}; };
DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %ld\n", DEBUG_CurrPid); DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %lx\n", DEBUG_CurrPid);
return 0; return 0;
} }