Example #1
0
        /// <summary>
        /// Try to look up field access info for given canon in metadata blobs for all available modules.
        /// </summary>
        /// <param name="metadataReader">Metadata reader for the declaring type</param>
        /// <param name="declaringTypeHandle">Declaring type for the method</param>
        /// <param name="fieldHandle">Field handle</param>
        /// <param name="canonFormKind">Canonical form to use</param>
        /// <param name="fieldAccessMetadata">Output - metadata information for field accessor construction</param>
        /// <returns>true when found, false otherwise</returns>
        private unsafe static bool TryGetFieldAccessMetadataFromFieldAccessMap(
            MetadataReader metadataReader,
            RuntimeTypeHandle declaringTypeHandle,
            FieldHandle fieldHandle,
            CanonicalFormKind canonFormKind,
            ref FieldAccessMetadata fieldAccessMetadata)
        {
            CanonicallyEquivalentEntryLocator canonWrapper = new CanonicallyEquivalentEntryLocator(declaringTypeHandle, canonFormKind);
            TypeManagerHandle fieldHandleModule            = ModuleList.Instance.GetModuleForMetadataReader(metadataReader);
            bool              isDynamicType = RuntimeAugments.IsDynamicType(declaringTypeHandle);
            string            fieldName     = null;
            RuntimeTypeHandle declaringTypeHandleDefinition = Instance.GetTypeDefinition(declaringTypeHandle);

            foreach (NativeFormatModuleInfo mappingTableModule in ModuleList.EnumerateModules(RuntimeAugments.GetModuleFromTypeHandle(declaringTypeHandle)))
            {
                NativeReader fieldMapReader;
                if (!TryGetNativeReaderForBlob(mappingTableModule, ReflectionMapBlob.FieldAccessMap, out fieldMapReader))
                {
                    continue;
                }

                NativeParser    fieldMapParser = new NativeParser(fieldMapReader, 0);
                NativeHashtable fieldHashtable = new NativeHashtable(fieldMapParser);

                ExternalReferencesTable externalReferences = default(ExternalReferencesTable);
                if (!externalReferences.InitializeCommonFixupsTable(mappingTableModule))
                {
                    continue;
                }

                var lookup = fieldHashtable.Lookup(canonWrapper.LookupHashCode);

                NativeParser entryParser;
                while (!(entryParser = lookup.GetNext()).IsNull)
                {
                    // Grammar of a hash table entry:
                    // Flags + DeclaringType + MdHandle or Name + Cookie or Ordinal or Offset

                    FieldTableFlags entryFlags = (FieldTableFlags)entryParser.GetUnsigned();

                    if ((canonFormKind == CanonicalFormKind.Universal) != ((entryFlags & FieldTableFlags.IsUniversalCanonicalEntry) != 0))
                    {
                        continue;
                    }

                    RuntimeTypeHandle entryDeclaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle) &&
                        !canonWrapper.IsCanonicallyEquivalent(entryDeclaringTypeHandle))
                    {
                        continue;
                    }

                    if ((entryFlags & FieldTableFlags.HasMetadataHandle) != 0)
                    {
                        Handle entryFieldHandle = (((int)HandleType.Field << 24) | (int)entryParser.GetUnsigned()).AsHandle();
                        if (!fieldHandle.Equals(entryFieldHandle))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (fieldName == null)
                        {
                            QTypeDefinition qTypeDefinition;

                            bool success = Instance.TryGetMetadataForNamedType(
                                declaringTypeHandleDefinition,
                                out qTypeDefinition);
                            Debug.Assert(success);

                            MetadataReader nativeFormatMetadataReader = qTypeDefinition.NativeFormatReader;

                            fieldName = nativeFormatMetadataReader.GetString(fieldHandle.GetField(nativeFormatMetadataReader).Name);
                        }

                        string entryFieldName = entryParser.GetString();

                        if (fieldName != entryFieldName)
                        {
                            continue;
                        }
                    }

                    int    fieldOffset = -1;
                    int    threadStaticsStartOffset = -1;
                    IntPtr fieldAddressCookie       = IntPtr.Zero;

                    if (canonFormKind == CanonicalFormKind.Universal)
                    {
                        if (!TypeLoaderEnvironment.Instance.TryGetFieldOffset(declaringTypeHandle, entryParser.GetUnsigned() /* field ordinal */, out fieldOffset))
                        {
                            Debug.Assert(false);
                            return(false);
                        }
                    }
                    else
                    {
                        if ((entryFlags & FieldTableFlags.StorageClass) == FieldTableFlags.ThreadStatic)
                        {
                            if ((entryFlags & FieldTableFlags.FieldOffsetEncodedDirectly) != 0)
                            {
                                if ((entryFlags & FieldTableFlags.IsAnyCanonicalEntry) == 0)
                                {
                                    int rvaToThreadStaticFieldOffsets = (int)externalReferences.GetRvaFromIndex(entryParser.GetUnsigned());
                                    fieldAddressCookie       = RvaToNonGenericStaticFieldAddress(mappingTableModule.Handle, rvaToThreadStaticFieldOffsets);
                                    threadStaticsStartOffset = *(int *)fieldAddressCookie.ToPointer();
                                }
                                fieldOffset = (int)entryParser.GetUnsigned();
                            }
                            else
                            {
                                int rvaToThreadStaticFieldOffsets = (int)externalReferences.GetRvaFromIndex(entryParser.GetUnsigned());
                                fieldAddressCookie = RvaToNonGenericStaticFieldAddress(mappingTableModule.Handle, rvaToThreadStaticFieldOffsets);
                                ThreadStaticFieldOffsets *pThreadStaticFieldOffsets = (ThreadStaticFieldOffsets *)fieldAddressCookie.ToPointer();

                                threadStaticsStartOffset = (int)pThreadStaticFieldOffsets->StartingOffsetInTlsBlock;
                                fieldOffset = (int)pThreadStaticFieldOffsets->FieldOffset;
                            }
                        }
                        else
                        {
                            if ((entryFlags & FieldTableFlags.FieldOffsetEncodedDirectly) != 0)
                            {
                                fieldOffset = (int)entryParser.GetUnsigned();
                            }
                            else
                            {
#if PROJECTN
                                fieldOffset = (int)externalReferences.GetRvaFromIndex(entryParser.GetUnsigned());
#else
                                fieldOffset        = 0;
                                fieldAddressCookie = externalReferences.GetAddressFromIndex(entryParser.GetUnsigned());

                                if ((entryFlags & FieldTableFlags.IsGcSection) != 0)
                                {
                                    fieldOffset = (int)entryParser.GetUnsigned();
                                }
#endif
                            }
                        }
                    }

                    if ((entryFlags & FieldTableFlags.StorageClass) == FieldTableFlags.ThreadStatic)
                    {
                        // TODO: CoreRT support

                        if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle))
                        {
                            if (!TypeLoaderEnvironment.Instance.TryGetThreadStaticStartOffset(declaringTypeHandle, out threadStaticsStartOffset))
                            {
                                return(false);
                            }
                        }

                        fieldAddressCookie = new IntPtr(threadStaticsStartOffset);
                    }

                    fieldAccessMetadata.MappingTableModule = mappingTableModule.Handle;
                    fieldAccessMetadata.Cookie             = fieldAddressCookie;
                    fieldAccessMetadata.Flags  = entryFlags;
                    fieldAccessMetadata.Offset = fieldOffset;
                    return(true);
                }
            }

            return(false);
        }
        private MethodNameAndSignature GetMethodNameAndSignatureFromNativeReader(NativeReader nativeLayoutReader, TypeManagerHandle moduleHandle, uint nativeLayoutOffset)
        {
            NativeParser parser = new NativeParser(nativeLayoutReader, nativeLayoutOffset);

            string methodName = parser.GetString();

            // Signatures are indirected to through a relative offset so that we don't have to parse them
            // when not comparing signatures (parsing them requires resolving types and is tremendously
            // expensive).
            NativeParser     sigParser = parser.GetParserFromRelativeOffset();
            RuntimeSignature methodSig = RuntimeSignature.CreateFromNativeLayoutSignature(moduleHandle, sigParser.Offset);

            return(new MethodNameAndSignature(methodName, methodSig));
        }
