void ReadLines(PdbReader reader, IImageStream stream) { var docs = new Dictionary<long, DbiDocument>(); stream.Position = 0; while (stream.Position < stream.Length) { var sig = (ModuleStreamType)stream.ReadUInt32(); var size = stream.ReadUInt32(); var begin = stream.Position; var end = (begin + size + 3) & ~3; if (sig == ModuleStreamType.FileInfo) ReadFiles(reader, docs, stream, end); stream.Position = end; } var sortedFuncs = new DbiFunction[Functions.Count]; Functions.CopyTo(sortedFuncs, 0); Array.Sort(sortedFuncs, (a, b) => a.Address.CompareTo(b.Address)); stream.Position = 0; while (stream.Position < stream.Length) { var sig = (ModuleStreamType)stream.ReadUInt32(); var size = stream.ReadUInt32(); var begin = stream.Position; var end = begin + size; if (sig == ModuleStreamType.Lines) ReadLines(sortedFuncs, docs, stream, end); stream.Position = end; } }
public void LoadFunctions(PdbReader reader, IImageStream stream) { stream.Position = 0; using (var substream = stream.Create(stream.FileOffset + stream.Position, cbSyms)) ReadFunctions(substream); if (Functions.Count > 0) { stream.Position += cbSyms + cbOldLines; using (var substream = stream.Create(stream.FileOffset + stream.Position, cbLines)) ReadLines(reader, substream); } }
/// <summary> /// Creates a new <see cref="ISymbolReader"/> instance /// </summary> /// <param name="pdbStream">PDB file stream which is now owned by this method</param> /// <returns>A new <see cref="ISymbolReader"/> instance or <c>null</c>.</returns> public static ISymbolReader Create(IImageStream pdbStream) { if (pdbStream == null) return null; try { var pdbReader = new PdbReader(); pdbReader.Read(pdbStream); return pdbReader; } catch (IOException) { } catch (UnauthorizedAccessException) { } catch (SecurityException) { } finally { if (pdbStream != null) pdbStream.Dispose(); } return null; }
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; string name; switch (type) { case SymbolType.S_BLOCK32: { stream.Position += 4; childEnd = stream.ReadUInt32(); var len = stream.ReadUInt32(); var addr = PdbAddress.ReadAddress(stream); name = PdbReader.ReadCString(stream); child = new DbiScope(method, this, name, addr.Offset, len); break; } case SymbolType.S_UNAMESPACE: namespacesList.Add(new DbiNamespace(PdbReader.ReadCString(stream))); break; case SymbolType.S_MANSLOT: { var variable = new DbiVariable(); variable.Read(stream); localsList.Add(variable); break; } case SymbolType.S_OEM: if (stream.Position + 20 > end) { break; } if (!ReadAndCompareBytes(stream, end, dotNetOemGuid)) { Debug.Fail("Unknown OEM record GUID, not .NET GUID"); break; } stream.Position += 4; // typeIndex or 0 name = ReadUnicodeString(stream, end); Debug.Assert(name != null); if (name == null) { break; } var data = stream.ReadBytes((int)(end - stream.Position)); if (oemInfos == null) { oemInfos = new List <OemInfo>(1); } oemInfos.Add(new OemInfo(name, data)); break; case SymbolType.S_MANCONSTANT: uint signatureToken = stream.ReadUInt32(); object value; if (!NumericReader.TryReadNumeric(stream, end, out value)) { break; } name = PdbReader.ReadCString(stream); if (constants == null) { constants = new List <ConstantInfo>(); } constants.Add(new ConstantInfo(name, signatureToken, value)); break; case SymbolType.S_END: break; default: break; } stream.Position = end; if (child != null) { child.Read(counter, stream, childEnd.Value); childrenList.Add(child); child = null; } } counter.Decrement(); if (stream.Position != scopeEnd) { Debugger.Break(); } }
void ReadFiles(PdbReader reader, Dictionary<long, DbiDocument> documents, IImageStream stream, long end) { var begin = stream.Position; while (stream.Position < end) { var id = stream.Position - begin; var nameId = stream.ReadUInt32(); var len = stream.ReadByte(); /*var type = */stream.ReadByte(); var doc = reader.GetDocument(nameId); documents.Add(id, doc); stream.Position += len; stream.Position = (stream.Position + 3) & (~3); } }