Example #1
0
        private string?TryGetSourceLinkUrl(DocumentHandle handle)
        {
            var document = _pdbReader.GetDocument(handle);

            if (document.Name.IsNil)
            {
                return(null);
            }

            var documentName = _pdbReader.GetString(document.Name);

            if (documentName is null)
            {
                return(null);
            }

            foreach (var cdiHandle in _pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition))
            {
                var cdi = _pdbReader.GetCustomDebugInformation(cdiHandle);
                if (_pdbReader.GetGuid(cdi.Kind) == PortableCustomDebugInfoKinds.SourceLink && !cdi.Value.IsNil)
                {
                    var blobReader     = _pdbReader.GetBlobReader(cdi.Value);
                    var sourceLinkJson = blobReader.ReadUTF8(blobReader.Length);

                    var map = SourceLinkMap.Parse(sourceLinkJson);

                    if (map.TryGetUri(documentName, out var uri))
                    {
                        return(uri);
                    }
                }
            }

            return(null);
        }
Example #2
0
        private string GetAttributeArgument(CustomAttribute attribute, MetadataReader metadataReader)
        {
            var signature       = metadataReader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature;
            var signatureReader = metadataReader.GetBlobReader(signature);
            var valueReader     = metadataReader.GetBlobReader(attribute.Value);

            valueReader.ReadUInt16();              // Skip prolog
            signatureReader.ReadSignatureHeader(); // Skip header

            int parameterCount;

            signatureReader.TryReadCompressedInteger(out parameterCount);

            signatureReader.ReadSignatureTypeCode(); // Skip return type

            for (int i = 0; i < parameterCount; i++)
            {
                var signatureTypeCode = signatureReader.ReadSignatureTypeCode();
                if (signatureTypeCode == SignatureTypeCode.String)
                {
                    return(valueReader.ReadSerializedString());
                }
            }

            return(string.Empty);
        }
Example #3
0
        /// <exception cref="BadImageFormatException">Invalid data format.</exception>
        private static void ReadMethodCustomDebugInformation(
            MetadataReader reader,
            MethodDefinitionHandle methodHandle,
            out ImmutableArray <HoistedLocalScopeRecord> hoistedLocalScopes,
            out string defaultNamespace
            )
        {
            hoistedLocalScopes = TryGetCustomDebugInformation(
                reader,
                methodHandle,
                PortableCustomDebugInfoKinds.StateMachineHoistedLocalScopes,
                out var info
                )
              ? DecodeHoistedLocalScopes(reader.GetBlobReader(info.Value))
              : ImmutableArray <HoistedLocalScopeRecord> .Empty;

            // TODO: consider looking this up once per module (not for every method)
            defaultNamespace = TryGetCustomDebugInformation(
                reader,
                EntityHandle.ModuleDefinition,
                PortableCustomDebugInfoKinds.DefaultNamespace,
                out info
                )
              ? DecodeDefaultNamespace(reader.GetBlobReader(info.Value))
              : "";
        }
Example #4
0
        private Object ResolveMethodSpecification(MethodSpecificationHandle handle)
        {
            MethodSpecification methodSpecification = _metadataReader.GetMethodSpecification(handle);

            object resolvedMethod = GetObject(methodSpecification.Method, NotFoundBehavior.ReturnResolutionFailure);

            if (resolvedMethod is ResolutionFailure)
            {
                return(resolvedMethod);
            }

            MethodDesc methodDef = resolvedMethod as MethodDesc;

            if (methodDef == null)
            {
                ThrowHelper.ThrowBadImageFormatException($"method expected for handle {handle.ToString()}");
            }

            BlobReader          signatureReader = _metadataReader.GetBlobReader(methodSpecification.Signature);
            EcmaSignatureParser parser          = new EcmaSignatureParser(this, signatureReader, NotFoundBehavior.ReturnResolutionFailure);

            TypeDesc[] instantiation = parser.ParseMethodSpecSignature();

            if (instantiation == null)
            {
                return(parser.ResolutionFailure);
            }

            return(Context.GetInstantiatedMethod(methodDef, new Instantiation(instantiation)));
        }
Example #5
0
            private void LookupMetadataDefinitions(
                TypeDefinition typeDefinition,
                OrderPreservingMultiDictionary <string, MetadataDefinition> definitionMap)
            {
                // Only bother looking for extension methods in static types.
                if ((typeDefinition.Attributes & TypeAttributes.Abstract) != 0 &&
                    (typeDefinition.Attributes & TypeAttributes.Sealed) != 0)
                {
                    foreach (var child in typeDefinition.GetMethods())
                    {
                        var method = _metadataReader.GetMethodDefinition(child);
                        if ((method.Attributes & MethodAttributes.SpecialName) != 0 ||
                            (method.Attributes & MethodAttributes.RTSpecialName) != 0)
                        {
                            continue;
                        }

                        // SymbolTreeInfo is only searched for types and extension methods.
                        // So we don't want to pull in all methods here.  As a simple approximation
                        // we just pull in methods that have attributes on them.
                        if ((method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public &&
                            (method.Attributes & MethodAttributes.Static) != 0 &&
                            method.GetParameters().Count > 0 &&
                            method.GetCustomAttributes().Count > 0)
                        {
                            // Decode method signature to get the target type name (i.e. type name for the first parameter)
                            var blob      = _metadataReader.GetBlobReader(method.Signature);
                            var decoder   = new SignatureDecoder <ParameterTypeInfo, object>(ParameterTypeInfoProvider.Instance, _metadataReader, genericContext: null);
                            var signature = decoder.DecodeMethodSignature(ref blob);

                            // It'd be good if we don't need to go through all parameters and make unnecessary allocations.
                            // However, this is not possible with meatadata reader API right now (although it's possible by copying code from meatadata reader implementaion)
                            if (signature.ParameterTypes.Length > 0)
                            {
                                _containsExtensionsMethod = true;
                                var firstParameterTypeInfo = signature.ParameterTypes[0];
                                var definition             = new MetadataDefinition(MetadataDefinitionKind.Member, _metadataReader.GetString(method.Name), firstParameterTypeInfo);
                                definitionMap.Add(definition.Name, definition);
                            }
                        }
                    }
                }

                foreach (var child in typeDefinition.GetNestedTypes())
                {
                    var type = _metadataReader.GetTypeDefinition(child);

                    // We don't include internals from metadata assemblies.  It's less likely that
                    // a project would have IVT to it and so it helps us save on memory.  It also
                    // means we can avoid loading lots and lots of obfuscated code in the case the
                    // dll was obfuscated.
                    if (IsPublic(type.Attributes))
                    {
                        var definition = MetadataDefinition.Create(_metadataReader, type);
                        definitionMap.Add(definition.Name, definition);
                        _allTypeDefinitions.Add(definition);
                    }
                }
            }
// Enabling this for MONO, because it's required by GetFrameworkName.
// More details are in the comment for that method
#if !FEATURE_ASSEMBLY_LOADFROM || MONO
        //  This method copied from DNX source: https://github.com/aspnet/dnx/blob/e0726f769aead073af2d8cd9db47b89e1745d574/src/Microsoft.Dnx.Tooling/Utils/LockFileUtils.cs#L385
        //  System.Reflection.Metadata 1.1 is expected to have an API that helps with this.
        /// <summary>
        /// Gets the fixed (required) string arguments of a custom attribute.
        /// Only attributes that have only fixed string arguments.
        /// </summary>
        private static List <string> GetFixedStringArguments(MetadataReader reader, CustomAttribute attribute)
        {
            // TODO: Nick Guerrera ([email protected]) hacked this method for temporary use.
            // There is a blob decoder feature in progress but it won't ship in time for our milestone.
            // Replace this method with the blob decoder feature when later it is availale.

            var signature       = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature;
            var signatureReader = reader.GetBlobReader(signature);
            var valueReader     = reader.GetBlobReader(attribute.Value);
            var arguments       = new List <string>();

            var prolog = valueReader.ReadUInt16();

            if (prolog != 1)
            {
                // Invalid custom attribute prolog
                return(arguments);
            }

            var header = signatureReader.ReadSignatureHeader();

            if (header.Kind != SignatureKind.Method || header.IsGeneric)
            {
                // Invalid custom attribute constructor signature
                return(arguments);
            }

            int parameterCount;

            if (!signatureReader.TryReadCompressedInteger(out parameterCount))
            {
                // Invalid custom attribute constructor signature
                return(arguments);
            }

            var returnType = signatureReader.ReadSignatureTypeCode();

            if (returnType != SignatureTypeCode.Void)
            {
                // Invalid custom attribute constructor signature
                return(arguments);
            }

            for (int i = 0; i < parameterCount; i++)
            {
                var signatureTypeCode = signatureReader.ReadSignatureTypeCode();
                if (signatureTypeCode == SignatureTypeCode.String)
                {
                    // Custom attribute constructor must take only strings
                    arguments.Add(valueReader.ReadSerializedString());
                }
            }

            return(arguments);
        }
Example #7
0
        private static string DumpRec(this MetadataReader reader, EntityHandle handle)
        {
            switch (handle.Kind)
            {
            case HandleKind.AssemblyReference:
                return(reader.GetString(reader.GetAssemblyReference((AssemblyReferenceHandle)handle).Name));

            case HandleKind.TypeDefinition:
            {
                TypeDefinition type = reader.GetTypeDefinition((TypeDefinitionHandle)handle);
                return(getQualifiedName(type.Namespace, type.Name));
            }

            case HandleKind.MethodDefinition:
            {
                MethodDefinition method = reader.GetMethodDefinition((MethodDefinitionHandle)handle);
                var blob       = reader.GetBlobReader(method.Signature);
                var decoder    = new SignatureDecoder <string, object>(ConstantSignatureVisualizer.Instance, reader, genericContext: null);
                var signature  = decoder.DecodeMethodSignature(ref blob);
                var parameters = signature.ParameterTypes.Join(", ");
                return($"{signature.ReturnType} {DumpRec(reader, method.GetDeclaringType())}.{reader.GetString(method.Name)}({parameters})");
            }

            case HandleKind.MemberReference:
            {
                MemberReference member     = reader.GetMemberReference((MemberReferenceHandle)handle);
                var             blob       = reader.GetBlobReader(member.Signature);
                var             decoder    = new SignatureDecoder <string, object>(ConstantSignatureVisualizer.Instance, reader, genericContext: null);
                var             signature  = decoder.DecodeMethodSignature(ref blob);
                var             parameters = signature.ParameterTypes.Join(", ");
                return($"{signature.ReturnType} {DumpRec(reader, member.Parent)}.{reader.GetString(member.Name)}({parameters})");
            }

            case HandleKind.TypeReference:
            {
                TypeReference type = reader.GetTypeReference((TypeReferenceHandle)handle);
                return(getQualifiedName(type.Namespace, type.Name));
            }

            default:
                return(null);
            }

            string getQualifiedName(StringHandle leftHandle, StringHandle rightHandle)
            {
                string name = reader.GetString(rightHandle);

                if (!leftHandle.IsNil)
                {
                    name = reader.GetString(leftHandle) + "." + name;
                }
                return(name);
            }
        }
Example #8
0
        private Object ResolveMethodSpecification(MethodSpecificationHandle handle)
        {
            MethodSpecification methodSpecification = _metadataReader.GetMethodSpecification(handle);

            MethodDesc methodDef = GetMethod(methodSpecification.Method);

            BlobReader          signatureReader = _metadataReader.GetBlobReader(methodSpecification.Signature);
            EcmaSignatureParser parser          = new EcmaSignatureParser(this, signatureReader);

            TypeDesc[] instantiation = parser.ParseMethodSpecSignature();
            return(Context.GetInstantiatedMethod(methodDef, new Instantiation(instantiation)));
        }
        public CustomAttributeValue <TType> DecodeValue(EntityHandle constructor, BlobHandle value)
        {
            BlobHandle signature;

            switch (constructor.Kind)
            {
            case HandleKind.MethodDefinition:
                MethodDefinition definition = _reader.GetMethodDefinition((MethodDefinitionHandle)constructor);
                signature = definition.Signature;
                break;

            case HandleKind.MemberReference:
                MemberReference reference = _reader.GetMemberReference((MemberReferenceHandle)constructor);
                signature = reference.Signature;
                break;

            default:
                throw new BadImageFormatException();
            }

            BlobReader signatureReader = _reader.GetBlobReader(signature);
            BlobReader valueReader     = _reader.GetBlobReader(value);

            ushort prolog = valueReader.ReadUInt16();

            if (prolog != 1)
            {
                throw new BadImageFormatException();
            }

            SignatureHeader header = signatureReader.ReadSignatureHeader();

            if (header.Kind != SignatureKind.Method || header.IsGeneric)
            {
                throw new BadImageFormatException();
            }

            int parameterCount           = signatureReader.ReadCompressedInteger();
            SignatureTypeCode returnType = signatureReader.ReadSignatureTypeCode();

            if (returnType != SignatureTypeCode.Void)
            {
                throw new BadImageFormatException();
            }

            ImmutableArray <CustomAttributeTypedArgument <TType> > fixedArguments = DecodeFixedArguments(ref signatureReader, ref valueReader, parameterCount);
            ImmutableArray <CustomAttributeNamedArgument <TType> > namedArguments = DecodeNamedArguments(ref valueReader);

            return(new CustomAttributeValue <TType>(fixedArguments, namedArguments));
        }
Example #10
0
        //<SnippetReadPdb>
        static string ReadDocumentPath(MetadataReader reader, Document doc)
        {
            BlobReader blob = reader.GetBlobReader(doc.Name);

            // Read path separator character
            var separator = (char)blob.ReadByte();
            var sb        = new StringBuilder(blob.Length * 2);

            // Read path segments
            while (true)
            {
                BlobHandle bh = blob.ReadBlobHandle();

                if (!bh.IsNil)
                {
                    byte[] nameBytes = reader.GetBlobBytes(bh);
                    sb.Append(Encoding.UTF8.GetString(nameBytes));
                }

                if (blob.Offset >= blob.Length)
                {
                    break;
                }

                sb.Append(separator);
            }

            return(sb.ToString());
        }
        void ParseEnum(TypeDefinition enumTypeDef)
        {
            // TODO: verify that int32 is the enums storage type for constant read below

            InspectorEnum ienum = new InspectorEnum();

            ienum.Name = metaReader.GetString(enumTypeDef.Name);

            InspectorEnums [ienum.Name] = ienum;

            var fields = enumTypeDef.GetFields();

            foreach (var fieldHandle in fields)
            {
                var inspectorField = new InspectorField();

                var fieldDef = metaReader.GetFieldDefinition(fieldHandle);

                if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0)
                {
                    var constantHandle = fieldDef.GetDefaultValue();
                    var constant       = metaReader.GetConstant(constantHandle);

                    BlobReader constantReader = metaReader.GetBlobReader(constant.Value);

                    ienum.Values [metaReader.GetString(fieldDef.Name)] = constantReader.ReadInt32();
                }
            }

            return;
        }
