Made the winedbg an external and WineLib program.
Centralized output handling (preparation for console usage).
Fixed a few debug information reading options (stabs and sym).
Started a framework to hold debugger's internal variables.

diff --git a/Makefile.in b/Makefile.in
index 998bf5c..ef9332f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -28,7 +28,6 @@
 LIBSUBDIRS = \
 	controls \
 	console \
-	debugger \
 	dlls/advapi32 \
 	dlls/crtdll \
 	dlls/display \
@@ -60,17 +59,25 @@
 	miscemu \
 	server
 
-PROGSUBDIRS = libtest programs
+PROGSUBDIRS = \
+	debugger \
+	libtest \
+	programs
 
 DOCSUBDIRS = documentation
 
 INCSUBDIRS = include
 
+# Stand-alone programs
 PROGRAMS = \
 	loader/dos/dosmod \
 	server/wineserver \
 	windows/x11drv/wineclipsrv
 
+# Programs that link with libwine
+LIBPROGRAMS = \
+	debugger/winedbg
+
 # Sub-directories to run make into
 SUBDIRS = \
 	$(TOOLSUBDIRS) \
@@ -90,7 +97,6 @@
 LIBOBJS = \
 	controls/controls.o \
 	console/console.o \
-	debugger/debugger.o \
 	dlls/advapi32/advapi32.o \
 	dlls/crtdll/crtdll.o \
 	dlls/display/display.o \
@@ -126,7 +132,7 @@
 
 EMU_TARGET = @EMU_TARGET@
 
-all: Make.rules $(PROGRAMS) $(EMU_TARGET)
+all: Make.rules $(PROGRAMS) $(LIBPROGRAMS) $(EMU_TARGET)
 	@echo "Wine build complete."
 
 LIBLINTS = $(LIBOBJS:.o=.ln) 
@@ -167,15 +173,16 @@
 	[ -f wine.sym ] && $(INSTALL_DATA) wine.sym $(libdir)/wine.sym
 	$(INSTALL_PROGRAM) wine $(bindir)/wine
 
-install:: $(PROGRAMS) $(EMU_TARGET:%=install_%) $(LIBEXT:%=install_%)
+install:: $(PROGRAMS) $(LIBPROGRAMS) $(EMU_TARGET:%=install_%) $(LIBEXT:%=install_%)
 	[ -d $(bindir) ] || $(MKDIR) $(bindir)
 	$(INSTALL_PROGRAM) server/wineserver $(bindir)/wineserver
 	$(INSTALL_PROGRAM) windows/x11drv/wineclipsrv $(bindir)/wineclipsrv
 	$(INSTALL_PROGRAM) loader/dos/dosmod $(bindir)/dosmod
+	$(INSTALL_PROGRAM) debugger/winedbg $(bindir)/winedbg
 
 uninstall::
 	cd $(libdir) && $(RM) libwine.a libwine.so libwine.so.$(SOVERSION) wine.sym
-	cd $(bindir) && $(RM) wine wineserver wineclipsrv dosmod
+	cd $(bindir) && $(RM) wine wineserver wineclipsrv dosmod winedbg
 
 lib$(MODULE).so.$(SOVERSION): $(OBJS) Makefile.in Make.rules.in
 	$(LDSHARED) $(OBJS) -o $@
@@ -191,9 +198,11 @@
 checklink::
 	$(CC) -o checklink $(TOPSRCDIR)/library/checklink.c -L. -lwine $(LDOPTIONS) $(X_LIBS) $(XLIB) $(LIBS) && $(RM) checklink
 
-$(EMUOBJS) $(LIBOBJS) $(DLLOBJS) $(PROGRAMS): $(TOOLSUBDIRS) dummy
+$(EMUOBJS) $(LIBOBJS) $(DLLOBJS) $(PROGRAMS) $(LIBPROGRAMS): $(TOOLSUBDIRS) dummy
 	@cd `dirname $@` && $(MAKE) `basename $@`
 
+$(LIBPROGRAMS): lib$(MODULE).$(LIBEXT) $(DLLOBJS)
+
 $(LIBLINTS) $(EMULINTS): dummy
 	@cd `dirname $@` && $(MAKE) lint
 
diff --git a/debugger/.cvsignore b/debugger/.cvsignore
index 8e7a162..7f47d23 100644
--- a/debugger/.cvsignore
+++ b/debugger/.cvsignore
@@ -1,4 +1,6 @@
 Makefile
 lex.yy.c
+winedbg
+winedbg.spec.c
 y.tab.c
 y.tab.h
diff --git a/debugger/Makefile.in b/debugger/Makefile.in
index df5677b..a6d15b9 100644
--- a/debugger/Makefile.in
+++ b/debugger/Makefile.in
@@ -1,9 +1,12 @@
-DEFS      = -D__WINE__ -DLIBDIR="\"$(libdir)\""
+DEFS      = -DWINELIB
 TOPSRCDIR = @top_srcdir@
 TOPOBJDIR = ..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
-MODULE    = debugger
+MODULE    = none
+PROGRAMS  = winedbg
+ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XLIB) $(LIBS)
+WRCEXTRA  = -A -p $*
 
 C_SRCS = \
 	break.c \
@@ -24,19 +27,15 @@
 	types.c \
 	winedbg.c
 
+SPEC_SRCS = winedbg.spec
+
 EXTRA_SRCS = dbg.y debug.l
 EXTRA_OBJS = y.tab.o lex.yy.o
 
-all: $(MODULE).o
+all: $(PROGRAMS)
 
 depend: y.tab.h
 
-#
-# This is a special test program that helps debug the internal debugger.
-#
-debug: $(MODULE).o dbgmain.o ../misc/xmalloc.o
-	$(CC) -o debug $(MODULE).o dbgmain.o ../misc/xmalloc.o
-
 @MAKE_RULES@
 
 y.tab.c y.tab.h: dbg.y
@@ -45,4 +44,7 @@
 lex.yy.c: debug.l
 	$(LEX) -8 -I $(SRCDIR)/debug.l
 
+winedbg: $(OBJS)
+	$(CC) -o $@ $(OBJS) $(LDOPTIONS) $(ALL_LIBS)
+
 ### Dependencies:
diff --git a/debugger/break.c b/debugger/break.c
index f38cb2f..616dbc8 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -185,7 +185,7 @@
 	    if (!DEBUG_WRITE_MEM( (void*)DEBUG_ToLinear(&breakpoints[i].addr), 
 				  &ch, sizeof(ch) ))
 	    {
-	       fprintf(stderr, "Invalid address for breakpoint %d, disabling it\n", i);
+	       DEBUG_Printf(DBG_CHN_MESG, "Invalid address for breakpoint %d, disabling it\n", i);
 	       breakpoints[i].enabled = FALSE;
 	    }
 	 }
@@ -291,7 +291,7 @@
       }
    }
    
-   fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
+   DEBUG_Printf( DBG_CHN_MESG, "Too many breakpoints. Please delete some.\n" );
    return -1;
 }
 
@@ -361,10 +361,10 @@
 
     breakpoints[num].u.opcode  = ch;
 
-    fprintf( stderr, "Breakpoint %d at ", num );
+    DEBUG_Printf( DBG_CHN_MESG, "Breakpoint %d at ", num );
     DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32 : 16,
 			TRUE );
-    fprintf( stderr, "\n" );
+    DEBUG_Printf( DBG_CHN_MESG, "\n" );
 }
 
 
@@ -382,7 +382,9 @@
    
    assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
 
-   DEBUG_FixAddress( &value.addr, CS_reg(&DEBUG_context) );
+#ifdef __i386__
+   DEBUG_FixAddress( &value.addr, DEBUG_context.SegCs );
+#endif
    
    if ( value.type != NULL && value.type == DEBUG_TypeIntConst )
    {
@@ -408,7 +410,7 @@
    for (reg = 0; reg < 4 && (mask & (1 << reg)); reg++);
    if (reg == 4)
    {
-      fprintf(stderr, "All i386 hardware watchpoints have been set. Delete some\n");
+      DEBUG_Printf(DBG_CHN_MESG, "All i386 hardware watchpoints have been set. Delete some\n");
       return;
    }
 #endif
@@ -422,16 +424,16 @@
    
    if (!DEBUG_GetWatchedValue( num, &breakpoints[num].u.w.oldval)) 
    {
-      fprintf(stderr, "Bad address. Watchpoint not set\n");
+      DEBUG_Printf(DBG_CHN_MESG, "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_Printf( DBG_CHN_MESG, "Watchpoint %d at ", num );
    DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? 32:16, TRUE );
-   fprintf( stderr, "\n" );
+   DEBUG_Printf( DBG_CHN_MESG, "\n" );
 }
 
 /***********************************************************************
@@ -443,7 +445,7 @@
 {
     if ((num <= 0) || (num >= next_bp) || breakpoints[num].refcount == 0)
     {
-        fprintf( stderr, "Invalid breakpoint number %d\n", num );
+        DEBUG_Printf( DBG_CHN_MESG, "Invalid breakpoint number %d\n", num );
         return;
     }
 
@@ -470,7 +472,7 @@
 {
     if ((num <= 0) || (num >= next_bp) || breakpoints[num].refcount == 0)
     {
-        fprintf( stderr, "Invalid breakpoint number %d\n", num );
+        DEBUG_Printf( DBG_CHN_MESG, "Invalid breakpoint number %d\n", num );
         return;
     }
     breakpoints[num].enabled = (enable) ? TRUE : FALSE;
@@ -557,40 +559,40 @@
 {
     int i;
 
-    fprintf( stderr, "Breakpoints:\n" );
+    DEBUG_Printf( DBG_CHN_MESG, "Breakpoints:\n" );
     for (i = 1; i < next_bp; i++)
     {
         if (breakpoints[i].refcount && breakpoints[i].type == DBG_BREAK)
         {
-            fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
+            DEBUG_Printf( DBG_CHN_MESG, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
             DEBUG_PrintAddress( &breakpoints[i].addr, 
 				breakpoints[i].is32 ? 32 : 16, TRUE);
-            fprintf( stderr, " (%u)\n", breakpoints[i].refcount );
+            DEBUG_Printf( DBG_CHN_MESG, " (%u)\n", breakpoints[i].refcount );
 	    if( breakpoints[i].condition != NULL )
 	    {
-	        fprintf(stderr, "\t\tstop when  ");
+	        DEBUG_Printf(DBG_CHN_MESG, "\t\tstop when  ");
  		DEBUG_DisplayExpr(breakpoints[i].condition);
-		fprintf(stderr, "\n");
+		DEBUG_Printf(DBG_CHN_MESG, "\n");
 	    }
         }
     }
-    fprintf( stderr, "Watchpoints:\n" );
+    DEBUG_Printf( DBG_CHN_MESG, "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_Printf( DBG_CHN_MESG, "%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", 
+            DEBUG_Printf( DBG_CHN_MESG, " 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_Printf(DBG_CHN_MESG, "\t\tstop when  ");
  		DEBUG_DisplayExpr(breakpoints[i].condition);
-		fprintf(stderr, "\n");
+		DEBUG_Printf(DBG_CHN_MESG, "\n");
 	    }
         }
     }
@@ -613,9 +615,9 @@
 	 /*
 	  * Something wrong - unable to evaluate this expression.
 	  */
-	 fprintf(stderr, "Unable to evaluate expression ");
+	 DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression ");
 	 DEBUG_DisplayExpr(breakpoints[bpnum].condition);
-	 fprintf(stderr, "\nTurning off condition\n");
+	 DEBUG_Printf(DBG_CHN_MESG, "\nTurning off condition\n");
 	 DEBUG_AddBPCondition(bpnum, NULL);
       }
       else if( !DEBUG_GetExprValue( &value, NULL) )
@@ -658,10 +660,10 @@
     {
         if (!DEBUG_ShallBreak(bpnum)) return TRUE;
 
-        fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
+        DEBUG_Printf( DBG_CHN_MESG, "Stopped on breakpoint %d at ", bpnum );
         syminfo = DEBUG_PrintAddress( &breakpoints[bpnum].addr,
 				      breakpoints[bpnum].is32 ? 32 : 16, TRUE );
-        fprintf( stderr, "\n" );
+        DEBUG_Printf( DBG_CHN_MESG, "\n" );
 	
 	if( syminfo.list.sourcefile != NULL )
 	    DEBUG_List(&syminfo.list, NULL, 0);
@@ -674,16 +676,18 @@
        /* If not single-stepping, do not back up over the int3 instruction */
        if (code == EXCEPTION_BREAKPOINT) 
        {
-	   EIP_reg(&DEBUG_context)++;
+#ifdef __i386__
+	   DEBUG_context.Eip++;
 	   addr.off++;
+#endif
        }
        if (!DEBUG_ShallBreak(wpnum)) return TRUE;
        
-       fprintf(stderr, "Stopped on watchpoint %d at ", wpnum);
+       DEBUG_Printf(DBG_CHN_MESG, "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", 
+       DEBUG_Printf(DBG_CHN_MESG, " values: old=%lu new=%lu\n", 
 	       oldval, breakpoints[wpnum].u.w.oldval);
        if (syminfo.list.sourcefile != NULL)
 	  DEBUG_List(&syminfo.list, NULL, 0);
@@ -740,7 +744,7 @@
 }
 
 /***********************************************************************
- *           DEBUG_RestartExecution
+ *           DEBUG_SuspendExecution
  *
  * Remove all breakpoints before entering the debug loop
  */
@@ -791,7 +795,7 @@
       {
 	if( mode == EXEC_CONT && count > 1 )
 	  {
-	    fprintf(stderr, "Not stopped at any breakpoint; argument ignored.\n");
+	    DEBUG_Printf(DBG_CHN_MESG, "Not stopped at any breakpoint; argument ignored.\n");
 	  }
       }
     
@@ -823,7 +827,7 @@
 	    && status == FUNC_IS_TRAMPOLINE )
 	  {
 #if 0
-	    fprintf(stderr, "Not stepping into trampoline at %x (no lines)\n",
+	    DEBUG_Printf(DBG_CHN_MESG, "Not stepping into trampoline at %x (no lines)\n",
 		    addr2.off);
 #endif
 	    mode = EXEC_STEP_OVER_TRAMPOLINE;
@@ -832,7 +836,7 @@
 	if( mode == EXEC_STEP_INSTR && status == FUNC_HAS_NO_LINES )
 	  {
 #if 0
-	    fprintf(stderr, "Not stepping into function at %x (no lines)\n",
+	    DEBUG_Printf(DBG_CHN_MESG, "Not stepping into function at %x (no lines)\n",
 		    addr2.off);
 #endif
 	    mode = EXEC_STEP_OVER;
@@ -844,8 +848,8 @@
       {
 	if( DEBUG_CheckLinenoStatus(&addr) == FUNC_HAS_NO_LINES )
 	  {
-	    fprintf(stderr, "Single stepping until exit from function, \n");
-	    fprintf(stderr, "which has no line number information.\n");
+	    DEBUG_Printf(DBG_CHN_MESG, "Single stepping until exit from function, \n");
+	    DEBUG_Printf(DBG_CHN_MESG, "which has no line number information.\n");
 	    
 	    ret_mode = mode = EXEC_FINISH;
 	  }
@@ -909,6 +913,8 @@
         DEBUG_context.EFlags |= STEP_FLAG;
 #endif
         break;
+    case EXEC_KILL:
+        break;
     default:
         RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
     }
@@ -921,7 +927,7 @@
 {
     if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
     {
-        fprintf( stderr, "Invalid breakpoint number %d\n", num );
+        DEBUG_Printf( DBG_CHN_MESG, "Invalid breakpoint number %d\n", num );
         return FALSE;
     }
 
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 9f1a0be..1a2e9e8 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -896,7 +896,7 @@
     char       		buffer[4];
 
     if (size != 1 && size != 2 && size != 4) {
-        fprintf(stderr, "Illegal size specified\n");
+        DEBUG_Printf(DBG_CHN_MESG, "Illegal size specified\n");
     } else {
        DEBUG_READ_MEM((void*)DEBUG_ToLinear( addr ), buffer, size);
 
@@ -1020,22 +1020,21 @@
 void db_print_address(char *seg, int size, struct i_addr *addrp, int byref)
 {
 	if (addrp->is_reg) {
-	    fprintf(stderr,"%s", db_reg[size][addrp->disp]);
+	    DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[size][addrp->disp]);
 	    return;
 	}
 
 	if (seg) {
-	    fprintf(stderr,"%s:", seg);
+	    DEBUG_Printf(DBG_CHN_MESG,"%s:", seg);
 	}
 
 	if (addrp->base != 0 || addrp->index != 0) {
-	    fprintf(stderr,"0x%x", addrp->disp);
-	    fprintf(stderr,"(");
+	    DEBUG_Printf(DBG_CHN_MESG,"0x%x(", addrp->disp);
 	    if (addrp->base)
-		fprintf(stderr,"%s", addrp->base);
+		DEBUG_Printf(DBG_CHN_MESG,"%s", addrp->base);
 	    if (addrp->index)
-		fprintf(stderr,",%s,%d", addrp->index, 1<<addrp->ss);
-	    fprintf(stderr,")");
+		DEBUG_Printf(DBG_CHN_MESG,",%s,%d", addrp->index, 1<<addrp->ss);
+	    DEBUG_Printf(DBG_CHN_MESG,")");
 	} 
 	else {
 
@@ -1045,11 +1044,11 @@
 	       void*	a1;
 	       void*	a2;
 
-               fprintf(stderr,"0x%x -> ", addrp->disp);
+               DEBUG_Printf(DBG_CHN_MESG,"0x%x -> ", addrp->disp);
 	       if (!DEBUG_READ_MEM((void*)addrp->disp, &a1, sizeof(a1))) {
-		   fprintf(stderr, "(invalid source)");
+		   DEBUG_Printf(DBG_CHN_MESG, "(invalid source)");
 	       } else if (!DEBUG_READ_MEM(a1, &a2, sizeof(a2))) {
-		  fprintf(stderr, "(invalid destination)");
+		  DEBUG_Printf(DBG_CHN_MESG, "(invalid destination)");
 	       } else {
 		  db_task_printsym((unsigned long)a1, 0);
                }
@@ -1085,30 +1084,30 @@
 	     * Normal address modes.
 	     */
 	    db_read_address( addr, short_addr, regmodrm, &address);
-	    fprintf(stderr,fp->f_name);
+	    DEBUG_Printf(DBG_CHN_MESG,fp->f_name);
 	    switch(fp->f_size) {
 		case SNGL:
-		    fprintf(stderr,"s");
+		    DEBUG_Printf(DBG_CHN_MESG,"s");
 		    break;
 		case DBLR:
-		    fprintf(stderr,"l");
+		    DEBUG_Printf(DBG_CHN_MESG,"l");
 		    break;
 		case EXTR:
-		    fprintf(stderr,"t");
+		    DEBUG_Printf(DBG_CHN_MESG,"t");
 		    break;
 		case WORD:
-		    fprintf(stderr,"s");
+		    DEBUG_Printf(DBG_CHN_MESG,"s");
 		    break;
 		case LONG:
-		    fprintf(stderr,"l");
+		    DEBUG_Printf(DBG_CHN_MESG,"l");
 		    break;
 		case QUAD:
-		    fprintf(stderr,"q");
+		    DEBUG_Printf(DBG_CHN_MESG,"q");
 		    break;
 		default:
 		    break;
 	    }
-	    fprintf(stderr,"\t");
+	    DEBUG_Printf(DBG_CHN_MESG,"\t");
 	    db_print_address(seg, BYTE, &address, 0);
 	}
 	else {
@@ -1118,25 +1117,25 @@
 	    switch (fp->f_rrmode) {
 		case op2(ST,STI):
 		    name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
-		    fprintf(stderr,"%s\t%%st,%%st(%d)",name,f_rm(regmodrm));
+		    DEBUG_Printf(DBG_CHN_MESG,"%s\t%%st,%%st(%d)",name,f_rm(regmodrm));
 		    break;
 		case op2(STI,ST):
 		    name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
-		    fprintf(stderr,"%s\t%%st(%d),%%st",name, f_rm(regmodrm));
+		    DEBUG_Printf(DBG_CHN_MESG,"%s\t%%st(%d),%%st",name, f_rm(regmodrm));
 		    break;
 		case op1(STI):
 		    name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
-		    fprintf(stderr,"%s\t%%st(%d)",name, f_rm(regmodrm));
+		    DEBUG_Printf(DBG_CHN_MESG,"%s\t%%st(%d)",name, f_rm(regmodrm));
 		    break;
 		case op1(X):
-		    fprintf(stderr,"%s", ((char **)fp->f_rrname)[f_rm(regmodrm)]);
+		    DEBUG_Printf(DBG_CHN_MESG,"%s", ((char **)fp->f_rrname)[f_rm(regmodrm)]);
 		    break;
 		case op1(XA):
-		    fprintf(stderr,"%s\t%%ax",
+		    DEBUG_Printf(DBG_CHN_MESG,"%s\t%%ax",
 				 ((char **)fp->f_rrname)[f_rm(regmodrm)]);
 		    break;
 		default:
-		    fprintf(stderr,"<bad instruction>");
+		    DEBUG_Printf(DBG_CHN_MESG,"<bad instruction>");
 		    break;
 	    }
 	}
@@ -1174,7 +1173,7 @@
         switch (DEBUG_GetSelectorType(addr->seg)) {
 	case 16: db_disasm_16 = 1; break;
 	case 32: db_disasm_16 = 0; break;
-	default: fprintf(stderr, "Bad selector %ld\n", addr->seg); return;
+	default: DEBUG_Printf(DBG_CHN_MESG, "Bad selector %ld\n", addr->seg); return;
 	}
 
 	get_value_inc( inst, addr, 1, FALSE );
@@ -1224,15 +1223,15 @@
 		    break;
 		case 0xf0:
 		    if( db_display )
-			fprintf(stderr,"lock ");
+			DEBUG_Printf(DBG_CHN_MESG,"lock ");
 		    break;
 		case 0xf2:
 		    if( db_display )
-			fprintf(stderr,"repne ");
+			DEBUG_Printf(DBG_CHN_MESG,"repne ");
 		    break;
 		case 0xf3:
 		    if( db_display )
-			fprintf(stderr,"repe ");	/* XXX repe VS rep */
+			DEBUG_Printf(DBG_CHN_MESG,"repe ");	/* XXX repe VS rep */
 		    break;
 		default:
 		    prefix = FALSE;
@@ -1297,28 +1296,28 @@
 	  if( db_display )
 	    {
 	      if (size == WORD)
-		fprintf(stderr,i_name);
+		DEBUG_Printf(DBG_CHN_MESG,i_name);
 	      else
-		fprintf(stderr,ip->i_extra);
+		DEBUG_Printf(DBG_CHN_MESG,ip->i_extra);
 	    }
 	}
 	else {
 	  if( db_display )
 	    {
-	      fprintf(stderr,i_name);
+	      DEBUG_Printf(DBG_CHN_MESG,i_name);
 	    }
 	    if (i_size != NONE) {
 		if (i_size == BYTE) {
 		  if( db_display )
 		    {
-		      fprintf(stderr,"b");
+		      DEBUG_Printf(DBG_CHN_MESG,"b");
 		    }
 		    size = BYTE;
 		}
 		else if (i_size == WORD) {
 		  if( db_display )
 		    {
-		      fprintf(stderr,"w");
+		      DEBUG_Printf(DBG_CHN_MESG,"w");
 		    }
 		    size = WORD;
 		}
@@ -1326,28 +1325,28 @@
 		  {
 		  if( db_display )
 		    {
-		      fprintf(stderr,"w");
+		      DEBUG_Printf(DBG_CHN_MESG,"w");
 		    }
 		  }
 		else
 		  {
 		  if( db_display )
 		    {
-		      fprintf(stderr,"l");
+		      DEBUG_Printf(DBG_CHN_MESG,"l");
 		    }
 		  }
 	    }
 	}
 	if( db_display )
 	  {
-	    fprintf(stderr,"\t");
+	    DEBUG_Printf(DBG_CHN_MESG,"\t");
 	  }
 	for (first = TRUE;
 	     i_mode != 0;
 	     i_mode >>= 8, first = FALSE)
 	{
 	    if (!first && db_display)
-		fprintf(stderr,",");
+		DEBUG_Printf(DBG_CHN_MESG,",");
 
 	    switch (i_mode & 0xFF) {
 
@@ -1361,7 +1360,7 @@
 		case Eind:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"*");
+		      DEBUG_Printf(DBG_CHN_MESG,"*");
 		      db_print_address(seg, size, &address, 1);
 		    }
 		    break;
@@ -1383,42 +1382,42 @@
 		case R:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%s", db_reg[size][f_reg(regmodrm)]);
+		      DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[size][f_reg(regmodrm)]);
 		    }
 		    break;
 
 		case Rw:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%s", db_reg[WORD][f_reg(regmodrm)]);
+		      DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[WORD][f_reg(regmodrm)]);
 		    }
 		    break;
 
 		case Ri:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%s", db_reg[size][f_rm(inst)]);
+		      DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[size][f_rm(inst)]);
 		    }
 		    break;
 
 		case S:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%s", db_seg_reg[f_reg(regmodrm)]);
