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).

diff --git a/debugger/break.c b/debugger/break.c
index d5fa643..2199505 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 <stdio.h>
 #include "debugger.h"
 
+#ifdef __i386__
+#define DR7_CONTROL_SHIFT	16
+#define DR7_CONTROL_SIZE 	4
+
+#define DR7_RW_EXECUTE 		(0x0)
+#define DR7_RW_WRITE		(0x1)
+#define DR7_RW_READ		(0x3)
+
+#define DR7_LEN_1		(0x0)
+#define DR7_LEN_2		(0x4)
+#define DR7_LEN_4		(0xC)
+
+#define DR7_LOCAL_ENABLE_SHIFT	0
+#define DR7_GLOBAL_ENABLE_SHIFT 1
+#define DR7_ENABLE_SIZE 	2
+
+#define DR7_LOCAL_ENABLE_MASK	(0x55)
+#define DR7_GLOBAL_ENABLE_MASK	(0xAA)
+
+#define DR7_CONTROL_RESERVED	(0xFC00)
+#define DR7_LOCAL_SLOWDOWN	(0x100)
+#define DR7_GLOBAL_SLOWDOWN	(0x200)
+
+#define	DR7_ENABLE_MASK(dr)	(1<<(DR7_LOCAL_ENABLE_SHIFT+DR7_ENABLE_SIZE*(dr)))
+#define	IS_DR7_SET(ctrl,dr) 	((ctrl)&DR7_ENABLE_MASK(dr))
 #define INT3          0xcc   /* int 3 opcode */
+#endif
 
 #define MAX_BREAKPOINTS 100
 
@@ -17,7 +44,6 @@
 
 static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */
 
-
 /***********************************************************************
  *           DEBUG_IsStepOverInstr
  *
@@ -122,7 +148,7 @@
     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 @@
  */
 void DEBUG_SetBreakpoints( BOOL set )
 {
-    int 	i;
-    char	ch;
+   int		i;
+   
+#ifdef __i386__
+   DEBUG_context.Dr7 &= ~DR7_LOCAL_ENABLE_MASK;
+#endif
+   
+   for (i = 0; i < next_bp; i++)
+   {
+      if (!(breakpoints[i].refcount && breakpoints[i].enabled))
+	 continue;
+      
+      switch (breakpoints[i].type) {
+      case DBG_BREAK:
+	 {
+#ifdef __i386__
+	    char ch = set ? INT3 : breakpoints[i].u.opcode;
+#endif
+	    
+	    if (!DEBUG_WRITE_MEM( (void*)DEBUG_ToLinear(&breakpoints[i].addr), 
+				  &ch, sizeof(ch) ))
+	    {
+	       fprintf(stderr, "Invalid address for breakpoint %d, disabling it\n", i);
+	       breakpoints[i].enabled = FALSE;
+	    }
+	 }
+	 break;
+      case DBG_WATCH:
+	 if (set) 
+	 {
+#ifdef __i386__
+	    DWORD	bits;
+	    int		reg = breakpoints[i].u.w.reg;
+	    LPDWORD	lpdr = NULL;
 
-    for (i = 0; i < MAX_BREAKPOINTS; i++)
-    {
-        if (breakpoints[i].refcount && breakpoints[i].enabled)
-        {
-	    ch = set ? INT3 : breakpoints[i].opcode;
-
-            if (!DEBUG_WRITE_MEM( (void*)DEBUG_ToLinear(&breakpoints[i].addr), &ch, sizeof(ch) ))
-            {
-                fprintf( stderr, "Invalid address for breakpoint %d, disabling it\n", i );
-                breakpoints[i].enabled = FALSE;
-            }
-        }
-    }
+	    switch (reg) 
+	    {
+	       case 0: lpdr = &DEBUG_context.Dr0; break;
+	       case 1: lpdr = &DEBUG_context.Dr1; break;
+	       case 2: lpdr = &DEBUG_context.Dr2; break;
+	       case 3: lpdr = &DEBUG_context.Dr3; break;
+	       default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
+	    }
+	    
+	    *lpdr = DEBUG_ToLinear(&breakpoints[i].addr);
+	    fprintf(stderr, "Setting DR%d %08lx\n", (lpdr - &DEBUG_context.Dr0) / 4, *lpdr);
+	    bits = (breakpoints[i].u.w.rw) ? DR7_RW_WRITE : DR7_RW_READ;
+	    switch (breakpoints[i].u.w.len + 1)
+	    {
+	       case 4: bits |= DR7_LEN_4;	break;
+	       case 2: bits |= DR7_LEN_2;	break;
+	       case 1: bits |= DR7_LEN_1;	break;
+	       default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
+	    }
+	    
+	    DEBUG_context.Dr7 &= ~(0x0F << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg));
+	    DEBUG_context.Dr7 |= bits << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg);
+	    DEBUG_context.Dr7 |= DR7_ENABLE_MASK(reg) | DR7_LOCAL_SLOWDOWN;
+#endif
+	 }
+	 break;
+      }
+   }
+   fprintf(stderr, "Setting DR7 %08lx\n", DEBUG_context.Dr7);
 }
 