Example #12
0
        public ImmutableDictionary <string, string> GetCompilationOptions()
        {
            using var _ = PooledDictionary <string, string> .GetInstance(out var result);

            foreach (var handle in _pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition))
            {
                var customDebugInformation = _pdbReader.GetCustomDebugInformation(handle);
                if (_pdbReader.GetGuid(customDebugInformation.Kind) == PortableCustomDebugInfoKinds.CompilationOptions)
                {
                    var blobReader = _pdbReader.GetBlobReader(customDebugInformation.Value);

                    // Compiler flag bytes are UTF-8 null-terminated key-value pairs
                    var nullIndex = blobReader.IndexOf(0);
                    while (nullIndex >= 0)
                    {
                        var key = blobReader.ReadUTF8(nullIndex);

                        // Skip the null terminator
                        blobReader.ReadByte();

                        nullIndex = blobReader.IndexOf(0);
                        var value = blobReader.ReadUTF8(nullIndex);

                        result.Add(key, value);

                        // Skip the null terminator
                        blobReader.ReadByte();
                        nullIndex = blobReader.IndexOf(0);
                    }
                }
            }

            return(result.ToImmutableDictionary());
        }
Example #13
0
        private ulong HandleConstant(EcmaModule module, ConstantHandle constantHandle)
        {
            MetadataReader reader   = module.MetadataReader;
            Constant       constant = reader.GetConstant(constantHandle);
            BlobReader     blob     = reader.GetBlobReader(constant.Value);

            switch (constant.TypeCode)
            {
            case ConstantTypeCode.Byte:
                return((ulong)blob.ReadByte());

            case ConstantTypeCode.Int16:
                return((ulong)blob.ReadInt16());

            case ConstantTypeCode.Int32:
                return((ulong)blob.ReadInt32());

            case ConstantTypeCode.Int64:
                return((ulong)blob.ReadInt64());

            case ConstantTypeCode.SByte:
                return((ulong)blob.ReadSByte());

            case ConstantTypeCode.UInt16:
                return((ulong)blob.ReadUInt16());

            case ConstantTypeCode.UInt32:
                return((ulong)blob.ReadUInt32());

            case ConstantTypeCode.UInt64:
                return((ulong)blob.ReadUInt64());
            }
            System.Diagnostics.Debug.Assert(false);
            return(0);
        }
