Commit e61d33bf authored by John R. Sheets's avatar John R. Sheets Committed by Alexandre Julliard

Added cvdump tool to dump CodeView symbol information.

parent cb98a6ed
...@@ -92,7 +92,7 @@ INSTALLSUBDIRS = $(DLLDIR) $(DOCSUBDIRS) $(INCSUBDIRS) ...@@ -92,7 +92,7 @@ INSTALLSUBDIRS = $(DLLDIR) $(DOCSUBDIRS) $(INCSUBDIRS)
LINTSUBDIRS = $(LIBSUBDIRS) $(DLLDIR) $(EMUSUBDIRS) $(DOCSUBDIRS) LINTSUBDIRS = $(LIBSUBDIRS) $(DLLDIR) $(EMUSUBDIRS) $(DOCSUBDIRS)
# Extra sub-directories to clean # Extra sub-directories to clean
CLEANSUBDIRS = dlls include include/bitmaps include/wine CLEANSUBDIRS = dlls include include/bitmaps include/wine tools/cvdump
LIBOBJS = \ LIBOBJS = \
controls/controls.o \ controls/controls.o \
......
...@@ -6314,6 +6314,7 @@ resources/Makefile ...@@ -6314,6 +6314,7 @@ resources/Makefile
scheduler/Makefile scheduler/Makefile
server/Makefile server/Makefile
tools/Makefile tools/Makefile
tools/cvdump/Makefile
tools/wrc/Makefile tools/wrc/Makefile
tsx11/Makefile tsx11/Makefile
win32/Makefile win32/Makefile
...@@ -6537,6 +6538,7 @@ resources/Makefile ...@@ -6537,6 +6538,7 @@ resources/Makefile
scheduler/Makefile scheduler/Makefile
server/Makefile server/Makefile
tools/Makefile tools/Makefile
tools/cvdump/Makefile
tools/wrc/Makefile tools/wrc/Makefile
tsx11/Makefile tsx11/Makefile
win32/Makefile win32/Makefile
......
...@@ -1056,6 +1056,7 @@ resources/Makefile ...@@ -1056,6 +1056,7 @@ resources/Makefile
scheduler/Makefile scheduler/Makefile
server/Makefile server/Makefile
tools/Makefile tools/Makefile
tools/cvdump/Makefile
tools/wrc/Makefile tools/wrc/Makefile
tsx11/Makefile tsx11/Makefile
win32/Makefile win32/Makefile
......
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
PROGRAMS = cvdump@PROGEXT@
MODULE = none
C_SRCS = cvcrunch.c cvdump.c cvload.c
all: $(PROGRAMS)
@MAKE_RULES@
cvdump@PROGEXT@: $(OBJS)
$(CC) $(CFLAGS) -o cvdump@PROGEXT@ $(OBJS)
### Dependencies:
/*
* Functions to process in-memory arrays of CodeView data sections
* (currently only contains sstSrcModule).
*
* Copyright 2000 John R. Sheets
*/
/* FIXME - Change to cvprint.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "peexe.h"
#include "cvinclude.h"
/************************ sstSrcModule ************************/
/* Print out stuff in OMFSourceModule block. Rather than using the supplied
* OMFSourceModule struct, we'll extract each piece of data separately from
* the block of memory (rawdata). This struct (and the others used in
* sstSrcModule sections) is pretty useless. We can't use sizeof() on it
* because it contains the first element of the file offset array (i.e. baseSrcFile),
* which we need to parse separately anyway. See below for problems with the
* other structs.
*
* The contents of this section look like this (the first two fields are
* already extracted and passed in as parameters):
*
* unsigned short cFile
* unsigned short cSeg
* unsigned long baseSrcFile[cFile]
* unsigned long segarray[cSeg * 2]
* unsigned short segindexarray[cSeg]
*/
int PrintSrcModuleInfo (BYTE* rawdata, short *filecount, short *segcount)
{
int i;
int datalen;
unsigned short cFile;
unsigned short cSeg;
unsigned long *baseSrcFile;
unsigned long *segarray;
unsigned short *segindexarray;
/* Get all our pointers straightened out
*/
cFile = *(short*)rawdata;
cSeg = *(short*)(rawdata + 2);
baseSrcFile = (long*)(rawdata + 4);
segarray = &baseSrcFile[cFile];
segindexarray = (short*)(&segarray[cSeg * 2]);
/* Pass # of segments and files back to calling function
*/
*filecount = cFile;
*segcount = cSeg;
printf ("\n Module table: Found %d file(s) and %d segment(s)\n", cFile, cSeg);
for (i = 0; i < cFile; i++)
{
printf (" File #%d begins at an offset of 0x%lx in this section\n",
i + 1, baseSrcFile[i]);
}
for (i = 0; i < cSeg; i++)
{
printf (" Segment #%d start = 0x%lx, end = 0x%lx, seg index = %d\n",
i + 1, segarray[i * 2], segarray[(i * 2) + 1], segindexarray[i]);
}
/* Return the total length of the data (in bytes) that we used, so
* we'll know how far to jump ahead for the next part of the sstSrcModule.
*/
datalen = ((BYTE*)(&segindexarray[cSeg]) - rawdata);
/* printf ("datalen before padding = %d\n", datalen); */
if (datalen % 4)
datalen += 4 - (datalen % 4);
/* printf ("datalen after padding = %d\n", datalen); */
return datalen;
}
/* Print out the contents of a OMFSourceFile block. Unfortunately, the official
* version of this struct (probably quite outdated) claims that the 'cFName' field
* is a short. Based on experimentation with MSVC 5.0 .DBG files, this field is
* quite clearly only a single byte. Yet another reason to do it all by hand
* and avoid the "official" structs.
*
* The contents of this section look like this (the first field is
* pre-extracted, and 'pad' is ignored):
*
* unsigned short cSeg
* unsigned short pad
* unsigned long baseSrcLn[cSeg]
* unsigned long segarray[cSeg * 2]
* char cFName
* char Name[cFName]
*/
int PrintSrcModuleFileInfo (BYTE* rawdata)
{
int i;
int datalen;
unsigned short cSeg;
unsigned long *baseSrcLn;
unsigned long *segarray;
unsigned char cFName;
char Name[256];
/* Get all our pointers straightened out
*/
cSeg = *(short*)(rawdata);
/* Skip the 'pad' field */
baseSrcLn = (long*)(rawdata + 4);
segarray = &baseSrcLn[cSeg];
cFName = *((char*)&segarray[cSeg * 2]);
snprintf (Name, cFName + 1, "%s", (char*)&segarray[cSeg * 2] + 1);
/* printf ("cSeg = %d\n", cSeg); */
printf ("\n File table: '%s'\n", Name);
for (i = 0; i < cSeg; i++)
{
printf (" Segment #%d start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
i + 1, segarray[i * 2], segarray[(i * 2) + 1], baseSrcLn[i]);
}
/* Return the total length of the data (in bytes) that we used, so
* we'll know how far to jump ahead for the next part of the sstSrcModule.
*/
datalen = ((BYTE*)(&segarray[cSeg * 2]) + cFName + 1 - rawdata);
/* printf ("datalen before padding = %d\n", datalen); */
if (datalen % 4)
datalen += 4 - (datalen % 4);
/* printf ("datalen after padding = %d\n", datalen); */
return datalen;
}
/* Print out the contents of a OMFSourceLine block. The contents of this section
* look like this:
*
* unsigned short Seg
* unsigned short cPair
* unsigned long offset[cPair]
* unsigned long linenumber[cPair]
*/
int PrintSrcModuleLineInfo (BYTE* rawdata, int tablecount)
{
int i;
int datalen;
unsigned short Seg;
unsigned short cPair;
unsigned long *offset;
unsigned short *linenumber;
Seg = *(short*)rawdata;
cPair = *(short*)(rawdata + 2);
offset = (long*)(rawdata + 4);
linenumber = (short*)&offset[cPair];
printf ("\n Line table #%d: Found %d line numbers for segment index %d\n",
tablecount, cPair, Seg);
for (i = 0; i < cPair; i++)
{
printf (" Pair #%2d: offset = [0x%8lx], linenumber = %d\n",
i + 1, offset[i], linenumber[i]);
}
/* Return the total length of the data (in bytes) that we used, so
* we'll know how far to jump ahead for the next part of the sstSrcModule.
*/
datalen = ((BYTE*)(&linenumber[cPair]) - rawdata);
/* printf ("datalen before padding = %d\n", datalen); */
if (datalen % 4)
datalen += 4 - (datalen % 4);
/* printf ("datalen after padding = %d\n", datalen); */
return datalen;
}
/*
* Includes for cvdump tool.
*
* Copyright 2000 John R. Sheets
*/
/* #define VERBOSE */
#include "peexe.h"
#include "neexe.h"
#include "cvinclude.h"
typedef enum { CV_NONE, CV_DOS, CV_NT, CV_DBG } CVHeaderType;
/*
* Function Prototypes
*/
/* From cvload.c */
CVHeaderType GetHeaderType (FILE *debugfile);
int ReadDOSFileHeader (FILE *debugfile, IMAGE_DOS_HEADER *doshdr);
int ReadPEFileHeader (FILE *debugfile, IMAGE_NT_HEADERS *nthdr);
int ReadDBGFileHeader (FILE *debugfile, IMAGE_SEPARATE_DEBUG_HEADER *dbghdr);
int ReadSectionHeaders (FILE *debugfile, int numsects, IMAGE_SECTION_HEADER **secthdrs);
int ReadDebugDir (FILE *debugfile, int numdirs, IMAGE_DEBUG_DIRECTORY **debugdirs);
int ReadCodeViewHeader (FILE *debugfile, OMFSignature *sig, OMFDirHeader *dirhdr);
int ReadCodeViewDirectory (FILE *debugfile, int entrynum, OMFDirEntry **entries);
int ReadModuleData (FILE *debugfile, int entrynum, OMFDirEntry *entries,
int *module_count, OMFModuleFull **modules);
int ReadChunk (FILE *debugfile, void *dest, int length, int fileoffset);
/* From cvprint.c */
int PrintSrcModuleInfo (BYTE* rawdata, short *filecount, short *segcount);
int PrintSrcModuleFileInfo (BYTE* rawdata);
int PrintSrcModuleLineInfo (BYTE* rawdata, int tablecount);
/*
* CodeView 4 Debug format - declarations
*
* (based on cvinfo.h and cvexefmt.h from the Win32 SDK)
*/
#define sstModule 0x120
#define sstAlignSym 0x125
#define sstSrcModule 0x127
#define sstLibraries 0x128
#define sstGlobalSym 0x129
#define sstGlobalPub 0x12a
#define sstGlobalTypes 0x12b
#define sstSegMap 0x12d
#define sstFileIndex 0x133
#define sstStaticSym 0x134
#if 0
/* Old, crusty value */
#define S_PUB32 0x0203
#endif
#define S_PUB32 0x1009
#include "pshpack1.h"
/*
* CodeView headers
*/
typedef struct OMFSignature
{
char Signature[4];
long filepos;
} OMFSignature;
typedef struct OMFDirHeader
{
unsigned short cbDirHeader;
unsigned short cbDirEntry;
unsigned long cDir;
long lfoNextDir;
unsigned long flags;
} OMFDirHeader;
typedef struct OMFDirEntry
{
unsigned short SubSection;
unsigned short iMod;
long lfo;
unsigned long cb;
} OMFDirEntry;
/*
* sstModule subsection
*/
typedef struct OMFSegDesc
{
unsigned short Seg;
unsigned short pad;
unsigned long Off;
unsigned long cbSeg;
} OMFSegDesc;
/* Must chop off the OMFSegDesc* field, because we need to write this
* struct out to a file. If we write the whole struct out, we'll end up
* with (*OMFSegDesc), not (OMFSegDesc). See OMFModuleFull.
*/
typedef struct OMFModule
{
unsigned short ovlNumber;
unsigned short iLib;
unsigned short cSeg;
char Style[2];
} OMFModule;
/* Full version, with memory pointers, too. Use OMFModule for writing out to
* a file, and OMFModuleFull for reading. If offsetof() were available, we
* could use that instead.
*/
typedef struct OMFModuleFull
{
unsigned short ovlNumber;
unsigned short iLib;
unsigned short cSeg;
char Style[2];
OMFSegDesc *SegInfo;
char *Name;
} OMFModuleFull;
/*
* sstGlobalPub section
*/
/* Header for symbol table.
*/
typedef struct OMFSymHash
{
unsigned short symhash;
unsigned short addrhash;
unsigned long cbSymbol;
unsigned long cbHSym;
unsigned long cbHAddr;
} OMFSymHash;
/* Symbol table entry.
*/
typedef struct DATASYM32
{
unsigned short reclen;
unsigned short rectyp;
unsigned long typind;
unsigned long off;
unsigned short seg;
} DATASYM32;
typedef DATASYM32 PUBSYM32;
/*
* sstSegMap section
*/
typedef struct OMFSegMapDesc
{
unsigned short flags;
unsigned short ovl;
unsigned short group;
unsigned short frame;
unsigned short iSegName;
unsigned short iClassName;
unsigned long offset;
unsigned long cbSeg;
} OMFSegMapDesc;
typedef struct OMFSegMap
{
unsigned short cSeg;
unsigned short cSegLog;
OMFSegMapDesc rgDesc[0];
} OMFSegMap;
/*
* sstSrcModule section
*/
typedef struct OMFSourceLine
{
unsigned short Seg;
unsigned short cLnOff;
unsigned long offset[1];
unsigned short lineNbr[1];
} OMFSourceLine;
typedef struct OMFSourceFile
{
unsigned short cSeg;
unsigned short reserved;
unsigned long baseSrcLn[1];
unsigned short cFName;
char Name;
} OMFSourceFile;
typedef struct OMFSourceModule
{
unsigned short cFile;
unsigned short cSeg;
unsigned long baseSrcFile[1];
} OMFSourceModule;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment