Example #1
0
 public static ImmutableArray <byte> GetSourceLinkBlob(this MetadataReader reader)
 {
     return((from handle in reader.CustomDebugInformation
             let cdi = reader.GetCustomDebugInformation(handle)
                       where reader.GetGuid(cdi.Kind) == PortableCustomDebugInfoKinds.SourceLink
                       select reader.GetBlobContent(cdi.Value)).Single());
 }
Example #2
0
        private static RuntimeAssemblyName CreateRuntimeAssemblyNameFromMetadata(
            MetadataReader reader,
            StringHandle name,
            Version version,
            StringHandle culture,
            BlobHandle publicKeyOrToken,
            AssemblyFlags assemblyFlags)
        {
            AssemblyNameFlags assemblyNameFlags = AssemblyNameFlags.None;

            if (0 != (assemblyFlags & AssemblyFlags.PublicKey))
            {
                assemblyNameFlags |= AssemblyNameFlags.PublicKey;
            }
            if (0 != (assemblyFlags & AssemblyFlags.Retargetable))
            {
                assemblyNameFlags |= AssemblyNameFlags.Retargetable;
            }
            int contentType = ((int)assemblyFlags) & 0x00000E00;

            assemblyNameFlags |= (AssemblyNameFlags)contentType;

            return(new RuntimeAssemblyName(
                       name.GetString(reader),
                       version,
                       culture.GetString(reader),
                       assemblyNameFlags,
                       reader.GetBlobContent(publicKeyOrToken).ToArray()
                       ));
        }
        private static AssemblyIdentity ReadAssemblyIdentity(MetadataReader metadataReader)
        {
            var     assemblyDefinition = metadataReader.GetAssemblyDefinition();
            string  name        = metadataReader.GetString(assemblyDefinition.Name);
            Version version     = assemblyDefinition.Version;
            string  cultureName = metadataReader.GetString(assemblyDefinition.Culture);
            ImmutableArray <byte> publicKeyOrToken = metadataReader.GetBlobContent(assemblyDefinition.PublicKey);
            AssemblyFlags         flags            = assemblyDefinition.Flags;
            bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;

            return(new AssemblyIdentity(name, version, cultureName, publicKeyOrToken, hasPublicKey: hasPublicKey));
        }
        private Mapping <AssemblyReferenceHandle> MapAssemblyReferenceImpl(AssemblyReferenceHandle handle)
        {
            AssemblyReference     assemblyReference = _sourceMetadata.GetAssemblyReference(handle);
            string                name             = _sourceMetadata.GetString(assemblyReference.Name);
            string                culture          = _sourceMetadata.GetString(assemblyReference.Culture);
            ImmutableArray <byte> publicKeyOrToken = _sourceMetadata.GetBlobContent(assemblyReference.PublicKeyOrToken);

            foreach (var targetHandle in _targetMetadata.AssemblyReferences)
            {
                AssemblyReference target = _targetMetadata.GetAssemblyReference(targetHandle);
                if (!_targetMetadata.StringComparer.Equals(target.Name, name))
                {
                    continue;
                }

                if (!_targetMetadata.StringComparer.Equals(target.Culture, culture))
                {
                    continue;
                }

                if (!publicKeyOrToken.IsDefaultOrEmpty)
                {
                    if (target.Version != assemblyReference.Version)
                    {
                        continue;
                    }

                    ImmutableArray <byte> targetPublicKeyOrToken = _targetMetadata.GetBlobContent(target.PublicKeyOrToken);
                    if (!targetPublicKeyOrToken.SequenceEqual(targetPublicKeyOrToken))
                    {
                        continue;
                    }
                }

                return(new Mapping <AssemblyReferenceHandle>(targetHandle));
            }

            return(new Mapping <AssemblyReferenceHandle>());
        }