Example #14
0
            private void AddNamespaceParts(
                StringHandle namespaceHandle, List <string> simpleNames)
            {
                var blobReader = _metadataReader.GetBlobReader(namespaceHandle);

                while (true)
                {
                    int dotIndex = blobReader.IndexOf((byte)'.');
                    unsafe
                    {
                        // Note: we won't get any string sharing as we're just using the
                        // default string decoded.  However, that's ok.  We only produce
                        // these strings when we first read metadata.  Then we create and
                        // persist our own index.  In the future when we read in that index
                        // there's no way for us to share strings between us and the
                        // compiler at that point.
                        if (dotIndex == -1)
                        {
                            simpleNames.Add(MetadataStringDecoder.DefaultUTF8.GetString(
                                                blobReader.CurrentPointer, blobReader.RemainingBytes));
                            return;
                        }
                        else
                        {
                            simpleNames.Add(MetadataStringDecoder.DefaultUTF8.GetString(
                                                blobReader.CurrentPointer, dotIndex));
                            blobReader.Offset += dotIndex + 1;
                        }
                    }
                }
            }
Example #15
0
        /// <summary>
        /// Extracts the method signature from the metadata by rid
        /// </summary>
        public R2RMethod(byte[] image, MetadataReader mdReader, uint rid, int entryPointId, GenericElementTypes[] instanceArgs, uint[] tok)
        {
            Token = _mdtMethodDef | rid;
            EntryPointRuntimeFunctionId = entryPointId;

            _mdReader        = mdReader;
            RuntimeFunctions = new List <RuntimeFunction>();

            // get the method signature from the MethodDefhandle
            MethodDefinitionHandle methodDefHandle = MetadataTokens.MethodDefinitionHandle((int)rid);

            _methodDef = mdReader.GetMethodDefinition(methodDefHandle);
            Name       = mdReader.GetString(_methodDef.Name);
            BlobReader signatureReader = mdReader.GetBlobReader(_methodDef.Signature);

            TypeDefinitionHandle declaringTypeHandle = _methodDef.GetDeclaringType();
            TypeDefinition       declaringTypeDef;

            while (!declaringTypeHandle.IsNil)
            {
                declaringTypeDef    = mdReader.GetTypeDefinition(declaringTypeHandle);
                DeclaringType       = mdReader.GetString(declaringTypeDef.Name) + "." + DeclaringType;
                declaringTypeHandle = declaringTypeDef.GetDeclaringType();
            }

            NamespaceDefinitionHandle namespaceHandle = declaringTypeDef.NamespaceDefinition;

            while (!namespaceHandle.IsNil)
            {
                NamespaceDefinition namespaceDef = mdReader.GetNamespaceDefinition(namespaceHandle);
                DeclaringType   = mdReader.GetString(namespaceDef.Name) + "." + DeclaringType;
                namespaceHandle = namespaceDef.Parent;
            }

            SignatureHeader signatureHeader = signatureReader.ReadSignatureHeader();

            IsGeneric = signatureHeader.IsGeneric;
            GenericParameterHandleCollection genericParams = _methodDef.GetGenericParameters();

            _genericParamInstanceMap = new Dictionary <string, GenericInstance>();

            int argCount = signatureReader.ReadCompressedInteger();

            if (IsGeneric)
            {
                argCount = signatureReader.ReadCompressedInteger();
            }

            ReturnType = new SignatureType(ref signatureReader, mdReader, genericParams);
            ArgTypes   = new SignatureType[argCount];
            for (int i = 0; i < argCount; i++)
            {
                ArgTypes[i] = new SignatureType(ref signatureReader, mdReader, genericParams);
            }

            if (IsGeneric && instanceArgs != null && tok != null)
            {
                InitGenericInstances(genericParams, instanceArgs, tok);
            }
        }
Example #16
0
        internal unsafe SharpLangType ResolveTypeHandle(ISharpLangGenericContext context, Handle handle)
        {
            switch (handle.Kind)
            {
            case HandleKind.TypeDefinition:
                return(ResolveTypeDef(null, (TypeDefinitionHandle)handle));

            case HandleKind.TypeReference:
            {
                var typeReference = MetadataReader.GetTypeReference((TypeReferenceHandle)handle);
                var module        = ResolveModule(typeReference.ResolutionScope);
                if (module == null)
                {
                    throw new InvalidOperationException("Could not resolve module");
                }
                return(module.ResolveType(MetadataReader.GetString(typeReference.Namespace), MetadataReader.GetString(typeReference.Name)));
            }

            case HandleKind.TypeSpecification:
            {
                var typeSpecification = MetadataReader.GetTypeSpecification((TypeSpecificationHandle)handle);
                var signatureReader   = MetadataReader.GetBlobReader(typeSpecification.Signature);

                return(ReadSignature(context, signatureReader));
            }

            case HandleKind.GenericParameter:
            default:
                throw new NotImplementedException();
            }
        }
Example #17
0
        public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader,
                                  out PrimitiveTypeCode underlyingType)
        {
            underlyingType = 0;
            EntityHandle baseType = typeDefinition.GetBaseTypeOrNil();

            if (baseType.IsNil)
            {
                return(false);
            }
            if (!baseType.IsKnownType(reader, KnownTypeCode.Enum))
            {
                return(false);
            }
            foreach (var handle in typeDefinition.GetFields())
            {
                var field = reader.GetFieldDefinition(handle);
                if ((field.Attributes & FieldAttributes.Static) != 0)
                {
                    continue;
                }
                var blob = reader.GetBlobReader(field.Signature);
                if (blob.ReadSignatureHeader().Kind != SignatureKind.Field)
                {
                    return(false);
                }
                underlyingType = (PrimitiveTypeCode)blob.ReadByte();
                return(true);
            }
            return(false);
        }
Example #18
0
 public static BlobReader GetSingleBlob(Guid infoGuid, MetadataReader pdbReader)
 {
     return((from cdiHandle in pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition)
             let cdi = pdbReader.GetCustomDebugInformation(cdiHandle)
                       where pdbReader.GetGuid(cdi.Kind) == infoGuid
                       select pdbReader.GetBlobReader(cdi.Value)).Single());
 }
Example #19
0
        // TODO: this needs to be made more robust.
        // We currently rely on the fact that all attributes defined by the Q# compiler
        // have a single constructor taking a single string argument.
        private static (string, string)? GetAttribute(MetadataReader metadataReader, CustomAttribute attribute)
        {
            var attrType = GetAttributeType(metadataReader, attribute);

            QsCompilerError.Verify(attrType.HasValue, "the type of the custom attribute could not be determined");
            var(ns, name) = attrType.Value;

            var attrNS = metadataReader.GetString(ns);

            if (attrNS.StartsWith("Microsoft.Quantum", StringComparison.InvariantCulture))
            {
                var attrReader = metadataReader.GetBlobReader(attribute.Value);
                _ = attrReader.ReadUInt16(); // All custom attributes start with 0x0001, so read that now and discard it.
                try
                {
                    var serialization = attrReader.ReadSerializedString(); // FIXME: this needs to be made more robust
                    return(metadataReader.GetString(name), serialization);
                }
                catch
                {
                    return(null);
                }
            }
            return(null);
        }
Example #20
0
        public static string SignatureWithHeaderToString(this MetadataReader reader, BlobHandle srcHandle)
        {
            var blobReader    = reader.GetBlobReader(srcHandle);
            var stringBuilder = new StringBuilder();

            var header = blobReader.ReadSignatureHeader();

            stringBuilder.Append($"{header.Kind} ");
            switch (header.Kind)
            {
            case SignatureKind.Method:
            case SignatureKind.Property:
                MethodSignatureToString(reader, header, ref blobReader, stringBuilder);
                break;

            case SignatureKind.Field:
                FieldSignatureToString(reader, ref blobReader, stringBuilder);
                break;

            case SignatureKind.LocalVariables:
                LocalSignatureToString(reader, ref blobReader, stringBuilder);
                break;

            case SignatureKind.MethodSpecification:
                MethodSpecSignatureToString(reader, ref blobReader, stringBuilder);
                break;

            default:
                throw new BadImageFormatException();
            }

            return(stringBuilder.ToString());
        }
        /// <summary>
        /// Get the strong name of a reference assembly represented by the 'metadataReader'
        /// </summary>
        private static string GetAssemblyStrongName(MetadataReader metadataReader)
        {
            AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();
            string             asmName            = metadataReader.GetString(assemblyDefinition.Name);
            string             asmVersion         = assemblyDefinition.Version.ToString();
            string             asmCulture         = metadataReader.GetString(assemblyDefinition.Culture);

            asmCulture = (asmCulture == string.Empty) ? "neutral" : asmCulture;

            AssemblyHashAlgorithm hashAlgorithm = assemblyDefinition.HashAlgorithm;
            BlobHandle            blobHandle    = assemblyDefinition.PublicKey;
            BlobReader            blobReader    = metadataReader.GetBlobReader(blobHandle);

            byte[] publickey = blobReader.ReadBytes(blobReader.Length);

            HashAlgorithm hashImpl = null;

            switch (hashAlgorithm)
            {
            case AssemblyHashAlgorithm.Sha1:
                hashImpl = SHA1.Create();
                break;

            case AssemblyHashAlgorithm.MD5:
                hashImpl = MD5.Create();
                break;

            case AssemblyHashAlgorithm.Sha256:
                hashImpl = SHA256.Create();
                break;

            case AssemblyHashAlgorithm.Sha384:
                hashImpl = SHA384.Create();
                break;

            case AssemblyHashAlgorithm.Sha512:
                hashImpl = SHA512.Create();
                break;

            default:
                throw new NotSupportedException();
            }

            byte[] publicKeyHash       = hashImpl.ComputeHash(publickey);
            byte[] publicKeyTokenBytes = new byte[8];
            // Note that, the low 8 bytes of the hash of public key in reverse order is the public key tokens.
            for (int i = 1; i <= 8; i++)
            {
                publicKeyTokenBytes[i - 1] = publicKeyHash[publicKeyHash.Length - i];
            }

            // Convert bytes to hex format strings in lower case.
            string publicKeyTokenString = BitConverter.ToString(publicKeyTokenBytes).Replace("-", string.Empty).ToLowerInvariant();
            string strongAssemblyName   = string.Format(CultureInfo.InvariantCulture,
                                                        "{0}, Version={1}, Culture={2}, PublicKeyToken={3}",
                                                        asmName, asmVersion, asmCulture, publicKeyTokenString);

            return(strongAssemblyName);
        }
Example #22
0
        public static string TypeSignatureToString(this MetadataReader reader, BlobHandle srcHandle)
        {
            var blobReader    = reader.GetBlobReader(srcHandle);
            var stringBuilder = new StringBuilder();

            TypeSignatureToString(reader, ref blobReader, stringBuilder);
            return(stringBuilder.ToString());
        }
