summaryrefslogtreecommitdiffstats
path: root/src/cvutil.cpp
diff options
context:
space:
mode:
authorsagitario <sagitario@fc51e93f-b9fe-4711-8d8d-3ae870c5f7d8>2010-08-08 08:37:12 (GMT)
committersagitario <sagitario@fc51e93f-b9fe-4711-8d8d-3ae870c5f7d8>2010-08-08 08:37:12 (GMT)
commit59dc1509092a46bb18e08f54ac5c4f859ca0ffa8 (patch)
tree44b893a9c077e1f531e87ac7bb9953a46e254548 /src/cvutil.cpp
parent81f3ca8636f863d32f0da61c214077305f28ccfc (diff)
downloadcv2pdb-59dc1509092a46bb18e08f54ac5c4f859ca0ffa8.zip
cv2pdb-59dc1509092a46bb18e08f54ac5c4f859ca0ffa8.tar.gz
cv2pdb-59dc1509092a46bb18e08f54ac5c4f859ca0ffa8.tar.bz2
Version 0.15
* thanks to patches by Z3N, the resulting pdb is now usable by more debuggers * now uses shared file access to executable * incomplete structs/classes are now added as user defined types to avoid confusing debugger for following symbols * fixed name demangling of very long names * added name demangling support for @safe/@trusted/@property/pure/nothrow/ref * base classes are added to D/cpp-interfaces to allow viewing the virtual function table pointer * structs, classes and interfaces now have an internal qualifier attached that allows the preview in autoexp.dat to show better info for structs and interfaces
Diffstat (limited to 'src/cvutil.cpp')
-rw-r--r--src/cvutil.cpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/cvutil.cpp b/src/cvutil.cpp
new file mode 100644
index 0000000..c125b41
--- /dev/null
+++ b/src/cvutil.cpp
@@ -0,0 +1,169 @@
+// Convert DMD CodeView debug information to PDB files
+// Copyright (c) 2009-2010 by Rainer Schuetze, All Rights Reserved
+//
+// License for redistribution is given by the Artistic License 2.0
+// see file LICENSE for further details
+
+#include "cvutil.h"
+
+bool isStruct(const codeview_type* cvtype)
+{
+ switch(cvtype->common.id)
+ {
+ case LF_STRUCTURE_V1:
+ case LF_CLASS_V1:
+ case LF_STRUCTURE_V2:
+ case LF_CLASS_V2:
+ case LF_STRUCTURE_V3:
+ case LF_CLASS_V3:
+ return true;
+ }
+ return false;
+}
+
+int getStructProperty(const codeview_type* cvtype)
+{
+ switch(cvtype->common.id)
+ {
+ case LF_STRUCTURE_V1:
+ case LF_CLASS_V1:
+ return cvtype->struct_v1.property;
+ case LF_STRUCTURE_V2:
+ case LF_CLASS_V2:
+ return cvtype->struct_v2.property;
+ case LF_STRUCTURE_V3:
+ case LF_CLASS_V3:
+ return cvtype->struct_v3.property;
+ }
+ return 0;
+}
+
+int getStructFieldlist(const codeview_type* cvtype)
+{
+ switch(cvtype->common.id)
+ {
+ case LF_STRUCTURE_V1:
+ case LF_CLASS_V1:
+ return cvtype->struct_v1.fieldlist;
+ case LF_STRUCTURE_V2:
+ case LF_CLASS_V2:
+ return cvtype->struct_v2.fieldlist;
+ case LF_STRUCTURE_V3:
+ case LF_CLASS_V3:
+ return cvtype->struct_v3.fieldlist;
+ }
+ return 0;
+}
+
+const BYTE* getStructName(const codeview_type* cvtype, bool &cstr)
+{
+ int value, leaf_len;
+ switch(cvtype->common.id)
+ {
+ case LF_STRUCTURE_V1:
+ case LF_CLASS_V1:
+ cstr = false;
+ leaf_len = numeric_leaf(&value, &cvtype->struct_v1.structlen);
+ return (const BYTE*) &cvtype->struct_v1.structlen + leaf_len;
+ case LF_STRUCTURE_V2:
+ case LF_CLASS_V2:
+ cstr = false;
+ leaf_len = numeric_leaf(&value, &cvtype->struct_v2.structlen);
+ return (const BYTE*) &cvtype->struct_v2.structlen + leaf_len;
+ case LF_STRUCTURE_V3:
+ case LF_CLASS_V3:
+ cstr = true;
+ leaf_len = numeric_leaf(&value, &cvtype->struct_v3.structlen);
+ return (const BYTE*) &cvtype->struct_v3.structlen + leaf_len;
+ }
+ return 0;
+}
+
+bool cmpStructName(const codeview_type* cvtype, const BYTE* name, bool cstr)
+{
+ bool cstr2;
+ const BYTE* name2 = getStructName(cvtype, cstr2);
+ if(!name || !name2)
+ return name == name2;
+ return dstrcmp(name, cstr, name2, cstr2);
+}
+
+bool isCompleteStruct(const codeview_type* type, const BYTE* name, bool cstr)
+{
+ return isStruct(type)
+ && !(getStructProperty(type) & kPropIncomplete)
+ && cmpStructName(type, name, cstr);
+}
+
+int 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
+ {
+ length = 0; // error!
+ }
+ break;
+ }
+ return length;
+}
+