Example #3
0
        /// <summary>
        /// Try to look up field acccess info for given canon in metadata blobs for all available modules.
        /// </summary>
        /// <param name="metadataReader">Metadata reader for the declaring type</param>
        /// <param name="declaringTypeHandle">Declaring type for the method</param>
        /// <param name="fieldHandle">Field handle</param>
        /// <param name="canonFormKind">Canonical form to use</param>
        /// <param name="fieldAccessMetadata">Output - metadata information for field accessor construction</param>
        /// <returns>true when found, false otherwise</returns>
        private static bool TryGetFieldAccessMetadataFromFieldAccessMap(
            MetadataReader metadataReader,
            RuntimeTypeHandle declaringTypeHandle,
            FieldHandle fieldHandle,
            CanonicalFormKind canonFormKind,
            ref FieldAccessMetadata fieldAccessMetadata)
        {
            CanonicallyEquivalentEntryLocator canonWrapper = new CanonicallyEquivalentEntryLocator(declaringTypeHandle, canonFormKind);
            TypeManagerHandle fieldHandleModule            = ModuleList.Instance.GetModuleForMetadataReader(metadataReader);
            bool              isDynamicType = RuntimeAugments.IsDynamicType(declaringTypeHandle);
            string            fieldName     = null;
            RuntimeTypeHandle declaringTypeHandleDefinition = Instance.GetTypeDefinition(declaringTypeHandle);

            foreach (NativeFormatModuleInfo mappingTableModule in ModuleList.EnumerateModules(RuntimeAugments.GetModuleFromTypeHandle(declaringTypeHandle)))
            {
                NativeReader fieldMapReader;
                if (!TryGetNativeReaderForBlob(mappingTableModule, ReflectionMapBlob.FieldAccessMap, out fieldMapReader))
                {
                    continue;
                }

                NativeParser    fieldMapParser = new NativeParser(fieldMapReader, 0);
                NativeHashtable fieldHashtable = new NativeHashtable(fieldMapParser);

                ExternalReferencesTable externalReferences = default(ExternalReferencesTable);
                if (!externalReferences.InitializeCommonFixupsTable(mappingTableModule))
                {
                    continue;
                }

                var lookup = fieldHashtable.Lookup(canonWrapper.LookupHashCode);

                NativeParser entryParser;
                while (!(entryParser = lookup.GetNext()).IsNull)
                {
                    // Grammar of a hash table entry:
                    // Flags + DeclaringType + MdHandle or Name + Cookie or Ordinal or Offset

                    FieldTableFlags entryFlags = (FieldTableFlags)entryParser.GetUnsigned();

                    if ((canonFormKind == CanonicalFormKind.Universal) != entryFlags.HasFlag(FieldTableFlags.IsUniversalCanonicalEntry))
                    {
                        continue;
                    }

                    RuntimeTypeHandle entryDeclaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle) &&
                        !canonWrapper.IsCanonicallyEquivalent(entryDeclaringTypeHandle))
                    {
                        continue;
                    }

                    if (entryFlags.HasFlag(FieldTableFlags.HasMetadataHandle))
                    {
                        Handle entryFieldHandle = (((int)HandleType.Field << 24) | (int)entryParser.GetUnsigned()).AsHandle();
                        if (!fieldHandle.Equals(entryFieldHandle))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (fieldName == null)
                        {
                            QTypeDefinition qTypeDefinition;

                            bool success = Instance.TryGetMetadataForNamedType(
                                declaringTypeHandleDefinition,
                                out qTypeDefinition);
                            Debug.Assert(success);

                            MetadataReader nativeFormatMetadataReader = qTypeDefinition.NativeFormatReader;

                            fieldName = nativeFormatMetadataReader.GetString(fieldHandle.GetField(nativeFormatMetadataReader).Name);
                        }

                        string entryFieldName = entryParser.GetString();

                        if (fieldName != entryFieldName)
                        {
                            continue;
                        }
                    }

                    int    cookieOrOffsetOrOrdinal = (int)entryParser.GetUnsigned();
                    int    fieldOffset;
                    IntPtr fieldAddressCookie = IntPtr.Zero;

                    if (canonFormKind == CanonicalFormKind.Universal)
                    {
                        if (!TypeLoaderEnvironment.Instance.TryGetFieldOffset(declaringTypeHandle, (uint)cookieOrOffsetOrOrdinal, out fieldOffset))
                        {
                            Debug.Assert(false);
                            return(false);
                        }
                    }
                    else
                    {
#if CORERT
                        fieldOffset = cookieOrOffsetOrOrdinal;
#else
                        fieldOffset = (int)externalReferences.GetRvaFromIndex((uint)cookieOrOffsetOrOrdinal);
#endif
                    }

                    if ((entryFlags & FieldTableFlags.StorageClass) == FieldTableFlags.ThreadStatic)
                    {
                        if (canonFormKind != CanonicalFormKind.Universal)
                        {
                            fieldAddressCookie = RvaToNonGenericStaticFieldAddress(mappingTableModule.Handle, fieldOffset);
                        }

                        if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle))
                        {
                            // In this case we didn't find an exact match, but we did find a canonically equivalent match
                            // We might be in the dynamic type case, or the canonically equivalent, but not the same case.

                            if (!RuntimeAugments.IsDynamicType(declaringTypeHandle))
                            {
                                int offsetToCreateCookieFor = fieldOffset;
                                // We're working with a statically generated type, but we didn't find an exact match in the tables
                                if (canonFormKind != CanonicalFormKind.Universal)
                                {
                                    offsetToCreateCookieFor = checked ((int)TypeLoaderEnvironment.GetThreadStaticTypeOffsetFromThreadStaticCookie(fieldAddressCookie));
                                }

                                fieldAddressCookie = TypeLoaderEnvironment.Instance.TryGetThreadStaticFieldOffsetCookieForTypeAndFieldOffset(declaringTypeHandle, checked ((uint)offsetToCreateCookieFor));
                            }
                        }
                    }

                    fieldAccessMetadata.MappingTableModule = mappingTableModule.Handle;
                    fieldAccessMetadata.Cookie             = fieldAddressCookie;
                    fieldAccessMetadata.Flags  = entryFlags;
                    fieldAccessMetadata.Offset = fieldOffset;
                    return(true);
                }
            }

            return(false);
        }
        public static RuntimeTypeHandle GetTypeFromNativeLayoutSignature(ref NativeParser parser, TypeManagerHandle moduleHandle, uint offset)
        {
            RuntimeTypeHandle typeHandle;

            parser.Offset = offset;
            TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(ref parser, moduleHandle, null, null, out typeHandle);

            return(typeHandle);
        }
