/*********************************************************************** * Microsoft (R) Debugging Information Dumper * * Copyright (C) Microsoft Corp 1987-1995. All rights reserved. * * File: dumpsym6.c * * File Comments: * ***********************************************************************/ #include <assert.h> #include <io.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "cvdef.h" #include "cvinfo.h" #include "cvexefmt.h" #include "cvdump.h" // Various definitions #include "debsym.h" // SYMBOLS definitions #include "symrec.h" // SYMBOLS definitions LOCAL void C6SymError(void); LOCAL void C6BlockSym(void); LOCAL void C6ProcSym(void); LOCAL void C6LabSym(void); LOCAL void C6WithSym(void); LOCAL void C6EntrySym(void); LOCAL void C6SkipSym(void); LOCAL void C6ChangeModel(void); LOCAL void C6CodeSegSym(void); LOCAL void C6EndSym(void); LOCAL void C6BpSym(void); LOCAL void C6RegSym(void); LOCAL void C6ConSym(void); LOCAL void C6CobolTypeDefSym(void); LOCAL void C6LocalSym(void); LOCAL void C6ChangeModelSym(void); extern int iModToList; // The module number to list extern long cbRec; // # bytes left in record extern WORD rect; // Type of symbol record extern WORD Gets (); // Get a byte of input extern WORD WGets (); // Get a word of input extern ulong LGets (); // Get a long word of input extern char f386; int cIndent = 0; #define GetOffset() (f386 ? LGets () : (long) WGets ()) typedef struct { uchar tsym; void (*pfcn) (void); } symfcn; const symfcn SymFcnC6[] = { { S_BLOCK, C6BlockSym }, { S_PROC, C6ProcSym }, { S_END, C6EndSym }, { S_BPREL, C6BpSym }, { S_LOCAL, C6LocalSym }, { S_LABEL, C6LabSym }, { S_WITH, C6WithSym }, { S_REG, C6RegSym }, { S_CONST, C6ConSym }, { S_ENTRY, C6EntrySym }, { S_NOOP, C6SkipSym }, { S_CODSEG, C6CodeSegSym }, { S_TYPEDEF, C6CobolTypeDefSym }, { S_CHGMODEL, C6ChangeModelSym }, }; #define SYMCNT (sizeof SymFcnC6 / sizeof (SymFcnC6[0])) void C6SymError (void) { Fatal ("Illegal symbol type found\n"); } /** * * Display SYMBOLS section. * */ void DumpSym (void) { PMOD pMod; ulong cbSym; ulong ulSignature; uchar name[256]; printf ("\n\n*** SYMBOLS section\n"); for (pMod = ModList; pMod != NULL; pMod = pMod->next) { if (((cbSym = pMod->SymbolSize) != 0) && ((iModToList == 0) || ((ushort)iModToList == pMod->iMod))) { _lseek(exefile, lfoBase + pMod->SymbolsAddr, SEEK_SET); cIndent = 0; strcpy (name, pMod->ModName); printf ("%s\n", name); cbRec = 4; ulSignature = LGets (); switch( ulSignature ){ case 1L: //M00 - 1L should not be hardcoded // Dump C7 debug info cbSym -= sizeof (ulong); // Subtract size of signature DumpModSymC7 (cbSym); break; default: // Symbols are in C6 format // M00 - seek could be eliminated for speed improvement // Re-seek because first four bytes are not signature _lseek(exefile, lfoBase + pMod->SymbolsAddr, SEEK_SET); DumpModSymC6 (cbSym); break; } } } putchar ('\n'); } void DumpModSymC6(ulong cbSym) { char sb[255]; // String buffer WORD cbName; // Length of string ushort i; while (cbSym > 0) { // Get record length cbRec = 1; cbRec = Gets (); cbSym -= cbRec + 1; rect = Gets (); f386 = (char) (rect & 0x80); // check for 32-bit sym rect &= ~0x80; for (i = 0; i < SYMCNT; i++) { if (SymFcnC6[i].tsym == (uchar) rect) { SymFcnC6[i].pfcn (); break; } } if( i == SYMCNT ){ // Couldn't find symbol record type in the table Fatal("Invalid symbol record type"); } if (cbRec > 0) { // display symbol name cbName = Gets (); GetBytes (sb, (size_t) cbName); sb[cbName] = '\0'; printf ("\t%s", sb); } putchar ('\n'); if (cbRec) { Fatal("Invalid file"); } putchar ('\n'); } } LOCAL void PrtIndent (void) { int n; for (n = cIndent; n > 0; putchar (' '), n--); } LOCAL void C6EndSym (void) { cIndent--; PrtIndent (); printf ("End"); } LOCAL void C6BpSym (void) { BPSYMTYPE bp; bp.off = GetOffset (); bp.typind = WGets (); PrtIndent (); if (f386) { printf ("BP-relative:\toff = %08lx, type %8s", bp.off, SzNameType(bp.typind)); } else { printf ("BP-relative:\toff = %04lx, type %8s", bp.off, SzNameType(bp.typind)); } } LOCAL void C6LocalSym (void) { LOCSYMTYPE loc; loc.off = GetOffset (); loc.seg = WGets (); loc.typind = WGets (); PrtIndent (); printf ( "Local:\tseg:off = %04x:%0*lx", loc.seg, f386? 8 : 4, loc.off ); printf (", type %8s, ", SzNameType(loc.typind)); } const char * const namereg[] = { "AL", // 0 "CL", // 1 "DL", // 2 "BL", // 3 "AH", // 4 "CH", // 5 "DH", // 6 "BH", // 7 "AX", // 8 "CX", // 9 "DX", // 10 "BX", // 11 "SP", // 12 "BP", // 13 "SI", // 14 "DI", // 15 "EAX", // 16 "ECX", // 17 "EDX", // 18 "EBX", // 19 "ESP", // 20 "EBP", // 21 "ESI", // 22 "EDI", // 23 "ES", // 24 "CS", // 25 "SS", // 26 "DS", // 27 "FS", // 28 "GS", // 29 "???", // 30 "???", // 31 "DX:AX", // 32 "ES:BX", // 33 "IP", // 34 "FLAGS", // 35 }; const char * const name87[] = { "ST (0)", "ST (1)", "ST (2)", "ST (3)", "ST (4)", "ST (5)", "ST (6)", "ST (7)" }; const char *SzNameReg(uchar reg) { if (reg <= 37) { return (namereg[reg]); } if (reg < 128 || reg > 135) { return ("???"); } return (name87[reg - 128]); } LOCAL void C6RegSym (void) { REGSYMTYPE regsym; regsym.typind = WGets (); regsym.reg = (char) Gets (); PrtIndent (); printf("Register:\ttype %8s, register = %s, ", SzNameType(regsym.typind), SzNameReg(regsym.reg)); } LOCAL void C6ConSym (void) { long len; WORD type; WORD code; static char buf[1024]; type = WGets (); PrtIndent (); printf ("Constant:\ttype %8s, ", SzNameType(type)); code = Gets(); if (code < 128) { len = code; // skip value bytes GetBytes(buf, (size_t) len); } else { switch (code) { case 133: // unsigned word case 137: // signed word len = WGets (); printf ("%x", (int) len); break; case 134: // signed long case 138: // unsigned long len = LGets (); printf ("%lx", len); break; case 136: // signed byte len = Gets (); printf ("%x", (int) len); break; default: printf ("??"); return; break; } } // now we should be at the name of the symbol } LOCAL void C6BlockSym (void) { BLKSYMTYPE block; int n; block.off = GetOffset(); block.len = WGets(); PrtIndent (); cIndent++; n = f386? 8 : 4; printf ( "Block Start : off = %0*lx, len = %04x", n, block.off, block.len); } LOCAL void C6ProcSym (void) { PROCSYMTYPE proc; int n; proc.off = GetOffset (); proc.typind = WGets (); proc.len = WGets (); proc.startoff = WGets (); proc.endoff = WGets (); proc.res = WGets(); proc.rtntyp = (char) Gets (); PrtIndent (); cIndent++; n = f386? 8 : 4; printf ( "Proc Start: off = %0*lx, type %8s, len = %04x\n", n, proc.off, SzNameType(proc.typind), proc.len); printf ( "\tDebug start = %04x, debug end = %04x, ", proc.startoff, proc.endoff); switch (proc.rtntyp) { case S_NEAR: printf ("NEAR,"); break; case S_FAR: printf ("FAR,"); break; default: printf ("???,"); } } LOCAL void C6LabSym () { LABSYMTYPE dat; int n; dat.off = GetOffset (); dat.rtntyp = (char) Gets (); PrtIndent (); n = f386? 8 : 4; printf ( "Code label: off = %0*lx,", n, dat.off); switch (dat.rtntyp) { case S_NEAR: printf ("NEAR,"); break; case S_FAR: printf ("FAR,"); break; default: printf ("???,"); } } LOCAL void C6WithSym () { WITHSYMTYPE dat; int n; dat.off = GetOffset (); dat.len = WGets (); PrtIndent (); cIndent++; n = f386? 8 : 4; printf ( "'With Start: off = %0*lx, len = %04x", n, dat.off,dat.len); } LOCAL void C6EntrySym (void) { PROCSYMTYPE proc; int n; proc.off = GetOffset (); proc.typind = WGets (); proc.len = WGets (); proc.startoff = WGets (); proc.endoff = WGets (); proc.res = WGets(); proc.rtntyp = (char) Gets (); PrtIndent (); cIndent++; n = f386? 8 : 4; printf ( "FORTARN Entry: off = %0*lx, type %8s, len = %04x\n", n, proc.off, SzNameType(proc.typind), proc.len); printf ( "\tDebug start = %04x, debug end = %04x, ", proc.startoff, proc.endoff); switch (proc.rtntyp) { case S_NEAR: printf ("NEAR,"); break; case S_FAR: printf ("FAR,"); break; default: printf ("???,"); } } LOCAL void C6SkipSym (void) { printf("Skip: %d bytes\n", cbRec); // skip the bytes in the skip record while (cbRec > 0) { Gets (); } } LOCAL void C6CodeSegSym(void) { ushort seg; ushort res; seg = WGets(); res = WGets(); printf("Change Default Seg: seg = %04x\n", seg); } LOCAL void C6CobolTypeDefSym (void) { ushort type; type = WGets (); printf ("Cobol Typedef: type = %d,", type); } LOCAL void C6ChangeModelSym (void) { ushort offset; ushort model; ushort byte1; ushort byte2; ushort byte3; ushort byte4; offset = WGets (); model= Gets (); byte1 = Gets(); byte2 = Gets(); byte3 = Gets(); byte4 = Gets(); printf ("Change Model: offset = 0x%04x model = 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", offset, model, byte1, byte2, byte3, byte4); }