No longer directly accessing debuggee memory.
Execution context (mode, steps...) are now linked to a thread.
Removed some X11 crst hacks.
Rewrote info/walk commands.
Removed direct debugger invocation code (and moved the rest to the new
winedbg.c file).

diff --git a/debugger/break.c b/debugger/break.c
index 68150d1..db80414 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -7,83 +7,43 @@
 
 #include "config.h"
 #include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include "wine/winbase16.h"
-#include "module.h"
-#include "neexe.h"
-#include "process.h"
-#include "task.h"
-#include "miscemu.h"
-#include "toolhelp.h"
 #include "debugger.h"
-#include "dosexe.h"
 
 #define INT3          0xcc   /* int 3 opcode */
 
 #define MAX_BREAKPOINTS 100
 
-typedef struct
-{
-    DBG_ADDR      addr;
-    BYTE          addrlen;
-    BYTE          opcode;
-    BOOL16        enabled;
-    WORD	  skipcount;
-    BOOL16        in_use;
-    struct expr * condition;
-} BREAKPOINT;
-
 static BREAKPOINT breakpoints[MAX_BREAKPOINTS];
 
 static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */
 
 
 /***********************************************************************
- *           DEBUG_ChangeOpcode
- *
- * Change the opcode at segment:addr.
- */
-static void DEBUG_SetOpcode( const DBG_ADDR *addr, BYTE op )
-{
-    BYTE *ptr = DBG_ADDR_TO_LIN(addr);
-
-    /* There are a couple of problems with this. On Linux prior to
-       1.1.62, this call fails (ENOACCESS) due to a bug in fs/exec.c.
-       This code is currently not tested at all on BSD.
-       How do I get the old protection in order to restore it later on?
-       */
-    if (mprotect((caddr_t)((int)ptr & (~4095)), 4096,
-                 PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
-    {
-        perror( "Can't set break point" );
-        return;
-    }
-    *ptr = op;
-    /* mprotect((caddr_t)(addr->off & ~4095), 4096,
-       PROT_READ | PROT_EXEC ); */
-}
-
-
-/***********************************************************************
  *           DEBUG_IsStepOverInstr
  *
  * Determine if the instruction at CS:EIP is an instruction that
  * we need to step over (like a call or a repetitive string move).
  */
-static BOOL DEBUG_IsStepOverInstr()
+static BOOL DEBUG_IsStepOverInstr(void)
 {
 #ifdef __i386__
-    BYTE *instr = (BYTE *)CTX_SEG_OFF_TO_LIN( &DEBUG_context,
-                                              CS_reg(&DEBUG_context),
-                                              EIP_reg(&DEBUG_context) );
+    BYTE*	instr;
+    BYTE	ch;
+    DBG_ADDR	addr;
+
+    addr.seg = DEBUG_context.SegCs;
+    addr.off = DEBUG_context.Eip;
+    /* FIXME: old code was using V86BASE(DEBUG_context)
+     * instead of passing thru DOSMEM_MemoryBase
+     */
+    instr = (BYTE*)DEBUG_ToLinear(&addr);
 
     for (;;)
     {
-        switch(*instr)
+        if (!DEBUG_READ_MEM(instr, &ch, sizeof(ch)))
+	    return FALSE;
+
+        switch (ch)
         {
           /* Skip all prefixes */
 
@@ -109,8 +69,9 @@
             return TRUE;
 
         case 0xff:  /* call <regmodrm> */
-            return (((instr[1] & 0x38) == 0x10) ||
-                    ((instr[1] & 0x38) == 0x18));
+	    if (!DEBUG_READ_MEM(instr + 1, &ch, sizeof(ch)))
+	        return FALSE;
+	    return (((ch & 0x38) == 0x10) || ((ch & 0x38) == 0x18));
 
           /* Handle string instructions */
 
@@ -149,21 +110,21 @@
 BOOL DEBUG_IsFctReturn(void)
 {
 #ifdef __i386__
-    BYTE *instr = (BYTE *)CTX_SEG_OFF_TO_LIN( &DEBUG_context,
-                                              CS_reg(&DEBUG_context),
-                                              EIP_reg(&DEBUG_context) );
+    BYTE*	instr;
+    BYTE  	ch;
+    DBG_ADDR	addr;
 
-    for (;;)
-    {
-        switch(*instr)
-        {
-	case 0xc2:
-	case 0xc3:
-	  return TRUE;
-        default:
-            return FALSE;
-        }
-    }
+    addr.seg = DEBUG_context.SegCs;
+    addr.off = DEBUG_context.Eip;
+    /* FIXME: old code was using V86BASE(DEBUG_context)
+     * instead of passing thru DOSMEM_MemoryBase
+     */
+    instr = (BYTE*)DEBUG_ToLinear(&addr);
+
+    if (!DEBUG_READ_MEM(instr, &ch, sizeof(ch)))
+       return FALSE;
+
+    return (ch == 0xc2) || (ch == 0xc3);
 #else
     return FALSE;
 #endif
@@ -177,21 +138,20 @@
  */
 void DEBUG_SetBreakpoints( BOOL set )
 {
-    int i;
+    int 	i;
+    char	ch;
 
     for (i = 0; i < MAX_BREAKPOINTS; i++)
     {
-        if (breakpoints[i].in_use && breakpoints[i].enabled)
+        if (breakpoints[i].refcount && breakpoints[i].enabled)
         {
-            /* Note: we check for read here, because if reading is allowed */
-            /*       writing permission will be forced in DEBUG_SetOpcode. */
-            if (DEBUG_IsBadReadPtr( &breakpoints[i].addr, 1 ))
+	    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;
             }
-            else DEBUG_SetOpcode( &breakpoints[i].addr,
-                                  set ? INT3 : breakpoints[i].opcode );
         }
     }
 }
@@ -209,7 +169,7 @@
 
     for (i = 0; i < MAX_BREAKPOINTS; i++)
     {
-        if (breakpoints[i].in_use && breakpoints[i].enabled &&
+        if (breakpoints[i].refcount && breakpoints[i].enabled &&
             breakpoints[i].addr.seg == addr->seg &&
             breakpoints[i].addr.off == addr->off) return i;
     }
@@ -227,9 +187,9 @@
     DBG_ADDR addr = *address;
     int num;
     unsigned int seg2;
-    BYTE *p;
+    BYTE ch;
 
-    DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
+    DEBUG_FixAddress( &addr, DEBUG_context.SegCs );
 
     if( addr.type != NULL && addr.type == DEBUG_TypeIntConst )
       {
@@ -243,27 +203,38 @@
 	addr.off = DEBUG_GetExprValue(&addr, NULL);
 	addr.seg = seg2;
       }
-    if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
+
+    if ((num = DEBUG_FindBreakpoint(&addr)) >= 1) 
+    {
+       breakpoints[num].refcount++;
+       return;
+    }
+
+    if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &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].in_use) break;
+            if (!breakpoints[num].refcount) break;
         if (num >= MAX_BREAKPOINTS)
         {
             fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
             return;
         }
     }
-    p = DBG_ADDR_TO_LIN( &addr );
     breakpoints[num].addr    = addr;
-    breakpoints[num].addrlen = !addr.seg ? 32 :
-                         (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
-    breakpoints[num].opcode  = *p;
+    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].in_use  = TRUE;
+    breakpoints[num].refcount = 1;
     breakpoints[num].skipcount = 0;
     fprintf( stderr, "Breakpoint %d at ", num );
     DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen,
@@ -279,12 +250,15 @@
  */
 void DEBUG_DelBreakpoint( int num )
 {
-    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
     {
         fprintf( stderr, "Invalid breakpoint number %d\n", num );
         return;
     }
 
+    if (--breakpoints[num].refcount > 0)
+       return;
+
     if( breakpoints[num].condition != NULL )
       {
 	DEBUG_FreeExpr(breakpoints[num].condition);
@@ -292,7 +266,7 @@
       }
 
     breakpoints[num].enabled = FALSE;
-    breakpoints[num].in_use  = FALSE;
+    breakpoints[num].refcount = 0;
     breakpoints[num].skipcount = 0;
 }
 
@@ -304,12 +278,12 @@
  */
 void DEBUG_EnableBreakpoint( int num, BOOL enable )
 {
-    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
     {
         fprintf( stderr, "Invalid breakpoint number %d\n", num );
         return;
     }
-    breakpoints[num].enabled = enable;
+    breakpoints[num].enabled = (enable) ? TRUE : FALSE;
     breakpoints[num].skipcount = 0;
 }
 
@@ -326,67 +300,21 @@
     fprintf( stderr, "Breakpoints:\n" );
     for (i = 1; i < next_bp; i++)
     {
-        if (breakpoints[i].in_use)
+        if (breakpoints[i].refcount)
         {
             fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
-            DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen,
-				TRUE);
-            fprintf( stderr, "\n" );
+            DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen, TRUE);
+            fprintf( stderr, " (%u)\n", breakpoints[i].refcount );
 	    if( breakpoints[i].condition != NULL )
-	      {
-		fprintf(stderr, "\t\tstop when  ");
+	    {
+	        fprintf(stderr, "\t\tstop when  ");
  		DEBUG_DisplayExpr(breakpoints[i].condition);
 		fprintf(stderr, "\n");
-	      }
+	    }
         }
     }
 }
 
-
-/***********************************************************************
- *           DEBUG_AddTaskEntryBreakpoint
- *
- * Add a breakpoint at the entry point of the given task
- */
-void DEBUG_AddTaskEntryBreakpoint( HTASK16 hTask )
-{
-    TDB *pTask = (TDB *)GlobalLock16( hTask );
-    NE_MODULE *pModule;
-    DBG_ADDR addr = { NULL, 0, 0 };
-
-    if ( pTask )
-    {
-        if (!(pModule = NE_GetPtr( pTask->hModule ))) return;
-        if (pModule->flags & NE_FFLAGS_LIBMODULE) return;  /* Library */
-
-        if (pModule->lpDosTask) { /* DOS module */
-            addr.seg = pModule->lpDosTask->init_cs | ((DWORD)pModule->self << 16);
-            addr.off = pModule->lpDosTask->init_ip;
-            fprintf( stderr, "DOS task '%s': ", NE_MODULE_NAME( pModule ) );
-            DEBUG_AddBreakpoint( &addr );
-        } else
-        if (!(pModule->flags & NE_FFLAGS_WIN32))  /* NE module */
-        {
-            addr.seg =
-		GlobalHandleToSel16(NE_SEG_TABLE(pModule)[pModule->cs-1].hSeg);
-            addr.off = pModule->ip;
-            fprintf( stderr, "Win16 task '%s': ", NE_MODULE_NAME( pModule ) );
-            DEBUG_AddBreakpoint( &addr );
-	}
-	else /* PE module */
-	{
-	    addr.seg = 0;
-	    addr.off = (DWORD)RVA_PTR( pModule->module32,
-			   OptionalHeader.AddressOfEntryPoint);
-	    fprintf( stderr, "Win32 task '%s': ", NE_MODULE_NAME( pModule ) );
-	    DEBUG_AddBreakpoint( &addr );
-	}
-    }
-
-    DEBUG_SetBreakpoints( TRUE );  /* Setup breakpoints */
-}
-
-
 /***********************************************************************
  *           DEBUG_ShouldContinue
  *
@@ -401,21 +329,22 @@
     struct list_id list;
 
 #ifdef __i386__
-      /* If not single-stepping, back up over the int3 instruction */
-    if (!(EFL_reg(&DEBUG_context) & STEP_FLAG)) EIP_reg(&DEBUG_context)--;
+    /* If not single-stepping, back up over the int3 instruction */
+    if (!(DEBUG_context.EFlags & STEP_FLAG)) 
+       DEBUG_context.Eip--;
 #endif
 
     DEBUG_GetCurrentAddress( &addr );
     bpnum = DEBUG_FindBreakpoint( &addr );