-
 /***********************************************************************
  *           DEBUG_FindBreakpoint
  *
  * Find the breakpoint for a given address. Return the breakpoint
  * number or -1 if none.
+ * If type is DBG_BREAKPOINT, addr is a complete addr
+ * If type is DBG_WATCHPOINT, only addr.off is meaningful and contains 
+ * linear address
  */
-int DEBUG_FindBreakpoint( const DBG_ADDR *addr )
+static int DEBUG_FindBreakpoint( const DBG_ADDR *addr, int type )
 {
-    int i;
-
-    for (i = 0; i < MAX_BREAKPOINTS; i++)
-    {
-        if (breakpoints[i].refcount && breakpoints[i].enabled &&
-            breakpoints[i].addr.seg == addr->seg &&
-            breakpoints[i].addr.off == addr->off) return i;
-    }
-    return -1;
+   int i;
+   
+   for (i = 0; i < next_bp; i++)
+   {
+      if (breakpoints[i].refcount && breakpoints[i].enabled &&
+	  breakpoints[i].type == type )
+      {
+	 if ((type == DBG_BREAK && 
+	      breakpoints[i].addr.seg == addr->seg &&
+	      breakpoints[i].addr.off == addr->off) ||
+	     (type == DBG_WATCH && 
+	      DEBUG_ToLinear(&breakpoints[i].addr) == addr->off))
+	    return i;
+      }
+   }
+   return -1;
 }
 
+/***********************************************************************
+ *           DEBUG_InitXPoint
+ *
+ * Find an empty slot in BP table to add a new break/watch point
+ */
+static	int	DEBUG_InitXPoint(int type, DBG_ADDR* addr)
+{
+   int	num;
+   
+   for (num = (next_bp < MAX_BREAKPOINTS) ? next_bp++ : 1; 
+	num < MAX_BREAKPOINTS; num++) 
+   {
+      if (breakpoints[num].refcount == 0) 
+      {
+	 breakpoints[num].refcount = 1;
+	 breakpoints[num].enabled = TRUE;
+	 breakpoints[num].type    = type;
+	 breakpoints[num].skipcount = 0;
+	 breakpoints[num].addr = *addr;
+	 breakpoints[num].is32 = 1;
+#ifdef __i386__
+	 if (addr->seg) 
+	 {
+	    switch (DEBUG_GetSelectorType( addr->seg )) 
+	    {
+	       case 32: break;
+	       case 16: breakpoints[num].is32 = 0; break;
+	       default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
+	    }
+	 }
+#endif
+	 return num;
+      }
+   }
+   
+   fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
+   return -1;
+}
+
+/***********************************************************************
+ *           DEBUG_GetWatchedValue
+ *
+ * Returns the value watched by watch point 'num'.
+ */
+static	BOOL	DEBUG_GetWatchedValue( int num, LPDWORD val )
+{
+   BYTE		buf[4];
+   
+   if (!DEBUG_READ_MEM((void*)DEBUG_ToLinear(&breakpoints[num].addr), 
+		       buf, breakpoints[num].u.w.len + 1))
+      return FALSE;
+   
+   switch (breakpoints[num].u.w.len + 1) 
+   {
+      case 4:	*val = *(DWORD*)buf;	break;
+      case 2:	*val = *(WORD*)buf;	break;
+      case 1:	*val = *(BYTE*)buf;	break;
+      default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
+   }
+   return TRUE;
+}
 
 /***********************************************************************
  *           DEBUG_AddBreakpoint
  *
  * Add a breakpoint.
  */