Example #23
0
        private static ImmutableArray <bool> ReadDynamicCustomDebugInformation(MetadataReader reader, EntityHandle variableOrConstantHandle)
        {
            if (TryGetCustomDebugInformation(reader, variableOrConstantHandle, PortableCustomDebugInfoKinds.DynamicLocalVariables, out var info))
            {
                return(DecodeDynamicFlags(reader.GetBlobReader(info.Value)));
            }

            return(default);
Example #24
0
        public static IEnumerable <string> GetLinkWithLibraryNames(this MetadataReader reader)
        {
            foreach (var attrHandle in reader.GetAssemblyDefinition().GetCustomAttributes())
            {
                var attr = reader.GetCustomAttribute(attrHandle);
                if (attr.Constructor.Kind != HandleKind.MemberReference)
                {
                    continue;
                }

                var ctor = reader.GetMemberReference((MemberReferenceHandle)attr.Constructor);

                var typeReference = reader.GetTypeReference((TypeReferenceHandle)ctor.Parent);
                if (reader.GetString(typeReference.Namespace) != "ObjCRuntime" ||
                    reader.GetString(typeReference.Name) != "LinkWithAttribute")
                {
                    continue;
                }

                // Unfortunately SRM does not yet have a number of facilities made public,
                // such as the *.Decoding namespace. Below we verify the raw signature of the
                // attribute, ensuring `void ObjCRuntime.LinkWithAttribute::.ctor(string)`.
                // See Decoding/MethodSignature.cs.cs in SRM.
                //
                // (header)(generic-type-param-count?)(param-count)(return-type)(param-types...)
                var sigReader = reader.GetBlobReader(ctor.Signature);
                if (sigReader.ReadSignatureHeader().IsGeneric ||                        // (skip generics)
                    sigReader.ReadCompressedInteger() != 1 ||                           // (param-count)
                    sigReader.ReadCompressedInteger() != (int)SignatureTypeCode.Void || // (return-type)
                    sigReader.ReadCompressedInteger() != (int)SignatureTypeCode.String) // (first param-type)
                {
                    continue;
                }

                // I could not actually find any uses of ReadSerializedString in SRM code,
                // but ยง II.23.3 Custom attributes of ECMA 335 indicates that we should expect
                // an LE unsigned int16 prolog of 0x0001 immediately followed by the fixed
                // argument value list, the format of which is defined by the ctor signature
                // itself as verified above, and is not repeated in the value blob.
                var valReader = reader.GetBlobReader(attr.Value);
                if (valReader.ReadUInt16() == 0x0001)
                {
                    yield return(valReader.ReadSerializedString());
                }
            }
        }
Example #25
0
        private uint LookupIbcMethodToken(MetadataType methodMetadataType, uint ibcToken, Dictionary <IBCBlobKey, BlobEntry> blobs)
        {
            var methodEntry    = (BlobEntry.ExternalMethodEntry)blobs[new IBCBlobKey(ibcToken, BlobType.ExternalMethodDef)];
            var signatureEntry = (BlobEntry.ExternalSignatureEntry)blobs[new IBCBlobKey(methodEntry.SignatureToken, BlobType.ExternalSignatureDef)];

            string methodName = Encoding.UTF8.GetString(methodEntry.Name);


            var ecmaType = (EcmaType)methodMetadataType.GetTypeDefinition();

            EcmaModule ecmaModule = ecmaType.EcmaModule;
            var        lookupClassTokenTypeDef = (int)LookupIbcTypeToken(ref ecmaModule, methodEntry.ClassToken, blobs);

            if (lookupClassTokenTypeDef != ecmaType.MetadataReader.GetToken(ecmaType.Handle))
            {
                throw new Exception($"Ibc MethodToken {ibcToken:x} incosistent classToken '{ibcToken:x}' with specified exact type '{ecmaType}'");
            }

            foreach (MethodDesc method in ecmaType.GetMethods())
            {
                if (method.Name == methodName)
                {
                    EcmaMethod ecmaCandidateMethod = method as EcmaMethod;
                    if (method == null)
                    {
                        continue;
                    }

                    MetadataReader metadataReader  = ecmaCandidateMethod.MetadataReader;
                    BlobReader     signatureReader = metadataReader.GetBlobReader(metadataReader.GetMethodDefinition(ecmaCandidateMethod.Handle).Signature);

                    // Compare for equality
                    if (signatureReader.RemainingBytes != signatureEntry.Signature.Length)
                    {
                        continue;
                    }
                    for (int i = 0; i < signatureEntry.Signature.Length; i++)
                    {
                        if (signatureReader.ReadByte() != signatureEntry.Signature[i])
                        {
                            continue;
                        }
                    }

                    // TODO, consider implementing the fuzzy matching that CrossGen implements
                    // It will be necessary for handling version tolerant ibc parsing of generics

                    // Exact match
                    return((uint)MetadataTokens.GetToken(ecmaCandidateMethod.Handle));
                }
            }

            if (_logger.IsVerbose)
            {
                _logger.Writer.WriteLine("Warning: Unable to find exact match for candidate external method");
            }
            return(0);
        }
Example #26
0
        /// <exception cref="BadImageFormatException">Invalid data format.</exception>
        private static void ReadMethodCustomDebugInformation(
            MetadataReader reader,
            MethodDefinitionHandle methodHandle,
            out ImmutableArray <HoistedLocalScopeRecord> hoistedLocalScopes,
            out string defaultNamespace)
        {
            hoistedLocalScopes = ImmutableArray <HoistedLocalScopeRecord> .Empty;

            foreach (var infoHandle in reader.GetCustomDebugInformation(methodHandle))
            {
                var info = reader.GetCustomDebugInformation(infoHandle);
                var id   = reader.GetGuid(info.Kind);
                if (id == PortableCustomDebugInfoKinds.StateMachineHoistedLocalScopes)
                {
                    // only single CDIof this kind is allowed on a method:
                    if (!hoistedLocalScopes.IsEmpty)
                    {
                        throw new BadImageFormatException();
                    }

                    hoistedLocalScopes = DecodeHoistedLocalScopes(reader.GetBlobReader(info.Value));
                }
            }

            // TODO: consider looking this up once per module (not for every method)
            defaultNamespace = null;
            foreach (var infoHandle in reader.GetCustomDebugInformation(EntityHandle.ModuleDefinition))
            {
                var info = reader.GetCustomDebugInformation(infoHandle);
                var id   = reader.GetGuid(info.Kind);
                if (id == PortableCustomDebugInfoKinds.DefaultNamespace)
                {
                    // only single CDI of this kind is allowed on the module:
                    if (defaultNamespace != null)
                    {
                        throw new BadImageFormatException();
                    }

                    var valueReader = reader.GetBlobReader(info.Value);
                    defaultNamespace = valueReader.ReadUTF8(valueReader.Length);
                }
            }

            defaultNamespace = defaultNamespace ?? "";
        }
Example #27
0
            public EntityHandle GetTypeFromSpecification(MetadataReader reader, TypeSpecificationHandle handle)
            {
                // Create a decoder to process the type specification (which happens with
                // instantiated generics).  It will call back into us to get the first handle
                // for the type def or type ref that the specification starts with.
                var sigReader = reader.GetBlobReader(reader.GetTypeSpecification(handle).Signature);

                return(new SignatureDecoder <EntityHandle, object>(this, reader, genericContext: null).DecodeType(ref sigReader));
            }
        public void WrongSignatureType()
        {
            using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(VarArgsToDecode).GetTypeInfo().Assembly)))
                using (var peReader = new PEReader(stream))
                {
                    MetadataReader reader   = peReader.GetMetadataReader();
                    var            provider = new DisassemblingTypeProvider();
                    var            decoder  = new SignatureDecoder <string, DisassemblingGenericContext>(provider, reader, genericContext: null);

                    BlobReader fieldSignature    = reader.GetBlobReader(reader.GetFieldDefinition(MetadataTokens.FieldDefinitionHandle(1)).Signature);
                    BlobReader methodSignature   = reader.GetBlobReader(reader.GetMethodDefinition(MetadataTokens.MethodDefinitionHandle(1)).Signature);
                    BlobReader propertySignature = reader.GetBlobReader(reader.GetPropertyDefinition(MetadataTokens.PropertyDefinitionHandle(1)).Signature);

                    Assert.Throws <BadImageFormatException>(() => decoder.DecodeMethodSignature(ref fieldSignature));
                    Assert.Throws <BadImageFormatException>(() => decoder.DecodeFieldSignature(ref methodSignature));
                    Assert.Throws <BadImageFormatException>(() => decoder.DecodeLocalSignature(ref propertySignature));
                }
        }