-    breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */
+    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.
 		 */
@@ -423,21 +352,21 @@
  		DEBUG_DisplayExpr(breakpoints[bpnum].condition);
 		fprintf(stderr, "\nTurning off condition\n");
 		DEBUG_AddBPCondition(bpnum, NULL);
-	      }
+	    }
 	    else if( ! DEBUG_GetExprValue( &cond_addr, NULL) )
-	      {
+	    {
 		return TRUE;
-	      }
-	  }
+	    }
+	}
 
         if( breakpoints[bpnum].skipcount > 0 )
-	  {
+	{
 	    breakpoints[bpnum].skipcount--;
 	    if( breakpoints[bpnum].skipcount > 0 )
-	      {
+	    {
 		return TRUE;
-	      }
-	  }
+	    }
+	}
         fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
         DEBUG_PrintAddress( &breakpoints[bpnum].addr,
                             breakpoints[bpnum].addrlen, TRUE );
@@ -449,9 +378,9 @@
 	 */
 	DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
 	if( list.sourcefile != NULL )
-	  {
+	{
 	    DEBUG_List(&list, NULL, 0);
-	  }
+	}
         return FALSE;
     }
 
@@ -460,8 +389,7 @@
      * 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( mode == EXEC_STEP_OVER || mode == EXEC_STEP_INSTR )
       {
 	if( DEBUG_CheckLinenoStatus(&addr) == AT_LINENUMBER )
 	  {
@@ -499,14 +427,24 @@
 #ifdef __i386__
     /* If there's no breakpoint and we are not single-stepping, then we     */
     /* must have encountered an int3 in the Windows program; let's skip it. */
-    if ((bpnum == -1) && !(EFL_reg(&DEBUG_context) & STEP_FLAG))
-        EIP_reg(&DEBUG_context)++;
+    if ((bpnum == -1) && !(DEBUG_context.EFlags & STEP_FLAG))
+        DEBUG_context.Eip++;
 #endif
 
-      /* no breakpoint, continue if in continuous mode */
+    /* no breakpoint, continue if in continuous mode */
     return (mode == EXEC_CONT || mode == EXEC_PASS || mode == EXEC_FINISH);
 }
 
+/***********************************************************************
+ *           DEBUG_RestartExecution
+ *
+ * Remove all breakpoints before entering the debug loop
+ */
+void	DEBUG_SuspendExecution( void )
+{
+   DEBUG_SetBreakpoints( FALSE );
+   breakpoints[0] = DEBUG_CurrThread->stepOverBP;
+}
 
 /***********************************************************************
  *           DEBUG_RestartExecution
@@ -522,7 +460,8 @@
     int	delta;
     int status;
     enum exec_mode ret_mode;
-    BYTE *instr;
+    DWORD instr;
+    unsigned char ch;
 
     DEBUG_GetCurrentAddress( &addr );
 
@@ -548,7 +487,7 @@
       {
 	if( mode == EXEC_CONT && count > 1 )
 	  {
-	    fprintf(stderr,"Not stopped at any breakpoint; argument ignored.\n");
+	    fprintf(stderr, "Not stopped at any breakpoint; argument ignored.\n");
 	  }
       }
     
@@ -557,16 +496,17 @@
 	mode = ret_mode = EXEC_STEPI_INSTR;
       }
 
-    instr = DBG_ADDR_TO_LIN( &addr );
+    instr = DEBUG_ToLinear( &addr );
+    DEBUG_READ_MEM((void*)instr, &ch, sizeof(ch));
     /*
      * See if the function we are stepping into has debug info
      * and line numbers.  If not, then we step over it instead.
      * FIXME - we need to check for things like thunks or trampolines,
      * as the actual function may in fact have debug info.
      */
-    if( *instr == 0xe8 )
+    if( ch == 0xe8 )
       {
-	delta = *(unsigned int*) (instr + 1);
+	DEBUG_READ_MEM((void*)(instr + 1), &delta, sizeof(delta));
 	addr2 = addr;
 	DEBUG_Disasm(&addr2, FALSE);
 	addr2.off += delta;
@@ -612,7 +552,7 @@
     case EXEC_CONT: /* Continuous execution */
     case EXEC_PASS: /* Continue, passing exception */
 #ifdef __i386__
-        EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
+        DEBUG_context.EFlags &= ~STEP_FLAG;
 #endif
         DEBUG_SetBreakpoints( TRUE );
         break;
@@ -625,14 +565,16 @@
        * address just after the call.
        */
 #ifdef __i386__
-      addr.off = *((unsigned int *) ESP_reg(&DEBUG_context) + 2);
-      EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
+      DEBUG_READ_MEM((void*)(DEBUG_context.Esp + 
+			     2 * sizeof(unsigned int)), 
+		     &addr.off, sizeof(addr.off));
+      DEBUG_context.EFlags &= ~STEP_FLAG;
 #endif
       breakpoints[0].addr    = addr;
       breakpoints[0].enabled = TRUE;
-      breakpoints[0].in_use  = TRUE;
+      breakpoints[0].refcount = 1;
       breakpoints[0].skipcount = 0;
-      breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
+      DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].opcode, sizeof(char));
       DEBUG_SetBreakpoints( TRUE );
       break;
 
