Beispiel #1
0
        public static unsafe bool TryGetTargetOfUnboxingAndInstantiatingStub(IntPtr maybeInstantiatingAndUnboxingStub, out IntPtr targetMethod)
        {
            targetMethod = IntPtr.Zero;

            // Get module
            IntPtr associatedModule = RuntimeAugments.GetOSModuleFromPointer(maybeInstantiatingAndUnboxingStub);
            if (associatedModule == IntPtr.Zero)
            {
                return false;
            }

            // Get UnboxingAndInstantiatingTable
            UnboxingAndInstantiatingStubMapEntry* pBlob;
            uint cbBlob;

            if (!RuntimeAugments.FindBlob(new TypeManagerHandle(associatedModule), (int)ReflectionMapBlob.UnboxingAndInstantiatingStubMap, (IntPtr)(&pBlob), (IntPtr)(&cbBlob)))
            {
                return false;
            }

            uint cStubs = cbBlob / (uint)sizeof(UnboxingAndInstantiatingStubMapEntry);

            for (uint i = 0; i < cStubs; ++i)
            {
                if (RvaToFunctionPointer(new TypeManagerHandle(associatedModule), pBlob[i].StubMethodRva) == maybeInstantiatingAndUnboxingStub)
                {
                    // We found a match, create pointer from RVA and move on.
                    targetMethod = RvaToFunctionPointer(new TypeManagerHandle(associatedModule), pBlob[i].MethodRva);
                    return true;
                }
            }

            // Stub not found.
            return false;
        }
Beispiel #2
0
        //
        // Returns the native layout info reader
        //
        internal static unsafe NativeReader GetNativeLayoutInfoReader(TypeManagerHandle moduleHandle)
        {
            Debug.Assert(!moduleHandle.IsNull);

            if (t_moduleNativeReaders == null)
            {
                t_moduleNativeReaders = new LowLevelDictionary <TypeManagerHandle, NativeReader>();
            }

            NativeReader result;

            if (t_moduleNativeReaders.TryGetValue(moduleHandle, out result))
            {
                return(result);
            }

            byte *pBlob;
            uint  cbBlob;

            if (RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.NativeLayoutInfo, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
            {
                result = new NativeReader(pBlob, cbBlob);
            }

            t_moduleNativeReaders.Add(moduleHandle, result);
            return(result);
        }
        // get the statics hash table, external references, and static info table for a module
        // TODO multi-file: consider whether we want to cache this info
        private unsafe bool GetStaticsInfoHashtable(IntPtr moduleHandle, out NativeHashtable staticsInfoHashtable, out ExternalReferencesTable externalReferencesLookup, out ExternalReferencesTable staticInfoLookup)
        {
            byte *pBlob;
            uint  cbBlob;

            staticsInfoHashtable     = default(NativeHashtable);
            externalReferencesLookup = default(ExternalReferencesTable);
            staticInfoLookup         = default(ExternalReferencesTable);

            // Load statics info hashtable
            if (!RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.StaticsInfoHashtable, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
            {
                return(false);
            }
            NativeReader reader = new NativeReader(pBlob, cbBlob);
            NativeParser parser = new NativeParser(reader, 0);

            if (!externalReferencesLookup.InitializeNativeReferences(moduleHandle))
            {
                return(false);
            }

            if (!staticInfoLookup.InitializeNativeStatics(moduleHandle))
            {
                return(false);
            }

            staticsInfoHashtable = new NativeHashtable(parser);

            return(true);
        }
Beispiel #4
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);
            }
        }
        /// <summary>
        /// Locate reflection blob in a given module and construct its metadata reader.
        /// </summary>
        /// <param name="moduleHandle">Module handle to register</param>
        unsafe void CreateMetadataReader(IntPtr moduleHandle)
        {
            uint *pBlob;
            uint  cbBlob;

            if (RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.EmbeddedMetadata, (IntPtr)(&pBlob), (IntPtr)(&cbBlob)))
            {
                MetadataReader reader = new MetadataReader((IntPtr)pBlob, (int)cbBlob);
                _moduleToMetadataReader.Add(moduleHandle, reader);
            }
        }
Beispiel #6
0
 public unsafe bool TryFindBlob(int blobId, out byte *pBlob, out uint cbBlob)
 {
     pBlob  = null;
     cbBlob = 0;
     fixed(byte **ppBlob = &pBlob)
     {
         fixed(uint *pcbBlob = &cbBlob)
         {
             return(RuntimeAugments.FindBlob(Handle, (int)blobId, new IntPtr(ppBlob), new IntPtr(pcbBlob)));
         }
     }
 }