+		      DEBUG_Printf(DBG_CHN_MESG,"%s", db_seg_reg[f_reg(regmodrm)]);
 		    }
 		    break;
 
 		case Si:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%s", db_seg_reg[f_reg(inst)]);
+		      DEBUG_Printf(DBG_CHN_MESG,"%s", db_seg_reg[f_reg(inst)]);
 		    }
 		    break;
 
 		case A:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%s", db_reg[size][0]);	/* acc */
+		      DEBUG_Printf(DBG_CHN_MESG,"%s", db_reg[size][0]);	/* acc */
 		    }
 		    break;
 
@@ -1426,22 +1425,22 @@
 		  if( db_display )
 		    {
 		      if (seg)
-			fprintf(stderr,"%s:", seg);
-		      fprintf(stderr,"(%s)", short_addr ? "%bx" : "%ebx");
+			DEBUG_Printf(DBG_CHN_MESG,"%s:", seg);
+		      DEBUG_Printf(DBG_CHN_MESG,"(%s)", short_addr ? "%bx" : "%ebx");
 		    }
 		    break;
 
 		case CL:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%%cl");
+		      DEBUG_Printf(DBG_CHN_MESG,"%%cl");
 		    }
 		    break;
 
 		case DX:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%%dx");
+		      DEBUG_Printf(DBG_CHN_MESG,"%%dx");
 		    }
 		    break;
 
@@ -1449,36 +1448,36 @@
 		  if( db_display )
 		    {
 		      if (seg)
-			fprintf(stderr,"%s:", seg);
-		      fprintf(stderr,"(%s)", short_addr ? "%si" : "%esi");
+			DEBUG_Printf(DBG_CHN_MESG,"%s:", seg);
+		      DEBUG_Printf(DBG_CHN_MESG,"(%s)", short_addr ? "%si" : "%esi");
 		    }
 		    break;
 
 		case DI:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%%es:(%s)", short_addr ? "%di" : "%edi");
+		      DEBUG_Printf(DBG_CHN_MESG,"%%es:(%s)", short_addr ? "%di" : "%edi");
 		    }
 		    break;
 
 		case CR:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%%cr%d", f_reg(regmodrm));
+		      DEBUG_Printf(DBG_CHN_MESG,"%%cr%d", f_reg(regmodrm));
 		    }
 		    break;
 
 		case DR:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%%dr%d", f_reg(regmodrm));
+		      DEBUG_Printf(DBG_CHN_MESG,"%%dr%d", f_reg(regmodrm));
 		    }
 		    break;
 
 		case TR:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"%%tr%d", f_reg(regmodrm));
+		      DEBUG_Printf(DBG_CHN_MESG,"%%tr%d", f_reg(regmodrm));
 		    }
 		    break;
 
@@ -1487,7 +1486,7 @@
 		    get_value_inc(imm, addr, len, FALSE);/* unsigned */
 		    if( db_display )
 		      {
-			fprintf(stderr,"$0x%x", imm);
+			DEBUG_Printf(DBG_CHN_MESG,"$0x%x", imm);
 		      }
 		    break;
 
@@ -1496,7 +1495,7 @@
 		    get_value_inc(imm, addr, len, TRUE); /* signed */
 		  if( db_display )
 		    {
-		      fprintf(stderr,"$%d", imm);
+		      DEBUG_Printf(DBG_CHN_MESG,"$%d", imm);
 		    }
 		    break;
 
@@ -1504,7 +1503,7 @@
 		    get_value_inc(imm, addr, 1, FALSE); /* unsigned */
 		  if( db_display )
 		    {
-		      fprintf(stderr,"$0x%x", imm);
+		      DEBUG_Printf(DBG_CHN_MESG,"$0x%x", imm);
 		    }
 		    break;
 
@@ -1512,7 +1511,7 @@
 		    get_value_inc(imm, addr, 1, TRUE); /* signed */
 		  if( db_display )
 		    {
-		      fprintf(stderr,"$%d", imm);
+		      DEBUG_Printf(DBG_CHN_MESG,"$%d", imm);
 		    }
 		    break;
 
@@ -1520,7 +1519,7 @@
 		    get_value_inc(imm, addr, 2, FALSE); /* unsigned */
 		  if( db_display )
 		    {
-		      fprintf(stderr,"$0x%x", imm);
+		      DEBUG_Printf(DBG_CHN_MESG,"$0x%x", imm);
 		    }
 		    break;
 
@@ -1528,7 +1527,7 @@
 		    get_value_inc(imm, addr, 4, FALSE);
 		  if( db_display )
 		    {
-		      fprintf(stderr,"$0x%x", imm);
+		      DEBUG_Printf(DBG_CHN_MESG,"$0x%x", imm);
 		    }
 		    break;
 
@@ -1545,7 +1544,7 @@
 		      }
 
 		    if (seg)
-			fprintf(stderr,"%s:0x%x",seg, displ);
+			DEBUG_Printf(DBG_CHN_MESG,"%s:0x%x",seg, displ);
 		    else
 			db_task_printsym(displ, short_addr ? WORD : LONG);
 		    break;
@@ -1587,14 +1586,14 @@
 		case o1:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"$1");
+		      DEBUG_Printf(DBG_CHN_MESG,"$1");
 		    }
 		    break;
 
 		case o3:
 		  if( db_display )
 		    {
-		      fprintf(stderr,"$3");
+		      DEBUG_Printf(DBG_CHN_MESG,"$3");
 		    }
 		    break;
 
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 1ed882b..913e1d4 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -95,7 +95,8 @@
     | error tEOL               { yyerrok; }
 
 command:
-      tQUIT tEOL               { DEBUG_Exit(0); }
+      tQUIT tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_KILL; return 1; }
     | tHELP tEOL               { DEBUG_Help(); }
     | tHELP tINFO tEOL         { DEBUG_HelpInfo(); }
     | tCONT tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
@@ -164,8 +165,8 @@
  					     DEBUG_FreeExprMem(); }
 
 pathname:
-      tIDENTIFIER                    { $$ = $1; }
-    | tPATH			     { $$ = $1; }
+      tIDENTIFIER              { $$ = $1; }
+    | tPATH		       { $$ = $1; }
 
 disassemble_command:
       tDISASSEMBLE tEOL              { DEBUG_Disassemble( NULL, NULL, 10 ); }
@@ -210,7 +211,7 @@
 				   }
 				 else
 				   {
-				     fprintf(stderr,"Unable to add breakpoint\n");
+				     DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
 				   }
 				}
     | tBREAK tIDENTIFIER ':' tNUM tEOL  { DBG_VALUE value;
@@ -220,9 +221,9 @@
 				   }
 				 else
 				   {
-				     fprintf(stderr,"Unable to add breakpoint\n");
+				     DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
 				   }
-				}
+			       }
     | tBREAK tNUM tEOL	       { struct name_hash *nh;
 				 DBG_VALUE value;
 				 DEBUG_GetCurrentAddress( &value.addr );
@@ -237,7 +238,7 @@
 				   }
 				 else
 				   {
-				     fprintf(stderr,"Unable to add breakpoint\n");
+				     DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
 				   }
                                }
 
@@ -255,7 +256,7 @@
 				 if( DEBUG_GetSymbolValue($2, -1, &value, TRUE) )
 				     DEBUG_AddWatchpoint( &value, 1 );
 				 else
-				     fprintf(stderr,"Unable to add breakpoint\n");
+				     DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
 				}
 
 info_command:
@@ -388,49 +389,43 @@
 static void issue_prompt(void)
 {
 #ifdef DONT_USE_READLINE
-   fprintf(stderr, "Wine-dbg>");
+   DEBUG_Printf(DBG_CHN_MESG, "Wine-dbg>");
 #endif
 }
 
 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");
+    else DEBUG_Printf(DBG_CHN_MESG,"Invalid mode (use 16 or 32)\n");
+}
+
+void DEBUG_Exit(DWORD ec)
+{
+   ExitProcess(ec);
 }
 
 static WINE_EXCEPTION_FILTER(wine_dbg_cmd)
 {
-	fprintf(stderr, "\nwine_dbg_cmd: ");
+   DEBUG_Printf(DBG_CHN_MESG, "\nwine_dbg_cmd: ");
    switch (GetExceptionCode()) {
    case DEBUG_STATUS_INTERNAL_ERROR:
-      fprintf(stderr, "WineDbg internal error\n");
+      DEBUG_Printf(DBG_CHN_MESG, "WineDbg internal error\n");
       break;
    case DEBUG_STATUS_NO_SYMBOL:
-      fprintf(stderr, "Undefined symbol\n");
+      DEBUG_Printf(DBG_CHN_MESG, "Undefined symbol\n");
       break;
    case DEBUG_STATUS_DIV_BY_ZERO:
-      fprintf(stderr, "Division by zero\n");
+      DEBUG_Printf(DBG_CHN_MESG, "Division by zero\n");
       break;
    case DEBUG_STATUS_BAD_TYPE:
-      fprintf(stderr, "No type or type mismatch\n");
+      DEBUG_Printf(DBG_CHN_MESG, "No type or type mismatch\n");
       break;
    default:
-      fprintf(stderr, "Exception %lx\n", GetExceptionCode());
+      DEBUG_Printf(DBG_CHN_MESG, "Exception %lx\n", GetExceptionCode());
       break;
    }
-   return EXCEPTION_EXECUTE_HANDLER;
-}
 
-/***********************************************************************
- *           DEBUG_Exit
- *
- * Kill current process.
- *
- */
-void DEBUG_Exit( DWORD exit_code )
-{
-    TASK_KillTask( 0 ); /* FIXME: should not be necessary */
-    TerminateProcess( DEBUG_CurrProcess->handle, exit_code );
+   return EXCEPTION_EXECUTE_HANDLER;
 }
 
 /***********************************************************************
@@ -456,17 +451,16 @@
     {
 #ifdef __i386__
         if (DEBUG_IsSelectorSystem(DEBUG_context.SegCs))
-            fprintf( stderr, " in 32-bit code (0x%08lx).\n", DEBUG_context.Eip );
+            DEBUG_Printf( DBG_CHN_MESG, " in 32-bit code (0x%08lx).\n", DEBUG_context.Eip );
         else
-            fprintf( stderr, " in 16-bit code (%04x:%04lx).\n",
-                     (WORD)DEBUG_context.SegCs, DEBUG_context.Eip );
+            DEBUG_Printf( DBG_CHN_MESG, " in 16-bit code (%04x:%04lx).\n",
+			  (WORD)DEBUG_context.SegCs, DEBUG_context.Eip );
 #else
-        fprintf( stderr, " (%p).\n", GET_IP(&DEBUG_context) );
+        DEBUG_Printf( DBG_CHN_MESG, " (%p).\n", GET_IP(&DEBUG_context) );
 #endif
     }
 
-    if (DEBUG_LoadEntryPoints("Loading new modules symbols:\n"))
-       DEBUG_ProcessDeferredDebug();
+    DEBUG_LoadEntryPoints("Loading new modules symbols:\n");
 
     if (force || !(is_debug && DEBUG_ShouldContinue( code, 
 						     DEBUG_CurrThread->dbg_exec_mode, 
@@ -478,13 +472,13 @@
 #ifdef __i386__
         switch (newmode = DEBUG_GetSelectorType(addr.seg)) {
 	case 16: case 32: break;
-	default: fprintf(stderr, "Bad CS (%ld)\n", addr.seg); newmode = 32;
+	default: DEBUG_Printf(DBG_CHN_MESG, "Bad CS (%ld)\n", addr.seg); newmode = 32;
 	}
 #else
         newmode = 32;
 #endif
         if (newmode != DEBUG_CurrThread->dbg_mode)
-            fprintf(stderr,"In %d bit mode.\n", DEBUG_CurrThread->dbg_mode = newmode);
+            DEBUG_Printf(DBG_CHN_MESG,"In %d bit mode.\n", DEBUG_CurrThread->dbg_mode = newmode);
 
 	DEBUG_DoDisplay();
 
@@ -520,9 +514,9 @@
 	    /* Show where we crashed */
 	    curr_frame = 0;
 	    DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, TRUE );
-	    fprintf(stderr,":  ");
+	    DEBUG_Printf(DBG_CHN_MESG,":  ");
 	    DEBUG_Disasm( &addr, TRUE );
-	    fprintf( stderr, "\n" );
+	    DEBUG_Printf( DBG_CHN_MESG, "\n" );
         }
 
         ret_ok = 0;
@@ -531,16 +525,20 @@
 	    __TRY 
 	    {
 	       issue_prompt();
-	       yyparse();
-	       flush_symbols();
+	       if (yyparse()) {
+		  DEBUG_CurrThread->dbg_exec_mode = EXEC_KILL;
+		  ret_ok = TRUE;
+	       } else {
+		  flush_symbols();
 
-	       DEBUG_GetCurrentAddress( &addr );
-	       if ((ret_ok = DEBUG_ValidateRegisters()))
-		  ret_ok = DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &addr ), &ch, 1 );
+		  DEBUG_GetCurrentAddress( &addr );
+		  ret_ok = DEBUG_ValidateRegisters() && 
+		     DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(&addr), &ch, 1);
+	       }
 	    } 
 	    __EXCEPT(wine_dbg_cmd)
 	    {
-	       ret_ok = 0;
+	       ret_ok = FALSE;
 	    }
 	    __ENDTRY;
 
@@ -553,14 +551,14 @@
      * if it was used.  Otherwise it would have been ignored.
      * In any case, we don't mess with it any more.
      */
-    if ((DEBUG_CurrThread->dbg_exec_mode == EXEC_CONT) || (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS))
+    if (DEBUG_CurrThread->dbg_exec_mode == EXEC_CONT || DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS)
 	DEBUG_CurrThread->dbg_exec_count = 0;
     
-    return (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS) ? 0 : DBG_CONTINUE;
+    return (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS) ? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
 }
 
 int yyerror(char* s)
 {
-   fprintf(stderr,"%s\n", s);
+   DEBUG_Printf(DBG_CHN_MESG,"%s\n", s);
    return 0;
 }
diff --git a/debugger/debug.l b/debugger/debug.l
index c0020d0..2884216 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -190,7 +190,7 @@
 
 .		{ if (syntax_error == 0)
                   {
-		    syntax_error ++; fprintf(stderr, "Syntax Error\n");
+		    syntax_error ++; DEBUG_Printf(DBG_CHN_MESG, "Syntax Error\n");
                   }
 		}
 
@@ -239,7 +239,7 @@
         line = readline ("Wine-dbg>");
         if (!line)
         {
-            fprintf( stderr, "\n" );
+            DEBUG_Printf( DBG_CHN_MESG, "\n" );
             DEBUG_Exit(0);
         }
 
@@ -264,8 +264,8 @@
         {
             if (size < len + 1)
             {
-                fprintf(stderr,"Fatal readline goof.\n");
-                DEBUG_Exit(0);
+                DEBUG_Printf(DBG_CHN_MESG,"Fatal readline goof.\n");
+		DEBUG_Exit(0);
             }
             strcpy(buf, line);
             buf[len] = '\n';
diff --git a/debugger/debugger.h b/debugger/debugger.h
index d95ce57..2ff273c 100644
--- a/debugger/debugger.h
+++ b/debugger/debugger.h
@@ -106,11 +106,12 @@
     EXEC_STEPI_OVER,  		/* Stepping over a call */
     EXEC_STEPI_INSTR,  		/* Single-stepping an instruction */
     EXEC_FINISH,		/* Step until we exit current frame */
-    EXEC_STEP_OVER_TRAMPOLINE  	/* Step over trampoline.  Requires that
+    EXEC_STEP_OVER_TRAMPOLINE, 	/* Step over trampoline.  Requires that
 				 * we dig the real return value off the stack
 				 * and set breakpoint there - not at the
 				 * instr just after the call.
 				 */
+    EXEC_KILL			/* terminate debugging session */
 };
 
 #define	DBG_BREAK 0
@@ -330,6 +331,7 @@
 extern int DEBUG_ReadMemory( const DBG_ADDR *address );
 extern void DEBUG_WriteMemory( const DBG_ADDR *address, int value );
 extern void DEBUG_ExamineMemory( const DBG_VALUE *addr, int count, char format);
+extern void DEBUG_InvalAddr( const DBG_ADDR* addr );
 extern void DEBUG_InvalLinAddr( void* addr );
 #ifdef __i386__
 extern void DEBUG_GetCurrentAddress( DBG_ADDR * );
@@ -342,21 +344,19 @@
 
   /* debugger/module.c */
 extern int  DEBUG_LoadEntryPoints( const char * prefix );
-extern void DEBUG_LoadModule32( const char* name, DWORD base );
+extern void DEBUG_LoadModule32( const char* name, HANDLE hFile, DWORD base );
 extern DBG_MODULE* DEBUG_AddModule(const char* name, int type, 
 				   void* mod_addr, HMODULE hmod);
 extern DBG_MODULE* DEBUG_FindModuleByName(const char* name, int type);
 extern DBG_MODULE* DEBUG_FindModuleByHandle(HANDLE handle, int type);
 extern DBG_MODULE* DEBUG_RegisterPEModule(HMODULE, u_long load_addr, const char* name);
 extern DBG_MODULE* DEBUG_RegisterELFModule(u_long load_addr, const char* name);
-extern int DEBUG_ProcessDeferredDebug(void);
 extern void DEBUG_InfoShare(void);
 
   /* debugger/msc.c */
-extern int DEBUG_RegisterMSCDebugInfo(DBG_MODULE* module, void* nth, unsigned long nth_ofs);
-extern int DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, void* nth, unsigned long nth_ofs);
+extern int DEBUG_RegisterMSCDebugInfo(DBG_MODULE* module, HANDLE hFile, void* nth, unsigned long nth_ofs);
+extern int DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile, void* nth, unsigned long nth_ofs);
 extern void DEBUG_InitCVDataTypes(void);
-extern int DEBUG_ProcessMSCDebugInfo(DBG_MODULE* module);
 
   /* debugger/registers.c */
 extern void DEBUG_SetRegister( enum debug_regs reg, int val );
@@ -375,7 +375,8 @@
 				  unsigned int * ebp);
 
   /* debugger/stabs.c */
-extern int DEBUG_ReadExecutableDbgInfo(void);
+extern int DEBUG_ReadExecutableDbgInfo(const char* exe_name);
+extern int DEBUG_ProcessElfObject(const char* filename, unsigned int load_offset);
 extern int DEBUG_ParseStabs(char * addr, unsigned int load_offset, unsigned int staboff, 
 			    int stablen, unsigned int strtaboff, int strtablen);
 
@@ -420,8 +421,16 @@
 extern void DEBUG_ExternalDebugger(void);
 
   /* debugger/dbg.y */
-extern void DEBUG_Exit( DWORD exit_code );
 extern BOOL DEBUG_Main( BOOL is_debug, BOOL force, DWORD code );
+extern void DEBUG_Exit( DWORD );
+
+  /* debugger/winedbg.c */
+#define DBG_CHN_MESG	1
+#define DBG_CHN_ERR	2
+#define DBG_CHN_WARN	4
+#define DBG_CHN_FIXME	8
+#define DBG_CHN_TRACE	16
+extern int DEBUG_Printf(int chn, const char* format, ...);
 
   /* Choose your allocator! */
 #if 1
@@ -455,4 +464,9 @@
 #define	DEBUG_STATUS_DIV_BY_ZERO	(DEBUG_STATUS_OFFSET+2)
 #define	DEBUG_STATUS_BAD_TYPE		(DEBUG_STATUS_OFFSET+3)
 
+#define  DBG_IVAR(_var)	DEBUG_IV_##_var
+#define  INTERNAL_VAR(_var,_val) extern int DBG_IVAR(_var);
+#include "intvar.h"
+#undef   INTERNAL_VAR
+
 #endif  /* __WINE_DEBUGGER_H */
diff --git a/debugger/display.c b/debugger/display.c
index 80926f9..56a03b4 100644
--- a/debugger/display.c
+++ b/debugger/display.c
@@ -60,9 +60,9 @@
     {
       if( displaypoints[i].exp != NULL )
 	{
-	  fprintf(stderr, "%d : ", i+1);
+	  DEBUG_Printf(DBG_CHN_MESG, "%d : ", i+1);
 	  DEBUG_DisplayExpr(displaypoints[i].exp);
-	  fprintf(stderr, "\n");
+	  DEBUG_Printf(DBG_CHN_MESG, "\n");
 	}
     }
 
@@ -85,16 +85,16 @@
 	  value = DEBUG_EvalExpr(displaypoints[i].exp);
 	  if( value.type == NULL )
 	    {
-	      fprintf(stderr, "Unable to evaluate expression ");
+	      DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression ");
 	      DEBUG_DisplayExpr(displaypoints[i].exp);
-	      fprintf(stderr, "\nDisabling...\n");
+	      DEBUG_Printf(DBG_CHN_MESG, "\nDisabling...\n");
 	      DEBUG_DelDisplay(i);
 	    }
 	  else
 	    {
-	      fprintf(stderr, "%d  : ", i + 1);
+	      DEBUG_Printf(DBG_CHN_MESG, "%d  : ", i + 1);
 	      DEBUG_DisplayExpr(displaypoints[i].exp);
-	      fprintf(stderr, " = ");
+	      DEBUG_Printf(DBG_CHN_MESG, " = ");
 	      if( displaypoints[i].format == 'i' )
 		{
 		  DEBUG_ExamineMemory( &value, 
@@ -121,7 +121,7 @@
   
   if( displaynum >= MAX_DISPLAY || displaynum == 0 || displaynum < -1 )
     {
-      fprintf(stderr, "Invalid display number\n");
+      DEBUG_Printf(DBG_CHN_MESG, "Invalid display number\n");
       return TRUE;
     }
   if( displaynum == -1 )
diff --git a/debugger/expr.c b/debugger/expr.c
index 298b62c..76f4f79 100644
--- a/debugger/expr.c
+++ b/debugger/expr.c
@@ -418,7 +418,7 @@
 	  break;
 	}
 #else
-      fprintf(stderr, "Function call no longer implemented\n");
+      DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
       /* would need to set up a call to this function, and then restore the current
        * context afterwards...
        */
@@ -637,7 +637,7 @@
 	}
       break;
     default:
-      fprintf(stderr,"Unexpected expression (%d).\n", exp->type);
+      DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
       break;
     }
