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; }
// // 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); }
/// <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); } }
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))); } } }
/// <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); }
// 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; }
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; }
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); }
/// <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; }
// 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)); }