Example #5
0
        private static RuntimeAssemblyName CreateRuntimeAssemblyNameFromMetadata(
            MetadataReader reader,
            StringHandle name,
            Version version,
            StringHandle culture,
            BlobHandle publicKeyOrToken,
            AssemblyFlags assemblyFlags)
        {
            AssemblyNameFlags assemblyNameFlags = AssemblyNameFlags.None;

            if (0 != (assemblyFlags & AssemblyFlags.PublicKey))
            {
                assemblyNameFlags |= AssemblyNameFlags.PublicKey;
            }
            if (0 != (assemblyFlags & AssemblyFlags.Retargetable))
            {
                assemblyNameFlags |= AssemblyNameFlags.Retargetable;
            }
            int contentType = ((int)assemblyFlags) & 0x00000E00;

            assemblyNameFlags |= (AssemblyNameFlags)contentType;

            byte[] publicKeyOrTokenByteArray;
            if (!publicKeyOrToken.IsNil)
            {
                ImmutableArray <byte> publicKeyOrTokenBlob = reader.GetBlobContent(publicKeyOrToken);
                publicKeyOrTokenByteArray = new byte[publicKeyOrTokenBlob.Length];
                publicKeyOrTokenBlob.CopyTo(publicKeyOrTokenByteArray);
            }
            else
            {
                publicKeyOrTokenByteArray = Array.Empty <byte>();
            }

            string cultureName = culture.GetString(reader);

            if (!String.IsNullOrEmpty(cultureName))
            {
                // Canonicalize spelling and force a CultureNotFoundException if not a valid culture
                CultureInfo cultureInfo = CultureInfo.GetCultureInfo(cultureName);
                cultureName = cultureInfo.Name;
            }

            return(new RuntimeAssemblyName(
                       name.GetString(reader),
                       version,
                       cultureName,
                       assemblyNameFlags,
                       publicKeyOrTokenByteArray
                       ));
        }
Example #6
0
        public static unsafe EditAndContinueMethodDebugInformation GetEncMethodDebugInfo(
            this ISymUnmanagedReader3 symReader,
            MethodDefinitionHandle handle
            )
        {
            const int S_OK = 0;

            if (symReader is ISymUnmanagedReader4 symReader4)
            {
                int hr = symReader4.GetPortableDebugMetadata(out byte *metadata, out int size);
                Marshal.ThrowExceptionForHR(hr);

                if (hr == S_OK)
                {
                    var pdbReader = new MetadataReader(metadata, size);

                    ImmutableArray <byte> GetCdiBytes(Guid kind) =>
                    TryGetCustomDebugInformation(pdbReader, handle, kind, out var info)
                          ? pdbReader.GetBlobContent(info.Value)
                          : default(ImmutableArray <byte>);

                    return(EditAndContinueMethodDebugInformation.Create(
                               compressedSlotMap: GetCdiBytes(
                                   PortableCustomDebugInfoKinds.EncLocalSlotMap
                                   ),
                               compressedLambdaMap: GetCdiBytes(
                                   PortableCustomDebugInfoKinds.EncLambdaAndClosureMap
                                   )
                               ));
                }
            }

            var cdi = CustomDebugInfoUtilities.GetCustomDebugInfoBytes(
                symReader,
                handle,
                methodVersion: 1
                );

            if (cdi == null)
            {
                return(EditAndContinueMethodDebugInformation.Create(
                           default(ImmutableArray <byte>),
                           default(ImmutableArray <byte>)
                           ));
            }

            return(GetEncMethodDebugInfo(cdi));
        }
