private unsafe bool TryGetStaticRuntimeFieldHandleComponents(RuntimeFieldHandle runtimeFieldHandle, out RuntimeTypeHandle declaringTypeHandle, out string fieldName) { fieldName = null; declaringTypeHandle = default(RuntimeTypeHandle); // Make sure it's not a dynamically allocated RuntimeFieldHandle before we attempt to use it to parse native layout data Debug.Assert(((*(IntPtr *)&runtimeFieldHandle).ToInt64() & 0x1) == 0); RuntimeFieldHandleInfo *fieldData = *(RuntimeFieldHandleInfo **)&runtimeFieldHandle; IntPtr remainingSignature; if (!GetTypeFromSignatureAndContext(fieldData->NativeLayoutInfoSignature, null, null, out declaringTypeHandle, out remainingSignature)) { return(false); } // GetTypeFromSignatureAndContext parses the type from the signature and returns a pointer to the next // part of the native layout signature to read which we get the field name from var reader = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(remainingSignature)); var parser = new NativeParser(reader, reader.AddressToOffset(remainingSignature)); fieldName = parser.GetString(); return(true); }
public static unsafe bool TryGetTargetOfUnboxingAndInstantiatingStub(IntPtr maybeInstantiatingAndUnboxingStub, out IntPtr targetMethod) { targetMethod = IntPtr.Zero; // Get module IntPtr associatedModule = RuntimeAugments.GetModuleFromPointer(maybeInstantiatingAndUnboxingStub); if (associatedModule == IntPtr.Zero) { return false; } // Get UnboxingAndInstantiatingTable UnboxingAndInstantiatingStubMapEntry* pBlob; uint cbBlob; if (!RuntimeAugments.FindBlob(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(associatedModule, pBlob[i].StubMethodRva) == maybeInstantiatingAndUnboxingStub) { // We found a match, create pointer from RVA and move on. targetMethod = RvaToFunctionPointer(associatedModule, pBlob[i].MethodRva); return true; } } // Stub not found. return false; }
private bool MethodSignatureHasVarsNeedingCallingConventionConverter_NativeLayout(TypeSystemContext context, IntPtr methodSig) { IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(methodSig); NativeReader reader = GetNativeLayoutInfoReader(moduleHandle); NativeParser parser = new NativeParser(reader, reader.AddressToOffset(methodSig)); MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned(); uint numGenArgs = callingConvention.HasFlag(MethodCallingConvention.Generic) ? parser.GetUnsigned() : 0; uint parameterCount = parser.GetUnsigned(); // Check the return type of the method if (TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.Parameter)) { return(true); } // Check the parameters of the method for (uint i = 0; i < parameterCount; i++) { if (TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.Parameter)) { return(true); } } return(false); }
/// <summary> /// Look up module containing given nativesignature and return the appropriate native parser. /// </summary> /// <param name="signature">Signature to look up</param> /// <returns>Native parser for the signature</param> internal static NativeParser GetNativeParserForSignature(IntPtr signature) { IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(signature); NativeReader reader = TypeLoaderEnvironment.GetNativeReaderForBlob(moduleHandle, ReflectionMapBlob.NativeLayoutInfo); return(new NativeParser(reader, reader.AddressToOffset(signature))); }
private unsafe bool TryGetStaticRuntimeMethodHandleComponents(RuntimeMethodHandle runtimeMethodHandle, out RuntimeTypeHandle declaringTypeHandle, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgs) { declaringTypeHandle = default(RuntimeTypeHandle); nameAndSignature = null; genericMethodArgs = null; // Make sure it's not a dynamically allocated RuntimeMethodHandle before we attempt to use it to parse native layout data Debug.Assert(((*(IntPtr *)&runtimeMethodHandle).ToInt64() & 0x1) == 0); RuntimeMethodHandleInfo *methodData = *(RuntimeMethodHandleInfo **)&runtimeMethodHandle; #if CORERT // The native layout info signature is a pair. // The first is a pointer that points to the TypeManager indirection cell. // The second is the offset into the native layout info blob in that TypeManager, where the native signature is encoded. IntPtr *nativeLayoutInfoSignatureData = (IntPtr *)methodData->NativeLayoutInfoSignature; RuntimeSignature signature = RuntimeSignature.CreateFromNativeLayoutSignature( *(IntPtr *)nativeLayoutInfoSignatureData[0], (uint)nativeLayoutInfoSignatureData[1].ToInt32()); #else IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(methodData->NativeLayoutInfoSignature); RuntimeSignature signature = RuntimeSignature.CreateFromNativeLayoutSignature( moduleHandle, GetNativeLayoutInfoReader(moduleHandle).AddressToOffset(methodData->NativeLayoutInfoSignature)); #endif RuntimeSignature remainingSignature; return(GetMethodFromSignatureAndContext(signature, null, null, out declaringTypeHandle, out nameAndSignature, out genericMethodArgs, out remainingSignature)); }
// Parse a native layout info blob into a type / method given a signature pointer in the executable image private object TryParseNativeSignature(TypeSystemContext typeSystemContext, ref IntPtr signature, RuntimeTypeHandle[] typeGenericArgumentHandles, RuntimeTypeHandle[] methodGenericArgumentHandles, bool isMethodSignature) { IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(signature); NativeReader reader = GetNativeLayoutInfoReader(moduleHandle); uint offset = reader.AddressToOffset(signature); NativeParser parser = new NativeParser(reader, offset); object retObject = TryParseNativeSignatureWorker(typeSystemContext, moduleHandle, ref parser, typeGenericArgumentHandles, methodGenericArgumentHandles, isMethodSignature); signature = reader.OffsetToAddress(parser.Offset); return retObject; }
public bool CompareMethodSignatures(RuntimeMethodSignature signature1, RuntimeMethodSignature signature2) { IntPtr nativeLayoutSignature1 = signature1.NativeLayoutSignature; IntPtr nativeLayoutSignature2 = signature2.NativeLayoutSignature; if ((nativeLayoutSignature1 != IntPtr.Zero) && (nativeLayoutSignature2 != IntPtr.Zero)) { if (nativeLayoutSignature1 == nativeLayoutSignature2) { return(true); } NativeReader reader1 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature1)); NativeParser parser1 = new NativeParser(reader1, reader1.AddressToOffset(nativeLayoutSignature1)); NativeReader reader2 = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(nativeLayoutSignature2)); NativeParser parser2 = new NativeParser(reader2, reader2.AddressToOffset(nativeLayoutSignature2)); return(CompareMethodSigs(parser1, parser2)); } else if (nativeLayoutSignature1 != IntPtr.Zero) { int token = signature2.Token; MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature2.ModuleHandle); MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader)); return(comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature1)); } else if (nativeLayoutSignature2 != IntPtr.Zero) { int token = signature1.Token; MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature1.ModuleHandle); MethodSignatureComparer comparer = new MethodSignatureComparer(metadataReader, token.AsHandle().ToMethodHandle(metadataReader)); return(comparer.IsMatchingNativeLayoutMethodSignature(nativeLayoutSignature2)); } else { // For now, RuntimeMethodSignatures are only used to compare for method signature equality (along with their Name) // So we can implement this with the simple equals check if (signature1.Token != signature2.Token) { return(false); } if (signature1.ModuleHandle != signature2.ModuleHandle) { return(false); } return(true); } }
public bool TryGetMethodNameAndSignatureFromNativeLayoutSignature(ref IntPtr signature, out MethodNameAndSignature nameAndSignature) { nameAndSignature = null; NativeReader reader = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(signature)); uint offset = reader.AddressToOffset(signature); NativeParser parser = new NativeParser(reader, offset); if (parser.IsNull) { return(false); } IntPtr methodSigPtr; IntPtr methodNameSigPtr; nameAndSignature = GetMethodNameAndSignature(ref parser, out methodNameSigPtr, out methodSigPtr); signature = (IntPtr)((long)signature + (parser.Offset - offset)); return(true); }
public uint GetGenericArgumentCountFromMethodNameAndSignature(MethodNameAndSignature signature) { if (signature.Signature.IsNativeLayoutSignature) { IntPtr sigPtr = signature.Signature.NativeLayoutSignature; NativeReader reader = GetNativeLayoutInfoReader(RuntimeAugments.GetModuleFromPointer(sigPtr)); NativeParser parser = new NativeParser(reader, reader.AddressToOffset(sigPtr)); return(GetGenericArgCountFromSig(parser)); } else { var metadataReader = ModuleList.Instance.GetMetadataReaderForModule(signature.Signature.ModuleHandle); var methodHandle = signature.Signature.Token.AsHandle().ToMethodHandle(metadataReader); var method = methodHandle.GetMethod(metadataReader); var methodSignature = method.Signature.GetMethodSignature(metadataReader); return(checked ((uint)methodSignature.GenericParameterCount)); } }
internal bool IsStaticMethodSignature(RuntimeMethodSignature methodSig) { if (methodSig.IsNativeLayoutSignature) { IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(methodSig.NativeLayoutSignature); NativeReader reader = GetNativeLayoutInfoReader(moduleHandle); NativeParser parser = new NativeParser(reader, reader.AddressToOffset(methodSig.NativeLayoutSignature)); MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned(); return(callingConvention.HasFlag(MethodCallingConvention.Static)); } else { var metadataReader = ModuleList.Instance.GetMetadataReaderForModule(methodSig.ModuleHandle); var methodHandle = methodSig.Token.AsHandle().ToMethodHandle(metadataReader); var method = methodHandle.GetMethod(metadataReader); return((method.Flags & MethodAttributes.Static) != 0); } }
private unsafe bool TryGetStaticRuntimeFieldHandleComponents(RuntimeFieldHandle runtimeFieldHandle, out RuntimeTypeHandle declaringTypeHandle, out string fieldName) { fieldName = null; declaringTypeHandle = default(RuntimeTypeHandle); // Make sure it's not a dynamically allocated RuntimeFieldHandle before we attempt to use it to parse native layout data Debug.Assert(((*(IntPtr *)&runtimeFieldHandle).ToInt64() & 0x1) == 0); RuntimeFieldHandleInfo *fieldData = *(RuntimeFieldHandleInfo **)&runtimeFieldHandle; #if CORERT // The native layout info signature is a pair. // The first is a pointer that points to the TypeManager indirection cell. // The second is the offset into the native layout info blob in that TypeManager, where the native signature is encoded. IntPtr *nativeLayoutInfoSignatureData = (IntPtr *)fieldData->NativeLayoutInfoSignature; RuntimeSignature signature = RuntimeSignature.CreateFromNativeLayoutSignature( *(IntPtr *)nativeLayoutInfoSignatureData[0], (uint)nativeLayoutInfoSignatureData[1].ToInt32()); #else IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(fieldData->NativeLayoutInfoSignature); RuntimeSignature signature = RuntimeSignature.CreateFromNativeLayoutSignature( moduleHandle, GetNativeLayoutInfoReader(moduleHandle).AddressToOffset(fieldData->NativeLayoutInfoSignature)); #endif RuntimeSignature remainingSignature; if (!GetTypeFromSignatureAndContext(signature, null, null, out declaringTypeHandle, out remainingSignature)) { return(false); } // GetTypeFromSignatureAndContext parses the type from the signature and returns a pointer to the next // part of the native layout signature to read which we get the field name from var reader = GetNativeLayoutInfoReader(remainingSignature.ModuleHandle); var parser = new NativeParser(reader, remainingSignature.NativeLayoutOffset); fieldName = parser.GetString(); return(true); }
internal bool GetCallingConverterDataFromMethodSignature_NativeLayout(TypeSystemContext context, IntPtr methodSig, NativeLayoutInfoLoadContext nativeLayoutContext, out bool hasThis, out TypeDesc[] parameters, out bool[] parametersWithGenericDependentLayout) { hasThis = false; parameters = null; IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(methodSig); NativeReader reader = GetNativeLayoutInfoReader(moduleHandle); NativeParser parser = new NativeParser(reader, reader.AddressToOffset(methodSig)); MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned(); hasThis = !callingConvention.HasFlag(MethodCallingConvention.Static); uint numGenArgs = callingConvention.HasFlag(MethodCallingConvention.Generic) ? parser.GetUnsigned() : 0; uint parameterCount = parser.GetUnsigned(); parameters = new TypeDesc[parameterCount + 1]; parametersWithGenericDependentLayout = new bool[parameterCount + 1]; // One extra parameter to account for the return type for (uint i = 0; i <= parameterCount; i++) { // NativeParser is a struct, so it can be copied. NativeParser parserCopy = parser; // Parse the signature twice. The first time to find out the exact type of the signature // The second time to identify if the parameter loaded via the signature should be forced to be // passed byref as part of the universal generic calling convention. parameters[i] = GetConstructedTypeFromParserAndNativeLayoutContext(ref parser, nativeLayoutContext); parametersWithGenericDependentLayout[i] = TypeSignatureHasVarsNeedingCallingConventionConverter(ref parserCopy, context, HasVarsInvestigationLevel.Parameter); if (parameters[i] == null) { return(false); } } return(true); }
private RuntimeTypeHandle GetExternalTypeHandle(ref NativeParser parser, uint typeIndex) { IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(parser.Reader.OffsetToAddress(parser.Offset)); Debug.Assert(moduleHandle != IntPtr.Zero); RuntimeTypeHandle result; TypeSystemContext context = TypeSystemContextFactory.Create(); { NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); nativeLayoutContext._moduleHandle = moduleHandle; nativeLayoutContext._typeSystemContext = context; TypeDesc type = nativeLayoutContext.GetExternalType(typeIndex); result = type.RuntimeTypeHandle; } TypeSystemContextFactory.Recycle(context); Debug.Assert(!result.IsNull()); return(result); }
// // Lazily parse the method signature, and construct the call converter data // private void EnsureCallConversionInfoLoaded() { if (_signatureParsed) { return; } lock (this) { // Check if race was won by another thread and the signature got parsed if (_signatureParsed) { return; } TypeSystemContext context = TypeSystemContextFactory.Create(); { NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); if (_methodSignature.IsNativeLayoutSignature) { nativeLayoutContext._moduleHandle = RuntimeAugments.GetModuleFromPointer(_methodSignature.NativeLayoutSignature); } else { nativeLayoutContext._moduleHandle = _methodSignature.ModuleHandle; } nativeLayoutContext._typeSystemContext = context; nativeLayoutContext._typeArgumentHandles = Instantiation.Empty; nativeLayoutContext._methodArgumentHandles = Instantiation.Empty; if (_typeArgs != null && _typeArgs.Length > 0) { nativeLayoutContext._typeArgumentHandles = context.ResolveRuntimeTypeHandles(_typeArgs); } if (_methodArgs != null && _methodArgs.Length > 0) { nativeLayoutContext._methodArgumentHandles = context.ResolveRuntimeTypeHandles(_methodArgs); } bool hasThis; TypeDesc[] parameters; bool[] paramsByRefForced; if (!TypeLoaderEnvironment.Instance.GetCallingConverterDataFromMethodSignature(context, _methodSignature, nativeLayoutContext, out hasThis, out parameters, out paramsByRefForced)) { Debug.Assert(false); Environment.FailFast("Failed to get type handles for parameters in method signature"); } Debug.Assert(parameters != null && parameters.Length >= 1); bool[] byRefParameters = new bool[parameters.Length]; RuntimeTypeHandle[] parameterHandles = new RuntimeTypeHandle[parameters.Length]; for (int j = 0; j < parameters.Length; j++) { ByRefType parameterAsByRefType = parameters[j] as ByRefType; if (parameterAsByRefType != null) { parameterAsByRefType.ParameterType.RetrieveRuntimeTypeHandleIfPossible(); parameterHandles[j] = parameterAsByRefType.ParameterType.RuntimeTypeHandle; byRefParameters[j] = true; } else { parameters[j].RetrieveRuntimeTypeHandleIfPossible(); parameterHandles[j] = parameters[j].RuntimeTypeHandle; byRefParameters[j] = false; } Debug.Assert(!parameterHandles[j].IsNull()); } // Build thunk data TypeHandle thReturnType = new TypeHandle(CallConverterThunk.GetByRefIndicatorAtIndex(0, byRefParameters), parameterHandles[0]); TypeHandle[] thParameters = null; if (parameters.Length > 1) { thParameters = new TypeHandle[parameters.Length - 1]; for (int i = 1; i < parameters.Length; i++) { thParameters[i - 1] = new TypeHandle(CallConverterThunk.GetByRefIndicatorAtIndex(i, byRefParameters), parameterHandles[i]); } } _argIteratorData = new ArgIteratorData(hasThis, false, thParameters, thReturnType); // StandardToStandard thunks don't actually need any parameters to change their ABI // so don't force any params to be adjusted if (!StandardToStandardThunk) { _paramsByRefForced = paramsByRefForced; } } TypeSystemContextFactory.Recycle(context); _signatureParsed = true; } }
/// <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); }