From d33bcb61399ad0c2dac0d8fb40e53292d270e317 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Wed, 15 Mar 2000 19:57:20 +0000 Subject: [PATCH] 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). --- debugger/break.c | 592 +++++++++++++++++++++++++++++++++++++++------------ debugger/db_disasm.c | 1 - debugger/dbg.y | 115 ++++++---- debugger/dbgmain.c | 10 +- debugger/debug.l | 7 +- debugger/debugger.h | 99 +++++---- debugger/display.c | 20 +- debugger/expr.c | 168 +++++++-------- debugger/hash.c | 286 +++++++++++++------------ debugger/info.c | 68 +++++- debugger/memory.c | 43 ++-- debugger/msc.c | 114 +++++----- debugger/source.c | 53 ++--- debugger/stabs.c | 82 +++---- debugger/stack.c | 24 +-- debugger/types.c | 223 +++++++++++-------- debugger/winedbg.c | 15 +- 17 files changed, 1188 insertions(+), 732 deletions(-) diff --git a/debugger/break.c b/debugger/break.c index d5fa64345e7..21995057f41 100644 --- a/debugger/break.c +++ b/debugger/break.c @@ -3,13 +3,40 @@ * * Copyright 1994 Martin von Loewis * Copyright 1995 Alexandre Julliard + * Copyright 1999,2000 Eric Pouech */ #include "config.h" #include #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; diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c index e6783a9e1db..9f1a0be3239 100644 --- a/debugger/db_disasm.c +++ b/debugger/db_disasm.c @@ -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; diff --git a/debugger/dbg.y b/debugger/dbg.y index f978d6405d7..516c5058a8a 100644 --- a/debugger/dbg.y +++ b/debugger/dbg.y @@ -4,6 +4,7 @@ * * Copyright 1993 Eric Youngdale * Copyright 1995 Morten Welinder + * Copyright 2000 Eric Pouech */ #include "config.h" @@ -21,8 +22,8 @@ extern FILE * yyin; int curr_frame = 0; -void issue_prompt(void); -void mode_command(int); +static void issue_prompt(void); +static void mode_command(int); void flush_symbols(void); int yylex(void); int yyerror(char *); @@ -31,7 +32,7 @@ int yyerror(char *); %union { - DBG_ADDR address; + DBG_VALUE value; enum debug_regs reg; char * string; int integer; @@ -46,7 +47,7 @@ int yyerror(char *); %token tPROCESS tMODREF %token tEOL tSTRING tDEBUGSTR %token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE -%token tSTEPI tNEXTI tFINISH tSHOW tDIR +%token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS %token tPATH %token tIDENTIFIER tSTRING tDEBUGSTR %token tNUM tFORMAT @@ -77,7 +78,7 @@ int yyerror(char *); %type expr lval lvalue %type type_cast type_expr -%type
expr_addr lval_addr +%type expr_addr lval_addr %type expr_value %type 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; } diff --git a/debugger/dbgmain.c b/debugger/dbgmain.c index aa84e8eda6b..4f2a1fc75d2 100644 --- a/debugger/dbgmain.c +++ b/debugger/dbgmain.c @@ -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; diff --git a/debugger/debug.l b/debugger/debug.l index 26513ed5d80..c0020d00e43 100644 --- a/debugger/debug.l +++ b/debugger/debug.l @@ -131,7 +131,7 @@ $gs { yylval.reg = REG_GS; return tREG; } help|hel|he|"?" { BEGIN(HELP_CMD); return tHELP; } backtrace|backtrac|backtra|backt|back|bac|ba|bt { BEGIN(NOCMD); return tBACKTRACE; } -where|wher|whe { BEGIN(NOCMD); return tBACKTRACE; } +where|wher|whe { BEGIN(NOCMD); return tBACKTRACE; } cont|con|co|c { BEGIN(NOCMD); return tCONT; } pass|pas|pa { BEGIN(NOCMD); return tPASS; } @@ -151,14 +151,15 @@ $gs { yylval.reg = REG_GS; return tREG; } break|brea|bre|br|b { BEGIN(PATH_EXPECTED); return tBREAK; } watch|watc|wat { BEGIN(PATH_EXPECTED); return tWATCH; } +whatis|whati|what { BEGIN(PATH_EXPECTED); return tWHATIS; } share|shar|sha { return tSHARE; } locals|local|loca|loc { return tLOCAL; } class|clas|cla { return tCLASS; } module|modul|modu|mod { return tMODULE; } -queue|queu|que { return tQUEUE; } +queue|queu|que { return tQUEUE; } process|proces|proce|proc { return tPROCESS; } -modref|modre|modr { return tMODREF; } +modref|modre|modr { return tMODREF; } registers|regs|reg|re { return tREGS; } segments|segment|segm|seg|se { return tSEGMENTS; } stack|stac|sta|st { return tSTACK; } diff --git a/debugger/debugger.h b/debugger/debugger.h index 1f3d02c6a16..104bfdebf8a 100644 --- a/debugger/debugger.h +++ b/debugger/debugger.h @@ -8,11 +8,12 @@ #define __WINE_DEBUGGER_H #include /* u_long ... */ +#include #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 */ diff --git a/debugger/display.c b/debugger/display.c index 431a289fe33..80926f99946 100644 --- a/debugger/display.c +++ b/debugger/display.c @@ -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); } diff --git a/debugger/expr.c b/debugger/expr.c index 877a1db5963..298b62c4bc9 100644 --- a/debugger/expr.c +++ b/debugger/expr.c @@ -9,7 +9,6 @@ #include #include #include -#include #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; } diff --git a/debugger/hash.c b/debugger/hash.c index 35aaf6b283a..cd6cd190014 100644 --- a/debugger/hash.c +++ b/debugger/hash.c @@ -55,14 +55,14 @@ struct name_hash int lines_alloc; WineLineNo * linetab; - DBG_ADDR addr; + DBG_VALUE value; unsigned short flags; unsigned short breakpoint_offset; unsigned int symbol_size; }; -static BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr ); +static BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value ); static int sortlist_valid = FALSE; static int sorttab_nsym; @@ -107,22 +107,22 @@ DEBUG_cmp_sym(const void * p1, const void * p2) return 1; } - if( (*name1)->addr.seg > (*name2)->addr.seg ) + if( (*name1)->value.addr.seg > (*name2)->value.addr.seg ) { return 1; } - if( (*name1)->addr.seg < (*name2)->addr.seg ) + if( (*name1)->value.addr.seg < (*name2)->value.addr.seg ) { return -1; } - if( (*name1)->addr.off > (*name2)->addr.off ) + if( (*name1)->value.addr.off > (*name2)->value.addr.off ) { return 1; } - if( (*name1)->addr.off < (*name2)->addr.off ) + if( (*name1)->value.addr.off < (*name2)->value.addr.off ) { return -1; } @@ -137,7 +137,7 @@ DEBUG_cmp_sym(const void * p1, const void * p2) */ static void -DEBUG_ResortSymbols() +DEBUG_ResortSymbols(void) { struct name_hash *nh; int nsym = 0; @@ -185,7 +185,7 @@ DEBUG_ResortSymbols() * Add a symbol to the table. */ struct name_hash * -DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source, +DEBUG_AddSymbol( const char * name, const DBG_VALUE *value, const char * source, int flags) { struct name_hash * new; @@ -195,16 +195,19 @@ DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source, char * c; int hash; + assert(value->cookie == DV_TARGET || value->cookie == DV_HOST); + hash = name_hash(name); for (nh = name_hash_table[hash]; nh; nh = nh->next) { if( ((nh->flags & SYM_INVALID) != 0) && strcmp(name, nh->name) == 0 ) { - nh->addr.off = addr->off; - nh->addr.seg = addr->seg; - if( nh->addr.type == NULL && addr->type != NULL ) + nh->value.addr = value->addr; + + if( nh->value.type == NULL && value->type != NULL ) { - nh->addr.type = addr->type; + nh->value.type = value->type; + nh->value.cookie = value->cookie; } /* it may happen that the same symbol is defined in several compilation * units, but the linker decides to merge it into a single instance. @@ -213,10 +216,11 @@ DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source, */ if ((flags & SYM_INVALID) == 0) nh->flags &= ~SYM_INVALID; + return nh; } - if (nh->addr.seg == addr->seg && - nh->addr.off == addr->off && + if (nh->value.addr.seg == value->addr.seg && + nh->value.addr.off == value->addr.off && strcmp(name, nh->name) == 0 ) { return nh; @@ -229,7 +233,7 @@ DEBUG_AddSymbol( const char * name, const DBG_ADDR *addr, const char * source, */ new = (struct name_hash *) DBG_alloc(sizeof(struct name_hash)); - new->addr = *addr; + new->value = *value; new->name = DBG_strdup(name); if( source != NULL ) @@ -334,7 +338,7 @@ BOOL DEBUG_Normalize(struct name_hash * nh ) * Get the address of a named symbol. */ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno, - DBG_ADDR *addr, int bp_flag ) + DBG_VALUE *value, int bp_flag ) { char buffer[256]; struct name_hash *nh; @@ -371,10 +375,12 @@ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno, */ if (!nh) { - return DEBUG_GetStackSymbolValue(name, addr); + return DEBUG_GetStackSymbolValue(name, value); } - return DEBUG_GetLineNumberAddr( nh, lineno, addr, bp_flag ); + value->type = nh->value.type; + value->cookie = nh->value.cookie; + return DEBUG_GetLineNumberAddr( nh, lineno, &value->addr, bp_flag ); } /*********************************************************************** @@ -383,13 +389,13 @@ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno, * Get the address of a named symbol. */ BOOL DEBUG_GetLineNumberAddr( struct name_hash * nh, const int lineno, - DBG_ADDR *addr, int bp_flag ) + DBG_ADDR *addr, int bp_flag ) { int i; if( lineno == -1 ) { - *addr = nh->addr; + *addr = nh->value.addr; if( bp_flag ) { addr->off += nh->breakpoint_offset; @@ -430,11 +436,13 @@ BOOL DEBUG_GetLineNumberAddr( struct name_hash * nh, const int lineno, * * Set the address of a named symbol. */ -BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr ) +BOOL DEBUG_SetSymbolValue( const char * name, const DBG_VALUE *value ) { char buffer[256]; struct name_hash *nh; + assert(value->cookie == DV_TARGET || value->cookie == DV_HOST); + for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next) if (!strcmp(nh->name, name)) break; @@ -447,9 +455,9 @@ BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr ) } if (!nh) return FALSE; - nh->addr = *addr; - nh->flags &= SYM_INVALID; - DEBUG_FixAddress( &nh->addr, DEBUG_context.SegDs ); + nh->value = *value; + nh->flags &= ~SYM_INVALID; + DEBUG_FixAddress( &nh->value.addr, DEBUG_context.SegDs ); return TRUE; } @@ -510,15 +518,15 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, */ low = 0; high = sorttab_nsym; - if( addr_sorttab[0]->addr.seg > addr->seg - || ( addr_sorttab[0]->addr.seg == addr->seg - && addr_sorttab[0]->addr.off > addr->off) ) + if( addr_sorttab[0]->value.addr.seg > addr->seg + || ( addr_sorttab[0]->value.addr.seg == addr->seg + && addr_sorttab[0]->value.addr.off > addr->off) ) { nearest = NULL; } - else if( addr_sorttab[high - 1]->addr.seg < addr->seg - || ( addr_sorttab[high - 1]->addr.seg == addr->seg - && addr_sorttab[high - 1]->addr.off < addr->off) ) + else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg + || ( addr_sorttab[high - 1]->value.addr.seg == addr->seg + && addr_sorttab[high - 1]->value.addr.off < addr->off) ) { nearest = addr_sorttab[high - 1]; } @@ -536,10 +544,10 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, */ if( mid > 0 && addr_sorttab[mid]->linetab == NULL ) { - if( (addr_sorttab[mid - 1]->addr.seg == - addr_sorttab[mid]->addr.seg) - && (addr_sorttab[mid - 1]->addr.off == - addr_sorttab[mid]->addr.off) + if( (addr_sorttab[mid - 1]->value.addr.seg == + addr_sorttab[mid]->value.addr.seg) + && (addr_sorttab[mid - 1]->value.addr.off == + addr_sorttab[mid]->value.addr.off) && (addr_sorttab[mid - 1]->linetab != NULL) ) { mid--; @@ -549,10 +557,10 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, if( (mid < sorttab_nsym - 1) && (addr_sorttab[mid]->linetab == NULL) ) { - if( (addr_sorttab[mid + 1]->addr.seg == - addr_sorttab[mid]->addr.seg) - && (addr_sorttab[mid + 1]->addr.off == - addr_sorttab[mid]->addr.off) + if( (addr_sorttab[mid + 1]->value.addr.seg == + addr_sorttab[mid]->value.addr.seg) + && (addr_sorttab[mid + 1]->value.addr.off == + addr_sorttab[mid]->value.addr.off) && (addr_sorttab[mid + 1]->linetab != NULL) ) { mid++; @@ -561,17 +569,17 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, nearest = addr_sorttab[mid]; #if 0 fprintf(stderr, "Found %x:%x when looking for %x:%x %x %s\n", - addr_sorttab[mid ]->addr.seg, - addr_sorttab[mid ]->addr.off, + addr_sorttab[mid ]->value.addr.seg, + addr_sorttab[mid ]->value.addr.off, addr->seg, addr->off, addr_sorttab[mid ]->linetab, addr_sorttab[mid ]->name); #endif break; } - if( (addr_sorttab[mid]->addr.seg < addr->seg) - || ( addr_sorttab[mid]->addr.seg == addr->seg - && addr_sorttab[mid]->addr.off <= addr->off) ) + if( (addr_sorttab[mid]->value.addr.seg < addr->seg) + || ( addr_sorttab[mid]->value.addr.seg == addr->seg + && addr_sorttab[mid]->value.addr.off <= addr->off) ) { low = mid; } @@ -649,7 +657,7 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, } if( (nearest->sourcefile != NULL) && (flag == TRUE) - && (addr->off - nearest->addr.off < 0x100000) ) + && (addr->off - nearest->value.addr.off < 0x100000) ) { /* @@ -685,24 +693,24 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, if (!sourcefile) sourcefile = nearest->sourcefile; else sourcefile++; - if (addr->off == nearest->addr.off) + if (addr->off == nearest->value.addr.off) sprintf( name_buffer, "%s%s [%s%s]", nearest->name, arglist, sourcefile, lineinfo); else sprintf( name_buffer, "%s+0x%lx%s [%s%s]", nearest->name, - addr->off - nearest->addr.off, + addr->off - nearest->value.addr.off, arglist, sourcefile, lineinfo ); } else { - if (addr->off == nearest->addr.off) + if (addr->off == nearest->value.addr.off) sprintf( name_buffer, "%s%s", nearest->name, arglist); else { - if (addr->seg && (nearest->addr.seg!=addr->seg)) + if (addr->seg && (nearest->value.addr.seg!=addr->seg)) return NULL; else sprintf( name_buffer, "%s+0x%lx%s", nearest->name, - addr->off - nearest->addr.off, arglist); + addr->off - nearest->value.addr.off, arglist); } } return name_buffer; @@ -717,7 +725,7 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, void DEBUG_ReadSymbolTable( const char * filename ) { FILE * symbolfile; - DBG_ADDR addr = { 0, 0 }; + DBG_VALUE value; int nargs; char type; char * cpnt; @@ -732,6 +740,11 @@ void DEBUG_ReadSymbolTable( const char * filename ) fprintf( stderr, "Reading symbols from file %s\n", filename ); + value.type = NULL; + value.addr.seg = 0; + value.addr.off = 0; + value.cookie = DV_TARGET; + while (1) { fgets( buffer, sizeof(buffer), symbolfile ); @@ -751,8 +764,8 @@ void DEBUG_ReadSymbolTable( const char * filename ) } if (!(*cpnt) || *cpnt == '\n') continue; - nargs = sscanf(buffer, "%lx %c %s", &addr.off, &type, name); - DEBUG_AddSymbol( name, &addr, NULL, SYM_WINE ); + nargs = sscanf(buffer, "%lx %c %s", &value.addr.off, &type, name); + DEBUG_AddSymbol( name, &value, NULL, SYM_WINE ); } fclose(symbolfile); } @@ -766,23 +779,27 @@ void DEBUG_ReadSymbolTable( const char * filename ) static void DEBUG_LoadEntryPoints16( HMODULE16 hModule, NE_MODULE *pModule, const char *name ) { - DBG_ADDR addr; - char buffer[256]; - FARPROC16 address; + DBG_VALUE value; + char buffer[256]; + FARPROC16 address; + unsigned char *cpnt = (unsigned char *)pModule + pModule->name_table; + + value.type = NULL; + value.cookie = DV_TARGET; + value.addr.seg = 0; + value.addr.off = 0; /* First search the resident names */ - unsigned char *cpnt = (unsigned char *)pModule + pModule->name_table; while (*cpnt) { cpnt += *cpnt + 1 + sizeof(WORD); sprintf( buffer, "%s.%.*s", name, *cpnt, cpnt + 1 ); if ((address = NE_GetEntryPoint(hModule, *(WORD *)(cpnt + *cpnt + 1)))) { - addr.seg = HIWORD(address); - addr.off = LOWORD(address); - addr.type = NULL; - DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC ); + value.addr.seg = HIWORD(address); + value.addr.off = LOWORD(address); + DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC ); } } @@ -796,10 +813,9 @@ static void DEBUG_LoadEntryPoints16( HMODULE16 hModule, NE_MODULE *pModule, sprintf( buffer, "%s.%.*s", name, *cpnt, cpnt + 1 ); if ((address = NE_GetEntryPoint(hModule, *(WORD *)(cpnt + *cpnt + 1)))) { - addr.seg = HIWORD(address); - addr.off = LOWORD(address); - addr.type = NULL; - DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC ); + value.addr.seg = HIWORD(address); + value.addr.off = LOWORD(address); + DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC ); } } } @@ -814,7 +830,7 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name ) { #define RVA(x) (hModule+(DWORD)(x)) - DBG_ADDR addr; + DBG_VALUE value; char buffer[256]; int i, j; IMAGE_SECTION_HEADER *pe_seg; @@ -823,20 +839,22 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name ) WORD *ordinals; void **functions; const char **names; - - addr.seg = 0; - addr.type = NULL; + + value.type = NULL; + value.cookie = DV_TARGET; + value.addr.seg = 0; + value.addr.off = 0; /* Add start of DLL */ - addr.off = hModule; - DEBUG_AddSymbol( name, &addr, NULL, SYM_WIN32 | SYM_FUNC ); + value.addr.off = hModule; + DEBUG_AddSymbol( name, &value, NULL, SYM_WIN32 | SYM_FUNC ); /* Add entry point */ sprintf( buffer, "%s.EntryPoint", name ); - addr.off = (DWORD)RVA_PTR( hModule, OptionalHeader.AddressOfEntryPoint ); - DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC ); + value.addr.off = (DWORD)RVA_PTR( hModule, OptionalHeader.AddressOfEntryPoint ); + DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC ); /* Add start of sections */ @@ -844,8 +862,8 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name ) for (i = 0; i < PE_HEADER(hModule)->FileHeader.NumberOfSections; i++) { sprintf( buffer, "%s.%s", name, pe_seg->Name ); - addr.off = RVA(pe_seg->VirtualAddress ); - DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC ); + value.addr.off = RVA(pe_seg->VirtualAddress ); + DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC ); pe_seg++; } @@ -864,8 +882,8 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name ) { if (!names[i]) continue; sprintf( buffer, "%s.%s", name, (char *)RVA(names[i]) ); - addr.off = RVA( functions[ordinals[i]] ); - DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC ); + value.addr.off = RVA( functions[ordinals[i]] ); + DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC ); } for (i = 0; i < exports->NumberOfFunctions; i++) @@ -876,8 +894,8 @@ static void DEBUG_LoadEntryPoints32( HMODULE hModule, const char *name ) if ((ordinals[j] == i) && names[j]) break; if (j < exports->NumberOfNames) continue; sprintf( buffer, "%s.%ld", name, i + exports->Base ); - addr.off = (DWORD)RVA( functions[i] ); - DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC ); + value.addr.off = (DWORD)RVA( functions[i] ); + DEBUG_AddSymbol( buffer, &value, NULL, SYM_WIN32 | SYM_FUNC ); } } DEBUG_RegisterDebugInfo(hModule, name); @@ -969,7 +987,8 @@ int DEBUG_LoadEntryPoints(const char* pfx) BOOL ok; WINE_MODREF*wm; DBG_LEPData lep; - + PDB* current = PROCESS_Current(); + lep.first = 0; lep.pfx = pfx; @@ -983,7 +1002,7 @@ int DEBUG_LoadEntryPoints(const char* pfx) DEBUG_LoadEntryPoints16( entry.hModule, pModule, entry.szModule ); } - for (wm=PROCESS_Current()->modref_list;wm;wm=wm->next) + for (wm = current->modref_list; wm; wm=wm->next) { if ((wm->flags & WINE_MODREF_INTERNAL)) { @@ -992,7 +1011,7 @@ int DEBUG_LoadEntryPoints(const char* pfx) } } if (lep.first) fprintf( stderr, " $"); - for (wm=PROCESS_Current()->modref_list;wm;wm=wm->next) + for (wm = current->modref_list; wm; wm=wm->next) { if (!(wm->flags & WINE_MODREF_INTERNAL)) { @@ -1022,9 +1041,8 @@ DEBUG_AddLineNumber( struct name_hash * func, int line_num, } func->linetab[func->n_lines].line_number = line_num; - func->linetab[func->n_lines].pc_offset.seg = func->addr.seg; - func->linetab[func->n_lines].pc_offset.off = func->addr.off + offset; - func->linetab[func->n_lines].pc_offset.type = NULL; + func->linetab[func->n_lines].pc_offset.seg = func->value.addr.seg; + func->linetab[func->n_lines].pc_offset.off = func->value.addr.off + offset; func->n_lines++; } @@ -1060,7 +1078,7 @@ DEBUG_AddLocal( struct name_hash * func, int regno, } void -DEBUG_DumpHashInfo() +DEBUG_DumpHashInfo(void) { int i; int depth; @@ -1102,15 +1120,15 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr) */ low = 0; high = sorttab_nsym; - if( addr_sorttab[0]->addr.seg > addr->seg - || ( addr_sorttab[0]->addr.seg == addr->seg - && addr_sorttab[0]->addr.off > addr->off) ) + if( addr_sorttab[0]->value.addr.seg > addr->seg + || ( addr_sorttab[0]->value.addr.seg == addr->seg + && addr_sorttab[0]->value.addr.off > addr->off) ) { nearest = NULL; } - else if( addr_sorttab[high - 1]->addr.seg < addr->seg - || ( addr_sorttab[high - 1]->addr.seg == addr->seg - && addr_sorttab[high - 1]->addr.off < addr->off) ) + else if( addr_sorttab[high - 1]->value.addr.seg < addr->seg + || ( addr_sorttab[high - 1]->value.addr.seg == addr->seg + && addr_sorttab[high - 1]->value.addr.off < addr->off) ) { nearest = addr_sorttab[high - 1]; } @@ -1128,10 +1146,10 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr) */ if( mid > 0 && addr_sorttab[mid]->linetab == NULL ) { - if( (addr_sorttab[mid - 1]->addr.seg == - addr_sorttab[mid]->addr.seg) - && (addr_sorttab[mid - 1]->addr.off == - addr_sorttab[mid]->addr.off) + if( (addr_sorttab[mid - 1]->value.addr.seg == + addr_sorttab[mid]->value.addr.seg) + && (addr_sorttab[mid - 1]->value.addr.off == + addr_sorttab[mid]->value.addr.off) && (addr_sorttab[mid - 1]->linetab != NULL) ) { mid--; @@ -1141,10 +1159,10 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr) if( (mid < sorttab_nsym - 1) && (addr_sorttab[mid]->linetab == NULL) ) { - if( (addr_sorttab[mid + 1]->addr.seg == - addr_sorttab[mid]->addr.seg) - && (addr_sorttab[mid + 1]->addr.off == - addr_sorttab[mid]->addr.off) + if( (addr_sorttab[mid + 1]->value.addr.seg == + addr_sorttab[mid]->value.addr.seg) + && (addr_sorttab[mid + 1]->value.addr.off == + addr_sorttab[mid]->value.addr.off) && (addr_sorttab[mid + 1]->linetab != NULL) ) { mid++; @@ -1153,17 +1171,17 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr) nearest = addr_sorttab[mid]; #if 0 fprintf(stderr, "Found %x:%x when looking for %x:%x %x %s\n", - addr_sorttab[mid ]->addr.seg, - addr_sorttab[mid ]->addr.off, + addr_sorttab[mid ]->value.addr.seg, + addr_sorttab[mid ]->value.addr.off, addr->seg, addr->off, addr_sorttab[mid ]->linetab, addr_sorttab[mid ]->name); #endif break; } - if( (addr_sorttab[mid]->addr.seg < addr->seg) - || ( addr_sorttab[mid]->addr.seg == addr->seg - && addr_sorttab[mid]->addr.off <= addr->off) ) + if( (addr_sorttab[mid]->value.addr.seg < addr->seg) + || ( addr_sorttab[mid]->value.addr.seg == addr->seg + && addr_sorttab[mid]->value.addr.off <= addr->off) ) { low = mid; } @@ -1206,13 +1224,13 @@ int DEBUG_CheckLinenoStatus( const DBG_ADDR *addr) * until it gets past the function prologue. We only do this if there * is more than one line number for the function, of course. */ - if( nearest->addr.off == addr->off && nearest->n_lines > 1 ) + if( nearest->value.addr.off == addr->off && nearest->n_lines > 1 ) { return NOT_ON_LINENUMBER; } if( (nearest->sourcefile != NULL) - && (addr->off - nearest->addr.off < 0x100000) ) + && (addr->off - nearest->value.addr.off < 0x100000) ) { low = 0; high = nearest->n_lines; @@ -1327,7 +1345,7 @@ DEBUG_GetFuncInfo( struct list_id * ret, const char * filename, * Get the address of a named symbol from the current stack frame. */ static -BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr ) +BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_VALUE *value ) { struct name_hash * curr_func; unsigned int ebp; @@ -1346,14 +1364,14 @@ BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr ) * comes up with RBRAC/LBRAC stabs in particular. */ if( (curr_func->local_vars[i].pc_start != 0) - && ((eip - curr_func->addr.off) + && ((eip - curr_func->value.addr.off) < curr_func->local_vars[i].pc_start) ) { continue; } if( (curr_func->local_vars[i].pc_end != 0) - && ((eip - curr_func->addr.off) + && ((eip - curr_func->value.addr.off) > curr_func->local_vars[i].pc_end) ) { continue; @@ -1364,44 +1382,32 @@ BOOL DEBUG_GetStackSymbolValue( const char * name, DBG_ADDR *addr ) /* * OK, we found it. Now figure out what to do with this. */ - /* FIXME: what if regno == 0 ($eax) */ if( curr_func->local_vars[i].regno != 0 ) { -#if 0 - /* FIXME: NEWDBG NIY */ - /* this is a hack: addr points to the current processor context - * (as defined while entering the debugger), and uses a pointer - * to main memory (thus sharing the process address space *AND* - * the debugger address space, which is not good with address - * space separation in place) - */ /* * Register variable. Point to DEBUG_context field. */ - addr->seg = 0; - addr->off = ((DWORD)DEBUG_context) + reg_ofs[curr_func->local_vars[i].regno]; - addr->type = curr_func->local_vars[i].type; -#else - fprintf(stderr, "No longer supported: value of register variable\n"); - addr->seg = 0; - addr->off = 0; - addr->type = NULL; -#endif - return TRUE; + value->addr.off = ((DWORD)&DEBUG_context) + + reg_ofs[curr_func->local_vars[i].regno - 1]; + value->cookie = DV_HOST; } - - addr->seg = 0; - addr->off = ebp + curr_func->local_vars[i].offset; - addr->type = curr_func->local_vars[i].type; + else + { + value->addr.off = ebp + curr_func->local_vars[i].offset; + value->cookie = DV_TARGET; + } + value->addr.seg = 0; + value->type = curr_func->local_vars[i].type; return TRUE; } } + return FALSE; } int -DEBUG_InfoLocals() +DEBUG_InfoLocals(void) { struct name_hash * curr_func; unsigned int ebp; @@ -1422,26 +1428,26 @@ DEBUG_InfoLocals() * comes up with RBRAC/LBRAC stabs in particular. */ if( (curr_func->local_vars[i].pc_start != 0) - && ((eip - curr_func->addr.off) + && ((eip - curr_func->value.addr.off) < curr_func->local_vars[i].pc_start) ) { continue; } if( (curr_func->local_vars[i].pc_end != 0) - && ((eip - curr_func->addr.off) + && ((eip - curr_func->value.addr.off) > curr_func->local_vars[i].pc_end) ) { continue; } - if( curr_func->local_vars[i].offset == 0 ) + if( curr_func->local_vars[i].regno != 0 ) { - ptr = (unsigned int *) (((DWORD)&DEBUG_context) - + reg_ofs[curr_func->local_vars[i].regno]); + ptr = (unsigned int *)(((DWORD)&DEBUG_context) + + reg_ofs[curr_func->local_vars[i].regno - 1]); fprintf(stderr, "%s:%s (optimized into register $%s) == 0x%8.8x\n", curr_func->name, curr_func->local_vars[i].name, - reg_name[curr_func->local_vars[i].regno], + reg_name[curr_func->local_vars[i].regno - 1], *ptr); } else @@ -1476,7 +1482,7 @@ int DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr) { - *addr = sym->addr; + *addr = sym->value.addr; return TRUE; } diff --git a/debugger/info.c b/debugger/info.c index 2a6e00b33bf..7f1f64f0705 100644 --- a/debugger/info.c +++ b/debugger/info.c @@ -8,6 +8,7 @@ #include "config.h" #include #include +#include #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 undisplay ", " delete display debugmsg [-+]\n", " mode [16,32] walk [wnd,class,queue,module,", -" process,modref ]", +" whatis process,modref ]", " info (see 'help info' for options)\n", "The 'x' command accepts repeat counts and formats (including 'i') in the", diff --git a/debugger/memory.c b/debugger/memory.c index 07759eee804..3a75dd39d4f 100644 --- a/debugger/memory.c +++ b/debugger/memory.c @@ -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; idbg_mode, FALSE );\ + DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, FALSE );\ fprintf(stderr,": ");\ } \ } \ diff --git a/debugger/msc.c b/debugger/msc.c index 5f134a9caf4..8842f34fe5d 100644 --- a/debugger/msc.c +++ b/debugger/msc.c @@ -1249,7 +1249,7 @@ DEBUG_ParseTypeTable(char * table, int len) } void -DEBUG_InitCVDataTypes() +DEBUG_InitCVDataTypes(void) { /* * These are the common builtin types that are used by VC++. @@ -1505,7 +1505,7 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) char namebuff[9]; char * nampnt; int naux; - DBG_ADDR new_addr; + DBG_VALUE new_value; int nfiles = 0; int nfiles_alloc = 0; struct CoffFiles orig_file; @@ -1520,6 +1520,9 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) linetab_indx = 0; + new_value.cookie = DV_TARGET; + new_value.type = NULL; + for(i=0; i < coff->N_Sym; i++ ) { /* @@ -1675,8 +1678,8 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) nampnt++; } - new_addr.seg = 0; - new_addr.off = (int) (deefer->load_addr + coff_sym->Value); + new_value.addr.seg = 0; + new_value.addr.off = (int) (deefer->load_addr + coff_sym->Value); if( curr_file->neps + 1 >= curr_file->neps_alloc ) { @@ -1689,7 +1692,7 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) fprintf(stderr,"\tAdding static symbol %s\n", nampnt); #endif curr_file->entries[curr_file->neps++] = - DEBUG_AddSymbol( nampnt, &new_addr, this_file, SYM_WIN32 ); + DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 ); i += naux; continue; } @@ -1715,11 +1718,11 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) nampnt++; } - new_addr.seg = 0; - new_addr.off = (int) (deefer->load_addr + coff_sym->Value); + new_value.addr.seg = 0; + new_value.addr.off = (int) (deefer->load_addr + coff_sym->Value); #if 0 - fprintf(stderr, "%d: %x %s\n", i, new_addr.off, nampnt); + fprintf(stderr, "%d: %x %s\n", i, new_value.addr.off, nampnt); fprintf(stderr,"\tAdding global symbol %s\n", nampnt); #endif @@ -1745,7 +1748,7 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) coff_files[j].neps_alloc * sizeof(struct name_hash *)); } coff_files[j].entries[coff_files[j].neps++] = - DEBUG_AddSymbol( nampnt, &new_addr, this_file, SYM_WIN32 ); + DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 ); i += naux; continue; } @@ -1774,11 +1777,11 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) nampnt++; } - new_addr.seg = 0; - new_addr.off = (int) (deefer->load_addr + coff_sym->Value); + new_value.addr.seg = 0; + new_value.addr.off = (int) (deefer->load_addr + coff_sym->Value); #if 0 - fprintf(stderr, "%d: %x %s\n", i, new_addr.off, nampnt); + fprintf(stderr, "%d: %x %s\n", i, new_value.addr.off, nampnt); fprintf(stderr,"\tAdding global data symbol %s\n", nampnt); #endif @@ -1786,7 +1789,7 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) /* * Now we need to figure out which file this guy belongs to. */ - DEBUG_AddSymbol( nampnt, &new_addr, NULL, SYM_WIN32 ); + DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 ); i += naux; continue; } @@ -1856,9 +1859,9 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) while(TRUE) { if (i+1 >= coff_files[j].neps) break; - DEBUG_GetSymbolAddr(coff_files[j].entries[i+1], &new_addr); + DEBUG_GetSymbolAddr(coff_files[j].entries[i+1], &new_value.addr); if( (((unsigned int)deefer->load_addr + - linepnt->VirtualAddr) >= new_addr.off) ) + linepnt->VirtualAddr) >= new_value.addr.off) ) { i++; } else break; @@ -1869,12 +1872,12 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) * start of the function, so we need to subtract that offset * first. */ - DEBUG_GetSymbolAddr(coff_files[j].entries[i], &new_addr); + DEBUG_GetSymbolAddr(coff_files[j].entries[i], &new_value.addr); DEBUG_AddLineNumber(coff_files[j].entries[i], linepnt->Linenum, (unsigned int) deefer->load_addr + linepnt->VirtualAddr - - new_addr.off); + - new_value.addr.off); } } } @@ -2013,7 +2016,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, int i; int j; int len; - DBG_ADDR new_addr; + DBG_VALUE new_value; int nsect; union any_size ptr; IMAGE_SECTION_HEADER * sectp; @@ -2070,12 +2073,13 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, */ memcpy(symname, sym->data.name, sym->data.namelen); - new_addr.seg = 0; - new_addr.type = DEBUG_GetCVType(sym->data.symtype); - new_addr.off = (unsigned int) deefer->load_addr + - sectp[sym->data.seg - 1].VirtualAddress + - sym->data.offset; - DEBUG_AddSymbol( symname, &new_addr, NULL, SYM_WIN32 | SYM_DATA ); + new_value.addr.seg = 0; + new_value.type = DEBUG_GetCVType(sym->data.symtype); + new_value.addr.off = (unsigned int) deefer->load_addr + + sectp[sym->data.seg - 1].VirtualAddress + + sym->data.offset; + new_value.cookie = DV_TARGET; + DEBUG_AddSymbol( symname, &new_value, NULL, SYM_WIN32 | SYM_DATA ); break; case S_GDATA_32: case S_LDATA_32: @@ -2099,12 +2103,13 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, */ memcpy(symname, sym->data32.name, sym->data32.namelen); - new_addr.seg = 0; - new_addr.type = DEBUG_GetCVType(sym->data32.symtype); - new_addr.off = (unsigned int) deefer->load_addr + - sectp[sym->data32.seg - 1].VirtualAddress + - sym->data32.offset; - DEBUG_AddSymbol( symname, &new_addr, NULL, SYM_WIN32 | SYM_DATA ); + new_value.addr.seg = 0; + new_value.type = DEBUG_GetCVType(sym->data32.symtype); + new_value.addr.off = (unsigned int) deefer->load_addr + + sectp[sym->data32.seg - 1].VirtualAddress + + sym->data32.offset; + new_value.cookie = DV_TARGET; + DEBUG_AddSymbol( symname, &new_value, NULL, SYM_WIN32 | SYM_DATA ); break; case S_THUNK: /* @@ -2113,12 +2118,13 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, * a PLT slot in the normal jargon that everyone else uses. */ memcpy(symname, sym->thunk.name, sym->thunk.namelen); - new_addr.seg = 0; - new_addr.type = NULL; - new_addr.off = (unsigned int) deefer->load_addr + - sectp[sym->thunk.segment - 1].VirtualAddress + - sym->thunk.offset; - thunk_sym = DEBUG_AddSymbol( symname, &new_addr, NULL, + new_value.addr.seg = 0; + new_value.type = NULL; + new_value.addr.off = (unsigned int) deefer->load_addr + + sectp[sym->thunk.segment - 1].VirtualAddress + + sym->thunk.offset; + new_value.cookie = DV_TARGET; + thunk_sym = DEBUG_AddSymbol( symname, &new_value, NULL, SYM_WIN32 | SYM_FUNC); DEBUG_SetSymbolSize(thunk_sym, sym->thunk.thunk_len); break; @@ -2128,11 +2134,12 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, * Global and static functions. */ memcpy(symname, sym->proc.name, sym->proc.namelen); - new_addr.seg = 0; - new_addr.type = DEBUG_GetCVType(sym->proc.proctype); - new_addr.off = (unsigned int) deefer->load_addr + - sectp[sym->proc.segment - 1].VirtualAddress + - sym->proc.offset; + new_value.addr.seg = 0; + new_value.type = DEBUG_GetCVType(sym->proc.proctype); + new_value.addr.off = (unsigned int) deefer->load_addr + + sectp[sym->proc.segment - 1].VirtualAddress + + sym->proc.offset; + new_value.cookie = DV_TARGET; /* * See if we can find a segment that this goes with. If so, * it means that we also may have line number information @@ -2142,10 +2149,10 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, { if( ((unsigned int) deefer->load_addr + sectp[linetab[i].segno - 1].VirtualAddress - + linetab[i].start <= new_addr.off) + + linetab[i].start <= new_value.addr.off) && ((unsigned int) deefer->load_addr + sectp[linetab[i].segno - 1].VirtualAddress - + linetab[i].end > new_addr.off) ) + + linetab[i].end > new_value.addr.off) ) { break; } @@ -2154,7 +2161,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, DEBUG_Normalize(curr_func); if( !linetab || linetab[i].linetab == NULL ) { - curr_func = DEBUG_AddSymbol( symname, &new_addr, NULL, + curr_func = DEBUG_AddSymbol( symname, &new_value, NULL, SYM_WIN32 | SYM_FUNC); } else @@ -2164,7 +2171,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, * and add whatever line numbers are appropriate for this * function. */ - curr_func = DEBUG_AddSymbol( symname, &new_addr, + curr_func = DEBUG_AddSymbol( symname, &new_value, linetab[i].sourcefile, SYM_WIN32 | SYM_FUNC); for(j=0; j < linetab[i].nline; j++) @@ -2193,11 +2200,12 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, * Global and static functions. */ memcpy(symname, sym->proc32.name, sym->proc32.namelen); - new_addr.seg = 0; - new_addr.type = DEBUG_GetCVType(sym->proc32.proctype); - new_addr.off = (unsigned int) deefer->load_addr + + new_value.addr.seg = 0; + new_value.type = DEBUG_GetCVType(sym->proc32.proctype); + new_value.addr.off = (unsigned int) deefer->load_addr + sectp[sym->proc32.segment - 1].VirtualAddress + sym->proc32.offset; + new_value.cookie = DV_TARGET; /* * See if we can find a segment that this goes with. If so, * it means that we also may have line number information @@ -2207,10 +2215,10 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, { if( ((unsigned int) deefer->load_addr + sectp[linetab[i].segno - 1].VirtualAddress - + linetab[i].start <= new_addr.off) + + linetab[i].start <= new_value.addr.off) && ((unsigned int) deefer->load_addr + sectp[linetab[i].segno - 1].VirtualAddress - + linetab[i].end > new_addr.off) ) + + linetab[i].end > new_value.addr.off) ) { break; } @@ -2219,7 +2227,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, DEBUG_Normalize(curr_func); if( !linetab || linetab[i].linetab == NULL ) { - curr_func = DEBUG_AddSymbol( symname, &new_addr, NULL, + curr_func = DEBUG_AddSymbol( symname, &new_value, NULL, SYM_WIN32 | SYM_FUNC); } else @@ -2229,7 +2237,7 @@ DEBUG_SnarfCodeView( struct deferred_debug_info * deefer, * and add whatever line numbers are appropriate for this * function. */ - curr_func = DEBUG_AddSymbol( symname, &new_addr, + curr_func = DEBUG_AddSymbol( symname, &new_value, linetab[i].sourcefile, SYM_WIN32 | SYM_FUNC); for(j=0; j < linetab[i].nline; j++) @@ -2970,7 +2978,7 @@ leave: } int -DEBUG_ProcessDeferredDebug() +DEBUG_ProcessDeferredDebug(void) { struct deferred_debug_info * deefer; struct CodeViewDebug * cvd; diff --git a/debugger/source.c b/debugger/source.c index 0b7e7c6ce18..1f212c3d0ab 100644 --- a/debugger/source.c +++ b/debugger/source.c @@ -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 #include #include #include @@ -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 diff --git a/debugger/stack.c b/debugger/stack.c index 46a2d1d1000..07f2a958488 100644 --- a/debugger/stack.c +++ b/debugger/stack.c @@ -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; diff --git a/debugger/types.c b/debugger/types.c index c827866c041..676911fad2a 100644 --- a/debugger/types.c +++ b/debugger/types.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -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; +} diff --git a/debugger/winedbg.c b/debugger/winedbg.c index 702cb1bfa96..f98a80c16d9 100644 --- a/debugger/winedbg.c +++ b/debugger/winedbg.c @@ -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: -- 2.11.4.GIT