diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cv2pdb.cpp | 49 | ||||
-rw-r--r-- | src/cv2pdb.h | 1 | ||||
-rw-r--r-- | src/cv2pdb.vcproj | 2 | ||||
-rw-r--r-- | src/cvutil.h | 2 | ||||
-rw-r--r-- | src/demangle.cpp | 148 | ||||
-rw-r--r-- | src/main.cpp | 7 | ||||
-rw-r--r-- | src/mscvpdb.h | 252 | ||||
-rw-r--r-- | src/symutil.cpp | 34 | ||||
-rw-r--r-- | src/symutil.h | 1 |
9 files changed, 349 insertions, 147 deletions
diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp index f4f674e..72cb610 100644 --- a/src/cv2pdb.cpp +++ b/src/cv2pdb.cpp @@ -1875,12 +1875,15 @@ void CV2PDB::ensureUDT(int type, const codeview_type* cvtype) if (getStructProperty(cvtype) & kPropIncomplete)
cvtype = findCompleteClassType(cvtype, &type);
- if(!findUdtSymbol(type + 0x1000))
- {
- char name[kMaxNameLen];
- int value, leaf_len = numeric_leaf(&value, &cvtype->struct_v1.structlen);
- pstrcpy_v(true, (BYTE*) name, (const BYTE*) &cvtype->struct_v1.structlen + leaf_len);
+ if(findUdtSymbol(type + 0x1000))
+ return;
+ char name[kMaxNameLen];
+ int value, leaf_len = numeric_leaf(&value, &cvtype->struct_v1.structlen);
+ pstrcpy_v(true, (BYTE*) name, (const BYTE*) &cvtype->struct_v1.structlen + leaf_len);
+
+ if (getStructProperty(cvtype) & kPropIncomplete)
+ {
checkUserTypeAlloc();
codeview_reftype* rdtype = (codeview_reftype*) (userTypes + cbUserTypes);
@@ -1895,6 +1898,8 @@ void CV2PDB::ensureUDT(int type, const codeview_type* cvtype) // addUdtSymbol(viewHelperType, "object_viewhelper");
addUdtSymbol(viewHelperType, name);
}
+ else
+ addUdtSymbol(type + 0x1000, name);
}
int CV2PDB::appendTypedef(int type, const char* name)
@@ -1916,7 +1921,7 @@ int CV2PDB::appendTypedef(int type, const char* name) dtype->enumeration_v2.type = basetype;
dtype->enumeration_v2.fieldlist = fieldlistType;
dtype->enumeration_v2.count = 0;
- dtype->enumeration_v2.property = 0x200;
+ dtype->enumeration_v2.property = kPropReserved2;
int len = cstrcpy_v (v3, (BYTE*) &dtype->enumeration_v2.p_name, name);
len += sizeof(dtype->enumeration_v2) - sizeof(dtype->enumeration_v2.p_name);
writeUserTypeLen(dtype, len);
@@ -2091,7 +2096,7 @@ bool CV2PDB::initGlobalTypes() 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 = fixProperty(t + 0x1000, type->struct_v1.property,
- type->struct_v1.fieldlist) | 0x200;
+ type->struct_v1.fieldlist) | kPropReserved2;
#if REMOVE_LF_DERIVED
dtype->struct_v2.derived = 0;
#else
@@ -2903,11 +2908,37 @@ codeview_symbol* CV2PDB::findUdtSymbol(int type) return 0;
}
+codeview_symbol* CV2PDB::findUdtSymbol(const char* name)
+{
+ for(int p = 0; p < cbGlobalSymbols; )
+ {
+ codeview_symbol* sym = (codeview_symbol*) (globalSymbols + p);
+ if(sym->common.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name))
+ return sym;
+ p += sym->common.len + 2;
+ }
+ for(int p = 0; p < cbStaticSymbols; )
+ {
+ codeview_symbol* sym = (codeview_symbol*) (staticSymbols + p);
+ if(sym->common.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name))
+ return sym;
+ p += sym->common.len + 2;
+ }
+ for(int p = 0; p < cbUdtSymbols; )
+ {
+ codeview_symbol* sym = (codeview_symbol*) (udtSymbols + p);
+ if(sym->common.id == S_UDT_V1 && p2ccmp(sym->udt_v1.p_name, name))
+ return sym;
+ p += sym->common.len + 2;
+ }
+ return 0;
+}
+
bool CV2PDB::addUdtSymbol(int type, const char* name)
{
- if (cbUdtSymbols + 300 > allocUdtSymbols)
+ if (cbUdtSymbols + 100 + kMaxNameLen > allocUdtSymbols)
{
- allocUdtSymbols += 5000;
+ allocUdtSymbols += kMaxNameLen + 5000;
udtSymbols = (BYTE*) realloc(udtSymbols, allocUdtSymbols);
}
diff --git a/src/cv2pdb.h b/src/cv2pdb.h index cdfed36..e352dcc 100644 --- a/src/cv2pdb.h +++ b/src/cv2pdb.h @@ -123,6 +123,7 @@ public: bool addPublics();
codeview_symbol* findUdtSymbol(int type);
+ codeview_symbol* findUdtSymbol(const char* name);
bool addUdtSymbol(int type, const char* name);
void ensureUDT(int type, const codeview_type* cvtype);
diff --git a/src/cv2pdb.vcproj b/src/cv2pdb.vcproj index cc0a479..fd3c973 100644 --- a/src/cv2pdb.vcproj +++ b/src/cv2pdb.vcproj @@ -69,6 +69,7 @@ GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
+ Profile="true"
/>
<Tool
Name="VCALinkTool"
@@ -145,6 +146,7 @@ OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
+ Profile="true"
/>
<Tool
Name="VCALinkTool"
diff --git a/src/cvutil.h b/src/cvutil.h index 4b35c6a..d9817e5 100644 --- a/src/cvutil.h +++ b/src/cvutil.h @@ -28,6 +28,7 @@ enum };
// class properties (also apply to struct,union and enum)
+static const int kPropNone = 0x00;
static const int kPropPacked = 0x01;
static const int kPropHasCtorDtor = 0x02;
static const int kPropHasOverOps = 0x04;
@@ -37,6 +38,7 @@ static const int kPropHasOverAsgn = 0x20; static const int kPropHasCasting = 0x40;
static const int kPropIncomplete = 0x80;
static const int kPropScoped = 0x100;
+static const int kPropReserved2 = 0x200;
bool isStruct(const codeview_type* cvtype);
bool isClass(const codeview_type* cvtype);
diff --git a/src/demangle.cpp b/src/demangle.cpp index 6c1ff30..af7c318 100644 --- a/src/demangle.cpp +++ b/src/demangle.cpp @@ -18,7 +18,141 @@ #include "symutil.h"
-using namespace std;
+#define USE_STDSTRING 1
+
+#if USE_STDSTRING
+typedef std::string string; //using namespace std;
+#else
+static const int maxLen = 4096;
+
+struct stringpool
+{
+ stringpool() : _first(0) {}
+
+ char* get()
+ {
+ if(!_first)
+ return new char[maxLen];
+ char* p = _first;
+ _first = *(char**) _first;
+ return p;
+ }
+ void put(char* p)
+ {
+ *(char**)p = _first;
+ _first = p;
+ }
+
+ char* _first;
+};
+stringpool pool;
+
+#define string _string // fool debugger to not use visualizers for std::string
+
+struct string
+{
+ string() : _p(0), _len(0), _const(false) { _p = pool.get(); }
+ //string(const char* p) : _cp(p), _len(strlen(p)), _const(true) {}
+ //string(const string& s) : _p(s.p), _len(s._len), _const(true) {}
+ string(const char* p, size_t len) : _cp(p), _len(len), _const(true) {}
+ template<int N> string(const char (&p)[N]) : _cp(p), _len(N-1), _const(true) {}
+ ~string() { if(!_const) pool.put(_p); }
+
+ size_t length() const { return _len; }
+
+ char operator[] (size_t idx) const
+ {
+ return _p[idx];
+ }
+ string substr(size_t pos, size_t len) const
+ {
+ return string(_p + pos, len);
+ }
+
+ template<int N> string operator+(const char (&p)[N])
+ {
+ assert(!_const);
+ assert(_len + N-1 < maxLen);
+
+ memcpy(_p + _len, p, N-1);
+ return string(_p, _len + N-1);
+ }
+ string operator+(string s)
+ {
+ assert(!_const);
+ assert(_len + s._len < maxLen);
+
+ memcpy(_p + _len, s._p, s._len);
+ return string(_p, _len + s._len);
+ }
+ template<int N> string operator+=(const char (&p)[N])
+ {
+ assert(!_const);
+ assert(_len + N-1 < maxLen);
+ memcpy(_p + _len, p, N-1);
+ _len += N - 1;
+ return *this;
+ }
+ string operator+=(const string& s)
+ {
+ assert(!_const);
+ assert(_len + s._len < maxLen);
+ memcpy(_p + _len, s._p, s._len);
+ _len += s._len;
+ return *this;
+ }
+ string operator+=(char c)
+ {
+ assert(!_const);
+ assert(_len < maxLen);
+ _p[_len++] = c;
+ return *this;
+ }
+ template<int N>string operator=(const char (&p)[N])
+ {
+ _len = N-1;
+ memcpy(_p, p, _len);
+ _const = true;
+ return *this;
+ }
+ string operator=(const string& s)
+ {
+ assert(!_const);
+ _len = s._len;
+ memcpy(_p, s._p, _len);
+ return *this;
+ }
+ bool operator==(const string& s) const
+ {
+ return _len == s._len && memcmp(_p, s._p, _len) == 0;
+ }
+
+ const char* c_str()
+ {
+ assert(!_const);
+ assert(_len < maxLen);
+ _p[_len] = 0;
+ return _p;
+ }
+
+ union
+ {
+ const char* _cp;
+ char* _p;
+ };
+ size_t _len;
+ bool _const;
+};
+
+template<int N> string operator+(const char (&p)[N], string s)
+{
+ assert(!s._const);
+ assert(s._len + N-1 < maxLen);
+ memmove(s._p + N - 1, s._p, s._len);
+ memcpy(s._p, p, N-1);
+ return string(s._p, s._len + N-1);
+}
+#endif
typedef unsigned char ubyte;
typedef long double real;
@@ -38,7 +172,6 @@ class Demangle public:
size_t ni;
string name;
- string (Demangle::*fparseTemplateInstanceName)();
static void error()
{
@@ -88,7 +221,7 @@ public: ni += 3;
try
{
- result = parseTemplateInstanceName(); // (this->*fparseTemplateInstanceName)();
+ result = parseTemplateInstanceName();
if (ni != nisave + i)
err = true;
}
@@ -281,7 +414,7 @@ public: return prop + p;
}
p = prop + parseType() +
- (isdelegate ? " delegate(" : " function(") + args + ")";
+ (isdelegate ? string(" delegate(") : string(" function(")) + args + ")";
isdelegate = 0;
goto L1;
}
@@ -454,8 +587,6 @@ public: goto Lnot;
}
- // fparseTemplateInstanceName = &parseTemplateInstanceName;
-
try
{
string result = parseQualifiedName();
@@ -522,12 +653,13 @@ void unittest() bool d_demangle(const char* name, char* demangled, int maxlen, bool plain)
{
-#if 0 // && def _DEBUG
+#ifdef _DEBUG
static bool once; if(!once) { once = true; unittest(); }
#endif
Demangle d;
- string r = d.demangle(name, plain);
+ string nm(name, strlen(name));
+ string r = d.demangle(nm, plain);
if (r.length == 0)
return false;
strncpy(demangled, r.c_str(), maxlen);
diff --git a/src/main.cpp b/src/main.cpp index 96864cc..9b6c247 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "PEImage.h"
#include "cv2pdb.h"
+#include "symutil.h"
#include <direct.h>
@@ -81,12 +82,12 @@ int main(int argc, char** argv) if (argc < 2)
{
printf("Convert DMD CodeView debug information to PDB files, Version %g\n", VERSION);
- printf("Copyright (c) 2009-2010 by Rainer Schuetze, All Rights Reserved\n");
+ printf("Copyright (c) 2009-2011 by Rainer Schuetze, All Rights Reserved\n");
printf("\n");
printf("License for redistribution is given by the Artistic License 2.0\n");
printf("see file LICENSE for further details\n");
printf("\n");
- printf("usage: %s [-Dversion|-C] <exe-file> [new-exe-file] [pdb-file]\n", argv[0]);
+ printf("usage: %s [-Dversion|-C|-n] <exe-file> [new-exe-file] [pdb-file]\n", argv[0]);
return -1;
}
@@ -103,6 +104,8 @@ int main(int argc, char** argv) Dversion = strtod (argv[0] + 2, 0);
else if (argv[0][1] == 'C')
Dversion = 0;
+ else if (argv[0][1] == 'n')
+ demangleSymbols = false;
else
fatal("unknwon option: %s", argv[0]);
}
diff --git a/src/mscvpdb.h b/src/mscvpdb.h index f8cf6a6..9a55e1f 100644 --- a/src/mscvpdb.h +++ b/src/mscvpdb.h @@ -126,7 +126,7 @@ union codeview_type unsigned short int len; short int id; short int attribute; - short int type; + unsigned short int type; } modifier_v1; struct @@ -142,7 +142,7 @@ union codeview_type unsigned short int len; short int id; short int attribute; - short int datatype; + unsigned short int datatype; struct p_string p_name; } pointer_v1; @@ -159,8 +159,8 @@ union codeview_type { unsigned short int len; short int id; - short int elemtype; - short int idxtype; + unsigned short int elemtype; + unsigned short int idxtype; unsigned short int arrlen; /* numeric leaf */ #if 0 struct p_string p_name; @@ -196,10 +196,10 @@ union codeview_type unsigned short int len; short int id; short int n_element; - short int fieldlist; + unsigned short int fieldlist; short int property; - short int derived; - short int vshape; + unsigned short int derived; + unsigned short int vshape; unsigned short int structlen; /* numeric leaf */ #if 0 struct p_string p_name; @@ -240,8 +240,8 @@ union codeview_type { unsigned short int len; short int id; - short int count; - short int fieldlist; + unsigned short int count; + unsigned short int fieldlist; short int property; unsigned short int un_len; /* numeric leaf */ #if 0 @@ -253,7 +253,7 @@ union codeview_type { unsigned short int len; short int id; - short int count; + unsigned short int count; short int property; unsigned int fieldlist; unsigned short int un_len; /* numeric leaf */ @@ -266,7 +266,7 @@ union codeview_type { unsigned short int len; short int id; - short int count; + unsigned short int count; short int property; unsigned int fieldlist; unsigned short int un_len; /* numeric leaf */ @@ -279,9 +279,9 @@ union codeview_type { unsigned short int len; short int id; - short int count; - short int type; - short int fieldlist; + unsigned short int count; + unsigned short int type; + unsigned short int fieldlist; short int property; struct p_string p_name; } enumeration_v1; @@ -290,7 +290,7 @@ union codeview_type { unsigned short int len; short int id; - short int count; + unsigned short int count; short int property; unsigned int type; unsigned int fieldlist; @@ -301,7 +301,7 @@ union codeview_type { unsigned short int len; short int id; - short int count; + unsigned short int count; short int property; unsigned int type; unsigned int fieldlist; @@ -434,27 +434,27 @@ union codeview_fieldtype struct { - short int id; - short int type; - short int attribute; - unsigned short int offset; /* numeric leaf */ + short int id; + unsigned short int type; + short int attribute; + unsigned short int offset; /* numeric leaf */ } bclass_v1; struct { - short int id; - short int attribute; - unsigned int type; - unsigned short int offset; /* numeric leaf */ + short int id; + short int attribute; + unsigned int type; + unsigned short int offset; /* numeric leaf */ } bclass_v2; struct { - short int id; - short int btype; - short int vbtype; - short int attribute; - unsigned short int vbpoff; /* numeric leaf */ + short int id; + unsigned short int btype; + unsigned short int vbtype; + short int attribute; + unsigned short int vbpoff; /* numeric leaf */ #if 0 unsigned short int vboff; /* numeric leaf */ #endif @@ -462,11 +462,11 @@ union codeview_fieldtype struct { - short int id; - short int attribute; - unsigned int btype; - unsigned int vbtype; - unsigned short int vbpoff; /* numeric leaf */ + short int id; + short int attribute; + unsigned int btype; + unsigned int vbtype; + unsigned short int vbpoff; /* numeric leaf */ #if 0 unsigned short int vboff; /* numeric leaf */ #endif @@ -494,38 +494,38 @@ union codeview_fieldtype struct { - short int id; - short int type; - struct p_string p_name; + short int id; + unsigned short int type; + struct p_string p_name; } friendfcn_v1; struct { - short int id; - short int _pad0; - unsigned int type; - struct p_string p_name; + short int id; + short int _pad0; + unsigned int type; + struct p_string p_name; } friendfcn_v2; struct { - short int id; - short int type; - short int attribute; - unsigned short int offset; /* numeric leaf */ + short int id; + unsigned short int type; + short int attribute; + unsigned short int offset; /* numeric leaf */ #if 0 - struct p_string p_name; + struct p_string p_name; #endif } member_v1; struct { - short int id; - short int attribute; - unsigned int type; - unsigned short int offset; /* numeric leaf */ + short int id; + short int attribute; + unsigned int type; + unsigned short int offset; /* numeric leaf */ #if 0 - struct p_string p_name; + struct p_string p_name; #endif } member_v2; @@ -543,132 +543,132 @@ union codeview_fieldtype struct { - short int id; - short int type; - short int attribute; - struct p_string p_name; + short int id; + unsigned short int type; + short int attribute; + struct p_string p_name; } stmember_v1; struct { - short int id; - short int attribute; - unsigned int type; - struct p_string p_name; + short int id; + short int attribute; + unsigned int type; + struct p_string p_name; } stmember_v2; struct { - short int id; - short int attribute; - unsigned int type; - char name[1]; + short int id; + short int attribute; + unsigned int type; + char name[1]; } stmember_v3; struct { - short int id; - short int count; - short int mlist; - struct p_string p_name; + short int id; + short int count; + unsigned short int mlist; + struct p_string p_name; } method_v1; struct { - short int id; - short int count; - unsigned int mlist; - struct p_string p_name; + short int id; + short int count; + unsigned int mlist; + struct p_string p_name; } method_v2; struct { - short int id; - short int count; - unsigned int mlist; - char name[1]; + short int id; + short int count; + unsigned int mlist; + char name[1]; } method_v3; struct { - short int id; - short int type; - struct p_string p_name; + short int id; + unsigned short int type; + struct p_string p_name; } nesttype_v1; struct { - short int id; - short int _pad0; - unsigned int type; - struct p_string p_name; + short int id; + short int _pad0; + unsigned int type; + struct p_string p_name; } nesttype_v2; struct { - short int id; - short int _pad0; - unsigned int type; - char name[1]; + short int id; + short int _pad0; + unsigned int type; + char name[1]; } nesttype_v3; struct { - short int id; - short int type; + short int id; + unsigned short int type; } vfunctab_v1; struct { - short int id; - short int _pad0; - unsigned int type; + short int id; + short int _pad0; + unsigned int type; } vfunctab_v2; struct { - short int id; - short int type; + short int id; + unsigned short int type; } friendcls_v1; struct { - short int id; - short int _pad0; - unsigned int type; + short int id; + short int _pad0; + unsigned int type; } friendcls_v2; struct { - short int id; - short int attribute; - short int type; - struct p_string p_name; + short int id; + short int attribute; + unsigned short int type; + struct p_string p_name; } onemethod_v1; struct { - short int id; - short int attribute; - unsigned int type; - struct p_string p_name; + short int id; + short int attribute; + unsigned int type; + struct p_string p_name; } onemethod_v2; struct { - short int id; - short int attribute; - unsigned int type; - char name[1]; + short int id; + short int attribute; + unsigned int type; + char name[1]; } onemethod_v3; struct { - short int id; - short int attribute; - short int type; - unsigned int vtab_offset; - struct p_string p_name; + short int id; + short int attribute; + unsigned short int type; + unsigned int vtab_offset; + struct p_string p_name; } onemethod_virt_v1; struct @@ -691,9 +691,9 @@ union codeview_fieldtype struct { - short int id; - short int type; - unsigned int offset; + short int id; + unsigned short int type; + unsigned int offset; } vfuncoff_v1; struct @@ -706,10 +706,10 @@ union codeview_fieldtype struct { - short int id; - short int attribute; - short int type; - struct p_string p_name; + short int id; + short int attribute; + unsigned short int type; + struct p_string p_name; } nesttypeex_v1; struct @@ -744,8 +744,8 @@ union codeview_oem_type short int oemid; // 0x42 for D short int id; // 1 short int count; // 2 - short int index_type; - short int elem_type; + short unsigned int index_type; + short unsigned int elem_type; } d_dyn_array; struct @@ -753,8 +753,8 @@ union codeview_oem_type short int oemid; // 0x42 for D short int id; // 2 short int count; // 2 - short int key_type; - short int elem_type; + short unsigned int key_type; + short unsigned int elem_type; } d_assoc_array; struct @@ -762,8 +762,8 @@ union codeview_oem_type short int oemid; // 0x42 for D short int id; // 3 short int count; // 2 - short int this_type; - short int func_type; + short unsigned int this_type; + short unsigned int func_type; } d_delegate; }; diff --git a/src/symutil.cpp b/src/symutil.cpp index 2660ea4..faed579 100644 --- a/src/symutil.cpp +++ b/src/symutil.cpp @@ -14,6 +14,7 @@ extern "C" { #include <assert.h>
char dotReplacementChar = '@';
+bool demangleSymbols = true;
int dsym2c(const BYTE* p, int len, char* cname, int maxclen)
{
@@ -26,6 +27,33 @@ int dsym2c(const BYTE* p, int len, char* cname, int maxclen) int ch = *p++;
if(ch == 0)
break;
+ if ((ch & 0xc0) == 0xc0)
+ {
+ zlen = (ch & 0x7) + 1;
+ zpos = ((ch >> 3) & 7) + 1; // + zlen;
+ if (zpos > cpos)
+ break;
+ for (int z = 0; z < zlen; z++)
+ cname[cpos + z] = cname[cpos - zpos + z];
+ cpos += zlen;
+ }
+ else if (ch >= 0x80)
+ {
+ if (p >= end)
+ break;
+ int ch2 = *p++;
+ zlen = (ch2 & 0x7f) | ((ch & 0x38) << 4);
+ if (p >= end)
+ break;
+ int ch3 = *p++;
+ zpos = (ch3 & 0x7f) | ((ch & 7) << 7);
+ if (zpos > cpos)
+ break;
+ for(int z = 0; z < zlen; z++)
+ cname[cpos + z] = cname[cpos - zpos + z];
+ cpos += zlen;
+ }
+#if 0
if (ch == 0x80)
{
if (p >= end)
@@ -48,13 +76,15 @@ int dsym2c(const BYTE* p, int len, char* cname, int maxclen) cname[cpos + z] = cname[cpos - zpos + z];
cpos += zlen;
}
+#endif
else
cname[cpos++] = ch;
}
cname[cpos] = 0;
- if (cname[0] == '_' && cname[1] == 'D' && isdigit(cname[2]))
- d_demangle(cname, cname, maxclen, true);
+ if(demangleSymbols)
+ if (cname[0] == '_' && cname[1] == 'D' && isdigit(cname[2]))
+ d_demangle(cname, cname, maxclen, true);
#if 1
for(int i = 0; i < cpos; i++)
diff --git a/src/symutil.h b/src/symutil.h index b3f020f..dfc8b76 100644 --- a/src/symutil.h +++ b/src/symutil.h @@ -30,5 +30,6 @@ int cstrcpy_v(bool v3, BYTE* d, const char* s); bool dstrcmp(const BYTE* s1, bool cstr1, const BYTE* s2, bool cstr2);
extern char dotReplacementChar;
+extern bool demangleSymbols;
#endif //__SYMUTIL_H__
|