Esempio n. 1
0
        private bool TryOpenCodeViewPortablePdb(DebugDirectoryEntry codeViewEntry, string peImageDirectory, Func <string, Stream> pdbFileStreamProvider, out MetadataReaderProvider provider, out string pdbPath, ref Exception errorToReport)
        {
            pdbPath  = null;
            provider = null;

            CodeViewDebugDirectoryData data;

            try
            {
                data = ReadCodeViewDebugDirectoryData(codeViewEntry);
            }
            catch (Exception e) when(e is BadImageFormatException || e is IOException)
            {
                errorToReport = errorToReport ?? e;
                return(false);
            }

            var id = new BlobContentId(data.Guid, codeViewEntry.Stamp);

            // The interpretation os the path in the CodeView needs to be platform agnostic,
            // so that PDBs built on Windows work on Unix-like systems and vice versa.
            // System.IO.Path.GetFileName() on Unix-like systems doesn't treat '\' as a file name separator,
            // so we need a custom implementation. Also avoid throwing an exception if the path contains invalid characters,
            // they might not be invalid on the other platform. It's up to the FS APIs to deal with that when opening the stream.
            string collocatedPdbPath = PathUtilities.CombinePathWithRelativePath(peImageDirectory, PathUtilities.GetFileName(data.Path));

            if (TryOpenPortablePdbFile(collocatedPdbPath, id, pdbFileStreamProvider, out provider, ref errorToReport))
            {
                pdbPath = collocatedPdbPath;
                return(true);
            }

            return(false);
        }
        partial void TryOpenEmbeddedPortablePdb(DebugDirectoryEntry embeddedPdbEntry, ref bool openedEmbeddedPdb, ref MetadataReaderProvider provider, ref Exception errorToReport)
        {
            provider = null;
            MetadataReaderProvider candidate = null;

            try
            {
                candidate = ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdbEntry);

                // throws if headers are invalid:
                candidate.GetMetadataReader();

                provider          = candidate;
                openedEmbeddedPdb = true;
                return;
            }
            catch (Exception e) when(e is BadImageFormatException || e is IOException)
            {
                errorToReport     = errorToReport ?? e;
                openedEmbeddedPdb = false;
            }
            finally
            {
                if (candidate == null)
                {
                    candidate?.Dispose();
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Reads the data pointed to by the specified Debug Directory entry and interprets them as PDB Checksum entry.
        /// </summary>
        /// <exception cref="ArgumentException"><paramref name="entry"/> is not a PDB Checksum entry.</exception>
        /// <exception cref="BadImageFormatException">Bad format of the data.</exception>
        /// <exception cref="IOException">IO error while reading from the underlying stream.</exception>
        /// <exception cref="InvalidOperationException">PE image not available.</exception>
        public PdbChecksumDebugDirectoryData ReadPdbChecksumDebugDirectoryData(DebugDirectoryEntry entry)
        {
            if (entry.Type != DebugDirectoryEntryType.PdbChecksum)
            {
                Throw.InvalidArgument(StarkPlatform.Reflection.Resources.SR.Format(SR.UnexpectedDebugDirectoryType, nameof(DebugDirectoryEntryType.PdbChecksum)), nameof(entry));
            }

            using (var block = GetDebugDirectoryEntryDataBlock(entry))
            {
                return(DecodePdbChecksumDebugDirectoryData(block));
            }
        }
        /// <summary>
        /// Reads the data pointed to by the specified Debug Directory entry and interprets them as Embedded Portable PDB blob.
        /// </summary>
        /// <returns>
        /// Provider of a metadata reader reading Portable PDB image.
        /// </returns>
        /// <exception cref="ArgumentException"><paramref name="entry"/> is not a <see cref="DebugDirectoryEntryType.EmbeddedPortablePdb"/> entry.</exception>
        /// <exception cref="BadImageFormatException">Bad format of the data.</exception>
        /// <exception cref="InvalidOperationException">PE image not available.</exception>
        public MetadataReaderProvider ReadEmbeddedPortablePdbDebugDirectoryData(DebugDirectoryEntry entry)
        {
            if (entry.Type != DebugDirectoryEntryType.EmbeddedPortablePdb)
            {
                Throw.InvalidArgument(StarkPlatform.Reflection.Resources.SR.Format(SR.UnexpectedDebugDirectoryType, nameof(DebugDirectoryEntryType.EmbeddedPortablePdb)), nameof(entry));
            }

            ValidateEmbeddedPortablePdbVersion(entry);

            using (var block = GetDebugDirectoryEntryDataBlock(entry))
            {
                var pdbImage = DecodeEmbeddedPortablePdbDebugDirectoryData(block);
                return(MetadataReaderProvider.FromPortablePdbImage(pdbImage));
            }
        }
        // internal for testing
        internal static void ValidateEmbeddedPortablePdbVersion(DebugDirectoryEntry entry)
        {
            // Major version encodes the version of Portable PDB format itself.
            // Minor version encodes the version of Embedded Portable PDB blob.
            // Accept any version of Portable PDB >= 1.0,
            // but only accept version 1.* of the Embedded Portable PDB blob.
            // Any breaking change in the format should rev major version of the embedded blob.
            ushort formatVersion = entry.MajorVersion;

            if (formatVersion < PortablePdbVersions.MinFormatVersion)
            {
                throw new BadImageFormatException(StarkPlatform.Reflection.Resources.SR.Format(SR.UnsupportedFormatVersion, PortablePdbVersions.Format(formatVersion)));
            }

            ushort embeddedBlobVersion = entry.MinorVersion;

            if (embeddedBlobVersion != PortablePdbVersions.DefaultEmbeddedVersion)
            {
                throw new BadImageFormatException(StarkPlatform.Reflection.Resources.SR.Format(SR.UnsupportedFormatVersion, PortablePdbVersions.Format(embeddedBlobVersion)));
            }
        }
Esempio n. 6
0
 partial void TryOpenEmbeddedPortablePdb(DebugDirectoryEntry embeddedPdbEntry, ref bool openedEmbeddedPdb, ref MetadataReaderProvider provider, ref Exception errorToReport);
Esempio n. 7
0
        private AbstractMemoryBlock GetDebugDirectoryEntryDataBlock(DebugDirectoryEntry entry)
        {
            int dataOffset = IsLoadedImage ? entry.DataRelativeVirtualAddress : entry.DataPointer;

            return(GetPEImage().GetMemoryBlock(dataOffset, entry.DataSize));
        }