@@ -656,111 +656,111 @@
   switch(exp->type)
     {
     case EXPR_TYPE_CAST:
-      fprintf(stderr, "((");
+      DEBUG_Printf(DBG_CHN_MESG, "((");
       DEBUG_PrintTypeCast(exp->un.cast.cast);
-      fprintf(stderr, ")");
+      DEBUG_Printf(DBG_CHN_MESG, ")");
       DEBUG_DisplayExpr(exp->un.cast.expr);
-      fprintf(stderr, ")");
+      DEBUG_Printf(DBG_CHN_MESG, ")");
       break;
     case EXPR_TYPE_REGISTER:
       DEBUG_PrintRegister(exp->un.rgister.reg);
       break;
     case EXPR_TYPE_US_CONST:
-      fprintf(stderr, "%ud", exp->un.u_const.value);
+      DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
       break;
     case EXPR_TYPE_CONST:
-      fprintf(stderr, "%d", exp->un.u_const.value);
+      DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
       break;
     case EXPR_TYPE_STRING:
-      fprintf(stderr, "\"%s\"", exp->un.string.str); 
+      DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str); 
       break;
     case EXPR_TYPE_SYMBOL:
-      fprintf(stderr, "%s" , exp->un.symbol.name);
+      DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
       break;
     case EXPR_TYPE_PSTRUCT:
       DEBUG_DisplayExpr(exp->un.structure.exp1);
-      fprintf(stderr, "->%s", exp->un.structure.element_name);
+      DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
       break;
     case EXPR_TYPE_STRUCT:
       DEBUG_DisplayExpr(exp->un.structure.exp1);
-      fprintf(stderr, ".%s", exp->un.structure.element_name);
+      DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
       break;
     case EXPR_TYPE_CALL:
-      fprintf(stderr, "%s(",exp->un.call.funcname);
+      DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
       for(i=0; i < exp->un.call.nargs; i++)
 	{
 	  DEBUG_DisplayExpr(exp->un.call.arg[i]);
 	  if( i != exp->un.call.nargs - 1 )
 	    {
-	      fprintf(stderr, ", ");
+	      DEBUG_Printf(DBG_CHN_MESG, ", ");
 	    }
 	}
-      fprintf(stderr, ")");
+      DEBUG_Printf(DBG_CHN_MESG, ")");
       break;
     case EXPR_TYPE_BINOP:
-      fprintf(stderr, "( ");
+      DEBUG_Printf(DBG_CHN_MESG, "( ");
       DEBUG_DisplayExpr(exp->un.binop.exp1);
       switch(exp->un.binop.binop_type)
 	{
 	case EXP_OP_ADD:
- 	  fprintf(stderr, " + ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " + ");
 	  break;
 	case EXP_OP_SUB:
- 	  fprintf(stderr, " - ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " - ");
 	  break;
 	case EXP_OP_SEG:
- 	  fprintf(stderr, ":");
+ 	  DEBUG_Printf(DBG_CHN_MESG, ":");
 	  break;
 	case EXP_OP_LOR:
- 	  fprintf(stderr, " || ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " || ");
 	  break;
 	case EXP_OP_LAND:
- 	  fprintf(stderr, " && ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " && ");
 	  break;
 	case EXP_OP_OR:
- 	  fprintf(stderr, " | ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " | ");
 	  break;
 	case EXP_OP_AND:
- 	  fprintf(stderr, " & ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " & ");
 	  break;
 	case EXP_OP_XOR:
- 	  fprintf(stderr, " ^ ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " ^ ");
  	  break;
 	case EXP_OP_EQ:
- 	  fprintf(stderr, " == ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " == ");
 	  break;
 	case EXP_OP_GT:
- 	  fprintf(stderr, " > ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " > ");
 	  break;
 	case EXP_OP_LT:
- 	  fprintf(stderr, " < ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " < ");
 	  break;
 	case EXP_OP_GE:
- 	  fprintf(stderr, " >= ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " >= ");
 	  break;
 	case EXP_OP_LE:
- 	  fprintf(stderr, " <= ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " <= ");
 	  break;
 	case EXP_OP_NE:
- 	  fprintf(stderr, " != ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " != ");
 	  break;
 	case EXP_OP_SHL:
- 	  fprintf(stderr, " << ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " << ");
 	  break;
 	case EXP_OP_SHR:
- 	  fprintf(stderr, " >> ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " >> ");
 	  break;
 	case EXP_OP_MUL:
- 	  fprintf(stderr, " * ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " * ");
 	  break;
 	case EXP_OP_DIV:
- 	  fprintf(stderr, " / ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " / ");
 	  break;
 	case EXP_OP_REM:
- 	  fprintf(stderr, " %% ");
+ 	  DEBUG_Printf(DBG_CHN_MESG, " %% ");
 	  break;
 	case EXP_OP_ARR:
- 	  fprintf(stderr, "[");
+ 	  DEBUG_Printf(DBG_CHN_MESG, "[");
 	  break;
 	default:
 	  break;
@@ -768,33 +768,33 @@
       DEBUG_DisplayExpr(exp->un.binop.exp2);
       if( exp->un.binop.binop_type == EXP_OP_ARR )
 	{
- 	  fprintf(stderr, "]");
+ 	  DEBUG_Printf(DBG_CHN_MESG, "]");
 	}
-      fprintf(stderr, " )");
+      DEBUG_Printf(DBG_CHN_MESG, " )");
       break;
     case EXPR_TYPE_UNOP:
       switch(exp->un.unop.unop_type)
 	{
 	case EXP_OP_NEG:
- 	  fprintf(stderr, "-");
+ 	  DEBUG_Printf(DBG_CHN_MESG, "-");
 	  break;
 	case EXP_OP_NOT:
-	  fprintf(stderr, "!");
+	  DEBUG_Printf(DBG_CHN_MESG, "!");
 	  break;
 	case EXP_OP_LNOT:
-	  fprintf(stderr, "~");
+	  DEBUG_Printf(DBG_CHN_MESG, "~");
  	  break;
 	case EXP_OP_DEREF:
-	  fprintf(stderr, "*");
+	  DEBUG_Printf(DBG_CHN_MESG, "*");
 	  break;
 	case EXP_OP_ADDR:
-	  fprintf(stderr, "&");
+	  DEBUG_Printf(DBG_CHN_MESG, "&");
 	  break;
 	}
       DEBUG_DisplayExpr(exp->un.unop.exp1);
       break;
     default:
-      fprintf(stderr,"Unexpected expression.\n");
+      DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
       break;
     }
@@ -851,7 +851,7 @@
       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
       break;
     default:
-      fprintf(stderr,"Unexpected expression.\n");
+      DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
       break;
     }
@@ -904,7 +904,7 @@
       DEBUG_FreeExpr(exp->un.unop.exp1);
       break;
     default:
-      fprintf(stderr,"Unexpected expression.\n");
+      DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
       break;
     }
diff --git a/debugger/hash.c b/debugger/hash.c
index 1eaf5ce..0544d65 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -146,7 +146,7 @@
 	    if( (nh->flags & SYM_INVALID) == 0 )
 	       nsym++;
 	    else
-	       fprintf( stderr, "Symbol %s is invalid\n", nh->name );
+	       DEBUG_Printf( DBG_CHN_MESG, "Symbol %s is invalid\n", nh->name );
 	  }
     }
 
@@ -198,6 +198,10 @@
     {
  	if( ((nh->flags & SYM_INVALID) != 0) && strcmp(name, nh->name) == 0 )
         {
+#if 0
+	    DEBUG_Printf(DBG_CHN_MESG, "Changing address for symbol %s (%08lx:%08lx => %08lx:%08lx)\n",
+			 name, nh->value.addr.seg, nh->value.addr.off, value->addr.seg, value->addr.off);
+#endif
  	    nh->value.addr = value->addr;
 
  	    if( nh->value.type == NULL && value->type != NULL )
@@ -223,6 +227,11 @@
         }
     }
 
+#if 0
+    DEBUG_Printf(DBG_CHN_TRACE, "adding symbol (%s) from file '%s' at 0x%04lx:%08lx\n",
+		 name, source, value->addr.seg, value->addr.off);
+#endif
+
     /*
      * First see if we already have an entry for this symbol.  If so
      * return it, so we don't end up with duplicates.
@@ -564,12 +573,12 @@
 		  }
 		nearest = addr_sorttab[mid];
 #if 0
-		fprintf(stderr, "Found %x:%x when looking for %x:%x %x %s\n",
-			addr_sorttab[mid ]->value.addr.seg,
-			addr_sorttab[mid ]->value.addr.off,
-			addr->seg, addr->off,
-			addr_sorttab[mid ]->linetab,
-			addr_sorttab[mid ]->name);
+		DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
+			     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;
 	      }
@@ -722,7 +731,6 @@
 {
     FILE * symbolfile;
     DBG_VALUE value;
-    int nargs;
     char type;
     char * cpnt;
     char buffer[256];
@@ -730,11 +738,11 @@
 
     if (!(symbolfile = fopen(filename, "r")))
     {
-        fprintf( stderr, "Unable to open symbol table %s\n", filename );
+        DEBUG_Printf( DBG_CHN_WARN, "Unable to open symbol table %s\n", filename );
         return;
     }
 
-    fprintf( stderr, "Reading symbols from file %s\n", filename );
+    DEBUG_Printf( DBG_CHN_MESG, "Reading symbols from file %s\n", filename );
 
     value.type = NULL;
     value.addr.seg = 0;
@@ -760,8 +768,8 @@
         }
         if (!(*cpnt) || *cpnt == '\n') continue;
 		
-        nargs = sscanf(buffer, "%lx %c %s", &value.addr.off, &type, name);
-        DEBUG_AddSymbol( name, &value, NULL, SYM_WINE );
+        if (sscanf(buffer, "%lx %c %s", &value.addr.off, &type, name) == 3)
+	   DEBUG_AddSymbol( name, &value, NULL, SYM_WINE );
     }
     fclose(symbolfile);
 }
@@ -837,7 +845,7 @@
 	{
 	  depth++;
 	}
-      fprintf(stderr, "Bucket %d: %d\n", i, depth);
+      DEBUG_Printf(DBG_CHN_MESG, "Bucket %d: %d\n", i, depth);
     }
 }
 
@@ -913,12 +921,12 @@
 		  }
 		nearest = addr_sorttab[mid];
 #if 0
-		fprintf(stderr, "Found %x:%x when looking for %x:%x %x %s\n",
-			addr_sorttab[mid ]->value.addr.seg,
-			addr_sorttab[mid ]->value.addr.off,
-			addr->seg, addr->off,
-			addr_sorttab[mid ]->linetab,
-			addr_sorttab[mid ]->name);
+		DEBUG_Printf(DBG_CHN_MESG, "Found %x:%x when looking for %x:%x %x %s\n",
+			     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;
 	      }
@@ -1055,11 +1063,11 @@
       {
 	if( filename != NULL )
 	  {
-	    fprintf(stderr, "No such function %s in %s\n", name, filename);
+	    DEBUG_Printf(DBG_CHN_MESG, "No such function %s in %s\n", name, filename);
 	  }
 	else
 	  {
-	    fprintf(stderr, "No such function %s\n", name);
+	    DEBUG_Printf(DBG_CHN_MESG, "No such function %s\n", name);
 	  }
 	ret->sourcefile = NULL;
 	ret->line = -1;
@@ -1188,17 +1196,17 @@
 	{
 	  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 - 1],
-		  *ptr);
+	  DEBUG_Printf(DBG_CHN_MESG, "%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 - 1],
+		       *ptr);
 	}
       else
 	{
 	  DEBUG_READ_MEM_VERBOSE((void*)(ebp + curr_func->local_vars[i].offset), 
 				 &val, sizeof(val));
-	  fprintf(stderr, "%s:%s == 0x%8.8x\n",
-		  curr_func->name, curr_func->local_vars[i].name, val);
+	  DEBUG_Printf(DBG_CHN_MESG, "%s:%s == 0x%8.8x\n",
+		       curr_func->name, curr_func->local_vars[i].name, val);
 	}
     }
 
diff --git a/debugger/info.c b/debugger/info.c
index 19ca90c..606e50c 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -29,7 +29,7 @@
   assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
   if( value->type == NULL ) 
     {
-      fprintf(stderr, "Unable to evaluate expression\n");
+      DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression\n");
       return;
     }
   
@@ -41,34 +41,34 @@
     case 'x':
       if (value->addr.seg) 
 	{
-	  DEBUG_nchar += fprintf( stderr, "0x%04lx", (long unsigned int) res );
+	  DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", (long unsigned int) res );
 	}
       else 
 	{
-	  DEBUG_nchar += fprintf( stderr, "0x%08lx", (long unsigned int) res );
+	  DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", (long unsigned int) res );
 	}
       break;
       
     case 'd':
-      DEBUG_nchar += fprintf( stderr, "%ld\n", (long int) res );
+      DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%ld\n", (long int) res );
       break;
       
     case 'c':
-      DEBUG_nchar += fprintf( stderr, "%d = '%c'",
-			      (char)(res & 0xff), (char)(res & 0xff) );
+      DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%d = '%c'",
+				   (char)(res & 0xff), (char)(res & 0xff) );
       break;
       
     case 'i':
     case 's':
     case 'w':
     case 'b':
-      fprintf( stderr, "Format specifier '%c' is meaningless in 'print' command\n", format );
+      DEBUG_Printf( DBG_CHN_MESG, "Format specifier '%c' is meaningless in 'print' command\n", format );
     case 0:
       if( default_format != NULL )
 	{
 	  if (strstr(default_format, "%S") == NULL)
 	    {
-	       DEBUG_nchar += fprintf( stderr, default_format, res );
+	       DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, default_format, res );
 	    } 
 	  else
 	    {
@@ -80,7 +80,7 @@
 		*/
 	       for (ptr = default_format; *ptr; ptr++) 
 	       {
-		  fprintf(stderr, "[%c]", *ptr);
+		  DEBUG_Printf(DBG_CHN_MESG, "[%c]", *ptr);
 
 		  if (*ptr == '%') state++;
 		  else if (state == 1) 
@@ -130,10 +130,10 @@
     const char *name = DEBUG_FindNearestSymbol( addr, flag, &rtn.sym, 0, 
 						&rtn.list );
 
-    if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg&0xFFFF );
-    if (addrlen == 16) fprintf( stderr, "0x%04lx", addr->off );
-    else fprintf( stderr, "0x%08lx", addr->off );
-    if (name) fprintf( stderr, " (%s)", name );
+    if (addr->seg) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx:", addr->seg&0xFFFF );
+    if (addrlen == 16) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", addr->off );
+    else DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", addr->off );
+    if (name) DEBUG_Printf( DBG_CHN_MESG, " (%s)", name );
     return rtn;
 }
 /***********************************************************************
@@ -152,10 +152,10 @@
     const char *name = DEBUG_FindNearestSymbol( addr, flag, &rtn.sym, ebp, 
 						&rtn.list );
 
-    if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg );
-    if (addrlen == 16) fprintf( stderr, "0x%04lx", addr->off );
-    else fprintf( stderr, "0x%08lx", addr->off );
-    if (name) fprintf( stderr, " (%s)", name );
+    if (addr->seg) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx:", addr->seg );
+    if (addrlen == 16) DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", addr->off );
+    else DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", addr->off );
+    if (name) DEBUG_Printf( DBG_CHN_MESG, " (%s)", name );
 
     return rtn;
 }
@@ -205,7 +205,7 @@
 NULL
 };
 
-    while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
+    while(helptext[i]) DEBUG_Printf(DBG_CHN_MESG,"%s\n", helptext[i++]);
 }
 
 
@@ -236,7 +236,7 @@
 NULL
 };
 
-    while(infotext[i]) fprintf(stderr,"%s\n", infotext[i++]);
+    while(infotext[i]) DEBUG_Printf(DBG_CHN_MESG,"%s\n", infotext[i++]);
 }
 
 /* FIXME: merge InfoClass and InfoClass2 */
@@ -244,19 +244,19 @@
 {
    WNDCLASSEXA	wca;
 
-   if (!GetClassInfoExA(0, name, &wca)) {
-      fprintf(stderr, "Cannot find class '%s'\n", name);
+   if (!GetClassInfoEx(0, name, &wca)) {
+      DEBUG_Printf(DBG_CHN_MESG, "Cannot find class '%s'\n", name);
       return;
    }
 
-   fprintf(stderr,  "Class '%s':\n", name);
-   fprintf(stderr,  
-	   "style=%08x  wndProc=%08lx\n"
-	   "inst=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
-	   "clsExtra=%d  winExtra=%d\n",
-	   wca.style, (DWORD)wca.lpfnWndProc, wca.hInstance,
-	   wca.hIcon, wca.hCursor, wca.hbrBackground,
-	   wca.cbClsExtra, wca.cbWndExtra);
+   DEBUG_Printf(DBG_CHN_MESG,  "Class '%s':\n", name);
+   DEBUG_Printf(DBG_CHN_MESG,  
+		"style=%08x  wndProc=%08lx\n"
+		"inst=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
+		"clsExtra=%d  winExtra=%d\n",
+		wca.style, (DWORD)wca.lpfnWndProc, wca.hInstance,
+		wca.hIcon, wca.hCursor, wca.hbrBackground,
+		wca.cbClsExtra, wca.cbWndExtra);
 
    /* FIXME: 
     * + print #windows (or even list of windows...)
@@ -268,34 +268,34 @@
 {
    WNDCLASSEXA	wca;
 
-   if (!GetClassInfoExA(GetWindowLongA(hWnd, GWL_HINSTANCE), name, &wca)) {
-      fprintf(stderr, "Cannot find class '%s'\n", name);
+   if (!GetClassInfoEx(GetWindowLong(hWnd, GWL_HINSTANCE), name, &wca)) {
+      DEBUG_Printf(DBG_CHN_MESG, "Cannot find class '%s'\n", name);
       return;
    }
 
-   fprintf(stderr,  "Class '%s':\n", name);
-   fprintf(stderr,  
-	   "style=%08x  wndProc=%08lx\n"
-	   "inst=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
-	   "clsExtra=%d  winExtra=%d\n",
-	   wca.style, (DWORD)wca.lpfnWndProc, wca.hInstance,
-	   wca.hIcon, wca.hCursor, wca.hbrBackground,
-	   wca.cbClsExtra, wca.cbWndExtra);
+   DEBUG_Printf(DBG_CHN_MESG,  "Class '%s':\n", name);
+   DEBUG_Printf(DBG_CHN_MESG,  
+		"style=%08x  wndProc=%08lx\n"
+		"inst=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
+		"clsExtra=%d  winExtra=%d\n",
+		wca.style, (DWORD)wca.lpfnWndProc, wca.hInstance,
+		wca.hIcon, wca.hCursor, wca.hbrBackground,
+		wca.cbClsExtra, wca.cbWndExtra);
 
    if (wca.cbClsExtra) {
       int		i;
       WORD		w;
 
-      fprintf(stderr,  "Extra bytes:" );
+      DEBUG_Printf(DBG_CHN_MESG,  "Extra bytes:" );
       for (i = 0; i < wca.cbClsExtra / 2; i++) {
 	 w = GetClassWord(hWnd, i * 2);
 	 /* FIXME: depends on i386 endian-ity */
-	 fprintf(stderr,  " %02x", HIBYTE(w));
-	 fprintf(stderr,  " %02x", LOBYTE(w));
+	 DEBUG_Printf(DBG_CHN_MESG,  " %02x", HIBYTE(w));
+	 DEBUG_Printf(DBG_CHN_MESG,  " %02x", LOBYTE(w));
       }
-      fprintf(stderr,  "\n" );
+      DEBUG_Printf(DBG_CHN_MESG,  "\n" );
     }
-    fprintf(stderr,  "\n" );
+    DEBUG_Printf(DBG_CHN_MESG,  "\n" );
 }
 
 struct class_walker {
@@ -311,9 +311,9 @@
    ATOM	atom;
    HWND	child;
 
-   if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
+   if (!GetClassName(hWnd, clsName, sizeof(clsName)))
       return;
-   if ((atom = FindAtomA(clsName)) == 0)
+   if ((atom = FindAtom(clsName)) == 0)
       return;
 
    for (i = 0; i < cw->used; i++) {
@@ -346,12 +346,12 @@
 
 void DEBUG_DumpQueue(DWORD q)
 {
-   fprintf(stderr, "No longer doing info queue '0x%08lx'\n", q);
+   DEBUG_Printf(DBG_CHN_MESG, "No longer doing info queue '0x%08lx'\n", q);
 }
 
 void DEBUG_WalkQueues(void)
 {
-   fprintf(stderr, "No longer walking queues list\n");
+   DEBUG_Printf(DBG_CHN_MESG, "No longer walking queues list\n");
 }
 
 void DEBUG_InfoWindow(HWND hWnd)
@@ -363,9 +363,9 @@
    int	i;
    WORD	w;
 
-   if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
+   if (!GetClassName(hWnd, clsName, sizeof(clsName)))
        strcpy(clsName, "-- Unknown --");
-   if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
+   if (!GetWindowText(hWnd, wndName, sizeof(wndName)))
       strcpy(wndName, "-- Empty --");
    if (!GetClientRect(hWnd, &clientRect))
       SetRectEmpty(&clientRect);
@@ -373,38 +373,38 @@
       SetRectEmpty(&windowRect);
 
    /* FIXME missing fields: hmemTaskQ, hrgnUpdate, dce, flags, pProp, scroll */
-   fprintf(stderr,
-	   "next=0x%04x  child=0x%04x  parent=0x%04x  owner=0x%04x  class='%s'\n"
-	   "inst=%08lx  active=%04x  idmenu=%08lx\n"
-	   "style=%08lx  exstyle=%08lx  wndproc=%08lx  text='%s'\n"
-	   "client=%d,%d-%d,%d  window=%d,%d-%d,%d sysmenu=%04x\n",
-	   GetWindow(hWnd, GW_HWNDNEXT), 
-	   GetWindow(hWnd, GW_CHILD),
-	   GetParent(hWnd), 
-	   GetWindow(hWnd, GW_OWNER),
-	   clsName,
-	   GetWindowLongA(hWnd, GWL_HINSTANCE), 
-	   GetLastActivePopup(hWnd),
-	   GetWindowLongA(hWnd, GWL_ID),
-	   GetWindowLongA(hWnd, GWL_STYLE),
-	   GetWindowLongA(hWnd, GWL_EXSTYLE),
-	   GetWindowLongA(hWnd, GWL_WNDPROC),
-	   wndName, 
-	   clientRect.left, clientRect.top, clientRect.right, clientRect.bottom, 
-	   windowRect.left, windowRect.top, windowRect.right, windowRect.bottom, 
-	   GetSystemMenu(hWnd, FALSE));
+   DEBUG_Printf(DBG_CHN_MESG,
+		"next=0x%04x  child=0x%04x  parent=0x%04x  owner=0x%04x  class='%s'\n"
+		"inst=%08lx  active=%04x  idmenu=%08lx\n"
+		"style=%08lx  exstyle=%08lx  wndproc=%08lx  text='%s'\n"
+		"client=%d,%d-%d,%d  window=%d,%d-%d,%d sysmenu=%04x\n",
+		GetWindow(hWnd, GW_HWNDNEXT), 
+		GetWindow(hWnd, GW_CHILD),
+		GetParent(hWnd), 
+		GetWindow(hWnd, GW_OWNER),
+		clsName,
+		GetWindowLong(hWnd, GWL_HINSTANCE), 
+		GetLastActivePopup(hWnd),
+		GetWindowLong(hWnd, GWL_ID),
+		GetWindowLong(hWnd, GWL_STYLE),
+		GetWindowLong(hWnd, GWL_EXSTYLE),
+		GetWindowLong(hWnd, GWL_WNDPROC),
+		wndName, 
+		clientRect.left, clientRect.top, clientRect.right, clientRect.bottom, 
+		windowRect.left, windowRect.top, windowRect.right, windowRect.bottom, 
+		GetSystemMenu(hWnd, FALSE));
 
-    if (GetClassLongA(hWnd, GCL_CBWNDEXTRA)) {
-        fprintf(stderr,  "Extra bytes:" );
-        for (i = 0; i < GetClassLongA(hWnd, GCL_CBWNDEXTRA) / 2; i++) {
+    if (GetClassLong(hWnd, GCL_CBWNDEXTRA)) {
+        DEBUG_Printf(DBG_CHN_MESG,  "Extra bytes:" );
+        for (i = 0; i < GetClassLong(hWnd, GCL_CBWNDEXTRA) / 2; i++) {
 	   w = GetWindowWord(hWnd, i * 2);
 	   /* FIXME: depends on i386 endian-ity */
-	   fprintf(stderr,  " %02x", HIBYTE(w));
-	   fprintf(stderr,  " %02x", LOBYTE(w));
+	   DEBUG_Printf(DBG_CHN_MESG,  " %02x", HIBYTE(w));
+	   DEBUG_Printf(DBG_CHN_MESG,  " %02x", LOBYTE(w));
 	}
-        fprintf(stderr, "\n");
+        DEBUG_Printf(DBG_CHN_MESG, "\n");
     }
-    fprintf(stderr, "\n");
+    DEBUG_Printf(DBG_CHN_MESG, "\n");
 }
 
 void DEBUG_WalkWindows(HWND hWnd, int indent)
@@ -417,21 +417,21 @@
       hWnd = GetDesktopWindow();
 
     if (!indent)  /* first time around */
-       fprintf(stderr,  
-	       "%-16.16s %-17.17s %-8.8s %s\n",
-	       "hwnd", "Class Name", " Style", " WndProc Text");
+       DEBUG_Printf(DBG_CHN_MESG,  
+		    "%-16.16s %-17.17s %-8.8s %s\n",
+		    "hwnd", "Class Name", " Style", " WndProc Text");
 
     do {
-       if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
+       if (!GetClassName(hWnd, clsName, sizeof(clsName)))
 	  strcpy(clsName, "-- Unknown --");
-       if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
+       if (!GetWindowText(hWnd, wndName, sizeof(wndName)))
 	  strcpy(wndName, "-- Empty --");
        
        /* FIXME: missing hmemTaskQ */
-       fprintf(stderr, "%*s%04x%*s", indent, "", hWnd, 13-indent,"");
-       fprintf(stderr, "%-17.17s %08lx %08lx %.14s\n",
-	       clsName, GetWindowLongA(hWnd, GWL_STYLE),
-	       GetWindowLongA(hWnd, GWL_WNDPROC), wndName);
+       DEBUG_Printf(DBG_CHN_MESG, "%*s%04x%*s", indent, "", hWnd, 13-indent,"");
+       DEBUG_Printf(DBG_CHN_MESG, "%-17.17s %08lx %08lx %.14s\n",
+		    clsName, GetWindowLong(hWnd, GWL_STYLE),
+		    GetWindowLong(hWnd, GWL_WNDPROC), wndName);
 
        if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
 	  DEBUG_WalkWindows(child, indent + 1 );
@@ -440,12 +440,12 @@
 
 void DEBUG_WalkProcess(void)
 {
-   fprintf(stderr, "No longer walking processes list\n");
+   DEBUG_Printf(DBG_CHN_MESG, "No longer walking processes list\n");
 }
 
 void DEBUG_WalkModref(DWORD p)
 {
-   fprintf(stderr, "No longer walking module references list\n");
+   DEBUG_Printf(DBG_CHN_MESG, "No longer walking module references list\n");
 }
 
 void DEBUG_InfoSegments(DWORD start, int length)
@@ -473,19 +473,19 @@
             flags[1] = (le.HighWord.Bits.Type & 0x2) ? 'w' : '-';
             flags[2] = '-';
         }
-        fprintf(stderr, 
-		"%04lx: sel=%04lx base=%08x limit=%08x %d-bit %c%c%c\n",
-		i, (i<<3)|7, 
-		(le.HighWord.Bits.BaseHi << 24) + 
-		    (le.HighWord.Bits.BaseMid << 16) + le.BaseLow,
-		((le.HighWord.Bits.LimitHi << 8) + le.LimitLow) << 
-		    (le.HighWord.Bits.Granularity ? 12 : 0),
-		le.HighWord.Bits.Default_Big ? 32 : 16,
-		flags[0], flags[1], flags[2] );
+        DEBUG_Printf(DBG_CHN_MESG, 
+		     "%04lx: sel=%04lx base=%08x limit=%08x %d-bit %c%c%c\n",
+		     i, (i<<3)|7, 
+		     (le.HighWord.Bits.BaseHi << 24) + 
+		     (le.HighWord.Bits.BaseMid << 16) + le.BaseLow,
+		     ((le.HighWord.Bits.LimitHi << 8) + le.LimitLow) << 
+		     (le.HighWord.Bits.Granularity ? 12 : 0),
+		     le.HighWord.Bits.Default_Big ? 32 : 16,
+		     flags[0], flags[1], flags[2] );
     }
 }
 
 void DEBUG_InfoVirtual(void)
 {
-   fprintf(stderr, "No longer providing virtual mapping information\n");
+   DEBUG_Printf(DBG_CHN_MESG, "No longer providing virtual mapping information\n");
 }
diff --git a/debugger/intvar.h b/debugger/intvar.h
new file mode 100644
index 0000000..1e3207e
--- /dev/null
+++ b/debugger/intvar.h
@@ -0,0 +1,3 @@
+INTERNAL_VAR(BreakAllThreadsStartup,		FALSE)
+INTERNAL_VAR(ExtDbgOnInvalidAddress,		FALSE)
+INTERNAL_VAR(ChannelMask,			DBG_CHN_MESG)
diff --git a/debugger/memory.c b/debugger/memory.c
index 19466e5..4889ce7 100644
--- a/debugger/memory.c
+++ b/debugger/memory.c
@@ -23,7 +23,7 @@
 
 static	void	DEBUG_Die(const char* msg)
 {
-   fprintf(stderr, msg);
+   DEBUG_Printf(DBG_CHN_MESG, msg);
    exit(1);
 }
 
@@ -118,16 +118,21 @@
 #endif
 }
 
+void	DEBUG_InvalAddr( const DBG_ADDR* addr )
+{
+   DEBUG_Printf(DBG_CHN_MESG,"*** Invalid address ");
+   DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, FALSE);
+   DEBUG_Printf(DBG_CHN_MESG,"\n");
+   if (DBG_IVAR(ExtDbgOnInvalidAddress)) DEBUG_ExternalDebugger();
+}
+
 void	DEBUG_InvalLinAddr( void* addr )
 {
    DBG_ADDR address;
 
    address.seg = 0;
    address.off = (unsigned long)addr;
-
-   fprintf(stderr,"*** Invalid address ");
-   DEBUG_PrintAddress(&address, DEBUG_CurrThread->dbg_mode, FALSE);
-   fprintf(stderr,"\n");
+   DEBUG_InvalAddr( &address );
 }
 
 /***********************************************************************
@@ -215,14 +220,14 @@
       }
     else if (!value.addr.seg && !value.addr.off)
     {
-	fprintf(stderr,"Invalid expression\n");
+	DEBUG_Printf(DBG_CHN_MESG,"Invalid expression\n");
 	return;
     }
 
     if (format != 'i' && count > 1)
     {
         DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, FALSE );
-        fprintf(stderr,": ");
+        DEBUG_Printf(DBG_CHN_MESG,": ");
     }
 
     pnt = (void*)DEBUG_ToLinear( &value.addr );
@@ -239,7 +244,7 @@
                     pnt += sizeof(wch);
                     fputc( (char)wch, stderr );
                 }
-		fprintf(stderr,"\n");
+		DEBUG_Printf(DBG_CHN_MESG,"\n");
 		return;
 	    }
           case 's': {
@@ -253,31 +258,31 @@
                     pnt++;
                     fputc( ch, stderr );
                 }
-		fprintf(stderr,"\n");
+		DEBUG_Printf(DBG_CHN_MESG,"\n");
 		return;
 	  }
 	case 'i':
 		while (count--)
                 {
                     DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, TRUE );
-                    fprintf(stderr,": ");
+                    DEBUG_Printf(DBG_CHN_MESG,": ");
                     DEBUG_Disasm( &value.addr, TRUE );
-                    fprintf(stderr,"\n");
+                    DEBUG_Printf(DBG_CHN_MESG,"\n");
 		}
 		return;
 #define DO_DUMP2(_t,_l,_f,_vv) { \
 	        _t _v; \
 		for(i=0; i<count; i++) { \
                     if (!DEBUG_READ_MEM_VERBOSE(pnt, &_v, sizeof(_t))) break; \
-                    fprintf(stderr,_f,(_vv)); \
+                    DEBUG_Printf(DBG_CHN_MESG,_f,(_vv)); \
                     pnt += sizeof(_t); value.addr.off += sizeof(_t); \
                     if ((i % (_l)) == (_l)-1) { \
-                        fprintf(stderr,"\n"); \
+                        DEBUG_Printf(DBG_CHN_MESG,"\n"); \
                         DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, FALSE );\
-                        fprintf(stderr,": ");\
+                        DEBUG_Printf(DBG_CHN_MESG,": ");\
                     } \
 		} \
-		fprintf(stderr,"\n"); \
+		DEBUG_Printf(DBG_CHN_MESG,"\n"); \
         } \
 	return
 #define DO_DUMP(_t,_l,_f) DO_DUMP2(_t,_l,_f,_v) 
diff --git a/debugger/module.c b/debugger/module.c
index f73dfb2..783b533 100644
--- a/debugger/module.c
+++ b/debugger/module.c
@@ -12,6 +12,7 @@
 #include "neexe.h"
 #include "peexe.h"
 #include "module.h"
+#include "file.h"
 #include "debugger.h"
 #include "toolhelp.h"
 
@@ -232,7 +233,7 @@
 /***********************************************************************
  *			DEBUG_LoadModule32
  */
-void	DEBUG_LoadModule32(const char* name, DWORD base)
+void	DEBUG_LoadModule32(const char* name, HANDLE hFile, DWORD base)
 {
     DBG_VALUE			value;
     char			buffer[256];
@@ -249,7 +250,7 @@
     /* FIXME: we make the assumption that hModule == base */
     wmod = DEBUG_RegisterPEModule((HMODULE)base, base, name);
 
-    fprintf(stderr, "Registring 32bit DLL '%s' at %08lx\n", name, base);
+    DEBUG_Printf(DBG_CHN_TRACE, "Registring 32bit DLL '%s' at %08lx\n", name, base);
     
     value.type = NULL;
     value.cookie = DV_TARGET;
@@ -257,15 +258,15 @@
     value.addr.off = 0;
     
     /* grab PE Header */
-    if (!DEBUG_READ_MEM_VERBOSE((void*)(base + OFFSET_OF(IMAGE_DOS_HEADER, e_lfanew)), 
+    if (!DEBUG_READ_MEM_VERBOSE((void*)(base + OFFSET_OF(IMAGE_DOS_HEADER, e_lfanew)),
 				&pe_header_ofs, sizeof(pe_header_ofs)) ||
 	!DEBUG_READ_MEM_VERBOSE((void*)(base + pe_header_ofs), 
 				&pe_header, sizeof(pe_header)))
 	return;
     
     if (wmod) {
-	DEBUG_RegisterMSCDebugInfo(wmod, &pe_header, pe_header_ofs);	
-	DEBUG_RegisterStabsDebugInfo(wmod, &pe_header, pe_header_ofs);
+	DEBUG_RegisterStabsDebugInfo(wmod, hFile, &pe_header, pe_header_ofs);
+	DEBUG_RegisterMSCDebugInfo(wmod, hFile, &pe_header, pe_header_ofs);	
     }
 
     /* Add start of DLL */
@@ -282,11 +283,9 @@
 	pe_header.FileHeader.SizeOfOptionalHeader;
     
     for (i = 0; i < pe_header.FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
-	if (!DEBUG_READ_MEM_VERBOSE((void*)(base + pe_seg_ofs), &pe_seg, sizeof(pe_seg)) ||
-	    !DEBUG_READ_MEM_VERBOSE((void*)pe_seg.Name, bufstr, sizeof(bufstr)))
+	if (!DEBUG_READ_MEM_VERBOSE((void*)(base + pe_seg_ofs), &pe_seg, sizeof(pe_seg)))
 	    continue;
-	bufstr[sizeof(bufstr) - 1] = 0;
-	sprintf(buffer, "%s.%s", name, bufstr);
+	sprintf(buffer, "%s.%s", name, pe_seg.Name);
 	value.addr.off = base + pe_seg.VirtualAddress;
 	DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
     }
@@ -359,6 +358,10 @@
     int		len;
 
     /* FIXME: we assume that a module is never removed from memory */
+    /* FIXME: this is (currently plain wrong when debugger is started by
+     *	      attaching to an existing program => the 16 bit modules will
+     *        not be shared... not much to do on debugger side... sigh
+     */
     if (ModuleFirst16(&entry)) do {
 	if (DEBUG_FindModuleByName(entry.szModule, DM_TYPE_UNKNOWN) ||
 	    !(moduleAddr = NE_GetPtr(entry.hModule)) ||
@@ -366,69 +369,28 @@
 	    (module.flags & NE_FFLAGS_WIN32) /* NE module */)
 	    continue;
 	if (!first) {
-	    if (pfx) fprintf(stderr, pfx);
-	    fprintf(stderr, "   ");
+	    if (pfx) DEBUG_Printf(DBG_CHN_MESG, pfx);
+	    DEBUG_Printf(DBG_CHN_MESG, "   ");
 	    rowcount = 3 + (pfx ? strlen(pfx) : 0);
 	    first = 1;
 	}
 	
 	len = strlen(entry.szModule);
 	if ((rowcount + len) > 76) {
-	    fprintf(stderr, "\n   ");
+	    DEBUG_Printf(DBG_CHN_MESG, "\n   ");
 	    rowcount = 3;
 	}
-	fprintf(stderr, " %s", entry.szModule);
+	DEBUG_Printf(DBG_CHN_MESG, " %s", entry.szModule);
 	rowcount += len + 1;
 	
 	DEBUG_LoadModule16(entry.hModule, &module, moduleAddr, entry.szModule);
     } while (ModuleNext16(&entry));
     
-    if (first) fprintf(stderr, "\n"); 
+    if (first) DEBUG_Printf(DBG_CHN_MESG, "\n"); 
     return first;
 }
 
 /***********************************************************************
- *		DEBUG_ProcessDeferredDebug
- *
- */
-int DEBUG_ProcessDeferredDebug(void)
-{
-    DBG_MODULE*	wmod;
-    int		sts;
-    int		last_proc = -1;
-    int		need_print = 0;
-    int		rowcount = 0;
-    int		len;
-
-    for (wmod = DEBUG_CurrProcess->modules; wmod; wmod = wmod->next) {
-	if (wmod->status != DM_STATUS_NEW) continue;
-	
-	if (last_proc != wmod->dbg_index) {
-	    if (!need_print) {
-		fprintf(stderr, "DeferredDebug for:");
-		rowcount = 18;
-		need_print = 1;
-	    }
-	    if (rowcount + (len = strlen(wmod->module_name)) > 76) {
-		rowcount = 0;
-		fprintf(stderr, "\n");
-	    } else {
-		fprintf(stderr, " ");
-		rowcount++;
-	    }
-	    rowcount += len;
-	    fprintf(stderr, wmod->module_name);
-	    last_proc = wmod->dbg_index;
-	}
-	
-	sts = (wmod->extra_info) ? DEBUG_ProcessMSCDebugInfo(wmod) : TRUE;
-	wmod->status = (sts) ? DM_STATUS_LOADED : DM_STATUS_ERROR;
-    }
-    if (need_print) fprintf(stderr, "\n");
-    return TRUE;
-}
-
-/***********************************************************************
  *           DEBUG_InfoShare
  *
  * Display shared libarary information.
@@ -438,7 +400,7 @@
     DBG_MODULE*	wmod;
     const char*	xtype;
 
-    fprintf(stderr, "Address\t\tModule\tName\n");
+    DEBUG_Printf(DBG_CHN_MESG, "Address\t\tModule\tName\n");
 
     for (wmod = DEBUG_CurrProcess->modules; wmod; wmod = wmod->next) {
 	switch (wmod->type) {
@@ -447,8 +409,8 @@
 	case DM_TYPE_ELF:	xtype = "ELF"; break;
 	default:		xtype = "???"; break;
 	}
-	fprintf(stderr, "0x%8.8x\t(%s)\t%s\n", (unsigned int)wmod->load_addr,
-		xtype, wmod->module_name);
+	DEBUG_Printf(DBG_CHN_MESG, "0x%8.8x\t(%s)\t%s\n", (unsigned int)wmod->load_addr,
+		     xtype, wmod->module_name);
     }
 }
 
@@ -482,13 +444,13 @@
 
     if (!(wmod = DEBUG_FindModuleByHandle(mod, DM_TYPE_UNKNOWN)) &&
 	!(wmod = DEBUG_FindModuleByAddr((void*)mod, DM_TYPE_UNKNOWN))) {
-	fprintf(stderr, "'0x%08lx' is not a valid module handle or address\n", mod);
+	DEBUG_Printf(DBG_CHN_MESG, "'0x%08lx' is not a valid module handle or address\n", mod);
 	return;
     }
 
-    fprintf(stderr, "Module '%s' (handle=0x%08x) at 0x%8.8x (%s/%s)\n",
-	    wmod->module_name, wmod->handle, (unsigned int)wmod->load_addr,
-	    DEBUG_GetModuleType(wmod->type), DEBUG_GetModuleStatus(wmod->status));
+    DEBUG_Printf(DBG_CHN_MESG, "Module '%s' (handle=0x%08x) at 0x%8.8x (%s/%s)\n",
+		 wmod->module_name, wmod->handle, (unsigned int)wmod->load_addr,
+		 DEBUG_GetModuleType(wmod->type), DEBUG_GetModuleStatus(wmod->status));
 }
 
 /***********************************************************************
@@ -501,7 +463,7 @@
     DBG_MODULE*	wmod;
     const char*	xtype;
 
-    fprintf(stderr, "Address\t\tModule\tName\n");
+    DEBUG_Printf(DBG_CHN_MESG, "Address\t\tModule\tName\n");
 
     for (wmod = DEBUG_CurrProcess->modules; wmod; wmod = wmod->next) {
 	switch (wmod->type) {
@@ -511,9 +473,9 @@
 	default:		xtype = "???"; break;
 	}
 	
-	fprintf(stderr, "0x%8.8x\t(%s)\t%s\n", 
-		(unsigned int)wmod->load_addr, DEBUG_GetModuleType(wmod->type), 
-		wmod->module_name);
+	DEBUG_Printf(DBG_CHN_MESG, "0x%8.8x\t(%s)\t%s\n", 
+		     (unsigned int)wmod->load_addr, DEBUG_GetModuleType(wmod->type), 
+		     wmod->module_name);
     }
 }
 
diff --git a/debugger/msc.c b/debugger/msc.c
index 998d342..bae9edd 100644
--- a/debugger/msc.c
+++ b/debugger/msc.c
@@ -16,16 +16,8 @@
  */
 
 #include "config.h"
-#include <stdio.h>
 #include <stdlib.h>
 
-#include <sys/types.h>
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <limits.h>
 #include <string.h>
 #include <unistd.h>
 #ifndef PATH_MAX
@@ -46,44 +38,79 @@
 
 #define	MSC_INFO(module)	((MSC_DBG_INFO*)((module)->extra_info))
 
+static int DEBUG_ProcessMSCDebugInfo(DBG_MODULE* module);
+
 /*
  * dbg_filename must be at least MAX_PATHNAME_LEN bytes in size
  */
-static void LocateDebugInfoFile(char *filename, char *dbg_filename)
+static void DEBUG_LocateDebugInfoFile(const char *filename, char *dbg_filename)
 {
-    char	  *str1 = DBG_alloc(MAX_PATHNAME_LEN*10);
-    char	  *str2 = DBG_alloc(MAX_PATHNAME_LEN);
-    char	  *file;
+    char	  *str1 = DBG_alloc(MAX_PATHNAME_LEN);
+    char	  *str2 = DBG_alloc(MAX_PATHNAME_LEN*10);
+    const char	  *file;
     char	  *name_part;
-    DOS_FULL_NAME fullname;
     
     file = strrchr(filename, '\\');
     if( file == NULL ) file = filename; else file++;
 
-    if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN))
-	if (SearchPathA(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))
-	    goto ok;
-    if (GetEnvironmentVariableA("_NT_ALT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN))
-	if (SearchPathA(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))
-	    goto ok;
-    if (SearchPathA(NULL, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))
-	goto ok;
+    if ((GetEnvironmentVariable("_NT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
+	 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
+	(GetEnvironmentVariable("_NT_ALT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
+	 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
+	(SearchPath(NULL, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part)))
+        lstrcpyn(dbg_filename, str2, MAX_PATHNAME_LEN);
     else
-    {
-quit:	
-        memcpy(dbg_filename, filename, MAX_PATHNAME_LEN);
-	DBG_free(str1);
-	DBG_free(str2);
-	return;
-    }
-ok:
-    if (DOSFS_GetFullName(str2, TRUE, &fullname))
-	memcpy(dbg_filename, fullname.long_name, MAX_PATHNAME_LEN);
-    else
-	goto quit;
+        lstrcpyn(dbg_filename, filename, MAX_PATHNAME_LEN);
     DBG_free(str1);
     DBG_free(str2);
-    return;
+}
+
+/***********************************************************************
+ *           DEBUG_MapDebugInfoFile
+ */
+static void*	DEBUG_MapDebugInfoFile(const char* name, DWORD offset, DWORD size,
+				       HANDLE* hFile, HANDLE* hMap)
+{
+    OFSTRUCT	ofs;
+    DWORD	g_offset;	/* offset aligned on map granuality */
+    DWORD	g_size;		/* size to map, with offset aligned */
+    char*	ret;
+
+    *hMap = 0;
+
+    if (name != NULL) {
+       char 	filename[MAX_PATHNAME_LEN];
+
+       DEBUG_LocateDebugInfoFile(name, filename);
+       if ((*hFile = OpenFile(filename, &ofs, OF_READ)) == HFILE_ERROR)
+	  return NULL;
+    }
+
+    if (!size) {
+       DWORD file_size = GetFileSize(*hFile, NULL);
+       if (file_size == (DWORD)-1) return NULL;
+       size = file_size - offset;
+    }
+
+    g_offset = offset & ~0xFFFF; /* FIXME: is granularity portable ? */
+    g_size = offset + size - g_offset;
+
+    if ((*hMap = CreateFileMapping(*hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == 0)
+       return NULL;
+    
+    if ((ret = MapViewOfFile(*hMap, FILE_MAP_READ, 0, g_offset, g_size)) != NULL)
+       ret += offset - g_offset;
+    return ret;
+}
+
+/***********************************************************************
+ *           DEBUG_UnmapDebugInfoFile
+ */
+static void	DEBUG_UnmapDebugInfoFile(HANDLE hFile, HANDLE hMap, void* addr)
+{
+   if (addr) UnmapViewOfFile(addr);
+   if (hMap) CloseHandle(hMap);
+   if (hFile) CloseHandle(hFile);
 }
 
 union any_size
@@ -790,7 +817,7 @@
 	       * This is a numeric leaf, I am too lazy to handle this right
 	       * now.
 	       */
-	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 	      break;
 	    }
 	  if( type->array.namelen != 0 )
@@ -825,7 +852,7 @@
 	       * This is a numeric leaf, I am too lazy to handle this right
 	       * now.
 	       */
-	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 	      break;
 	    }
 	  if( type->array32.namelen != 0 )
@@ -900,7 +927,7 @@
 		       * This is a numeric leaf, I am too lazy to handle this right
 		       * now.
 		       */
-		      fprintf(stderr, "Ignoring large numberic leaf.\n");
+		      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 		    }
 		  else
 		    {
@@ -920,7 +947,7 @@
 		       * This is a numeric leaf, I am too lazy to handle this right
 		       * now.
 		       */
-		      fprintf(stderr, "Ignoring large numberic leaf.\n");
+		      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 		    }
 		  else
 		    {
@@ -935,7 +962,7 @@
 		   * object in the fieldlist, or some other problem which I wouldn't
 		   * really know how to handle until it came up.
 		   */
-		  fprintf(stderr, "Unexpected entry in fieldlist\n");
+		  DEBUG_Printf(DBG_CHN_MESG, "Unexpected entry in fieldlist\n");
 		  break;
 		}
 
@@ -990,7 +1017,7 @@
 		       * This is a numeric leaf, I am too lazy to handle this right
 		       * now.
 		       */
-		      fprintf(stderr, "Ignoring large numberic leaf.\n");
+		      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 		    }
 		  else
 		    {
@@ -1010,7 +1037,7 @@
 		       * This is a numeric leaf, I am too lazy to handle this right
 		       * now.
 		       */
-		      fprintf(stderr, "Ignoring large numberic leaf.\n");
+		      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 		    }
 		  else
 		    {
@@ -1025,7 +1052,7 @@
 		   * object in the fieldlist, or some other problem which I wouldn't
 		   * really know how to handle until it came up.
 		   */
-		  fprintf(stderr, "Unexpected entry in fieldlist\n");
+		  DEBUG_Printf(DBG_CHN_MESG, "Unexpected entry in fieldlist\n");
 		  break;
 		}
 
@@ -1041,7 +1068,7 @@
 	       * This is a numeric leaf, I am too lazy to handle this right
 	       * now.
 	       */
-	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 	      break;
 	    }
 	  memset(symname, 0, sizeof(symname));
@@ -1075,7 +1102,7 @@
 	       * This is a numeric leaf, I am too lazy to handle this right
 	       * now.
 	       */
-	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 	      break;
 	    }
 	  memset(symname, 0, sizeof(symname));
@@ -1108,7 +1135,7 @@
 	       * This is a numeric leaf, I am too lazy to handle this right
 	       * now.
 	       */
-	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 	      break;
 	    }
 	  memset(symname, 0, sizeof(symname));
@@ -1143,7 +1170,7 @@
 	       * This is a numeric leaf, I am too lazy to handle this right
 	       * now.
 	       */
-	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      DEBUG_Printf(DBG_CHN_MESG, "Ignoring large numberic leaf.\n");
 	      break;
 	    }
 	  memset(symname, 0, sizeof(symname));
@@ -1274,7 +1301,7 @@
  * We don't fully process it here for performance reasons.
  */
 int
-DEBUG_RegisterMSCDebugInfo(DBG_MODULE* module, void* _nth, unsigned long nth_ofs)
+DEBUG_RegisterMSCDebugInfo(DBG_MODULE* module, HANDLE hFile, void* _nth, unsigned long nth_ofs)
 {
   int			  has_codeview = FALSE;
   int			  rtn = FALSE;
@@ -1309,7 +1336,7 @@
 	case IMAGE_DEBUG_TYPE_COFF:
 	  /*
 	   * If we have both codeview and COFF debug info, ignore the
-	   * coff debug info as  it would just confuse us, and it is 
+	   * coff debug info as it would just confuse us, and it is 
 	   * less complete.
 	   *
 	   * FIXME - this is broken - if we cannot find the PDB file, then
@@ -1335,11 +1362,6 @@
           if(   (dbg.Type != IMAGE_DEBUG_TYPE_MISC) ||
                 (nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) != 0 )
             {
-                char            fn[PATH_MAX];
-                int             fd = -1;
-                DOS_FULL_NAME   full_name;
-		char*		dbg_info;
-
                 /*
                  * Read the important bits.  What we do after this depends
                  * upon the type, but this is always enough so we are able
@@ -1349,31 +1371,27 @@
                  * the DataDirectory array's content. One its entry contains the *beloved*
                  * debug information. (Note the DataDirectory is mapped, not its content)
                  */
-		/* FIXME: the module->handle value is not usable in the debugger's process */
-		if (GetModuleFileNameA(module->handle, fn, sizeof(fn)) > 0 &&
-                    DOSFS_GetFullName(fn, TRUE, &full_name) &&
-                    (fd = open(full_name.long_name, O_RDONLY)) > 0)
-		{
-                    dbg_info = mmap(NULL, dbg.SizeOfData,
-				    PROT_READ, MAP_PRIVATE, fd, dbg.PointerToRawData);
-                    close(fd);
-                    if( dbg_info == (char *) 0xffffffff ) break;
-                }
-                else
-                {
-                    fprintf(stderr, " (not mapped: fn='%s', lfn='%s', fd=%d)\n", fn, full_name.long_name, fd);
-                    break;
-                }
-		if (!(module->extra_info = DBG_alloc(sizeof(MSC_DBG_INFO))))
-		    break;
+		HANDLE	hMap;
+		char*	dbg_info;
 
-		MSC_INFO(module)->dbg_info = dbg_info;
-		MSC_INFO(module)->dbg_size = dbg.SizeOfData;
-                MSC_INFO(module)->dbgdir = dbg;
-                MSC_INFO(module)->sect_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
-		   nth->FileHeader.SizeOfOptionalHeader;
-                MSC_INFO(module)->nsect = nth->FileHeader.NumberOfSections;
-            }
+		DEBUG_Printf(DBG_CHN_TRACE, "PE debugging info at %ld<%ld>\n", dbg.PointerToRawData, dbg.SizeOfData);
+		dbg_info = DEBUG_MapDebugInfoFile(NULL, dbg.PointerToRawData, dbg.SizeOfData,
+						  &hFile, &hMap);
+
+		if (dbg_info != NULL && 
+		    (module->extra_info = DBG_alloc(sizeof(MSC_DBG_INFO))) != NULL) {
+		   MSC_INFO(module)->dbg_info = dbg_info;
+		   MSC_INFO(module)->dbg_size = dbg.SizeOfData;
+		   MSC_INFO(module)->dbgdir = dbg;
+		   MSC_INFO(module)->sect_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
+		      nth->FileHeader.SizeOfOptionalHeader;
+		   MSC_INFO(module)->nsect = nth->FileHeader.NumberOfSections;
+		   DEBUG_ProcessMSCDebugInfo(module);
+		   DBG_free(MSC_INFO(module));
+		   MSC_INFO(module) = NULL;
+		}
+		DEBUG_UnmapDebugInfoFile(0, hMap, dbg_info);
+	    }
 	  break;
 #if 0
 	default:
@@ -1388,44 +1406,65 @@
 }
 
 /* look for stabs information in PE header (it's how mingw compiler provides its
- * debugging information
+ * debugging information), and also wine PE <-> ELF linking thru .wsolnk sections
  */
-int DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, void* _nth, unsigned long nth_ofs)
+int DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile, void* _nth, 
+				 unsigned long nth_ofs)
 {
     IMAGE_SECTION_HEADER	pe_seg;
     unsigned long		pe_seg_ofs;
-    int 		      	i, stabsize = 0, stabstrsize = 0;
-    unsigned int 		stabs = 0, stabstr = 0;
-    char			bufstr[256];
-    PIMAGE_NT_HEADERS		nth  = (PIMAGE_NT_HEADERS)_nth;
+    int 		      	i, stabsize = 0, stabstrsize = 0, xcnlnksize = 0;
+    unsigned int 		stabs = 0, stabstr = 0, xcnlnk = 0;
+    PIMAGE_NT_HEADERS		nth = (PIMAGE_NT_HEADERS)_nth;
 
     pe_seg_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
 	nth->FileHeader.SizeOfOptionalHeader;
 
     for (i = 0; i < nth->FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
       if (!DEBUG_READ_MEM_VERBOSE((void*)((char *)module->load_addr + pe_seg_ofs), 
-				  &pe_seg, sizeof(pe_seg)) ||
-	  !DEBUG_READ_MEM_VERBOSE((void*)pe_seg.Name, bufstr, sizeof(bufstr)))
-	  {fprintf(stderr, "err3\n");continue;}
-      bufstr[sizeof(bufstr) - 1] = 0;
+				  &pe_seg, sizeof(pe_seg)))
+	  continue;
 
-      if (!strcasecmp(bufstr, ".stab")) {
+      if (!strcasecmp(pe_seg.Name, ".stab")) {
 	stabs = pe_seg.VirtualAddress;
 	stabsize = pe_seg.SizeOfRawData;
-      } else if (!strncasecmp(bufstr, ".stabstr", 8)) {
+      } else if (!strncasecmp(pe_seg.Name, ".stabstr", 8)) {
 	stabstr = pe_seg.VirtualAddress;
 	stabstrsize = pe_seg.SizeOfRawData;
+      } else if (!strncasecmp(pe_seg.Name, ".xcnlnk", 7)) {
+	xcnlnk = pe_seg.VirtualAddress;
+	xcnlnksize = pe_seg.SizeOfRawData;
       }
     }
+
     if (stabstrsize && stabsize) {
-#ifdef _WE_SUPPORT_THE_STAB_TYPES_USED_BY_MINGW_TOO
-      /* Won't work currently, since MINGW32 uses some special typedefs
-       * which we do not handle yet. Support for them is a bit difficult.
-       */
-       /* FIXME: load_addr is in a different address space... */
-      DEBUG_ParseStabs(module->load_addr, 0, stabs, stabsize, stabstr, stabstrsize);
-#endif
-      fprintf(stderr,"(stabs not loaded)");
+       char*	s1 = DBG_alloc(stabsize+stabstrsize);
+
+       if (s1) {
+	  if (DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabs, s1, stabsize) &&
+	      DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabstr, 
+				     s1 + stabsize, stabstrsize)) {
+	     DEBUG_ParseStabs(s1, 0, 0, stabsize, stabsize, stabstrsize);
+	  } else {
+	     DEBUG_Printf(DBG_CHN_MESG, "couldn't read data block\n");
+	  }
+	  DBG_free(s1);
+       } else {
+	  DEBUG_Printf(DBG_CHN_MESG, "couldn't alloc %d bytes\n", 
+		       stabsize + stabstrsize);
+       }
+    }
+    if (xcnlnksize) {
+       DWORD	addr;
+       char	bufstr[256];
+
+       if (DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + xcnlnk, &addr, 
+				  sizeof(addr)) &&
+	   DEBUG_READ_MEM_VERBOSE((char*)addr, bufstr, sizeof(bufstr))) {
+	  bufstr[sizeof(bufstr) - 1] = 0;
+	  DEBUG_Printf(DBG_CHN_TRACE, "Got xcnlnk: argv0 '%s'\n", bufstr);
+ 	  DEBUG_ReadExecutableDbgInfo(bufstr);
+       }
     }
     return TRUE;
 }
@@ -1504,9 +1543,7 @@
 	  curr_file->linecnt = 0;
 	  curr_file->entries = NULL;
 	  curr_file->neps = curr_file->neps_alloc = 0;
-#if 0
-	  fprintf(stderr,"New file %s\n", curr_file->filename);
-#endif
+	  DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", curr_file->filename);
 	  i += naux;
 	  continue;
 	}
@@ -1527,19 +1564,19 @@
 	  if( curr_file->linetab_offset != -1 )
 	    {
 #if 0
-	      fprintf(stderr, "Duplicating sect from %s: %x %x %x %d %d\n",
-		      curr_file->filename,
-		      aux->Length,
-		      aux->NumberOfRelocations,
-		      aux->NumberOfLinenumbers,
-		      aux->Number,
-		      aux->Selection);
-	      fprintf(stderr, "More sect %d %x %d %d %d\n", 
-		      coff_sym->SectionNumber,
-		      coff_sym->Value,
-		      coff_sym->Type,
-		      coff_sym->StorageClass,
-		      coff_sym->NumberOfAuxSymbols);
+	      DEBUG_Printf(DBG_CHN_TRACE, "Duplicating sect from %s: %x %x %x %d %d\n",
+			   curr_file->filename,
+			   aux->Length,
+			   aux->NumberOfRelocations,
+			   aux->NumberOfLinenumbers,
+			   aux->Number,
+			   aux->Selection);
+	      DEBUG_Printf(DBG_CHN_TRACE, "More sect %d %x %d %d %d\n", 
+			   coff_sym->SectionNumber,
+			   coff_sym->Value,
+			   coff_sym->Type,
+			   coff_sym->StorageClass,
+			   coff_sym->NumberOfAuxSymbols);
 #endif
 
 	      /*
@@ -1555,7 +1592,7 @@
 		{
 		  nfiles_alloc += 10;
 		  coff_files = (struct CoffFiles *) DBG_realloc(coff_files,
-							     nfiles_alloc * sizeof(struct CoffFiles));
+								nfiles_alloc * sizeof(struct CoffFiles));
 		}
 	      curr_file = coff_files + nfiles;
 	      nfiles++;
@@ -1570,13 +1607,13 @@
 #if 0
 	  else
 	    {
-	      fprintf(stderr, "New text sect from %s: %x %x %x %d %d\n",
-		      curr_file->filename,
-		      aux->Length,
-		      aux->NumberOfRelocations,
-		      aux->NumberOfLinenumbers,
-		      aux->Number,
-		      aux->Selection);
+	      DEBUG_Printf(DBG_CHN_TRACE, "New text sect from %s: %x %x %x %d %d\n",
+			   curr_file->filename,
+			   aux->Length,
+			   aux->NumberOfRelocations,
+			   aux->NumberOfLinenumbers,
+			   aux->Number,
+			   aux->Selection);
 	    }
 #endif
 
@@ -1638,7 +1675,7 @@
 			 curr_file->neps_alloc * sizeof(struct name_hash *));
 	    }
 #if 0
-	  fprintf(stderr,"\tAdding static symbol %s\n", nampnt);
+	  DEBUG_Printf(DBG_CHN_TRACE,"\tAdding static symbol %s\n", nampnt);
 #endif
 	  curr_file->entries[curr_file->neps++] =
 	     DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 );
@@ -1671,9 +1708,9 @@
 	  new_value.addr.off = (int) ((char *)module->load_addr + coff_sym->Value);
 
 #if 0
-	  fprintf(stderr, "%d: %x %s\n", i, new_value.addr.off, nampnt);
+	  DEBUG_Printf(DBG_CHN_TRACE, "%d: %x %s\n", i, new_value.addr.off, nampnt);
 
-	  fprintf(stderr,"\tAdding global symbol %s\n", nampnt);
+	  DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global symbol %s\n", nampnt);
 #endif
 
 	  /*
@@ -1730,9 +1767,9 @@
 	  new_value.addr.off = (int) ((char *)module->load_addr + coff_sym->Value);
 
 #if 0
-	  fprintf(stderr, "%d: %x %s\n", i, new_value.addr.off, nampnt);
+	  DEBUG_Printf(DBG_CHN_TRACE, "%d: %x %s\n", i, new_value.addr.off, nampnt);
 
-	  fprintf(stderr,"\tAdding global data symbol %s\n", nampnt);
+	  DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global data symbol %s\n", nampnt);
 #endif
 
 	  /*
@@ -1755,8 +1792,8 @@
 	}
 
 #if 0
-      fprintf(stderr,"Skipping unknown entry %d %d %d\n", coff_sym->StorageClass, 
-	      coff_sym->SectionNumber, naux);
+      DEBUG_Printf(DBG_CHN_TRACE,"Skipping unknown entry %d %d %d\n", coff_sym->StorageClass, 
+		   coff_sym->SectionNumber, naux);
 #endif
 
       /*
@@ -2547,12 +2584,10 @@
     }
 }
 
-static int DEBUG_ProcessPDBFile( DBG_MODULE* module, char *full_filename )
+static int DEBUG_ProcessPDBFile( DBG_MODULE* module, const char *full_filename )
 {
-    char filename[MAX_PATHNAME_LEN];
-    struct stat	statbuf;
-    int	fd = -1;
-    char *image = (char *) 0xffffffff;
+    HANDLE hFile, hMap;
+    char *image = NULL;
     PDB_HEADER *pdb = NULL;
     PDB_TOC *toc = NULL;
     PDB_ROOT *root = NULL;
@@ -2565,29 +2600,11 @@
 
 
     /*
-     * Open and mmap() .PDB file
+     * Open and map() .PDB file
      */
-
-    LocateDebugInfoFile( full_filename, filename );
-
-    if ( stat( filename, &statbuf ) == -1 )
-    {
-        fprintf( stderr, "-Unable to open .PDB file %s\n", filename );
-        goto leave;
-    }
-
-    fd = open(filename, O_RDONLY);
-    if ( fd == -1 )
-    {
-        fprintf( stderr, "-Unable to open .PDB file %s\n", filename );
-        goto leave;
-    }
-
-    image = mmap( 0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0 );
-    if ( image == (char *) 0xffffffff )
-    {
-        fprintf(stderr, "-Unable to mmap .PDB file %s\n", filename);
-        goto leave;
+    if ((image = DEBUG_MapDebugInfoFile(full_filename, 0, 0, &hFile, &hMap)) == NULL) {
+       DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .PDB file %s\n", full_filename );
+       goto leave;
     }
 
     /*
@@ -2615,7 +2632,7 @@
         case 19970604:      /* VC 6.0 */
             break;
         default:
-            fprintf( stderr, "-Unknown root block version %ld\n", root->version );
+            DEBUG_Printf( DBG_CHN_ERR, "-Unknown root block version %ld\n", root->version );
     }
 
     switch ( types.version )
@@ -2625,7 +2642,7 @@
         case 19961031:      /* VC 5.0 / 6.0 */
             break;
         default:
-            fprintf( stderr, "-Unknown type info version %ld\n", types.version );
+            DEBUG_Printf( DBG_CHN_ERR, "-Unknown type info version %ld\n", types.version );
     }
 
     switch ( symbols.version )
@@ -2635,7 +2652,7 @@
         case 19970606:     /* VC 6.0 */
             break;
         default:
-            fprintf( stderr, "-Unknown symbol info version %ld\n", symbols.version );
+            DEBUG_Printf( DBG_CHN_ERR, "-Unknown symbol info version %ld\n", symbols.version );
     }
 
 
