| /* | |
| * 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 "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 | |
| * extracted and passed back out): | |
| * | |
| * 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; | |
| } | |