Пример #1
0
        private unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature methodNameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles)
        {
            // Generic method dictionaries have a header that has the hash code in it. Locate the header
            IntPtr dictionaryHeader = IntPtr.Subtract(methodDictionary, IntPtr.Size);
            int    lookupHashcode   = *(int *)dictionaryHeader;

            int loadedModuleCount = RuntimeAugments.GetLoadedModules(null);
            var moduleHandles     = new System.IntPtr[loadedModuleCount];

            RuntimeAugments.GetLoadedModules(moduleHandles);

            ExternalReferencesTable externalReferencesLookup;
            NativeHashtable         genericMethodsHashtable;

            foreach (IntPtr moduleHandle in moduleHandles)
            {
                if (!GetHashtableFromBlob(moduleHandle, ReflectionMapBlob.GenericMethodsHashtable, out genericMethodsHashtable, out externalReferencesLookup))
                {
                    continue;
                }

                var enumerator = genericMethodsHashtable.Lookup(lookupHashcode);

                NativeParser entryParser;
                while (!(entryParser = enumerator.GetNext()).IsNull)
                {
                    // Is this entry the dictionary we are looking for?
                    uint   dictionaryIndex        = entryParser.GetUnsigned();
                    IntPtr parsedMethodDictionary = externalReferencesLookup.GetIntPtrFromIndex(dictionaryIndex);
                    if (parsedMethodDictionary != methodDictionary)
                    {
                        continue;
                    }

                    // We have a match - fill in the results
                    declaringType = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

                    // Hash table names / sigs are indirected through to the native layout info
                    if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(moduleHandle, entryParser.GetUnsigned(), out methodNameAndSignature))
                    {
                        continue;
                    }

                    uint arity = entryParser.GetSequenceCount();
                    genericMethodArgumentHandles = new RuntimeTypeHandle[arity];

                    for (int i = 0; i < arity; i++)
                    {
                        genericMethodArgumentHandles[i] = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    }

                    return(true);
                }
            }

            declaringType                = default(RuntimeTypeHandle);
            methodNameAndSignature       = null;
            genericMethodArgumentHandles = null;
            return(false);
        }
