public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { if (!counter.Increment()) { throw new PdbException("Scopes too deep"); } while (stream.Position < scopeEnd) { var size = stream.ReadUInt16(); var begin = stream.Position; var end = begin + size; var type = (SymbolType)stream.ReadUInt16(); DbiScope child = null; uint? childEnd = null; switch (type) { case SymbolType.S_BLOCK32: { stream.Position += 4; childEnd = stream.ReadUInt32(); var len = stream.ReadUInt32(); var addr = PdbAddress.ReadAddress(stream); var name = PdbReader.ReadCString(stream); child = new DbiScope(name, addr.Offset, len); break; } case SymbolType.S_UNAMESPACE: Namespaces.Add(new DbiNamespace(PdbReader.ReadCString(stream))); break; case SymbolType.S_MANSLOT: { var variable = new DbiVariable(); variable.Read(stream); Variables.Add(variable); break; } } stream.Position = end; if (child != null) { child.Read(counter, stream, childEnd.Value); Children.Add(child); child = null; } } counter.Decrement(); if (stream.Position != scopeEnd) { Debugger.Break(); } }
public void Read(IImageStream stream, long recEnd) { stream.Position += 4; var end = stream.ReadUInt32(); stream.Position += 4; var len = stream.ReadUInt32(); stream.Position += 8; Token = stream.ReadUInt32(); Address = PdbAddress.ReadAddress(stream); stream.Position += 1 + 2; Name = PdbReader.ReadCString(stream); stream.Position = recEnd; Root = new DbiScope("", Address.Offset, len); Root.Read(new RecursionCounter(), stream, end); FixOffsets(new RecursionCounter(), Root); }
private void ReadLines(DbiFunction[] funcs, Dictionary <long, DbiDocument> documents, IImageStream stream, long end) { var address = PdbAddress.ReadAddress(stream); int first = 0; int last = funcs.Length - 1; int found = -1; while (first <= last) { var index = first + ((last - first) >> 1); var addr = funcs[index].Address; if (addr < address) { first = index + 1; } else if (addr > address) { last = index - 1; } else { found = index; break; } } if (found == -1) { return; } var flags = stream.ReadUInt16(); stream.Position += 4; if (funcs[found].Lines == null) { while (found > 0) { var prevFunc = funcs[found - 1]; if (prevFunc != null || prevFunc.Address != address) { break; } found--; } } else { while (found < funcs.Length - 1 && funcs[found] != null) { var nextFunc = funcs[found + 1]; if (nextFunc.Address != address) { break; } found++; } } var func = funcs[found]; if (func.Lines != null) { return; } func.Lines = new List <DbiSourceLine>(); while (stream.Position < end) { var document = documents[stream.ReadUInt32()]; var count = stream.ReadUInt32(); stream.Position += 4; const int LINE_ENTRY_SIZE = 8; const int COL_ENTRY_SIZE = 4; var lineTablePos = stream.Position; var colTablePos = stream.Position + count * LINE_ENTRY_SIZE; for (uint i = 0; i < count; i++) { stream.Position = lineTablePos + i * LINE_ENTRY_SIZE; var line = new DbiSourceLine { Document = document }; line.Offset = stream.ReadUInt32(); var lineFlags = stream.ReadUInt32(); line.LineBegin = lineFlags & 0x00ffffff; line.LineEnd = line.LineBegin + ((lineFlags >> 24) & 0x7F); if ((flags & 1) != 0) { stream.Position = colTablePos + i * COL_ENTRY_SIZE; line.ColumnBegin = stream.ReadUInt16(); line.ColumnEnd = stream.ReadUInt16(); } func.Lines.Add(line); } } }