|
|
1.1 root 1: /*++
2:
3:
4: Copyright (c) 1992 Microsoft Corporation
5:
6: Module Name:
7:
8: symtocv.c
9:
10: Abstract:
11:
12: This module handles the conversion activities requires for converting
13: C7/C8 SYM files to CODEVIEW debug data.
14:
15: Author:
16:
17: Wesley A. Witt (wesw) 13-April-1993
18:
19: Environment:
20:
21: Win32, User Mode
22:
23: --*/
24:
25: #include <windows.h>
26: #include <stdlib.h>
27: #include <stdio.h>
28: #include <string.h>
29:
30: #include "cv.h"
31: #include "symcvt.h"
32: #include "cvcommon.h"
33:
34: typedef struct tagSYMNAME {
35: BYTE length;
36: char name[1];
37: } SYMNAME, *PSYMNAME;
38:
39: typedef struct tagSYMSYMBOL {
40: WORD offset;
41: SYMNAME symName;
42: } SYMSYMBOL, *PSYMSYMBOL;
43:
44: typedef struct tagSYMFILEHEADER {
45: DWORD fileSize;
46: WORD reserved1;
47: WORD numSyms;
48: DWORD reserved2;
49: WORD nextOffset;
50: BYTE reserved3;
51: SYMNAME symName;
52: } SYMFILEHEADER, *PSYMFILEHEADER;
53:
54: typedef struct tagSYMHEADER {
55: WORD nextOffset;
56: WORD numSyms;
57: WORD reserved1;
58: WORD segment;
59: BYTE reserved2[12];
60: SYMNAME symName;
61: } SYMHEADER, *PSYMHEADER;
62:
63: #define SIZEOFSYMFILEHEADER 16
64: #define SIZEOFSYMHEADER 21
65: #define SIZEOFSYMBOL 3
66:
67: #define SYM_SEGMENT_NAME 0
68: #define SYM_SYMBOL_NAME 1
69: #define SYM_SEGMENT_ABS 2
70: #define SYM_SYMBOL_ABS 3
71:
72: typedef struct tagENUMINFO {
73: DATASYM16 *dataSym;
74: DATASYM16 *dataSym2;
75: DWORD numsyms;
76: SGI *sgi;
77: } ENUMINFO, *PENUMINFO;
78:
79: typedef BOOL (CALLBACK* SYMBOLENUMPROC)(PSYMNAME pSymName, int symType,
80: SEGMENT segment, UOFF16 offset,
81: PENUMINFO pEnumInfo);
82:
83:
84: static VOID GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable,
85: char * s );
86: DWORD CreateModulesFromSyms( PPOINTERS p );
87: DWORD CreatePublicsFromSyms( PPOINTERS p );
88: DWORD CreateSegMapFromSyms( PPOINTERS p );
89: static BOOL EnumSymbols( PPOINTERS p, SYMBOLENUMPROC lpEnumProc,
90: PENUMINFO pEnumInfo );
91:
92: int CSymSegs;
93:
94: BOOL CALLBACK
95: SymbolCount(PSYMNAME pSymName, int symType, SEGMENT segment,
96: UOFF16 offset, PENUMINFO pEnumInfo )
97: {
98: if ((symType == SYM_SEGMENT_NAME) && (segment > 0)) {
99: CSymSegs += 1;
100: }
101: pEnumInfo->numsyms++;
102: return TRUE;
103: }
104:
105: BOOL
106: ConvertSymToCv( PPOINTERS p )
107:
108: /*++
109:
110: Routine Description:
111:
112: This is the control function for the conversion of COFF to CODEVIEW
113: debug data. It calls individual functions for the conversion of
114: specific types of debug data.
115:
116:
117: Arguments:
118:
119: p - pointer to a POINTERS structure (see cofftocv.h)
120:
121:
122: Return Value:
123:
124: TRUE - conversion succeded
125: FALSE - conversion failed
126:
127: --*/
128:
129: {
130: ENUMINFO enumInfo;
131: DWORD dwSize;
132:
133: CSymSegs = 0;
134: enumInfo.numsyms = 0;
135: EnumSymbols( p, SymbolCount, &enumInfo );
136: dwSize = (enumInfo.numsyms * (sizeof(DATASYM16) + 10)) + 256000;
137: p->pCvCurr = p->pCvStart.ptr = malloc( dwSize );
138: if (p->pCvStart.ptr == NULL) {
139: return FALSE;
140: }
141: memset( p->pCvStart.ptr, 0, dwSize );
142:
143: try {
144:
145: CreateSignature( p );
146: CreatePublicsFromSyms( p );
147: CreateSymbolHashTable( p );
148: CreateAddressSortTable( p );
149: CreateSegMapFromSyms( p );
150: CreateModulesFromSyms( p );
151: CreateDirectories( p );
152: p->pCvStart.ptr = realloc( p->pCvStart.ptr, p->pCvStart.size );
153: return TRUE;
154:
155: } except (EXCEPTION_EXECUTE_HANDLER) {
156:
157: free( p->pCvStart.ptr );
158: p->pCvStart.ptr = NULL;
159: return FALSE;
160:
161: }
162: }
163:
164:
165: DWORD
166: CreateModulesFromSyms( PPOINTERS p )
167:
168: /*++
169:
170: Routine Description:
171:
172: Creates the individual CV module records. There is one CV module
173: record for each .FILE record in the COFF debug data. This is true
174: even if the COFF size is zero.
175:
176:
177: Arguments:
178:
179: p - pointer to a POINTERS structure (see cofftocv.h)
180:
181:
182: Return Value:
183:
184: The number of modules that were created.
185:
186: --*/
187:
188: {
189: char szDrive [_MAX_DRIVE];
190: char szDir [_MAX_DIR];
191: char szFname [_MAX_FNAME];
192: char szExt [_MAX_EXT];
193: OMFModule *m;
194: int i;
195: char * pb;
196:
197: _splitpath( p->iptrs.szName, szDrive, szDir, szFname, szExt );
198:
199: m = (OMFModule *) p->pCvCurr;
200:
201: m->ovlNumber = 0;
202: m->iLib = 0;
203: m->cSeg = CSymSegs;
204: m->Style[0] = 'C';
205: m->Style[1] = 'V';
206: for (i=0; i<CSymSegs; i++) {
207: m->SegInfo[i].Seg = i+1;
208: m->SegInfo[i].pad = 0;
209: m->SegInfo[i].Off = 0;
210: m->SegInfo[i].cbSeg = 0xffff;
211: }
212: pb = (char *) &m->SegInfo[CSymSegs];
213: sprintf( &pb[1], "%s.c", szFname );
214: pb[0] = strlen( &pb[1] );
215:
216: pb = (char *) NextMod(m);
217:
218: UpdatePtrs( p, &p->pCvModules, (LPVOID)pb, 1 );
219:
220: return 1;
221: }
222:
223: BOOL CALLBACK
224: ConvertASymtoPublic(PSYMNAME pSymName, int symType, SEGMENT segment,
225: UOFF16 offset, PENUMINFO pEnumInfo )
226: {
227: if (symType != SYM_SYMBOL_NAME) {
228: return TRUE;
229: }
230:
231: pEnumInfo->dataSym->rectyp = S_PUB16;
232: pEnumInfo->dataSym->seg = segment;
233: pEnumInfo->dataSym->off = offset;
234: pEnumInfo->dataSym->typind = 0;
235: pEnumInfo->dataSym->name[0] = pSymName->length;
236: strncpy( &pEnumInfo->dataSym->name[1], pSymName->name, pSymName->length );
237: pEnumInfo->dataSym2 = NextSym16( pEnumInfo->dataSym );
238: pEnumInfo->dataSym->reclen = (USHORT) ((DWORD)pEnumInfo->dataSym2 -
239: (DWORD)pEnumInfo->dataSym) - 2;
240: pEnumInfo->dataSym = pEnumInfo->dataSym2;
241: pEnumInfo->numsyms++;
242:
243: return TRUE;
244: }
245:
246: DWORD
247: CreatePublicsFromSyms( PPOINTERS p )
248:
249: /*++
250:
251: Routine Description:
252:
253: Creates the individual CV public symbol records. There is one CV
254: public record created for each COFF symbol that is marked as EXTERNAL
255: and has a section number greater than zero. The resulting CV publics
256: are sorted by section and offset.
257:
258:
259: Arguments:
260:
261: p - pointer to a POINTERS structure (see cofftocv.h)
262:
263:
264: Return Value:
265:
266: The number of publics created.
267:
268: --*/
269:
270: {
271: OMFSymHash *omfSymHash;
272: ENUMINFO enumInfo;
273:
274:
275: enumInfo.dataSym = (DATASYM16 *)
276: (PUCHAR)((DWORD)p->pCvCurr + sizeof(OMFSymHash));
277: enumInfo.numsyms = 0;
278:
279: EnumSymbols( p, ConvertASymtoPublic, &enumInfo );
280:
281: omfSymHash = (OMFSymHash *) p->pCvCurr;
282: UpdatePtrs(p, &p->pCvPublics, (LPVOID)enumInfo.dataSym,
283: enumInfo.numsyms );
284:
285: omfSymHash->cbSymbol = p->pCvPublics.size - sizeof(OMFSymHash);
286: omfSymHash->symhash = 0;
287: omfSymHash->addrhash = 0;
288: omfSymHash->cbHSym = 0;
289: omfSymHash->cbHAddr = 0;
290:
291: return enumInfo.numsyms;
292: }
293:
294:
295: BOOL CALLBACK
296: ConvertASegment( PSYMNAME pSymName, int symType, SEGMENT segment,
297: UOFF16 offset, PENUMINFO pEnumInfo )
298: {
299: if (symType != SYM_SEGMENT_NAME) {
300: return TRUE;
301: }
302:
303: if (segment == 0) {
304: return TRUE;
305: }
306:
307: pEnumInfo->numsyms++;
308:
309: pEnumInfo->sgi->sgf.fRead = TRUE;
310: pEnumInfo->sgi->sgf.fWrite = TRUE;
311: pEnumInfo->sgi->sgf.fExecute = TRUE;
312: pEnumInfo->sgi->sgf.f32Bit = 0;
313: pEnumInfo->sgi->sgf.fSel = 0;
314: pEnumInfo->sgi->sgf.fAbs = 0;
315: pEnumInfo->sgi->sgf.fGroup = 1;
316: pEnumInfo->sgi->iovl = 0;
317: pEnumInfo->sgi->igr = 0;
318: pEnumInfo->sgi->isgPhy = (USHORT) pEnumInfo->numsyms;
319: pEnumInfo->sgi->isegName = 0;
320: pEnumInfo->sgi->iclassName = 0;
321: pEnumInfo->sgi->doffseg = 0;
322: pEnumInfo->sgi->cbSeg = 0xFFFF;
323: pEnumInfo->sgi++;
324:
325: return TRUE;
326: }
327:
328:
329: DWORD
330: CreateSegMapFromSyms( PPOINTERS p )
331:
332: /*++
333:
334: Routine Description:
335:
336: Creates the CV segment map. The segment map is used by debuggers
337: to aid in address lookups. One segment is created for each COFF
338: section in the image.
339:
340: Arguments:
341:
342: p - pointer to a POINTERS structure (see cofftocv.h)
343:
344:
345: Return Value:
346:
347: The number of segments in the map.
348:
349: --*/
350:
351: {
352: SGM *sgm;
353: ENUMINFO enumInfo;
354:
355:
356: sgm = (SGM *) p->pCvCurr;
357: enumInfo.sgi = (SGI *) ((DWORD)p->pCvCurr + sizeof(SGM));
358: enumInfo.numsyms = 0;
359:
360: EnumSymbols( p, ConvertASegment, &enumInfo );
361:
362: sgm->cSeg = (USHORT)enumInfo.numsyms;
363: sgm->cSegLog = (USHORT)enumInfo.numsyms;
364:
365: UpdatePtrs( p, &p->pCvSegMap, (LPVOID)enumInfo.sgi, enumInfo.numsyms );
366:
367: return enumInfo.numsyms;
368: }
369:
370: BOOL
371: EnumSymbols( PPOINTERS p, SYMBOLENUMPROC lpEnumProc, PENUMINFO pEnumInfo )
372:
373: /*++
374:
375: Routine Description:
376:
377: This function enumerates all symbols ine the mapped SYM file
378:
379:
380: Arguments:
381:
382: p - pointer to a POINTERS structure
383: lpEnumProc - function to be called once for each function
384: pEnumInfo - data to be passed between the caller and the enum func
385:
386: Return Value:
387:
388: TRUE - success
389: FALSE - failure
390:
391: --*/
392:
393: {
394: PSYMFILEHEADER pSymFileHead;
395: PSYMHEADER pSymHead;
396: PSYMSYMBOL pSymSymbol;
397: DWORD i;
398: DWORD startPosition;
399: DWORD position;
400:
401:
402: pSymFileHead = (PSYMFILEHEADER) p->iptrs.fptr;
403: pSymSymbol = (PSYMSYMBOL) ((DWORD)pSymFileHead + SIZEOFSYMFILEHEADER +
404: pSymFileHead->symName.length + 1);
405:
406: if (!lpEnumProc(&pSymFileHead->symName, SYM_SEGMENT_ABS,
407: 0, 0, pEnumInfo )) {
408: return FALSE;
409: }
410:
411: for (i=0; i<pSymFileHead->numSyms; i++) {
412: if (!lpEnumProc(&pSymSymbol->symName, SYM_SYMBOL_ABS,
413: 0, pSymSymbol->offset, pEnumInfo )) {
414: return FALSE;
415: }
416: pSymSymbol = (PSYMSYMBOL) ((DWORD)pSymSymbol + SIZEOFSYMBOL +
417: pSymSymbol->symName.length);
418: }
419:
420: position = startPosition = ((LONG)pSymFileHead->nextOffset) << 4;
421:
422: do {
423: pSymHead = (PSYMHEADER) ((DWORD)p->iptrs.fptr + position);
424: pSymSymbol = (PSYMSYMBOL) ((DWORD)pSymHead + SIZEOFSYMHEADER +
425: pSymHead->symName.length);
426:
427: position = ((LONG)pSymHead->nextOffset) << 4;
428:
429: if (!lpEnumProc( &pSymHead->symName, SYM_SEGMENT_NAME,
430: pSymHead->segment, 0, pEnumInfo )) {
431: return FALSE;
432: }
433:
434: for (i=0; i<pSymHead->numSyms; i++) {
435: if (!lpEnumProc(&pSymSymbol->symName, SYM_SYMBOL_NAME,
436: pSymHead->segment, pSymSymbol->offset,
437: pEnumInfo )) {
438: return FALSE;
439: }
440: pSymSymbol = (PSYMSYMBOL) ((DWORD)pSymSymbol + SIZEOFSYMBOL +
441: pSymSymbol->symName.length);
442: }
443: } while ( position != startPosition && position != 0 );
444:
445: return 0;
446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.