From d72e2deaecf18a14f8b18e8adf61e7f68a9ede89 Mon Sep 17 00:00:00 2001 From: Sergey Turchanov Date: Sun, 24 Jan 1999 09:46:21 +0000 Subject: [PATCH] Fixed source line matching for functions in DEBUG_ProcessCoffDebug; searching for DBG and PDB files. --- debugger/msc.c | 135 +++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 61 deletions(-) diff --git a/debugger/msc.c b/debugger/msc.c index 80ed6cbb65d..e30ee21dcfe 100644 --- a/debugger/msc.c +++ b/debugger/msc.c @@ -35,6 +35,40 @@ #include "xmalloc.h" #include "file.h" +/* + *dbg_filename must be at least MAX_PATHNAME_LEN bytes in size +*/ +static void LocateDebugInfoFile(char *filename, char *dbg_filename) +{ + char str1[MAX_PATHNAME_LEN*10]; + char str2[MAX_PATHNAME_LEN]; + char *file; + char *name_part; + DOS_FULL_NAME fullname; + + file = strrchr(filename, '\\'); + if( file == NULL ) file = filename; else file++; + + if (GetEnvironmentVariable32A("_NT_SYMBOL_PATH", str1, sizeof(str1))) + if (SearchPath32A(str1, file, NULL, sizeof(str2), str2, &name_part)) + goto ok; + if (GetEnvironmentVariable32A("_NT_ALT_SYMBOL_PATH", str1, sizeof(str1))) + if (SearchPath32A(str1, file, NULL, sizeof(str2), str2, &name_part)) + goto ok; + if (SearchPath32A(NULL, file, NULL, sizeof(str2), str2, &name_part)) + goto ok; + else + { +quit: memcpy(dbg_filename, filename, MAX_PATHNAME_LEN); + return; + } +ok: + if (DOSFS_GetFullName(str2, TRUE, &fullname)) + memcpy(dbg_filename, fullname.long_name, MAX_PATHNAME_LEN); + else + goto quit; + return; +} /* * This is an index we use to keep track of the debug information * when we have multiple sources. We use the same database to also @@ -942,6 +976,9 @@ DEBUG_RegisterDebugInfo( HMODULE32 hModule, const char *module_name, if( (dbgptr->Type != IMAGE_DEBUG_TYPE_MISC) || (PE_HEADER(hModule)->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) != 0 ) { + char fn[PATH_MAX]; + int fd = -1; + DOS_FULL_NAME full_name; struct deferred_debug_info* deefer = (struct deferred_debug_info *) xmalloc(sizeof(*deefer)); deefer->module = hModule; @@ -952,40 +989,29 @@ DEBUG_RegisterDebugInfo( HMODULE32 hModule, const char *module_name, * upon the type, but this is always enough so we are able * to proceed if we know what we need to do next. */ - /* in some cases, debug information has not been mapped, so load it... - * basically, the PE loader maps all sections (data, resources...), but doesn't map + /* basically, the PE loader maps all sections (data, resources...), but doesn't map * the DataDirectory array's content. One its entry contains the *beloved* * debug information. (Note the DataDirectory is mapped, not its content) */ - if (IsBadReadPtr32((void*)hModule, dbgptr->PointerToRawData + dbgptr->SizeOfData)) - { - char fn[PATH_MAX]; - int fd = -1; - DOS_FULL_NAME full_name; - if (GetModuleFileName32A(hModule, fn, sizeof(fn)) > 0 && - DOSFS_GetFullName(fn, TRUE, &full_name) && - (fd = open(full_name.long_name, O_RDONLY)) > 0) - { - deefer->dbg_info = mmap(NULL, dbgptr->SizeOfData, - PROT_READ, MAP_PRIVATE, fd, dbgptr->PointerToRawData); - close(fd); - if( deefer->dbg_info == (char *) 0xffffffff ) - { - free(deefer); - break; - } - } - else + if (GetModuleFileName32A(hModule, fn, sizeof(fn)) > 0 && + DOSFS_GetFullName(fn, TRUE, &full_name) && + (fd = open(full_name.long_name, O_RDONLY)) > 0) + { + deefer->dbg_info = mmap(NULL, dbgptr->SizeOfData, + PROT_READ, MAP_PRIVATE, fd, dbgptr->PointerToRawData); + close(fd); + if( deefer->dbg_info == (char *) 0xffffffff ) { free(deefer); - fprintf(stderr, " (not mapped: fn=%s, lfn=%s, fd=%d)", fn, full_name.long_name, fd); break; } } else { - deefer->dbg_info = (char *)(hModule + dbgptr->PointerToRawData); + free(deefer); + fprintf(stderr, " (not mapped: fn=%s, lfn=%s, fd=%d)", fn, full_name.long_name, fd); + break; } deefer->dbg_size = dbgptr->SizeOfData; deefer->dbgdir = dbgptr; @@ -1402,7 +1428,8 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) for(j=0; j < nfiles; j++) { i = 0; - for(k=0; k < coff_files[j].linecnt; k++) + if( coff_files[j].neps != 0 ) + for(k=0; k < coff_files[j].linecnt; k++) { /* * Another monstrosity caused by the fact that we are using @@ -1418,17 +1445,13 @@ DEBUG_ProcessCoff(struct deferred_debug_info * deefer) */ while(TRUE) { + if (i+1 >= coff_files[j].neps) break; DEBUG_GetSymbolAddr(coff_files[j].entries[i+1], &new_addr); - if( (i+1 < coff_files[j].neps) - && ( ((unsigned int) deefer->load_addr + linepnt->VirtualAddr) - >= new_addr.off) ) - { + if( (((unsigned int)deefer->load_addr + + linepnt->VirtualAddr) >= new_addr.off) ) + { i++; - } - else - { - break; - } + } else break; } /* @@ -1808,7 +1831,7 @@ DEBUG_ProcessPDBFile(struct deferred_debug_info * deefer, char * full_filename) unsigned short * extent_table; int fd = -1; struct file_ent * fent; - char * filename; + char * filename[MAX_PATHNAME_LEN]; struct file_list * filelist = NULL; unsigned int gsym_record = 0; char * gsymtab = NULL; @@ -1827,25 +1850,8 @@ DEBUG_ProcessPDBFile(struct deferred_debug_info * deefer, char * full_filename) unsigned short * table; char * toc; unsigned int toc_blocks; - - /* - * FIXME - we should use some kind of search path mechanism to locate - * PDB files. Right now we just look in the current working directory, - * which works much of the time, I guess. Ideally we should be able to - * map the filename back using the settings in wine.ini and perhaps - * we could find it there. This bit of coding is left as an exercise - * for the reader. :-). - */ - filename = strrchr(full_filename, '\\'); - if( filename == NULL ) - { - filename = full_filename; - } - else - { - filename++; - } + LocateDebugInfoFile(full_filename, filename); status = stat(filename, &statbuf); if( status == -1 ) { @@ -2173,21 +2179,23 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename) IMAGE_SECTION_HEADER * sectp; struct stat statbuf; int status; - - status = stat(filename, &statbuf); + char dbg_file[MAX_PATHNAME_LEN]; + + LocateDebugInfoFile(filename, dbg_file); + status = stat(dbg_file, &statbuf); if( status == -1 ) { - fprintf(stderr, "-Unable to open .DBG file %s\n", filename); + fprintf(stderr, "-Unable to open .DBG file %s\n", dbg_file); goto leave; } /* * Now open the file, so that we can mmap() it. */ - fd = open(filename, O_RDONLY); + fd = open(dbg_file, O_RDONLY); if( fd == -1 ) { - fprintf(stderr, "Unable to open .DBG file %s\n", filename); + fprintf(stderr, "Unable to open .DBG file %s\n", dbg_file); goto leave; } @@ -2199,7 +2207,7 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename) MAP_PRIVATE, fd, 0); if( addr == (char *) 0xffffffff ) { - fprintf(stderr, "Unable to mmap .DBG file %s\n", filename); + fprintf(stderr, "Unable to mmap .DBG file %s\n", dbg_file); goto leave; } @@ -2208,11 +2216,16 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename) if( pdbg->TimeDateStamp != deefer->dbgdir->TimeDateStamp ) { fprintf(stderr, "Warning - %s has incorrect internal timestamp\n", - filename); - goto leave; + dbg_file); +/* goto leave; */ +/* + 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. +*/ } - fprintf(stderr, "Processing symbols from %s...\n", filename); + fprintf(stderr, "Processing symbols from %s...\n", dbg_file); dbghdr = (PIMAGE_DEBUG_DIRECTORY) ( addr + sizeof(*pdbg) + pdbg->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)