@@ -2646,7 +2663,7 @@
     if (      root->TimeDateStamp 
          != ((struct CodeViewDebug *)MSC_INFO(module)->dbg_info)->cv_timestamp ) 
     {
-        fprintf(stderr, "-Wrong time stamp of .PDB file %s\n", filename);
+        DEBUG_Printf(DBG_CHN_ERR, "-Wrong time stamp of .PDB file %s\n", full_filename);
         goto leave;
     }
 
@@ -2663,7 +2680,7 @@
     if ( symbols.pdbimport_size )
     {   
         /* FIXME */
-        fprintf(stderr, "-Type server .PDB imports ignored!\n" );
+        DEBUG_Printf(DBG_CHN_ERR, "-Type server .PDB imports ignored!\n" );
     }
 
     /* 
@@ -2738,8 +2755,7 @@
     if ( root ) pdb_free( root );
     if ( toc ) pdb_free( toc );
 
-    if ( image != (char *) 0xffffffff ) munmap( image, statbuf.st_size );
-    if ( fd != -1 ) close( fd );
+    DEBUG_UnmapDebugInfoFile(hFile, hMap, image);
 
     return TRUE;
 }
@@ -2750,61 +2766,33 @@
  */
 static
 int
-DEBUG_ProcessDBGFile(DBG_MODULE* module, char * filename)
+DEBUG_ProcessDBGFile(DBG_MODULE* module, const char* filename)
 {
-  char			      * addr = (char *) 0xffffffff;
+  HANDLE			hFile, hMap;
+  char			      * addr;
   char			      * codeview;
   struct CV4_DirHead	      * codeview_dir;
   struct CV4_DirEnt	      * codeview_dent;
   PIMAGE_DEBUG_DIRECTORY	dbghdr;
   DBG_MODULE			module2;
-  int				fd = -1;
   int				i;
   int				j;
   struct codeview_linetab_hdr * linetab;
   int				nsect;
   PIMAGE_SEPARATE_DEBUG_HEADER pdbg = NULL;
   IMAGE_SECTION_HEADER        * sectp;
-  struct stat			statbuf;
-  int				status;
-  char				dbg_file[MAX_PATHNAME_LEN];
 
-  LocateDebugInfoFile(filename, dbg_file);
-  status = stat(dbg_file, &statbuf);
-  if( status == -1 )
-    {
-      fprintf(stderr, "-Unable to open .DBG file %s\n", dbg_file);
-      goto leave;
-    }
-
-  /*
-   * Now open the file, so that we can mmap() it.
-   */
-  fd = open(dbg_file, O_RDONLY);
-  if( fd == -1 )
-    {
-      fprintf(stderr, "Unable to open .DBG file %s\n", dbg_file);
-      goto leave;
-    }
-
-
-  /*
-   * Now mmap() the file.
-   */
-  addr = mmap(0, statbuf.st_size, PROT_READ, 
-	      MAP_PRIVATE, fd, 0);
-  if( addr == (char *) 0xffffffff )
-    {
-      fprintf(stderr, "Unable to mmap .DBG file %s\n", dbg_file);
-      goto leave;
-    }
+  if ((addr = DEBUG_MapDebugInfoFile(filename, 0, 0, &hFile, &hMap)) == NULL) {
+     DEBUG_Printf(DBG_CHN_ERR, "-Unable to peruse .DBG file %s\n", filename);
+     goto leave;
+  }
 
   pdbg = (PIMAGE_SEPARATE_DEBUG_HEADER) addr;
 
   if( pdbg->TimeDateStamp != MSC_INFO(module)->dbgdir.TimeDateStamp )
     {
-      fprintf(stderr, "Warning - %s has incorrect internal timestamp\n",
-	      dbg_file);
+      DEBUG_Printf(DBG_CHN_ERR, "Warning - %s has incorrect internal timestamp\n",
+	      filename);
 /*      goto leave; */
 /*
    Well, sometimes this happens to DBG files which ARE REALLY the right .DBG
@@ -2813,7 +2801,7 @@
 */
    }
 
-  fprintf(stderr, "Processing symbols from %s...\n", dbg_file);
+  DEBUG_Printf(DBG_CHN_MESG, "Processing symbols from %s...\n", filename);
 
   dbghdr = (PIMAGE_DEBUG_DIRECTORY) (  addr + sizeof(*pdbg) 
 		 + pdbg->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) 
@@ -2918,20 +2906,12 @@
     }
 leave:
 
-  if( addr != (char *) 0xffffffff )
-    {
-      munmap(addr, statbuf.st_size);
-    }
-
-  if( fd != -1 )
-    {
-      close(fd);
-    }
+  DEBUG_UnmapDebugInfoFile(hFile, hMap, addr);
 
   return TRUE;
 }
 
-int
+static int 
 DEBUG_ProcessMSCDebugInfo(DBG_MODULE* module)
 {
   struct CodeViewDebug	     * cvd;
@@ -2946,9 +2926,7 @@
 	 * Standard COFF debug information that VC++ adds when you
 	 * use /debugtype:both with the linker.
 	 */
-#if 0
-	fprintf(stderr, "Processing COFF symbols...\n");
-#endif
+	DEBUG_Printf(DBG_CHN_TRACE, "Processing COFF symbols...\n");
 	sts = DEBUG_ProcessCoff(module);
 	break;
      case IMAGE_DEBUG_TYPE_CODEVIEW:
@@ -2967,9 +2945,7 @@
 	      break;
 	   }
 	sts = DEBUG_ProcessPDBFile(module, cvd->cv_name);