Example #5
0
 /// <summary>
 /// Construct the underlying module info enumerator used to iterate the module map
 /// </summary>
 /// <param name="moduleMap">Module map to enumerate</param>
 /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param>
 internal ModuleHandleEnumerator(ModuleMap moduleMap, TypeManagerHandle preferredModuleHandle)
 {
     _moduleInfoEnumerator = new ModuleInfoEnumerator(moduleMap, preferredModuleHandle);
 }
Example #6
0
 /// <summary>
 /// Construct the underlying module info enumerator used to iterate the module map
 /// </summary>
 /// <param name="moduleMap">Module map to enumerate</param>
 /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param>
 internal MetadataReaderEnumerator(ModuleMap moduleMap, TypeManagerHandle preferredModuleHandle)
 {
     _moduleInfoEnumerator = new NativeFormatModuleInfoEnumerator(moduleMap, preferredModuleHandle);
 }
Example #7
0
 /// <summary>
 /// Enumerate modules. Specify a module that should be enumerated first
 /// - this is used as an optimization in cases when a certain binary module is more probable
 /// to contain a certain information.
 /// </summary>
 /// <param name="preferredModule">Handle to the module which should be enumerated first</param>
 public static NativeFormatModuleInfoEnumerable EnumerateModules(TypeManagerHandle preferredModule)
 {
     return(new NativeFormatModuleInfoEnumerable(Instance._loadedModuleMap, preferredModule));
 }