-void DEBUG_AddBreakpoint( const DBG_ADDR *address )
+void DEBUG_AddBreakpoint( const DBG_VALUE *_value )
 {
-    DBG_ADDR addr = *address;
+    DBG_VALUE value = *_value;
     int num;
     unsigned int seg2;
     BYTE ch;
 
-    DEBUG_FixAddress( &addr, DEBUG_context.SegCs );
+    assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
 
-    if( addr.type != NULL && addr.type == DEBUG_TypeIntConst )
-      {
-	/*
-	 * We know that we have the actual offset stored somewhere
-	 * else in 32-bit space.  Grab it, and we
-	 * should be all set.
-	 */
-	seg2 = addr.seg;
-	addr.seg = 0;
-	addr.off = DEBUG_GetExprValue(&addr, NULL);
-	addr.seg = seg2;
-      }
+    DEBUG_FixAddress( &value.addr, DEBUG_context.SegCs );
 
-    if ((num = DEBUG_FindBreakpoint(&addr)) >= 1) 
+    if( value.type != NULL && value.type == DEBUG_TypeIntConst )
+    {
+       /*
+	* We know that we have the actual offset stored somewhere
+	* else in 32-bit space.  Grab it, and we
+	* should be all set.
+	*/
+       seg2 = value.addr.seg;
+       value.addr.seg = 0;
+       value.addr.off = DEBUG_GetExprValue(&value, NULL);
+       value.addr.seg = seg2;
+    }
+
+    if ((num = DEBUG_FindBreakpoint(&value.addr, DBG_BREAK)) >= 1) 
     {
        breakpoints[num].refcount++;
        return;
     }
 
-    if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &addr ), &ch, sizeof(ch)))
+    if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &value.addr ), &ch, sizeof(ch)))
 	return;
 
-    if (next_bp < MAX_BREAKPOINTS)
-        num = next_bp++;
-    else  /* try to find an empty slot */  
-    {
-        for (num = 1; num < MAX_BREAKPOINTS; num++)
-            if (!breakpoints[num].refcount) break;
-        if (num >= MAX_BREAKPOINTS)
-        {
-            fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
-            return;
-        }
-    }
-    breakpoints[num].addr    = addr;
-    breakpoints[num].addrlen = 32;
-#ifdef __i386__
-    if (addr.seg)
-       breakpoints[num].addrlen = DEBUG_GetSelectorType( addr.seg );
-    if (breakpoints[num].addrlen == 0) fprintf(stderr, "in bad shape\n");
-#endif
-    breakpoints[num].opcode  = ch;
-    breakpoints[num].enabled = TRUE;
-    breakpoints[num].refcount = 1;
-    breakpoints[num].skipcount = 0;
+    if ((num = DEBUG_InitXPoint(DBG_BREAK, &value.addr)) == -1)
+       return;
+
+    breakpoints[num].u.opcode  = ch;
+
     fprintf( stderr, "Breakpoint %d at ", num );
-    DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen,
+    DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32 : 16,
 			TRUE );
     fprintf( stderr, "\n" );
 }
 
 
+ /***********************************************************************
+ *           DEBUG_AddWatchpoint
+ *
+ * Add a watchpoint.
+ */
+void DEBUG_AddWatchpoint( const DBG_VALUE *_value, BOOL is_write )
+{
+   DBG_VALUE	value = *_value;
+   int		num, reg;
+   unsigned	seg2;
+   DWORD	mask = 0;
+   
+   assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
+
+   DEBUG_FixAddress( &value.addr, CS_reg(&DEBUG_context) );
+   
+   if ( value.type != NULL && value.type == DEBUG_TypeIntConst )
+   {
+      /*
+       * We know that we have the actual offset stored somewhere
+       * else in 32-bit space.  Grab it, and we
+       * should be all set.
+       */
+      seg2 = value.addr.seg;
+      value.addr.seg = 0;
+      value.addr.off = DEBUG_GetExprValue(&value, NULL);
+      value.addr.seg = seg2;
+   }
+   
+   for (num = 1; num < next_bp; num++) 
+   {
+      if (breakpoints[num].refcount && breakpoints[num].enabled && 
+	  breakpoints[num].type == DBG_WATCH) {
+	 mask |= (1 << breakpoints[num].u.w.reg);
+      }
+   }
+#ifdef __i386__
+   for (reg = 0; reg < 4 && (mask & (1 << reg)); reg++);
+   if (reg == 4)
+   {
+      fprintf(stderr, "All i386 hardware watchpoints have been set. Delete some\n");
+      return;
+   }
+#endif
+
+   if ((num = DEBUG_InitXPoint(DBG_WATCH, &value.addr)) == -1)
+      return;
+   
+   breakpoints[num].u.w.len = 4 - 1;
+   if (_value->type && DEBUG_GetObjectSize(_value->type) < 4)
+      breakpoints[num].u.w.len = 2 - 1;
+   
+   if (!DEBUG_GetWatchedValue( num, &breakpoints[num].u.w.oldval)) 
+   {
+      fprintf(stderr, "Bad address. Watchpoint not set\n");
+      breakpoints[num].refcount = 0;
+   }
+   
+   breakpoints[num].u.w.rw = (is_write) ? TRUE : FALSE;
+   breakpoints[reg].u.w.reg = reg;
+   
+   fprintf( stderr, "Watchpoint %d at ", num );
+   DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32:16, TRUE );
+   fprintf( stderr, "\n" );
+}
+
 /***********************************************************************
  *           DEBUG_DelBreakpoint
  *
@@ -250,7 +443,7 @@
  */
 void DEBUG_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 @@
        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_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 @@
 
 
 /***********************************************************************
+ *           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 @@
     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,9 +576,63 @@
 	    }
         }
     }
+    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;
+}
+
+/***********************************************************************
  *           DEBUG_ShouldContinue
  *
  * Determine if we should continue execution after a SIGTRAP signal when
@@ -323,10 +640,11 @@
  */
 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 @@
 #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 @@
      */
     ret_mode = mode;
 
-    bp = DEBUG_FindBreakpoint( &addr ); 
+    bp = DEBUG_FindBreakpoint( &addr, DBG_BREAK ); 
     if ( bp != -1 && bp != 0)
       {
 	/*
@@ -574,7 +880,8 @@
       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 @@
             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 @@
         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 e6783a9..9f1a0be 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -1011,7 +1011,6 @@
 {
     DBG_ADDR address;
 
-    address.type = NULL;
     address.seg = 0;
     address.off = addr;
 
diff --git a/debugger/dbg.y b/debugger/dbg.y
index f978d64..516c505 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 @@
 
 %union
 {
-    DBG_ADDR         address;
+    DBG_VALUE        value;
     enum debug_regs  reg;
     char *           string;
     int              integer;
@@ -46,7 +47,7 @@
 %token tPROCESS tMODREF
 %token tEOL tSTRING tDEBUGSTR
 %token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE
-%token tSTEPI tNEXTI tFINISH tSHOW tDIR
+%token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS
 %token <string> tPATH
 %token <string> tIDENTIFIER tSTRING tDEBUGSTR
 %token <integer> tNUM tFORMAT
@@ -77,7 +78,7 @@
 
 %type <expression> expr lval lvalue 
 %type <type> type_cast type_expr
-%type <address> expr_addr lval_addr
+%type <value> expr_addr lval_addr
 %type <integer> expr_value
 %type <string> pathname
 
@@ -144,19 +145,21 @@
     | 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 @@
     | 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 @@
 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 @@
 				   }
 				}
     | 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 @@
 				   }
                                }
 
-    | 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			{ $$ = 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 '.' 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 @@
 	
 %%
 
-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 @@
         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 @@
 	       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 @@
      */
     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 aa84e8e..4f2a1fc 100644
--- a/debugger/dbgmain.c
+++ b/debugger/dbgmain.c
@@ -32,7 +32,7 @@
   return(0);
 }
 
-HTASK16    GetCurrentTask()
+HTASK16    GetCurrentTask(void)
 {
   exit(0);
 }
@@ -70,17 +70,17 @@
 }
 
 
-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 @@
 	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 26513ed..c0020d0 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -131,7 +131,7 @@
 <INITIAL>help|hel|he|"?"		{ BEGIN(HELP_CMD); return tHELP; }
 
 <INITIAL>backtrace|backtrac|backtra|backt|back|bac|ba|bt { BEGIN(NOCMD); return tBACKTRACE; }
-<INITIAL>where|wher|whe                  { BEGIN(NOCMD); return tBACKTRACE; }
+<INITIAL>where|wher|whe                 { BEGIN(NOCMD); return tBACKTRACE; }
 
 <INITIAL>cont|con|co|c   		{ BEGIN(NOCMD); return tCONT; }
 <INITIAL>pass|pas|pa   			{ BEGIN(NOCMD); return tPASS; }
@@ -151,14 +151,15 @@
 
 <INITIAL,INFO_CMD,DEL_CMD>break|brea|bre|br|b	{ BEGIN(PATH_EXPECTED); return tBREAK; }
 <INITIAL>watch|watc|wat			{ BEGIN(PATH_EXPECTED); return tWATCH; }