@@ -642,14 +584,14 @@
         if (DEBUG_IsStepOverInstr())
         {
 #ifdef __i386__
-            EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
+            DEBUG_context.EFlags &= ~STEP_FLAG;
 #endif
             DEBUG_Disasm(&addr, FALSE);
             breakpoints[0].addr    = addr;
             breakpoints[0].enabled = TRUE;
-            breakpoints[0].in_use  = TRUE;
+            breakpoints[0].refcount = 1;
 	    breakpoints[0].skipcount = 0;
-            breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
+	    DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].opcode, sizeof(char));
             DEBUG_SetBreakpoints( TRUE );
             break;
         }
@@ -658,17 +600,18 @@
     case EXEC_STEP_INSTR: /* Single-stepping an instruction */
     case EXEC_STEPI_INSTR: /* Single-stepping an instruction */
 #ifdef __i386__
-        EFL_reg(&DEBUG_context) |= STEP_FLAG;
+        DEBUG_context.EFlags |= STEP_FLAG;
 #endif
         break;
     }
+    DEBUG_CurrThread->stepOverBP = breakpoints[0];
     return ret_mode;
 }
 
 int
 DEBUG_AddBPCondition(int num, struct expr * exp)
 {
-    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
     {
         fprintf( stderr, "Invalid breakpoint number %d\n", num );
         return FALSE;