Example #8
0
 /// <summary>
 /// Initialize module info and construct per-module metadata reader.
 /// </summary>
 /// <param name="moduleHandle">Handle (address) of module to initialize</param>
 internal NativeFormatModuleInfo(TypeManagerHandle moduleHandle, ModuleType moduleType, IntPtr pBlob, int cbBlob) : base(moduleHandle, moduleType)
 {
     MetadataReader = new MetadataReader((IntPtr)pBlob, (int)cbBlob);
 }
Example #9
0
 /// <summary>
 /// Initialize module info and construct per-module metadata reader.
 /// </summary>
 /// <param name="moduleHandle">Handle (address) of module to initialize</param>
 internal EcmaModuleInfo(TypeManagerHandle moduleHandle, PEReader pe, MetadataReader reader)
     : base(moduleHandle, ModuleType.Ecma)
 {
     PE             = pe;
     MetadataReader = reader;
 }
Example #10
0
        /// <summary>
        /// Locate module info for a given module. Fail if not found or before the module registry
        /// gets initialized. Must only be called for modules described as native format (not the mrt module, or an ECMA module)
        /// </summary>
        /// <param name="moduleHandle">Handle of module to look up</param>
        public NativeFormatModuleInfo GetModuleInfoByHandle(TypeManagerHandle moduleHandle)
        {
            ModuleMap moduleMap = _loadedModuleMap;

            return((NativeFormatModuleInfo)moduleMap.Modules[moduleMap.HandleToModuleIndex[moduleHandle]]);
        }
            internal override bool MatchParsedEntry(ref NativeParser entryParser, ref ExternalReferencesTable externalReferencesLookup, TypeManagerHandle moduleHandle)
            {
                // Compare entry with inputs as we parse it. If we get a mismatch, stop parsing and move to the next entry...
                RuntimeTypeHandle parsedDeclaringTypeHandle = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

                if (!parsedDeclaringTypeHandle.Equals(_declaringType))
                {
                    return(false);
                }

                // Hash table names / sigs are indirected through to the native layout info
                MethodNameAndSignature nameAndSignature;

                if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(moduleHandle, entryParser.GetUnsigned(), out nameAndSignature))
                {
                    return(false);
                }

                if (!nameAndSignature.Equals(_nameAndSignature))
                {
                    return(false);
                }

                int parsedArity = (int)entryParser.GetSequenceCount();
                int lookupArity = (_methodToLookup != null ? _methodToLookup.Instantiation.Length : _genericMethodArgumentHandles.Length);

                if (parsedArity != lookupArity)
                {
                    return(false);
                }

                for (int i = 0; i < parsedArity; i++)
                {
                    RuntimeTypeHandle parsedArg = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    RuntimeTypeHandle lookupArg = (_methodToLookup != null ? _methodToLookup.Instantiation[i].RuntimeTypeHandle : _genericMethodArgumentHandles[i]);
                    if (!parsedArg.Equals(lookupArg))
                    {
                        return(false);
                    }
                }

                return(true);
            }
            internal override bool MatchParsedEntry(ref NativeParser entryParser, ref ExternalReferencesTable externalReferencesLookup, TypeManagerHandle moduleHandle)
            {
                //
                // Entries read from the hashtable are loaded as GenericMethodDescs, and compared to the input.
                // This lookup is slower than the lookups using RuntimeTypeHandles, but can handle cases where we don't have
                // RuntimeTypeHandle values for all of the components of the input GenericMethodDesc, but still need to look it up in case the
                // method dictionary statically really exists
                //
                TypeSystemContext context = _methodToLookup.Context;

                RuntimeTypeHandle parsedDeclaringTypeHandle = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

                // Hash table names / sigs are indirected through to the native layout info
                MethodNameAndSignature nameAndSignature;

                if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(moduleHandle, entryParser.GetUnsigned(), out nameAndSignature))
                {
                    return(false);
                }

                RuntimeTypeHandle[] parsedArgsHandles = GetTypeSequence(ref externalReferencesLookup, ref entryParser);

                DefType            parsedDeclaringType = context.ResolveRuntimeTypeHandle(parsedDeclaringTypeHandle) as DefType;
                Instantiation      parsedArgs          = context.ResolveRuntimeTypeHandles(parsedArgsHandles);
                InstantiatedMethod parsedGenericMethod = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, parsedDeclaringType, nameAndSignature, parsedArgs, IntPtr.Zero, false);

                return(parsedGenericMethod == _methodToLookup);
            }
 internal abstract bool MatchParsedEntry(ref NativeParser entryParser, ref ExternalReferencesTable externalReferencesLookup, TypeManagerHandle moduleHandle);