+<INITIAL>whatis|whati|what		{ BEGIN(PATH_EXPECTED); return tWHATIS; }
 
 <INFO_CMD>share|shar|sha		{ return tSHARE; }
 <INFO_CMD>locals|local|loca|loc		{ return tLOCAL; }
 <INFO_CMD,WALK_CMD>class|clas|cla                  { return tCLASS; }
 <INFO_CMD,WALK_CMD>module|modul|modu|mod  { return tMODULE; }
-<INFO_CMD,WALK_CMD>queue|queu|que			{ return tQUEUE; }
+<INFO_CMD,WALK_CMD>queue|queu|que	{ return tQUEUE; }
 <INFO_CMD,WALK_CMD>process|proces|proce|proc   		{ return tPROCESS; }
-<INFO_CMD,WALK_CMD>modref|modre|modr			{ return tMODREF; }
+<INFO_CMD,WALK_CMD>modref|modre|modr	{ return tMODREF; }
 <INFO_CMD>registers|regs|reg|re		{ return tREGS; }
 <INFO_CMD>segments|segment|segm|seg|se	{ return tSEGMENTS; }
 <INFO_CMD>stack|stac|sta|st     		{ return tSTACK; }
diff --git a/debugger/debugger.h b/debugger/debugger.h
index 1f3d02c..104bfde 100644
--- a/debugger/debugger.h
+++ b/debugger/debugger.h
@@ -8,11 +8,12 @@
 #define __WINE_DEBUGGER_H
 
 #include <sys/types.h> /* u_long ... */
+#include <assert.h>
 #include "windef.h"
 #include "winbase.h"
 
 #ifdef __i386__
-#define STEP_FLAG 0x100 /* single step flag */
+#define STEP_FLAG 0x00000100 /* single step flag */
 #define V86_FLAG  0x00020000
 #endif
 
@@ -46,11 +47,20 @@
 
 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 @@
 				 * 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 @@
 
   /* 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 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_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 @@
 
   /* 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 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_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 @@
   /* 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 @@
 
   /* 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 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_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_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 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 431a289..80926f9 100644
--- a/debugger/display.c
+++ b/debugger/display.c
@@ -49,7 +49,7 @@
 }
 
 int
-DEBUG_InfoDisplay()
+DEBUG_InfoDisplay(void)
 {
   int i;
 
@@ -70,10 +70,10 @@
 }
 
 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 @@
     {
       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 @@
 	      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 877a1db..298b62c 100644
--- a/debugger/expr.c
+++ b/debugger/expr.c
@@ -9,7 +9,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <assert.h>
 #include "winbase.h"
 #include "wine/winbase16.h"
 #include "task.h"
@@ -120,7 +119,7 @@
 
 static
 struct expr *
-DEBUG_GetFreeExpr()
+DEBUG_GetFreeExpr(void)
 {
   struct expr * rtn;
 
@@ -133,7 +132,7 @@
 }
 
 void
-DEBUG_FreeExprMem()
+DEBUG_FreeExprMem(void)
 {
   next_expr_free = 0;
 }
@@ -291,13 +290,12 @@
   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 @@
   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 @@
       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 @@
       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 @@
        */
       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 @@
        */
       int		(*fptr)();
 
-      fptr = (int (*)()) rtn.off;
+      fptr = (int (*)()) rtn.addr.off;
       switch(exp->un.call.nargs)
 	{
 	case 0:
@@ -422,27 +425,30 @@
       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 @@
 	{
 	  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 @@
 	  scale2 = 1;
 	  if( type1 != NULL && type2 != NULL )
 	    {
-	      break;
+	      RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
 	    }
 	  else if( type1 != NULL )
 	    {
@@ -474,7 +481,6 @@
 	      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 @@
 	    {
 	      if( type1 != type2 )
 		{
-		  break;
+		  RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
 		}
 	      scale3 = DEBUG_GetObjectSize(type1);
 	    }
@@ -502,112 +508,89 @@
 	      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));
+	       RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
 	    }
-	  else
-	    {
-	      rtn.seg = 0;
-	      rtn.type = NULL;
-	      rtn.off = 0;
-	    }
+	  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));
+	       RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
 	    }
-	  else
-	    {
-	      rtn.seg = 0;
-	      rtn.type = NULL;
-	      rtn.off = 0;
-	    }
+	  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 @@
       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 @@
       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 @@
       break;
     default:
       fprintf(stderr,"Unexpected expression.\n");
-      DEBUG_Exit(123);
+      RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
       break;
     }
 
@@ -811,7 +803,7 @@
 }
 
 struct expr *
