Moved PE header definitions to winnt.h where they belong.
[wine] / tools / cvdump / cvcrunch.c
1 /*
2  * Functions to process in-memory arrays of CodeView data sections
3  * (currently only contains sstSrcModule).
4  *
5  * Copyright 2000 John R. Sheets
6  */
7
8 /* FIXME - Change to cvprint.c */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <windows.h>
14
15 #include "cvinclude.h"
16
17 /************************ sstSrcModule ************************/
18
19 /* Print out stuff in OMFSourceModule block.  Rather than using the supplied
20  * OMFSourceModule struct, we'll extract each piece of data separately from
21  * the block of memory (rawdata).  This struct (and the others used in
22  * sstSrcModule sections) is pretty useless.  We can't use sizeof() on it
23  * because it contains the first element of the file offset array (i.e. baseSrcFile),
24  * which we need to parse separately anyway.  See below for problems with the
25  * other structs.
26  *
27  * The contents of this section look like this (the first two fields are
28  * already extracted and passed in as parameters):
29  *
30  * unsigned short cFile
31  * unsigned short cSeg
32  * unsigned long baseSrcFile[cFile]
33  * unsigned long segarray[cSeg * 2]
34  * unsigned short segindexarray[cSeg]
35  */
36 int PrintSrcModuleInfo (BYTE* rawdata, short *filecount, short *segcount)
37 {
38     int i;
39     int datalen;
40
41     unsigned short cFile;
42     unsigned short cSeg;
43     unsigned long *baseSrcFile;
44     unsigned long *segarray;
45     unsigned short *segindexarray;
46
47     /* Get all our pointers straightened out
48      */
49     cFile = *(short*)rawdata;
50     cSeg = *(short*)(rawdata + 2);
51     baseSrcFile = (long*)(rawdata + 4);
52     segarray = &baseSrcFile[cFile];
53     segindexarray = (short*)(&segarray[cSeg * 2]);
54     
55     /* Pass # of segments and files back to calling function
56      */
57     *filecount = cFile;
58     *segcount = cSeg;
59
60     printf ("\n  Module table: Found %d file(s) and %d segment(s)\n", cFile, cSeg);
61     for (i = 0; i < cFile; i++)
62     {
63         printf ("    File #%d begins at an offset of 0x%lx in this section\n",
64                 i + 1, baseSrcFile[i]);
65     }
66
67     for (i = 0; i < cSeg; i++)
68     {
69         printf ("    Segment #%d start = 0x%lx, end = 0x%lx, seg index = %d\n",
70                 i + 1, segarray[i * 2], segarray[(i * 2) + 1], segindexarray[i]);
71     }
72
73     /* Return the total length of the data (in bytes) that we used, so
74      * we'll know how far to jump ahead for the next part of the sstSrcModule.
75      */
76     datalen = ((BYTE*)(&segindexarray[cSeg]) - rawdata);
77     /*  printf ("datalen before padding = %d\n", datalen); */
78     if (datalen % 4)
79         datalen += 4 - (datalen % 4);
80     /*  printf ("datalen after padding = %d\n", datalen); */
81
82     return datalen;
83 }
84
85 /* Print out the contents of a OMFSourceFile block.  Unfortunately, the official
86  * version of this struct (probably quite outdated) claims that the 'cFName' field
87  * is a short.  Based on experimentation with MSVC 5.0 .DBG files, this field is
88  * quite clearly only a single byte.  Yet another reason to do it all by hand
89  * and avoid the "official" structs.
90  *
91  * The contents of this section look like this (the first field is
92  * pre-extracted, and 'pad' is ignored):
93  *
94  * unsigned short cSeg
95  * unsigned short pad
96  * unsigned long baseSrcLn[cSeg]
97  * unsigned long segarray[cSeg * 2]
98  * char cFName
99  * char Name[cFName]
100  */
101 int PrintSrcModuleFileInfo (BYTE* rawdata)
102 {
103     int i;
104     int datalen;
105
106     unsigned short cSeg;
107     unsigned long *baseSrcLn;
108     unsigned long *segarray;
109     unsigned char cFName;
110     char Name[256];
111
112     /* Get all our pointers straightened out
113      */
114     cSeg = *(short*)(rawdata);
115     /* Skip the 'pad' field */
116     baseSrcLn = (long*)(rawdata + 4);
117     segarray = &baseSrcLn[cSeg];
118     cFName = *((char*)&segarray[cSeg * 2]);
119     snprintf (Name, cFName + 1, "%s", (char*)&segarray[cSeg * 2] + 1);
120
121     /*  printf ("cSeg = %d\n", cSeg); */
122     printf ("\n  File table: '%s'\n", Name);
123
124     for (i = 0; i < cSeg; i++)
125     {
126         printf ("    Segment #%d start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
127                 i + 1, segarray[i * 2], segarray[(i * 2) + 1], baseSrcLn[i]);
128     }
129
130     /* Return the total length of the data (in bytes) that we used, so
131      * we'll know how far to jump ahead for the next part of the sstSrcModule.
132      */
133     datalen = ((BYTE*)(&segarray[cSeg * 2]) + cFName  + 1 - rawdata);
134     /*  printf ("datalen before padding = %d\n", datalen); */
135     if (datalen % 4)
136         datalen += 4 - (datalen % 4);
137     /*  printf ("datalen after padding = %d\n", datalen); */
138
139     return datalen;
140 }
141
142 /* Print out the contents of a OMFSourceLine block.  The contents of this section
143  * look like this:
144  *
145  * unsigned short Seg
146  * unsigned short cPair
147  * unsigned long offset[cPair]
148  * unsigned long linenumber[cPair]
149  */
150 int PrintSrcModuleLineInfo (BYTE* rawdata, int tablecount)
151 {
152     int i;
153     int datalen;
154
155     unsigned short Seg;
156     unsigned short cPair;
157     unsigned long *offset;
158     unsigned short *linenumber;
159
160     Seg = *(short*)rawdata;
161     cPair = *(short*)(rawdata + 2);
162     offset = (long*)(rawdata + 4);
163     linenumber = (short*)&offset[cPair];
164
165     printf ("\n  Line table #%d: Found %d line numbers for segment index %d\n",
166             tablecount, cPair, Seg);
167
168     for (i = 0; i < cPair; i++)
169     {
170         printf ("    Pair #%2d: offset = [0x%8lx], linenumber = %d\n",
171                 i + 1, offset[i], linenumber[i]);
172     }
173
174     /* Return the total length of the data (in bytes) that we used, so
175      * we'll know how far to jump ahead for the next part of the sstSrcModule.
176      */
177     datalen = ((BYTE*)(&linenumber[cPair]) - rawdata);
178     /*  printf ("datalen before padding = %d\n", datalen); */
179     if (datalen % 4)
180         datalen += 4 - (datalen % 4);
181     /*  printf ("datalen after padding = %d\n", datalen); */
182
183     return datalen;
184 }
185