in ClrMemDiag/Utilities/PDB/PdbFile.cs [157:337]
private static void LoadManagedLines(PdbFunction[] funcs,
Dictionary<int, string> names,
BitAccess bits,
MsfDirectory dir,
Dictionary<string, int> nameIndex,
PdbStreamHelper reader,
uint limit,
Dictionary<string, PdbSource> sources)
{
Array.Sort(funcs, PdbFunction.byAddressAndToken);
Dictionary<int, PdbSource> checks = new Dictionary<int, PdbSource>();
// Read the files first
int begin = bits.Position;
while (bits.Position < limit)
{
int sig;
int siz;
bits.ReadInt32(out sig);
bits.ReadInt32(out siz);
int place = bits.Position;
int endSym = bits.Position + siz;
switch ((DEBUG_S_SUBSECTION)sig)
{
case DEBUG_S_SUBSECTION.FILECHKSMS:
while (bits.Position < endSym)
{
CV_FileCheckSum chk;
int ni = bits.Position - place;
bits.ReadUInt32(out chk.name);
bits.ReadUInt8(out chk.len);
bits.ReadUInt8(out chk.type);
string name = names[(int)chk.name];
PdbSource src;
if (!sources.TryGetValue(name.ToUpperInvariant(), out src))
{
int guidStream;
Guid doctypeGuid = Guid.Empty;
Guid languageGuid = Guid.Empty;
Guid vendorGuid = Guid.Empty;
Guid algorithmId = Guid.Empty;
byte[] checksum = null;
byte[] source = null;
if (nameIndex.TryGetValue("/SRC/FILES/" + name.ToUpperInvariant(), out guidStream))
{
var guidBits = new BitAccess(0x100);
dir._streams[guidStream].Read(reader, guidBits);
LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid, out algorithmId, out checksum, out source);
}
src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid, algorithmId, checksum, source);
sources.Add(name.ToUpperInvariant(), src);
}
checks.Add(ni, src);
bits.Position += chk.len;
bits.Align(4);
}
bits.Position = endSym;
break;
default:
bits.Position = endSym;
break;
}
}
// Read the lines next.
bits.Position = begin;
while (bits.Position < limit)
{
int sig;
int siz;
bits.ReadInt32(out sig);
bits.ReadInt32(out siz);
int endSym = bits.Position + siz;
switch ((DEBUG_S_SUBSECTION)sig)
{
case DEBUG_S_SUBSECTION.LINES:
{
CV_LineSection sec;
bits.ReadUInt32(out sec.off);
bits.ReadUInt16(out sec.sec);
bits.ReadUInt16(out sec.flags);
bits.ReadUInt32(out sec.cod);
int funcIndex = FindFunction(funcs, sec.sec, sec.off);
if (funcIndex < 0) break;
var func = funcs[funcIndex];
if (func.SequencePoints == null)
{
while (funcIndex > 0)
{
var f = funcs[funcIndex - 1];
if (f.SequencePoints != null || f.Segment != sec.sec || f.Address != sec.off) break;
func = f;
funcIndex--;
}
}
else
{
while (funcIndex < funcs.Length - 1 && func.SequencePoints != null)
{
var f = funcs[funcIndex + 1];
if (f.Segment != sec.sec || f.Address != sec.off) break;
func = f;
funcIndex++;
}
}
if (func.SequencePoints != null) break;
// Count the line blocks.
int begSym = bits.Position;
int blocks = 0;
while (bits.Position < endSym)
{
CV_SourceFile file;
bits.ReadUInt32(out file.index);
bits.ReadUInt32(out file.count);
bits.ReadUInt32(out file.linsiz); // Size of payload.
int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0));
bits.Position += linsiz;
blocks++;
}
func.SequencePoints = new PdbSequencePointCollection[blocks];
int block = 0;
bits.Position = begSym;
while (bits.Position < endSym)
{
CV_SourceFile file;
bits.ReadUInt32(out file.index);
bits.ReadUInt32(out file.count);
bits.ReadUInt32(out file.linsiz); // Size of payload.
PdbSource src = (PdbSource)checks[(int)file.index];
PdbSequencePointCollection tmp = new PdbSequencePointCollection(src, file.count);
func.SequencePoints[block++] = tmp;
PdbSequencePoint[] lines = tmp.Lines;
int plin = bits.Position;
int pcol = bits.Position + 8 * (int)file.count;
for (int i = 0; i < file.count; i++)
{
CV_Line line;
CV_Column column = new CV_Column();
bits.Position = plin + 8 * i;
bits.ReadUInt32(out line.offset);
bits.ReadUInt32(out line.flags);
uint lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart;
uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24;
//bool statement = ((line.flags & (uint)CV_Line_Flags.fStatement) == 0);
if ((sec.flags & 1) != 0)
{
bits.Position = pcol + 4 * i;
bits.ReadUInt16(out column.offColumnStart);
bits.ReadUInt16(out column.offColumnEnd);
}
lines[i] = new PdbSequencePoint(line.offset,
lineBegin,
column.offColumnStart,
lineBegin + delta,
column.offColumnEnd);
}
}
break;
}
}
bits.Position = endSym;
}
}