-DEBUG_CloneExpr(struct expr * exp)
+DEBUG_CloneExpr(const struct expr * exp)
 {
   int		i;
   struct expr * rtn;
@@ -860,7 +852,7 @@
       break;
     default:
       fprintf(stderr,"Unexpected expression.\n");
-      DEBUG_Exit(123);
+      RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
       break;
     }
 
@@ -913,7 +905,7 @@
       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 35aaf6b..cd6cd19 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -55,14 +55,14 @@
     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 @@
       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 @@
  */
 static
 void
-DEBUG_ResortSymbols()
+DEBUG_ResortSymbols(void)
 {
     struct name_hash *nh;
     int		nsym = 0;
@@ -185,7 +185,7 @@
  * 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 @@
     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 @@
 	     */
  	    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 @@
      */
     
     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 @@
  * 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 @@
      */
     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 @@
  * 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 @@
  *
  * 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 @@
     }
 
     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 @@
      */
     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 @@
 		 */
 		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 @@
 		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 @@
 		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 @@
       }
 
     if( (nearest->sourcefile != NULL) && (flag == TRUE)
-	&& (addr->off - nearest->addr.off < 0x100000) )
+	&& (addr->off - nearest->value.addr.off < 0x100000) )
       {
 
 	/*
@@ -685,24 +693,24 @@
         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 @@
 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 @@
 
     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 @@
         }
         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 @@
 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 @@
         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 @@
 {
 #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 @@
     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 @@
     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 @@
       {
           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 @@
             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 @@
     BOOL 	ok;
     WINE_MODREF*wm;
     DBG_LEPData	lep;
-    
+    PDB*	current = PROCESS_Current();
+
     lep.first = 0;
     lep.pfx = pfx;
 
@@ -983,7 +1002,7 @@
 	    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 @@
         }
     }
     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 @@
     }
 
   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 @@
 }
 
 void
-DEBUG_DumpHashInfo()
+DEBUG_DumpHashInfo(void)
 {
   int i;
   int depth;
@@ -1102,15 +1120,15 @@
      */
     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 @@
 		 */
 		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 @@
 		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 @@
 		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 @@
      * 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 @@
  * 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 @@
        * 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 @@
 	  /*
 	   * 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 @@
        * 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 @@
 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 2a6e00b..7f1f64f 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -8,6 +8,7 @@
 #include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
@@ -20,40 +21,41 @@
  *
  * Implementation of the 'print' command.
  */
-void DEBUG_PrintBasic( const DBG_ADDR *addr, int count, char format )
+void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format )
 {
   char        * default_format;
-  long long int value;
+  long long int res;
 
-  if( addr->type == NULL )
+  assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
+  if( value->type == NULL ) 
     {
       fprintf(stderr, "Unable to evaluate expression\n");
       return;
     }
   
   default_format = NULL;
-  value = DEBUG_GetExprValue(addr, &default_format);
+  res = DEBUG_GetExprValue(value, &default_format);
 
   switch(format)
     {
     case 'x':
-      if (addr->seg) 
+      if (value->addr.seg) 
 	{
-	  DEBUG_nchar += fprintf( stderr, "0x%04lx", (long unsigned int) value );
+	  DEBUG_nchar += fprintf( stderr, "0x%04lx", (long unsigned int) res );
 	}
       else 
 	{
-	  DEBUG_nchar += fprintf( stderr, "0x%08lx", (long unsigned int) value );
+	  DEBUG_nchar += fprintf( stderr, "0x%08lx", (long unsigned int) res );
 	}
       break;
       
     case 'd':
-      DEBUG_nchar += fprintf( stderr, "%ld\n", (long int) value );
+      DEBUG_nchar += fprintf( stderr, "%ld\n", (long int) res );
       break;
       
     case 'c':
       DEBUG_nchar += fprintf( stderr, "%d = '%c'",
-	       (char)(value & 0xff), (char)(value & 0xff) );
+			      (char)(res & 0xff), (char)(res & 0xff) );
       break;
       
     case 'i':
@@ -64,7 +66,51 @@
     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 @@
 "  display <expr>                         undisplay <disnum>",
 "  delete display <disnum>                debugmsg <class>[-+]<type>\n",
 "  mode [16,32]                           walk [wnd,class,queue,module,",
-"                                               process,modref <pid>]",
+"  whatis                                       process,modref <pid>]",
 "  info (see 'help info' for options)\n",
 
 "The 'x' command accepts repeat counts and formats (including 'i') in the",
diff --git a/debugger/memory.c b/debugger/memory.c
index 07759ee..3a75dd3 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 @@
 
 void DEBUG_GetCurrentAddress( DBG_ADDR *addr )
 {
-    addr->type = NULL;
 #ifdef __i386__
     addr->seg  = DEBUG_context.SegCs;
 
@@ -120,7 +120,6 @@
 {
    DBG_ADDR address;
 
-   address.type = NULL;
    address.seg = 0;
    address.off = (unsigned long)addr;
 
@@ -169,14 +168,16 @@
  *
  * 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 @@
      * 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 @@
 
     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 @@
 	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 @@
 		for(i=0; i<count; i++) { \
                     if (!DEBUG_READ_MEM_VERBOSE(pnt, &_v, sizeof(_t))) break; \
                     fprintf(stderr,_f,(_vv)); \
-                    pnt += sizeof(_t); addr.off += sizeof(_t); \
+                    pnt += sizeof(_t); value.addr.off += sizeof(_t); \
                     if ((i % (_l)) == (_l)-1) { \
                         fprintf(stderr,"\n"); \
-                        DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, FALSE );\
+                        DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, FALSE );\
                         fprintf(stderr,": ");\
                     } \
 		} \
diff --git a/debugger/msc.c b/debugger/msc.c
index 5f134a9..8842f34 100644
--- a/debugger/msc.c
+++ b/debugger/msc.c
@@ -1249,7 +1249,7 @@
 }
 
 void
