Example #1
0
        internal static SymReader CreateFromFile(string path, LazyMetadataImport metadataImport)
        {
            var pdbStream = PortableShim.FileStream.CreateReadShareDelete(path);
            var provider  = MetadataReaderProvider.FromPortablePdbStream(pdbStream);

            return(new SymReader(new PortablePdbReader(provider, metadataImport)));
        }
Example #2
0
        private bool TryCreateReaderForMatchingPdb(
            string pdbFilePath,
            Guid guid,
            uint stamp,
            int age,
            LazyMetadataImport metadataImport,
            out ISymUnmanagedReader reader)
        {
            try
            {
                if (PortableShim.File.Exists(pdbFilePath))
                {
                    var symReader = SymReader.CreateFromFile(pdbFilePath, metadataImport);
                    reader = symReader;
                    return(symReader.PdbReader.MatchesModule(guid, stamp, age));
                }
            }
            catch
            {
                // nop
            }

            reader = null;
            return(false);
        }
Example #3
0
        public void Dispose()
        {
            _metadataReaderProvider?.Dispose();
            _metadataReaderProvider = null;

            _lazyMetadataImport?.Dispose();
            _lazyMetadataImport = null;
        }
Example #4
0
        internal static ISymUnmanagedReader CreateFromStream(IStream stream, LazyMetadataImport metadataImport)
        {
            byte[] bytes;
            int size;
            stream.ReadAllBytes(out bytes, out size);

            return new SymReader(new PortablePdbReader(bytes, size, metadataImport));
        }
Example #5
0
        internal PortablePdbReader(byte[] buffer, int size, LazyMetadataImport metadataImport)
        {
            Debug.Assert(metadataImport != null);

            _metadataReader     = CreateMetadataReader(buffer, size, out _pinnedImage);
            _lazyMetadataImport = metadataImport;
            ImageSize           = size;
        }
Example #6
0
        internal PortablePdbReader(byte[] buffer, int size, LazyMetadataImport metadataImport)
        {
            Debug.Assert(metadataImport != null);

            _metadataReader = CreateMetadataReader(buffer, size, out _pinnedImage);
            _lazyMetadataImport = metadataImport;
            ImageSize = size;
        }
Example #7
0
        internal static ISymUnmanagedReader CreateFromStream(IStream stream, LazyMetadataImport metadataImport)
        {
            byte[] bytes;
            int    size;

            stream.ReadAllBytes(out bytes, out size);

            return(new SymReader(new PortablePdbReader(bytes, size, metadataImport)));
        }
Example #8
0
 public void Dispose()
 {
     if (!IsDisposed)
     {
         _pinnedImage.Free();
         _lazyMetadataImport.Dispose();
         _lazyMetadataImport = null;
     }
 }
        private bool TryFindMatchingPdb(
            string searchPaths,
            string peFileExtension, // with no leading .
            string pdbFileName,
            Guid guid,
            uint stamp,
            int age,
            LazyMetadataImport metadataImport,
            SymUnmanagedSearchPolicy searchPolicy,
            out ISymUnmanagedReader reader)
        {
            if (searchPaths == null)
            {
                reader = null;
                return(false);
            }

            foreach (var searchPath in searchPaths.Split(s_searchPathSeparators, StringSplitOptions.RemoveEmptyEntries))
            {
                // TODO: check symsrv policy
                if (searchPath.StartsWith("SRV*", StringComparison.OrdinalIgnoreCase))
                {
                    // TODO:
                    continue;
                }

                if (searchPath.StartsWith("SYMSRV*", StringComparison.OrdinalIgnoreCase))
                {
                    // TODO:
                    continue;
                }

                if (searchPath.StartsWith("CACHE*", StringComparison.OrdinalIgnoreCase))
                {
                    // TODO:
                    continue;
                }

                foreach (var subdir in GetSearchPathSubdirectories(searchPath, peFileExtension))
                {
                    if (TryCreateReaderForMatchingPdb(Path.Combine(subdir, pdbFileName), guid, stamp, age, metadataImport, out reader))
                    {
                        return(true);
                    }
                }
            }

            reader = null;
            return(false);
        }