-#if 0
-	fprintf(stderr, "Processing PDB file %s\n", cvd->cv_name);
-#endif
+	DEBUG_Printf(DBG_CHN_TRACE, "Processing PDB file %s\n", cvd->cv_name);
 	break;
      case IMAGE_DEBUG_TYPE_MISC:
 	/*
@@ -3007,6 +2983,7 @@
 	sts = FALSE;
 	break;
      }
+  module->status = (sts) ? DM_STATUS_LOADED : DM_STATUS_ERROR;
   return sts;
 }
 
diff --git a/debugger/registers.c b/debugger/registers.c
index 9f6610f..3e49ca6 100644
--- a/debugger/registers.c
+++ b/debugger/registers.c
@@ -85,7 +85,7 @@
         case REG_FS:  val = "%%fs";  break;
         case REG_GS:  val = "%%gs";  break;
     }
-    if (val) fprintf(stderr, val);
+    if (val) DEBUG_Printf(DBG_CHN_MESG, val);
     return TRUE;
 #else
     return FALSE;
@@ -195,40 +195,40 @@
  */
 void DEBUG_InfoRegisters(void)
 {
-    fprintf(stderr,"Register dump:\n");
+    DEBUG_Printf(DBG_CHN_MESG,"Register dump:\n");
 
 #ifdef __i386__
     /* First get the segment registers out of the way */
-    fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x FS:%04x GS:%04x",
-             (WORD)DEBUG_context.SegCs, (WORD)DEBUG_context.SegSs,
-             (WORD)DEBUG_context.SegDs, (WORD)DEBUG_context.SegEs,
-             (WORD)DEBUG_context.SegFs, (WORD)DEBUG_context.SegGs );
+    DEBUG_Printf( DBG_CHN_MESG," CS:%04x SS:%04x DS:%04x ES:%04x FS:%04x GS:%04x",
+		  (WORD)DEBUG_context.SegCs, (WORD)DEBUG_context.SegSs,
+		  (WORD)DEBUG_context.SegDs, (WORD)DEBUG_context.SegEs,
+		  (WORD)DEBUG_context.SegFs, (WORD)DEBUG_context.SegGs );
     if (DEBUG_CurrThread->dbg_mode == 16)
     {
         char flag[33];
 
-        fprintf( stderr,"\n IP:%04x SP:%04x BP:%04x FLAGS:%04x(%s)\n",
-                 LOWORD(DEBUG_context.Eip), LOWORD(DEBUG_context.Esp),
-                 LOWORD(DEBUG_context.Ebp), LOWORD(DEBUG_context.EFlags),
-		 DEBUG_Flags(LOWORD(DEBUG_context.EFlags), flag));
-	fprintf( stderr," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
-                 LOWORD(DEBUG_context.Eax), LOWORD(DEBUG_context.Ebx),
-                 LOWORD(DEBUG_context.Ecx), LOWORD(DEBUG_context.Edx),
-                 LOWORD(DEBUG_context.Esi), LOWORD(DEBUG_context.Edi) );
+        DEBUG_Printf( DBG_CHN_MESG,"\n IP:%04x SP:%04x BP:%04x FLAGS:%04x(%s)\n",
+		      LOWORD(DEBUG_context.Eip), LOWORD(DEBUG_context.Esp),
+		      LOWORD(DEBUG_context.Ebp), LOWORD(DEBUG_context.EFlags),
+		      DEBUG_Flags(LOWORD(DEBUG_context.EFlags), flag));
+	DEBUG_Printf( DBG_CHN_MESG," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
+		      LOWORD(DEBUG_context.Eax), LOWORD(DEBUG_context.Ebx),
+		      LOWORD(DEBUG_context.Ecx), LOWORD(DEBUG_context.Edx),
+		      LOWORD(DEBUG_context.Esi), LOWORD(DEBUG_context.Edi) );
     }
     else  /* 32-bit mode */
     {
         char flag[33];
 
-        fprintf( stderr, "\n EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx(%s)\n", 
-                 DEBUG_context.Eip, DEBUG_context.Esp,
-                 DEBUG_context.Ebp, DEBUG_context.EFlags,
-		 DEBUG_Flags(DEBUG_context.EFlags, flag));
-	fprintf( stderr, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n", 
-		 DEBUG_context.Eax, DEBUG_context.Ebx,
-                 DEBUG_context.Ecx, DEBUG_context.Edx );
-	fprintf( stderr, " ESI:%08lx EDI:%08lx\n",
-                 DEBUG_context.Esi, DEBUG_context.Edi );
+        DEBUG_Printf( DBG_CHN_MESG, "\n EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx(%s)\n", 
+		      DEBUG_context.Eip, DEBUG_context.Esp,
+		      DEBUG_context.Ebp, DEBUG_context.EFlags,
+		      DEBUG_Flags(DEBUG_context.EFlags, flag));
+	DEBUG_Printf( DBG_CHN_MESG, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n", 
+		      DEBUG_context.Eax, DEBUG_context.Ebx,
+		      DEBUG_context.Ecx, DEBUG_context.Edx );
+	DEBUG_Printf( DBG_CHN_MESG, " ESI:%08lx EDI:%08lx\n",
+		      DEBUG_context.Esi, DEBUG_context.Edi );
     }
 #endif
 }
@@ -249,8 +249,8 @@
 /* Check that a selector is a valid ring-3 LDT selector, or a NULL selector */
 #define CHECK_SEG(seg,name) \
     if (((seg) & ~3) && ((((seg) & 7) != 7) || !DEBUG_IsSelector(seg))) { \
-        fprintf( stderr, "*** Invalid value for %s register: %04x\n", \
-                 (name), (WORD)(seg) ); \
+        DEBUG_Printf( DBG_CHN_MESG, "*** Invalid value for %s register: %04x\n", \
+                      (name), (WORD)(seg) ); \
         return FALSE; \
     }
 
@@ -268,14 +268,14 @@
 
     if (!(DEBUG_context.SegCs & ~3))
     {
-        fprintf( stderr, "*** Invalid value for CS register: %04x\n",
-                 (WORD)DEBUG_context.SegCs );
+        DEBUG_Printf( DBG_CHN_MESG, "*** Invalid value for CS register: %04x\n",
+		      (WORD)DEBUG_context.SegCs );
         return FALSE;
     }
     if (!(DEBUG_context.SegSs & ~3))
     {
-        fprintf( stderr, "*** Invalid value for SS register: %04x\n",
-                 (WORD)DEBUG_context.SegSs );
+        DEBUG_Printf( DBG_CHN_MESG, "*** Invalid value for SS register: %04x\n",
+		      (WORD)DEBUG_context.SegSs );
         return FALSE;
     }
     return TRUE;
diff --git a/debugger/source.c b/debugger/source.c
index 1f212c3..e4f2365 100644
--- a/debugger/source.c
+++ b/debugger/source.c
@@ -53,12 +53,12 @@
 {
   struct searchlist * sl;
 
-  fprintf(stderr,"Search list :\n");
+  DEBUG_Printf(DBG_CHN_MESG,"Search list :\n");
   for(sl = listhead; sl; sl = sl->next)
     {
-      fprintf(stderr, "\t%s\n", sl->path);
+      DEBUG_Printf(DBG_CHN_MESG, "\t%s\n", sl->path);
     }
-  fprintf(stderr, "\n");
+  DEBUG_Printf(DBG_CHN_MESG, "\n");
 }
 
 void
@@ -186,7 +186,7 @@
 	      /*
 	       * Still couldn't find it.  Ask user for path to add.
 	       */
-	      fprintf(stderr,"Enter path to file %s: ", sourcefile);
+	      DEBUG_Printf(DBG_CHN_MESG,"Enter path to file %s: ", sourcefile);
 	      fgets(tmppath, sizeof(tmppath), stdin);
 	      
 	      if( tmppath[strlen(tmppath)-1] == '\n' )
@@ -217,7 +217,7 @@
 		  ol->nlines = 0;
 		  ol->linelist = NULL;
 		  ofiles = ol;
-		  fprintf(stderr,"Unable to open file %s\n", tmppath);
+		  DEBUG_Printf(DBG_CHN_MESG,"Unable to open file %s\n", tmppath);
 		  return FALSE;
 		}
 	    }
@@ -314,7 +314,7 @@
 	  memcpy(&buffer, addr + ol->linelist[i], 
 		 (ol->linelist[i+1] - ol->linelist[i]) - 1);
 	}
-      fprintf(stderr,"%d\t%s\n", i + 1,  buffer);
+      DEBUG_Printf(DBG_CHN_MESG,"%d\t%s\n", i + 1,  buffer);
     }
 
   munmap(addr, ol->size);
@@ -343,7 +343,7 @@
       && source2->sourcefile != NULL 
       && strcmp(source1->sourcefile, source2->sourcefile) != 0 )
     {
-      fprintf(stderr, "Ambiguous source file specification.\n");
+      DEBUG_Printf(DBG_CHN_MESG, "Ambiguous source file specification.\n");
       return;
     }
 
@@ -367,7 +367,7 @@
 
   if( sourcefile == NULL )
     {
-      fprintf(stderr, "No source file specified.\n");
+      DEBUG_Printf(DBG_CHN_MESG, "No source file specified.\n");
       return;
     }
 
@@ -430,10 +430,10 @@
    char	ch;
 
    DEBUG_PrintAddress( addr, DEBUG_CurrThread->dbg_mode, TRUE );
-   fprintf(stderr,": ");
+   DEBUG_Printf(DBG_CHN_MESG,": ");
    if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(addr), &ch, sizeof(ch))) return 0;
    DEBUG_Disasm( addr, TRUE );
-   fprintf(stderr,"\n");
+   DEBUG_Printf(DBG_CHN_MESG,"\n");
    return 1;
 }
 
@@ -469,7 +469,7 @@
       }
     else if (!value->addr.seg && !value->addr.off)
     {
-        fprintf(stderr,"Invalid expression\n");
+        DEBUG_Printf(DBG_CHN_MESG,"Invalid expression\n");
         return;
     }
 }
diff --git a/debugger/stabs.c b/debugger/stabs.c
index 30a7c46..807b36b 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -4,6 +4,7 @@
  * File stabs.c - read stabs information from the wine executable itself.
  *
  * Copyright (C) 1996, Eric Youngdale.
+ *		 1999, 2000 Eric Pouech
  */
 
 #include "config.h"
@@ -23,7 +24,6 @@
 #define PATH_MAX _MAX_PATH
 #endif
 
-#include "options.h"
 #include "debugger.h"
 
 #if defined(__svr4__) || defined(__sun)
@@ -240,7 +240,7 @@
 {
   struct datatype** ret;
   
-  /* fprintf(stderr, "creating type id for (%d,%d)\n", filenr, subnr); */
+  /* DEBUG_Printf(DBG_CHN_MESG, "creating type id for (%d,%d)\n", filenr, subnr); */
   
   /* FIXME: I could perhaps create a dummy include_def for each compilation
    * unit which would allow not to handle those two cases separately
@@ -271,7 +271,7 @@
 	}
       ret = &idef->vector[subnr];
     }
-  /* fprintf(stderr,"(%d,%d) is %d\n",filenr,subnr,ret); */
+  /* DEBUG_Printf(DBG_CHN_MESG,"(%d,%d) is %d\n",filenr,subnr,ret); */
   return ret;
 }
 
@@ -403,7 +403,7 @@
 	  expect = DT_FUNC;
 	  break;
 	default:
-	  fprintf(stderr, "Unknown type (%c).\n",ptr[1]);
+	  DEBUG_Printf(DBG_CHN_MESG, "Unknown type (%c).\n",ptr[1]);
 	  return FALSE;
 	}
       if( expect != -1 && expect != DEBUG_GetType(ktd->types[count]) )
@@ -491,7 +491,7 @@
 	  /*
 	   * If this ever happens, just bump the counter.
 	   */
-	  fprintf(stderr, "Typedef nesting overflow\n");
+	  DEBUG_Printf(DBG_CHN_MESG, "Typedef nesting overflow\n");
 	  return FALSE;
 	}
       
@@ -535,7 +535,7 @@
 	  curr_types[ntypes++] = *dt;
 	  break;
 	default:
-	  fprintf(stderr, "Unknown type (%c).\n",c[1]);
+	  DEBUG_Printf(DBG_CHN_MESG, "Unknown type (%c).\n",c[1]);
 	}
       typename = NULL;
       
@@ -594,7 +594,7 @@
 	    } 
 	  else 
 	    {
-	      fprintf(stderr, "Unknown condition %p %p (%s)\n", *dt, *dt2, ptr);
+	      DEBUG_Printf(DBG_CHN_MESG, "Unknown condition %p %p (%s)\n", *dt, *dt2, ptr);
 	    }
 	  if( *tc == '\0' )
 	    *c = '\0';
@@ -679,7 +679,7 @@
 		{
 		  failure = 1;
 		  /* ... but proceed parsing to the end of the stab */
-		  fprintf(stderr, "failure on %s %s\n", ptr, ti);
+		  DEBUG_Printf(DBG_CHN_MESG, "failure on %s %s\n", ptr, ti);
 		}
 	    }
 	  
@@ -723,7 +723,7 @@
 	    strcpy(c, tc + 1);
 	  break;
 	default:
-	  fprintf(stderr, "Unknown type (%c).\n",c[1]);
+	  DEBUG_Printf(DBG_CHN_MESG, "Unknown type (%c).\n",c[1]);
 	  break;
 	}
     }
@@ -852,7 +852,7 @@
            * ignore them, and when we process the normal symbol table
            * we should do the right thing.
            *
-           * With a.out, they actually do make some amount of sense.
+           * With a.out or mingw, they actually do make some amount of sense.
            */
           new_value.addr.seg = 0;
           new_value.type = DEBUG_ParseStabType(ptr);
@@ -862,9 +862,9 @@
           stab_strcpy(symname, ptr);
 #ifdef __ELF__
           curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
-                                      SYM_WINE | SYM_DATA | SYM_INVALID);
+                                      SYM_WINE | SYM_DATA | SYM_INVALID );
 #else
-          curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath, 
+          curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
                                       SYM_WINE | SYM_DATA );
 #endif
           break;
@@ -956,22 +956,30 @@
            * on, we will add the line number information and the
            * local symbols.
            */
-          if( !in_external_file )
+          if( !in_external_file)
             {
-              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
-               * it this way because otherwise we end up dirtying
-               * all of the pages related to the stabs, and that
-               * sucks up swap space like crazy.
-               */
               stab_strcpy(symname, ptr);
-              curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
-                                           SYM_WINE | SYM_FUNC);
+	      if (*symname)
+		{
+		  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
+		   * it this way because otherwise we end up dirtying
+		   * all of the pages related to the stabs, and that
+		   * sucks up swap space like crazy.
+		   */
+		  curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
+					       SYM_WINE | SYM_FUNC);
+		} 
+	      else
+		{
+		  /* some GCC seem to use a N_FUN "" to mark the end of a function */
+		  curr_func = NULL;
+		}
             }
           else
             {
@@ -1054,16 +1062,16 @@
            */
           break;
         default:
-	  fprintf(stderr, "Unkown stab type 0x%02x\n", stab_ptr->n_type);
+	  DEBUG_Printf(DBG_CHN_MESG, "Unkown stab type 0x%02x\n", stab_ptr->n_type);
           break;
         }
 
       stabbuff[0] = '\0';
 
 #if 0
-      fprintf(stderr, "%d %x %s\n", stab_ptr->n_type, 
-              (unsigned int) stab_ptr->n_value,
-              strs + (unsigned int) stab_ptr->n_un.n_name);
+      DEBUG_Printf(DBG_CHN_MESG, "%d %x %s\n", stab_ptr->n_type, 
+		   (unsigned int) stab_ptr->n_value,
+		   strs + (unsigned int) stab_ptr->n_un.n_name);
 #endif
     }
 
@@ -1110,7 +1118,8 @@
        * Ignore certain types of entries which really aren't of that much
        * interest.
        */
-      if( ELF32_ST_TYPE(symp->st_info) == STT_SECTION )
+      if( ELF32_ST_TYPE(symp->st_info) == STT_SECTION ||
+	  symp->st_shndx == STN_UNDEF )
 	{
 	  continue;
 	}
@@ -1160,15 +1169,13 @@
   return TRUE;
 }
 
-static
 int
 DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
 {
   int			rtn = FALSE;
-  struct stat		statbuf;
+  char		      * addr = (char*)0xffffffff;
   int			fd = -1;
-  int			status;
-  char		      * addr = (char *) 0xffffffff;
+  struct stat		statbuf;
   Elf32_Ehdr	      * ehptr;
   Elf32_Shdr	      * spnt;
   char		      * shstrtab;
@@ -1177,15 +1184,13 @@
   int			stabsect;
   int			stabstrsect;
 
-
   /*
    * Make sure we can stat and open this file.
    */
   if( filename == NULL )
       goto leave;
 
-  status = stat(filename, &statbuf);
-  if( status == -1 )
+  if (stat(filename, &statbuf) == -1)
     {
       char *s,*t,*fn,*paths;
       if (strchr(filename,'/'))
@@ -1207,25 +1212,28 @@
 	DBG_free(fn);
 	if (t) s = t+1; else break;
       }
-      if (!s || !*s) fprintf(stderr," not found");
+      if (!s || !*s) DEBUG_Printf(DBG_CHN_MESG," not found");
       DBG_free(paths);
       goto leave;
     }
 
+  if (DEBUG_FindModuleByName(filename, DM_TYPE_ELF))
+    goto leave;
+
+  DEBUG_Printf(DBG_CHN_MESG, "Loading stabs debug symbols from %s (0x%08lx)\n", 
+	       filename, load_offset);
+
   /*
    * Now open the file, so that we can mmap() it.
    */
-  fd = open(filename, O_RDONLY);
-  if( fd == -1 )
+  if ((fd = open(filename, O_RDONLY)) == -1)
       goto leave;
 
-
   /*
    * Now mmap() the file.
    */
-  addr = mmap(0, statbuf.st_size, PROT_READ, 
-	      MAP_PRIVATE, fd, 0);
-  if( addr == (char *) 0xffffffff )
+  addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+  if (addr == (char*)0xffffffff)
       goto leave;
 
   /*
@@ -1255,20 +1263,22 @@
 	  stabstrsect = i;
     }
 
-  if( stabsect == -1 || stabstrsect == -1 )
-      goto leave;
+  if( stabsect == -1 || stabstrsect == -1 ) {
+    DEBUG_Printf(DBG_CHN_WARN, "no .stab section\n");
+    goto leave;
+  }
 
   /*
    * OK, now just parse all of the stabs.
    */
-  rtn = DEBUG_ParseStabs(addr, load_offset, 
-			 spnt[stabsect].sh_offset,
-			 spnt[stabsect].sh_size,
-			 spnt[stabstrsect].sh_offset,
-			 spnt[stabstrsect].sh_size);
-
-  if( rtn != TRUE )
-      goto leave;
+  if (!(rtn = DEBUG_ParseStabs(addr, load_offset, 
+			       spnt[stabsect].sh_offset,
+			       spnt[stabsect].sh_size,
+			       spnt[stabstrsect].sh_offset,
+			       spnt[stabstrsect].sh_size))) {
+    DEBUG_Printf(DBG_CHN_WARN, "bad stabs\n");
+    goto leave;
+  }
 
   for(i=0; i < nsect; i++)
     {
@@ -1285,22 +1295,17 @@
 
 leave:
 
-  if( addr != (char *) 0xffffffff )
-      munmap(addr, statbuf.st_size);
+  if (addr != (char*)0xffffffff)
+    munmap(addr, statbuf.st_size);
 
-  if( fd != -1 )
-      close(fd);
+  if (fd != -1) close(fd);
 
-  return (rtn);
-
+  return rtn;
 }
 
 int
-DEBUG_ReadExecutableDbgInfo(void)
+DEBUG_ReadExecutableDbgInfo(const char* exe_name)
 {
-  const char	      * exe_name;
-  DBG_VALUE		val;
-  u_long		dyn_addr;
   Elf32_Dyn		dyn;
   struct r_debug        dbg_hdr;
   u_long		lm_addr;
@@ -1308,9 +1313,7 @@
   Elf32_Ehdr	        ehdr;
   char			bufstr[256];
   int			rtn = FALSE;
-  int                   rowcount;
-
-  exe_name = argv0;
+  DBG_VALUE		val;
 
   /*
    * Make sure we can stat and open this file.
@@ -1319,19 +1322,20 @@
       goto leave;
 
   fprintf( stderr, "Loading symbols: %s", exe_name );
-  rowcount = 17 + strlen(exe_name);
   DEBUG_ProcessElfObject(exe_name, 0);
 
+  /* previous step should have loaded symbol _DYNAMIC if it exists inside 
+   * the main executable
+   */
   if (!DEBUG_GetSymbolValue("_DYNAMIC", -1, &val, FALSE)) {
     fprintf(stderr, "Can't find symbol _DYNAMIC\n");
     goto leave;
   }
-  dyn_addr = val.addr.off;
 
   do {
-    if (!DEBUG_READ_MEM_VERBOSE((void*)dyn_addr, &dyn, sizeof(dyn)))
+    if (!DEBUG_READ_MEM_VERBOSE((void*)val.addr.off, &dyn, sizeof(dyn)))
       goto leave;
-    dyn_addr += sizeof(dyn);
+    val.addr.off += sizeof(dyn);
   } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
   if (dyn.d_tag == DT_NULL) goto leave;
 
@@ -1351,124 +1355,34 @@
     {
       if (!DEBUG_READ_MEM_VERBOSE((void*)lm_addr, &lm, sizeof(lm)))
 	goto leave;
-      if (!DEBUG_READ_MEM_VERBOSE((void*)lm.l_addr, &ehdr, sizeof(ehdr)))
-	continue;
-      /*
-       * We already got the stuff for the executable using the
-       * argv[0] entry above.  Here we only need to concentrate on any
-       * shared libraries which may be loaded.
-       */
-      if( (lm.l_addr == 0) || (ehdr.e_type != ET_DYN) )
-	  continue;
-
-      if( lm.l_name != NULL )
-      {
-	  if (!DEBUG_READ_MEM_VERBOSE(lm.l_name, bufstr, sizeof(bufstr)))
-	    continue;
-	  bufstr[sizeof(bufstr) - 1] = '\0';
-          if (rowcount + strlen(bufstr) > 76)
-          {
-              fprintf( stderr, "\n   " );
-              rowcount = 3;
-          }
-          fprintf( stderr, " %s", bufstr );
-          rowcount += strlen(bufstr) + 1;
-	  DEBUG_ProcessElfObject(bufstr, lm.l_addr);
+      if (lm.l_addr != 0 &&
+	  DEBUG_READ_MEM_VERBOSE((void*)lm.l_addr, &ehdr, sizeof(ehdr)) &&
+	  ehdr.e_type == ET_DYN && /* only look at dynamic modules */
+	  lm.l_name != NULL &&
+	  DEBUG_READ_MEM_VERBOSE(lm.l_name, bufstr, sizeof(bufstr))) {
+	bufstr[sizeof(bufstr) - 1] = '\0';
+	DEBUG_ProcessElfObject(bufstr, lm.l_addr);
       }
     }
-
+  
   rtn = TRUE;
 
 leave:
-  fprintf( stderr, "\n" );
-  return (rtn);
-
+  return rtn;
 }
 
 #else	/* !__ELF__ */
 
-#ifdef linux
-/*
- * a.out linux.
- */
+int
+DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
+{
+  return FALSE;
+}
+
 int
 DEBUG_ReadExecutableDbgInfo(void)
 {
-  char		      * addr = (char *) 0xffffffff;
-  char		      * exe_name;
-  struct exec	      * ahdr;
-  int			fd = -1;
-  int			rtn = FALSE;
-  unsigned int		staboff;
-  struct stat		statbuf;
-  int			status;
-  unsigned int		stroff;
-
-  exe_name = argv0;
-
-  /*
-   * Make sure we can stat and open this file.
-   */
-  if( exe_name == NULL )
-      goto leave;
-
-  status = stat(exe_name, &statbuf);
-  if( status == -1 )
-      goto leave;
-
-  /*
-   * Now open the file, so that we can mmap() it.
-   */
-  fd = open(exe_name, O_RDONLY);
-  if( fd == -1 )
-      goto leave;
-
-
-  /*
-   * Now mmap() the file.
-   */
-  addr = mmap(0, statbuf.st_size, PROT_READ, 
-	      MAP_PRIVATE, fd, 0);
-  if( addr == (char *) 0xffffffff )
-      goto leave;
-
-  ahdr = (struct exec *) addr;
-
-  staboff = N_SYMOFF(*ahdr);
-  stroff = N_STROFF(*ahdr);
-  rtn = DEBUG_ParseStabs(addr, 0, 
-			 staboff, 
-			 ahdr->a_syms,
-			 stroff,
-			 statbuf.st_size - stroff);
-
-  /*
-   * Give a nice status message here...
-   */
-  fprintf( stderr, "Loading symbols: %s", exe_name );
-
-  rtn = TRUE;
-
-leave:
-
-  if( addr != (char *) 0xffffffff )
-      munmap(addr, statbuf.st_size);
-
-  if( fd != -1 )
-      close(fd);
-
-  return (rtn);
-
+  return FALSE;
 }
-#else
-/*
- * Non-linux, non-ELF platforms.
- */
-int
-DEBUG_ReadExecutableDbgInfo(void)
-{
-return FALSE;
-}
-#endif
 
 #endif  /* __ELF__ */
diff --git a/debugger/stack.c b/debugger/stack.c
index 07f2a95..1b0935d 100644
--- a/debugger/stack.c
+++ b/debugger/stack.c
@@ -64,7 +64,7 @@
     value.addr.seg = DEBUG_context.SegSs;
     value.addr.off = DEBUG_context.Esp;
 
-    fprintf(stderr,"Stack dump:\n");
+    DEBUG_Printf(DBG_CHN_MESG,"Stack dump:\n");
     switch (DEBUG_GetSelectorType(value.addr.seg)) {
     case 32: /* 32-bit mode */
        DEBUG_ExamineMemory( &value, 24, 'x' );
@@ -74,9 +74,9 @@
         DEBUG_ExamineMemory( &value, 24, 'w' );
 	break;
     default:
-       fprintf(stderr, "Bad segment (%ld)\n", value.addr.seg);
+       DEBUG_Printf(DBG_CHN_MESG, "Bad segment (%ld)\n", value.addr.seg);
     }
-    fprintf(stderr,"\n");
+    DEBUG_Printf(DBG_CHN_MESG,"\n");
 #endif
 }
 
