winedbg (take 2)

Eric Pouech pouech-eric at wanadoo.fr
Mon Feb 2 16:09:18 CST 2004


Robert Shearman did some more tests on my previous patch, which ended up 
with two bugs. So, here's the new patch with the two one-liners to make 
it more correct.
Alexandre, please use this one instead.

A+
-------------- next part --------------
Name:          wd_load
ChangeLog:     
	- now detecting Dwarf debug information in ELF modules
	  (but don't load it)
	- separated module management (pe.c, elf.c) from debug information management (stabs.c, msc.c)
	- worked around new wine-pthread and wine-kthread loaders (no longer use "wine" as default loader)
	  (stronger detection at run-time that debuggee's loader is what winedbg thinks it is)
	- better convergence of gdb-proxy and winedbg for ELF handling
	- fixed ELF link-map walking - now using all loaded shared libs - (with the help of R Shearman)
	- added a bit of const correctness
License:       X11
GenDate:       2004/02/02 22:06:35 UTC
ModifiedFiles: programs/winedbg/Makefile.in programs/winedbg/debugger.h programs/winedbg/gdbproxy.c programs/winedbg/hash.c programs/winedbg/memory.c programs/winedbg/module.c programs/winedbg/msc.c programs/winedbg/stabs.c programs/winedbg/winedbg.c
AddedFiles:    programs/winedbg/elf.c programs/winedbg/pe.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/Makefile.in,v
retrieving revision 1.2
diff -u -u -r1.2 Makefile.in
--- programs/winedbg/Makefile.in	15 Dec 2002 01:19:53 -0000	1.2
+++ programs/winedbg/Makefile.in	25 Jan 2004 14:13:05 -0000
@@ -11,6 +11,7 @@
 	break.c \
 	db_disasm.c \
 	display.c \
+	elf.c \
 	expr.c \
 	ext_debugger.c \
 	gdbproxy.c \
@@ -19,6 +20,7 @@
 	memory.c \
 	module.c \
 	msc.c \
+	pe.c \
 	registers.c \
 	source.c \
 	stabs.c	\
Index: programs/winedbg/debugger.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/debugger.h,v
retrieving revision 1.16
diff -u -u -r1.16 debugger.h
--- programs/winedbg/debugger.h	15 Dec 2003 19:53:08 -0000	1.16
+++ programs/winedbg/debugger.h	1 Feb 2004 09:47:03 -0000
@@ -267,20 +267,20 @@
 #define DEBUG_WRITE_MEM_VERBOSE(addr, buf, len) \
       (DEBUG_WRITE_MEM((addr), (buf), (len)) || (DEBUG_InvalLinAddr( addr ),0))
 
-enum DbgInfoLoad {DIL_DEFERRED, DIL_LOADED, DIL_NOINFO, DIL_ERROR};
+enum DbgInfoLoad {DIL_DEFERRED, DIL_LOADED, DIL_NOINFO, DIL_NOT_SUPPORTED, DIL_ERROR};
 enum DbgModuleType {DMT_UNKNOWN, DMT_ELF, DMT_NE, DMT_PE};
 
 typedef struct tagDBG_MODULE {
    void*			load_addr;
    unsigned long		size;
-   char*			module_name;
+   const char*  		module_name;
    enum DbgInfoLoad		dil;
    enum DbgModuleType		type;
    unsigned short		main : 1;
    short int			dbg_index;
    HMODULE                      handle;
-   struct tagMSC_DBG_INFO*	msc_info;
-   struct tagELF_DBG_INFO*	elf_info;
+   struct tagMSC_DBG_INFO*	msc_dbg_info;
+   struct tagELF_DBG_INFO*	elf_dbg_info;
 } DBG_MODULE;
 
 typedef struct {
@@ -335,6 +335,26 @@
 extern int DEBUG_InfoDisplay(void);
 extern int DEBUG_EnableDisplay(int displaynum, int enable);
 
+  /* debugger/elf.c */
+#define ELF_INFO_PATH           0x0001
+#define ELF_INFO_DEBUG_HEADER   0x0002
+#define ELF_INFO_SEGMENTS       0x0004
+#define ELF_INFO_MODULE         0x0008
+
+struct elf_info
+{
+    unsigned            flags;
+    char*               elf_path;       /* path to unix elf path, if ELF_INFO_PATH is set */
+    size_t              elf_path_len;
+    void*               load_addr;      /* 32 bit linear addr, where ELF module is loaded */
+    unsigned long       size;           /* size of elf module (guessed) */
+    unsigned long       dbg_hdr_addr;   /* address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
+    unsigned long       segments[3];    /* addresses of .text, .data and .bss segments (not filled yet) */
+};
+
+extern enum DbgInfoLoad DEBUG_ReadWineLoaderDbgInfo(HANDLE hProcess, struct elf_info* elf_info);
+extern BOOL             DEBUG_SetElfSoLoadBreakpoint(const struct elf_info* elf_info);
+
   /* debugger/expr.c */
 extern void DEBUG_FreeExprMem(void);
 struct expr * DEBUG_IntVarExpr(const char* name);
@@ -432,27 +452,34 @@
 extern int  DEBUG_PrintStringW(const DBG_ADDR* address, int len);
 
   /* debugger/module.c */
+extern DBG_MODULE* DEBUG_AddModule(const char* name, enum DbgModuleType type,
+                                   void* mod_addr, unsigned long size, HMODULE hmodule);
 extern int  DEBUG_LoadEntryPoints( const char * prefix );
-extern void DEBUG_LoadModule32( const char* name, HANDLE hFile, void *base );
 extern DBG_MODULE* DEBUG_FindModuleByName(const char* name, enum DbgModuleType type);
 extern DBG_MODULE* DEBUG_FindModuleByHandle(HANDLE handle, enum DbgModuleType type);
 extern DBG_MODULE* DEBUG_FindModuleByAddr(void* addr, enum DbgModuleType type);
 extern DBG_MODULE* DEBUG_GetProcessMainModule(DBG_PROCESS* process);
-extern DBG_MODULE* DEBUG_RegisterELFModule(void *load_addr, unsigned long size,
-					   const char* name);
-extern enum DbgInfoLoad DEBUG_RegisterPEDebugInfo(DBG_MODULE* wmod, HANDLE hFile,
-						  void* _nth, unsigned long nth_ofs);
 extern void DEBUG_ReportDIL(enum DbgInfoLoad dil, const char* pfx,
 			    const char* filename, void *load_addr);
 extern void DEBUG_InfoShare(void);
 
   /* debugger/msc.c */
+extern void DEBUG_InitCVDataTypes(void);
+extern enum DbgInfoLoad DEBUG_ProcessDebugDirectory( DBG_MODULE *module, const BYTE* file_map,
+                                                     PIMAGE_DEBUG_DIRECTORY dbg, int nDbg );
+
+  /* debugger/pe.c */
+extern void* DEBUG_MapDebugInfoFile(const char* name, DWORD offset, DWORD size,
+                                    HANDLE* hFile, HANDLE* hMap);
+extern void DEBUG_UnmapDebugInfoFile(HANDLE hFile, HANDLE hMap, const void* addr);
+extern void DEBUG_LoadPEModule( const char* name, HANDLE hFile, void *base );
 extern enum DbgInfoLoad DEBUG_RegisterMSCDebugInfo(DBG_MODULE* module, HANDLE hFile,
 						   void* nth, unsigned long nth_ofs);
 extern enum DbgInfoLoad DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module,
 						     HANDLE hFile, void* nth,
 						     unsigned long nth_ofs);
-extern void DEBUG_InitCVDataTypes(void);
+extern enum DbgInfoLoad DEBUG_RegisterPEDebugInfo(DBG_MODULE* wmod, HANDLE hFile,
+						  void* _nth, unsigned long nth_ofs);
 
   /* debugger/registers.c */
 extern void DEBUG_InfoRegisters(const CONTEXT* ctx);
@@ -477,8 +504,7 @@
 				  unsigned int * ebp);
 
   /* debugger/stabs.c */
-extern enum DbgInfoLoad DEBUG_ReadExecutableDbgInfo(const char* exe_name);
-extern enum DbgInfoLoad DEBUG_ParseStabs(char * addr, void *load_offset,
+extern enum DbgInfoLoad DEBUG_ParseStabs(const char* addr, void *load_offset,
 					 unsigned int staboff, int stablen,
 					 unsigned int strtaboff, int strtablen);
 
Index: programs/winedbg/gdbproxy.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/gdbproxy.c,v
retrieving revision 1.16
diff -u -u -r1.16 gdbproxy.c
--- programs/winedbg/gdbproxy.c	15 Dec 2003 19:53:08 -0000	1.16
+++ programs/winedbg/gdbproxy.c	31 Jan 2004 11:00:13 -0000
@@ -102,8 +102,6 @@
     unsigned long               wine_segs[3];   /* load addresses of the ELF wine exec segments (text, bss and data) */
 };
 
-extern int read_elf_info(const char* filename, unsigned long tab[]);
-
 /* =============================================== *
  *       B A S I C   M A N I P U L A T I O N S     *
  * =============================================== *
@@ -620,29 +618,6 @@
                         de->u.CreateProcessInfo.hThread,
                         de->u.CreateProcessInfo.lpStartAddress,
                         de->u.CreateProcessInfo.lpThreadLocalBase);
-#if 0
-        DEBUG_LoadModule32(DEBUG_CurrProcess->imageName, de->u.CreateProcessInfo.hFile,
-                           de->u.CreateProcessInfo.lpBaseOfImage);
-
-        if (buffer[0])  /* we got a process name */
-        {
-            DWORD type;
-            if (!GetBinaryTypeA( buffer, &type ))
-            {
-                /* not a Windows binary, assume it's a Unix executable then */
-                char unixname[MAX_PATH];
-                /* HACK!! should fix DEBUG_ReadExecutableDbgInfo to accept DOS filenames */
-                if (wine_get_unix_file_name( buffer, unixname, sizeof(unixname) ))
-                {
-                    DEBUG_ReadExecutableDbgInfo( unixname );
-                    break;
-                }
-            }
-        }
-        /* if it is a Windows binary, or an invalid or missing file name,
-         * we use wine itself as the main executable */
-        DEBUG_ReadExecutableDbgInfo( "wine" );
-#endif
         break;
 
     case LOAD_DLL_DEBUG_EVENT:
@@ -1980,7 +1955,7 @@
     int                 s_len = sizeof(s_addrs);
     struct pollfd       pollfd;
     char                wine_path[MAX_PATH];
-    char*               ptr;
+    struct elf_info     elf_info;
 
     /* step 1: create socket for gdb connection request */
     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
@@ -1995,11 +1970,16 @@
         return FALSE;
 
     /* step 2: find out wine executable location (as a Unix filename) */
-    ptr = getenv("WINELOADER");
-    strcpy(wine_path, ptr ? ptr : "wine");
+    elf_info.flags = ELF_INFO_PATH | ELF_INFO_SEGMENTS;
+    elf_info.elf_path = wine_path;
+    elf_info.elf_path_len = sizeof(wine_path);
+    if (DEBUG_ReadWineLoaderDbgInfo(de->u.CreateProcessInfo.hProcess, &elf_info) == DIL_ERROR)
+        return FALSE;
+    gdbctx->wine_segs[0] = elf_info.segments[0];
+    gdbctx->wine_segs[1] = elf_info.segments[1];
+    gdbctx->wine_segs[2] = elf_info.segments[2];
 
     fprintf(stderr, "Using wine_path: %s\n", wine_path);
-    read_elf_info(wine_path, gdbctx->wine_segs);
 
     /* step 3: fire up gdb (if requested) */
     if (flags & 1)
Index: programs/winedbg/hash.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/hash.c,v
retrieving revision 1.15
diff -u -u -r1.15 hash.c
--- programs/winedbg/hash.c	15 Dec 2003 19:53:08 -0000	1.15
+++ programs/winedbg/hash.c	1 Feb 2004 08:43:49 -0000
@@ -704,7 +704,7 @@
 
     module = DEBUG_FindModuleByAddr((void*)DEBUG_ToLinear(addr), DMT_UNKNOWN);
     if (module) {
-        char *p, *name = module->module_name;
+        const char *p, *name = module->module_name;
         if ((p = strrchr(name, '/'))) name = p + 1;
         if ((p = strrchr(name, '\\'))) name = p + 1;
         snprintf( modbuf, sizeof(modbuf), " in %s", name);
Index: programs/winedbg/memory.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/memory.c,v
retrieving revision 1.6
diff -u -u -r1.6 memory.c
--- programs/winedbg/memory.c	15 Dec 2003 19:53:08 -0000	1.6
+++ programs/winedbg/memory.c	31 Jan 2004 08:58:04 -0000
@@ -140,7 +140,7 @@
 void	DEBUG_InvalAddr( const DBG_ADDR* addr )
 {
    DEBUG_Printf("*** Invalid address ");
-   DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, FALSE);
+   DEBUG_PrintAddress(addr, DEBUG_CurrThread ? DEBUG_CurrThread->dbg_mode : MODE_32, FALSE);
    DEBUG_Printf("\n");
    if (DBG_IVAR(ExtDbgOnInvalidAddress)) DEBUG_ExternalDebugger();
 }
Index: programs/winedbg/module.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/module.c,v
retrieving revision 1.5
diff -u -u -r1.5 module.c
--- programs/winedbg/module.c	15 Dec 2003 19:53:08 -0000	1.5
+++ programs/winedbg/module.c	25 Jan 2004 14:27:56 -0000
@@ -1,4 +1,3 @@
-/* -*- tab-width: 8; c-basic-offset: 4 -*- */
 /*
  * File module.c - module handling for the wine debugger
  *
@@ -34,8 +33,8 @@
  * Creates and links a new module to the current process
  *
  */
-static DBG_MODULE* DEBUG_AddModule(const char* name, enum DbgModuleType type,
-                                   void* mod_addr, unsigned long size, HMODULE hmodule)
+DBG_MODULE* DEBUG_AddModule(const char* name, enum DbgModuleType type,
+                            void* mod_addr, unsigned long size, HMODULE hmodule)
 {
     DBG_MODULE*	wmod;
 
@@ -52,6 +51,7 @@
     wmod->handle = hmodule;
     wmod->dbg_index = DEBUG_CurrProcess->next_index;
     wmod->module_name = DBG_strdup(name);
+    DEBUG_CurrProcess->next_index++;
 
     DEBUG_CurrProcess->modules = DBG_realloc(DEBUG_CurrProcess->modules,
 					     ++DEBUG_CurrProcess->num_modules * sizeof(DBG_MODULE*));
@@ -130,39 +130,6 @@
     return process->modules[0];
 }
 
-/***********************************************************************
- *			DEBUG_RegisterELFModule
- *
- * ELF modules are also entered into the list - this is so that we
- * can make 'info shared' types of displays possible.
- */
-DBG_MODULE* DEBUG_RegisterELFModule(void *load_addr, unsigned long size, const char* name)
-{
-    DBG_MODULE*	wmod = DEBUG_AddModule(name, DMT_ELF, load_addr, size, 0);
-
-    if (!wmod) return NULL;
-
-    DEBUG_CurrProcess->next_index++;
-
-    return wmod;
-}
-
-/***********************************************************************
- *			DEBUG_RegisterPEModule
- *
- */
-static DBG_MODULE* DEBUG_RegisterPEModule(HMODULE hModule, void *load_addr,
-                                          unsigned long size, const char *module_name)
-{
-    DBG_MODULE*	wmod = DEBUG_AddModule(module_name, DMT_PE, load_addr, size, hModule);
-
-    if (!wmod) return NULL;
-
-    DEBUG_CurrProcess->next_index++;
-
-    return wmod;
-}
-
 #if 0
 /***********************************************************************
  *			DEBUG_RegisterNEModule
@@ -273,152 +240,6 @@
 #endif
 
 /***********************************************************************
- *			DEBUG_LoadModule32
- */
-void	DEBUG_LoadModule32(const char* name, HANDLE hFile, void *base)
-{
-     IMAGE_NT_HEADERS		pe_header;
-     DWORD			nth_ofs;
-     DBG_MODULE*		wmod = NULL;
-     int 			i;
-     IMAGE_SECTION_HEADER 	pe_seg;
-     DWORD			pe_seg_ofs;
-     DWORD			size = 0;
-     enum DbgInfoLoad		dil = DIL_ERROR;
-
-     /* grab PE Header */
-     if (!DEBUG_READ_MEM_VERBOSE( (char *)base + OFFSET_OF(IMAGE_DOS_HEADER, e_lfanew),
-				 &nth_ofs, sizeof(nth_ofs)) ||
-	 !DEBUG_READ_MEM_VERBOSE( (char *)base + nth_ofs, &pe_header, sizeof(pe_header)))
-	 return;
-
-     pe_seg_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
-	 pe_header.FileHeader.SizeOfOptionalHeader;
-
-     for (i = 0; i < pe_header.FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
-	 if (!DEBUG_READ_MEM_VERBOSE( (char *)base + pe_seg_ofs, &pe_seg, sizeof(pe_seg)))
-	     continue;
-	 if (size < pe_seg.VirtualAddress + pe_seg.SizeOfRawData)
-	     size = pe_seg.VirtualAddress + pe_seg.SizeOfRawData;
-     }
-
-     /* FIXME: we make the assumption that hModule == base */
-     wmod = DEBUG_RegisterPEModule((HMODULE)base, base, size, name);
-     if (wmod) {
-	 dil = DEBUG_RegisterStabsDebugInfo(wmod, hFile, &pe_header, nth_ofs);
-	 if (dil != DIL_LOADED)
-	     dil = DEBUG_RegisterMSCDebugInfo(wmod, hFile, &pe_header, nth_ofs);
-	 if (dil != DIL_LOADED)
-	     dil = DEBUG_RegisterPEDebugInfo(wmod, hFile, &pe_header, nth_ofs);
-	 wmod->dil = dil;
-     }
-
-     DEBUG_ReportDIL(dil, "32bit DLL", name, base);
-}
-
-/***********************************************************************
- *			DEBUG_RegisterPEDebugInfo
- */
-enum DbgInfoLoad	DEBUG_RegisterPEDebugInfo(DBG_MODULE* wmod, HANDLE hFile,
-						  void* _nth, unsigned long nth_ofs)
-{
-    DBG_VALUE			value;
-    char			buffer[512];
-    char			bufstr[256];
-    unsigned int 		i;
-    IMAGE_SECTION_HEADER 	pe_seg;
-    DWORD			pe_seg_ofs;
-    IMAGE_DATA_DIRECTORY 	dir;
-    DWORD			dir_ofs;
-    const char*			prefix;
-    IMAGE_NT_HEADERS*		nth = (PIMAGE_NT_HEADERS)_nth;
-    void *			base = wmod->load_addr;
-
-    value.type = NULL;
-    value.cookie = DV_TARGET;
-    value.addr.seg = 0;
-    value.addr.off = 0;
-
-    /* Add start of DLL */
-    value.addr.off = (unsigned long)base;
-    if ((prefix = strrchr(wmod->module_name, '\\' ))) prefix++;
-    else prefix = wmod->module_name;
-
-    DEBUG_AddSymbol(prefix, &value, NULL, SYM_WIN32 | SYM_FUNC);
-
-    /* Add entry point */
-    snprintf(buffer, sizeof(buffer), "%s.EntryPoint", prefix);
-    value.addr.off = (unsigned long)base + nth->OptionalHeader.AddressOfEntryPoint;
-    DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
-
-    /* Add start of sections */
-    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( (char *)base + pe_seg_ofs, &pe_seg, sizeof(pe_seg)))
-	    continue;
-	snprintf(buffer, sizeof(buffer), "%s.%s", prefix, pe_seg.Name);
-	value.addr.off = (unsigned long)base + pe_seg.VirtualAddress;
-	DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
-    }
-
-    /* Add exported functions */
-    dir_ofs = nth_ofs +
-	OFFSET_OF(IMAGE_NT_HEADERS,
-		  OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
-    if (DEBUG_READ_MEM_VERBOSE( (char *)base + dir_ofs, &dir, sizeof(dir)) && dir.Size) {
-	IMAGE_EXPORT_DIRECTORY 	exports;
-	WORD*			ordinals = NULL;
-	void**			functions = NULL;
-	DWORD*			names = NULL;
-	unsigned int		j;
-
-	if (DEBUG_READ_MEM_VERBOSE( (char *)base + dir.VirtualAddress,
-				   &exports, sizeof(exports)) &&
-
-	    ((functions = DBG_alloc(sizeof(functions[0]) * exports.NumberOfFunctions))) &&
-	    DEBUG_READ_MEM_VERBOSE( (char *)base + exports.AddressOfFunctions,
-				   functions, sizeof(functions[0]) * exports.NumberOfFunctions) &&
-
-	    ((ordinals = DBG_alloc(sizeof(ordinals[0]) * exports.NumberOfNames))) &&
-	    DEBUG_READ_MEM_VERBOSE( (char *)base + (DWORD)exports.AddressOfNameOrdinals,
-				   ordinals, sizeof(ordinals[0]) * exports.NumberOfNames) &&
-
-	    ((names = DBG_alloc(sizeof(names[0]) * exports.NumberOfNames))) &&
-	    DEBUG_READ_MEM_VERBOSE( (char *)base + (DWORD)exports.AddressOfNames,
-				   names, sizeof(names[0]) * exports.NumberOfNames)) {
-
-	    for (i = 0; i < exports.NumberOfNames; i++) {
-		if (!names[i] ||
-		    !DEBUG_READ_MEM_VERBOSE( (char *)base + names[i], bufstr, sizeof(bufstr)))
-		    continue;
-		bufstr[sizeof(bufstr) - 1] = 0;
-		snprintf(buffer, sizeof(buffer), "%s.%s", prefix, bufstr);
-		value.addr.off = (unsigned long)base + (DWORD)functions[ordinals[i]];
-		DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
-	    }
-
-	    for (i = 0; i < exports.NumberOfFunctions; i++) {
-		if (!functions[i]) continue;
-		/* Check if we already added it with a name */
-		for (j = 0; j < exports.NumberOfNames; j++)
-		    if ((ordinals[j] == i) && names[j]) break;
-		if (j < exports.NumberOfNames) continue;
-		snprintf(buffer, sizeof(buffer), "%s.%ld", prefix, i + exports.Base);
-		value.addr.off = (unsigned long)base + (DWORD)functions[i];
-		DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
-	    }
-	}
-	DBG_free(functions);
-	DBG_free(ordinals);
-	DBG_free(names);
-    }
-    /* no real debug info, only entry points */
-    return DIL_NOINFO;
-}
-
-/***********************************************************************
  *           	DEBUG_LoadEntryPoints
  *
  * Load the entry points of all the modules into the hash table.
@@ -484,6 +305,9 @@
     case DIL_NOINFO:
 	fmt = "No debug information in %s '%s' (%p)\n";
 	break;
+    case DIL_NOT_SUPPORTED:
+        fmt = "Unsupported debug information in %s '%s' (%p)\n";
+        break;
     case DIL_ERROR:
 	fmt = "Can't find file for %s '%s' (%p)\n";
 	break;
@@ -508,11 +332,12 @@
 static const char*      DEBUG_GetDbgInfo(enum DbgInfoLoad dil)
 {
     switch (dil) {
-    case DIL_LOADED:	return "loaded";
-    case DIL_DEFERRED: 	return "deferred";
-    case DIL_NOINFO:	return "none";
-    case DIL_ERROR:	return "error";
-    default:            return "?";
+    case DIL_LOADED:            return "loaded";
+    case DIL_DEFERRED:          return "deferred";
+    case DIL_NOINFO:            return "none";
+    case DIL_NOT_SUPPORTED:     return "not supported";
+    case DIL_ERROR:             return "error";
+    default:                    return "?";
     }
 }
 
Index: programs/winedbg/msc.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/msc.c,v
retrieving revision 1.6
diff -u -u -r1.6 msc.c
--- programs/winedbg/msc.c	15 Dec 2003 19:53:08 -0000	1.6
+++ programs/winedbg/msc.c	1 Feb 2004 08:56:00 -0000
@@ -79,83 +79,6 @@
           return EXCEPTION_CONTINUE_SEARCH;
 }
 
-/***********************************************************************
- *           DEBUG_LocateDebugInfoFile
- *
- * NOTE: dbg_filename must be at least MAX_PATHNAME_LEN bytes in size
- */
-static void DEBUG_LocateDebugInfoFile(const char *filename, char *dbg_filename)
-{
-    char	  *str1 = DBG_alloc(MAX_PATHNAME_LEN);
-    char	  *str2 = DBG_alloc(MAX_PATHNAME_LEN*10);
-    const char	  *file;
-    char	  *name_part;
-
-    file = strrchr(filename, '\\');
-    if( file == NULL ) file = filename; else file++;
-
-    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
-        lstrcpyn(dbg_filename, filename, MAX_PATHNAME_LEN);
-    DBG_free(str1);
-    DBG_free(str2);
-}
-
-/***********************************************************************
- *           DEBUG_MapDebugInfoFile
- */
-static void*	DEBUG_MapDebugInfoFile(const char* name, DWORD offset, DWORD size,
-				       HANDLE* hFile, HANDLE* hMap)
-{
-    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 = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
-	  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!=INVALID_HANDLE_VALUE) CloseHandle(hFile);
-}
-
-
-
 /*========================================================================
  * Process COFF debug information.
  */
