|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1993 Microsoft Corporation
4:
5: Module Name:
6:
7: symbols.c
8:
9: Abstract:
10:
11: This file contains all support for the symbol table.
12:
13: Author:
14:
15: Wesley Witt (wesw) 1-May-1993
16:
17: Environment:
18:
19: User Mode
20:
21: --*/
22:
23: #include <windows.h>
24: #include <stdlib.h>
25: #include <stdio.h>
26: #include <string.h>
27: #include <imagehlp.h>
28:
29: #include "drwatson.h"
30: #include "proto.h"
31: #include "cv.h"
32: #include "messages.h"
33:
34:
35: #define n_name N.ShortName
36: #define n_zeroes N.Name.Short
37: #define n_nptr N.LongName[1]
38: #define n_offset N.Name.Long
39:
40: void GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s );
41: PSYMBOL AllocSym( DWORD symSize, PSYMBOL *symHead, PSYMBOL *symTail );
42: int _CRTAPI1 SymbolCompare( const void *arg1, const void *arg2 );
43:
44:
45: PSYMBOL
46: SymbolSearch( DWORD key, PSYMBOL *base, DWORD num )
47: {
48: PSYMBOL *lo = base;
49: PSYMBOL *hi = base + (num - 1);
50: PSYMBOL *mid = NULL;
51: DWORD half = 0;
52:
53: while (lo <= hi) {
54: if (half = num / 2) {
55: mid = lo + (num & 1 ? half : (half - 1));
56: if ((key >= (*mid)->addr) &&
57: (key < ((*mid)->addr + (*mid)->size))) {
58: return *mid;
59: }
60: if (key < (*mid)->addr) {
61: hi = mid - 1;
62: num = num & 1 ? half : half-1;
63: }
64: else {
65: lo = mid + 1;
66: num = half;
67: }
68: }
69: else
70: if (num) {
71: if ((key >= (*lo)->addr) &&
72: (key < ((*lo)->addr + (*lo)->size))) {
73: return *lo;
74: }
75: else {
76: break;
77: }
78: }
79: else {
80: break;
81: }
82: }
83: return NULL;
84: }
85:
86: PSYMBOL
87: GetSymFromAddr( DWORD dwAddr, PDWORD pdwDisplacement, PMODULEINFO mi )
88: {
89: PSYMBOL sym = NULL;
90:
91: if (mi == NULL) {
92: return sym;
93: }
94:
95: sym = SymbolSearch( dwAddr, mi->symbolTable, mi->numsyms );
96: if (sym !=NULL) {
97: *pdwDisplacement = dwAddr - sym->addr;
98: }
99:
100: return sym;
101: }
102:
103: PMODULEINFO
104: GetModuleForPC( PDEBUGPACKET dp, DWORD dwPcAddr )
105: {
106: PMODULEINFO mi = dp->miHead;
107:
108: Assert( mi != NULL );
109: while (mi) {
110: if ((dwPcAddr >= mi->dwLoadAddress) &&
111: (dwPcAddr <= mi->dwLoadAddress + mi->dwImageSize)) {
112: return mi;
113: }
114: mi = mi->next;
115: }
116:
117: return NULL;
118: }
119:
120: PSYMBOL
121: GetSymFromAddrAllContexts( DWORD dwAddr, PDWORD pdwDisplacement, PDEBUGPACKET dp )
122: {
123: PMODULEINFO mi = GetModuleForPC( dp, dwAddr );
124: if (mi == NULL) {
125: return NULL;
126: }
127: return GetSymFromAddr( dwAddr, pdwDisplacement, mi );
128: }
129:
130: void
131: DumpSymbols( PDEBUGPACKET dp )
132: {
133: DWORD i;
134: PSYMBOL *sym;
135: char *szSymName;
136: PMODULEINFO mi;
137:
138:
139: lprintf( MSG_SYMBOL_TABLE );
140:
141: mi = dp->miHead;
142: while (mi) {
143: lprintfs( "%s\r\n", mi->szName );
144: for (i=0,sym=mi->symbolTable; i<mi->numsyms; i++,sym++) {
145: szSymName = UnDName( &(*sym)->szName[1] );
146: lprintfs( "%08x %s\r\n", (*sym)->addr, szSymName );
147: }
148: lprintfs( "\r\n" );
149: mi = mi->next;
150: }
151:
152: return;
153: }
154:
155: PSYMBOL
156: AllocSym( DWORD symSize, PSYMBOL *symHead, PSYMBOL *symTail )
157: {
158: PSYMBOL sym;
159:
160: sym = (PSYMBOL) malloc( sizeof(SYMBOL)+symSize );
161: if (sym == NULL) {
162: return NULL;
163: }
164: memset( sym, 0, sizeof(SYMBOL)+symSize );
165:
166: if (*symHead == NULL) {
167: *symTail = *symHead = sym;
168: return sym;
169: }
170: else {
171: (*symTail)->next = sym;
172: *symTail = sym;
173: return sym;
174: }
175: return NULL;
176: }
177:
178: BOOL
179: LoadFpoData( PMODULEINFO mi, PFPO_DATA start, DWORD size )
180: {
181: mi->pFpoData = (PFPO_DATA) malloc( size );
182:
183: if (mi->pFpoData == NULL) {
184: return FALSE;
185: }
186:
187: memcpy( mi->pFpoData, start, size );
188:
189: mi->dwEntries = size / sizeof(FPO_DATA);
190:
191: return TRUE;
192: }
193:
194: BOOL
195: LoadExceptionData( PMODULEINFO mi, PRUNTIME_FUNCTION start, DWORD size )
196: {
197: DWORD cFunc;
198: DWORD index;
199: PRUNTIME_FUNCTION rf;
200: PRUNTIME_FUNCTION tf;
201:
202:
203: if (size == 0) {
204: return FALSE;
205: }
206:
207: cFunc = size / sizeof(RUNTIME_FUNCTION);
208:
209: //
210: // Find the start of the padded page (end of the real data)
211: //
212: rf = tf = start;
213: for(index=0; index<cFunc && tf->BeginAddress; tf++,index++) {
214: ;
215: }
216:
217: if (index<cFunc) {
218: cFunc = index;
219: size = index * sizeof(RUNTIME_FUNCTION);
220: }
221:
222: mi->pExceptionData = (PRUNTIME_FUNCTION) malloc( size );
223: if (mi->pExceptionData == NULL) {
224: return FALSE;
225: }
226:
227: memcpy( mi->pExceptionData, rf, size );
228:
229: //
230: // if the image has been relocated then the addresses must be fixed up
231: //
232: if (mi->dwLoadAddress != mi->dwBaseOfImage) {
233: long diff = (LONG)mi->dwLoadAddress - mi->dwBaseOfImage;
234:
235: for (index=0; index<cFunc; index++) {
236: mi->pExceptionData[index].BeginAddress += diff;
237: mi->pExceptionData[index].EndAddress += diff;
238: mi->pExceptionData[index].PrologEndAddress += diff;
239: }
240: }
241:
242: mi->dwEntries = cFunc;
243:
244: return TRUE;
245: }
246:
247: BOOL
248: LoadCoffSymbols( PMODULEINFO mi,
249: PUCHAR stringTable,
250: PIMAGE_SYMBOL allSymbols,
251: DWORD numberOfSymbols
252: )
253: {
254: PIMAGE_SYMBOL NextSymbol;
255: PIMAGE_SYMBOL Symbol;
256: PIMAGE_AUX_SYMBOL AuxSymbol;
257: SYMBOL *sym;
258: char szSymName[256];
259: DWORD len;
260: DWORD numaux;
261: DWORD i;
262: DWORD j;
263: DWORD addr;
264: PSYMBOL *symbolTable;
265: PSYMBOL *symbolTable2;
266: PSYMBOL symHead = NULL;
267: PSYMBOL symTail = NULL;
268:
269: Assert( mi != NULL );
270: NextSymbol = allSymbols;
271: for (i= 0; i < numberOfSymbols; i++) {
272: Symbol = NextSymbol++;
273: if (Symbol->StorageClass == IMAGE_SYM_CLASS_EXTERNAL && Symbol->SectionNumber > 0) {
274: GetSymName( Symbol, stringTable, szSymName );
275: addr = Symbol->Value + mi->dwLoadAddress;
276: len = strlen( szSymName );
277: sym = AllocSym ( len+1, &symHead, &symTail );
278: sym->szName[0] = (UCHAR) len;
279: strcpy( &sym->szName[1], szSymName );
280: sym->addr = addr;
281: mi->numsyms++;
282: }
283: if (numaux = Symbol->NumberOfAuxSymbols) {
284: for (j=numaux; j; --j) {
285: AuxSymbol = (PIMAGE_AUX_SYMBOL) NextSymbol;
286: NextSymbol++;
287: ++i;
288: }
289: }
290: }
291:
292: mi->symbolTable = (PSYMBOL*) malloc( mi->numsyms * sizeof(PSYMBOL) );
293: Assert( mi->symbolTable != NULL );
294:
295: sym = symHead;
296: symbolTable = mi->symbolTable;
297: while (sym) {
298: *symbolTable = sym;
299: symbolTable++;
300: sym = sym->next;
301: }
302:
303: qsort( (void*)mi->symbolTable, mi->numsyms, sizeof(PSYMBOL), SymbolCompare );
304:
305: for (i=0,symbolTable=mi->symbolTable; i<mi->numsyms; i++,symbolTable++) {
306: if (i+1 < mi->numsyms) {
307: symbolTable2 = symbolTable+1;
308: (*symbolTable)->size = (*symbolTable2)->addr - (*symbolTable)->addr;
309: }
310: }
311:
312: return TRUE;
313: }
314:
315: BOOL
316: LoadCodeViewSymbols( PMODULEINFO mi,
317: PUCHAR pCvData,
318: PIMAGE_SECTION_HEADER sectionHdrs,
319: DWORD numSections
320: )
321: {
322: OMFSignature *omfSig;
323: OMFDirHeader *omfDirHdr;
324: OMFDirEntry *omfDirEntry;
325: DATASYM32 *dataSym;
326: OMFSymHash *omfSymHash;
327: SYMBOL *sym;
328: DWORD i;
329: DWORD j;
330: DWORD k;
331: DWORD addr;
332: PSYMBOL *symbolTable;
333: PSYMBOL *symbolTable2;
334: PIMAGE_SECTION_HEADER sh;
335: PSYMBOL symHead = NULL;
336: PSYMBOL symTail = NULL;
337:
338:
339: Assert( mi != NULL );
340: omfSig = (OMFSignature*) pCvData;
341: if ((strncmp( omfSig->Signature, "NB08", 4 ) != 0) &&
342: (strncmp( omfSig->Signature, "NB09", 4 ) != 0)) {
343: return FALSE;
344: }
345:
346: omfDirHdr = (OMFDirHeader*) ((DWORD)omfSig + (DWORD)omfSig->filepos);
347: omfDirEntry = (OMFDirEntry*) ((DWORD)omfDirHdr + sizeof(OMFDirHeader));
348:
349: for (i=0; i<omfDirHdr->cDir; i++,omfDirEntry++) {
350: if (omfDirEntry->SubSection == sstGlobalPub) {
351: omfSymHash = (OMFSymHash*) ((DWORD)omfSig + omfDirEntry->lfo);
352: dataSym = (DATASYM32*) ((DWORD)omfSig + omfDirEntry->lfo + sizeof(OMFSymHash));
353: for (j=sizeof(OMFSymHash); j<=omfSymHash->cbSymbol; ) {
354: sym = AllocSym ( dataSym->name[0]+1, &symHead, &symTail );
355: if (sym != NULL) {
356: for (k=0,addr=0,sh=sectionHdrs; k<numSections; k++, sh++) {
357: if (k+1 == dataSym->seg) {
358: addr = sh->VirtualAddress;
359: }
360: }
361: addr += (dataSym->off + mi->dwLoadAddress);
362: memcpy( sym->szName, dataSym->name, dataSym->name[0]+1 );
363: sym->addr = addr;
364: j += dataSym->reclen + 2;
365: dataSym = (DATASYM32*) ((DWORD)dataSym + dataSym->reclen + 2);
366: mi->numsyms++;
367: }
368: }
369: break;
370: }
371: }
372:
373:
374: mi->symbolTable = (PSYMBOL*) malloc( mi->numsyms * sizeof(PSYMBOL) );
375: if (mi->symbolTable == NULL) {
376: return FALSE;
377: }
378:
379: sym = symHead;
380: symbolTable = mi->symbolTable;
381: i = 0;
382: while (sym) {
383: i++;
384: *symbolTable = sym;
385: symbolTable++;
386: sym = sym->next;
387: }
388:
389: qsort( (void*)mi->symbolTable, mi->numsyms, sizeof(PSYMBOL), SymbolCompare );
390:
391: for (i=0,symbolTable=mi->symbolTable; i<mi->numsyms; i++,symbolTable++) {
392: if (i+1 < mi->numsyms) {
393: symbolTable2 = symbolTable+1;
394: (*symbolTable)->size = (*symbolTable2)->addr - (*symbolTable)->addr;
395: }
396: }
397:
398: return TRUE;
399: }
400:
401: void
402: GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s )
403: {
404: DWORD i;
405:
406: if (Symbol->n_zeroes) {
407: for (i=0; i<8; i++) {
408: if ((Symbol->n_name[i]>0x1f) && (Symbol->n_name[i]<0x7f)) {
409: *s++ = Symbol->n_name[i];
410: }
411: }
412: *s = 0;
413: }
414: else {
415: strcpy( s, &StringTable[Symbol->n_offset] );
416: }
417: }
418:
419: int
420: _CRTAPI1
421: SymbolCompare( const void *arg1, const void *arg2 )
422: {
423: if ((*(PSYMBOL*)arg1)->addr < (*(PSYMBOL*)arg2)->addr) {
424: return -1;
425: }
426: if ((*(PSYMBOL*)arg1)->addr > (*(PSYMBOL*)arg2)->addr) {
427: return 1;
428: }
429: return 0;
430: }
431:
432: char *
433: UnDName (char * dName)
434: {
435: static char outBuf[512];
436: char *p;
437:
438: if (*dName == '_') {
439: ++dName;
440: strcpy(outBuf, dName);
441: p = strchr(outBuf, '@');
442: if (p) {
443: *p = '\0';
444: }
445: }
446: else
447: if(UnDecorateSymbolName( dName,
448: outBuf,
449: sizeof(outBuf),
450: UNDNAME_COMPLETE ) == 0 ) {
451: return NULL;
452: }
453:
454: return outBuf;
455: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.