|
|
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.