Example #14
0
        private object TryParseNativeSignatureWorker(TypeSystemContext typeSystemContext, TypeManagerHandle moduleHandle, ref NativeParser parser, RuntimeTypeHandle[] typeGenericArgumentHandles, RuntimeTypeHandle[] methodGenericArgumentHandles, bool isMethodSignature)
        {
            Instantiation typeGenericArguments = typeSystemContext.ResolveRuntimeTypeHandles(typeGenericArgumentHandles ?? Array.Empty<RuntimeTypeHandle>());
            Instantiation methodGenericArguments = typeSystemContext.ResolveRuntimeTypeHandles(methodGenericArgumentHandles ?? Array.Empty<RuntimeTypeHandle>());

            NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext();
            nativeLayoutContext._module = ModuleList.GetModuleInfoByHandle(moduleHandle);
            nativeLayoutContext._typeSystemContext = typeSystemContext;
            nativeLayoutContext._typeArgumentHandles = typeGenericArguments;
            nativeLayoutContext._methodArgumentHandles = methodGenericArguments;

            if (isMethodSignature)
                return nativeLayoutContext.GetMethod(ref parser);
            else
                return nativeLayoutContext.GetType(ref parser);
        }
Example #15
0
 /// <summary>
 /// Enumerate metadata readers. Specify a module that should be enumerated first
 /// - this is used as an optimization in cases when a certain binary module is more probable
 /// to contain a certain information.
 /// </summary>
 /// <param name="preferredModule">Handle to the module which should be enumerated first</param>
 public static MetadataReaderEnumerable EnumerateMetadataReaders(TypeManagerHandle preferredModule)
 {
     return(new MetadataReaderEnumerable(Instance._loadedModuleMap, preferredModule));
 }
