|
|
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: mi->dwEntries = cFunc;
230:
231: return TRUE;
232: }
233:
234: BOOL
235: LoadCoffSymbols( PMODULEINFO mi,
236: PUCHAR stringTable,
237: PIMAGE_SYMBOL allSymbols,
238: DWORD numberOfSymbols
239: )
240: {
241: PIMAGE_SYMBOL NextSymbol;
242: PIMAGE_SYMBOL Symbol;
243: PIMAGE_AUX_SYMBOL AuxSymbol;
244: SYMBOL *sym;
245: char szSymName[256];
246: DWORD len;
247: DWORD numaux;
248: DWORD i;
249: DWORD j;
250: DWORD addr;
251: PSYMBOL *symbolTable;
252: PSYMBOL *symbolTable2;
253: PSYMBOL symHead = NULL;
254: PSYMBOL symTail = NULL;
255:
256: Assert( mi != NULL );
257: NextSymbol = allSymbols;
258: for (i= 0; i < numberOfSymbols; i++) {
259: Symbol = NextSymbol++;
260: if (Symbol->StorageClass == IMAGE_SYM_CLASS_EXTERNAL && Symbol->SectionNumber > 0) {
261: GetSymName( Symbol, stringTable, szSymName );
262: addr = Symbol->Value + mi->dwLoadAddress;
263: len = strlen( szSymName );
264: sym = AllocSym ( len+1, &symHead, &symTail );
265: sym->szName[0] = (UCHAR) len;
266: strcpy( &sym->szName[1], szSymName );
267: sym->addr = addr;
268: mi->numsyms++;
269: }
270: if (numaux = Symbol->NumberOfAuxSymbols) {
271: for (j=numaux; j; --j) {
272: AuxSymbol = (PIMAGE_AUX_SYMBOL) NextSymbol;
273: NextSymbol++;
274: ++i;
275: }
276: }
277: }
278:
279: mi->symbolTable = (PSYMBOL*) malloc( mi->numsyms * sizeof(PSYMBOL) );
280: Assert( mi->symbolTable != NULL );
281:
282: sym = symHead;
283: symbolTable = mi->symbolTable;
284: while (sym) {
285: *symbolTable = sym;
286: symbolTable++;
287: sym = sym->next;
288: }
289:
290: qsort( (void*)mi->symbolTable, mi->numsyms, sizeof(PSYMBOL), SymbolCompare );
291:
292: for (i=0,symbolTable=mi->symbolTable; i<mi->numsyms; i++,symbolTable++) {
293: if (i+1 < mi->numsyms) {
294: symbolTable2 = symbolTable+1;
295: (*symbolTable)->size = (*symbolTable2)->addr - (*symbolTable)->addr;
296: }
297: }
298:
299: return TRUE;
300: }
301:
302: BOOL
303: LoadCodeViewSymbols( PMODULEINFO mi,
304: PUCHAR pCvData,
305: PIMAGE_SECTION_HEADER sectionHdrs,
306: DWORD numSections
307: )
308: {
309: OMFSignature *omfSig;
310: OMFDirHeader *omfDirHdr;
311: OMFDirEntry *omfDirEntry;
312: DATASYM32 *dataSym;
313: OMFSymHash *omfSymHash;
314: SYMBOL *sym;
315: DWORD i;
316: DWORD j;
317: DWORD k;
318: DWORD addr;
319: PSYMBOL *symbolTable;
320: PSYMBOL *symbolTable2;
321: PIMAGE_SECTION_HEADER sh;
322: PSYMBOL symHead = NULL;
323: PSYMBOL symTail = NULL;
324:
325:
326: Assert( mi != NULL );
327: omfSig = (OMFSignature*) pCvData;
328: if ((strncmp( omfSig->Signature, "NB08", 4 ) != 0) &&
329: (strncmp( omfSig->Signature, "NB09", 4 ) != 0)) {
330: return FALSE;
331: }
332:
333: omfDirHdr = (OMFDirHeader*) ((DWORD)omfSig + (DWORD)omfSig->filepos);
334: omfDirEntry = (OMFDirEntry*) ((DWORD)omfDirHdr + sizeof(OMFDirHeader));
335:
336: for (i=0; i<omfDirHdr->cDir; i++,omfDirEntry++) {
337: if (omfDirEntry->SubSection == sstGlobalPub) {
338: omfSymHash = (OMFSymHash*) ((DWORD)omfSig + omfDirEntry->lfo);
339: dataSym = (DATASYM32*) ((DWORD)omfSig + omfDirEntry->lfo + sizeof(OMFSymHash));
340: for (j=sizeof(OMFSymHash); j<=omfSymHash->cbSymbol; ) {
341: sym = AllocSym ( dataSym->name[0]+1, &symHead, &symTail );
342: if (sym != NULL) {
343: for (k=0,addr=0,sh=sectionHdrs; k<numSections; k++, sh++) {
344: if (k+1 == dataSym->seg) {
345: addr = sh->VirtualAddress;
346: }
347: }
348: addr += (dataSym->off + mi->dwLoadAddress);
349: memcpy( sym->szName, dataSym->name, dataSym->name[0]+1 );
350: sym->addr = addr;
351: j += dataSym->reclen + 2;
352: dataSym = (DATASYM32*) ((DWORD)dataSym + dataSym->reclen + 2);
353: mi->numsyms++;
354: }
355: }
356: break;
357: }
358: }
359:
360:
361: mi->symbolTable = (PSYMBOL*) malloc( mi->numsyms * sizeof(PSYMBOL) );
362: if (mi->symbolTable == NULL) {
363: return FALSE;
364: }
365:
366: sym = symHead;
367: symbolTable = mi->symbolTable;
368: i = 0;
369: while (sym) {
370: i++;
371: *symbolTable = sym;
372: symbolTable++;
373: sym = sym->next;
374: }
375:
376: qsort( (void*)mi->symbolTable, mi->numsyms, sizeof(PSYMBOL), SymbolCompare );
377:
378: for (i=0,symbolTable=mi->symbolTable; i<mi->numsyms; i++,symbolTable++) {
379: if (i+1 < mi->numsyms) {
380: symbolTable2 = symbolTable+1;
381: (*symbolTable)->size = (*symbolTable2)->addr - (*symbolTable)->addr;
382: }
383: }
384:
385: return TRUE;
386: }
387:
388: void
389: GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s )
390: {
391: DWORD i;
392:
393: if (Symbol->n_zeroes) {
394: for (i=0; i<8; i++) {
395: if ((Symbol->n_name[i]>0x1f) && (Symbol->n_name[i]<0x7f)) {
396: *s++ = Symbol->n_name[i];
397: }
398: }
399: *s = 0;
400: }
401: else {
402: strcpy( s, &StringTable[Symbol->n_offset] );
403: }
404: }
405:
406: int
407: _CRTAPI1
408: SymbolCompare( const void *arg1, const void *arg2 )
409: {
410: if ((*(PSYMBOL*)arg1)->addr < (*(PSYMBOL*)arg2)->addr) {
411: return -1;
412: }
413: if ((*(PSYMBOL*)arg1)->addr > (*(PSYMBOL*)arg2)->addr) {
414: return 1;
415: }
416: return 0;
417: }
418:
419: char *
420: UnDName (char * dName)
421: {
422: static char outBuf[512];
423: char *p;
424:
425: if (*dName == '_') {
426: ++dName;
427: strcpy(outBuf, dName);
428: p = strchr(outBuf, '@');
429: if (p) {
430: *p = '\0';
431: }
432: }
433: else
434: if(UnDecorateSymbolName( dName,
435: outBuf,
436: sizeof(outBuf),
437: UNDNAME_COMPLETE ) == 0 ) {
438: return NULL;
439: }
440:
441: return outBuf;
442: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.