@@ -234,7 +157,7 @@
    coff_file->entries[coff_file->neps++] = sym;
 }
 
-static enum DbgInfoLoad DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
+static enum DbgInfoLoad DEBUG_ProcessCoff( DBG_MODULE *module, const BYTE* root )
 {
   PIMAGE_AUX_SYMBOL		aux;
   PIMAGE_COFF_SYMBOLS_HEADER	coff;
@@ -369,7 +292,7 @@
 	  && (naux == 0)
 	  && (coff_sym->SectionNumber == 1) )
 	{
-	  DWORD	base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
+	  DWORD	base = module->msc_dbg_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
 	  /*
 	   * This is a normal static function when naux == 0.
 	   * Just register it.  The current file is the correct
@@ -396,7 +319,7 @@
           && (coff_sym->SectionNumber > 0) )
 	{
 	  const char* this_file = NULL;
-	  DWORD	base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
+	  DWORD	base = module->msc_dbg_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
 	  nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
 
 	  new_value.addr.seg = 0;
@@ -405,7 +328,7 @@
 	  WINE_TRACE_(winedbg_msc)("%d: %lx %s\n", i, new_value.addr.off, nampnt);
 	  WINE_TRACE_(winedbg_msc)(
               "\tAdding global symbol %s (sect=%s)\n",
-              nampnt, module->msc_info->sectp[coff_sym->SectionNumber - 1].Name);
+              nampnt, module->msc_dbg_info->sectp[coff_sym->SectionNumber - 1].Name);
 
 	  /*
 	   * Now we need to figure out which file this guy belongs to.
@@ -432,7 +355,7 @@
       if(    (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
           && (coff_sym->SectionNumber > 0) )
 	{
-	  DWORD	base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
+	  DWORD	base = module->msc_dbg_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
 	  /*
 	   * Similar to above, but for the case of data symbols.
 	   * These aren't treated as entrypoints.
@@ -1760,10 +1683,10 @@
 
 union any_size
 {
-  char		 * c;
-  short		 * s;
-  int		 * i;
-  unsigned int   * ui;
+  const char*           c;
+  const short*          s;
+  const int*            i;
+  const unsigned int*   ui;
 };
 
 struct startend
@@ -1778,18 +1701,18 @@
   unsigned int		   segno;
   unsigned int		   start;
   unsigned int		   end;
-  char			 * sourcefile;
-  unsigned short	 * linetab;
-  unsigned int		 * offtab;
+  const char		 * sourcefile;
+  const unsigned short	 * linetab;
+  const unsigned int	 * offtab;
 };
 
 static struct codeview_linetab_hdr *
-DEBUG_SnarfLinetab(char * linetab,
+DEBUG_SnarfLinetab(const char * linetab,
 		   int    size)
 {
   int				  file_segcount;
   char				  filename[PATH_MAX];
-  unsigned int			* filetab;
+  const unsigned int		* filetab;
   char				* fn;
   int				  i;
   int				  k;
@@ -1809,7 +1732,7 @@
   nfile = *pnt.s++;
   nseg = *pnt.s++;
 
-  filetab = (unsigned int *) pnt.c;
+  filetab = (const unsigned int *) pnt.c;
 
   /*
    * Now count up the number of segments in the file.
@@ -2049,8 +1972,8 @@
 static unsigned int
 DEBUG_MapCVOffset( DBG_MODULE *module, unsigned int offset )
 {
-    int        nomap = module->msc_info->nomap;
-    OMAP_DATA *omapp = module->msc_info->omapp;
+    int        nomap = module->msc_dbg_info->nomap;
+    OMAP_DATA *omapp = module->msc_dbg_info->omapp;
     int i;
 
     if ( !nomap || !omapp )
@@ -2070,8 +1993,8 @@
                    int size, int cookie, int flags,
                    struct codeview_linetab_hdr *linetab )
 {
-    int			  nsect = module->msc_info->nsect;
-    PIMAGE_SECTION_HEADER sectp = module->msc_info->sectp;
+    int			  nsect = module->msc_dbg_info->nsect;
+    PIMAGE_SECTION_HEADER sectp = module->msc_dbg_info->sectp;
 
     struct name_hash *symbol;
     char symname[PATH_MAX];
@@ -2162,7 +2085,7 @@
 }
 
 static int
-DEBUG_SnarfCodeView( DBG_MODULE	*module, LPBYTE root, int offset, int size,
+DEBUG_SnarfCodeView( DBG_MODULE	*module, const BYTE* root, int offset, int size,
                      struct codeview_linetab_hdr *linetab )
 {
     struct name_hash *curr_func = NULL;
@@ -2788,7 +2711,7 @@
 #define	sstSrcModule		0x127
 
 
-static enum DbgInfoLoad DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
+static enum DbgInfoLoad DEBUG_ProcessCodeView( DBG_MODULE *module, const BYTE* root )
 {
     PCODEVIEW_HEADER cv = (PCODEVIEW_HEADER)root;
     enum DbgInfoLoad dil = DIL_ERROR;
@@ -2860,10 +2783,8 @@
 /*========================================================================
  * Process debug directory.
  */
-static enum DbgInfoLoad DEBUG_ProcessDebugDirectory( DBG_MODULE *module,
-						     LPBYTE file_map,
-						     PIMAGE_DEBUG_DIRECTORY dbg,
-						     int nDbg )
+enum DbgInfoLoad DEBUG_ProcessDebugDirectory( DBG_MODULE *module, const BYTE* file_map,
+                                              PIMAGE_DEBUG_DIRECTORY dbg, int nDbg )
 {
     enum DbgInfoLoad dil;
     int i;
@@ -2874,8 +2795,8 @@
         {
             if ( dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC )
             {
-                module->msc_info->nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
-                module->msc_info->omapp = (OMAP_DATA *)(file_map + dbg[i].PointerToRawData);
+                module->msc_dbg_info->nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
+                module->msc_dbg_info->omapp = (OMAP_DATA *)(file_map + dbg[i].PointerToRawData);
                 break;
             }
         }
@@ -2932,214 +2853,3 @@
 }
 
 
-/*========================================================================
- * Process DBG file.
- */
-static enum DbgInfoLoad DEBUG_ProcessDBGFile( DBG_MODULE *module,
-					      const char *filename, DWORD timestamp )
-{
-    enum DbgInfoLoad dil = DIL_ERROR;
-    HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
-    LPBYTE file_map = NULL;
-    PIMAGE_SEPARATE_DEBUG_HEADER hdr;
-    PIMAGE_DEBUG_DIRECTORY dbg;
-    int nDbg;
-
-    WINE_TRACE("Processing DBG file %s\n", filename);
-
-    file_map = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
-    if ( !file_map )
-    {
-        WINE_ERR("-Unable to peruse .DBG file %s\n", filename);
-        goto leave;
-    }
-
-    hdr = (PIMAGE_SEPARATE_DEBUG_HEADER) file_map;
-
-    if ( hdr->TimeDateStamp != timestamp )
-    {
-        WINE_ERR("Warning - %s has incorrect internal timestamp\n", filename);
-        /*
-         *  Well, sometimes this happens to DBG files which ARE REALLY the right .DBG
-         *  files but nonetheless this check fails. Anyway, WINDBG (debugger for
-         *  Windows by Microsoft) loads debug symbols which have incorrect timestamps.
-         */
-    }
-
-
-    dbg = (PIMAGE_DEBUG_DIRECTORY) ( file_map + sizeof(*hdr)
-		 + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)
-		 + hdr->ExportedNamesSize );
-
-    nDbg = hdr->DebugDirectorySize / sizeof(*dbg);
-
-    dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
-
-
- leave:
-    DEBUG_UnmapDebugInfoFile( hFile, hMap, file_map );
-    return dil;
-}
-
-
-/*========================================================================
- * Process MSC debug information in PE file.
- */
-enum DbgInfoLoad DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
-					     void *_nth, unsigned long nth_ofs )
-{
-    enum DbgInfoLoad	   dil = DIL_ERROR;
-    PIMAGE_NT_HEADERS      nth = (PIMAGE_NT_HEADERS)_nth;
-    PIMAGE_DATA_DIRECTORY  dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
-    PIMAGE_DEBUG_DIRECTORY dbg = NULL;
-    int                    nDbg;
-    MSC_DBG_INFO           extra_info = { 0, NULL, 0, NULL };
-    HANDLE	           hMap = 0;
-    LPBYTE                 file_map = NULL;
-
-
-    /* Read in section data */
-
-    module->msc_info = &extra_info;
-    extra_info.nsect = nth->FileHeader.NumberOfSections;
-    extra_info.sectp = DBG_alloc( extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) );
-    if ( !extra_info.sectp )
-        goto leave;
-
-    if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr +
-		                  nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
-		                  nth->FileHeader.SizeOfOptionalHeader,
-                                  extra_info.sectp,
-                                  extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) ) )
-        goto leave;
-
-    /* Read in debug directory */
-
-    nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
-    if ( !nDbg )
-        goto leave;
-
-    dbg = (PIMAGE_DEBUG_DIRECTORY) DBG_alloc( nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) );
-    if ( !dbg )
-        goto leave;
-
-    if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr + dir->VirtualAddress,
-                                  dbg, nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) ) )
-        goto leave;
-
-
-    /* Map in PE file */
-    file_map = DEBUG_MapDebugInfoFile( NULL, 0, 0, &hFile, &hMap );
-    if ( !file_map )
-        goto leave;
-
-
-    /* Parse debug directory */
-
-    if ( nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED )
-    {
-        /* Debug info is stripped to .DBG file */
-
-        PIMAGE_DEBUG_MISC misc = (PIMAGE_DEBUG_MISC)(file_map + dbg->PointerToRawData);
-
-        if ( nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC
-                       || misc->DataType != IMAGE_DEBUG_MISC_EXENAME )
-        {
-            WINE_ERR("-Debug info stripped, but no .DBG file in module %s\n",
-                     module->module_name );
-            goto leave;
-        }
-
-        dil = DEBUG_ProcessDBGFile( module, misc->Data, nth->FileHeader.TimeDateStamp );
-    }
-    else
-    {
-        /* Debug info is embedded into PE module */
-        /* FIXME: the nDBG information we're manipulating comes from the debuggee
-         * address space. However, the following code will be made against the
-         * version mapped in the debugger address space. There are cases (for example
-         * when the PE sections are compressed in the file and become decompressed
-         * in the debuggee address space) where the two don't match.
-         * Therefore, redo the DBG information lookup with the mapped data
-         */
-        PIMAGE_NT_HEADERS      mpd_nth = (PIMAGE_NT_HEADERS)(file_map + nth_ofs);
-        PIMAGE_DATA_DIRECTORY  mpd_dir;
-        PIMAGE_DEBUG_DIRECTORY mpd_dbg = NULL;
-
-        /* sanity checks */
-        if ( mpd_nth->Signature != IMAGE_NT_SIGNATURE ||
-             mpd_nth->FileHeader.NumberOfSections != nth->FileHeader.NumberOfSections ||
-             (mpd_nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) != 0)
-            goto leave;
-        mpd_dir = mpd_nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
-
-        if ((mpd_dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY)) != nDbg)
-            goto leave;
-
-        mpd_dbg = (PIMAGE_DEBUG_DIRECTORY)(file_map + mpd_dir->VirtualAddress);
-
-        dil = DEBUG_ProcessDebugDirectory( module, file_map, mpd_dbg, nDbg );
-    }
-
-
- leave:
-    module->msc_info = NULL;
-
-    DEBUG_UnmapDebugInfoFile( 0, hMap, file_map );
-    if ( extra_info.sectp ) DBG_free( extra_info.sectp );
-    if ( dbg ) DBG_free( dbg );
-    return dil;
-}
-
-
-/*========================================================================
- * look for stabs information in PE header (it's how mingw compiler provides its
- * debugging information), and also wine PE <-> ELF linking through .wsolnk sections
- */
-enum DbgInfoLoad 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;
-    PIMAGE_NT_HEADERS		nth = (PIMAGE_NT_HEADERS)_nth;
-    enum DbgInfoLoad		dil = DIL_ERROR;
-
-    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)))
-	  continue;
-
-      if (!strcasecmp(pe_seg.Name, ".stab")) {
-	stabs = pe_seg.VirtualAddress;
-	stabsize = pe_seg.SizeOfRawData;
-      } else if (!strncasecmp(pe_seg.Name, ".stabstr", 8)) {
-	stabstr = pe_seg.VirtualAddress;
-	stabstrsize = pe_seg.SizeOfRawData;
-      }
-    }
-
-    if (stabstrsize && stabsize) {
-       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)) {
-	     dil = DEBUG_ParseStabs(s1, 0, 0, stabsize, stabsize, stabstrsize);
-	  } else {
-	     DEBUG_Printf("couldn't read data block\n");
-	  }
-	  DBG_free(s1);
-       } else {
-	  DEBUG_Printf("couldn't alloc %d bytes\n", stabsize + stabstrsize);
-       }
-    } else {
-       dil = DIL_NOINFO;
-    }
-    return dil;
-}
Index: programs/winedbg/stabs.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/stabs.c,v
retrieving revision 1.11
diff -u -u -r1.11 stabs.c
--- programs/winedbg/stabs.c	15 Dec 2003 19:53:08 -0000	1.11
+++ programs/winedbg/stabs.c	1 Feb 2004 09:47:44 -0000
@@ -56,22 +56,9 @@
 #define __ELF__
 #endif
 
