예제 #1
0
        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));
        }
예제 #2
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;
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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));
        }
예제 #5
0
        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;
        }
예제 #6
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;
            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);
        }
예제 #7
0
        /// <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);
        }