From dd308fa75adfe87dbff2201f60972ecadfe14e68 Mon Sep 17 00:00:00 2001 From: sagitario Date: Tue, 1 May 2012 16:13:31 +0000 Subject: Version 0.24 * supports unicode characters in file names * improve interpretation of DWARF location expression --- CHANGES | 6 +++ VERSION | 2 +- src/PEImage.cpp | 18 +++++-- src/PEImage.h | 6 +-- src/cv2pdb.cpp | 16 ++++-- src/cv2pdb.h | 6 +-- src/cv2pdb.vcproj | 7 ++- src/dwarf2pdb.cpp | 111 +++++++++++++++++++++--------------------- src/main.cpp | 142 ++++++++++++++++++++++++++++++++---------------------- src/mspdb.cpp | 2 +- src/mspdb.h | 2 +- test/cvtest.d | 28 +++++++++++ 12 files changed, 212 insertions(+), 134 deletions(-) diff --git a/CHANGES b/CHANGES index 37d7286..7acfa25 100644 --- a/CHANGES +++ b/CHANGES @@ -163,3 +163,9 @@ unreleased Version 0.22 * added DWARF support * added x64 support * tweaked visualizer for associative array element to just show key and value + +2012-05-01 Version 0.24 + + * supports unicode characters in file names + * improve interpretation of DWARF location expression + diff --git a/VERSION b/VERSION index 11300d1..d57b67e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -VERSION = 0.23 +VERSION = 0.24 diff --git a/src/PEImage.cpp b/src/PEImage.cpp index 1a9afbd..c2c01c5 100644 --- a/src/PEImage.cpp +++ b/src/PEImage.cpp @@ -18,8 +18,16 @@ extern "C" { #include #include +#ifdef UNICODE +#define T_sopen _wsopen +#define T_open _wopen +#else +#define T_sopen sopen +#define T_open open +#endif + /////////////////////////////////////////////////////////////////////// -PEImage::PEImage(const char* iname) +PEImage::PEImage(const TCHAR* iname) : dump_base(0) , dump_total_len(0) , dirHeader(0) @@ -51,12 +59,12 @@ PEImage::~PEImage() } /////////////////////////////////////////////////////////////////////// -bool PEImage::load(const char* iname) +bool PEImage::load(const TCHAR* iname) { if (fd != -1) return setError("file already open"); - fd = sopen(iname, O_RDONLY | O_BINARY, SH_DENYWR); + fd = T_sopen(iname, O_RDONLY | O_BINARY, SH_DENYWR); if (fd == -1) return setError("Can't open file"); @@ -78,7 +86,7 @@ bool PEImage::load(const char* iname) } /////////////////////////////////////////////////////////////////////// -bool PEImage::save(const char* oname) +bool PEImage::save(const TCHAR* oname) { if (fd != -1) return setError("file already open"); @@ -86,7 +94,7 @@ bool PEImage::save(const char* oname) 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); + fd = T_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"); diff --git a/src/PEImage.h b/src/PEImage.h index a2009aa..45bc76b 100644 --- a/src/PEImage.h +++ b/src/PEImage.h @@ -19,7 +19,7 @@ struct OMFDirEntry; class PEImage : public LastError { public: - PEImage(const char* iname = 0); + PEImage(const TCHAR* iname = 0); ~PEImage(); template P* DP(int off) const @@ -56,8 +56,8 @@ public: return 0; } - bool load(const char* iname); - bool save(const char* oname); + bool load(const TCHAR* iname); + bool save(const TCHAR* oname); bool replaceDebugSection (const void* data, int datalen, bool initCV); bool initCVPtr(bool initDbgDir); diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp index aa6380c..86e0409 100644 --- a/src/cv2pdb.cpp +++ b/src/cv2pdb.cpp @@ -125,10 +125,18 @@ bool CV2PDB::cleanup(bool commit) return true; } -bool CV2PDB::openPDB(const char* pdbname) +bool CV2PDB::openPDB(const TCHAR* pdbname) { +#ifdef UNICODE + const wchar_t* pdbnameW = pdbname; + char pdbnameA[260]; // = L"c:\\tmp\\aa\\ddoc4.pdb"; + WideCharToMultiByte(CP_UTF8, 0, pdbname, -1, pdbnameA, 260, 0, 0); + // wcstombs (pdbnameA, pdbname, 260); +#else + const char* pdbnameA = pdbname; wchar_t pdbnameW[260]; // = L"c:\\tmp\\aa\\ddoc4.pdb"; mbstowcs (pdbnameW, pdbname, 260); +#endif if (!initMsPdb ()) return setError("cannot load PDB helper DLL"); @@ -142,11 +150,11 @@ bool CV2PDB::openPDB(const char* pdbname) printf("PDB::QueryPdbImplementationVersion() = %d\n", pdb->QueryPdbImplementationVersion()); #endif - rsds = (OMFSignatureRSDS *) new char[24 + strlen(pdbname) + 1]; // sizeof(OMFSignatureRSDS) without name + rsds = (OMFSignatureRSDS *) new char[24 + strlen(pdbnameA) + 1]; // sizeof(OMFSignatureRSDS) without name memcpy (rsds->Signature, "RSDS", 4); pdb->QuerySignature2(&rsds->guid); rsds->unknown = pdb->QueryAge(); - strcpy(rsds->name, pdbname); + strcpy(rsds->name, pdbnameA); int rc = pdb->CreateDBI("", &dbi); if (rc <= 0 || !dbi) @@ -3096,7 +3104,7 @@ bool CV2PDB::addSymbols() return rc; } -bool CV2PDB::writeImage(const char* opath) +bool CV2PDB::writeImage(const TCHAR* opath) { int len = sizeof(*rsds) + strlen((char*)(rsds + 1)) + 1; if (!img.replaceDebugSection(rsds, len, true)) diff --git a/src/cv2pdb.h b/src/cv2pdb.h index 1adbe61..03e0b5e 100644 --- a/src/cv2pdb.h +++ b/src/cv2pdb.h @@ -28,7 +28,7 @@ public: ~CV2PDB(); bool cleanup(bool commit); - bool openPDB(const char* pdbname); + bool openPDB(const TCHAR* pdbname); bool setError(const char* msg); bool createModules(); @@ -152,7 +152,7 @@ public: bool createSrcLineBitmap(); int getNextSrcLine(int seg, unsigned int off); - bool writeImage(const char* opath); + bool writeImage(const TCHAR* opath); mspdb::Mod* globalMod(); @@ -163,7 +163,7 @@ public: bool addDWARFLines(); bool addDWARFPublics(); bool relocateDebugLineInfo(); - bool writeDWARFImage(const char* opath); + bool writeDWARFImage(const TCHAR* opath); bool addDWARFSectionContrib(mspdb::Mod* mod, unsigned long pclo, unsigned long pchi); bool addDWARFProc(DWARF_InfoData& id, DWARF_CompilationUnit* cu, unsigned char* &locals, unsigned char* end); diff --git a/src/cv2pdb.vcproj b/src/cv2pdb.vcproj index bb7e6e7..ea09f64 100644 --- a/src/cv2pdb.vcproj +++ b/src/cv2pdb.vcproj @@ -1,7 +1,7 @@ > stack[stackDepth-1]; stackDepth--; break; + case DW_OP_shra: stack[stackDepth-2] = stack[stackDepth-2] >> stack[stackDepth-1]; stackDepth--; break; + case DW_OP_xor: stack[stackDepth-2] = stack[stackDepth-2] ^ stack[stackDepth-1]; stackDepth--; break; + case DW_OP_eq: stack[stackDepth-2] = stack[stackDepth-2] == stack[stackDepth-1]; stackDepth--; break; + case DW_OP_ge: stack[stackDepth-2] = stack[stackDepth-2] >= stack[stackDepth-1]; stackDepth--; break; + case DW_OP_gt: stack[stackDepth-2] = stack[stackDepth-2] > stack[stackDepth-1]; stackDepth--; break; + case DW_OP_le: stack[stackDepth-2] = stack[stackDepth-2] <= stack[stackDepth-1]; stackDepth--; break; + case DW_OP_lt: stack[stackDepth-2] = stack[stackDepth-2] < stack[stackDepth-1]; stackDepth--; break; + case DW_OP_ne: stack[stackDepth-2] = stack[stackDepth-2] != stack[stackDepth-1]; stackDepth--; break; + case DW_OP_bra: case DW_OP_skip: size = RD2(p) + 2; break; } - if(id >= 0) - stackDepth++; p += size; } - while(false); // stackDepth > 0); + while(stackDepth > 0); size = p - loc; - return data; + return stack[0]; } -long decodeLocation(unsigned long long loc, int &id) +long decodeLocation(unsigned long long loc, bool push0, int &id) { int size; - return decodeLocation((unsigned char*) &loc, id, size); + return decodeLocation((unsigned char*) &loc, push0, id, size); } unsigned char* CV2PDB::getDWARFAbbrev(int off, int findcode) @@ -726,7 +729,7 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, { if(id.name) { - off = decodeLocation(id.location, cvid); + off = decodeLocation(id.location, false, cvid); if(cvid == S_BPREL_V2) appendStackVar(id.name, getTypeByDWARFOffset(cu, id.type), off + frameOff); } @@ -740,7 +743,7 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, case DW_TAG_variable: if(id.name) { - off = decodeLocation(id.location, cvid); + off = decodeLocation(id.location, false, cvid); if(cvid == S_BPREL_V2) appendStackVar(id.name, getTypeByDWARFOffset(cu, id.type), off + frameOff); } @@ -815,7 +818,7 @@ int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* c int cvid = -1; if (id.tag == DW_TAG_member && id.name) { - int off = isunion ? 0 : decodeLocation(id.member_location, cvid); + int off = isunion ? 0 : decodeLocation(id.member_location, true, cvid); if(isunion || cvid == S_CONSTANT_V2) { checkDWARFTypeAlloc(kMaxNameLen + 100); @@ -826,7 +829,7 @@ int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* c } else if(id.tag == DW_TAG_inheritance) { - int off = decodeLocation(id.member_location, cvid); + int off = decodeLocation(id.member_location, true, cvid); if(cvid == S_CONSTANT_V2) { codeview_fieldtype* bc = (codeview_fieldtype*) (dwarfTypes + cbDwarfTypes); @@ -1253,7 +1256,7 @@ bool CV2PDB::iterateDWARFDebugInfo(int op) else { int cvid; - segOff = decodeLocation(id.location, cvid); + segOff = decodeLocation(id.location, false, cvid); if(cvid == S_GDATA_V2) seg = img.findSection(segOff); if(seg >= 0) @@ -1691,7 +1694,7 @@ bool CV2PDB::addDWARFPublics() return true; } -bool CV2PDB::writeDWARFImage(const char* opath) +bool CV2PDB::writeDWARFImage(const TCHAR* opath) { int len = sizeof(*rsds) + strlen((char*)(rsds + 1)) + 1; if (!img.replaceDebugSection(rsds, len, false)) diff --git a/src/main.cpp b/src/main.cpp index 7ac2972..110589d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,32 @@ double #include "../VERSION" ; +#ifdef UNICODE +#define T_toupper towupper +#define T_getdcwd _wgetdcwd +#define T_strlen wcslen +#define T_strcpy wcscpy +#define T_strcat wcscat +#define T_strstr wcsstr +#define T_strtod wcstod +#define T_strrchr wcsrchr +#define T_unlink _wremove +#define T_main wmain +#define SARG "%S" +#else +#define T_toupper toupper +#define T_getdcwd _getdcwd +#define T_strlen strlen +#define T_strcpy strcpy +#define T_strcat strcat +#define T_strstr strstr +#define T_strtod strtod +#define T_strrchr strrchr +#define T_unlink unlink +#define T_main main +#define SARG "%s" +#endif + void fatal(const char *message, ...) { va_list argptr; @@ -24,18 +50,18 @@ void fatal(const char *message, ...) exit(1); } -void makefullpath(char* pdbname) +void makefullpath(TCHAR* pdbname) { - char* pdbstart = pdbname; - char fullname[260]; - char* pfullname = fullname; + TCHAR* pdbstart = pdbname; + TCHAR fullname[260]; + TCHAR* pfullname = fullname; int drive = 0; if (pdbname[0] && pdbname[1] == ':') { if (pdbname[2] == '\\' || pdbname[2] == '/') return; - drive = toupper (pdbname[0]); + drive = T_toupper (pdbname[0]); pdbname += 2; } else @@ -45,8 +71,8 @@ void makefullpath(char* pdbname) if (*pdbname != '\\' && *pdbname != '/') { - _getdcwd(drive, pfullname, sizeof(fullname) - 2); - pfullname += strlen(pfullname); + T_getdcwd(drive, pfullname, sizeof(fullname)/sizeof(fullname[0]) - 2); + pfullname += T_strlen(pfullname); if (pfullname[-1] != '\\') *pfullname++ = '\\'; } @@ -55,42 +81,30 @@ void makefullpath(char* pdbname) *pfullname++ = 'a' - 1 + drive; *pfullname++ = ':'; } - strcpy(pfullname, pdbname); - strcpy(pdbstart, fullname); + T_strcpy(pfullname, pdbname); + T_strcpy(pdbstart, fullname); - for(char*p = pdbstart; *p; p++) + for(TCHAR*p = pdbstart; *p; p++) if (*p == '/') *p = '\\'; // remove relative parts "./" and "../" - while (char* p = strstr (pdbstart, "\\.\\")) - strcpy(p, p + 2); + while (TCHAR* p = T_strstr (pdbstart, TEXT("\\.\\"))) + T_strcpy(p, p + 2); - while (char* p = strstr (pdbstart, "\\..\\")) + while (TCHAR* p = T_strstr (pdbstart, TEXT("\\..\\"))) { - for (char* q = p - 1; q >= pdbstart; q--) + for (TCHAR* q = p - 1; q >= pdbstart; q--) if (*q == '\\') { - strcpy(q, p + 3); + T_strcpy(q, p + 3); break; } } } -int main(int argc, char** argv) +int T_main(int argc, TCHAR* argv[]) { - if (argc < 2) - { - printf("Convert DMD CodeView/DWARF debug information to PDB files, Version %g\n", VERSION); - printf("Copyright (c) 2009-2012 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|-n|-sC] [new-exe-file] [pdb-file]\n", argv[0]); - return -1; - } - PEImage img; double Dversion = 2.043; @@ -101,7 +115,7 @@ int main(int argc, char** argv) if (argv[0][1] == '-') break; if (argv[0][1] == 'D') - Dversion = strtod (argv[0] + 2, 0); + Dversion = T_strtod(argv[0] + 2, 0); else if (argv[0][1] == 'C') Dversion = 0; else if (argv[0][1] == 'n') @@ -109,91 +123,103 @@ int main(int argc, char** argv) else if (argv[0][1] == 'e') useTypedefEnum = true; else if (argv[0][1] == 's' && argv[0][2]) - dotReplacementChar = argv[0][2]; + dotReplacementChar = (char)argv[0][2]; else - fatal("unknown option: %s", argv[0]); + fatal("unknown option: " SARG, argv[0]); + } + + if (argc < 2) + { + printf("Convert DMD CodeView/DWARF debug information to PDB files, Version %g\n", VERSION); + printf("Copyright (c) 2009-2012 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: " SARG " [-Dversion|-C|-n|-sC] [new-exe-file] [pdb-file]\n", argv[0]); + return -1; } if (!img.load(argv[1])) - fatal("%s: %s", argv[1], img.getLastError()); + fatal(SARG ": %s", argv[1], img.getLastError()); if (img.countCVEntries() == 0 && !img.hasDWARF()) - fatal("%s: no codeview debug entries found", argv[1]); + fatal(SARG ": no codeview debug entries found", argv[1]); CV2PDB cv2pdb(img); cv2pdb.Dversion = Dversion; cv2pdb.initLibraries(); - char* outname = argv[1]; + TCHAR* outname = argv[1]; if (argc > 2 && argv[2][0]) outname = argv[2]; - char pdbname[260]; + TCHAR pdbname[260]; if (argc > 3) - strcpy (pdbname, argv[3]); + T_strcpy (pdbname, argv[3]); else { - strcpy (pdbname, outname); - char *pDot = strrchr (pdbname, '.'); - if (!pDot || pDot <= strrchr (pdbname, '/') || pDot <= strrchr (pdbname, '\\')) - strcat (pdbname, ".pdb"); + T_strcpy (pdbname, outname); + TCHAR *pDot = T_strrchr (pdbname, '.'); + if (!pDot || pDot <= T_strrchr (pdbname, '/') || pDot <= T_strrchr (pdbname, '\\')) + T_strcat (pdbname, TEXT(".pdb")); else - strcpy (pDot, ".pdb"); + T_strcpy (pDot, TEXT(".pdb")); } makefullpath(pdbname); - unlink(pdbname); + T_unlink(pdbname); if(!cv2pdb.openPDB(pdbname)) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if(img.hasDWARF()) { if(!cv2pdb.relocateDebugLineInfo()) - fatal("%s: %s", argv[1], cv2pdb.getLastError()); + fatal(SARG ": %s", argv[1], cv2pdb.getLastError()); if(!cv2pdb.createDWARFModules()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if(!cv2pdb.addDWARFTypes()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if(!cv2pdb.addDWARFLines()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if (!cv2pdb.addDWARFPublics()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if (!cv2pdb.writeDWARFImage(outname)) - fatal("%s: %s", outname, cv2pdb.getLastError()); + fatal(SARG ": %s", outname, cv2pdb.getLastError()); } else { if (!cv2pdb.initSegMap()) - fatal("%s: %s", argv[1], cv2pdb.getLastError()); + fatal(SARG ": %s", argv[1], cv2pdb.getLastError()); if (!cv2pdb.initGlobalSymbols()) - fatal("%s: %s", argv[1], cv2pdb.getLastError()); + fatal(SARG ": %s", argv[1], cv2pdb.getLastError()); if (!cv2pdb.initGlobalTypes()) - fatal("%s: %s", argv[1], cv2pdb.getLastError()); + fatal(SARG ": %s", argv[1], cv2pdb.getLastError()); if (!cv2pdb.createModules()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if (!cv2pdb.addTypes()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if (!cv2pdb.addSymbols()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if (!cv2pdb.addSrcLines()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if (!cv2pdb.addPublics()) - fatal("%s: %s", pdbname, cv2pdb.getLastError()); + fatal(SARG ": %s", pdbname, cv2pdb.getLastError()); if (!cv2pdb.writeImage(outname)) - fatal("%s: %s", outname, cv2pdb.getLastError()); + fatal(SARG ": %s", outname, cv2pdb.getLastError()); } return 0; diff --git a/src/mspdb.cpp b/src/mspdb.cpp index 76ec6d7..ee30833 100644 --- a/src/mspdb.cpp +++ b/src/mspdb.cpp @@ -93,7 +93,7 @@ bool exitMsPdb() return true; } -mspdb::PDB* CreatePDB(wchar_t* pdbname) +mspdb::PDB* CreatePDB(const wchar_t* pdbname) { if (!initMsPdb ()) return 0; diff --git a/src/mspdb.h b/src/mspdb.h index 16209b4..a0abf78 100644 --- a/src/mspdb.h +++ b/src/mspdb.h @@ -526,7 +526,7 @@ public: virtual void EnumNameMap_Special::get(char const * *,unsigned long *); bool initMsPdb(); bool exitMsPdb(); -mspdb::PDB* CreatePDB(wchar_t* pdbname); +mspdb::PDB* CreatePDB(const wchar_t* pdbname); extern char* mspdb_dll; diff --git a/test/cvtest.d b/test/cvtest.d index 0794e9e..5b5d233 100644 --- a/test/cvtest.d +++ b/test/cvtest.d @@ -1,6 +1,24 @@ module cvtest; +version(none) +{ + int[int] global_oem_int_assoc_array; + + int args(int a, int b, int c, int abc) + { + int d = a + b; + int e = b + c; + foreach(x; global_oem_int_assoc_array) + e += x; + return d + e + abc; + } + void main() + { + args(3, 4, 5, 345); + } +} +version(all): import std.string; import std.stdio; @@ -220,6 +238,15 @@ void voidpointers(ubyte* p) const(int*) const_ip2 = cast(const(int*)) p; } +int args(int a, int b, int c, int abc) +{ + int d = a + b; + int e = b + c; + foreach(x; global_oem_int_assoc_array) + e += x; + return d + e + abc; +} + size_t arrays() { int[] iarr; @@ -330,6 +357,7 @@ int main(char[][]argv) long lng = 3; ulong ulng = 4; + args(3, 4, 5, 345); voidpointers(null); arrays(); lexical_scope(); -- cgit v0.12