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( new TypeManagerHandle(*(IntPtr *)nativeLayoutInfoSignatureData[0]), (uint)nativeLayoutInfoSignatureData[1].ToInt32()); #else IntPtr moduleHandle = RuntimeAugments.GetOSModuleFromPointer(methodData->NativeLayoutInfoSignature); RuntimeSignature signature = RuntimeSignature.CreateFromNativeLayoutSignature( new TypeManagerHandle(moduleHandle), GetNativeLayoutInfoReader(new TypeManagerHandle(moduleHandle)).AddressToOffset(methodData->NativeLayoutInfoSignature)); #endif RuntimeSignature remainingSignature; return(GetMethodFromSignatureAndContext(signature, null, null, out declaringTypeHandle, out nameAndSignature, out genericMethodArgs, out remainingSignature)); }
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; }
/// <summary> /// Locate the containing module for a method and try to resolve its name based on start address. /// </summary> public static string GetMethodNameFromStartAddressIfAvailable(IntPtr methodStartAddress) { IntPtr moduleStartAddress = RuntimeAugments.GetOSModuleFromPointer(methodStartAddress); int rva = (int)((nuint)methodStartAddress - (nuint)moduleStartAddress); foreach (TypeManagerHandle handle in ModuleList.Enumerate()) { if (handle.OsModuleBase == moduleStartAddress) { string name = _perModuleMethodNameResolverHashtable.GetOrCreateValue(handle.GetIntPtrUNSAFE()).GetMethodNameFromRvaIfAvailable(rva); if (name != null) { return(name); } } } // We haven't found information in the stack trace metadata tables, but maybe reflection will have this if (ReflectionExecution.TryGetMethodMetadataFromStartAddress(methodStartAddress, out MetadataReader reader, out TypeDefinitionHandle typeHandle, out MethodHandle methodHandle)) { return(MethodNameFormatter.FormatMethodName(reader, typeHandle, methodHandle)); } return(null); }
/// <summary> /// Locate the containing module for a method and try to resolve its name based on start address. /// </summary> public static string GetMethodNameFromStartAddressIfAvailable(IntPtr methodStartAddress) { IntPtr moduleStartAddress = RuntimeAugments.GetOSModuleFromPointer(methodStartAddress); int rva = (int)(methodStartAddress.ToInt64() - moduleStartAddress.ToInt64()); return(_perModuleMethodNameResolverHashtable .GetOrCreateValue(moduleStartAddress) .GetMethodNameFromRvaIfAvailable(rva)); }
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 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; RuntimeSignature signature; #if !CORERT // If the system module is compiled with as a type manager, all modules are compiled as such if (ModuleList.Instance.SystemModule.Handle.IsTypeManager) #endif { // 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; signature = RuntimeSignature.CreateFromNativeLayoutSignature( new TypeManagerHandle(*(IntPtr *)nativeLayoutInfoSignatureData[0]), (uint)nativeLayoutInfoSignatureData[1].ToInt32()); } #if !CORERT else { IntPtr moduleHandle = RuntimeAugments.GetOSModuleFromPointer(fieldData->NativeLayoutInfoSignature); signature = RuntimeSignature.CreateFromNativeLayoutSignature( new TypeManagerHandle(moduleHandle), GetNativeLayoutInfoReader(new TypeManagerHandle(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); var parser = new NativeParser(reader, remainingSignature.NativeLayoutOffset); fieldName = parser.GetString(); return(true); }
/// <summary> /// Locate the containing module for a method and try to resolve its name based on start address. /// </summary> public static string GetMethodNameFromStartAddressIfAvailable(IntPtr methodStartAddress) { IntPtr moduleStartAddress = RuntimeAugments.GetOSModuleFromPointer(methodStartAddress); int rva = (int)(methodStartAddress.ToInt64() - moduleStartAddress.ToInt64()); foreach (TypeManagerHandle handle in ModuleList.Enumerate()) { if (handle.OsModuleBase == moduleStartAddress) { string name = _perModuleMethodNameResolverHashtable.GetOrCreateValue(handle.GetIntPtrUNSAFE()).GetMethodNameFromRvaIfAvailable(rva); if (name != null) { return(name); } } } return(null); }
/// <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.GetOSModuleFromPointer(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.GetLoadedOSModules(null); s_loadedModules = new IntPtr[moduleCount]; s_perModuleDebugInfo = new IDiaSession[moduleCount]; // Actually read the module addresses into the array RuntimeAugments.GetLoadedOSModules(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); }
/// <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.GetOSModuleFromPointer(ip); if (moduleBase == IntPtr.Zero) { rva = -1; return(null); } rva = (int)(ip.ToInt64() - moduleBase.ToInt64()); if (s_loadedModules == null) { // Lazily create the map from module bases to debug info s_loadedModules = new Dictionary <IntPtr, IDiaSession>(); } // Locate module index based on base address IDiaSession diaSession; if (s_loadedModules.TryGetValue(moduleBase, out diaSession)) { 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_loadedModules.Add(moduleBase, diaSession); return(diaSession); }