-#ifdef __ELF__
-#ifdef HAVE_ELF_H
-# include <elf.h>
-#endif
-#ifdef HAVE_LINK_H
-# include <link.h>
-#endif
-#ifdef HAVE_SYS_LINK_H
-# include <sys/link.h>
-#endif
-#endif
-
 #include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
-WINE_DECLARE_DEBUG_CHANNEL(winedbg_stabs);
+WINE_DEFAULT_DEBUG_CHANNEL(winedbg_stabs);
 
 #ifndef N_UNDF
 #define N_UNDF		0x00
@@ -100,11 +87,6 @@
 #define N_EXCL		0xc2
 #define N_RBRAC		0xe0
 
-typedef struct tagELF_DBG_INFO
-{
-    void *elf_addr;
-} ELF_DBG_INFO;
-
 struct stab_nlist {
   union {
     char *n_name;
@@ -235,7 +217,7 @@
 {
   struct datatype** ret;
 
-  WINE_TRACE_(winedbg_stabs)("creating type id for (%d,%d)\n", filenr, subnr);
+  WINE_TRACE("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
@@ -266,24 +248,25 @@
 	}
       ret = &idef->vector[subnr];
     }
-  WINE_TRACE_(winedbg_stabs)("(%d,%d) is %p\n",filenr,subnr,ret);
+  WINE_TRACE("(%d,%d) is %p\n",filenr,subnr,ret);
   return ret;
 }
 
 static
 struct datatype**
-DEBUG_ReadTypeEnum(char **x) {
+DEBUG_ReadTypeEnum(LPCSTR *x)
+{
     int filenr,subnr;
 
     if (**x=='(') {
 	(*x)++;					/* '(' */
-	filenr=strtol(*x,x,10);	                /* <int> */
+	filenr=strtol(*x,(char**)x,10);	        /* <int> */
 	(*x)++;					/* ',' */
-	subnr=strtol(*x,x,10);		        /* <int> */
+	subnr=strtol(*x,(char**)x,10);		/* <int> */
 	(*x)++;					/* ')' */
     } else {
     	filenr = 0;
-	subnr = strtol(*x,x,10);        	/* <int> */
+	subnr = strtol(*x,(char**)x,10);        /* <int> */
     }
     return DEBUG_FileSubNr2StabEnum(filenr,subnr);
 }
@@ -291,7 +274,7 @@
 /*#define PTS_DEBUG*/
 struct ParseTypedefData
 {
-    char*		ptr;
+    const char*		ptr;
     char		buf[1024];
     int			idx;
 #ifdef PTS_DEBUG
@@ -322,7 +305,7 @@
 
 static int DEBUG_PTS_ReadID(struct ParseTypedefData* ptd)
 {
-    char*	        first = ptd->ptr;
+    const char*	        first = ptd->ptr;
     unsigned int	len;
 
     PTS_ABORTIF(ptd, (ptd->ptr = strchr(ptd->ptr, ':')) == NULL);
@@ -611,7 +594,7 @@
 	    if (*++ptd->ptr == 's') {
 		ptd->ptr++;
 		if (DEBUG_PTS_ReadNum(ptd, &sz) == -1) {
-		    WINE_ERR_(winedbg_stabs)("Not an attribute... NIY\n");
+		    WINE_ERR("Not an attribute... NIY\n");
 		    ptd->ptr -= 2;
 		    return -1;
 		}
@@ -669,7 +652,7 @@
 		*DEBUG_FileSubNr2StabEnum(filenr1, subnr1) = new_dt;
 	    } else {
 		if (DEBUG_GetType(dt1) != DT_STRUCT) {
-		    WINE_ERR_(winedbg_stabs)("Forward declaration is not an aggregate\n");
+		    WINE_ERR("Forward declaration is not an aggregate\n");
 		    return -1;
 		}
 
@@ -784,7 +767,7 @@
             }
             break;
 	default:
-	    WINE_ERR_(winedbg_stabs)("Unknown type '%c'\n", ptd->ptr[-1]);
+	    WINE_ERR("Unknown type '%c'\n", ptd->ptr[-1]);
 	    return -1;
 	}
     }
@@ -809,7 +792,7 @@
     return 0;
 }
 
-static int DEBUG_ParseTypedefStab(char* ptr, const char* typename)
+static int DEBUG_ParseTypedefStab(const char* ptr, const char* typename)
 {
     struct ParseTypedefData	ptd;
     struct datatype*		dt;
@@ -838,20 +821,20 @@
     if (ret == -1 || *ptd.ptr) {
 #ifdef PTS_DEBUG
         int     i;
-	WINE_TRACE_(winedbg_stabs)("Failure on %s\n", ptr);
+	WINE_TRACE("Failure on %s\n", ptr);
         if (ret == -1)
         {
             for (i = 0; i < ptd.err_idx; i++)
             {
-                WINE_TRACE_(winedbg_stabs)("[%d]: line %d => %s\n", 
-                                           i, ptd.errors[i].line, ptd.errors[i].ptr);
+                WINE_TRACE("[%d]: line %d => %s\n", 
+                           i, ptd.errors[i].line, ptd.errors[i].ptr);
             }
         }
         else
-            WINE_TRACE_(winedbg_stabs)("[0]: => %s\n", ptd.ptr);
+            WINE_TRACE("[0]: => %s\n", ptd.ptr);
             
 #else
-	WINE_ERR_(winedbg_stabs)("Failure on %s at %s\n", ptr, ptd.ptr);
+	WINE_ERR("Failure on %s at %s\n", ptr, ptd.ptr);
 #endif
 	return FALSE;
     }
@@ -859,8 +842,8 @@
     return TRUE;
 }
 
-static struct datatype *
-DEBUG_ParseStabType(const char * stab)
+static struct datatype*
+DEBUG_ParseStabType(const char* stab)
 {
     const char* c = stab - 1;
 
@@ -888,31 +871,31 @@
      * The next is either an integer or a (integer,integer).
      * The DEBUG_ReadTypeEnum takes care that stab_types is large enough.
      */
-    return *DEBUG_ReadTypeEnum((char**)&c);
+    return *DEBUG_ReadTypeEnum(&c);
 }
 
-enum DbgInfoLoad DEBUG_ParseStabs(char * addr, void *load_offset,
+enum DbgInfoLoad DEBUG_ParseStabs(const char* addr, void* load_offset,
 				  unsigned int staboff, int stablen,
 				  unsigned int strtaboff, int strtablen)
 {
-  struct name_hash    * curr_func = NULL;
-  struct wine_locals  * curr_loc = NULL;
-  struct name_hash    * curr_sym = NULL;
-  char                  currpath[PATH_MAX];
-  int                   i;
-  int                   in_external_file = FALSE;
-  int                   last_nso = -1;
-  unsigned int          len;
-  DBG_VALUE	        new_value;
-  int                   nstab;
-  char                * ptr;
-  char                * stabbuff;
-  unsigned int          stabbufflen;
-  struct stab_nlist   * stab_ptr;
-  char                * strs;
-  int                   strtabinc;
-  char                * subpath = NULL;
-  char                  symname[4096];
+  struct name_hash*             curr_func = NULL;
+  struct wine_locals*           curr_loc = NULL;
+  struct name_hash*             curr_sym = NULL;
+  char                          currpath[PATH_MAX];
+  int                           i;
+  int                           in_external_file = FALSE;
+  int                           last_nso = -1;
+  unsigned int                  len;
+  DBG_VALUE	                new_value;
+  int                           nstab;
+  const char*                   ptr;
+  char*                         stabbuff;
+  unsigned int                  stabbufflen;
+  const struct stab_nlist*      stab_ptr;
+  const char*                   strs;
+  int                           strtabinc;
+  const char*                   subpath = NULL;
+  char                          symname[4096];
 
   nstab = stablen / sizeof(struct stab_nlist);
   stab_ptr = (struct stab_nlist *) (addr + staboff);
@@ -1200,15 +1183,15 @@
            */
           break;
         default:
-          WINE_ERR_(winedbg_stabs)("Unknown stab type 0x%02x\n", stab_ptr->n_type);
+          WINE_ERR("Unknown stab type 0x%02x\n", stab_ptr->n_type);
           break;
         }
 
       stabbuff[0] = '\0';
 
-      WINE_TRACE_(winedbg_stabs)("0x%02x %x %s\n", stab_ptr->n_type,
-                                 (unsigned int) stab_ptr->n_value,
-                                 strs + (unsigned int) stab_ptr->n_un.n_name);
+      WINE_TRACE("0x%02x %x %s\n", stab_ptr->n_type,
+                 (unsigned int) stab_ptr->n_value,
+                 strs + (unsigned int) stab_ptr->n_un.n_name);
     }
 
   DEBUG_FreeIncludes();
@@ -1216,498 +1199,3 @@
   return DIL_LOADED;
 }
 