Example #16
0
 public static unsafe bool FindBlob(TypeManagerHandle typeManager, int blobId, IntPtr ppbBlob, IntPtr pcbBlob)
 {
     return(RuntimeImports.RhFindBlob(typeManager, (uint)blobId, (byte **)ppbBlob, (uint *)pcbBlob));
 }
Example #17
0
 /// <summary>
 /// Enumerate module handles (simplified version for code that only needs the module addresses).
 /// Specify a module that should be enumerated first
 /// - this is used as an optimization in cases when a certain binary module is more probable
 /// to contain a certain information.
 /// </summary>
 /// <param name="preferredModule">Handle to the module which should be enumerated first</param>
 public static ModuleHandleEnumerable Enumerate(TypeManagerHandle preferredModule)
 {
     return(new ModuleHandleEnumerable(Instance._loadedModuleMap, preferredModule));
 }
Example #18
0
 /// <summary>
 /// Store module map and preferred module to pass to the enumerator upon construction.
 /// </summary>
 /// <param name="moduleMap">Module map to enumerate</param>
 /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param>
 internal NativeFormatModuleInfoEnumerable(ModuleMap moduleMap, TypeManagerHandle preferredModuleHandle)
 {
     _moduleMap             = moduleMap;
     _preferredModuleHandle = preferredModuleHandle;
 }
 /// <summary>
 /// Resolve a given 32-bit integer (staticFieldRVA) representing a static field address.
 /// For "local" static fields residing in the module given by moduleHandle, staticFieldRVA
 /// directly contains the RVA of the static field. For remote static fields residing in other
 /// modules, staticFieldRVA has the highest bit set (FieldAccessFlags.RemoteStaticFieldRVA)
 /// and it contains the RVA of a RemoteStaticFieldDescriptor structure residing in the module
 /// given by moduleHandle that holds a pointer to the indirection cell
 /// of the remote static field and its offset within the cell.
 /// </summary>
 /// <param name="moduleHandle">Reference module handle used for static field lookup</param>
 /// <param name="staticFieldRVA">
 /// RVA of static field for local fields; for remote fields, RVA of a RemoteStaticFieldDescriptor
 /// structure for the field or-ed with the FieldAccessFlags.RemoteStaticFieldRVA bit
 /// </param>
 public static unsafe IntPtr RvaToNonGenericStaticFieldAddress(TypeManagerHandle moduleHandle, int staticFieldRVA)
 {
     // TODO: implement for CoreRT
     throw new NotImplementedException();
 }