Example #7
0
        internal static string GetAssemblyDisplayName(MetadataReader reader, AssemblyReference assemblyRef)
        {
            string nameStr     = reader.GetString(assemblyRef.Name);
            string cultureName = assemblyRef.Culture.IsNil ? "" : reader.GetString(assemblyRef.Culture);
            ImmutableArray <byte> publicKeyOrToken = reader.GetBlobContent(assemblyRef.PublicKeyOrToken);
            bool hasPublicKey = (assemblyRef.Flags & AssemblyFlags.PublicKey) != 0;

            return(BuildDisplayName(
                       name: nameStr,
                       version: assemblyRef.Version,
                       cultureName: cultureName,
                       publicKeyOrToken: publicKeyOrToken,
                       hasPublicKey: hasPublicKey,
                       isRetargetable: (assemblyRef.Flags & AssemblyFlags.Retargetable) != 0,
                       contentType: (AssemblyContentType)((int)(assemblyRef.Flags & AssemblyFlags.ContentTypeMask) >> 9)));
        }
        private static RuntimeAssemblyName CreateRuntimeAssemblyNameFromMetadata(
            MetadataReader reader,
            StringHandle name,
            Version version,
            StringHandle culture,
            BlobHandle publicKeyOrToken,
            AssemblyFlags assemblyFlags)
        {
            AssemblyNameFlags assemblyNameFlags = AssemblyNameFlags.None;

            if (0 != (assemblyFlags & AssemblyFlags.PublicKey))
            {
                assemblyNameFlags |= AssemblyNameFlags.PublicKey;
            }
            if (0 != (assemblyFlags & AssemblyFlags.Retargetable))
            {
                assemblyNameFlags |= AssemblyNameFlags.Retargetable;
            }
            int contentType = ((int)assemblyFlags) & 0x00000E00;

            assemblyNameFlags |= (AssemblyNameFlags)contentType;

            byte[] publicKeyOrTokenByteArray;
            if (!publicKeyOrToken.IsNil)
            {
                ImmutableArray <byte> publicKeyOrTokenBlob = reader.GetBlobContent(publicKeyOrToken);
                publicKeyOrTokenByteArray = new byte[publicKeyOrTokenBlob.Length];
                publicKeyOrTokenBlob.CopyTo(publicKeyOrTokenByteArray);
            }
            else
            {
                publicKeyOrTokenByteArray = Array.Empty <byte>();
            }

            return(new RuntimeAssemblyName(
                       name.GetString(reader),
                       version,
                       culture.GetString(reader),
                       assemblyNameFlags,
                       publicKeyOrTokenByteArray
                       ));
        }
        private static ImmutableArray <AssemblyIdentity> ReadReferences(MetadataReader metadataReader)
        {
            var builder = ImmutableArray.CreateBuilder <AssemblyIdentity>();

            foreach (var referenceHandle in metadataReader.AssemblyReferences)
            {
                var reference = metadataReader.GetAssemblyReference(referenceHandle);

                string  refname        = metadataReader.GetString(reference.Name);
                Version refversion     = reference.Version;
                string  refcultureName = metadataReader.GetString(reference.Culture);
                ImmutableArray <byte> refpublicKeyOrToken = metadataReader.GetBlobContent(reference.PublicKeyOrToken);
                AssemblyFlags         refflags            = reference.Flags;
                bool refhasPublicKey = (refflags & AssemblyFlags.PublicKey) != 0;

                builder.Add(new AssemblyIdentity(refname, refversion, refcultureName, refpublicKeyOrToken, hasPublicKey: refhasPublicKey));
            }

            return(builder.ToImmutable());
        }
Example #10
0
        public ImmutableArray <SourceDocument> FindSourceDocuments(ISymbol symbol)
        {
            var documentHandles = SymbolSourceDocumentFinder.FindDocumentHandles(symbol, _dllReader, _pdbReader);

            using var _ = ArrayBuilder <SourceDocument> .GetInstance(out var sourceDocuments);

            foreach (var handle in documentHandles)
            {
                var document = _pdbReader.GetDocument(handle);
                var filePath = _pdbReader.GetString(document.Name);

                var hashAlgorithmGuid = _pdbReader.GetGuid(document.HashAlgorithm);
                var hashAlgorithm     = SourceHashAlgorithms.GetSourceHashAlgorithm(hashAlgorithmGuid);
                var checksum          = _pdbReader.GetBlobContent(document.Hash);

                var embeddedText = TryGetEmbeddedSourceText(handle);

                sourceDocuments.Add(new SourceDocument(filePath, hashAlgorithm, checksum, embeddedText));
            }

            return(sourceDocuments.ToImmutable());
        }
        private static AssemblyIdentity CreateAssemblyIdentity(
            MetadataReader reader,
            Version version,
            AssemblyFlags flags,
            BlobHandle publicKey,
            StringHandle name,
            StringHandle culture,
            bool isReference)
        {
            var  publicKeyOrToken = reader.GetBlobContent(publicKey);
            bool hasPublicKey;

            if (isReference)
            {
                hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
            }
            else
            {
                // Assembly definitions never contain a public key token, they only can have a full key or nothing,
                // so the flag AssemblyFlags.PublicKey does not make sense for them and is ignored.
                // See Ecma-335, Partition II Metadata, 22.2 "Assembly : 0x20".
                // This also corresponds to the behavior of the native C# compiler and sn.exe tool.
                hasPublicKey = !publicKeyOrToken.IsEmpty;
            }

            if (publicKeyOrToken.IsEmpty)
            {
                publicKeyOrToken = default;
            }

            return(new AssemblyIdentity(
                       name: reader.GetString(name),
                       version: version,
                       cultureName: culture.IsNil ? null : reader.GetString(culture),
                       publicKeyOrToken: publicKeyOrToken,
                       hasPublicKey: hasPublicKey,
                       isRetargetable: (flags & AssemblyFlags.Retargetable) != 0,
                       contentType: (AssemblyContentType)((int)(flags & AssemblyFlags.ContentTypeMask) >> 9)));
        }