Пример #2
0
        private static unsafe bool TryGetStructData(RuntimeTypeHandle structTypeHandle, out ExternalReferencesTable externalReferences, out NativeParser entryParser)
        {
            int structHashcode = structTypeHandle.GetHashCode();

            externalReferences = default(ExternalReferencesTable);
            entryParser        = default(NativeParser);
            foreach (TypeManagerHandle module in RuntimeAugments.GetLoadedModules())
            {
                NativeReader structMapReader;
                if (TryGetNativeReaderForBlob(module, ReflectionMapBlob.StructMarshallingStubMap, out structMapReader))
                {
                    NativeParser    structMapParser = new NativeParser(structMapReader, 0);
                    NativeHashtable structHashtable = new NativeHashtable(structMapParser);

                    externalReferences.InitializeCommonFixupsTable(module);

                    var lookup = structHashtable.Lookup(structHashcode);
                    while (!(entryParser = lookup.GetNext()).IsNull)
                    {
                        RuntimeTypeHandle foundStructType = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                        if (foundStructType.Equals(structTypeHandle))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Пример #3
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.
                    if (_loadedModuleMap.HandleToModuleIndex.TryGetValue(moduleHandle, out _))
                    {
                        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;

                    _moduleRegistrationCallbacks?.Invoke(newModuleInfo);
                }

                // Atomically update the module map
                _loadedModuleMap = new ModuleMap(updatedModules);
            }
        }
Пример #4
0
        /// <summary>
        /// Get the NativeLayout for a type from a ReadyToRun image.
        /// </summary>
        public bool TryGetMetadataNativeLayout(TypeDesc concreteType, out IntPtr nativeLayoutInfoModule, out uint nativeLayoutInfoToken)
        {
            nativeLayoutInfoModule = default(IntPtr);
            nativeLayoutInfoToken  = 0;
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
            var nativeMetadataType = concreteType.GetTypeDefinition() as TypeSystem.NativeFormat.NativeFormatType;
            if (nativeMetadataType == null)
            {
                return(false);
            }

            var canonForm = concreteType.ConvertToCanonForm(CanonicalFormKind.Specific);
            var hashCode  = canonForm.GetHashCode();

            var loadedModulesCount  = RuntimeAugments.GetLoadedModules(null);
            var loadedModuleHandles = new IntPtr[loadedModulesCount];
            var loadedModules       = RuntimeAugments.GetLoadedModules(loadedModuleHandles);
            Debug.Assert(loadedModulesCount == loadedModules);

#if SUPPORTS_R2R_LOADING
            foreach (var moduleHandle in loadedModuleHandles)
            {
                ExternalReferencesTable externalFixupsTable;
                NativeHashtable         typeTemplatesHashtable = LoadHashtable(moduleHandle, ReflectionMapBlob.MetadataBasedTypeTemplateMap, out externalFixupsTable);

                if (typeTemplatesHashtable.IsNull)
                {
                    continue;
                }

                var enumerator         = typeTemplatesHashtable.Lookup(hashCode);
                var nativeMetadataUnit = nativeMetadataType.Context.ResolveMetadataUnit(moduleHandle);

                NativeParser entryParser;
                while (!(entryParser = enumerator.GetNext()).IsNull)
                {
                    var      entryTypeHandle = entryParser.GetUnsigned().AsHandle();
                    TypeDesc typeDesc        = nativeMetadataUnit.GetType(entryTypeHandle);
                    Debug.Assert(typeDesc != null);
                    if (typeDesc == canonForm)
                    {
                        TypeLoaderLogger.WriteLine("Found metadata template for type " + concreteType.ToString() + ": " + typeDesc.ToString());
                        nativeLayoutInfoToken = (uint)externalFixupsTable.GetRvaFromIndex(entryParser.GetUnsigned());
                        if (nativeLayoutInfoToken == BadTokenFixupValue)
                        {
                            throw new BadImageFormatException();
                        }

                        nativeLayoutInfoModule = moduleHandle;
                        return(true);
                    }
                }
            }
#endif
#endif

            return(false);
        }
Пример #5
0
        private TypeDesc TryGetTypeTemplate_Internal(TypeDesc concreteType, CanonicalFormKind kind, out IntPtr nativeLayoutInfoModule, out uint nativeLayoutInfoToken)
        {
            nativeLayoutInfoModule = default(IntPtr);
            nativeLayoutInfoToken  = 0;
            var canonForm = concreteType.ConvertToCanonForm(kind);
            var hashCode  = canonForm.GetHashCode();

            var loadedModulesCount  = RuntimeAugments.GetLoadedModules(null);
            var loadedModuleHandles = new IntPtr[loadedModulesCount];
            var loadedModules       = RuntimeAugments.GetLoadedModules(loadedModuleHandles);

            Debug.Assert(loadedModulesCount == loadedModules);

            foreach (var moduleHandle in loadedModuleHandles)
            {
                ExternalReferencesTable externalFixupsTable;
                NativeHashtable         typeTemplatesHashtable = LoadHashtable(moduleHandle, ReflectionMapBlob.TypeTemplateMap, out externalFixupsTable);

                if (typeTemplatesHashtable.IsNull)
                {
                    continue;
                }

                var enumerator = typeTemplatesHashtable.Lookup(hashCode);

                NativeParser entryParser;
                while (!(entryParser = enumerator.GetNext()).IsNull)
                {
                    RuntimeTypeHandle candidateTemplateTypeHandle = externalFixupsTable.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    TypeDesc          candidateTemplate           = concreteType.Context.ResolveRuntimeTypeHandle(candidateTemplateTypeHandle);

                    if (canonForm == candidateTemplate.ConvertToCanonForm(kind))
                    {
                        TypeLoaderLogger.WriteLine("Found template for type " + concreteType.ToString() + ": " + candidateTemplate.ToString());
                        nativeLayoutInfoToken = (uint)externalFixupsTable.GetRvaFromIndex(entryParser.GetUnsigned());
                        if (nativeLayoutInfoToken == BadTokenFixupValue)
                        {
                            // TODO: once multifile gets fixed up, make this throw a BadImageFormatException
                            TypeLoaderLogger.WriteLine("ERROR: template not fixed up, skipping");
                            continue;
                        }

                        Debug.Assert(
                            (kind != CanonicalFormKind.Universal && candidateTemplate != candidateTemplate.ConvertToCanonForm(kind)) ||
                            (kind == CanonicalFormKind.Universal && candidateTemplate == candidateTemplate.ConvertToCanonForm(kind)));

                        nativeLayoutInfoModule = moduleHandle;
                        return(candidateTemplate);
                    }
                }
            }

            TypeLoaderLogger.WriteLine("ERROR: Cannot find a suitable template for type " + concreteType.ToString());
            return(null);
        }
        private unsafe static void GenerateErrorReportForDump(LowLevelList <byte[]> serializedExceptions)
        {
            checked
            {
                int loadedModuleCount = RuntimeAugments.GetLoadedModules(null);
                int cbModuleHandles   = sizeof(System.IntPtr) * loadedModuleCount;
                int cbFinalBuffer     = sizeof(ERROR_REPORT_BUFFER_HEADER) + sizeof(SERIALIZED_ERROR_REPORT_HEADER) + cbModuleHandles;
                for (int i = 0; i < serializedExceptions.Count; i++)
                {
                    cbFinalBuffer += serializedExceptions[i].Length;
                }

                byte[] finalBuffer = new byte[cbFinalBuffer];
                fixed(byte *pBuffer = finalBuffer)
                {
                    byte *pCursor     = pBuffer;
                    int   cbRemaining = cbFinalBuffer;

                    ERROR_REPORT_BUFFER_HEADER *pDacHeader = (ERROR_REPORT_BUFFER_HEADER *)pCursor;

                    pDacHeader->WriteHeader(cbFinalBuffer);
                    pCursor     += sizeof(ERROR_REPORT_BUFFER_HEADER);
                    cbRemaining -= sizeof(ERROR_REPORT_BUFFER_HEADER);

                    SERIALIZED_ERROR_REPORT_HEADER *pPayloadHeader = (SERIALIZED_ERROR_REPORT_HEADER *)pCursor;

                    pPayloadHeader->WriteHeader(serializedExceptions.Count, loadedModuleCount);
                    pCursor     += sizeof(SERIALIZED_ERROR_REPORT_HEADER);
                    cbRemaining -= sizeof(SERIALIZED_ERROR_REPORT_HEADER);

                    // copy the serialized exceptions to report buffer
                    for (int i = 0; i < serializedExceptions.Count; i++)
                    {
                        int cbChunk = serializedExceptions[i].Length;
                        Array.CopyToNative(serializedExceptions[i], 0, (IntPtr)pCursor, cbChunk);
                        cbRemaining -= cbChunk;
                        pCursor     += cbChunk;
                    }

                    // copy the module-handle array to report buffer
                    System.IntPtr[] loadedModuleHandles = new System.IntPtr[loadedModuleCount];
                    RuntimeAugments.GetLoadedModules(loadedModuleHandles);
                    Array.CopyToNative(loadedModuleHandles, 0, (IntPtr)pCursor, loadedModuleHandles.Length);
                    cbRemaining -= cbModuleHandles;
                    pCursor     += cbModuleHandles;

                    Debug.Assert(cbRemaining == 0);
                }

                UpdateErrorReportBuffer(finalBuffer);
            }
        }
        /// <summary>
        /// Add a new module registration callback. Invoke the callback for all currently
        /// registered modules.
        /// </summary>
        /// <param name="moduleRegistrationCallback">Callback gets passed the module handle</param>
        internal void AddModuleRegistrationCallback(Action <IntPtr> moduleRegistrationCallback)
        {
            _moduleRegistrationCallbacks += moduleRegistrationCallback;
            int loadedModulesCount = RuntimeAugments.GetLoadedModules(null);

            IntPtr[] loadedModuleHandles = new IntPtr[loadedModulesCount];
            int      loadedModules       = RuntimeAugments.GetLoadedModules(loadedModuleHandles);

            Debug.Assert(loadedModulesCount == loadedModules);
            foreach (IntPtr moduleHandle in loadedModuleHandles)
            {
                moduleRegistrationCallback(moduleHandle);
            }
        }
Пример #8
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);
                IntPtr[] loadedModuleHandles      = new IntPtr[loadedModuleCount];
                int      loadedModuleCountUpdated = RuntimeAugments.GetLoadedModules(loadedModuleHandles);
                Debug.Assert(loadedModuleCount == loadedModuleCountUpdated);

                LowLevelList <IntPtr> newModuleHandles = new LowLevelList <IntPtr>(loadedModuleHandles.Length);
                foreach (IntPtr 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 = new ModuleInfo(newModuleHandles[newModuleIndex], moduleType);

                    updatedModules[oldModuleCount + newModuleIndex] = newModuleInfo;

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

                // Atomically update the module map
                _loadedModuleMap = new ModuleMap(updatedModules);
            }
        }
