summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES8
-rw-r--r--Makefile11
-rw-r--r--TODO3
-rw-r--r--VERSION2
-rw-r--r--autoexp.snippet46
-rw-r--r--src/PEImage.h4
-rw-r--r--src/cv2pdb.cpp161
-rw-r--r--src/cv2pdb.h10
-rw-r--r--src/cv2pdb.sln9
-rw-r--r--src/dviewhelper/dviewhelper.cpp72
-rw-r--r--src/main.cpp2
-rw-r--r--test/Makefile40
-rw-r--r--test/cvtest.d50
-rw-r--r--test/cvtest.vcproj74
14 files changed, 405 insertions, 87 deletions
diff --git a/CHANGES b/CHANGES
index 2a729a9..9488922 100644
--- a/CHANGES
+++ b/CHANGES
@@ -33,3 +33,11 @@ Version history
* fixed crash when long is used as index or element type of dynamic or
associative arrays
+
+2009-06-06 Version 0.5
+
+ * fixed error in __viewhelper field of string type, that could screw up type info
+ * added support for wstring and dstring
+ * fixed problems with debug info inside library by combining debug info of different modules
+ into a single pseudo-module
+ * now also replaces '.' by '@' in enumerator types for more consistent debug info
diff --git a/Makefile b/Makefile
index 3d1be76..ef11080 100644
--- a/Makefile
+++ b/Makefile
@@ -32,13 +32,18 @@ SRC = src\cv2pdb.cpp \
src\symutil.h \
src\dviewhelper\dviewhelper.cpp
-ADD = Makefile src\cv2pdb.vcproj src\dviewhelper\dviewhelper.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\Release\dviewhelper.dll
-TEST = test\cvtest.d
+TEST = test\cvtest.d \
+ test\cvtest.vcproj \
+ test\Makefile \
all: bin src
@@ -70,6 +75,6 @@ $(BIN_ZIP): $(BIN) $(DOC) Makefile
IDEDIR = $(VSINSTALLDIR)\Common7\IDE
-$(BIN): $(SRC) $(ADD) VERSION
+$(BIN): $(SRC) $(ADD) $(TEST) VERSION
if exist "$(IDEDIR)\VCExpress.exe" "$(IDEDIR)\VCExpress.exe" /Build Release src\cv2pdb.sln
if not exist "$(IDEDIR)\VCExpress.exe" "$(IDEDIR)\devenv.exe" /Build Release src\cv2pdb.sln
diff --git a/TODO b/TODO
index 341b1b6..e217f00 100644
--- a/TODO
+++ b/TODO
@@ -22,3 +22,6 @@ in the future, but not all have a known solution.
* assoc_array.length cannot be displayed (it is assoc_array.a->nodes)
* enum values not displayed
* does not work with debug version of phobos
+* map dchar to something displayable
+* workaround for ulong (written by DMD as int[])
+* last code bytes in module not included in last source line
diff --git a/VERSION b/VERSION
index ef5fa03..f264463 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-VERSION = 0.4
+VERSION = 0.5
diff --git a/autoexp.snippet b/autoexp.snippet
index 6dd1a3b..45dd5c8 100644
--- a/autoexp.snippet
+++ b/autoexp.snippet
@@ -19,8 +19,12 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [AutoExpand]
-string_viewhelper=$ADDIN(dviewhelper.dll,_DStringView@28)
object_viewhelper=$ADDIN(dviewhelper.dll,_DObjectView@28)
+string_viewhelper=$ADDIN(dviewhelper.dll,_DStringView@28)
+wstring_viewhelper=$ADDIN(dviewhelper.dll,_DWStringView@28)
+dstring_viewhelper=$ADDIN(dviewhelper.dll,_DDStringView@28)
+
+;; eo section AutoExpand for D variables ;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; D types visualizer
@@ -30,20 +34,45 @@ object_viewhelper=$ADDIN(dviewhelper.dll,_DObjectView@28)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [Visualizer]
-; string: dynamic array of char
-const char[]|char[]|string {
+; string, wstring and dstring use __viewhelper
+string|wstring|dstring {
preview (
- #if ($e.data == 0) ( "null" )
- #else (
+ #if ($e.data == 0) ( "null" )
+ #else (
#(
"[", $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]
+ )
+ )
+ )
+ children (
+ #(
+ length: [$e.length, i],
+ data: [$e.data]
+ )
+ )
+}
+
+; strings as dynamic arrays of char (no __viewhelper, check -D option for cv2pdb!)
+const char[]|char[]|const wchar[]|wchar[]|const dchar[]|dchar[] {
+ preview (
+ #if ($e.data == 0) ( "null" )
+ #else (
+ #(
+ "[", $e.length, "] ", [$e.data]
+ )
+ )
+ )
+ stringview (
+ #if ($e.data == 0) ( "null" )
+ #else (
#(
[$e.data, s]
)
@@ -126,3 +155,4 @@ internal@aaA<*,*> {
)
}
+;; eo section Visualizer for D variables ;;;;;;;;;;;;;;;;;;;;;;
diff --git a/src/PEImage.h b/src/PEImage.h
index df50395..039d2a1 100644
--- a/src/PEImage.h
+++ b/src/PEImage.h
@@ -48,7 +48,7 @@ public:
for (int i = 0; i < hdr->FileHeader.NumberOfSections; i++)
{
if (rva >= sec[i].VirtualAddress &&
- rva + len <= sec[i].VirtualAddress + sec[i].SizeOfRawData)
+ rva + len <= sec[i].VirtualAddress + sec[i].SizeOfRawData)
return DPV<P>(sec[i].PointerToRawData + rva - sec[i].VirtualAddress, len);
}
return 0;
@@ -63,6 +63,8 @@ public:
int countCVEntries() const;
OMFDirEntry* getCVEntry(int i) const;
+ int getCVSize() const { return dbgDir->SizeOfData; }
+
// utilities
static void* alloc_aligned(unsigned int size, unsigned int align, unsigned int alignoff = 0);
static void free_aligned(void* p);
diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp
index 49cb158..a8da38d 100644
--- a/src/cv2pdb.cpp
+++ b/src/cv2pdb.cpp
@@ -23,6 +23,7 @@ CV2PDB::CV2PDB(PEImage& image)
, pointerTypes(0)
, Dversion(2)
{
+ useGlobalMod = true;
thisIsNotRef = true;
v3 = true;
countEntries = img.countCVEntries();
@@ -152,14 +153,25 @@ bool CV2PDB::createModules()
const BYTE* plib = getLibrary (module->iLib);
const char* lib = (!plib || !*plib ? name : p2c(plib, 1));
- if (modules[entry->iMod])
+ mspdb::Mod* mod;
+ if (useGlobalMod)
{
- modules[entry->iMod]->Close();
- modules[entry->iMod] = 0;
+ mod = globalMod();
+ if(!mod)
+ return false;
}
- int rc = dbi->OpenMod(name, lib, &modules[entry->iMod]);
- if (rc <= 0 || !modules[entry->iMod])
- return setError("cannot create mod");
+ 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");
+ mod = modules[entry->iMod];
+ }
for (int s = 0; s < module->cSeg; s++)
{
@@ -168,7 +180,7 @@ bool CV2PDB::createModules()
if (segMap && segIndex < segMap->cSeg)
segFlags = segMapDesc[segIndex].flags;
segFlags = 0x60101020; // 0x40401040, 0x60500020; // TODO
- rc = modules[entry->iMod]->AddSecContrib(segIndex, segDesc[s].Off, segDesc[s].cbSeg, segFlags);
+ int rc = mod->AddSecContrib(segIndex, segDesc[s].Off, segDesc[s].cbSeg, segFlags);
if (rc <= 0)
return setError("cannot add section contribution to module");
}
@@ -177,6 +189,17 @@ bool CV2PDB::createModules()
return true;
}
+mspdb::Mod* CV2PDB::globalMod()
+{
+ if (!globmod)
+ {
+ int rc = dbi->OpenMod("__Globals", "__Globals", &globmod);
+ if (rc <= 0 || !globmod)
+ setError("cannot create global module");
+ }
+ return globmod;
+}
+
bool CV2PDB::initLibraries()
{
libraries = 0;
@@ -825,7 +848,7 @@ int CV2PDB::translateType(int type)
bool CV2PDB::nameOfBasicType(int type, char* name, int maxlen)
{
- int size = type & 7;
+ int size = type & 0xf;
int typ = (type & 0xf0) >> 4;
int mode = (type & 0x700) >> 8;
@@ -897,6 +920,9 @@ bool CV2PDB::nameOfBasicType(int type, char* name, int maxlen)
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)
@@ -1051,10 +1077,20 @@ bool CV2PDB::nameOfDynamicArray(int indexType, int elemType, char* name, int max
{
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)
+ strcpy(name, "wstring");
+ else if (Dversion >= 2 && strcmp(name, "const dchar") == 0)
+ strcpy(name, "dstring");
+
else if (Dversion < 2 && strcmp(name, "char") == 0)
strcpy(name, "string");
+ else if (Dversion < 2 && strcmp(name, "wchar") == 0)
+ strcpy(name, "wstring");
+ else if (Dversion < 2 && strcmp(name, "dchar") == 0)
+ strcpy(name, "dstring");
else
strcat (name, "[]");
// sprintf(name, "dyn_array<%X,%X>", indexType, elemType);
@@ -1117,7 +1153,7 @@ const char* CV2PDB::appendDynamicArray(int indexType, int elemType)
int dataptrType = nextUserType++;
int dstringType = 0;
- if(strcmp(name, "string") == 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);
@@ -1127,10 +1163,12 @@ const char* CV2PDB::appendDynamicArray(int indexType, int elemType)
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, 2, helpfieldlistType, 0, 0, 0, 0, "string_viewhelper");
+ cbUserTypes += addClass(dtype, 0, helpfieldlistType, 0, 0, 0, 0, helpertype);
dstringType = nextUserType++;
- addUdtSymbol(dstringType, "string_viewhelper");
+ addUdtSymbol(dstringType, helpertype);
}
// nextUserType + 1: field list (size, array)
@@ -1149,10 +1187,10 @@ const char* CV2PDB::appendDynamicArray(int indexType, int elemType)
int numElem = 2;
rdtype->fieldlist.len = len1 + len2 + 2;
- if(strcmp(name, "string") == 0)
+ if(dstringType > 0)
{
dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + rdtype->fieldlist.len - 2);
- rdtype->fieldlist.len = addFieldMember(dfieldtype, 1, 0, dstringType, "__viewhelper");
+ rdtype->fieldlist.len += addFieldMember(dfieldtype, 1, 0, dstringType, "__viewhelper");
numElem++;
}
@@ -1368,7 +1406,7 @@ int CV2PDB::appendObjectType (int object_derived_type)
cbUserTypes += rdtype->fieldlist.len + 2;
dtype = (codeview_type*) (userTypes + cbUserTypes);
- cbUserTypes += addClass(dtype, 2, helpfieldlistType, 0, 0, 0, 0, "object_viewhelper");
+ cbUserTypes += addClass(dtype, 0, helpfieldlistType, 0, 0, 0, 0, "object_viewhelper");
viewHelperType = nextUserType++;
addUdtSymbol(viewHelperType, "object_viewhelper");
}
@@ -1731,6 +1769,14 @@ 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;
+ }
+
for (int m = 0; m < countEntries; m++)
{
OMFDirEntry* entry = img.getCVEntry(m);
@@ -1740,12 +1786,9 @@ bool CV2PDB::addTypes()
if (!mod)
return setError("sstSrcModule for non-existing module");
- int cb = cbGlobalTypes;
- int rc = mod->AddTypes(globalTypes, cb);
+ int rc = mod->AddTypes(globalTypes, cbGlobalTypes);
if (rc <= 0)
return setError("cannot add type info to module");
- // does it make sense to add symbols more than once?
- // break;
}
}
return true;
@@ -1758,7 +1801,7 @@ bool CV2PDB::addSrcLines()
OMFDirEntry* entry = img.getCVEntry(m);
if(entry->SubSection == sstSrcModule)
{
- mspdb::Mod* mod = modules[entry->iMod];
+ mspdb::Mod* mod = useGlobalMod ? globalMod() : modules[entry->iMod];
if (!mod)
return setError("sstSrcModule for non-existing module");
@@ -1811,7 +1854,7 @@ bool CV2PDB::addPublics()
{
mspdb::Mod* mod = 0;
if (entry->iMod < countEntries)
- mod = modules[entry->iMod];
+ mod = useGlobalMod ? globalMod() : modules[entry->iMod];
OMFSymHash* header = img.CVP<OMFSymHash>(entry->lfo);
BYTE* symbols = img.CVP<BYTE>(entry->lfo + sizeof(OMFSymHash));
@@ -1890,6 +1933,9 @@ int CV2PDB::copySymbols(BYTE* srcSymbols, int srcSize, BYTE* destSymbols, int de
{
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;
@@ -2054,36 +2100,26 @@ bool CV2PDB::addUdtSymbol(int type, const char* name)
return true;
}
-bool CV2PDB::addSymbols(int iMod, BYTE* symbols, int cb)
-{
- 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)
- {
- if (!globmod)
- {
- int rc = dbi->OpenMod("<Globals>", "<Globals>", &globmod);
- if (rc <= 0 || !globmod)
- return setError("cannot create global module");
- }
- mod = globmod;
- }
- if (!mod)
- return setError("no module to set symbols");
-
- int prefix = mod == globmod ? 3 : 4;
+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];
+ DWORD* data = new DWORD[2 * words + 1000];
int databytes = copySymbols(symbols, cb, (BYTE*) (data + prefix), 0);
- if (staticSymbols)
+
+ bool rc = writeSymbols(mod, data, databytes, prefix, addGlobals);
+ 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 (globalSymbols)
+ if (addGlobals && globalSymbols)
databytes = copySymbols(globalSymbols, cbGlobalSymbols, (BYTE*) (data + prefix), databytes);
- if (udtSymbols)
+ if (addGlobals && udtSymbols)
databytes = copySymbols(udtSymbols, cbUdtSymbols, (BYTE*) (data + prefix), databytes);
data[0] = 4;
@@ -2094,15 +2130,36 @@ bool CV2PDB::addSymbols(int iMod, BYTE* symbols, int cb)
int rc = mod->AddSymbols((BYTE*) data, ((databytes + 3) / 4 + prefix) * 4);
if (rc <= 0)
return setError("cannot add symbols to module");
- delete [] data;
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");
+
+ return addSymbols(mod, symbols, cb, addGlobals);
+}
+
bool CV2PDB::addSymbols()
{
if (!initGlobalSymbols())
return false;
+ int prefix = 4;
+ DWORD* data = 0;
+ int databytes = 0;
+ if (useGlobalMod)
+ 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);
@@ -2112,8 +2169,11 @@ bool CV2PDB::addSymbols()
switch(entry->SubSection)
{
case sstAlignSym:
- if (!addSymbols (entry->iMod, symbols + 4, entry->cb - 4))
+ 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:
@@ -2121,7 +2181,12 @@ bool CV2PDB::addSymbols()
break; // handled in initGlobalSymbols
}
}
- return true;
+ bool rc = true;
+ if (useGlobalMod)
+ rc = writeSymbols (globalMod(), data, databytes, prefix, true);
+
+ delete [] data;
+ return rc;
}
bool CV2PDB::writeImage(const char* opath)
diff --git a/src/cv2pdb.h b/src/cv2pdb.h
index fec2dff..e132e95 100644
--- a/src/cv2pdb.h
+++ b/src/cv2pdb.h
@@ -89,15 +89,20 @@ public:
bool addSrcLines();
bool addPublics();
+ bool addUdtSymbol(int type, const char* name);
+
// returns new destSize
int copySymbols(BYTE* srcSymbols, int srcSize, BYTE* destSymbols, int destSize);
- bool addUdtSymbol(int type, const char* name);
- bool addSymbols(int iMod, BYTE* symbols, int cb);
+ bool writeSymbols(mspdb::Mod* mod, DWORD* data, int databytes, int prefix, bool addGlobals);
+ bool addSymbols(mspdb::Mod* mod, BYTE* symbols, int cb, bool addGlobals);
+ bool addSymbols(int iMod, BYTE* symbols, int cb, bool addGlobals);
bool addSymbols();
bool writeImage(const char* opath);
+ mspdb::Mod* globalMod();
+
// private:
BYTE* libraries;
@@ -139,6 +144,7 @@ public:
int nextUserType;
int objectType;
+ bool useGlobalMod;
bool thisIsNotRef;
bool v3;
const char* lastError;
diff --git a/src/cv2pdb.sln b/src/cv2pdb.sln
index e83abbb..18f285d 100644
--- a/src/cv2pdb.sln
+++ b/src/cv2pdb.sln
@@ -17,6 +17,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\VERSION = ..\VERSION
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cvtest", "..\test\cvtest.vcproj", "{CCC0643D-7D3F-4D5E-AE0E-C871776E86AF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {5E2BD27D-446A-4C99-9829-135F7C000D90} = {5E2BD27D-446A-4C99-9829-135F7C000D90}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -31,6 +36,10 @@ Global
{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
+ {CCC0643D-7D3F-4D5E-AE0E-C871776E86AF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CCC0643D-7D3F-4D5E-AE0E-C871776E86AF}.Debug|Win32.Build.0 = Debug|Win32
+ {CCC0643D-7D3F-4D5E-AE0E-C871776E86AF}.Release|Win32.ActiveCfg = Release|Win32
+ {CCC0643D-7D3F-4D5E-AE0E-C871776E86AF}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/dviewhelper/dviewhelper.cpp b/src/dviewhelper/dviewhelper.cpp
index 594c231..110cc09 100644
--- a/src/dviewhelper/dviewhelper.cpp
+++ b/src/dviewhelper/dviewhelper.cpp
@@ -6,8 +6,11 @@
// 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)
+// Compile the DLL and add the following lines to AUTOEXP.DAT in section [AutoExpand]
+// string_viewhelper=$ADDIN(<path to the DLL>\dviewhelper.dll,_DStringView@28)
+// wstring_viewhelper=$ADDIN(<path to the DLL>\dviewhelper.dll,_DWStringView@28)
+// dstring_viewhelper=$ADDIN(<path to the DLL>\dviewhelper.dll,_DDStringView@28)
+// object_viewhelper=$ADDIN(<path to the DLL>\dviewhelper.dll,_DObjectView@28)
//
///////////////////////////////////////////////////////////////////////////////
@@ -35,9 +38,10 @@ struct DString
DWORD data;
};
-__declspec(dllexport)
-HRESULT WINAPI DStringView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings,
- char *pResult, size_t max, DWORD reserved)
+///////////////////////////////////////////////////////////////////////////////
+
+HRESULT WINAPI StringView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings,
+ char *pResult, size_t max, DWORD sizePerChar)
{
// Get the string struct
DString dstr;
@@ -53,19 +57,65 @@ HRESULT WINAPI DStringView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOO
return S_OK;
}
+ char* pData = pResult + 1;
DWORD cnt = (dstr.length < max - 3 ? dstr.length : max - 3);
- if (pHelper->ReadDebuggeeMemory(pHelper, dstr.data, cnt, pResult + 1, &read) != S_OK)
+ if (sizePerChar * cnt > max)
+ pData = new char[sizePerChar * cnt];
+
+ if (pHelper->ReadDebuggeeMemory(pHelper, dstr.data, sizePerChar * cnt, pData, &read) != S_OK)
{
strncpy(pResult,"Cannot access data", max);
- return S_OK;
+ }
+ else
+ {
+ //! @todo: proper utf8/16/32 translation
+ for (DWORD p = 0; p < cnt; p++)
+ {
+ int ch;
+ if (sizePerChar == 4)
+ ch = ((long*) pData) [p];
+ else if (sizePerChar == 2)
+ ch = ((short*) pData) [p];
+ else
+ ch = pData [p];
+
+ if (ch >= 128 && ch < -128)
+ pResult[p + 1] = -1;
+ else
+ pResult[p + 1] = (char) ch;
+ }
+ pResult[0] = '\"';
+ pResult[cnt+1] = '\"';
+ pResult[cnt+2] = 0;
}
- pResult[0] = '\"';
- pResult[cnt+1] = '\"';
- pResult[cnt+2] = 0;
+ if(pData != pResult + 1)
+ delete [] pData;
return S_OK;
}
+
+__declspec(dllexport)
+HRESULT WINAPI DStringView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings,
+ char *pResult, size_t max, DWORD reserved)
+{
+ return StringView(dwAddress, pHelper, nBase, bUniStrings, pResult, max, 1);
+}
+
+__declspec(dllexport)
+HRESULT WINAPI DWStringView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings,
+ char *pResult, size_t max, DWORD reserved)
+{
+ return StringView(dwAddress, pHelper, nBase, bUniStrings, pResult, max, 2);
+}
+
+__declspec(dllexport)
+HRESULT WINAPI DDStringView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings,
+ char *pResult, size_t max, DWORD reserved)
+{
+ return StringView(dwAddress, pHelper, nBase, bUniStrings, pResult, max, 4);
+}
+
__declspec(dllexport)
HRESULT WINAPI DObjectView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings,
char *pResult, size_t max, DWORD reserved)
@@ -107,4 +157,4 @@ HRESULT WINAPI DObjectView(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOO
return S_OK;
}
-} // extern "C" \ No newline at end of file
+} // extern "C"
diff --git a/src/main.cpp b/src/main.cpp
index fb80f30..98c6d7f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -86,7 +86,7 @@ int main(int argc, char** argv)
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] <exe-file> [new-exe-file] [pdb-file]\n", argv[0]);
+ printf("usage: %s [-Dversion|-C] <exe-file> [new-exe-file] [pdb-file]\n", argv[0]);
return -1;
}
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..6bed715
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,40 @@
+
+PROJECT = cvtest
+
+SRC = cvtest.d
+
+DBGDIR = ..\bin\Debug
+RELDIR = ..\bin\Release
+
+DMD = c:\l\dmd-2.030\windows\bin\dmd.exe
+# DMD = c:\l\dmd-1.045\windows\bin\dmd.exe
+
+CV2PDB_DBG = $(DBGDIR)\cv2pdb.exe
+CV2PDB_REL = $(RELDIR)\cv2pdb.exe
+
+DFLAGS = -L/DELEXECUTABLE
+LIBS = phobos.lib
+
+default: dbg_exe
+release: rel_exe
+
+dbg_exe: $(DBGDIR)\$(PROJECT).exe
+rel_exe: $(RELDIR)\$(PROJECT).exe
+
+######################
+$(DBGDIR)\$(PROJECT).exe : $(DBGDIR)\$(PROJECT)_cv.exe $(CV2PDB_DBG)
+ $(CV2PDB_DBG) $(DBGDIR)\$(PROJECT)_cv.exe $@
+
+$(DBGDIR)\$(PROJECT)_cv.exe : $(SRC) Makefile
+ $(DMD) -of$@ -g -unittest $(DFLAGS) @<<
+ $(SRC) $(LIBS)
+<<NOKEEP
+
+
+$(RELDIR)\$(PROJECT).exe : $(RELDIR)\$(PROJECT)_cv.exe $(CV2PDB_REL)
+ $(CV2PDB_REL) $(RELDIR)\$(PROJECT)_cv.exe $@
+
+$(RELDIR)\$(PROJECT)_cv.exe : $(SRC) Makefile
+ $(DMD) -of$@ -g -release -unittest $(DFLAGS) @<<
+ $(SRC) $(LIBS)
+<<NOKEEP
diff --git a/test/cvtest.d b/test/cvtest.d
index c978f03..c5b80a1 100644
--- a/test/cvtest.d
+++ b/test/cvtest.d
@@ -1,12 +1,14 @@
module cvtest;
+import std.string;
+import std.stdio;
///////////////// field types ////////////////////////
// field type LF_ENUMERATE_V1
enum enum_name
{
- kEnum1,
+ kEnum1 = 1,
kEnum2,
kEnum3,
kEnum500 = 500,
@@ -125,13 +127,16 @@ class Templ(T)
}
}
-enum stringMixin = "int a = 0;
-return x + a;
-";
-
-int mixinTest(int x)
+version(D2)
{
- mixin(stringMixin);
+ string stringMixin = "int a = 0;
+ return x + a;
+ ";
+
+ int mixinTest(int x)
+ {
+ mixin(stringMixin);
+ }
}
int main2(char[][]argv)
@@ -180,6 +185,8 @@ int main(char[][]argv)
main2(argv);
+ writefln("Hello world");
+
int[int] int_arr;
int_arr[1] = 100;
int_arr[98] = 101;
@@ -200,18 +207,22 @@ int main(char[][]argv)
struc_arr[ab2] = 6;
struc_arr[ab3] = 7;
- Templ!(int) templ = new Templ!(int);
- int y = templ.foo(3);
- int z = mixinTest(7);
+ Templ!(int) templ = new Templ!(int);
+ int y = templ.foo(3);
+ version(D2)
+ int z = mixinTest(7);
- (new Test).test();
+ (new Test).test();
+
+ dmd_quirks();
+ strings();
int[] dynint_arr;
dynint_arr ~= 12;
return dynint_arr.length;
}
-alias invariant(char)[] string;
+// alias invariant(char)[] string;
class Test
{
@@ -231,3 +242,18 @@ class Test
return dyn_arr.length + assoc_arr.length + clss.c;
}
}
+
+int strings()
+{
+ string cs = "char string";
+ wstring ws = "wchar string"w;
+ dstring ds = "dchar string"d;
+
+ return 0;
+}
+
+void dmd_quirks()
+{
+ long quirk_long; // written as delegate<void*,int>
+ ulong quirk_ulong; // written as int[]
+}
diff --git a/test/cvtest.vcproj b/test/cvtest.vcproj
new file mode 100644
index 0000000..f769bce
--- /dev/null
+++ b/test/cvtest.vcproj
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="cvtest"
+ ProjectGUID="{CCC0643D-7D3F-4D5E-AE0E-C871776E86AF}"
+ RootNamespace="cvtest"
+ Keyword="MakeFileProj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\bin\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake -f Makefile"
+ ReBuildCommandLine=""
+ CleanCommandLine=""
+ Output="..\bin\Debug\cvtest.exe"
+ PreprocessorDefinitions="WIN32;_DEBUG"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\bin\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake -f Makefile release"
+ ReBuildCommandLine=""
+ CleanCommandLine=""
+ Output="..\bin\Release\cvtest.exe"
+ PreprocessorDefinitions="WIN32;NDEBUG"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\cvtest.d"
+ >
+ </File>
+ <File
+ RelativePath=".\Makefile"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>