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); } }
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); } }
internal IBinaryReader CreateDataReader_NoLock(RVA rva, uint size) { var reader = dataReader.Create(rvaConverter.ToFileOffset(rva), size); if (reader.Length == size) { return(reader); } reader.Dispose(); return(MemoryImageStream.CreateEmpty()); }
void ReadInternal(IImageStream stream) { stream.Position = 0; string sig = Encoding.ASCII.GetString(stream.ReadBytes(30)); if (sig != "Microsoft C/C++ MSF 7.00\r\n\u001ADS\0") { throw new PdbException("Invalid signature"); } stream.Position += 2; uint pageSize = stream.ReadUInt32(); uint fpm = stream.ReadUInt32(); uint pageCount = stream.ReadUInt32(); uint rootSize = stream.ReadUInt32(); stream.ReadUInt32(); var numOfRootPages = RoundUpDiv(rootSize, pageSize); var numOfPtrPages = RoundUpDiv(numOfRootPages * 4, pageSize); if (pageCount * pageSize != stream.Length) { throw new PdbException("File size mismatch"); } var pages = new IImageStream[pageCount]; try { FileOffset offset = 0; for (uint i = 0; i < pageCount; i++) { pages[i] = stream.Create(offset, pageSize); offset += pageSize; } var rootPages = new IImageStream[numOfRootPages]; int pageIndex = 0; for (int i = 0; i < numOfPtrPages && pageIndex < numOfRootPages; i++) { var ptrPage = pages[stream.ReadUInt32()]; ptrPage.Position = 0; for (; ptrPage.Position < ptrPage.Length && pageIndex < numOfRootPages; pageIndex++) { rootPages[pageIndex] = pages[ptrPage.ReadUInt32()]; } } ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize); } finally { foreach (var page in pages) { if (page != null) { page.Dispose(); } } } ReadNames(); ReadStringTable(); var tokenMapStream = ReadModules(); documents = new Dictionary <string, DbiDocument>(StringComparer.OrdinalIgnoreCase); foreach (var module in modules) { if (IsValidStreamIndex(module.StreamId)) { module.LoadFunctions(this, streams[module.StreamId].Content); } } if (IsValidStreamIndex(tokenMapStream ?? STREAM_INVALID_INDEX)) { ApplyRidMap(streams[tokenMapStream.Value].Content); } functions = new Dictionary <uint, DbiFunction>(); foreach (var module in modules) { foreach (var func in module.Functions) { functions.Add(func.Token, func); } } }
/// <summary> /// Clones this <see cref="IImageStream"/> /// </summary> /// <param name="self">this</param> /// <returns>A new <see cref="IImageStream"/> instance</returns> public static IImageStream Clone(this IImageStream self) { return(self.Create(0, long.MaxValue)); }
/// <summary> /// Creates a stream that can access all data starting from <paramref name="offset"/> /// </summary> /// <param name="self">this</param> /// <param name="offset">Offset relative to the beginning of the stream</param> /// <returns>A new stream</returns> public static IImageStream Create(this IImageStream self, FileOffset offset) { return(self.Create(offset, long.MaxValue)); }
/// <inheritdoc/> protected override void InitializeInternal(IImageStream mdStream) { bool disposeOfMdStream = false; IImageStream imageStream = null; DotNetStream dns = null; try { if (peImage != null) { Debug.Assert(mdStream == null); Debug.Assert(cor20Header != null); var mdOffset = peImage.ToFileOffset(cor20Header.MetaData.VirtualAddress); mdStream = peImage.CreateStream(mdOffset, cor20Header.MetaData.Size); disposeOfMdStream = true; } else { Debug.Assert(mdStream != null); } foreach (var sh in mdHeader.StreamHeaders) { imageStream = mdStream.Create((FileOffset)sh.Offset, sh.StreamSize); switch (sh.Name.ToUpperInvariant()) { case "#STRINGS": if (stringsStream == null) { stringsStream = new StringsStream(imageStream, sh); imageStream = null; allStreams.Add(stringsStream); continue; } break; case "#US": if (usStream == null) { usStream = new USStream(imageStream, sh); imageStream = null; allStreams.Add(usStream); continue; } break; case "#BLOB": if (blobStream == null) { blobStream = new BlobStream(imageStream, sh); imageStream = null; allStreams.Add(blobStream); continue; } break; case "#GUID": if (guidStream == null) { guidStream = new GuidStream(imageStream, sh); imageStream = null; allStreams.Add(guidStream); continue; } break; case "#~": // Only if #Schema is used case "#-": if (tablesStream == null) { tablesStream = new TablesStream(imageStream, sh); imageStream = null; allStreams.Add(tablesStream); continue; } break; case "#PDB": // Case sensitive comparison since it's a stream that's not read by the CLR, // only by other libraries eg. System.Reflection.Metadata. if (isStandalonePortablePdb && pdbStream == null && sh.Name == "#Pdb") { pdbStream = new PdbStream(imageStream, sh); imageStream = null; allStreams.Add(pdbStream); continue; } break; } dns = new DotNetStream(imageStream, sh); imageStream = null; allStreams.Add(dns); dns = null; } } finally { if (disposeOfMdStream) { mdStream.Dispose(); } if (imageStream != null) { imageStream.Dispose(); } if (dns != null) { dns.Dispose(); } } if (tablesStream == null) { throw new BadImageFormatException("Missing MD stream"); } if (pdbStream != null) { tablesStream.Initialize(pdbStream.TypeSystemTableRows); } else { tablesStream.Initialize(null); } // The pointer tables are used iff row count != 0 hasFieldPtr = !tablesStream.FieldPtrTable.IsEmpty; hasMethodPtr = !tablesStream.MethodPtrTable.IsEmpty; hasParamPtr = !tablesStream.ParamPtrTable.IsEmpty; hasEventPtr = !tablesStream.EventPtrTable.IsEmpty; hasPropertyPtr = !tablesStream.PropertyPtrTable.IsEmpty; hasDeletedRows = tablesStream.HasDelete; }
void ReadInternal(IImageStream stream) { stream.Position = 0; string sig = Encoding.ASCII.GetString(stream.ReadBytes(30)); if (sig != "Microsoft C/C++ MSF 7.00\r\n\u001ADS\0") throw new PdbException("Invalid signature"); stream.Position += 2; uint pageSize = stream.ReadUInt32(); uint fpm = stream.ReadUInt32(); uint pageCount = stream.ReadUInt32(); uint rootSize = stream.ReadUInt32(); stream.ReadUInt32(); var numOfRootPages = RoundUpDiv(rootSize, pageSize); var numOfPtrPages = RoundUpDiv(numOfRootPages * 4, pageSize); if (pageCount * pageSize != stream.Length) throw new PdbException("File size mismatch"); var pages = new IImageStream[pageCount]; try { FileOffset offset = 0; for (uint i = 0; i < pageCount; i++) { pages[i] = stream.Create(offset, pageSize); offset += pageSize; } var rootPages = new IImageStream[numOfRootPages]; int pageIndex = 0; for (int i = 0; i < numOfPtrPages && pageIndex < numOfRootPages; i++) { var ptrPage = pages[stream.ReadUInt32()]; ptrPage.Position = 0; for (; ptrPage.Position < ptrPage.Length && pageIndex < numOfRootPages; pageIndex++) rootPages[pageIndex] = pages[ptrPage.ReadUInt32()]; } ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize); } finally { foreach (var page in pages) { if (page != null) page.Dispose(); } } ReadNames(); ReadStringTable(); var tokenMapStream = ReadModules(); documents = new Dictionary<string, DbiDocument>(StringComparer.OrdinalIgnoreCase); foreach (var module in modules) if (IsValidStreamIndex(module.StreamId)) module.LoadFunctions(this, streams[module.StreamId].Content); if (IsValidStreamIndex(tokenMapStream ?? STREAM_INVALID_INDEX)) ApplyRidMap(streams[tokenMapStream.Value].Content); functions = new Dictionary<uint, DbiFunction>(); foreach (var module in modules) foreach (var func in module.Functions) { functions.Add(func.Token, func); } }
/// <inheritdoc/> protected override void InitializeInternal(IImageStream mdStream) { var hotHeapVersion = peImage == null ? HotHeapVersion.CLR20 : GetHotHeapVersion(peImage.FileName, mdHeader.VersionString); bool disposeOfMdStream = false; IImageStream imageStream = null, fullStream = null; DotNetStream dns = null; List <HotStream> hotStreams = null; HotStream hotStream = null; var newAllStreams = new List <DotNetStream>(allStreams); try { if (peImage != null) { Debug.Assert(mdStream == null); Debug.Assert(cor20Header != null); var mdOffset = peImage.ToFileOffset(cor20Header.MetaData.VirtualAddress); mdStream = peImage.CreateStream(mdOffset, cor20Header.MetaData.Size); disposeOfMdStream = true; } else { Debug.Assert(mdStream != null); } for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--) { var sh = mdHeader.StreamHeaders[i]; imageStream = mdStream.Create((FileOffset)sh.Offset, sh.StreamSize); switch (sh.Name) { case "#Strings": if (stringsStream == null) { stringsStream = new StringsStream(imageStream, sh); imageStream = null; newAllStreams.Add(stringsStream); continue; } break; case "#US": if (usStream == null) { usStream = new USStream(imageStream, sh); imageStream = null; newAllStreams.Add(usStream); continue; } break; case "#Blob": if (blobStream == null) { blobStream = new BlobStream(imageStream, sh); imageStream = null; newAllStreams.Add(blobStream); continue; } break; case "#GUID": if (guidStream == null) { guidStream = new GuidStream(imageStream, sh); imageStream = null; newAllStreams.Add(guidStream); continue; } break; case "#~": if (tablesStream == null) { tablesStream = new TablesStream(imageStream, sh); imageStream = null; newAllStreams.Add(tablesStream); continue; } break; case "#!": if (peImage == null) { break; } if (hotStreams == null) { hotStreams = new List <HotStream>(); } fullStream = peImage.CreateFullStream(); hotStream = HotStream.Create(hotHeapVersion, imageStream, sh, fullStream, mdStream.FileOffset + sh.Offset); fullStream = null; hotStreams.Add(hotStream); newAllStreams.Add(hotStream); hotStream = null; imageStream = null; continue; case "#Pdb": if (isStandalonePortablePdb && pdbStream == null) { pdbStream = new PdbStream(imageStream, sh); imageStream = null; allStreams.Add(pdbStream); continue; } break; } dns = new DotNetStream(imageStream, sh); imageStream = null; newAllStreams.Add(dns); dns = null; } } finally { if (disposeOfMdStream) { mdStream.Dispose(); } if (imageStream != null) { imageStream.Dispose(); } if (fullStream != null) { fullStream.Dispose(); } if (dns != null) { dns.Dispose(); } if (hotStream != null) { hotStream.Dispose(); } newAllStreams.Reverse(); allStreams = ThreadSafeListCreator.MakeThreadSafe(newAllStreams); } if (tablesStream == null) { throw new BadImageFormatException("Missing MD stream"); } if (hotStreams != null) { hotStreams.Reverse(); InitializeHotStreams(hotStreams); } if (pdbStream != null) { tablesStream.Initialize(pdbStream.TypeSystemTableRows); } else { tablesStream.Initialize(null); } }