|
|
1.1 root 1: /*++
2:
3:
4: Copyright (c) 1992 Microsoft Corporation
5:
6: Module Name:
7:
8: cv.c
9:
10: Abstract:
11:
12: This module handles the conversion activities requires for converting
13: COFF debug data to CODEVIEW debug data.
14:
15: Author:
16:
17: Wesley A. Witt (wesw) 19-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 tagOFFSETSORT {
35: DWORD dwOffset; // offset for the symbol
36: DWORD dwSection; // section number of the symbol
37: DATASYM32 *dataSym; // pointer to the symbol info
38: } OFFSETSORT;
39:
40:
41: #define n_name N.ShortName
42: #define n_zeroes N.Name.Short
43: #define n_nptr N.LongName[1]
44: #define n_offset N.Name.Long
45:
46: static VOID GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s );
47: DWORD CreateModulesFromCoff( PPOINTERS p );
48: DWORD CreatePublicsFromCoff( PPOINTERS p );
49: DWORD CreateSegMapFromCoff( PPOINTERS p );
50:
51: BOOL
52: ConvertCoffToCv( PPOINTERS p )
53:
54: /*++
55:
56: Routine Description:
57:
58: This is the control function for the conversion of COFF to CODEVIEW
59: debug data. It calls individual functions for the conversion of
60: specific types of debug data.
61:
62:
63: Arguments:
64:
65: p - pointer to a POINTERS structure (see cofftocv.h)
66:
67:
68: Return Value:
69:
70: TRUE - conversion succeded
71: FALSE - conversion failed
72:
73: --*/
74:
75: {
76: p->pCvCurr = p->pCvStart.ptr = malloc( p->iptrs.fsize );
77: if (p->pCvStart.ptr == NULL) {
78: return FALSE;
79: }
80: memset( p->pCvStart.ptr, 0, p->iptrs.fsize );
81:
82: try {
83: CreateSignature( p );
84: CreateModulesFromCoff( p );
85: CreatePublicsFromCoff( p );
86: CreateSymbolHashTable( p );
87: CreateAddressSortTable( p );
88: CreateSegMapFromCoff( p );
89: CreateDirectories( p );
90: } except (EXCEPTION_EXECUTE_HANDLER) {
91: free( p->pCvStart.ptr );
92: p->pCvStart.ptr = NULL;
93: return FALSE;
94: }
95:
96: p->pCvStart.ptr = realloc( p->pCvStart.ptr, p->pCvStart.size );
97:
98: return TRUE;
99: }
100:
101:
102: DWORD
103: CreateModulesFromCoff( PPOINTERS p )
104:
105: /*++
106:
107: Routine Description:
108:
109: Creates the individual CV module records. There is one CV module
110: record for each .FILE record in the COFF debug data. This is true
111: even if the COFF size is zero.
112:
113:
114: Arguments:
115:
116: p - pointer to a POINTERS structure (see cofftocv.h)
117:
118:
119: Return Value:
120:
121: The number of modules that were created.
122:
123: --*/
124:
125: {
126: int i;
127: DWORD numaux;
128: DWORD nummods = 0;
129: char szSymName[256];
130: PIMAGE_SYMBOL Symbol;
131: PIMAGE_AUX_SYMBOL AuxSymbol;
132: OMFModule *m;
133: int cSeg;
134: char * pb;
135: BOOLEAN rgfCode[100];
136:
137: memset(rgfCode, 2, sizeof(rgfCode));
138:
139: m = NULL;
140:
141: for (i= 0, Symbol = p->iptrs.AllSymbols;
142: i < (int) p->iptrs.numberOfSymbols;
143: i += numaux + 1, Symbol += numaux + 1) {
144:
145: /*
146: * Get the number of aux symbol records for this symbol
147: */
148:
149: numaux = Symbol->NumberOfAuxSymbols;
150: AuxSymbol = (PIMAGE_AUX_SYMBOL) (Symbol+1);
151:
152: /*
153: * If this is a FILE record -- then we need to create a
154: * module item to correspond to this file record.
155: */
156:
157: if (Symbol->StorageClass == IMAGE_SYM_CLASS_FILE) {
158: if (m == NULL) {
159: m = (OMFModule *) p->pCvCurr;
160: } else {
161: /*
162: * Clean up the last item, if we saw any
163: * section records then drop them in here
164: */
165:
166: if (cSeg > 0) {
167: m->cSeg = cSeg;
168: pb = (char *) &m->SegInfo[cSeg];
169: *pb = strlen(szSymName);
170: memcpy(pb+1, szSymName, *pb);
171:
172: m = NextMod(m);
173: nummods++;
174: }
175: }
176:
177: cSeg = 0;
178: m->ovlNumber = 0;
179: m->iLib = 0;
180: m->Style[0] = 'C';
181: m->Style[1] = 'V';
182:
183: /*
184: * Save off the file name to use when we have finished
185: * processing this module
186: */
187:
188: memcpy(szSymName, (char *)AuxSymbol, numaux*sizeof(IMAGE_AUX_SYMBOL));
189: szSymName[numaux*sizeof(IMAGE_AUX_SYMBOL)] = 0;
190:
191: }
192: /*
193: * We have found a "SECTION" record. Add the info to the
194: * module record
195: */
196: else if ((Symbol->SectionNumber & 0xffff) > 0xfff0) {
197: continue;
198: } else if (Symbol->SectionNumber > sizeof(rgfCode)/sizeof(rgfCode[0])) {
199: return 0;
200: } else if ((m != NULL) &&
201: (rgfCode[Symbol->SectionNumber] != 0) &&
202: (Symbol->StorageClass == IMAGE_SYM_CLASS_STATIC) &&
203: ((*Symbol->n_name == '.') ||
204: (Symbol->Type == IMAGE_SYM_TYPE_NULL)) &&
205: (Symbol->NumberOfAuxSymbols == 1) &&
206: (AuxSymbol->Section.Length != 0)) {
207:
208: if (rgfCode[Symbol->SectionNumber] == 2) {
209: if ((p->iptrs.sectionHdrs[Symbol->SectionNumber - 1].
210: Characteristics & IMAGE_SCN_CNT_CODE) == 0) {
211: rgfCode[Symbol->SectionNumber] = 0;
212: continue;
213: }
214: rgfCode[Symbol->SectionNumber] = 1;
215: }
216:
217: m->SegInfo[cSeg].Seg = Symbol->SectionNumber;
218: m->SegInfo[cSeg].cbSeg = AuxSymbol->Section.Length;
219: m->SegInfo[cSeg].Off = Symbol->Value -
220: p->iptrs.sectionHdrs[Symbol->SectionNumber-1].
221: VirtualAddress;
222: cSeg += 1;
223: }
224: }
225:
226: /*
227: * Wrap up the last possible open module record
228: */
229:
230: if (m != NULL) {
231: if (cSeg > 0) {
232: m->cSeg = cSeg;
233: pb = (char *) &m->SegInfo[cSeg];
234: *pb = strlen(szSymName);
235: memcpy(pb+1, szSymName, *pb);
236:
237: m = NextMod(m);
238: nummods++;
239: }
240: }
241:
242: UpdatePtrs( p, &p->pCvModules, (LPVOID)m, nummods );
243:
244: return nummods;
245: }
246:
247:
248: DWORD
249: CreatePublicsFromCoff( PPOINTERS p )
250:
251: /*++
252:
253: Routine Description:
254:
255: Creates the individual CV public symbol records. There is one CV
256: public record created for each COFF symbol that is marked as EXTERNAL
257: and has a section number greater than zero. The resulting CV publics
258: are sorted by section and offset.
259:
260:
261: Arguments:
262:
263: p - pointer to a POINTERS structure (see cofftocv.h)
264:
265:
266: Return Value:
267:
268: The number of publics created.
269:
270: --*/
271:
272: {
273: int i;
274: DWORD numaux;
275: DWORD numsyms = 0;
276: char szSymName[256];
277: PIMAGE_SYMBOL Symbol;
278: OMFSymHash *omfSymHash;
279: DATASYM32 *dataSym;
280: DATASYM32 *dataSym2;
281:
282: omfSymHash = (OMFSymHash *) p->pCvCurr;
283: dataSym = (DATASYM32 *) (PUCHAR)((DWORD)omfSymHash + sizeof(OMFSymHash));
284:
285: for (i= 0, Symbol = p->iptrs.AllSymbols;
286: i < p->iptrs.numberOfSymbols;
287: i += numaux + 1, Symbol += numaux + 1) {
288:
289: if ((Symbol->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) &&
290: (Symbol->SectionNumber > 0)) {
291:
292: GetSymName( Symbol, p->iptrs.stringTable, szSymName );
293: dataSym->rectyp = S_PUB32;
294: dataSym->seg = Symbol->SectionNumber;
295: dataSym->off = Symbol->Value -
296: p->iptrs.sectionHdrs[Symbol->SectionNumber-1].VirtualAddress;
297: dataSym->typind = 0;
298: dataSym->name[0] = strlen( szSymName );
299: strcpy( &dataSym->name[1], szSymName );
300: dataSym2 = NextSym32( dataSym );
301: dataSym->reclen = (USHORT) ((DWORD)dataSym2 - (DWORD)dataSym) - 2;
302: dataSym = dataSym2;
303: numsyms += 1;
304: }
305: numaux = Symbol->NumberOfAuxSymbols;
306: }
307:
308: UpdatePtrs( p, &p->pCvPublics, (LPVOID)dataSym, numsyms );
309:
310: omfSymHash->cbSymbol = p->pCvPublics.size - sizeof(OMFSymHash);
311: omfSymHash->symhash = 0;
312: omfSymHash->addrhash = 0;
313: omfSymHash->cbHSym = 0;
314: omfSymHash->cbHAddr = 0;
315:
316: return numsyms;
317: } /* CreatePublisFromCoff() */
318:
319:
320: DWORD
321: CreateSegMapFromCoff( PPOINTERS p )
322:
323: /*++
324:
325: Routine Description:
326:
327: Creates the CV segment map. The segment map is used by debuggers
328: to aid in address lookups. One segment is created for each COFF
329: section in the image.
330:
331: Arguments:
332:
333: p - pointer to a POINTERS structure (see cofftocv.h)
334:
335:
336: Return Value:
337:
338: The number of segments in the map.
339:
340: --*/
341:
342: {
343: int i;
344: SGM *sgm;
345: SGI *sgi;
346: PIMAGE_SECTION_HEADER sh;
347:
348:
349: sgm = (SGM *) p->pCvCurr;
350: sgi = (SGI *) ((DWORD)p->pCvCurr + sizeof(SGM));
351:
352: sgm->cSeg = p->iptrs.numberOfSections;
353: sgm->cSegLog = p->iptrs.numberOfSections;
354:
355: sh = p->iptrs.sectionHdrs;
356:
357: for (i=0; i<p->iptrs.numberOfSections; i++, sh++) {
358: sgi->sgf.fRead = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_READ) == IMAGE_SCN_MEM_READ;
359: sgi->sgf.fWrite = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_WRITE) == IMAGE_SCN_MEM_WRITE;
360: sgi->sgf.fExecute = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_EXECUTE) == IMAGE_SCN_MEM_EXECUTE;
361: sgi->sgf.f32Bit = 1;
362: sgi->sgf.fSel = 0;
363: sgi->sgf.fAbs = 0;
364: sgi->sgf.fGroup = 1;
365: sgi->iovl = 0;
366: sgi->igr = 0;
367: sgi->isgPhy = (USHORT) i + 1;
368: sgi->isegName = 0;
369: sgi->iclassName = 0;
370: sgi->doffseg = 0;
371: sgi->cbSeg = sh->SizeOfRawData;
372: sgi++;
373: }
374:
375: UpdatePtrs( p, &p->pCvSegMap, (LPVOID)sgi, i );
376:
377: return i;
378: }
379:
380:
381: void
382: GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s )
383:
384: /*++
385:
386: Routine Description:
387:
388: Extracts the COFF symbol from the image symbol pointer and puts
389: the ascii text in the character pointer passed in.
390:
391:
392: Arguments:
393:
394: Symbol - COFF Symbol Record
395: StringTable - COFF string table
396: s - buffer for the symbol string
397:
398:
399: Return Value:
400:
401: void
402:
403: --*/
404:
405: {
406: DWORD i;
407:
408: if (Symbol->n_zeroes) {
409: for (i=0; i<8; i++) {
410: if ((Symbol->n_name[i]>0x1f) && (Symbol->n_name[i]<0x7f)) {
411: *s++ = Symbol->n_name[i];
412: }
413: }
414: *s = 0;
415: }
416: else {
417: strcpy( s, &StringTable[Symbol->n_offset] );
418: }
419: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.