-#ifdef __ELF__
-
-/*
- * Walk through the entire symbol table and add any symbols we find there.
- * This can be used in cases where we have stripped ELF shared libraries,
- * or it can be used in cases where we have data symbols for which the address
- * isn't encoded in the stabs.
- *
- * This is all really quite easy, since we don't have to worry about line
- * numbers or local data variables.
- */
-static int DEBUG_ProcessElfSymtab(DBG_MODULE* module, char* addr,
-				  void *load_addr, Elf32_Shdr* symtab,
-				  Elf32_Shdr* strtab)
-{
-  char		* curfile = NULL;
-  struct name_hash * curr_sym = NULL;
-  int		  flags;
-  int		  i;
-  DBG_VALUE       new_value;
-  int		  nsym;
-  char		* strp;
-  char		* symname;
-  Elf32_Sym	* symp;
-
-  symp = (Elf32_Sym *) (addr + symtab->sh_offset);
-  nsym = symtab->sh_size / sizeof(*symp);
-  strp = (char *) (addr + strtab->sh_offset);
-
-  for (i = 0; i < nsym; i++, symp++)
-    {
-      /*
-       * Ignore certain types of entries which really aren't of that much
-       * interest.
-       */
-      if( ELF32_ST_TYPE(symp->st_info) == STT_SECTION ||
-	  symp->st_shndx == STN_UNDEF )
-	{
-	  continue;
-	}
-
-      symname = strp + symp->st_name;
-
-      /*
-       * Save the name of the current file, so we have a way of tracking
-       * static functions/data.
-       */
-      if( ELF32_ST_TYPE(symp->st_info) == STT_FILE )
-	{
-	  curfile = symname;
-	  continue;
-	}
-
-      new_value.type = NULL;
-      new_value.addr.seg = 0;
-      new_value.addr.off = (unsigned long)load_addr + symp->st_value;
-      new_value.cookie = DV_TARGET;
-      flags = SYM_WINE | ((ELF32_ST_TYPE(symp->st_info) == STT_FUNC)
-			  ? SYM_FUNC : SYM_DATA);
-      if( ELF32_ST_BIND(symp->st_info) == STB_GLOBAL )
-	  curr_sym = DEBUG_AddSymbol( symname, &new_value, NULL, flags );
-      else
-	  curr_sym = DEBUG_AddSymbol( symname, &new_value, curfile, flags );
-
-      /*
-       * Record the size of the symbol.  This can come in handy in
-       * some cases.  Not really used yet, however.
-       */
-      if( symp->st_size != 0 )
-	  DEBUG_SetSymbolSize(curr_sym, symp->st_size);
-    }
-
-  return TRUE;
-}
-
-/*
- * Loads the symbolic information from ELF module stored in 'filename'
- * the module has been loaded at 'load_offset' address, so symbols' address
- * relocation is performed
- * returns
- *	-1 if the file cannot be found/opened
- *	0 if the file doesn't contain symbolic info (or this info cannot be
- *	read or parsed)
- *	1 on success
- */
-enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module)
-{
-    enum DbgInfoLoad dil = DIL_ERROR;
-    char*	addr = (char*)0xffffffff;
-    int		fd = -1;
-    struct stat	statbuf;
-    Elf32_Ehdr* ehptr;
-    Elf32_Shdr* spnt;
-    char*	shstrtab;
-    int	       	i;
-    int		stabsect;
-    int		stabstrsect;
-
-    if (module->type != DMT_ELF || !module->elf_info) {
-	WINE_ERR("Bad elf module '%s'\n", module->module_name);
-	return DIL_ERROR;
-    }
-
-    /* check that the file exists, and that the module hasn't been loaded yet */
-    if (stat(module->module_name, &statbuf) == -1) goto leave;
-    if (S_ISDIR(statbuf.st_mode)) goto leave;
-
-    /*
-     * Now open the file, so that we can mmap() it.
-     */
-    if ((fd = open(module->module_name, O_RDONLY)) == -1) goto leave;
-
-    dil = DIL_NOINFO;
-    /*
-     * Now mmap() the file.
-     */
-    addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-    if (addr == (char*)0xffffffff) goto leave;
-
-    /*
-     * Next, we need to find a few of the internal ELF headers within
-     * this thing.  We need the main executable header, and the section
-     * table.
-     */
-    ehptr = (Elf32_Ehdr*) addr;
-    spnt = (Elf32_Shdr*) (addr + ehptr->e_shoff);
-    shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
-
-    stabsect = stabstrsect = -1;
-
-    for (i = 0; i < ehptr->e_shnum; i++) {
-	if (strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0)
-	    stabsect = i;
-
-	if (strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0)
-	    stabstrsect = i;
-    }
-
-    if (stabsect == -1 || stabstrsect == -1) {
-	WINE_WARN("No .stab section\n");
-	goto leave;
-    }
-
-    /*
-     * OK, now just parse all of the stabs.
-     */
-    if (DEBUG_ParseStabs(addr,
-			 module->elf_info->elf_addr,
-			 spnt[stabsect].sh_offset,
-			 spnt[stabsect].sh_size,
-			 spnt[stabstrsect].sh_offset,
-			 spnt[stabstrsect].sh_size)) {
-	dil = DIL_LOADED;
-    } else {
-	dil = DIL_ERROR;
-	WINE_WARN("Couldn't read correctly read stabs\n");
-	goto leave;
-    }
-
-    for (i = 0; i < ehptr->e_shnum; i++) {
-	if (   (strcmp(shstrtab + spnt[i].sh_name, ".symtab") == 0)
-	    && (spnt[i].sh_type == SHT_SYMTAB))
-	    DEBUG_ProcessElfSymtab(module, addr, module->elf_info->elf_addr,
-				   spnt + i, spnt + spnt[i].sh_link);
-
-	if (   (strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0)
-	    && (spnt[i].sh_type == SHT_DYNSYM))
-	    DEBUG_ProcessElfSymtab(module, addr, module->elf_info->elf_addr,
-				   spnt + i, spnt + spnt[i].sh_link);
-    }
-
- leave:
-    if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
-    if (fd != -1) close(fd);
-
-    return dil;
-}
-
-/*
- * Loads the information for ELF module stored in 'filename'
- * the module has been loaded at 'load_offset' address
- * returns
- *	-1 if the file cannot be found/opened
- *	0 if the file doesn't contain symbolic info (or this info cannot be
- *	read or parsed)
- *	1 on success
- */
-static enum DbgInfoLoad DEBUG_ProcessElfFile(const char* filename,
-					     void *load_offset,
-					     unsigned int* dyn_addr)
-{
-    static const unsigned char elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
-    enum DbgInfoLoad dil = DIL_ERROR;
-    char*	addr = (char*)0xffffffff;
-    int		fd = -1;
-    struct stat	statbuf;
-    Elf32_Ehdr* ehptr;
-    Elf32_Shdr* spnt;
-    Elf32_Phdr*	ppnt;
-    char      * shstrtab;
-    int	       	i;
-    DBG_MODULE* module = NULL;
-    DWORD	size;
-    DWORD	delta;
-
-    WINE_TRACE("Processing elf file '%s'\n", filename);
-
-    /* check that the file exists, and that the module hasn't been loaded yet */
-    if (stat(filename, &statbuf) == -1) goto leave;
-
-    /*
-     * Now open the file, so that we can mmap() it.
-     */
-    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*)-1) goto leave;
-
-    dil = DIL_NOINFO;
-
-    /*
-     * Next, we need to find a few of the internal ELF headers within
-     * this thing.  We need the main executable header, and the section
-     * table.
-     */
-    ehptr = (Elf32_Ehdr*) addr;
-    if (memcmp( ehptr->e_ident, elf_signature, sizeof(elf_signature) )) goto leave;
-
-    spnt = (Elf32_Shdr*) (addr + ehptr->e_shoff);
-    shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
-
-    /* if non relocatable ELF, then remove fixed address from computation
-     * otherwise, all addresses are zero based
-     */
-    delta = (load_offset == 0) ? ehptr->e_entry : 0;
-
-    /* grab size of module once loaded in memory */
-    ppnt = (Elf32_Phdr*) (addr + ehptr->e_phoff);
-    size = 0;
-    for (i = 0; i < ehptr->e_phnum; i++) {
-	if (ppnt[i].p_type != PT_LOAD) continue;
-	if (size < ppnt[i].p_vaddr - delta + ppnt[i].p_memsz)
-	    size = ppnt[i].p_vaddr - delta + ppnt[i].p_memsz;
-    }
-
-    for (i = 0; i < ehptr->e_shnum; i++)
-    {
-	if (strcmp(shstrtab + spnt[i].sh_name, ".bss") == 0 &&
-	    spnt[i].sh_type == SHT_NOBITS)
-        {
-	    if (size < spnt[i].sh_addr - delta + spnt[i].sh_size)
-		size = spnt[i].sh_addr - delta + spnt[i].sh_size;
-	}
-	if (strcmp(shstrtab + spnt[i].sh_name, ".dynamic") == 0 &&
-	    spnt[i].sh_type == SHT_DYNAMIC)
-        {
-	    if (dyn_addr) *dyn_addr = spnt[i].sh_addr;
-	}
-    }
-
-    module = DEBUG_RegisterELFModule((load_offset == 0) ? (void *)ehptr->e_entry : load_offset,
-				     size, filename);
-    if (!module) {
-	dil = DIL_ERROR;
-	goto leave;
-    }
-
-    if ((module->elf_info = DBG_alloc(sizeof(ELF_DBG_INFO))) == NULL) {
-	WINE_ERR("OOM\n");
-	exit(0);
-    }
-
-    module->elf_info->elf_addr = load_offset;
-    dil = DEBUG_LoadElfStabs(module);
-
- leave:
-    if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
-    if (fd != -1) close(fd);
-    if (module) module->dil = dil;
-
-    return dil;
-}
-
-static enum DbgInfoLoad DEBUG_ProcessElfFileFromPath(const char * filename,
-						     void *load_offset,
-						     unsigned int* dyn_addr,
-						     const char* path)
-{
-    enum DbgInfoLoad	dil = DIL_ERROR;
-    char 	*s, *t, *fn;
-    char*	paths = NULL;
-
-    if (!path) return -1;
-
-    for (s = paths = DBG_strdup(path); s && *s; s = (t) ? (t+1) : NULL) {
-	t = strchr(s, ':');
-	if (t) *t = '\0';
-	fn = (char*)DBG_alloc(strlen(filename) + 1 + strlen(s) + 1);
-	if (!fn) break;
-	strcpy(fn, s );
-	strcat(fn, "/");
-	strcat(fn, filename);
-	dil = DEBUG_ProcessElfFile(fn, load_offset, dyn_addr);
-	DBG_free(fn);
-	if (dil != DIL_ERROR) break;
-	s = (t) ? (t+1) : NULL;
-    }
-
-    DBG_free(paths);
-    return dil;
-}
-
-static enum DbgInfoLoad DEBUG_ProcessElfObject(const char* filename,
-					       void *load_offset,
-					       unsigned int* dyn_addr)
-{
-   enum DbgInfoLoad	dil = DIL_ERROR;
-
-   if (filename == NULL) return DIL_ERROR;
-   if (DEBUG_FindModuleByName(filename, DMT_ELF)) return DIL_LOADED;
-
-   if (strstr (filename, "libstdc++")) return DIL_ERROR; /* We know we can't do it */
-   dil = DEBUG_ProcessElfFile(filename, load_offset, dyn_addr);
-
-   /* if relative pathname, try some absolute base dirs */
-   if (dil == DIL_ERROR && !strchr(filename, '/')) {
-      dil = DEBUG_ProcessElfFileFromPath(filename, load_offset, dyn_addr, getenv("PATH"));
-      if (dil == DIL_ERROR)
-	dil = DEBUG_ProcessElfFileFromPath(filename, load_offset, dyn_addr, getenv("LD_LIBRARY_PATH"));
-      if (dil == DIL_ERROR)
-	dil = DEBUG_ProcessElfFileFromPath(filename, load_offset, dyn_addr, getenv("WINEDLLPATH"));
-   }
-
-   DEBUG_ReportDIL(dil, "ELF", filename, load_offset);
-
-   return dil;
-}
-
-static	BOOL	DEBUG_WalkList(struct r_debug* dbg_hdr)
-{
-    void *lm_addr;
-    struct link_map     lm;
-    Elf32_Ehdr	        ehdr;
-    char		bufstr[256];
-
-    /*
-     * Now walk the linked list.  In all known ELF implementations,
-     * the dynamic loader maintains this linked list for us.  In some
-     * cases the first entry doesn't appear with a name, in other cases it
-     * does.
-     */
-    for (lm_addr = (void *)dbg_hdr->r_map; lm_addr; lm_addr = (void *)lm.l_next) {
-	if (!DEBUG_READ_MEM_VERBOSE(lm_addr, &lm, sizeof(lm)))
-	    return FALSE;
-
-	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((void*)lm.l_name, bufstr, sizeof(bufstr))) {
-	    bufstr[sizeof(bufstr) - 1] = '\0';
-	    DEBUG_ProcessElfObject(bufstr, (void *)lm.l_addr, NULL);
-	}
-    }
-
-    return TRUE;
-}
-
-static BOOL DEBUG_RescanElf(void)
-{
-    struct r_debug        dbg_hdr;
-
-    if (!DEBUG_CurrProcess ||
-	!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_CurrProcess->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
-       return FALSE;
-
-    switch (dbg_hdr.r_state) {
-    case RT_CONSISTENT:
-       DEBUG_WalkList(&dbg_hdr);
-       DEBUG_CheckDelayedBP();
-       break;
-    case RT_ADD:
-       break;
-    case RT_DELETE:
-       /* FIXME: this is not currently handled, would need some kind of mark&sweep algo */
-      break;
-    }
-    return FALSE;
-}
-
-enum DbgInfoLoad	DEBUG_ReadExecutableDbgInfo(const char* exe_name)
-{
-    Elf32_Dyn		dyn;
-    struct r_debug      dbg_hdr;
-    enum DbgInfoLoad	dil = DIL_NOINFO;
-    unsigned int	dyn_addr;
-
-    /*
-     * Make sure we can stat and open this file.
-     */
-    if (exe_name == NULL) goto leave;
-    DEBUG_ProcessElfObject(exe_name, 0, &dyn_addr);
-
-    do {
-	if (!DEBUG_READ_MEM_VERBOSE((void*)dyn_addr, &dyn, sizeof(dyn)))
-	    goto leave;
-	dyn_addr += sizeof(dyn);
-    } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
-    if (dyn.d_tag == DT_NULL) goto leave;
-
-    /*
-     * OK, now dig into the actual tables themselves.
-     */
-    if (!DEBUG_READ_MEM_VERBOSE((void*)dyn.d_un.d_ptr, &dbg_hdr, sizeof(dbg_hdr)))
-	goto leave;
-
-    assert(!DEBUG_CurrProcess->dbg_hdr_addr);
-    DEBUG_CurrProcess->dbg_hdr_addr = (unsigned long)dyn.d_un.d_ptr;
-
-    if (dbg_hdr.r_brk) {
-	DBG_VALUE	value;
-
-	WINE_TRACE("Setting up a breakpoint on r_brk(%lx)\n", (unsigned long)dbg_hdr.r_brk);
-
-	DEBUG_SetBreakpoints(FALSE);
-	value.type = NULL;
-	value.cookie = DV_TARGET;
-	value.addr.seg = 0;
-	value.addr.off = (DWORD)dbg_hdr.r_brk;
-	DEBUG_AddBreakpoint(&value, DEBUG_RescanElf, TRUE);
-	DEBUG_SetBreakpoints(TRUE);
-    }
-
-    dil = DEBUG_WalkList(&dbg_hdr);
-
- leave:
-    return dil;
-}
-
-/* FIXME: merge with some of the routines above */
-int read_elf_info(const char* filename, unsigned long tab[])
-{
-    static const unsigned char elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
-    char*	addr;
-    Elf32_Ehdr* ehptr;
-    Elf32_Shdr* spnt;
-    char*       shstrtab;
-    int	       	i;
-    int         ret = 0;
-    HANDLE      hFile;
-    HANDLE      hMap = 0;
-
-    addr = NULL;
-    hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
-                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-    if (hFile == INVALID_HANDLE_VALUE) goto leave;
-    hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
-    if (hMap == 0) goto leave;
-    addr = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
-    if (addr == NULL) goto leave;
-
-    ehptr = (Elf32_Ehdr*) addr;
-    if (memcmp(ehptr->e_ident, elf_signature, sizeof(elf_signature))) goto leave;
-
-    spnt = (Elf32_Shdr*) (addr + ehptr->e_shoff);
-    shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
-
-    tab[0] = tab[1] = tab[2] = 0;
-    for (i = 0; i < ehptr->e_shnum; i++)
-    {
-    }
-    ret = 1;
- leave:
-    if (addr != NULL) UnmapViewOfFile(addr);
-    if (hMap != 0) CloseHandle(hMap);
-    if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
-    return ret;
-}
-
-#else	/* !__ELF__ */
-
-enum DbgInfoLoad	DEBUG_ReadExecutableDbgInfo(const char* exe_name)
-{
-  return FALSE;
-}
-
-int read_elf_info(const char* filename, unsigned long tab[])
-{
-    return 0;
-}
-
-#endif  /* __ELF__ */
Index: programs/winedbg/winedbg.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/programs/winedbg/winedbg.c,v
retrieving revision 1.17
diff -u -u -r1.17 winedbg.c
--- programs/winedbg/winedbg.c	15 Dec 2003 19:53:08 -0000	1.17
+++ programs/winedbg/winedbg.c	31 Jan 2004 10:51:04 -0000
@@ -674,8 +674,8 @@
 
 static	BOOL	DEBUG_HandleDebugEvent(DEBUG_EVENT* de)
 {
-    char		buffer[256];
-    DWORD cont = DBG_CONTINUE;
+    char	buffer[256];
+    DWORD       cont = DBG_CONTINUE;
 
     DEBUG_CurrPid = de->dwProcessId;
     DEBUG_CurrTid = de->dwThreadId;
@@ -782,24 +782,30 @@
             WINE_ERR("Couldn't create thread\n");
             break;
         }
+        else
+        {
+            struct elf_info     elf_info;
 
-        DEBUG_InitCurrProcess();
-        DEBUG_InitCurrThread();
-
-        /* module is either PE, NE or ELF module (for WineLib), but all
-         * are loaded with wine, so load its symbols, then the main module
-         */
-        do
-        {
-            char*   ptr = getenv("WINELOADER");
-
-            if (!ptr || DEBUG_ReadExecutableDbgInfo( ptr ) == DIL_ERROR)
-                DEBUG_ReadExecutableDbgInfo( "wine" );
-        } while (0);
+            DEBUG_InitCurrProcess();
+            DEBUG_InitCurrThread();
 
-        DEBUG_LoadModule32(DEBUG_CurrProcess->imageName, de->u.CreateProcessInfo.hFile,
-                           de->u.CreateProcessInfo.lpBaseOfImage);
+            elf_info.flags = ELF_INFO_MODULE;
 
+            if (DEBUG_ReadWineLoaderDbgInfo(DEBUG_CurrProcess->handle, &elf_info) != DIL_ERROR &&
+                DEBUG_SetElfSoLoadBreakpoint(&elf_info))
+            {
+                /* then load the main module's symbols */
+                DEBUG_LoadPEModule(DEBUG_CurrProcess->imageName, 
+                                   de->u.CreateProcessInfo.hFile,
+                                   de->u.CreateProcessInfo.lpBaseOfImage);
+            }
+            else
+            {
+                DEBUG_DelThread(DEBUG_CurrProcess->threads);
+                DEBUG_DelProcess(DEBUG_CurrProcess);
+                DEBUG_Printf("Couldn't load process\n");
+            }
+        }
         break;
 
     case EXIT_THREAD_DEBUG_EVENT:
@@ -850,7 +856,7 @@
                    de->u.LoadDll.dwDebugInfoFileOffset,
                    de->u.LoadDll.nDebugInfoSize);
         _strupr(buffer);