Пример #9
0
        internal unsafe bool TryGetStaticGenericTypeForComponents(GenericTypeLookupData lookupData, out RuntimeTypeHandle runtimeTypeHandle)
        {
            // Search the hashtable for a generic instantiation match
            // TODO multi-file: consider whether we can limit the search somehow,
            // i.e. not look at all the modules

            runtimeTypeHandle = default(RuntimeTypeHandle);

            int loadedModuleCount = RuntimeAugments.GetLoadedModules(null);
            var moduleHandles     = new System.IntPtr[loadedModuleCount];

            RuntimeAugments.GetLoadedModules(moduleHandles);

            NativeHashtable         genericsHashtable;
            ExternalReferencesTable externalReferencesLookup;

            foreach (IntPtr moduleHandle in moduleHandles)
            {
                if (!GetHashtableFromBlob(moduleHandle, ReflectionMapBlob.GenericsHashtable, out genericsHashtable, out externalReferencesLookup))
                {
                    continue;
                }

                int lookupHashcode = lookupData.LookupHashCode();
                var enumerator     = genericsHashtable.Lookup(lookupHashcode);

                NativeParser entryParser;
                while (!(entryParser = enumerator.GetNext()).IsNull)
                {
                    RuntimeTypeHandle tentativeType = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

                    if (!lookupData.MatchParsedEntry(tentativeType))
                    {
                        continue;
                    }

                    runtimeTypeHandle = tentativeType;
                    Debug.Assert(RuntimeAugments.IsGenericType(runtimeTypeHandle));

                    return(true);
                }
            }

            return(false);
        }
