|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1992 Microsoft Corporation
4:
5: Module Name:
6:
7: cvcommon.c
8:
9: Abstract:
10:
11: This file contians a set of common routines which are used in
12: doing symbol conversions from one type of symbols to CodeView
13: symbols.
14:
15: Author:
16:
17: Jim Schaad (jimsch) 22 May 1993
18:
19: --*/
20:
21: #include <windows.h>
22: #include <stdlib.h>
23: #include "cv.h"
24: #include "symcvt.h"
25: #include "cvcommon.h"
26:
27: typedef struct tagSYMHASH {
28: DWORD dwHashVal; // hash value for the symbol
29: DWORD dwHashBucket; // hash bucket number
30: DATASYM16 * dataSym; // pointer to the symbol info
31: } SYMHASH;
32:
33: typedef struct tagOFFSETSORT {
34: DWORD dwOffset; // offset for the symbol
35: DWORD dwSection; // section number of the symbol
36: DATASYM16 * dataSym; // pointer to the symbol info
37: } OFFSETSORT;
38:
39:
40: int _CRTAPI1 SymHashCompare( const void *arg1, const void *arg2 );
41: int _CRTAPI1 OffsetSortCompare( const void *arg1, const void *arg2 );
42:
43:
44: DWORD
45: CreateSignature( PPOINTERS p )
46:
47: /*++
48:
49: Routine Description:
50:
51: Creates the CODEVIEW signature record. Currently this converter only
52: generates NB08 data (MS C/C++ 7.0).
53:
54:
55: Arguments:
56:
57: p - pointer to a POINTERS structure (see cofftocv.h)
58:
59:
60: Return Value:
61:
62: number of records generates, this is always 1.
63:
64: --*/
65:
66: {
67: OMFSignature *omfSig;
68:
69: omfSig = (OMFSignature *) p->pCvCurr;
70: strcpy( omfSig->Signature, "NB08" );
71: omfSig->filepos = 0;
72: p->pCvStart.size += sizeof(OMFSignature);
73: p->pCvCurr = (PUCHAR) p->pCvCurr + sizeof(OMFSignature);
74: return 1;
75: } /* CreateSignature() */
76:
77:
78: DWORD
79: CreateDirectories( PPOINTERS p )
80:
81: /*++
82:
83: Routine Description:
84:
85: This is the control function for the generation of the CV directories.
86: It calls individual functions for the generation of specific types of
87: debug directories.
88:
89:
90: Arguments:
91:
92: p - pointer to a POINTERS structure (see cofftocv.h)
93:
94:
95: Return Value:
96:
97: the number of directories created.
98:
99: --*/
100:
101: {
102: OMFDirHeader *omfDir = (OMFDirHeader *)p->pCvCurr;
103: OMFSignature *omfSig = (OMFSignature *)p->pCvStart.ptr;
104: OMFDirEntry *omfDirEntry = NULL;
105:
106: omfSig->filepos = (DWORD)p->pCvCurr - (DWORD)p->pCvStart.ptr;
107:
108: omfDir->cbDirHeader = sizeof(OMFDirHeader);
109: omfDir->cbDirEntry = sizeof(OMFDirEntry);
110: omfDir->cDir = 0;
111: omfDir->lfoNextDir = 0;
112: omfDir->flags = 0;
113:
114: p->pCvStart.size += sizeof(OMFDirHeader);
115: p->pCvCurr = (PUCHAR) p->pCvCurr + sizeof(OMFDirHeader);
116:
117: omfDir->cDir += CreateModuleDirectoryEntries( p );
118: omfDir->cDir += CreatePublicDirectoryEntries( p );
119: omfDir->cDir += CreateSegMapDirectoryEntries( p );
120:
121: strcpy(p->pCvCurr, "NB080000");
122: p->pCvStart.size += 8;
123: p->pCvCurr += 8;
124: *((DWORD *) (p->pCvCurr-4)) = p->pCvStart.size;
125:
126: return omfDir->cDir;
127: } /* CreateDirectories() */
128:
129:
130: DWORD
131: CreateModuleDirectoryEntries( PPOINTERS p )
132:
133: /*++
134:
135: Routine Description:
136:
137: Creates directory entries for each module in the image.
138:
139:
140: Arguments:
141:
142: p - pointer to a POINTERS structure (see cofftocv.h)
143:
144:
145: Return Value:
146:
147: the number of directory entries created.
148:
149: --*/
150:
151: {
152: OMFDirEntry *omfDirEntry = NULL;
153: OMFModule *m = NULL;
154: OMFModule *mNext = NULL;
155: DWORD i = 0;
156: DWORD mSize = 0;
157: DWORD lfo = (DWORD)p->pCvModules.ptr - (DWORD)p->pCvStart.ptr;
158:
159: m = (OMFModule *) p->pCvModules.ptr;
160: for (i=0; i<p->pCvModules.count; i++) {
161: mNext = NextMod(m);
162:
163: omfDirEntry = (OMFDirEntry *) p->pCvCurr;
164:
165: mSize = (DWORD)mNext - (DWORD)m;
166: omfDirEntry->SubSection = sstModule;
167: omfDirEntry->iMod = (USHORT) i + 1;
168: omfDirEntry->lfo = lfo;
169: omfDirEntry->cb = mSize;
170:
171: lfo += mSize;
172:
173: p->pCvStart.size += sizeof(OMFDirEntry);
174: p->pCvCurr = (PUCHAR) p->pCvCurr + sizeof(OMFDirEntry);
175:
176: m = mNext;
177: }
178:
179: return p->pCvModules.count;
180: } /* CreateModuleDirectoryEntries() */
181:
182:
183: DWORD
184: CreatePublicDirectoryEntries( PPOINTERS p )
185:
186: /*++
187:
188: Routine Description:
189:
190: Creates the directory entry for the global publics.
191:
192: Arguments:
193:
194: p - pointer to a POINTERS structure (see cofftocv.h)
195:
196:
197: Return Value:
198:
199: the number of directory entries created, always 1.
200:
201: --*/
202:
203: {
204: OMFDirEntry *omfDirEntry = (OMFDirEntry *) p->pCvCurr;
205:
206: omfDirEntry->SubSection = sstGlobalPub;
207: omfDirEntry->iMod = 0xffff;
208: omfDirEntry->lfo = (DWORD)p->pCvPublics.ptr - (DWORD)p->pCvStart.ptr;
209: omfDirEntry->cb = p->pCvPublics.size;
210:
211: p->pCvStart.size += sizeof(OMFDirEntry);
212: p->pCvCurr = (PUCHAR) p->pCvCurr + sizeof(OMFDirEntry);
213:
214: return 1;
215: } /* CreatePublicDirectoryEntries() */
216:
217:
218: DWORD
219: CreateSegMapDirectoryEntries( PPOINTERS p )
220:
221: /*++
222:
223: Routine Description:
224:
225: Creates the directory entry for the segment map.
226:
227:
228: Arguments:
229:
230: p - pointer to a POINTERS structure (see cofftocv.h)
231:
232:
233: Return Value:
234:
235: the number of directory entries created, always 1.
236:
237: --*/
238:
239: {
240: OMFDirEntry *omfDirEntry = (OMFDirEntry *) p->pCvCurr;
241:
242: omfDirEntry->SubSection = sstSegMap;
243: omfDirEntry->iMod = 0xffff;
244: omfDirEntry->lfo = (DWORD)p->pCvSegMap.ptr - (DWORD)p->pCvStart.ptr;
245: omfDirEntry->cb = p->pCvSegMap.size;
246:
247: p->pCvStart.size += sizeof(OMFDirEntry);
248: p->pCvCurr = (PUCHAR) p->pCvCurr + sizeof(OMFDirEntry);
249:
250: return 1;
251: } /* CreateSegMapDirectoryEntries() */
252:
253:
254: DWORD
255: DWordXorLrl( char *szSym )
256:
257: /*++
258:
259: Routine Description:
260:
261: This function will take an ascii character string and generate
262: a hash for that string. The hash algorithm is the CV NB08 hash
263: algorithm.
264:
265:
266: Arguments:
267:
268: szSym - a character pointer, the first char is the string length
269:
270:
271: Return Value:
272:
273: The generated hash value.
274:
275: --*/
276:
277: {
278: char *pName = szSym+1;
279: int cb = *szSym;
280: char *pch;
281: DWORD hash = 0;
282: DWORD UNALIGNED *pul = (DWORD *) pName;
283: static rgMask[] = {0, 0xff, 0xffff, 0xffffff};
284:
285: pch = pName + cb - 1;
286: while (isdigit(*pch)) {
287: pch--;
288: }
289:
290: if (*pch == '@') {
291: cb = pch - pName;
292: }
293:
294: for (; cb > 3; cb-=4, pul++) {
295: hash = _lrotl(hash, 4);
296: hash ^= (*pul & 0xdfdfdfdf);
297: }
298:
299: if (cb > 0) {
300: hash = _lrotl(hash,4);
301: hash ^= ((*pul & rgMask[cb]) & 0xdfdfdfdf);
302: }
303:
304: return hash;
305: } /* DWordXorLrl() */
306:
307:
308:
309: OMFModule *
310: NextMod(
311: OMFModule * pMod
312: )
313: /*++
314:
315: Routine Description:
316:
317: description-of-function.
318:
319: Arguments:
320:
321: argument-name - Supplies | Returns description of argument.
322: .
323: .
324:
325: Return Value:
326:
327: return-value - Description of conditions needed to return value. - or -
328: None.
329:
330: --*/
331:
332: {
333: char * pb;
334:
335: pb = (char *) &(pMod->SegInfo[pMod->cSeg]);
336: pb += *pb + 1;
337: pb = (char *) (((unsigned long) pb + 3) & ~3);
338:
339: return (OMFModule *) pb;
340: } /* NextMod() */
341:
342:
343:
344: int
345: _CRTAPI1
346: SymHashCompare(
347: const void * arg1,
348: const void * arg2
349: )
350: /*++
351:
352: Routine Description:
353:
354: Sort compare function for sorting SYMHASH records by hashed
355: bucket number.
356:
357:
358: Arguments:
359:
360: arg1 - record #1
361: arg2 - record #2
362:
363:
364: Return Value:
365:
366: -1 - record #1 is < record #2
367: 0 - records are equal
368: 1 - record #1 is > record #2
369:
370: --*/
371:
372: {
373: if (((SYMHASH*)arg1)->dwHashBucket < ((SYMHASH*)arg2)->dwHashBucket) {
374: return -1;
375: }
376: if (((SYMHASH*)arg1)->dwHashBucket > ((SYMHASH*)arg2)->dwHashBucket) {
377: return 1;
378: }
379: return 0;
380: } /* SymHashCompare() */
381:
382:
383: DWORD
384: CreateSymbolHashTable(
385: PPOINTERS p
386: )
387: /*++
388:
389: Routine Description:
390:
391:
392: Creates the CV symbol hash table. This hash table is used
393: primarily by debuggers to access symbols in a quick manner.
394:
395:
396: Arguments:
397:
398: p - pointer to a POINTERS structure (see cofftocv.h)
399:
400:
401: Return Value:
402:
403: The number of buckets is the hash table.
404:
405: --*/
406:
407: {
408: DWORD i;
409: DWORD j;
410: int k;
411: DWORD numsyms;
412: DWORD numbuckets;
413: OMFSymHash *omfSymHash;
414: DATASYM16 *dataSymStart;
415: DATASYM16 *dataSym;
416: LPVOID pHashData;
417: USHORT *pCHash;
418: DWORD *pHashTable;
419: USHORT *pBucketCounts;
420: DWORD *pChainTable;
421: SYMHASH *symHashStart;
422: SYMHASH *symHash;
423: DWORD dwHashVal;
424: char * sz;
425:
426: numsyms = p->pCvPublics.count;
427: numbuckets = (numsyms+9) / 10;
428: numbuckets = (1 + numbuckets) & ~1;
429:
430: symHashStart =
431: symHash = (SYMHASH *) malloc( numsyms * sizeof(SYMHASH) );
432: if (symHashStart == NULL) {
433: return 0;
434: }
435:
436: memset( symHashStart, 0, numsyms * sizeof(SYMHASH) );
437:
438: pHashData = (LPVOID) p->pCvCurr;
439: pCHash = (USHORT *) pHashData;
440: pHashTable = (DWORD *) ((DWORD)pHashData + sizeof(DWORD));
441: pBucketCounts = (USHORT *) ((DWORD)pHashTable +
442: (sizeof(DWORD) * numbuckets));
443: pChainTable = (DWORD *) ((DWORD)pBucketCounts +
444: ((sizeof(USHORT) * numbuckets)));
445:
446: omfSymHash = (OMFSymHash *) p->pCvPublics.ptr;
447: dataSymStart =
448: dataSym = (DATASYM16 *) ((DWORD)omfSymHash + sizeof(OMFSymHash));
449:
450: *pCHash = (USHORT)numbuckets;
451:
452: /*
453: * cruise thru the symbols and calculate the hash values
454: * and the hash bucket numbers; save the info away for later use
455: */
456: for (i=0; i<numsyms; i++, symHash++) {
457: switch( dataSym->rectyp ) {
458: case S_PUB16:
459: sz = dataSym->name;
460: break;
461:
462: case S_PUB32:
463: sz = ((DATASYM32 *) dataSym)->name;
464: break;
465:
466: default:
467: continue;
468: exit(1);
469: }
470:
471: dwHashVal = DWordXorLrl( sz );
472: symHash->dwHashBucket = dwHashVal % numbuckets;
473: pBucketCounts[symHash->dwHashBucket] += 1;
474: symHash->dataSym = dataSym;
475: dataSym = ((DATASYM16 *) ((char *) dataSym + dataSym->reclen + 2));
476: }
477:
478: qsort( (void*)symHashStart, numsyms, sizeof(SYMHASH), SymHashCompare );
479:
480: j = (char *)pChainTable - (char *)pHashData;
481: for (i=0, k = 0; i<numbuckets;
482: k += pBucketCounts[i], i += 1, pHashTable++ ) {
483: *pHashTable = (DWORD) j + (k * 4);
484: }
485:
486: dataSymStart = (DATASYM16 *) (PUCHAR)((DWORD)omfSymHash);
487: for (i=0,symHash=symHashStart; i<numsyms; i++,symHash++,pChainTable++) {
488: *pChainTable = (DWORD) (DWORD)symHash->dataSym - (DWORD)dataSymStart;
489: }
490:
491: UpdatePtrs( p, &p->pCvSymHash, (LPVOID)pChainTable, numsyms );
492:
493: omfSymHash->symhash = 6;
494: omfSymHash->cbHSym = p->pCvSymHash.size;
495:
496: free( symHashStart );
497:
498: return numbuckets;
499: } /* CreateSymbolHashTable() */
500:
501:
502: VOID
503: UpdatePtrs( PPOINTERS p, PPTRINFO pi, LPVOID lpv, DWORD count )
504:
505: /*++
506:
507: Routine Description:
508:
509: This function is called by ALL functions that put data into the
510: CV data area. After putting the data into the CV memory this function
511: must be called. It will adjust all of the necessary pointers so the
512: the next guy doesn't get hosed.
513:
514:
515: Arguments:
516:
517: p - pointer to a POINTERS structure (see cofftocv.h)
518: pi - the CV pointer that is to be updated
519: lpv - current pointer into the CV data
520: count - the number of items that were placed into the CV data
521:
522:
523: Return Value:
524:
525: void
526:
527: --*/
528:
529: {
530: pi->ptr = p->pCvCurr;
531: pi->size = (DWORD) ((DWORD)lpv - (DWORD)p->pCvCurr);
532: pi->count = count;
533:
534: p->pCvStart.size += pi->size;
535: p->pCvCurr = (PUCHAR) lpv;
536:
537: return;
538: } /* UpdatePtrs() */
539:
540:
541: int
542: _CRTAPI1
543: OffsetSortCompare( const void *arg1, const void *arg2 )
544:
545: /*++
546:
547: Routine Description:
548:
549: Sort compare function for sorting OFFETSORT records by section number.
550:
551:
552: Arguments:
553:
554: arg1 - record #1
555: arg2 - record #2
556:
557:
558: Return Value:
559:
560: -1 - record #1 is < record #2
561: 0 - records are equal
562: 1 - record #1 is > record #2
563:
564: --*/
565:
566: {
567: if (((OFFSETSORT*)arg1)->dwSection < ((OFFSETSORT*)arg2)->dwSection) {
568: return -1;
569: }
570: if (((OFFSETSORT*)arg1)->dwSection > ((OFFSETSORT*)arg2)->dwSection) {
571: return 1;
572: }
573: if (((OFFSETSORT*)arg1)->dwOffset < ((OFFSETSORT*)arg2)->dwOffset) {
574: return -1;
575: }
576: if (((OFFSETSORT*)arg1)->dwOffset > ((OFFSETSORT*)arg2)->dwOffset) {
577: return 1;
578: }
579: return 0;
580: } /* OffsetSortCompare() */
581:
582:
583: DWORD
584: CreateAddressSortTable( PPOINTERS p )
585:
586: /*++
587:
588: Routine Description:
589:
590:
591: Creates the CV address sort table. This hash table is used
592: primarily by debuggers to access symbols in a quick manner when
593: all you have is an address.
594:
595: Arguments:
596:
597: p - pointer to a POINTERS structure (see cofftocv.h)
598:
599:
600: Return Value:
601:
602: The number of sections in the table.
603:
604: --*/
605:
606: {
607: DWORD i;
608: DWORD j;
609: int k;
610: DWORD numsyms = p->pCvPublics.count;
611: DWORD numsections;
612: OMFSymHash *omfSymHash;
613: DATASYM16 *dataSymStart;
614: DATASYM16 *dataSym;
615: LPVOID pAddressData;
616: USHORT *pCSeg;
617: DWORD *pSegTable;
618: USHORT *pOffsetCounts;
619: DWORD *pOffsetTable;
620: OFFSETSORT *pOffsetSortStart;
621: OFFSETSORT *pOffsetSort;
622:
623: extern int CSymSegs;
624:
625: if (p->iptrs.fileHdr) {
626: numsections = p->iptrs.fileHdr->NumberOfSections;
627: } else if (p->iptrs.sepHdr) {
628: numsections = p->iptrs.sepHdr->NumberOfSections;
629: } else {
630: numsections = CSymSegs;
631: }
632:
633: pOffsetSortStart =
634: pOffsetSort = (OFFSETSORT *) malloc( numsyms * sizeof(OFFSETSORT) );
635:
636: if (pOffsetSort == NULL) {
637: return 0;
638: }
639:
640: memset( pOffsetSortStart, 0, numsyms * sizeof(OFFSETSORT) );
641:
642: pAddressData = (LPVOID) p->pCvCurr;
643: pCSeg = (USHORT *) pAddressData;
644: pSegTable = (DWORD *) ((DWORD)pAddressData + sizeof(DWORD));
645: pOffsetCounts = (USHORT *) ((DWORD)pSegTable +
646: (sizeof(DWORD) * numsections));
647: pOffsetTable = (DWORD *) ((DWORD)pOffsetCounts +
648: ((sizeof(USHORT) * numsections)));
649: if (numsections & 1) {
650: pOffsetTable = (DWORD *) ((DWORD)pOffsetTable + 2);
651: }
652:
653: omfSymHash = (OMFSymHash *) p->pCvPublics.ptr;
654: dataSymStart =
655: dataSym = (DATASYM16 *) ((DWORD)omfSymHash + sizeof(OMFSymHash));
656:
657: *pCSeg = (USHORT)numsections;
658:
659: for (i=0;
660: i<numsyms;
661: i++, pOffsetSort++)
662: {
663: switch(dataSym->rectyp) {
664: case S_PUB16:
665: pOffsetSort->dwOffset = dataSym->off;
666: pOffsetSort->dwSection = dataSym->seg;
667: break;
668:
669: case S_PUB32:
670: pOffsetSort->dwOffset = ((DATASYM32 *) dataSym)->off;
671: pOffsetSort->dwSection = ((DATASYM32 *) dataSym)->seg;
672: }
673:
674: pOffsetSort->dataSym = dataSym;
675: pOffsetCounts[pOffsetSort->dwSection - 1] += 1;
676: dataSym = ((DATASYM16 *) ((char *) dataSym + dataSym->reclen + 2)); }
677:
678: //#if 0
679: qsort((void*)pOffsetSortStart, numsyms, sizeof(OFFSETSORT),
680: OffsetSortCompare );
681: //#endif
682:
683: j = (DWORD) (DWORD)pOffsetTable - (DWORD)pAddressData;
684: for (i=0, k=0; i<numsections;
685: k += pOffsetCounts[i], i += 1, pSegTable++) {
686: *pSegTable = (DWORD) j + (k * 4);
687: }
688:
689: dataSymStart = (DATASYM16 *) (PUCHAR)((DWORD)omfSymHash);
690: for (i=0, pOffsetSort=pOffsetSortStart;
691: i < numsyms;
692: i++, pOffsetSort++, pOffsetTable++) {
693: *pOffsetTable = (DWORD)pOffsetSort->dataSym - (DWORD)dataSymStart;
694: }
695:
696: UpdatePtrs( p, &p->pCvAddrSort, (LPVOID)pOffsetTable, numsyms );
697:
698: omfSymHash->addrhash = 5;
699: omfSymHash->cbHAddr = p->pCvAddrSort.size;
700:
701: free( pOffsetSortStart );
702:
703: return numsections;
704: } /* CreateAddressSort() */
705:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.