Example #12
0
        /// <exception cref="BadImageFormatException">An exception from metadata reader.</exception>
        private static AssemblyIdentity CreateAssemblyIdentityOrThrow(
            this MetadataReader reader,
            Version version,
            AssemblyFlags flags,
            BlobHandle publicKey,
            StringHandle name,
            StringHandle culture,
            bool isReference)
        {
            string nameStr = reader.GetString(name);

            if (!MetadataHelpers.IsValidMetadataIdentifier(nameStr))
            {
                throw new BadImageFormatException(string.Format(CodeAnalysisResources.InvalidAssemblyName, nameStr));
            }

            string cultureName = culture.IsNil ? null : reader.GetString(culture);

            if (cultureName != null && !MetadataHelpers.IsValidMetadataIdentifier(cultureName))
            {
                throw new BadImageFormatException(string.Format(CodeAnalysisResources.InvalidCultureName, cultureName));
            }

            ImmutableArray <byte> publicKeyOrToken = reader.GetBlobContent(publicKey);
            bool hasPublicKey;

            if (isReference)
            {
                hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
                if (hasPublicKey)
                {
                    if (!MetadataHelpers.IsValidPublicKey(publicKeyOrToken))
                    {
                        throw new BadImageFormatException(CodeAnalysisResources.InvalidPublicKey);
                    }
                }
                else
                {
                    if (!publicKeyOrToken.IsEmpty &&
                        publicKeyOrToken.Length != AssemblyIdentity.PublicKeyTokenSize)
                    {
                        throw new BadImageFormatException(CodeAnalysisResources.InvalidPublicKeyToken);
                    }
                }
            }
            else
            {
                // Assembly definitions never contain a public key token, they only can have a full key or nothing,
                // so the flag AssemblyFlags.PublicKey does not make sense for them and is ignored.
                // See Ecma-335, Partition II Metadata, 22.2 "Assembly : 0x20".
                // This also corresponds to the behavior of the native C# compiler and sn.exe tool.
                hasPublicKey = !publicKeyOrToken.IsEmpty;
                if (hasPublicKey && !MetadataHelpers.IsValidPublicKey(publicKeyOrToken))
                {
                    throw new BadImageFormatException(CodeAnalysisResources.InvalidPublicKey);
                }
            }

            if (publicKeyOrToken.IsEmpty)
            {
                publicKeyOrToken = default(ImmutableArray <byte>);
            }

            return(new AssemblyIdentity(
                       name: nameStr,
                       version: version,
                       cultureName: cultureName,
                       publicKeyOrToken: publicKeyOrToken,
                       hasPublicKey: hasPublicKey,
                       isRetargetable: (flags & AssemblyFlags.Retargetable) != 0,
                       contentType: (AssemblyContentType)((int)(flags & AssemblyFlags.ContentTypeMask) >> 9),
                       noThrow: true));
        }
 private ImmutableArray <byte> GetCdiBytes(MethodDefinitionHandle methodHandle, Guid kind)
 => TryGetCustomDebugInformation(_pdbReader, methodHandle, kind, out var cdi) ?
 _pdbReader.GetBlobContent(cdi.Value) : default;
Example #14
0
 public static ImmutableArray <byte> GetBlobContent(this BlobHandle handle, MetadataReader reader) => reader.GetBlobContent(handle);