~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/tools/winedump/debug.c

Version: ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*
  2  * Made after:
  3  *      CVDump - Parses through a Visual Studio .DBG file in CodeView 4 format
  4  *      and dumps the info to STDOUT in a human-readable format
  5  *
  6  *      Copyright 2000 John R. Sheets
  7  *
  8  * This library is free software; you can redistribute it and/or
  9  * modify it under the terms of the GNU Lesser General Public
 10  * License as published by the Free Software Foundation; either
 11  * version 2.1 of the License, or (at your option) any later version.
 12  *
 13  * This library is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  * Lesser General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU Lesser General Public
 19  * License along with this library; if not, write to the Free Software
 20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 21  */
 22 
 23 #include "config.h"
 24 #include "wine/port.h"
 25 
 26 #include <stdlib.h>
 27 #include <stdarg.h>
 28 #include <stdio.h>
 29 #ifdef HAVE_UNISTD_H
 30 # include <unistd.h>
 31 #endif
 32 #include <time.h>
 33 #ifdef HAVE_SYS_TYPES_H
 34 # include <sys/types.h>
 35 #endif
 36 #ifdef HAVE_SYS_STAT_H
 37 # include <sys/stat.h>
 38 #endif
 39 #ifdef HAVE_SYS_MMAN_H
 40 #include <sys/mman.h>
 41 #endif
 42 #include <fcntl.h>
 43 
 44 #include "windef.h"
 45 #include "winbase.h"
 46 #include "winedump.h"
 47 #include "wine/mscvpdb.h"
 48 
 49 /*
 50  * .DBG File Layout:
 51  *
 52  * IMAGE_SEPARATE_DEBUG_HEADER
 53  * IMAGE_SECTION_HEADER[]
 54  * IMAGE_DEBUG_DIRECTORY[]
 55  * OMFSignature
 56  * debug data (typical example)
 57  *   - IMAGE_DEBUG_TYPE_MISC
 58  *   - IMAGE_DEBUG_TYPE_FPO
 59  *   - IMAGE_DEBUG_TYPE_CODEVIEW
 60  * OMFDirHeader
 61  * OMFDirEntry[]
 62  */
 63 
 64 /*
 65  * Descriptions:
 66  *
 67  * (hdr)  IMAGE_SEPARATE_DEBUG_HEADER - .DBG-specific file header; holds info that
 68  *        applies to the file as a whole, including # of COFF sections, file offsets, etc.
 69  * (hdr)  IMAGE_SECTION_HEADER - list of COFF sections copied verbatim from .EXE;
 70  *        although this directory contains file offsets, these offsets are meaningless
 71  *        in the context of the .DBG file, because only the section headers are copied
 72  *        to the .DBG file...not the binary data it points to.
 73  * (hdr)  IMAGE_DEBUG_DIRECTORY - list of different formats of debug info contained in file
 74  *        (see IMAGE_DEBUG_TYPE_* descriptions below); tells where each section starts
 75  * (hdr)  OMFSignature (CV) - Contains "NBxx" signature, plus file offset telling how far
 76  *        into the IMAGE_DEBUG_TYPE_CODEVIEW section the OMFDirHeader and OMFDirEntry's sit
 77  * (data) IMAGE_DEBUG_TYPE_MISC - usually holds name of original .EXE file
 78  * (data) IMAGE_DEBUG_TYPE_FPO - Frame Pointer Optimization data; used for dealing with
 79  *        optimized stack frames (optional)
 80  * (data) IMAGE_DEBUG_TYPE_CODEVIEW - *** THE GOOD STUFF ***
 81  *        This block of data contains all the symbol tables, line number info, etc.,
 82  *        that the Visual C++ debugger needs.
 83  * (hdr)  OMFDirHeader (CV) -
 84  * (hdr)  OMFDirEntry (CV) - list of subsections within CodeView debug data section
 85  */
 86 
 87 /*
 88  * The .DBG file typically has three arrays of directory entries, which tell
 89  * the OS or debugger where in the file to look for the actual data
 90  *
 91  * IMAGE_SECTION_HEADER - number of entries determined by:
 92  *    (IMAGE_SEPARATE_DEBUG_HEADER.NumberOfSections)
 93  *
 94  * IMAGE_DEBUG_DIRECTORY - number of entries determined by:
 95  *    (IMAGE_SEPARATE_DEBUG_HEADER.DebugDirectorySize / sizeof (IMAGE_DEBUG_DIRECTORY))
 96  *
 97  * OMFDirEntry - number of entries determined by:
 98  *    (OMFDirHeader.cDir)
 99  */