Example #20
0
 /// <summary>
 /// Store module map and preferred module to pass to the enumerator upon construction.
 /// </summary>
 /// <param name="moduleMap">Module map to enumerate</param>
 /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param>
 internal MetadataReaderEnumerable(ModuleMap moduleMap, TypeManagerHandle preferredModuleHandle)
 {
     _moduleMap             = moduleMap;
     _preferredModuleHandle = preferredModuleHandle;
 }
        private bool CompareTypeSigWithType(ref NativeParser parser, TypeManagerHandle moduleHandle, Handle typeHandle)
        {
            while (typeHandle.HandleType == HandleType.TypeSpecification)
            {
                typeHandle = typeHandle
                             .ToTypeSpecificationHandle(_metadataReader)
                             .GetTypeSpecification(_metadataReader)
                             .Signature;
            }

            // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader
            // expects to read it in.
            uint startOffset = parser.Offset;

            uint data;
            var  typeSignatureKind = parser.GetTypeSignatureKind(out data);

            switch (typeSignatureKind)
            {
            case TypeSignatureKind.Lookback:
            {
                NativeParser lookbackParser = parser.GetLookbackParser(data);
                return(CompareTypeSigWithType(ref lookbackParser, moduleHandle, typeHandle));
            }

            case TypeSignatureKind.Modifier:
            {
                // Ensure the modifier kind (vector, pointer, byref) is the same
                TypeModifierKind modifierKind = (TypeModifierKind)data;
                switch (modifierKind)
                {
                case TypeModifierKind.Array:
                    if (typeHandle.HandleType == HandleType.SZArraySignature)
                    {
                        return(CompareTypeSigWithType(ref parser, moduleHandle, typeHandle
                                                      .ToSZArraySignatureHandle(_metadataReader)
                                                      .GetSZArraySignature(_metadataReader)
                                                      .ElementType));
                    }
                    return(false);

                case TypeModifierKind.ByRef:
                    if (typeHandle.HandleType == HandleType.ByReferenceSignature)
                    {
                        return(CompareTypeSigWithType(ref parser, moduleHandle, typeHandle
                                                      .ToByReferenceSignatureHandle(_metadataReader)
                                                      .GetByReferenceSignature(_metadataReader)
                                                      .Type));
                    }
                    return(false);

                case TypeModifierKind.Pointer:
                    if (typeHandle.HandleType == HandleType.PointerSignature)
                    {
                        return(CompareTypeSigWithType(ref parser, moduleHandle, typeHandle
                                                      .ToPointerSignatureHandle(_metadataReader)
                                                      .GetPointerSignature(_metadataReader)
                                                      .Type));
                    }
                    return(false);

                default:
                    Debug.Assert(null == "invalid type modifier kind");
                    return(false);
                }
            }

            case TypeSignatureKind.Variable:
            {
                bool isMethodVar = (data & 0x1) == 1;
                uint index       = data >> 1;

                if (isMethodVar)
                {
                    if (typeHandle.HandleType == HandleType.MethodTypeVariableSignature)
                    {
                        return(index == typeHandle
                               .ToMethodTypeVariableSignatureHandle(_metadataReader)
                               .GetMethodTypeVariableSignature(_metadataReader)
                               .Number);
                    }
                }
                else
                {
                    if (typeHandle.HandleType == HandleType.TypeVariableSignature)
                    {
                        return(index == typeHandle
                               .ToTypeVariableSignatureHandle(_metadataReader)
                               .GetTypeVariableSignature(_metadataReader)
                               .Number);
                    }
                }

                return(false);
            }

            case TypeSignatureKind.MultiDimArray:
            {
                if (typeHandle.HandleType != HandleType.ArraySignature)
                {
                    return(false);
                }

                ArraySignature sig = typeHandle
                                     .ToArraySignatureHandle(_metadataReader)
                                     .GetArraySignature(_metadataReader);

                if (data != sig.Rank)
                {
                    return(false);
                }

                if (!CompareTypeSigWithType(ref parser, moduleHandle, sig.ElementType))
                {
                    return(false);
                }

                uint boundCount1 = parser.GetUnsigned();
                for (uint i = 0; i < boundCount1; i++)
                {
                    parser.GetUnsigned();
                }

                uint lowerBoundCount1 = parser.GetUnsigned();

                for (uint i = 0; i < lowerBoundCount1; i++)
                {
                    parser.GetUnsigned();
                }
                break;
            }

            case TypeSignatureKind.FunctionPointer:
            {
                // callingConvention is in data
                uint argCount1 = parser.GetUnsigned();

                for (uint i = 0; i < argCount1; i++)
                {
                    if (!CompareTypeSigWithType(ref parser, moduleHandle, typeHandle))
                    {
                        return(false);
                    }
                }
                return(false);
            }

            case TypeSignatureKind.Instantiation:
            {
                if (typeHandle.HandleType != HandleType.TypeInstantiationSignature)
                {
                    return(false);
                }

                TypeInstantiationSignature sig = typeHandle
                                                 .ToTypeInstantiationSignatureHandle(_metadataReader)
                                                 .GetTypeInstantiationSignature(_metadataReader);

                if (!CompareTypeSigWithType(ref parser, moduleHandle, sig.GenericType))
                {
                    return(false);
                }

                uint genericArgIndex = 0;
                foreach (Handle genericArgumentTypeHandle in sig.GenericTypeArguments)
                {
                    if (genericArgIndex >= data)
                    {
                        // The metadata generic has more parameters than the native layour
                        return(false);
                    }
                    if (!CompareTypeSigWithType(ref parser, moduleHandle, genericArgumentTypeHandle))
                    {
                        return(false);
                    }
                    genericArgIndex++;
                }
                // Make sure all generic parameters have been matched
                return(genericArgIndex == data);
            }

            case TypeSignatureKind.BuiltIn:
            case TypeSignatureKind.External:
            {
                RuntimeTypeHandle type2;
                switch (typeHandle.HandleType)
                {
                case HandleType.TypeDefinition:
                    if (!TypeLoaderEnvironment.Instance.TryGetNamedTypeForMetadata(
                            new QTypeDefinition(_metadataReader, typeHandle.ToTypeDefinitionHandle(_metadataReader)), out type2))
                    {
                        return(false);
                    }
                    break;

                case HandleType.TypeReference:
                    if (!TypeLoaderEnvironment.TryResolveNamedTypeForTypeReference(
                            _metadataReader, typeHandle.ToTypeReferenceHandle(_metadataReader), out type2))
                    {
                        return(false);
                    }
                    break;

                default:
                    return(false);
                }

                RuntimeTypeHandle type1 = default(RuntimeTypeHandle);
                if (typeSignatureKind == TypeSignatureKind.External)
                {
                    type1 = SigParsing.GetTypeFromNativeLayoutSignature(ref parser, moduleHandle, startOffset);
                }
                else
                {
                    type1 = ((Internal.TypeSystem.WellKnownType)data).GetRuntimeTypeHandle();
                }

                return(type1.Equals(type2));
            }

            default:
                return(false);
            }
            return(true);
        }