Example #10
0
        internal static SymReader CreateFromFile(string path, LazyMetadataImport metadataImport)
        {
            byte[] bytes;
            try
            {
                // TODO: use memory mapped files?
                bytes = PortableShim.File.ReadAllBytes(path);
            }
            catch
            {
                return null;
            }

            return new SymReader(new PortablePdbReader(bytes, bytes.Length, metadataImport));
        }
Example #11
0
        internal static SymReader CreateFromFile(string path, LazyMetadataImport metadataImport)
        {
            byte[] bytes;
            try
            {
                // TODO: use memory mapped files?
                bytes = PortableShim.File.ReadAllBytes(path);
            }
            catch
            {
                return(null);
            }

            return(new SymReader(new PortablePdbReader(bytes, bytes.Length, metadataImport)));
        }
Example #12
0
        /// Takes ownership of <paramref name="pdbReader"/> and <paramref name="metadataImport"/>.
        internal SymReader(PortablePdbReader pdbReader, LazyMetadataImport metadataImport)
        {
            Debug.Assert(pdbReader != null);
            Debug.Assert(metadataImport != null);

            pdbReader.SymReader = this;
            _pdbReaders         = new List <PortablePdbReader>()
            {
                pdbReader
            };

            _metadataImport    = metadataImport;
            _lazyDocumentMap   = new Lazy <DocumentMap>(() => new DocumentMap(_pdbReaders[0].MetadataReader));
            _methodMap         = new Lazy <MethodMap>(() => new MethodMap(_pdbReaders[0]));
            _lazyMethodExtents = new Lazy <MethodExtents>(() => new MethodExtents(_pdbReaders[0]));
            _lazyVbSemantics   = new Lazy <bool>(() => IsVisualBasicAssembly());
        }
Example #13
0
        /// <summary>
        /// The method takes ownership of the <paramref name="provider"/> upon entry and disposes it in case of a failure to construct the reader.
        /// </summary>
        internal PortablePdbReader(MetadataReaderProvider provider, LazyMetadataImport metadataImport)
        {
            Debug.Assert(metadataImport != null);
            Debug.Assert(provider != null);

            try
            {
                _metadataReader = provider.GetMetadataReader();
            }
            finally
            {
                // dispose the provider on error:
                if (_metadataReader == null)
                {
                    provider.Dispose();
                }
            }

            _metadataReaderProvider = provider;
            _lazyMetadataImport     = metadataImport;
        }
Example #14
0
        private bool TryCreateReaderForMatchingPdb(
            string pdbFilePath,
            Guid guid,
            uint stamp,
            int age,
            LazyMetadataImport metadataImport,
            out ISymUnmanagedReader reader)
        {
            if (PortableShim.File.Exists(pdbFilePath))
            {
                SymReader symReader;
                try
                {
                    symReader = SymReader.CreateFromFile(pdbFilePath, metadataImport);
                }
                catch
                {
                    reader = null;
                    return(false);
                }

                try
                {
                    if (symReader.PdbReader.MatchesModule(guid, stamp, age))
                    {
                        reader    = symReader;
                        symReader = null;
                        return(true);
                    }
                }
                finally
                {
                    symReader?.Destroy();
                }
            }

            reader = null;
            return(false);
        }
Example #15
0
        private bool TryCreateReaderForMatchingPdb(
            string pdbFilePath,
            Guid guid,
            uint stamp,
            int age,
            LazyMetadataImport metadataImport,
            out ISymUnmanagedReader reader)
        {
            if (PortableShim.File.Exists(pdbFilePath))
            {
                PortablePdbReader pdbReader;
                try
                {
                    pdbReader = new PortablePdbReader(SymReader.CreateProviderFromFile(pdbFilePath), version: 1, previousDocumentCount: 0);
                }
                catch
                {
                    reader = null;
                    return(false);
                }

                try
                {
                    if (pdbReader.MatchesModule(guid, stamp, age))
                    {
                        reader    = new SymReader(pdbReader, metadataImport);
                        pdbReader = null;
                        return(true);
                    }
                }
                finally
                {
                    pdbReader?.Dispose();
                }
            }

            reader = null;
            return(false);
        }