100 
101 extern const IMAGE_NT_HEADERS*  PE_nt_headers;
102 static const void*              cv_base /* = 0 */;
103 
104 static int dump_cv_sst_module(const OMFDirEntry* omfde)
105 {
106     const OMFModule*    module;
107     const OMFSegDesc*   segDesc;
108     int         i;
109 
110     module = PRD(Offset(cv_base) + omfde->lfo, sizeof(OMFModule));
111     if (!module) {printf("Can't get the OMF-Module, aborting\n"); return FALSE;}
112 
113     printf("    olvNumber:          %u\n", module->ovlNumber);
114     printf("    iLib:               %u\n", module->iLib);
115     printf("    cSeg:               %u\n", module->cSeg);
116     printf("    Style:              %c%c\n", module->Style[0], module->Style[1]);
117     printf("    Name:               %.*s\n",
118            *(const BYTE*)((const char*)(module + 1) + sizeof(OMFSegDesc) * module->cSeg),
119            (const char*)(module + 1) + sizeof(OMFSegDesc) * module->cSeg + 1);
120 
121     segDesc = PRD(Offset(module + 1), sizeof(OMFSegDesc) * module->cSeg);
122     if (!segDesc) {printf("Can't get the OMF-SegDesc, aborting\n"); return FALSE;}
123 
124     for (i = 0; i < module->cSeg; i++)
125     {
126         printf ("      segment #%2d: offset = [0x%8x], size = [0x%8x]\n",
127                 segDesc->Seg, segDesc->Off, segDesc->cbSeg);
128         segDesc++;
129     }
130     return TRUE;
131 }
132 
133 static int dump_cv_sst_global_pub(const OMFDirEntry* omfde)
134 {
135     long                fileoffset;
136     const OMFSymHash*   header;
137     const BYTE*         symbols;
138 
139     fileoffset = Offset(cv_base) + omfde->lfo;
140     printf ("    GlobalPub section starts at file offset 0x%lx\n", fileoffset);
141     printf ("    Symbol table starts at 0x%lx\n", fileoffset + sizeof (OMFSymHash));
142 
143     printf ("\n                           ----- Begin Symbol Table -----\n");
144 
145     header = PRD(fileoffset, sizeof(OMFSymHash));
146     if (!header) {printf("Can't get OMF-SymHash, aborting\n");return FALSE;}
147 
148     symbols = PRD(fileoffset + sizeof(OMFSymHash), header->cbSymbol);
149     if (!symbols) {printf("Can't OMF-SymHash details, aborting\n"); return FALSE;}
150 
151     codeview_dump_symbols(symbols, header->cbSymbol);
152 
153     return TRUE;
154 }
155 
156 static int dump_cv_sst_global_sym(const OMFDirEntry* omfde)
157 {
158     /*** NOT YET IMPLEMENTED ***/
159     return TRUE;
160 }
161 
162 static int dump_cv_sst_static_sym(const OMFDirEntry* omfde)
163 {
164     /*** NOT YET IMPLEMENTED ***/
165     return TRUE;
166 }
167 
168 static int dump_cv_sst_libraries(const OMFDirEntry* omfde)
169 {
170     /*** NOT YET IMPLEMENTED ***/
171     return TRUE;
172 }
173 
174 static int dump_cv_sst_global_types(const OMFDirEntry* omfde)
175 {
176     long                fileoffset;
177     const OMFGlobalTypes*types;
178     const BYTE*         data;
179     unsigned            sz;
180 
181     fileoffset = Offset(cv_base) + omfde->lfo;
182     printf ("    GlobalTypes section starts at file offset 0x%lx\n", fileoffset);
183 
184     printf ("\n                           ----- Begin Global Types Table -----\n");
185 
186     types = PRD(fileoffset, sizeof(OMFGlobalTypes));
187     if (!types) {printf("Can't get OMF-GlobalTypes, aborting\n");return FALSE;}
188 
189     sz = omfde->cb - sizeof(OMFGlobalTypes) - sizeof(DWORD) * types->cTypes;
190     data = PRD(fileoffset + sizeof(OMFGlobalTypes) + sizeof(DWORD) * types->cTypes, sz);
191     if (!data) {printf("Can't OMF-SymHash details, aborting\n"); return FALSE;}
192 
193     /* doc says:
194      * - for NB07 & NB08 (that we don't support yet), offsets are from types
195      * - for NB09, offsets are from data
196      * For now, we only support the latter
197      */
198     codeview_dump_types_from_offsets(data, (const DWORD*)(types + 1), types->cTypes);
199 
200     return TRUE;
201 }
202 
203 static int dump_cv_sst_seg_map(const OMFDirEntry* omfde)
204 {
205     const OMFSegMap*            segMap;
206     const OMFSegMapDesc*        segMapDesc;
207     int         i;
208 
209     segMap = PRD(Offset(cv_base) + omfde->lfo, sizeof(OMFSegMap));
210     if (!segMap) {printf("Can't get SegMap, aborting\n");return FALSE;}
211 
212     printf("    cSeg:          %u\n", segMap->cSeg);
213     printf("    cSegLog:       %u\n", segMap->cSegLog);
214 
215     segMapDesc = PRD(Offset(segMap + 1), segMap->cSeg * sizeof(OMFSegDesc));
216     if (!segMapDesc) {printf("Can't get SegDescr array, aborting\n");return FALSE;}
217 
218     for (i = 0; i < segMap->cSeg; i++)
219     {
220         printf("    SegDescr #%2d\n", i + 1);
221         printf("      flags:         %04X\n", segMapDesc[i].flags);
222         printf("      ovl:           %u\n", segMapDesc[i].ovl);
223         printf("      group:         %u\n", segMapDesc[i].group);
224         printf("      frame:         %u\n", segMapDesc[i].frame);
225         printf("      iSegName:      %u\n", segMapDesc[i].iSegName);
226         printf("      iClassName:    %u\n", segMapDesc[i].iClassName);
227         printf("      offset:        %lu\n", segMapDesc[i].offset);
228         printf("      cbSeg:         %lu\n", segMapDesc[i].cbSeg);
229     }
230 
231     return TRUE;
232 }
233 
234 static int dump_cv_sst_file_index(const OMFDirEntry* omfde)
235 {
236     /*** NOT YET IMPLEMENTED ***/
237     return TRUE;
238 }
239 
240 static int dump_cv_sst_src_module(const OMFDirEntry* omfde)
241 {
242     int                         i, j;
243     const BYTE*                 rawdata;
244     const unsigned long*        seg_info_dw;
245     const unsigned short*       seg_info_w;
246     unsigned                    ofs;
247     const OMFSourceModule*      sourceModule;
248     const OMFSourceFile*        sourceFile;
249     const OMFSourceLine*        sourceLine;
250 
251     rawdata = PRD(Offset(cv_base) + omfde->lfo, omfde->cb);
252     if (!rawdata) {printf("Can't get srcModule subsection details, aborting\n");return FALSE;}
253 
254     /* FIXME: check ptr validity */
255     sourceModule = (const void*)rawdata;
256     printf ("    Module table: Found %d file(s) and %d segment(s)\n",
257             sourceModule->cFile, sourceModule->cSeg);
258     for (i = 0; i < sourceModule->cFile; i++)
259     {
260         printf ("      File #%2d begins at an offset of 0x%lx in this section\n",
261                 i + 1, sourceModule->baseSrcFile[i]);
262     }
263 
264     /* FIXME: check ptr validity */
265     seg_info_dw = (const void*)((const char*)(sourceModule + 1) +
266                           sizeof(unsigned long) * (sourceModule->cFile - 1));
267     seg_info_w = (const unsigned short*)(&seg_info_dw[sourceModule->cSeg * 2]);
268     for (i = 0; i <  sourceModule->cSeg; i++)
269     {
270         printf ("      Segment #%2d start = 0x%lx, end = 0x%lx, seg index = %u\n",
271                 i + 1, seg_info_dw[i * 2], seg_info_dw[(i * 2) + 1],
272                 seg_info_w[i]);
273     }
274     ofs = sizeof(OMFSourceModule) + sizeof(unsigned long) * (sourceModule->cFile - 1) +
275         sourceModule->cSeg * (2 * sizeof(unsigned long) + sizeof(unsigned short));
276     ofs = (ofs + 3) & ~3;
277 
278     /* the OMFSourceFile is quite unpleasant to use:
279      * we have first:
280      *  unsigned short  number of segments
281      *  unsigned short  reserved
282      *  unsigned long   baseSrcLn[# segments]
283      *  unsigned long   offset[2 * #segments]
284      *                          odd indices are start offsets
285      *                          even indices are end offsets
286      *  unsigned char   string length for file name
287      *  char            file name (length is previous field)
288      */
289     /* FIXME: check ptr validity */
290     sourceFile = (const void*)(rawdata + ofs);
291     seg_info_dw = (const void*)((const char*)sourceFile + 2 * sizeof(unsigned short) +
292                           sourceFile->cSeg * sizeof(unsigned long));
293 
294     ofs += 2 * sizeof(unsigned short) + 3 * sourceFile->cSeg * sizeof(unsigned long);
295 
296     printf("    File table: %.*s\n",
297            *(const BYTE*)((const char*)sourceModule + ofs), (const char*)sourceModule + ofs + 1);
298 
299     for (i = 0; i < sourceFile->cSeg; i++)
300     {
301         printf ("      Segment #%2d start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
302                 i + 1, seg_info_dw[i * 2], seg_info_dw[(i * 2) + 1], sourceFile->baseSrcLn[i]);
303     }
304     /* add file name length */
305     ofs += *(const BYTE*)((const char*)sourceModule + ofs) + 1;
306     ofs = (ofs + 3) & ~3;
307 
308     for (i = 0; i < sourceModule->cSeg; i++)
309     {
310         sourceLine = (const void*)(rawdata + ofs);
311         seg_info_dw = (const void*)((const char*)sourceLine + 2 * sizeof(unsigned short));
312         seg_info_w = (const void*)(&seg_info_dw[sourceLine->cLnOff]);
313 
314         printf ("    Line table #%2d: Found %d line numbers for segment index %d\n",
315                 i, sourceLine->cLnOff, sourceLine->Seg);
316 
317         for (j = 0; j < sourceLine->cLnOff; j++)
318         {
319             printf ("      Pair #%2d: offset = [0x%8lx], linenumber = %d\n",
320                     j + 1, seg_info_dw[j], seg_info_w[j]);
321         }
322         ofs += 2 * sizeof(unsigned short) +
323             sourceLine->cLnOff * (sizeof(unsigned long) + sizeof(unsigned short));
324         ofs = (ofs + 3) & ~3;
325     }
326 
327     return TRUE;
328 }
329 
330 static int dump_cv_sst_align_sym(const OMFDirEntry* omfde)
331 {
332     const char* rawdata = PRD(Offset(cv_base) + omfde->lfo, omfde->cb);
333 
334     if (!rawdata) {printf("Can't get srcAlignSym subsection details, aborting\n");return FALSE;}
335     if (omfde->cb < sizeof(DWORD)) return TRUE;
336     codeview_dump_symbols(rawdata + sizeof(DWORD), omfde->cb - sizeof(DWORD));
337 
338     return TRUE;
339 }
340 
341 static void dump_codeview_all_modules(const OMFDirHeader *omfdh)
342 {
343     unsigned            i;
344     const OMFDirEntry*  dirEntry;
345     const char*         str;
346 
347     if (!omfdh || !omfdh->cDir) return;
348 
349     dirEntry = PRD(Offset(omfdh + 1), omfdh->cDir * sizeof(OMFDirEntry));
350     if (!dirEntry) {printf("Can't read DirEntry array, aborting\n"); return;}
351 
352     for (i = 0; i < omfdh->cDir; i++)
353     {
354         switch (dirEntry[i].SubSection)
355         {
356         case sstModule:         str = "sstModule";      break;
357         case sstAlignSym:       str = "sstAlignSym";    break;
358         case sstSrcModule:      str = "sstSrcModule";   break;
359         case sstLibraries:      str = "sstLibraries";   break;
360         case sstGlobalSym:      str = "sstGlobalSym";   break;
361         case sstGlobalPub:      str = "sstGlobalPub";   break;
362         case sstGlobalTypes:    str = "sstGlobalTypes"; break;
363         case sstSegMap:         str = "sstSegMap";      break;
364         case sstFileIndex:      str = "sstFileIndex";   break;
365         case sstStaticSym:      str = "sstStaticSym";   break;
366         default:                str = "<undefined>";    break;
367         }
368         printf("Module #%2d (%p)\n", i + 1, &dirEntry[i]);
369         printf("  SubSection:            %04X (%s)\n", dirEntry[i].SubSection, str);
370         printf("  iMod:                  %d\n", dirEntry[i].iMod);
371         printf("  lfo:                   %d\n", dirEntry[i].lfo);
372         printf("  cb:                    %u\n", dirEntry[i].cb);
373 
374         switch (dirEntry[i].SubSection)
375         {
376         case sstModule:         dump_cv_sst_module(&dirEntry[i]);       break;
377         case sstAlignSym:       dump_cv_sst_align_sym(&dirEntry[i]);    break;
378         case sstSrcModule:      dump_cv_sst_src_module(&dirEntry[i]);   break;
379         case sstLibraries:      dump_cv_sst_libraries(&dirEntry[i]);    break;
380         case sstGlobalSym:      dump_cv_sst_global_sym(&dirEntry[i]);   break;
381         case sstGlobalPub:      dump_cv_sst_global_pub(&dirEntry[i]);   break;
382         case sstGlobalTypes:    dump_cv_sst_global_types(&dirEntry[i]); break;
383         case sstSegMap:         dump_cv_sst_seg_map(&dirEntry[i]);      break;
384         case sstFileIndex:      dump_cv_sst_file_index(&dirEntry[i]);   break;
385         case sstStaticSym:      dump_cv_sst_static_sym(&dirEntry[i]);   break;
386         default:                printf("unsupported type %x\n", dirEntry[i].SubSection); break;
387         }
388         printf("\n");
389     }
390 
391     return;
392 }
393 
394 static void dump_codeview_headers(unsigned long base, unsigned long len)
395 {
396     const OMFDirHeader* dirHeader;
397     const char*         signature;
398     const OMFDirEntry*  dirEntry;
399     const OMFSignature* sig;
400     unsigned            i;
401     int modulecount = 0, alignsymcount = 0, srcmodulecount = 0, librariescount = 0;
402     int globalsymcount = 0, globalpubcount = 0, globaltypescount = 0;
403     int segmapcount = 0, fileindexcount = 0, staticsymcount = 0;
404 
405     cv_base = PRD(base, len);
406     if (!cv_base) {printf("Can't get full debug content, aborting\n");return;}
407 
408     signature = cv_base;
409 
410     printf("    CodeView Data\n");
411     printf("      Signature:         %.4s\n", signature);
412 
413     if (memcmp(signature, "NB10", 4) == 0)
414     {
415         const CODEVIEW_PDB_DATA* pdb_data;
416         pdb_data = (const void *)cv_base;
417 
418         printf("      Filepos:           0x%08lX\n", pdb_data->filepos);
419         printf("      TimeStamp:         %08X (%s)\n",
420                pdb_data->timestamp, get_time_str(pdb_data->timestamp));
421         printf("      Age:               %08X\n", pdb_data->age);
422         printf("      Filename:          %s\n", pdb_data->name);
423         return;
424     }
425     if (memcmp(signature, "RSDS", 4) == 0)
426     {
427         const OMFSignatureRSDS* rsds_data;
428 
429         rsds_data = (const void *)cv_base;
430         printf("      Guid:              %s\n", get_guid_str(&rsds_data->guid));
431         printf("      Age:               %08X\n", rsds_data->age);
432         printf("      Filename:          %s\n", rsds_data->name);
433         return;
434     }
435 
436     if (memcmp(signature, "NB09", 4) != 0 && memcmp(signature, "NB11", 4) != 0)
437     {
438         printf("Unsupported signature (%.4s), aborting\n", signature);
439         return;
440     }
441 
442     sig = cv_base;
443 
444     printf("      Filepos:           0x%08lX\n", sig->filepos);
445 
446     dirHeader = PRD(Offset(cv_base) + sig->filepos, sizeof(OMFDirHeader));
447     if (!dirHeader) {printf("Can't get debug header, aborting\n"); return;}
448 
449     printf("      Size of header:    0x%4X\n", dirHeader->cbDirHeader);
450     printf("      Size per entry:    0x%4X\n", dirHeader->cbDirEntry);
451     printf("      # of entries:      0x%8X (%d)\n", dirHeader->cDir, dirHeader->cDir);
452     printf("      Offset to NextDir: 0x%8X\n", dirHeader->lfoNextDir);
453     printf("      Flags:             0x%8X\n", dirHeader->flags);
454 
455     if (!dirHeader->cDir) return;
456 
457     dirEntry = PRD(Offset(dirHeader + 1), sizeof(OMFDirEntry) * dirHeader->cDir);
458     if (!dirEntry) {printf("Can't get DirEntry array, aborting\n");return;}
459 
460     for (i = 0; i < dirHeader->cDir; i++)
461     {
462         switch (dirEntry[i].SubSection)
463         {
464         case sstModule:         modulecount++;          break;
465         case sstAlignSym:       alignsymcount++;        break;
466         case sstSrcModule:      srcmodulecount++;       break;
467         case sstLibraries:      librariescount++;       break;
468         case sstGlobalSym:      globalsymcount++;       break;
469         case sstGlobalPub:      globalpubcount++;       break;
470         case sstGlobalTypes:    globaltypescount++;     break;
471         case sstSegMap:         segmapcount++;          break;
472         case sstFileIndex:      fileindexcount++;       break;
473         case sstStaticSym:      staticsymcount++;       break;
474         }
475     }
476 
477     /* This one has to be > 0
478      */
479     printf ("\nFound: %d sstModule subsections\n", modulecount);
480 
481     if (alignsymcount > 0)    printf ("       %d sstAlignSym subsections\n", alignsymcount);
482     if (srcmodulecount > 0)   printf ("       %d sstSrcModule subsections\n", srcmodulecount);
483     if (librariescount > 0)   printf ("       %d sstLibraries subsections\n", librariescount);
484     if (globalsymcount > 0)   printf ("       %d sstGlobalSym subsections\n", globalsymcount);
485     if (globalpubcount > 0)   printf ("       %d sstGlobalPub subsections\n", globalpubcount);
486     if (globaltypescount > 0) printf ("       %d sstGlobalTypes subsections\n", globaltypescount);
487     if (segmapcount > 0)      printf ("       %d sstSegMap subsections\n", segmapcount);
488     if (fileindexcount > 0)   printf ("       %d sstFileIndex subsections\n", fileindexcount);
489     if (staticsymcount > 0)   printf ("       %d sstStaticSym subsections\n", staticsymcount);
490 
491     dump_codeview_all_modules(dirHeader);
492 }
493 
494 static const char *get_coff_name( const IMAGE_SYMBOL *coff_sym, const char *coff_strtab )
495 {
496    static       char    namebuff[9];
497    const char*          nampnt;
498 
499    if( coff_sym->N.Name.Short )
500       {
501          memcpy(namebuff, coff_sym->N.ShortName, 8);
502          namebuff[8] = '\0';
503          nampnt = &namebuff[0];
504       }
505    else
506       {
507          nampnt = coff_strtab + coff_sym->N.Name.Long;
508       }
509 
510    if( nampnt[0] == '_' )
511       nampnt++;
512    return nampnt;
513 }
514 
515 void    dump_coff(unsigned long coffbase, unsigned long len, const void* pmt)
516 {
517     const IMAGE_COFF_SYMBOLS_HEADER *coff = (const IMAGE_COFF_SYMBOLS_HEADER *)PRD(coffbase, len);
518     const IMAGE_SYMBOL              *coff_sym;
519     const IMAGE_SYMBOL              *coff_symbols =
520                                         (const IMAGE_SYMBOL *) ((const char *)coff + coff->LvaToFirstSymbol);
521     const char                      *coff_strtab = (const char *) (coff_symbols + coff->NumberOfSymbols);
522     const IMAGE_SECTION_HEADER      *sectHead = pmt;
523     unsigned int                    i;
524     const char                      *nampnt;
525     int                             naux;
526 
527     printf("\nDebug table: COFF format. modbase %p, coffbase %p\n", PRD(0, 0), coff);
528     printf("  ID  | seg:offs    [  abs   ] | symbol/function name\n");
529     for(i=0; i < coff->NumberOfSymbols; i++ )
530     {
531       coff_sym = coff_symbols + i;
532       naux = coff_sym->NumberOfAuxSymbols;
533 
534       if( coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE )
535         {
536           printf("file %s\n", (const char *) (coff_sym + 1));
537           i += naux;
538           continue;
539         }
540 
541       if(    (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
542           && (naux == 0)
543           && (coff_sym->SectionNumber == 1) )
544         {
545           DWORD base = sectHead[coff_sym->SectionNumber - 1].VirtualAddress;
546           /*
547            * This is a normal static function when naux == 0.
548            * Just register it.  The current file is the correct
549            * one in this instance.
550            */
551           nampnt = get_coff_name( coff_sym, coff_strtab );
552 
553           printf("%05d | %02d:%08x [%08x] | %s\n", i, coff_sym->SectionNumber - 1, coff_sym->Value - base, coff_sym->Value, nampnt);
554           i += naux;
555           continue;
556         }
557 
558       if(    (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
559           && ISFCN(coff_sym->Type)
560           && (coff_sym->SectionNumber > 0) )
561         {
562           DWORD base = sectHead[coff_sym->SectionNumber - 1].VirtualAddress;
563 
564           nampnt = get_coff_name( coff_sym, coff_strtab );
565 
566           /* FIXME: add code to find out the file this symbol belongs to,
567            * see winedbg */
568           printf("%05d | %02d:%08x [%08x] | %s\n", i, coff_sym->SectionNumber - 1, coff_sym->Value - base, coff_sym->Value, nampnt);
569           i += naux;
570           continue;
571         }
572 
573       /*
574        * For now, skip past the aux entries.
575        */
576       i += naux;
577 
578     }
579 }
580 
581 void    dump_codeview(unsigned long base, unsigned long len)
582 {
583     dump_codeview_headers(base, len);
584 }
585 
586 void    dump_frame_pointer_omission(unsigned long base, unsigned long len)
587 {
588     const FPO_DATA*     fpo;
589     const FPO_DATA*     last;
590     const char*         x;
591     /* FPO is used to describe nonstandard stack frames */
592     printf("Range             #loc #pmt Prlg #reg Info\n"
593            "-----------------+----+----+----+----+------------\n");
594 
595     fpo = (const FPO_DATA*)PRD(base, len);
596     if (!fpo) {printf("Couldn't get FPO blob\n"); return;}
597     last = (const FPO_DATA*)((const char*)fpo + len);
598 
599     while (fpo < last && fpo->ulOffStart)
600     {
601         switch (fpo->cbFrame)
602         {
603         case FRAME_FPO: x = "FRAME_FPO"; break;
604         case FRAME_NONFPO: x = "FRAME_NONFPO"; break;
605         case FRAME_TRAP: x = "FRAME_TRAP"; break;
606         case FRAME_TSS: x = "case FRAME_TSS"; break;
607         default: x = NULL; break;
608         }
609         printf("%08x-%08x %4u %4u %4u %4u %s%s%s\n",
610                fpo->ulOffStart, fpo->ulOffStart + fpo->cbProcSize,
611                fpo->cdwLocals, fpo->cdwParams, fpo->cbProlog, fpo->cbRegs,
612                x, fpo->fHasSEH ? " SEH" : "", fpo->fUseBP ? " UseBP" : "");
613         fpo++;
614     }
615 }
616 
617 struct stab_nlist
618 {
619     union
620     {
621         char*                   n_name;
622         struct stab_nlist*      n_next;
623         long                    n_strx;
624     } n_un;
625     unsigned char       n_type;
626     char                n_other;
627     short               n_desc;
628     unsigned long       n_value;
629 };
630 
631 static const char * const stabs_defs[] = {
632     NULL,NULL,NULL,NULL,                /* 00 */
633     NULL,NULL,NULL,NULL,                /* 08 */
634     NULL,NULL,NULL,NULL,                /* 10 */
635     NULL,NULL,NULL,NULL,                /* 18 */
636     "GSYM","FNAME","FUN","STSYM",       /* 20 */
637     "LCSYM","MAIN","ROSYM","PC",        /* 28 */
638     NULL,"NSYMS","NOMAP",NULL,          /* 30 */
639     "OBJ",NULL,"OPT",NULL,              /* 38 */
640     "RSYM","M2C","SLINE","DSLINE",      /* 40 */
641     "BSLINE","DEFD","FLINE",NULL,       /* 48 */
642     "EHDECL",NULL,"CATCH",NULL,         /* 50 */
643     NULL,NULL,NULL,NULL,                /* 58 */
644     "SSYM","ENDM","SO",NULL,            /* 60 */
645     NULL,NULL,NULL,NULL,                /* 68 */
646     NULL,NULL,NULL,NULL,                /* 70 */
647     NULL,NULL,NULL,NULL,                /* 78 */
648     "LSYM","BINCL","SOL",NULL,          /* 80 */
649     NULL,NULL,NULL,NULL,                /* 88 */
650     NULL,NULL,NULL,NULL,                /* 90 */
651     NULL,NULL,NULL,NULL,                /* 98 */
652     "PSYM","EINCL","ENTRY",NULL,        /* a0 */
653     NULL,NULL,NULL,NULL,                /* a8 */
654     NULL,NULL,NULL,NULL,                /* b0 */
655     NULL,NULL,NULL,NULL,                /* b8 */
656     "LBRAC","EXCL","SCOPE",NULL,        /* c0 */
657     NULL,NULL,NULL,NULL,                /* c8 */
658     NULL,NULL,NULL,NULL,                /* d0 */
659     NULL,NULL,NULL,NULL,                /* d8 */
660     "RBRAC","BCOMM","ECOMM",NULL,       /* e0 */
661     "ECOML","WITH",NULL,NULL,           /* e8 */
662     "NBTEXT","NBDATA","NBBSS","NBSTS",  /* f0 */
663     "NBLCS",NULL,NULL,NULL              /* f8 */
664 };
665 
666 void    dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr)
667 {
668     int                         i;
669     int                         nstab;
670     const char*                 ptr;
671     char*                       stabbuff;
672     unsigned int                stabbufflen;
673     const struct stab_nlist*    stab_ptr = pv_stabs;
674     const char*                 strs_end;
675     char                        n_buffer[16];
676 
677     nstab = szstabs / sizeof(struct stab_nlist);
678     strs_end = stabstr + szstr;
679 
680     /*
681      * Allocate a buffer into which we can build stab strings for cases
682      * where the stab is continued over multiple lines.
683      */
684     stabbufflen = 65536;
685     stabbuff = malloc(stabbufflen);
686 
687     stabbuff[0] = '\0';
688 
689     printf("#Sym n_type n_othr   n_desc n_value  n_strx String\n");
690 
691     for (i = 0; i < nstab; i++, stab_ptr++)
692     {
693         ptr = stabstr + stab_ptr->n_un.n_strx;
694         if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end))
695         {
696             ptr = "[[*** bad string ***]]";
697         }
698         else if (ptr[strlen(ptr) - 1] == '\\')
699         {
700             /*
701              * Indicates continuation.  Append this to the buffer, and go onto the
702              * next record.  Repeat the process until we find a stab without the
703              * '/' character, as this indicates we have the whole thing.
704              */
705             unsigned    len = strlen(ptr);
706             if (strlen(stabbuff) + len > stabbufflen)
707             {
708                 stabbufflen += 65536;
709                 stabbuff = realloc(stabbuff, stabbufflen);
710             }
711             strncat(stabbuff, ptr, len - 1);
712             continue;
713         }
714         else if (stabbuff[0] != '\0')
715         {
716             strcat(stabbuff, ptr);
717             ptr = stabbuff;
718         }
719         if ((stab_ptr->n_type & 1) || !stabs_defs[stab_ptr->n_type / 2])
720             sprintf(n_buffer, "<0x%02x>", stab_ptr->n_type);
721         else
722             sprintf(n_buffer, "%-6s", stabs_defs[stab_ptr->n_type / 2]);
723         printf("%4d %s %-8x % 6d %-8lx %-6lx %s\n", 
724                i, n_buffer, stab_ptr->n_other, stab_ptr->n_desc, stab_ptr->n_value,
725                stab_ptr->n_un.n_strx, ptr);
726     }
727     free(stabbuff);
728 }
729 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.