mirror of
https://github.com/reactos/wine.git
synced 2025-02-03 10:43:30 +00:00
Introduced DBG_VALUE struct to manipulate debugger/debuggee address space.
Added watch (hardware assisted debugging) and whatis (type of expr) commands. Fixed some issues in local vars handling (stabs parsing & registers optimization).
This commit is contained in:
parent
38828c4e3a
commit
d33bcb6139
594
debugger/break.c
594
debugger/break.c
@ -3,13 +3,40 @@
|
||||
*
|
||||
* Copyright 1994 Martin von Loewis
|
||||
* Copyright 1995 Alexandre Julliard
|
||||
* Copyright 1999,2000 Eric Pouech
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include "debugger.h"
|
||||
|
||||
#ifdef __i386__
|
||||
#define DR7_CONTROL_SHIFT 16
|
||||
#define DR7_CONTROL_SIZE 4
|
||||
|
||||
#define DR7_RW_EXECUTE (0x0)
|
||||
#define DR7_RW_WRITE (0x1)
|
||||
#define DR7_RW_READ (0x3)
|
||||
|
||||
#define DR7_LEN_1 (0x0)
|
||||
#define DR7_LEN_2 (0x4)
|
||||
#define DR7_LEN_4 (0xC)
|
||||
|
||||
#define DR7_LOCAL_ENABLE_SHIFT 0
|
||||
#define DR7_GLOBAL_ENABLE_SHIFT 1
|
||||
#define DR7_ENABLE_SIZE 2
|
||||
|
||||
#define DR7_LOCAL_ENABLE_MASK (0x55)
|
||||
#define DR7_GLOBAL_ENABLE_MASK (0xAA)
|
||||
|
||||
#define DR7_CONTROL_RESERVED (0xFC00)
|
||||
#define DR7_LOCAL_SLOWDOWN (0x100)
|
||||
#define DR7_GLOBAL_SLOWDOWN (0x200)
|
||||
|
||||
#define DR7_ENABLE_MASK(dr) (1<<(DR7_LOCAL_ENABLE_SHIFT+DR7_ENABLE_SIZE*(dr)))
|
||||
#define IS_DR7_SET(ctrl,dr) ((ctrl)&DR7_ENABLE_MASK(dr))
|
||||
#define INT3 0xcc /* int 3 opcode */
|
||||
#endif
|
||||
|
||||
#define MAX_BREAKPOINTS 100
|
||||
|
||||
@ -17,7 +44,6 @@ static BREAKPOINT breakpoints[MAX_BREAKPOINTS];
|
||||
|
||||
static int next_bp = 1; /* breakpoint 0 is reserved for step-over */
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_IsStepOverInstr
|
||||
*
|
||||
@ -122,7 +148,7 @@ BOOL DEBUG_IsFctReturn(void)
|
||||
instr = (BYTE*)DEBUG_ToLinear(&addr);
|
||||
|
||||
if (!DEBUG_READ_MEM(instr, &ch, sizeof(ch)))
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
|
||||
return (ch == 0xc2) || (ch == 0xc3);
|
||||
#else
|
||||
@ -138,111 +164,278 @@ BOOL DEBUG_IsFctReturn(void)
|
||||
*/
|
||||
void DEBUG_SetBreakpoints( BOOL set )
|
||||
{
|
||||
int i;
|
||||
char ch;
|
||||
int i;
|
||||
|
||||
#ifdef __i386__
|
||||
DEBUG_context.Dr7 &= ~DR7_LOCAL_ENABLE_MASK;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < next_bp; i++)
|
||||
{
|
||||
if (!(breakpoints[i].refcount && breakpoints[i].enabled))
|
||||
continue;
|
||||
|
||||
switch (breakpoints[i].type) {
|
||||
case DBG_BREAK:
|
||||
{
|
||||
#ifdef __i386__
|
||||
char ch = set ? INT3 : breakpoints[i].u.opcode;
|
||||
#endif
|
||||
|
||||
if (!DEBUG_WRITE_MEM( (void*)DEBUG_ToLinear(&breakpoints[i].addr),
|
||||
&ch, sizeof(ch) ))
|
||||
{
|
||||
fprintf(stderr, "Invalid address for breakpoint %d, disabling it\n", i);
|
||||
breakpoints[i].enabled = FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DBG_WATCH:
|
||||
if (set)
|
||||
{
|
||||
#ifdef __i386__
|
||||
DWORD bits;
|
||||
int reg = breakpoints[i].u.w.reg;
|
||||
LPDWORD lpdr = NULL;
|
||||
|
||||
for (i = 0; i < MAX_BREAKPOINTS; i++)
|
||||
{
|
||||
if (breakpoints[i].refcount && breakpoints[i].enabled)
|
||||
{
|
||||
ch = set ? INT3 : breakpoints[i].opcode;
|
||||
|
||||
if (!DEBUG_WRITE_MEM( (void*)DEBUG_ToLinear(&breakpoints[i].addr), &ch, sizeof(ch) ))
|
||||
{
|
||||
fprintf( stderr, "Invalid address for breakpoint %d, disabling it\n", i );
|
||||
breakpoints[i].enabled = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (reg)
|
||||
{
|
||||
case 0: lpdr = &DEBUG_context.Dr0; break;
|
||||
case 1: lpdr = &DEBUG_context.Dr1; break;
|
||||
case 2: lpdr = &DEBUG_context.Dr2; break;
|
||||
case 3: lpdr = &DEBUG_context.Dr3; break;
|
||||
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
}
|
||||
|
||||
*lpdr = DEBUG_ToLinear(&breakpoints[i].addr);
|
||||
fprintf(stderr, "Setting DR%d %08lx\n", (lpdr - &DEBUG_context.Dr0) / 4, *lpdr);
|
||||
bits = (breakpoints[i].u.w.rw) ? DR7_RW_WRITE : DR7_RW_READ;
|
||||
switch (breakpoints[i].u.w.len + 1)
|
||||
{
|
||||
case 4: bits |= DR7_LEN_4; break;
|
||||
case 2: bits |= DR7_LEN_2; break;
|
||||
case 1: bits |= DR7_LEN_1; break;
|
||||
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
}
|
||||
|
||||
DEBUG_context.Dr7 &= ~(0x0F << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg));
|
||||
DEBUG_context.Dr7 |= bits << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg);
|
||||
DEBUG_context.Dr7 |= DR7_ENABLE_MASK(reg) | DR7_LOCAL_SLOWDOWN;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Setting DR7 %08lx\n", DEBUG_context.Dr7);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_FindBreakpoint
|
||||
*
|
||||
* Find the breakpoint for a given address. Return the breakpoint
|
||||
* number or -1 if none.
|
||||
* If type is DBG_BREAKPOINT, addr is a complete addr
|
||||
* If type is DBG_WATCHPOINT, only addr.off is meaningful and contains
|
||||
* linear address
|
||||
*/
|
||||
int DEBUG_FindBreakpoint( const DBG_ADDR *addr )
|
||||
static int DEBUG_FindBreakpoint( const DBG_ADDR *addr, int type )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_BREAKPOINTS; i++)
|
||||
{
|
||||
if (breakpoints[i].refcount && breakpoints[i].enabled &&
|
||||
breakpoints[i].addr.seg == addr->seg &&
|
||||
breakpoints[i].addr.off == addr->off) return i;
|
||||
}
|
||||
return -1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < next_bp; i++)
|
||||
{
|
||||
if (breakpoints[i].refcount && breakpoints[i].enabled &&
|
||||
breakpoints[i].type == type )
|
||||
{
|
||||
if ((type == DBG_BREAK &&
|
||||
breakpoints[i].addr.seg == addr->seg &&
|
||||
breakpoints[i].addr.off == addr->off) ||
|
||||
(type == DBG_WATCH &&
|
||||
DEBUG_ToLinear(&breakpoints[i].addr) == addr->off))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_InitXPoint
|
||||
*
|
||||
* Find an empty slot in BP table to add a new break/watch point
|
||||
*/
|
||||
static int DEBUG_InitXPoint(int type, DBG_ADDR* addr)
|
||||
{
|
||||
int num;
|
||||
|
||||
for (num = (next_bp < MAX_BREAKPOINTS) ? next_bp++ : 1;
|
||||
num < MAX_BREAKPOINTS; num++)
|
||||
{
|
||||
if (breakpoints[num].refcount == 0)
|
||||
{
|
||||
breakpoints[num].refcount = 1;
|
||||
breakpoints[num].enabled = TRUE;
|
||||
breakpoints[num].type = type;
|
||||
breakpoints[num].skipcount = 0;
|
||||
breakpoints[num].addr = *addr;
|
||||
breakpoints[num].is32 = 1;
|
||||
#ifdef __i386__
|
||||
if (addr->seg)
|
||||
{
|
||||
switch (DEBUG_GetSelectorType( addr->seg ))
|
||||
{
|
||||
case 32: break;
|
||||
case 16: breakpoints[num].is32 = 0; break;
|
||||
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return num;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_GetWatchedValue
|
||||
*
|
||||
* Returns the value watched by watch point 'num'.
|
||||
*/
|
||||
static BOOL DEBUG_GetWatchedValue( int num, LPDWORD val )
|
||||
{
|
||||
BYTE buf[4];
|
||||
|
||||
if (!DEBUG_READ_MEM((void*)DEBUG_ToLinear(&breakpoints[num].addr),
|
||||
buf, breakpoints[num].u.w.len + 1))
|
||||
return FALSE;
|
||||
|
||||
switch (breakpoints[num].u.w.len + 1)
|
||||
{
|
||||
case 4: *val = *(DWORD*)buf; break;
|
||||
case 2: *val = *(WORD*)buf; break;
|
||||
case 1: *val = *(BYTE*)buf; break;
|
||||
default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_AddBreakpoint
|
||||
*
|
||||
* Add a breakpoint.
|
||||
*/
|
||||
void DEBUG_AddBreakpoint( const DBG_ADDR *address )
|
||||
void DEBUG_AddBreakpoint( const DBG_VALUE *_value )
|
||||
{
|
||||
DBG_ADDR addr = *address;
|
||||
DBG_VALUE value = *_value;
|
||||
int num;
|
||||
unsigned int seg2;
|
||||
BYTE ch;
|
||||
|
||||
DEBUG_FixAddress( &addr, DEBUG_context.SegCs );
|
||||
assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
|
||||
|
||||
if( addr.type != NULL && addr.type == DEBUG_TypeIntConst )
|
||||
{
|
||||
/*
|
||||
* We know that we have the actual offset stored somewhere
|
||||
* else in 32-bit space. Grab it, and we
|
||||
* should be all set.
|
||||
*/
|
||||
seg2 = addr.seg;
|
||||
addr.seg = 0;
|
||||
addr.off = DEBUG_GetExprValue(&addr, NULL);
|
||||
addr.seg = seg2;
|
||||
}
|
||||
DEBUG_FixAddress( &value.addr, DEBUG_context.SegCs );
|
||||
|
||||
if ((num = DEBUG_FindBreakpoint(&addr)) >= 1)
|
||||
if( value.type != NULL && value.type == DEBUG_TypeIntConst )
|
||||
{
|
||||
/*
|
||||
* We know that we have the actual offset stored somewhere
|
||||
* else in 32-bit space. Grab it, and we
|
||||
* should be all set.
|
||||
*/
|
||||
seg2 = value.addr.seg;
|
||||
value.addr.seg = 0;
|
||||
value.addr.off = DEBUG_GetExprValue(&value, NULL);
|
||||
value.addr.seg = seg2;
|
||||
}
|
||||
|
||||
if ((num = DEBUG_FindBreakpoint(&value.addr, DBG_BREAK)) >= 1)
|
||||
{
|
||||
breakpoints[num].refcount++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &addr ), &ch, sizeof(ch)))
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &value.addr ), &ch, sizeof(ch)))
|
||||
return;
|
||||
|
||||
if (next_bp < MAX_BREAKPOINTS)
|
||||
num = next_bp++;
|
||||
else /* try to find an empty slot */
|
||||
{
|
||||
for (num = 1; num < MAX_BREAKPOINTS; num++)
|
||||
if (!breakpoints[num].refcount) break;
|
||||
if (num >= MAX_BREAKPOINTS)
|
||||
{
|
||||
fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
breakpoints[num].addr = addr;
|
||||
breakpoints[num].addrlen = 32;
|
||||
#ifdef __i386__
|
||||
if (addr.seg)
|
||||
breakpoints[num].addrlen = DEBUG_GetSelectorType( addr.seg );
|
||||
if (breakpoints[num].addrlen == 0) fprintf(stderr, "in bad shape\n");
|
||||
#endif
|
||||
breakpoints[num].opcode = ch;
|
||||
breakpoints[num].enabled = TRUE;
|
||||
breakpoints[num].refcount = 1;
|
||||
breakpoints[num].skipcount = 0;
|
||||
if ((num = DEBUG_InitXPoint(DBG_BREAK, &value.addr)) == -1)
|
||||
return;
|
||||
|
||||
breakpoints[num].u.opcode = ch;
|
||||
|
||||
fprintf( stderr, "Breakpoint %d at ", num );
|
||||
DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen,
|
||||
DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32 : 16,
|
||||
TRUE );
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_AddWatchpoint
|
||||
*
|
||||
* Add a watchpoint.
|
||||
*/
|
||||
void DEBUG_AddWatchpoint( const DBG_VALUE *_value, BOOL is_write )
|
||||
{
|
||||
DBG_VALUE value = *_value;
|
||||
int num, reg;
|
||||
unsigned seg2;
|
||||
DWORD mask = 0;
|
||||
|
||||
assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
|
||||
|
||||
DEBUG_FixAddress( &value.addr, CS_reg(&DEBUG_context) );
|
||||
|
||||
if ( value.type != NULL && value.type == DEBUG_TypeIntConst )
|
||||
{
|
||||
/*
|
||||
* We know that we have the actual offset stored somewhere
|
||||
* else in 32-bit space. Grab it, and we
|
||||
* should be all set.
|
||||
*/
|
||||
seg2 = value.addr.seg;
|
||||
value.addr.seg = 0;
|
||||
value.addr.off = DEBUG_GetExprValue(&value, NULL);
|
||||
value.addr.seg = seg2;
|
||||
}
|
||||
|
||||
for (num = 1; num < next_bp; num++)
|
||||
{
|
||||
if (breakpoints[num].refcount && breakpoints[num].enabled &&
|
||||
breakpoints[num].type == DBG_WATCH) {
|
||||
mask |= (1 << breakpoints[num].u.w.reg);
|
||||
}
|
||||
}
|
||||
#ifdef __i386__
|
||||
for (reg = 0; reg < 4 && (mask & (1 << reg)); reg++);
|
||||
if (reg == 4)
|
||||
{
|
||||
fprintf(stderr, "All i386 hardware watchpoints have been set. Delete some\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((num = DEBUG_InitXPoint(DBG_WATCH, &value.addr)) == -1)
|
||||
return;
|
||||
|
||||
breakpoints[num].u.w.len = 4 - 1;
|
||||
if (_value->type && DEBUG_GetObjectSize(_value->type) < 4)
|
||||
breakpoints[num].u.w.len = 2 - 1;
|
||||
|
||||
if (!DEBUG_GetWatchedValue( num, &breakpoints[num].u.w.oldval))
|
||||
{
|
||||
fprintf(stderr, "Bad address. Watchpoint not set\n");
|
||||
breakpoints[num].refcount = 0;
|
||||
}
|
||||
|
||||
breakpoints[num].u.w.rw = (is_write) ? TRUE : FALSE;
|
||||
breakpoints[reg].u.w.reg = reg;
|
||||
|
||||
fprintf( stderr, "Watchpoint %d at ", num );
|
||||
DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32:16, TRUE );
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_DelBreakpoint
|
||||
*
|
||||
@ -250,7 +443,7 @@ void DEBUG_AddBreakpoint( const DBG_ADDR *address )
|
||||
*/
|
||||
void DEBUG_DelBreakpoint( int num )
|
||||
{
|
||||
if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
|
||||
if ((num <= 0) || (num >= next_bp) || breakpoints[num].refcount == 0)
|
||||
{
|
||||
fprintf( stderr, "Invalid breakpoint number %d\n", num );
|
||||
return;
|
||||
@ -260,17 +453,16 @@ void DEBUG_DelBreakpoint( int num )
|
||||
return;
|
||||
|
||||
if( breakpoints[num].condition != NULL )
|
||||
{
|
||||
DEBUG_FreeExpr(breakpoints[num].condition);
|
||||
breakpoints[num].condition = NULL;
|
||||
}
|
||||
{
|
||||
DEBUG_FreeExpr(breakpoints[num].condition);
|
||||
breakpoints[num].condition = NULL;
|
||||
}
|
||||
|
||||
breakpoints[num].enabled = FALSE;
|
||||
breakpoints[num].refcount = 0;
|
||||
breakpoints[num].skipcount = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_EnableBreakpoint
|
||||
*
|
||||
@ -278,7 +470,7 @@ void DEBUG_DelBreakpoint( int num )
|
||||
*/
|
||||
void DEBUG_EnableBreakpoint( int num, BOOL enable )
|
||||
{
|
||||
if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
|
||||
if ((num <= 0) || (num >= next_bp) || breakpoints[num].refcount == 0)
|
||||
{
|
||||
fprintf( stderr, "Invalid breakpoint number %d\n", num );
|
||||
return;
|
||||
@ -288,6 +480,76 @@ void DEBUG_EnableBreakpoint( int num, BOOL enable )
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_FindTriggeredWatchpoint
|
||||
*
|
||||
* Lookup the watchpoints to see if one has been triggered
|
||||
* Return >= (watch point index) if one is found and *oldval is set to
|
||||
* the value watched before the TRAP
|
||||
* Return -1 if none found (*oldval is undetermined)
|
||||
*
|
||||
* Unfortunately, Linux does *NOT* (A REAL PITA) report with ptrace
|
||||
* the DR6 register value, so we have to look with our own need the
|
||||
* cause of the TRAP.
|
||||
* -EP
|
||||
*/
|
||||
static int DEBUG_FindTriggeredWatchpoint(LPDWORD oldval)
|
||||
{
|
||||
int i;
|
||||
int found = -1;
|
||||
DWORD val = 0;
|
||||
|
||||
/* Method 1 => get triggered watchpoint from context (doesn't work on Linux
|
||||
* 2.2.x)
|
||||
*/
|
||||
for (i = 0; i < next_bp; i++)
|
||||
{
|
||||
#ifdef __i386__
|
||||
if (breakpoints[i].refcount && breakpoints[i].enabled &&
|
||||
breakpoints[i].type == DBG_WATCH &&
|
||||
(DEBUG_context.Dr6 & (1 << breakpoints[i].u.w.reg)))
|
||||
{
|
||||
DEBUG_context.Dr6 &= ~(1 << breakpoints[i].u.w.reg);
|
||||
|
||||
*oldval = breakpoints[i].u.w.oldval;
|
||||
if (DEBUG_GetWatchedValue(i, &val)) {
|
||||
breakpoints[i].u.w.oldval = val;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Method 1 failed, trying method2 */
|
||||
|
||||
/* Method 2 => check if value has changed among registered watchpoints
|
||||
* this really sucks, but this is how gdb 4.18 works on my linux box
|
||||
* -EP
|
||||
*/
|
||||
for (i = 0; i < next_bp; i++)
|
||||
{
|
||||
#ifdef __i386__
|
||||
if (breakpoints[i].refcount && breakpoints[i].enabled &&
|
||||
breakpoints[i].type == DBG_WATCH &&
|
||||
DEBUG_GetWatchedValue(i, &val))
|
||||
{
|
||||
*oldval = breakpoints[i].u.w.oldval;
|
||||
if (val != *oldval)
|
||||
{
|
||||
DEBUG_context.Dr6 &= ~(1 << breakpoints[i].u.w.reg);
|
||||
breakpoints[i].u.w.oldval = val;
|
||||
found = i;
|
||||
/* cannot break, because two watch points may have been triggered on
|
||||
* the same acces
|
||||
* only one will be reported to the user (FIXME ?)
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_InfoBreakpoints
|
||||
*
|
||||
@ -300,10 +562,11 @@ void DEBUG_InfoBreakpoints(void)
|
||||
fprintf( stderr, "Breakpoints:\n" );
|
||||
for (i = 1; i < next_bp; i++)
|
||||
{
|
||||
if (breakpoints[i].refcount)
|
||||
if (breakpoints[i].refcount && breakpoints[i].type == DBG_BREAK)
|
||||
{
|
||||
fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
|
||||
DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen, TRUE);
|
||||
DEBUG_PrintAddress( &breakpoints[i].addr,
|
||||
breakpoints[i].is32 ? 32 : 16, TRUE);
|
||||
fprintf( stderr, " (%u)\n", breakpoints[i].refcount );
|
||||
if( breakpoints[i].condition != NULL )
|
||||
{
|
||||
@ -313,6 +576,60 @@ void DEBUG_InfoBreakpoints(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf( stderr, "Watchpoints:\n" );
|
||||
for (i = 1; i < next_bp; i++)
|
||||
{
|
||||
if (breakpoints[i].refcount && breakpoints[i].type == DBG_WATCH)
|
||||
{
|
||||
fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
|
||||
DEBUG_PrintAddress( &breakpoints[i].addr,
|
||||
breakpoints[i].is32 ? 32 : 16, TRUE);
|
||||
fprintf( stderr, " on %d byte%s (%c)\n",
|
||||
breakpoints[i].u.w.len + 1,
|
||||
breakpoints[i].u.w.len > 0 ? "s" : "",
|
||||
breakpoints[i].u.w.rw ? 'W' : 'R');
|
||||
if( breakpoints[i].condition != NULL )
|
||||
{
|
||||
fprintf(stderr, "\t\tstop when ");
|
||||
DEBUG_DisplayExpr(breakpoints[i].condition);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_ShallBreak
|
||||
*
|
||||
* Check whether or not the condition (bp / skipcount) of a break/watch
|
||||
* point are met.
|
||||
*/
|
||||
static BOOL DEBUG_ShallBreak( int bpnum )
|
||||
{
|
||||
if ( breakpoints[bpnum].condition != NULL )
|
||||
{
|
||||
DBG_VALUE value = DEBUG_EvalExpr(breakpoints[bpnum].condition);
|
||||
|
||||
if ( value.type == NULL )
|
||||
{
|
||||
/*
|
||||
* Something wrong - unable to evaluate this expression.
|
||||
*/
|
||||
fprintf(stderr, "Unable to evaluate expression ");
|
||||
DEBUG_DisplayExpr(breakpoints[bpnum].condition);
|
||||
fprintf(stderr, "\nTurning off condition\n");
|
||||
DEBUG_AddBPCondition(bpnum, NULL);
|
||||
}
|
||||
else if( !DEBUG_GetExprValue( &value, NULL) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( breakpoints[bpnum].skipcount > 0 && --breakpoints[bpnum].skipcount > 0 )
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@ -323,10 +640,11 @@ void DEBUG_InfoBreakpoints(void)
|
||||
*/
|
||||
BOOL DEBUG_ShouldContinue( DWORD code, enum exec_mode mode, int * count )
|
||||
{
|
||||
DBG_ADDR addr;
|
||||
DBG_ADDR cond_addr;
|
||||
int bpnum;
|
||||
struct list_id list;
|
||||
DBG_ADDR addr;
|
||||
int bpnum;
|
||||
DWORD oldval;
|
||||
int wpnum;
|
||||
struct symbol_info syminfo;
|
||||
|
||||
#ifdef __i386__
|
||||
/* If not single-stepping, back up over the int3 instruction */
|
||||
@ -335,94 +653,82 @@ BOOL DEBUG_ShouldContinue( DWORD code, enum exec_mode mode, int * count )
|
||||
#endif
|
||||
|
||||
DEBUG_GetCurrentAddress( &addr );
|
||||
bpnum = DEBUG_FindBreakpoint( &addr );
|
||||
bpnum = DEBUG_FindBreakpoint( &addr, DBG_BREAK );
|
||||
breakpoints[0].enabled = FALSE; /* disable the step-over breakpoint */
|
||||
|
||||
if ((bpnum != 0) && (bpnum != -1))
|
||||
{
|
||||
if( breakpoints[bpnum].condition != NULL )
|
||||
{
|
||||
cond_addr = DEBUG_EvalExpr(breakpoints[bpnum].condition);
|
||||
if( cond_addr.type == NULL )
|
||||
{
|
||||
/*
|
||||
* Something wrong - unable to evaluate this expression.
|
||||
*/
|
||||
fprintf(stderr, "Unable to evaluate expression ");
|
||||
DEBUG_DisplayExpr(breakpoints[bpnum].condition);
|
||||
fprintf(stderr, "\nTurning off condition\n");
|
||||
DEBUG_AddBPCondition(bpnum, NULL);
|
||||
}
|
||||
else if( ! DEBUG_GetExprValue( &cond_addr, NULL) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (!DEBUG_ShallBreak(bpnum)) return TRUE;
|
||||
|
||||
if( breakpoints[bpnum].skipcount > 0 )
|
||||
{
|
||||
breakpoints[bpnum].skipcount--;
|
||||
if( breakpoints[bpnum].skipcount > 0 )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
|
||||
DEBUG_PrintAddress( &breakpoints[bpnum].addr,
|
||||
breakpoints[bpnum].addrlen, TRUE );
|
||||
syminfo = DEBUG_PrintAddress( &breakpoints[bpnum].addr,
|
||||
breakpoints[bpnum].is32 ? 32 : 16, TRUE );
|
||||
fprintf( stderr, "\n" );
|
||||
|
||||
/*
|
||||
* See if there is a source file for this bp. If so,
|
||||
* then dig it out and display one line.
|
||||
*/
|
||||
DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
|
||||
if( list.sourcefile != NULL )
|
||||
{
|
||||
DEBUG_List(&list, NULL, 0);
|
||||
}
|
||||
if( syminfo.list.sourcefile != NULL )
|
||||
DEBUG_List(&syminfo.list, NULL, 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wpnum = DEBUG_FindTriggeredWatchpoint(&oldval);
|
||||
if ((wpnum != 0) && (wpnum != -1))
|
||||
{
|
||||
/* If not single-stepping, do not back up over the int3 instruction */
|
||||
if (code == EXCEPTION_BREAKPOINT)
|
||||
{
|
||||
EIP_reg(&DEBUG_context)++;
|
||||
addr.off++;
|
||||
}
|
||||
if (!DEBUG_ShallBreak(wpnum)) return TRUE;
|
||||
|
||||
fprintf(stderr, "Stopped on watchpoint %d at ", wpnum);
|
||||
syminfo = DEBUG_PrintAddress( &addr, !addr.seg ? 32 :
|
||||
DEBUG_GetSelectorType( addr.seg ), TRUE );
|
||||
|
||||
fprintf(stderr, " values: old=%lu new=%lu\n",
|
||||
oldval, breakpoints[wpnum].u.w.oldval);
|
||||
if (syminfo.list.sourcefile != NULL)
|
||||
DEBUG_List(&syminfo.list, NULL, 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If our mode indicates that we are stepping line numbers,
|
||||
* get the current function, and figure out if we are exactly
|
||||
* on a line number or not.
|
||||
*/
|
||||
if( mode == EXEC_STEP_OVER || mode == EXEC_STEP_INSTR )
|
||||
{
|
||||
{
|
||||
if( DEBUG_CheckLinenoStatus(&addr) == AT_LINENUMBER )
|
||||
{
|
||||
{
|
||||
(*count)--;
|
||||
}
|
||||
}
|
||||
else if( mode == EXEC_STEPI_OVER
|
||||
|| mode == EXEC_STEPI_INSTR )
|
||||
|
||||
{
|
||||
}
|
||||
}
|
||||
else if( mode == EXEC_STEPI_OVER || mode == EXEC_STEPI_INSTR )
|
||||
{
|
||||
(*count)--;
|
||||
}
|
||||
}
|
||||
|
||||
if( *count > 0 || mode == EXEC_FINISH )
|
||||
{
|
||||
{
|
||||
/*
|
||||
* We still need to execute more instructions.
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are about to stop, then print out the source line if we
|
||||
* have it.
|
||||
*/
|
||||
if ((mode != EXEC_CONT && mode != EXEC_PASS && mode != EXEC_FINISH))
|
||||
{
|
||||
DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
|
||||
if( list.sourcefile != NULL )
|
||||
{
|
||||
DEBUG_List(&list, NULL, 0);
|
||||
}
|
||||
}
|
||||
if (mode != EXEC_CONT && mode != EXEC_PASS && mode != EXEC_FINISH)
|
||||
{
|
||||
DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &syminfo.list);
|
||||
if( syminfo.list.sourcefile != NULL )
|
||||
{
|
||||
DEBUG_List(&syminfo.list, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
/* If there's no breakpoint and we are not single-stepping, then we */
|
||||
@ -471,7 +777,7 @@ enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
|
||||
*/
|
||||
ret_mode = mode;
|
||||
|
||||
bp = DEBUG_FindBreakpoint( &addr );
|
||||
bp = DEBUG_FindBreakpoint( &addr, DBG_BREAK );
|
||||
if ( bp != -1 && bp != 0)
|
||||
{
|
||||
/*
|
||||
@ -574,7 +880,8 @@ enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
|
||||
breakpoints[0].enabled = TRUE;
|
||||
breakpoints[0].refcount = 1;
|
||||
breakpoints[0].skipcount = 0;
|
||||
DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].opcode, sizeof(char));
|
||||
DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].u.opcode,
|
||||
sizeof(char));
|
||||
DEBUG_SetBreakpoints( TRUE );
|
||||
break;
|
||||
|
||||
@ -591,7 +898,8 @@ enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
|
||||
breakpoints[0].enabled = TRUE;
|
||||
breakpoints[0].refcount = 1;
|
||||
breakpoints[0].skipcount = 0;
|
||||
DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].opcode, sizeof(char));
|
||||
DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].u.opcode,
|
||||
sizeof(char));
|
||||
DEBUG_SetBreakpoints( TRUE );
|
||||
break;
|
||||
}
|
||||
@ -603,6 +911,8 @@ enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
|
||||
DEBUG_context.EFlags |= STEP_FLAG;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
}
|
||||
DEBUG_CurrThread->stepOverBP = breakpoints[0];
|
||||
return ret_mode;
|
||||
|
@ -1011,7 +1011,6 @@ static void db_task_printsym(unsigned int addr, int size)
|
||||
{
|
||||
DBG_ADDR address;
|
||||
|
||||
address.type = NULL;
|
||||
address.seg = 0;
|
||||
address.off = addr;
|
||||
|
||||
|
115
debugger/dbg.y
115
debugger/dbg.y
@ -4,6 +4,7 @@
|
||||
*
|
||||
* Copyright 1993 Eric Youngdale
|
||||
* Copyright 1995 Morten Welinder
|
||||
* Copyright 2000 Eric Pouech
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -21,8 +22,8 @@
|
||||
extern FILE * yyin;
|
||||
int curr_frame = 0;
|
||||
|
||||
void issue_prompt(void);
|
||||
void mode_command(int);
|
||||
static void issue_prompt(void);
|
||||
static void mode_command(int);
|
||||
void flush_symbols(void);
|
||||
int yylex(void);
|
||||
int yyerror(char *);
|
||||
@ -31,7 +32,7 @@ int yyerror(char *);
|
||||
|
||||
%union
|
||||
{
|
||||
DBG_ADDR address;
|
||||
DBG_VALUE value;
|
||||
enum debug_regs reg;
|
||||
char * string;
|
||||
int integer;
|
||||
@ -46,7 +47,7 @@ int yyerror(char *);
|
||||
%token tPROCESS tMODREF
|
||||
%token tEOL tSTRING tDEBUGSTR
|
||||
%token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE
|
||||
%token tSTEPI tNEXTI tFINISH tSHOW tDIR
|
||||
%token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS
|
||||
%token <string> tPATH
|
||||
%token <string> tIDENTIFIER tSTRING tDEBUGSTR
|
||||
%token <integer> tNUM tFORMAT
|
||||
@ -77,7 +78,7 @@ int yyerror(char *);
|
||||
|
||||
%type <expression> expr lval lvalue
|
||||
%type <type> type_cast type_expr
|
||||
%type <address> expr_addr lval_addr
|
||||
%type <value> expr_addr lval_addr
|
||||
%type <integer> expr_value
|
||||
%type <string> pathname
|
||||
|
||||
@ -144,19 +145,21 @@ command:
|
||||
| tCOND tNUM tEOL { DEBUG_AddBPCondition($2, NULL); }
|
||||
| tCOND tNUM expr tEOL { DEBUG_AddBPCondition($2, $3); }
|
||||
| tSYMBOLFILE pathname tEOL{ DEBUG_ReadSymbolTable($2); }
|
||||
| tWHATIS expr_addr tEOL { DEBUG_PrintType(&$2); DEBUG_FreeExprMem(); }
|
||||
| list_command
|
||||
| disassemble_command
|
||||
| set_command
|
||||
| x_command
|
||||
| print_command
|
||||
| break_command
|
||||
| watch_command
|
||||
| info_command
|
||||
| walk_command
|
||||
|
||||
set_command:
|
||||
tSET tREG '=' expr_value tEOL { DEBUG_SetRegister( $2, $4 );
|
||||
DEBUG_FreeExprMem(); }
|
||||
| tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory( &$2, $4 );
|
||||
| tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory( &$2.addr, $4 );
|
||||
DEBUG_FreeExprMem(); }
|
||||
|
||||
pathname:
|
||||
@ -180,7 +183,7 @@ list_arg:
|
||||
| pathname ':' tNUM { $$.sourcefile = $1; $$.line = $3; }
|
||||
| tIDENTIFIER { DEBUG_GetFuncInfo( & $$, NULL, $1); }
|
||||
| pathname ':' tIDENTIFIER { DEBUG_GetFuncInfo( & $$, $1, $3); }
|
||||
| '*' expr_addr { DEBUG_FindNearestSymbol( & $2, FALSE, NULL,
|
||||
| '*' expr_addr { DEBUG_FindNearestSymbol( & $2.addr, FALSE, NULL,
|
||||
0, & $$ );
|
||||
DEBUG_FreeExprMem(); }
|
||||
|
||||
@ -199,20 +202,20 @@ print_command:
|
||||
break_command:
|
||||
tBREAK '*' expr_addr tEOL { DEBUG_AddBreakpoint( &$3 );
|
||||
DEBUG_FreeExprMem(); }
|
||||
| tBREAK tIDENTIFIER tEOL { DBG_ADDR addr;
|
||||
if( DEBUG_GetSymbolValue($2, -1, &addr, TRUE) )
|
||||
| tBREAK tIDENTIFIER tEOL { DBG_VALUE value;
|
||||
if( DEBUG_GetSymbolValue($2, -1, &value, TRUE) )
|
||||
{
|
||||
DEBUG_AddBreakpoint( &addr );
|
||||
DEBUG_AddBreakpoint( &value );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Unable to add breakpoint\n");
|
||||
}
|
||||
}
|
||||
| tBREAK tIDENTIFIER ':' tNUM tEOL { DBG_ADDR addr;
|
||||
if( DEBUG_GetSymbolValue($2, $4, &addr, TRUE) )
|
||||
| tBREAK tIDENTIFIER ':' tNUM tEOL { DBG_VALUE value;
|
||||
if( DEBUG_GetSymbolValue($2, $4, &value, TRUE) )
|
||||
{
|
||||
DEBUG_AddBreakpoint( &addr );
|
||||
DEBUG_AddBreakpoint( &value );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -220,15 +223,16 @@ break_command:
|
||||
}
|
||||
}
|
||||
| tBREAK tNUM tEOL { struct name_hash *nh;
|
||||
DBG_ADDR addr;
|
||||
DEBUG_GetCurrentAddress( &addr );
|
||||
DEBUG_FindNearestSymbol(&addr, TRUE,
|
||||
DBG_VALUE value;
|
||||
DEBUG_GetCurrentAddress( &value.addr );
|
||||
DEBUG_FindNearestSymbol(&value.addr, TRUE,
|
||||
&nh, 0, NULL);
|
||||
if( nh != NULL )
|
||||
{
|
||||
DEBUG_GetLineNumberAddr(nh,
|
||||
$2, &addr, TRUE);
|
||||
DEBUG_AddBreakpoint( &addr );
|
||||
DEBUG_GetLineNumberAddr(nh, $2, &value.addr, TRUE);
|
||||
value.type = NULL;
|
||||
value.cookie = DV_TARGET;
|
||||
DEBUG_AddBreakpoint( &value );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -236,19 +240,29 @@ break_command:
|
||||
}
|
||||
}
|
||||
|
||||
| tBREAK tEOL { DBG_ADDR addr;
|
||||
DEBUG_GetCurrentAddress( &addr );
|
||||
DEBUG_AddBreakpoint( &addr );
|
||||
| tBREAK tEOL { DBG_VALUE value;
|
||||
DEBUG_GetCurrentAddress( &value.addr );
|
||||
value.type = NULL;
|
||||
value.cookie = DV_TARGET;
|
||||
DEBUG_AddBreakpoint( &value );
|
||||
}
|
||||
|
||||
watch_command:
|
||||
tWATCH '*' expr_addr tEOL { DEBUG_AddWatchpoint( &$3, 1 );
|
||||
DEBUG_FreeExprMem(); }
|
||||
| tWATCH tIDENTIFIER tEOL { DBG_VALUE value;
|
||||
if( DEBUG_GetSymbolValue($2, -1, &value, TRUE) )
|
||||
DEBUG_AddWatchpoint( &value, 1 );
|
||||
else
|
||||
fprintf(stderr,"Unable to add breakpoint\n");
|
||||
}
|
||||
|
||||
info_command:
|
||||
tINFO tBREAK tEOL { DEBUG_InfoBreakpoints(); }
|
||||
| tINFO tCLASS tSTRING tEOL { DEBUG_InfoClass( $3 ); DEBUG_FreeExprMem(); }
|
||||
| tINFO tSHARE tEOL { DEBUG_InfoShare(); }
|
||||
| tINFO tMODULE expr_value tEOL { DEBUG_DumpModule( $3 );
|
||||
DEBUG_FreeExprMem(); }
|
||||
| tINFO tQUEUE expr_value tEOL { DEBUG_DumpQueue( $3 );
|
||||
DEBUG_FreeExprMem(); }
|
||||
| tINFO tMODULE expr_value tEOL { DEBUG_DumpModule( $3 ); DEBUG_FreeExprMem(); }
|
||||
| tINFO tQUEUE expr_value tEOL { DEBUG_DumpQueue( $3 ); DEBUG_FreeExprMem(); }
|
||||
| tINFO tREGS tEOL { DEBUG_InfoRegisters(); }
|
||||
| tINFO tSEGMENTS expr_value tEOL { DEBUG_InfoSegments( $3, 1 ); DEBUG_FreeExprMem(); }
|
||||
| tINFO tSEGMENTS tEOL { DEBUG_InfoSegments( 0, -1 ); }
|
||||
@ -296,9 +310,10 @@ expr_addr:
|
||||
expr { $$ = DEBUG_EvalExpr($1); }
|
||||
|
||||
expr_value:
|
||||
expr { DBG_ADDR addr = DEBUG_EvalExpr($1);
|
||||
expr { DBG_VALUE value = DEBUG_EvalExpr($1);
|
||||
/* expr_value is typed as an integer */
|
||||
if (!addr.off || !DEBUG_READ_MEM((void*)addr.off, &$$, sizeof($$)))
|
||||
if (!value.addr.off ||
|
||||
!DEBUG_READ_MEM((void*)value.addr.off, &$$, sizeof($$)))
|
||||
$$ = 0; }
|
||||
/*
|
||||
* The expr rule builds an expression tree. When we are done, we call
|
||||
@ -315,8 +330,7 @@ expr:
|
||||
| expr '.' tIDENTIFIER { $$ = DEBUG_StructExpr($1, $3); }
|
||||
| tIDENTIFIER '(' ')' { $$ = DEBUG_CallExpr($1, 0); }
|
||||
| tIDENTIFIER '(' expr ')' { $$ = DEBUG_CallExpr($1, 1, $3); }
|
||||
| tIDENTIFIER '(' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 2, $3,
|
||||
$5); }
|
||||
| tIDENTIFIER '(' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 2, $3, $5); }
|
||||
| tIDENTIFIER '(' expr ',' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7); }
|
||||
| tIDENTIFIER '(' expr ',' expr ',' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7, $9); }
|
||||
| tIDENTIFIER '(' expr ',' expr ',' expr ',' expr ',' expr ')' { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7, $9, $11); }
|
||||
@ -370,24 +384,39 @@ lvalue:
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
issue_prompt(){
|
||||
static void issue_prompt(void)
|
||||
{
|
||||
#ifdef DONT_USE_READLINE
|
||||
fprintf(stderr,"Wine-dbg>");
|
||||
fprintf(stderr, "Wine-dbg>");
|
||||
#endif
|
||||
}
|
||||
|
||||
void mode_command(int newmode)
|
||||
static void mode_command(int newmode)
|
||||
{
|
||||
if ((newmode == 16) || (newmode == 32)) DEBUG_CurrThread->dbg_mode = newmode;
|
||||
else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
|
||||
}
|
||||
|
||||
static WINE_EXCEPTION_FILTER(no_symbol)
|
||||
static WINE_EXCEPTION_FILTER(wine_dbg)
|
||||
{
|
||||
if (GetExceptionCode() == DEBUG_STATUS_NO_SYMBOL)
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
switch (GetExceptionCode()) {
|
||||
case DEBUG_STATUS_INTERNAL_ERROR:
|
||||
fprintf(stderr, "WineDbg internal error\n");
|
||||
break;
|
||||
case DEBUG_STATUS_NO_SYMBOL:
|
||||
fprintf(stderr, "Undefined symbol\n");
|
||||
break;
|
||||
case DEBUG_STATUS_DIV_BY_ZERO:
|
||||
fprintf(stderr, "Division by zero\n");
|
||||
break;
|
||||
case DEBUG_STATUS_BAD_TYPE:
|
||||
fprintf(stderr, "No type or type mismatch\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Exception %lx\n", GetExceptionCode());
|
||||
break;
|
||||
}
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@ -444,8 +473,6 @@ BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code )
|
||||
DBG_ADDR addr;
|
||||
DEBUG_GetCurrentAddress( &addr );
|
||||
|
||||
/* EPP if (USER_Driver) USER_Driver->pBeginDebugging(); */
|
||||
|
||||
#ifdef __i386__
|
||||
switch (newmode = DEBUG_GetSelectorType(addr.seg)) {
|
||||
case 16: case 32: break;
|
||||
@ -509,9 +536,8 @@ BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code )
|
||||
if ((ret_ok = DEBUG_ValidateRegisters()))
|
||||
ret_ok = DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &addr ), &ch, 1 );
|
||||
}
|
||||
__EXCEPT(no_symbol)
|
||||
__EXCEPT(wine_dbg)
|
||||
{
|
||||
fprintf(stderr, "Undefined symbol\n");
|
||||
ret_ok = 0;
|
||||
}
|
||||
__ENDTRY;
|
||||
@ -527,13 +553,12 @@ BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code )
|
||||
*/
|
||||
if ((DEBUG_CurrThread->dbg_exec_mode == EXEC_CONT) || (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS))
|
||||
DEBUG_CurrThread->dbg_exec_count = 0;
|
||||
/* EPP if (USER_Driver) USER_Driver->pEndDebugging(); */
|
||||
|
||||
return (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS) ? 0 : DBG_CONTINUE;
|
||||
}
|
||||
|
||||
int yyerror(char* s)
|
||||
{
|
||||
fprintf(stderr,"%s\n", s);
|
||||
return 0;
|
||||
fprintf(stderr,"%s\n", s);
|
||||
return 0;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ XFlush(Display * d )
|
||||
return(0);
|
||||
}
|
||||
|
||||
HTASK16 GetCurrentTask()
|
||||
HTASK16 GetCurrentTask(void)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
@ -70,17 +70,17 @@ void WIN_DumpWindow( HWND hwnd )
|
||||
}
|
||||
|
||||
|
||||
void CLASS_WalkClasses()
|
||||
void CLASS_WalkClasses(void)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void MODULE_WalkModules()
|
||||
void MODULE_WalkModules(void)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void QUEUE_WalkQueues()
|
||||
void QUEUE_WalkQueues(void)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
@ -173,7 +173,7 @@ struct CodeViewDebug
|
||||
char cv_name[1];
|
||||
};
|
||||
|
||||
test_pdbstuff()
|
||||
test_pdbstuff(void)
|
||||
{
|
||||
struct deferred_debug_info deefer;
|
||||
IMAGE_DEBUG_DIRECTORY dinfo;
|
||||
|
@ -131,7 +131,7 @@ $gs { yylval.reg = REG_GS; return tREG; }
|
||||
<INITIAL>help|hel|he|"?" { BEGIN(HELP_CMD); return tHELP; }
|
||||
|
||||
<INITIAL>backtrace|backtrac|backtra|backt|back|bac|ba|bt { BEGIN(NOCMD); return tBACKTRACE; }
|
||||
<INITIAL>where|wher|whe { BEGIN(NOCMD); return tBACKTRACE; }
|
||||
<INITIAL>where|wher|whe { BEGIN(NOCMD); return tBACKTRACE; }
|
||||
|
||||
<INITIAL>cont|con|co|c { BEGIN(NOCMD); return tCONT; }
|
||||
<INITIAL>pass|pas|pa { BEGIN(NOCMD); return tPASS; }
|
||||
@ -151,14 +151,15 @@ $gs { yylval.reg = REG_GS; return tREG; }
|
||||
|
||||
<INITIAL,INFO_CMD,DEL_CMD>break|brea|bre|br|b { BEGIN(PATH_EXPECTED); return tBREAK; }
|
||||
<INITIAL>watch|watc|wat { BEGIN(PATH_EXPECTED); return tWATCH; }
|
||||
<INITIAL>whatis|whati|what { BEGIN(PATH_EXPECTED); return tWHATIS; }
|
||||
|
||||
<INFO_CMD>share|shar|sha { return tSHARE; }
|
||||
<INFO_CMD>locals|local|loca|loc { return tLOCAL; }
|
||||
<INFO_CMD,WALK_CMD>class|clas|cla { return tCLASS; }
|
||||
<INFO_CMD,WALK_CMD>module|modul|modu|mod { return tMODULE; }
|
||||
<INFO_CMD,WALK_CMD>queue|queu|que { return tQUEUE; }
|
||||
<INFO_CMD,WALK_CMD>queue|queu|que { return tQUEUE; }
|
||||
<INFO_CMD,WALK_CMD>process|proces|proce|proc { return tPROCESS; }
|
||||
<INFO_CMD,WALK_CMD>modref|modre|modr { return tMODREF; }
|
||||
<INFO_CMD,WALK_CMD>modref|modre|modr { return tMODREF; }
|
||||
<INFO_CMD>registers|regs|reg|re { return tREGS; }
|
||||
<INFO_CMD>segments|segment|segm|seg|se { return tSEGMENTS; }
|
||||
<INFO_CMD>stack|stac|sta|st { return tSTACK; }
|
||||
|
@ -8,11 +8,12 @@
|
||||
#define __WINE_DEBUGGER_H
|
||||
|
||||
#include <sys/types.h> /* u_long ... */
|
||||
#include <assert.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
||||
#ifdef __i386__
|
||||
#define STEP_FLAG 0x100 /* single step flag */
|
||||
#define STEP_FLAG 0x00000100 /* single step flag */
|
||||
#define V86_FLAG 0x00020000
|
||||
#endif
|
||||
|
||||
@ -46,11 +47,20 @@ extern struct datatype * DEBUG_TypeString;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct datatype * type;
|
||||
DWORD seg; /* 0xffffffff means current default segment (cs or ds) */
|
||||
DWORD off;
|
||||
DWORD seg; /* 0xffffffff means current default segment (cs or ds) */
|
||||
DWORD off;
|
||||
} DBG_ADDR;
|
||||
|
||||
#define DV_TARGET 0xF00D
|
||||
#define DV_HOST 0x50DA
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct datatype* type;
|
||||
int cookie; /* DV_??? */
|
||||
DBG_ADDR addr;
|
||||
} DBG_VALUE;
|
||||
|
||||
struct list_id
|
||||
{
|
||||
char * sourcefile;
|
||||
@ -101,15 +111,27 @@ enum exec_mode
|
||||
* instr just after the call.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
#define DBG_BREAK 0
|
||||
#define DBG_WATCH 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DBG_ADDR addr;
|
||||
BYTE addrlen;
|
||||
BYTE opcode;
|
||||
WORD skipcount;
|
||||
WORD enabled : 1,
|
||||
refcount;
|
||||
type : 1,
|
||||
is32 : 1,
|
||||
refcount : 13;
|
||||
WORD skipcount;
|
||||
union {
|
||||
BYTE opcode;
|
||||
struct {
|
||||
BYTE rw : 1,
|
||||
len : 2;
|
||||
BYTE reg;
|
||||
DWORD oldval;
|
||||
} w;
|
||||
} u;
|
||||
struct expr * condition;
|
||||
} BREAKPOINT;
|
||||
|
||||
@ -171,8 +193,8 @@ enum debug_regs
|
||||
|
||||
/* debugger/break.c */
|
||||
extern void DEBUG_SetBreakpoints( BOOL set );
|
||||
extern int DEBUG_FindBreakpoint( const DBG_ADDR *addr );
|
||||
extern void DEBUG_AddBreakpoint( const DBG_ADDR *addr );
|
||||
extern void DEBUG_AddBreakpoint( const DBG_VALUE *addr );
|
||||
extern void DEBUG_AddWatchpoint( const DBG_VALUE *addr, int is_write );
|
||||
extern void DEBUG_DelBreakpoint( int num );
|
||||
extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
|
||||
extern void DEBUG_InfoBreakpoints(void);
|
||||
@ -181,6 +203,7 @@ extern BOOL DEBUG_ShouldContinue( DWORD code, enum exec_mode mode, int * count )
|
||||
extern void DEBUG_SuspendExecution( void );
|
||||
extern enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count );
|
||||
extern BOOL DEBUG_IsFctReturn(void);
|
||||
extern int DEBUG_AddBPCondition(int bpnum, struct expr * exp);
|
||||
|
||||
/* debugger/db_disasm.c */
|
||||
extern void DEBUG_Disasm( DBG_ADDR *addr, int display );
|
||||
@ -200,15 +223,11 @@ struct expr * DEBUG_StructExpr(struct expr *, const char * element);
|
||||
struct expr * DEBUG_ArrayExpr(struct expr *, struct expr * index);
|
||||
struct expr * DEBUG_CallExpr(const char *, int nargs, ...);
|
||||
struct expr * DEBUG_TypeCastExpr(struct datatype *, struct expr *);
|
||||
extern int DEBUG_ExprValue(const DBG_ADDR *, unsigned int *);
|
||||
extern DBG_ADDR DEBUG_EvalExpr(struct expr *);
|
||||
extern DBG_VALUE DEBUG_EvalExpr(struct expr *);
|
||||
extern int DEBUG_DelDisplay(int displaynum);
|
||||
extern struct expr * DEBUG_CloneExpr(struct expr * exp);
|
||||
extern struct expr * DEBUG_CloneExpr(const struct expr * exp);
|
||||
extern int DEBUG_FreeExpr(struct expr * exp);
|
||||
extern int DEBUG_DisplayExpr(struct expr * exp);
|
||||
|
||||
/* more debugger/break.c */
|
||||
extern int DEBUG_AddBPCondition(int bpnum, struct expr * exp);
|
||||
extern int DEBUG_DisplayExpr(const struct expr * exp);
|
||||
|
||||
/* debugger/display.c */
|
||||
extern int DEBUG_DoDisplay(void);
|
||||
@ -219,15 +238,12 @@ extern int DEBUG_InfoDisplay(void);
|
||||
|
||||
/* debugger/hash.c */
|
||||
extern struct name_hash * DEBUG_AddSymbol( const char *name,
|
||||
const DBG_ADDR *addr,
|
||||
const char * sourcefile,
|
||||
const DBG_VALUE *addr,
|
||||
const char *sourcefile,
|
||||
int flags);
|
||||
extern struct name_hash * DEBUG_AddInvSymbol( const char *name,
|
||||
const DBG_ADDR *addr,
|
||||
const char * sourcefile);
|
||||
extern BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
|
||||
DBG_ADDR *addr, int );
|
||||
extern BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr );
|
||||
DBG_VALUE *addr, int );
|
||||
extern BOOL DEBUG_SetSymbolValue( const char * name, const DBG_VALUE *addr );
|
||||
extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
struct name_hash ** rtn,
|
||||
unsigned int ebp,
|
||||
@ -235,7 +251,7 @@ extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
extern void DEBUG_ReadSymbolTable( const char * filename );
|
||||
extern int DEBUG_LoadEntryPoints( const char * prefix );
|
||||
extern void DEBUG_AddLineNumber( struct name_hash * func, int line_num,
|
||||
unsigned long offset );
|
||||
unsigned long offset );
|
||||
extern struct wine_locals *
|
||||
DEBUG_AddLocal( struct name_hash * func, int regno,
|
||||
int offset,
|
||||
@ -250,14 +266,14 @@ extern int DEBUG_SetSymbolBPOff(struct name_hash * sym, unsigned int len);
|
||||
extern int DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr);
|
||||
extern int DEBUG_cmp_sym(const void * p1, const void * p2);
|
||||
extern BOOL DEBUG_GetLineNumberAddr( struct name_hash *, const int lineno,
|
||||
DBG_ADDR *addr, int bp_flag );
|
||||
DBG_ADDR *addr, int bp_flag );
|
||||
|
||||
extern int DEBUG_SetLocalSymbolType(struct wine_locals * sym,
|
||||
struct datatype * type);
|
||||
BOOL DEBUG_Normalize(struct name_hash * nh );
|
||||
|
||||
/* debugger/info.c */
|
||||
extern void DEBUG_PrintBasic( const DBG_ADDR *addr, 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,
|
||||
int addrlen, int flag );
|
||||
extern void DEBUG_Help(void);
|
||||
@ -282,7 +298,7 @@ extern void DEBUG_WalkWindows(HWND hWnd, int indent);
|
||||
/* debugger/memory.c */
|
||||
extern int DEBUG_ReadMemory( const DBG_ADDR *address );
|
||||
extern void DEBUG_WriteMemory( const DBG_ADDR *address, int value );
|
||||
extern void DEBUG_ExamineMemory( const DBG_ADDR *addr, int count, char format);
|
||||
extern void DEBUG_ExamineMemory( const DBG_VALUE *addr, int count, char format);
|
||||
extern void DEBUG_InvalLinAddr( void* addr );
|
||||
#ifdef __i386__
|
||||
extern void DEBUG_GetCurrentAddress( DBG_ADDR * );
|
||||
@ -311,7 +327,8 @@ extern int DEBUG_GetCurrentFrame(struct name_hash ** name,
|
||||
|
||||
/* debugger/stabs.c */
|
||||
extern int DEBUG_ReadExecutableDbgInfo(void);
|
||||
extern int DEBUG_ParseStabs(char * addr, unsigned int load_offset, unsigned int staboff, int stablen, unsigned int strtaboff, int strtablen);
|
||||
extern int DEBUG_ParseStabs(char * addr, unsigned int load_offset, unsigned int staboff,
|
||||
int stablen, unsigned int strtaboff, int strtablen);
|
||||
|
||||
/* debugger/msc.c */
|
||||
extern int DEBUG_RegisterDebugInfo( HMODULE, const char *);
|
||||
@ -325,8 +342,7 @@ extern int DEBUG_nchar;
|
||||
extern void DEBUG_InitTypes(void);
|
||||
extern struct datatype * DEBUG_NewDataType(enum debug_type xtype,
|
||||
const char * typename);
|
||||
extern unsigned int
|
||||
DEBUG_TypeDerefPointer(const DBG_ADDR * addr, struct datatype ** newtype);
|
||||
extern unsigned int DEBUG_TypeDerefPointer(const DBG_VALUE *value, struct datatype ** newtype);
|
||||
extern int DEBUG_AddStructElement(struct datatype * dt,
|
||||
char * name, struct datatype * type,
|
||||
int offset, int size);
|
||||
@ -334,20 +350,21 @@ extern int DEBUG_SetStructSize(struct datatype * dt, int size);
|
||||
extern int DEBUG_SetPointerType(struct datatype * dt, struct datatype * dt2);
|
||||
extern int DEBUG_SetArrayParams(struct datatype * dt, int min, int max,
|
||||
struct datatype * dt2);
|
||||
extern void DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level );
|
||||
extern unsigned int DEBUG_FindStructElement(DBG_ADDR * addr,
|
||||
extern void DEBUG_Print( const DBG_VALUE *addr, int count, char format, int level );
|
||||
extern unsigned int DEBUG_FindStructElement(DBG_VALUE * addr,
|
||||
const char * ele_name, int * tmpbuf);
|
||||
extern struct datatype * DEBUG_GetPointerType(struct datatype * dt);
|
||||
extern int DEBUG_GetObjectSize(struct datatype * dt);
|
||||
extern unsigned int DEBUG_ArrayIndex(const DBG_ADDR * addr, DBG_ADDR * result, int index);
|
||||
extern unsigned int DEBUG_ArrayIndex(const DBG_VALUE * addr, DBG_VALUE * result, int index);
|
||||
extern struct datatype * DEBUG_FindOrMakePointerType(struct datatype * reftype);
|
||||
extern long long int DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format);
|
||||
extern long long int DEBUG_GetExprValue(const DBG_VALUE * addr, char ** format);
|
||||
extern int DEBUG_SetBitfieldParams(struct datatype * dt, int offset,
|
||||
int nbits, struct datatype * dt2);
|
||||
extern int DEBUG_CopyFieldlist(struct datatype * dt, struct datatype * dt2);
|
||||
extern enum debug_type DEBUG_GetType(struct datatype * dt);
|
||||
extern struct datatype * DEBUG_TypeCast(enum debug_type, const char *);
|
||||
extern int DEBUG_PrintTypeCast(struct datatype *);
|
||||
extern int DEBUG_PrintTypeCast(const struct datatype *);
|
||||
extern int DEBUG_PrintType( const DBG_VALUE* addr );
|
||||
|
||||
/* debugger/source.c */
|
||||
extern void DEBUG_ShowDir(void);
|
||||
@ -355,7 +372,7 @@ extern void DEBUG_AddPath(const char * path);
|
||||
extern void DEBUG_List(struct list_id * line1, struct list_id * line2,
|
||||
int delta);
|
||||
extern void DEBUG_NukePath(void);
|
||||
extern void DEBUG_Disassemble( const DBG_ADDR *, const DBG_ADDR*, int offset );
|
||||
extern void DEBUG_Disassemble( const DBG_VALUE *, const DBG_VALUE*, int offset );
|
||||
|
||||
/* debugger/external.c */
|
||||
extern void DEBUG_ExternalDebugger(void);
|
||||
@ -390,6 +407,10 @@ extern char* DEBUG_XStrDup(const char *str);
|
||||
extern HANDLE dbg_heap;
|
||||
#endif
|
||||
|
||||
#define DEBUG_STATUS_NO_SYMBOL 0x80003000
|
||||
#define DEBUG_STATUS_OFFSET 0x80003000
|
||||
#define DEBUG_STATUS_INTERNAL_ERROR (DEBUG_STATUS_OFFSET+0)
|
||||
#define DEBUG_STATUS_NO_SYMBOL (DEBUG_STATUS_OFFSET+1)
|
||||
#define DEBUG_STATUS_DIV_BY_ZERO (DEBUG_STATUS_OFFSET+2)
|
||||
#define DEBUG_STATUS_BAD_TYPE (DEBUG_STATUS_OFFSET+3)
|
||||
|
||||
#endif /* __WINE_DEBUGGER_H */
|
||||
|
@ -49,7 +49,7 @@ DEBUG_AddDisplay(struct expr * exp, int count, char format)
|
||||
}
|
||||
|
||||
int
|
||||
DEBUG_InfoDisplay()
|
||||
DEBUG_InfoDisplay(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -70,10 +70,10 @@ DEBUG_InfoDisplay()
|
||||
}
|
||||
|
||||
int
|
||||
DEBUG_DoDisplay()
|
||||
DEBUG_DoDisplay(void)
|
||||
{
|
||||
DBG_ADDR addr;
|
||||
int i;
|
||||
DBG_VALUE value;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* First find a slot where we can store this display.
|
||||
@ -82,8 +82,8 @@ DEBUG_DoDisplay()
|
||||
{
|
||||
if( displaypoints[i].exp != NULL )
|
||||
{
|
||||
addr = DEBUG_EvalExpr(displaypoints[i].exp);
|
||||
if( addr.type == NULL )
|
||||
value = DEBUG_EvalExpr(displaypoints[i].exp);
|
||||
if( value.type == NULL )
|
||||
{
|
||||
fprintf(stderr, "Unable to evaluate expression ");
|
||||
DEBUG_DisplayExpr(displaypoints[i].exp);
|
||||
@ -97,13 +97,13 @@ DEBUG_DoDisplay()
|
||||
fprintf(stderr, " = ");
|
||||
if( displaypoints[i].format == 'i' )
|
||||
{
|
||||
DEBUG_ExamineMemory( &addr,
|
||||
displaypoints[i].count,
|
||||
displaypoints[i].format);
|
||||
DEBUG_ExamineMemory( &value,
|
||||
displaypoints[i].count,
|
||||
displaypoints[i].format);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_Print( &addr,
|
||||
DEBUG_Print( &value,
|
||||
displaypoints[i].count,
|
||||
displaypoints[i].format, 0);
|
||||
}
|
||||
|
168
debugger/expr.c
168
debugger/expr.c
@ -9,7 +9,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "winbase.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "task.h"
|
||||
@ -120,7 +119,7 @@ static int next_expr_free = 0;
|
||||
|
||||
static
|
||||
struct expr *
|
||||
DEBUG_GetFreeExpr()
|
||||
DEBUG_GetFreeExpr(void)
|
||||
{
|
||||
struct expr * rtn;
|
||||
|
||||
@ -133,7 +132,7 @@ DEBUG_GetFreeExpr()
|
||||
}
|
||||
|
||||
void
|
||||
DEBUG_FreeExprMem()
|
||||
DEBUG_FreeExprMem(void)
|
||||
{
|
||||
next_expr_free = 0;
|
||||
}
|
||||
@ -291,13 +290,12 @@ DEBUG_CallExpr(const char * funcname, int nargs, ...)
|
||||
return ex;
|
||||
}
|
||||
|
||||
DBG_ADDR
|
||||
DEBUG_EvalExpr(struct expr * exp)
|
||||
DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
|
||||
{
|
||||
DBG_ADDR rtn;
|
||||
DBG_VALUE rtn;
|
||||
int i;
|
||||
DBG_ADDR exp1;
|
||||
DBG_ADDR exp2;
|
||||
DBG_VALUE exp1;
|
||||
DBG_VALUE exp2;
|
||||
unsigned int cexp[5];
|
||||
int scale1;
|
||||
int scale2;
|
||||
@ -306,29 +304,34 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
struct datatype * type2;
|
||||
|
||||
rtn.type = NULL;
|
||||
rtn.off = NULL;
|
||||
rtn.seg = NULL;
|
||||
rtn.addr.off = 0;
|
||||
rtn.addr.seg = 0;
|
||||
|
||||
switch(exp->type)
|
||||
{
|
||||
case EXPR_TYPE_CAST:
|
||||
rtn = DEBUG_EvalExpr(exp->un.cast.expr);
|
||||
rtn.type = exp->un.cast.cast;
|
||||
if (DEBUG_GetType(rtn.type) == DT_POINTER)
|
||||
rtn.cookie = DV_TARGET;
|
||||
break;
|
||||
case EXPR_TYPE_STRING:
|
||||
rtn.type = DEBUG_TypeString;
|
||||
rtn.off = (unsigned int) &exp->un.string.str;
|
||||
rtn.seg = 0;
|
||||
rtn.cookie = DV_HOST;
|
||||
rtn.addr.off = (unsigned int) &exp->un.string.str;
|
||||
rtn.addr.seg = 0;
|
||||
break;
|
||||
case EXPR_TYPE_CONST:
|
||||
rtn.type = DEBUG_TypeIntConst;
|
||||
rtn.off = (unsigned int) &exp->un.constant.value;
|
||||
rtn.seg = 0;
|
||||
rtn.cookie = DV_HOST;
|
||||
rtn.addr.off = (unsigned int) &exp->un.constant.value;
|
||||
rtn.addr.seg = 0;
|
||||
break;
|
||||
case EXPR_TYPE_US_CONST:
|
||||
rtn.type = DEBUG_TypeUSInt;
|
||||
rtn.off = (unsigned int) &exp->un.u_const.value;
|
||||
rtn.seg = 0;
|
||||
rtn.cookie = DV_HOST;
|
||||
rtn.addr.off = (unsigned int) &exp->un.u_const.value;
|
||||
rtn.addr.seg = 0;
|
||||
break;
|
||||
case EXPR_TYPE_SYMBOL:
|
||||
if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
|
||||
@ -340,12 +343,13 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
|
||||
if( exp1.type == NULL )
|
||||
{
|
||||
break;
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
rtn.off = DEBUG_TypeDerefPointer(&exp1, &type1);
|
||||
rtn.cookie = DV_TARGET;
|
||||
rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &type1);
|
||||
if( type1 == NULL )
|
||||
{
|
||||
break;
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
rtn.type = type1;
|
||||
DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
|
||||
@ -355,7 +359,7 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
|
||||
if( exp1.type == NULL )
|
||||
{
|
||||
break;
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
rtn = exp1;
|
||||
DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
|
||||
@ -381,8 +385,7 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
*/
|
||||
if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
|
||||
{
|
||||
fprintf(stderr, "Failed to find symbol\n");
|
||||
break;
|
||||
RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -392,7 +395,7 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
*/
|
||||
int (*fptr)();
|
||||
|
||||
fptr = (int (*)()) rtn.off;
|
||||
fptr = (int (*)()) rtn.addr.off;
|
||||
switch(exp->un.call.nargs)
|
||||
{
|
||||
case 0:
|
||||
@ -422,27 +425,30 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
exp->un.call.result = 0;
|
||||
#endif
|
||||
rtn.type = DEBUG_TypeInt;
|
||||
rtn.off = (unsigned int) &exp->un.call.result;
|
||||
rtn.cookie = DV_HOST;
|
||||
rtn.addr.off = (unsigned int) &exp->un.call.result;
|
||||
|
||||
break;
|
||||
case EXPR_TYPE_REGISTER:
|
||||
rtn.type = DEBUG_TypeIntConst;
|
||||
rtn.cookie = DV_HOST;
|
||||
exp->un.rgister.result = DEBUG_GetRegister(exp->un.rgister.reg);
|
||||
rtn.off = (unsigned int) &exp->un.rgister.result;
|
||||
rtn.addr.off = (unsigned int) &exp->un.rgister.result;
|
||||
#ifdef __i386__
|
||||
if( exp->un.rgister.reg == REG_EIP )
|
||||
rtn.seg = DEBUG_context.SegCs;
|
||||
rtn.addr.seg = DEBUG_context.SegCs;
|
||||
else
|
||||
rtn.seg = DEBUG_context.SegDs;
|
||||
rtn.addr.seg = DEBUG_context.SegDs;
|
||||
#endif
|
||||
DEBUG_FixAddress( &rtn, 0 );
|
||||
DEBUG_FixAddress( &rtn.addr, 0 );
|
||||
break;
|
||||
case EXPR_TYPE_BINOP:
|
||||
exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
|
||||
exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
|
||||
rtn.cookie = DV_HOST;
|
||||
if( exp1.type == NULL || exp2.type == NULL )
|
||||
{
|
||||
break;
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
if( exp1.type == DEBUG_TypeIntConst && exp2.type == DEBUG_TypeIntConst )
|
||||
{
|
||||
@ -452,7 +458,8 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
{
|
||||
rtn.type = DEBUG_TypeInt;
|
||||
}
|
||||
rtn.off = (unsigned int) &exp->un.binop.result;
|
||||
rtn.addr.seg = 0;
|
||||
rtn.addr.off = (unsigned int) &exp->un.binop.result;
|
||||
switch(exp->un.binop.binop_type)
|
||||
{
|
||||
case EXP_OP_ADD:
|
||||
@ -462,7 +469,7 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
scale2 = 1;
|
||||
if( type1 != NULL && type2 != NULL )
|
||||
{
|
||||
break;
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
else if( type1 != NULL )
|
||||
{
|
||||
@ -474,7 +481,6 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
scale1 = DEBUG_GetObjectSize(type2);
|
||||
rtn.type = exp2.type;
|
||||
}
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) * scale1 + scale2 * VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_SUB:
|
||||
@ -487,7 +493,7 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
{
|
||||
if( type1 != type2 )
|
||||
{
|
||||
break;
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
scale3 = DEBUG_GetObjectSize(type1);
|
||||
}
|
||||
@ -502,112 +508,89 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
scale1 = DEBUG_GetObjectSize(type2);
|
||||
rtn.type = exp2.type;
|
||||
}
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
|
||||
break;
|
||||
case EXP_OP_SEG:
|
||||
rtn.seg = VAL(exp1);
|
||||
rtn.cookie = DV_TARGET;
|
||||
rtn.addr.seg = VAL(exp1);
|
||||
exp->un.binop.result = VAL(exp2);
|
||||
#ifdef __i386__
|
||||
DEBUG_FixSegment(&rtn);
|
||||
DEBUG_FixSegment(&rtn.addr);
|
||||
#endif
|
||||
break;
|
||||
case EXP_OP_LOR:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) || VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_LAND:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) && VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_OR:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) | VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_AND:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) & VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_XOR:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_EQ:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) == VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_GT:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) > VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_LT:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) < VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_GE:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_LE:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_NE:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) != VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_SHL:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_SHR:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_MUL:
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) * VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_DIV:
|
||||
if( VAL(exp2) != 0 )
|
||||
if( VAL(exp2) == 0 )
|
||||
{
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) / VAL(exp2));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtn.seg = 0;
|
||||
rtn.type = NULL;
|
||||
rtn.off = 0;
|
||||
RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
|
||||
}
|
||||
exp->un.binop.result = (VAL(exp1) / VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_REM:
|
||||
if( VAL(exp2) != 0 )
|
||||
if( VAL(exp2) == 0 )
|
||||
{
|
||||
rtn.seg = 0;
|
||||
exp->un.binop.result = (VAL(exp1) % VAL(exp2));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtn.seg = 0;
|
||||
rtn.type = NULL;
|
||||
rtn.off = 0;
|
||||
RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
|
||||
}
|
||||
exp->un.binop.result = (VAL(exp1) % VAL(exp2));
|
||||
break;
|
||||
case EXP_OP_ARR:
|
||||
DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
|
||||
break;
|
||||
default:
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EXPR_TYPE_UNOP:
|
||||
exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
|
||||
rtn.cookie = DV_HOST;
|
||||
if( exp1.type == NULL )
|
||||
{
|
||||
break;
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
rtn.off = (unsigned int) &exp->un.unop.result;
|
||||
rtn.addr.seg = 0;
|
||||
rtn.addr.off = (unsigned int) &exp->un.unop.result;
|
||||
if( exp1.type == DEBUG_TypeIntConst )
|
||||
{
|
||||
rtn.type = exp1.type;
|
||||
@ -619,48 +602,57 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||
switch(exp->un.unop.unop_type)
|
||||
{
|
||||
case EXP_OP_NEG:
|
||||
rtn.seg = 0;
|
||||
exp->un.unop.result = -VAL(exp1);
|
||||
break;
|
||||
case EXP_OP_NOT:
|
||||
rtn.seg = 0;
|
||||
exp->un.unop.result = !VAL(exp1);
|
||||
break;
|
||||
case EXP_OP_LNOT:
|
||||
rtn.seg = 0;
|
||||
exp->un.unop.result = ~VAL(exp1);
|
||||
break;
|
||||
case EXP_OP_DEREF:
|
||||
rtn.seg = 0;
|
||||
rtn.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
|
||||
rtn.cookie = exp1.cookie;
|
||||
rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
|
||||
if (!rtn.type)
|
||||
{
|
||||
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||
}
|
||||
break;
|
||||
case EXP_OP_FORCE_DEREF:
|
||||
rtn.seg = exp1.seg;
|
||||
rtn.off = DEBUG_READ_MEM((void*)exp1.off, &rtn.off, sizeof(rtn.off));
|
||||
rtn.cookie = exp1.cookie;
|
||||
rtn.addr.seg = exp1.addr.seg;
|
||||
if (exp1.cookie == DV_TARGET)
|
||||
DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
|
||||
else
|
||||
memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
|
||||
break;
|
||||
case EXP_OP_ADDR:
|
||||
rtn.seg = 0;
|
||||
/* FIXME: even for a 16 bit entity ? */
|
||||
rtn.cookie = DV_TARGET;
|
||||
rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
|
||||
exp->un.unop.result = exp1.off;
|
||||
exp->un.unop.result = exp1.addr.off;
|
||||
break;
|
||||
default:
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unexpected expression.\n");
|
||||
DEBUG_Exit(123);
|
||||
fprintf(stderr,"Unexpected expression (%d).\n", exp->type);
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
DEBUG_DisplayExpr(struct expr * exp)
|
||||
DEBUG_DisplayExpr(const struct expr * exp)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
switch(exp->type)
|
||||
{
|
||||
case EXPR_TYPE_CAST:
|
||||
@ -680,7 +672,7 @@ DEBUG_DisplayExpr(struct expr * exp)
|
||||
fprintf(stderr, "%d", exp->un.u_const.value);
|
||||
break;
|
||||
case EXPR_TYPE_STRING:
|
||||
fprintf(stderr, "\"%s\"", exp->un.string.str);
|
||||
fprintf(stderr, "\"%s\"", exp->un.string.str);
|
||||
break;
|
||||
case EXPR_TYPE_SYMBOL:
|
||||
fprintf(stderr, "%s" , exp->un.symbol.name);
|
||||
@ -803,7 +795,7 @@ DEBUG_DisplayExpr(struct expr * exp)
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unexpected expression.\n");
|
||||
DEBUG_Exit(123);
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -811,7 +803,7 @@ DEBUG_DisplayExpr(struct expr * exp)
|
||||
}
|
||||
|
||||
struct expr *
|
||||
DEBUG_CloneExpr(struct expr * exp)
|
||||
DEBUG_CloneExpr(const struct expr * exp)
|
||||
{
|
||||
int i;
|
||||
struct expr * rtn;
|
||||
@ -860,7 +852,7 @@ DEBUG_CloneExpr(struct expr * exp)
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unexpected expression.\n");
|
||||
DEBUG_Exit(123);
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -913,7 +905,7 @@ DEBUG_FreeExpr(struct expr * exp)
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unexpected expression.\n");
|
||||
DEBUG_Exit(123);
|
||||
RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
286
debugger/hash.c
286
debugger/hash.c
@ -55,14 +55,14 @@ struct name_hash
|
||||
int lines_alloc;
|
||||
WineLineNo * linetab;
|
||||
|
||||
DBG_ADDR addr;
|
||||
DBG_VALUE value;
|
||||
unsigned short flags;
|
||||
unsigned short breakpoint_offset;
|
||||
unsigned int symbol_size;
|
||||
};
|
||||
|
||||
|
||||
static BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr );
|
||||
static BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value );
|
||||
static int sortlist_valid = FALSE;
|
||||
|
||||
static int sorttab_nsym;
|
||||
@ -107,22 +107,22 @@ DEBUG_cmp_sym(const void * p1, const void * p2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( (*name1)->addr.seg > (*name2)->addr.seg )
|
||||
if( (*name1)->value.addr.seg > (*name2)->value.addr.seg )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( (*name1)->addr.seg < (*name2)->addr.seg )
|
||||
if( (*name1)->value.addr.seg < (*name2)->value.addr.seg )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( (*name1)->addr.off > (*name2)->addr.off )
|
||||
if( (*name1)->value.addr.off > (*name2)->value.addr.off )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( (*name1)->addr.off < (*name2)->addr.off )
|
||||
if( (*name1)->value.addr.off < (*name2)->value.addr.off )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -137,7 +137,7 @@ DEBUG_cmp_sym(const void * p1, const void * p2)
|
||||
*/
|
||||
static
|
||||
void
|
||||
DEBUG_ResortSymbols()
|
||||
DEBUG_ResortSymbols(void)
|
||||
{
|
||||
struct name_hash *nh;
|
||||
int nsym = 0;
|
||||
@ -185,7 +185,7 @@ DEBUG_ResortSymbols()
|
||||
* Add a symbol to the table.
|
||||
*/
|
||||
struct name_hash *
|
||||
DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source,
|
||||
DEBUG_AddSymbol( const char * name, const DBG_VALUE *value, const char * source,
|
||||
int flags)
|
||||
{
|
||||
struct name_hash * new;
|
||||
@ -195,16 +195,19 @@ DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source,
|
||||
char * c;
|
||||
int hash;
|
||||
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
||||
hash = name_hash(name);
|
||||
for (nh = name_hash_table[hash]; nh; nh = nh->next)
|
||||
{
|
||||
if( ((nh->flags & SYM_INVALID) != 0) && strcmp(name, nh->name) == 0 )
|
||||
{
|
||||
nh->addr.off = addr->off;
|
||||
nh->addr.seg = addr->seg;
|
||||
if( nh->addr.type == NULL && addr->type != NULL )
|
||||
nh->value.addr = value->addr;
|
||||
|
||||
if( nh->value.type == NULL && value->type != NULL )
|
||||
{
|
||||
nh->addr.type = addr->type;
|
||||
nh->value.type = value->type;
|
||||
nh->value.cookie = value->cookie;
|
||||
}
|
||||
/* it may happen that the same symbol is defined in several compilation
|
||||
* units, but the linker decides to merge it into a single instance.
|
||||
@ -213,10 +216,11 @@ DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source,
|
||||
*/
|
||||
if ((flags & SYM_INVALID) == 0)
|
||||
nh->flags &= ~SYM_INVALID;
|
||||
|
||||
return nh;
|
||||
}
|
||||
if (nh->addr.seg == addr->seg &&
|
||||
nh->addr.off == addr->off &&
|
||||
if (nh->value.addr.seg == value->addr.seg &&
|
||||
nh->value.addr.off == value->addr.off &&
|
||||
strcmp(name, nh->name) == 0 )
|
||||
{
|
||||
return nh;
|
||||
@ -229,7 +233,7 @@ DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source,
|
||||
*/
|
||||
|
||||
new = (struct name_hash *) DBG_alloc(sizeof(struct name_hash));
|
||||
new->addr = *addr;
|
||||
new->value = *value;
|
||||
new->name = DBG_strdup(name);
|
||||
|
||||
if( source != NULL )
|
||||
@ -334,7 +338,7 @@ BOOL DEBUG_Normalize(struct name_hash * nh )
|
||||
* Get the address of a named symbol.
|
||||
*/
|
||||
BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
|
||||
DBG_ADDR *addr, int bp_flag )
|
||||
DBG_VALUE *value, int bp_flag )
|
||||
{
|
||||
char buffer[256];
|
||||
struct name_hash *nh;
|
||||
@ -371,10 +375,12 @@ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
|
||||
*/
|
||||
if (!nh)
|
||||
{
|
||||
return DEBUG_GetStackSymbolValue(name, addr);
|
||||
return DEBUG_GetStackSymbolValue(name, value);
|
||||
}
|
||||
|
||||
return DEBUG_GetLineNumberAddr( nh, lineno, addr, bp_flag );
|
||||
value->type = nh->value.type;
|
||||
value->cookie = nh->value.cookie;
|
||||
return DEBUG_GetLineNumberAddr( nh, lineno, &value->addr, bp_flag );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@ -383,13 +389,13 @@ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
|
||||
* Get the address of a named symbol.
|
||||
*/
|
||||
BOOL DEBUG_GetLineNumberAddr( struct name_hash * nh, const int lineno,
|
||||
DBG_ADDR *addr, int bp_flag )
|
||||
DBG_ADDR *addr, int bp_flag )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( lineno == -1 )
|
||||
{
|
||||
*addr = nh->addr;
|
||||
*addr = nh->value.addr;
|
||||
if( bp_flag )
|
||||
{
|
||||
addr->off += nh->breakpoint_offset;
|
||||
@ -430,11 +436,13 @@ BOOL DEBUG_GetLineNumberAddr( struct name_hash * nh, const int lineno,
|
||||
*
|
||||
* Set the address of a named symbol.
|
||||
*/
|
||||
BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr )
|
||||
BOOL DEBUG_SetSymbolValue( const char * name, const DBG_VALUE *value )
|
||||
{
|
||||
char buffer[256];
|
||||
struct name_hash *nh;
|
||||
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
||||
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
|
||||
if (!strcmp(nh->name, name)) break;
|
||||
|
||||
@ -447,9 +455,9 @@ BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr )
|
||||
}
|
||||
|
||||
if (!nh) return FALSE;
|
||||
nh->addr = *addr;
|
||||
nh->flags &= SYM_INVALID;
|
||||
DEBUG_FixAddress( &nh->addr, DEBUG_context.SegDs );
|
||||
nh->value = *value;
|
||||
nh->flags &= ~SYM_INVALID;
|
||||
DEBUG_FixAddress( &nh->value.addr, DEBUG_context.SegDs );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -510,15 +518,15 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
*/
|
||||
low = 0;
|
||||
high = sorttab_nsym;
|
||||
if( addr_sorttab[0]->addr.seg > addr->seg
|
||||
|| ( addr_sorttab[0]->addr.seg == addr->seg
|
||||
&& addr_sorttab[0]->addr.off > addr->off) )
|
||||
if( addr_sorttab[0]->value.addr.seg > addr->seg
|
||||
|| ( addr_sorttab[0]->value.addr.seg == addr->seg
|
||||
&& addr_sorttab[0]->value.addr.off > addr->off) )
|
||||
{
|
||||
nearest = NULL;
|
||||
}
|
||||
else if( addr_sorttab[high - 1]->addr.seg < addr->seg
|
||||
|| ( addr_sorttab[high - 1]->addr.seg == addr->seg
|
||||
&& addr_sorttab[high - 1]->addr.off < addr->off) )
|
||||
else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
|
||||
|| ( addr_sorttab[high - 1]->value.addr.seg == addr->seg
|
||||
&& addr_sorttab[high - 1]->value.addr.off < addr->off) )
|
||||
{
|
||||
nearest = addr_sorttab[high - 1];
|
||||
}
|
||||
@ -536,10 +544,10 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
*/
|
||||
if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
|
||||
{
|
||||
if( (addr_sorttab[mid - 1]->addr.seg ==
|
||||
addr_sorttab[mid]->addr.seg)
|
||||
&& (addr_sorttab[mid - 1]->addr.off ==
|
||||
addr_sorttab[mid]->addr.off)
|
||||
if( (addr_sorttab[mid - 1]->value.addr.seg ==
|
||||
addr_sorttab[mid]->value.addr.seg)
|
||||
&& (addr_sorttab[mid - 1]->value.addr.off ==
|
||||
addr_sorttab[mid]->value.addr.off)
|
||||
&& (addr_sorttab[mid - 1]->linetab != NULL) )
|
||||
{
|
||||
mid--;
|
||||
@ -549,10 +557,10 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
if( (mid < sorttab_nsym - 1)
|
||||
&& (addr_sorttab[mid]->linetab == NULL) )
|
||||
{
|
||||
if( (addr_sorttab[mid + 1]->addr.seg ==
|
||||
addr_sorttab[mid]->addr.seg)
|
||||
&& (addr_sorttab[mid + 1]->addr.off ==
|
||||
addr_sorttab[mid]->addr.off)
|
||||
if( (addr_sorttab[mid + 1]->value.addr.seg ==
|
||||
addr_sorttab[mid]->value.addr.seg)
|
||||
&& (addr_sorttab[mid + 1]->value.addr.off ==
|
||||
addr_sorttab[mid]->value.addr.off)
|
||||
&& (addr_sorttab[mid + 1]->linetab != NULL) )
|
||||
{
|
||||
mid++;
|
||||
@ -561,17 +569,17 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
nearest = addr_sorttab[mid];
|
||||
#if 0
|
||||
fprintf(stderr, "Found %x:%x when looking for %x:%x %x %s\n",
|
||||
addr_sorttab[mid ]->addr.seg,
|
||||
addr_sorttab[mid ]->addr.off,
|
||||
addr_sorttab[mid ]->value.addr.seg,
|
||||
addr_sorttab[mid ]->value.addr.off,
|
||||
addr->seg, addr->off,
|
||||
addr_sorttab[mid ]->linetab,
|
||||
addr_sorttab[mid ]->name);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if( (addr_sorttab[mid]->addr.seg < addr->seg)
|
||||
|| ( addr_sorttab[mid]->addr.seg == addr->seg
|
||||
&& addr_sorttab[mid]->addr.off <= addr->off) )
|
||||
if( (addr_sorttab[mid]->value.addr.seg < addr->seg)
|
||||
|| ( addr_sorttab[mid]->value.addr.seg == addr->seg
|
||||
&& addr_sorttab[mid]->value.addr.off <= addr->off) )
|
||||
{
|
||||
low = mid;
|
||||
}
|
||||
@ -649,7 +657,7 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
}
|
||||
|
||||
if( (nearest->sourcefile != NULL) && (flag == TRUE)
|
||||
&& (addr->off - nearest->addr.off < 0x100000) )
|
||||
&& (addr->off - nearest->value.addr.off < 0x100000) )
|
||||
{
|
||||
|
||||
/*
|
||||
@ -685,24 +693,24 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
if (!sourcefile) sourcefile = nearest->sourcefile;
|
||||
else sourcefile++;
|
||||
|
||||
if (addr->off == nearest->addr.off)
|
||||
if (addr->off == nearest->value.addr.off)
|
||||
sprintf( name_buffer, "%s%s [%s%s]", nearest->name,
|
||||
arglist, sourcefile, lineinfo);
|
||||
else
|
||||
sprintf( name_buffer, "%s+0x%lx%s [%s%s]", nearest->name,
|
||||
addr->off - nearest->addr.off,
|
||||
addr->off - nearest->value.addr.off,
|
||||
arglist, sourcefile, lineinfo );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr->off == nearest->addr.off)
|
||||
if (addr->off == nearest->value.addr.off)
|
||||
sprintf( name_buffer, "%s%s", nearest->name, arglist);
|
||||
else {
|
||||
if (addr->seg && (nearest->addr.seg!=addr->seg))
|
||||
if (addr->seg && (nearest->value.addr.seg!=addr->seg))
|
||||
return NULL;
|
||||
else
|
||||
sprintf( name_buffer, "%s+0x%lx%s", nearest->name,
|
||||
addr->off - nearest->addr.off, arglist);
|
||||
addr->off - nearest->value.addr.off, arglist);
|
||||
}
|
||||
}
|
||||
return name_buffer;
|
||||
@ -717,7 +725,7 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
void DEBUG_ReadSymbolTable( const char * filename )
|
||||
{
|
||||
FILE * symbolfile;
|
||||
DBG_ADDR addr = { 0, 0 };
|
||||
DBG_VALUE value;
|
||||
int nargs;
|
||||
char type;
|
||||
char * cpnt;
|
||||
@ -732,6 +740,11 @@ void DEBUG_ReadSymbolTable( const char * filename )
|
||||
|
||||
fprintf( stderr, "Reading symbols from file %s\n", filename );
|
||||
|
||||
value.type = NULL;
|
||||
value.addr.seg = 0;
|
||||
value.addr.off = 0;
|
||||
value.cookie = DV_TARGET;
|
||||
|
||||
while (1)
|
||||
{
|
||||
fgets( buffer, sizeof(buffer), symbolfile );
|
||||
@ -751,8 +764,8 @@ void DEBUG_ReadSymbolTable( const char * filename )
|
||||
}
|
||||
if (!(*cpnt) || *cpnt == '\n') continue;
|
||||
|
||||
nargs = sscanf(buffer, "%lx %c %s", &addr.off, &type, name);
|
||||
DEBUG_AddSymbol( name, &addr, NULL, SYM_WINE );
|
||||
nargs = sscanf(buffer, "%lx %c %s", &value.addr.off, &type, name);
|
||||
DEBUG_AddSymbol( name, &value, NULL, SYM_WINE );
|
||||
}
|
||||
fclose(symbolfile);
|
||||
}
|
||||
@ -766,23 +779,27 @@ void DEBUG_ReadSymbolTable( const char * filename )
|
||||
static void DEBUG_LoadEntryPoints16( HMODULE16 hModule, NE_MODULE *pModule,
|
||||
const char *name )
|
||||
{
|
||||
DBG_ADDR addr;
|
||||
char buffer[256];
|
||||
FARPROC16 address;
|
||||
DBG_VALUE value;
|
||||
char buffer[256];
|
||||
FARPROC16 address;
|
||||
unsigned char *cpnt = (unsigned char *)pModule + pModule->name_table;
|
||||
|
||||
value.type = NULL;
|
||||
value.cookie = DV_TARGET;
|
||||
value.addr.seg = 0;
|
||||
value.addr.off = 0;
|
||||
|
||||
/* First search the resident names */
|
||||
|
||||
unsigned char *cpnt = (unsigned char *)pModule + pModule->name_table;
|
||||
while (*cpnt)
|
||||
{
|
||||
cpnt += *cpnt + 1 + sizeof(WORD);
|
||||
sprintf( buffer, "%s.%.*s", name, *cpnt, cpnt + 1 );
|
||||
if ((address = NE_GetEntryPoint(hModule, *(WORD *)(cpnt + *cpnt + 1))))
|
||||
{
|
||||
addr.seg = HIWORD(address);
|
||||
addr.off = LOWORD(address);
|
||||
addr.type = NULL;
|
||||
DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
value.addr.seg = HIWORD(address);
|
||||
value.addr.off = LOWORD(address);
|
||||
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
}
|
||||
}
|
||||
|
||||
@ -796,10 +813,9 @@ static void DEBUG_LoadEntryPoints16( HMODULE16 hModule, NE_MODULE *pModule,
|
||||
sprintf( buffer, "%s.%.*s", name, *cpnt, cpnt + 1 );
|
||||
if ((address = NE_GetEntryPoint(hModule, *(WORD *)(cpnt + *cpnt + 1))))
|
||||
{
|
||||
addr.seg = HIWORD(address);
|
||||
addr.off = LOWORD(address);
|
||||
addr.type = NULL;
|
||||
DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
value.addr.seg = HIWORD(address);
|
||||
value.addr.off = LOWORD(address);
|
||||
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -814,7 +830,7 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name )
|
||||
{
|
||||
#define RVA(x) (hModule+(DWORD)(x))
|
||||
|
||||
DBG_ADDR addr;
|
||||
DBG_VALUE value;
|
||||
char buffer[256];
|
||||
int i, j;
|
||||
IMAGE_SECTION_HEADER *pe_seg;
|
||||
@ -823,20 +839,22 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name )
|
||||
WORD *ordinals;
|
||||
void **functions;
|
||||
const char **names;
|
||||
|
||||
addr.seg = 0;
|
||||
addr.type = NULL;
|
||||
|
||||
value.type = NULL;
|
||||
value.cookie = DV_TARGET;
|
||||
value.addr.seg = 0;
|
||||
value.addr.off = 0;
|
||||
|
||||
/* Add start of DLL */
|
||||
|
||||
addr.off = hModule;
|
||||
DEBUG_AddSymbol( name, &addr, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
value.addr.off = hModule;
|
||||
DEBUG_AddSymbol( name, &value, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
|
||||
/* Add entry point */
|
||||
|
||||
sprintf( buffer, "%s.EntryPoint", name );
|
||||
addr.off = (DWORD)RVA_PTR( hModule, OptionalHeader.AddressOfEntryPoint );
|
||||
DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
value.addr.off = (DWORD)RVA_PTR( hModule, OptionalHeader.AddressOfEntryPoint );
|
||||
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
|
||||
/* Add start of sections */
|
||||
|
||||
@ -844,8 +862,8 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name )
|
||||
for (i = 0; i < PE_HEADER(hModule)->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
sprintf( buffer, "%s.%s", name, pe_seg->Name );
|
||||
addr.off = RVA(pe_seg->VirtualAddress );
|
||||
DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
value.addr.off = RVA(pe_seg->VirtualAddress );
|
||||
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
pe_seg++;
|
||||
}
|
||||
|
||||
@ -864,8 +882,8 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name )
|
||||
{
|
||||
if (!names[i]) continue;
|
||||
sprintf( buffer, "%s.%s", name, (char *)RVA(names[i]) );
|
||||
addr.off = RVA( functions[ordinals[i]] );
|
||||
DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
value.addr.off = RVA( functions[ordinals[i]] );
|
||||
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
}
|
||||
|
||||
for (i = 0; i < exports->NumberOfFunctions; i++)
|
||||
@ -876,8 +894,8 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name )
|
||||
if ((ordinals[j] == i) && names[j]) break;
|
||||
if (j < exports->NumberOfNames) continue;
|
||||
sprintf( buffer, "%s.%ld", name, i + exports->Base );
|
||||
addr.off = (DWORD)RVA( functions[i] );
|
||||
DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
value.addr.off = (DWORD)RVA( functions[i] );
|
||||
DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC );
|
||||
}
|
||||
}
|
||||
DEBUG_RegisterDebugInfo(hModule, name);
|
||||
@ -969,7 +987,8 @@ int DEBUG_LoadEntryPoints(const char* pfx)
|
||||
BOOL ok;
|
||||
WINE_MODREF*wm;
|
||||
DBG_LEPData lep;
|
||||
|
||||
PDB* current = PROCESS_Current();
|
||||
|
||||
lep.first = 0;
|
||||
lep.pfx = pfx;
|
||||
|
||||
@ -983,7 +1002,7 @@ int DEBUG_LoadEntryPoints(const char* pfx)
|
||||
DEBUG_LoadEntryPoints16( entry.hModule, pModule, entry.szModule );
|
||||
}
|
||||
|
||||
for (wm=PROCESS_Current()->modref_list;wm;wm=wm->next)
|
||||
for (wm = current->modref_list; wm; wm=wm->next)
|
||||
{
|
||||
if ((wm->flags & WINE_MODREF_INTERNAL))
|
||||
{
|
||||
@ -992,7 +1011,7 @@ int DEBUG_LoadEntryPoints(const char* pfx)
|
||||
}
|
||||
}
|
||||
if (lep.first) fprintf( stderr, " $");
|
||||
for (wm=PROCESS_Current()->modref_list;wm;wm=wm->next)
|
||||
for (wm = current->modref_list; wm; wm=wm->next)
|
||||
{
|
||||
if (!(wm->flags & WINE_MODREF_INTERNAL))
|
||||
{
|
||||
@ -1022,9 +1041,8 @@ DEBUG_AddLineNumber( struct name_hash * func, int line_num,
|
||||
}
|
||||
|
||||
func->linetab[func->n_lines].line_number = line_num;
|
||||
func->linetab[func->n_lines].pc_offset.seg = func->addr.seg;
|
||||
func->linetab[func->n_lines].pc_offset.off = func->addr.off + offset;
|
||||
func->linetab[func->n_lines].pc_offset.type = NULL;
|
||||
func->linetab[func->n_lines].pc_offset.seg = func->value.addr.seg;
|
||||
func->linetab[func->n_lines].pc_offset.off = func->value.addr.off + offset;
|
||||
func->n_lines++;
|
||||
}
|
||||
|
||||
@ -1060,7 +1078,7 @@ DEBUG_AddLocal( struct name_hash * func, int regno,
|
||||
}
|
||||
|
||||
void
|
||||
DEBUG_DumpHashInfo()
|
||||
DEBUG_DumpHashInfo(void)
|
||||
{
|
||||
int i;
|
||||
int depth;
|
||||
@ -1102,15 +1120,15 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
|
||||
*/
|
||||
low = 0;
|
||||
high = sorttab_nsym;
|
||||
if( addr_sorttab[0]->addr.seg > addr->seg
|
||||
|| ( addr_sorttab[0]->addr.seg == addr->seg
|
||||
&& addr_sorttab[0]->addr.off > addr->off) )
|
||||
if( addr_sorttab[0]->value.addr.seg > addr->seg
|
||||
|| ( addr_sorttab[0]->value.addr.seg == addr->seg
|
||||
&& addr_sorttab[0]->value.addr.off > addr->off) )
|
||||
{
|
||||
nearest = NULL;
|
||||
}
|
||||
else if( addr_sorttab[high - 1]->addr.seg < addr->seg
|
||||
|| ( addr_sorttab[high - 1]->addr.seg == addr->seg
|
||||
&& addr_sorttab[high - 1]->addr.off < addr->off) )
|
||||
else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg
|
||||
|| ( addr_sorttab[high - 1]->value.addr.seg == addr->seg
|
||||
&& addr_sorttab[high - 1]->value.addr.off < addr->off) )
|
||||
{
|
||||
nearest = addr_sorttab[high - 1];
|
||||
}
|
||||
@ -1128,10 +1146,10 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
|
||||
*/
|
||||
if( mid > 0 && addr_sorttab[mid]->linetab == NULL )
|
||||
{
|
||||
if( (addr_sorttab[mid - 1]->addr.seg ==
|
||||
addr_sorttab[mid]->addr.seg)
|
||||
&& (addr_sorttab[mid - 1]->addr.off ==
|
||||
addr_sorttab[mid]->addr.off)
|
||||
if( (addr_sorttab[mid - 1]->value.addr.seg ==
|
||||
addr_sorttab[mid]->value.addr.seg)
|
||||
&& (addr_sorttab[mid - 1]->value.addr.off ==
|
||||
addr_sorttab[mid]->value.addr.off)
|
||||
&& (addr_sorttab[mid - 1]->linetab != NULL) )
|
||||
{
|
||||
mid--;
|
||||
@ -1141,10 +1159,10 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
|
||||
if( (mid < sorttab_nsym - 1)
|
||||
&& (addr_sorttab[mid]->linetab == NULL) )
|
||||
{
|
||||
if( (addr_sorttab[mid + 1]->addr.seg ==
|
||||
addr_sorttab[mid]->addr.seg)
|
||||
&& (addr_sorttab[mid + 1]->addr.off ==
|
||||
addr_sorttab[mid]->addr.off)
|
||||
if( (addr_sorttab[mid + 1]->value.addr.seg ==
|
||||
addr_sorttab[mid]->value.addr.seg)
|
||||
&& (addr_sorttab[mid + 1]->value.addr.off ==
|
||||
addr_sorttab[mid]->value.addr.off)
|
||||
&& (addr_sorttab[mid + 1]->linetab != NULL) )
|
||||
{
|
||||
mid++;
|
||||
@ -1153,17 +1171,17 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
|
||||
nearest = addr_sorttab[mid];
|
||||
#if 0
|
||||
fprintf(stderr, "Found %x:%x when looking for %x:%x %x %s\n",
|
||||
addr_sorttab[mid ]->addr.seg,
|
||||
addr_sorttab[mid ]->addr.off,
|
||||
addr_sorttab[mid ]->value.addr.seg,
|
||||
addr_sorttab[mid ]->value.addr.off,
|
||||
addr->seg, addr->off,
|
||||
addr_sorttab[mid ]->linetab,
|
||||
addr_sorttab[mid ]->name);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if( (addr_sorttab[mid]->addr.seg < addr->seg)
|
||||
|| ( addr_sorttab[mid]->addr.seg == addr->seg
|
||||
&& addr_sorttab[mid]->addr.off <= addr->off) )
|
||||
if( (addr_sorttab[mid]->value.addr.seg < addr->seg)
|
||||
|| ( addr_sorttab[mid]->value.addr.seg == addr->seg
|
||||
&& addr_sorttab[mid]->value.addr.off <= addr->off) )
|
||||
{
|
||||
low = mid;
|
||||
}
|
||||
@ -1206,13 +1224,13 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr)
|
||||
* until it gets past the function prologue. We only do this if there
|
||||
* is more than one line number for the function, of course.
|
||||
*/
|
||||
if( nearest->addr.off == addr->off && nearest->n_lines > 1 )
|
||||
if( nearest->value.addr.off == addr->off && nearest->n_lines > 1 )
|
||||
{
|
||||
return NOT_ON_LINENUMBER;
|
||||
}
|
||||
|
||||
if( (nearest->sourcefile != NULL)
|
||||
&& (addr->off - nearest->addr.off < 0x100000) )
|
||||
&& (addr->off - nearest->value.addr.off < 0x100000) )
|
||||
{
|
||||
low = 0;
|
||||
high = nearest->n_lines;
|
||||
@ -1327,7 +1345,7 @@ DEBUG_GetFuncInfo( struct list_id * ret, const char * filename,
|
||||
* Get the address of a named symbol from the current stack frame.
|
||||
*/
|
||||
static
|
||||
BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr )
|
||||
BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value )
|
||||
{
|
||||
struct name_hash * curr_func;
|
||||
unsigned int ebp;
|
||||
@ -1346,14 +1364,14 @@ BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr )
|
||||
* comes up with RBRAC/LBRAC stabs in particular.
|
||||
*/
|
||||
if( (curr_func->local_vars[i].pc_start != 0)
|
||||
&& ((eip - curr_func->addr.off)
|
||||
&& ((eip - curr_func->value.addr.off)
|
||||
< curr_func->local_vars[i].pc_start) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( (curr_func->local_vars[i].pc_end != 0)
|
||||
&& ((eip - curr_func->addr.off)
|
||||
&& ((eip - curr_func->value.addr.off)
|
||||
> curr_func->local_vars[i].pc_end) )
|
||||
{
|
||||
continue;
|
||||
@ -1364,44 +1382,32 @@ BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr )
|
||||
/*
|
||||
* OK, we found it. Now figure out what to do with this.
|
||||
*/
|
||||
/* FIXME: what if regno == 0 ($eax) */
|
||||
if( curr_func->local_vars[i].regno != 0 )
|
||||
{
|
||||
#if 0
|
||||
/* FIXME: NEWDBG NIY */
|
||||
/* this is a hack: addr points to the current processor context
|
||||
* (as defined while entering the debugger), and uses a pointer
|
||||
* to main memory (thus sharing the process address space *AND*
|
||||
* the debugger address space, which is not good with address
|
||||
* space separation in place)
|
||||
*/
|
||||
/*
|
||||
* Register variable. Point to DEBUG_context field.
|
||||
*/
|
||||
addr->seg = 0;
|
||||
addr->off = ((DWORD)DEBUG_context) + reg_ofs[curr_func->local_vars[i].regno];
|
||||
addr->type = curr_func->local_vars[i].type;
|
||||
#else
|
||||
fprintf(stderr, "No longer supported: value of register variable\n");
|
||||
addr->seg = 0;
|
||||
addr->off = 0;
|
||||
addr->type = NULL;
|
||||
#endif
|
||||
return TRUE;
|
||||
value->addr.off = ((DWORD)&DEBUG_context) +
|
||||
reg_ofs[curr_func->local_vars[i].regno - 1];
|
||||
value->cookie = DV_HOST;
|
||||
}
|
||||
|
||||
addr->seg = 0;
|
||||
addr->off = ebp + curr_func->local_vars[i].offset;
|
||||
addr->type = curr_func->local_vars[i].type;
|
||||
else
|
||||
{
|
||||
value->addr.off = ebp + curr_func->local_vars[i].offset;
|
||||
value->cookie = DV_TARGET;
|
||||
}
|
||||
value->addr.seg = 0;
|
||||
value->type = curr_func->local_vars[i].type;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
DEBUG_InfoLocals()
|
||||
DEBUG_InfoLocals(void)
|
||||
{
|
||||
struct name_hash * curr_func;
|
||||
unsigned int ebp;
|
||||
@ -1422,26 +1428,26 @@ DEBUG_InfoLocals()
|
||||
* comes up with RBRAC/LBRAC stabs in particular.
|
||||
*/
|
||||
if( (curr_func->local_vars[i].pc_start != 0)
|
||||
&& ((eip - curr_func->addr.off)
|
||||
&& ((eip - curr_func->value.addr.off)
|
||||
< curr_func->local_vars[i].pc_start) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( (curr_func->local_vars[i].pc_end != 0)
|
||||
&& ((eip - curr_func->addr.off)
|
||||
&& ((eip - curr_func->value.addr.off)
|
||||
> curr_func->local_vars[i].pc_end) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( curr_func->local_vars[i].offset == 0 )
|
||||
if( curr_func->local_vars[i].regno != 0 )
|
||||
{
|
||||
ptr = (unsigned int *) (((DWORD)&DEBUG_context)
|
||||
+ reg_ofs[curr_func->local_vars[i].regno]);
|
||||
ptr = (unsigned int *)(((DWORD)&DEBUG_context)
|
||||
+ reg_ofs[curr_func->local_vars[i].regno - 1]);
|
||||
fprintf(stderr, "%s:%s (optimized into register $%s) == 0x%8.8x\n",
|
||||
curr_func->name, curr_func->local_vars[i].name,
|
||||
reg_name[curr_func->local_vars[i].regno],
|
||||
reg_name[curr_func->local_vars[i].regno - 1],
|
||||
*ptr);
|
||||
}
|
||||
else
|
||||
@ -1476,7 +1482,7 @@ int
|
||||
DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr)
|
||||
{
|
||||
|
||||
*addr = sym->addr;
|
||||
*addr = sym->value.addr;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
@ -20,40 +21,41 @@
|
||||
*
|
||||
* Implementation of the 'print' command.
|
||||
*/
|
||||
void DEBUG_PrintBasic( const DBG_ADDR *addr, int count, char format )
|
||||
void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format )
|
||||
{
|
||||
char * default_format;
|
||||
long long int value;
|
||||
long long int res;
|
||||
|
||||
if( addr->type == NULL )
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
if( value->type == NULL )
|
||||
{
|
||||
fprintf(stderr, "Unable to evaluate expression\n");
|
||||
return;
|
||||
}
|
||||
|
||||
default_format = NULL;
|
||||
value = DEBUG_GetExprValue(addr, &default_format);
|
||||
res = DEBUG_GetExprValue(value, &default_format);
|
||||
|
||||
switch(format)
|
||||
{
|
||||
case 'x':
|
||||
if (addr->seg)
|
||||
if (value->addr.seg)
|
||||
{
|
||||
DEBUG_nchar += fprintf( stderr, "0x%04lx", (long unsigned int) value );
|
||||
DEBUG_nchar += fprintf( stderr, "0x%04lx", (long unsigned int) res );
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_nchar += fprintf( stderr, "0x%08lx", (long unsigned int) value );
|
||||
DEBUG_nchar += fprintf( stderr, "0x%08lx", (long unsigned int) res );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
DEBUG_nchar += fprintf( stderr, "%ld\n", (long int) value );
|
||||
DEBUG_nchar += fprintf( stderr, "%ld\n", (long int) res );
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
DEBUG_nchar += fprintf( stderr, "%d = '%c'",
|
||||
(char)(value & 0xff), (char)(value & 0xff) );
|
||||
(char)(res & 0xff), (char)(res & 0xff) );
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
@ -64,7 +66,51 @@ void DEBUG_PrintBasic( const DBG_ADDR *addr, int count, char format )
|
||||
case 0:
|
||||
if( default_format != NULL )
|
||||
{
|
||||
DEBUG_nchar += fprintf( stderr, default_format, value );
|
||||
if (strstr(default_format, "%S") == NULL)
|
||||
{
|
||||
DEBUG_nchar += fprintf( stderr, default_format, res );
|
||||
}
|
||||
else
|
||||
{
|
||||
char* ptr;
|
||||
int state = 0;
|
||||
|
||||
/* FIXME: simplistic implementation for default_format being
|
||||
* foo%Sbar => will print foo, then string then bar
|
||||
*/
|
||||
for (ptr = default_format; *ptr; ptr++)
|
||||
{
|
||||
fprintf(stderr, "[%c]", *ptr);
|
||||
|
||||
if (*ptr == '%') state++;
|
||||
else if (state == 1)
|
||||
{
|
||||
if (*ptr == 'S')
|
||||
{
|
||||
char ch;
|
||||
char* str = (char*)(long)res;
|
||||
|
||||
for (; DEBUG_READ_MEM(str, &ch, 1) && ch; str++) {
|
||||
fputc(ch, stderr);
|
||||
DEBUG_nchar++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* shouldn't happen */
|
||||
fputc('%', stderr);
|
||||
fputc(*ptr, stderr);
|
||||
DEBUG_nchar += 2;
|
||||
}
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fputc(*ptr, stderr);
|
||||
DEBUG_nchar++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -144,7 +190,7 @@ void DEBUG_Help(void)
|
||||
" display <expr> undisplay <disnum>",
|
||||
" delete display <disnum> debugmsg <class>[-+]<type>\n",
|
||||
" mode [16,32] walk [wnd,class,queue,module,",
|
||||
" process,modref <pid>]",
|
||||
" whatis process,modref <pid>]",
|
||||
" info (see 'help info' for options)\n",
|
||||
|
||||
"The 'x' command accepts repeat counts and formats (including 'i') in the",
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright 1993 Eric Youngdale
|
||||
* Copyright 1995 Alexandre Julliard
|
||||
* Copyright 2000 Eric Pouech
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -103,7 +104,6 @@ BOOL DEBUG_IsSelectorSystem(WORD sel)
|
||||
|
||||
void DEBUG_GetCurrentAddress( DBG_ADDR *addr )
|
||||
{
|
||||
addr->type = NULL;
|
||||
#ifdef __i386__
|
||||
addr->seg = DEBUG_context.SegCs;
|
||||
|
||||
@ -120,7 +120,6 @@ void DEBUG_InvalLinAddr( void* addr )
|
||||
{
|
||||
DBG_ADDR address;
|
||||
|
||||
address.type = NULL;
|
||||
address.seg = 0;
|
||||
address.off = (unsigned long)addr;
|
||||
|
||||
@ -169,14 +168,16 @@ void DEBUG_WriteMemory( const DBG_ADDR *address, int value )
|
||||
*
|
||||
* Implementation of the 'x' command.
|
||||
*/
|
||||
void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
|
||||
void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format )
|
||||
{
|
||||
DBG_ADDR addr = * address;
|
||||
DBG_VALUE value = *_value;
|
||||
int i;
|
||||
unsigned char * pnt;
|
||||
struct datatype * testtype;
|
||||
|
||||
DEBUG_FixAddress( &addr,
|
||||
assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
|
||||
|
||||
DEBUG_FixAddress( &value.addr,
|
||||
(format == 'i') ?
|
||||
DEBUG_context.SegCs :
|
||||
DEBUG_context.SegDs );
|
||||
@ -186,31 +187,31 @@ void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
|
||||
* reading. We will use the same segment as what we have already,
|
||||
* and hope that this is a sensible thing to do.
|
||||
*/
|
||||
if( addr.type != NULL )
|
||||
if( value.type != NULL )
|
||||
{
|
||||
if( addr.type == DEBUG_TypeIntConst )
|
||||
if( value.type == DEBUG_TypeIntConst )
|
||||
{
|
||||
/*
|
||||
* We know that we have the actual offset stored somewhere
|
||||
* else in 32-bit space. Grab it, and we
|
||||
* should be all set.
|
||||
*/
|
||||
unsigned int seg2 = addr.seg;
|
||||
addr.seg = 0;
|
||||
addr.off = DEBUG_GetExprValue(&addr, NULL);
|
||||
addr.seg = seg2;
|
||||
unsigned int seg2 = value.addr.seg;
|
||||
value.addr.seg = 0;
|
||||
value.addr.off = DEBUG_GetExprValue(&value, NULL);
|
||||
value.addr.seg = seg2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG_TypeDerefPointer(&addr, &testtype) == 0)
|
||||
if (DEBUG_TypeDerefPointer(&value, &testtype) == 0)
|
||||
return;
|
||||
if( testtype != NULL || addr.type == DEBUG_TypeIntConst )
|
||||
if( testtype != NULL || value.type == DEBUG_TypeIntConst )
|
||||
{
|
||||
addr.off = DEBUG_GetExprValue(&addr, NULL);
|
||||
value.addr.off = DEBUG_GetExprValue(&value, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!addr.seg && !addr.off)
|
||||
else if (!value.addr.seg && !value.addr.off)
|
||||
{
|
||||
fprintf(stderr,"Invalid expression\n");
|
||||
return;
|
||||
@ -218,11 +219,11 @@ void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
|
||||
|
||||
if (format != 'i' && count > 1)
|
||||
{
|
||||
DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, FALSE );
|
||||
DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, FALSE );
|
||||
fprintf(stderr,": ");
|
||||
}
|
||||
|
||||
pnt = (void*)DEBUG_ToLinear( &addr );
|
||||
pnt = (void*)DEBUG_ToLinear( &value.addr );
|
||||
|
||||
switch(format)
|
||||
{
|
||||
@ -256,9 +257,9 @@ void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
|
||||
case 'i':
|
||||
while (count--)
|
||||
{
|
||||
DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, TRUE );
|
||||
DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, TRUE );
|
||||
fprintf(stderr,": ");
|
||||
DEBUG_Disasm( &addr, TRUE );
|
||||
DEBUG_Disasm( &value.addr, TRUE );
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
return;
|
||||
@ -267,10 +268,10 @@ void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
|
||||
for(i=0; i<count; i++) { \
|
||||
if (!DEBUG_READ_MEM_VERBOSE(pnt, &_v, sizeof(_t))) break; \
|
||||
fprintf(stderr,_f,(_vv)); \
|
||||
pnt += sizeof(_t); addr.off += sizeof(_t); \
|
||||
pnt += sizeof(_t); value.addr.off += sizeof(_t); \
|
||||
if ((i % (_l)) == (_l)-1) { \
|
||||
fprintf(stderr,"\n"); \
|
||||
DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, FALSE );\
|
||||
DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, FALSE );\
|
||||
fprintf(stderr,": ");\
|
||||
} \
|
||||
} \
|
||||
|
114
debugger/msc.c
114
debugger/msc.c
@ -1249,7 +1249,7 @@ DEBUG_ParseTypeTable(char * table, int len)
|
||||
}
|
||||
|
||||
void
|
||||
DEBUG_InitCVDataTypes()
|
||||
DEBUG_InitCVDataTypes(void)
|
||||
{
|
||||
/*
|
||||
* These are the common builtin types that are used by VC++.
|
||||
@ -1505,7 +1505,7 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
char namebuff[9];
|
||||
char * nampnt;
|
||||
int naux;
|
||||
DBG_ADDR new_addr;
|
||||
DBG_VALUE new_value;
|
||||
int nfiles = 0;
|
||||
int nfiles_alloc = 0;
|
||||
struct CoffFiles orig_file;
|
||||
@ -1520,6 +1520,9 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
|
||||
linetab_indx = 0;
|
||||
|
||||
new_value.cookie = DV_TARGET;
|
||||
new_value.type = NULL;
|
||||
|
||||
for(i=0; i < coff->N_Sym; i++ )
|
||||
{
|
||||
/*
|
||||
@ -1675,8 +1678,8 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
nampnt++;
|
||||
}
|
||||
|
||||
new_addr.seg = 0;
|
||||
new_addr.off = (int) (deefer->load_addr + coff_sym->Value);
|
||||
new_value.addr.seg = 0;
|
||||
new_value.addr.off = (int) (deefer->load_addr + coff_sym->Value);
|
||||
|
||||
if( curr_file->neps + 1 >= curr_file->neps_alloc )
|
||||
{
|
||||
@ -1689,7 +1692,7 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
fprintf(stderr,"\tAdding static symbol %s\n", nampnt);
|
||||
#endif
|
||||
curr_file->entries[curr_file->neps++] =
|
||||
DEBUG_AddSymbol( nampnt, &new_addr, this_file, SYM_WIN32 );
|
||||
DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 );
|
||||
i += naux;
|
||||
continue;
|
||||
}
|
||||
@ -1715,11 +1718,11 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
nampnt++;
|
||||
}
|
||||
|
||||
new_addr.seg = 0;
|
||||
new_addr.off = (int) (deefer->load_addr + coff_sym->Value);
|
||||
new_value.addr.seg = 0;
|
||||
new_value.addr.off = (int) (deefer->load_addr + coff_sym->Value);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "%d: %x %s\n", i, new_addr.off, nampnt);
|
||||
fprintf(stderr, "%d: %x %s\n", i, new_value.addr.off, nampnt);
|
||||
|
||||
fprintf(stderr,"\tAdding global symbol %s\n", nampnt);
|
||||
#endif
|
||||
@ -1745,7 +1748,7 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
coff_files[j].neps_alloc * sizeof(struct name_hash *));
|
||||
}
|
||||
coff_files[j].entries[coff_files[j].neps++] =
|
||||
DEBUG_AddSymbol( nampnt, &new_addr, this_file, SYM_WIN32 );
|
||||
DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 );
|
||||
i += naux;
|
||||
continue;
|
||||
}
|
||||
@ -1774,11 +1777,11 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
nampnt++;
|
||||
}
|
||||
|
||||
new_addr.seg = 0;
|
||||
new_addr.off = (int) (deefer->load_addr + coff_sym->Value);
|
||||
new_value.addr.seg = 0;
|
||||
new_value.addr.off = (int) (deefer->load_addr + coff_sym->Value);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "%d: %x %s\n", i, new_addr.off, nampnt);
|
||||
fprintf(stderr, "%d: %x %s\n", i, new_value.addr.off, nampnt);
|
||||
|
||||
fprintf(stderr,"\tAdding global data symbol %s\n", nampnt);
|
||||
#endif
|
||||
@ -1786,7 +1789,7 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
/*
|
||||
* Now we need to figure out which file this guy belongs to.
|
||||
*/
|
||||
DEBUG_AddSymbol( nampnt, &new_addr, NULL, SYM_WIN32 );
|
||||
DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 );
|
||||
i += naux;
|
||||
continue;
|
||||
}
|
||||
@ -1856,9 +1859,9 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
while(TRUE)
|
||||
{
|
||||
if (i+1 >= coff_files[j].neps) break;
|
||||
DEBUG_GetSymbolAddr(coff_files[j].entries[i+1], &new_addr);
|
||||
DEBUG_GetSymbolAddr(coff_files[j].entries[i+1], &new_value.addr);
|
||||
if( (((unsigned int)deefer->load_addr +
|
||||
linepnt->VirtualAddr) >= new_addr.off) )
|
||||
linepnt->VirtualAddr) >= new_value.addr.off) )
|
||||
{
|
||||
i++;
|
||||
} else break;
|
||||
@ -1869,12 +1872,12 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer)
|
||||
* start of the function, so we need to subtract that offset
|
||||
* first.
|
||||
*/
|
||||
DEBUG_GetSymbolAddr(coff_files[j].entries[i], &new_addr);
|
||||
DEBUG_GetSymbolAddr(coff_files[j].entries[i], &new_value.addr);
|
||||
DEBUG_AddLineNumber(coff_files[j].entries[i],
|
||||
linepnt->Linenum,
|
||||
(unsigned int) deefer->load_addr
|
||||
+ linepnt->VirtualAddr
|
||||
- new_addr.off);
|
||||
- new_value.addr.off);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2013,7 +2016,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
int i;
|
||||
int j;
|
||||
int len;
|
||||
DBG_ADDR new_addr;
|
||||
DBG_VALUE new_value;
|
||||
int nsect;
|
||||
union any_size ptr;
|
||||
IMAGE_SECTION_HEADER * sectp;
|
||||
@ -2070,12 +2073,13 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
*/
|
||||
|
||||
memcpy(symname, sym->data.name, sym->data.namelen);
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = DEBUG_GetCVType(sym->data.symtype);
|
||||
new_addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->data.seg - 1].VirtualAddress +
|
||||
sym->data.offset;
|
||||
DEBUG_AddSymbol( symname, &new_addr, NULL, SYM_WIN32 | SYM_DATA );
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = DEBUG_GetCVType(sym->data.symtype);
|
||||
new_value.addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->data.seg - 1].VirtualAddress +
|
||||
sym->data.offset;
|
||||
new_value.cookie = DV_TARGET;
|
||||
DEBUG_AddSymbol( symname, &new_value, NULL, SYM_WIN32 | SYM_DATA );
|
||||
break;
|
||||
case S_GDATA_32:
|
||||
case S_LDATA_32:
|
||||
@ -2099,12 +2103,13 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
*/
|
||||
|
||||
memcpy(symname, sym->data32.name, sym->data32.namelen);
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = DEBUG_GetCVType(sym->data32.symtype);
|
||||
new_addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->data32.seg - 1].VirtualAddress +
|
||||
sym->data32.offset;
|
||||
DEBUG_AddSymbol( symname, &new_addr, NULL, SYM_WIN32 | SYM_DATA );
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = DEBUG_GetCVType(sym->data32.symtype);
|
||||
new_value.addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->data32.seg - 1].VirtualAddress +
|
||||
sym->data32.offset;
|
||||
new_value.cookie = DV_TARGET;
|
||||
DEBUG_AddSymbol( symname, &new_value, NULL, SYM_WIN32 | SYM_DATA );
|
||||
break;
|
||||
case S_THUNK:
|
||||
/*
|
||||
@ -2113,12 +2118,13 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
* a PLT slot in the normal jargon that everyone else uses.
|
||||
*/
|
||||
memcpy(symname, sym->thunk.name, sym->thunk.namelen);
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = NULL;
|
||||
new_addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->thunk.segment - 1].VirtualAddress +
|
||||
sym->thunk.offset;
|
||||
thunk_sym = DEBUG_AddSymbol( symname, &new_addr, NULL,
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = NULL;
|
||||
new_value.addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->thunk.segment - 1].VirtualAddress +
|
||||
sym->thunk.offset;
|
||||
new_value.cookie = DV_TARGET;
|
||||
thunk_sym = DEBUG_AddSymbol( symname, &new_value, NULL,
|
||||
SYM_WIN32 | SYM_FUNC);
|
||||
DEBUG_SetSymbolSize(thunk_sym, sym->thunk.thunk_len);
|
||||
break;
|
||||
@ -2128,11 +2134,12 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
* Global and static functions.
|
||||
*/
|
||||
memcpy(symname, sym->proc.name, sym->proc.namelen);
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = DEBUG_GetCVType(sym->proc.proctype);
|
||||
new_addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->proc.segment - 1].VirtualAddress +
|
||||
sym->proc.offset;
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = DEBUG_GetCVType(sym->proc.proctype);
|
||||
new_value.addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->proc.segment - 1].VirtualAddress +
|
||||
sym->proc.offset;
|
||||
new_value.cookie = DV_TARGET;
|
||||
/*
|
||||
* See if we can find a segment that this goes with. If so,
|
||||
* it means that we also may have line number information
|
||||
@ -2142,10 +2149,10 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
{
|
||||
if( ((unsigned int) deefer->load_addr
|
||||
+ sectp[linetab[i].segno - 1].VirtualAddress
|
||||
+ linetab[i].start <= new_addr.off)
|
||||
+ linetab[i].start <= new_value.addr.off)
|
||||
&& ((unsigned int) deefer->load_addr
|
||||
+ sectp[linetab[i].segno - 1].VirtualAddress
|
||||
+ linetab[i].end > new_addr.off) )
|
||||
+ linetab[i].end > new_value.addr.off) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -2154,7 +2161,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
DEBUG_Normalize(curr_func);
|
||||
if( !linetab || linetab[i].linetab == NULL )
|
||||
{
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_addr, NULL,
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_value, NULL,
|
||||
SYM_WIN32 | SYM_FUNC);
|
||||
}
|
||||
else
|
||||
@ -2164,7 +2171,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
* and add whatever line numbers are appropriate for this
|
||||
* function.
|
||||
*/
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_addr,
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_value,
|
||||
linetab[i].sourcefile,
|
||||
SYM_WIN32 | SYM_FUNC);
|
||||
for(j=0; j < linetab[i].nline; j++)
|
||||
@ -2193,11 +2200,12 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
* Global and static functions.
|
||||
*/
|
||||
memcpy(symname, sym->proc32.name, sym->proc32.namelen);
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = DEBUG_GetCVType(sym->proc32.proctype);
|
||||
new_addr.off = (unsigned int) deefer->load_addr +
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = DEBUG_GetCVType(sym->proc32.proctype);
|
||||
new_value.addr.off = (unsigned int) deefer->load_addr +
|
||||
sectp[sym->proc32.segment - 1].VirtualAddress +
|
||||
sym->proc32.offset;
|
||||
new_value.cookie = DV_TARGET;
|
||||
/*
|
||||
* See if we can find a segment that this goes with. If so,
|
||||
* it means that we also may have line number information
|
||||
@ -2207,10 +2215,10 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
{
|
||||
if( ((unsigned int) deefer->load_addr
|
||||
+ sectp[linetab[i].segno - 1].VirtualAddress
|
||||
+ linetab[i].start <= new_addr.off)
|
||||
+ linetab[i].start <= new_value.addr.off)
|
||||
&& ((unsigned int) deefer->load_addr
|
||||
+ sectp[linetab[i].segno - 1].VirtualAddress
|
||||
+ linetab[i].end > new_addr.off) )
|
||||
+ linetab[i].end > new_value.addr.off) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -2219,7 +2227,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
DEBUG_Normalize(curr_func);
|
||||
if( !linetab || linetab[i].linetab == NULL )
|
||||
{
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_addr, NULL,
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_value, NULL,
|
||||
SYM_WIN32 | SYM_FUNC);
|
||||
}
|
||||
else
|
||||
@ -2229,7 +2237,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer,
|
||||
* and add whatever line numbers are appropriate for this
|
||||
* function.
|
||||
*/
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_addr,
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_value,
|
||||
linetab[i].sourcefile,
|
||||
SYM_WIN32 | SYM_FUNC);
|
||||
for(j=0; j < linetab[i].nline; j++)
|
||||
@ -2970,7 +2978,7 @@ leave:
|
||||
}
|
||||
|
||||
int
|
||||
DEBUG_ProcessDeferredDebug()
|
||||
DEBUG_ProcessDeferredDebug(void)
|
||||
{
|
||||
struct deferred_debug_info * deefer;
|
||||
struct CodeViewDebug * cvd;
|
||||
|
@ -49,7 +49,7 @@ static int DEBUG_start_sourceline = -1;
|
||||
static int DEBUG_end_sourceline = -1;
|
||||
|
||||
void
|
||||
DEBUG_ShowDir()
|
||||
DEBUG_ShowDir(void)
|
||||
{
|
||||
struct searchlist * sl;
|
||||
|
||||
@ -78,7 +78,7 @@ DEBUG_AddPath(const char * path)
|
||||
}
|
||||
|
||||
void
|
||||
DEBUG_NukePath()
|
||||
DEBUG_NukePath(void)
|
||||
{
|
||||
struct searchlist * sl;
|
||||
struct searchlist * nxt;
|
||||
@ -422,7 +422,7 @@ DEBUG_List(struct list_id * source1, struct list_id * source2,
|
||||
DEBUG_end_sourceline = end;
|
||||
}
|
||||
|
||||
DBG_ADDR DEBUG_LastDisassemble={NULL,0,0};
|
||||
DBG_ADDR DEBUG_LastDisassemble={0,0};
|
||||
|
||||
static int
|
||||
_disassemble(DBG_ADDR *addr)
|
||||
@ -438,33 +438,36 @@ _disassemble(DBG_ADDR *addr)
|
||||
}
|
||||
|
||||
void
|
||||
_disassemble_fixaddr(DBG_ADDR *addr) {
|
||||
_disassemble_fixaddr(DBG_VALUE *value) {
|
||||
DWORD seg2;
|
||||
struct datatype *testtype;
|
||||
|
||||
DEBUG_FixAddress(addr, DEBUG_context.SegCs);
|
||||
if( addr->type != NULL )
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
||||
DEBUG_FixAddress(&value->addr, DEBUG_context.SegCs);
|
||||
|
||||
if( value->type != NULL )
|
||||
{
|
||||
if( addr->type == DEBUG_TypeIntConst )
|
||||
if( value->type == DEBUG_TypeIntConst )
|
||||
{
|
||||
/*
|
||||
* We know that we have the actual offset stored somewhere
|
||||
* else in 32-bit space. Grab it, and we
|
||||
* should be all set.
|
||||
*/
|
||||
seg2 = addr->seg;
|
||||
addr->seg = 0;
|
||||
addr->off = DEBUG_GetExprValue(addr, NULL);
|
||||
addr->seg = seg2;
|
||||
seg2 = value->addr.seg;
|
||||
value->addr.seg = 0;
|
||||
value->addr.off = DEBUG_GetExprValue(value, NULL);
|
||||
value->addr.seg = seg2;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_TypeDerefPointer(addr, &testtype);
|
||||
if( testtype != NULL || addr->type == DEBUG_TypeIntConst )
|
||||
addr->off = DEBUG_GetExprValue(addr, NULL);
|
||||
DEBUG_TypeDerefPointer(value, &testtype);
|
||||
if( testtype != NULL || value->type == DEBUG_TypeIntConst )
|
||||
value->addr.off = DEBUG_GetExprValue(value, NULL);
|
||||
}
|
||||
}
|
||||
else if (!addr->seg && !addr->off)
|
||||
else if (!value->addr.seg && !value->addr.off)
|
||||
{
|
||||
fprintf(stderr,"Invalid expression\n");
|
||||
return;
|
||||
@ -472,18 +475,18 @@ _disassemble_fixaddr(DBG_ADDR *addr) {
|
||||
}
|
||||
|
||||
void
|
||||
DEBUG_Disassemble(const DBG_ADDR *xstart,const DBG_ADDR *xend,int offset)
|
||||
DEBUG_Disassemble(const DBG_VALUE *xstart,const DBG_VALUE *xend,int offset)
|
||||
{
|
||||
int i;
|
||||
DBG_ADDR last;
|
||||
DBG_ADDR end,start;
|
||||
DBG_VALUE end,start;
|
||||
|
||||
if (xstart) {
|
||||
start=*xstart;
|
||||
start = *xstart;
|
||||
_disassemble_fixaddr(&start);
|
||||
}
|
||||
if (xend) {
|
||||
end=*xend;
|
||||
end = *xend;
|
||||
_disassemble_fixaddr(&end);
|
||||
}
|
||||
if (!xstart && !xend) {
|
||||
@ -493,26 +496,26 @@ DEBUG_Disassemble(const DBG_ADDR *xstart,const DBG_ADDR *xend,int offset)
|
||||
|
||||
for (i=0;i<offset;i++)
|
||||
if (!_disassemble(&last)) break;
|
||||
memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
|
||||
DEBUG_LastDisassemble = last;
|
||||
return;
|
||||
}
|
||||
last = start;
|
||||
last = start.addr;
|
||||
if (!xend) {
|
||||
for (i=0;i<offset;i++)
|
||||
if (!_disassemble(&last)) break;
|
||||
memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
|
||||
DEBUG_LastDisassemble = last;
|
||||
return;
|
||||
}
|
||||
while (last.off <= end.off)
|
||||
while (last.off <= end.addr.off)
|
||||
if (!_disassemble(&last)) break;
|
||||
memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
|
||||
DEBUG_LastDisassemble = last;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
main()
|
||||
main(void)
|
||||
{
|
||||
int i, j;
|
||||
DEBUG_AddPath("../../de");
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
@ -426,7 +425,7 @@ DEBUG_HandlePreviousTypedef(const char * name, const char * stab)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int DEBUG_FreeRegisteredTypedefs()
|
||||
static int DEBUG_FreeRegisteredTypedefs(void)
|
||||
{
|
||||
int count;
|
||||
int j;
|
||||
@ -775,10 +774,10 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
|
||||
struct name_hash * curr_sym = NULL;
|
||||
char currpath[PATH_MAX];
|
||||
int i;
|
||||
int ignore = FALSE;
|
||||
int in_external_file = FALSE;
|
||||
int last_nso = -1;
|
||||
int len;
|
||||
DBG_ADDR new_addr;
|
||||
DBG_VALUE new_value;
|
||||
int nstab;
|
||||
char * ptr;
|
||||
char * stabbuff;
|
||||
@ -855,16 +854,17 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
|
||||
*
|
||||
* With a.out, they actually do make some amount of sense.
|
||||
*/
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = DEBUG_ParseStabType(ptr);
|
||||
new_addr.off = load_offset + stab_ptr->n_value;
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = DEBUG_ParseStabType(ptr);
|
||||
new_value.addr.off = load_offset + stab_ptr->n_value;
|
||||
new_value.cookie = DV_TARGET;
|
||||
|
||||
stab_strcpy(symname, ptr);
|
||||
#ifdef __ELF__
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_addr, currpath,
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
|
||||
SYM_WINE | SYM_DATA | SYM_INVALID);
|
||||
#else
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_addr, currpath,
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
|
||||
SYM_WINE | SYM_DATA );
|
||||
#endif
|
||||
break;
|
||||
@ -883,20 +883,20 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
|
||||
/*
|
||||
* These are static symbols and BSS symbols.
|
||||
*/
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = DEBUG_ParseStabType(ptr);
|
||||
new_addr.off = load_offset + stab_ptr->n_value;
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = DEBUG_ParseStabType(ptr);
|
||||
new_value.addr.off = load_offset + stab_ptr->n_value;
|
||||
new_value.cookie = DV_TARGET;
|
||||
|
||||
stab_strcpy(symname, ptr);
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_addr, currpath,
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
|
||||
SYM_WINE | SYM_DATA );
|
||||
break;
|
||||
case N_PSYM:
|
||||
/*
|
||||
* These are function parameters.
|
||||
*/
|
||||
if( (curr_func != NULL)
|
||||
&& (stab_ptr->n_value != 0) )
|
||||
if( curr_func != NULL && !in_external_file )
|
||||
{
|
||||
stab_strcpy(symname, ptr);
|
||||
curr_loc = DEBUG_AddLocal( curr_func, 0,
|
||||
@ -905,34 +905,29 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
|
||||
}
|
||||
break;
|
||||
case N_RSYM:
|
||||
if( curr_func != NULL )
|
||||
if( curr_func != NULL && !in_external_file )
|
||||
{
|
||||
stab_strcpy(symname, ptr);
|
||||
curr_loc = DEBUG_AddLocal( curr_func, stab_ptr->n_value,
|
||||
curr_loc = DEBUG_AddLocal( curr_func, stab_ptr->n_value + 1,
|
||||
0, 0, 0, symname );
|
||||
DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
|
||||
}
|
||||
break;
|
||||
case N_LSYM:
|
||||
if( (curr_func != NULL)
|
||||
&& (stab_ptr->n_value != 0) )
|
||||
if( curr_func != NULL && !in_external_file )
|
||||
{
|
||||
stab_strcpy(symname, ptr);
|
||||
curr_loc = DEBUG_AddLocal( curr_func, 0,
|
||||
stab_ptr->n_value, 0, 0, symname );
|
||||
DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
|
||||
}
|
||||
else if (curr_func == NULL)
|
||||
{
|
||||
stab_strcpy(symname, ptr);
|
||||
}
|
||||
break;
|
||||
case N_SLINE:
|
||||
/*
|
||||
* This is a line number. These are always relative to the start
|
||||
* of the function (N_FUN), and this makes the lookup easier.
|
||||
*/
|
||||
if( curr_func != NULL )
|
||||
if( curr_func != NULL && !in_external_file )
|
||||
{
|
||||
#ifdef __ELF__
|
||||
DEBUG_AddLineNumber(curr_func, stab_ptr->n_desc,
|
||||
@ -961,11 +956,12 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
|
||||
* on, we will add the line number information and the
|
||||
* local symbols.
|
||||
*/
|
||||
if( !ignore )
|
||||
if( !in_external_file )
|
||||
{
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = DEBUG_ParseStabType(ptr);
|
||||
new_addr.off = load_offset + stab_ptr->n_value;
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = DEBUG_ParseStabType(ptr);
|
||||
new_value.addr.off = load_offset + stab_ptr->n_value;
|
||||
new_value.cookie = DV_TARGET;
|
||||
/*
|
||||
* Copy the string to a temp buffer so we
|
||||
* can kill everything after the ':'. We do
|
||||
@ -974,7 +970,7 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
|
||||
* sucks up swap space like crazy.
|
||||
*/
|
||||
stab_strcpy(symname, ptr);
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_addr, currpath,
|
||||
curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
|
||||
SYM_WINE | SYM_FUNC);
|
||||
}
|
||||
else
|
||||
@ -1031,16 +1027,7 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
|
||||
* If this is the main source, enable the debug stuff, otherwise
|
||||
* ignore it.
|
||||
*/
|
||||
if( subpath == NULL || strcmp(ptr, subpath) == 0 )
|
||||
{
|
||||
ignore = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ignore = TRUE;
|
||||
DEBUG_Normalize(curr_func);
|
||||
curr_func = NULL;
|
||||
}
|
||||
in_external_file = !(subpath == NULL || strcmp(ptr, subpath) == 0);
|
||||
break;
|
||||
case N_UNDF:
|
||||
strs += strtabinc;
|
||||
@ -1106,7 +1093,7 @@ DEBUG_ProcessElfSymtab(char * addr, unsigned int load_offset,
|
||||
struct name_hash * curr_sym = NULL;
|
||||
int flags;
|
||||
int i;
|
||||
DBG_ADDR new_addr;
|
||||
DBG_VALUE new_value;
|
||||
int nsym;
|
||||
char * strp;
|
||||
char * symname;
|
||||
@ -1148,19 +1135,20 @@ DEBUG_ProcessElfSymtab(char * addr, unsigned int load_offset,
|
||||
* we will have to keep the darned thing, because there can be
|
||||
* multiple local symbols by the same name.
|
||||
*/
|
||||
if( (DEBUG_GetSymbolValue(symname, -1, &new_addr, FALSE ) == TRUE)
|
||||
&& (new_addr.off == (load_offset + symp->st_value)) )
|
||||
if( (DEBUG_GetSymbolValue(symname, -1, &new_value, FALSE ) == TRUE)
|
||||
&& (new_value.addr.off == (load_offset + symp->st_value)) )
|
||||
continue;
|
||||
|
||||
new_addr.seg = 0;
|
||||
new_addr.type = NULL;
|
||||
new_addr.off = load_offset + symp->st_value;
|
||||
new_value.addr.seg = 0;
|
||||
new_value.type = NULL;
|
||||
new_value.addr.off = load_offset + symp->st_value;
|
||||
new_value.cookie = DV_TARGET;
|
||||
flags = SYM_WINE | (ELF32_ST_BIND(symp->st_info) == STT_FUNC
|
||||
? SYM_FUNC : SYM_DATA);
|
||||
if( ELF32_ST_BIND(symp->st_info) == STB_GLOBAL )
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_addr, NULL, flags );
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_value, NULL, flags );
|
||||
else
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_addr, curfile, flags );
|
||||
curr_sym = DEBUG_AddSymbol( symname, &new_value, curfile, flags );
|
||||
|
||||
/*
|
||||
* Record the size of the symbol. This can come in handy in
|
||||
|
@ -57,23 +57,24 @@ typedef struct
|
||||
void DEBUG_InfoStack(void)
|
||||
{
|
||||
#ifdef __i386__
|
||||
DBG_ADDR addr;
|
||||
|
||||
addr.type = NULL;
|
||||
addr.seg = DEBUG_context.SegSs;
|
||||
addr.off = DEBUG_context.Esp;
|
||||
DBG_VALUE value;
|
||||
|
||||
value.type = NULL;
|
||||
value.cookie = DV_TARGET;
|
||||
value.addr.seg = DEBUG_context.SegSs;
|
||||
value.addr.off = DEBUG_context.Esp;
|
||||
|
||||
fprintf(stderr,"Stack dump:\n");
|
||||
switch (DEBUG_GetSelectorType(addr.seg)) {
|
||||
switch (DEBUG_GetSelectorType(value.addr.seg)) {
|
||||
case 32: /* 32-bit mode */
|
||||
DEBUG_ExamineMemory( &addr, 24, 'x' );
|
||||
DEBUG_ExamineMemory( &value, 24, 'x' );
|
||||
break;
|
||||
case 16: /* 16-bit mode */
|
||||
addr.off &= 0xffff;
|
||||
DEBUG_ExamineMemory( &addr, 24, 'w' );
|
||||
value.addr.off &= 0xffff;
|
||||
DEBUG_ExamineMemory( &value, 24, 'w' );
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Bad segment (%ld)\n", addr.seg);
|
||||
fprintf(stderr, "Bad segment (%ld)\n", value.addr.seg);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
#endif
|
||||
@ -317,7 +318,7 @@ void DEBUG_BackTrace(BOOL noisy)
|
||||
if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK32FRAME*)next_switch );
|
||||
return;
|
||||
}
|
||||
code.type = NULL;
|
||||
|
||||
code.seg = 0;
|
||||
code.off = frame32.retaddr;
|
||||
|
||||
@ -352,7 +353,6 @@ void DEBUG_BackTrace(BOOL noisy)
|
||||
return;
|
||||
}
|
||||
|
||||
code.type = NULL;
|
||||
code.seg = frame16.cs;
|
||||
code.off = frame16.ip;
|
||||
|
||||
|
223
debugger/types.c
223
debugger/types.c
@ -11,7 +11,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -294,7 +293,7 @@ DEBUG_FindOrMakePointerType(struct datatype * reftype)
|
||||
}
|
||||
|
||||
void
|
||||
DEBUG_InitTypes()
|
||||
DEBUG_InitTypes(void)
|
||||
{
|
||||
static int beenhere = 0;
|
||||
struct datatype * chartype;
|
||||
@ -313,7 +312,6 @@ DEBUG_InitTypes()
|
||||
* Initialize a few builtin types.
|
||||
*/
|
||||
|
||||
|
||||
DEBUG_TypeInt = DEBUG_InitBasic(BASIC_INT,"int",4,1,"%d");
|
||||
chartype = DEBUG_InitBasic(BASIC_CHAR,"char",1,1,"'%c'");
|
||||
DEBUG_InitBasic(BASIC_LONG,"long int",4,1,"%d");
|
||||
@ -345,40 +343,55 @@ DEBUG_InitTypes()
|
||||
}
|
||||
|
||||
long long int
|
||||
DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format)
|
||||
DEBUG_GetExprValue(const DBG_VALUE *_value, char ** format)
|
||||
{
|
||||
DBG_ADDR address = *addr;
|
||||
unsigned int rtn;
|
||||
struct datatype * type2 = NULL;
|
||||
struct en_values * e;
|
||||
char * def_format = "0x%x";
|
||||
DBG_VALUE value = *_value;
|
||||
|
||||
assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
|
||||
|
||||
rtn = 0;
|
||||
address.seg = 0; /* FIXME? I don't quite get this... */
|
||||
assert(addr->type != NULL);
|
||||
value.addr.seg = 0; /* FIXME? I don't quite get this... */
|
||||
assert(value.type != NULL);
|
||||
|
||||
switch(addr->type->type)
|
||||
switch(value.type->type)
|
||||
{
|
||||
case DT_BASIC:
|
||||
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)addr->off, &rtn, addr->type->un.basic.basic_size))
|
||||
return 0;
|
||||
|
||||
if( (addr->type->un.basic.b_signed)
|
||||
&& ((addr->type->un.basic.basic_size & 3) != 0)
|
||||
&& ((rtn >> (addr->type->un.basic.basic_size * 8 - 1)) != 0) )
|
||||
if (value.type == DEBUG_TypeIntConst)
|
||||
{
|
||||
assert(_value->cookie == DV_HOST);
|
||||
rtn = *(int*)value.addr.off;
|
||||
def_format = value.type->un.basic.output_format;
|
||||
break;
|
||||
}
|
||||
|
||||
rtn = 0;
|
||||
if (_value->cookie == DV_TARGET) {
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)value.addr.off, &rtn, value.type->un.basic.basic_size))
|
||||
return 0;
|
||||
} else {
|
||||
memcpy(&rtn, (void*)value.addr.off, value.type->un.basic.basic_size);
|
||||
}
|
||||
|
||||
if( (value.type->un.basic.b_signed)
|
||||
&& ((value.type->un.basic.basic_size & 3) != 0)
|
||||
&& ((rtn >> (value.type->un.basic.basic_size * 8 - 1)) != 0) )
|
||||
{
|
||||
rtn = rtn | ((-1) << (addr->type->un.basic.basic_size * 8));
|
||||
rtn = rtn | ((-1) << (value.type->un.basic.basic_size * 8));
|
||||
}
|
||||
if( addr->type->un.basic.output_format != NULL )
|
||||
if( value.type->un.basic.output_format != NULL )
|
||||
{
|
||||
def_format = addr->type->un.basic.output_format;
|
||||
def_format = value.type->un.basic.output_format;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for single character prints that are out of range.
|
||||
*/
|
||||
if( addr->type->un.basic.basic_size == 1
|
||||
if( value.type->un.basic.basic_size == 1
|
||||
&& strcmp(def_format, "'%c'") == 0
|
||||
&& ((rtn < 0x20) || (rtn > 0x80)) )
|
||||
{
|
||||
@ -386,10 +399,14 @@ DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format)
|
||||
}
|
||||
break;
|
||||
case DT_POINTER:
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)addr->off, &rtn, sizeof(void*)))
|
||||
return 0;
|
||||
if (_value->cookie == DV_TARGET) {
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)value.addr.off, &rtn, sizeof(void*)))
|
||||
return 0;
|
||||
} else {
|
||||
rtn = *(unsigned int*)(value.addr.off);
|
||||
}
|
||||
|
||||
type2 = addr->type->un.pointer.pointsto;
|
||||
type2 = value.type->un.pointer.pointsto;
|
||||
|
||||
if (!type2)
|
||||
{
|
||||
@ -398,12 +415,16 @@ DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format)
|
||||
break;
|
||||
}
|
||||
|
||||
if( type2->type == DT_BASIC && type2->un.basic.basic_size == 1 )
|
||||
{
|
||||
def_format = "\"%s\"";
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)rtn, &rtn, 1))
|
||||
return 0;
|
||||
break;
|
||||
if( type2->type == DT_BASIC && type2->un.basic.basic_size == 1 )
|
||||
{
|
||||
if ( _value->cookie == DV_TARGET ) {
|
||||
char ch;
|
||||
def_format = "\"%S\"";
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)rtn, &ch, 1))
|
||||
return 0;
|
||||
} else {
|
||||
def_format = "\"%s\"";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -412,14 +433,16 @@ DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format)
|
||||
break;
|
||||
case DT_ARRAY:
|
||||
case DT_STRUCT:
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)addr->off, &rtn, sizeof(rtn)))
|
||||
assert(_value->cookie == DV_TARGET);
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)value.addr.off, &rtn, sizeof(rtn)))
|
||||
return 0;
|
||||
def_format = "0x%8.8x";
|
||||
break;
|
||||
case DT_ENUM:
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)addr->off, &rtn, sizeof(rtn)))
|
||||
assert(_value->cookie == DV_TARGET);
|
||||
if (!DEBUG_READ_MEM_VERBOSE((void*)value.addr.off, &rtn, sizeof(rtn)))
|
||||
return 0;
|
||||
for(e = addr->type->un.enumeration.members; e; e = e->next )
|
||||
for(e = value.type->un.enumeration.members; e; e = e->next )
|
||||
{
|
||||
if( e->value == rtn )
|
||||
{
|
||||
@ -428,7 +451,7 @@ DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format)
|
||||
}
|
||||
if( e != NULL )
|
||||
{
|
||||
rtn = (int) e->name;
|
||||
rtn = (int) e->name;
|
||||
def_format = "%s";
|
||||
}
|
||||
else
|
||||
@ -450,53 +473,63 @@ DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format)
|
||||
}
|
||||
|
||||
unsigned int
|
||||
DEBUG_TypeDerefPointer(const DBG_ADDR * addr, struct datatype ** newtype)
|
||||
DEBUG_TypeDerefPointer(const DBG_VALUE *value, struct datatype ** newtype)
|
||||
{
|
||||
DBG_ADDR address = *addr;
|
||||
unsigned int val;
|
||||
DBG_ADDR addr = value->addr;
|
||||
unsigned int val;
|
||||
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
||||
*newtype = NULL;
|
||||
|
||||
/*
|
||||
* Make sure that this really makes sense.
|
||||
*/
|
||||
if( addr->type->type != DT_POINTER || !DEBUG_READ_MEM((void*)addr->off, &val, sizeof(val)))
|
||||
{
|
||||
*newtype = NULL;
|
||||
return 0;
|
||||
}
|
||||
if( value->type->type != DT_POINTER )
|
||||
return 0;
|
||||
|
||||
*newtype = addr->type->un.pointer.pointsto;
|
||||
address.off = val;
|
||||
return DEBUG_ToLinear(&address); /* FIXME: is this right (or "better") ? */
|
||||
if (value->cookie == DV_TARGET) {
|
||||
if (!DEBUG_READ_MEM((void*)value->addr.off, &val, sizeof(val)))
|
||||
return 0;
|
||||
} else {
|
||||
val = *(unsigned int*)value->addr.off;
|
||||
}
|
||||
|
||||
*newtype = value->type->un.pointer.pointsto;
|
||||
addr.off = val;
|
||||
return DEBUG_ToLinear(&addr); /* FIXME: is this right (or "better") ? */
|
||||
}
|
||||
|
||||
unsigned int
|
||||
DEBUG_FindStructElement(DBG_ADDR * addr, const char * ele_name, int * tmpbuf)
|
||||
DEBUG_FindStructElement(DBG_VALUE* value, const char * ele_name, int * tmpbuf)
|
||||
{
|
||||
struct member * m;
|
||||
unsigned int mask;
|
||||
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
||||
/*
|
||||
* Make sure that this really makes sense.
|
||||
*/
|
||||
if( addr->type->type != DT_STRUCT )
|
||||
if( value->type->type != DT_STRUCT )
|
||||
{
|
||||
addr->type = NULL;
|
||||
value->type = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for(m = addr->type->un.structure.members; m; m = m->next)
|
||||
for(m = value->type->un.structure.members; m; m = m->next)
|
||||
{
|
||||
if( strcmp(m->name, ele_name) == 0 )
|
||||
{
|
||||
addr->type = m->type;
|
||||
value->type = m->type;
|
||||
if( (m->offset & 7) != 0 || (m->size & 7) != 0)
|
||||
{
|
||||
/*
|
||||
* Bitfield operation. We have to extract the field and store
|
||||
* it in a temporary buffer so that we get it all right.
|
||||
*/
|
||||
*tmpbuf = ((*(int* ) (addr->off + (m->offset >> 3))) >> (m->offset & 7));
|
||||
addr->off = (int) tmpbuf;
|
||||
*tmpbuf = ((*(int* ) (value->addr.off + (m->offset >> 3))) >> (m->offset & 7));
|
||||
value->addr.off = (int) tmpbuf;
|
||||
|
||||
mask = 0xffffffff << (m->size);
|
||||
*tmpbuf &= ~mask;
|
||||
@ -513,13 +546,13 @@ DEBUG_FindStructElement(DBG_ADDR * addr, const char * ele_name, int * tmpbuf)
|
||||
}
|
||||
else
|
||||
{
|
||||
addr->off += (m->offset >> 3);
|
||||
value->addr.off += (m->offset >> 3);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
addr->type = NULL;
|
||||
value->type = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -717,27 +750,29 @@ int DEBUG_GetObjectSize(struct datatype * dt)
|
||||
}
|
||||
|
||||
unsigned int
|
||||
DEBUG_ArrayIndex(const DBG_ADDR * addr, DBG_ADDR * result, int index)
|
||||
DEBUG_ArrayIndex(const DBG_VALUE * value, DBG_VALUE * result, int index)
|
||||
{
|
||||
int size;
|
||||
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
||||
/*
|
||||
* Make sure that this really makes sense.
|
||||
*/
|
||||
if( addr->type->type == DT_POINTER )
|
||||
if( value->type->type == DT_POINTER )
|
||||
{
|
||||
/*
|
||||
* Get the base type, so we know how much to index by.
|
||||
*/
|
||||
size = DEBUG_GetObjectSize(addr->type->un.pointer.pointsto);
|
||||
result->type = addr->type->un.pointer.pointsto;
|
||||
result->off = (*(unsigned int*) (addr->off)) + size * index;
|
||||
size = DEBUG_GetObjectSize(value->type->un.pointer.pointsto);
|
||||
result->type = value->type->un.pointer.pointsto;
|
||||
result->addr.off = (*(unsigned int*) (value->addr.off)) + size * index;
|
||||
}
|
||||
else if (addr->type->type == DT_ARRAY)
|
||||
else if (value->type->type == DT_ARRAY)
|
||||
{
|
||||
size = DEBUG_GetObjectSize(addr->type->un.array.basictype);
|
||||
result->type = addr->type->un.array.basictype;
|
||||
result->off = addr->off + size * (index - addr->type->un.array.start);
|
||||
size = DEBUG_GetObjectSize(value->type->un.array.basictype);
|
||||
result->type = value->type->un.array.basictype;
|
||||
result->addr.off = value->addr.off + size * (index - value->type->un.array.start);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -749,14 +784,16 @@ DEBUG_ArrayIndex(const DBG_ADDR * addr, DBG_ADDR * result, int index)
|
||||
* Implementation of the 'print' command.
|
||||
*/
|
||||
void
|
||||
DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
|
||||
DEBUG_Print( const DBG_VALUE *value, int count, char format, int level )
|
||||
{
|
||||
DBG_ADDR addr1;
|
||||
DBG_VALUE val1;
|
||||
int i;
|
||||
struct member * m;
|
||||
char * pnt;
|
||||
int size;
|
||||
long long int value;
|
||||
int xval;
|
||||
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
@ -764,12 +801,12 @@ DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
|
||||
return;
|
||||
}
|
||||
|
||||
if( addr->type == NULL )
|
||||
if( value->type == NULL )
|
||||
{
|
||||
/* No type, just print the addr value */
|
||||
if (addr->seg && (addr->seg != 0xffffffff))
|
||||
DEBUG_nchar += fprintf( stderr, "0x%04lx: ", addr->seg );
|
||||
DEBUG_nchar += fprintf( stderr, "0x%08lx", addr->off );
|
||||
if (value->addr.seg && (value->addr.seg != 0xffffffff))
|
||||
DEBUG_nchar += fprintf( stderr, "0x%04lx: ", value->addr.seg );
|
||||
DEBUG_nchar += fprintf( stderr, "0x%08lx", value->addr.off );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -790,23 +827,22 @@ DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
|
||||
format = '\0';
|
||||
}
|
||||
|
||||
switch(addr->type->type)
|
||||
switch(value->type->type)
|
||||
{
|
||||
case DT_BASIC:
|
||||
case DT_ENUM:
|
||||
case DT_CONST:
|
||||
case DT_POINTER:
|
||||
DEBUG_PrintBasic(addr, 1, format);
|
||||
DEBUG_PrintBasic(value, 1, format);
|
||||
break;
|
||||
case DT_STRUCT:
|
||||
DEBUG_nchar += fprintf(stderr, "{");
|
||||
for(m = addr->type->un.structure.members; m; m = m->next)
|
||||
for(m = value->type->un.structure.members; m; m = m->next)
|
||||
{
|
||||
addr1 = *addr;
|
||||
DEBUG_FindStructElement(&addr1, m->name,
|
||||
(int *) &value);
|
||||
val1 = *value;
|
||||
DEBUG_FindStructElement(&val1, m->name, &xval);
|
||||
DEBUG_nchar += fprintf(stderr, "%s=", m->name);
|
||||
DEBUG_Print(&addr1, 1, format, level + 1);
|
||||
DEBUG_Print(&val1, 1, format, level + 1);
|
||||
if( m->next != NULL )
|
||||
{
|
||||
DEBUG_nchar += fprintf(stderr, ", ");
|
||||
@ -823,15 +859,15 @@ DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
|
||||
/*
|
||||
* Loop over all of the entries, printing stuff as we go.
|
||||
*/
|
||||
size = DEBUG_GetObjectSize(addr->type->un.array.basictype);
|
||||
size = DEBUG_GetObjectSize(value->type->un.array.basictype);
|
||||
if( size == 1 )
|
||||
{
|
||||
/*
|
||||
* Special handling for character arrays.
|
||||
*/
|
||||
pnt = (char *) addr->off;
|
||||
pnt = (char *) value->addr.off;
|
||||
DEBUG_nchar += fprintf(stderr, "\"");
|
||||
for( i=addr->type->un.array.start; i < addr->type->un.array.end; i++ )
|
||||
for( i=value->type->un.array.start; i < value->type->un.array.end; i++ )
|
||||
{
|
||||
fputc(*pnt++, stderr);
|
||||
DEBUG_nchar++;
|
||||
@ -844,14 +880,14 @@ DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
|
||||
DEBUG_nchar += fprintf(stderr, "\"");
|
||||
break;
|
||||
}
|
||||
addr1 = *addr;
|
||||
addr1.type = addr->type->un.array.basictype;
|
||||
val1 = *value;
|
||||
val1.type = value->type->un.array.basictype;
|
||||
DEBUG_nchar += fprintf(stderr, "{");
|
||||
for( i=addr->type->un.array.start; i <= addr->type->un.array.end; i++ )
|
||||
for( i=value->type->un.array.start; i <= value->type->un.array.end; i++ )
|
||||
{
|
||||
DEBUG_Print(&addr1, 1, format, level + 1);
|
||||
addr1.off += size;
|
||||
if( i == addr->type->un.array.end )
|
||||
DEBUG_Print(&val1, 1, format, level + 1);
|
||||
val1.addr.off += size;
|
||||
if( i == value->type->un.array.end )
|
||||
{
|
||||
DEBUG_nchar += fprintf(stderr, "}");
|
||||
}
|
||||
@ -881,7 +917,7 @@ leave:
|
||||
}
|
||||
|
||||
int
|
||||
DEBUG_DumpTypes()
|
||||
DEBUG_DumpTypes(void)
|
||||
{
|
||||
struct datatype * dt = NULL;
|
||||
struct member * m;
|
||||
@ -980,11 +1016,10 @@ DEBUG_TypeCast(enum debug_type type, const char * name)
|
||||
}
|
||||
|
||||
int
|
||||
DEBUG_PrintTypeCast(struct datatype * dt)
|
||||
DEBUG_PrintTypeCast(const struct datatype * dt)
|
||||
{
|
||||
char * name;
|
||||
const char* name = "none";
|
||||
|
||||
name = "none";
|
||||
if( dt->name != NULL )
|
||||
{
|
||||
name = dt->name;
|
||||
@ -1024,4 +1059,18 @@ DEBUG_PrintTypeCast(struct datatype * dt)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int DEBUG_PrintType( const DBG_VALUE *value )
|
||||
{
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
||||
if (!value->type)
|
||||
{
|
||||
fprintf(stderr, "Unknown type\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (!DEBUG_PrintTypeCast(value->type))
|
||||
return FALSE;
|
||||
fprintf(stderr, "\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -176,12 +176,14 @@ static void DEBUG_InitCurrThread(void)
|
||||
if (!Options.debug) return;
|
||||
|
||||
if (DEBUG_CurrThread->start) {
|
||||
DBG_ADDR addr;
|
||||
DBG_VALUE value;
|
||||
|
||||
DEBUG_SetBreakpoints(FALSE);
|
||||
addr.seg = 0;
|
||||
addr.off = (DWORD)DEBUG_CurrThread->start;
|
||||
DEBUG_AddBreakpoint(&addr);
|
||||
value.type = NULL;
|
||||
value.cookie = DV_TARGET;
|
||||
value.addr.seg = 0;
|
||||
value.addr.off = (DWORD)DEBUG_CurrThread->start;
|
||||
DEBUG_AddBreakpoint(&value);
|
||||
DEBUG_SetBreakpoints(TRUE);
|
||||
} else {
|
||||
DEBUG_CurrThread->wait_for_first_exception = 1;
|
||||
@ -386,6 +388,11 @@ static DWORD CALLBACK DEBUG_MainLoop(DWORD pid)
|
||||
|
||||
DEBUG_InitCurrProcess();
|
||||
DEBUG_InitCurrThread();
|
||||
#ifdef _WE_SUPPORT_THE_STAB_TYPES_USED_BY_MINGW_TOO
|
||||
/* so far, process name is not set */
|
||||
DEBUG_RegisterDebugInfo((DWORD)de.u.CreateProcessInfo.lpBaseOfImage,
|
||||
"wine-exec");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case EXIT_THREAD_DEBUG_EVENT:
|
||||
|
Loading…
x
Reference in New Issue
Block a user