Example #16
0
        private bool TryCreateReaderForMatchingPdb(
            string pdbFilePath,
            Guid guid, 
            uint stamp, 
            int age,
            LazyMetadataImport metadataImport,
            out ISymUnmanagedReader reader)
        {
            try
            {
                if (PortableShim.File.Exists(pdbFilePath))
                {
                    var symReader = SymReader.CreateFromFile(pdbFilePath, metadataImport);
                    reader = symReader;
                    return symReader.PdbReader.MatchesModule(guid, stamp, age);
                }
            }
            catch
            {
                // nop
            }

            reader = null;
            return false;
        }
Example #17
0
 internal static ISymUnmanagedReader CreateFromStream(IStream stream, LazyMetadataImport metadataImport)
 {
     return(new SymReader(new PortablePdbReader(CreateProviderFromStream(stream), version: 1, previousDocumentCount: 0), metadataImport));
 }
Example #18
0
 internal static SymReader CreateFromFile(string path, LazyMetadataImport metadataImport)
 {
     return(new SymReader(new PortablePdbReader(CreateProviderFromFile(path), version: 1, previousDocumentCount: 0), metadataImport));
 }
Example #19
0
 public void Dispose()
 {
     if (!IsDisposed)
     {
         _pinnedImage.Free();
         _lazyMetadataImport.Dispose();
         _lazyMetadataImport = null;
     }
 }
Example #20
0
        internal static ISymUnmanagedReader CreateFromStream(IStream stream, LazyMetadataImport metadataImport)
        {
            var interopStream = new ReadOnlyInteropStream(stream);
            var header        = new byte[2 * sizeof(int)];
            int bytesRead     = interopStream.TryReadAll(header, 0, header.Length);

            MetadataReaderProvider provider;

            // detect Embedded Portable PDB signature:
            if (bytesRead == header.Length && header[0] == 'M' && header[1] == 'P' && header[2] == 'D' && header[3] == 'B')
            {
                int size = BitConverter.ToInt32(header, startIndex: sizeof(int));

                // TODO: We could avoid allocating managed memory here if FromPortablePdbImage accepted non-seekable stream in prefetch mode.
                // The implemenation in S.R.M. allocates native memory.
                byte[] decompressed;
                try
                {
                    decompressed = new byte[size];
                }
                catch
                {
                    throw new BadImageFormatException();
                }

                var deflate = new DeflateStream(interopStream, CompressionMode.Decompress, leaveOpen: true);
                if (size > 0)
                {
                    int actualLength;

                    try
                    {
                        actualLength = deflate.TryReadAll(decompressed, 0, decompressed.Length);
                    }
                    catch (InvalidDataException e)
                    {
                        throw new BadImageFormatException(e.Message, e.InnerException);
                    }

                    if (actualLength != decompressed.Length)
                    {
                        throw new BadImageFormatException();
                    }
                }

                // Check that there is no more compressed data left,
                // in case the decompressed size specified in the header is smaller
                // than the actual decompressed size of the data.
                if (deflate.ReadByte() != -1)
                {
                    throw new BadImageFormatException();
                }

                provider = MetadataReaderProvider.FromPortablePdbImage(ImmutableByteArrayInterop.DangerousCreateFromUnderlyingArray(ref decompressed));
            }
            else
            {
                interopStream.Position = 0;
                provider = MetadataReaderProvider.FromPortablePdbStream(interopStream);
            }

            return(new SymReader(new PortablePdbReader(provider, metadataImport)));
        }
Example #21
0
        private bool TryFindMatchingPdb(
            string searchPaths,
            string peFileExtension, // with no leading .
            string pdbFileName,
            Guid guid, 
            uint stamp, 
            int age, 
            LazyMetadataImport metadataImport,
            SymUnmanagedSearchPolicy searchPolicy, 
            out ISymUnmanagedReader reader)
        {
            if (searchPaths == null)
            {
                reader = null;
                return false;
            }

            foreach (var searchPath in searchPaths.Split(SearchPathSeparators, StringSplitOptions.RemoveEmptyEntries))
            {
                // TODO: check symsrv policy
                if (searchPath.StartsWith("SRV*", StringComparison.OrdinalIgnoreCase))
                {
                    // TODO:
                    continue;
                }

                if (searchPath.StartsWith("SYMSRV*", StringComparison.OrdinalIgnoreCase))
                {
                    // TODO:
                    continue;
                }

                if (searchPath.StartsWith("CACHE*", StringComparison.OrdinalIgnoreCase))
                {
                    // TODO:
                    continue;
                }

                foreach (var subdir in GetSearchPathSubdirectories(searchPath, peFileExtension))
                {
                    if (TryCreateReaderForMatchingPdb(Path.Combine(subdir, pdbFileName), guid, stamp, age, metadataImport, out reader))
                    {
                        return true;
                    }
                }
            }

            reader = null;
            return false;
        }