-        DEBUG_LoadModule32(buffer, de->u.LoadDll.hFile, de->u.LoadDll.lpBaseOfDll);
+        DEBUG_LoadPEModule(buffer, de->u.LoadDll.hFile, de->u.LoadDll.lpBaseOfDll);
         DEBUG_CheckDelayedBP();
         if (DBG_IVAR(BreakOnDllLoad))
         {
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ programs/winedbg/elf.c	2004-02-02 23:03:43.000000000 +0100
@@ -0,0 +1,591 @@
+/*
+ * File elf.c - processing of ELF files
+ *
+ * Copyright (C) 1996, Eric Youngdale.
+ *		 1999-2004 Eric Pouech
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+#include "debugger.h"
+
+#if defined(__svr4__) || defined(__sun)
+#define __ELF__
+#endif
+
+#ifdef __ELF__
+#ifdef HAVE_ELF_H
+# include <elf.h>
+#endif
+#ifdef HAVE_LINK_H
+# include <link.h>
+#endif
+#ifdef HAVE_SYS_LINK_H
+# include <sys/link.h>
+#endif
+#endif
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
+
+typedef struct tagELF_DBG_INFO
+{
+    void *elf_addr;
+} ELF_DBG_INFO;
+
+#ifdef __ELF__
+
+/*
+ * Walk through the entire symbol table and add any symbols we find there.
+ * This can be used in cases where we have stripped ELF shared libraries,
+ * or it can be used in cases where we have data symbols for which the address
+ * isn't encoded in the stabs.
+ *
+ * This is all really quite easy, since we don't have to worry about line
+ * numbers or local data variables.
+ */
+static int DEBUG_ProcessElfSymtab(DBG_MODULE* module, const char* addr,
+				  void *load_addr, const Elf32_Shdr* symtab,
+				  const Elf32_Shdr* strtab)
+{
+    const char*         curfile = NULL;
+    struct name_hash*   curr_sym = NULL;
+    int		        flags;
+    int		        i;
+    DBG_VALUE           new_value;
+    int		        nsym;
+    const char*         strp;
+    const char*         symname;
+    const Elf32_Sym*    symp;
+
+    symp = (Elf32_Sym *)(addr + symtab->sh_offset);
+    nsym = symtab->sh_size / sizeof(*symp);
+    strp = (char *)(addr + strtab->sh_offset);
+
+    for (i = 0; i < nsym; i++, symp++)
+    {
+        /*
+         * Ignore certain types of entries which really aren't of that much
+         * interest.
+         */
+        if (ELF32_ST_TYPE(symp->st_info) == STT_SECTION || 
+            symp->st_shndx == STN_UNDEF)
+        {
+            continue;
+        }
+
+        symname = strp + symp->st_name;
+
+        /*
+         * Save the name of the current file, so we have a way of tracking
+         * static functions/data.
+         */
+        if (ELF32_ST_TYPE(symp->st_info) == STT_FILE)
+        {
+            curfile = symname;
+            continue;
+        }
+
+        new_value.type = NULL;
+        new_value.addr.seg = 0;
+        new_value.addr.off = (unsigned long)load_addr + symp->st_value;
+        new_value.cookie = DV_TARGET;
+        flags = SYM_WINE | ((ELF32_ST_TYPE(symp->st_info) == STT_FUNC)
+                            ? SYM_FUNC : SYM_DATA);
+        if (ELF32_ST_BIND(symp->st_info) == STB_GLOBAL)
+            curr_sym = DEBUG_AddSymbol(symname, &new_value, NULL, flags);
+        else
+            curr_sym = DEBUG_AddSymbol(symname, &new_value, curfile, flags);
+
+        /*
+         * Record the size of the symbol.  This can come in handy in
+         * some cases.  Not really used yet, however.
+         */
+        if (symp->st_size != 0)
+            DEBUG_SetSymbolSize(curr_sym, symp->st_size);
+    }
+
+    return TRUE;
+}
+
+/*
+ * Loads the symbolic information from ELF module stored in 'filename'
+ * the module has been loaded at 'load_offset' address, so symbols' address
+ * relocation is performed
+ * returns
+ *	-1 if the file cannot be found/opened
+ *	0 if the file doesn't contain symbolic info (or this info cannot be
+ *	read or parsed)
+ *	1 on success
+ */
+enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module)
+{
+    enum DbgInfoLoad    dil = DIL_ERROR;
+    char*	        addr = (char*)0xffffffff;
+    int		        fd = -1;
+    struct stat	        statbuf;
+    const Elf32_Ehdr*   ehptr;
+    const Elf32_Shdr*   spnt;
+    const char*	        shstrtab;
+    int	       	        i;
+    int		        stabsect, stabstrsect, debugsect;
+    
+    if (module->type != DMT_ELF || !module->elf_dbg_info)
+    {
+	WINE_ERR("Bad elf module '%s'\n", module->module_name);
+	return DIL_ERROR;
+    }
+
+    /* check that the file exists, and that the module hasn't been loaded yet */
+    if (stat(module->module_name, &statbuf) == -1) goto leave;
+    if (S_ISDIR(statbuf.st_mode)) goto leave;
+
+    /*
+     * Now open the file, so that we can mmap() it.
+     */
+    if ((fd = open(module->module_name, O_RDONLY)) == -1) goto leave;
+
+    dil = DIL_NOINFO;
+    /*
+     * Now mmap() the file.
+     */
+    addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (addr == (char*)0xffffffff) goto leave;
+
+    /*
+     * Next, we need to find a few of the internal ELF headers within
+     * this thing.  We need the main executable header, and the section
+     * table.
+     */
+    ehptr = (Elf32_Ehdr*)addr;
+    spnt = (Elf32_Shdr*)(addr + ehptr->e_shoff);
+    shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
+
+    stabsect = stabstrsect = debugsect = -1;
+
+    for (i = 0; i < ehptr->e_shnum; i++)
+    {
+	if (strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0)
+	    stabsect = i;
+	if (strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0)
+	    stabstrsect = i;
+	if (strcmp(shstrtab + spnt[i].sh_name, ".debug_info") == 0)
+	    debugsect = i;
+    }
+
+    if (stabsect != -1 && stabstrsect != -1)
+    {
+        /*
+         * OK, now just parse all of the stabs.
+         */
+        if (DEBUG_ParseStabs(addr,
+                             module->elf_dbg_info->elf_addr,
+                             spnt[stabsect].sh_offset,
+                             spnt[stabsect].sh_size,
+                             spnt[stabstrsect].sh_offset,
+                             spnt[stabstrsect].sh_size))
+        {
+            dil = DIL_LOADED;
+        }
+        else
+        {
+            dil = DIL_ERROR;
+            WINE_WARN("Couldn't read correctly read stabs\n");
+            goto leave;
+        }
+    }
+    else if (debugsect != -1)
+    {
+        /* Dwarf 2 debug information */
+        dil = DIL_NOT_SUPPORTED;
+    }
+    /* now load dynamic symbol info */
+    for (i = 0; i < ehptr->e_shnum; i++)
+    {
+	if ((strcmp(shstrtab + spnt[i].sh_name, ".symtab") == 0) &&
+	    (spnt[i].sh_type == SHT_SYMTAB))
+	    DEBUG_ProcessElfSymtab(module, addr, module->elf_dbg_info->elf_addr,
+				   spnt + i, spnt + spnt[i].sh_link);
+
+	if ((strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0) &&
+	    (spnt[i].sh_type == SHT_DYNSYM))
+	    DEBUG_ProcessElfSymtab(module, addr, module->elf_dbg_info->elf_addr,
+				   spnt + i, spnt + spnt[i].sh_link);
+    }
+
+leave:
+    if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
+    if (fd != -1) close(fd);
+
+    return dil;
+}
+
+/*
+ * Loads the information for ELF module stored in 'filename'
+ * the module has been loaded at 'load_offset' address
+ * returns
+ *	-1 if the file cannot be found/opened
+ *	0 if the file doesn't contain symbolic info (or this info cannot be
+ *	read or parsed)
+ *	1 on success
+ */
+static enum DbgInfoLoad DEBUG_ProcessElfFile(HANDLE hProcess,
+                                             const char* filename,
+					     void *load_offset,
+					     struct elf_info* elf_info)
+{
+    static const unsigned char elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
+    enum DbgInfoLoad    dil = DIL_ERROR;
+    const char*	        addr = (char*)0xffffffff;
+    int		        fd = -1;
+    struct stat	        statbuf;
+    const Elf32_Ehdr*   ehptr;
+    const Elf32_Shdr*   spnt;
+    const Elf32_Phdr*	ppnt;
+    const char*         shstrtab;
+    int	       	        i;
+    DWORD	        delta;
+
+    WINE_TRACE("Processing elf file '%s' at %p\n", filename, load_offset);
+
+    /* check that the file exists, and that the module hasn't been loaded yet */
+    if (stat(filename, &statbuf) == -1) goto leave;
+
+    /*
+     * Now open the file, so that we can mmap() it.
+     */
+    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*)-1) goto leave;
+
+    dil = DIL_NOINFO;
+
+    /*
+     * Next, we need to find a few of the internal ELF headers within
+     * this thing.  We need the main executable header, and the section
+     * table.
+     */
+    ehptr = (Elf32_Ehdr*)addr;
+    if (memcmp(ehptr->e_ident, elf_signature, sizeof(elf_signature))) goto leave;
+
+    spnt = (Elf32_Shdr*)(addr + ehptr->e_shoff);
+    shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
+
+    /* if non relocatable ELF, then remove fixed address from computation
+     * otherwise, all addresses are zero based
+     */
+    delta = (load_offset == 0) ? ehptr->e_entry : 0;
+
+    /* grab size of module once loaded in memory */
+    ppnt = (Elf32_Phdr*)(addr + ehptr->e_phoff);
+    elf_info->size = 0;
+    for (i = 0; i < ehptr->e_phnum; i++)
+    {
+	if (ppnt[i].p_type != PT_LOAD) continue;
+	if (elf_info->size < ppnt[i].p_vaddr - delta + ppnt[i].p_memsz)
+	    elf_info->size = ppnt[i].p_vaddr - delta + ppnt[i].p_memsz;
+    }
+
+    for (i = 0; i < ehptr->e_shnum; i++)
+    {
+	if (strcmp(shstrtab + spnt[i].sh_name, ".bss") == 0 &&
+	    spnt[i].sh_type == SHT_NOBITS)
+        {
+	    if (elf_info->size < spnt[i].sh_addr - delta + spnt[i].sh_size)
+		elf_info->size = spnt[i].sh_addr - delta + spnt[i].sh_size;
+	}
+	if (strcmp(shstrtab + spnt[i].sh_name, ".dynamic") == 0 &&
+	    spnt[i].sh_type == SHT_DYNAMIC)
+        {
+	    if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
+            {
+                Elf32_Dyn       dyn;
+                char*           ptr = (char*)spnt[i].sh_addr;
+                unsigned long   len;
+
+                do
+                {
+                    if (!ReadProcessMemory(hProcess, ptr, &dyn, sizeof(dyn), &len) ||
+                        len != sizeof(dyn) ||
+                        !((dyn.d_tag >= 0 && 
+                           dyn.d_tag < DT_NUM+DT_PROCNUM+DT_EXTRANUM) ||
+                          (dyn.d_tag >= DT_LOOS && dyn.d_tag < DT_HIOS) ||
+                          (dyn.d_tag >= DT_LOPROC && dyn.d_tag < DT_HIPROC))
+                        )
+                        dyn.d_tag = DT_NULL;
+                    ptr += sizeof(dyn);
+                } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
+                if (dyn.d_tag == DT_NULL)
+                {
+                    dil = DIL_ERROR;
+                    goto leave;
+                }
+                elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
+            }
+	}
+    }
+
+    elf_info->segments[0] = elf_info->segments[1] = elf_info->segments[2] = 0;
+    if (elf_info->flags & ELF_INFO_PATH)
+    {
+        strncpy(elf_info->elf_path, filename, elf_info->elf_path_len);
+        elf_info->elf_path[elf_info->elf_path_len - 1] = '\0';
+    }
+
+    elf_info->load_addr = (load_offset == 0) ? (void *)ehptr->e_entry : load_offset;
+
+    if (elf_info->flags & ELF_INFO_MODULE)
+    {
+        DBG_MODULE* module;
+
+        module = DEBUG_AddModule(filename, DMT_ELF, elf_info->load_addr, elf_info->size, 0);
+        if (module)
+        {
+            if ((module->elf_dbg_info = DBG_alloc(sizeof(ELF_DBG_INFO))) == NULL) 
+            {
+                WINE_ERR("OOM\n");
+                exit(0);
+            }
+            module->elf_dbg_info->elf_addr = load_offset;
+            module->dil = dil = DEBUG_LoadElfStabs(module);
+        }
+        else dil = DIL_ERROR;
+    }
+
+leave:
+    if (addr != (char*)0xffffffff) munmap((void*)addr, statbuf.st_size);
+    if (fd != -1) close(fd);
+
+    return dil;
+}
+
+static enum DbgInfoLoad DEBUG_ProcessElfFileFromPath(HANDLE hProcess,
+                                                     const char * filename,
+						     void *load_offset,
+						     const char* path,
+                                                     struct elf_info* elf_info)
+{
+    enum DbgInfoLoad	dil = DIL_ERROR;
+    char                *s, *t, *fn;
+    char*	        paths = NULL;
+
+    if (!path) return dil;
+
+    for (s = paths = DBG_strdup(path); s && *s; s = (t) ? (t+1) : NULL) 
+    {
+	t = strchr(s, ':');
+	if (t) *t = '\0';
+	fn = (char*)DBG_alloc(strlen(filename) + 1 + strlen(s) + 1);
+	if (!fn) break;
+	strcpy(fn, s );
+	strcat(fn, "/");
+	strcat(fn, filename);
+	dil = DEBUG_ProcessElfFile(hProcess, fn, load_offset, elf_info);
+	DBG_free(fn);
+	if (dil != DIL_ERROR) break;
+	s = (t) ? (t+1) : NULL;
+    }
+
+    DBG_free(paths);
+    return dil;
+}
+
+static enum DbgInfoLoad DEBUG_ProcessElfObject(HANDLE hProcess,
+                                               const char* filename,
+                                               void *load_offset,
+					       struct elf_info* elf_info)
+{
+   enum DbgInfoLoad	dil = DIL_ERROR;
+
+   if (filename == NULL || !*filename) return DIL_ERROR;
+   if (DEBUG_FindModuleByName(filename, DMT_ELF))
+   {
+       assert(!(elf_info->flags & ELF_INFO_PATH));
+       return DIL_LOADED;
+   }
+
+   if (strstr(filename, "libstdc++")) return DIL_ERROR; /* We know we can't do it */
+   dil = DEBUG_ProcessElfFile(hProcess, filename, load_offset, elf_info);
+   /* if relative pathname, try some absolute base dirs */
+   if (dil == DIL_ERROR && !strchr(filename, '/'))
+   {
+       dil = DEBUG_ProcessElfFileFromPath(hProcess, filename, load_offset, 
+                                          getenv("PATH"), elf_info);
+       if (dil == DIL_ERROR)
+           dil = DEBUG_ProcessElfFileFromPath(hProcess, filename, load_offset,
+                                              getenv("LD_LIBRARY_PATH"), elf_info);
+       if (dil == DIL_ERROR)
+           dil = DEBUG_ProcessElfFileFromPath(hProcess, filename, load_offset,
+                                              getenv("WINEDLLPATH"), elf_info);
+   }
+
+   DEBUG_ReportDIL(dil, "ELF", filename, load_offset);
+
+   return dil;
+}
+
+static	BOOL	DEBUG_WalkList(const struct r_debug* dbg_hdr)
+{
+    void*               lm_addr;
+    struct link_map     lm;
+    char		bufstr[256];
+    struct elf_info     elf_info;
+
+    elf_info.flags = ELF_INFO_MODULE;
+    /*
+     * Now walk the linked list.  In all known ELF implementations,
+     * the dynamic loader maintains this linked list for us.  In some
+     * cases the first entry doesn't appear with a name, in other cases it
+     * does.
+     */
+    for (lm_addr = (void *)dbg_hdr->r_map; lm_addr; lm_addr = (void *)lm.l_next)
+    {
+	if (!DEBUG_READ_MEM_VERBOSE(lm_addr, &lm, sizeof(lm)))
+	    return FALSE;
+
+	if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
+	    lm.l_name != NULL &&
+	    DEBUG_READ_MEM_VERBOSE((void*)lm.l_name, bufstr, sizeof(bufstr))) 
+        {
+	    bufstr[sizeof(bufstr) - 1] = '\0';
+            DEBUG_ProcessElfObject(DEBUG_CurrProcess->handle, bufstr, 
+                                   (void *)lm.l_addr, &elf_info);
+	}
+    }
+
+    return TRUE;
+}
+
+static BOOL DEBUG_RescanElf(void)
+{
+    struct r_debug        dbg_hdr;
+
+    if (DEBUG_CurrProcess &&
+	DEBUG_READ_MEM_VERBOSE((void*)DEBUG_CurrProcess->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
+    {
+        switch (dbg_hdr.r_state) 
+        {
+        case RT_CONSISTENT:
+            DEBUG_WalkList(&dbg_hdr);
+            DEBUG_CheckDelayedBP();
+            break;
+        case RT_ADD:
+            break;
+        case RT_DELETE:
+            /* FIXME: this is not currently handled */
+            break;
+        }
+    }
+    return FALSE;
+}
+
+/******************************************************************
+ *		DEBUG_ReadWineLoaderDbgInfo
+ *
+ * Try to find a decent wine executable which could have loader the debuggee
+ */
+enum DbgInfoLoad	DEBUG_ReadWineLoaderDbgInfo(HANDLE hProcess, struct elf_info* elf_info)
+{
+    const char*         ptr;
+    enum DbgInfoLoad    dil;
+
+    /* All binaries are loaded with WINELOADER (if run from tree) or by the
+     * main executable (either wine-kthread or wine-pthread)
+     * Note: the heuristic use to know wether we need to load wine-pthread or 
+     * wine-kthread is not 100% safe
+     */
+    elf_info->flags |= ELF_INFO_DEBUG_HEADER;
+    if ((ptr = getenv("WINELOADER")))
+        dil = DEBUG_ProcessElfObject(hProcess, ptr, 0, elf_info);
+    else 
+    {
+        if ((dil = DEBUG_ProcessElfObject(hProcess, "wine-kthread", 0, elf_info)) == DIL_ERROR)
+            dil = DEBUG_ProcessElfObject(hProcess, "wine-pthread", 0, elf_info);
+    }
+    return dil;
+}
+
+/******************************************************************
+ *		DEBUG_SetElfSoLoadBreakpoint
+ *
+ * Sets a breakpoint to handle .so loading events, so we can add debug info
+ * on the fly
+ */
+BOOL    DEBUG_SetElfSoLoadBreakpoint(const struct elf_info* elf_info)
+{
+    struct r_debug      dbg_hdr;
+    
+    /*
+     * OK, now dig into the actual tables themselves.
+     */
+    if (!DEBUG_READ_MEM_VERBOSE((void*)elf_info->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
+        return FALSE;
+
+    assert(!DEBUG_CurrProcess->dbg_hdr_addr);
+    DEBUG_CurrProcess->dbg_hdr_addr = elf_info->dbg_hdr_addr;
+
+    if (dbg_hdr.r_brk)
+    {
+        DBG_VALUE	value;
+
+        WINE_TRACE("Setting up a breakpoint on r_brk(%lx)\n", 
+                   (unsigned long)dbg_hdr.r_brk);
+
+        DEBUG_SetBreakpoints(FALSE);
+        value.type = NULL;
+        value.cookie = DV_TARGET;
+        value.addr.seg = 0;
+        value.addr.off = (DWORD)dbg_hdr.r_brk;
+        DEBUG_AddBreakpoint(&value, DEBUG_RescanElf, TRUE);
+        DEBUG_SetBreakpoints(TRUE);
+    }
+    
+    return DEBUG_WalkList(&dbg_hdr);
+}
+
+#else	/* !__ELF__ */
+
+enum DbgInfoLoad	DEBUG_ReadExecutableDbgInfo(HANDLE hProcess, struct elf_info* elf_info)
+{
+    return DIL_ERROR;
+}
+
+BOOL    DEBUG_SetElfSoLoadBreakpoint(const struct elf_info* elf_info)
+{
+    return FALSE;
+}
+
+#endif  /* __ELF__ */
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ programs/winedbg/pe.c	2004-02-01 10:47:09.000000000 +0100
@@ -0,0 +1,513 @@
+/*
+ * File pe.c - handle PE module information
+ *
+ * Copyright (C) 1996, Eric Youngdale.
+ * Copyright (C) 1999, 2000, Ulrich Weigand.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+#include "wine/exception.h"
+#include "wine/debug.h"
+#include "excpt.h"
+#include "debugger.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
+
+#define MAX_PATHNAME_LEN 1024
+
+typedef struct
+{
+    DWORD  from;
+    DWORD  to;
+
+} OMAP_DATA;
+
+typedef struct tagMSC_DBG_INFO
+{
+    int			        nsect;
+    PIMAGE_SECTION_HEADER       sectp;
+    int			        nomap;
+    OMAP_DATA*                  omapp;
+
+} MSC_DBG_INFO;
+
+/***********************************************************************
+ *           DEBUG_LocateDebugInfoFile
+ *
+ * NOTE: dbg_filename must be at least MAX_PATHNAME_LEN bytes in size
+ */
+static void DEBUG_LocateDebugInfoFile(const char* filename, char* dbg_filename)
+{
+    char*       str1 = DBG_alloc(MAX_PATHNAME_LEN);
+    char*       str2 = DBG_alloc(MAX_PATHNAME_LEN*10);
+    const char* file;
+    char*       name_part;
+
+    file = strrchr(filename, '\\');
+    if (file == NULL) file = filename; else file++;
+
+    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
+        lstrcpyn(dbg_filename, filename, MAX_PATHNAME_LEN);
+    DBG_free(str1);
+    DBG_free(str2);
+}
+
+/***********************************************************************
+ *           DEBUG_MapDebugInfoFile
+ */
+void*	DEBUG_MapDebugInfoFile(const char* name, DWORD offset, DWORD size,
+                               HANDLE* hFile, HANDLE* hMap)
+{
+    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 = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
+            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
+ */
+void	DEBUG_UnmapDebugInfoFile(HANDLE hFile, HANDLE hMap, const void* addr)
+{
+    if (addr) UnmapViewOfFile((void*)addr);
+    if (hMap) CloseHandle(hMap);
+    if (hFile!=INVALID_HANDLE_VALUE) CloseHandle(hFile);
+}
+
+/*========================================================================
+ * Process DBG file.
+ */
+static enum DbgInfoLoad DEBUG_ProcessDBGFile(DBG_MODULE* module,
+                                             const char* filename, DWORD timestamp)
+{
+    enum DbgInfoLoad            dil = DIL_ERROR;
+    HANDLE                      hFile = INVALID_HANDLE_VALUE, hMap = 0;
+    const BYTE*                 file_map = NULL;
+    PIMAGE_SEPARATE_DEBUG_HEADER hdr;
+    PIMAGE_DEBUG_DIRECTORY      dbg;
+    int                         nDbg;
+
+    WINE_TRACE("Processing DBG file %s\n", filename);
+
+    file_map = DEBUG_MapDebugInfoFile(filename, 0, 0, &hFile, &hMap);
+    if (!file_map)
+    {
+        WINE_ERR("-Unable to peruse .DBG file %s\n", filename);
+        goto leave;
+    }
+
+    hdr = (PIMAGE_SEPARATE_DEBUG_HEADER) file_map;
+
+    if (hdr->TimeDateStamp != timestamp)
+    {
+        WINE_ERR("Warning - %s has incorrect internal timestamp\n", filename);
+        /*
+         *  Well, sometimes this happens to DBG files which ARE REALLY the right .DBG
+         *  files but nonetheless this check fails. Anyway, WINDBG (debugger for
+         *  Windows by Microsoft) loads debug symbols which have incorrect timestamps.
+         */
+    }
+
+
+    dbg = (PIMAGE_DEBUG_DIRECTORY) 
+        (file_map + sizeof(*hdr) + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)
+         + hdr->ExportedNamesSize);
+
+    nDbg = hdr->DebugDirectorySize / sizeof(*dbg);
+
+    dil = DEBUG_ProcessDebugDirectory(module, file_map, dbg, nDbg);
+
+leave:
+    DEBUG_UnmapDebugInfoFile(hFile, hMap, file_map);
+    return dil;
+}
+
+
+/*========================================================================
+ * Process MSC debug information in PE file.
+ */
+enum DbgInfoLoad DEBUG_RegisterMSCDebugInfo(DBG_MODULE* module, HANDLE hFile,
+                                            void* _nth, unsigned long nth_ofs)
+{
+    enum DbgInfoLoad	   dil = DIL_ERROR;
+    PIMAGE_NT_HEADERS      nth = (PIMAGE_NT_HEADERS)_nth;
+    PIMAGE_DATA_DIRECTORY  dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
+    PIMAGE_DEBUG_DIRECTORY dbg = NULL;
+    int                    nDbg;
+    MSC_DBG_INFO           extra_info = { 0, NULL, 0, NULL };
+    HANDLE	           hMap = 0;
+    const BYTE*            file_map = NULL;
+
+    /* Read in section data */
+
+    module->msc_dbg_info = &extra_info;
+    extra_info.nsect = nth->FileHeader.NumberOfSections;
+    extra_info.sectp = DBG_alloc(extra_info.nsect * sizeof(IMAGE_SECTION_HEADER));
+    if (!extra_info.sectp)
+        goto leave;
+
+    if (!DEBUG_READ_MEM_VERBOSE((char*)module->load_addr +
+                                nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
+                                nth->FileHeader.SizeOfOptionalHeader,
+                                extra_info.sectp,
+                                extra_info.nsect * sizeof(IMAGE_SECTION_HEADER)))
+        goto leave;
+
+    /* Read in debug directory */
+
+    nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
+    if (!nDbg)
+        goto leave;
+
+    dbg = (PIMAGE_DEBUG_DIRECTORY) DBG_alloc(nDbg * sizeof(IMAGE_DEBUG_DIRECTORY));
+    if (!dbg)
+        goto leave;
+
+    if (!DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + dir->VirtualAddress,
+                                dbg, nDbg * sizeof(IMAGE_DEBUG_DIRECTORY)))
+        goto leave;
+
+
+    /* Map in PE file */
+    file_map = DEBUG_MapDebugInfoFile(NULL, 0, 0, &hFile, &hMap);
+    if (!file_map)
+        goto leave;
+
+
+    /* Parse debug directory */
+
+    if (nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED)
+    {
+        /* Debug info is stripped to .DBG file */
+
+        PIMAGE_DEBUG_MISC misc = (PIMAGE_DEBUG_MISC)(file_map + dbg->PointerToRawData);
+
+        if (nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC
+                       || misc->DataType != IMAGE_DEBUG_MISC_EXENAME)
+        {
+            WINE_ERR("-Debug info stripped, but no .DBG file in module %s\n",
+                     module->module_name);
+            goto leave;
+        }
+
+        dil = DEBUG_ProcessDBGFile(module, misc->Data, nth->FileHeader.TimeDateStamp);
+    }
+    else
+    {
+        /* Debug info is embedded into PE module */
+        /* FIXME: the nDBG information we're manipulating comes from the debuggee
+         * address space. However, the following code will be made against the
+         * version mapped in the debugger address space. There are cases (for example
+         * when the PE sections are compressed in the file and become decompressed
+         * in the debuggee address space) where the two don't match.
+         * Therefore, redo the DBG information lookup with the mapped data
+         */
+        PIMAGE_NT_HEADERS      mpd_nth = (PIMAGE_NT_HEADERS)(file_map + nth_ofs);
+        PIMAGE_DATA_DIRECTORY  mpd_dir;
+        PIMAGE_DEBUG_DIRECTORY mpd_dbg = NULL;
+
+        /* sanity checks */
+        if (mpd_nth->Signature != IMAGE_NT_SIGNATURE ||
+             mpd_nth->FileHeader.NumberOfSections != nth->FileHeader.NumberOfSections ||
+             (mpd_nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) != 0)
+            goto leave;
+        mpd_dir = mpd_nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
+
+        if ((mpd_dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY)) != nDbg)
+            goto leave;
+
+        mpd_dbg = (PIMAGE_DEBUG_DIRECTORY)(file_map + mpd_dir->VirtualAddress);
+
+        dil = DEBUG_ProcessDebugDirectory(module, file_map, mpd_dbg, nDbg);
+    }
+
+
+leave:
+    module->msc_dbg_info = NULL;
+
+    DEBUG_UnmapDebugInfoFile(0, hMap, file_map);
+    if (extra_info.sectp) DBG_free(extra_info.sectp);
+    if (dbg) DBG_free(dbg);
+    return dil;
+}
+
+
+/*========================================================================
+ * look for stabs information in PE header (it's how mingw compiler provides its
+ * debugging information), and also wine PE <-> ELF linking through .wsolnk sections
+ */
+enum DbgInfoLoad 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;
+    PIMAGE_NT_HEADERS		nth = (PIMAGE_NT_HEADERS)_nth;
+    enum DbgInfoLoad		dil = DIL_ERROR;
+
+    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)))
+            continue;
+
+        if (!strcasecmp(pe_seg.Name, ".stab"))
+        {
+            stabs = pe_seg.VirtualAddress;
+            stabsize = pe_seg.SizeOfRawData;
+        }
+        else if (!strncasecmp(pe_seg.Name, ".stabstr", 8))
+        {
+            stabstr = pe_seg.VirtualAddress;
+            stabstrsize = pe_seg.SizeOfRawData;
+        }
+    }
+
+    if (stabstrsize && stabsize)
+    {
+        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))
+            {
+                dil = DEBUG_ParseStabs(s1, 0, 0, stabsize, stabsize, stabstrsize);
+            }
+            else
+            {
+                DEBUG_Printf("couldn't read data block\n");
+            }
+            DBG_free(s1);
+        }
+        else 
+        {
+            DEBUG_Printf("couldn't alloc %d bytes\n", stabsize + stabstrsize);
+        }
+    }
+    else
+    {
+        dil = DIL_NOINFO;
+    }
+    return dil;
+}
+
+/***********************************************************************
+ *			DEBUG_RegisterPEDebugInfo
+ */
+enum DbgInfoLoad	DEBUG_RegisterPEDebugInfo(DBG_MODULE* wmod, HANDLE hFile,
+						  void* _nth, unsigned long nth_ofs)
+{
+    DBG_VALUE			value;
+    char			buffer[512];
+    char			bufstr[256];
+    unsigned int 		i;
+    IMAGE_SECTION_HEADER 	pe_seg;
+    DWORD			pe_seg_ofs;
+    IMAGE_DATA_DIRECTORY 	dir;
+    DWORD			dir_ofs;
+    const char*			prefix;
+    IMAGE_NT_HEADERS*		nth = (PIMAGE_NT_HEADERS)_nth;
+    void*			base = wmod->load_addr;
+
+    value.type = NULL;
+    value.cookie = DV_TARGET;
+    value.addr.seg = 0;
+    value.addr.off = 0;
+
+    /* Add start of DLL */
+    value.addr.off = (unsigned long)base;
+    if ((prefix = strrchr(wmod->module_name, '\\'))) prefix++;
+    else prefix = wmod->module_name;
+
+    DEBUG_AddSymbol(prefix, &value, NULL, SYM_WIN32 | SYM_FUNC);
+
+    /* Add entry point */
+    snprintf(buffer, sizeof(buffer), "%s.EntryPoint", prefix);
+    value.addr.off = (unsigned long)base + nth->OptionalHeader.AddressOfEntryPoint;
+    DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
+
+    /* Add start of sections */
+    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((char*)base + pe_seg_ofs, &pe_seg, sizeof(pe_seg)))
+	    continue;
+	snprintf(buffer, sizeof(buffer), "%s.%s", prefix, pe_seg.Name);
+	value.addr.off = (unsigned long)base + pe_seg.VirtualAddress;
+	DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
+    }
+
+    /* Add exported functions */
+    dir_ofs = nth_ofs +
+	OFFSET_OF(IMAGE_NT_HEADERS,
+		  OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
+    if (DEBUG_READ_MEM_VERBOSE((char*)base + dir_ofs, &dir, sizeof(dir)) && dir.Size)
+    {
+	IMAGE_EXPORT_DIRECTORY 	exports;
+	WORD*			ordinals = NULL;
+	void**			functions = NULL;
+	DWORD*			names = NULL;
+	unsigned int		j;
+
+	if (DEBUG_READ_MEM_VERBOSE((char*)base + dir.VirtualAddress,
+				   &exports, sizeof(exports)) &&
+
+	    ((functions = DBG_alloc(sizeof(functions[0]) * exports.NumberOfFunctions))) &&
+	    DEBUG_READ_MEM_VERBOSE((char*)base + exports.AddressOfFunctions,
+				   functions, sizeof(functions[0]) * exports.NumberOfFunctions) &&
+
+	    ((ordinals = DBG_alloc(sizeof(ordinals[0]) * exports.NumberOfNames))) &&
+	    DEBUG_READ_MEM_VERBOSE((char*)base + (DWORD)exports.AddressOfNameOrdinals,
+				   ordinals, sizeof(ordinals[0]) * exports.NumberOfNames) &&
+
+	    ((names = DBG_alloc(sizeof(names[0]) * exports.NumberOfNames))) &&
+	    DEBUG_READ_MEM_VERBOSE((char*)base + (DWORD)exports.AddressOfNames,
+				   names, sizeof(names[0]) * exports.NumberOfNames))
+        {
+
+	    for (i = 0; i < exports.NumberOfNames; i++)
+            {
+		if (!names[i] ||
+		    !DEBUG_READ_MEM_VERBOSE((char*)base + names[i], bufstr, sizeof(bufstr)))
+		    continue;
+		bufstr[sizeof(bufstr) - 1] = 0;
+		snprintf(buffer, sizeof(buffer), "%s.%s", prefix, bufstr);
+		value.addr.off = (unsigned long)base + (DWORD)functions[ordinals[i]];
+		DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
+	    }
+
+	    for (i = 0; i < exports.NumberOfFunctions; i++)
+            {
+		if (!functions[i]) continue;
+		/* Check if we already added it with a name */
+		for (j = 0; j < exports.NumberOfNames; j++)
+		    if ((ordinals[j] == i) && names[j]) break;
+		if (j < exports.NumberOfNames) continue;
+		snprintf(buffer, sizeof(buffer), "%s.%ld", prefix, i + exports.Base);
+		value.addr.off = (unsigned long)base + (DWORD)functions[i];
+		DEBUG_AddSymbol(buffer, &value, NULL, SYM_WIN32 | SYM_FUNC);
+	    }
+	}
+	DBG_free(functions);
+	DBG_free(ordinals);
+	DBG_free(names);
+    }
+    /* no real debug info, only entry points */
+    return DIL_NOINFO;
+}
+
+/***********************************************************************
+ *			DEBUG_LoadPEModule
+ */
+void	DEBUG_LoadPEModule(const char* name, HANDLE hFile, void* base)
+{
+     IMAGE_NT_HEADERS		pe_header;
+     DWORD			nth_ofs;
+     DBG_MODULE*		wmod = NULL;
+     int 			i;
+     IMAGE_SECTION_HEADER 	pe_seg;
+     DWORD			pe_seg_ofs;
+     DWORD			size = 0;
+     enum DbgInfoLoad		dil = DIL_ERROR;
+
+     /* grab PE Header */
+     if (!DEBUG_READ_MEM_VERBOSE((char*)base + OFFSET_OF(IMAGE_DOS_HEADER, e_lfanew),
+				 &nth_ofs, sizeof(nth_ofs)) ||
+	 !DEBUG_READ_MEM_VERBOSE((char*)base + nth_ofs, &pe_header, sizeof(pe_header)))
+	 return;
+
+     pe_seg_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
+	 pe_header.FileHeader.SizeOfOptionalHeader;
+
+     for (i = 0; i < pe_header.FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg))
+     {
+	 if (!DEBUG_READ_MEM_VERBOSE((char*)base + pe_seg_ofs, &pe_seg, sizeof(pe_seg)))
+	     continue;
+	 if (size < pe_seg.VirtualAddress + pe_seg.SizeOfRawData)
+	     size = pe_seg.VirtualAddress + pe_seg.SizeOfRawData;
+     }
+
+     /* FIXME: we make the assumption that hModule == base */
+     wmod = DEBUG_AddModule(name, DMT_PE, base, size, (HMODULE)base);
+
+     if (wmod)
+     {
+	 dil = DEBUG_RegisterStabsDebugInfo(wmod, hFile, &pe_header, nth_ofs);
+	 if (dil != DIL_LOADED)
+	     dil = DEBUG_RegisterMSCDebugInfo(wmod, hFile, &pe_header, nth_ofs);
+	 if (dil != DIL_LOADED)
+	     dil = DEBUG_RegisterPEDebugInfo(wmod, hFile, &pe_header, nth_ofs);
+	 wmod->dil = dil;
+     }
+
+     DEBUG_ReportDIL(dil, "32bit DLL", name, base);
+}


More information about the wine-patches mailing list