Beispiel #7
0
        /// <summary>
        /// Initialize module info and construct per-module metadata reader.
        /// </summary>
        /// <param name="moduleHandle">Handle (address) of module to initialize</param>
        internal unsafe ModuleInfo(IntPtr moduleHandle)
        {
            Handle = moduleHandle;

            byte *pBlob;
            uint  cbBlob;

            if (RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.EmbeddedMetadata, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
            {
                MetadataReader = new MetadataReader((IntPtr)pBlob, (int)cbBlob);
            }
        }
        public static unsafe bool TryGetTargetOfUnboxingAndInstantiatingStub(IntPtr maybeInstantiatingAndUnboxingStub, out IntPtr targetMethod)
        {
            targetMethod = RuntimeAugments.GetTargetOfUnboxingAndInstantiatingStub(maybeInstantiatingAndUnboxingStub);
            if (targetMethod != IntPtr.Zero)
            {
                return true;
            }

            // TODO: The rest of the code in this function is specific to ProjectN only. When we kill the binder, get rid of this
            // linear search code (the only API that should be used for the lookup is the one above)

            // Get module
            IntPtr associatedModule = RuntimeAugments.GetOSModuleFromPointer(maybeInstantiatingAndUnboxingStub);
            if (associatedModule == IntPtr.Zero)
            {
                return false;
            }

            // Module having a type manager means we are not in ProjectN mode. Bail out earlier.
            foreach (TypeManagerHandle handle in ModuleList.Enumerate())
            {
                if (handle.OsModuleBase == associatedModule && handle.IsTypeManager)
                {
                    return false;
                }
            }

            // Get UnboxingAndInstantiatingTable
            UnboxingAndInstantiatingStubMapEntry* pBlob;
            uint cbBlob;

            if (!RuntimeAugments.FindBlob(new TypeManagerHandle(associatedModule), (int)ReflectionMapBlob.UnboxingAndInstantiatingStubMap, (IntPtr)(&pBlob), (IntPtr)(&cbBlob)))
            {
                return false;
            }

            uint cStubs = cbBlob / (uint)sizeof(UnboxingAndInstantiatingStubMapEntry);

            for (uint i = 0; i < cStubs; ++i)
            {
                if (RvaToFunctionPointer(new TypeManagerHandle(associatedModule), pBlob[i].StubMethodRva) == maybeInstantiatingAndUnboxingStub)
                {
                    // We found a match, create pointer from RVA and move on.
                    targetMethod = RvaToFunctionPointer(new TypeManagerHandle(associatedModule), pBlob[i].MethodRva);
                    return true;
                }
            }

            // Stub not found.
            return false;
        }
        private unsafe static bool TryGetNativeReaderForBlob(IntPtr module, ReflectionMapBlob blob, out NativeReader reader)
        {
            byte *pBlob;
            uint  cbBlob;

            if (RuntimeAugments.FindBlob(module, (int)blob, (IntPtr)(&pBlob), (IntPtr)(&cbBlob)))
            {
                reader = new NativeReader(pBlob, cbBlob);
                return(true);
            }

            reader = default(NativeReader);
            return(false);
        }
        private unsafe bool Initialize(TypeManagerHandle typeManager, ReflectionMapBlob blobId)
        {
            byte *pBlob;
            uint  cbBlob;

            if (!RuntimeAugments.FindBlob(typeManager, (int)blobId, (IntPtr)(void *)&pBlob, (IntPtr)(void *)&cbBlob))
            {
                _elements      = IntPtr.Zero;
                _elementsCount = 0;
                return(false);
            }

            _elements      = (IntPtr)pBlob;
            _elementsCount = (uint)(cbBlob / sizeof(uint));

            return(true);
        }
            unsafe public ExternalReferencesTable(IntPtr moduleHandle, ReflectionMapBlob blobId)
            {
                _moduleHandle = moduleHandle;

                uint *pBlob;
                uint  cbBlob;

                if (RuntimeAugments.FindBlob(moduleHandle, (int)blobId, (IntPtr)(&pBlob), (IntPtr)(&cbBlob)))
                {
                    _count = cbBlob / sizeof(uint);
                    _base  = pBlob;
                }
                else
                {
                    _count = 0;
                    _base  = null;
                }
            }
        private unsafe bool Initialize(IntPtr moduleHandle, ReflectionMapBlob blobId)
        {
            _moduleHandle = moduleHandle;

            byte *pBlob;
            uint  cbBlob;

            if (!RuntimeAugments.FindBlob(moduleHandle, (int)blobId, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
            {
                _elements      = IntPtr.Zero;
                _elementsCount = 0;
                return(false);
            }

            _elements      = (IntPtr)pBlob;
            _elementsCount = (uint)(cbBlob / sizeof(TableElement));
            return(true);
        }
Beispiel #13
0
        // get the generics hash table and external references table for a module
        // TODO multi-file: consider whether we want to cache this info
        private unsafe bool GetHashtableFromBlob(IntPtr moduleHandle, ReflectionMapBlob blobId, out NativeHashtable hashtable, out ExternalReferencesTable externalReferencesLookup)
        {
            byte* pBlob;
            uint cbBlob;

            hashtable = default(NativeHashtable);
            externalReferencesLookup = default(ExternalReferencesTable);

            if (!RuntimeAugments.FindBlob(moduleHandle, (int)blobId, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
                return false;

            NativeReader reader = new NativeReader(pBlob, cbBlob);
            NativeParser parser = new NativeParser(reader, 0);

            hashtable = new NativeHashtable(parser);

            return externalReferencesLookup.InitializeNativeReferences(moduleHandle);
        }
        //
        // Returns the native layout info reader
        //
        internal unsafe NativeReader GetNativeLayoutInfoReader(IntPtr moduleHandle)
        {
            Debug.Assert(moduleHandle != IntPtr.Zero);

            if (t_moduleNativeReaders == null)
                t_moduleNativeReaders = new LowLevelDictionary<IntPtr, NativeReader>();

            NativeReader result = null;
            if (t_moduleNativeReaders.TryGetValue(moduleHandle, out result))
                return result;

            byte* pBlob;
            uint cbBlob;
            if (RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.NativeLayoutInfo, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
                result = new NativeReader(pBlob, cbBlob);

            t_moduleNativeReaders.Add(moduleHandle, result);
            return result;
        }
Beispiel #15
0
        private MetadataTable(IntPtr moduleHandle, ReflectionMapBlob blobId, int elementSize)
        {
            Debug.Assert(elementSize != 0);

            _elementSize = elementSize;

            byte *pBlob;
            uint  cbBlob;

            if (!RuntimeAugments.FindBlob(moduleHandle, (int)blobId, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
            {
                pBlob  = null;
                cbBlob = 0;
            }

            Debug.Assert(cbBlob % elementSize == 0);

            _blob        = pBlob;
            ElementCount = cbBlob / (uint)elementSize;
        }
Beispiel #16
0
        private unsafe Stream ReadResourceFromBlob(ResourceInfo resourceInfo)
        {
            byte *pBlob;
            uint  cbBlob;

            if (!RuntimeAugments.FindBlob(resourceInfo.ModuleHandle, (int)ReflectionMapBlob.BlobIdResourceData, (IntPtr)(&pBlob), (IntPtr)(&cbBlob)))
            {
                throw new BadImageFormatException();
            }

            checked
            {
                if (resourceInfo.Index > cbBlob || resourceInfo.Index + resourceInfo.Length > cbBlob)
                {
                    throw new BadImageFormatException();
                }
            }

            UnmanagedMemoryStream stream = new UnmanagedMemoryStream(pBlob + resourceInfo.Index, resourceInfo.Length);

            return(stream);
        }
Beispiel #17
0
        /// <summary>
        /// Initialize module info and construct per-module metadata reader.
        /// </summary>
        /// <param name="moduleHandle">Handle (address) of module to initialize</param>
        internal ModuleInfo(IntPtr moduleHandle, ModuleType moduleType)
        {
            Handle     = moduleHandle;
            ModuleType = moduleType;

            byte *pBlob;
            uint  cbBlob;

            if (RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.EmbeddedMetadata, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
            {
                MetadataReader = new MetadataReader((IntPtr)pBlob, (int)cbBlob);
            }

            DynamicModule *dynamicModulePtr = (DynamicModule *)MemoryHelpers.AllocateMemory(sizeof(DynamicModule));

            dynamicModulePtr->CbSize = DynamicModule.DynamicModuleSize;
            Debug.Assert(sizeof(DynamicModule) >= dynamicModulePtr->CbSize);

#if SUPPORTS_R2R_LOADING
            if (moduleType == ModuleType.ReadyToRun)
            {
                // ReadyToRun modules utilize dynamic type resolution
                dynamicModulePtr->DynamicTypeSlotDispatchResolve = Intrinsics.AddrOf(
                    (Func <IntPtr, IntPtr, ushort, IntPtr>)ReadyToRunCallbacks.ResolveTypeSlotDispatch);
            }
            else
#endif
            {
                Debug.Assert(moduleType == ModuleType.Eager);
                // Pre-generated modules do not
                dynamicModulePtr->DynamicTypeSlotDispatchResolve = IntPtr.Zero;
            }

            dynamicModulePtr->GetRuntimeException = Intrinsics.AddrOf(
                (Func <ExceptionIDs, Exception>)RuntimeExceptionHelpers.GetRuntimeException);

            DynamicModulePtr = dynamicModulePtr;
        }
Beispiel #18
0
        // Lazy loadings of hashtables (load on-demand only)
        private unsafe NativeHashtable LoadHashtable(IntPtr moduleHandle, ReflectionMapBlob hashtableBlobId, out ExternalReferencesTable externalFixupsTable)
        {
            // Load the common fixups table
            externalFixupsTable = default(ExternalReferencesTable);
            if (!externalFixupsTable.InitializeCommonFixupsTable(moduleHandle))
            {
                return(default(NativeHashtable));
            }

            // Load the hashtable
            byte *pBlob;
            uint  cbBlob;

            if (!RuntimeAugments.FindBlob(moduleHandle, (int)hashtableBlobId, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
            {
                return(default(NativeHashtable));
            }

            NativeReader reader = new NativeReader(pBlob, cbBlob);
            NativeParser parser = new NativeParser(reader, 0);

            return(new NativeHashtable(parser));
        }