@@ -87,7 +87,7 @@
     frames = (struct bt_info *)DBG_realloc(frames,
 					   nframe*sizeof(struct bt_info));
     if (noisy)
-      fprintf(stderr,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
+      DEBUG_Printf(DBG_CHN_MESG,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
               frameno);
     frames[theframe].cs = code->seg;
     frames[theframe].eip = code->off;
@@ -101,7 +101,7 @@
     frames[theframe].ss = stack->seg;
     frames[theframe].ebp = stack->off;
     if (noisy) {
-      fprintf( stderr, (bits == 16) ? " (bp=%04lx)\n" : " (ebp=%08lx)\n", stack->off );
+      DEBUG_Printf( DBG_CHN_MESG, (bits == 16) ? " (bp=%04lx)\n" : " (ebp=%08lx)\n", stack->off );
     }
 }
 
@@ -115,11 +115,7 @@
     if (!p) return FALSE;
     
     if (!DEBUG_READ_MEM(p, &frame, sizeof(frame))) {
-        if (noisy) {
-	    fprintf(stderr,"*** Invalid address ");
-	    DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, FALSE);
-	    fprintf(stderr,"\n");
-	}
+        if (noisy) DEBUG_InvalAddr(addr);
 	return FALSE;
     }
     if (!frame.bp) return FALSE;
@@ -127,8 +123,8 @@
     frames = (struct bt_info *)DBG_realloc(frames,
 					   nframe*sizeof(struct bt_info));
     if (noisy)
-        fprintf(stderr,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
-		frameno);
+        DEBUG_Printf(DBG_CHN_MESG,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
+		     frameno);
     if (frame.bp & 1) *cs = frame.cs;
     else {
         /* not explicitly marked as far call,
@@ -156,11 +152,11 @@
     frames[theframe].ss = addr->seg = ss;
     frames[theframe].ebp = addr->off = frame.bp & ~1;
     if (noisy) {
-        fprintf( stderr, " (bp=%04lx", addr->off );
+        DEBUG_Printf( DBG_CHN_MESG, " (bp=%04lx", addr->off );
         if (possible_cs) {
-	    fprintf( stderr, ", far call assumed" );
+	    DEBUG_Printf( DBG_CHN_MESG, ", far call assumed" );
 	}
-	fprintf( stderr, ")\n" );
+	DEBUG_Printf( DBG_CHN_MESG, ")\n" );
     }
     return TRUE;
 }
@@ -175,11 +171,7 @@
     if (!p) return FALSE;
     
     if (!DEBUG_READ_MEM(p, &frame, sizeof(frame))) {
-       if (noisy) {
-	  fprintf(stderr,"*** Invalid address ");
-	  DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, FALSE);
-	  fprintf(stderr,"\n");
-       }
+       if (noisy) DEBUG_InvalAddr(addr);
        return FALSE;
     }
     if (!frame.ip) return FALSE;
@@ -188,8 +180,8 @@
     frames = (struct bt_info *)DBG_realloc(frames,
 					   nframe*sizeof(struct bt_info));
     if (noisy)
-       fprintf(stderr,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
-	       frameno);
+       DEBUG_Printf(DBG_CHN_MESG,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
+		    frameno);
     frames[theframe].cs = addr->seg = *cs;
     frames[theframe].eip = addr->off = frame.ip;
     if (noisy)
@@ -199,7 +191,7 @@
         DEBUG_FindNearestSymbol( addr, TRUE, 
 				 &frames[theframe].frame.sym, frame.bp, 
 				 &frames[theframe].frame.list);
-    if (noisy) fprintf( stderr, " (ebp=%08lx)\n", frame.bp );
+    if (noisy) DEBUG_Printf( DBG_CHN_MESG, " (ebp=%08lx)\n", frame.bp );
     frames[theframe].ss = addr->seg = ss;
     frames[theframe].ebp = frame.bp;
     if (addr->off == frame.bp) return FALSE;
@@ -226,13 +218,13 @@
     STACK32FRAME       	frame32;
     char		ch;
 
-    if (noisy) fprintf( stderr, "Backtrace:\n" );
+    if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Backtrace:\n" );
 
     nframe = 1;
     if (frames) DBG_free( frames );
     frames = (struct bt_info *) DBG_alloc( sizeof(struct bt_info) );
     if (noisy)
-        fprintf(stderr,"%s%d ",(curr_frame == 0 ? "=>" : "  "), frameno);
+        DEBUG_Printf(DBG_CHN_MESG,"%s%d ",(curr_frame == 0 ? "=>" : "  "), frameno);
 
     if (DEBUG_IsSelectorSystem(ss)) ss = 0;
     if (DEBUG_IsSelectorSystem(cs)) cs = 0;
@@ -250,7 +242,7 @@
 				     &frames[0].frame.list);
         frames[0].ss = addr.seg = ss;
 	frames[0].ebp = addr.off = DEBUG_context.Ebp;
-        if (noisy) fprintf( stderr, " (ebp=%08x)\n", frames[0].ebp );
+        if (noisy) DEBUG_Printf( DBG_CHN_MESG, " (ebp=%08x)\n", frames[0].ebp );
         is16 = FALSE;
 	break;
     case 16:
@@ -263,11 +255,11 @@
 				     &frames[0].frame.list);
         frames[0].ss = addr.seg = ss;
 	frames[0].ebp = addr.off = LOWORD(DEBUG_context.Ebp);
-        if (noisy) fprintf( stderr, " (bp=%04x)\n", frames[0].ebp );
+        if (noisy) DEBUG_Printf( DBG_CHN_MESG, " (bp=%04x)\n", frames[0].ebp );
         is16 = TRUE;
 	break;
     default:
-        if (noisy) fprintf( stderr, "Bad segment '%u'\n", ss);
+        if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad segment '%u'\n", ss);
 	return;
     }
 
@@ -276,14 +268,14 @@
      */
     cur_switch = (DWORD)DEBUG_CurrThread->teb + OFFSET_OF(TEB, cur_stack);
     if (!DEBUG_READ_MEM((void*)cur_switch, &next_switch, sizeof(next_switch))) {
-        if (noisy) fprintf( stderr, "Can't read TEB:cur_stack\n");
+        if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Can't read TEB:cur_stack\n");
 	return;
     }
 
     if (is16) {
         if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) {
-	    if (noisy) fprintf( stderr, "Bad stack frame %p\n", 
-				(STACK32FRAME*)next_switch );
+	    if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad stack frame %p\n", 
+				     (STACK32FRAME*)next_switch );
 	    return;
 	}
 	cur_switch = (DWORD)frame32.frame16;
@@ -295,7 +287,7 @@
 	p = DEBUG_ToLinear(&tmp);
 	
 	if (!DEBUG_READ_MEM((void*)p, &frame16, sizeof(STACK16FRAME))) {
-	    if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK16FRAME*)p );
+	    if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad stack frame %p\n", (STACK16FRAME*)p );
 	    return;
 	}
 	cur_switch = (DWORD)frame16.frame32;
@@ -315,7 +307,7 @@
 	   if (is16) {
 	      
 	       if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) {
-		  if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK32FRAME*)next_switch );
+		  if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad stack frame %p\n", (STACK32FRAME*)next_switch );
 		  return;
 	       }
 
@@ -333,8 +325,8 @@
 	       p = DEBUG_ToLinear(&tmp);
 	       
 	       if (!DEBUG_READ_MEM((void*)p, &frame16, sizeof(STACK16FRAME))) {
-		   if (noisy) fprintf( stderr, "Bad stack frame %p\n", 
-				       (STACK16FRAME*)p );
+		   if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad stack frame %p\n", 
+					    (STACK16FRAME*)p );
 		   return;
 	       }
 	       cur_switch = (DWORD)frame16.frame32;
@@ -348,8 +340,8 @@
 	      p = DEBUG_ToLinear(&tmp);
 	      
 	      if (!DEBUG_READ_MEM((void*)p, &frame16, sizeof(STACK16FRAME))) {
-		  if (noisy) fprintf( stderr, "Bad stack frame %p\n",
-				      (STACK16FRAME*)p );
+		  if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad stack frame %p\n",
+					   (STACK16FRAME*)p );
 		  return;
 	      }
 	      
@@ -363,8 +355,8 @@
 	      
 	      next_switch = cur_switch;
 	      if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) {
-		 if (noisy) fprintf( stderr, "Bad stack frame %p\n", 
-				     (STACK32FRAME*)next_switch );
+		 if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Bad stack frame %p\n", 
+					  (STACK32FRAME*)next_switch );
 		 return;
 	      }
 	      cur_switch = (DWORD)frame32.frame16;
@@ -383,7 +375,7 @@
 	      : DEBUG_Frame32( &addr, &cs, ++frameno, noisy);
 	}
     }
-    if (noisy) fprintf( stderr, "\n" );
+    if (noisy) DEBUG_Printf( DBG_CHN_MESG, "\n" );
 #endif
 }
 
diff --git a/debugger/types.c b/debugger/types.c
index 64f1290..f200c99 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -794,7 +794,7 @@
 
   if (count != 1)
     {
-      fprintf( stderr, "Count other than 1 is meaningless in 'print' command\n" );
+      DEBUG_Printf( DBG_CHN_MESG, "Count other than 1 is meaningless in 'print' command\n" );
       return;
     }
   
@@ -802,8 +802,8 @@
   {
       /* No type, just print the addr value */
       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 );
+          DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%04lx: ", value->addr.seg );
+      DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", value->addr.off );
       goto leave;
   }
   
@@ -814,13 +814,13 @@
 
   if( DEBUG_nchar > DEBUG_maxchar )
     {
-      fprintf(stderr, "...");
+      DEBUG_Printf(DBG_CHN_MESG, "...");
       goto leave;
     }
 
   if( format == 'i' || format == 's' || format == 'w' || format == 'b' )
     {
-      fprintf( stderr, "Format specifier '%c' is meaningless in 'print' command\n", format );
+      DEBUG_Printf( DBG_CHN_MESG, "Format specifier '%c' is meaningless in 'print' command\n", format );
       format = '\0';
     }
 
@@ -833,24 +833,24 @@
       DEBUG_PrintBasic(value, 1, format);
       break;
     case DT_STRUCT:
-      DEBUG_nchar += fprintf(stderr, "{");
+      DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "{");
       for(m = value->type->un.structure.members; m; m = m->next)
 	{
 	  val1 = *value;
 	  DEBUG_FindStructElement(&val1, m->name, &xval);
-	  DEBUG_nchar += fprintf(stderr, "%s=", m->name);
+	  DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%s=", m->name);
 	  DEBUG_Print(&val1, 1, format, level + 1);
 	  if( m->next != NULL )
 	    {
-	      DEBUG_nchar += fprintf(stderr, ", ");
+	      DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, ", ");
 	    }
 	  if( DEBUG_nchar > DEBUG_maxchar )
 	    {
-	      fprintf(stderr, "...}");
+	      DEBUG_Printf(DBG_CHN_MESG, "...}");
 	      goto leave;
 	    }
 	}
-      DEBUG_nchar += fprintf(stderr, "}");
+      DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "}");
       break;
     case DT_ARRAY:
       /*
@@ -863,38 +863,38 @@
 	   * Special handling for character arrays.
 	   */
 	  pnt = (char *) value->addr.off;
-	  DEBUG_nchar += fprintf(stderr, "\"");
+	  DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "\"");
 	  for( i=value->type->un.array.start; i < value->type->un.array.end; i++ )
 	    {
 	      fputc(*pnt++, stderr);
 	      DEBUG_nchar++;
 	      if( DEBUG_nchar > DEBUG_maxchar )
 		{
-		  fprintf(stderr, "...\"");
+		  DEBUG_Printf(DBG_CHN_MESG, "...\"");
 		  goto leave;
 		}
 	    }
-	  DEBUG_nchar += fprintf(stderr, "\"");
+	  DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "\"");
 	  break;
 	}
       val1 = *value;
       val1.type = value->type->un.array.basictype;
-      DEBUG_nchar += fprintf(stderr, "{");
+      DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "{");
       for( i=value->type->un.array.start; i <= value->type->un.array.end; i++ )
 	{
 	  DEBUG_Print(&val1, 1, format, level + 1);
 	  val1.addr.off += size;
 	  if( i == value->type->un.array.end )
 	    {
-	      DEBUG_nchar += fprintf(stderr, "}");
+	      DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "}");
 	    }
 	  else
 	    {
-	      DEBUG_nchar += fprintf(stderr, ", ");
+	      DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, ", ");
 	    }
 	  if( DEBUG_nchar > DEBUG_maxchar )
 	    {
-	      fprintf(stderr, "...}");
+	      DEBUG_Printf(DBG_CHN_MESG, "...}");
 	      goto leave;
 	    }
 	}
@@ -908,7 +908,7 @@
 
   if( level == 0 )
     {
-      DEBUG_nchar += fprintf(stderr, "\n");
+      DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "\n");
     }
   return;
 }
@@ -935,11 +935,11 @@
 	  switch(dt->type)
 	    {
 	    case DT_BASIC:
-	      fprintf(stderr, "0x%p - BASIC(%s)\n",
+	      DEBUG_Printf(DBG_CHN_MESG, "0x%p - BASIC(%s)\n",
 		      dt, name);
 	      break;
 	    case DT_POINTER:
-	      fprintf(stderr, "0x%p - POINTER(%s)(%p)\n",
+	      DEBUG_Printf(DBG_CHN_MESG, "0x%p - POINTER(%s)(%p)\n",
 		      dt, name, dt->un.pointer.pointsto);
 	      break;
 	    case DT_STRUCT:
@@ -954,27 +954,26 @@
 		      nm++;
 		    }
 		}
-	      fprintf(stderr, "0x%p - STRUCT(%s) %d %d %s\n", dt, name,
-		      dt->un.structure.size, nm, member_name);
+	      DEBUG_Printf(DBG_CHN_MESG, "0x%p - STRUCT(%s) %d %d %s\n", dt, name,
+			   dt->un.structure.size, nm, member_name);
 	      break;
 	    case DT_ARRAY:
-	      fprintf(stderr, "0x%p - ARRAY(%s)(%p)\n",
-		      dt, name, dt->un.array.basictype);
+	      DEBUG_Printf(DBG_CHN_MESG, "0x%p - ARRAY(%s)(%p)\n",
+			   dt, name, dt->un.array.basictype);
 	      break;
 	    case DT_ENUM:
-	      fprintf(stderr, "0x%p - ENUM(%s)\n",
-		      dt, name);
+	      DEBUG_Printf(DBG_CHN_MESG, "0x%p - ENUM(%s)\n", dt, name);
 	      break;
 	    case DT_BITFIELD:
-	      fprintf(stderr, "0x%p - BITFIELD(%s)\n", dt, name);
+	      DEBUG_Printf(DBG_CHN_MESG, "0x%p - BITFIELD(%s)\n", dt, name);
 	      break;
 	    case DT_FUNC:
-	      fprintf(stderr, "0x%p - FUNC(%s)(%p)\n",
-		      dt, name, dt->un.funct.rettype);
+	      DEBUG_Printf(DBG_CHN_MESG, "0x%p - FUNC(%s)(%p)\n",
+			   dt, name, dt->un.funct.rettype);
 	      break;
 	    case DT_CONST:
 	    case DT_TYPEDEF:
-	      fprintf(stderr, "What???\n");
+	      DEBUG_Printf(DBG_CHN_MESG, "What???\n");
 	      break;
 	    }
 	}
@@ -1025,31 +1024,31 @@
   switch(dt->type)
     {
     case DT_BASIC:
-      fprintf(stderr, "%s", name);
+      DEBUG_Printf(DBG_CHN_MESG, "%s", name);
       break;
     case DT_POINTER:
       DEBUG_PrintTypeCast(dt->un.pointer.pointsto);
-      fprintf(stderr, "*");
+      DEBUG_Printf(DBG_CHN_MESG, "*");
       break;
     case DT_STRUCT:
-      fprintf(stderr, "struct %s", name);
+      DEBUG_Printf(DBG_CHN_MESG, "struct %s", name);
       break;
     case DT_ARRAY:
-      fprintf(stderr, "%s[]", name);
+      DEBUG_Printf(DBG_CHN_MESG, "%s[]", name);
       break;
     case DT_ENUM:
-      fprintf(stderr, "enum %s", name);
+      DEBUG_Printf(DBG_CHN_MESG, "enum %s", name);
       break;
     case DT_BITFIELD:
-      fprintf(stderr, "unsigned %s", name);
+      DEBUG_Printf(DBG_CHN_MESG, "unsigned %s", name);
       break;
     case DT_FUNC:
       DEBUG_PrintTypeCast(dt->un.funct.rettype);
-      fprintf(stderr, "(*%s)()", name);
+      DEBUG_Printf(DBG_CHN_MESG, "(*%s)()", name);
       break;
     case DT_CONST:
     case DT_TYPEDEF:
-      fprintf(stderr, "What???\n");
+      DEBUG_Printf(DBG_CHN_MESG, "What???\n");
       break;
     }
 
@@ -1062,12 +1061,12 @@
 
    if (!value->type) 
    {
-      fprintf(stderr, "Unknown type\n");
+      DEBUG_Printf(DBG_CHN_MESG, "Unknown type\n");
       return FALSE;
    }
    if (!DEBUG_PrintTypeCast(value->type))
       return FALSE;
-   fprintf(stderr, "\n");
+   DEBUG_Printf(DBG_CHN_MESG, "\n");
    return TRUE;
 }
 
diff --git a/debugger/winedbg.c b/debugger/winedbg.c
index be37c11..0bdc6d5 100644
--- a/debugger/winedbg.c
+++ b/debugger/winedbg.c
@@ -7,7 +7,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <sys/stat.h>
+#include <string.h>
 #include "debugger.h"
 
 #include "thread.h"
@@ -16,21 +16,39 @@
 #include "winuser.h"
 
 #include "winreg.h"
-#include "debugtools.h"
-#include "options.h"
 
 #ifdef DBG_need_heap
 HANDLE dbg_heap = 0;
 #endif
 
-DEFAULT_DEBUG_CHANNEL(winedbg);
-    
 DBG_PROCESS*	DEBUG_CurrProcess = NULL;
 DBG_THREAD*	DEBUG_CurrThread = NULL;
 CONTEXT		DEBUG_context;
 
 static DBG_PROCESS* proc = NULL;
