diff options
author | sagitario <sagitario@fc51e93f-b9fe-4711-8d8d-3ae870c5f7d8> | 2009-06-19 11:03:14 (GMT) |
---|---|---|
committer | sagitario <sagitario@fc51e93f-b9fe-4711-8d8d-3ae870c5f7d8> | 2009-06-19 11:03:14 (GMT) |
commit | d2251150c76d9c2b139c3cc86aeaedd99ba2d03d (patch) | |
tree | 2273ab1599f51006f8d8bf57f95ea64b35518c60 | |
parent | d23bb945bd86c6533c78846f095337d776e2bc4a (diff) | |
download | cv2pdb-d2251150c76d9c2b139c3cc86aeaedd99ba2d03d.zip cv2pdb-d2251150c76d9c2b139c3cc86aeaedd99ba2d03d.tar.gz cv2pdb-d2251150c76d9c2b139c3cc86aeaedd99ba2d03d.tar.bz2 |
v0.9:
* fixed line number info at the end of a segment or when switching to another file because of inline expansion
* fixed line numbers > 32767 and sections with 0 line number entries
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | INSTALL | 13 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | src/cv2pdb.cpp | 137 | ||||
-rw-r--r-- | src/cv2pdb.h | 9 |
7 files changed, 158 insertions, 14 deletions
@@ -57,3 +57,10 @@ Version history to arrays with less than 1024 entries
* renamed data pointer member of dynamic arrays to "ptr" to be consistent with the array property
in D.
+
+2009-06-19 Version 0.9
+
+ * fixed line number info at the end of a segment or when switching to another file
+ because of inline expansion
+ * fixed line numbers > 32767 and sections with 0 line number entries
+
@@ -34,11 +34,7 @@ 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. 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
+4. 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
@@ -48,6 +44,13 @@ for the section [hresult]. These lines will enable a convenient display of strings, dynamic arrays,
associative arrays, object types and null references.
+5. 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. Alternatively,
+the full path can be specified in the corresponding entries in the
+[AutoExpand] section of autoexp.dat.
+
+
Building from source
--------------------
The source package comes with a Visual Studio 2008 project and solution
@@ -19,7 +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
-* also works for the Digital Mars C/C++ compiler DMC
+* also works debugging executables built with the Digital Mars C/C++ compiler DMC
License information
-------------------
@@ -21,7 +21,5 @@ in the future, but not all have a known solution. * type display of delegate does not have arguments
* 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
@@ -1 +1 @@ -VERSION = 0.8
+VERSION = 0.9
diff --git a/src/cv2pdb.cpp b/src/cv2pdb.cpp index 48d42b9..4db93b1 100644 --- a/src/cv2pdb.cpp +++ b/src/cv2pdb.cpp @@ -15,11 +15,12 @@ static const int kIncomplete = 0x80; CV2PDB::CV2PDB(PEImage& image)
: img(image), pdb(0), dbi(0), libraries(0), rsds(0), modules(0), globmod(0)
-, segMap(0), segMapDesc(0), globalTypeHeader(0)
+, segMap(0), segMapDesc(0), segFrame2Index(0), globalTypeHeader(0)
, globalTypes(0), cbGlobalTypes(0), allocGlobalTypes(0)
, userTypes(0), cbUserTypes(0), allocUserTypes(0)
, globalSymbols(0), cbGlobalSymbols(0), staticSymbols(0), cbStaticSymbols(0)
, udtSymbols(0), cbUdtSymbols(0), allocUdtSymbols(0)
+, srcLineStart(0), srcLineSections(0)
, pointerTypes(0)
, Dversion(2)
{
@@ -66,6 +67,15 @@ bool CV2PDB::cleanup(bool commit) free(udtSymbols);
delete [] pointerTypes;
+ for(int i = 0; i < srcLineSections; i++)
+ delete [] srcLineStart[i];
+ delete [] srcLineStart;
+ srcLineStart = 0;
+ srcLineSections = 0;
+
+ delete [] segFrame2Index;
+ segFrame2Index = 0;
+
globalTypes = 0;
cbGlobalTypes = 0;
allocGlobalTypes = 0;
@@ -230,12 +240,20 @@ bool CV2PDB::initSegMap() case sstSegMap: segMap = img.CVP<OMFSegMap>(entry->lfo);
segMapDesc = img.CVP<OMFSegMapDesc>(entry->lfo + sizeof(OMFSegMap));
+ int maxframe = -1;
for (int s = 0; s < segMap->cSeg; s++)
{
int rc = dbi->AddSec(segMapDesc[s].frame, segMapDesc[s].flags, segMapDesc[s].offset, segMapDesc[s].cbSeg); if (rc <= 0) return setError("cannot add section"); + if (segMapDesc[s].frame > maxframe) + maxframe = segMapDesc[s].frame; }
+
+ segFrame2Index = new int[maxframe + 1];
+ memset(segFrame2Index, -1, (maxframe + 1) * sizeof(*segFrame2Index));
+ for (int s = 0; s < segMap->cSeg; s++)
+ segFrame2Index[segMapDesc[s].frame] = s;
break;
}
}
@@ -1835,6 +1853,110 @@ bool CV2PDB::addTypes() return true; } +bool CV2PDB::markSrcLineInBitmap(int segIndex, int adr)
+{
+ if (segIndex < 0 || segIndex >= segMap->cSeg) + return setError("invalid segment info in line number info"); + + int off = adr - segMapDesc[segIndex].offset; + if (off < 0 || off >= (int) segMapDesc[segIndex].cbSeg) + return setError("invalid segment offset in line number info"); + + srcLineStart[segIndex][off] = true; + return true; +}
+
+bool CV2PDB::createSrcLineBitmap()
+{
+ if (srcLineStart)
+ return true;
+ if (!segMap || !segMapDesc || !segFrame2Index)
+ return false;
+
+ srcLineSections = segMap->cSeg;
+ srcLineStart = new char*[srcLineSections];
+ memset(srcLineStart, 0, srcLineSections * sizeof (*srcLineStart));
+
+ for (int s = 0; s < segMap->cSeg; s++)
+ {
+ srcLineStart[s] = new char[segMapDesc[s].cbSeg];
+ memset(srcLineStart[s], 0, segMapDesc[s].cbSeg);
+ }
+
+ for (int m = 0; m < countEntries; m++)
+ {
+ OMFDirEntry* entry = img.getCVEntry(m);
+ if(entry->SubSection == sstSrcModule) + { + // mark the beginning of each line + OMFSourceModule* sourceModule = img.CVP<OMFSourceModule>(entry->lfo); + int* segStartEnd = img.CVP<int>(entry->lfo + 4 + 4 * sourceModule->cFile); + short* seg = img.CVP<short>(entry->lfo + 4 + 4 * sourceModule->cFile + 8 * sourceModule->cSeg); + + for (int f = 0; f < sourceModule->cFile; f++) + { + int cvoff = entry->lfo + sourceModule->baseSrcFile[f]; + OMFSourceFile* sourceFile = img.CVP<OMFSourceFile> (cvoff); + int* lnSegStartEnd = img.CVP<int>(cvoff + 4 + 4 * sourceFile->cSeg); + + for (int s = 0; s < sourceFile->cSeg; s++) + { + int lnoff = entry->lfo + sourceFile->baseSrcLn[s]; + OMFSourceLine* sourceLine = img.CVP<OMFSourceLine> (lnoff); + short* lineNo = img.CVP<short> (lnoff + 4 + 4 * sourceLine->cLnOff); + + int cnt = sourceLine->cLnOff; + int segIndex = segFrame2Index[sourceLine->Seg]; + + // also mark the start of the line info segment + if (!markSrcLineInBitmap(segIndex, lnSegStartEnd[2*s])) + return false; + + for (int ln = 0; ln < cnt; ln++) + if (!markSrcLineInBitmap(segIndex, sourceLine->offset[ln])) + return false; + } + } + } + if (entry->SubSection == sstModule) + { + // mark the beginning of each section + OMFModule* module = img.CVP<OMFModule>(entry->lfo); + OMFSegDesc* segDesc = img.CVP<OMFSegDesc>(entry->lfo + sizeof(OMFModule)); + + for (int s = 0; s < module->cSeg; s++)
+ {
+ int seg = segDesc[s].Seg; + int segIndex = seg >= 0 && seg < segMap->cSeg ? segFrame2Index[seg] : -1; + if (!markSrcLineInBitmap(segIndex, segDesc[s].Off)) + return false; + }
+ } + }
+
+ return true;
+}
+
+int CV2PDB::getNextSrcLine(int seg, unsigned int off)
+{
+ if (!createSrcLineBitmap())
+ return -1;
+
+ int s = segFrame2Index[seg]; + if (s < 0) + return -1; + + off -= segMapDesc[s].offset;
+ if (off < 0 || off >= segMapDesc[s].cbSeg)
+ return 0;
+
+ for (off++; off < segMapDesc[s].cbSeg; off++)
+ if (srcLineStart[s][off])
+ break;
+
+ return off + segMapDesc[s].offset;
+}
+
bool CV2PDB::addSrcLines()
{
for (int m = 0; m < countEntries; m++)
@@ -1862,11 +1984,16 @@ bool CV2PDB::addSrcLines() { int lnoff = entry->lfo + sourceFile->baseSrcLn[s]; OMFSourceLine* sourceLine = img.CVP<OMFSourceLine> (lnoff); - short* lineNo = img.CVP<short> (lnoff + 4 + 4 * sourceLine->cLnOff); + unsigned short* lineNo = img.CVP<unsigned short> (lnoff + 4 + 4 * sourceLine->cLnOff); - int segoff = lnSegStartEnd[2*s]; - int seglength = lnSegStartEnd[2*s + 1] - segoff; + int seg = sourceLine->Seg; int cnt = sourceLine->cLnOff; + if(cnt <= 0) + continue; + int segoff = lnSegStartEnd[2*s]; + // lnSegStartEnd[2*s + 1] only spans until the first byte of the last source line + int segend = getNextSrcLine(seg, sourceLine->offset[cnt-1]); + int seglength = (segend >= 0 ? segend - 1 - segoff : lnSegStartEnd[2*s + 1] - segoff); mspdb::LineInfoEntry* lineInfo = new mspdb::LineInfoEntry[cnt]; for (int ln = 0; ln < cnt; ln++) @@ -1874,7 +2001,7 @@ bool CV2PDB::addSrcLines() 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], + int rc = mod->AddLines(name, seg, segoff, seglength, segoff, lineNo[0], (unsigned char*) lineInfo, cnt * sizeof(*lineInfo)); if (rc <= 0) return setError("cannot add line number info to module"); diff --git a/src/cv2pdb.h b/src/cv2pdb.h index 005b5c7..06f953a 100644 --- a/src/cv2pdb.h +++ b/src/cv2pdb.h @@ -100,6 +100,10 @@ public: bool addSymbols(int iMod, BYTE* symbols, int cb, bool addGlobals);
bool addSymbols();
+ bool markSrcLineInBitmap(int segIndex, int adr);
+ bool createSrcLineBitmap();
+ int getNextSrcLine(int seg, unsigned int off);
+
bool writeImage(const char* opath);
mspdb::Mod* globalMod();
@@ -121,6 +125,8 @@ public: OMFSegMap* segMap;
OMFSegMapDesc* segMapDesc;
+ int* segFrame2Index;
+
OMFGlobalTypes* globalTypeHeader;
unsigned char* globalTypes;
@@ -150,6 +156,9 @@ public: bool v3;
const char* lastError;
+ int srcLineSections;
+ char** srcLineStart; // array of bitmaps per segment, indicating whether src line start is available for corresponding address
+
double Dversion;
};
|