-DEBUG_InitCVDataTypes()
+DEBUG_InitCVDataTypes(void)
 {
   /*
    * These are the common builtin types that are used by VC++.
@@ -1505,7 +1505,7 @@
   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 @@
 
   linetab_indx = 0;
 
+  new_value.cookie = DV_TARGET;
+  new_value.type = NULL;
+
   for(i=0; i < coff->N_Sym; i++ )
     {
       /*
@@ -1675,8 +1678,8 @@
 	      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 @@
 	  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 @@
 	      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 @@
 			 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 @@
 	      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 @@
 	  /*
 	   * 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 @@
 	      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 @@
 	       * 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 @@
   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 @@
 	   */
 
 	  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 @@
 	   */
 
 	  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 @@
 	   * 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 @@
 	   * 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 @@
 	    {
 	      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_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 @@
 	       * 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 @@
 	   * 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 @@
 	    {
 	      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_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 @@
 	       * 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 @@
 }
 
 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 0b7e7c6..1f212c3 100644
--- a/debugger/source.c
+++ b/debugger/source.c
@@ -49,7 +49,7 @@
 static int DEBUG_end_sourceline = -1;
 
 void
-DEBUG_ShowDir()
+DEBUG_ShowDir(void)
 {
   struct searchlist * sl;
 
@@ -78,7 +78,7 @@
 }
 
 void
-DEBUG_NukePath()
+DEBUG_NukePath(void)
 {
   struct searchlist * sl;
   struct searchlist * nxt;
@@ -422,7 +422,7 @@
   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 @@
 }
 
 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 @@
 }
 
 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 @@
 
     for (i=0;i<offset;i++)
       if (!_disassemble(&last)) break;
-    memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
+    DEBUG_LastDisassemble = last;
     return;
   }
-  last = start;
+  last = start.addr;
   if (!xend) {
     for (i=0;i<offset;i++)
       if (!_disassemble(&last)) break;
-    memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
+    DEBUG_LastDisassemble = last;
     return;
   }
-  while (last.off <= end.off)
+  while (last.off <= end.addr.off)
     if (!_disassemble(&last)) break;
-  memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
+  DEBUG_LastDisassemble = last;
   return;
 }
 
 
 
 #if 0
-main()
+main(void)
 {
   int i, j;
   DEBUG_AddPath("../../de");
diff --git a/debugger/stabs.c b/debugger/stabs.c
index 7407847..b240a01 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -8,7 +8,6 @@
 
 #include "config.h"
 
-#include <assert.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -426,7 +425,7 @@
   return TRUE;
 }
 
