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));
        }
Example #6
0
        // 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);
        }
Example #14
0
        //
        // 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;
            }
        }
Example #15
0
        /// <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);
        }