Пример #10
0
        /// <summary>
        /// Register initially (eagerly) loaded modules.
        /// </summary>
        internal ModuleList()
        {
            _loadedModuleMap             = new ModuleMap(new ModuleInfo[0]);
            _moduleRegistrationCallbacks = default(Action <ModuleInfo>);
            _moduleRegistrationLock      = new Lock();

            // Fetch modules that have already been registered with the runtime
            int loadedModuleCount = RuntimeAugments.GetLoadedModules(null);

            IntPtr[] loadedModuleHandles      = new IntPtr[loadedModuleCount];
            int      loadedModuleCountUpdated = RuntimeAugments.GetLoadedModules(loadedModuleHandles);

            Debug.Assert(loadedModuleCount == loadedModuleCountUpdated);

            foreach (IntPtr moduleHandle in loadedModuleHandles)
            {
                RegisterModule(moduleHandle);
            }
        }
Пример #11
0
        private bool TryGetStaticGenericMethodDictionaryForComponents(GenericMethodLookupData lookupData, out IntPtr result)
        {
            // Search the hashtable for a generic instantiation match

            int loadedModuleCount = RuntimeAugments.GetLoadedModules(null);
            var moduleHandles     = new System.IntPtr[loadedModuleCount];

            RuntimeAugments.GetLoadedModules(moduleHandles);

            ExternalReferencesTable externalReferencesLookup;
            NativeHashtable         genericMethodsHashtable;

            foreach (IntPtr moduleHandle in moduleHandles)
            {
                if (!GetHashtableFromBlob(moduleHandle, ReflectionMapBlob.GenericMethodsHashtable, out genericMethodsHashtable, out externalReferencesLookup))
                {
                    continue;
                }

                int lookupHashcode = lookupData.LookupHashCode();
                var enumerator     = genericMethodsHashtable.Lookup(lookupHashcode);

                NativeParser entryParser;
                while (!(entryParser = enumerator.GetNext()).IsNull)
                {
                    uint dictionaryIndex = entryParser.GetUnsigned();

                    if (!lookupData.MatchParsedEntry(ref entryParser, ref externalReferencesLookup, moduleHandle))
                    {
                        continue;
                    }

                    // Current entry matched all inputs, return success
                    result = externalReferencesLookup.GetIntPtrFromIndex(dictionaryIndex);
                    return(true);
                }
            }

            result = IntPtr.Zero;
            return(false);
        }
