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