Example #22
0
        public int GetReaderForFile2(
            [MarshalAs(UnmanagedType.Interface)] object metadataImport,
            [MarshalAs(UnmanagedType.LPWStr)] string fileName,
            [MarshalAs(UnmanagedType.LPWStr)] string searchPath,
            SymUnmanagedSearchPolicy searchPolicy,
            [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader reader)
        {
            reader = null;
            try
            {
                var mdImport = metadataImport as IMetadataImport;
                if (mdImport == null || string.IsNullOrEmpty(fileName))
                {
                    return(HResult.E_INVALIDARG);
                }

                // See DIA: FLocatePdbDefault, FLocateCvFilePathHelper, FLocatePdbSymsrv, FLocateCvFilePathHelper
                //
                // 1) Try open Combine(<PE directory>, <PDB file name>) (unless RestrictReferencePath)
                // 2) Try open PDB path (unless RestrictOriginalPath)
                // 3) Search Paths - semicolon separated paths
                //    a) searchPath parameter
                //    b) registry (unless RestrictRegistry)
                //       Use search paths from registry Software\Microsoft\VisualStudio\MSPDB, value SymbolSearchPath
                //       with environment variables expanded (ExpandEnvironmentStrings)
                //       i) try USER
                //       ii) try MACHINE
                //    c) environment vars
                //        i) _NT_ALT_SYMBOL_PATH
                //       ii) _NT_SYMBOL_PATH
                //       ii) SystemRoot (unless RestrictSystemRoot)
                //
                //    for each search path:
                //       special paths: SRV*<server>, SYMSRV*SYMSRV.DLL*<server> => symbol server (unless RestrictSymsrv)
                //                      CACHE*<cache> => sym cache (unless RestrictSymsrv)
                //
                //       A) try open <path>\symbols\<PE file extension>\<PDB file name>
                //       B) try open <path>\<PE file extension>\<PDB file name>
                //       C) try open <path>\<PDB file name>
                //
                // Each attempt checks if PDB ID matches.
                //
                // Search policy: all is restricted unless explicitly allowed.
                // After opened store to cache if CACHE* given (only the first cache?)

                if (!TryReadCodeViewData(fileName, out var codeViewData, out uint stamp))
                {
                    return(HResult.E_FAIL); // TODO: specific error code (ecToHresult)?
                }

                Guid   guid        = codeViewData.Guid;
                int    age         = codeViewData.Age;
                string pdbFileName = Path.GetFileName(codeViewData.Path);
                var    lazyImport  = new LazyMetadataImport(mdImport);

                // 1) next to the PE file
                if ((searchPolicy & SymUnmanagedSearchPolicy.AllowReferencePathAccess) != 0)
                {
                    string peDirectory = Path.GetDirectoryName(fileName);
                    string pdbFilePath = Path.Combine(peDirectory, pdbFileName);

                    if (TryCreateReaderForMatchingPdb(pdbFilePath, guid, stamp, age, lazyImport, out reader))
                    {
                        return(HResult.S_OK);
                    }
                }

                // 2) PDB path as specified in Debug Directory
                if ((searchPolicy & SymUnmanagedSearchPolicy.AllowOriginalPathAccess) != 0)
                {
                    if (TryCreateReaderForMatchingPdb(codeViewData.Path, guid, stamp, age, lazyImport, out reader))
                    {
                        return(HResult.S_OK);
                    }
                }

                // 3) Search Paths
                string peFileExtension = Path.GetExtension(fileName).TrimStart('.');

                foreach (var searchPaths in GetSearchPathsSequence(searchPath, searchPolicy))
                {
                    if (TryFindMatchingPdb(searchPaths, peFileExtension, pdbFileName, guid, stamp, age, lazyImport, searchPolicy, out reader))
                    {
                        return(HResult.S_OK);
                    }
                }

                return(HResult.E_PDB_NOT_FOUND);
            }
            finally
            {
                InteropUtilities.TransferOwnershipOrRelease(ref metadataImport, reader);
            }
        }
Example #23
0
        public int GetReaderForFile2(
            [MarshalAs(UnmanagedType.Interface)]object metadataImport,
            [MarshalAs(UnmanagedType.LPWStr)]string fileName,
            [MarshalAs(UnmanagedType.LPWStr)]string searchPath,
            SymUnmanagedSearchPolicy searchPolicy,
            [MarshalAs(UnmanagedType.Interface)]out ISymUnmanagedReader reader)
        {
            reader = null;
            try
            {
                var mdImport = metadataImport as IMetadataImport;
                if (mdImport == null || string.IsNullOrEmpty(fileName))
                {
                    return HResult.E_INVALIDARG;
                }

                // See DIA: FLocatePdbDefault, FLocateCvFilePathHelper, FLocatePdbSymsrv, FLocateCvFilePathHelper
                //
                // 1) Try open Combine(<PE directory>, <PDB file name>) (unless RestrictReferencePath)
                // 2) Try open PDB path (unless RestrictOriginalPath)
                // 3) Search Paths - semicolon separated paths
                //    a) searchPath parameter
                //    b) registry (unless RestrictRegistry)
                //       Use search paths from registry Software\Microsoft\VisualStudio\MSPDB, value SymbolSearchPath
                //       with environment variables expanded (ExpandEnvironmentStrings)
                //       i) try USER
                //       ii) try MACHINE
                //    c) environment vars
                //        i) _NT_ALT_SYMBOL_PATH
                //       ii) _NT_SYMBOL_PATH
                //       ii) SystemRoot (unless RestrictSystemRoot)
                //
                //    for each search path:
                //       special paths: SRV*<server>, SYMSRV*SYMSRV.DLL*<server> => symbol server (unless RestrictSymsrv)
                //                      CACHE*<cache> => sym cache (unless RestrictSymsrv)
                //
                //       A) try open <path>\symbols\<PE file extension>\<PDB file name>
                //       B) try open <path>\<PE file extension>\<PDB file name>
                //       C) try open <path>\<PDB file name>
                //
                // Each attempt checks if PDB ID matches.
                //
                // Search policy: all is restricted unless explicitly allowed. 
                // After opened store to cache if CACHE* given (only the first cache?)

                CodeViewDebugDirectoryData codeViewData;
                uint stamp;
                if (!TryReadCodeViewData(fileName, out codeViewData, out stamp))
                {
                    return HResult.E_FAIL; // TODO: specific error code (ecToHresult)?
                }

                Guid guid = codeViewData.PdbId;
                int age = codeViewData.Age;
                string pdbFileName = Path.GetFileName(codeViewData.Path);
                var lazyImport = new LazyMetadataImport(mdImport);

                // 1) next to the PE file 
                if ((searchPolicy & SymUnmanagedSearchPolicy.AllowReferencePathAccess) != 0)
                {
                    string peDirectory = Path.GetDirectoryName(fileName);
                    string pdbFilePath = Path.Combine(peDirectory, pdbFileName);

                    if (TryCreateReaderForMatchingPdb(pdbFilePath, guid, stamp, age, lazyImport, out reader))
                    {
                        return HResult.S_OK;
                    }
                }

                // 2) PDB path as specified in Debug Directory
                if ((searchPolicy & SymUnmanagedSearchPolicy.AllowOriginalPathAccess) != 0)
                {
                    if (TryCreateReaderForMatchingPdb(codeViewData.Path, guid, stamp, age, lazyImport, out reader))
                    {
                        return HResult.S_OK;
                    }
                }

                // 3) Search Paths
                string peFileExtension = Path.GetExtension(fileName).TrimStart('.');

                foreach (var searchPaths in GetSearchPathsSequence(searchPath, searchPolicy))
                {
                    if (TryFindMatchingPdb(searchPaths, peFileExtension, pdbFileName, guid, stamp, age, lazyImport, searchPolicy, out reader))
                    {
                        return HResult.S_OK;
                    }
                }

                return HResult.E_PDB_NOT_FOUND;
            }
            finally
            {
                InteropUtilities.TransferOwnershipOrRelease(ref metadataImport, reader);
            }
        }