Пример #12
0
        public bool TryLookupExactMethodPointerForComponents(RuntimeTypeHandle declaringType, MethodNameAndSignature nameAndSignature, RuntimeTypeHandle[] genericMethodArgumentHandles, out IntPtr result)
        {
            int lookupHashcode = declaringType.GetHashCode();

            int loadedModuleCount = RuntimeAugments.GetLoadedModules(null);
            var moduleHandles     = new System.IntPtr[loadedModuleCount];

            RuntimeAugments.GetLoadedModules(moduleHandles);

            NativeHashtable         hashtable;
            ExternalReferencesTable externalReferencesLookup;

            HandleBasedGenericMethodLookup lookupData = new HandleBasedGenericMethodLookup(declaringType, nameAndSignature, genericMethodArgumentHandles);

            foreach (IntPtr moduleHandle in moduleHandles)
            {
                if (!GetHashtableFromBlob(moduleHandle, ReflectionMapBlob.ExactMethodInstantiationsHashtable, out hashtable, out externalReferencesLookup))
                {
                    continue;
                }

                var enumerator = hashtable.Lookup(lookupHashcode);

                NativeParser entryParser;
                while (!(entryParser = enumerator.GetNext()).IsNull)
                {
                    if (!lookupData.MatchParsedEntry(ref entryParser, ref externalReferencesLookup, moduleHandle))
                    {
                        continue;
                    }

                    // We found a match
                    result = externalReferencesLookup.GetIntPtrFromIndex(entryParser.GetUnsigned());
                    return(true);
                }
            }

            result = IntPtr.Zero;
            return(false);
        }
