Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1590 lines
30 KiB

#include "compact.h"
#if DBG //{
char DbArray[50];
void DDHeapUsage(char *Modulename){
#if 1
if (DbArray[0] == FALSE)
return;
printf("DB 0, This dump not supported for this version\n");
#else
_HEAPINFO hinfo;
int heapstatus;
unsigned long usedSpace =0L;
unsigned long freeSpace =0L;
unsigned long maxFree = 0L;
if (DbArray[0] == FALSE)
return;
printf("DB 0, Packing Module: %s\n", Modulename);
hinfo._pentry = NULL;
while ((heapstatus = _heapwalk(&hinfo)) == _HEAPOK) {
if (hinfo._useflag == _USEDENTRY)
usedSpace += hinfo._size;
else{
freeSpace += hinfo._size;
if (hinfo._size > maxFree)
maxFree = hinfo._size;
}
}
printf("Used: 0x%8.8lx, Free: 0x%8.8lx, MaxFree: 0x%8.8lx, Total: 0x%8.8lx\n",
usedSpace, freeSpace, maxFree, usedSpace + freeSpace);
switch (heapstatus) {
case _HEAPBADPTR:
printf("ERROR - bad ptr to heap\n");
break;
case _HEAPBADBEGIN:
printf("ERROR - bad start of heap\n");
break;
case _HEAPBADNODE:
printf("ERROR - bad node in heap\n");
break;
default:
break;
}
#endif
}
void * __cdecl TrapMalloc(size_t size){
if (DbArray[1]) {
printf("DB 1, malloc request 0x%8.8x\n", size);
}
return(malloc(size));
}
#define PrintType(name) printf("%s\n",name);
typedef struct texttab {
int txtkey;
char *txtstr;
} TEXTTAB;
void DumpType(CV_typ_t, TYPPTR);
void PrintStr(const uchar *);
ushort PrintNumeric( void *);
void ShowStr(const char *, const uchar *);
bool_t printflag = TRUE;
LOCAL const char *C7CallTyp (ushort);
LOCAL void PrintBAttr (CV_fldattr_t);
LOCAL void PrintMAttr (CV_fldattr_t);
LOCAL void PrintFAttr (CV_fldattr_t);
LOCAL void PrintVBAttr (CV_fldattr_t);
LOCAL void PrintProp (CV_prop_t);
LOCAL void FieldList (ushort, void *, bool_t);
LOCAL void DumpHex (TYPPTR);
LOCAL void PushType (CV_typ_t);
static char *XlateC7PtrMode[] = {
"Pointer",
"Reference",
"Pointer to member",
"Pointer to member function",
"???",
"???",
"???",
"???"
};
static char *XlateC7PtrType[ ] = {
"Near",
"Far",
"Huge",
"BasedSeg",
"BasedVal",
"BasedSegVal",
"BasedAddr",
"BasedSegAdr",
"BasedOnType",
"BasedOnSelf",
"Near32",
"Far32",
"???",
"???",
"???",
"???"
};
char *C7MPropStrings[] = {
"VANILLA",
"VIRTUAL",
"STATIC",
"FRIEND",
"INTRODUCING VIRTUAL",
"PURE VIRTUAL",
"PURE INTRO"
};
char *C7AccessStrings[] = {
"NONE", "PRIVATE", "PROTECT", "PUBLIC"
};
char *C7ModifierStrings[] = {
"NO ATTRIBUTE", "CONST", "VOLATILE", "CONST VOLATILE"
};
char *C7VtsStrings[] = {
"NEAR",
"FAR",
"THIN",
"ADDRESS POINT DISPLACEMENT",
"POINTER TO METACLASS DESCRIPTOR",
"???",
"???",
"???",
"???",
"???",
"???",
"???",
"???",
"???",
"???",
"???"
};
extern CV_typ_t NewIndex;
#define LIMTYPES 8000
CV_typ_t TypeStack[LIMTYPES];
ushort cTypes;
ushort iTypes;
void CheckDouble (TENTRY *OldEntry)
{
ushort i;
TYPPTR pFirst;
uchar **pBuf;
TYPPTR pSecond = (TYPPTR)(OldEntry->TypeString);
if (printflag == FALSE) {
return;
}
if ((pSecond->leaf != LF_STRUCTURE) && (pSecond->leaf != LF_CLASS)) {
return;
}
for (i = 0; i < NewIndex - CV_FIRST_NONPRIM; i++) {
pBuf = pGType[i / GTYPE_INC];
pFirst = (TYPPTR)pBuf[i % GTYPE_INC];
if (pFirst != pSecond) {
switch (pFirst->leaf) {
case LF_CLASS:
case LF_STRUCTURE:
{
plfStructure plfF = (plfStructure)(&pFirst->leaf);
plfStructure plfS = (plfStructure)(&pSecond->leaf);
ushort cbNumeric;
uchar *pNameF;
uchar *pNameS;
cbNumeric = C7SizeOfNumeric ((uchar *)(&plfF->data));
pNameF = &plfF->data[0] + cbNumeric;
cbNumeric = C7SizeOfNumeric ((uchar *)(&plfS->data));
pNameS = &plfS->data[0] + cbNumeric;
if ((*pNameS == 11) &&
(memcmp ((uchar *)pNameS + 1, "(anonymous)", 11) == 0)) {
return;
}
if (*pNameF == *pNameS) {
if (memcmp ((char *)pNameF + 1, (char *)pNameS + 1, *pNameF) == 0) {
DumpFull ();
DASSERT (FALSE);
}
}
break;
}
default:
break;
}
}
}
}
void DumpLocalList (CV_typ_t start)
{
TYPPTR pType;
CV_typ_t type;
TENTRY *OldEntry;
CV_typ_t dummy;
if (printflag == FALSE) {
return;
}
printf ("****** 0x%04x start\n", start);
cTypes = 0;
iTypes = 0;
if (start < CV_FIRST_NONPRIM) {
return;
}
TypeStack[cTypes++] = start;
while (iTypes < cTypes) {
type = TypeStack[iTypes];
OldEntry = GetTypeEntry ((CV_typ_t)(type - CV_FIRST_NONPRIM), &dummy);
pType = (TYPPTR)(OldEntry->TypeString);
DumpFullType (type, pType, TRUE);
//DumpHex (pType);
iTypes++;
}
printf ("****** 0x%04x end\n", start);
}
void DumpGlobalList (CV_typ_t start)
{
TYPPTR pType;
CV_typ_t type;
uchar **pBuf;
if (printflag == FALSE) {
return;
}
printf ("****** 0x%04x start\n ", start);
cTypes = 0;
iTypes = 0;
if (start < CV_FIRST_NONPRIM) {
return;
}
TypeStack[cTypes++] = start;
while (iTypes < cTypes) {
type = TypeStack[iTypes];
pBuf = pGType[(type - CV_FIRST_NONPRIM) / GTYPE_INC];
pType = (TYPPTR)pBuf[(type - CV_FIRST_NONPRIM) % GTYPE_INC];
DumpFullType (type, pType, TRUE);
//DumpHex (pType);
iTypes++;
}
printf ("****** 0x%04x end\n", start);
}
void DumpFull (void)
{
ushort i;
TYPPTR pType;
uchar **pBuf;
if (printflag == FALSE) {
return;
}
for (i = 0; i < NewIndex - CV_FIRST_NONPRIM; i++) {
pBuf = pGType[i / GTYPE_INC];
pType = (TYPPTR)pBuf[i % GTYPE_INC];
DumpFullType ((CV_typ_t)(CV_FIRST_NONPRIM + i), pType, FALSE);
}
}
void DumpPartial (void)
{
ushort i;
TYPPTR pType;
uchar **pBuf;
if (printflag == FALSE) {
return;
}
for (i = 0; i < NewIndex - CV_FIRST_NONPRIM; i++) {
pBuf = pGType[i / GTYPE_INC];
pType = (TYPPTR)pBuf[i % GTYPE_INC];
DumpPartialType ((CV_typ_t)(CV_FIRST_NONPRIM + i), pType, FALSE);
}
}
void DumpPartialType (CV_typ_t usIndex, TYPPTR pType, bool_t fReplace)
{
switch (pType->leaf) {
case LF_POINTER :
{
plfPointer plf = (plfPointer)(&pType->leaf);
printf ("LF_POINTER ");
if (plf->attr.isconst) {
printf ("CONST ");
}
else if (plf->attr.isvolatile) {
printf ("VOLATILE ");
}
else {
printf ("NONE ");
}
printf ("0x%04x 0x%04x", plf->utype, plf->attr);
break;
}
case LF_MODIFIER:
{
plfModifier plf = (plfModifier)(&pType->leaf);
printf ("LF_MODIFIER ");
if (plf->attr.MOD_const && plf->attr.MOD_volatile) {
printf ("CONST VOLATILE ");
}
else if (plf->attr.MOD_const) {
printf ("CONST, ");
}
else if (plf->attr.MOD_volatile) {
printf ("\tVOLATILE ");
}
else {
printf ("NONE ");
}
printf ("0x%04x", plf->type);
break;
}
case LF_CLASS:
case LF_STRUCTURE:
{
plfStructure plf = (plfStructure)(&pType->leaf);
ushort cbNumeric;
uchar *pName;
printf ("LF_STRUCTURE ");
cbNumeric = PrintNumeric (&plf->data);
pName = &plf->data[0] + cbNumeric;
PrintStr (pName);
if (fReplace) {
printf (" REPLACEMENT");
}
break;
}
case LF_UNION:
{
plfUnion plf = (plfUnion)(&pType->leaf);
ushort cbNumeric;
uchar *pName;
printf ("LF_UNION ");
printf ("%4d ", plf->count);
cbNumeric = PrintNumeric (&plf->data);
pName = &plf->data[0] + cbNumeric;
PrintStr (pName);
if (fReplace) {
printf (" REPLACEMENT");
}
break;
}
case LF_ENUM:
{
plfEnum plf = (plfEnum)(&pType->leaf);
printf ("LF_ENUM ");
printf ("%4d ", plf->count);
printf ("0x%04x ", plf->utype);
PrintStr (plf->Name);
if (fReplace) {
printf (" REPLACEMENT");
}
break;
}
case LF_VTSHAPE:
{
plfVTShape plf = (plfVTShape)(&pType->leaf);
printf ("LF_VTSHAPE ");
printf("0x%04x", plf->count);
break;
}
case LF_BARRAY:
{
plfBArray plf = (plfBArray)(&pType->leaf);
printf ("LF_BARRAY");
break;
}
case LF_PROCEDURE:
{
plfProc plf = (plfProc)(&pType->leaf);
printf ("LF_PROCEDURE 0x%04x 0x%04x 0x%04x 0x%02x",
plf->rvtype, plf->parmcount, plf->arglist, plf->calltype);
break;
}
case LF_MFUNCTION:
{
plfMFunc plf = (plfMFunc)(&pType->leaf);
printf ("LF_MFUNCTION 0x%04x 0x%04x 0x%04x 0x%02x 0x%04x 0x%04x 0x%04x",
plf->rvtype, plf->parmcount, plf->arglist, plf->calltype, plf->classtype,
plf->thistype, plf->thisadjust);
break;
}
case LF_ARRAY :
{
plfArray plf = (plfArray)(&pType->leaf);
uchar *pName;
printf ("LF_ARRAY ");
printf ("0x%04x ", plf->elemtype);
printf ("0x%04x ", plf->idxtype);
pName = &plf->data[0];
pName += PrintNumeric (&plf->data);
PrintStr (pName);
break;
}
case LF_COBOL0:
{
printf ("Cobol 0 Record" );
//M00 Need to dump COBOL0 Type
break;
}
case LF_COBOL1:
{
printf ("Cobol 1 Record" );
break;
}
case LF_BITFIELD:
{
plfBitfield plf = (plfBitfield)(&pType->leaf);
printf ("LF_BITFIELD ");
printf ("%d ", plf->length);
printf ("%d ", plf->position);
printf ("0x%04x", plf->type);
break;
}
case LF_SKIP:
{
plfSkip plf = (plfSkip)(&pType->leaf);
printf ("LF_SKIP");
}
case LF_LIST:
{
printf ("LF_LIST");
break;
}
case LF_DERIVED:
{
plfDerived plf = (plfDerived)(&pType->leaf);
printf ("LF_DERIVED");
break;
}
case LF_ARGLIST:
{
plfArgList plf = (plfArgList)(&pType->leaf);
printf ("LF_ARGLIST %d", plf->count);
break;
}
case LF_FIELDLIST:
{
printf ("LF_FIELDLIST");
break;
}
case LF_METHODLIST:
{
plfMethodList plf = (plfMethodList)(&pType->leaf);
printf ("LF_METHODLIST");
break;
}
case LF_DEFARG:
{
plfDefArg plf = (plfDefArg)(&pType->leaf);
printf ("LF_DEFARG");
break;
}
case LF_LABEL:
{
plfLabel plf = (plfLabel)(&pType->leaf);
printf ("LF_LABEL");
break;
}
case LF_NULL:
{
printf ("LF_NULL");
break;
}
case LF_PRECOMP:
{
printf ("LF_PRECOMP");
break;
}
case LF_ENDPRECOMP:
{
printf ("LF_ENDPRECOMP");
break;
}
default:
{
printf ("UNRECOGNIZED TYPE");
}
}
printf ("\t0x%04x: %4d\n", usIndex, pCurMod->ModuleIndex);
}
void DumpFullType (ushort usIndex, TYPPTR pType, bool_t fPush)
{
if (printflag == FALSE) {
return;
}
printf ("0x%04x: Length = %u, Leaf = 0x%04x ", usIndex, pType->len, pType->leaf);
switch (pType->leaf) {
case LF_POINTER :
{
plfPointer plf = (plfPointer)(&pType->leaf);
PrintType ("LF_POINTER");
printf ("\t");
if (plf->attr.isconst) {
printf ("CONST ");
}
if (plf->attr.isvolatile) {
printf ("VOLATILE ");
}
printf ("%s (%s)",
XlateC7PtrMode[plf->attr.ptrmode],
XlateC7PtrType[plf->attr.ptrtype]);
if (plf->attr.isflat32) {
printf (" 16:32");
}
printf ("\n\tElement type: 0x%04x", plf->utype);
if (fPush) {
PushType (plf->utype);
}
switch (plf->attr.ptrmode) {
case CV_PTR_MODE_PTR:
{
switch (plf->attr.ptrtype) {
case CV_PTR_BASE_SEG:
{
printf (", Segment#: 0x%04x", plf->pbase.bseg );
break;
}
case CV_PTR_BASE_TYPE:
{
printf (", base symbol type = 0x%04x",
plf->pbase.btype.index);
ShowStr (", name = '", plf->pbase.btype.name);
printf ("'");
break;
}
case CV_PTR_BASE_SELF:
{
printf (", Based on self" );
break;
}
case CV_PTR_BASE_VAL:
{
printf (", Based on value in symbol:\n" );
//DumpOneSymC7 ((uchar *)&(plf->pbase.Sym[0]));
break;
}
case CV_PTR_BASE_SEGVAL:
{
printf (", Based on segment in symbol:\n" );
//DumpOneSymC7 ((uchar *)&(plf->pbase.Sym[0]));
break;
}
case CV_PTR_BASE_ADDR:
{
printf (", Based on address of symbol:\n" );
//DumpOneSymC7 ((uchar *)&(plf->pbase.Sym[0]));
break;
}
case CV_PTR_BASE_SEGADDR:
{
printf (", Based on segment of symbol:\n" );
//DumpOneSymC7 ((uchar *)&(plf->pbase.Sym[0]));
break;
}
}
break;
}
case CV_PTR_MODE_PMFUNC:
case CV_PTR_MODE_PMEM:
{
printf (", Containing class = 0x%04x\n", plf->pbase.pm.pmclass);
if (fPush) {
PushType (plf->pbase.pm.pmclass);
}
printf (", Type of pointer to member = 0x%04x", plf->pbase.pm.pmenum);
if (fPush) {
PushType (plf->pbase.pm.pmenum);
}
break;
}
}
printf ("\n" );
break;
}
case LF_MODIFIER:
{
plfModifier plf = (plfModifier)(&pType->leaf);
PrintType ("LF_MODIFIER");
if (plf->attr.MOD_const && plf->attr.MOD_volatile) {
printf ("\tCONST VOLATILE, ");
}
else if (plf->attr.MOD_const) {
printf ("\tCONST, ");
}
else if (plf->attr.MOD_volatile) {
printf ("\tVOLATILE, ");
}
else {
printf ("\tNONE, ");
}
printf ("\tmodifies type 0x%04x\n", plf->type);
if (fPush) {
PushType (plf->type);
}
break;
}
case LF_CLASS:
case LF_STRUCTURE:
{
plfStructure plf = (plfStructure)(&pType->leaf);
ushort cbNumeric;
uchar *pName;
if (plf->leaf == LF_CLASS ) {
PrintType ("LF_CLASS");
}
else {
PrintType ("LF_STRUCTURE");
}
printf ("\t# members = %d, ", plf->count);
printf (" field list type 0x%04x, ", plf->field);
if (fPush) {
PushType (plf->field);
}
PrintProp( plf->property );
printf ("\n");
printf ("\tDerivation list type 0x%04x, ", plf->derived);
if (fPush) {
PushType (plf->derived);
}
printf ("VT shape type 0x%04x\n", plf->vshape);
if (fPush) {
PushType (plf->vshape);
}
printf ("\tSize = ");
cbNumeric = PrintNumeric (plf->data);
pName = plf->data + cbNumeric;
ShowStr (", class name = ", pName);
printf("\n");
break;
}
case LF_UNION:
{
plfUnion plf = (plfUnion)(&pType->leaf);
ushort cbNumeric;
uchar *pName;
PrintType ("LF_UNION");
printf ("\t# members = %d, ", plf->count);
printf (" field list type 0x%04x, ", plf->field);
if (fPush) {
PushType (plf->field);
}
PrintProp( plf->property );
printf ("Size = ");
cbNumeric = PrintNumeric (plf->data);
pName = plf->data + cbNumeric;
ShowStr ("\t,class name = ", pName);
printf("\n");
break;
}
case LF_ENUM:
{
plfEnum plf = (plfEnum)(&pType->leaf);
PrintType ("LF_ENUM");
printf ("\t# members = %d, ", plf->count);
printf (" type = 0x%04x", plf->utype);
if (fPush) {
PushType (plf->utype);
}
printf (" field list type 0x%04x\n", plf->field);
PrintProp (plf->property);
ShowStr ("\tenum name = ", plf->Name);
printf("\n");
break;
}
case LF_VTSHAPE:
{
plfVTShape plf = (plfVTShape)(&pType->leaf);
ushort j;
uchar * pDesc;
uchar ch;
ushort usCount;
PrintType ("LF_VTSHAPE");
printf("\tNumber of entries: %u\n", usCount = plf->count);
pDesc = plf->desc;
for( j = 0; j < usCount; j++) {
if (!(j & 1)) {
ch = *pDesc++;
}
else {
ch >>= 4;
}
printf("\t\t[%u]: %s\n", j, C7VtsStrings[ch & 0xf]);
}
break;
}
case LF_BARRAY:
{
plfBArray plf = (plfBArray)(&pType->leaf);
PrintType ("LF_BARRAY");
printf (" Element type 0x%04x\n", plf->utype);
if (fPush) {
PushType (plf->utype);
}
break;
}
case LF_PROCEDURE:
{
plfProc plf = (plfProc)(&pType->leaf);
PrintType ("LF_PROCEDURE");
printf ("\tReturn type = 0x%04x, ", plf->rvtype);
if (fPush) {
PushType (plf->rvtype);
}
printf ("Call type = %s\n", C7CallTyp (plf->calltype));
printf ("\t# Parms = %d, ", plf->parmcount );
printf ("Arg list type = 0x%04x\n", plf->arglist);
if (fPush) {
PushType (plf->arglist);
}
break;
}
case LF_MFUNCTION:
{
plfMFunc plf = (plfMFunc)(&pType->leaf);
PrintType ("LF_MFUNCTION");
printf ("\tReturn type = 0x%04x, ", plf->rvtype);
if (fPush) {
PushType (plf->rvtype);
}
printf ("Class type = 0x%04x, ", plf->classtype);
if (fPush) {
PushType (plf->classtype);
}
printf ("This type = 0x%04x, \n", plf->thistype);
if (fPush) {
PushType (plf->thistype);
}
printf ("\tCall type = %s, ", C7CallTyp (plf->calltype));
printf ("Parms = %d, ", plf->parmcount );
printf ("Arg list type = 0x%04x, ", plf->arglist);
if (fPush) {
PushType (plf->arglist);
}
printf ("This adjust = %lx\n", plf->thisadjust );
break;
}
case LF_ARRAY :
{
plfArray plf = (plfArray)(&pType->leaf);
uchar *pName;
PrintType ("LF_ARRAY");
printf ("\tElement type = 0x%04x\n", plf->elemtype);
if (fPush) {
PushType (plf->elemtype);
}
printf ("\tIndex type = 0x%04x\n", plf->idxtype);
if (fPush) {
PushType (plf->idxtype);
}
printf ("\tlength = " );
pName = &plf->data[0];
pName += PrintNumeric (&plf->data);
ShowStr ("\n\tName = ", pName);
printf ("\n");
break;
}
case LF_COBOL0:
{
printf ("Cobol 0 Record\n" );
//M00 Need to dump COBOL0 Type
break;
}
case LF_COBOL1:
{
printf ("Cobol 1 Record\n" );
break;
}
case LF_BITFIELD:
{
plfBitfield plf = (plfBitfield)(&pType->leaf);
PrintType ("LF_BITFIELD");
printf ("\tbits = %d, ", plf->length);
printf ("starting position = %d", plf->position);
printf (", Type = 0x%04x\n", plf->type);
if (fPush) {
PushType (plf->type);
}
break;
}
case LF_SKIP:
{
plfSkip plf = (plfSkip)(&pType->leaf);
PrintType ("LF_SKIP");
printf ("\tNext effective type index: 0x%04x.\n", plf->type);
//printf ("\tBytes Skipped:\n");
//DumpHex (plf->data, cbLen - offsetof (lfSkip, data));
// Advance the count index to plf->type
usIndex = plf->type - 1; // -1 negates +1 at return time
}
case LF_LIST:
{
printf ("LF_LIST ignored\n");
break;
}
case LF_DERIVED:
{
plfDerived plf = (plfDerived)(&pType->leaf);
unsigned int i;
PrintType ("LF_DERIVED");
//M00 - Could do a check that count is correct compared to length
for (i = 0; i < plf->count; i++) {
printf("\tderived[%d] = 0x%04x\n", i, plf->drvdcls[i]);
if (fPush) {
PushType (plf->drvdcls[i]);
}
}
break;
}
case LF_ARGLIST:
{
plfArgList plf = (plfArgList)(&pType->leaf);
unsigned int i;
printf ("LF_ARGLIST argument count = %d\n", plf->count);
for (i = 0; i < plf->count; i++) {
// Verify that data isn't past end of record
DASSERT ((ushort)((uchar *)(&(plf->arg[i])) - (uchar *)plf) < pType->len);
printf("\tlist[%d] = 0x%04x\n", i, plf->arg[i]);
if (fPush) {
PushType (plf->arg[i]);
}
}
break;
}
case LF_FIELDLIST:
{
PrintType ("LF_FIELDLIST");
FieldList ((ushort)(pType->len - offsetof (lfFieldList,data)), &pType->data, fPush);
break;
}
case LF_METHODLIST:
{
plfMethodList plf = (plfMethodList)(&pType->leaf);
int i;
pmlMethod pml;
ushort cb;
ushort cbLeaf;
PrintType ("LF_METHODLIST");
pml = (pmlMethod)(&plf->mList);
cbLeaf = sizeof (ushort); // Size of leaf index
for (i = 0; cbLeaf < pType->len; i++) {
printf ("\tlist[%d] = ", i);
PrintFAttr (pml->attr);
printf ("0x%04x, ", pml->index);
if (fPush) {
PushType (pml->index);
}
if (pml->attr.mprop == CV_MTintro) {
printf (" vfptr offset = %ld", *((long UNALIGNED *)((uchar *)pml + sizeof(*pml))));
cb = sizeof (*pml) + sizeof (long);
}
else {
cb = sizeof (*pml);
}
pml = (pmlMethod)((uchar *)pml + cb);
cbLeaf += cb;
printf ("\n");
}
break;
}
case LF_DEFARG:
{
plfDefArg plf = (plfDefArg)(&pType->leaf);
PrintType ("LF_DEFARG");
printf ("type = 0x%04x, ", plf->type);
if (fPush) {
PushType (plf->type);
}
PrintStr (plf->expr);
printf ("\n");
break;
}
case LF_LABEL:
{
plfLabel plf = (plfLabel)(&pType->leaf);
PrintType ("LF_LABEL");
switch (plf->mode) {
case CV_LABEL_NEAR:
printf("\tmode = NEAR(0x%04x)\n", (ushort)plf->mode);
break;
case CV_LABEL_FAR:
printf("\tmode = FAR(0x%04x)\n", (ushort)plf->mode);
break;
default:
printf("\tmode = ???(0x%04x)\n", (ushort)plf->mode);
break;
}
break;
}
case LF_NULL:
{
PrintType ("LF_NULL");
break;
}
case LF_PRECOMP:
{
plfPreComp plf = (plfPreComp)(&pType->leaf);
PrintType ("LF_PRECOMP");
printf ("\t\tstart = 0x%04x, count = 0x%04x, signature = 0x%08lx\n ",
plf->start, plf->count, plf->signature);
printf ("\t\tIncluded file = ");
PrintStr (plf->name);
printf ("\n");
usIndex = usIndex + plf->count - 1;
break;
}
case LF_ENDPRECOMP:
{
plfEndPreComp plf = (plfEndPreComp)(&pType->leaf);
PrintType ("LF_ENDPRECOMP");
printf ("\t\tsignature = 0x%08lx\n ", plf->signature);
break;
}
default:
{
PrintType ("UNRECOGNIZED TYPE");
}
}
printf ("\n");
}
LOCAL void FieldList (ushort cbLen, void *pRec, bool_t fPush)
{
ushort cbCur;
ushort cb;
void * pLeaf;
int i;
pLeaf = pRec;
cbCur = 0;
i = 0;
while (cbCur < cbLen) {
printf ("\tlist[%d] = ", i++);
switch (*((ushort *)pLeaf)) {
case LF_INDEX:
printf ("Type Index = \n", ((plfIndex)pLeaf)->index);
if (fPush) {
PushType (((plfIndex)pLeaf)->index);
}
cb = sizeof( lfIndex );
break;
case LF_BCLASS:
{
plfBClass plf = (plfBClass)pLeaf;
printf ("LF_BCLASS, ");
PrintBAttr (plf->attr);
printf ("type = 0x%04x", plf->index);
if (fPush) {
PushType (plf->index);
}
printf (", offset = ");
cb = sizeof (*plf) + PrintNumeric( plf->offset);
printf ("\n");
break;
}
case LF_VBCLASS:
{
plfVBClass plf = (plfVBClass)pLeaf;
printf ("LF_VBCLASS, ");
PrintVBAttr (plf->attr);
printf ("direct base type = 0x%04x\n", plf->index);
if (fPush) {
PushType (plf->index);
}
printf ("\t\tvirtual base ptr = 0x%04x, vbpoff = ", plf->vbptr);
if (fPush) {
PushType (plf->vbptr);
}
cb = sizeof (*plf) + PrintNumeric (plf->vbpoff);
printf (", vbind = ");
cb += PrintNumeric ((uchar *)plf + cb);
printf ("\n");
break;
}
case LF_IVBCLASS:
{
plfVBClass plf = (plfVBClass)pLeaf;
printf ("LF_IVBCLASS, ");
PrintVBAttr (plf->attr);
printf ("indirect base type = 0x%04x\n", plf->index);
if (fPush) {
PushType (plf->index);
}
printf ("\t\tvirtual base ptr = 0x%04x, vbpoff = ", plf->vbptr);
if (fPush) {
PushType (plf->vbptr);
}
cb = sizeof (*plf) + PrintNumeric (plf->vbpoff);
printf (", vbind = ");
cb += PrintNumeric ((uchar *)plf + cb);
printf ("\n");
break;
}
case LF_FRIENDCLS:
{
plfFriendCls plf = (plfFriendCls)pLeaf;
printf ("LF_FRIENDCLS, ");
printf ("type = 0x%04x\n", plf->index);
if (fPush) {
PushType (plf->index);
}
cb = sizeof (*plf);
break;
}
case LF_FRIENDFCN:
{
plfFriendFcn plf = (plfFriendFcn)pLeaf;
printf ("LF_FRIENDFCN, ");
printf ("type = 0x%04x", plf->index);
if (fPush) {
PushType (plf->index);
}
ShowStr ("\tfunction name = ", (uchar *) plf->Name);
printf ("\n");
cb = sizeof (*plf) + plf->Name[0];
break;
}
case LF_MEMBER:
{
plfMember plf = (plfMember)pLeaf;
printf ("LF_MEMBER, ");
PrintMAttr( plf->attr );
printf ("type = 0x%04x, offset = ", plf->index);
if (fPush) {
PushType (plf->index);
}
cb = sizeof (*plf) + PrintNumeric(plf->offset);
ShowStr ("\n\t\tmember name = '", (uchar *)plf + cb);
printf ("'\n");
cb += *((uchar *)plf + cb) + 1; // Add length of the string
break;
}
case LF_STMEMBER:
{
plfSTMember plf = (plfSTMember)pLeaf;
printf("LF_STATICMEMBER, ");
PrintMAttr( plf->attr );
printf("type = 0x%04x", plf->index);
if (fPush) {
PushType (plf->index);
}
ShowStr( "\t\tmember name = ", (uchar *) plf->Name);
printf("\n");
cb = sizeof (*plf) + plf->Name[0];
break;
}
case LF_VFUNCTAB:
{
plfVFuncTab plf = (plfVFuncTab)pLeaf;
printf ("LF_VFUNCTAB, ");
printf ("type = 0x%04x\n", plf->type);
if (fPush) {
PushType (plf->type);
}
cb = sizeof (*plf);
break;
}
case LF_METHOD:
{
plfMethod plf = (plfMethod)pLeaf;
printf ("LF_METHOD, ");
printf ("count = %d, ", plf->count);
printf ("list = 0x%04x, ", plf->mList);
if (fPush) {
PushType (plf->mList);
}
ShowStr ("name = '", (uchar *) plf->Name);
printf ("'\n");
cb = sizeof (*plf) + plf->Name[0];
break;
}
case LF_ONEMETHOD:
{
plfOneMethod plf = (plfOneMethod)pLeaf;
printf ("LF_ONEMETHOD, ");
PrintFAttr (plf->attr);
printf ("index = 0x%04x, ", plf->index);
if (fPush) {
PushType (plf->index);
}
cb = (plf->attr.mprop == CV_MTintro) ? sizeof(long) : 0;
ShowStr ("name = '", (uchar *) plf->vbaseoff[cb]);
printf ("'\n");
cb = sizeof (*plf) + plf->vbaseoff[cb] + 1;
break;
}
case LF_ENUMERATE:
{
plfEnumerate plf = (plfEnumerate)pLeaf;
printf ("LF_ENUMERATE, ");
PrintMAttr( plf->attr );
printf ("value = ");
cb = offsetof (lfEnumerate, value) + PrintNumeric( plf->value );
ShowStr (", name = '", (uchar *)pLeaf + cb );
printf ("\n");
cb += *((uchar *)pLeaf + cb) + 1;
break;
}
case LF_NESTTYPE:
{
plfNestType plf = (plfNestType)pLeaf;
printf ("LF_NESTTYPE, ");
printf ("type = 0x%04x, ", plf->index);
if (fPush) {
PushType (plf->index);
}
PrintStr (plf->Name);
printf ("\n");
cb = sizeof (*plf) + plf->Name[0];
break;
}
default:
printf("unknown leaf %x\n", *((ushort *)pRec));
DASSERT (FALSE);
break;
}
cbCur += cb;
pLeaf = (uchar *) pLeaf + cb;
// Skip any pad bytes present
if ((cbCur < cbLen) && ((*((uchar *)pLeaf) & LF_PAD0) == LF_PAD0)) {
cb = *((uchar *)pLeaf) & 0xF;
pLeaf = (uchar *) pLeaf + cb;
cbCur += cb;
}
// Check data alignment
if ((cbCur < cbLen) && (((uchar *) pLeaf - (uchar *) pRec) & 0x3)) {
printf ("Error: Leaf is not aligned on a 4 byte boundery\n" );
}
}
}
const char * const C7CallTyps[] = {
"C short",
"C long",
"PLM long",
"PLM short",
"NEAR FASTCALL",
"FAR FASTCALL",
"PCODE",
"NEAR STDCALL",
"FAR STDCALL"
};
LOCAL const char *C7CallTyp (ushort calltype)
{
if (calltype < (sizeof(C7CallTyps)/sizeof(C7CallTyps[0]))) {
return (C7CallTyps[calltype]);
}
else {
return ("???");
}
}
// Print the properties info
LOCAL void PrintProp (CV_prop_t prop)
{
int i;
i = 0;
if (prop.packed) {
printf ("PACKED, ");
i++;
}
if (prop.ctor) {
printf ("CONSTRUCTOR, ");
i++;
}
if (prop.ovlops) {
printf ("OVERLOAD, ");
i++;
}
if (prop.isnested) {
printf ("NESTED, " );
i++;
}
if ( i == 4 ) {
printf ("\n\t\t");
i = 0;
}
if (prop.cnested) {
printf ("CONTAINS NESTED, " );
i++;
}
if ( i == 4 ) {
printf ("\n\t\t");
i = 0;
}
if (prop.opassign) {
printf ("OVERLOADED ASSIGNMENT, " );
i++;
}
if ( i == 4 ) {
printf ("\n\t\t");
i = 0;
}
if (prop.opcast) {
printf ("CASTING, " );
}
}
// attribute field for base classes
LOCAL void PrintBAttr (CV_fldattr_t attr)
{
if (attr.pseudo) {
printf ("(pseudo), ");
}
printf("%s, ", C7AccessStrings[attr.access]);
printf("%s, ", C7MPropStrings[attr.mprop]);
}
// attribute field for virtual base classes
LOCAL void PrintVBAttr (CV_fldattr_t attr)
{
if (attr.pseudo) {
printf ("(pseudo), ");
}
printf("%s, ", C7AccessStrings[attr.access]);
}
// attribute field for members, static members and enumerates
LOCAL void PrintMAttr (CV_fldattr_t attr)
{
printf("%s, ", C7AccessStrings[attr.access]);
}
// attribute field for methods
LOCAL void PrintFAttr (CV_fldattr_t attr)
{
printf("%s, ", C7AccessStrings[attr.access]);
printf("%s, ", C7MPropStrings[attr.mprop]);
if (attr.pseudo) {
printf("(psuedo), ");
}
}
void ShowStr(const char *psz, const uchar *pstr)
{
printf("%s", psz);
PrintStr(pstr);
}
// Input is a length prefixed string
void PrintStr (const uchar *pstr)
{
int i;
if( *pstr ){
for( i = *pstr++; i; i-- ){
putchar ( *pstr++ );
}
}
else{
printf ("(none)");
}
}
// Displays the data and returns how many bytes it occupied
ushort PrintNumeric( void *pNum )
{
char c;
ushort usIndex;
#if 0
double dblTmp;
long double ldblTmp;
#endif
usIndex = *(ushort *) pNum;
pNum = (ushort *) pNum + 1;
if( usIndex < LF_NUMERIC ){
printf ("%4u ", usIndex);
return (2);
}
switch (usIndex) {
case LF_CHAR:
c = *((char *)pNum);
printf ("%d(0x%2x) ", (short)c, (uchar)c);
return (2 + sizeof(uchar));
case LF_SHORT:
printf ("%d ", *((short UNALIGNED *)pNum));
return (2 + sizeof(short));
case LF_USHORT:
printf ("%u ", *((ushort UNALIGNED *)pNum));
return (2 + sizeof(ushort));
case LF_LONG:
printf ("%ld ", *((long UNALIGNED *)pNum));
return (2 + sizeof(long));
case LF_ULONG:
printf ("%lu ", *((ulong UNALIGNED *)pNum));
return (2 + sizeof(ulong));
#if 0
case LF_REAL32:
dblTmp = *((float UNALIGNED *)(pNum));
printf ("%f ", dblTmp);
return (2 + 4);
case LF_REAL64:
dblTmp = *((double UNALIGNED *)(pNum));
printf ("%f ", dblTmp);
return (2 + 8);
case LF_REAL80:
ldblTmp = *((long double UNALIGNED *)(pNum));
printf ("%lf ", ldblTmp);
return (2 + 10);
case LF_REAL128:
//M00 - Note converts from 128 to 80 bits to display
ldblTmp = *((long double UNALIGNED *)(pNum));
printf ("%lf ", ldblTmp);
return (2 + 16);
#else
case LF_REAL32:
printf ("floating point not support ");
return (2 + 4);
case LF_REAL64:
printf ("floating point not support ");
return (2 + 8);
case LF_REAL80:
printf ("floating point not support ");
return (2 + 10);
case LF_REAL128:
//M00 - Note converts from 128 to 80 bits to display
printf ("floating point not support ");
return (2 + 16);
#endif
default:
printf ("Invalid Numeric Leaf ");
return (2);
}
}
LOCAL void PushType (CV_typ_t type)
{
ushort i;
if (type < CV_FIRST_NONPRIM) {
return;
}
for (i = 0; i < cTypes; i++) {
if (type == TypeStack[i]) {
return;
}
}
TypeStack[cTypes++] = type;
if (cTypes == LIMTYPES) {
printf ("Type list depth exceeds %d\n", LIMTYPES);
AppExit (0);
}
}
LOCAL void DumpHex (TYPPTR pType)
{
int num_on_line = 0;
ushort usCount = pType->len + sizeof (ushort);
uchar *pBytes = (uchar *)pType;
printf("\t");
while (usCount--) {
printf ("%02x ", *pBytes++);
if (++num_on_line == 16) {
num_on_line = 0;
printf ("\n");
if (usCount != 0) {
printf ("\t");
}
}
}
printf ("\n");
}
#endif //}