Example #29
0
        public static EntityHandle GetGenericType(this MetadataReader reader, TypeSpecification typeSpec)
        {
            var blobReader = reader.GetBlobReader(typeSpec.Signature);

            var typeCode = blobReader.ReadCompressedInteger();

            if (typeCode != (int)SignatureTypeCode.GenericTypeInstance)
            {
                return(default);
Example #30
0
        private static string GetFileName(MetadataReader reader, DocumentHandle documentHandle)
        {
            var document = reader.GetDocument(documentHandle);

            if (document.Name.IsNil)
            {
                return(null);
            }

            var nameReader = reader.GetBlobReader(document.Name);

            int separator = nameReader.ReadByte();

            if (!FileNameUtilities.IsDirectorySeparator((char)separator))
            {
                return(FileNameUtilities.GetFileName(reader.GetString(document.Name)));
            }

            // find the last part handle:
            BlobHandle partHandle = default(BlobHandle);

            while (nameReader.RemainingBytes > 0)
            {
                partHandle = nameReader.ReadBlobHandle();
            }

            if (partHandle.IsNil)
            {
                return(string.Empty);
            }

            var partReader = reader.GetBlobReader(partHandle);
            var part       = partReader.ReadUTF8(partReader.Length);

            if (part.IndexOf('\0') >= 0)
            {
                // bad metadata
                return(null);
            }

            // it is valid to encode document name so that the parts contain directory separators:
            return(FileNameUtilities.GetFileName(part));
        }