summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsagitario <sagitario@fc51e93f-b9fe-4711-8d8d-3ae870c5f7d8>2009-06-04 21:34:44 (GMT)
committersagitario <sagitario@fc51e93f-b9fe-4711-8d8d-3ae870c5f7d8>2009-06-04 21:34:44 (GMT)
commit890a9b3e4f9384f8937646d49848aa669f93ed8e (patch)
tree922645525e098b8a22ff6c890df830eac382a39d
parent1ebb42385c535860df1455656f39699bffb20937 (diff)
downloadcv2pdb-890a9b3e4f9384f8937646d49848aa669f93ed8e.zip
cv2pdb-890a9b3e4f9384f8937646d49848aa669f93ed8e.tar.gz
cv2pdb-890a9b3e4f9384f8937646d49848aa669f93ed8e.tar.bz2
-rw-r--r--CHANGES10
-rw-r--r--INSTALL15
-rw-r--r--Makefile9
-rw-r--r--README10
-rw-r--r--TODO6
-rw-r--r--VERSION2
-rw-r--r--autoexp.snippet46
-rw-r--r--src/cv2pdb.cpp203
-rw-r--r--src/cv2pdb.h2
-rw-r--r--src/cv2pdb.sln18
-rw-r--r--src/dviewhelper/dviewhelper.cpp110
-rw-r--r--src/dviewhelper/dviewhelper.vcproj186
-rw-r--r--src/main.cpp2
13 files changed, 538 insertions, 81 deletions
diff --git a/CHANGES b/CHANGES
index 6c51426..5728ff6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -18,3 +18,13 @@ Version history
* support for field type LF_VFUNCTAB and symbol type S_CONSTANT used by DMC.
* added stringview to autoexp.dat for full length text display.
+2009-06-01 Version 0.3
+
+ * static members' debug info was not correctly converted, causing debugger confusion
+ * now works on executables compiled by DMC
+ - added command line switch -C to disable some D feature and
+ to remove function name from local variables
+ - added support for type LF_BITFIELD.
+ * added fields __viewhelper to classes string and object
+ * new addin dviewhelper.dll to display correctly terminated strings
+ and derived object type
diff --git a/INSTALL b/INSTALL
index 16a0a97..4b82dbd 100644
--- a/INSTALL
+++ b/INSTALL
@@ -34,18 +34,23 @@ navigating to the file extensions option page (found in Tools -> Options
with editor "Microsoft Visual C++". This will also enable display of
variables in the "Auto" watch window.
-4. You should also add the contents of the file autoexp.snippet to the
-[AutoExpand] section of the file autoexp.dat found in
+4. the file dviewhelper.dll must be copied into a directory where
+the debugger can find it. This can be any directory accessible through your
+PATH variable or <Visual Studio Installation Path>\Common7\IDE.
+
+5. You should also add the contents of the file autoexp.snippet to the
+[AutoExpand] and [Visualizer] sections of the file autoexp.dat found in
<Visual Studio Installation Path>\Common7\Packages\Debugger.
Please note that in a standard installation of Visual Studio, the
-section [AutoExpand] extends to the bottom of the file but a few lines
+section [AutoExpand] is at the beginning of that file, followed by
+the section [Visualizer], which extends to the bottom of the file but a few lines
for the section [hresult].
These lines will enable a convenient display of strings, dynamic arrays,
-associative arrays and null references.
+associative arrays, object types and null references.
Building from source
--------------------
The source package comes with a Visual Studio 2008 project and solution
that work with both the Standard and the Express version. These won't
-work in VS2005, but creating a VS2005 project should be easy.
+work in VS2005, but creating VS2005 projects should be easy.
diff --git a/Makefile b/Makefile
index b6b1595..3d1be76 100644
--- a/Makefile
+++ b/Makefile
@@ -29,13 +29,14 @@ SRC = src\cv2pdb.cpp \
src\PEImage.cpp \
src\PEImage.h \
src\symutil.cpp \
- src\symutil.h
+ src\symutil.h \
+ src\dviewhelper\dviewhelper.cpp
-ADD = Makefile src\cv2pdb.vcproj src\cv2pdb.sln
+ADD = Makefile src\cv2pdb.vcproj src\dviewhelper\dviewhelper.vcproj src\cv2pdb.sln
DOC = VERSION README INSTALL LICENSE CHANGES TODO autoexp.snippet
-BIN = bin\Release\cv2pdb.exe
+BIN = bin\Release\cv2pdb.exe bin\Release\dviewhelper.dll
TEST = test\cvtest.d
@@ -48,7 +49,7 @@ DOWNLOADS = ..\downloads
$(DOWNLOADS):
if not exist $(DOWNLOADS)\nul mkdir $(DOWNLOADS)
-
+
###############################
SRC_ZIP = $(DOWNLOADS)\cv2pdb_src_$(VERSION).zip
diff --git a/README b/README
index f2df67b..5311130 100644
--- a/README
+++ b/README
@@ -9,7 +9,7 @@ were created with the Digital Mars DMD compiler, as seamless as possible
in current versions of Visual Studio (i.e Visual Studio 2008 and
VCExpress).
As a side effect, other applications might also benefit from the
-converted debug information, like WinDbg.
+converted debug information, like WinDbg or DMC.
Features
--------
@@ -19,6 +19,7 @@ Features
* generates generic debug info for dynamic arrays, associative arrays and delegates
* autoexp.dat allows convenient display of dynamic and associative arrays in watch windows
* demangles function names for convenient display of callstack
+* support for DMC CodeView information
License information
-------------------
@@ -63,13 +64,16 @@ Description:
cv2pdb.exe is a command line tool which outputs its usage information
if run without arguments:
- usage: cv2pdb [-Dversion] <exe-file> [new-exe-file] [pdb-file]
+ usage: cv2pdb [-Dversion|-C] <exe-file> [new-exe-file] [pdb-file]
With the -D option, you can specify the version of the DMD compiler
you are using. Unfortunately, this information is not embedded into
the debug information. The default is -D2. So far, this information
is only needed to determine whether "char[]" or "const char[]" is
-translated to "string".
+translated to "string".
+Option -C tells the program, that you want to debug a program compiled
+with DMC, the Digital Mars C/C++ compiler. It will disable some of the
+D specific functions and will enable adjustment of stack variable names.
The first file name on the command line is expected to be the executable
or dynamic library compiled by the DMD compiler and containing the
diff --git a/TODO b/TODO
index f40c257..774b819 100644
--- a/TODO
+++ b/TODO
@@ -12,8 +12,6 @@ in the future, but not all have a known solution.
but it looks ugly
* "this.var" is not a valid debugger expression, you have to use
"var" or "this->var"
-* strings are displayed zero-terminated, not D style (though display
- is often ok)
* global/static vars have to be watched with full module and class name
specified (e.g. module@globvar)
* type of associative arrays is displayed as aa<*> to allow overload
@@ -21,5 +19,5 @@ in the future, but not all have a known solution.
* DMD does not emit different debug information for const and invariant,
type info is the same
* type display of delegate does not have arguments
-* assoc_array.length cannot be displayed (it is assoc_array.a->length)
-* support DMC debug info?
+* assoc_array.length cannot be displayed (it is assoc_array.a->nodes)
+* enum values not displayed
diff --git a/VERSION b/VERSION
index ec3d324..29f5f7d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-VERSION = 0.2
+VERSION = 0.3
diff --git a/autoexp.snippet b/autoexp.snippet
index 0d9c132..6dd1a3b 100644
--- a/autoexp.snippet
+++ b/autoexp.snippet
@@ -6,25 +6,44 @@
;;
;; D types
;;
-;; add the content of this file to the [AutoExpand] section
-;; of
+;; add the content of this file to
;; <Visual Studio Installation Path>\Common7\Package\Debugger\autoexp.dat
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; load helper dll dviewhelper.dll to display strings
+;;
+;; add the following 2 lines to the [AutoExpand] section
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; [AutoExpand]
+
+string_viewhelper=$ADDIN(dviewhelper.dll,_DStringView@28)
+object_viewhelper=$ADDIN(dviewhelper.dll,_DObjectView@28)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; D types visualizer
+;;
+;; add the remainder of this file to the [Visualizer] section
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; [Visualizer]
+
; string: dynamic array of char
const char[]|char[]|string {
preview (
- #if ($e.data == 0) ( "null" )
- #else (
+ #if ($e.data == 0) ( "null" )
+ #else (
#(
- "[", $e.length, "] ", [$e.data, s]
+ "[", $e.length, "] ", [$e.__viewhelper]
+ ;; "[", $e.length, "] ", [$e.data,s]
)
)
)
stringview (
- #if ($e.data == 0) ( "null" )
- #else (
+ #if ($e.data == 0) ( "null" )
+ #else (
#(
[$e.data, s]
)
@@ -85,7 +104,6 @@ aa<*> {
right : right,
; size : $c.size
) : $e
-
)
)
}
@@ -99,10 +117,12 @@ internal@aaA<*,*> {
;; display null references for class objects
*@* {
- preview(
- #(
- #if (&$e == 0) ( "null" )
- #else ( [$e,!] )
- )
+ preview(
+ #(
+ #if (&$e == 0) ( "null" )
+ #else ( #( "[", [$e.__viewhelper], "] ", [$e,!] ) )
+ ;; #else ( #( [$e,!] ) )
+ )
)
}
+
diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp
index bb91af7..f2ead36 100644
--- a/src/cv2pdb.cpp
+++ b/src/cv2pdb.cpp
@@ -446,7 +446,7 @@ int CV2PDB::addFields(codeview_reftype* dfieldlist, const codeview_reftype* fiel
break;
case LF_STMEMBER_V1:
- dfieldtype->stmember_v2.id = v3 ? LF_METHOD_V3 : LF_METHOD_V2;
+ 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);
pos += sizeof(dfieldtype->stmember_v1) - sizeof(dfieldtype->stmember_v1.p_name);
@@ -576,6 +576,34 @@ int CV2PDB::addFieldMember(codeview_fieldtype* dfieldtype, int attr, int offset,
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);
+
+ 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);
+
+ 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)
@@ -1078,12 +1106,34 @@ const char* CV2PDB::appendDynamicArray(int indexType, int elemType)
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)
+ {
+ // 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;
+
+ dtype = (codeview_type*) (userTypes + cbUserTypes);
+ cbUserTypes += addClass(dtype, 2, helpfieldlistType, 0, 0, 0, 0, "string_viewhelper");
+ dstringType = nextUserType++;
+ addUdtSymbol(dstringType, "string_viewhelper");
+ }
// 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;
@@ -1091,20 +1141,24 @@ const char* CV2PDB::appendDynamicArray(int indexType, int elemType)
// member elemType* data[]
dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1);
- int len2 = addFieldMember(dfieldtype, 1, 4, nextUserType, "data");
+ int len2 = addFieldMember(dfieldtype, 1, 4, dataptrType, "data");
+ int numElem = 2;
rdtype->fieldlist.len = len1 + len2 + 2;
- cbUserTypes += rdtype->fieldlist.len + 2;
- static char name[256];
- nameOfDynamicArray(indexType, elemType, name, sizeof(name));
+ if(strcmp(name, "string") == 0)
+ {
+ dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + rdtype->fieldlist.len - 2);
+ rdtype->fieldlist.len = addFieldMember(dfieldtype, 1, 0, dstringType, "__viewhelper");
+ numElem++;
+ }
- // nextUserType + 2: struct
+ cbUserTypes += rdtype->fieldlist.len + 2;
dtype = (codeview_type*) (userTypes + cbUserTypes);
- cbUserTypes += addClass(dtype, 2, nextUserType + 1, 0, 0, 0, 8, name);
+ cbUserTypes += addClass(dtype, numElem, fieldlistType, 0, 0, 0, 8, name);
+ int udType = nextUserType++;
- nextUserType += 3;
- addUdtSymbol(nextUserType - 1, name);
+ addUdtSymbol(udType, name);
return name;
}
@@ -1291,53 +1345,65 @@ int CV2PDB::appendObjectType (int object_derived_type)
checkUserTypeAlloc();
// append object type info
- int typeNo = nextUserType;
- codeview_reftype* rdtype = (codeview_reftype*) (userTypes + cbUserTypes);
-
+ codeview_reftype* rdtype;
+ 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;
+
+ dtype = (codeview_type*) (userTypes + cbUserTypes);
+ cbUserTypes += addClass(dtype, 2, helpfieldlistType, 0, 0, 0, 0, "object_viewhelper");
+ viewHelperType = nextUserType++;
+ 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*
- codeview_type* dtype = (codeview_type*) (userTypes + cbUserTypes);
- dtype->pointer_v2.id = LF_POINTER_V2;
- dtype->pointer_v2.len = 10;
- dtype->pointer_v2.datatype = typeNo;
- dtype->pointer_v2.attribute = 0x800A;
- cbUserTypes += dtype->generic.len + 2;
+ dtype = (codeview_type*) (userTypes + cbUserTypes);
+ cbUserTypes += addPointerType(dtype, vtableType);
+ 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 = typeNo + 1; // vtable*
+ 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"
dtype = (codeview_type*) (userTypes + cbUserTypes);
- dtype->struct_v2.id = v3 ? LF_CLASS_V3 : LF_CLASS_V2;
- dtype->struct_v2.n_element = 1;
- dtype->struct_v2.fieldlist = typeNo + 2;
- dtype->struct_v2.property = 0;
- dtype->struct_v2.derived = object_derived_type;
- dtype->struct_v2.vshape = typeNo;
- dtype->struct_v2.structlen = 4;
- int len = cstrcpy_v (v3, (BYTE*) (&dtype->struct_v2 + 1), OBJECT_SYMBOL);
- len += sizeof (dtype->struct_v2);
- for (; len & 3; len++)
- userTypes[cbUserTypes + len] = 0xf4 - (len & 3);
- dtype->struct_v2.len = len - 2;
- cbUserTypes += dtype->generic.len + 2;
-
- objectType = typeNo + 3;
- nextUserType += 4;
+ cbUserTypes += addClass(dtype, numElem, fieldListType, 0, object_derived_type, vtableType, 4, OBJECT_SYMBOL);
+ objectType = nextUserType++;
addUdtSymbol(objectType, OBJECT_SYMBOL);
return objectType;
@@ -1398,7 +1464,7 @@ bool CV2PDB::initGlobalTypes()
codeview_reftype* rdtype = (codeview_reftype*) (globalTypes + cbGlobalTypes);
// for debugging, cancel special processing after the limit
- unsigned int typeLimit = 0x7fffffff;
+ unsigned int typeLimit = 0x7fffffff; // 0x1ddd; //
if (t > typeLimit)
{
dtype->pointer_v2.id = LF_POINTER_V2;
@@ -1483,7 +1549,7 @@ bool CV2PDB::initGlobalTypes()
len += leaf_len + sizeof(dtype->struct_v2) - sizeof(type->struct_v2.structlen);
// remember type index of derived list for object.Object
- if (type->struct_v1.derived)
+ if (Dversion > 0 && type->struct_v1.derived)
if (memcmp((char*) &type->struct_v1.structlen + leaf_len, "\x0dobject.Object", 14) == 0)
object_derived_type = type->struct_v1.derived;
break;
@@ -1503,11 +1569,12 @@ bool CV2PDB::initGlobalTypes()
case LF_POINTER_V1:
dtype->pointer_v2.id = LF_POINTER_V2;
dtype->pointer_v2.datatype = translateType(type->pointer_v1.datatype);
- if (type->pointer_v1.datatype >= 0x1000 && (type->pointer_v1.attribute & 0xE0) == 0)
+ if (Dversion > 0 && type->pointer_v1.datatype >= 0x1000
+ && (type->pointer_v1.attribute & 0xE0) == 0)
{
if (thisIsNotRef) // const pointer for this
pointerTypes[t] = appendPointerType(type->pointer_v1.datatype,
- type->pointer_v1.attribute | 0x400);
+ type->pointer_v1.attribute | 0x400);
dtype->pointer_v2.attribute = type->pointer_v1.attribute | 0x20; // convert to reference
}
else
@@ -1611,6 +1678,14 @@ bool CV2PDB::initGlobalTypes()
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);
+ len = sizeof(rdtype->bitfield_v2);
+ break;
+
default:
memcpy(dtype, type, len);
break;
@@ -1624,7 +1699,8 @@ bool CV2PDB::initGlobalTypes()
}
#if 1
- appendObjectType (object_derived_type);
+ if(Dversion > 0)
+ appendObjectType (object_derived_type);
#endif
#if 1
if (cbGlobalTypes + cbUserTypes > allocGlobalTypes)
@@ -1695,17 +1771,19 @@ bool CV2PDB::addSrcLines()
int segoff = lnSegStartEnd[2*s];
int seglength = lnSegStartEnd[2*s + 1] - segoff;
+ int cnt = sourceLine->cLnOff;
- mspdb::LineInfoEntry* lineInfo = new mspdb::LineInfoEntry[sourceLine->cLnOff];
- for (int ln = 0; ln < sourceLine->cLnOff; ln++)
+ 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, sourceLine->Seg, segoff, seglength, segoff, lineNo[0],
- (unsigned char*) lineInfo, sourceLine->cLnOff * sizeof(*lineInfo));
+ (unsigned char*) lineInfo, cnt * sizeof(*lineInfo));
if (rc <= 0)
return setError("cannot add line number info to module");
+ delete [] lineInfo;
}
}
}
@@ -1872,6 +1950,23 @@ int CV2PDB::copySymbols(BYTE* srcSymbols, int srcSize, BYTE* destSymbols, int de
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;
@@ -1889,18 +1984,24 @@ int CV2PDB::copySymbols(BYTE* srcSymbols, int srcSize, BYTE* destSymbols, int de
case S_PROCREF_V1:
case S_DATAREF_V1:
case S_LPROCREF_V1:
- // 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
- destSize += 4;
+ 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 = sym->constant_v1.type;
+ 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,
diff --git a/src/cv2pdb.h b/src/cv2pdb.h
index a900e6c..fec2dff 100644
--- a/src/cv2pdb.h
+++ b/src/cv2pdb.h
@@ -47,6 +47,8 @@ public:
int addPointerType(unsigned char* dtype, int type, int attr = 0x800A);
int addFieldMember(codeview_fieldtype* dfieldtype, int attr, int offset, int type, const char* name);
+ int addFieldStaticMember(codeview_fieldtype* dfieldtype, int attr, int type, const char* name);
+ int addFieldNestedType(codeview_fieldtype* dfieldtype, int type, const char* name);
void checkUserTypeAlloc(int size = 1000, int add = 10000);
diff --git a/src/cv2pdb.sln b/src/cv2pdb.sln
index 451ef68..e83abbb 100644
--- a/src/cv2pdb.sln
+++ b/src/cv2pdb.sln
@@ -3,6 +3,20 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cv2pdb", "cv2pdb.vcproj", "{5E2BD27D-446A-4C99-9829-135F7C000D90}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dviewhelper", "dviewhelper\dviewhelper.vcproj", "{E4424774-A7A0-4502-8626-2723904D70EA}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7F4A9B6A-05A2-45D0-AFC3-3754B7FB77B9}"
+ ProjectSection(SolutionItems) = preProject
+ ..\autoexp.snippet = ..\autoexp.snippet
+ ..\CHANGES = ..\CHANGES
+ ..\INSTALL = ..\INSTALL
+ ..\LICENSE = ..\LICENSE
+ ..\Makefile = ..\Makefile
+ ..\README = ..\README
+ ..\TODO = ..\TODO
+ ..\VERSION = ..\VERSION
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -13,6 +27,10 @@ Global
{5E2BD27D-446A-4C99-9829-135F7C000D90}.Debug|Win32.Build.0 = Debug|Win32
{5E2BD27D-446A-4C99-9829-135F7C000D90}.Release|Win32.ActiveCfg = Release|Win32
{5E2BD27D-446A-4C99-9829-135F7C000D90}.Release|Win32.Build.0 = Release|Win32
+ {E4424774-A7A0-4502-8626-2723904D70EA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E4424774-A7A0-4502-8626-2723904D70EA}.Debug|Win32.Build.0 = Debug|Win32
+ {E4424774-A7A0-4502-8626-2723904D70EA}.Release|Win32.ActiveCfg = Release|Win32
+ {E4424774-A7A0-4502-8626-2723904D70EA}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/dviewhelper/dviewhelper.cpp b/src/dviewhelper/dviewhelper.cpp
new file mode 100644
index 0000000..594c231
--- /dev/null
+++ b/src/dviewhelper/dviewhelper.cpp
@@ -0,0 +1,110 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// DViewHelper - Expression Evaluator for the D string and object class
+// 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
+//
+// Compile the DLL and add this to AUTOEXP.DAT in section [AutoExpand]
+// string=$ADDIN(<path to the DLL>\dviewhelper.dll,_DStringView@28)
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <windows.h>
+#include <stdio.h>
+
+extern "C" {
+
+// Copied from MSDN
+struct DEBUGHELPER
+{
+ DWORD dwVersion;
+ BOOL (WINAPI *ReadDebuggeeMemory)(DEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
+ // from here only when dwVersion >= 0x20000
+ DWORDLONG (WINAPI *GetRealAddress)(DEBUGHELPER *pThis);
+ BOOL (WINAPI *ReadDebuggeeMemoryEx)(DEBUGHELPER *pThis, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
+ int (WINAPI *GetProcessorType)(DEBUGHELPER *pThis);
+};
+
+struct DString
+{
+ DWORD length;
+ DWORD data;
+};
+
+__declspec(dllexport)
+HRESULT WINAPI DStringView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings,
+ char *pResult, size_t max, DWORD reserved)
+{
+ // Get the string struct
+ DString dstr;
+ DWORD read;
+ if (pHelper->ReadDebuggeeMemory(pHelper, dwAddress, sizeof(dstr), &dstr, &read) != S_OK)
+ {
+ strncpy(pResult,"Cannot access struct", max);
+ return S_OK;
+ }
+ if (dstr.length == 0)
+ {
+ strncpy(pResult,"\"\"", max);
+ return S_OK;
+ }
+
+ DWORD cnt = (dstr.length < max - 3 ? dstr.length : max - 3);
+ if (pHelper->ReadDebuggeeMemory(pHelper, dstr.data, cnt, pResult + 1, &read) != S_OK)
+ {
+ strncpy(pResult,"Cannot access data", max);
+ return S_OK;
+ }
+
+ pResult[0] = '\"';
+ pResult[cnt+1] = '\"';
+ pResult[cnt+2] = 0;
+ return S_OK;
+}
+
+__declspec(dllexport)
+HRESULT WINAPI DObjectView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings,
+ char *pResult, size_t max, DWORD reserved)
+{
+ if(dwAddress == 0)
+ {
+ strncpy(pResult,"null", max);
+ return S_OK;
+ }
+
+ DWORD read;
+ DWORD vtablePtr;
+ if (pHelper->ReadDebuggeeMemory(pHelper, dwAddress, sizeof(vtablePtr), &vtablePtr, &read) != S_OK)
+ {
+ strncpy(pResult,"Cannot access object", max);
+ return S_OK;
+ }
+ DWORD classinfoPtr;
+ if (pHelper->ReadDebuggeeMemory(pHelper, vtablePtr, sizeof(vtablePtr), &classinfoPtr, &read) != S_OK)
+ {
+ strncpy(pResult,"Cannot access vtable", max);
+ return S_OK;
+ }
+ DString dstr;
+ if (pHelper->ReadDebuggeeMemory(pHelper, classinfoPtr + 16, sizeof(dstr), &dstr, &read) != S_OK)
+ {
+ strncpy(pResult,"Cannot access class info", max);
+ return S_OK;
+ }
+
+ DWORD cnt = (dstr.length < max - 1 ? dstr.length : max - 1);
+ if (pHelper->ReadDebuggeeMemory(pHelper, dstr.data, cnt, pResult, &read) != S_OK)
+ {
+ strncpy(pResult,"Cannot access name data", max);
+ return S_OK;
+ }
+
+ pResult[cnt] = 0;
+ return S_OK;
+}
+
+} // extern "C" \ No newline at end of file
diff --git a/src/dviewhelper/dviewhelper.vcproj b/src/dviewhelper/dviewhelper.vcproj
new file mode 100644
index 0000000..67e1907
--- /dev/null
+++ b/src/dviewhelper/dviewhelper.vcproj
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="dviewhelper"
+ ProjectGUID="{E4424774-A7A0-4502-8626-2723904D70EA}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../bin/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/$(ProjectName).dll"
+ LinkIncremental="2"
+ ModuleDefinitionFile=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../../bin/$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/$(ProjectName).dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\dviewhelper.cpp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/main.cpp b/src/main.cpp
index 16dbb34..fb80f30 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -101,6 +101,8 @@ int main(int argc, char** argv)
break;
if (argv[0][1] == 'D')
Dversion = strtod (argv[0] + 2, 0);
+ else if (argv[0][1] == 'C')
+ Dversion = 0;
else
fatal("unknwon option: %s", argv[0]);
}