Example #22
0
        /// <summary>
        /// Register all modules which were added (Registered) to the runtime and are not already registered with the TypeLoader.
        /// </summary>
        /// <param name="moduleType">Type to assign to all new modules.</param>
        public void RegisterNewModules(ModuleType moduleType)
        {
            // prevent multiple threads from registering modules concurrently
            using (LockHolder.Hold(_moduleRegistrationLock))
            {
                // Fetch modules that have already been registered with the runtime
                int loadedModuleCount = RuntimeAugments.GetLoadedModules(null);
                TypeManagerHandle[] loadedModuleHandles = new TypeManagerHandle[loadedModuleCount];
                int loadedModuleCountUpdated            = RuntimeAugments.GetLoadedModules(loadedModuleHandles);
                Debug.Assert(loadedModuleCount == loadedModuleCountUpdated);

                LowLevelList <TypeManagerHandle> newModuleHandles = new LowLevelList <TypeManagerHandle>(loadedModuleHandles.Length);
                foreach (TypeManagerHandle moduleHandle in loadedModuleHandles)
                {
                    // Skip already registered modules.
                    int oldModuleIndex;
                    if (_loadedModuleMap.HandleToModuleIndex.TryGetValue(moduleHandle, out oldModuleIndex))
                    {
                        continue;
                    }

                    newModuleHandles.Add(moduleHandle);
                }

                // Copy existing modules to new dictionary
                int          oldModuleCount = _loadedModuleMap.Modules.Length;
                ModuleInfo[] updatedModules = new ModuleInfo[oldModuleCount + newModuleHandles.Count];
                if (oldModuleCount > 0)
                {
                    Array.Copy(_loadedModuleMap.Modules, 0, updatedModules, 0, oldModuleCount);
                }

                for (int newModuleIndex = 0; newModuleIndex < newModuleHandles.Count; newModuleIndex++)
                {
                    ModuleInfo newModuleInfo;

                    unsafe
                    {
                        byte *pBlob;
                        uint  cbBlob;

                        if (RuntimeAugments.FindBlob(newModuleHandles[newModuleIndex], (int)ReflectionMapBlob.EmbeddedMetadata, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
                        {
                            newModuleInfo = new NativeFormatModuleInfo(newModuleHandles[newModuleIndex], moduleType, (IntPtr)pBlob, (int)cbBlob);
                        }
                        else
                        {
                            newModuleInfo = new ModuleInfo(newModuleHandles[newModuleIndex], moduleType);
                        }
                    }

                    updatedModules[oldModuleCount + newModuleIndex] = newModuleInfo;

                    if (_moduleRegistrationCallbacks != null)
                    {
                        _moduleRegistrationCallbacks(newModuleInfo);
                    }
                }

                // Atomically update the module map
                _loadedModuleMap = new ModuleMap(updatedModules);
            }
        }
Example #23
0
 public abstract IntPtr GetThreadStaticGCDescForDynamicType(TypeManagerHandle handle, int index);