From 8970bccd2901d6e7d77272cd28a20af62e9702f8 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Sat, 18 Oct 2014 20:07:09 -0700 Subject: Updated mscvpdb.h with latest from WINE. --- src/cv2pdb.cpp | 156 +- src/cv2pdb.h | 3 +- src/cv2pdb.vcxproj | 1 + src/cv2pdb.vcxproj.filters | 3 + src/cvutil.cpp | 10 +- src/dcvinfo.h | 43 + src/dwarf2pdb.cpp | 20 +- src/mscvpdb.h | 4292 +++++++++++++++++++++++--------------------- src/readDwarf.cpp | 4 +- 9 files changed, 2351 insertions(+), 2181 deletions(-) create mode 100644 src/dcvinfo.h diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp index 2388844..6eb3937 100644 --- a/src/cv2pdb.cpp +++ b/src/cv2pdb.cpp @@ -153,7 +153,7 @@ bool CV2PDB::openPDB(const TCHAR* pdbname, const TCHAR* pdbref) rsds = (OMFSignatureRSDS *) new char[24 + strlen(pdbnameA) + 1]; // sizeof(OMFSignatureRSDS) without name memcpy (rsds->Signature, "RSDS", 4); pdb->QuerySignature2(&rsds->guid); - rsds->unknown = pdb->QueryAge(); + rsds->age = pdb->QueryAge(); strcpy(rsds->name, pdbnameA); int rc = pdb->CreateDBI("", &dbi); @@ -371,7 +371,7 @@ int CV2PDB::_doFields(int cmd, codeview_reftype* dfieldlist, const codeview_reft codeview_fieldtype* dfieldtype = (codeview_fieldtype*)(dp + dpos); int copylen = 0; - switch (fieldtype->common.id) + switch (fieldtype->generic.id) { case LF_ENUMERATE_V1: if (dp && v3) @@ -484,10 +484,10 @@ int CV2PDB::_doFields(int cmd, codeview_reftype* dfieldlist, const codeview_reft if(cmd == kCmdOffsetFirstVirtualMethod) if(const codeview_type* cvtype = getTypeData(fieldtype->method_v1.mlist)) - if(cvtype->common.id == LF_METHODLIST_V1 && cvtype->common.len > 2) + if (cvtype->generic.id == LF_METHODLIST_V1 && cvtype->generic.len > 2) { // just check the first entry - const unsigned short *pattr = (const unsigned short*)(&cvtype->common + 1); + const unsigned short *pattr = (const unsigned short*)(&cvtype->generic + 1); int mode =(*pattr >> 2) & 7; if(mode == 4 || mode == 6) return *(const unsigned*)(&pattr[2]); @@ -609,7 +609,7 @@ int CV2PDB::_doFields(int cmd, codeview_reftype* dfieldlist, const codeview_reft base_classes++; if (dp) { - dfieldtype->vbclass_v2.id = fieldtype->common.id == LF_VBCLASS_V1 ? LF_VBCLASS_V2 : LF_IVBCLASS_V2; + dfieldtype->vbclass_v2.id = fieldtype->generic.id == LF_VBCLASS_V1 ? LF_VBCLASS_V2 : LF_IVBCLASS_V2; dfieldtype->vbclass_v2.attribute = fieldtype->vbclass_v1.attribute; dfieldtype->vbclass_v2.btype = fieldtype->vbclass_v1.btype; dfieldtype->vbclass_v2.vbtype = fieldtype->vbclass_v1.vbtype; @@ -735,7 +735,7 @@ int CV2PDB::addPointerType(codeview_type* dtype, int type, int attr) dtype->pointer_v2.len = 10; dtype->pointer_v2.datatype = translateType(type); dtype->pointer_v2.attribute = attr; - return dtype->common.len + 2; // no alignment data needed, because always 12 bytes + return dtype->generic.len + 2; // no alignment data needed, because always 12 bytes } int CV2PDB::addPointerType(unsigned char* dtype, int type, int attr) { @@ -815,7 +815,7 @@ void CV2PDB::writeUserTypeLen(codeview_type* type, int len) for (; len & 3; len++) p[len] = 0xf4 - (len & 3); - type->common.len = len - 2; + type->generic.len = len - 2; cbUserTypes += len; } @@ -853,7 +853,7 @@ const codeview_type* CV2PDB::getUserTypeData(int type) while(type > 0 && pos < cbUserTypes) { const codeview_type* ptype = (codeview_type*)(userTypes + pos); - int len = ptype->common.len + 2; + int len = ptype->generic.len + 2; pos += len; type--; } @@ -870,7 +870,7 @@ const codeview_type* CV2PDB::getConvertedTypeData(int type) while(type > 0 && pos < cbGlobalTypes) { const codeview_type* ptype = (codeview_type*)(globalTypes + pos); - int len = ptype->common.len + 2; + int len = ptype->generic.len + 2; pos += len; type--; } @@ -911,7 +911,7 @@ const codeview_type* CV2PDB::findCompleteClassType(const codeview_type* cvtype, *ptype = t; return type; } - pos += type->common.len + 2; + pos += type->generic.len + 2; } } return cvtype; @@ -920,11 +920,11 @@ const codeview_type* CV2PDB::findCompleteClassType(const codeview_type* cvtype, int CV2PDB::findMemberFunctionType(codeview_symbol* lastGProcSym, int thisPtrType) { const codeview_type* proctype = getTypeData(lastGProcSym->proc_v2.proctype); - if (!proctype || proctype->common.id != LF_PROCEDURE_V1) + if (!proctype || proctype->generic.id != LF_PROCEDURE_V1) return lastGProcSym->proc_v2.proctype; const codeview_type* thisPtrData = getTypeData(thisPtrType); - if (!thisPtrData || thisPtrData->common.id != LF_POINTER_V1) + if (!thisPtrData || thisPtrData->generic.id != LF_POINTER_V1) return lastGProcSym->proc_v2.proctype; int thistype = thisPtrData->pointer_v1.datatype; @@ -936,7 +936,7 @@ int CV2PDB::findMemberFunctionType(codeview_symbol* lastGProcSym, int thisPtrTyp { // remember: mfunction_v1.class_type falsely is pointer, not class type const codeview_type* type = (const codeview_type*)(typeData + offset[t]); - if (type->common.id == LF_MFUNCTION_V1 && type->mfunction_v1.this_type == thisPtrType) + if (type->generic.id == LF_MFUNCTION_V1 && type->mfunction_v1.this_type == thisPtrType) { if (type->mfunction_v1.arglist == proctype->procedure_v1.arglist && type->mfunction_v1.call == proctype->procedure_v1.call && @@ -961,7 +961,7 @@ int CV2PDB::fixProperty(int type, int prop, int fieldType) for (unsigned int t = 0; t < globalTypeHeader->cTypes; t++) { const codeview_reftype* cvtype = (const codeview_reftype*)(typeData + offset[t]); - if (cvtype->common.id == LF_FIELDLIST_V1 || cvtype->common.id == LF_FIELDLIST_V2) + if (cvtype->generic.id == LF_FIELDLIST_V1 || cvtype->generic.id == LF_FIELDLIST_V2) { if (countNestedTypes(cvtype, type) > 0) { @@ -1059,11 +1059,11 @@ int CV2PDB::sizeofType(int type) if (!cvtype) return 4; - if (cvtype->common.id == LF_CLASS_V1 || cvtype->common.id == LF_STRUCTURE_V1) + if (cvtype->generic.id == LF_CLASS_V1 || cvtype->generic.id == LF_STRUCTURE_V1) return sizeofClassType(cvtype); - if (cvtype->common.id == LF_OEM_V1 || cvtype->common.id == LF_OEM_V2) - if (((codeview_oem_type*) (&cvtype->common + 1))->common.oemid == 0x42) + if (cvtype->generic.id == LF_OEM_V1 || cvtype->generic.id == LF_OEM_V2) + if (((codeview_oem_type*)(&cvtype->generic + 1))->generic.oemid == 0x42) return 8; // all D oem types // everything else must be pointer or function pointer @@ -1085,16 +1085,16 @@ int CV2PDB::translateType(int type) if (!cvtype) return type; - if (cvtype->common.id != LF_OEM_V1) + if (cvtype->generic.id != LF_OEM_V1) return type; - codeview_oem_type* oem = (codeview_oem_type*) (&cvtype->common + 1); - if (oem->common.oemid == 0x42 && oem->common.id == 3) + codeview_oem_type* oem = (codeview_oem_type*)(&cvtype->generic + 1); + if (oem->generic.oemid == 0x42 && oem->generic.id == 3) { if (oem->d_delegate.this_type == 0x403 && oem->d_delegate.func_type == 0x74) return translateType(0x13); // int64 } - if (oem->common.oemid == 0x42 && oem->common.id == 1 && Dversion == 0) + if (oem->generic.oemid == 0x42 && oem->generic.id == 1 && Dversion == 0) { // C does not have D types, so this must be unsigned long if (oem->d_dyn_array.index_type == 0x12 && oem->d_dyn_array.elem_type == 0x74) @@ -1213,7 +1213,7 @@ bool CV2PDB::nameOfType(int type, char* name, int maxlen) return setError("nameOfType: invalid type while retreiving name of type"); int leaf_len, value, len; - switch(ptype->common.id) + switch(ptype->generic.id) { case LF_CLASS_V1: case LF_STRUCTURE_V1: @@ -1322,7 +1322,7 @@ bool CV2PDB::nameOfType(int type, char* name, int maxlen) break; case LF_OEM_V1: - if (!nameOfOEMType((codeview_oem_type*) (&ptype->common + 1), name, maxlen)) + if (!nameOfOEMType((codeview_oem_type*) (&ptype->generic + 1), name, maxlen)) return false; break; default: @@ -1386,11 +1386,11 @@ bool CV2PDB::nameOfDelegate(int thisType, int funcType, char* name, int maxlen) bool CV2PDB::nameOfOEMType(codeview_oem_type* oem, char* name, int maxlen) { - if (oem->common.oemid == 0x42 && oem->common.id == 1) + if (oem->generic.oemid == 0x42 && oem->generic.id == 1) return nameOfDynamicArray(oem->d_dyn_array.index_type, oem->d_dyn_array.elem_type, name, maxlen); - if (oem->common.oemid == 0x42 && oem->common.id == 2) + if (oem->generic.oemid == 0x42 && oem->generic.id == 2) return nameOfAssocArray(oem->d_assoc_array.key_type, oem->d_assoc_array.elem_type, name, maxlen); - if (oem->common.oemid == 0x42 && oem->common.id == 3) + if (oem->generic.oemid == 0x42 && oem->generic.id == 3) return nameOfDelegate(oem->d_delegate.this_type, oem->d_delegate.func_type, name, maxlen); return setError("nameOfOEMType: unknown OEM type record"); @@ -1692,11 +1692,11 @@ int CV2PDB::appendObjectType (int object_type, int enumType, const char* classSy // vtable rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->common.len = 6; - rdtype->common.id = LF_VTSHAPE_V1; - ((unsigned short*) (&rdtype->common + 1))[0] = 1; - ((unsigned short*) (&rdtype->common + 1))[1] = 0xf150; - cbUserTypes += rdtype->common.len + 2; + rdtype->generic.len = 6; + rdtype->generic.id = LF_VTSHAPE_V1; + ((unsigned short*)(&rdtype->generic + 1))[0] = 1; + ((unsigned short*)(&rdtype->generic + 1))[1] = 0xf150; + cbUserTypes += rdtype->generic.len + 2; int vtableType = nextUserType++; // vtable* @@ -1728,7 +1728,7 @@ int CV2PDB::appendObjectType (int object_type, int enumType, const char* classSy numElem++; } - cbUserTypes += rdtype->common.len + 2; + cbUserTypes += rdtype->generic.len + 2; int fieldListType = nextUserType++; dtype = (codeview_type*) (userTypes + cbUserTypes); @@ -1840,13 +1840,13 @@ int CV2PDB::getBaseClass(const codeview_type* cvtype) cvtype = findCompleteClassType(cvtype); const codeview_reftype* fieldlist = (const codeview_reftype*) getConvertedTypeData(getStructFieldlist(cvtype)); - if(!fieldlist || (fieldlist->common.id != LF_FIELDLIST_V1 && fieldlist->common.id != LF_FIELDLIST_V2)) + if (!fieldlist || (fieldlist->generic.id != LF_FIELDLIST_V1 && fieldlist->generic.id != LF_FIELDLIST_V2)) return 0; codeview_fieldtype* fieldtype = (codeview_fieldtype*)(fieldlist->fieldlist.list); - if(fieldtype->common.id == LF_BCLASS_V1) + if (fieldtype->generic.id == LF_BCLASS_V1) return fieldtype->bclass_v1.type; - if(fieldtype->common.id == LF_BCLASS_V2) + if (fieldtype->generic.id == LF_BCLASS_V2) return fieldtype->bclass_v2.type; return 0; } @@ -1857,7 +1857,7 @@ int CV2PDB::countBaseClasses(const codeview_type* cvtype) cvtype = findCompleteClassType(cvtype); const codeview_reftype* fieldlist = (const codeview_reftype*) getConvertedTypeData(getStructFieldlist(cvtype)); - if(!fieldlist || (fieldlist->common.id != LF_FIELDLIST_V1 && fieldlist->common.id != LF_FIELDLIST_V2)) + if (!fieldlist || (fieldlist->generic.id != LF_FIELDLIST_V1 && fieldlist->generic.id != LF_FIELDLIST_V2)) return 0; return _doFields(kCmdCountBaseClasses, 0, fieldlist, 0); @@ -1884,14 +1884,14 @@ bool CV2PDB::isCppInterface(const codeview_type* cvtype) cvtype = findCompleteClassType(cvtype); const codeview_reftype* fieldlist = (const codeview_reftype*) getTypeData(getStructFieldlist(cvtype)); - if(!fieldlist || (fieldlist->common.id != LF_FIELDLIST_V1 && fieldlist->common.id != LF_FIELDLIST_V2)) + if (!fieldlist || (fieldlist->generic.id != LF_FIELDLIST_V1 && fieldlist->generic.id != LF_FIELDLIST_V2)) return false; codeview_fieldtype* fieldtype = (codeview_fieldtype*)(fieldlist->fieldlist.list); const codeview_type* basetype = 0; - if(fieldtype->common.id == LF_BCLASS_V1) + if (fieldtype->generic.id == LF_BCLASS_V1) basetype = getTypeData(fieldtype->bclass_v1.type); - if(fieldtype->common.id == LF_BCLASS_V2) + if (fieldtype->generic.id == LF_BCLASS_V2) basetype = getTypeData(fieldtype->bclass_v2.type); if(basetype) return isCppInterface(basetype); @@ -2061,7 +2061,7 @@ bool CV2PDB::initGlobalTypes() const codeview_reftype* rtype = (codeview_reftype*)(typeData + offset[t]); int leaf_len, value; - int len = type->common.len + 2; + int len = type->generic.len + 2; checkGlobalTypeAlloc(len + 1000); unsigned int clsstype; @@ -2080,13 +2080,13 @@ bool CV2PDB::initGlobalTypes() continue; } - switch (type->common.id) + switch (type->generic.id) { case LF_OEM_V1: { - codeview_oem_type* oem = (codeview_oem_type*) (&type->common + 1); + codeview_oem_type* oem = (codeview_oem_type*)(&type->generic + 1); - if (oem->common.oemid == 0x42 && oem->common.id == 1) + if (oem->generic.oemid == 0x42 && oem->generic.id == 1) { if(Dversion == 0) // in dmc, this is used for (u)int64 { @@ -2101,12 +2101,12 @@ bool CV2PDB::initGlobalTypes() len = addClass(dtype, 0, 0, kPropIncomplete, 0, 0, 0, name); } } - else if (oem->common.oemid == 0x42 && oem->common.id == 3) + else if (oem->generic.oemid == 0x42 && oem->generic.id == 3) { const char* name = appendDelegate(oem->d_delegate.this_type, oem->d_delegate.func_type); len = addClass(dtype, 0, 0, kPropIncomplete, 0, 0, 0, name); } - else if (oem->common.oemid == 0x42 && oem->common.id == 2) + else if (oem->generic.oemid == 0x42 && oem->generic.id == 2) { const char* name = appendAssocArray(oem->d_assoc_array.key_type, oem->d_assoc_array.elem_type); len = addClass(dtype, 0, 0, kPropIncomplete, 0, 0, 0, name); @@ -2150,7 +2150,7 @@ bool CV2PDB::initGlobalTypes() dtype->struct_v2.n_element = type->struct_v1.n_element; if(type->struct_v1.fieldlist != 0) if(const codeview_type* td = getTypeData(type->struct_v1.fieldlist)) - if(td->common.id == LF_FIELDLIST_V1 || td->common.id == LF_FIELDLIST_V2) + if(td->generic.id == LF_FIELDLIST_V1 || td->generic.id == LF_FIELDLIST_V2) dtype->struct_v2.n_element = countFields((const codeview_reftype*)td); dtype->struct_v2.property = fixProperty(t + 0x1000, type->struct_v1.property, type->struct_v1.fieldlist) | kPropReserved2; @@ -2228,7 +2228,7 @@ bool CV2PDB::initGlobalTypes() { // fix class_type to point to class, not pointer to class codeview_type* ctype = (codeview_type*)(typeData + offset[clsstype - 0x1000]); - if (ctype->common.id == LF_POINTER_V1) + if (ctype->generic.id == LF_POINTER_V1) dtype->mfunction_v2.class_type = translateType(ctype->pointer_v1.datatype); } dtype->mfunction_v2.this_type = translateType(type->mfunction_v1.this_type); @@ -2261,7 +2261,7 @@ bool CV2PDB::initGlobalTypes() case LF_DERIVED_V1: #if REMOVE_LF_DERIVED - rdtype->common.id = LF_NULL_V1; + rdtype->generic.id = LF_NULL_V1; len = 4; #else rdtype->derived_v2.id = LF_DERIVED_V2; @@ -2284,10 +2284,10 @@ bool CV2PDB::initGlobalTypes() case LF_METHODLIST_V1: { - dtype->common.id = LF_METHODLIST_V2; + dtype->generic.id = LF_METHODLIST_V2; const unsigned short* pattr = (const unsigned short*)((const char*)type + 4); unsigned* dpattr = (unsigned*)((char*)dtype + 4); - while ((const char*)pattr + 4 <= (const char*)type + type->common.len + 2) + while ((const char*)pattr + 4 <= (const char*)type + type->generic.len + 2) { // type translation? switch ((*pattr >> 2) & 7) @@ -2326,7 +2326,7 @@ bool CV2PDB::initGlobalTypes() for (; len & 3; len++) globalTypes[cbGlobalTypes + len] = 0xf4 - (len & 3); - dtype->common.len = len - 2; + dtype->generic.len = len - 2; cbGlobalTypes += len; } @@ -2359,7 +2359,7 @@ int CV2PDB::appendClassTypeEnum(const codeview_type* fieldlist, int type, const BYTE data[200]; int len = addFieldNestedType((codeview_fieldtype*) data, type, name); - int fieldlen = fieldlist->common.len + 2; + int fieldlen = fieldlist->generic.len + 2; int off = (unsigned char*) fieldlist - globalTypes; checkGlobalTypeAlloc(len); @@ -2369,7 +2369,7 @@ int CV2PDB::appendClassTypeEnum(const codeview_type* fieldlist, int type, const cbGlobalTypes += len; codeview_type* nfieldlist = (codeview_type*) (globalTypes + off); - nfieldlist->common.len = fieldlen + len - 2; + nfieldlist->generic.len = fieldlen + len - 2; return len; } @@ -2385,7 +2385,7 @@ int CV2PDB::insertBaseClass(const codeview_type* fieldlist, int type) for (; len & 3; len++) p[len] = 0xf4 - (len & 3); - int fieldlen = fieldlist->common.len + 2; + int fieldlen = fieldlist->generic.len + 2; int off = (unsigned char*) fieldlist - globalTypes; checkGlobalTypeAlloc(len); @@ -2395,7 +2395,7 @@ int CV2PDB::insertBaseClass(const codeview_type* fieldlist, int type) cbGlobalTypes += len; codeview_type* nfieldlist = (codeview_type*) (globalTypes + off); - nfieldlist->common.len = fieldlen + len - 2; + nfieldlist->generic.len = fieldlen + len - 2; return len; } @@ -2405,9 +2405,9 @@ bool CV2PDB::insertClassTypeEnums() for (unsigned int t = 0; pos < cbGlobalTypes && t < globalTypeHeader->cTypes; t++) { codeview_type* type = (codeview_type*)(globalTypes + pos); - int typelen = type->common.len + 2; + int typelen = type->generic.len + 2; - switch(type->common.id) + switch(type->generic.id) { case LF_STRUCTURE_V3: case LF_STRUCTURE_V2: @@ -2421,7 +2421,7 @@ bool CV2PDB::insertClassTypeEnums() int basetype = 0; const char* name; - if(type->common.id == LF_STRUCTURE_V2 || type->common.id == LF_STRUCTURE_V3) + if(type->generic.id == LF_STRUCTURE_V2 || type->generic.id == LF_STRUCTURE_V3) { enumtype = structEnumType; basetype = structBaseType; @@ -2684,12 +2684,12 @@ bool CV2PDB::addPublics() for (unsigned int i = 0; i < header->cbSymbol; i += length) { union codeview_symbol* sym = (union codeview_symbol*)(symbols + i); - length = sym->common.len + 2; - if (!sym->common.id || length < 4) + length = sym->generic.len + 2; + if (!sym->generic.id || length < 4) break; int rc; - switch (sym->common.id) + switch (sym->generic.id) { case S_GDATA_V1: case S_LDATA_V1: @@ -2743,15 +2743,15 @@ int CV2PDB::copySymbols(BYTE* srcSymbols, int srcSize, BYTE* destSymbols, int de for (int i = 0; i < srcSize; i += length) { codeview_symbol* sym = (codeview_symbol*)(srcSymbols + i); - length = sym->common.len + 2; - if (!sym->common.id || length < 4) + length = sym->generic.len + 2; + if (!sym->generic.id || length < 4) break; codeview_symbol* dsym = (codeview_symbol*)(destSymbols + destSize); memcpy(dsym, sym, length); destlength = length; - switch (sym->common.id) + switch (sym->generic.id) { case S_UDT_V1: dsym->udt_v1.type = translateType(sym->udt_v1.type); @@ -2820,8 +2820,8 @@ int CV2PDB::copySymbols(BYTE* srcSymbols, int srcSize, BYTE* destSymbols, int de else if (type == 0 && p2ccmp(dsym->stack_v1.p_name, "@send")) { destlength = 4; - dsym->common.id = S_END_V1; - dsym->common.len = destlength - 2; + dsym->generic.id = S_END_V1; + dsym->generic.len = destlength - 2; } else #endif @@ -2944,23 +2944,23 @@ codeview_symbol* CV2PDB::findUdtSymbol(int type) for(int p = 0; p < cbGlobalSymbols; ) { codeview_symbol* sym = (codeview_symbol*) (globalSymbols + p); - if(sym->common.id == S_UDT_V1 && sym->udt_v1.type == type) + if(sym->generic.id == S_UDT_V1 && sym->udt_v1.type == type) return sym; - p += sym->common.len + 2; + p += sym->generic.len + 2; } for(int p = 0; p < cbStaticSymbols; ) { codeview_symbol* sym = (codeview_symbol*) (staticSymbols + p); - if(sym->common.id == S_UDT_V1 && sym->udt_v1.type == type) + if(sym->generic.id == S_UDT_V1 && sym->udt_v1.type == type) return sym; - p += sym->common.len + 2; + p += sym->generic.len + 2; } for(int p = 0; p < cbUdtSymbols; ) { codeview_symbol* sym = (codeview_symbol*) (udtSymbols + p); - if(sym->common.id == S_UDT_V1 && sym->udt_v1.type == type) + if(sym->generic.id == S_UDT_V1 && sym->udt_v1.type == type) return sym; - p += sym->common.len + 2; + p += sym->generic.len + 2; } return 0; } @@ -2970,23 +2970,23 @@ codeview_symbol* CV2PDB::findUdtSymbol(const char* name) for(int p = 0; p < cbGlobalSymbols; ) { codeview_symbol* sym = (codeview_symbol*) (globalSymbols + p); - if(sym->common.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name)) + if(sym->generic.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name)) return sym; - p += sym->common.len + 2; + p += sym->generic.len + 2; } for(int p = 0; p < cbStaticSymbols; ) { codeview_symbol* sym = (codeview_symbol*) (staticSymbols + p); - if(sym->common.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name)) + if(sym->generic.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name)) return sym; - p += sym->common.len + 2; + p += sym->generic.len + 2; } for(int p = 0; p < cbUdtSymbols; ) { codeview_symbol* sym = (codeview_symbol*) (udtSymbols + p); - if(sym->common.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name)) + if(sym->generic.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name)) return sym; - p += sym->common.len + 2; + p += sym->generic.len + 2; } return 0; } diff --git a/src/cv2pdb.h b/src/cv2pdb.h index d12af5b..6f88903 100644 --- a/src/cv2pdb.h +++ b/src/cv2pdb.h @@ -16,7 +16,8 @@ #include extern "C" { -#include "mscvpdb.h" + #include "mscvpdb.h" + #include "dcvinfo.h" } class PEImage; diff --git a/src/cv2pdb.vcxproj b/src/cv2pdb.vcxproj index 00e669e..d54b98b 100644 --- a/src/cv2pdb.vcxproj +++ b/src/cv2pdb.vcxproj @@ -110,6 +110,7 @@ + diff --git a/src/cv2pdb.vcxproj.filters b/src/cv2pdb.vcxproj.filters index 3bf032c..c374026 100644 --- a/src/cv2pdb.vcxproj.filters +++ b/src/cv2pdb.vcxproj.filters @@ -66,5 +66,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/src/cvutil.cpp b/src/cvutil.cpp index b8ad78a..9905ba8 100644 --- a/src/cvutil.cpp +++ b/src/cvutil.cpp @@ -8,7 +8,7 @@ bool isStruct(const codeview_type* cvtype) { - switch(cvtype->common.id) + switch (cvtype->generic.id) { case LF_STRUCTURE_V1: case LF_CLASS_V1: @@ -23,7 +23,7 @@ bool isStruct(const codeview_type* cvtype) bool isClass(const codeview_type* cvtype) { - switch(cvtype->common.id) + switch (cvtype->generic.id) { case LF_CLASS_V1: case LF_CLASS_V2: @@ -35,7 +35,7 @@ bool isClass(const codeview_type* cvtype) int getStructProperty(const codeview_type* cvtype) { - switch(cvtype->common.id) + switch (cvtype->generic.id) { case LF_STRUCTURE_V1: case LF_CLASS_V1: @@ -52,7 +52,7 @@ int getStructProperty(const codeview_type* cvtype) int getStructFieldlist(const codeview_type* cvtype) { - switch(cvtype->common.id) + switch (cvtype->generic.id) { case LF_STRUCTURE_V1: case LF_CLASS_V1: @@ -70,7 +70,7 @@ int getStructFieldlist(const codeview_type* cvtype) const BYTE* getStructName(const codeview_type* cvtype, bool &cstr) { int value, leaf_len; - switch(cvtype->common.id) + switch (cvtype->generic.id) { case LF_STRUCTURE_V1: case LF_CLASS_V1: diff --git a/src/dcvinfo.h b/src/dcvinfo.h new file mode 100644 index 0000000..cb3257b --- /dev/null +++ b/src/dcvinfo.h @@ -0,0 +1,43 @@ +#ifndef __DCVINFO_H__ +#define __DCVINFO_H__ + +// DMD CodeViev extensions + +union codeview_oem_type +{ + struct + { + short int oemid; + short int id; + short int count; + } generic; + + struct + { + short int oemid; // 0x42 for D + short int id; // 1 + short int count; // 2 + short unsigned int index_type; + short unsigned int elem_type; + } d_dyn_array; + + struct + { + short int oemid; // 0x42 for D + short int id; // 2 + short int count; // 2 + short unsigned int key_type; + short unsigned int elem_type; + } d_assoc_array; + + struct + { + short int oemid; // 0x42 for D + short int id; // 3 + short int count; // 2 + short unsigned int this_type; + short unsigned int func_type; + } d_delegate; +}; + +#endif diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp index 79708ac..028bb82 100644 --- a/src/dwarf2pdb.cpp +++ b/src/dwarf2pdb.cpp @@ -112,10 +112,10 @@ void CV2PDB::appendStackVar(const char* name, int type, Location& loc) } else { - cvs->stack_xxxx_v3.id = S_BPREL_XXXX_V3; - cvs->stack_xxxx_v3.unknown = baseReg; - len = cstrcpy_v (true, (BYTE*) cvs->stack_xxxx_v3.name, name); - len += (BYTE*) &cvs->stack_xxxx_v3.name - (BYTE*) cvs; + cvs->regrel_v3.id = S_REGREL_V3; + cvs->regrel_v3.reg = baseReg; + len = cstrcpy_v(true, (BYTE*)cvs->regrel_v3.name, name); + len += (BYTE*)&cvs->regrel_v3.name - (BYTE*)cvs; } for (; len & (align-1); len++) udtSymbols[cbUdtSymbols + len] = 0xf4 - (len & 3); @@ -152,8 +152,8 @@ bool CV2PDB::appendEndArg() checkUdtSymbolAlloc(8); codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); - cvs->common.id = S_ENDARG_V1; - cvs->common.len = 2; + cvs->generic.id = S_ENDARG_V1; + cvs->generic.len = 2; cbUdtSymbols += 4; return true; } @@ -163,8 +163,8 @@ void CV2PDB::appendEnd() checkUdtSymbolAlloc(8); codeview_symbol*cvs = (codeview_symbol*) (udtSymbols + cbUdtSymbols); - cvs->common.id = S_END_V1; - cvs->common.len = 2; + cvs->generic.id = S_END_V1; + cvs->generic.len = 2; cbUdtSymbols += 4; } @@ -264,9 +264,7 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE { Location param; if (decodeLocation(id.location.expr.ptr, id.location.expr.len, param, pframeBase)) - { appendStackVar(id.name, getTypeByDWARFPtr(cu, id.type), param); - } } } prev = cursor; @@ -289,9 +287,7 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE { Location var; if (decodeLocation(id.location.expr.ptr, id.location.expr.len, var, pframeBase)) - { appendStackVar(id.name, getTypeByDWARFPtr(cu, id.type), var); - } } } else if (id.tag == DW_TAG_lexical_block) diff --git a/src/mscvpdb.h b/src/mscvpdb.h index 9a55e1f..ae3a084 100644 --- a/src/mscvpdb.h +++ b/src/mscvpdb.h @@ -1,2083 +1,2209 @@ -/* - * MS debug information definitions. - * - * Copyright (C) 1996 Eric Youngdale - * Copyright (C) 1999-2000 Ulrich Weigand - * Copyright (C) 2004 Eric Pouech - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* MS has stored all its debug information in a set of structures - * which has been rather consistent across the years (ie you can grasp - * some continuity, and not so many drastic changes). - * - * A bit of history on the various formats - * MSVC 1.0 PDB v1 (new format for debug info) - * MSVC 2.0 Inclusion in link of debug info (PDB v2) - * MSVC 5.0 Types are 24 bits (instead of 16 for <= 4.x) - * MSVC x.0 PDB (change in internal streams layout) - * - * .DBG Contains COFF, FPO and Codeview info - * .PDB New format for debug info (information is - * derived from Codeview information) - * VCx0.PDB x major MSVC number, stores types, while - * .PDB stores symbols. - * - * Debug information can either be found in the debug section of a PE - * module (in something close to a .DBG file), or the debug section - * can actually refer to an external file, which can be in turn, - * either a .DBG or .PDB file. - * - * Regarding PDB files: - * ------------------- - * They are implemented as a set of internal files (as a small file - * system). The file is split into blocks, an internal file is made - * of a set of blocks. Internal files are accessed through - * numbers. For example, - * 1/ is the ROOT (basic information on the file) - * 2/ is the Symbol information (global symbols, local variables...) - * 3/ is the Type internal file (each the symbols can have type - * information associated with it). - * - * Over the years, three formats existed for the PDB: - * - ?? was rather linked to 16 bit code (our support shall be rather - * bad) - * - JG: it's the signature embedded in the file header. This format - * has been used in MSVC 2.0 => 5.0. - * - DS: it's the signature embedded in the file header. It's the - * current format supported my MS. - * - * Types internal stream - * --------------------- - * Types (from the Type internal file) have existed in three flavors - * (note that those flavors came as historical evolution, but there - * isn't a one to one link between types evolution and PDB formats' - * evolutions: - * - the first flavor (suffixed by V1 in this file), where the types - * and subtypes are 16 bit entities; and where strings are in Pascal - * format (first char is their length and are not 0 terminated) - * - the second flavor (suffixed by V2) differs from first flavor with - * types and subtypes as 32 bit entities. This forced some - * reordering of fields in some types - * - the third flavor (suffixed by V3) differs from second flavor with - * strings stored as C strings (ie are 0 terminated, instead of - * length prefixed) - * The different flavors can coexist in the same file (is this really - * true ??) - * - * For the evolution of types, the need of the second flavor was the - * number of types to be defined (limited to 0xFFFF, including the C - * basic types); the need of the third flavor is the increase of - * symbol size (to be greater than 256), which was likely needed for - * complex C++ types (nested + templates). - * - * It's somehow difficult to represent the layout of those types on - * disk because: - * - some integral values are stored as numeric leaf, which size is - * variable depending on its value - * - * Symbols internal stream - * ----------------------- - * Here also we find three flavors (that we've suffixed with _V1, _V2 - * and _V3) even if their evolution is closer to the evolution of - * types, they are not completely linked together. - */ - -/* - * some minor modifications have been done by Rainer Schuetze, mainly - * adding structs for the OEM types used by the DMD compiler - */ - -#include "pshpack1.h" - -/* ======================================== * - * Type information - * ======================================== */ - -struct p_string -{ - unsigned char namelen; - char name[1]; -}; - -union codeview_type -{ - struct - { - unsigned short int len; - short int id; - } common; - - struct - { - unsigned short int len; - short int id; - short int attribute; - unsigned short int type; - } modifier_v1; - - struct - { - unsigned short int len; - short int id; - int type; - short int attribute; - } modifier_v2; - - struct - { - unsigned short int len; - short int id; - short int attribute; - unsigned short int datatype; - struct p_string p_name; - } pointer_v1; - - struct - { - unsigned short int len; - short int id; - unsigned int datatype; - unsigned int attribute; - struct p_string p_name; - } pointer_v2; - - struct - { - unsigned short int len; - short int id; - unsigned short int elemtype; - unsigned short int idxtype; - unsigned short int arrlen; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } array_v1; - - struct - { - unsigned short int len; - short int id; - unsigned int elemtype; - unsigned int idxtype; - unsigned short int arrlen; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } array_v2; - - struct - { - unsigned short int len; - short int id; - unsigned int elemtype; - unsigned int idxtype; - unsigned short int arrlen; /* numeric leaf */ -#if 0 - char name[1]; -#endif - } array_v3; - - struct - { - unsigned short int len; - short int id; - short int n_element; - unsigned short int fieldlist; - short int property; - unsigned short int derived; - unsigned short int vshape; - unsigned short int structlen; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } struct_v1; - - struct - { - unsigned short int len; - short int id; - short int n_element; - short int property; - unsigned int fieldlist; - unsigned int derived; - unsigned int vshape; - unsigned short int structlen; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } struct_v2; - - struct - { - unsigned short int len; - short int id; - short int n_element; - short int property; - unsigned int fieldlist; - unsigned int derived; - unsigned int vshape; - unsigned short int structlen; /* numeric leaf */ -#if 0 - char name[1]; -#endif - } struct_v3; - - struct - { - unsigned short int len; - short int id; - unsigned short int count; - unsigned short int fieldlist; - short int property; - unsigned short int un_len; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } union_v1; - - struct - { - unsigned short int len; - short int id; - unsigned short int count; - short int property; - unsigned int fieldlist; - unsigned short int un_len; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } union_v2; - - struct - { - unsigned short int len; - short int id; - unsigned short int count; - short int property; - unsigned int fieldlist; - unsigned short int un_len; /* numeric leaf */ -#if 0 - char name[1]; -#endif - } union_v3; - - struct - { - unsigned short int len; - short int id; - unsigned short int count; - unsigned short int type; - unsigned short int fieldlist; - short int property; - struct p_string p_name; - } enumeration_v1; - - struct - { - unsigned short int len; - short int id; - unsigned short int count; - short int property; - unsigned int type; - unsigned int fieldlist; - struct p_string p_name; - } enumeration_v2; - - struct - { - unsigned short int len; - short int id; - unsigned short int count; - short int property; - unsigned int type; - unsigned int fieldlist; - char name[1]; - } enumeration_v3; - - struct - { - unsigned short int len; - short int id; - unsigned short int rvtype; - unsigned char call; - unsigned char reserved; - unsigned short int params; - unsigned short int arglist; - } procedure_v1; - - struct - { - unsigned short int len; - short int id; - unsigned int rvtype; - unsigned char call; - unsigned char reserved; - unsigned short int params; - unsigned int arglist; - } procedure_v2; - - struct - { - unsigned short int len; - short int id; - unsigned short int rvtype; - unsigned short int class_type; - unsigned short int this_type; - unsigned char call; - unsigned char reserved; - unsigned short int params; - unsigned short int arglist; - unsigned int this_adjust; - } mfunction_v1; - - struct - { - unsigned short int len; - short int id; - unsigned int rvtype; - unsigned int class_type; - unsigned this_type; - unsigned char call; - unsigned char reserved; - unsigned short params; - unsigned int arglist; - unsigned int this_adjust; - } mfunction_v2; -}; - -union codeview_reftype -{ - struct - { - unsigned short int len; - short int id; - } common; - - struct - { - unsigned short int len; - short int id; - unsigned char list[1]; - } fieldlist; - - struct - { - unsigned short int len; - short int id; - unsigned char nbits; - unsigned char bitoff; - unsigned short type; - } bitfield_v1; - - struct - { - unsigned short int len; - short int id; - unsigned int type; - unsigned char nbits; - unsigned char bitoff; - } bitfield_v2; - - struct - { - unsigned short int len; - short int id; - unsigned short num; - unsigned short args[1]; - } arglist_v1; - - struct - { - unsigned short int len; - short int id; - unsigned num; - unsigned args[1]; - } arglist_v2; - - struct - { - unsigned short int len; - short int id; - unsigned short num; - unsigned short drvdcls[1]; - } derived_v1; - - struct - { - unsigned short int len; - short int id; - unsigned num; - unsigned drvdcls[1]; - } derived_v2; -}; - -union codeview_fieldtype -{ - struct - { - short int id; - } common; - - struct - { - short int id; - unsigned short int type; - short int attribute; - unsigned short int offset; /* numeric leaf */ - } bclass_v1; - - struct - { - short int id; - short int attribute; - unsigned int type; - unsigned short int offset; /* numeric leaf */ - } bclass_v2; - - struct - { - short int id; - unsigned short int btype; - unsigned short int vbtype; - short int attribute; - unsigned short int vbpoff; /* numeric leaf */ -#if 0 - unsigned short int vboff; /* numeric leaf */ -#endif - } vbclass_v1; - - struct - { - short int id; - short int attribute; - unsigned int btype; - unsigned int vbtype; - unsigned short int vbpoff; /* numeric leaf */ -#if 0 - unsigned short int vboff; /* numeric leaf */ -#endif - } vbclass_v2; - - struct - { - short int id; - short int attribute; - unsigned short int value; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } enumerate_v1; - - struct - { - short int id; - short int attribute; - unsigned short int value; /* numeric leaf */ -#if 0 - char name[1]; -#endif - } enumerate_v3; - - struct - { - short int id; - unsigned short int type; - struct p_string p_name; - } friendfcn_v1; - - struct - { - short int id; - short int _pad0; - unsigned int type; - struct p_string p_name; - } friendfcn_v2; - - struct - { - short int id; - unsigned short int type; - short int attribute; - unsigned short int offset; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } member_v1; - - struct - { - short int id; - short int attribute; - unsigned int type; - unsigned short int offset; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } member_v2; - - struct - { - short int id; - short int attribute; - unsigned int type; - unsigned short int offset; /* numeric leaf */ -#if 0 - unsigned char name[1]; -#endif - } - member_v3; - - struct - { - short int id; - unsigned short int type; - short int attribute; - struct p_string p_name; - } stmember_v1; - - struct - { - short int id; - short int attribute; - unsigned int type; - struct p_string p_name; - } stmember_v2; - - struct - { - short int id; - short int attribute; - unsigned int type; - char name[1]; - } stmember_v3; - - struct - { - short int id; - short int count; - unsigned short int mlist; - struct p_string p_name; - } method_v1; - - struct - { - short int id; - short int count; - unsigned int mlist; - struct p_string p_name; - } method_v2; - - struct - { - short int id; - short int count; - unsigned int mlist; - char name[1]; - } method_v3; - - struct - { - short int id; - unsigned short int type; - struct p_string p_name; - } nesttype_v1; - - struct - { - short int id; - short int _pad0; - unsigned int type; - struct p_string p_name; - } nesttype_v2; - - struct - { - short int id; - short int _pad0; - unsigned int type; - char name[1]; - } nesttype_v3; - - struct - { - short int id; - unsigned short int type; - } vfunctab_v1; - - struct - { - short int id; - short int _pad0; - unsigned int type; - } vfunctab_v2; - - struct - { - short int id; - unsigned short int type; - } friendcls_v1; - - struct - { - short int id; - short int _pad0; - unsigned int type; - } friendcls_v2; - - struct - { - short int id; - short int attribute; - unsigned short int type; - struct p_string p_name; - } onemethod_v1; - - struct - { - short int id; - short int attribute; - unsigned int type; - struct p_string p_name; - } onemethod_v2; - - struct - { - short int id; - short int attribute; - unsigned int type; - char name[1]; - } onemethod_v3; - - struct - { - short int id; - short int attribute; - unsigned short int type; - unsigned int vtab_offset; - struct p_string p_name; - } onemethod_virt_v1; - - struct - { - short int id; - short int attribute; - unsigned int type; - unsigned int vtab_offset; - struct p_string p_name; - } onemethod_virt_v2; - - struct - { - short int id; - short int attribute; - unsigned int type; - unsigned int vtab_offset; - char name[1]; - } onemethod_virt_v3; - - struct - { - short int id; - unsigned short int type; - unsigned int offset; - } vfuncoff_v1; - - struct - { - short int id; - short int _pad0; - unsigned int type; - unsigned int offset; - } vfuncoff_v2; - - struct - { - short int id; - short int attribute; - unsigned short int type; - struct p_string p_name; - } nesttypeex_v1; - - struct - { - short int id; - short int attribute; - unsigned int type; - struct p_string p_name; - } nesttypeex_v2; - - struct - { - short int id; - short int attribute; - unsigned int type; - struct p_string p_name; - } membermodify_v2; - -}; - -union codeview_oem_type -{ - struct - { - short int oemid; - short int id; - short int count; - } common; - - struct - { - short int oemid; // 0x42 for D - short int id; // 1 - short int count; // 2 - short unsigned int index_type; - short unsigned int elem_type; - } d_dyn_array; - - struct - { - short int oemid; // 0x42 for D - short int id; // 2 - short int count; // 2 - short unsigned int key_type; - short unsigned int elem_type; - } d_assoc_array; - - struct - { - short int oemid; // 0x42 for D - short int id; // 3 - short int count; // 2 - short unsigned int this_type; - short unsigned int func_type; - } d_delegate; -}; - -/* - * This covers the basic datatypes that VC++ seems to be using these days. - * 32 bit mode only. There are additional numbers for the pointers in 16 - * bit mode. There are many other types listed in the documents, but these - * are apparently not used by the compiler, or represent pointer types - * that are not used. - * - * Official MS documentation says that type (< 0x4000, so 12 bits) is made of: - * +----------+------+------+----------+------+ - * | 11 | 10-8 | 7-4 | 3 | 2-0 | - * +----------+------+------+----------+------+ - * | reserved | mode | type | reserved | size | - * +----------+------+------+----------+------+ - * In recent PDB files, type 8 exists, and is seen as an HRESULT... So we've - * added this basic type... as if bit 3 had been integrated into the size field - */ - -/* the type number of a built-in type is a 16-bit value specified in the following format: - bit # | 11 | 10-8 | 7-4 | 3 | 2-0 | - field | reserved | mode | type | reserved | size | - - where - is one of the following types: - 0x00 Special - 0x01 Signed integral value - 0x02 Unsigned integral value - 0x03 Boolean - 0x04 Real - 0x05 Complex - 0x06 Special2 - 0x07 Real int value - 0x08 Reserved - 0x09 Reserved - 0x0a Reserved - 0x0b Reserved - 0x0c Reserved - 0x0d Reserved - 0x0e Reserved - 0x0f Reserved for debugger expression evaluator - - is an enumerated value for each of the types. - Type = special - 0x00 No type - 0x01 Absolute symbol - 0x02 Segment - 0x03 Void - 0x04 Basic 8-byte currency value - 0x05 Near Basic string - 0x06 Far Basic string - 0x07 Untranslated type from previous Microsoft symbol formats - Type = signed/unsigned integral and Boolean values - 0x00 1 byte - 0x01 2 byte - 0x02 4 byte - 0x03 8 byte - 0x04 Reserved - 0x05 Reserved - 0x06 Reserved - 0x07 Reserved - Type = real and complex - 0x00 32 bit - 0x01 64 bit - 0x02 80 bit - 0x03 128 bit - 0x04 48 bit - 0x05 Reserved - 0x06 Reserved - 0x07 Reserved - Type = special2 - 0x00 Bit - 0x01 Pascal CHAR - Type = Real int - 0x00 Char - 0x01 Wide character - 0x02 2-byte signed integer - 0x03 2-byte unsigned integer - 0x04 4-byte signed integer - 0x05 4-byte unsigned integer - 0x06 8-byte signed integer - 0x07 8-byte unsigned integer - - is the pointer mode: - 0x00 Direct; not a pointer - 0x01 Near pointer - 0x02 Far pointer - 0x03 Huge pointer - 0x04 32-bit near pointer - 0x05 32-bit far pointer - 0x06 64-bit near pointer - 0x07 Reserved -*/ - -/* basic types */ -#define T_NOTYPE 0x0000 /* Notype */ -#define T_ABS 0x0001 /* Abs */ -#define T_SEGMENT 0x0002 /* segment type */ -#define T_VOID 0x0003 /* Void */ -#define T_CURRENCY 0x0004 /* basic 8-byte currency value */ -#define T_NBASICSTR 0x0005 /* near basic string */ -#define T_FBASICSTR 0x0006 /* far basic string */ -#define T_NOTTRANS 0x0007 /* untranslated type record from MS symbol format */ -#define T_HRESULT 0x0008 /* HRESULT - or error code ??? */ -#define T_CHAR 0x0010 /* signed char */ -#define T_SHORT 0x0011 /* short */ -#define T_LONG 0x0012 /* long */ -#define T_QUAD 0x0013 /* long long */ -#define T_UCHAR 0x0020 /* unsigned char */ -#define T_USHORT 0x0021 /* unsigned short */ -#define T_ULONG 0x0022 /* unsigned long */ -#define T_UQUAD 0x0023 /* unsigned long long */ -#define T_BOOL08 0x0030 /* 8-bit boolean */ -#define T_BOOL16 0x0031 /* 16-bit boolean */ -#define T_BOOL32 0x0032 /* 32-bit boolean */ -#define T_BOOL64 0x0033 /* 64-bit boolean */ -#define T_REAL32 0x0040 /* float */ -#define T_REAL64 0x0041 /* double */ -#define T_REAL80 0x0042 /* 80-bit real */ -#define T_REAL128 0x0043 /* 128-bit real */ -#define T_REAL48 0x0044 /* 48-bit real */ -#define T_CPLX32 0x0050 /* 32-bit complex number */ -#define T_CPLX64 0x0051 /* 64-bit complex number */ -#define T_CPLX80 0x0052 /* 80-bit complex number */ -#define T_CPLX128 0x0053 /* 128-bit complex number */ -#define T_BIT 0x0060 /* bit */ -#define T_PASCHAR 0x0061 /* pascal CHAR */ -#define T_RCHAR 0x0070 /* real char */ -#define T_WCHAR 0x0071 /* wide char */ -#define T_INT2 0x0072 /* real 16-bit signed int */ -#define T_UINT2 0x0073 /* real 16-bit unsigned int */ -#define T_INT4 0x0074 /* int */ -#define T_UINT4 0x0075 /* unsigned int */ -#define T_INT8 0x0076 /* 64-bit signed int */ -#define T_UINT8 0x0077 /* 64-bit unsigned int */ - - -/* near pointers to basic types */ -#define T_PVOID 0x0103 /* near pointer to void */ -#define T_PCHAR 0x0110 /* Near pointer to 8-bit signed */ -#define T_PSHORT 0x0111 /* Near pointer to 16-bit signed */ -#define T_PLONG 0x0112 /* Near pointer to 32-bit signed */ -#define T_PQUAD 0x0113 /* Near pointer to 64-bit signed */ -#define T_PUCHAR 0x0120 /* Near pointer to 8-bit unsigned */ -#define T_PUSHORT 0x0121 /* Near pointer to 16-bit unsigned */ -#define T_PULONG 0x0122 /* Near pointer to 32-bit unsigned */ -#define T_PUQUAD 0x0123 /* Near pointer to 64-bit unsigned */ -#define T_PBOOL08 0x0130 /* Near pointer to 8-bit Boolean */ -#define T_PBOOL16 0x0131 /* Near pointer to 16-bit Boolean */ -#define T_PBOOL32 0x0132 /* Near pointer to 32-bit Boolean */ -#define T_PBOOL64 0x0133 /* Near pointer to 64-bit Boolean */ -#define T_PREAL32 0x0140 /* Near pointer to 32-bit real */ -#define T_PREAL64 0x0141 /* Near pointer to 64-bit real */ -#define T_PREAL80 0x0142 /* Near pointer to 80-bit real */ -#define T_PREAL128 0x0143 /* Near pointer to 128-bit real */ -#define T_PREAL48 0x0144 /* Near pointer to 48-bit real */ -#define T_PCPLX32 0x0150 /* Near pointer to 32-bit complex */ -#define T_PCPLX64 0x0151 /* Near pointer to 64-bit complex */ -#define T_PCPLX80 0x0152 /* Near pointer to 80-bit complex */ -#define T_PCPLX128 0x0153 /* Near pointer to 128-bit complex */ -#define T_PRCHAR 0x0170 /* Near pointer to a real char */ -#define T_PWCHAR 0x0171 /* Near pointer to a wide char */ -#define T_PINT2 0x0172 /* Near pointer to 16-bit signed int */ -#define T_PUINT2 0x0173 /* Near pointer to 16-bit unsigned int */ -#define T_PINT4 0x0174 /* Near pointer to 32-bit signed int */ -#define T_PUINT4 0x0175 /* Near pointer to 32-bit unsigned int */ -#define T_PINT8 0x0176 /* Near pointer to 64-bit signed int */ -#define T_PUINT8 0x0177 /* Near pointer to 64-bit unsigned int */ - - -/* far pointers to basic types */ -#define T_PFVOID 0x0203 /* Far pointer to void */ -#define T_PFCHAR 0x0210 /* Far pointer to 8-bit signed */ -#define T_PFSHORT 0x0211 /* Far pointer to 16-bit signed */ -#define T_PFLONG 0x0212 /* Far pointer to 32-bit signed */ -#define T_PFQUAD 0x0213 /* Far pointer to 64-bit signed */ -#define T_PFUCHAR 0x0220 /* Far pointer to 8-bit unsigned */ -#define T_PFUSHORT 0x0221 /* Far pointer to 16-bit unsigned */ -#define T_PFULONG 0x0222 /* Far pointer to 32-bit unsigned */ -#define T_PFUQUAD 0x0223 /* Far pointer to 64-bit unsigned */ -#define T_PFBOOL08 0x0230 /* Far pointer to 8-bit Boolean */ -#define T_PFBOOL16 0x0231 /* Far pointer to 16-bit Boolean */ -#define T_PFBOOL32 0x0232 /* Far pointer to 32-bit Boolean */ -#define T_PFBOOL64 0x0233 /* Far pointer to 64-bit Boolean */ -#define T_PFREAL32 0x0240 /* Far pointer to 32-bit real */ -#define T_PFREAL64 0x0241 /* Far pointer to 64-bit real */ -#define T_PFREAL80 0x0242 /* Far pointer to 80-bit real */ -#define T_PFREAL128 0x0243 /* Far pointer to 128-bit real */ -#define T_PFREAL48 0x0244 /* Far pointer to 48-bit real */ -#define T_PFCPLX32 0x0250 /* Far pointer to 32-bit complex */ -#define T_PFCPLX64 0x0251 /* Far pointer to 64-bit complex */ -#define T_PFCPLX80 0x0252 /* Far pointer to 80-bit complex */ -#define T_PFCPLX128 0x0253 /* Far pointer to 128-bit complex */ -#define T_PFRCHAR 0x0270 /* Far pointer to a real char */ -#define T_PFWCHAR 0x0271 /* Far pointer to a wide char */ -#define T_PFINT2 0x0272 /* Far pointer to 16-bit signed int */ -#define T_PFUINT2 0x0273 /* Far pointer to 16-bit unsigned int */ -#define T_PFINT4 0x0274 /* Far pointer to 32-bit signed int */ -#define T_PFUINT4 0x0275 /* Far pointer to 32-bit unsigned int */ -#define T_PFINT8 0x0276 /* Far pointer to 64-bit signed int */ -#define T_PFUINT8 0x0277 /* Far pointer to 64-bit unsigned int */ - - -/* huge pointers to basic types */ -#define T_PHVOID 0x0303 /* Huge pointer to void */ -#define T_PHCHAR 0x0310 /* Huge pointer to 8-bit signed */ -#define T_PHSHORT 0x0311 /* Huge pointer to 16-bit signed */ -#define T_PHLONG 0x0312 /* Huge pointer to 32-bit signed */ -#define T_PHQUAD 0x0313 /* Huge pointer to 64-bit signed */ -#define T_PHUCHAR 0x0320 /* Huge pointer to 8-bit unsigned */ -#define T_PHUSHORT 0x0321 /* Huge pointer to 16-bit unsigned */ -#define T_PHULONG 0x0322 /* Huge pointer to 32-bit unsigned */ -#define T_PHUQUAD 0x0323 /* Huge pointer to 64-bit unsigned */ -#define T_PHBOOL08 0x0330 /* Huge pointer to 8-bit Boolean */ -#define T_PHBOOL16 0x0331 /* Huge pointer to 16-bit Boolean */ -#define T_PHBOOL32 0x0332 /* Huge pointer to 32-bit Boolean */ -#define T_PHBOOL64 0x0333 /* Huge pointer to 64-bit Boolean */ -#define T_PHREAL32 0x0340 /* Huge pointer to 32-bit real */ -#define T_PHREAL64 0x0341 /* Huge pointer to 64-bit real */ -#define T_PHREAL80 0x0342 /* Huge pointer to 80-bit real */ -#define T_PHREAL128 0x0343 /* Huge pointer to 128-bit real */ -#define T_PHREAL48 0x0344 /* Huge pointer to 48-bit real */ -#define T_PHCPLX32 0x0350 /* Huge pointer to 32-bit complex */ -#define T_PHCPLX64 0x0351 /* Huge pointer to 64-bit complex */ -#define T_PHCPLX80 0x0352 /* Huge pointer to 80-bit complex */ -#define T_PHCPLX128 0x0353 /* Huge pointer to 128-bit real */ -#define T_PHRCHAR 0x0370 /* Huge pointer to a real char */ -#define T_PHWCHAR 0x0371 /* Huge pointer to a wide char */ -#define T_PHINT2 0x0372 /* Huge pointer to 16-bit signed int */ -#define T_PHUINT2 0x0373 /* Huge pointer to 16-bit unsigned int */ -#define T_PHINT4 0x0374 /* Huge pointer to 32-bit signed int */ -#define T_PHUINT4 0x0375 /* Huge pointer to 32-bit unsigned int */ -#define T_PHINT8 0x0376 /* Huge pointer to 64-bit signed int */ -#define T_PHUINT8 0x0377 /* Huge pointer to 64-bit unsigned int */ - - -/* 32-bit near pointers to basic types */ -#define T_32PVOID 0x0403 /* 32-bit near pointer to void */ -#define T_32PHRESULT 0x0408 /* 16:32 near pointer to HRESULT - or error code ??? */ -#define T_32PCHAR 0x0410 /* 16:32 near pointer to 8-bit signed */ -#define T_32PSHORT 0x0411 /* 16:32 near pointer to 16-bit signed */ -#define T_32PLONG 0x0412 /* 16:32 near pointer to 32-bit signed */ -#define T_32PQUAD 0x0413 /* 16:32 near pointer to 64-bit signed */ -#define T_32PUCHAR 0x0420 /* 16:32 near pointer to 8-bit unsigned */ -#define T_32PUSHORT 0x0421 /* 16:32 near pointer to 16-bit unsigned */ -#define T_32PULONG 0x0422 /* 16:32 near pointer to 32-bit unsigned */ -#define T_32PUQUAD 0x0423 /* 16:32 near pointer to 64-bit unsigned */ -#define T_32PBOOL08 0x0430 /* 16:32 near pointer to 8-bit Boolean */ -#define T_32PBOOL16 0x0431 /* 16:32 near pointer to 16-bit Boolean */ -#define T_32PBOOL32 0x0432 /* 16:32 near pointer to 32-bit Boolean */ -#define T_32PBOOL64 0x0433 /* 16:32 near pointer to 64-bit Boolean */ -#define T_32PREAL32 0x0440 /* 16:32 near pointer to 32-bit real */ -#define T_32PREAL64 0x0441 /* 16:32 near pointer to 64-bit real */ -#define T_32PREAL80 0x0442 /* 16:32 near pointer to 80-bit real */ -#define T_32PREAL128 0x0443 /* 16:32 near pointer to 128-bit real */ -#define T_32PREAL48 0x0444 /* 16:32 near pointer to 48-bit real */ -#define T_32PCPLX32 0x0450 /* 16:32 near pointer to 32-bit complex */ -#define T_32PCPLX64 0x0451 /* 16:32 near pointer to 64-bit complex */ -#define T_32PCPLX80 0x0452 /* 16:32 near pointer to 80-bit complex */ -#define T_32PCPLX128 0x0453 /* 16:32 near pointer to 128-bit complex */ -#define T_32PRCHAR 0x0470 /* 16:32 near pointer to a real char */ -#define T_32PWCHAR 0x0471 /* 16:32 near pointer to a wide char */ -#define T_32PINT2 0x0472 /* 16:32 near pointer to 16-bit signed int */ -#define T_32PUINT2 0x0473 /* 16:32 near pointer to 16-bit unsigned int */ -#define T_32PINT4 0x0474 /* 16:32 near pointer to 32-bit signed int */ -#define T_32PUINT4 0x0475 /* 16:32 near pointer to 32-bit unsigned int */ -#define T_32PINT8 0x0476 /* 16:32 near pointer to 64-bit signed int */ -#define T_32PUINT8 0x0477 /* 16:32 near pointer to 64-bit unsigned int */ - - -/* 32-bit far pointers to basic types */ -#define T_32PFVOID 0x0503 /* 32-bit far pointer to void */ -#define T_32PFCHAR 0x0510 /* 16:32 far pointer to 8-bit signed */ -#define T_32PFSHORT 0x0511 /* 16:32 far pointer to 16-bit signed */ -#define T_32PFLONG 0x0512 /* 16:32 far pointer to 32-bit signed */ -#define T_32PFQUAD 0x0513 /* 16:32 far pointer to 64-bit signed */ -#define T_32PFUCHAR 0x0520 /* 16:32 far pointer to 8-bit unsigned */ -#define T_32PFUSHORT 0x0521 /* 16:32 far pointer to 16-bit unsigned */ -#define T_32PFULONG 0x0522 /* 16:32 far pointer to 32-bit unsigned */ -#define T_32PFUQUAD 0x0523 /* 16:32 far pointer to 64-bit unsigned */ -#define T_32PFBOOL08 0x0530 /* 16:32 far pointer to 8-bit Boolean */ -#define T_32PFBOOL16 0x0531 /* 16:32 far pointer to 16-bit Boolean */ -#define T_32PFBOOL32 0x0532 /* 16:32 far pointer to 32-bit Boolean */ -#define T_32PFBOOL64 0x0533 /* 16:32 far pointer to 64-bit Boolean */ -#define T_32PFREAL32 0x0540 /* 16:32 far pointer to 32-bit real */ -#define T_32PFREAL64 0x0541 /* 16:32 far pointer to 64-bit real */ -#define T_32PFREAL80 0x0542 /* 16:32 far pointer to 80-bit real */ -#define T_32PFREAL128 0x0543 /* 16:32 far pointer to 128-bit real */ -#define T_32PFREAL48 0x0544 /* 16:32 far pointer to 48-bit real */ -#define T_32PFCPLX32 0x0550 /* 16:32 far pointer to 32-bit complex */ -#define T_32PFCPLX64 0x0551 /* 16:32 far pointer to 64-bit complex */ -#define T_32PFCPLX80 0x0552 /* 16:32 far pointer to 80-bit complex */ -#define T_32PFCPLX128 0x0553 /* 16:32 far pointer to 128-bit complex */ -#define T_32PFRCHAR 0x0570 /* 16:32 far pointer to a real char */ -#define T_32PFWCHAR 0x0571 /* 16:32 far pointer to a wide char */ -#define T_32PFINT2 0x0572 /* 16:32 far pointer to 16-bit signed int */ -#define T_32PFUINT2 0x0573 /* 16:32 far pointer to 16-bit unsigned int */ -#define T_32PFINT4 0x0574 /* 16:32 far pointer to 32-bit signed int */ -#define T_32PFUINT4 0x0575 /* 16:32 far pointer to 32-bit unsigned int */ -#define T_32PFINT8 0x0576 /* 16:32 far pointer to 64-bit signed int */ -#define T_32PFUINT8 0x0577 /* 16:32 far pointer to 64-bit unsigned int */ - - -/* counts, bit masks, and shift values needed to access various parts of the built-in type numbers */ -#define T_MAXPREDEFINEDTYPE 0x0580 /* maximum type index for all built-in types */ -#define T_MAXBASICTYPE 0x0080 /* maximum type index all non-pointer built-in types */ -#define T_BASICTYPE_MASK 0x00ff /* mask of bits that can potentially identify a non-pointer basic type */ -#define T_BASICTYPE_SHIFT 8 /* shift count to push out the basic type bits from a type number */ -#define T_MODE_MASK 0x0700 /* type mode mask (ptr/non-ptr) */ -#define T_SIZE_MASK 0x0007 /* type size mask (depends on 'type' value) */ -#define T_TYPE_MASK 0x00f0 /* type type mask (data treatment mode) */ - -/* bit patterns for the portion of a built-in type number */ -#define T_NEARPTR_BITS 0x0100 -#define T_FARPTR_BITS 0x0200 -#define T_HUGEPTR_BITS 0x0300 -#define T_NEAR32PTR_BITS 0x0400 -#define T_FAR32PTR_BITS 0x0500 -#define T_NEAR64PTR_BITS 0x0600 - -#define LF_MODIFIER_V1 0x0001 -#define LF_POINTER_V1 0x0002 -#define LF_ARRAY_V1 0x0003 -#define LF_CLASS_V1 0x0004 -#define LF_STRUCTURE_V1 0x0005 -#define LF_UNION_V1 0x0006 -#define LF_ENUM_V1 0x0007 -#define LF_PROCEDURE_V1 0x0008 -#define LF_MFUNCTION_V1 0x0009 -#define LF_VTSHAPE_V1 0x000a -#define LF_COBOL0_V1 0x000b -#define LF_COBOL1_V1 0x000c -#define LF_BARRAY_V1 0x000d -#define LF_LABEL_V1 0x000e -#define LF_NULL_V1 0x000f -#define LF_NOTTRAN_V1 0x0010 -#define LF_DIMARRAY_V1 0x0011 -#define LF_VFTPATH_V1 0x0012 -#define LF_PRECOMP_V1 0x0013 -#define LF_ENDPRECOMP_V1 0x0014 -#define LF_OEM_V1 0x0015 -#define LF_TYPESERVER_V1 0x0016 - -#define LF_MODIFIER_V2 0x1001 /* variants with new 32-bit type indices (V2) */ -#define LF_POINTER_V2 0x1002 -#define LF_ARRAY_V2 0x1003 -#define LF_CLASS_V2 0x1004 -#define LF_STRUCTURE_V2 0x1005 -#define LF_UNION_V2 0x1006 -#define LF_ENUM_V2 0x1007 -#define LF_PROCEDURE_V2 0x1008 -#define LF_MFUNCTION_V2 0x1009 -#define LF_COBOL0_V2 0x100a -#define LF_BARRAY_V2 0x100b -#define LF_DIMARRAY_V2 0x100c -#define LF_VFTPATH_V2 0x100d -#define LF_PRECOMP_V2 0x100e -#define LF_OEM_V2 0x100f - -#define LF_SKIP_V1 0x0200 -#define LF_ARGLIST_V1 0x0201 -#define LF_DEFARG_V1 0x0202 -#define LF_LIST_V1 0x0203 -#define LF_FIELDLIST_V1 0x0204 -#define LF_DERIVED_V1 0x0205 -#define LF_BITFIELD_V1 0x0206 -#define LF_METHODLIST_V1 0x0207 -#define LF_DIMCONU_V1 0x0208 -#define LF_DIMCONLU_V1 0x0209 -#define LF_DIMVARU_V1 0x020a -#define LF_DIMVARLU_V1 0x020b -#define LF_REFSYM_V1 0x020c - -#define LF_SKIP_V2 0x1200 /* variants with new 32-bit type indices (V2) */ -#define LF_ARGLIST_V2 0x1201 -#define LF_DEFARG_V2 0x1202 -#define LF_FIELDLIST_V2 0x1203 -#define LF_DERIVED_V2 0x1204 -#define LF_BITFIELD_V2 0x1205 -#define LF_METHODLIST_V2 0x1206 -#define LF_DIMCONU_V2 0x1207 -#define LF_DIMCONLU_V2 0x1208 -#define LF_DIMVARU_V2 0x1209 -#define LF_DIMVARLU_V2 0x120a - -/* Field lists */ -#define LF_BCLASS_V1 0x0400 -#define LF_VBCLASS_V1 0x0401 -#define LF_IVBCLASS_V1 0x0402 -#define LF_ENUMERATE_V1 0x0403 -#define LF_FRIENDFCN_V1 0x0404 -#define LF_INDEX_V1 0x0405 -#define LF_MEMBER_V1 0x0406 -#define LF_STMEMBER_V1 0x0407 -#define LF_METHOD_V1 0x0408 -#define LF_NESTTYPE_V1 0x0409 -#define LF_VFUNCTAB_V1 0x040a -#define LF_FRIENDCLS_V1 0x040b -#define LF_ONEMETHOD_V1 0x040c -#define LF_VFUNCOFF_V1 0x040d -#define LF_NESTTYPEEX_V1 0x040e -#define LF_MEMBERMODIFY_V1 0x040f - -#define LF_BCLASS_V2 0x1400 /* variants with new 32-bit type indices (V2) */ -#define LF_VBCLASS_V2 0x1401 -#define LF_IVBCLASS_V2 0x1402 -#define LF_FRIENDFCN_V2 0x1403 -#define LF_INDEX_V2 0x1404 -#define LF_MEMBER_V2 0x1405 -#define LF_STMEMBER_V2 0x1406 -#define LF_METHOD_V2 0x1407 -#define LF_NESTTYPE_V2 0x1408 -#define LF_VFUNCTAB_V2 0x1409 -#define LF_FRIENDCLS_V2 0x140a -#define LF_ONEMETHOD_V2 0x140b -#define LF_VFUNCOFF_V2 0x140c -#define LF_NESTTYPEEX_V2 0x140d - -#define LF_ENUMERATE_V3 0x1502 -#define LF_ARRAY_V3 0x1503 -#define LF_CLASS_V3 0x1504 -#define LF_STRUCTURE_V3 0x1505 -#define LF_UNION_V3 0x1506 -#define LF_ENUM_V3 0x1507 -#define LF_MEMBER_V3 0x150d -#define LF_STMEMBER_V3 0x150e -#define LF_METHOD_V3 0x150f -#define LF_NESTTYPE_V3 0x1510 -#define LF_ONEMETHOD_V3 0x1511 - -#define LF_NUMERIC 0x8000 /* numeric leaf types */ -#define LF_CHAR 0x8000 -#define LF_SHORT 0x8001 -#define LF_USHORT 0x8002 -#define LF_LONG 0x8003 -#define LF_ULONG 0x8004 -#define LF_REAL32 0x8005 -#define LF_REAL64 0x8006 -#define LF_REAL80 0x8007 -#define LF_REAL128 0x8008 -#define LF_QUADWORD 0x8009 -#define LF_UQUADWORD 0x800a -#define LF_REAL48 0x800b -#define LF_COMPLEX32 0x800c -#define LF_COMPLEX64 0x800d -#define LF_COMPLEX80 0x800e -#define LF_COMPLEX128 0x800f -#define LF_VARSTRING 0x8010 - -/* ======================================== * - * Symbol information - * ======================================== */ - -union codeview_symbol -{ - struct - { - short int len; - short int id; - } common; - - struct - { - short int len; - short int id; - unsigned int offset; - unsigned short segment; - unsigned short symtype; - struct p_string p_name; - } data_v1; - - struct - { - short int len; - short int id; - unsigned int symtype; - unsigned int offset; - unsigned short segment; - struct p_string p_name; - } data_v2; - - struct - { - short int len; - short int id; - unsigned int symtype; - unsigned int offset; - unsigned short segment; - char name[1]; - } data_v3; - - struct - { - short int len; - short int id; - unsigned int pparent; - unsigned int pend; - unsigned int next; - unsigned int offset; - unsigned short segment; - unsigned short thunk_len; - unsigned char thtype; - struct p_string p_name; - } thunk_v1; - - struct - { - short int len; - short int id; - unsigned int pparent; - unsigned int pend; - unsigned int next; - unsigned int offset; - unsigned short segment; - unsigned short thunk_len; - unsigned char thtype; - char name[1]; - } thunk_v3; - - struct - { - short int len; - short int id; - unsigned int pparent; - unsigned int pend; - unsigned int next; - unsigned int proc_len; - unsigned int debug_start; - unsigned int debug_end; - unsigned int offset; - unsigned short segment; - unsigned short proctype; - unsigned char flags; - struct p_string p_name; - } proc_v1; - - struct - { - short int len; - short int id; - unsigned int pparent; - unsigned int pend; - unsigned int next; - unsigned int proc_len; - unsigned int debug_start; - unsigned int debug_end; - unsigned int proctype; - unsigned int offset; - unsigned short segment; - unsigned char flags; - struct p_string p_name; - } proc_v2; - - struct - { - short int len; - short int id; - unsigned int pparent; - unsigned int pend; - unsigned int next; - unsigned int proc_len; - unsigned int debug_start; - unsigned int debug_end; - unsigned int proctype; - unsigned int offset; - unsigned short segment; - unsigned char flags; - char name[1]; - } proc_v3; - - struct - { - short int len; - short int id; - unsigned int symtype; - unsigned int offset; - unsigned short segment; - struct p_string p_name; - } public_v2; - - struct - { - short int len; - short int id; - unsigned int symtype; - unsigned int offset; - unsigned short segment; - char name[1]; - } public_v3; - - struct - { - short int len; /* Total length of this entry */ - short int id; /* Always S_BPREL_V1 */ - unsigned int offset; /* Stack offset relative to BP */ - unsigned short symtype; - struct p_string p_name; - } stack_v1; - - struct - { - short int len; /* Total length of this entry */ - short int id; /* Always S_BPREL_V2 */ - unsigned int offset; /* Stack offset relative to EBP */ - unsigned int symtype; - struct p_string p_name; - } stack_v2; - - struct - { - short int len; /* Total length of this entry */ - short int id; /* Always S_BPREL_V3 */ - int offset; /* Stack offset relative to BP */ - unsigned int symtype; - char name[1]; - } stack_v3; - - struct - { - short int len; /* Total length of this entry */ - short int id; /* Always S_BPREL_V3 */ - int offset; /* Stack offset relative to BP */ - unsigned int symtype; - unsigned short unknown; - char name[1]; - } stack_xxxx_v3; - - struct - { - short int len; /* Total length of this entry */ - short int id; /* Always S_REGISTER */ - unsigned short type; - unsigned short reg; - struct p_string p_name; - /* don't handle register tracking */ - } register_v1; - - struct - { - short int len; /* Total length of this entry */ - short int id; /* Always S_REGISTER_V2 */ - unsigned int type; /* check whether type & reg are correct */ - unsigned short reg; - struct p_string p_name; - /* don't handle register tracking */ - } register_v2; - - struct - { - short int len; /* Total length of this entry */ - short int id; /* Always S_REGISTER_V3 */ - unsigned int type; /* check whether type & reg are correct */ - unsigned short reg; - char name[1]; - /* don't handle register tracking */ - } register_v3; - - struct - { - short int len; - short int id; - unsigned int parent; - unsigned int end; - unsigned int length; - unsigned int offset; - unsigned short segment; - struct p_string p_name; - } block_v1; - - struct - { - short int len; - short int id; - unsigned int parent; - unsigned int end; - unsigned int length; - unsigned int offset; - unsigned short segment; - char name[1]; - } block_v3; - - struct - { - short int len; - short int id; - unsigned int offset; - unsigned short segment; - unsigned char flags; - struct p_string p_name; - } label_v1; - - struct - { - short int len; - short int id; - unsigned int offset; - unsigned short segment; - unsigned char flags; - char name[1]; - } label_v3; - - struct - { - short int len; - short int id; - unsigned short type; - unsigned short cvalue; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } constant_v1; - - struct - { - short int len; - short int id; - unsigned type; - unsigned short cvalue; /* numeric leaf */ -#if 0 - struct p_string p_name; -#endif - } constant_v2; - - struct - { - short int len; - short int id; - unsigned type; - unsigned short cvalue; -#if 0 - char name[1]; -#endif - } constant_v3; - - struct - { - short int len; - short int id; - unsigned short type; - struct p_string p_name; - } udt_v1; - - struct - { - short int len; - short int id; - unsigned type; - struct p_string p_name; - } udt_v2; - - struct - { - short int len; - short int id; - unsigned int type; - char name[1]; - } udt_v3; - - struct - { - short int len; - short int id; - char signature[4]; - struct p_string p_name; - } objname_v1; - - struct - { - short int len; - short int id; - unsigned int unknown; - struct p_string p_name; - } compiland_v1; - - struct - { - short int len; - short int id; - unsigned unknown1[4]; - unsigned short unknown2; - struct p_string p_name; - } compiland_v2; - - struct - { - short int len; - short int id; - unsigned int unknown; - char name[1]; - } compiland_v3; - - struct - { - short int len; - short int id; - unsigned int offset; - unsigned short segment; - } ssearch_v1; - - struct - { - short int len; - short int id; - short int flags; - char style; - char count; /* optional */ - char reglist[1]; /* count elements */ - - } functionret_v1; - - struct - { - short int len; - short int id; - unsigned int checksum; - unsigned int offset; - unsigned int module; - struct p_string p_name; // not included in len - } procref_v1; - - struct - { - short int len; - short int id; - unsigned short int sizeLocals; // sum of size of locals and arguments - unsigned short int unknown[10]; - unsigned short int info; // hasAlloca,hasSetjmp,hasLongjmp,hasInlAsm,hasEH,inl_specified,hasSEH,naked,hasGsChecks,hasEHa,noStackOrdering,wasInlined,strictGsCheck - // return UDT,instance constructor,instance constructor with virtual base - unsigned int unknown2; - } funcinfo_32; -}; - -#define S_COMPILAND_V1 0x0001 -#define S_REGISTER_V1 0x0002 -#define S_CONSTANT_V1 0x0003 -#define S_UDT_V1 0x0004 -#define S_SSEARCH_V1 0x0005 -#define S_END_V1 0x0006 -#define S_SKIP_V1 0x0007 -#define S_CVRESERVE_V1 0x0008 -#define S_OBJNAME_V1 0x0009 -#define S_ENDARG_V1 0x000a -#define S_COBOLUDT_V1 0x000b -#define S_MANYREG_V1 0x000c -#define S_RETURN_V1 0x000d -#define S_ENTRYTHIS_V1 0x000e - -#define S_BPREL_V1 0x0200 -#define S_LDATA_V1 0x0201 -#define S_GDATA_V1 0x0202 -#define S_PUB_V1 0x0203 -#define S_LPROC_V1 0x0204 -#define S_GPROC_V1 0x0205 -#define S_THUNK_V1 0x0206 -#define S_BLOCK_V1 0x0207 -#define S_WITH_V1 0x0208 -#define S_LABEL_V1 0x0209 -#define S_CEXMODEL_V1 0x020a -#define S_VFTPATH_V1 0x020b -#define S_REGREL_V1 0x020c -#define S_LTHREAD_V1 0x020d -#define S_GTHREAD_V1 0x020e - -#define S_PROCREF_V1 0x0400 -#define S_DATAREF_V1 0x0401 -#define S_ALIGN_V1 0x0402 -#define S_LPROCREF_V1 0x0403 - -#define S_REGISTER_V2 0x1001 /* Variants with new 32-bit type indices */ -#define S_CONSTANT_V2 0x1002 -#define S_UDT_V2 0x1003 -#define S_COBOLUDT_V2 0x1004 -#define S_MANYREG_V2 0x1005 -#define S_BPREL_V2 0x1006 -#define S_LDATA_V2 0x1007 -#define S_GDATA_V2 0x1008 -#define S_PUB_V2 0x1009 -#define S_LPROC_V2 0x100a -#define S_GPROC_V2 0x100b -#define S_VFTTABLE_V2 0x100c -#define S_REGREL_V2 0x100d -#define S_LTHREAD_V2 0x100e -#define S_GTHREAD_V2 0x100f -#if 0 -#define S_XXXXXXXXX_32 0x1012 /* seems linked to a function, content unknown */ -#endif -#define S_FUNCINFO_32 0x1012 -#define S_COMPILAND_V2 0x1013 - -#define S_COMPILAND_V3 0x1101 -#define S_THUNK_V3 0x1102 -#define S_BLOCK_V3 0x1103 -#define S_LABEL_V3 0x1105 -#define S_REGISTER_V3 0x1106 -#define S_CONSTANT_V3 0x1107 -#define S_UDT_V3 0x1108 -#define S_BPREL_V3 0x110B -#define S_LDATA_V3 0x110C -#define S_GDATA_V3 0x110D -#define S_PUB_V3 0x110E -#define S_LPROC_V3 0x110F -#define S_GPROC_V3 0x1110 -#define S_BPREL_XXXX_V3 0x1111 /* not really understood, but looks like bprel... */ -#define S_MSTOOL_V3 0x1116 /* compiler command line options and build information */ -#define S_PUB_FUNC1_V3 0x1125 /* didn't get the difference between the two */ -#define S_PUB_FUNC2_V3 0x1127 - -#define S_COMPILER_V4 0x113c /* compiler version info? */ -#define S_MSTOOL_V4 0x113d /* compiler command line options and build information */ - -#define S_LINKER_1 0x112c /* symbol info emitted from linker */ -#define S_SEGINFO_1 0x1136 /* emitted by linker */ -#define S_SEGINFO_2 0x1137 /* emitted by linker */ - -/* ======================================== * - * Line number information - * ======================================== */ - -union any_size -{ - const char* c; - const unsigned char* uc; - const short* s; - const int* i; - const unsigned int* ui; -}; - -struct startend -{ - unsigned int start; - unsigned int end; -}; - -struct codeview_linetab -{ - unsigned int nline; - unsigned int segno; - unsigned int start; - unsigned int end; - unsigned int source; - const unsigned short* linetab; - const unsigned int* offtab; -}; - - -/* ======================================== * - * PDB file information - * ======================================== */ - - -struct PDB_FILE -{ - DWORD size; - DWORD unknown; -}; - -struct PDB_JG_HEADER -{ - CHAR ident[40]; - DWORD signature; - DWORD block_size; - WORD free_list; - WORD total_alloc; - struct PDB_FILE toc; - WORD toc_block[1]; -}; - -struct PDB_DS_HEADER -{ - char signature[32]; - DWORD block_size; - DWORD unknown1; - DWORD num_pages; - DWORD toc_size; - DWORD unknown2; - DWORD toc_page; -}; - -struct PDB_JG_TOC -{ - DWORD num_files; - struct PDB_FILE file[1]; -}; - -struct PDB_DS_TOC -{ - DWORD num_files; - DWORD file_size[1]; -}; - -struct PDB_JG_ROOT -{ - DWORD Version; - DWORD TimeDateStamp; - DWORD Age; - DWORD cbNames; - CHAR names[1]; -}; - -struct PDB_DS_ROOT -{ - DWORD Version; - DWORD TimeDateStamp; - DWORD Age; - GUID guid; - DWORD cbNames; - CHAR names[1]; -}; - -typedef struct _PDB_TYPES_OLD -{ - DWORD version; - WORD first_index; - WORD last_index; - DWORD type_size; - WORD file; - WORD pad; -} PDB_TYPES_OLD, *PPDB_TYPES_OLD; - -typedef struct _PDB_TYPES -{ - DWORD version; - DWORD type_offset; - DWORD first_index; - DWORD last_index; - DWORD type_size; - WORD file; - WORD pad; - DWORD hash_size; - DWORD hash_base; - DWORD hash_offset; - DWORD hash_len; - DWORD search_offset; - DWORD search_len; - DWORD unknown_offset; - DWORD unknown_len; -} PDB_TYPES, *PPDB_TYPES; - -typedef struct _PDB_SYMBOL_RANGE -{ - WORD segment; - WORD pad1; - DWORD offset; - DWORD size; - DWORD characteristics; - WORD index; - WORD pad2; -} PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE; - -typedef struct _PDB_SYMBOL_RANGE_EX -{ - WORD segment; - WORD pad1; - DWORD offset; - DWORD size; - DWORD characteristics; - WORD index; - WORD pad2; - DWORD timestamp; - DWORD unknown; -} PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX; - -typedef struct _PDB_SYMBOL_FILE -{ - DWORD unknown1; - PDB_SYMBOL_RANGE range; - WORD flag; - WORD file; - DWORD symbol_size; - DWORD lineno_size; - DWORD unknown2; - DWORD nSrcFiles; - DWORD attribute; - CHAR filename[1]; -} PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE; - -typedef struct _PDB_SYMBOL_FILE_EX -{ - DWORD unknown1; - PDB_SYMBOL_RANGE_EX range; - WORD flag; - WORD file; - DWORD symbol_size; - DWORD lineno_size; - DWORD unknown2; - DWORD nSrcFiles; - DWORD attribute; - DWORD reserved[2]; - CHAR filename[1]; -} PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX; - -typedef struct _PDB_SYMBOL_SOURCE -{ - WORD nModules; - WORD nSrcFiles; - WORD table[1]; -} PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE; - -typedef struct _PDB_SYMBOL_IMPORT -{ - DWORD unknown1; - DWORD unknown2; - DWORD TimeDateStamp; - DWORD Age; - CHAR filename[1]; -} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT; - -typedef struct _PDB_SYMBOLS_OLD -{ - WORD hash1_file; - WORD hash2_file; - WORD gsym_file; - WORD pad; - DWORD module_size; - DWORD offset_size; - DWORD hash_size; - DWORD srcmodule_size; -} PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD; - -typedef struct _PDB_SYMBOLS -{ - DWORD signature; - DWORD version; - DWORD unknown; - DWORD hash1_file; - DWORD hash2_file; - WORD gsym_file; - WORD unknown1; - DWORD module_size; - DWORD offset_size; - DWORD hash_size; - DWORD srcmodule_size; - DWORD pdbimport_size; - DWORD resvd[5]; -} PDB_SYMBOLS, *PPDB_SYMBOLS; - -#include "poppack.h" - -/* ---------------------------------------------- - * Information used for parsing - * ---------------------------------------------- */ - -typedef struct -{ - DWORD from; - DWORD to; -} OMAP_DATA; - -struct msc_debug_info -{ - struct module* module; - int nsect; - const IMAGE_SECTION_HEADER* sectp; - int nomap; - const OMAP_DATA* omapp; - const BYTE* root; -}; - -/* coff.c */ -extern BOOL coff_process_info(const struct msc_debug_info* msc_dbg); - -/* =================================================== - * The old CodeView stuff (for NB09 and NB11) - * =================================================== */ - -#define sstModule 0x120 -#define sstTypes 0x121 -#define sstPublic 0x122 -#define sstPublicSym 0x123 -#define sstSymbols 0x124 -#define sstAlignSym 0x125 -#define sstSrcLnSeg 0x126 -#define sstSrcModule 0x127 -#define sstLibraries 0x128 -#define sstGlobalSym 0x129 -#define sstGlobalPub 0x12a -#define sstGlobalTypes 0x12b -#define sstMPC 0x12c -#define sstSegMap 0x12d -#define sstSegName 0x12e -#define sstPreComp 0x12f -#define sstFileIndex 0x133 -#define sstStaticSym 0x134 - -/* overall structure information */ -typedef struct OMFSignature -{ - char Signature[4]; - long filepos; -} OMFSignature; - -typedef struct OMFSignatureRSDS -{ - char Signature[4]; - GUID guid; - DWORD unknown; - CHAR name[1]; -} OMFSignatureRSDS; - -typedef struct _CODEVIEW_PDB_DATA -{ - char Signature[4]; - long filepos; - DWORD timestamp; - DWORD unknown; - CHAR name[1]; -} CODEVIEW_PDB_DATA, *PCODEVIEW_PDB_DATA; - -typedef struct OMFDirHeader -{ - WORD cbDirHeader; - WORD cbDirEntry; - DWORD cDir; - DWORD lfoNextDir; - DWORD flags; -} OMFDirHeader; - -typedef struct OMFDirEntry -{ - WORD SubSection; - WORD iMod; - DWORD lfo; - DWORD cb; -} OMFDirEntry; - -/* sstModule subsection */ - -typedef struct OMFSegDesc -{ - WORD Seg; - WORD pad; - DWORD Off; - DWORD cbSeg; -} OMFSegDesc; - -typedef struct OMFModule -{ - WORD ovlNumber; - WORD iLib; - WORD cSeg; - char Style[2]; -/* - OMFSegDesc SegInfo[cSeg]; - p_string Name; -*/ -} OMFModule; - -typedef struct OMFGlobalTypes -{ - DWORD flags; - DWORD cTypes; -/* - DWORD offset[cTypes]; - types_record[]; -*/ -} OMFGlobalTypes; - -/* sstGlobalPub section */ - -/* Header for symbol table */ -typedef struct OMFSymHash -{ - unsigned short symhash; - unsigned short addrhash; - unsigned long cbSymbol; - unsigned long cbHSym; - unsigned long cbHAddr; -} OMFSymHash; - -/* sstSegMap section */ - -typedef struct OMFSegMapDesc -{ - unsigned short flags; - unsigned short ovl; - unsigned short group; - unsigned short frame; - unsigned short iSegName; - unsigned short iClassName; - unsigned long offset; - unsigned long cbSeg; -} OMFSegMapDesc; - -typedef struct OMFSegMap -{ - unsigned short cSeg; - unsigned short cSegLog; -/* OMFSegMapDesc rgDesc[0];*/ -} OMFSegMap; - - -/* sstSrcModule section */ - -typedef struct OMFSourceLine -{ - unsigned short Seg; - unsigned short cLnOff; - unsigned long offset[1]; - unsigned short lineNbr[1]; -} OMFSourceLine; - -typedef struct OMFSourceFile -{ - unsigned short cSeg; - unsigned short reserved; - unsigned long baseSrcLn[1]; - unsigned short cFName; - char Name; -} OMFSourceFile; - -typedef struct OMFSourceModule -{ - unsigned short cFile; - unsigned short cSeg; - unsigned long baseSrcFile[1]; -} OMFSourceModule; +/* + * MS debug information definitions. + * + * Copyright (C) 1996 Eric Youngdale + * Copyright (C) 1999-2000 Ulrich Weigand + * Copyright (C) 2004 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* MS has stored all its debug information in a set of structures + * which has been rather consistent across the years (ie you can grasp + * some continuity, and not so many drastic changes). + * + * A bit of history on the various formats + * MSVC 1.0 PDB v1 (new format for debug info) + * MSVC 2.0 Inclusion in link of debug info (PDB v2) + * MSVC 5.0 Types are 24 bits (instead of 16 for <= 4.x) + * MSVC x.0 PDB (change in internal streams layout) + * + * .DBG Contains COFF, FPO and Codeview info + * .PDB New format for debug info (information is + * derived from Codeview information) + * VCx0.PDB x major MSVC number, stores types, while + * .PDB stores symbols. + * + * Debug information can either be found in the debug section of a PE + * module (in something close to a .DBG file), or the debug section + * can actually refer to an external file, which can be in turn, + * either a .DBG or .PDB file. + * + * Regarding PDB files: + * ------------------- + * They are implemented as a set of internal files (as a small file + * system). The file is split into blocks, an internal file is made + * of a set of blocks. Internal files are accessed through + * numbers. For example, + * 1/ is the ROOT (basic information on the file) + * 2/ is the Symbol information (global symbols, local variables...) + * 3/ is the Type internal file (each the symbols can have type + * information associated with it). + * + * Over the years, three formats existed for the PDB: + * - ?? was rather linked to 16 bit code (our support shall be rather + * bad) + * - JG: it's the signature embedded in the file header. This format + * has been used in MSVC 2.0 => 5.0. + * - DS: it's the signature embedded in the file header. It's the + * current format supported my MS. + * + * Types internal stream + * --------------------- + * Types (from the Type internal file) have existed in three flavors + * (note that those flavors came as historical evolution, but there + * isn't a one to one link between types evolution and PDB formats' + * evolutions: + * - the first flavor (suffixed by V1 in this file), where the types + * and subtypes are 16 bit entities; and where strings are in Pascal + * format (first char is their length and are not 0 terminated) + * - the second flavor (suffixed by V2) differs from first flavor with + * types and subtypes as 32 bit entities. This forced some + * reordering of fields in some types + * - the third flavor (suffixed by V3) differs from second flavor with + * strings stored as C strings (ie are 0 terminated, instead of + * length prefixed) + * The different flavors can coexist in the same file (is this really + * true ??) + * + * For the evolution of types, the need of the second flavor was the + * number of types to be defined (limited to 0xFFFF, including the C + * basic types); the need of the third flavor is the increase of + * symbol size (to be greater than 256), which was likely needed for + * complex C++ types (nested + templates). + * + * It's somehow difficult to represent the layout of those types on + * disk because: + * - some integral values are stored as numeric leaf, which size is + * variable depending on its value + * + * Symbols internal stream + * ----------------------- + * Here also we find three flavors (that we've suffixed with _V1, _V2 + * and _V3) even if their evolution is closer to the evolution of + * types, they are not completely linked together. + */ + +#include "pshpack1.h" + +/* ======================================== * + * Type information + * ======================================== */ + +struct p_string +{ + unsigned char namelen; + char name[1]; +}; + +union codeview_type +{ + struct + { + unsigned short int len; + short int id; + } generic; + + struct + { + unsigned short int len; + short int id; + short int attribute; + short int type; + } modifier_v1; + + struct + { + unsigned short int len; + short int id; + int type; + short int attribute; + } modifier_v2; + + struct + { + unsigned short int len; + short int id; + short int attribute; + short int datatype; + struct p_string p_name; + } pointer_v1; + + struct + { + unsigned short int len; + short int id; + unsigned int datatype; + unsigned int attribute; + struct p_string p_name; + } pointer_v2; + + struct + { + unsigned short int len; + short int id; + short int elemtype; + short int idxtype; + unsigned short int arrlen; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } array_v1; + + struct + { + unsigned short int len; + short int id; + unsigned int elemtype; + unsigned int idxtype; + unsigned short int arrlen; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } array_v2; + + struct + { + unsigned short int len; + short int id; + unsigned int elemtype; + unsigned int idxtype; + unsigned short int arrlen; /* numeric leaf */ +#if 0 + char name[1]; +#endif + } array_v3; + + struct + { + unsigned short int len; + short int id; + short int n_element; + short int fieldlist; + short int property; + short int derived; + short int vshape; + unsigned short int structlen; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } struct_v1; + + struct + { + unsigned short int len; + short int id; + short int n_element; + short int property; + unsigned int fieldlist; + unsigned int derived; + unsigned int vshape; + unsigned short int structlen; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } struct_v2; + + struct + { + unsigned short int len; + short int id; + short int n_element; + short int property; + unsigned int fieldlist; + unsigned int derived; + unsigned int vshape; + unsigned short int structlen; /* numeric leaf */ +#if 0 + char name[1]; +#endif + } struct_v3; + + struct + { + unsigned short int len; + short int id; + short int count; + short int fieldlist; + short int property; + unsigned short int un_len; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } union_v1; + + struct + { + unsigned short int len; + short int id; + short int count; + short int property; + unsigned int fieldlist; + unsigned short int un_len; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } union_v2; + + struct + { + unsigned short int len; + short int id; + short int count; + short int property; + unsigned int fieldlist; + unsigned short int un_len; /* numeric leaf */ +#if 0 + char name[1]; +#endif + } union_v3; + + struct + { + unsigned short int len; + short int id; + short int count; + short int type; + short int fieldlist; + short int property; + struct p_string p_name; + } enumeration_v1; + + struct + { + unsigned short int len; + short int id; + short int count; + short int property; + unsigned int type; + unsigned int fieldlist; + struct p_string p_name; + } enumeration_v2; + + struct + { + unsigned short int len; + short int id; + short int count; + short int property; + unsigned int type; + unsigned int fieldlist; + char name[1]; + } enumeration_v3; + + struct + { + unsigned short int len; + short int id; + unsigned short int rvtype; + unsigned char call; + unsigned char reserved; + unsigned short int params; + unsigned short int arglist; + } procedure_v1; + + struct + { + unsigned short int len; + short int id; + unsigned int rvtype; + unsigned char call; + unsigned char reserved; + unsigned short int params; + unsigned int arglist; + } procedure_v2; + + struct + { + unsigned short int len; + short int id; + unsigned short int rvtype; + unsigned short int class_type; + unsigned short int this_type; + unsigned char call; + unsigned char reserved; + unsigned short int params; + unsigned short int arglist; + unsigned int this_adjust; + } mfunction_v1; + + struct + { + unsigned short int len; + short int id; + unsigned int rvtype; + unsigned int class_type; + unsigned this_type; + unsigned char call; + unsigned char reserved; + unsigned short params; + unsigned int arglist; + unsigned int this_adjust; + } mfunction_v2; +}; + +union codeview_reftype +{ + struct + { + unsigned short int len; + short int id; + } generic; + + struct + { + unsigned short int len; + short int id; + unsigned char list[1]; + } fieldlist; + + struct + { + unsigned short int len; + short int id; + unsigned char nbits; + unsigned char bitoff; + unsigned short type; + } bitfield_v1; + + struct + { + unsigned short int len; + short int id; + unsigned int type; + unsigned char nbits; + unsigned char bitoff; + } bitfield_v2; + + struct + { + unsigned short int len; + short int id; + unsigned short num; + unsigned short args[1]; + } arglist_v1; + + struct + { + unsigned short int len; + short int id; + unsigned num; + unsigned args[1]; + } arglist_v2; + + struct + { + unsigned short int len; + short int id; + unsigned short num; + unsigned short drvdcls[1]; + } derived_v1; + + struct + { + unsigned short int len; + short int id; + unsigned num; + unsigned drvdcls[1]; + } derived_v2; +}; + +union codeview_fieldtype +{ + struct + { + short int id; + } generic; + + struct + { + short int id; + short int type; + short int attribute; + unsigned short int offset; /* numeric leaf */ + } bclass_v1; + + struct + { + short int id; + short int attribute; + unsigned int type; + unsigned short int offset; /* numeric leaf */ + } bclass_v2; + + struct + { + short int id; + short int btype; + short int vbtype; + short int attribute; + unsigned short int vbpoff; /* numeric leaf */ +#if 0 + unsigned short int vboff; /* numeric leaf */ +#endif + } vbclass_v1; + + struct + { + short int id; + short int attribute; + unsigned int btype; + unsigned int vbtype; + unsigned short int vbpoff; /* numeric leaf */ +#if 0 + unsigned short int vboff; /* numeric leaf */ +#endif + } vbclass_v2; + + struct + { + short int id; + short int attribute; + unsigned short int value; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } enumerate_v1; + + struct + { + short int id; + short int attribute; + unsigned short int value; /* numeric leaf */ +#if 0 + char name[1]; +#endif + } enumerate_v3; + + struct + { + short int id; + short int type; + struct p_string p_name; + } friendfcn_v1; + + struct + { + short int id; + short int _pad0; + unsigned int type; + struct p_string p_name; + } friendfcn_v2; + + struct + { + short int id; + short int type; + short int attribute; + unsigned short int offset; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } member_v1; + + struct + { + short int id; + short int attribute; + unsigned int type; + unsigned short int offset; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } member_v2; + + struct + { + short int id; + short int attribute; + unsigned int type; + unsigned short int offset; /* numeric leaf */ +#if 0 + unsigned char name[1]; +#endif + } + member_v3; + + struct + { + short int id; + short int type; + short int attribute; + struct p_string p_name; + } stmember_v1; + + struct + { + short int id; + short int attribute; + unsigned int type; + struct p_string p_name; + } stmember_v2; + + struct + { + short int id; + short int attribute; + unsigned int type; + char name[1]; + } stmember_v3; + + struct + { + short int id; + short int count; + short int mlist; + struct p_string p_name; + } method_v1; + + struct + { + short int id; + short int count; + unsigned int mlist; + struct p_string p_name; + } method_v2; + + struct + { + short int id; + short int count; + unsigned int mlist; + char name[1]; + } method_v3; + + struct + { + short int id; + short int type; + struct p_string p_name; + } nesttype_v1; + + struct + { + short int id; + short int _pad0; + unsigned int type; + struct p_string p_name; + } nesttype_v2; + + struct + { + short int id; + short int _pad0; + unsigned int type; + char name[1]; + } nesttype_v3; + + struct + { + short int id; + short int type; + } vfunctab_v1; + + struct + { + short int id; + short int _pad0; + unsigned int type; + } vfunctab_v2; + + struct + { + short int id; + short int type; + } friendcls_v1; + + struct + { + short int id; + short int _pad0; + unsigned int type; + } friendcls_v2; + + struct + { + short int id; + short int attribute; + short int type; + struct p_string p_name; + } onemethod_v1; + + struct + { + short int id; + short int attribute; + unsigned int type; + struct p_string p_name; + } onemethod_v2; + + struct + { + short int id; + short int attribute; + unsigned int type; + char name[1]; + } onemethod_v3; + + struct + { + short int id; + short int attribute; + short int type; + unsigned int vtab_offset; + struct p_string p_name; + } onemethod_virt_v1; + + struct + { + short int id; + short int attribute; + unsigned int type; + unsigned int vtab_offset; + struct p_string p_name; + } onemethod_virt_v2; + + struct + { + short int id; + short int attribute; + unsigned int type; + unsigned int vtab_offset; + char name[1]; + } onemethod_virt_v3; + + struct + { + short int id; + short int type; + unsigned int offset; + } vfuncoff_v1; + + struct + { + short int id; + short int _pad0; + unsigned int type; + unsigned int offset; + } vfuncoff_v2; + + struct + { + short int id; + short int attribute; + short int type; + struct p_string p_name; + } nesttypeex_v1; + + struct + { + short int id; + short int attribute; + unsigned int type; + struct p_string p_name; + } nesttypeex_v2; + + struct + { + short int id; + short int attribute; + unsigned int type; + struct p_string p_name; + } membermodify_v2; + + struct + { + short int id; + short int ref; + } index_v1; + + struct + { + short int id; + short int unk; + unsigned int ref; + } index_v2; +}; + + +/* + * This covers the basic datatypes that VC++ seems to be using these days. + * 32 bit mode only. There are additional numbers for the pointers in 16 + * bit mode. There are many other types listed in the documents, but these + * are apparently not used by the compiler, or represent pointer types + * that are not used. + * + * Official MS documentation says that type (< 0x4000, so 12 bits) is made of: + * +----------+------+------+----------+------+ + * | 11 | 10-8 | 7-4 | 3 | 2-0 | + * +----------+------+------+----------+------+ + * | reserved | mode | type | reserved | size | + * +----------+------+------+----------+------+ + * In recent PDB files, type 8 exists, and is seen as an HRESULT... So we've + * added this basic type... as if bit 3 had been integrated into the size field + */ + +/* the type number of a built-in type is a 16-bit value specified in the following format: + bit # | 11 | 10-8 | 7-4 | 3 | 2-0 | + field | reserved | mode | type | reserved | size | + + where + is one of the following types: + 0x00 Special + 0x01 Signed integral value + 0x02 Unsigned integral value + 0x03 Boolean + 0x04 Real + 0x05 Complex + 0x06 Special2 + 0x07 Real int value + 0x08 Reserved + 0x09 Reserved + 0x0a Reserved + 0x0b Reserved + 0x0c Reserved + 0x0d Reserved + 0x0e Reserved + 0x0f Reserved for debugger expression evaluator + + is an enumerated value for each of the types. + Type = special + 0x00 No type + 0x01 Absolute symbol + 0x02 Segment + 0x03 Void + 0x04 Basic 8-byte currency value + 0x05 Near Basic string + 0x06 Far Basic string + 0x07 Untranslated type from previous Microsoft symbol formats + Type = signed/unsigned integral and Boolean values + 0x00 1 byte + 0x01 2 byte + 0x02 4 byte + 0x03 8 byte + 0x04 Reserved + 0x05 Reserved + 0x06 Reserved + 0x07 Reserved + Type = real and complex + 0x00 32 bit + 0x01 64 bit + 0x02 80 bit + 0x03 128 bit + 0x04 48 bit + 0x05 Reserved + 0x06 Reserved + 0x07 Reserved + Type = special2 + 0x00 Bit + 0x01 Pascal CHAR + Type = Real int + 0x00 Char + 0x01 Wide character + 0x02 2-byte signed integer + 0x03 2-byte unsigned integer + 0x04 4-byte signed integer + 0x05 4-byte unsigned integer + 0x06 8-byte signed integer + 0x07 8-byte unsigned integer + + is the pointer mode: + 0x00 Direct; not a pointer + 0x01 Near pointer + 0x02 Far pointer + 0x03 Huge pointer + 0x04 32-bit near pointer + 0x05 32-bit far pointer + 0x06 64-bit near pointer + 0x07 Reserved +*/ + +/* basic types */ +#define T_NOTYPE 0x0000 /* Notype */ +#define T_ABS 0x0001 /* Abs */ +#define T_SEGMENT 0x0002 /* segment type */ +#define T_VOID 0x0003 /* Void */ +#define T_CURRENCY 0x0004 /* basic 8-byte currency value */ +#define T_NBASICSTR 0x0005 /* near basic string */ +#define T_FBASICSTR 0x0006 /* far basic string */ +#define T_NOTTRANS 0x0007 /* untranslated type record from MS symbol format */ +#define T_HRESULT 0x0008 /* HRESULT - or error code ??? */ +#define T_CHAR 0x0010 /* signed char */ +#define T_SHORT 0x0011 /* short */ +#define T_LONG 0x0012 /* long */ +#define T_QUAD 0x0013 /* long long */ +#define T_UCHAR 0x0020 /* unsigned char */ +#define T_USHORT 0x0021 /* unsigned short */ +#define T_ULONG 0x0022 /* unsigned long */ +#define T_UQUAD 0x0023 /* unsigned long long */ +#define T_BOOL08 0x0030 /* 8-bit boolean */ +#define T_BOOL16 0x0031 /* 16-bit boolean */ +#define T_BOOL32 0x0032 /* 32-bit boolean */ +#define T_BOOL64 0x0033 /* 64-bit boolean */ +#define T_REAL32 0x0040 /* float */ +#define T_REAL64 0x0041 /* double */ +#define T_REAL80 0x0042 /* 80-bit real */ +#define T_REAL128 0x0043 /* 128-bit real */ +#define T_REAL48 0x0044 /* 48-bit real */ +#define T_CPLX32 0x0050 /* 32-bit complex number */ +#define T_CPLX64 0x0051 /* 64-bit complex number */ +#define T_CPLX80 0x0052 /* 80-bit complex number */ +#define T_CPLX128 0x0053 /* 128-bit complex number */ +#define T_BIT 0x0060 /* bit */ +#define T_PASCHAR 0x0061 /* pascal CHAR */ +#define T_RCHAR 0x0070 /* real char */ +#define T_WCHAR 0x0071 /* wide char */ +#define T_INT2 0x0072 /* real 16-bit signed int */ +#define T_UINT2 0x0073 /* real 16-bit unsigned int */ +#define T_INT4 0x0074 /* int */ +#define T_UINT4 0x0075 /* unsigned int */ +#define T_INT8 0x0076 /* 64-bit signed int */ +#define T_UINT8 0x0077 /* 64-bit unsigned int */ + + +/* near pointers to basic types */ +#define T_PVOID 0x0103 /* near pointer to void */ +#define T_PCHAR 0x0110 /* Near pointer to 8-bit signed */ +#define T_PSHORT 0x0111 /* Near pointer to 16-bit signed */ +#define T_PLONG 0x0112 /* Near pointer to 32-bit signed */ +#define T_PQUAD 0x0113 /* Near pointer to 64-bit signed */ +#define T_PUCHAR 0x0120 /* Near pointer to 8-bit unsigned */ +#define T_PUSHORT 0x0121 /* Near pointer to 16-bit unsigned */ +#define T_PULONG 0x0122 /* Near pointer to 32-bit unsigned */ +#define T_PUQUAD 0x0123 /* Near pointer to 64-bit unsigned */ +#define T_PBOOL08 0x0130 /* Near pointer to 8-bit Boolean */ +#define T_PBOOL16 0x0131 /* Near pointer to 16-bit Boolean */ +#define T_PBOOL32 0x0132 /* Near pointer to 32-bit Boolean */ +#define T_PBOOL64 0x0133 /* Near pointer to 64-bit Boolean */ +#define T_PREAL32 0x0140 /* Near pointer to 32-bit real */ +#define T_PREAL64 0x0141 /* Near pointer to 64-bit real */ +#define T_PREAL80 0x0142 /* Near pointer to 80-bit real */ +#define T_PREAL128 0x0143 /* Near pointer to 128-bit real */ +#define T_PREAL48 0x0144 /* Near pointer to 48-bit real */ +#define T_PCPLX32 0x0150 /* Near pointer to 32-bit complex */ +#define T_PCPLX64 0x0151 /* Near pointer to 64-bit complex */ +#define T_PCPLX80 0x0152 /* Near pointer to 80-bit complex */ +#define T_PCPLX128 0x0153 /* Near pointer to 128-bit complex */ +#define T_PRCHAR 0x0170 /* Near pointer to a real char */ +#define T_PWCHAR 0x0171 /* Near pointer to a wide char */ +#define T_PINT2 0x0172 /* Near pointer to 16-bit signed int */ +#define T_PUINT2 0x0173 /* Near pointer to 16-bit unsigned int */ +#define T_PINT4 0x0174 /* Near pointer to 32-bit signed int */ +#define T_PUINT4 0x0175 /* Near pointer to 32-bit unsigned int */ +#define T_PINT8 0x0176 /* Near pointer to 64-bit signed int */ +#define T_PUINT8 0x0177 /* Near pointer to 64-bit unsigned int */ + + +/* far pointers to basic types */ +#define T_PFVOID 0x0203 /* Far pointer to void */ +#define T_PFCHAR 0x0210 /* Far pointer to 8-bit signed */ +#define T_PFSHORT 0x0211 /* Far pointer to 16-bit signed */ +#define T_PFLONG 0x0212 /* Far pointer to 32-bit signed */ +#define T_PFQUAD 0x0213 /* Far pointer to 64-bit signed */ +#define T_PFUCHAR 0x0220 /* Far pointer to 8-bit unsigned */ +#define T_PFUSHORT 0x0221 /* Far pointer to 16-bit unsigned */ +#define T_PFULONG 0x0222 /* Far pointer to 32-bit unsigned */ +#define T_PFUQUAD 0x0223 /* Far pointer to 64-bit unsigned */ +#define T_PFBOOL08 0x0230 /* Far pointer to 8-bit Boolean */ +#define T_PFBOOL16 0x0231 /* Far pointer to 16-bit Boolean */ +#define T_PFBOOL32 0x0232 /* Far pointer to 32-bit Boolean */ +#define T_PFBOOL64 0x0233 /* Far pointer to 64-bit Boolean */ +#define T_PFREAL32 0x0240 /* Far pointer to 32-bit real */ +#define T_PFREAL64 0x0241 /* Far pointer to 64-bit real */ +#define T_PFREAL80 0x0242 /* Far pointer to 80-bit real */ +#define T_PFREAL128 0x0243 /* Far pointer to 128-bit real */ +#define T_PFREAL48 0x0244 /* Far pointer to 48-bit real */ +#define T_PFCPLX32 0x0250 /* Far pointer to 32-bit complex */ +#define T_PFCPLX64 0x0251 /* Far pointer to 64-bit complex */ +#define T_PFCPLX80 0x0252 /* Far pointer to 80-bit complex */ +#define T_PFCPLX128 0x0253 /* Far pointer to 128-bit complex */ +#define T_PFRCHAR 0x0270 /* Far pointer to a real char */ +#define T_PFWCHAR 0x0271 /* Far pointer to a wide char */ +#define T_PFINT2 0x0272 /* Far pointer to 16-bit signed int */ +#define T_PFUINT2 0x0273 /* Far pointer to 16-bit unsigned int */ +#define T_PFINT4 0x0274 /* Far pointer to 32-bit signed int */ +#define T_PFUINT4 0x0275 /* Far pointer to 32-bit unsigned int */ +#define T_PFINT8 0x0276 /* Far pointer to 64-bit signed int */ +#define T_PFUINT8 0x0277 /* Far pointer to 64-bit unsigned int */ + + +/* huge pointers to basic types */ +#define T_PHVOID 0x0303 /* Huge pointer to void */ +#define T_PHCHAR 0x0310 /* Huge pointer to 8-bit signed */ +#define T_PHSHORT 0x0311 /* Huge pointer to 16-bit signed */ +#define T_PHLONG 0x0312 /* Huge pointer to 32-bit signed */ +#define T_PHQUAD 0x0313 /* Huge pointer to 64-bit signed */ +#define T_PHUCHAR 0x0320 /* Huge pointer to 8-bit unsigned */ +#define T_PHUSHORT 0x0321 /* Huge pointer to 16-bit unsigned */ +#define T_PHULONG 0x0322 /* Huge pointer to 32-bit unsigned */ +#define T_PHUQUAD 0x0323 /* Huge pointer to 64-bit unsigned */ +#define T_PHBOOL08 0x0330 /* Huge pointer to 8-bit Boolean */ +#define T_PHBOOL16 0x0331 /* Huge pointer to 16-bit Boolean */ +#define T_PHBOOL32 0x0332 /* Huge pointer to 32-bit Boolean */ +#define T_PHBOOL64 0x0333 /* Huge pointer to 64-bit Boolean */ +#define T_PHREAL32 0x0340 /* Huge pointer to 32-bit real */ +#define T_PHREAL64 0x0341 /* Huge pointer to 64-bit real */ +#define T_PHREAL80 0x0342 /* Huge pointer to 80-bit real */ +#define T_PHREAL128 0x0343 /* Huge pointer to 128-bit real */ +#define T_PHREAL48 0x0344 /* Huge pointer to 48-bit real */ +#define T_PHCPLX32 0x0350 /* Huge pointer to 32-bit complex */ +#define T_PHCPLX64 0x0351 /* Huge pointer to 64-bit complex */ +#define T_PHCPLX80 0x0352 /* Huge pointer to 80-bit complex */ +#define T_PHCPLX128 0x0353 /* Huge pointer to 128-bit real */ +#define T_PHRCHAR 0x0370 /* Huge pointer to a real char */ +#define T_PHWCHAR 0x0371 /* Huge pointer to a wide char */ +#define T_PHINT2 0x0372 /* Huge pointer to 16-bit signed int */ +#define T_PHUINT2 0x0373 /* Huge pointer to 16-bit unsigned int */ +#define T_PHINT4 0x0374 /* Huge pointer to 32-bit signed int */ +#define T_PHUINT4 0x0375 /* Huge pointer to 32-bit unsigned int */ +#define T_PHINT8 0x0376 /* Huge pointer to 64-bit signed int */ +#define T_PHUINT8 0x0377 /* Huge pointer to 64-bit unsigned int */ + + +/* 32-bit near pointers to basic types */ +#define T_32PVOID 0x0403 /* 32-bit near pointer to void */ +#define T_32PHRESULT 0x0408 /* 16:32 near pointer to HRESULT - or error code ??? */ +#define T_32PCHAR 0x0410 /* 16:32 near pointer to 8-bit signed */ +#define T_32PSHORT 0x0411 /* 16:32 near pointer to 16-bit signed */ +#define T_32PLONG 0x0412 /* 16:32 near pointer to 32-bit signed */ +#define T_32PQUAD 0x0413 /* 16:32 near pointer to 64-bit signed */ +#define T_32PUCHAR 0x0420 /* 16:32 near pointer to 8-bit unsigned */ +#define T_32PUSHORT 0x0421 /* 16:32 near pointer to 16-bit unsigned */ +#define T_32PULONG 0x0422 /* 16:32 near pointer to 32-bit unsigned */ +#define T_32PUQUAD 0x0423 /* 16:32 near pointer to 64-bit unsigned */ +#define T_32PBOOL08 0x0430 /* 16:32 near pointer to 8-bit Boolean */ +#define T_32PBOOL16 0x0431 /* 16:32 near pointer to 16-bit Boolean */ +#define T_32PBOOL32 0x0432 /* 16:32 near pointer to 32-bit Boolean */ +#define T_32PBOOL64 0x0433 /* 16:32 near pointer to 64-bit Boolean */ +#define T_32PREAL32 0x0440 /* 16:32 near pointer to 32-bit real */ +#define T_32PREAL64 0x0441 /* 16:32 near pointer to 64-bit real */ +#define T_32PREAL80 0x0442 /* 16:32 near pointer to 80-bit real */ +#define T_32PREAL128 0x0443 /* 16:32 near pointer to 128-bit real */ +#define T_32PREAL48 0x0444 /* 16:32 near pointer to 48-bit real */ +#define T_32PCPLX32 0x0450 /* 16:32 near pointer to 32-bit complex */ +#define T_32PCPLX64 0x0451 /* 16:32 near pointer to 64-bit complex */ +#define T_32PCPLX80 0x0452 /* 16:32 near pointer to 80-bit complex */ +#define T_32PCPLX128 0x0453 /* 16:32 near pointer to 128-bit complex */ +#define T_32PRCHAR 0x0470 /* 16:32 near pointer to a real char */ +#define T_32PWCHAR 0x0471 /* 16:32 near pointer to a wide char */ +#define T_32PINT2 0x0472 /* 16:32 near pointer to 16-bit signed int */ +#define T_32PUINT2 0x0473 /* 16:32 near pointer to 16-bit unsigned int */ +#define T_32PINT4 0x0474 /* 16:32 near pointer to 32-bit signed int */ +#define T_32PUINT4 0x0475 /* 16:32 near pointer to 32-bit unsigned int */ +#define T_32PINT8 0x0476 /* 16:32 near pointer to 64-bit signed int */ +#define T_32PUINT8 0x0477 /* 16:32 near pointer to 64-bit unsigned int */ + + +/* 32-bit far pointers to basic types */ +#define T_32PFVOID 0x0503 /* 32-bit far pointer to void */ +#define T_32PFHRESULT 0x0508 /* 16:32 far pointer to HRESULT - or error code ??? */ +#define T_32PFCHAR 0x0510 /* 16:32 far pointer to 8-bit signed */ +#define T_32PFSHORT 0x0511 /* 16:32 far pointer to 16-bit signed */ +#define T_32PFLONG 0x0512 /* 16:32 far pointer to 32-bit signed */ +#define T_32PFQUAD 0x0513 /* 16:32 far pointer to 64-bit signed */ +#define T_32PFUCHAR 0x0520 /* 16:32 far pointer to 8-bit unsigned */ +#define T_32PFUSHORT 0x0521 /* 16:32 far pointer to 16-bit unsigned */ +#define T_32PFULONG 0x0522 /* 16:32 far pointer to 32-bit unsigned */ +#define T_32PFUQUAD 0x0523 /* 16:32 far pointer to 64-bit unsigned */ +#define T_32PFBOOL08 0x0530 /* 16:32 far pointer to 8-bit Boolean */ +#define T_32PFBOOL16 0x0531 /* 16:32 far pointer to 16-bit Boolean */ +#define T_32PFBOOL32 0x0532 /* 16:32 far pointer to 32-bit Boolean */ +#define T_32PFBOOL64 0x0533 /* 16:32 far pointer to 64-bit Boolean */ +#define T_32PFREAL32 0x0540 /* 16:32 far pointer to 32-bit real */ +#define T_32PFREAL64 0x0541 /* 16:32 far pointer to 64-bit real */ +#define T_32PFREAL80 0x0542 /* 16:32 far pointer to 80-bit real */ +#define T_32PFREAL128 0x0543 /* 16:32 far pointer to 128-bit real */ +#define T_32PFREAL48 0x0544 /* 16:32 far pointer to 48-bit real */ +#define T_32PFCPLX32 0x0550 /* 16:32 far pointer to 32-bit complex */ +#define T_32PFCPLX64 0x0551 /* 16:32 far pointer to 64-bit complex */ +#define T_32PFCPLX80 0x0552 /* 16:32 far pointer to 80-bit complex */ +#define T_32PFCPLX128 0x0553 /* 16:32 far pointer to 128-bit complex */ +#define T_32PFRCHAR 0x0570 /* 16:32 far pointer to a real char */ +#define T_32PFWCHAR 0x0571 /* 16:32 far pointer to a wide char */ +#define T_32PFINT2 0x0572 /* 16:32 far pointer to 16-bit signed int */ +#define T_32PFUINT2 0x0573 /* 16:32 far pointer to 16-bit unsigned int */ +#define T_32PFINT4 0x0574 /* 16:32 far pointer to 32-bit signed int */ +#define T_32PFUINT4 0x0575 /* 16:32 far pointer to 32-bit unsigned int */ +#define T_32PFINT8 0x0576 /* 16:32 far pointer to 64-bit signed int */ +#define T_32PFUINT8 0x0577 /* 16:32 far pointer to 64-bit unsigned int */ + +/* 64-bit near pointers to basic types */ +#define T_64PVOID 0x0603 /* 64-bit near pointer to void */ +#define T_64PHRESULT 0x0608 /* 64 near pointer to HRESULT - or error code ??? */ +#define T_64PCHAR 0x0610 /* 64 near pointer to 8-bit signed */ +#define T_64PSHORT 0x0611 /* 64 near pointer to 16-bit signed */ +#define T_64PLONG 0x0612 /* 64 near pointer to 32-bit signed */ +#define T_64PQUAD 0x0613 /* 64 near pointer to 64-bit signed */ +#define T_64PUCHAR 0x0620 /* 64 near pointer to 8-bit unsigned */ +#define T_64PUSHORT 0x0621 /* 64 near pointer to 16-bit unsigned */ +#define T_64PULONG 0x0622 /* 64 near pointer to 32-bit unsigned */ +#define T_64PUQUAD 0x0623 /* 64 near pointer to 64-bit unsigned */ +#define T_64PBOOL08 0x0630 /* 64 near pointer to 8-bit Boolean */ +#define T_64PBOOL16 0x0631 /* 64 near pointer to 16-bit Boolean */ +#define T_64PBOOL32 0x0632 /* 64 near pointer to 32-bit Boolean */ +#define T_64PBOOL64 0x0633 /* 64 near pointer to 64-bit Boolean */ +#define T_64PREAL32 0x0640 /* 64 near pointer to 32-bit real */ +#define T_64PREAL64 0x0641 /* 64 near pointer to 64-bit real */ +#define T_64PREAL80 0x0642 /* 64 near pointer to 80-bit real */ +#define T_64PREAL128 0x0643 /* 64 near pointer to 128-bit real */ +#define T_64PREAL48 0x0644 /* 64 near pointer to 48-bit real */ +#define T_64PCPLX32 0x0650 /* 64 near pointer to 32-bit complex */ +#define T_64PCPLX64 0x0651 /* 64 near pointer to 64-bit complex */ +#define T_64PCPLX80 0x0652 /* 64 near pointer to 80-bit complex */ +#define T_64PCPLX128 0x0653 /* 64 near pointer to 128-bit complex */ +#define T_64PRCHAR 0x0670 /* 64 near pointer to a real char */ +#define T_64PWCHAR 0x0671 /* 64 near pointer to a wide char */ +#define T_64PINT2 0x0672 /* 64 near pointer to 16-bit signed int */ +#define T_64PUINT2 0x0673 /* 64 near pointer to 16-bit unsigned int */ +#define T_64PINT4 0x0674 /* 64 near pointer to 32-bit signed int */ +#define T_64PUINT4 0x0675 /* 64 near pointer to 32-bit unsigned int */ +#define T_64PINT8 0x0676 /* 64 near pointer to 64-bit signed int */ +#define T_64PUINT8 0x0677 /* 64 near pointer to 64-bit unsigned int */ + +/* counts, bit masks, and shift values needed to access various parts of the built-in type numbers */ +#define T_MAXPREDEFINEDTYPE 0x0580 /* maximum type index for all built-in types */ +#define T_MAXBASICTYPE 0x0080 /* maximum type index all non-pointer built-in types */ +#define T_BASICTYPE_MASK 0x00ff /* mask of bits that can potentially identify a non-pointer basic type */ +#define T_BASICTYPE_SHIFT 8 /* shift count to push out the basic type bits from a type number */ +#define T_MODE_MASK 0x0700 /* type mode mask (ptr/non-ptr) */ +#define T_SIZE_MASK 0x0007 /* type size mask (depends on 'type' value) */ +#define T_TYPE_MASK 0x00f0 /* type type mask (data treatment mode) */ + +/* bit patterns for the portion of a built-in type number */ +#define T_NEARPTR_BITS 0x0100 +#define T_FARPTR_BITS 0x0200 +#define T_HUGEPTR_BITS 0x0300 +#define T_NEAR32PTR_BITS 0x0400 +#define T_FAR32PTR_BITS 0x0500 +#define T_NEAR64PTR_BITS 0x0600 + +#define LF_MODIFIER_V1 0x0001 +#define LF_POINTER_V1 0x0002 +#define LF_ARRAY_V1 0x0003 +#define LF_CLASS_V1 0x0004 +#define LF_STRUCTURE_V1 0x0005 +#define LF_UNION_V1 0x0006 +#define LF_ENUM_V1 0x0007 +#define LF_PROCEDURE_V1 0x0008 +#define LF_MFUNCTION_V1 0x0009 +#define LF_VTSHAPE_V1 0x000a +#define LF_COBOL0_V1 0x000b +#define LF_COBOL1_V1 0x000c +#define LF_BARRAY_V1 0x000d +#define LF_LABEL_V1 0x000e +#define LF_NULL_V1 0x000f +#define LF_NOTTRAN_V1 0x0010 +#define LF_DIMARRAY_V1 0x0011 +#define LF_VFTPATH_V1 0x0012 +#define LF_PRECOMP_V1 0x0013 +#define LF_ENDPRECOMP_V1 0x0014 +#define LF_OEM_V1 0x0015 +#define LF_TYPESERVER_V1 0x0016 + +#define LF_MODIFIER_V2 0x1001 /* variants with new 32-bit type indices (V2) */ +#define LF_POINTER_V2 0x1002 +#define LF_ARRAY_V2 0x1003 +#define LF_CLASS_V2 0x1004 +#define LF_STRUCTURE_V2 0x1005 +#define LF_UNION_V2 0x1006 +#define LF_ENUM_V2 0x1007 +#define LF_PROCEDURE_V2 0x1008 +#define LF_MFUNCTION_V2 0x1009 +#define LF_COBOL0_V2 0x100a +#define LF_BARRAY_V2 0x100b +#define LF_DIMARRAY_V2 0x100c +#define LF_VFTPATH_V2 0x100d +#define LF_PRECOMP_V2 0x100e +#define LF_OEM_V2 0x100f + +#define LF_SKIP_V1 0x0200 +#define LF_ARGLIST_V1 0x0201 +#define LF_DEFARG_V1 0x0202 +#define LF_LIST_V1 0x0203 +#define LF_FIELDLIST_V1 0x0204 +#define LF_DERIVED_V1 0x0205 +#define LF_BITFIELD_V1 0x0206 +#define LF_METHODLIST_V1 0x0207 +#define LF_DIMCONU_V1 0x0208 +#define LF_DIMCONLU_V1 0x0209 +#define LF_DIMVARU_V1 0x020a +#define LF_DIMVARLU_V1 0x020b +#define LF_REFSYM_V1 0x020c + +#define LF_SKIP_V2 0x1200 /* variants with new 32-bit type indices (V2) */ +#define LF_ARGLIST_V2 0x1201 +#define LF_DEFARG_V2 0x1202 +#define LF_FIELDLIST_V2 0x1203 +#define LF_DERIVED_V2 0x1204 +#define LF_BITFIELD_V2 0x1205 +#define LF_METHODLIST_V2 0x1206 +#define LF_DIMCONU_V2 0x1207 +#define LF_DIMCONLU_V2 0x1208 +#define LF_DIMVARU_V2 0x1209 +#define LF_DIMVARLU_V2 0x120a + +/* Field lists */ +#define LF_BCLASS_V1 0x0400 +#define LF_VBCLASS_V1 0x0401 +#define LF_IVBCLASS_V1 0x0402 +#define LF_ENUMERATE_V1 0x0403 +#define LF_FRIENDFCN_V1 0x0404 +#define LF_INDEX_V1 0x0405 +#define LF_MEMBER_V1 0x0406 +#define LF_STMEMBER_V1 0x0407 +#define LF_METHOD_V1 0x0408 +#define LF_NESTTYPE_V1 0x0409 +#define LF_VFUNCTAB_V1 0x040a +#define LF_FRIENDCLS_V1 0x040b +#define LF_ONEMETHOD_V1 0x040c +#define LF_VFUNCOFF_V1 0x040d +#define LF_NESTTYPEEX_V1 0x040e +#define LF_MEMBERMODIFY_V1 0x040f + +#define LF_BCLASS_V2 0x1400 /* variants with new 32-bit type indices (V2) */ +#define LF_VBCLASS_V2 0x1401 +#define LF_IVBCLASS_V2 0x1402 +#define LF_FRIENDFCN_V2 0x1403 +#define LF_INDEX_V2 0x1404 +#define LF_MEMBER_V2 0x1405 +#define LF_STMEMBER_V2 0x1406 +#define LF_METHOD_V2 0x1407 +#define LF_NESTTYPE_V2 0x1408 +#define LF_VFUNCTAB_V2 0x1409 +#define LF_FRIENDCLS_V2 0x140a +#define LF_ONEMETHOD_V2 0x140b +#define LF_VFUNCOFF_V2 0x140c +#define LF_NESTTYPEEX_V2 0x140d + +#define LF_ENUMERATE_V3 0x1502 +#define LF_ARRAY_V3 0x1503 +#define LF_CLASS_V3 0x1504 +#define LF_STRUCTURE_V3 0x1505 +#define LF_UNION_V3 0x1506 +#define LF_ENUM_V3 0x1507 +#define LF_MEMBER_V3 0x150d +#define LF_STMEMBER_V3 0x150e +#define LF_METHOD_V3 0x150f +#define LF_NESTTYPE_V3 0x1510 +#define LF_ONEMETHOD_V3 0x1511 + +#define LF_NUMERIC 0x8000 /* numeric leaf types */ +#define LF_CHAR 0x8000 +#define LF_SHORT 0x8001 +#define LF_USHORT 0x8002 +#define LF_LONG 0x8003 +#define LF_ULONG 0x8004 +#define LF_REAL32 0x8005 +#define LF_REAL64 0x8006 +#define LF_REAL80 0x8007 +#define LF_REAL128 0x8008 +#define LF_QUADWORD 0x8009 +#define LF_UQUADWORD 0x800a +#define LF_REAL48 0x800b +#define LF_COMPLEX32 0x800c +#define LF_COMPLEX64 0x800d +#define LF_COMPLEX80 0x800e +#define LF_COMPLEX128 0x800f +#define LF_VARSTRING 0x8010 + +/* ======================================== * + * Symbol information + * ======================================== */ + +union codeview_symbol +{ + struct + { + short int len; + short int id; + } generic; + + struct + { + short int len; + short int id; + unsigned int offset; + unsigned short segment; + unsigned short symtype; + struct p_string p_name; + } data_v1; + + struct + { + short int len; + short int id; + unsigned int symtype; + unsigned int offset; + unsigned short segment; + struct p_string p_name; + } data_v2; + + struct + { + short int len; + short int id; + unsigned int symtype; + unsigned int offset; + unsigned short segment; + char name[1]; + } data_v3; + + struct + { + short int len; + short int id; + unsigned int pparent; + unsigned int pend; + unsigned int next; + unsigned int offset; + unsigned short segment; + unsigned short thunk_len; + unsigned char thtype; + struct p_string p_name; + } thunk_v1; + + struct + { + short int len; + short int id; + unsigned int pparent; + unsigned int pend; + unsigned int next; + unsigned int offset; + unsigned short segment; + unsigned short thunk_len; + unsigned char thtype; + char name[1]; + } thunk_v3; + + struct + { + short int len; + short int id; + unsigned int pparent; + unsigned int pend; + unsigned int next; + unsigned int proc_len; + unsigned int debug_start; + unsigned int debug_end; + unsigned int offset; + unsigned short segment; + unsigned short proctype; + unsigned char flags; + struct p_string p_name; + } proc_v1; + + struct + { + short int len; + short int id; + unsigned int pparent; + unsigned int pend; + unsigned int next; + unsigned int proc_len; + unsigned int debug_start; + unsigned int debug_end; + unsigned int proctype; + unsigned int offset; + unsigned short segment; + unsigned char flags; + struct p_string p_name; + } proc_v2; + + struct + { + short int len; + short int id; + unsigned int pparent; + unsigned int pend; + unsigned int next; + unsigned int proc_len; + unsigned int debug_start; + unsigned int debug_end; + unsigned int proctype; + unsigned int offset; + unsigned short segment; + unsigned char flags; + char name[1]; + } proc_v3; + + struct + { + short int len; + short int id; + unsigned int symtype; + unsigned int offset; + unsigned short segment; + struct p_string p_name; + } public_v2; + + struct + { + short int len; + short int id; + unsigned int symtype; + unsigned int offset; + unsigned short segment; + char name[1]; + } public_v3; + + struct + { + short int len; /* Total length of this entry */ + short int id; /* Always S_BPREL_V1 */ + unsigned int offset; /* Stack offset relative to BP */ + unsigned short symtype; + struct p_string p_name; + } stack_v1; + + struct + { + short int len; /* Total length of this entry */ + short int id; /* Always S_BPREL_V2 */ + unsigned int offset; /* Stack offset relative to EBP */ + unsigned int symtype; + struct p_string p_name; + } stack_v2; + + struct + { + short int len; /* Total length of this entry */ + short int id; /* Always S_BPREL_V3 */ + int offset; /* Stack offset relative to BP */ + unsigned int symtype; + char name[1]; + } stack_v3; + + struct + { + short int len; /* Total length of this entry */ + short int id; /* Always S_BPREL_V3 */ + int offset; /* Stack offset relative to BP */ + unsigned int symtype; + unsigned short reg; + char name[1]; + } regrel_v3; + + struct + { + short int len; /* Total length of this entry */ + short int id; /* Always S_REGISTER */ + unsigned short type; + unsigned short reg; + struct p_string p_name; + /* don't handle register tracking */ + } register_v1; + + struct + { + short int len; /* Total length of this entry */ + short int id; /* Always S_REGISTER_V2 */ + unsigned int type; /* check whether type & reg are correct */ + unsigned short reg; + struct p_string p_name; + /* don't handle register tracking */ + } register_v2; + + struct + { + short int len; /* Total length of this entry */ + short int id; /* Always S_REGISTER_V3 */ + unsigned int type; /* check whether type & reg are correct */ + unsigned short reg; + char name[1]; + /* don't handle register tracking */ + } register_v3; + + struct + { + short int len; + short int id; + unsigned int parent; + unsigned int end; + unsigned int length; + unsigned int offset; + unsigned short segment; + struct p_string p_name; + } block_v1; + + struct + { + short int len; + short int id; + unsigned int parent; + unsigned int end; + unsigned int length; + unsigned int offset; + unsigned short segment; + char name[1]; + } block_v3; + + struct + { + short int len; + short int id; + unsigned int offset; + unsigned short segment; + unsigned char flags; + struct p_string p_name; + } label_v1; + + struct + { + short int len; + short int id; + unsigned int offset; + unsigned short segment; + unsigned char flags; + char name[1]; + } label_v3; + + struct + { + short int len; + short int id; + unsigned short type; + unsigned short cvalue; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } constant_v1; + + struct + { + short int len; + short int id; + unsigned type; + unsigned short cvalue; /* numeric leaf */ +#if 0 + struct p_string p_name; +#endif + } constant_v2; + + struct + { + short int len; + short int id; + unsigned type; + unsigned short cvalue; +#if 0 + char name[1]; +#endif + } constant_v3; + + struct + { + short int len; + short int id; + unsigned short type; + struct p_string p_name; + } udt_v1; + + struct + { + short int len; + short int id; + unsigned type; + struct p_string p_name; + } udt_v2; + + struct + { + short int len; + short int id; + unsigned int type; + char name[1]; + } udt_v3; + + struct + { + short int len; + short int id; + char signature[4]; + struct p_string p_name; + } objname_v1; + + struct + { + short int len; + short int id; + unsigned int unknown; + struct p_string p_name; + } compiland_v1; + + struct + { + short int len; + short int id; + unsigned unknown1[4]; + unsigned short unknown2; + struct p_string p_name; + } compiland_v2; + + struct + { + short int len; + short int id; + unsigned int unknown; + char name[1]; + } compiland_v3; + + struct + { + short int len; + short int id; + unsigned int offset; + unsigned short segment; + unsigned short symtype; + struct p_string p_name; + } thread_v1; + + struct + { + short int len; + short int id; + unsigned int symtype; + unsigned int offset; + unsigned short segment; + struct p_string p_name; + } thread_v2; + + struct + { + short int len; + short int id; + unsigned int symtype; + unsigned int offset; + unsigned short segment; + char name[1]; + } thread_v3; + + struct + { + short int len; + short int id; + unsigned int offset; + unsigned short segment; + } ssearch_v1; + + struct + { + short int len; + short int id; + unsigned int offset; + unsigned int unknown; + } security_cookie_v3; + + struct + { + short int len; + short int id; + unsigned int sz_frame; /* size of frame */ + unsigned int unknown2; + unsigned int unknown3; + unsigned int sz_saved_regs; /* size of saved registers from callee */ + unsigned int eh_offset; /* offset for exception handler */ + unsigned short eh_sect; /* section for exception handler */ + unsigned int flags; + } frame_info_v2; + + struct + { + short int len; + short int id; + unsigned int checksum; + unsigned int offset; + unsigned int module; + struct p_string p_name; // not included in len + } procref_v1; + + struct + { + short int len; + short int id; + unsigned short int sizeLocals; // sum of size of locals and arguments + unsigned short int unknown[10]; + unsigned short int info; // hasAlloca,hasSetjmp,hasLongjmp,hasInlAsm,hasEH,inl_specified,hasSEH,naked,hasGsChecks,hasEHa,noStackOrdering,wasInlined,strictGsCheck + // return UDT,instance constructor,instance constructor with virtual base + unsigned int unknown2; + } funcinfo_32; +}; + +#define S_COMPILAND_V1 0x0001 +#define S_REGISTER_V1 0x0002 +#define S_CONSTANT_V1 0x0003 +#define S_UDT_V1 0x0004 +#define S_SSEARCH_V1 0x0005 +#define S_END_V1 0x0006 +#define S_SKIP_V1 0x0007 +#define S_CVRESERVE_V1 0x0008 +#define S_OBJNAME_V1 0x0009 +#define S_ENDARG_V1 0x000a +#define S_COBOLUDT_V1 0x000b +#define S_MANYREG_V1 0x000c +#define S_RETURN_V1 0x000d +#define S_ENTRYTHIS_V1 0x000e + +#define S_BPREL_V1 0x0200 +#define S_LDATA_V1 0x0201 +#define S_GDATA_V1 0x0202 +#define S_PUB_V1 0x0203 +#define S_LPROC_V1 0x0204 +#define S_GPROC_V1 0x0205 +#define S_THUNK_V1 0x0206 +#define S_BLOCK_V1 0x0207 +#define S_WITH_V1 0x0208 +#define S_LABEL_V1 0x0209 +#define S_CEXMODEL_V1 0x020a +#define S_VFTPATH_V1 0x020b +#define S_REGREL_V1 0x020c +#define S_LTHREAD_V1 0x020d +#define S_GTHREAD_V1 0x020e + +#define S_PROCREF_V1 0x0400 +#define S_DATAREF_V1 0x0401 +#define S_ALIGN_V1 0x0402 +#define S_LPROCREF_V1 0x0403 + +#define S_REGISTER_V2 0x1001 /* Variants with new 32-bit type indices */ +#define S_CONSTANT_V2 0x1002 +#define S_UDT_V2 0x1003 +#define S_COBOLUDT_V2 0x1004 +#define S_MANYREG_V2 0x1005 +#define S_BPREL_V2 0x1006 +#define S_LDATA_V2 0x1007 +#define S_GDATA_V2 0x1008 +#define S_PUB_V2 0x1009 +#define S_LPROC_V2 0x100a +#define S_GPROC_V2 0x100b +#define S_VFTTABLE_V2 0x100c +#define S_REGREL_V2 0x100d +#define S_LTHREAD_V2 0x100e +#define S_GTHREAD_V2 0x100f +#define S_FRAMEINFO_V2 0x1012 +#define S_COMPILAND_V2 0x1013 + +#define S_COMPILAND_V3 0x1101 +#define S_THUNK_V3 0x1102 +#define S_BLOCK_V3 0x1103 +#define S_LABEL_V3 0x1105 +#define S_REGISTER_V3 0x1106 +#define S_CONSTANT_V3 0x1107 +#define S_UDT_V3 0x1108 +#define S_BPREL_V3 0x110B +#define S_LDATA_V3 0x110C +#define S_GDATA_V3 0x110D +#define S_PUB_V3 0x110E +#define S_LPROC_V3 0x110F +#define S_GPROC_V3 0x1110 +#define S_REGREL_V3 0x1111 +#define S_LTHREAD_V3 0x1112 +#define S_GTHREAD_V3 0x1113 +#define S_MSTOOL_V3 0x1116 /* compiler command line options and build information */ +#define S_PUB_FUNC1_V3 0x1125 /* didn't get the difference between the two */ +#define S_PUB_FUNC2_V3 0x1127 +#define S_SECTINFO_V3 0x1136 +#define S_SUBSECTINFO_V3 0x1137 +#define S_ENTRYPOINT_V3 0x1138 +#define S_SECUCOOKIE_V3 0x113A +#define S_MSTOOLINFO_V3 0x113C +#define S_MSTOOLENV_V3 0x113D + +/* ======================================== * + * Line number information + * ======================================== */ + +struct codeview_linetab_block +{ + unsigned short seg; + unsigned short num_lines; + unsigned int offsets[1]; /* in fact num_lines */ +/* unsigned short linenos[]; */ +}; + +struct startend +{ + unsigned int start; + unsigned int end; +}; + +#define LT2_LINES_BLOCK 0x000000f2 +#define LT2_FILES_BLOCK 0x000000f4 + +/* there's a new line tab structure from MS Studio 2005 and after + * it's made of a list of codeview_linetab2 blocks. + * We've only seen (so far) list with a single LT2_FILES_BLOCK and several + * LT2_LINES_BLOCK. The LT2_FILES block has been encountered either as first + * or last block of the list. + * A LT2_FILES contains one or several codeview_linetab2_file:s + */ + +struct codeview_linetab2 +{ + DWORD header; + DWORD size_of_block; +}; + +static inline const struct codeview_linetab2* codeview_linetab2_next_block(const struct codeview_linetab2* lt2) +{ + return (const struct codeview_linetab2*)((const char*)(lt2 + 1) + lt2->size_of_block); +} + +struct codeview_linetab2_file +{ + DWORD offset; /* offset in string table for filename */ + WORD unk; /* always 0x0110... type of following information ??? */ + BYTE md5[16]; /* MD5 signature of file (signature on file's content or name ???) */ + WORD pad0; /* always 0 */ +}; + +struct codeview_lt2blk_files +{ + struct codeview_linetab2 lt2; /* LT2_FILES */ + struct codeview_linetab2_file file[1]; +}; + +struct codeview_lt2blk_lines +{ + struct codeview_linetab2 lt2; /* LT2_LINE_BLOCK */ + DWORD start; /* start address of function with line numbers */ + DWORD seg; /* segment of function with line numbers */ + DWORD size; /* size of function with line numbers */ + DWORD file_offset; /* offset for accessing corresponding codeview_linetab2_file */ + DWORD nlines; /* number of lines in this block */ + DWORD size_lines; /* number of bytes following for line number information */ + struct { + DWORD offset; /* offset (from :) for line number */ + DWORD lineno; /* the line number (OR:ed with 0x80000000 why ???) */ + } l[1]; /* actually array of */ +}; + +/* ======================================== * + * PDB file information + * ======================================== */ + + +struct PDB_FILE +{ + DWORD size; + DWORD unknown; +}; + +struct PDB_JG_HEADER +{ + CHAR ident[40]; + DWORD signature; + DWORD block_size; + WORD free_list; + WORD total_alloc; + struct PDB_FILE toc; + WORD toc_block[1]; +}; + +struct PDB_DS_HEADER +{ + char signature[32]; + DWORD block_size; + DWORD unknown1; + DWORD num_pages; + DWORD toc_size; + DWORD unknown2; + DWORD toc_page; +}; + +struct PDB_JG_TOC +{ + DWORD num_files; + struct PDB_FILE file[1]; +}; + +struct PDB_DS_TOC +{ + DWORD num_files; + DWORD file_size[1]; +}; + +struct PDB_JG_ROOT +{ + DWORD Version; + DWORD TimeDateStamp; + DWORD Age; + DWORD cbNames; + CHAR names[1]; +}; + +struct PDB_DS_ROOT +{ + DWORD Version; + DWORD TimeDateStamp; + DWORD Age; + GUID guid; + DWORD cbNames; + CHAR names[1]; +}; + +typedef struct _PDB_TYPES_OLD +{ + DWORD version; + WORD first_index; + WORD last_index; + DWORD type_size; + WORD file; + WORD pad; +} PDB_TYPES_OLD, *PPDB_TYPES_OLD; + +typedef struct _PDB_TYPES +{ + DWORD version; + DWORD type_offset; + DWORD first_index; + DWORD last_index; + DWORD type_size; + WORD file; + WORD pad; + DWORD hash_size; + DWORD hash_base; + DWORD hash_offset; + DWORD hash_len; + DWORD search_offset; + DWORD search_len; + DWORD unknown_offset; + DWORD unknown_len; +} PDB_TYPES, *PPDB_TYPES; + +typedef struct _PDB_SYMBOL_RANGE +{ + WORD segment; + WORD pad1; + DWORD offset; + DWORD size; + DWORD characteristics; + WORD index; + WORD pad2; +} PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE; + +typedef struct _PDB_SYMBOL_RANGE_EX +{ + WORD segment; + WORD pad1; + DWORD offset; + DWORD size; + DWORD characteristics; + WORD index; + WORD pad2; + DWORD timestamp; + DWORD unknown; +} PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX; + +typedef struct _PDB_SYMBOL_FILE +{ + DWORD unknown1; + PDB_SYMBOL_RANGE range; + WORD flag; + WORD file; + DWORD symbol_size; + DWORD lineno_size; + DWORD unknown2; + DWORD nSrcFiles; + DWORD attribute; + CHAR filename[1]; +} PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE; + +typedef struct _PDB_SYMBOL_FILE_EX +{ + DWORD unknown1; + PDB_SYMBOL_RANGE_EX range; + WORD flag; + WORD file; + DWORD symbol_size; + DWORD lineno_size; + DWORD unknown2; + DWORD nSrcFiles; + DWORD attribute; + DWORD reserved[2]; + CHAR filename[1]; +} PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX; + +typedef struct _PDB_SYMBOL_SOURCE +{ + WORD nModules; + WORD nSrcFiles; + WORD table[1]; +} PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE; + +typedef struct _PDB_SYMBOL_IMPORT +{ + DWORD unknown1; + DWORD unknown2; + DWORD TimeDateStamp; + DWORD Age; + CHAR filename[1]; +} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT; + +typedef struct _PDB_SYMBOLS_OLD +{ + WORD hash1_file; + WORD hash2_file; + WORD gsym_file; + WORD pad; + DWORD module_size; + DWORD offset_size; + DWORD hash_size; + DWORD srcmodule_size; +} PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD; + +typedef struct _PDB_SYMBOLS +{ + DWORD signature; + DWORD version; + DWORD unknown; + DWORD hash1_file; + DWORD hash2_file; + WORD gsym_file; + WORD unknown1; + DWORD module_size; + DWORD offset_size; + DWORD hash_size; + DWORD srcmodule_size; + DWORD pdbimport_size; + DWORD resvd0; + DWORD stream_index_size; + DWORD unknown2_size; + WORD resvd3; + WORD machine; + DWORD resvd4; +} PDB_SYMBOLS, *PPDB_SYMBOLS; + +typedef struct +{ + WORD FPO; + WORD unk0; + WORD unk1; + WORD unk2; + WORD unk3; + WORD segments; +} PDB_STREAM_INDEXES_OLD; + +typedef struct +{ + WORD FPO; + WORD unk0; + WORD unk1; + WORD unk2; + WORD unk3; + WORD segments; + WORD unk4; + WORD unk5; + WORD unk6; + WORD FPO_EXT; + WORD unk7; +} PDB_STREAM_INDEXES; + +typedef struct _PDB_FPO_DATA +{ + DWORD start; + DWORD func_size; + DWORD locals_size; + DWORD params_size; + DWORD maxstack_size; + DWORD str_offset; + WORD prolog_size; + WORD savedregs_size; +#define PDB_FPO_DFL_SEH 0x00000001 +#define PDB_FPO_DFL_EH 0x00000002 +#define PDB_FPO_DFL_IN_BLOCK 0x00000004 + DWORD flags; +} PDB_FPO_DATA; + +#include "poppack.h" + +/* ---------------------------------------------- + * Information used for parsing + * ---------------------------------------------- */ + +typedef struct +{ + DWORD from; + DWORD to; +} OMAP_DATA; + +struct msc_debug_info +{ + struct module* module; + int nsect; + const IMAGE_SECTION_HEADER* sectp; + int nomap; + const OMAP_DATA* omapp; + const BYTE* root; +}; + +/* coff.c */ +extern BOOL coff_process_info(const struct msc_debug_info* msc_dbg); + +/* =================================================== + * The old CodeView stuff (for NB09 and NB11) + * =================================================== */ + +#define sstModule 0x120 +#define sstTypes 0x121 +#define sstPublic 0x122 +#define sstPublicSym 0x123 +#define sstSymbols 0x124 +#define sstAlignSym 0x125 +#define sstSrcLnSeg 0x126 +#define sstSrcModule 0x127 +#define sstLibraries 0x128 +#define sstGlobalSym 0x129 +#define sstGlobalPub 0x12a +#define sstGlobalTypes 0x12b +#define sstMPC 0x12c +#define sstSegMap 0x12d +#define sstSegName 0x12e +#define sstPreComp 0x12f +#define sstFileIndex 0x133 +#define sstStaticSym 0x134 + +/* overall structure information */ +typedef struct OMFSignature +{ + char Signature[4]; + long filepos; +} OMFSignature; + +typedef struct OMFSignatureRSDS +{ + char Signature[4]; + GUID guid; + DWORD age; + CHAR name[1]; +} OMFSignatureRSDS; + +typedef struct _CODEVIEW_PDB_DATA +{ + char Signature[4]; + long filepos; + DWORD timestamp; + DWORD age; + CHAR name[1]; +} CODEVIEW_PDB_DATA, *PCODEVIEW_PDB_DATA; + +typedef struct OMFDirHeader +{ + WORD cbDirHeader; + WORD cbDirEntry; + DWORD cDir; + DWORD lfoNextDir; + DWORD flags; +} OMFDirHeader; + +typedef struct OMFDirEntry +{ + WORD SubSection; + WORD iMod; + DWORD lfo; + DWORD cb; +} OMFDirEntry; + +/* sstModule subsection */ + +typedef struct OMFSegDesc +{ + WORD Seg; + WORD pad; + DWORD Off; + DWORD cbSeg; +} OMFSegDesc; + +typedef struct OMFModule +{ + WORD ovlNumber; + WORD iLib; + WORD cSeg; + char Style[2]; +/* + OMFSegDesc SegInfo[cSeg]; + p_string Name; +*/ +} OMFModule; + +typedef struct OMFGlobalTypes +{ + DWORD flags; + DWORD cTypes; +/* + DWORD offset[cTypes]; + types_record[]; +*/ +} OMFGlobalTypes; + +/* sstGlobalPub section */ + +/* Header for symbol table */ +typedef struct OMFSymHash +{ + unsigned short symhash; + unsigned short addrhash; + unsigned long cbSymbol; + unsigned long cbHSym; + unsigned long cbHAddr; +} OMFSymHash; + +/* sstSegMap section */ + +typedef struct OMFSegMapDesc +{ + unsigned short flags; + unsigned short ovl; + unsigned short group; + unsigned short frame; + unsigned short iSegName; + unsigned short iClassName; + unsigned long offset; + unsigned long cbSeg; +} OMFSegMapDesc; + +typedef struct OMFSegMap +{ + unsigned short cSeg; + unsigned short cSegLog; +/* OMFSegMapDesc rgDesc[0];*/ +} OMFSegMap; + + +/* sstSrcModule section */ + +typedef struct OMFSourceLine +{ + unsigned short Seg; + unsigned short cLnOff; + unsigned long offset[1]; + unsigned short lineNbr[1]; +} OMFSourceLine; + +typedef struct OMFSourceFile +{ + unsigned short cSeg; + unsigned short reserved; + unsigned long baseSrcLn[1]; + unsigned short cFName; + char Name; +} OMFSourceFile; + +typedef struct OMFSourceModule +{ + unsigned short cFile; + unsigned short cSeg; + unsigned long baseSrcFile[1]; +} OMFSourceModule; diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp index a5d0075..d6d0391 100644 --- a/src/readDwarf.cpp +++ b/src/readDwarf.cpp @@ -322,12 +322,12 @@ long decodeLocation(byte* loc, long len, bool push0, int &id, int& size) case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: - id = (op == DW_OP_breg4 ? S_BPREL_XXXX_V3 : op == DW_OP_breg5 ? S_BPREL_V2 : S_REGISTER_V2); + id = (op == DW_OP_breg4 ? S_REGREL_V3 : op == DW_OP_breg5 ? S_BPREL_V2 : S_REGISTER_V2); stack[stackDepth++] = SLEB128(p); break; case DW_OP_bregx: data = LEB128(p); // reg - id = (data == DW_OP_breg4 ? S_BPREL_XXXX_V3 : data == DW_OP_breg5 ? S_BPREL_V2 : S_REGISTER_V2); + id = (data == DW_OP_breg4 ? S_REGREL_V3 : data == DW_OP_breg5 ? S_BPREL_V2 : S_REGISTER_V2); stack[stackDepth++] = SLEB128(p); break; -- cgit v0.12