-static int DEBUG_FreeRegisteredTypedefs()
+static int DEBUG_FreeRegisteredTypedefs(void)
 {
   int			 count;
   int			 j;
@@ -775,10 +774,10 @@
   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 @@
            *
            * 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 @@
           /*
            * 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 @@
             }
           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 @@
            * 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 @@
                * 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 @@
            * 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 @@
   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 @@
        * 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 46a2d1d..07f2a95 100644
--- a/debugger/stack.c
+++ b/debugger/stack.c
@@ -57,23 +57,24 @@
 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 @@
 		  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 @@
 		  return;
 	      }
 	      
-	      code.type = NULL;
 	      code.seg  = frame16.cs;
 	      code.off  = frame16.ip;
 	      
diff --git a/debugger/types.c b/debugger/types.c
index c827866..676911f 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -11,7 +11,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <assert.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -294,7 +293,7 @@
 }
 
 void
-DEBUG_InitTypes()
+DEBUG_InitTypes(void)
 {
   static int beenhere = 0;
   struct datatype * chartype;
@@ -313,7 +312,6 @@
    * 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 @@
 }
 
 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 @@
 	}
       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 @@
         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 @@
       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 @@
 	}
       if( e != NULL )
 	{
-	  rtn = (int) e->name;
+ 	  rtn = (int) e->name;
 	  def_format = "%s";
 	}
       else
@@ -450,53 +473,63 @@
 }
 
 unsigned int
-DEBUG_TypeDerefPointer(const DBG_ADDR * addr, struct datatype ** newtype)
+DEBUG_TypeDerefPointer(const DBG_VALUE *value, struct datatype ** newtype)
 {
-  DBG_ADDR address = *addr;
-  unsigned int val;
+  DBG_ADDR	addr = value->addr;
+  unsigned int	val;
+
+  assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
+
+  *newtype = NULL;
 
   /*
    * Make sure that this really makes sense.
    */
-  if( addr->type->type != DT_POINTER || !DEBUG_READ_MEM((void*)addr->off, &val, sizeof(val)))
-    {
-      *newtype = NULL;
-      return 0;
-    }
+  if( value->type->type != DT_POINTER )
+     return 0;
 
-  *newtype = addr->type->un.pointer.pointsto;
-  address.off = val;
-  return DEBUG_ToLinear(&address); /* FIXME: is this right (or "better") ? */
+  if (value->cookie == DV_TARGET) {
+     if (!DEBUG_READ_MEM((void*)value->addr.off, &val, sizeof(val)))
+	return 0;
+  } else {
+     val = *(unsigned int*)value->addr.off;
+  }
+
+  *newtype = value->type->un.pointer.pointsto;
+  addr.off = val;
+  return DEBUG_ToLinear(&addr); /* FIXME: is this right (or "better") ? */
 }
 
 unsigned int
-DEBUG_FindStructElement(DBG_ADDR * addr, const char * ele_name, int * tmpbuf)
+DEBUG_FindStructElement(DBG_VALUE* value, const char * ele_name, int * tmpbuf)
 {
   struct member * m;
   unsigned int    mask;
 
+  assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
+
   /*
    * Make sure that this really makes sense.
    */
-  if( addr->type->type != DT_STRUCT )
+  if( value->type->type != DT_STRUCT )
     {
-      addr->type = NULL;
+      value->type = NULL;
       return FALSE;
     }
 
-  for(m = addr->type->un.structure.members; m; m = m->next)
+  for(m = value->type->un.structure.members; m; m = m->next)
     {
       if( strcmp(m->name, ele_name) == 0 )
 	{
-	  addr->type = m->type;
+	  value->type = m->type;
 	  if( (m->offset & 7) != 0 || (m->size & 7) != 0)
 	    {
 	      /*
 	       * Bitfield operation.  We have to extract the field and store
 	       * it in a temporary buffer so that we get it all right.
 	       */
-	      *tmpbuf = ((*(int* ) (addr->off + (m->offset >> 3))) >> (m->offset & 7));
-	      addr->off = (int) tmpbuf;
+	      *tmpbuf = ((*(int* ) (value->addr.off + (m->offset >> 3))) >> (m->offset & 7));
+	      value->addr.off = (int) tmpbuf;
 
 	      mask = 0xffffffff << (m->size);
 	      *tmpbuf &= ~mask;
@@ -513,13 +546,13 @@
 	    }
 	  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 @@
 }
 
 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 @@
  * 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 @@
       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 @@
       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 @@
       /*
        * 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_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 @@
 }
 
 int
-DEBUG_DumpTypes()
+DEBUG_DumpTypes(void)
 {
   struct datatype * dt = NULL;
   struct member * m;
@@ -980,11 +1016,10 @@
 }
 
 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 @@
   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 702cb1b..f98a80c 100644
--- a/debugger/winedbg.c
+++ b/debugger/winedbg.c
@@ -176,12 +176,14 @@
     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 @@
 	    
 	    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: