private bool FindMatchingInterfaceSlot(IntPtr moduleHandle, NativeReader nativeLayoutReader, ref NativeParser entryParser, ref ExternalReferencesTable extRefs, ref RuntimeTypeHandle declaringType, ref MethodNameAndSignature methodNameAndSignature, RuntimeTypeHandle openTargetTypeHandle, RuntimeTypeHandle[] targetTypeInstantiation, bool variantDispatch) { uint numTargetImplementations = entryParser.GetUnsigned(); for (uint j = 0; j < numTargetImplementations; j++) { uint nameAndSigToken = extRefs.GetRvaFromIndex(entryParser.GetUnsigned()); MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, nameAndSigToken); RuntimeTypeHandle targetTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); #if REFLECTION_EXECUTION_TRACE ReflectionExecutionLogger.WriteLine(" Searching for GVM implementation on targe type = " + GetTypeNameDebug(targetTypeHandle)); #endif uint numIfaceImpls = entryParser.GetUnsigned(); for (uint k = 0; k < numIfaceImpls; k++) { RuntimeTypeHandle implementingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); uint numIfaceSigs = entryParser.GetUnsigned(); if (!openTargetTypeHandle.Equals(implementingTypeHandle)) { // Skip over signatures data for (uint l = 0; l < numIfaceSigs; l++) entryParser.GetUnsigned(); continue; } for (uint l = 0; l < numIfaceSigs; l++) { RuntimeTypeHandle currentIfaceTypeHandle = default(RuntimeTypeHandle); NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, extRefs.GetRvaFromIndex(entryParser.GetUnsigned())); IntPtr currentIfaceSigPtr = ifaceSigParser.Reader.OffsetToAddress(ifaceSigParser.Offset); if (TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(currentIfaceSigPtr, targetTypeInstantiation, null, out currentIfaceTypeHandle, out currentIfaceSigPtr)) { Debug.Assert(!currentIfaceTypeHandle.IsNull()); if ((!variantDispatch && declaringType.Equals(currentIfaceTypeHandle)) || (variantDispatch && RuntimeAugments.IsAssignableFrom(declaringType, currentIfaceTypeHandle))) { #if REFLECTION_EXECUTION_TRACE ReflectionExecutionLogger.WriteLine(" " + (declaringType.Equals(currentIfaceTypeHandle) ? "Exact" : "Variant-compatible") + " match found on this target type!"); #endif // We found the GVM slot target for the input interface GVM call, so let's update the interface GVM slot and return success to the caller declaringType = targetTypeHandle; methodNameAndSignature = targetMethodNameAndSignature; return true; } } } } } return false; }
private MethodNameAndSignature GetMethodNameAndSignatureFromNativeReader(NativeReader nativeLayoutReader, 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(); IntPtr methodSigPtr = sigParser.Reader.OffsetToAddress(sigParser.Offset); return new MethodNameAndSignature(methodName, RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr)); }
public void Decode(NativeReader reader) { if (reader.ReadUInt32(0) != Signature) reader.ThrowBadImageFormatException(); reader.Read(4, out ScopeDefinitions); }
// Creates a metadata reader on a memory-mapped file block public unsafe MetadataReader(IntPtr pBuffer, int cbBuffer) { _streamReader = new NativeReader((byte*)pBuffer, (uint)cbBuffer); _header = new MetadataHeader(); _header.Decode(_streamReader); }
public NativeHashtable(NativeParser parser) { uint header = parser.GetUInt8(); _reader = parser.Reader; _baseOffset = parser.Offset; int numberOfBucketsShift = (int)(header >> 2); if (numberOfBucketsShift > 31) _reader.ThrowBadImageFormatException(); _bucketMask = (uint)((1 << numberOfBucketsShift) - 1); byte entryIndexSize = (byte)(header & 3); if (entryIndexSize > 2) _reader.ThrowBadImageFormatException(); _entryIndexSize = entryIndexSize; }
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; }
public NativeParser(NativeReader reader, uint offset) { _reader = reader; _offset = offset; }
// 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; }
// 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; }
public NativeParser(NativeReader reader, uint offset) { _reader = reader; _offset = offset; }
// 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); }