-static BOOL bBreakAllThreads = FALSE;
+
+/* build internal vars table */
+#define  INTERNAL_VAR(_var,_val) int DBG_IVAR(_var) = _val;
+#include "intvar.h"
+#undef   INTERNAL_VAR
+
+int	DEBUG_Printf(int chn, const char* format, ...)
+{
+    char	buf[1024];
+    va_list 	valist;
+
+    va_start(valist, format);
+    vsprintf(buf, format, valist);
+    va_end(valist);
+#if 0
+    if (DBG_IVAR(ChannelMask) & chn)
+	WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, strlen(buf), NULL, NULL);
+    if (chn == DBG_CHN_MESG) fwrite(buf, strlen(buf), 1, stderr);
+#else
+    if (DBG_IVAR(ChannelMask) & chn) fwrite(buf, strlen(buf), 1, stderr); 
+#endif
+    return strlen(buf);
+}
 
 static	BOOL DEBUG_Init(void)
 {
@@ -39,10 +57,12 @@
     DWORD	val;
     DWORD 	count = sizeof(val);
 
-    if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) {
-	if (!RegQueryValueExA(hkey, "BreakAllThreadsStartup", 0, &type, (LPSTR)&val, &count)) {
-	    bBreakAllThreads = val;
-	}
+    if (!RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) {
+#define  INTERNAL_VAR(_var,_val) \
+ 	if (!RegQueryValueEx(hkey, #_var, 0, &type, (LPSTR)&val, &count)) \
+	    DBG_IVAR(_var) = val;
+#include "intvar.h"
+#undef   INTERNAL_VAR
 	RegCloseKey(hkey);
     }
     return TRUE;
@@ -51,7 +71,7 @@
 static WINE_EXCEPTION_FILTER(wine_dbg)
 {
     DEBUG_ExternalDebugger();
-    fprintf(stderr, "\nwine_dbg: Exception %lx\n", GetExceptionCode());
+    DEBUG_Printf(DBG_CHN_MESG, "\nwine_dbg: Exception %lx\n", GetExceptionCode());
     return EXCEPTION_EXECUTE_HANDLER;
 }
 
@@ -88,7 +108,7 @@
 static	void			DEBUG_DelProcess(DBG_PROCESS* p)
 {
     if (p->threads != NULL) {
-	ERR("Shouldn't happen\n");
+	DEBUG_Printf(DBG_CHN_ERR, "Shouldn't happen\n");
 	while (p->threads) DEBUG_DelThread(p->threads);
     }
     if (p->prev) p->prev->next = p->next;
@@ -110,42 +130,7 @@
      * Initialize the type handling stuff.
      */
     DEBUG_InitTypes();
-    DEBUG_InitCVDataTypes();
-    
-    /*
-     * In some cases we can read the stabs information directly
-     * from the executable.  If this is the case, we don't need
-     * to bother with trying to read a symbol file, as the stabs
-     * also have line number and local variable information.
-     * As long as gcc is used for the compiler, stabs will
-     * be the default.  On SVr4, DWARF could be used, but we
-     * don't grok that yet, and in this case we fall back to using
-     * the wine.sym file.
-     */
-    if( DEBUG_ReadExecutableDbgInfo() == FALSE )
-    {
-	char*		symfilename = "wine.sym";
-	struct stat	statbuf;
-	HKEY 		hWineConf, hkey;
-	DWORD 		count;
-	char 		symbolTableFile[256];
-	
-	if (-1 == stat(symfilename, &statbuf) )
-	    symfilename = LIBDIR "wine.sym";
-	
-	strcpy(symbolTableFile, symfilename);
-	if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config", &hWineConf)) {
-	    if (!RegOpenKeyA(hWineConf, "wine", &hkey)) {
-		count = sizeof(symbolTableFile);
-		RegQueryValueA(hkey, "SymbolTableFile", symbolTableFile, &count);
-		RegCloseKey(hkey);
-	    }
-	    RegCloseKey(hWineConf);
-	}
-	DEBUG_ReadSymbolTable(symbolTableFile);
-    }
-    DEBUG_LoadEntryPoints(NULL);
-    DEBUG_ProcessDeferredDebug();
+    DEBUG_InitCVDataTypes();    
 }
 
 static BOOL DEBUG_ProcessGetString(char* buffer, int size, HANDLE hp, LPSTR addr)
@@ -206,10 +191,9 @@
 
 static	void			DEBUG_InitCurrThread(void)
 {
-    if (!Options.debug) return;
-
     if (DEBUG_CurrThread->start) {
-	if (DEBUG_CurrThread->process->num_threads == 1 || bBreakAllThreads) {
+	if (DEBUG_CurrThread->process->num_threads == 1 || 
+	    DBG_IVAR(BreakAllThreadsStartup)) {
 	    DBG_VALUE	value;
 	    
 	    DEBUG_SetBreakpoints(FALSE);
@@ -239,7 +223,9 @@
     BOOL	is_debug = FALSE;
     BOOL	ret;
 
-    if (first_chance && !Options.debug && !force ) return 0;  /* pass to app first */
+    /* FIXME: need for a configuration var ? */
+    /* pass to app first ??? */
+    /* if (first_chance && !force) return 0; */
 
     switch (rec->ExceptionCode)
     {
@@ -247,83 +233,80 @@
     case EXCEPTION_SINGLE_STEP:
         is_debug = TRUE;
         break;
-    case CONTROL_C_EXIT:
-        if (!Options.debug) DEBUG_Exit(0);
-        break;
     }
 
     if (!is_debug)
     {
         /* print some infos */
-        fprintf( stderr, "%s: ",
-                 first_chance ? "First chance exception" : "Unhandled exception" );
+        DEBUG_Printf( DBG_CHN_MESG, "%s: ",
+		      first_chance ? "First chance exception" : "Unhandled exception" );
         switch(rec->ExceptionCode)
         {
         case EXCEPTION_INT_DIVIDE_BY_ZERO:
-            fprintf( stderr, "divide by zero" );
+            DEBUG_Printf( DBG_CHN_MESG, "divide by zero" );
             break;
         case EXCEPTION_INT_OVERFLOW:
-            fprintf( stderr, "overflow" );
+            DEBUG_Printf( DBG_CHN_MESG, "overflow" );
             break;
         case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
-            fprintf( stderr, "array bounds " );
+            DEBUG_Printf( DBG_CHN_MESG, "array bounds " );
             break;
         case EXCEPTION_ILLEGAL_INSTRUCTION:
-            fprintf( stderr, "illegal instruction" );
+            DEBUG_Printf( DBG_CHN_MESG, "illegal instruction" );
             break;
         case EXCEPTION_STACK_OVERFLOW:
-            fprintf( stderr, "stack overflow" );
+            DEBUG_Printf( DBG_CHN_MESG, "stack overflow" );
             break;
         case EXCEPTION_PRIV_INSTRUCTION:
-            fprintf( stderr, "priviledged instruction" );
+            DEBUG_Printf( DBG_CHN_MESG, "priviledged instruction" );
             break;
         case EXCEPTION_ACCESS_VIOLATION:
             if (rec->NumberParameters == 2)
-                fprintf( stderr, "page fault on %s access to 0x%08lx", 
-                         rec->ExceptionInformation[0] ? "write" : "read",
-                         rec->ExceptionInformation[1] );
+                DEBUG_Printf( DBG_CHN_MESG, "page fault on %s access to 0x%08lx", 
+			      rec->ExceptionInformation[0] ? "write" : "read",
+			      rec->ExceptionInformation[1] );
             else
-                fprintf( stderr, "page fault" );
+                DEBUG_Printf( DBG_CHN_MESG, "page fault" );
             break;
         case EXCEPTION_DATATYPE_MISALIGNMENT:
-            fprintf( stderr, "Alignment" );
+            DEBUG_Printf( DBG_CHN_MESG, "Alignment" );
             break;
         case CONTROL_C_EXIT:
-            fprintf( stderr, "^C" );
+            DEBUG_Printf( DBG_CHN_MESG, "^C" );
             break;
         case EXCEPTION_CRITICAL_SECTION_WAIT:
-            fprintf( stderr, "critical section %08lx wait failed", 
-		     rec->ExceptionInformation[0] );
+            DEBUG_Printf( DBG_CHN_MESG, "critical section %08lx wait failed", 
+			  rec->ExceptionInformation[0] );
             break;
         default:
-            fprintf( stderr, "%08lx", rec->ExceptionCode );
+            DEBUG_Printf( DBG_CHN_MESG, "%08lx", rec->ExceptionCode );
             break;
         }
     }
 
-#if 1
-    fprintf(stderr, "Entering debugger 	PC=%lx EFL=%08lx mode=%d count=%d\n",
-	    DEBUG_context.Eip, DEBUG_context.EFlags, 
-	    DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
-#endif
+    DEBUG_Printf(DBG_CHN_TRACE, 
+		 "Entering debugger 	PC=%lx EFL=%08lx mode=%d count=%d\n",
+		 DEBUG_context.Eip, DEBUG_context.EFlags, 
+		 DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
 
     ret = DEBUG_Main( is_debug, force, rec->ExceptionCode );
-#if 1
-    fprintf(stderr, "Exiting debugger 	PC=%lx EFL=%08lx mode=%d count=%d\n",
-	    DEBUG_context.Eip, DEBUG_context.EFlags, 
-	    DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
-#endif
+
+    DEBUG_Printf(DBG_CHN_TRACE, 
+		 "Exiting debugger 	PC=%lx EFL=%08lx mode=%d count=%d\n",
+		 DEBUG_context.Eip, DEBUG_context.EFlags, 
+		 DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
 
     return ret;
 }
 
-static	DWORD	DEBUG_HandleDebugEvent(DEBUG_EVENT* de)
+static	BOOL	DEBUG_HandleDebugEvent(DEBUG_EVENT* de, LPDWORD cont)
 {
     char		buffer[256];
-    DWORD		cont;
+    BOOL		ret;
     
     __TRY {
-	cont = 0L;
+	ret = TRUE;
+	*cont = 0L;
 	
 	if ((DEBUG_CurrProcess = DEBUG_GetProcess(de->dwProcessId)) != NULL)
 	    DEBUG_CurrThread = DEBUG_GetThread(DEBUG_CurrProcess, de->dwThreadId);
@@ -332,45 +315,47 @@
 	
 	switch (de->dwDebugEventCode) {
 	case EXCEPTION_DEBUG_EVENT:
-	    if (!DEBUG_CurrThread) break;
+	    if (!DEBUG_CurrThread) {
+		DEBUG_Printf(DBG_CHN_ERR, "%08lx:%08lx: not a registered process or thread (perhaps a 16 bit one ?)\n",
+			     de->dwProcessId, de->dwThreadId);
+		break;
+	    }
 	    
-	    TRACE("%08lx:%08lx: exception code=%08lx %d\n", 
-		  de->dwProcessId, de->dwThreadId, 
-		  de->u.Exception.ExceptionRecord.ExceptionCode,
-		  DEBUG_CurrThread->wait_for_first_exception);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: exception code=%08lx %d\n", 
+			 de->dwProcessId, de->dwThreadId, 
+			 de->u.Exception.ExceptionRecord.ExceptionCode,
+			 DEBUG_CurrThread->wait_for_first_exception);
 	    
 	    DEBUG_context.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS|CONTEXT_DEBUG_REGISTERS;
 	    if (!GetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context)) {
-		WARN("Can't get thread's context\n");
+		DEBUG_Printf(DBG_CHN_WARN, "Can't get thread's context\n");
 		break;
 	    }
 	    
-	    TRACE("%p:%p\n", de->u.Exception.ExceptionRecord.ExceptionAddress, 
-		  (void*)DEBUG_context.Eip);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%p:%p\n", de->u.Exception.ExceptionRecord.ExceptionAddress, 
+			 (void*)DEBUG_context.Eip);
 	    
-	    cont = DEBUG_HandleException(&de->u.Exception.ExceptionRecord, 
-					 de->u.Exception.dwFirstChance, 
-					 DEBUG_CurrThread->wait_for_first_exception);
-	    
-	    if (DEBUG_CurrThread->wait_for_first_exception) {
+	    *cont = DEBUG_HandleException(&de->u.Exception.ExceptionRecord, 
+					  de->u.Exception.dwFirstChance, 
+					  DEBUG_CurrThread->wait_for_first_exception);
+	    if (DEBUG_CurrThread->dbg_exec_mode == EXEC_KILL) {
+		ret = FALSE;
+	    } else {
 		DEBUG_CurrThread->wait_for_first_exception = 0;
-#ifdef __i386__
-		DEBUG_context.Eip--;
-#endif
+		SetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context);
 	    }
-	    SetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context);
 	    break;
 	    
 	case CREATE_THREAD_DEBUG_EVENT:
-	    TRACE("%08lx:%08lx: create thread D @%p\n", de->dwProcessId, de->dwThreadId, 
-		  de->u.CreateThread.lpStartAddress);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: create thread D @%p\n", de->dwProcessId, de->dwThreadId, 
+			 de->u.CreateThread.lpStartAddress);
 	    
 	    if (DEBUG_CurrProcess == NULL) {
-		ERR("Unknown process\n");
+		DEBUG_Printf(DBG_CHN_ERR, "Unknown process\n");
 		break;
 	    }
 	    if (DEBUG_GetThread(DEBUG_CurrProcess, de->dwThreadId) != NULL) {
-		TRACE("Thread already listed, skipping\n");
+		DEBUG_Printf(DBG_CHN_TRACE, "Thread already listed, skipping\n");
 		break;
 	    }
 	    
@@ -380,7 +365,7 @@
 					       de->u.CreateThread.lpStartAddress, 
 					       de->u.CreateThread.lpThreadLocalBase);
 	    if (!DEBUG_CurrThread) {
-		ERR("Couldn't create thread\n");
+		DEBUG_Printf(DBG_CHN_ERR, "Couldn't create thread\n");
 		break;
 	    }
 	    DEBUG_InitCurrThread();
@@ -389,27 +374,30 @@
 	case CREATE_PROCESS_DEBUG_EVENT:
 	    DEBUG_ProcessGetStringIndirect(buffer, sizeof(buffer), 
                                            de->u.CreateProcessInfo.hProcess, 
-                                           de->u.LoadDll.lpImageName);
+                                           de->u.CreateProcessInfo.lpImageName);
 	    
 	    /* FIXME unicode ? de->u.CreateProcessInfo.fUnicode */
-	    TRACE("%08lx:%08lx: create process %s @%p\n", 
-		  de->dwProcessId, de->dwThreadId, 
-		  buffer,
-		  de->u.CreateProcessInfo.lpStartAddress);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: create process %s @%p (%ld<%ld>)\n", 
+			 de->dwProcessId, de->dwThreadId, 
+			 buffer,
+			 de->u.CreateProcessInfo.lpStartAddress,
+			 de->u.CreateProcessInfo.dwDebugInfoFileOffset,
+			 de->u.CreateProcessInfo.nDebugInfoSize);
 	    
 	    if (DEBUG_GetProcess(de->dwProcessId) != NULL) {
-		TRACE("Skipping already defined process\n");
+		DEBUG_Printf(DBG_CHN_TRACE, "Skipping already defined process\n");
 		break;
 	    }
 	    DEBUG_CurrProcess = DEBUG_AddProcess(de->dwProcessId,
 						 de->u.CreateProcessInfo.hProcess);
 	    if (DEBUG_CurrProcess == NULL) {
-		ERR("Unknown process\n");
+		DEBUG_Printf(DBG_CHN_ERR, "Unknown process\n");
 		break;
 	    }
 	    
-	    TRACE("%08lx:%08lx: create thread I @%p\n", de->dwProcessId, de->dwThreadId, 
-		  de->u.CreateProcessInfo.lpStartAddress);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: create thread I @%p\n", 
+			 de->dwProcessId, de->dwThreadId, 
+			 de->u.CreateProcessInfo.lpStartAddress);
 	    
 	    DEBUG_CurrThread = DEBUG_AddThread(DEBUG_CurrProcess, 	
 					       de->dwThreadId, 
@@ -417,25 +405,23 @@
 					       de->u.CreateProcessInfo.lpStartAddress, 
 					       de->u.CreateProcessInfo.lpThreadLocalBase);
 	    if (!DEBUG_CurrThread) {
-		ERR("Couldn't create thread\n");
+		DEBUG_Printf(DBG_CHN_ERR, "Couldn't create thread\n");
 		break;
 	    }
 	    
 	    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
+	    DEBUG_LoadModule32("<Debugged process>", de->u.CreateProcessInfo.hFile, 
+			       (DWORD)de->u.CreateProcessInfo.lpBaseOfImage);
 	    break;
 	    
 	case EXIT_THREAD_DEBUG_EVENT:
-	    TRACE("%08lx:%08lx: exit thread (%ld)\n", 
-		  de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: exit thread (%ld)\n", 
+			 de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
 	    
 	    if (DEBUG_CurrThread == NULL) {
-		ERR("Unknown thread\n");
+		DEBUG_Printf(DBG_CHN_ERR, "Unknown thread\n");
 		break;
 	    }
 	    /* FIXME: remove break point set on thread startup */
@@ -443,22 +429,24 @@
 	    break;
 	    
 	case EXIT_PROCESS_DEBUG_EVENT:
-	    TRACE("%08lx:%08lx: exit process (%ld)\n", 
-		  de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: exit process (%ld)\n", 
+			 de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode);
 	    
 	    if (DEBUG_CurrProcess == NULL) {
-		ERR("Unknown process\n");
+		DEBUG_Printf(DBG_CHN_ERR, "Unknown process\n");
 		break;
 	    }
+	    /* just in case */
+	    DEBUG_SetBreakpoints(FALSE);
 	    /* kill last thread */
 	    DEBUG_DelThread(DEBUG_CurrProcess->threads);
-	    /* FIXME: remove break point set on thread startup */
 	    DEBUG_DelProcess(DEBUG_CurrProcess);
+	    ret = FALSE;
 	    break;
 	    
 	case LOAD_DLL_DEBUG_EVENT:
 	    if (DEBUG_CurrThread == NULL) {
-		ERR("Unknown thread\n");
+		DEBUG_Printf(DBG_CHN_ERR, "Unknown thread\n");
 		break;
 	    }
 	    DEBUG_ProcessGetStringIndirect(buffer, sizeof(buffer), 
@@ -466,20 +454,23 @@
                                            de->u.LoadDll.lpImageName);
 	    
 	    /* FIXME unicode: de->u.LoadDll.fUnicode */
-	    TRACE("%08lx:%08lx: loads DLL %s @%p\n", de->dwProcessId, de->dwThreadId, 
-		  buffer, de->u.LoadDll.lpBaseOfDll);
-	    CharUpperA(buffer);
-	    DEBUG_LoadModule32( buffer, (DWORD)de->u.LoadDll.lpBaseOfDll);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: loads DLL %s @%p (%ld<%ld>)\n", 
+			 de->dwProcessId, de->dwThreadId, 
+			 buffer, de->u.LoadDll.lpBaseOfDll,
+			 de->u.LoadDll.dwDebugInfoFileOffset,
+			 de->u.LoadDll.nDebugInfoSize);
+	    CharUpper(buffer);
+	    DEBUG_LoadModule32(buffer, de->u.LoadDll.hFile, (DWORD)de->u.LoadDll.lpBaseOfDll);
 	    break;
 	    
 	case UNLOAD_DLL_DEBUG_EVENT:
-	    TRACE("%08lx:%08lx: unload DLL @%p\n", de->dwProcessId, de->dwThreadId, 
-		  de->u.UnloadDll.lpBaseOfDll);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: unload DLL @%p\n", de->dwProcessId, de->dwThreadId, 
+			 de->u.UnloadDll.lpBaseOfDll);
 	    break;
 	    
 	case OUTPUT_DEBUG_STRING_EVENT:
 	    if (DEBUG_CurrThread == NULL) {
-		ERR("Unknown thread\n");
+		DEBUG_Printf(DBG_CHN_ERR, "Unknown thread\n");
 		break;
 	    }
 	    
@@ -488,111 +479,119 @@
 				   de->u.DebugString.lpDebugStringData);
 	    
 	    /* fixme unicode de->u.DebugString.fUnicode ? */
-	    TRACE("%08lx:%08lx: output debug string (%s)\n", 
-		  de->dwProcessId, de->dwThreadId, 
-		  buffer);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: output debug string (%s)\n", 
+			 de->dwProcessId, de->dwThreadId, buffer);
 	    break;
 	    
 	case RIP_EVENT:
-	    TRACE("%08lx:%08lx: rip error=%ld type=%ld\n", 
-		  de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError, 
-		  de->u.RipInfo.dwType);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: rip error=%ld type=%ld\n", 
+			 de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError, 
+			 de->u.RipInfo.dwType);
 	    break;
 	    
 	default:
-	    TRACE("%08lx:%08lx: unknown event (%ld)\n", 
-		  de->dwProcessId, de->dwThreadId, de->dwDebugEventCode);
+	    DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: unknown event (%ld)\n", 
+			 de->dwProcessId, de->dwThreadId, de->dwDebugEventCode);
 	}
 	
     } __EXCEPT(wine_dbg) {
-	cont = 0;
+	*cont = 0;
+	ret = TRUE;
     }
     __ENDTRY;
 
-    return cont;
+    return ret;
 }
 
 static	DWORD	CALLBACK	DEBUG_MainLoop(DWORD pid)
 {
     DEBUG_EVENT		de;
     DWORD		cont;
+    BOOL		ret = TRUE;
 
+    DEBUG_Printf(DBG_CHN_MESG, " on pid %ld\n", pid);
+    
     DEBUG_Init();
 
-    while (WaitForDebugEvent(&de, INFINITE)) {
-	cont = DEBUG_HandleDebugEvent(&de);
+    while (ret && WaitForDebugEvent(&de, INFINITE)) {
+	ret = DEBUG_HandleDebugEvent(&de, &cont);
 	ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
     }
     
-    TRACE("WineDbg terminated on pid %ld\n", pid);
+    DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %ld\n", pid);
     
-    return 0L;
+    ExitProcess(0);
 }
 
-static	DWORD	CALLBACK	DEBUG_StarterFromPID(LPVOID pid)
+int PASCAL WinMain(HINSTANCE hInst, HINSTANCE prev, LPSTR _cmdline, int show)
 {
-    TRACE("WineDbg started on pid %ld\n", (DWORD)pid);
-    
-    if (!DebugActiveProcess((DWORD)pid)) {
-	TRACE("Can't debug process %ld: %ld\n", (DWORD)pid, GetLastError());
-	return 0;
+    char*		argv[5];
+    char*		cmdline = strdup(_cmdline);
+    char*		ptr = cmdline;
+    int			instr = FALSE;
+    int			argc = 0;
+
+    while ((*ptr == ' ' || *ptr == '\t') && *ptr != 0) ptr++;
+    argv[argc++] = ptr;
+    for (; *ptr; ptr++) {
+	if ((*ptr == ' ' || *ptr == '\t') && !instr) {
+	    *ptr++ = 0;
+	    while (*ptr == ' ' || *ptr == '\t') ptr++;
+	    if (*ptr) argv[argc++] = ptr;
+	    if (argc >= sizeof(argv) / sizeof(argv[0])) return 0;
+	} else if (*ptr == '"') {
+	    instr = !instr;
+	}
     }
-    return DEBUG_MainLoop((DWORD)pid);
-}
 
-void	DEBUG_Attach(DWORD pid)
-{
-    CreateThread(NULL, 0, DEBUG_StarterFromPID, (LPVOID)pid, 0, NULL);
-}
-
-struct dsfcl {
-    HANDLE	hEvent;
-    LPSTR	lpCmdLine;
-    int		showWindow;
-    DWORD	error;
-};
-
-static	DWORD	CALLBACK	DEBUG_StarterFromCmdLine(LPVOID p)
-{
-    PROCESS_INFORMATION	info;
-    STARTUPINFOA	startup;
-    BOOL		ok = TRUE;
-
-    memset(&startup, 0, sizeof(startup));
-    startup.cb = sizeof(startup);
-    startup.dwFlags = STARTF_USESHOWWINDOW;
-    startup.wShowWindow = ((struct dsfcl*)p)->showWindow;
-
-    /* any value >= 32 will do, simulate a correct handle value */
-    ((struct dsfcl*)p)->error = 0xFFFFFFFF;
-    if (!CreateProcessA(NULL, ((struct dsfcl*)p)->lpCmdLine, NULL, NULL, 
-			FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
-	((struct dsfcl*)p)->error = GetLastError();
-	ok = FALSE;
+#if 0
+    /* would require to change .spec with a cuiexe type */
+    /* keep it as a guiexe for now, so that Wine won't touch the Unix stdin, 
+     * stdout and stderr streams
+     */
+    if (1 /*DBG_IVAR(UseXterm)*/) {
+	COORD		pos;
+	
+	/* This is a hack: it forces creation of an xterm, not done by default */
+	pos.x = 0; pos.y = 1;
+	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
     }
-    SetEvent(((struct dsfcl*)p)->hEvent);
-    if (ok) DEBUG_MainLoop(info.dwProcessId);
+#endif
 
+    DEBUG_Printf(DBG_CHN_MESG, "Starting WineDbg... ");
+    if (argc == 2) {
+	DWORD	pid = atoi(argv[0]);
+	HANDLE	hEvent = atoi(argv[1]);
+
+	if (pid != 0 && hEvent != 0) {
+	    free(cmdline);
+
+	    if (!DebugActiveProcess(pid)) {
+		DEBUG_Printf(DBG_CHN_ERR, "Can't attach process %ld: %ld\n", 
+			     pid, GetLastError());
+		return 0;
+	    }
+	    SetEvent(hEvent);
+	    return DEBUG_MainLoop(pid);
+	}
+    }
+    do {
+	PROCESS_INFORMATION	info;
+	STARTUPINFOA		startup;
+
+	free(cmdline);
+
+	memset(&startup, 0, sizeof(startup));
+	startup.cb = sizeof(startup);
+	startup.dwFlags = STARTF_USESHOWWINDOW;
+	startup.wShowWindow = SW_SHOWNORMAL;
+
+	if (CreateProcess(NULL, _cmdline, NULL, NULL, 
+			  FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
+	    return DEBUG_MainLoop(info.dwProcessId);
+	}
+	DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", _cmdline);
+    } while (0);
     return 0;
 }
 
-DWORD	DEBUG_WinExec(LPSTR lpCmdLine, int sw)
-{
-    struct dsfcl 	s;
-    BOOL		ret;
-
-    if ((s.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL))) {
-	s.lpCmdLine = lpCmdLine;
-	s.showWindow = sw;
-	if (CreateThread(NULL, 0, DEBUG_StarterFromCmdLine, (LPVOID)&s, 0, NULL)) {
-	    WaitForSingleObject(s.hEvent, INFINITE);
-	    ret = s.error;
-	} else {
-	    ret = 3; /* (dummy) error value for non created thread */
-	}
-	CloseHandle(s.hEvent);
-    } else {
-	ret = 1; /* (dummy) error value for non created event */
-    }
-    return ret;
-}
diff --git a/debugger/winedbg.spec b/debugger/winedbg.spec
new file mode 100644
index 0000000..6d2c649
--- /dev/null
+++ b/debugger/winedbg.spec
@@ -0,0 +1,5 @@
+name	winedbg
+mode	guiexe
+type	win32
+init	WinMain
+
diff --git a/include/stackframe.h b/include/stackframe.h
index 80b3073..9cc0389 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -96,15 +96,15 @@
 /* Push a DWORD on the 32-bit stack */
 static inline void WINE_UNUSED stack32_push( CONTEXT86 *context, DWORD val )
 {
-    ESP_reg(context) -= sizeof(DWORD);
-    *(DWORD *)ESP_reg(context) = val;
+    context->Esp -= sizeof(DWORD);
+    *(DWORD *)context->Esp = val;
 }
 
 /* Pop a DWORD from the 32-bit stack */
 static inline DWORD WINE_UNUSED stack32_pop( CONTEXT86 *context )
 {
-    DWORD ret = *(DWORD *)ESP_reg(context);
-    ESP_reg(context) += sizeof(DWORD);
+    DWORD ret = *(DWORD *)context->Esp;
+    context->Esp += sizeof(DWORD);
     return ret;
 }