From b5b9076d2370cb7a5d9fe30c7ffee38e19def0c7 Mon Sep 17 00:00:00 2001 From: sagitario Date: Fri, 12 Mar 2010 11:59:48 +0000 Subject: * names of local function are now demangled * added managed C++ project to integrate cv2pdb with CLR --- CHANGES | 4 + src/cv2pdb.cpp | 3210 ++++++++++++++++++++++----------------------- src/demangle.cpp | 35 +- src/main.cpp | 38 +- src/managed/cv2pdb.vcproj | 237 ++++ src/managed/main.cpp | 89 ++ src/mscvpdb.h | 10 +- src/symutil.cpp | 98 +- test/Makefile | 2 +- test/cvtest.d | 21 +- 10 files changed, 2055 insertions(+), 1689 deletions(-) create mode 100644 src/managed/cv2pdb.vcproj create mode 100644 src/managed/main.cpp diff --git a/CHANGES b/CHANGES index 993adb9..4460394 100644 --- a/CHANGES +++ b/CHANGES @@ -84,3 +84,7 @@ Version history Version 0.12 * added patch to convert binaries produced by Metroworks CodeWarrior + * names of local function are now demangled + * dmd 2.041 fixes long/ulong support (patch http://d.puremagic.com/issues/show_bug.cgi?id=3373 + no longer needed) + * added managed C++ project to integrate cv2pdb with CLR (thanks to Alexander Bothe) diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp index a503eda..c56fa75 100644 --- a/src/cv2pdb.cpp +++ b/src/cv2pdb.cpp @@ -129,11 +129,11 @@ bool CV2PDB::openPDB(const char* pdbname) //printf("PDB::QueryImplementationVersion() = %d\n", pdb->QueryImplementationVersion()); //printf("PDB::QueryPdbImplementationVersion() = %d\n", pdb->QueryPdbImplementationVersion()); - rsds = (OMFSignatureRSDS *) new char[24 + strlen(pdbname) + 1]; // sizeof(OMFSignatureRSDS) without name - memcpy (rsds->Signature, "RSDS", 4); + rsds = (OMFSignatureRSDS *) new char[24 + strlen(pdbname) + 1]; // sizeof(OMFSignatureRSDS) without name + memcpy (rsds->Signature, "RSDS", 4); pdb->QuerySignature2(&rsds->guid); - rsds->unknown = pdb->QueryAge(); - strcpy(rsds->name, pdbname); + rsds->unknown = pdb->QueryAge(); + strcpy(rsds->name, pdbname); int rc = pdb->CreateDBI("", &dbi); if (rc <= 0 || !dbi) @@ -164,29 +164,29 @@ bool CV2PDB::createModules() for (int m = 0; m < countEntries; m++) { OMFDirEntry* entry = img.getCVEntry(m); - if (entry->SubSection == sstModule) - { - OMFModule* module = img.CVP(entry->lfo); - OMFSegDesc* segDesc = img.CVP(entry->lfo + sizeof(OMFModule)); - BYTE* pname = img.CVP(entry->lfo + sizeof(OMFModule) + sizeof(OMFSegDesc) * module->cSeg); - char *name = p2c(pname); - const BYTE* plib = getLibrary (module->iLib); - const char* lib = (!plib || !*plib ? name : p2c(plib, 1)); - - mspdb::Mod* mod; - if (useGlobalMod) - { - mod = globalMod(); - if(!mod) - return false; - } - else - { - if (modules[entry->iMod]) - { - modules[entry->iMod]->Close(); - modules[entry->iMod] = 0; - } + if (entry->SubSection == sstModule) + { + OMFModule* module = img.CVP(entry->lfo); + OMFSegDesc* segDesc = img.CVP(entry->lfo + sizeof(OMFModule)); + BYTE* pname = img.CVP(entry->lfo + sizeof(OMFModule) + sizeof(OMFSegDesc) * module->cSeg); + char *name = p2c(pname); + const BYTE* plib = getLibrary (module->iLib); + const char* lib = (!plib || !*plib ? name : p2c(plib, 1)); + + mspdb::Mod* mod; + if (useGlobalMod) + { + mod = globalMod(); + if(!mod) + return false; + } + else + { + if (modules[entry->iMod]) + { + modules[entry->iMod]->Close(); + modules[entry->iMod] = 0; + } int rc = dbi->OpenMod(name, lib, &modules[entry->iMod]); if (rc <= 0 || !modules[entry->iMod]) return setError("cannot create mod"); @@ -195,16 +195,16 @@ bool CV2PDB::createModules() for (int s = 0; s < module->cSeg; s++) { - int segIndex = segDesc[s].Seg; - int segFlags = 0; - if (segMap && segIndex < segMap->cSeg) - segFlags = segMapDesc[segIndex].flags; + int segIndex = segDesc[s].Seg; + int segFlags = 0; + if (segMap && segIndex < segMap->cSeg) + segFlags = segMapDesc[segIndex].flags; segFlags = 0x60101020; // 0x40401040, 0x60500020; // TODO - int rc = mod->AddSecContrib(segIndex, segDesc[s].Off, segDesc[s].cbSeg, segFlags); - if (rc <= 0) - return setError("cannot add section contribution to module"); + int rc = mod->AddSecContrib(segIndex, segDesc[s].Off, segDesc[s].cbSeg, segFlags); + if (rc <= 0) + return setError("cannot add section contribution to module"); } - } + } } return true; } @@ -247,17 +247,17 @@ bool CV2PDB::initSegMap() OMFDirEntry* entry = img.getCVEntry(m); switch(entry->SubSection) { - case sstSegMap: + case sstSegMap: segMap = img.CVP(entry->lfo); segMapDesc = img.CVP(entry->lfo + sizeof(OMFSegMap)); int maxframe = -1; for (int s = 0; s < segMap->cSeg; s++) { - int rc = dbi->AddSec(segMapDesc[s].frame, segMapDesc[s].flags, segMapDesc[s].offset, segMapDesc[s].cbSeg); - if (rc <= 0) - return setError("cannot add section"); - if (segMapDesc[s].frame > maxframe) - maxframe = segMapDesc[s].frame; + int rc = dbi->AddSec(segMapDesc[s].frame, segMapDesc[s].flags, segMapDesc[s].offset, segMapDesc[s].cbSeg); + if (rc <= 0) + return setError("cannot add section"); + if (segMapDesc[s].frame > maxframe) + maxframe = segMapDesc[s].frame; } segFrame2Index = new int[maxframe + 1]; @@ -270,115 +270,115 @@ bool CV2PDB::initSegMap() return true; } -int CV2PDB::numeric_leaf(int* value, const void* leaf) -{ - unsigned short int type = *(const unsigned short int*) leaf; - leaf = (const unsigned short int*) leaf + 2; - int length = 2; - - *value = 0; - switch (type) - { - case LF_CHAR: - length += 1; - *value = *(const char*)leaf; - break; - - case LF_SHORT: - length += 2; - *value = *(const short*)leaf; - break; - - case LF_USHORT: - length += 2; - *value = *(const unsigned short*)leaf; - break; - - case LF_LONG: - case LF_ULONG: - length += 4; - *value = *(const int*)leaf; - break; - - case LF_COMPLEX64: - case LF_QUADWORD: - case LF_UQUADWORD: - case LF_REAL64: - length += 8; - break; - - case LF_COMPLEX32: - case LF_REAL32: - length += 4; - break; - - case LF_REAL48: - length += 6; - break; - - case LF_COMPLEX80: - case LF_REAL80: - length += 10; - break; - - case LF_COMPLEX128: - case LF_REAL128: - length += 16; - break; - - case LF_VARSTRING: - length += 2 + *(const unsigned short*)leaf; - break; - - default: - if (type < LF_NUMERIC) - *value = type; - else - { - setError("unsupported numeric leaf"); - length = 0; - } - break; - } - return length; -} - -int CV2PDB::copy_leaf(unsigned char* dp, int& dpos, const unsigned char* p, int& pos) -{ - int value; - int leaf_len = numeric_leaf(&value, p + pos); - memcpy(dp + dpos, p + pos, leaf_len); - pos += leaf_len; - dpos += leaf_len; - return leaf_len; -} - -static int copy_p2dsym(unsigned char* dp, int& dpos, const unsigned char* p, int& pos, int maxdlen) -{ - int len = dsym2c(p + pos + 1, p[pos], (char*) dp + dpos, maxdlen - dpos) + 1; - dpos += len; - pos += p[pos] + 1; - return len; -} - -// if dfieldlist == 0, count fields +int CV2PDB::numeric_leaf(int* value, const void* leaf) +{ + unsigned short int type = *(const unsigned short int*) leaf; + leaf = (const unsigned short int*) leaf + 2; + int length = 2; + + *value = 0; + switch (type) + { + case LF_CHAR: + length += 1; + *value = *(const char*)leaf; + break; + + case LF_SHORT: + length += 2; + *value = *(const short*)leaf; + break; + + case LF_USHORT: + length += 2; + *value = *(const unsigned short*)leaf; + break; + + case LF_LONG: + case LF_ULONG: + length += 4; + *value = *(const int*)leaf; + break; + + case LF_COMPLEX64: + case LF_QUADWORD: + case LF_UQUADWORD: + case LF_REAL64: + length += 8; + break; + + case LF_COMPLEX32: + case LF_REAL32: + length += 4; + break; + + case LF_REAL48: + length += 6; + break; + + case LF_COMPLEX80: + case LF_REAL80: + length += 10; + break; + + case LF_COMPLEX128: + case LF_REAL128: + length += 16; + break; + + case LF_VARSTRING: + length += 2 + *(const unsigned short*)leaf; + break; + + default: + if (type < LF_NUMERIC) + *value = type; + else + { + setError("unsupported numeric leaf"); + length = 0; + } + break; + } + return length; +} + +int CV2PDB::copy_leaf(unsigned char* dp, int& dpos, const unsigned char* p, int& pos) +{ + int value; + int leaf_len = numeric_leaf(&value, p + pos); + memcpy(dp + dpos, p + pos, leaf_len); + pos += leaf_len; + dpos += leaf_len; + return leaf_len; +} + +static int copy_p2dsym(unsigned char* dp, int& dpos, const unsigned char* p, int& pos, int maxdlen) +{ + int len = dsym2c(p + pos + 1, p[pos], (char*) dp + dpos, maxdlen - dpos) + 1; + dpos += len; + pos += p[pos] + 1; + return len; +} + +// if dfieldlist == 0, count fields int CV2PDB::addFields(codeview_reftype* dfieldlist, const codeview_reftype* fieldlist, int maxdlen) { int len = fieldlist->fieldlist.len - 2; const unsigned char* p = fieldlist->fieldlist.list; unsigned char* dp = dfieldlist ? dfieldlist->fieldlist.list : 0; int pos = 0, dpos = 0; - int leaf_len, value; + int leaf_len, value; int cntFields = 0; int prev = pos; while (pos < len && !hadError()) { - if (p[pos] >= 0xf1) /* LF_PAD... */ - { - pos += p[pos] & 0x0f; - continue; - } + if (p[pos] >= 0xf1) /* LF_PAD... */ + { + pos += p[pos] & 0x0f; + continue; + } if(pos & 3) { setError("bad field alignment!"); @@ -386,203 +386,203 @@ int CV2PDB::addFields(codeview_reftype* dfieldlist, const codeview_reftype* fiel } prev = pos; - const codeview_fieldtype* fieldtype = (const codeview_fieldtype*)(p + pos); - codeview_fieldtype* dfieldtype = (codeview_fieldtype*)(dp + dpos); + const codeview_fieldtype* fieldtype = (const codeview_fieldtype*)(p + pos); + codeview_fieldtype* dfieldtype = (codeview_fieldtype*)(dp + dpos); int copylen = 0; - switch (fieldtype->generic.id) + switch (fieldtype->common.id) { case LF_ENUMERATE_V1: - if (dp && v3) - { - dfieldtype->enumerate_v3.id = LF_ENUMERATE_V3; - dfieldtype->enumerate_v3.attribute = fieldtype->enumerate_v1.attribute; - pos += sizeof(fieldtype->enumerate_v1) - sizeof(fieldtype->enumerate_v1.value); - dpos += sizeof(fieldtype->enumerate_v3) - sizeof(fieldtype->enumerate_v3.value); - copy_leaf(dp, dpos, p, pos); - copy_p2dsym(dp, dpos, p, pos, maxdlen); - } - else - { - leaf_len = numeric_leaf(&value, &fieldtype->enumerate_v1.value); - copylen = 2 + 2 + leaf_len + p[pos + 4 + leaf_len] + 1; // id,attr,value,name - } + if (dp && v3) + { + dfieldtype->enumerate_v3.id = LF_ENUMERATE_V3; + dfieldtype->enumerate_v3.attribute = fieldtype->enumerate_v1.attribute; + pos += sizeof(fieldtype->enumerate_v1) - sizeof(fieldtype->enumerate_v1.value); + dpos += sizeof(fieldtype->enumerate_v3) - sizeof(fieldtype->enumerate_v3.value); + copy_leaf(dp, dpos, p, pos); + copy_p2dsym(dp, dpos, p, pos, maxdlen); + } + else + { + leaf_len = numeric_leaf(&value, &fieldtype->enumerate_v1.value); + copylen = 2 + 2 + leaf_len + p[pos + 4 + leaf_len] + 1; // id,attr,value,name + } break; case LF_ENUMERATE_V3: - leaf_len = numeric_leaf(&value, &fieldtype->enumerate_v3.value); - copylen = 2 + 2 + leaf_len + strlen((const char*) p + pos + 4 + leaf_len) + 1; // id,attr,value,name + leaf_len = numeric_leaf(&value, &fieldtype->enumerate_v3.value); + copylen = 2 + 2 + leaf_len + strlen((const char*) p + pos + 4 + leaf_len) + 1; // id,attr,value,name + break; + + case LF_MEMBER_V1: + if (dp) + { + dfieldtype->member_v2.id = v3 ? LF_MEMBER_V3 : LF_MEMBER_V2; + dfieldtype->member_v2.attribute = fieldtype->member_v1.attribute; + dfieldtype->member_v2.type = translateType(fieldtype->member_v1.type); + dpos += sizeof(dfieldtype->member_v2.id) + sizeof(dfieldtype->member_v2.attribute) + sizeof(dfieldtype->member_v2.type); + } + pos += sizeof(dfieldtype->member_v1.id) + sizeof(dfieldtype->member_v1.attribute) + sizeof(dfieldtype->member_v1.type); + if (dp && v3) + { + copy_leaf(dp, dpos, p, pos); + copy_p2dsym(dp, dpos, p, pos, maxdlen); + } + else + { + leaf_len = numeric_leaf(&value, &fieldtype->member_v1.offset); + copylen = leaf_len + p[pos + leaf_len] + 1; // value,name + } + break; + + case LF_MEMBER_V2: + leaf_len = numeric_leaf(&value, &fieldtype->member_v1.offset); + copylen = sizeof(dfieldtype->member_v2) - sizeof(dfieldtype->member_v2.offset); + copylen += leaf_len + p[pos + copylen + leaf_len] + 1; // value,name break; - case LF_MEMBER_V1: - if (dp) - { - dfieldtype->member_v2.id = v3 ? LF_MEMBER_V3 : LF_MEMBER_V2; - dfieldtype->member_v2.attribute = fieldtype->member_v1.attribute; - dfieldtype->member_v2.type = translateType(fieldtype->member_v1.type); - dpos += sizeof(dfieldtype->member_v2.id) + sizeof(dfieldtype->member_v2.attribute) + sizeof(dfieldtype->member_v2.type); - } - pos += sizeof(dfieldtype->member_v1.id) + sizeof(dfieldtype->member_v1.attribute) + sizeof(dfieldtype->member_v1.type); - if (dp && v3) - { - copy_leaf(dp, dpos, p, pos); - copy_p2dsym(dp, dpos, p, pos, maxdlen); - } - else - { - leaf_len = numeric_leaf(&value, &fieldtype->member_v1.offset); - copylen = leaf_len + p[pos + leaf_len] + 1; // value,name - } - break; - - case LF_MEMBER_V2: - leaf_len = numeric_leaf(&value, &fieldtype->member_v1.offset); - copylen = sizeof(dfieldtype->member_v2) - sizeof(dfieldtype->member_v2.offset); - copylen += leaf_len + p[pos + copylen + leaf_len] + 1; // value,name - break; - - case LF_MEMBER_V3: - leaf_len = numeric_leaf(&value, &fieldtype->member_v3.offset); - copylen = sizeof(dfieldtype->member_v3) - sizeof(dfieldtype->member_v3.offset); - copylen += leaf_len + strlen((const char*) p + pos + copylen + leaf_len) + 1; // value,name - break; - - case LF_BCLASS_V1: - if (dp) - { - dfieldtype->bclass_v2.id = LF_BCLASS_V2; - dfieldtype->bclass_v2.attribute = fieldtype->bclass_v1.attribute; - dfieldtype->bclass_v2.type = translateType(fieldtype->bclass_v1.type); - } - pos += sizeof(fieldtype->bclass_v1) - sizeof(fieldtype->bclass_v1.offset); -#if 1 - copylen = numeric_leaf(&value, &fieldtype->bclass_v1.offset); - if (dp) - { - dpos += sizeof(dfieldtype->bclass_v2) - sizeof(fieldtype->bclass_v2.offset); + case LF_MEMBER_V3: + leaf_len = numeric_leaf(&value, &fieldtype->member_v3.offset); + copylen = sizeof(dfieldtype->member_v3) - sizeof(dfieldtype->member_v3.offset); + copylen += leaf_len + strlen((const char*) p + pos + copylen + leaf_len) + 1; // value,name + break; + + case LF_BCLASS_V1: + if (dp) + { + dfieldtype->bclass_v2.id = LF_BCLASS_V2; + dfieldtype->bclass_v2.attribute = fieldtype->bclass_v1.attribute; + dfieldtype->bclass_v2.type = translateType(fieldtype->bclass_v1.type); + } + pos += sizeof(fieldtype->bclass_v1) - sizeof(fieldtype->bclass_v1.offset); +#if 1 + copylen = numeric_leaf(&value, &fieldtype->bclass_v1.offset); + if (dp) + { + dpos += sizeof(dfieldtype->bclass_v2) - sizeof(fieldtype->bclass_v2.offset); memcpy (dp + dpos, p + pos, copylen); dpos += copylen; // dp[dpos++] = 0; } pos += copylen; copylen = 0; -#else - dfieldtype->member_v2.id = LF_MEMBER_V2; - dfieldtype->member_v2.attribute = 0; - dfieldtype->member_v2.type = fieldtype->bclass_v1.type; - dfieldtype->member_v2.offset = fieldtype->bclass_v1.offset; - //memcpy (&dfieldtype->member_v2 + 1, "\0", 1); - //dpos += sizeof(dfieldtype->member_v2) + 1; - memcpy (&dfieldtype->member_v2 + 1, "\004base", 5); - dpos += sizeof(dfieldtype->member_v2) + 5; - - pos += numeric_leaf(&value, &fieldtype->bclass_v1.offset); -#endif - break; - - case LF_BCLASS_V2: - leaf_len = numeric_leaf(&value, &fieldtype->bclass_v2.offset); - copylen = sizeof(dfieldtype->bclass_v2) - 2 + leaf_len; - break; +#else + dfieldtype->member_v2.id = LF_MEMBER_V2; + dfieldtype->member_v2.attribute = 0; + dfieldtype->member_v2.type = fieldtype->bclass_v1.type; + dfieldtype->member_v2.offset = fieldtype->bclass_v1.offset; + //memcpy (&dfieldtype->member_v2 + 1, "\0", 1); + //dpos += sizeof(dfieldtype->member_v2) + 1; + memcpy (&dfieldtype->member_v2 + 1, "\004base", 5); + dpos += sizeof(dfieldtype->member_v2) + 5; + + pos += numeric_leaf(&value, &fieldtype->bclass_v1.offset); +#endif + break; + + case LF_BCLASS_V2: + leaf_len = numeric_leaf(&value, &fieldtype->bclass_v2.offset); + copylen = sizeof(dfieldtype->bclass_v2) - 2 + leaf_len; + break; case LF_METHOD_V1: if (dp) { - dfieldtype->method_v2.id = v3 ? LF_METHOD_V3 : LF_METHOD_V2; - dfieldtype->method_v2.count = fieldtype->method_v1.count; - dfieldtype->method_v2.mlist = fieldtype->method_v1.mlist; - dpos += sizeof(dfieldtype->method_v2) - sizeof(dfieldtype->method_v2.p_name); - } - pos += sizeof(dfieldtype->method_v1) - sizeof(dfieldtype->method_v1.p_name); - if (v3 && dp) - copy_p2dsym(dp, dpos, p, pos, maxdlen); - else - copylen = fieldtype->method_v1.p_name.namelen + 1; - break; + dfieldtype->method_v2.id = v3 ? LF_METHOD_V3 : LF_METHOD_V2; + dfieldtype->method_v2.count = fieldtype->method_v1.count; + dfieldtype->method_v2.mlist = fieldtype->method_v1.mlist; + dpos += sizeof(dfieldtype->method_v2) - sizeof(dfieldtype->method_v2.p_name); + } + pos += sizeof(dfieldtype->method_v1) - sizeof(dfieldtype->method_v1.p_name); + if (v3 && dp) + copy_p2dsym(dp, dpos, p, pos, maxdlen); + else + copylen = fieldtype->method_v1.p_name.namelen + 1; + break; case LF_METHOD_V2: - copylen = sizeof(dfieldtype->method_v2) - sizeof(dfieldtype->method_v2.p_name); - copylen += fieldtype->method_v2.p_name.namelen + 1; - break; + copylen = sizeof(dfieldtype->method_v2) - sizeof(dfieldtype->method_v2.p_name); + copylen += fieldtype->method_v2.p_name.namelen + 1; + break; case LF_METHOD_V3: - copylen = sizeof(dfieldtype->method_v3); - copylen += strlen((const char*) p + pos + copylen) + 1; - break; - - case LF_STMEMBER_V1: + copylen = sizeof(dfieldtype->method_v3); + copylen += strlen((const char*) p + pos + copylen) + 1; + break; + + case LF_STMEMBER_V1: if (dp) { - dfieldtype->stmember_v2.id = v3 ? LF_STMEMBER_V3 : LF_STMEMBER_V2; - dfieldtype->stmember_v2.attribute = fieldtype->stmember_v1.attribute; - dfieldtype->stmember_v2.type = translateType(fieldtype->stmember_v1.type); - dpos += sizeof(dfieldtype->stmember_v2) - sizeof(dfieldtype->stmember_v2.p_name); - } - pos += sizeof(dfieldtype->stmember_v1) - sizeof(dfieldtype->stmember_v1.p_name); - if (v3 && dp) - copy_p2dsym(dp, dpos, p, pos, maxdlen); - else - copylen = fieldtype->stmember_v1.p_name.namelen + 1; - break; - - case LF_STMEMBER_V2: - copylen = sizeof(dfieldtype->stmember_v2) - sizeof(dfieldtype->stmember_v2.p_name); - copylen += fieldtype->stmember_v2.p_name.namelen + 1; - break; - - case LF_STMEMBER_V3: - copylen = sizeof(dfieldtype->stmember_v3) - sizeof(dfieldtype->stmember_v3.name); - copylen += strlen(fieldtype->stmember_v3.name) + 1; - break; - - case LF_NESTTYPE_V1: + dfieldtype->stmember_v2.id = v3 ? LF_STMEMBER_V3 : LF_STMEMBER_V2; + dfieldtype->stmember_v2.attribute = fieldtype->stmember_v1.attribute; + dfieldtype->stmember_v2.type = translateType(fieldtype->stmember_v1.type); + dpos += sizeof(dfieldtype->stmember_v2) - sizeof(dfieldtype->stmember_v2.p_name); + } + pos += sizeof(dfieldtype->stmember_v1) - sizeof(dfieldtype->stmember_v1.p_name); + if (v3 && dp) + copy_p2dsym(dp, dpos, p, pos, maxdlen); + else + copylen = fieldtype->stmember_v1.p_name.namelen + 1; + break; + + case LF_STMEMBER_V2: + copylen = sizeof(dfieldtype->stmember_v2) - sizeof(dfieldtype->stmember_v2.p_name); + copylen += fieldtype->stmember_v2.p_name.namelen + 1; + break; + + case LF_STMEMBER_V3: + copylen = sizeof(dfieldtype->stmember_v3) - sizeof(dfieldtype->stmember_v3.name); + copylen += strlen(fieldtype->stmember_v3.name) + 1; + break; + + case LF_NESTTYPE_V1: if (dp) { - dfieldtype->nesttype_v2.id = v3 ? LF_NESTTYPE_V3 : LF_NESTTYPE_V2; - dfieldtype->nesttype_v2.type = translateType(fieldtype->nesttype_v1.type); - dfieldtype->nesttype_v2._pad0 = 0; - dpos += sizeof(dfieldtype->nesttype_v2) - sizeof(dfieldtype->nesttype_v2.p_name); - } - pos += sizeof(dfieldtype->nesttype_v1) - sizeof(dfieldtype->nesttype_v1.p_name); - if (v3 && dp) - copy_p2dsym(dp, dpos, p, pos, maxdlen); - else - copylen = fieldtype->nesttype_v1.p_name.namelen + 1; - break; - - case LF_NESTTYPE_V2: - copylen = sizeof(dfieldtype->nesttype_v2) - sizeof(dfieldtype->nesttype_v2.p_name); - copylen += fieldtype->nesttype_v2.p_name.namelen + 1; - break; - - case LF_NESTTYPE_V3: - copylen = sizeof(dfieldtype->nesttype_v3) - sizeof(dfieldtype->nesttype_v3.name); - copylen += strlen(fieldtype->nesttype_v3.name) + 1; - break; - - case LF_VFUNCTAB_V1: + dfieldtype->nesttype_v2.id = v3 ? LF_NESTTYPE_V3 : LF_NESTTYPE_V2; + dfieldtype->nesttype_v2.type = translateType(fieldtype->nesttype_v1.type); + dfieldtype->nesttype_v2._pad0 = 0; + dpos += sizeof(dfieldtype->nesttype_v2) - sizeof(dfieldtype->nesttype_v2.p_name); + } + pos += sizeof(dfieldtype->nesttype_v1) - sizeof(dfieldtype->nesttype_v1.p_name); + if (v3 && dp) + copy_p2dsym(dp, dpos, p, pos, maxdlen); + else + copylen = fieldtype->nesttype_v1.p_name.namelen + 1; + break; + + case LF_NESTTYPE_V2: + copylen = sizeof(dfieldtype->nesttype_v2) - sizeof(dfieldtype->nesttype_v2.p_name); + copylen += fieldtype->nesttype_v2.p_name.namelen + 1; + break; + + case LF_NESTTYPE_V3: + copylen = sizeof(dfieldtype->nesttype_v3) - sizeof(dfieldtype->nesttype_v3.name); + copylen += strlen(fieldtype->nesttype_v3.name) + 1; + break; + + case LF_VFUNCTAB_V1: if (dp) { - dfieldtype->vfunctab_v2.id = LF_VFUNCTAB_V2; - dfieldtype->vfunctab_v2.type = fieldtype->vfunctab_v1.type; - dfieldtype->vfunctab_v2._pad0 = 0; - dpos += sizeof(dfieldtype->vfunctab_v2); - } - pos += sizeof(fieldtype->vfunctab_v1); - break; - - case LF_VFUNCTAB_V2: - copylen = sizeof(dfieldtype->vfunctab_v2); - break; - - // throw away friend function declarations, there is no v3 replacement and the debugger won't need them - case LF_FRIENDFCN_V1: - pos += sizeof(fieldtype->friendfcn_v1) + fieldtype->friendfcn_v1.p_name.namelen - 1; - continue; - case LF_FRIENDFCN_V2: - copylen = sizeof(fieldtype->friendfcn_v2) + fieldtype->friendfcn_v2.p_name.namelen - 1; - continue; - + dfieldtype->vfunctab_v2.id = LF_VFUNCTAB_V2; + dfieldtype->vfunctab_v2.type = fieldtype->vfunctab_v1.type; + dfieldtype->vfunctab_v2._pad0 = 0; + dpos += sizeof(dfieldtype->vfunctab_v2); + } + pos += sizeof(fieldtype->vfunctab_v1); + break; + + case LF_VFUNCTAB_V2: + copylen = sizeof(dfieldtype->vfunctab_v2); + break; + + // throw away friend function declarations, there is no v3 replacement and the debugger won't need them + case LF_FRIENDFCN_V1: + pos += sizeof(fieldtype->friendfcn_v1) + fieldtype->friendfcn_v1.p_name.namelen - 1; + continue; + case LF_FRIENDFCN_V2: + copylen = sizeof(fieldtype->friendfcn_v2) + fieldtype->friendfcn_v2.p_name.namelen - 1; + continue; + case LF_FRIENDCLS_V1: if(dp) { @@ -595,14 +595,14 @@ int CV2PDB::addFields(codeview_reftype* dfieldlist, const codeview_reftype* fiel break; case LF_FRIENDCLS_V2: copylen = sizeof(fieldtype->friendcls_v2); - break; - - // necessary to convert this info? no data associated with it, so it might not be used + break; + + // necessary to convert this info? no data associated with it, so it might not be used case LF_VBCLASS_V1: case LF_IVBCLASS_V1: if (dp) { - dfieldtype->vbclass_v2.id = fieldtype->generic.id == LF_VBCLASS_V1 ? LF_VBCLASS_V2 : LF_IVBCLASS_V2; + dfieldtype->vbclass_v2.id = fieldtype->common.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; @@ -612,18 +612,18 @@ int CV2PDB::addFields(codeview_reftype* dfieldlist, const codeview_reftype* fiel leaf_len = numeric_leaf(&value, &fieldtype->vbclass_v1.vbpoff); leaf_len += numeric_leaf(&value, (char*) &fieldtype->vbclass_v1.vbpoff + leaf_len); copylen = leaf_len; - break; - + break; + case LF_VBCLASS_V2: case LF_IVBCLASS_V2: leaf_len = numeric_leaf(&value, &fieldtype->vbclass_v2.vbpoff); leaf_len += numeric_leaf(&value, (char*) &fieldtype->vbclass_v2.vbpoff + leaf_len); copylen = sizeof(fieldtype->vbclass_v2) - sizeof(fieldtype->vbclass_v2.vbpoff) + leaf_len; break; - - default: - setError("unsupported field entry"); - break; + + default: + setError("unsupported field entry"); + break; } if (dp) @@ -639,188 +639,188 @@ int CV2PDB::addFields(codeview_reftype* dfieldlist, const codeview_reftype* fiel } return dp ? dpos : cntFields; } - + int CV2PDB::countFields(const codeview_reftype* fieldlist) { return addFields(0, fieldlist, 0); } - + int CV2PDB::addAggregate(codeview_type* dtype, bool clss, int n_element, int fieldlist, int property, int derived, int vshape, int structlen, const char*name) { dtype->struct_v2.id = clss ? (v3 ? LF_CLASS_V3 : LF_CLASS_V2) : (v3 ? LF_STRUCTURE_V3 : LF_STRUCTURE_V2); - dtype->struct_v2.n_element = n_element; - dtype->struct_v2.fieldlist = fieldlist; - dtype->struct_v2.property = property; - dtype->struct_v2.derived = derived; - dtype->struct_v2.vshape = vshape; - dtype->struct_v2.structlen = structlen; - int len = cstrcpy_v(v3, (BYTE*)(&dtype->struct_v2 + 1), name); - len += sizeof (dtype->struct_v2); + dtype->struct_v2.n_element = n_element; + dtype->struct_v2.fieldlist = fieldlist; + dtype->struct_v2.property = property; + dtype->struct_v2.derived = derived; + dtype->struct_v2.vshape = vshape; + dtype->struct_v2.structlen = structlen; + int len = cstrcpy_v(v3, (BYTE*)(&dtype->struct_v2 + 1), name); + len += sizeof (dtype->struct_v2); unsigned char* p = (unsigned char*) dtype; for (; len & 3; len++) p[len] = 0xf4 - (len & 3); dtype->struct_v2.len = len - 2; - return len; -} - + return len; +} + int CV2PDB::addClass(codeview_type* dtype, int n_element, int fieldlist, int property, int derived, int vshape, int structlen, const char*name) -{ - return addAggregate(dtype, true, n_element, fieldlist, property, derived, vshape, structlen, name); -} - +{ + return addAggregate(dtype, true, n_element, fieldlist, property, derived, vshape, structlen, name); +} + int CV2PDB::addStruct(codeview_type* dtype, int n_element, int fieldlist, int property, int derived, int vshape, int structlen, const char*name) -{ - return addAggregate(dtype, false, n_element, fieldlist, property, derived, vshape, structlen, name); -} - -int CV2PDB::addPointerType(codeview_type* dtype, int type, int attr) -{ - dtype->pointer_v2.id = LF_POINTER_V2; - dtype->pointer_v2.len = 10; - dtype->pointer_v2.datatype = translateType(type); - dtype->pointer_v2.attribute = attr; - return dtype->generic.len + 2; // no alignment data needed, because always 12 bytes -} -int CV2PDB::addPointerType(unsigned char* dtype, int type, int attr) -{ - return addPointerType((codeview_type*) dtype, type, attr); -} - -int CV2PDB::addFieldMember(codeview_fieldtype* dfieldtype, int attr, int offset, int type, const char* name) -{ - dfieldtype->member_v2.id = v3 ? LF_MEMBER_V3 : LF_MEMBER_V2; - dfieldtype->member_v2.attribute = attr; - dfieldtype->member_v2.offset = offset; - dfieldtype->member_v2.type = translateType(type); - int len = cstrcpy_v(v3, (BYTE*)(&dfieldtype->member_v2 + 1), name); - len += sizeof (dfieldtype->member_v2); - +{ + return addAggregate(dtype, false, n_element, fieldlist, property, derived, vshape, structlen, name); +} + +int CV2PDB::addPointerType(codeview_type* dtype, int type, int attr) +{ + dtype->pointer_v2.id = LF_POINTER_V2; + 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 +} +int CV2PDB::addPointerType(unsigned char* dtype, int type, int attr) +{ + return addPointerType((codeview_type*) dtype, type, attr); +} + +int CV2PDB::addFieldMember(codeview_fieldtype* dfieldtype, int attr, int offset, int type, const char* name) +{ + dfieldtype->member_v2.id = v3 ? LF_MEMBER_V3 : LF_MEMBER_V2; + dfieldtype->member_v2.attribute = attr; + dfieldtype->member_v2.offset = offset; + dfieldtype->member_v2.type = translateType(type); + int len = cstrcpy_v(v3, (BYTE*)(&dfieldtype->member_v2 + 1), name); + len += sizeof (dfieldtype->member_v2); + unsigned char* p = (unsigned char*) dfieldtype; for (; len & 3; len++) p[len] = 0xf4 - (len & 3); return len; -} - -int CV2PDB::addFieldStaticMember(codeview_fieldtype* dfieldtype, int attr, int type, const char* name) -{ - dfieldtype->stmember_v2.id = v3 ? LF_STMEMBER_V3 : LF_STMEMBER_V2; - dfieldtype->stmember_v2.attribute = attr; - dfieldtype->stmember_v2.type = translateType(type); - int len = cstrcpy_v(v3, (BYTE*)(&dfieldtype->stmember_v2.p_name), name); - len += sizeof (dfieldtype->stmember_v2) - sizeof (dfieldtype->stmember_v2.p_name); - +} + +int CV2PDB::addFieldStaticMember(codeview_fieldtype* dfieldtype, int attr, int type, const char* name) +{ + dfieldtype->stmember_v2.id = v3 ? LF_STMEMBER_V3 : LF_STMEMBER_V2; + dfieldtype->stmember_v2.attribute = attr; + dfieldtype->stmember_v2.type = translateType(type); + int len = cstrcpy_v(v3, (BYTE*)(&dfieldtype->stmember_v2.p_name), name); + len += sizeof (dfieldtype->stmember_v2) - sizeof (dfieldtype->stmember_v2.p_name); + unsigned char* p = (unsigned char*) dfieldtype; for (; len & 3; len++) p[len] = 0xf4 - (len & 3); return len; -} - -int CV2PDB::addFieldNestedType(codeview_fieldtype* dfieldtype, int type, const char* name) -{ - dfieldtype->nesttype_v2.id = v3 ? LF_NESTTYPE_V3 : LF_NESTTYPE_V2; - dfieldtype->nesttype_v2._pad0 = 0; - dfieldtype->nesttype_v2.type = type; - int len = cstrcpy_v(v3, (BYTE*)(&dfieldtype->nesttype_v2.p_name), name); - len += sizeof (dfieldtype->nesttype_v2) - sizeof(dfieldtype->nesttype_v2.p_name); - +} + +int CV2PDB::addFieldNestedType(codeview_fieldtype* dfieldtype, int type, const char* name) +{ + dfieldtype->nesttype_v2.id = v3 ? LF_NESTTYPE_V3 : LF_NESTTYPE_V2; + dfieldtype->nesttype_v2._pad0 = 0; + dfieldtype->nesttype_v2.type = type; + int len = cstrcpy_v(v3, (BYTE*)(&dfieldtype->nesttype_v2.p_name), name); + len += sizeof (dfieldtype->nesttype_v2) - sizeof(dfieldtype->nesttype_v2.p_name); + unsigned char* p = (unsigned char*) dfieldtype; for (; len & 3; len++) p[len] = 0xf4 - (len & 3); return len; -} - -void CV2PDB::checkUserTypeAlloc(int size, int add) -{ - if (cbUserTypes + size >= allocUserTypes) - { - allocUserTypes += add; - userTypes = (BYTE*) realloc(userTypes, allocUserTypes); - } -} - -const codeview_type* CV2PDB::getTypeData(int type) -{ - if (!globalTypeHeader) - return 0; - if (type < 0x1000 || type >= (int) (0x1000 + globalTypeHeader->cTypes + nextUserType)) - return 0; - if (type >= (int) (0x1000 + globalTypeHeader->cTypes)) - return getUserTypeData(type); - +} + +void CV2PDB::checkUserTypeAlloc(int size, int add) +{ + if (cbUserTypes + size >= allocUserTypes) + { + allocUserTypes += add; + userTypes = (BYTE*) realloc(userTypes, allocUserTypes); + } +} + +const codeview_type* CV2PDB::getTypeData(int type) +{ + if (!globalTypeHeader) + return 0; + if (type < 0x1000 || type >= (int) (0x1000 + globalTypeHeader->cTypes + nextUserType)) + return 0; + if (type >= (int) (0x1000 + globalTypeHeader->cTypes)) + return getUserTypeData(type); + DWORD* offset = (DWORD*)(globalTypeHeader + 1); BYTE* typeData = (BYTE*)(offset + globalTypeHeader->cTypes); return (codeview_type*)(typeData + offset[type - 0x1000]); } - -const codeview_type* CV2PDB::getUserTypeData(int type) -{ - type -= 0x1000 + globalTypeHeader->cTypes; - if (type < 0 || type >= nextUserType - 0x1000) - return 0; - - int pos = 0; - while(type > 0) - { + +const codeview_type* CV2PDB::getUserTypeData(int type) +{ + type -= 0x1000 + globalTypeHeader->cTypes; + if (type < 0 || type >= nextUserType - 0x1000) + return 0; + + int pos = 0; + while(type > 0) + { const codeview_type* ptype = (codeview_type*)(userTypes + pos); - int len = ptype->generic.len + 2; + int len = ptype->common.len + 2; pos += len; type--; } return (codeview_type*)(userTypes + pos); -} - -const codeview_type* CV2PDB::findCompleteClassType(const codeview_type* cvtype) -{ - if (!globalTypeHeader) - return 0; +} + +const codeview_type* CV2PDB::findCompleteClassType(const codeview_type* cvtype) +{ + if (!globalTypeHeader) + return 0; int value; - int cvleaf_len = numeric_leaf(&value, &cvtype->struct_v1.structlen); + int cvleaf_len = numeric_leaf(&value, &cvtype->struct_v1.structlen); DWORD* offset = (DWORD*)(globalTypeHeader + 1); BYTE* typeData = (BYTE*)(offset + globalTypeHeader->cTypes); - for (unsigned int t = 0; t < globalTypeHeader->cTypes; t++) - { + for (unsigned int t = 0; t < globalTypeHeader->cTypes; t++) + { const codeview_type* type = (const codeview_type*)(typeData + offset[t]); - if (type->generic.id == LF_CLASS_V1 || type->generic.id == LF_STRUCTURE_V1) + if (type->common.id == LF_CLASS_V1 || type->common.id == LF_STRUCTURE_V1) { if (!(type->struct_v1.property & kIncomplete)) { - int leaf_len = numeric_leaf(&value, &type->struct_v1.structlen); - if (pstrcmp((const BYTE*) &cvtype->struct_v1.structlen + cvleaf_len, - (const BYTE*) &type->struct_v1.structlen + leaf_len) == 0) + int leaf_len = numeric_leaf(&value, &type->struct_v1.structlen); + if (pstrcmp((const BYTE*) &cvtype->struct_v1.structlen + cvleaf_len, + (const BYTE*) &type->struct_v1.structlen + leaf_len) == 0) return type; } } - } - return cvtype; -} - -int CV2PDB::findMemberFunctionType(codeview_symbol* lastGProcSym, int thisPtrType) -{ - const codeview_type* proctype = getTypeData(lastGProcSym->proc_v2.proctype); - if (!proctype || proctype->generic.id != LF_PROCEDURE_V1) - return lastGProcSym->proc_v2.proctype; - - const codeview_type* thisPtrData = getTypeData(thisPtrType); - if (!thisPtrData || thisPtrData->generic.id != LF_POINTER_V1) - return lastGProcSym->proc_v2.proctype; - - int thistype = thisPtrData->pointer_v1.datatype; - - // search method with same arguments and return type + } + return 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) + return lastGProcSym->proc_v2.proctype; + + const codeview_type* thisPtrData = getTypeData(thisPtrType); + if (!thisPtrData || thisPtrData->common.id != LF_POINTER_V1) + return lastGProcSym->proc_v2.proctype; + + int thistype = thisPtrData->pointer_v1.datatype; + + // search method with same arguments and return type DWORD* offset = (DWORD*)(globalTypeHeader + 1); BYTE* typeData = (BYTE*)(offset + globalTypeHeader->cTypes); - for (unsigned int t = 0; t < globalTypeHeader->cTypes; t++) - { - // remember: mfunction_v1.class_type falsely is pointer, not class type + for (unsigned int t = 0; t < globalTypeHeader->cTypes; t++) + { + // remember: mfunction_v1.class_type falsely is pointer, not class type const codeview_type* type = (const codeview_type*)(typeData + offset[t]); - if (type->generic.id == LF_MFUNCTION_V1 && type->mfunction_v1.this_type == thisPtrType) + if (type->common.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 && @@ -830,220 +830,220 @@ int CV2PDB::findMemberFunctionType(codeview_symbol* lastGProcSym, int thisPtrTyp } } } - return lastGProcSym->proc_v2.proctype; -} - -int CV2PDB::sizeofClassType(const codeview_type* cvtype) -{ - if (cvtype->struct_v1.property & kIncomplete) - cvtype = findCompleteClassType(cvtype); - - int value; - int leaf_len = numeric_leaf(&value, &cvtype->struct_v1.structlen); - return value; -} - -int CV2PDB::sizeofBasicType(int type) -{ - int size = type & 7; - int typ = (type & 0xf0) >> 4; - int mode = (type & 0x700) >> 8; - - switch (mode) - { - case 1: - case 2: - case 3: - case 4: - case 5: // pointer variations - return 4; - case 6: // 64-bit pointer - return 8; - case 7: // reserved - return 4; - case 0: // not pointer - switch (typ) - { - case 0: // special, cannot determine - return 4; - case 1: - case 2: // integral types - switch (size) - { - case 0: return 1; - case 1: return 2; - case 2: return 4; - case 3: return 8; - // other reserved - } - return 4; - case 3: // boolean - return 1; - case 4: - case 5: // real and complex - switch (size) - { - case 0: return 4; - case 1: return 8; - case 2: return 10; - case 3: return 16; - case 4: return 6; - // other reserved - } - return 4; - case 6: // special2 (bit or pascal char) - return 1; - case 7: // real int - switch (size) - { - case 0: return 1; // char - case 1: return 4; // wide char - case 2: return 2; - case 3: return 2; - case 4: return 4; - case 5: return 4; - case 6: return 8; - case 7: return 8; - } - } - } - return 4; -} - -int CV2PDB::sizeofType(int type) -{ - if (type < 0x1000) - return sizeofBasicType(type); - - const codeview_type* cvtype = getTypeData(type); - if (!cvtype) - return 4; - - if (cvtype->generic.id == LF_CLASS_V1 || cvtype->generic.id == LF_STRUCTURE_V1) - return sizeofClassType(cvtype); - - 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 - return 4; -} - -// to be used when writing new type only to avoid double translation -int CV2PDB::translateType(int type) -{ - if (type < 0x1000) - { - for(int i = 0; i < cntTypedefs; i++) - if(type == typedefs[i]) - return translatedTypedefs[i]; - return type; - } - - const codeview_type* cvtype = getTypeData(type); - if (!cvtype) - return type; - - if (cvtype->generic.id != LF_OEM_V1) - return type; - - codeview_oem_type* oem = (codeview_oem_type*) (&cvtype->generic + 1); - if (oem->generic.oemid == 0x42 && oem->generic.id == 3) - { + return lastGProcSym->proc_v2.proctype; +} + +int CV2PDB::sizeofClassType(const codeview_type* cvtype) +{ + if (cvtype->struct_v1.property & kIncomplete) + cvtype = findCompleteClassType(cvtype); + + int value; + int leaf_len = numeric_leaf(&value, &cvtype->struct_v1.structlen); + return value; +} + +int CV2PDB::sizeofBasicType(int type) +{ + int size = type & 7; + int typ = (type & 0xf0) >> 4; + int mode = (type & 0x700) >> 8; + + switch (mode) + { + case 1: + case 2: + case 3: + case 4: + case 5: // pointer variations + return 4; + case 6: // 64-bit pointer + return 8; + case 7: // reserved + return 4; + case 0: // not pointer + switch (typ) + { + case 0: // special, cannot determine + return 4; + case 1: + case 2: // integral types + switch (size) + { + case 0: return 1; + case 1: return 2; + case 2: return 4; + case 3: return 8; + // other reserved + } + return 4; + case 3: // boolean + return 1; + case 4: + case 5: // real and complex + switch (size) + { + case 0: return 4; + case 1: return 8; + case 2: return 10; + case 3: return 16; + case 4: return 6; + // other reserved + } + return 4; + case 6: // special2 (bit or pascal char) + return 1; + case 7: // real int + switch (size) + { + case 0: return 1; // char + case 1: return 4; // wide char + case 2: return 2; + case 3: return 2; + case 4: return 4; + case 5: return 4; + case 6: return 8; + case 7: return 8; + } + } + } + return 4; +} + +int CV2PDB::sizeofType(int type) +{ + if (type < 0x1000) + return sizeofBasicType(type); + + const codeview_type* cvtype = getTypeData(type); + if (!cvtype) + return 4; + + if (cvtype->common.id == LF_CLASS_V1 || cvtype->common.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) + return 8; // all D oem types + + // everything else must be pointer or function pointer + return 4; +} + +// to be used when writing new type only to avoid double translation +int CV2PDB::translateType(int type) +{ + if (type < 0x1000) + { + for(int i = 0; i < cntTypedefs; i++) + if(type == typedefs[i]) + return translatedTypedefs[i]; + return type; + } + + const codeview_type* cvtype = getTypeData(type); + if (!cvtype) + return type; + + if (cvtype->common.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) + { if (oem->d_delegate.this_type == 0x403 && oem->d_delegate.func_type == 0x74) return 0x76; // long - } - - return type; -} - -bool CV2PDB::nameOfBasicType(int type, char* name, int maxlen) -{ - int size = type & 0xf; - int typ = (type & 0xf0) >> 4; - int mode = (type & 0x700) >> 8; - - switch (typ) - { - case 0: // special, cannot determine - if (size == 3) - strcpy(name, "void"); - else - return setError("nameOfBasicType: unsupported basic special type"); - break; - case 1: // signed integral types - switch (size) - { - case 0: strcpy(name, "byte"); break; // cannot distinguish char und byte - case 1: strcpy(name, "short"); break; - case 2: strcpy(name, "int"); break; - case 3: strcpy(name, "long"); break; - default: - return setError("nameOfBasicType: unsupported basic signed integral type"); - // other reserved - } - break; - case 2: // unsigned integral types - switch (size) - { - case 0: strcpy(name, "ubyte"); break; - case 1: strcpy(name, "ushort"); break; - case 2: strcpy(name, "uint"); break; - case 3: strcpy(name, "ulong"); break; - default: - return setError("nameOfBasicType: unsupported basic unsigned integral type"); - } - break; - case 3: // boolean - strcpy(name, "bool"); - break; - case 4: - switch (size) - { - case 0: strcpy(name, "ifloat"); break; - case 1: strcpy(name, "idouble"); break; - case 2: strcpy(name, "ireal"); break; - default: - return setError("nameOfBasicType: unsupported basic complex type"); - } - break; - case 5: // real and complex - switch (size) - { - case 0: strcpy(name, "float"); break; - case 1: strcpy(name, "double"); break; - case 2: strcpy(name, "real"); break; - default: - return setError("nameOfBasicType: unsupported basic real type"); - } - break; - case 6: // special2 (bit or pascal char) - return setError("nameOfBasicType: unsupported basic special2 type"); - return 1; - case 7: // real int - switch (size) - { - case 0: strcpy(name, "char"); break; - case 1: strcpy(name, "wchar"); break; //?? - case 2: strcpy(name, "short"); break; - case 3: strcpy(name, "ushort"); break; - case 4: strcpy(name, "int"); break; - case 5: strcpy(name, "uint"); break; - case 6: strcpy(name, "long"); break; - case 7: strcpy(name, "ulong"); break; - case 8: strcpy(name, "dchar"); break; - default: - return setError("nameOfBasicType: unsupported size real int type"); - } - } - if (mode != 0 && mode != 7) - strcat(name, "*"); - return true; -} - -bool CV2PDB::nameOfModifierType(int type, int mod, char* name, int maxlen) -{ + } + + return type; +} + +bool CV2PDB::nameOfBasicType(int type, char* name, int maxlen) +{ + int size = type & 0xf; + int typ = (type & 0xf0) >> 4; + int mode = (type & 0x700) >> 8; + + switch (typ) + { + case 0: // special, cannot determine + if (size == 3) + strcpy(name, "void"); + else + return setError("nameOfBasicType: unsupported basic special type"); + break; + case 1: // signed integral types + switch (size) + { + case 0: strcpy(name, "byte"); break; // cannot distinguish char und byte + case 1: strcpy(name, "short"); break; + case 2: strcpy(name, "int"); break; + case 3: strcpy(name, "long"); break; + default: + return setError("nameOfBasicType: unsupported basic signed integral type"); + // other reserved + } + break; + case 2: // unsigned integral types + switch (size) + { + case 0: strcpy(name, "ubyte"); break; + case 1: strcpy(name, "ushort"); break; + case 2: strcpy(name, "uint"); break; + case 3: strcpy(name, "ulong"); break; + default: + return setError("nameOfBasicType: unsupported basic unsigned integral type"); + } + break; + case 3: // boolean + strcpy(name, "bool"); + break; + case 4: + switch (size) + { + case 0: strcpy(name, "ifloat"); break; + case 1: strcpy(name, "idouble"); break; + case 2: strcpy(name, "ireal"); break; + default: + return setError("nameOfBasicType: unsupported basic complex type"); + } + break; + case 5: // real and complex + switch (size) + { + case 0: strcpy(name, "float"); break; + case 1: strcpy(name, "double"); break; + case 2: strcpy(name, "real"); break; + default: + return setError("nameOfBasicType: unsupported basic real type"); + } + break; + case 6: // special2 (bit or pascal char) + return setError("nameOfBasicType: unsupported basic special2 type"); + return 1; + case 7: // real int + switch (size) + { + case 0: strcpy(name, "char"); break; + case 1: strcpy(name, "wchar"); break; //?? + case 2: strcpy(name, "short"); break; + case 3: strcpy(name, "ushort"); break; + case 4: strcpy(name, "int"); break; + case 5: strcpy(name, "uint"); break; + case 6: strcpy(name, "long"); break; + case 7: strcpy(name, "ulong"); break; + case 8: strcpy(name, "dchar"); break; + default: + return setError("nameOfBasicType: unsupported size real int type"); + } + } + if (mode != 0 && mode != 7) + strcat(name, "*"); + return true; +} + +bool CV2PDB::nameOfModifierType(int type, int mod, char* name, int maxlen) +{ *name = 0; if(mod & 1) strcat(name, "const "); @@ -1055,46 +1055,46 @@ bool CV2PDB::nameOfModifierType(int type, int mod, char* name, int maxlen) if(!nameOfType(type, name + len, maxlen - len)) return false; return true; -} - -bool CV2PDB::nameOfType(int type, char* name, int maxlen) -{ - if(type < 0x1000) - return nameOfBasicType(type, name, maxlen); - - const codeview_type* ptype = getTypeData(type); - if(!ptype) - return setError("nameOfType: invalid type while retreiving name of type"); - - int leaf_len, value, len; - switch(ptype->generic.id) - { - case LF_CLASS_V1: +} + +bool CV2PDB::nameOfType(int type, char* name, int maxlen) +{ + if(type < 0x1000) + return nameOfBasicType(type, name, maxlen); + + const codeview_type* ptype = getTypeData(type); + if(!ptype) + return setError("nameOfType: invalid type while retreiving name of type"); + + int leaf_len, value, len; + switch(ptype->common.id) + { + case LF_CLASS_V1: case LF_STRUCTURE_V1: - leaf_len = numeric_leaf(&value, &ptype->struct_v1.structlen); + leaf_len = numeric_leaf(&value, &ptype->struct_v1.structlen); p2ccpy(name, (const BYTE*) &ptype->struct_v1.structlen + leaf_len); break; - case LF_CLASS_V2: + case LF_CLASS_V2: case LF_STRUCTURE_V2: - leaf_len = numeric_leaf(&value, &ptype->struct_v2.structlen); + leaf_len = numeric_leaf(&value, &ptype->struct_v2.structlen); p2ccpy(name, (const BYTE*) &ptype->struct_v2.structlen + leaf_len); break; - case LF_CLASS_V3: + case LF_CLASS_V3: case LF_STRUCTURE_V3: - leaf_len = numeric_leaf(&value, &ptype->struct_v3.structlen); + leaf_len = numeric_leaf(&value, &ptype->struct_v3.structlen); strcpy(name, (const char*) &ptype->struct_v3.structlen + leaf_len); break; case LF_UNION_V1: - leaf_len = numeric_leaf(&value, &ptype->union_v1.un_len); + leaf_len = numeric_leaf(&value, &ptype->union_v1.un_len); p2ccpy(name, (const BYTE*) &ptype->union_v1.un_len + leaf_len); break; case LF_UNION_V2: - leaf_len = numeric_leaf(&value, &ptype->union_v2.un_len); + leaf_len = numeric_leaf(&value, &ptype->union_v2.un_len); p2ccpy(name, (const BYTE*) &ptype->union_v2.un_len + leaf_len); break; case LF_UNION_V3: - leaf_len = numeric_leaf(&value, &ptype->union_v3.un_len); + leaf_len = numeric_leaf(&value, &ptype->union_v3.un_len); strcpy(name, (const char*) &ptype->union_v3.un_len + leaf_len); break; @@ -1112,23 +1112,23 @@ bool CV2PDB::nameOfType(int type, char* name, int maxlen) case LF_ARRAY_V1: if(!nameOfType(ptype->array_v1.elemtype, name, maxlen)) return false; - leaf_len = numeric_leaf(&value, &ptype->array_v1.arrlen); - len = strlen(name); - sprintf(name + len, "[%d]", leaf_len); + leaf_len = numeric_leaf(&value, &ptype->array_v1.arrlen); + len = strlen(name); + sprintf(name + len, "[%d]", leaf_len); break; case LF_ARRAY_V2: if(!nameOfType(ptype->array_v2.elemtype, name, maxlen)) return false; - leaf_len = numeric_leaf(&value, &ptype->array_v2.arrlen); - len = strlen(name); - sprintf(name + len, "[%d]", leaf_len); + leaf_len = numeric_leaf(&value, &ptype->array_v2.arrlen); + len = strlen(name); + sprintf(name + len, "[%d]", leaf_len); break; case LF_ARRAY_V3: if(!nameOfType(ptype->array_v3.elemtype, name, maxlen)) return false; - leaf_len = numeric_leaf(&value, &ptype->array_v3.arrlen); - len = strlen(name); - sprintf(name + len, "[%d]", leaf_len); + leaf_len = numeric_leaf(&value, &ptype->array_v3.arrlen); + len = strlen(name); + sprintf(name + len, "[%d]", leaf_len); break; case LF_ENUM_V1: @@ -1157,39 +1157,39 @@ bool CV2PDB::nameOfType(int type, char* name, int maxlen) if(!nameOfType(ptype->procedure_v1.rvtype, name, maxlen)) return false; strcat(name, "()"); - break; + break; case LF_PROCEDURE_V2: if(!nameOfType(ptype->procedure_v2.rvtype, name, maxlen)) return false; strcat(name, "()"); - break; + break; case LF_MFUNCTION_V1: if(!nameOfType(ptype->mfunction_v1.rvtype, name, maxlen)) return false; strcat(name, "()"); - break; + break; case LF_MFUNCTION_V2: if(!nameOfType(ptype->mfunction_v2.rvtype, name, maxlen)) return false; strcat(name, "()"); - break; + break; case LF_OEM_V1: - if (!nameOfOEMType((codeview_oem_type*) (&ptype->generic + 1), name, maxlen)) + if (!nameOfOEMType((codeview_oem_type*) (&ptype->common + 1), name, maxlen)) return false; break; default: return setError("nameOfType: unsupported type"); } return true; -} - -bool CV2PDB::nameOfDynamicArray(int indexType, int elemType, char* name, int maxlen) -{ - if (!nameOfType(elemType, name, maxlen)) - return false; - +} + +bool CV2PDB::nameOfDynamicArray(int indexType, int elemType, char* name, int maxlen) +{ + if (!nameOfType(elemType, name, maxlen)) + return false; + if (Dversion >= 2 && strcmp(name, "const char") == 0) strcpy(name, "string"); else if (Dversion >= 2 && strcmp(name, "const wchar") == 0) @@ -1204,120 +1204,120 @@ bool CV2PDB::nameOfDynamicArray(int indexType, int elemType, char* name, int max else if (Dversion < 2 && strcmp(name, "dchar") == 0) strcpy(name, "dstring"); else - strcat (name, "[]"); - // sprintf(name, "dyn_array<%X,%X>", indexType, elemType); - return true; -} - -bool CV2PDB::nameOfAssocArray(int indexType, int elemType, char* name, int maxlen) -{ - strcpy(name, "aa<"); - int len = strlen(name); - if (!nameOfType(elemType, name + len, maxlen - len)) - return false; - strcat(name, "["); - len = strlen(name); - if (!nameOfType(indexType, name + len, maxlen - len)) - return false; - strcat(name,"]>"); - - // sprintf(name, "assoc_array<%X,%X>", indexType, elemType); - return true; -} - -bool CV2PDB::nameOfDelegate(int thisType, int funcType, char* name, int maxlen) -{ - strcpy(name, "delegate "); - int len = strlen(name); - if (!nameOfType(funcType, name + len, maxlen - len)) - return false; - // sprintf(name, "delegate<%X,%X>", indexType, elemType); - return true; -} - -bool CV2PDB::nameOfOEMType(codeview_oem_type* oem, char* name, int maxlen) -{ - if (oem->generic.oemid == 0x42 && oem->generic.id == 1) + strcat (name, "[]"); + // sprintf(name, "dyn_array<%X,%X>", indexType, elemType); + return true; +} + +bool CV2PDB::nameOfAssocArray(int indexType, int elemType, char* name, int maxlen) +{ + strcpy(name, "aa<"); + int len = strlen(name); + if (!nameOfType(elemType, name + len, maxlen - len)) + return false; + strcat(name, "["); + len = strlen(name); + if (!nameOfType(indexType, name + len, maxlen - len)) + return false; + strcat(name,"]>"); + + // sprintf(name, "assoc_array<%X,%X>", indexType, elemType); + return true; +} + +bool CV2PDB::nameOfDelegate(int thisType, int funcType, char* name, int maxlen) +{ + strcpy(name, "delegate "); + int len = strlen(name); + if (!nameOfType(funcType, name + len, maxlen - len)) + return false; + // sprintf(name, "delegate<%X,%X>", indexType, elemType); + return true; +} + +bool CV2PDB::nameOfOEMType(codeview_oem_type* oem, char* name, int maxlen) +{ + if (oem->common.oemid == 0x42 && oem->common.id == 1) return nameOfDynamicArray(oem->d_dyn_array.index_type, oem->d_dyn_array.elem_type, name, maxlen); - if (oem->generic.oemid == 0x42 && oem->generic.id == 2) + if (oem->common.oemid == 0x42 && oem->common.id == 2) return nameOfAssocArray(oem->d_assoc_array.key_type, oem->d_assoc_array.elem_type, name, maxlen); - if (oem->generic.oemid == 0x42 && oem->generic.id == 3) + if (oem->common.oemid == 0x42 && oem->common.id == 3) return nameOfDelegate(oem->d_delegate.this_type, oem->d_delegate.func_type, name, maxlen); return setError("nameOfOEMType: unknown OEM type record"); } - -const char* CV2PDB::appendDynamicArray(int indexType, int elemType) -{ - indexType = translateType(indexType); - elemType = translateType(elemType); - + +const char* CV2PDB::appendDynamicArray(int indexType, int elemType) +{ + indexType = translateType(indexType); + elemType = translateType(elemType); + codeview_reftype* rdtype; - codeview_type* dtype; - - checkUserTypeAlloc(); - - static char name[256]; - nameOfDynamicArray(indexType, elemType, name, sizeof(name)); - - // nextUserType: pointer to elemType - cbUserTypes += addPointerType(userTypes + cbUserTypes, elemType); - int dataptrType = nextUserType++; - - int dstringType = 0; - if(strcmp(name, "string") == 0 || strcmp(name, "wstring") == 0 || strcmp(name, "dstring") == 0) - { - // nextUserType + 1: field list (size, array) + codeview_type* dtype; + + checkUserTypeAlloc(); + + static char name[256]; + nameOfDynamicArray(indexType, elemType, name, sizeof(name)); + + // nextUserType: pointer to elemType + cbUserTypes += addPointerType(userTypes + cbUserTypes, elemType); + int dataptrType = nextUserType++; + + int dstringType = 0; + if(strcmp(name, "string") == 0 || strcmp(name, "wstring") == 0 || strcmp(name, "dstring") == 0) + { + // nextUserType + 1: field list (size, array) rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - int helpfieldlistType = nextUserType++; - - rdtype->fieldlist.len = 2; - cbUserTypes += rdtype->fieldlist.len + 2; - - char helpertype[64]; - strcat(strcpy(helpertype, name), "_viewhelper"); + rdtype->fieldlist.id = LF_FIELDLIST_V2; + int helpfieldlistType = nextUserType++; + + rdtype->fieldlist.len = 2; + cbUserTypes += rdtype->fieldlist.len + 2; + + char helpertype[64]; + strcat(strcpy(helpertype, name), "_viewhelper"); dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, 0, helpfieldlistType, 0, 0, 0, 0, helpertype); dstringType = nextUserType++; - addUdtSymbol(dstringType, helpertype); + addUdtSymbol(dstringType, helpertype); } - - // nextUserType + 1: field list (size, array) + + // nextUserType + 1: field list (size, array) rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - int fieldlistType = nextUserType++; - - // member indexType length - codeview_fieldtype* dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; - int len1 = addFieldMember(dfieldtype, 1, 0, indexType, "length"); - - // member elemType* data[] - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); - int len2 = addFieldMember(dfieldtype, 1, 4, dataptrType, "ptr"); - - int numElem = 2; - rdtype->fieldlist.len = len1 + len2 + 2; - - if(dstringType > 0) - { - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + rdtype->fieldlist.len - 2); - rdtype->fieldlist.len += addFieldMember(dfieldtype, 1, 0, dstringType, "__viewhelper"); - numElem++; - } - - cbUserTypes += rdtype->fieldlist.len + 2; + rdtype->fieldlist.id = LF_FIELDLIST_V2; + int fieldlistType = nextUserType++; + + // member indexType length + codeview_fieldtype* dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + int len1 = addFieldMember(dfieldtype, 1, 0, indexType, "length"); + + // member elemType* data[] + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); + int len2 = addFieldMember(dfieldtype, 1, 4, dataptrType, "ptr"); + + int numElem = 2; + rdtype->fieldlist.len = len1 + len2 + 2; + + if(dstringType > 0) + { + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + rdtype->fieldlist.len - 2); + rdtype->fieldlist.len += addFieldMember(dfieldtype, 1, 0, dstringType, "__viewhelper"); + numElem++; + } + + cbUserTypes += rdtype->fieldlist.len + 2; dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, numElem, fieldlistType, 0, 0, 0, 8, name); - int udType = nextUserType++; - - addUdtSymbol(udType, name); - return name; -} - -const char* CV2PDB::appendAssocArray(int keyType, int elemType) -{ - // rebuilding types + int udType = nextUserType++; + + addUdtSymbol(udType, name); + return name; +} + +const char* CV2PDB::appendAssocArray(int keyType, int elemType) +{ + // rebuilding types // struct aaA { // aaA *left; // aaA *right; @@ -1325,333 +1325,333 @@ const char* CV2PDB::appendAssocArray(int keyType, int elemType) // keyType key; // elemType value; // }; - - keyType = translateType(keyType); - elemType = translateType(elemType); - + + keyType = translateType(keyType); + elemType = translateType(elemType); + codeview_reftype* rdtype; - codeview_type* dtype; - codeview_fieldtype* dfieldtype; - - checkUserTypeAlloc(); - - static char name[256]; -#if 1 - char keyname[256]; - char elemname[256]; - if(!nameOfType(keyType, keyname, sizeof(keyname))) - return false; - if(!nameOfType(elemType, elemname, sizeof(elemname))) - return false; - - sprintf(name, "internal@aaA<%s,%s>", keyname, elemname); - - // undefined struct aaA + codeview_type* dtype; + codeview_fieldtype* dfieldtype; + + checkUserTypeAlloc(); + + static char name[256]; +#if 1 + char keyname[256]; + char elemname[256]; + if(!nameOfType(keyType, keyname, sizeof(keyname))) + return false; + if(!nameOfType(elemType, elemname, sizeof(elemname))) + return false; + + sprintf(name, "internal@aaA<%s,%s>", keyname, elemname); + + // undefined struct aaA dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, 0, 0, kIncomplete, 0, 0, 0, name); int aaAType = nextUserType++; - // pointer to aaA - cbUserTypes += addPointerType(userTypes + cbUserTypes, aaAType); + // pointer to aaA + cbUserTypes += addPointerType(userTypes + cbUserTypes, aaAType); int aaAPtrType = nextUserType++; - - // field list (left, right, hash, key, value) + + // field list (left, right, hash, key, value) rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - - // member aaA* left - dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; - int len1 = addFieldMember(dfieldtype, 1, 0, aaAPtrType, "left"); - - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); - int len2 = addFieldMember(dfieldtype, 1, 4, aaAPtrType, "right"); - - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2); - int len3 = addFieldMember(dfieldtype, 1, 8, 0x74, "hash"); - - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2 + len3); - int len4 = addFieldMember(dfieldtype, 1, 12, keyType, "key"); - - int typeLen = sizeofType(keyType); - typeLen = (typeLen + 3) & ~3; // align to 4 byte - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2 + len3 + len4); - int len5 = addFieldMember(dfieldtype, 1, 12 + typeLen, elemType, "value"); - - int elemLen = sizeofType(elemType); - elemLen = (elemLen + 3) & ~3; // align to 4 byte - - rdtype->fieldlist.len = len1 + len2 + len3 + len4 + len5 + 2; - cbUserTypes += rdtype->fieldlist.len + 2; + rdtype->fieldlist.id = LF_FIELDLIST_V2; + + // member aaA* left + dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + int len1 = addFieldMember(dfieldtype, 1, 0, aaAPtrType, "left"); + + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); + int len2 = addFieldMember(dfieldtype, 1, 4, aaAPtrType, "right"); + + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2); + int len3 = addFieldMember(dfieldtype, 1, 8, 0x74, "hash"); + + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2 + len3); + int len4 = addFieldMember(dfieldtype, 1, 12, keyType, "key"); + + int typeLen = sizeofType(keyType); + typeLen = (typeLen + 3) & ~3; // align to 4 byte + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2 + len3 + len4); + int len5 = addFieldMember(dfieldtype, 1, 12 + typeLen, elemType, "value"); + + int elemLen = sizeofType(elemType); + elemLen = (elemLen + 3) & ~3; // align to 4 byte + + rdtype->fieldlist.len = len1 + len2 + len3 + len4 + len5 + 2; + cbUserTypes += rdtype->fieldlist.len + 2; int fieldListType = nextUserType++; - + dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, 5, fieldListType, 0, 0, 0, 12 + typeLen + elemLen, name); - addUdtSymbol(nextUserType, name); + addUdtSymbol(nextUserType, name); int completeAAAType = nextUserType++; // struct BB { // aaA*[] b; // size_t nodes; // total number of aaA nodes // }; - const char* dynArray = appendDynamicArray(0x74, aaAPtrType); + const char* dynArray = appendDynamicArray(0x74, aaAPtrType); int dynArrType = nextUserType - 1; - // field list (aaA*[] b, size_t nodes) + // field list (aaA*[] b, size_t nodes) rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - - // member aaA*[] b - dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; - len1 = addFieldMember(dfieldtype, 1, 0, dynArrType, "b"); - - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); - len2 = addFieldMember(dfieldtype, 1, 8, 0x74, "nodes"); - - rdtype->fieldlist.len = len1 + len2 + 2; - cbUserTypes += rdtype->fieldlist.len + 2; + rdtype->fieldlist.id = LF_FIELDLIST_V2; + + // member aaA*[] b + dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + len1 = addFieldMember(dfieldtype, 1, 0, dynArrType, "b"); + + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); + len2 = addFieldMember(dfieldtype, 1, 8, 0x74, "nodes"); + + rdtype->fieldlist.len = len1 + len2 + 2; + cbUserTypes += rdtype->fieldlist.len + 2; int bbFieldListType = nextUserType++; - - sprintf(name, "internal@BB<%s,%s>", keyname, elemname); - - // struct BB + + sprintf(name, "internal@BB<%s,%s>", keyname, elemname); + + // struct BB dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, 2, bbFieldListType, 0, 0, 0, 12, name); - addUdtSymbol(nextUserType, name); + addUdtSymbol(nextUserType, name); int bbType = nextUserType++; - + // struct AA { // BB* a; // }; - // pointer to BB - cbUserTypes += addPointerType(userTypes + cbUserTypes, bbType); + // pointer to BB + cbUserTypes += addPointerType(userTypes + cbUserTypes, bbType); int bbPtrType = nextUserType++; -#else - int len1, bbPtrType = elemType; -#endif - - // field list (BB* aa) +#else + int len1, bbPtrType = elemType; +#endif + + // field list (BB* aa) rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - - // member aaA*[] b - dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; - len1 = addFieldMember(dfieldtype, 1, 0, bbPtrType, "a"); - - rdtype->fieldlist.len = len1 + 2; - cbUserTypes += rdtype->fieldlist.len + 2; + rdtype->fieldlist.id = LF_FIELDLIST_V2; + + // member aaA*[] b + dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + len1 = addFieldMember(dfieldtype, 1, 0, bbPtrType, "a"); + + rdtype->fieldlist.len = len1 + 2; + cbUserTypes += rdtype->fieldlist.len + 2; int aaFieldListType = nextUserType++; - - nameOfAssocArray(keyType, elemType, name, sizeof(name)); + + nameOfAssocArray(keyType, elemType, name, sizeof(name)); dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, 1, aaFieldListType, 0, 0, 0, 4, name); - - addUdtSymbol(nextUserType, name); - nextUserType++; - - return name; -} - -const char* CV2PDB::appendDelegate(int thisType, int funcType) -{ - thisType = translateType(thisType); - funcType = translateType(funcType); - + + addUdtSymbol(nextUserType, name); + nextUserType++; + + return name; +} + +const char* CV2PDB::appendDelegate(int thisType, int funcType) +{ + thisType = translateType(thisType); + funcType = translateType(funcType); + codeview_reftype* rdtype; - codeview_type* dtype; - - checkUserTypeAlloc(); - - // nextUserType + 1: pointer to funcType - cbUserTypes += addPointerType(userTypes + cbUserTypes, funcType); - - bool thisTypeIsVoid = (thisType == 0x403); - if (!thisTypeIsVoid) - { - // nextUserType: pointer to thisType + codeview_type* dtype; + + checkUserTypeAlloc(); + + // nextUserType + 1: pointer to funcType + cbUserTypes += addPointerType(userTypes + cbUserTypes, funcType); + + bool thisTypeIsVoid = (thisType == 0x403); + if (!thisTypeIsVoid) + { + // nextUserType: pointer to thisType dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addPointerType(dtype, thisType); } - - // nextUserType + 2: field list (size, array) + + // nextUserType + 2: field list (size, array) rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - - // member thisType* thisptr - codeview_fieldtype* dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; - int len1 = addFieldMember(dfieldtype, 1, 0, thisTypeIsVoid ? thisType : nextUserType + 1, "thisptr"); - - // member funcType* funcptr - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); - int len2 = addFieldMember(dfieldtype, 1, 4, nextUserType, "funcptr"); - - rdtype->fieldlist.len = len1 + len2 + 2; - cbUserTypes += rdtype->fieldlist.len + 2; - - static char name[256]; - nameOfDelegate(thisType, funcType, name, sizeof(name)); - - // nextUserType + 3: struct delegate<> + rdtype->fieldlist.id = LF_FIELDLIST_V2; + + // member thisType* thisptr + codeview_fieldtype* dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + int len1 = addFieldMember(dfieldtype, 1, 0, thisTypeIsVoid ? thisType : nextUserType + 1, "thisptr"); + + // member funcType* funcptr + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); + int len2 = addFieldMember(dfieldtype, 1, 4, nextUserType, "funcptr"); + + rdtype->fieldlist.len = len1 + len2 + 2; + cbUserTypes += rdtype->fieldlist.len + 2; + + static char name[256]; + nameOfDelegate(thisType, funcType, name, sizeof(name)); + + // nextUserType + 3: struct delegate<> dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, 2, nextUserType + (thisTypeIsVoid ? 1 : 2), 0, 0, 0, 8, name); - - nextUserType += thisTypeIsVoid ? 3 : 4; - addUdtSymbol(nextUserType - 1, name); - return name; -} - -int CV2PDB::appendObjectType (int object_derived_type) -{ - checkUserTypeAlloc(); - - // append object type info + + nextUserType += thisTypeIsVoid ? 3 : 4; + addUdtSymbol(nextUserType - 1, name); + return name; +} + +int CV2PDB::appendObjectType (int object_derived_type) +{ + checkUserTypeAlloc(); + + // append object type info codeview_reftype* rdtype; - codeview_type* dtype; - - int viewHelperType = 0; - bool addViewHelper = true; - if(addViewHelper) - { + codeview_type* dtype; + + int viewHelperType = 0; + bool addViewHelper = true; + if(addViewHelper) + { rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - int helpfieldlistType = nextUserType++; - rdtype->fieldlist.len = 2; - cbUserTypes += rdtype->fieldlist.len + 2; - + rdtype->fieldlist.id = LF_FIELDLIST_V2; + int helpfieldlistType = nextUserType++; + rdtype->fieldlist.len = 2; + cbUserTypes += rdtype->fieldlist.len + 2; + dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, 0, helpfieldlistType, 0, 0, 0, 0, "object_viewhelper"); viewHelperType = nextUserType++; - addUdtSymbol(viewHelperType, "object_viewhelper"); - } - - // vtable + addUdtSymbol(viewHelperType, "object_viewhelper"); + } + + // vtable rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - 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* + 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; + int vtableType = nextUserType++; + + // vtable* dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addPointerType(dtype, vtableType); - int vtablePtrType = nextUserType++; - - // field list + int vtablePtrType = nextUserType++; + + // field list rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - - codeview_fieldtype* dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; - dfieldtype->vfunctab_v2.id = LF_VFUNCTAB_V2; // id correct? - dfieldtype->vfunctab_v2._pad0 = 0; - dfieldtype->vfunctab_v2.type = vtablePtrType; // vtable* - rdtype->fieldlist.len = sizeof(dfieldtype->vfunctab_v2) + 2; - int numElem = 1; - - if(addViewHelper) - { - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + rdtype->fieldlist.len - 2); - rdtype->fieldlist.len += addFieldMember(dfieldtype, 1, 0, viewHelperType, "__viewhelper"); - numElem++; - } - - cbUserTypes += rdtype->generic.len + 2; - int fieldListType = nextUserType++; - -#define OBJECT_SYMBOL "object@Object" - + rdtype->fieldlist.id = LF_FIELDLIST_V2; + + codeview_fieldtype* dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + dfieldtype->vfunctab_v2.id = LF_VFUNCTAB_V2; // id correct? + dfieldtype->vfunctab_v2._pad0 = 0; + dfieldtype->vfunctab_v2.type = vtablePtrType; // vtable* + rdtype->fieldlist.len = sizeof(dfieldtype->vfunctab_v2) + 2; + int numElem = 1; + + if(addViewHelper) + { + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + rdtype->fieldlist.len - 2); + rdtype->fieldlist.len += addFieldMember(dfieldtype, 1, 0, viewHelperType, "__viewhelper"); + numElem++; + } + + cbUserTypes += rdtype->common.len + 2; + int fieldListType = nextUserType++; + +#define OBJECT_SYMBOL "object@Object" + dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, numElem, fieldListType, 0, object_derived_type, vtableType, 4, OBJECT_SYMBOL); - objectType = nextUserType++; - - addUdtSymbol(objectType, OBJECT_SYMBOL); - return objectType; -} - -int CV2PDB::appendPointerType(int pointedType, int attr) -{ - checkUserTypeAlloc(); - - cbUserTypes += addPointerType(userTypes + cbUserTypes, pointedType, attr); - nextUserType++; - - return nextUserType - 1; -} - -int CV2PDB::appendComplex(int cplxtype, int basetype, int elemsize, const char* name) -{ - basetype = translateType(basetype); - + objectType = nextUserType++; + + addUdtSymbol(objectType, OBJECT_SYMBOL); + return objectType; +} + +int CV2PDB::appendPointerType(int pointedType, int attr) +{ + checkUserTypeAlloc(); + + cbUserTypes += addPointerType(userTypes + cbUserTypes, pointedType, attr); + nextUserType++; + + return nextUserType - 1; +} + +int CV2PDB::appendComplex(int cplxtype, int basetype, int elemsize, const char* name) +{ + basetype = translateType(basetype); + codeview_reftype* rdtype; - codeview_type* dtype; - - checkUserTypeAlloc(); - - // nextUserType: field list (size, array) + codeview_type* dtype; + + checkUserTypeAlloc(); + + // nextUserType: field list (size, array) rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - - // member type re - codeview_fieldtype* dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; - int len1 = addFieldMember(dfieldtype, 1, 0, basetype, "re"); - - // member funcType* funcptr - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); - int len2 = addFieldMember(dfieldtype, 1, elemsize, basetype, "im"); - - rdtype->fieldlist.len = len1 + len2 + 2; - cbUserTypes += rdtype->fieldlist.len + 2; + rdtype->fieldlist.id = LF_FIELDLIST_V2; + + // member type re + codeview_fieldtype* dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + int len1 = addFieldMember(dfieldtype, 1, 0, basetype, "re"); + + // member funcType* funcptr + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); + int len2 = addFieldMember(dfieldtype, 1, elemsize, basetype, "im"); + + rdtype->fieldlist.len = len1 + len2 + 2; + cbUserTypes += rdtype->fieldlist.len + 2; int fieldlistType = nextUserType++; - - // nextUserType + 3: struct delegate<> + + // nextUserType + 3: struct delegate<> dtype = (codeview_type*) (userTypes + cbUserTypes); cbUserTypes += addClass(dtype, 2, fieldlistType, 0, 0, 0, 2*elemsize, name); - - int classType = nextUserType++; - addUdtSymbol(classType, name); - - typedefs[cntTypedefs] = cplxtype; - translatedTypedefs[cntTypedefs] = classType; - cntTypedefs++; - - return classType; -} - -int CV2PDB::appendTypedef(int type, const char* name) -{ - checkUserTypeAlloc(); - - int basetype = type; - if(type == 0x78) - basetype = 0x75; // dchar type not understood by debugger, use uint instead - + + int classType = nextUserType++; + addUdtSymbol(classType, name); + + typedefs[cntTypedefs] = cplxtype; + translatedTypedefs[cntTypedefs] = classType; + cntTypedefs++; + + return classType; +} + +int CV2PDB::appendTypedef(int type, const char* name) +{ + checkUserTypeAlloc(); + + int basetype = type; + if(type == 0x78) + basetype = 0x75; // dchar type not understood by debugger, use uint instead + codeview_reftype* rdtype = (codeview_reftype*) (userTypes + cbUserTypes); - rdtype->fieldlist.id = LF_FIELDLIST_V2; - rdtype->fieldlist.len = 2; - cbUserTypes += rdtype->fieldlist.len + 2; + rdtype->fieldlist.id = LF_FIELDLIST_V2; + rdtype->fieldlist.len = 2; + cbUserTypes += rdtype->fieldlist.len + 2; int fieldlistType = nextUserType++; codeview_type* dtype = (codeview_type*) (userTypes + cbUserTypes); - dtype->enumeration_v2.id = (v3 ? LF_ENUM_V3 : LF_ENUM_V2); - dtype->enumeration_v2.type = basetype; - dtype->enumeration_v2.fieldlist = fieldlistType; - dtype->enumeration_v2.count = 0; - dtype->enumeration_v2.property = 0x200; - int len = cstrcpy_v (v3, (BYTE*) &dtype->enumeration_v2.p_name, name); - len += sizeof(dtype->enumeration_v2) - sizeof(dtype->enumeration_v2.p_name); - dtype->enumeration_v2.len = len - 2; - cbUserTypes += len; - - typedefs[cntTypedefs] = type; - translatedTypedefs[cntTypedefs] = nextUserType; - cntTypedefs++; - - nextUserType++; - return nextUserType - 1; -} - -void CV2PDB::appendTypedefs() -{ + dtype->enumeration_v2.id = (v3 ? LF_ENUM_V3 : LF_ENUM_V2); + dtype->enumeration_v2.type = basetype; + dtype->enumeration_v2.fieldlist = fieldlistType; + dtype->enumeration_v2.count = 0; + dtype->enumeration_v2.property = 0x200; + int len = cstrcpy_v (v3, (BYTE*) &dtype->enumeration_v2.p_name, name); + len += sizeof(dtype->enumeration_v2) - sizeof(dtype->enumeration_v2.p_name); + dtype->enumeration_v2.len = len - 2; + cbUserTypes += len; + + typedefs[cntTypedefs] = type; + translatedTypedefs[cntTypedefs] = nextUserType; + cntTypedefs++; + + nextUserType++; + return nextUserType - 1; +} + +void CV2PDB::appendTypedefs() +{ appendTypedef(0x10, "byte"); appendTypedef(0x20, "ubyte"); appendTypedef(0x21, "ushort"); @@ -1666,16 +1666,16 @@ void CV2PDB::appendTypedefs() appendComplex(0x50, 0x40, 4, "cfloat"); appendComplex(0x51, 0x41, 8, "cdouble"); appendComplex(0x52, 0x42, 10, "creal"); -} - +} + bool CV2PDB::initGlobalTypes() { int object_derived_type = 0; for (int m = 0; m < countEntries; m++) { OMFDirEntry* entry = img.getCVEntry(m); - if(entry->SubSection == sstGlobalTypes) - { + if(entry->SubSection == sstGlobalTypes) + { globalTypeHeader = img.CVP(entry->lfo); DWORD* offset = img.CVP(entry->lfo + sizeof(OMFGlobalTypes)); BYTE* typeData = img.CVP(entry->lfo + sizeof(OMFGlobalTypes) + 4*globalTypeHeader->cTypes); @@ -1693,7 +1693,7 @@ bool CV2PDB::initGlobalTypes() *(DWORD*) globalTypes = 4; cbGlobalTypes = 4; - nextUserType = globalTypeHeader->cTypes + 0x1000; + nextUserType = globalTypeHeader->cTypes + 0x1000; appendTypedefs(); @@ -1701,9 +1701,9 @@ bool CV2PDB::initGlobalTypes() { const codeview_type* type = (codeview_type*)(typeData + offset[t]); const codeview_reftype* rtype = (codeview_reftype*)(typeData + offset[t]); - int leaf_len, value; + int leaf_len, value; - int len = type->generic.len + 2; + int len = type->common.len + 2; if (cbGlobalTypes + len + 1000 > allocGlobalTypes) { allocGlobalTypes += len + 1000; @@ -1726,23 +1726,23 @@ bool CV2PDB::initGlobalTypes() continue; } - switch (type->generic.id) + switch (type->common.id) { case LF_OEM_V1: { - codeview_oem_type* oem = (codeview_oem_type*) (&type->generic + 1); + codeview_oem_type* oem = (codeview_oem_type*) (&type->common + 1); - if (oem->generic.oemid == 0x42 && oem->generic.id == 1) + if (oem->common.oemid == 0x42 && oem->common.id == 1) { const char* name = appendDynamicArray(oem->d_dyn_array.index_type, oem->d_dyn_array.elem_type); len = addClass(dtype, 0, 0, kIncomplete, 0, 0, 0, name); } - else if (oem->generic.oemid == 0x42 && oem->generic.id == 3) + else if (oem->common.oemid == 0x42 && oem->common.id == 3) { const char* name = appendDelegate(oem->d_delegate.this_type, oem->d_delegate.func_type); len = addClass(dtype, 0, 0, kIncomplete, 0, 0, 0, name); } - else if (oem->generic.oemid == 0x42 && oem->generic.id == 2) + else if (oem->common.oemid == 0x42 && oem->common.id == 2) { const char* name = appendAssocArray(oem->d_assoc_array.key_type, oem->d_assoc_array.elem_type); len = addClass(dtype, 0, 0, kIncomplete, 0, 0, 0, name); @@ -1767,11 +1767,11 @@ bool CV2PDB::initGlobalTypes() case LF_PROCEDURE_V1: dtype->procedure_v2.id = LF_PROCEDURE_V2; - dtype->procedure_v2.rvtype = translateType(type->procedure_v1.rvtype); - dtype->procedure_v2.call = type->procedure_v1.call; - dtype->procedure_v2.reserved = type->procedure_v1.reserved; - dtype->procedure_v2.params = type->procedure_v1.params; - dtype->procedure_v2.arglist = type->procedure_v1.arglist; + dtype->procedure_v2.rvtype = translateType(type->procedure_v1.rvtype); + dtype->procedure_v2.call = type->procedure_v1.call; + dtype->procedure_v2.reserved = type->procedure_v1.reserved; + dtype->procedure_v2.params = type->procedure_v1.params; + dtype->procedure_v2.arglist = type->procedure_v1.arglist; len = sizeof(dtype->procedure_v2); break; @@ -1782,49 +1782,49 @@ bool CV2PDB::initGlobalTypes() //dtype->struct_v2.id = v3 ? LF_STRUCTURE_V3 : LF_STRUCTURE_V2; dtype->struct_v2.id = v3 ? LF_CLASS_V3 : LF_CLASS_V2; LF_CLASS_V1_struct: - dtype->struct_v2.fieldlist = type->struct_v1.fieldlist; - 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->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 = type->struct_v1.property | 0x200; -#if REMOVE_LF_DERIVED - dtype->struct_v2.derived = 0; -#else - dtype->struct_v2.derived = type->struct_v1.derived; -#endif - dtype->struct_v2.vshape = type->struct_v1.vshape; - leaf_len = numeric_leaf(&value, &type->struct_v1.structlen); - memcpy (&dtype->struct_v2.structlen, &type->struct_v1.structlen, leaf_len); - len = pstrcpy_v(v3, (BYTE*) &dtype->struct_v2.structlen + leaf_len, - (const BYTE*) &type->struct_v1.structlen + leaf_len); - // alternate name can be added here? -#if 0 - if (dtype->struct_v2.id == LF_CLASS_V2) - len += pstrcpy((BYTE*) &dtype->struct_v2.structlen + leaf_len + len, - (const BYTE*) &type->struct_v1.structlen + leaf_len); -#endif - len += leaf_len + sizeof(dtype->struct_v2) - sizeof(type->struct_v2.structlen); - - // remember type index of derived list for object.Object - if (Dversion > 0 && dtype->struct_v2.derived) - if (memcmp((char*) &type->struct_v1.structlen + leaf_len, "\x0dobject.Object", 14) == 0) - object_derived_type = type->struct_v1.derived; - break; - + dtype->struct_v2.fieldlist = type->struct_v1.fieldlist; + 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) + dtype->struct_v2.n_element = countFields((const codeview_reftype*)td); + dtype->struct_v2.property = type->struct_v1.property | 0x200; +#if REMOVE_LF_DERIVED + dtype->struct_v2.derived = 0; +#else + dtype->struct_v2.derived = type->struct_v1.derived; +#endif + dtype->struct_v2.vshape = type->struct_v1.vshape; + leaf_len = numeric_leaf(&value, &type->struct_v1.structlen); + memcpy (&dtype->struct_v2.structlen, &type->struct_v1.structlen, leaf_len); + len = pstrcpy_v(v3, (BYTE*) &dtype->struct_v2.structlen + leaf_len, + (const BYTE*) &type->struct_v1.structlen + leaf_len); + // alternate name can be added here? +#if 0 + if (dtype->struct_v2.id == LF_CLASS_V2) + len += pstrcpy((BYTE*) &dtype->struct_v2.structlen + leaf_len + len, + (const BYTE*) &type->struct_v1.structlen + leaf_len); +#endif + len += leaf_len + sizeof(dtype->struct_v2) - sizeof(type->struct_v2.structlen); + + // remember type index of derived list for object.Object + if (Dversion > 0 && dtype->struct_v2.derived) + if (memcmp((char*) &type->struct_v1.structlen + leaf_len, "\x0dobject.Object", 14) == 0) + object_derived_type = type->struct_v1.derived; + break; + case LF_UNION_V1: dtype->union_v2.id = v3 ? LF_UNION_V3 : LF_UNION_V2; - dtype->union_v2.count = type->union_v1.count; - dtype->union_v2.fieldlist = type->struct_v1.fieldlist; - dtype->union_v2.property = type->struct_v1.property; - leaf_len = numeric_leaf(&value, &type->union_v1.un_len); - memcpy (&dtype->union_v2.un_len, &type->union_v1.un_len, leaf_len); - len = pstrcpy_v(v3, (BYTE*) &dtype->union_v2.un_len + leaf_len, - (const BYTE*) &type->union_v1.un_len + leaf_len); - len += leaf_len + sizeof(dtype->union_v2) - sizeof(type->union_v2.un_len); - break; - + dtype->union_v2.count = type->union_v1.count; + dtype->union_v2.fieldlist = type->struct_v1.fieldlist; + dtype->union_v2.property = type->struct_v1.property; + leaf_len = numeric_leaf(&value, &type->union_v1.un_len); + memcpy (&dtype->union_v2.un_len, &type->union_v1.un_len, leaf_len); + len = pstrcpy_v(v3, (BYTE*) &dtype->union_v2.un_len + leaf_len, + (const BYTE*) &type->union_v1.un_len + leaf_len); + len += leaf_len + sizeof(dtype->union_v2) - sizeof(type->union_v2.un_len); + break; + case LF_POINTER_V1: dtype->pointer_v2.id = LF_POINTER_V2; dtype->pointer_v2.datatype = translateType(type->pointer_v1.datatype); @@ -1845,54 +1845,54 @@ bool CV2PDB::initGlobalTypes() dtype->array_v2.id = v3 ? LF_ARRAY_V3 : LF_ARRAY_V2; dtype->array_v2.elemtype = translateType(type->array_v1.elemtype); dtype->array_v2.idxtype = translateType(type->array_v1.idxtype); - leaf_len = numeric_leaf(&value, &type->array_v1.arrlen); - memcpy (&dtype->array_v2.arrlen, &type->array_v1.arrlen, leaf_len); - len = pstrcpy_v(v3, (BYTE*) &dtype->array_v2.arrlen + leaf_len, - (const BYTE*) &type->array_v1.arrlen + leaf_len); - len += leaf_len + sizeof(dtype->array_v2) - sizeof(dtype->array_v2.arrlen); - // followed by name + leaf_len = numeric_leaf(&value, &type->array_v1.arrlen); + memcpy (&dtype->array_v2.arrlen, &type->array_v1.arrlen, leaf_len); + len = pstrcpy_v(v3, (BYTE*) &dtype->array_v2.arrlen + leaf_len, + (const BYTE*) &type->array_v1.arrlen + leaf_len); + len += leaf_len + sizeof(dtype->array_v2) - sizeof(dtype->array_v2.arrlen); + // followed by name break; - + case LF_MFUNCTION_V1: - dtype->mfunction_v2.id = LF_MFUNCTION_V2; - dtype->mfunction_v2.rvtype = translateType(type->mfunction_v1.rvtype); - clsstype = type->mfunction_v1.class_type; - dtype->mfunction_v2.class_type = translateType(clsstype); - if (clsstype >= 0x1000 && clsstype < 0x1000 + globalTypeHeader->cTypes) - { - // fix class_type to point to class, not pointer to class - codeview_type* ctype = (codeview_type*)(typeData + offset[clsstype - 0x1000]); - 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); - dtype->mfunction_v2.call = type->mfunction_v1.call; - dtype->mfunction_v2.reserved = type->mfunction_v1.reserved; - dtype->mfunction_v2.params = type->mfunction_v1.params; - dtype->mfunction_v2.arglist = type->mfunction_v1.arglist; - dtype->mfunction_v2.this_adjust = type->mfunction_v1.this_adjust; + dtype->mfunction_v2.id = LF_MFUNCTION_V2; + dtype->mfunction_v2.rvtype = translateType(type->mfunction_v1.rvtype); + clsstype = type->mfunction_v1.class_type; + dtype->mfunction_v2.class_type = translateType(clsstype); + if (clsstype >= 0x1000 && clsstype < 0x1000 + globalTypeHeader->cTypes) + { + // 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) + dtype->mfunction_v2.class_type = translateType(ctype->pointer_v1.datatype); + } + dtype->mfunction_v2.this_type = translateType(type->mfunction_v1.this_type); + dtype->mfunction_v2.call = type->mfunction_v1.call; + dtype->mfunction_v2.reserved = type->mfunction_v1.reserved; + dtype->mfunction_v2.params = type->mfunction_v1.params; + dtype->mfunction_v2.arglist = type->mfunction_v1.arglist; + dtype->mfunction_v2.this_adjust = type->mfunction_v1.this_adjust; len = sizeof(dtype->mfunction_v2); break; case LF_ENUM_V1: dtype->enumeration_v2.id = v3 ? LF_ENUM_V3 : LF_ENUM_V2; - dtype->enumeration_v2.count = type->enumeration_v1.count; - dtype->enumeration_v2.type = translateType(type->enumeration_v1.type); - dtype->enumeration_v2.fieldlist = type->enumeration_v1.fieldlist; - dtype->enumeration_v2.property = type->enumeration_v1.property; - len = pstrcpy_v (v3, (BYTE*) &dtype->enumeration_v2.p_name, (BYTE*) &type->enumeration_v1.p_name); - len += sizeof(dtype->enumeration_v2) - sizeof(dtype->enumeration_v2.p_name); + dtype->enumeration_v2.count = type->enumeration_v1.count; + dtype->enumeration_v2.type = translateType(type->enumeration_v1.type); + dtype->enumeration_v2.fieldlist = type->enumeration_v1.fieldlist; + dtype->enumeration_v2.property = type->enumeration_v1.property; + len = pstrcpy_v (v3, (BYTE*) &dtype->enumeration_v2.p_name, (BYTE*) &type->enumeration_v1.p_name); + len += sizeof(dtype->enumeration_v2) - sizeof(dtype->enumeration_v2.p_name); break; case LF_FIELDLIST_V1: case LF_FIELDLIST_V2: - rdtype->fieldlist.id = LF_FIELDLIST_V2; + rdtype->fieldlist.id = LF_FIELDLIST_V2; len = addFields(rdtype, rtype, allocGlobalTypes - cbGlobalTypes) + 4; break; case LF_DERIVED_V1: #if REMOVE_LF_DERIVED - rdtype->generic.id = LF_NULL_V1; + rdtype->common.id = LF_NULL_V1; len = 4; #else rdtype->derived_v2.id = LF_DERIVED_V2; @@ -1915,38 +1915,38 @@ bool CV2PDB::initGlobalTypes() case LF_METHODLIST_V1: { - 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->generic.len + 2) + dtype->common.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) { // type translation? - switch ((*pattr >> 2) & 7) - { - case 4: - case 6: - *dpattr++ = *pattr++; - default: - *dpattr++ = *pattr++; - *dpattr++ = *pattr++; - break; - } + switch ((*pattr >> 2) & 7) + { + case 4: + case 6: + *dpattr++ = *pattr++; + default: + *dpattr++ = *pattr++; + *dpattr++ = *pattr++; + break; + } } len = (char*) dpattr - (char*)dtype; break; } case LF_MODIFIER_V1: dtype->modifier_v2.id = LF_MODIFIER_V2; - dtype->modifier_v2.attribute = type->modifier_v1.attribute; - dtype->modifier_v2.type = translateType(type->modifier_v1.type); + dtype->modifier_v2.attribute = type->modifier_v1.attribute; + dtype->modifier_v2.type = translateType(type->modifier_v1.type); len = sizeof(dtype->modifier_v2); break; case LF_BITFIELD_V1: rdtype->bitfield_v2.id = LF_BITFIELD_V2; - rdtype->bitfield_v2.nbits = rtype->bitfield_v1.nbits; - rdtype->bitfield_v2.bitoff = rtype->bitfield_v1.bitoff; - rdtype->bitfield_v2.type = translateType(rtype->bitfield_v1.type); + rdtype->bitfield_v2.nbits = rtype->bitfield_v1.nbits; + rdtype->bitfield_v2.bitoff = rtype->bitfield_v1.bitoff; + rdtype->bitfield_v2.type = translateType(rtype->bitfield_v1.type); len = sizeof(rdtype->bitfield_v2); break; @@ -1957,71 +1957,71 @@ bool CV2PDB::initGlobalTypes() for (; len & 3; len++) globalTypes[cbGlobalTypes + len] = 0xf4 - (len & 3); - dtype->generic.len = len - 2; + dtype->common.len = len - 2; cbGlobalTypes += len; } - -#if 1 - if(Dversion > 0) - appendObjectType (object_derived_type); -#endif -#if 1 + +#if 1 + if(Dversion > 0) + appendObjectType (object_derived_type); +#endif +#if 1 if (cbGlobalTypes + cbUserTypes > allocGlobalTypes) { allocGlobalTypes += cbUserTypes + 1000; globalTypes = (unsigned char*) realloc(globalTypes, allocGlobalTypes); } - - memcpy (globalTypes + cbGlobalTypes, userTypes, cbUserTypes); - cbGlobalTypes += cbUserTypes; -#endif - } - } - return !hadError(); -} + + memcpy (globalTypes + cbGlobalTypes, userTypes, cbUserTypes); + cbGlobalTypes += cbUserTypes; +#endif + } + } + return !hadError(); +} bool CV2PDB::addTypes() { if (!globalTypes) return true; - if (useGlobalMod) - { - int rc = globalMod()->AddTypes(globalTypes, cbGlobalTypes); - if (rc <= 0) - return setError("cannot add type info to module"); - return true; - } + if (useGlobalMod) + { + int rc = globalMod()->AddTypes(globalTypes, cbGlobalTypes); + if (rc <= 0) + return setError("cannot add type info to module"); + return true; + } for (int m = 0; m < countEntries; m++) { OMFDirEntry* entry = img.getCVEntry(m); - if(entry->SubSection == sstSrcModule) - { - mspdb::Mod* mod = modules[entry->iMod]; - if (!mod) - return setError("sstSrcModule for non-existing module"); - - int rc = mod->AddTypes(globalTypes, cbGlobalTypes); - if (rc <= 0) - return setError("cannot add type info to module"); - } - } - return true; -} + if(entry->SubSection == sstSrcModule) + { + mspdb::Mod* mod = modules[entry->iMod]; + if (!mod) + return setError("sstSrcModule for non-existing module"); + + int rc = mod->AddTypes(globalTypes, cbGlobalTypes); + if (rc <= 0) + return setError("cannot add type info to module"); + } + } + return true; +} bool CV2PDB::markSrcLineInBitmap(int segIndex, int adr) { - if (segIndex < 0 || segIndex >= segMap->cSeg) - return setError("invalid segment info in line number info"); - - int off = adr - segMapDesc[segIndex].offset; - if (off < 0 || off >= (int) segMapDesc[segIndex].cbSeg) - return setError("invalid segment offset in line number info"); - - srcLineStart[segIndex][off] = true; - return true; + if (segIndex < 0 || segIndex >= segMap->cSeg) + return setError("invalid segment info in line number info"); + + int off = adr - segMapDesc[segIndex].offset; + if (off < 0 || off >= (int) segMapDesc[segIndex].cbSeg) + return setError("invalid segment offset in line number info"); + + srcLineStart[segIndex][off] = true; + return true; } bool CV2PDB::createSrcLineBitmap() @@ -2048,52 +2048,52 @@ bool CV2PDB::createSrcLineBitmap() for (int m = 0; m < countEntries; m++) { OMFDirEntry* entry = img.getCVEntry(m); - if(entry->SubSection == sstSrcModule) - { - // mark the beginning of each line - OMFSourceModule* sourceModule = img.CVP(entry->lfo); - int* segStartEnd = img.CVP(entry->lfo + 4 + 4 * sourceModule->cFile); - short* seg = img.CVP(entry->lfo + 4 + 4 * sourceModule->cFile + 8 * sourceModule->cSeg); - - for (int f = 0; f < sourceModule->cFile; f++) - { - int cvoff = entry->lfo + sourceModule->baseSrcFile[f]; - OMFSourceFile* sourceFile = img.CVP (cvoff); - int* lnSegStartEnd = img.CVP(cvoff + 4 + 4 * sourceFile->cSeg); - - for (int s = 0; s < sourceFile->cSeg; s++) - { - int lnoff = entry->lfo + sourceFile->baseSrcLn[s]; - OMFSourceLine* sourceLine = img.CVP (lnoff); - short* lineNo = img.CVP (lnoff + 4 + 4 * sourceLine->cLnOff); - - int cnt = sourceLine->cLnOff; - int segIndex = segFrame2Index[sourceLine->Seg]; - - // also mark the start of the line info segment - if (!markSrcLineInBitmap(segIndex, lnSegStartEnd[2*s])) - return false; - - for (int ln = 0; ln < cnt; ln++) - if (!markSrcLineInBitmap(segIndex, sourceLine->offset[ln])) - return false; - } - } - } - if (entry->SubSection == sstModule) - { - // mark the beginning of each section - OMFModule* module = img.CVP(entry->lfo); - OMFSegDesc* segDesc = img.CVP(entry->lfo + sizeof(OMFModule)); - + if(entry->SubSection == sstSrcModule) + { + // mark the beginning of each line + OMFSourceModule* sourceModule = img.CVP(entry->lfo); + int* segStartEnd = img.CVP(entry->lfo + 4 + 4 * sourceModule->cFile); + short* seg = img.CVP(entry->lfo + 4 + 4 * sourceModule->cFile + 8 * sourceModule->cSeg); + + for (int f = 0; f < sourceModule->cFile; f++) + { + int cvoff = entry->lfo + sourceModule->baseSrcFile[f]; + OMFSourceFile* sourceFile = img.CVP (cvoff); + int* lnSegStartEnd = img.CVP(cvoff + 4 + 4 * sourceFile->cSeg); + + for (int s = 0; s < sourceFile->cSeg; s++) + { + int lnoff = entry->lfo + sourceFile->baseSrcLn[s]; + OMFSourceLine* sourceLine = img.CVP (lnoff); + short* lineNo = img.CVP (lnoff + 4 + 4 * sourceLine->cLnOff); + + int cnt = sourceLine->cLnOff; + int segIndex = segFrame2Index[sourceLine->Seg]; + + // also mark the start of the line info segment + if (!markSrcLineInBitmap(segIndex, lnSegStartEnd[2*s])) + return false; + + for (int ln = 0; ln < cnt; ln++) + if (!markSrcLineInBitmap(segIndex, sourceLine->offset[ln])) + return false; + } + } + } + if (entry->SubSection == sstModule) + { + // mark the beginning of each section + OMFModule* module = img.CVP(entry->lfo); + OMFSegDesc* segDesc = img.CVP(entry->lfo + sizeof(OMFModule)); + for (int s = 0; s < module->cSeg; s++) { - int seg = segDesc[s].Seg; - int segIndex = seg >= 0 && seg < segMap->cSeg ? segFrame2Index[seg] : -1; - if (!markSrcLineInBitmap(segIndex, segDesc[s].Off)) - return false; + int seg = segDesc[s].Seg; + int segIndex = seg >= 0 && seg < segMap->cSeg ? segFrame2Index[seg] : -1; + if (!markSrcLineInBitmap(segIndex, segDesc[s].Off)) + return false; } - } + } } return true; @@ -2104,10 +2104,10 @@ int CV2PDB::getNextSrcLine(int seg, unsigned int off) if (!createSrcLineBitmap()) return -1; - int s = segFrame2Index[seg]; - if (s < 0) - return -1; - + int s = segFrame2Index[seg]; + if (s < 0) + return -1; + off -= segMapDesc[s].offset; if (off < 0 || off >= segMapDesc[s].cbSeg || off > LONG_MAX) return 0; @@ -2124,53 +2124,53 @@ bool CV2PDB::addSrcLines() for (int m = 0; m < countEntries; m++) { OMFDirEntry* entry = img.getCVEntry(m); - if(entry->SubSection == sstSrcModule) - { - mspdb::Mod* mod = useGlobalMod ? globalMod() : modules[entry->iMod]; - if (!mod) - return setError("sstSrcModule for non-existing module"); - - OMFSourceModule* sourceModule = img.CVP(entry->lfo); - int* segStartEnd = img.CVP(entry->lfo + 4 + 4 * sourceModule->cFile); - short* seg = img.CVP(entry->lfo + 4 + 4 * sourceModule->cFile + 8 * sourceModule->cSeg); - - for (int f = 0; f < sourceModule->cFile; f++) - { - int cvoff = entry->lfo + sourceModule->baseSrcFile[f]; - OMFSourceFile* sourceFile = img.CVP (cvoff); - int* lnSegStartEnd = img.CVP(cvoff + 4 + 4 * sourceFile->cSeg); - BYTE* pname = (BYTE*)(lnSegStartEnd + 2 * sourceFile->cSeg); - char* name = p2c (pname); - - for (int s = 0; s < sourceFile->cSeg; s++) - { - int lnoff = entry->lfo + sourceFile->baseSrcLn[s]; - OMFSourceLine* sourceLine = img.CVP (lnoff); - unsigned short* lineNo = img.CVP (lnoff + 4 + 4 * sourceLine->cLnOff); - - int seg = sourceLine->Seg; - int cnt = sourceLine->cLnOff; - if(cnt <= 0) - continue; - int segoff = lnSegStartEnd[2*s]; - // lnSegStartEnd[2*s + 1] only spans until the first byte of the last source line - int segend = getNextSrcLine(seg, sourceLine->offset[cnt-1]); - int seglength = (segend >= 0 ? segend - 1 - segoff : lnSegStartEnd[2*s + 1] - segoff); - - mspdb::LineInfoEntry* lineInfo = new mspdb::LineInfoEntry[cnt]; - for (int ln = 0; ln < cnt; ln++) - { - lineInfo[ln].offset = sourceLine->offset[ln] - segoff; - lineInfo[ln].line = lineNo[ln] - lineNo[0]; - } - int rc = mod->AddLines(name, seg, segoff, seglength, segoff, lineNo[0], - (unsigned char*) lineInfo, cnt * sizeof(*lineInfo)); - if (rc <= 0) - return setError("cannot add line number info to module"); - delete [] lineInfo; - } - } - } + if(entry->SubSection == sstSrcModule) + { + mspdb::Mod* mod = useGlobalMod ? globalMod() : modules[entry->iMod]; + if (!mod) + return setError("sstSrcModule for non-existing module"); + + OMFSourceModule* sourceModule = img.CVP(entry->lfo); + int* segStartEnd = img.CVP(entry->lfo + 4 + 4 * sourceModule->cFile); + short* seg = img.CVP(entry->lfo + 4 + 4 * sourceModule->cFile + 8 * sourceModule->cSeg); + + for (int f = 0; f < sourceModule->cFile; f++) + { + int cvoff = entry->lfo + sourceModule->baseSrcFile[f]; + OMFSourceFile* sourceFile = img.CVP (cvoff); + int* lnSegStartEnd = img.CVP(cvoff + 4 + 4 * sourceFile->cSeg); + BYTE* pname = (BYTE*)(lnSegStartEnd + 2 * sourceFile->cSeg); + char* name = p2c (pname); + + for (int s = 0; s < sourceFile->cSeg; s++) + { + int lnoff = entry->lfo + sourceFile->baseSrcLn[s]; + OMFSourceLine* sourceLine = img.CVP (lnoff); + unsigned short* lineNo = img.CVP (lnoff + 4 + 4 * sourceLine->cLnOff); + + int seg = sourceLine->Seg; + int cnt = sourceLine->cLnOff; + if(cnt <= 0) + continue; + int segoff = lnSegStartEnd[2*s]; + // lnSegStartEnd[2*s + 1] only spans until the first byte of the last source line + int segend = getNextSrcLine(seg, sourceLine->offset[cnt-1]); + int seglength = (segend >= 0 ? segend - 1 - segoff : lnSegStartEnd[2*s + 1] - segoff); + + mspdb::LineInfoEntry* lineInfo = new mspdb::LineInfoEntry[cnt]; + for (int ln = 0; ln < cnt; ln++) + { + lineInfo[ln].offset = sourceLine->offset[ln] - segoff; + lineInfo[ln].line = lineNo[ln] - lineNo[0]; + } + int rc = mod->AddLines(name, seg, segoff, seglength, segoff, lineNo[0], + (unsigned char*) lineInfo, cnt * sizeof(*lineInfo)); + if (rc <= 0) + return setError("cannot add line number info to module"); + delete [] lineInfo; + } + } + } } return true; } @@ -2180,64 +2180,64 @@ bool CV2PDB::addPublics() for (int m = 0; m < countEntries; m++) { OMFDirEntry* entry = img.getCVEntry(m); - if(entry->SubSection == sstGlobalPub) - { - mspdb::Mod* mod = 0; - if (entry->iMod < countEntries) - mod = useGlobalMod ? globalMod() : modules[entry->iMod]; - - OMFSymHash* header = img.CVP(entry->lfo); - BYTE* symbols = img.CVP(entry->lfo + sizeof(OMFSymHash)); - int length; - for (unsigned int i = 0; i < header->cbSymbol; i += length) - { - union codeview_symbol* sym = (union codeview_symbol*)(symbols + i); - length = sym->generic.len + 2; - if (!sym->generic.id || length < 4) - break; - - int rc; - switch (sym->generic.id) - { - case S_GDATA_V1: - case S_LDATA_V1: - case S_PUB_V1: - char symname[2000]; - dsym2c((BYTE*)sym->data_v1.p_name.name, sym->data_v1.p_name.namelen, symname, sizeof(symname)); - int type = translateType(sym->data_v1.symtype); - if (mod) - rc = mod->AddPublic2(symname, sym->data_v1.segment, sym->data_v1.offset, type); - else - rc = dbi->AddPublic2(symname, sym->data_v1.segment, sym->data_v1.offset, type); - if (rc <= 0) - return setError("cannot add public"); - break; - } - } - } - } - return true; -} + if(entry->SubSection == sstGlobalPub) + { + mspdb::Mod* mod = 0; + if (entry->iMod < countEntries) + mod = useGlobalMod ? globalMod() : modules[entry->iMod]; + + OMFSymHash* header = img.CVP(entry->lfo); + BYTE* symbols = img.CVP(entry->lfo + sizeof(OMFSymHash)); + int length; + 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) + break; + + int rc; + switch (sym->common.id) + { + case S_GDATA_V1: + case S_LDATA_V1: + case S_PUB_V1: + char symname[2000]; + dsym2c((BYTE*)sym->data_v1.p_name.name, sym->data_v1.p_name.namelen, symname, sizeof(symname)); + int type = translateType(sym->data_v1.symtype); + if (mod) + rc = mod->AddPublic2(symname, sym->data_v1.segment, sym->data_v1.offset, type); + else + rc = dbi->AddPublic2(symname, sym->data_v1.segment, sym->data_v1.offset, type); + if (rc <= 0) + return setError("cannot add public"); + break; + } + } + } + } + return true; +} bool CV2PDB::initGlobalSymbols() { for (int m = 0; m < countEntries; m++) { OMFDirEntry* entry = img.getCVEntry(m); - if (entry->SubSection == sstGlobalSym) - { - BYTE* symbols = img.CVP(entry->lfo); - OMFSymHash* header = (OMFSymHash*) symbols; - globalSymbols = symbols + sizeof(OMFSymHash); - cbGlobalSymbols = header->cbSymbol; - } - if (entry->SubSection == sstStaticSym) - { - BYTE* symbols = img.CVP(entry->lfo); - OMFSymHash* header = (OMFSymHash*) symbols; - staticSymbols = symbols + sizeof(OMFSymHash); - cbStaticSymbols = header->cbSymbol; - } + if (entry->SubSection == sstGlobalSym) + { + BYTE* symbols = img.CVP(entry->lfo); + OMFSymHash* header = (OMFSymHash*) symbols; + globalSymbols = symbols + sizeof(OMFSymHash); + cbGlobalSymbols = header->cbSymbol; + } + if (entry->SubSection == sstStaticSym) + { + BYTE* symbols = img.CVP(entry->lfo); + OMFSymHash* header = (OMFSymHash*) symbols; + staticSymbols = symbols + sizeof(OMFSymHash); + cbStaticSymbols = header->cbSymbol; + } } return true; } @@ -2248,184 +2248,184 @@ int CV2PDB::copySymbols(BYTE* srcSymbols, int srcSize, BYTE* destSymbols, int de codeview_symbol* lastGProcSym = 0; int type, length, destlength; int leaf_len, value; - for (int i = 0; i < srcSize; i += length) - { - codeview_symbol* sym = (codeview_symbol*)(srcSymbols + i); - 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->generic.id) - { - case S_UDT_V1: - dsym->udt_v1.type = translateType(sym->udt_v1.type); - for(int p = 0; p < dsym->udt_v1.p_name.namelen; p++) - if(dsym->udt_v1.p_name.name[p] == '.') - dsym->udt_v1.p_name.name[p] = '@'; - //sym->udt_v1.type = 0x101e; - break; - - case S_LDATA_V1: - dsym->data_v2.id = v3 ? S_LDATA_V3 : S_LDATA_V2; - goto case_DATA_V1; - case S_GDATA_V1: - dsym->data_v2.id = v3 ? S_GDATA_V3 : S_GDATA_V2; - case_DATA_V1: - dsym->data_v2.symtype = translateType(sym->data_v1.symtype); - dsym->data_v2.offset = sym->data_v1.offset; - dsym->data_v2.offset = sym->data_v1.offset; - dsym->data_v2.segment = sym->data_v1.segment; - destlength = pstrcpy_v (v3, (BYTE*) &dsym->data_v2.p_name, (BYTE*) &sym->data_v1.p_name); - destlength += (BYTE*) &dsym->data_v2.p_name - (BYTE*) dsym; - dsym->data_v2.len = destlength - 2; - break; - - case S_LPROC_V1: - dsym->proc_v2.id = v3 ? S_LPROC_V3 : S_LPROC_V2; - goto case_PROC_V1; - case S_GPROC_V1: - dsym->proc_v2.id = v3 ? S_GPROC_V3 : S_GPROC_V2; - case_PROC_V1: - dsym->proc_v2.pparent = sym->proc_v1.pparent; - dsym->proc_v2.pend = sym->proc_v1.pend; - dsym->proc_v2.next = sym->proc_v1.next; - dsym->proc_v2.proc_len = sym->proc_v1.proc_len; - dsym->proc_v2.debug_start = sym->proc_v1.debug_start; - dsym->proc_v2.debug_end = sym->proc_v1.debug_end; - dsym->proc_v2.offset = sym->proc_v1.offset; - dsym->proc_v2.segment = sym->proc_v1.segment; - dsym->proc_v2.proctype = translateType(sym->proc_v1.proctype); - dsym->proc_v2.flags = sym->proc_v1.flags; - - destlength = pstrcpy_v (v3, (BYTE*) &dsym->proc_v2.p_name, (BYTE*) &sym->proc_v1.p_name); - destlength += (BYTE*) &dsym->proc_v2.p_name - (BYTE*) dsym; - dsym->data_v2.len = destlength - 2; - - lastGProcSym = dsym; - break; - - case S_BPREL_V1: - type = dsym->stack_v1.symtype; -#if 1 - if (type == 0 && p2ccmp(dsym->stack_v1.p_name, "@sblk")) - { - unsigned offset = dsym->stack_v1.offset & 0xffff; - unsigned length = dsym->stack_v1.offset >> 16; - dsym->block_v3.id = S_BLOCK_V3; - dsym->block_v3.parent = 0; - dsym->block_v3.end = 0; // destSize + sizeof(dsym->block_v3) + 12; - dsym->block_v3.length = length; - dsym->block_v3.offset = offset + (lastGProcSym ? lastGProcSym->proc_v2.offset : 0); - dsym->block_v3.segment = (lastGProcSym ? lastGProcSym->proc_v2.segment : 0); - dsym->block_v3.name[0] = 0; - destlength = sizeof(dsym->block_v3); - dsym->data_v2.len = destlength - 2; - } - else if (type == 0 && p2ccmp(dsym->stack_v1.p_name, "@send")) - { - destlength = 4; - dsym->generic.id = S_END_V1; - dsym->generic.len = destlength - 2; - } -#endif - if (p2ccmp(dsym->stack_v1.p_name, "this")) - { - if (lastGProcSym) - lastGProcSym->proc_v2.proctype = findMemberFunctionType(lastGProcSym, type); - if (thisIsNotRef && pointerTypes) - { -#if 0 - // insert function info before this - memset (&dsym->funcinfo_32, 0, sizeof (dsym->funcinfo_32)); - dsym->funcinfo_32.id = S_FUNCINFO_32; - dsym->funcinfo_32.len = sizeof (dsym->funcinfo_32) - 2; - dsym->funcinfo_32.sizeLocals = 4; - dsym->funcinfo_32.info = 0x220; - destSize += sizeof (dsym->funcinfo_32); - codeview_symbol* dsym = (codeview_symbol*)(destSymbols + destSize); - memcpy(dsym, sym, length); -#endif -#if 0 - // create another "this" symbol that is a pointer to the object, not a reference - destSize += length; - codeview_symbol* dsym = (codeview_symbol*)(destSymbols + destSize); - memcpy(dsym, sym, length); -#endif - if (type >= 0x1000 && pointerTypes[type - 0x1000]) - type = pointerTypes[type - 0x1000]; - } - } - else if(Dversion == 0) - { - int p = -1; - for(int i = 0; i < dsym->stack_v1.p_name.namelen; i++) - if(dsym->stack_v1.p_name.name[i] == ':') - p = i + 1; - if(p > 0) - { - for(int i = p; i < dsym->stack_v1.p_name.namelen; i++) - dsym->stack_v1.p_name.name[i - p] = dsym->stack_v1.p_name.name[i]; - dsym->stack_v1.p_name.namelen -= p; - destlength = sizeof(dsym->stack_v1) + dsym->stack_v1.p_name.namelen - 1; + 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) + break; + + codeview_symbol* dsym = (codeview_symbol*)(destSymbols + destSize); + memcpy(dsym, sym, length); + destlength = length; + + switch (sym->common.id) + { + case S_UDT_V1: + dsym->udt_v1.type = translateType(sym->udt_v1.type); + for(int p = 0; p < dsym->udt_v1.p_name.namelen; p++) + if(dsym->udt_v1.p_name.name[p] == '.') + dsym->udt_v1.p_name.name[p] = '@'; + //sym->udt_v1.type = 0x101e; + break; + + case S_LDATA_V1: + dsym->data_v2.id = v3 ? S_LDATA_V3 : S_LDATA_V2; + goto case_DATA_V1; + case S_GDATA_V1: + dsym->data_v2.id = v3 ? S_GDATA_V3 : S_GDATA_V2; + case_DATA_V1: + dsym->data_v2.symtype = translateType(sym->data_v1.symtype); + dsym->data_v2.offset = sym->data_v1.offset; + dsym->data_v2.offset = sym->data_v1.offset; + dsym->data_v2.segment = sym->data_v1.segment; + destlength = pstrcpy_v (v3, (BYTE*) &dsym->data_v2.p_name, (BYTE*) &sym->data_v1.p_name); + destlength += (BYTE*) &dsym->data_v2.p_name - (BYTE*) dsym; + dsym->data_v2.len = destlength - 2; + break; + + case S_LPROC_V1: + dsym->proc_v2.id = v3 ? S_LPROC_V3 : S_LPROC_V2; + goto case_PROC_V1; + case S_GPROC_V1: + dsym->proc_v2.id = v3 ? S_GPROC_V3 : S_GPROC_V2; + case_PROC_V1: + dsym->proc_v2.pparent = sym->proc_v1.pparent; + dsym->proc_v2.pend = sym->proc_v1.pend; + dsym->proc_v2.next = sym->proc_v1.next; + dsym->proc_v2.proc_len = sym->proc_v1.proc_len; + dsym->proc_v2.debug_start = sym->proc_v1.debug_start; + dsym->proc_v2.debug_end = sym->proc_v1.debug_end; + dsym->proc_v2.offset = sym->proc_v1.offset; + dsym->proc_v2.segment = sym->proc_v1.segment; + dsym->proc_v2.proctype = translateType(sym->proc_v1.proctype); + dsym->proc_v2.flags = sym->proc_v1.flags; + + destlength = pstrcpy_v (v3, (BYTE*) &dsym->proc_v2.p_name, (BYTE*) &sym->proc_v1.p_name); + destlength += (BYTE*) &dsym->proc_v2.p_name - (BYTE*) dsym; + dsym->data_v2.len = destlength - 2; + + lastGProcSym = dsym; + break; + + case S_BPREL_V1: + type = dsym->stack_v1.symtype; +#if 1 + if (type == 0 && p2ccmp(dsym->stack_v1.p_name, "@sblk")) + { + unsigned offset = dsym->stack_v1.offset & 0xffff; + unsigned length = dsym->stack_v1.offset >> 16; + dsym->block_v3.id = S_BLOCK_V3; + dsym->block_v3.parent = 0; + dsym->block_v3.end = 0; // destSize + sizeof(dsym->block_v3) + 12; + dsym->block_v3.length = length; + dsym->block_v3.offset = offset + (lastGProcSym ? lastGProcSym->proc_v2.offset : 0); + dsym->block_v3.segment = (lastGProcSym ? lastGProcSym->proc_v2.segment : 0); + dsym->block_v3.name[0] = 0; + destlength = sizeof(dsym->block_v3); + dsym->data_v2.len = destlength - 2; + } + else if (type == 0 && p2ccmp(dsym->stack_v1.p_name, "@send")) + { + destlength = 4; + dsym->common.id = S_END_V1; + dsym->common.len = destlength - 2; + } +#endif + if (p2ccmp(dsym->stack_v1.p_name, "this")) + { + if (lastGProcSym) + lastGProcSym->proc_v2.proctype = findMemberFunctionType(lastGProcSym, type); + if (thisIsNotRef && pointerTypes) + { +#if 0 + // insert function info before this + memset (&dsym->funcinfo_32, 0, sizeof (dsym->funcinfo_32)); + dsym->funcinfo_32.id = S_FUNCINFO_32; + dsym->funcinfo_32.len = sizeof (dsym->funcinfo_32) - 2; + dsym->funcinfo_32.sizeLocals = 4; + dsym->funcinfo_32.info = 0x220; + destSize += sizeof (dsym->funcinfo_32); + codeview_symbol* dsym = (codeview_symbol*)(destSymbols + destSize); + memcpy(dsym, sym, length); +#endif +#if 0 + // create another "this" symbol that is a pointer to the object, not a reference + destSize += length; + codeview_symbol* dsym = (codeview_symbol*)(destSymbols + destSize); + memcpy(dsym, sym, length); +#endif + if (type >= 0x1000 && pointerTypes[type - 0x1000]) + type = pointerTypes[type - 0x1000]; + } + } + else if(Dversion == 0) + { + int p = -1; + for(int i = 0; i < dsym->stack_v1.p_name.namelen; i++) + if(dsym->stack_v1.p_name.name[i] == ':') + p = i + 1; + if(p > 0) + { + for(int i = p; i < dsym->stack_v1.p_name.namelen; i++) + dsym->stack_v1.p_name.name[i - p] = dsym->stack_v1.p_name.name[i]; + dsym->stack_v1.p_name.namelen -= p; + destlength = sizeof(dsym->stack_v1) + dsym->stack_v1.p_name.namelen - 1; for (; destlength & 3; destlength++) destSymbols[destSize + destlength] = 0; dsym->stack_v1.len = destlength - 2; - } - } - dsym->stack_v1.symtype = translateType(type); - //sym->stack_v1.symtype = 0x1012; - break; - case S_ENDARG_V1: - case S_RETURN_V1: - case S_SSEARCH_V1: - break; - case S_END_V1: - lastGProcSym = 0; - break; - case S_COMPILAND_V1: - if (((dsym->compiland_v1.unknown >> 8) & 0xFF) == 0) // C? - dsym->compiland_v1.unknown = (dsym->compiland_v1.unknown & ~0xFF00 | 0x100); // C++ - break; - case S_PROCREF_V1: - case S_DATAREF_V1: - case S_LPROCREF_V1: - if(Dversion > 0) - { - // dmd does not add a string, but it's not obvious to detect whether it exists or not - if (dsym->procref_v1.len != sizeof(dsym->procref_v1) - 4) - break; - - dsym->procref_v1.p_name.namelen = 0; - memset (dsym->procref_v1.p_name.name, 0, 3); // also 4-byte alignment assumed - destlength += 4; - } - else - // throw entry away, it's use is unknown anyway, and it causes a lot of trouble - destlength = 0; - break; - - case S_CONSTANT_V1: - dsym->constant_v2.id = v3 ? S_CONSTANT_V3 : S_CONSTANT_V2; - dsym->constant_v2.type = translateType(sym->constant_v1.type); - leaf_len = numeric_leaf(&value, &sym->constant_v1.cvalue); - memcpy(&dsym->constant_v2.cvalue, &sym->constant_v1.cvalue, leaf_len); - destlength = pstrcpy_v (v3, (BYTE*) &dsym->constant_v2.cvalue + leaf_len, - (BYTE*) &sym->constant_v1.cvalue + leaf_len); - destlength += sizeof(dsym->constant_v2) - sizeof(dsym->constant_v2.cvalue) + leaf_len; - dsym->constant_v2.len = destlength - 2; - break; - - case S_ALIGN_V1: - continue; // throw away - break; - - default: - sym = sym; - break; + } + } + dsym->stack_v1.symtype = translateType(type); + //sym->stack_v1.symtype = 0x1012; + break; + case S_ENDARG_V1: + case S_RETURN_V1: + case S_SSEARCH_V1: + break; + case S_END_V1: + lastGProcSym = 0; + break; + case S_COMPILAND_V1: + if (((dsym->compiland_v1.unknown >> 8) & 0xFF) == 0) // C? + dsym->compiland_v1.unknown = (dsym->compiland_v1.unknown & ~0xFF00 | 0x100); // C++ + break; + case S_PROCREF_V1: + case S_DATAREF_V1: + case S_LPROCREF_V1: + if(Dversion > 0) + { + // dmd does not add a string, but it's not obvious to detect whether it exists or not + if (dsym->procref_v1.len != sizeof(dsym->procref_v1) - 4) + break; + + dsym->procref_v1.p_name.namelen = 0; + memset (dsym->procref_v1.p_name.name, 0, 3); // also 4-byte alignment assumed + destlength += 4; + } + else + // throw entry away, it's use is unknown anyway, and it causes a lot of trouble + destlength = 0; + break; + + case S_CONSTANT_V1: + dsym->constant_v2.id = v3 ? S_CONSTANT_V3 : S_CONSTANT_V2; + dsym->constant_v2.type = translateType(sym->constant_v1.type); + leaf_len = numeric_leaf(&value, &sym->constant_v1.cvalue); + memcpy(&dsym->constant_v2.cvalue, &sym->constant_v1.cvalue, leaf_len); + destlength = pstrcpy_v (v3, (BYTE*) &dsym->constant_v2.cvalue + leaf_len, + (BYTE*) &sym->constant_v1.cvalue + leaf_len); + destlength += sizeof(dsym->constant_v2) - sizeof(dsym->constant_v2.cvalue) + leaf_len; + dsym->constant_v2.len = destlength - 2; + break; + + case S_ALIGN_V1: + continue; // throw away + break; + + default: + sym = sym; + break; } destSize += destlength; @@ -2441,65 +2441,65 @@ bool CV2PDB::addUdtSymbol(int type, const char* name) udtSymbols = (BYTE*) realloc(udtSymbols, allocUdtSymbols); } - codeview_symbol* sym = (codeview_symbol*) (udtSymbols + cbUdtSymbols); - sym->udt_v1.id = S_UDT_V1; - sym->udt_v1.type = translateType(type); - strcpy (sym->udt_v1.p_name.name, name); - sym->udt_v1.p_name.namelen = strlen(sym->udt_v1.p_name.name); - sym->udt_v1.len = sizeof(sym->udt_v1) + sym->udt_v1.p_name.namelen - 1 - 2; - cbUdtSymbols += sym->udt_v1.len + 2; - - return true; + codeview_symbol* sym = (codeview_symbol*) (udtSymbols + cbUdtSymbols); + sym->udt_v1.id = S_UDT_V1; + sym->udt_v1.type = translateType(type); + strcpy (sym->udt_v1.p_name.name, name); + sym->udt_v1.p_name.namelen = strlen(sym->udt_v1.p_name.name); + sym->udt_v1.len = sizeof(sym->udt_v1) + sym->udt_v1.p_name.namelen - 1 - 2; + cbUdtSymbols += sym->udt_v1.len + 2; + + return true; } bool CV2PDB::addSymbols(mspdb::Mod* mod, BYTE* symbols, int cb, bool addGlobals) -{ - int prefix = 4; // mod == globmod ? 3 : 4; - int words = (cb + cbGlobalSymbols + cbStaticSymbols + cbUdtSymbols + 3) / 4 + prefix; - DWORD* data = new DWORD[2 * words + 1000]; - - int databytes = copySymbols(symbols, cb, (BYTE*) (data + prefix), 0); - +{ + int prefix = 4; // mod == globmod ? 3 : 4; + int words = (cb + cbGlobalSymbols + cbStaticSymbols + cbUdtSymbols + 3) / 4 + prefix; + DWORD* data = new DWORD[2 * words + 1000]; + + int databytes = copySymbols(symbols, cb, (BYTE*) (data + prefix), 0); + bool rc = writeSymbols(mod, data, databytes, prefix, addGlobals); - delete [] data; - return rc; -} + delete [] data; + return rc; +} bool CV2PDB::writeSymbols(mspdb::Mod* mod, DWORD* data, int databytes, int prefix, bool addGlobals) -{ - if (addGlobals && staticSymbols) - databytes = copySymbols(staticSymbols, cbStaticSymbols, (BYTE*) (data + prefix), databytes); - if (addGlobals && globalSymbols) - databytes = copySymbols(globalSymbols, cbGlobalSymbols, (BYTE*) (data + prefix), databytes); - if (addGlobals && udtSymbols) - databytes = copySymbols(udtSymbols, cbUdtSymbols, (BYTE*) (data + prefix), databytes); - - data[0] = 4; - data[1] = 0xf1; - data[2] = databytes + 4 * (prefix - 3); - if (prefix > 3) - data[3] = 1; - int rc = mod->AddSymbols((BYTE*) data, ((databytes + 3) / 4 + prefix) * 4); - if (rc <= 0) - return setError("cannot add symbols to module"); - return true; +{ + if (addGlobals && staticSymbols) + databytes = copySymbols(staticSymbols, cbStaticSymbols, (BYTE*) (data + prefix), databytes); + if (addGlobals && globalSymbols) + databytes = copySymbols(globalSymbols, cbGlobalSymbols, (BYTE*) (data + prefix), databytes); + if (addGlobals && udtSymbols) + databytes = copySymbols(udtSymbols, cbUdtSymbols, (BYTE*) (data + prefix), databytes); + + data[0] = 4; + data[1] = 0xf1; + data[2] = databytes + 4 * (prefix - 3); + if (prefix > 3) + data[3] = 1; + int rc = mod->AddSymbols((BYTE*) data, ((databytes + 3) / 4 + prefix) * 4); + if (rc <= 0) + return setError("cannot add symbols to module"); + return true; } bool CV2PDB::addSymbols(int iMod, BYTE* symbols, int cb, bool addGlobals) { mspdb::Mod* mod = 0; - if (iMod < countEntries) - mod = modules[iMod]; - for (int i = 0; !mod && i < countEntries; i++) - mod = modules[i]; // add global symbols to first module - if (!mod) - mod = globalMod(); - if (!mod) - return setError("no module to set symbols"); - + if (iMod < countEntries) + mod = modules[iMod]; + for (int i = 0; !mod && i < countEntries; i++) + mod = modules[i]; // add global symbols to first module + if (!mod) + mod = globalMod(); + if (!mod) + return setError("no module to set symbols"); + return addSymbols(mod, symbols, cb, addGlobals); -} - +} + bool CV2PDB::addSymbols() { if (!initGlobalSymbols()) @@ -2509,33 +2509,33 @@ bool CV2PDB::addSymbols() DWORD* data = 0; int databytes = 0; if (useGlobalMod) - data = new DWORD[2 * img.getCVSize() + 1000]; // enough for all symbols + data = new DWORD[2 * img.getCVSize() + 1000]; // enough for all symbols bool addGlobals = true; for (int m = 0; m < countEntries; m++) { OMFDirEntry* entry = img.getCVEntry(m); - mspdb::Mod* mod = 0; - BYTE* symbols = img.CVP(entry->lfo); + mspdb::Mod* mod = 0; + BYTE* symbols = img.CVP(entry->lfo); switch(entry->SubSection) { - case sstAlignSym: + case sstAlignSym: if (useGlobalMod) - databytes = copySymbols(symbols + 4, entry->cb - 4, (BYTE*) (data + prefix), databytes); - else if (!addSymbols (entry->iMod, symbols + 4, entry->cb - 4, addGlobals)) - return false; - addGlobals = false; - break; - - case sstStaticSym: - case sstGlobalSym: - break; // handled in initGlobalSymbols - } + databytes = copySymbols(symbols + 4, entry->cb - 4, (BYTE*) (data + prefix), databytes); + else if (!addSymbols (entry->iMod, symbols + 4, entry->cb - 4, addGlobals)) + return false; + addGlobals = false; + break; + + case sstStaticSym: + case sstGlobalSym: + break; // handled in initGlobalSymbols + } } bool rc = true; if (useGlobalMod) - rc = writeSymbols (globalMod(), data, databytes, prefix, true); + rc = writeSymbols (globalMod(), data, databytes, prefix, true); delete [] data; return rc; diff --git a/src/demangle.cpp b/src/demangle.cpp index 883680c..87bef71 100644 --- a/src/demangle.cpp +++ b/src/demangle.cpp @@ -183,6 +183,18 @@ public: hasthisptr = true; goto Lagain; + case 'y': + p = "immutable(" + parseType() + ")"; + goto L1; + + case 'x': + p = "const(" + parseType() + ")"; + goto L1; + + case 'O': + p = "shared(" + parseType() + ")"; + goto L1; + case 'F': // D function case 'U': // C function case 'W': // Windows function @@ -214,7 +226,7 @@ public: goto Ldefault; case 'K': - args += "inout "; + args += "ref "; ni++; goto Ldefault; @@ -427,16 +439,18 @@ public: try { string result = parseQualifiedName(); - if (!plainName) + string typed_result = parseType(result); + while(ni < name.length) { - result = parseType(result); - while(ni < name.length){ - result += " . " + parseType(parseQualifiedName()); - } - - if (ni != name.length) - goto Lnot; + // throw away outer type (e.g. for local functions) + result = result + "." + parseQualifiedName(); + typed_result = parseType(result); } + if (!plainName) + result = typed_result; + + if (ni != name.length) + goto Lnot; return result; } catch (MangleException e) @@ -456,6 +470,7 @@ void unittest() static string table[][2] = { + { "_D6object14_moduleTlsCtorUZv15_moduleTlsCtor2MFAPS6object10ModuleInfoiZv", "void object._moduleTlsCtor._moduleTlsCtor2(struct object.ModuleInfo*[], int)"}, { "_D7dparser3dmd8Template21TemplateTypeParameter13overloadMatchMFC7dparser3dmd8Template17TemplateParameterZi", "int dparser.dmd.Template.TemplateTypeParameter.overloadMatch(class dparser.dmd.Template.TemplateParameter)"}, { "printf", "printf" }, { "_foo", "_foo" }, @@ -484,6 +499,8 @@ void unittest() bool d_demangle(const char* name, char* demangled, int maxlen, bool plain) { + // static bool once; if(!once) unittest(); once = true; + Demangle d; string r = d.demangle(name, plain); if (r.length == 0) diff --git a/src/main.cpp b/src/main.cpp index 98c6d7f..55bbf8c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,25 +3,25 @@ // // License for redistribution is given by the Artistic License 2.0 // see file LICENSE for further details - -#include "PEImage.h" -#include "cv2pdb.h" - -#include - -double -#include "../VERSION" -; - -void fatal(const char *message, ...) -{ - va_list argptr; - va_start(argptr, message); - vprintf(message, argptr); - va_end(argptr); - printf("\n"); - exit(1); -} + +#include "PEImage.h" +#include "cv2pdb.h" + +#include + +double +#include "../VERSION" +; + +void fatal(const char *message, ...) +{ + va_list argptr; + va_start(argptr, message); + vprintf(message, argptr); + va_end(argptr); + printf("\n"); + exit(1); +} void makefullpath(char* pdbname) { diff --git a/src/managed/cv2pdb.vcproj b/src/managed/cv2pdb.vcproj new file mode 100644 index 0000000..121e29e --- /dev/null +++ b/src/managed/cv2pdb.vcproj @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/managed/main.cpp b/src/managed/main.cpp new file mode 100644 index 0000000..3f2ac5b --- /dev/null +++ b/src/managed/main.cpp @@ -0,0 +1,89 @@ +// Convert DMD CodeView debug information to PDB files +// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// +// License for redistribution is given by the Artistic License 2.0 +// see file LICENSE for further details + +// CLR interface to cv2pdb created by Alexander Bothe + +#include "../PEImage.h" +#include "../cv2pdb.h" +#include "vcclr.h" + +using namespace System; +using namespace System::IO; +using namespace System::Text; + +namespace CodeViewToPDB +{ + ///Exports DMD CodeView debug information from an executable file to a separate .pdb file + public ref class CodeViewToPDBConverter + { + public: + delegate void MsgHandler(String^ Message); + ///If an error occurs it will be reported via this event + static event MsgHandler^ Message; + + ///Exports DMD CodeView debug information from an executable file to a separate .pdb file + static bool DoConvert(String^ InputExe,String^ OutputExe,String^ OutputPDBFile,bool IsD2) + { + if(!File::Exists(InputExe)) + { + Message("Input file doesn't exist!"); + return false; + } + + if(String::IsNullOrEmpty(OutputPDBFile) || String::IsNullOrEmpty(OutputExe)) + { + Message("Empty arguments not allowed!"); + return false; + } + + char* input=(char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(InputExe).ToPointer(); + char* outname=(char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(OutputExe).ToPointer(); + char* pdbname=(char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(OutputPDBFile).ToPointer(); + + PEImage img(input); + + if (img.countCVEntries() == 0) + { + Message("No codeview debug entries found"); + return false; + } + + CV2PDB cv2pdb(img); + cv2pdb.initLibraries(); + cv2pdb.Dversion = IsD2?2:1; + + File::Delete(OutputPDBFile); + + if(cv2pdb.openPDB(pdbname) + && cv2pdb.initSegMap() + && cv2pdb.initGlobalTypes() + && cv2pdb.createModules() + && cv2pdb.addTypes() + && cv2pdb.addSymbols() + && cv2pdb.addSrcLines() + && cv2pdb.addPublics() + && cv2pdb.writeImage(outname)) + { } + else + { + Message(gcnew String(cv2pdb.getLastError())); + return false; + } + + return true; + } + + static bool DoConvert(String^ Exe,String^ OutputPDBFile) + { + return DoConvert(Exe,Exe,OutputPDBFile,true); + } + + static bool DoConvert(String^ Exe) + { + return DoConvert(Exe,Exe,Path::ChangeExtension(Exe,".pdb"),true); + } + }; +} diff --git a/src/mscvpdb.h b/src/mscvpdb.h index 12b4177..f8cf6a6 100644 --- a/src/mscvpdb.h +++ b/src/mscvpdb.h @@ -119,7 +119,7 @@ union codeview_type { unsigned short int len; short int id; - } generic; + } common; struct { @@ -365,7 +365,7 @@ union codeview_reftype { unsigned short int len; short int id; - } generic; + } common; struct { @@ -430,7 +430,7 @@ union codeview_fieldtype struct { short int id; - } generic; + } common; struct { @@ -737,7 +737,7 @@ union codeview_oem_type short int oemid; short int id; short int count; - } generic; + } common; struct { @@ -1224,7 +1224,7 @@ union codeview_symbol { short int len; short int id; - } generic; + } common; struct { diff --git a/src/symutil.cpp b/src/symutil.cpp index 6f5e42f..5556f1d 100644 --- a/src/symutil.cpp +++ b/src/symutil.cpp @@ -17,40 +17,40 @@ char dotReplacementChar = '@'; int dsym2c(const BYTE* p, BYTE len, char* cname, int maxclen) { - int zlen, zpos, cpos = 0; - - // decompress symbol - while (len-- > 0) - { - int ch = *p++; - if (ch == 0x80) - { - if (len-- <= 0) - break; - zlen = *p++ & 0x7f; - if (len-- <= 0) - break; - zpos = *p++ & 0x7f; - if (zpos > cpos) - break; - for(int z = 0; z < zlen; z++) - cname[cpos + z] = cname[cpos - zpos + z]; - cpos += zlen; - break; - } - else if (ch > 0x80) - { - zlen = (ch & 0x7) + 1; - zpos = ((ch >> 3) & 0xf) - 7; // + zlen; - for(int z = 0; z < zlen; z++) - cname[cpos + z] = cname[cpos - zpos + z]; - cpos += zlen; - } - else - cname[cpos++] = ch; - } - - cname[cpos] = 0; + int zlen, zpos, cpos = 0; + + // decompress symbol + while (len-- > 0) + { + int ch = *p++; + if (ch == 0x80) + { + if (len-- <= 0) + break; + zlen = *p++ & 0x7f; + if (len-- <= 0) + break; + zpos = *p++ & 0x7f; + if (zpos > cpos) + break; + for(int z = 0; z < zlen; z++) + cname[cpos + z] = cname[cpos - zpos + z]; + cpos += zlen; + break; + } + else if (ch > 0x80) + { + zlen = (ch & 0x7) + 1; + zpos = ((ch >> 3) & 0xf) - 7; // + zlen; + for(int z = 0; z < zlen; z++) + cname[cpos + z] = cname[cpos - zpos + z]; + cpos += zlen; + } + else + cname[cpos++] = ch; + } + + cname[cpos] = 0; if (cname[0] == '_' && cname[1] == 'D' && isdigit(cname[2])) d_demangle(cname, cname, maxclen, true); @@ -60,21 +60,21 @@ int dsym2c(const BYTE* p, BYTE len, char* cname, int maxclen) cname[i] = dotReplacementChar; #endif - return cpos; + return cpos; } char* p2c(const BYTE* p, int idx) { - static char cname[4][2560]; - int len = *p++; - -#if 1 - memcpy(cname[idx], p, len); - cname[idx][len] = 0; -#else - dsym2c(p, len, cname[idx], 2560); -#endif - return cname[idx]; + static char cname[4][2560]; + int len = *p++; + +#if 1 + memcpy(cname[idx], p, len); + cname[idx][len] = 0; +#else + dsym2c(p, len, cname[idx], 2560); +#endif + return cname[idx]; } char* p2c(const p_string& p, int idx) @@ -133,9 +133,9 @@ int pstrcpy_v(bool v3, BYTE* d, const BYTE* s) return pstrcpy(d, s); int len = *s++; - int clen = dsym2c(s, len, (char*) d, 1000) + 1; - - return clen; + int clen = dsym2c(s, len, (char*) d, 1000) + 1; + + return clen; } int cstrcpy_v(bool v3, BYTE* d, const char* s) @@ -147,6 +147,6 @@ int cstrcpy_v(bool v3, BYTE* d, const char* s) assert(len < 256); memcpy(d, s, len + 1); - return len + 1; + return len + 1; } diff --git a/test/Makefile b/test/Makefile index 6bed715..43e0f17 100644 --- a/test/Makefile +++ b/test/Makefile @@ -6,7 +6,7 @@ SRC = cvtest.d DBGDIR = ..\bin\Debug RELDIR = ..\bin\Release -DMD = c:\l\dmd-2.030\windows\bin\dmd.exe +DMD = c:\l\dmd-2.040\windows\bin\dmd.exe # DMD = c:\l\dmd-1.045\windows\bin\dmd.exe CV2PDB_DBG = $(DBGDIR)\cv2pdb.exe diff --git a/test/cvtest.d b/test/cvtest.d index 2336fc8..f504500 100644 --- a/test/cvtest.d +++ b/test/cvtest.d @@ -129,6 +129,21 @@ class Templ(T) } } +struct struc +{ + int a; + struc * next; +} + +class class_with_struct_member +{ + int c1; + int c2; + struc *s1; + + this() { s1 = new struc; } +}; + version(D2) { string stringMixin = "int a = 0; @@ -183,6 +198,8 @@ int main2(char[][]argv) int delegate() dg = &inst_method.method; int res = dg(); + class_with_struct_member cwsm = new class_with_struct_member; + return 0; } @@ -215,11 +232,13 @@ int main(char[][]argv) struc_arr[ab2] = 6; struc_arr[ab3] = 7; + struc s = { 2, null }; + Templ!(int) templ = new Templ!(int); int y = templ.foo(3); version(D2) int z = mixinTest(7); - + (new Test).test(); dmd_quirks(); -- cgit v0.12