Пример #13
0
        private static unsafe bool GetMarshallersForDelegate(RuntimeTypeHandle delegateTypeHandle, out IntPtr openStub, out IntPtr closedStub, out IntPtr delegateCreationStub)
        {
            int delegateHashcode = delegateTypeHandle.GetHashCode();

            openStub             = IntPtr.Zero;
            closedStub           = IntPtr.Zero;
            delegateCreationStub = IntPtr.Zero;

            foreach (TypeManagerHandle module in RuntimeAugments.GetLoadedModules())
            {
                NativeReader delegateMapReader;
                if (TryGetNativeReaderForBlob(module, ReflectionMapBlob.DelegateMarshallingStubMap, out delegateMapReader))
                {
                    NativeParser    delegateMapParser = new NativeParser(delegateMapReader, 0);
                    NativeHashtable delegateHashtable = new NativeHashtable(delegateMapParser);

                    ExternalReferencesTable externalReferences = default(ExternalReferencesTable);
                    externalReferences.InitializeCommonFixupsTable(module);

                    var          lookup = delegateHashtable.Lookup(delegateHashcode);
                    NativeParser entryParser;
                    while (!(entryParser = lookup.GetNext()).IsNull)
                    {
                        RuntimeTypeHandle foundDelegateType = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                        if (foundDelegateType.Equals(delegateTypeHandle))
                        {
                            openStub             = externalReferences.GetIntPtrFromIndex(entryParser.GetUnsigned());
                            closedStub           = externalReferences.GetIntPtrFromIndex(entryParser.GetUnsigned());
                            delegateCreationStub = externalReferences.GetIntPtrFromIndex(entryParser.GetUnsigned());
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Пример #14
0
        private InstantiatedMethod TryGetGenericMethodTemplate_Internal(InstantiatedMethod concreteMethod, CanonicalFormKind kind, out IntPtr nativeLayoutInfoModule, out uint nativeLayoutInfoToken)
        {
            nativeLayoutInfoModule = default(IntPtr);
            nativeLayoutInfoToken  = 0;
            var canonForm           = concreteMethod.GetCanonMethodTarget(kind);
            var hashCode            = canonForm.GetHashCode();
            var loadedModulesCount  = RuntimeAugments.GetLoadedModules(null);
            var loadedModuleHandles = new IntPtr[loadedModulesCount];
            var loadedModules       = RuntimeAugments.GetLoadedModules(loadedModuleHandles);

            Debug.Assert(loadedModulesCount == loadedModules);

            foreach (var moduleHandle in loadedModuleHandles)
            {
                NativeReader nativeLayoutReader = TypeLoaderEnvironment.Instance.GetNativeLayoutInfoReader(moduleHandle);
                if (nativeLayoutReader == null)
                {
                    continue;
                }

                ExternalReferencesTable externalFixupsTable;
                NativeHashtable         genericMethodTemplatesHashtable = LoadHashtable(moduleHandle, ReflectionMapBlob.GenericMethodsTemplateMap, out externalFixupsTable);

                if (genericMethodTemplatesHashtable.IsNull)
                {
                    continue;
                }

                var context = new NativeLayoutInfoLoadContext
                {
                    _typeSystemContext     = concreteMethod.Context,
                    _typeArgumentHandles   = concreteMethod.OwningType.Instantiation,
                    _methodArgumentHandles = concreteMethod.Instantiation,
                    _moduleHandle          = moduleHandle
                };

                var enumerator = genericMethodTemplatesHashtable.Lookup(hashCode);

                NativeParser entryParser;
                while (!(entryParser = enumerator.GetNext()).IsNull)
                {
                    var methodSignatureParser = new NativeParser(nativeLayoutReader, externalFixupsTable.GetRvaFromIndex(entryParser.GetUnsigned()));

                    // Get the unified generic method holder and convert it to its canonical form
                    var candidateTemplate = (InstantiatedMethod)context.GetMethod(ref methodSignatureParser);
                    Debug.Assert(candidateTemplate.Instantiation.Length > 0);

                    if (canonForm == candidateTemplate.GetCanonMethodTarget(kind))
                    {
                        TypeLoaderLogger.WriteLine("Found template for generic method " + concreteMethod.ToString() + ": " + candidateTemplate.ToString());
                        nativeLayoutInfoModule = moduleHandle;
                        nativeLayoutInfoToken  = (uint)externalFixupsTable.GetRvaFromIndex(entryParser.GetUnsigned());
                        if (nativeLayoutInfoToken == BadTokenFixupValue)
                        {
                            // TODO: once multifile gets fixed up, make this throw a BadImageFormatException
                            TypeLoaderLogger.WriteLine("ERROR: template not fixed up, skipping");
                            continue;
                        }

                        Debug.Assert(
                            (kind != CanonicalFormKind.Universal && candidateTemplate != candidateTemplate.GetCanonMethodTarget(kind)) ||
                            (kind == CanonicalFormKind.Universal && candidateTemplate == candidateTemplate.GetCanonMethodTarget(kind)));

                        return(candidateTemplate);
                    }
                }
            }

            TypeLoaderLogger.WriteLine("ERROR: Cannot find a suitable template for generic method " + concreteMethod.ToString());
            return(null);
        }
Пример #15
0
        /// <summary>
        /// Locate and lazily load debug info for the native app module overlapping given
        /// virtual address.
        /// </summary>
        /// <param name="ip">Instruction pointer address (code address for the lookup)</param>
        /// <param name="rva">Output VA relative to module base</param>
        private static IDiaSession GetDiaSession(IntPtr ip, out int rva)
        {
            if (ip == IntPtr.Zero)
            {
                rva = -1;
                return(null);
            }

            IntPtr moduleBase = RuntimeAugments.GetModuleFromPointer(ip);

            if (moduleBase == IntPtr.Zero)
            {
                rva = -1;
                return(null);
            }

            rva = (int)(ip.ToInt64() - moduleBase.ToInt64());

            if (s_loadedModules == null)
            {
                // Lazily create the parallel arrays s_loadedModules and s_perModuleDebugInfo
                int moduleCount = RuntimeAugments.GetLoadedModules(null);

                s_loadedModules      = new IntPtr[moduleCount];
                s_perModuleDebugInfo = new IDiaSession[moduleCount];

                // Actually read the module addresses into the array
                RuntimeAugments.GetLoadedModules(s_loadedModules);
            }

            // Locate module index based on base address
            int moduleIndex = s_loadedModules.Length;

            do
            {
                if (--moduleIndex < 0)
                {
                    return(null);
                }
            }while(s_loadedModules[moduleIndex] != moduleBase);

            IDiaSession diaSession = s_perModuleDebugInfo[moduleIndex];

            if (diaSession != null)
            {
                return(diaSession);
            }

            string modulePath = RuntimeAugments.TryGetFullPathToApplicationModule(moduleBase);

            if (modulePath == null)
            {
                return(null);
            }

            int indexOfLastDot = modulePath.LastIndexOf('.');

            if (indexOfLastDot == -1)
            {
                return(null);
            }

            IDiaDataSource diaDataSource = GetDiaDataSource();

            if (diaDataSource == null)
            {
                return(null);
            }

            // Look for .pdb next to .exe / dll - if it's not there, bail.
            String pdbPath = modulePath.Substring(0, indexOfLastDot) + ".pdb";
            int    hr      = diaDataSource.LoadDataFromPdb(pdbPath);

            if (hr != S_OK)
            {
                return(null);
            }

            hr = diaDataSource.OpenSession(out diaSession);
            if (hr != S_OK)
            {
                return(null);
            }

            s_perModuleDebugInfo[moduleIndex] = diaSession;
            return(diaSession);
        }