From 1157fd5b8b7ad5feced2304400ea2a6d34fc9998 Mon Sep 17 00:00:00 2001 From: sagitario Date: Tue, 13 Apr 2010 06:33:54 +0000 Subject: --- CHANGES | 2 ++ README | 2 +- VERSION | 2 +- autoexp.snippet | 41 +++++++++++++++++++++++ src/LastError.h | 2 +- src/PEImage.cpp | 74 ++++++++++++++++++++--------------------- src/PEImage.h | 26 +++++++-------- src/cv2pdb.cpp | 42 +++++++++++++++++------ src/cv2pdb.h | 2 +- src/demangle.h | 2 +- src/dviewhelper/dviewhelper.cpp | 2 +- src/main.cpp | 4 +-- src/mspdb.cpp | 2 +- src/mspdb.h | 8 ++--- src/symutil.cpp | 2 +- src/symutil.h | 2 +- 16 files changed, 139 insertions(+), 76 deletions(-) diff --git a/CHANGES b/CHANGES index 4460394..236686c 100644 --- a/CHANGES +++ b/CHANGES @@ -88,3 +88,5 @@ Version 0.12 * dmd 2.041 fixes long/ulong support (patch http://d.puremagic.com/issues/show_bug.cgi?id=3373 no longer needed) * added managed C++ project to integrate cv2pdb with CLR (thanks to Alexander Bothe) + * dmd 2.043 uses different implementation of associative arrays, use command line + option -D 2.043 or above to produce the respective debug info diff --git a/README b/README index f9851f8..cf17e0c 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ This is the README file for cv2pdb, a converter of DMD CodeView debug information to PDB files -Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +Copyright (c) 2009-2010 by Rainer Schuetze, All Rights Reserved The goal of this project is to make debugging of D applications that were created with the Digital Mars DMD compiler, as seamless as possible diff --git a/VERSION b/VERSION index 2a01178..b8eae15 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -VERSION = 0.11 +VERSION = 0.12 diff --git a/autoexp.snippet b/autoexp.snippet index 0165311..5917595 100644 --- a/autoexp.snippet +++ b/autoexp.snippet @@ -154,6 +154,47 @@ aa<*> { ) } +;; display associative array (starting with with dmd2.043, new sizes 4 and 31 were added, and +;; a list is used per hash entry instead of a tree +;; remember to pass -D 2.043 to cv2pdb to produce suitable debug info +;; +aa2<*> { + preview( + #if($e.a == 0 || $e.a->b.ptr == 0) ( "null" ) + ; expressions must be in a single line (sigh) + #elif($e.a->b.length == 4 || $e.a->b.length == 31 || $e.a->b.length == 97 || $e.a->b.length == 389 || $e.a->b.length == 1543 || $e.a->b.length == 6151 || $e.a->b.length == 24593 || $e.a->b.length == 98317 || $e.a->b.length == 393241 || $e.a->b.length == 1572869 || $e.a->b.length == 6291469 || $e.a->b.length == 25165843) + ( + #if($e.a->nodes > 1024) ( + #( "[", $e.a->nodes, "] ", [(void*) $e.a], " too large for expansion" ) + ) + #else ( + #( "[", $e.a->nodes, "] ", [(void*) $e.a] ) + ) + ) + #elif (1) ; no #else in a series of #elif !? + ( + #( "[", $e.a->nodes, "] ", [(void*) $e.a], " uninitialized" ) + ) + ) + children( + #if($e.a == 0 || $e.a->b.ptr == 0 || $e.a->nodes > 1024) + ( #array( expr: 0, size: 0 ) ) + #else ( + #( + #array ( + expr: &$e.a->b.ptr[$i], + size: $e.a->b.length + ) : + ; DMD 2.043+ + #list ( + head : $e, + next : next + ) : $e + ) + ) + ) +} + ; display tree internal@aaA<*,*> { preview( diff --git a/src/LastError.h b/src/LastError.h index b7b6f27..4cbb0b9 100644 --- a/src/LastError.h +++ b/src/LastError.h @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 diff --git a/src/PEImage.cpp b/src/PEImage.cpp index d926078..2a3cbc0 100644 --- a/src/PEImage.cpp +++ b/src/PEImage.cpp @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 @@ -40,48 +40,48 @@ PEImage::~PEImage() bool PEImage::load(const char* iname) { if (fd != -1) - return setError("file already open"); + return setError("file already open"); - fd = open(iname, O_RDONLY | O_BINARY); - if (fd == -1) - return setError("Can't open file"); - - struct stat s; - if (fstat(fd, &s) < 0) - return setError("Can't get size"); - dump_total_len = s.st_size; + fd = open(iname, O_RDONLY | O_BINARY); + if (fd == -1) + return setError("Can't open file"); + + struct stat s; + if (fstat(fd, &s) < 0) + return setError("Can't get size"); + dump_total_len = s.st_size; dump_base = alloc_aligned(dump_total_len, 0x1000); - if (!dump_base) - return setError("Out of memory"); - if (read(fd, dump_base, dump_total_len) != dump_total_len) - return setError("Cannot read file"); - - - close(fd); - fd = -1; - return initPtr(true); + if (!dump_base) + return setError("Out of memory"); + if (read(fd, dump_base, dump_total_len) != dump_total_len) + return setError("Cannot read file"); + + + close(fd); + fd = -1; + return initPtr(true); } /////////////////////////////////////////////////////////////////////// bool PEImage::save(const char* oname) { if (fd != -1) - return setError("file already open"); - + return setError("file already open"); + if (!dump_base) - return setError("no data to dump"); - - fd = open(oname, O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, S_IREAD | S_IWRITE | S_IEXEC); - if (fd == -1) - return setError("Can't create file"); - - if (write(fd, dump_base, dump_total_len) != dump_total_len) - return setError("Cannot write file"); - - close(fd); - fd = -1; - return true; + return setError("no data to dump"); + + fd = open(oname, O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, S_IREAD | S_IWRITE | S_IEXEC); + if (fd == -1) + return setError("Can't create file"); + + if (write(fd, dump_base, dump_total_len) != dump_total_len) + return setError("Cannot write file"); + + close(fd); + fd = -1; + return true; } /////////////////////////////////////////////////////////////////////// @@ -203,17 +203,17 @@ bool PEImage::initPtr(bool initDbgDir) OMFSignature* sig = DPV(cv_base, dbgDir->SizeOfData); if (!sig) return setError("invalid debug data base address and size"); - if (memcmp(sig->Signature, "NB09", 4) != 0 && memcmp(sig->Signature, "NB11", 4) != 0) - { + if (memcmp(sig->Signature, "NB09", 4) != 0 && memcmp(sig->Signature, "NB11", 4) != 0) + { // return setError("can only handle debug info of type NB09 and NB11"); dirHeader = 0; dirEntry = 0; return true; } - dirHeader = CVP(sig->filepos); + dirHeader = CVP(sig->filepos); if (!dirHeader) return setError("invalid cv dir header data base address"); - dirEntry = CVP(sig->filepos + dirHeader->cbDirHeader); + dirEntry = CVP(sig->filepos + dirHeader->cbDirHeader); if (!dirEntry) return setError("cv debug dir entries invalid"); diff --git a/src/PEImage.h b/src/PEImage.h index 039d2a1..a43d02b 100644 --- a/src/PEImage.h +++ b/src/PEImage.h @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 @@ -39,20 +39,20 @@ public: return DPV

(cv_base + off, sizeof(P)); } - template P* RVA(unsigned long rva, int len) - { + template P* RVA(unsigned long rva, int len) + { IMAGE_DOS_HEADER *dos = DPV (0); IMAGE_NT_HEADERS32* hdr = DPV (dos->e_lfanew); IMAGE_SECTION_HEADER* sec = IMAGE_FIRST_SECTION(hdr); - - for (int i = 0; i < hdr->FileHeader.NumberOfSections; i++) - { - if (rva >= sec[i].VirtualAddress && - rva + len <= sec[i].VirtualAddress + sec[i].SizeOfRawData) - return DPV

(sec[i].PointerToRawData + rva - sec[i].VirtualAddress, len); - } - return 0; - } + + for (int i = 0; i < hdr->FileHeader.NumberOfSections; i++) + { + if (rva >= sec[i].VirtualAddress && + rva + len <= sec[i].VirtualAddress + sec[i].SizeOfRawData) + return DPV

(sec[i].PointerToRawData + rva - sec[i].VirtualAddress, len); + } + return 0; + } bool load(const char* iname); bool save(const char* oname); @@ -71,7 +71,7 @@ public: private: int fd; - void* dump_base; + void* dump_base; int dump_total_len; IMAGE_DOS_HEADER *dos; diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp index c56fa75..0a66e8e 100644 --- a/src/cv2pdb.cpp +++ b/src/cv2pdb.cpp @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 @@ -1211,7 +1211,10 @@ bool CV2PDB::nameOfDynamicArray(int indexType, int elemType, char* name, int max bool CV2PDB::nameOfAssocArray(int indexType, int elemType, char* name, int maxlen) { - strcpy(name, "aa<"); + if(Dversion >= 2.043) + strcpy(name, "aa2<"); // to distinguish tree from list implementation + else + strcpy(name, "aa<"); int len = strlen(name); if (!nameOfType(elemType, name + len, maxlen - len)) return false; @@ -1359,33 +1362,50 @@ const char* CV2PDB::appendAssocArray(int keyType, int elemType) rdtype = (codeview_reftype*) (userTypes + cbUserTypes); rdtype->fieldlist.id = LF_FIELDLIST_V2; + int len1 = 0; + int len2 = 0; + int off = 0; // member aaA* left - dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; - int len1 = addFieldMember(dfieldtype, 1, 0, aaAPtrType, "left"); - - dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); - int len2 = addFieldMember(dfieldtype, 1, 4, aaAPtrType, "right"); + if(Dversion >= 2.043) + { + dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + len1 = addFieldMember(dfieldtype, 1, off, aaAPtrType, "next"); + off += 4; + } + else + { + dfieldtype = (codeview_fieldtype*)rdtype->fieldlist.list; + len1 = addFieldMember(dfieldtype, 1, off, aaAPtrType, "left"); + off += 4; + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1); + len2 = addFieldMember(dfieldtype, 1, off, aaAPtrType, "right"); + off += 4; + } dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2); - int len3 = addFieldMember(dfieldtype, 1, 8, 0x74, "hash"); + int len3 = addFieldMember(dfieldtype, 1, off, 0x74, "hash"); + off += 4; dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2 + len3); - int len4 = addFieldMember(dfieldtype, 1, 12, keyType, "key"); + int len4 = addFieldMember(dfieldtype, 1, off, keyType, "key"); int typeLen = sizeofType(keyType); typeLen = (typeLen + 3) & ~3; // align to 4 byte + off += typeLen; + dfieldtype = (codeview_fieldtype*)(rdtype->fieldlist.list + len1 + len2 + len3 + len4); - int len5 = addFieldMember(dfieldtype, 1, 12 + typeLen, elemType, "value"); + int len5 = addFieldMember(dfieldtype, 1, off, elemType, "value"); int elemLen = sizeofType(elemType); elemLen = (elemLen + 3) & ~3; // align to 4 byte + off += elemLen; rdtype->fieldlist.len = len1 + len2 + len3 + len4 + len5 + 2; cbUserTypes += rdtype->fieldlist.len + 2; int fieldListType = nextUserType++; dtype = (codeview_type*) (userTypes + cbUserTypes); - cbUserTypes += addClass(dtype, 5, fieldListType, 0, 0, 0, 12 + typeLen + elemLen, name); + cbUserTypes += addClass(dtype, len2 == 0 ? 4 : 5, fieldListType, 0, 0, 0, off, name); addUdtSymbol(nextUserType, name); int completeAAAType = nextUserType++; diff --git a/src/cv2pdb.h b/src/cv2pdb.h index 03271d5..48b67d5 100644 --- a/src/cv2pdb.h +++ b/src/cv2pdb.h @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 diff --git a/src/demangle.h b/src/demangle.h index 0a63c60..430b41e 100644 --- a/src/demangle.h +++ b/src/demangle.h @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 diff --git a/src/dviewhelper/dviewhelper.cpp b/src/dviewhelper/dviewhelper.cpp index 110cc09..3cee363 100644 --- a/src/dviewhelper/dviewhelper.cpp +++ b/src/dviewhelper/dviewhelper.cpp @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////// // // DViewHelper - Expression Evaluator for the D string and object class -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 diff --git a/src/main.cpp b/src/main.cpp index 55bbf8c..644e27d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 @@ -81,7 +81,7 @@ 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 by Rainer Schuetze, All Rights Reserved\n"); + printf("Copyright (c) 2009-2010 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"); diff --git a/src/mspdb.cpp b/src/mspdb.cpp index b7a92a4..fe10243 100644 --- a/src/mspdb.cpp +++ b/src/mspdb.cpp @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 diff --git a/src/mspdb.h b/src/mspdb.h index c3b92ec..7104fc2 100644 --- a/src/mspdb.h +++ b/src/mspdb.h @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 @@ -239,8 +239,8 @@ public: virtual bool Src::QueryByNameW(unsigned short *,struct SrcHeaderOut *)co public: virtual bool Src::AddW(struct SrcHeaderW const *,void const *); }; -#include "pshpack1.h" - +#include "pshpack1.h" + struct LineInfoEntry { unsigned int offset; @@ -294,7 +294,7 @@ struct TypeData // followed by TypeChunks }; -#include "poppack.h" +#include "poppack.h" struct Mod { public: virtual unsigned long Mod::QueryInterfaceVersion(void); diff --git a/src/symutil.cpp b/src/symutil.cpp index 5556f1d..fe8f3e6 100644 --- a/src/symutil.cpp +++ b/src/symutil.cpp @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 diff --git a/src/symutil.h b/src/symutil.h index a055a7a..aa69987 100644 --- a/src/symutil.h +++ b/src/symutil.h @@ -1,5 +1,5 @@ // Convert DMD CodeView debug information to PDB files -// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved +// 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 -- cgit v0.12