|
|
1.1 ! root 1: /*++ ! 2: ! 3: ! 4: Copyright (c) 1992 Microsoft Corporation ! 5: ! 6: Module Name: ! 7: ! 8: symtocv.c ! 9: ! 10: Abstract: ! 11: ! 12: This module handles the conversion activities requires for converting ! 13: C7/C8 SYM files to CODEVIEW debug data. ! 14: ! 15: Author: ! 16: ! 17: Wesley A. Witt (wesw) 13-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 tagSYMNAME { ! 35: BYTE length; ! 36: char name[1]; ! 37: } SYMNAME, *PSYMNAME; ! 38: ! 39: typedef struct tagSYMSYMBOL { ! 40: WORD offset; ! 41: SYMNAME symName; ! 42: } SYMSYMBOL, *PSYMSYMBOL; ! 43: ! 44: typedef struct tagSYMFILEHEADER { ! 45: DWORD fileSize; ! 46: WORD reserved1; ! 47: WORD numSyms; ! 48: DWORD reserved2; ! 49: WORD nextOffset; ! 50: BYTE reserved3; ! 51: SYMNAME symName; ! 52: } SYMFILEHEADER, *PSYMFILEHEADER; ! 53: ! 54: typedef struct tagSYMHEADER { ! 55: WORD nextOffset; ! 56: WORD numSyms; ! 57: WORD reserved1; ! 58: WORD segment; ! 59: BYTE reserved2[12]; ! 60: SYMNAME symName; ! 61: } SYMHEADER, *PSYMHEADER; ! 62: ! 63: #define SIZEOFSYMFILEHEADER 16 ! 64: #define SIZEOFSYMHEADER 21 ! 65: #define SIZEOFSYMBOL 3 ! 66: ! 67: #define SYM_SEGMENT_NAME 0 ! 68: #define SYM_SYMBOL_NAME 1 ! 69: #define SYM_SEGMENT_ABS 2 ! 70: #define SYM_SYMBOL_ABS 3 ! 71: ! 72: typedef struct tagENUMINFO { ! 73: DATASYM16 *dataSym; ! 74: DATASYM16 *dataSym2; ! 75: DWORD numsyms; ! 76: SGI *sgi; ! 77: } ENUMINFO, *PENUMINFO; ! 78: ! 79: typedef BOOL (CALLBACK* SYMBOLENUMPROC)(PSYMNAME pSymName, int symType, ! 80: SEGMENT segment, UOFF16 offset, ! 81: PENUMINFO pEnumInfo); ! 82: ! 83: ! 84: static VOID GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, ! 85: char * s ); ! 86: DWORD CreateModulesFromSyms( PPOINTERS p ); ! 87: DWORD CreatePublicsFromSyms( PPOINTERS p ); ! 88: DWORD CreateSegMapFromSyms( PPOINTERS p ); ! 89: static BOOL EnumSymbols( PPOINTERS p, SYMBOLENUMPROC lpEnumProc, ! 90: PENUMINFO pEnumInfo ); ! 91: ! 92: int CSymSegs; ! 93: ! 94: BOOL CALLBACK ! 95: SymbolCount(PSYMNAME pSymName, int symType, SEGMENT segment, ! 96: UOFF16 offset, PENUMINFO pEnumInfo ) ! 97: { ! 98: if ((symType == SYM_SEGMENT_NAME) && (segment > 0)) { ! 99: CSymSegs += 1; ! 100: } ! 101: pEnumInfo->numsyms++; ! 102: return TRUE; ! 103: } ! 104: ! 105: BOOL ! 106: ConvertSymToCv( PPOINTERS p ) ! 107: ! 108: /*++ ! 109: ! 110: Routine Description: ! 111: ! 112: This is the control function for the conversion of COFF to CODEVIEW ! 113: debug data. It calls individual functions for the conversion of ! 114: specific types of debug data. ! 115: ! 116: ! 117: Arguments: ! 118: ! 119: p - pointer to a POINTERS structure (see cofftocv.h) ! 120: ! 121: ! 122: Return Value: ! 123: ! 124: TRUE - conversion succeded ! 125: FALSE - conversion failed ! 126: ! 127: --*/ ! 128: ! 129: { ! 130: ENUMINFO enumInfo; ! 131: DWORD dwSize; ! 132: ! 133: CSymSegs = 0; ! 134: enumInfo.numsyms = 0; ! 135: EnumSymbols( p, SymbolCount, &enumInfo ); ! 136: dwSize = (enumInfo.numsyms * (sizeof(DATASYM16) + 10)) + 256000; ! 137: p->pCvCurr = p->pCvStart.ptr = malloc( dwSize ); ! 138: if (p->pCvStart.ptr == NULL) { ! 139: return FALSE; ! 140: } ! 141: memset( p->pCvStart.ptr, 0, dwSize ); ! 142: ! 143: try { ! 144: ! 145: CreateSignature( p ); ! 146: CreatePublicsFromSyms( p ); ! 147: CreateSymbolHashTable( p ); ! 148: CreateAddressSortTable( p ); ! 149: CreateSegMapFromSyms( p ); ! 150: CreateModulesFromSyms( p ); ! 151: CreateDirectories( p ); ! 152: p->pCvStart.ptr = realloc( p->pCvStart.ptr, p->pCvStart.size ); ! 153: return TRUE; ! 154: ! 155: } except (EXCEPTION_EXECUTE_HANDLER) { ! 156: ! 157: free( p->pCvStart.ptr ); ! 158: p->pCvStart.ptr = NULL; ! 159: return FALSE; ! 160: ! 161: } ! 162: } ! 163: ! 164: ! 165: DWORD ! 166: CreateModulesFromSyms( PPOINTERS p ) ! 167: ! 168: /*++ ! 169: ! 170: Routine Description: ! 171: ! 172: Creates the individual CV module records. There is one CV module ! 173: record for each .FILE record in the COFF debug data. This is true ! 174: even if the COFF size is zero. ! 175: ! 176: ! 177: Arguments: ! 178: ! 179: p - pointer to a POINTERS structure (see cofftocv.h) ! 180: ! 181: ! 182: Return Value: ! 183: ! 184: The number of modules that were created. ! 185: ! 186: --*/ ! 187: ! 188: { ! 189: char szDrive [_MAX_DRIVE]; ! 190: char szDir [_MAX_DIR]; ! 191: char szFname [_MAX_FNAME]; ! 192: char szExt [_MAX_EXT]; ! 193: OMFModule *m; ! 194: int i; ! 195: char * pb; ! 196: ! 197: _splitpath( p->iptrs.szName, szDrive, szDir, szFname, szExt ); ! 198: ! 199: m = (OMFModule *) p->pCvCurr; ! 200: ! 201: m->ovlNumber = 0; ! 202: m->iLib = 0; ! 203: m->cSeg = CSymSegs; ! 204: m->Style[0] = 'C'; ! 205: m->Style[1] = 'V'; ! 206: for (i=0; i<CSymSegs; i++) { ! 207: m->SegInfo[i].Seg = i+1; ! 208: m->SegInfo[i].pad = 0; ! 209: m->SegInfo[i].Off = 0; ! 210: m->SegInfo[i].cbSeg = 0xffff; ! 211: } ! 212: pb = (char *) &m->SegInfo[CSymSegs]; ! 213: sprintf( &pb[1], "%s.c", szFname ); ! 214: pb[0] = strlen( &pb[1] ); ! 215: ! 216: pb = (char *) NextMod(m); ! 217: ! 218: UpdatePtrs( p, &p->pCvModules, (LPVOID)pb, 1 ); ! 219: ! 220: return 1; ! 221: } ! 222: ! 223: BOOL CALLBACK ! 224: ConvertASymtoPublic(PSYMNAME pSymName, int symType, SEGMENT segment, ! 225: UOFF16 offset, PENUMINFO pEnumInfo ) ! 226: { ! 227: if (symType != SYM_SYMBOL_NAME) { ! 228: return TRUE; ! 229: } ! 230: ! 231: pEnumInfo->dataSym->rectyp = S_PUB16; ! 232: pEnumInfo->dataSym->seg = segment; ! 233: pEnumInfo->dataSym->off = offset; ! 234: pEnumInfo->dataSym->typind = 0; ! 235: pEnumInfo->dataSym->name[0] = pSymName->length; ! 236: strncpy( &pEnumInfo->dataSym->name[1], pSymName->name, pSymName->length ); ! 237: pEnumInfo->dataSym2 = NextSym16( pEnumInfo->dataSym ); ! 238: pEnumInfo->dataSym->reclen = (USHORT) ((DWORD)pEnumInfo->dataSym2 - ! 239: (DWORD)pEnumInfo->dataSym) - 2; ! 240: pEnumInfo->dataSym = pEnumInfo->dataSym2; ! 241: pEnumInfo->numsyms++; ! 242: ! 243: return TRUE; ! 244: } ! 245: ! 246: DWORD ! 247: CreatePublicsFromSyms( PPOINTERS p ) ! 248: ! 249: /*++ ! 250: ! 251: Routine Description: ! 252: ! 253: Creates the individual CV public symbol records. There is one CV ! 254: public record created for each COFF symbol that is marked as EXTERNAL ! 255: and has a section number greater than zero. The resulting CV publics ! 256: are sorted by section and offset. ! 257: ! 258: ! 259: Arguments: ! 260: ! 261: p - pointer to a POINTERS structure (see cofftocv.h) ! 262: ! 263: ! 264: Return Value: ! 265: ! 266: The number of publics created. ! 267: ! 268: --*/ ! 269: ! 270: { ! 271: OMFSymHash *omfSymHash; ! 272: ENUMINFO enumInfo; ! 273: ! 274: ! 275: enumInfo.dataSym = (DATASYM16 *) ! 276: (PUCHAR)((DWORD)p->pCvCurr + sizeof(OMFSymHash)); ! 277: enumInfo.numsyms = 0; ! 278: ! 279: EnumSymbols( p, ConvertASymtoPublic, &enumInfo ); ! 280: ! 281: omfSymHash = (OMFSymHash *) p->pCvCurr; ! 282: UpdatePtrs(p, &p->pCvPublics, (LPVOID)enumInfo.dataSym, ! 283: enumInfo.numsyms ); ! 284: ! 285: omfSymHash->cbSymbol = p->pCvPublics.size - sizeof(OMFSymHash); ! 286: omfSymHash->symhash = 0; ! 287: omfSymHash->addrhash = 0; ! 288: omfSymHash->cbHSym = 0; ! 289: omfSymHash->cbHAddr = 0; ! 290: ! 291: return enumInfo.numsyms; ! 292: } ! 293: ! 294: ! 295: BOOL CALLBACK ! 296: ConvertASegment( PSYMNAME pSymName, int symType, SEGMENT segment, ! 297: UOFF16 offset, PENUMINFO pEnumInfo ) ! 298: { ! 299: if (symType != SYM_SEGMENT_NAME) { ! 300: return TRUE; ! 301: } ! 302: ! 303: if (segment == 0) { ! 304: return TRUE; ! 305: } ! 306: ! 307: pEnumInfo->numsyms++; ! 308: ! 309: pEnumInfo->sgi->sgf.fRead = TRUE; ! 310: pEnumInfo->sgi->sgf.fWrite = TRUE; ! 311: pEnumInfo->sgi->sgf.fExecute = TRUE; ! 312: pEnumInfo->sgi->sgf.f32Bit = 0; ! 313: pEnumInfo->sgi->sgf.fSel = 0; ! 314: pEnumInfo->sgi->sgf.fAbs = 0; ! 315: pEnumInfo->sgi->sgf.fGroup = 1; ! 316: pEnumInfo->sgi->iovl = 0; ! 317: pEnumInfo->sgi->igr = 0; ! 318: pEnumInfo->sgi->isgPhy = (USHORT) pEnumInfo->numsyms; ! 319: pEnumInfo->sgi->isegName = 0; ! 320: pEnumInfo->sgi->iclassName = 0; ! 321: pEnumInfo->sgi->doffseg = 0; ! 322: pEnumInfo->sgi->cbSeg = 0xFFFF; ! 323: pEnumInfo->sgi++; ! 324: ! 325: return TRUE; ! 326: } ! 327: ! 328: ! 329: DWORD ! 330: CreateSegMapFromSyms( PPOINTERS p ) ! 331: ! 332: /*++ ! 333: ! 334: Routine Description: ! 335: ! 336: Creates the CV segment map. The segment map is used by debuggers ! 337: to aid in address lookups. One segment is created for each COFF ! 338: section in the image. ! 339: ! 340: Arguments: ! 341: ! 342: p - pointer to a POINTERS structure (see cofftocv.h) ! 343: ! 344: ! 345: Return Value: ! 346: ! 347: The number of segments in the map. ! 348: ! 349: --*/ ! 350: ! 351: { ! 352: SGM *sgm; ! 353: ENUMINFO enumInfo; ! 354: ! 355: ! 356: sgm = (SGM *) p->pCvCurr; ! 357: enumInfo.sgi = (SGI *) ((DWORD)p->pCvCurr + sizeof(SGM)); ! 358: enumInfo.numsyms = 0; ! 359: ! 360: EnumSymbols( p, ConvertASegment, &enumInfo ); ! 361: ! 362: sgm->cSeg = (USHORT)enumInfo.numsyms; ! 363: sgm->cSegLog = (USHORT)enumInfo.numsyms; ! 364: ! 365: UpdatePtrs( p, &p->pCvSegMap, (LPVOID)enumInfo.sgi, enumInfo.numsyms ); ! 366: ! 367: return enumInfo.numsyms; ! 368: } ! 369: ! 370: BOOL ! 371: EnumSymbols( PPOINTERS p, SYMBOLENUMPROC lpEnumProc, PENUMINFO pEnumInfo ) ! 372: ! 373: /*++ ! 374: ! 375: Routine Description: ! 376: ! 377: This function enumerates all symbols ine the mapped SYM file ! 378: ! 379: ! 380: Arguments: ! 381: ! 382: p - pointer to a POINTERS structure ! 383: lpEnumProc - function to be called once for each function ! 384: pEnumInfo - data to be passed between the caller and the enum func ! 385: ! 386: Return Value: ! 387: ! 388: TRUE - success ! 389: FALSE - failure ! 390: ! 391: --*/ ! 392: ! 393: { ! 394: PSYMFILEHEADER pSymFileHead; ! 395: PSYMHEADER pSymHead; ! 396: PSYMSYMBOL pSymSymbol; ! 397: DWORD i; ! 398: DWORD startPosition; ! 399: DWORD position; ! 400: ! 401: ! 402: pSymFileHead = (PSYMFILEHEADER) p->iptrs.fptr; ! 403: pSymSymbol = (PSYMSYMBOL) ((DWORD)pSymFileHead + SIZEOFSYMFILEHEADER + ! 404: pSymFileHead->symName.length + 1); ! 405: ! 406: if (!lpEnumProc(&pSymFileHead->symName, SYM_SEGMENT_ABS, ! 407: 0, 0, pEnumInfo )) { ! 408: return FALSE; ! 409: } ! 410: ! 411: for (i=0; i<pSymFileHead->numSyms; i++) { ! 412: if (!lpEnumProc(&pSymSymbol->symName, SYM_SYMBOL_ABS, ! 413: 0, pSymSymbol->offset, pEnumInfo )) { ! 414: return FALSE; ! 415: } ! 416: pSymSymbol = (PSYMSYMBOL) ((DWORD)pSymSymbol + SIZEOFSYMBOL + ! 417: pSymSymbol->symName.length); ! 418: } ! 419: ! 420: position = startPosition = ((LONG)pSymFileHead->nextOffset) << 4; ! 421: ! 422: do { ! 423: pSymHead = (PSYMHEADER) ((DWORD)p->iptrs.fptr + position); ! 424: pSymSymbol = (PSYMSYMBOL) ((DWORD)pSymHead + SIZEOFSYMHEADER + ! 425: pSymHead->symName.length); ! 426: ! 427: position = ((LONG)pSymHead->nextOffset) << 4; ! 428: ! 429: if (!lpEnumProc( &pSymHead->symName, SYM_SEGMENT_NAME, ! 430: pSymHead->segment, 0, pEnumInfo )) { ! 431: return FALSE; ! 432: } ! 433: ! 434: for (i=0; i<pSymHead->numSyms; i++) { ! 435: if (!lpEnumProc(&pSymSymbol->symName, SYM_SYMBOL_NAME, ! 436: pSymHead->segment, pSymSymbol->offset, ! 437: pEnumInfo )) { ! 438: return FALSE; ! 439: } ! 440: pSymSymbol = (PSYMSYMBOL) ((DWORD)pSymSymbol + SIZEOFSYMBOL + ! 441: pSymSymbol->symName.length); ! 442: } ! 443: } while ( position != startPosition && position != 0 ); ! 444: ! 445: return 0; ! 446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.