Commit d33bcb61 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

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