/// <summary>
        /// Creates a new <see cref="SymbolReader"/> instance
        /// </summary>
        /// <param name="pdbContext">PDB context</param>
        /// <param name="pdbStream">PDB file stream which is now owned by this method</param>
        /// <returns>A new <see cref="SymbolReader"/> instance or <c>null</c>.</returns>
        public static SymbolReader Create(PdbReaderContext pdbContext, DataReaderFactory pdbStream)
        {
            if (pdbStream == null)
            {
                return(null);
            }
            try {
                var debugDir = pdbContext.CodeViewDebugDirectory;
                if (debugDir == null)
                {
                    return(null);
                }
                if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age))
                {
                    return(null);
                }

                var pdbReader = new PdbReader(pdbGuid, age);
                pdbReader.Read(pdbStream.CreateReader());
                if (pdbReader.MatchesModule)
                {
                    return(pdbReader);
                }
                return(null);
            }
            catch (PdbException) {
            }
            catch (IOException) {
            }
            finally {
                pdbStream?.Dispose();
            }
            return(null);
        }
예제 #2
0
        public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFactory pdbStream, bool isEmbeddedPortablePdb)
        {
            bool disposePdbStream = true;

            try {
                if (!pdbContext.HasDebugInfo)
                {
                    return(null);
                }
                if (pdbStream == null)
                {
                    return(null);
                }
                if (pdbStream.Length < 4)
                {
                    return(null);
                }
                if (pdbStream.CreateReader().ReadUInt32() != 0x424A5342)
                {
                    return(null);
                }

                var debugDir = pdbContext.CodeViewDebugDirectory;
                if (debugDir == null)
                {
                    return(null);
                }
                if (debugDir.MinorVersion != DDW.PortablePdbConstants.PortableCodeViewVersionMagic)
                {
                    return(null);
                }
                bool validFormatVersion = debugDir.MajorVersion == DDW.PortablePdbConstants.FormatVersion;
                Debug.Assert(validFormatVersion, $"New Portable PDB version: 0x{debugDir.MajorVersion:X4}");
                if (!validFormatVersion)
                {
                    return(null);
                }
                if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age))
                {
                    return(null);
                }

                var reader = new PortablePdbReader(pdbStream, isEmbeddedPortablePdb ? PdbFileKind.EmbeddedPortablePDB : PdbFileKind.PortablePDB);
                if (!reader.MatchesModule(pdbGuid, debugDir.TimeDateStamp, age))
                {
                    return(null);
                }
                disposePdbStream = false;
                return(reader);
            }
            catch (IOException) {
            }
            finally {
                if (disposePdbStream)
                {
                    pdbStream?.Dispose();
                }
            }
            return(null);
        }
예제 #3
0
 public static SymbolReader TryCreateEmbeddedPortablePdbReader(PdbReaderContext pdbContext, Metadata metadata)
 {
     if (metadata == null)
     {
         return(null);
     }
     try {
         if (!pdbContext.HasDebugInfo)
         {
             return(null);
         }
         var embeddedDir = pdbContext.TryGetDebugDirectoryEntry(ImageDebugType.EmbeddedPortablePdb);
         if (embeddedDir == null)
         {
             return(null);
         }
         var reader = pdbContext.CreateReader(embeddedDir.PointerToRawData, embeddedDir.SizeOfData);
         if (reader.Length < 8)
         {
             return(null);
         }
         // "MPDB" = 0x4244504D
         if (reader.ReadUInt32() != 0x4244504D)
         {
             return(null);
         }
         uint uncompressedSize = reader.ReadUInt32();
         // If this fails, see the (hopefully) updated spec:
         //		https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PE-COFF.md#embedded-portable-pdb-debug-directory-entry-type-17
         bool newVersion = (uncompressedSize & 0x80000000) != 0;
         Debug.Assert(!newVersion);
         if (newVersion)
         {
             return(null);
         }
         var decompressedBytes = new byte[uncompressedSize];
         using (var deflateStream = new DeflateStream(reader.AsStream(), CompressionMode.Decompress)) {
             int pos = 0;
             while (pos < decompressedBytes.Length)
             {
                 int read = deflateStream.Read(decompressedBytes, pos, decompressedBytes.Length - pos);
                 if (read == 0)
                 {
                     break;
                 }
                 pos += read;
             }
             if (pos != decompressedBytes.Length)
             {
                 return(null);
             }
             var stream = ByteArrayDataReaderFactory.Create(decompressedBytes, filename: null);
             return(TryCreate(pdbContext, stream, isEmbeddedPortablePdb: true));
         }
     }
     catch (IOException) {
     }
     return(null);
 }
        public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFactory pdbStream, bool isEmbeddedPortablePdb)
        {
            bool disposePdbStream = true;

            try {
                if (!pdbContext.HasDebugInfo)
                {
                    return(null);
                }
                if (pdbStream is null)
                {
                    return(null);
                }
                if (pdbStream.Length < 4)
                {
                    return(null);
                }
                if (pdbStream.CreateReader().ReadUInt32() != 0x424A5342)
                {
                    return(null);
                }

                var debugDir = pdbContext.CodeViewDebugDirectory;
                if (debugDir is null)
                {
                    return(null);
                }
                // Don't check that debugDir.MinorVersion == PortablePdbConstants.PortableCodeViewVersionMagic
                // and debugDir.MajorVersion == PortablePdbConstants.FormatVersion since it could be a converted
                // WindowsPDB file: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PE-COFF.md#codeview-debug-directory-entry-type-2
                if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age))
                {
                    return(null);
                }

                var reader = new PortablePdbReader(pdbStream, isEmbeddedPortablePdb ? PdbFileKind.EmbeddedPortablePDB : PdbFileKind.PortablePDB);
                if (!reader.MatchesModule(pdbGuid, debugDir.TimeDateStamp, age))
                {
                    return(null);
                }
                disposePdbStream = false;
                return(reader);
            }
            catch (IOException) {
            }
            finally {
                if (disposePdbStream)
                {
                    pdbStream?.Dispose();
                }
            }
            return(null);
        }
예제 #5
0
        public static SymbolReader Create(PdbReaderContext pdbContext, MD.Metadata metadata, DataReaderFactory pdbStream)
        {
            ISymUnmanagedReader  unmanagedReader = null;
            SymbolReaderImpl     symReader       = null;
            ReaderMetaDataImport mdImporter      = null;
            DataReaderIStream    comPdbStream    = null;
            bool error = true;

            try {
                if (pdbStream is null)
                {
                    return(null);
                }
                var debugDir = pdbContext.CodeViewDebugDirectory;
                if (debugDir is null)
                {
                    return(null);
                }
                if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age))
                {
                    return(null);
                }

                unmanagedReader = CreateSymUnmanagedReader(pdbContext.Options);
                if (unmanagedReader is null)
                {
                    return(null);
                }

                mdImporter   = new ReaderMetaDataImport(metadata);
                comPdbStream = new DataReaderIStream(pdbStream);
                int hr = unmanagedReader.Initialize(mdImporter, null, null, comPdbStream);
                if (hr < 0)
                {
                    return(null);
                }

                symReader = new SymbolReaderImpl(unmanagedReader, new object[] { pdbStream, mdImporter, comPdbStream });
                if (!symReader.MatchesModule(pdbGuid, debugDir.TimeDateStamp, age))
                {
                    return(null);
                }

                error = false;
                return(symReader);
            }
            catch (IOException) {
            }
            catch (InvalidCastException) {
            }
            catch (COMException) {
            }
            finally {
                if (error)
                {
                    pdbStream?.Dispose();
                    symReader?.Dispose();
                    mdImporter?.Dispose();
                    comPdbStream?.Dispose();
                    (unmanagedReader as ISymUnmanagedDispose)?.Destroy();
                }
            }
            return(null);
        }