|
|
1.1 ! root 1: /*++ ! 2: ! 3: ! 4: Copyright (c) 1992 Microsoft Corporation ! 5: ! 6: Module Name: ! 7: ! 8: cv.c ! 9: ! 10: Abstract: ! 11: ! 12: This module handles the conversion activities requires for converting ! 13: COFF debug data to CODEVIEW debug data. ! 14: ! 15: Author: ! 16: ! 17: Wesley A. Witt (wesw) 19-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 tagOFFSETSORT { ! 35: DWORD dwOffset; // offset for the symbol ! 36: DWORD dwSection; // section number of the symbol ! 37: DATASYM32 *dataSym; // pointer to the symbol info ! 38: } OFFSETSORT; ! 39: ! 40: ! 41: #define n_name N.ShortName ! 42: #define n_zeroes N.Name.Short ! 43: #define n_nptr N.LongName[1] ! 44: #define n_offset N.Name.Long ! 45: ! 46: static VOID GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s ); ! 47: DWORD CreateModulesFromCoff( PPOINTERS p ); ! 48: DWORD CreatePublicsFromCoff( PPOINTERS p ); ! 49: DWORD CreateSegMapFromCoff( PPOINTERS p ); ! 50: ! 51: BOOL ! 52: ConvertCoffToCv( PPOINTERS p ) ! 53: ! 54: /*++ ! 55: ! 56: Routine Description: ! 57: ! 58: This is the control function for the conversion of COFF to CODEVIEW ! 59: debug data. It calls individual functions for the conversion of ! 60: specific types of debug data. ! 61: ! 62: ! 63: Arguments: ! 64: ! 65: p - pointer to a POINTERS structure (see cofftocv.h) ! 66: ! 67: ! 68: Return Value: ! 69: ! 70: TRUE - conversion succeded ! 71: FALSE - conversion failed ! 72: ! 73: --*/ ! 74: ! 75: { ! 76: p->pCvCurr = p->pCvStart.ptr = malloc( p->iptrs.fsize ); ! 77: if (p->pCvStart.ptr == NULL) { ! 78: return FALSE; ! 79: } ! 80: memset( p->pCvStart.ptr, 0, p->iptrs.fsize ); ! 81: ! 82: try { ! 83: CreateSignature( p ); ! 84: CreateModulesFromCoff( p ); ! 85: CreatePublicsFromCoff( p ); ! 86: CreateSymbolHashTable( p ); ! 87: CreateAddressSortTable( p ); ! 88: CreateSegMapFromCoff( p ); ! 89: CreateDirectories( p ); ! 90: } except (EXCEPTION_EXECUTE_HANDLER) { ! 91: free( p->pCvStart.ptr ); ! 92: p->pCvStart.ptr = NULL; ! 93: return FALSE; ! 94: } ! 95: ! 96: p->pCvStart.ptr = realloc( p->pCvStart.ptr, p->pCvStart.size ); ! 97: ! 98: return TRUE; ! 99: } ! 100: ! 101: ! 102: DWORD ! 103: CreateModulesFromCoff( PPOINTERS p ) ! 104: ! 105: /*++ ! 106: ! 107: Routine Description: ! 108: ! 109: Creates the individual CV module records. There is one CV module ! 110: record for each .FILE record in the COFF debug data. This is true ! 111: even if the COFF size is zero. ! 112: ! 113: ! 114: Arguments: ! 115: ! 116: p - pointer to a POINTERS structure (see cofftocv.h) ! 117: ! 118: ! 119: Return Value: ! 120: ! 121: The number of modules that were created. ! 122: ! 123: --*/ ! 124: ! 125: { ! 126: int i; ! 127: DWORD numaux; ! 128: DWORD nummods = 0; ! 129: char szSymName[256]; ! 130: PIMAGE_SYMBOL Symbol; ! 131: PIMAGE_AUX_SYMBOL AuxSymbol; ! 132: OMFModule *m; ! 133: int cSeg; ! 134: char * pb; ! 135: BOOLEAN rgfCode[100]; ! 136: ! 137: memset(rgfCode, 2, sizeof(rgfCode)); ! 138: ! 139: m = NULL; ! 140: ! 141: for (i= 0, Symbol = p->iptrs.AllSymbols; ! 142: i < (int) p->iptrs.numberOfSymbols; ! 143: i += numaux + 1, Symbol += numaux + 1) { ! 144: ! 145: /* ! 146: * Get the number of aux symbol records for this symbol ! 147: */ ! 148: ! 149: numaux = Symbol->NumberOfAuxSymbols; ! 150: AuxSymbol = (PIMAGE_AUX_SYMBOL) (Symbol+1); ! 151: ! 152: /* ! 153: * If this is a FILE record -- then we need to create a ! 154: * module item to correspond to this file record. ! 155: */ ! 156: ! 157: if (Symbol->StorageClass == IMAGE_SYM_CLASS_FILE) { ! 158: if (m == NULL) { ! 159: m = (OMFModule *) p->pCvCurr; ! 160: } else { ! 161: /* ! 162: * Clean up the last item, if we saw any ! 163: * section records then drop them in here ! 164: */ ! 165: ! 166: if (cSeg > 0) { ! 167: m->cSeg = cSeg; ! 168: pb = (char *) &m->SegInfo[cSeg]; ! 169: *pb = strlen(szSymName); ! 170: memcpy(pb+1, szSymName, *pb); ! 171: ! 172: m = NextMod(m); ! 173: nummods++; ! 174: } ! 175: } ! 176: ! 177: cSeg = 0; ! 178: m->ovlNumber = 0; ! 179: m->iLib = 0; ! 180: m->Style[0] = 'C'; ! 181: m->Style[1] = 'V'; ! 182: ! 183: /* ! 184: * Save off the file name to use when we have finished ! 185: * processing this module ! 186: */ ! 187: ! 188: memcpy(szSymName, (char *)AuxSymbol, numaux*sizeof(IMAGE_AUX_SYMBOL)); ! 189: szSymName[numaux*sizeof(IMAGE_AUX_SYMBOL)] = 0; ! 190: ! 191: } ! 192: /* ! 193: * We have found a "SECTION" record. Add the info to the ! 194: * module record ! 195: */ ! 196: else if ((Symbol->SectionNumber & 0xffff) > 0xfff0) { ! 197: continue; ! 198: } else if (Symbol->SectionNumber > sizeof(rgfCode)/sizeof(rgfCode[0])) { ! 199: return 0; ! 200: } else if ((m != NULL) && ! 201: (rgfCode[Symbol->SectionNumber] != 0) && ! 202: (Symbol->StorageClass == IMAGE_SYM_CLASS_STATIC) && ! 203: ((*Symbol->n_name == '.') || ! 204: (Symbol->Type == IMAGE_SYM_TYPE_NULL)) && ! 205: (Symbol->NumberOfAuxSymbols == 1) && ! 206: (AuxSymbol->Section.Length != 0)) { ! 207: ! 208: if (rgfCode[Symbol->SectionNumber] == 2) { ! 209: if ((p->iptrs.sectionHdrs[Symbol->SectionNumber - 1]. ! 210: Characteristics & IMAGE_SCN_CNT_CODE) == 0) { ! 211: rgfCode[Symbol->SectionNumber] = 0; ! 212: continue; ! 213: } ! 214: rgfCode[Symbol->SectionNumber] = 1; ! 215: } ! 216: ! 217: m->SegInfo[cSeg].Seg = Symbol->SectionNumber; ! 218: m->SegInfo[cSeg].cbSeg = AuxSymbol->Section.Length; ! 219: m->SegInfo[cSeg].Off = Symbol->Value - ! 220: p->iptrs.sectionHdrs[Symbol->SectionNumber-1]. ! 221: VirtualAddress; ! 222: cSeg += 1; ! 223: } ! 224: } ! 225: ! 226: /* ! 227: * Wrap up the last possible open module record ! 228: */ ! 229: ! 230: if (m != NULL) { ! 231: if (cSeg > 0) { ! 232: m->cSeg = cSeg; ! 233: pb = (char *) &m->SegInfo[cSeg]; ! 234: *pb = strlen(szSymName); ! 235: memcpy(pb+1, szSymName, *pb); ! 236: ! 237: m = NextMod(m); ! 238: nummods++; ! 239: } ! 240: } ! 241: ! 242: UpdatePtrs( p, &p->pCvModules, (LPVOID)m, nummods ); ! 243: ! 244: return nummods; ! 245: } ! 246: ! 247: ! 248: DWORD ! 249: CreatePublicsFromCoff( PPOINTERS p ) ! 250: ! 251: /*++ ! 252: ! 253: Routine Description: ! 254: ! 255: Creates the individual CV public symbol records. There is one CV ! 256: public record created for each COFF symbol that is marked as EXTERNAL ! 257: and has a section number greater than zero. The resulting CV publics ! 258: are sorted by section and offset. ! 259: ! 260: ! 261: Arguments: ! 262: ! 263: p - pointer to a POINTERS structure (see cofftocv.h) ! 264: ! 265: ! 266: Return Value: ! 267: ! 268: The number of publics created. ! 269: ! 270: --*/ ! 271: ! 272: { ! 273: int i; ! 274: DWORD numaux; ! 275: DWORD numsyms = 0; ! 276: char szSymName[256]; ! 277: PIMAGE_SYMBOL Symbol; ! 278: OMFSymHash *omfSymHash; ! 279: DATASYM32 *dataSym; ! 280: DATASYM32 *dataSym2; ! 281: ! 282: omfSymHash = (OMFSymHash *) p->pCvCurr; ! 283: dataSym = (DATASYM32 *) (PUCHAR)((DWORD)omfSymHash + sizeof(OMFSymHash)); ! 284: ! 285: for (i= 0, Symbol = p->iptrs.AllSymbols; ! 286: i < p->iptrs.numberOfSymbols; ! 287: i += numaux + 1, Symbol += numaux + 1) { ! 288: ! 289: if ((Symbol->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) && ! 290: (Symbol->SectionNumber > 0)) { ! 291: ! 292: GetSymName( Symbol, p->iptrs.stringTable, szSymName ); ! 293: dataSym->rectyp = S_PUB32; ! 294: dataSym->seg = Symbol->SectionNumber; ! 295: dataSym->off = Symbol->Value - ! 296: p->iptrs.sectionHdrs[Symbol->SectionNumber-1].VirtualAddress; ! 297: dataSym->typind = 0; ! 298: dataSym->name[0] = strlen( szSymName ); ! 299: strcpy( &dataSym->name[1], szSymName ); ! 300: dataSym2 = NextSym32( dataSym ); ! 301: dataSym->reclen = (USHORT) ((DWORD)dataSym2 - (DWORD)dataSym) - 2; ! 302: dataSym = dataSym2; ! 303: numsyms += 1; ! 304: } ! 305: numaux = Symbol->NumberOfAuxSymbols; ! 306: } ! 307: ! 308: UpdatePtrs( p, &p->pCvPublics, (LPVOID)dataSym, numsyms ); ! 309: ! 310: omfSymHash->cbSymbol = p->pCvPublics.size - sizeof(OMFSymHash); ! 311: omfSymHash->symhash = 0; ! 312: omfSymHash->addrhash = 0; ! 313: omfSymHash->cbHSym = 0; ! 314: omfSymHash->cbHAddr = 0; ! 315: ! 316: return numsyms; ! 317: } /* CreatePublisFromCoff() */ ! 318: ! 319: ! 320: DWORD ! 321: CreateSegMapFromCoff( PPOINTERS p ) ! 322: ! 323: /*++ ! 324: ! 325: Routine Description: ! 326: ! 327: Creates the CV segment map. The segment map is used by debuggers ! 328: to aid in address lookups. One segment is created for each COFF ! 329: section in the image. ! 330: ! 331: Arguments: ! 332: ! 333: p - pointer to a POINTERS structure (see cofftocv.h) ! 334: ! 335: ! 336: Return Value: ! 337: ! 338: The number of segments in the map. ! 339: ! 340: --*/ ! 341: ! 342: { ! 343: int i; ! 344: SGM *sgm; ! 345: SGI *sgi; ! 346: PIMAGE_SECTION_HEADER sh; ! 347: ! 348: ! 349: sgm = (SGM *) p->pCvCurr; ! 350: sgi = (SGI *) ((DWORD)p->pCvCurr + sizeof(SGM)); ! 351: ! 352: sgm->cSeg = p->iptrs.numberOfSections; ! 353: sgm->cSegLog = p->iptrs.numberOfSections; ! 354: ! 355: sh = p->iptrs.sectionHdrs; ! 356: ! 357: for (i=0; i<p->iptrs.numberOfSections; i++, sh++) { ! 358: sgi->sgf.fRead = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_READ) == IMAGE_SCN_MEM_READ; ! 359: sgi->sgf.fWrite = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_WRITE) == IMAGE_SCN_MEM_WRITE; ! 360: sgi->sgf.fExecute = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_EXECUTE) == IMAGE_SCN_MEM_EXECUTE; ! 361: sgi->sgf.f32Bit = 1; ! 362: sgi->sgf.fSel = 0; ! 363: sgi->sgf.fAbs = 0; ! 364: sgi->sgf.fGroup = 1; ! 365: sgi->iovl = 0; ! 366: sgi->igr = 0; ! 367: sgi->isgPhy = (USHORT) i + 1; ! 368: sgi->isegName = 0; ! 369: sgi->iclassName = 0; ! 370: sgi->doffseg = 0; ! 371: sgi->cbSeg = sh->SizeOfRawData; ! 372: sgi++; ! 373: } ! 374: ! 375: UpdatePtrs( p, &p->pCvSegMap, (LPVOID)sgi, i ); ! 376: ! 377: return i; ! 378: } ! 379: ! 380: ! 381: void ! 382: GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s ) ! 383: ! 384: /*++ ! 385: ! 386: Routine Description: ! 387: ! 388: Extracts the COFF symbol from the image symbol pointer and puts ! 389: the ascii text in the character pointer passed in. ! 390: ! 391: ! 392: Arguments: ! 393: ! 394: Symbol - COFF Symbol Record ! 395: StringTable - COFF string table ! 396: s - buffer for the symbol string ! 397: ! 398: ! 399: Return Value: ! 400: ! 401: void ! 402: ! 403: --*/ ! 404: ! 405: { ! 406: DWORD i; ! 407: ! 408: if (Symbol->n_zeroes) { ! 409: for (i=0; i<8; i++) { ! 410: if ((Symbol->n_name[i]>0x1f) && (Symbol->n_name[i]<0x7f)) { ! 411: *s++ = Symbol->n_name[i]; ! 412: } ! 413: } ! 414: *s = 0; ! 415: } ! 416: else { ! 417: strcpy( s, &StringTable[Symbol->n_offset] ); ! 418: } ! 419: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.