summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRainer Schuetze <r.sagitario@gmx.de>2017-06-18 07:34:17 (GMT)
committerRainer Schuetze <r.sagitario@gmx.de>2017-06-18 07:34:17 (GMT)
commit31189818cbfc6d0bebf82025f3df632a287b61d6 (patch)
tree03684d03a660083b070d967e3d5aa4bc98b6915d /src
parentc1c515d00cedc8cb7453616bf0da80141b62454f (diff)
downloadcv2pdb-31189818cbfc6d0bebf82025f3df632a287b61d6.zip
cv2pdb-31189818cbfc6d0bebf82025f3df632a287b61d6.tar.gz
cv2pdb-31189818cbfc6d0bebf82025f3df632a287b61d6.tar.bz2
* when using mspdb120.dll (VS2013) or later, do not emit view helpers
* remove method declarations from struct or class records (they confuse mspdb*.dll if having forward references?)
Diffstat (limited to 'src')
-rw-r--r--src/cv2pdb.cpp84
-rw-r--r--src/cv2pdb.h3
-rw-r--r--src/cvutil.h2
-rw-r--r--src/mscvpdb.h20
4 files changed, 87 insertions, 22 deletions
diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp
index b93b21b..5fc8f12 100644
--- a/src/cv2pdb.cpp
+++ b/src/cv2pdb.cpp
@@ -38,7 +38,10 @@ CV2PDB::CV2PDB(PEImage& image)
nextDwarfType = 0x1000;
addClassTypeEnum = true;
+ addObjectViewHelper = true;
addStringViewHelper = false;
+ methodListToOneMethod = true;
+ removeMethodLists = true;
useTypedefEnum = false;
useGlobalMod = true;
thisIsNotRef = true;
@@ -182,6 +185,10 @@ bool CV2PDB::openPDB(const TCHAR* pdbname, const TCHAR* pdbref)
printf("TPI::QueryImplementationVersion() = %d\n", tpi->QueryImplementationVersion());
#endif
+ // only add helper for VS2012 or earlier, that default to the old debug engine
+ addClassTypeEnum = mspdb::vsVersion < 12;
+ addStringViewHelper = mspdb::vsVersion < 12;
+ addObjectViewHelper = mspdb::vsVersion < 12;
return true;
}
@@ -479,12 +486,31 @@ int CV2PDB::_doFields(int cmd, codeview_reftype* dfieldlist, const codeview_reft
break;
case LF_METHOD_V1:
+ {
+ auto prevdpos = dpos;
+ auto mlisttype = getTypeData(fieldtype->method_v1.mlist);
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);
+ if (methodListToOneMethod && fieldtype->method_v1.count == 1 && mlisttype)
+ {
+ dfieldtype->onemethod_v2.id = v3 ? LF_ONEMETHOD_V3 : LF_ONEMETHOD_V2;
+ dfieldtype->onemethod_v2.attribute = mlisttype->methodlist_v1.attr;
+ dfieldtype->onemethod_v2.type = translateType(mlisttype->methodlist_v1.fntype);
+ dpos += sizeof(dfieldtype->onemethod_v2) - sizeof(dfieldtype->onemethod_v2.p_name);
+ int mode = (mlisttype->methodlist_v1.attr >> 2) & 7;
+ if (mode == 4 || mode == 6) // introducing virtual
+ {
+ *(unsigned*)(dp + dpos) = mlisttype->methodlist_v1.vbaseoff[0];
+ dpos += sizeof(unsigned);
+ }
+ }
+ else
+ {
+ 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)
@@ -492,18 +518,22 @@ int CV2PDB::_doFields(int cmd, codeview_reftype* dfieldlist, const codeview_reft
else
copylen = pstrmemlen(&fieldtype->method_v1.p_name.namelen);
- if(cmd == kCmdOffsetFirstVirtualMethod)
- if(const codeview_type* cvtype = getTypeData(fieldtype->method_v1.mlist))
- if (cvtype->generic.id == LF_METHODLIST_V1 && cvtype->generic.len > 2)
- {
- // just check the first entry
- const unsigned short *pattr = (const unsigned short*)(&cvtype->generic + 1);
- int mode =(*pattr >> 2) & 7;
- if(mode == 4 || mode == 6)
- return *(const unsigned*)(&pattr[2]);
- }
+ if(removeMethodLists && cmd != kCmdOffsetFirstVirtualMethod)
+ {
+ dpos = prevdpos;
+ pos += copylen;
+ continue; // throw away copy and do not count
+ }
+ if(cmd == kCmdOffsetFirstVirtualMethod && mlisttype)
+ if (mlisttype->generic.id == LF_METHODLIST_V1 && mlisttype->generic.len > 2)
+ {
+ // just check the first entry
+ int mode = (mlisttype->methodlist_v1.attr >> 2) & 7;
+ if(mode == 4 || mode == 6)
+ return mlisttype->methodlist_v1.vbaseoff[0];
+ }
break;
-
+ }
case LF_METHOD_V2:
copylen = sizeof(dfieldtype->method_v2) - sizeof(dfieldtype->method_v2.p_name);
copylen += pstrmemlen(&fieldtype->method_v2.p_name.namelen);
@@ -1724,7 +1754,7 @@ int CV2PDB::appendObjectType (int object_type, int enumType, const char* classSy
codeview_type* dtype;
int viewHelperType = 0;
- bool addViewHelper = object_type == kClassTypeObject;
+ bool addViewHelper = addObjectViewHelper && object_type == kClassTypeObject;
if(addViewHelper)
{
rdtype = (codeview_reftype*) (userTypes + cbUserTypes);
@@ -2101,7 +2131,10 @@ bool CV2PDB::initGlobalTypes()
ifaceBaseType = appendObjectType (kClassTypeIface, ifaceEnumType, IFACE_SYMBOL);
cppIfaceBaseType = appendObjectType (kClassTypeCppIface, cppIfaceEnumType, CPPIFACE_SYMBOL);
}
- classBaseType = appendObjectType (kClassTypeObject, classEnumType, OBJECT_SYMBOL);
+ if (auto sym = findUdtSymbol(OBJECT_SYMBOL))
+ classBaseType = sym->udt_v1.type;
+ else
+ classBaseType = appendObjectType (kClassTypeObject, classEnumType, OBJECT_SYMBOL);
}
for (unsigned int t = 0; t < globalTypeHeader->cTypes && !hadError(); t++)
@@ -2332,20 +2365,29 @@ bool CV2PDB::initGlobalTypes()
case LF_METHODLIST_V1:
{
+ if (methodListToOneMethod || removeMethodLists)
+ {
+ dtype->generic.id = LF_NULL_V1;
+ len = 4;
+ break;
+ }
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)
{
- // type translation?
switch ((*pattr >> 2) & 7)
{
case 4:
case 6:
- *dpattr++ = *pattr++;
+ *dpattr++ = *pattr++; // attribute
+ *dpattr++ = translateType(*pattr++); // type
+ *dpattr++ = *(unsigned*)pattr; // vbaseoff
+ pattr += 2;
+ break;
default:
- *dpattr++ = *pattr++;
- *dpattr++ = *pattr++;
+ *dpattr++ = *pattr++; // attribute
+ *dpattr++ = translateType(*pattr++); // type
break;
}
}
diff --git a/src/cv2pdb.h b/src/cv2pdb.h
index 91dd165..a7883a4 100644
--- a/src/cv2pdb.h
+++ b/src/cv2pdb.h
@@ -245,6 +245,9 @@ public:
bool addClassTypeEnum;
bool addStringViewHelper;
+ bool addObjectViewHelper;
+ bool methodListToOneMethod;
+ bool removeMethodLists;
bool useGlobalMod;
bool thisIsNotRef;
bool v3;
diff --git a/src/cvutil.h b/src/cvutil.h
index 3467ca3..669a476 100644
--- a/src/cvutil.h
+++ b/src/cvutil.h
@@ -10,7 +10,7 @@
#include "cv2pdb.h"
#include "symutil.h"
-#define OBJECT_SYMBOL "object@Object"
+#define OBJECT_SYMBOL "object.Object"
#define IFACE_SYMBOL "DInterface"
#define CPPIFACE_SYMBOL "CppInterface"
diff --git a/src/mscvpdb.h b/src/mscvpdb.h
index 6a699c4..b377a64 100644
--- a/src/mscvpdb.h
+++ b/src/mscvpdb.h
@@ -352,6 +352,26 @@ union codeview_type
unsigned int arglist;
unsigned int this_adjust;
} mfunction_v2;
+
+ struct
+ {
+ unsigned short int len;
+ short int id;
+ unsigned short int attr;
+ unsigned short int fntype;
+ unsigned int vbaseoff[1]; // vtbl offset if introducing virtual
+ } methodlist_v1;
+
+ struct
+ {
+ unsigned short int len;
+ short int id;
+ unsigned short int attr;
+ unsigned short int pad0;
+ unsigned int fntype;
+ unsigned int vbaseoff[1]; // vtbl offset if introducing virtual
+ } methodlist_v2;
+
};
union codeview_reftype