コード例 #1
0
        private void ParseAvailableTypes()
        {
            R2RSection      availableTypesSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES];
            int             availableTypesOffset  = GetOffset(availableTypesSection.RelativeVirtualAddress);
            NativeParser    parser         = new NativeParser(Image, (uint)availableTypesOffset);
            NativeHashtable availableTypes = new NativeHashtable(Image, parser);

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = availableTypes.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                uint rid = curParser.GetUnsigned();
                rid = rid >> 1;
                TypeDefinitionHandle typeDefHandle = MetadataTokens.TypeDefinitionHandle((int)rid);

                TypeDefinition typeDef = _mdReader.GetTypeDefinition(typeDefHandle);
                string         name    = _mdReader.GetString(typeDef.Name);
                if (!typeDef.Namespace.IsNil)
                {
                    name = _mdReader.GetString(typeDef.Namespace) + "." + name;
                }
                AvailableTypes.Add(name);
                curParser = allEntriesEnum.GetNext();
            }
        }
コード例 #2
0
        /// <summary>
        /// Iterates through a native hashtable to get all RIDs
        /// </summary>
        private void ParseAvailableTypes()
        {
            if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES))
            {
                return;
            }

            HashSet <uint> added = new HashSet <uint>();

            R2RSection      availableTypesSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES];
            int             availableTypesOffset  = GetOffset(availableTypesSection.RelativeVirtualAddress);
            NativeParser    parser         = new NativeParser(Image, (uint)availableTypesOffset);
            NativeHashtable availableTypes = new NativeHashtable(Image, parser, (uint)(availableTypesOffset + availableTypesSection.Size));

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = availableTypes.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                uint rid = curParser.GetUnsigned();
                rid = rid >> 1;
                if (added.Contains(rid))
                {
                    continue;
                }

                TypeDefinitionHandle typeDefHandle    = MetadataTokens.TypeDefinitionHandle((int)rid);
                string             typeDefName        = MetadataNameFormatter.FormatHandle(MetadataReader, typeDefHandle);
                ExportedTypeHandle exportedTypeHandle = MetadataTokens.ExportedTypeHandle((int)rid);
                string             exportedTypeName   = GetExportedTypeFullName(MetadataReader, exportedTypeHandle);
                if (typeDefName == null && exportedTypeName == null)
                {
                    R2RDump.WriteWarning($"AvailableType with rid {rid} is not a TypeDef or ExportedType");
                }
                if (typeDefName != null)
                {
                    AvailableTypes.Add(typeDefName);
                    added.Add(rid);
                }
                if (exportedTypeName != null)
                {
                    AvailableTypes.Add("exported " + exportedTypeName);
                    added.Add(rid);
                }

                curParser = allEntriesEnum.GetNext();
            }
        }
コード例 #3
0
        /// <summary>
        /// Initialize generic method instances with argument types and runtime function indices from InstanceMethodEntrypoints
        /// </summary>
        private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint)
        {
            if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS))
            {
                return;
            }
            R2RSection      instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS];
            int             instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress);
            NativeParser    parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset);
            NativeHashtable instMethodEntryPoints = new NativeHashtable(Image, parser, (uint)(instMethodEntryPointsOffset + instMethodEntryPointSection.Size));

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                uint methodFlags = curParser.GetCompressedData();
                uint rid         = curParser.GetCompressedData();
                if ((methodFlags & (byte)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0)
                {
                    uint             nArgs  = curParser.GetCompressedData();
                    CorElementType[] args   = new CorElementType[nArgs];
                    uint[]           tokens = new uint[nArgs];
                    for (int i = 0; i < nArgs; i++)
                    {
                        args[i] = (CorElementType)curParser.GetByte();
                        if (args[i] == CorElementType.ELEMENT_TYPE_VALUETYPE)
                        {
                            tokens[i] = curParser.GetCompressedData();
                            tokens[i] = (tokens[i] >> 2);
                        }
                    }

                    int         runtimeFunctionId;
                    FixupCell[] fixups;
                    GetRuntimeFunctionIndexFromOffset((int)curParser.Offset, out runtimeFunctionId, out fixups);
                    R2RMethod method = new R2RMethod(R2RMethods.Count, MetadataReader, rid, runtimeFunctionId, args, tokens, fixups);
                    if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < isEntryPoint.Length)
                    {
                        isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                    }
                    R2RMethods.Add(method);
                }
                curParser = allEntriesEnum.GetNext();
            }
        }
コード例 #4
0
ファイル: R2RReader.cs プロジェクト: hsharber/coreclr
        /// <summary>
        /// Initialize generic method instances with argument types and runtime function indices from InstanceMethodEntrypoints
        /// </summary>
        private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint)
        {
            if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS))
            {
                return;
            }
            R2RSection      instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS];
            int             instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress);
            NativeParser    parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset);
            NativeHashtable instMethodEntryPoints = new NativeHashtable(Image, parser, (uint)(instMethodEntryPointsOffset + instMethodEntryPointSection.Size));

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                uint methodFlags = curParser.GetCompressedData();
                uint rid         = curParser.GetCompressedData();
                if ((methodFlags & (byte)R2RMethod.EncodeMethodSigFlags.ENCODE_METHOD_SIG_MethodInstantiation) != 0)
                {
                    uint nArgs = curParser.GetCompressedData();
                    R2RMethod.GenericElementTypes[] args = new R2RMethod.GenericElementTypes[nArgs];
                    uint[] tokens = new uint[nArgs];
                    for (int i = 0; i < nArgs; i++)
                    {
                        args[i] = (R2RMethod.GenericElementTypes)curParser.GetByte();
                        if (args[i] == R2RMethod.GenericElementTypes.ValueType)
                        {
                            tokens[i] = curParser.GetCompressedData();
                            tokens[i] = (tokens[i] >> 2);
                        }
                    }

                    int       id     = GetEntryPointIdFromOffset((int)curParser.Offset);
                    R2RMethod method = new R2RMethod(_mdReader, rid, id, args, tokens);
                    if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < isEntryPoint.Length)
                    {
                        isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                    }
                    R2RMethods.Add(method);
                }
                curParser = allEntriesEnum.GetNext();
            }
        }
コード例 #5
0
ファイル: R2RReader.cs プロジェクト: mazhongbin/coreclr
        private void ParseAvailableTypes()
        {
            R2RSection      availableTypesSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES];
            int             availableTypesOffset  = GetOffset(availableTypesSection.RelativeVirtualAddress);
            NativeParser    parser         = new NativeParser(Image, (uint)availableTypesOffset);
            NativeHashtable availableTypes = new NativeHashtable(Image, parser, (uint)(availableTypesOffset + availableTypesSection.Size));

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = availableTypes.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                uint rid = curParser.GetUnsigned();
                rid = rid >> 1;
                TypeDefinitionHandle typeDefHandle = MetadataTokens.TypeDefinitionHandle((int)rid);
                AvailableTypes.Add(GetTypeDefFullName(_mdReader, typeDefHandle));
                curParser = allEntriesEnum.GetNext();
            }
        }
コード例 #6
0
        /// <summary>
        /// Iterates through a native hashtable to get all RIDs
        /// </summary>
        private void ParseAvailableTypes()
        {
            if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES))
            {
                return;
            }

            R2RSection      availableTypesSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES];
            int             availableTypesOffset  = GetOffset(availableTypesSection.RelativeVirtualAddress);
            NativeParser    parser         = new NativeParser(Image, (uint)availableTypesOffset);
            NativeHashtable availableTypes = new NativeHashtable(Image, parser, (uint)(availableTypesOffset + availableTypesSection.Size));

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = availableTypes.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                uint rid = curParser.GetUnsigned();

                bool isExportedType = (rid & 1) != 0;
                rid = rid >> 1;

                if (isExportedType)
                {
                    ExportedTypeHandle exportedTypeHandle = MetadataTokens.ExportedTypeHandle((int)rid);
                    string             exportedTypeName   = GetExportedTypeFullName(MetadataReader, exportedTypeHandle);
                    AvailableTypes.Add("exported " + exportedTypeName);
                }
                else
                {
                    TypeDefinitionHandle typeDefHandle = MetadataTokens.TypeDefinitionHandle((int)rid);
                    string typeDefName = MetadataNameFormatter.FormatHandle(MetadataReader, typeDefHandle);
                    AvailableTypes.Add(typeDefName);
                }

                curParser = allEntriesEnum.GetNext();
            }
        }
コード例 #7
0
ファイル: R2RReader.cs プロジェクト: v-zhpa/coreclr
        /// <summary>
        /// Initializes the fields of the R2RHeader
        /// </summary>
        /// <param name="filename">PE image</param>
        /// <exception cref="BadImageFormatException">The Cor header flag must be ILLibrary</exception>
        public unsafe R2RReader(string filename)
        {
            Filename = filename;
            _image   = File.ReadAllBytes(filename);

            fixed(byte *p = _image)
            {
                IntPtr ptr = (IntPtr)p;

                peReader = new PEReader(p, _image.Length);

                IsR2R = (peReader.PEHeaders.CorHeader.Flags == CorFlags.ILLibrary);
                if (!IsR2R)
                {
                    throw new BadImageFormatException("The file is not a ReadyToRun image");
                }

                Machine   = peReader.PEHeaders.CoffHeader.Machine;
                ImageBase = peReader.PEHeaders.PEHeader.ImageBase;

                // initialize R2RHeader
                DirectoryEntry r2rHeaderDirectory = peReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory;
                int            r2rHeaderOffset    = GetOffset(r2rHeaderDirectory.RelativeVirtualAddress);

                R2RHeader = new R2RHeader(_image, r2rHeaderDirectory.RelativeVirtualAddress, r2rHeaderOffset);
                if (r2rHeaderDirectory.Size != R2RHeader.Size)
                {
                    throw new BadImageFormatException("The calculated size of the R2RHeader doesn't match the size saved in the ManagedNativeHeaderDirectory");
                }

                // initialize R2RMethods
                if (peReader.HasMetadata)
                {
                    MetadataReader mdReader = peReader.GetMetadataReader();

                    int runtimeFunctionSize = 2;
                    if (Machine == Machine.Amd64)
                    {
                        runtimeFunctionSize = 3;
                    }
                    runtimeFunctionSize *= sizeof(int);
                    R2RSection runtimeFunctionSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS];
                    uint       nRuntimeFunctions      = (uint)(runtimeFunctionSection.Size / runtimeFunctionSize);
                    int        runtimeFunctionOffset  = GetOffset(runtimeFunctionSection.RelativeVirtualAddress);
                    bool[]     isEntryPoint           = new bool[nRuntimeFunctions];
                    for (int i = 0; i < nRuntimeFunctions; i++)
                    {
                        isEntryPoint[i] = false;
                    }

                    // initialize R2RMethods with method signatures from MethodDefHandle, and runtime function indices from MethodDefEntryPoints
                    int         methodDefEntryPointsRVA    = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS].RelativeVirtualAddress;
                    int         methodDefEntryPointsOffset = GetOffset(methodDefEntryPointsRVA);
                    NativeArray methodEntryPoints          = new NativeArray(_image, (uint)methodDefEntryPointsOffset);
                    uint        nMethodEntryPoints         = methodEntryPoints.GetCount();
                    R2RMethods = new List <R2RMethod>();
                    for (uint rid = 1; rid <= nMethodEntryPoints; rid++)
                    {
                        int offset = 0;
                        if (methodEntryPoints.TryGetAt(_image, rid - 1, ref offset))
                        {
                            R2RMethod method = new R2RMethod(_image, mdReader, rid, GetEntryPointIdFromOffset(offset), null, null);

                            if (method.EntryPointRuntimeFunctionId < 0 || method.EntryPointRuntimeFunctionId >= nRuntimeFunctions)
                            {
                                throw new BadImageFormatException("EntryPointRuntimeFunctionId out of bounds");
                            }
                            isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                            R2RMethods.Add(method);
                        }
                    }

                    // instance method table
                    R2RSection      instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS];
                    int             instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress);
                    NativeParser    parser = new NativeParser(_image, (uint)instMethodEntryPointsOffset);
                    NativeHashtable instMethodEntryPoints = new NativeHashtable(_image, parser);
                    NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries();
                    NativeParser curParser = allEntriesEnum.GetNext();
                    while (!curParser.IsNull())
                    {
                        byte methodFlags = curParser.GetByte();
                        byte rid         = curParser.GetByte();
                        if ((methodFlags & (byte)R2RMethod.EncodeMethodSigFlags.ENCODE_METHOD_SIG_MethodInstantiation) != 0)
                        {
                            byte nArgs = curParser.GetByte();
                            R2RMethod.GenericElementTypes[] args = new R2RMethod.GenericElementTypes[nArgs];
                            uint[] tokens = new uint[nArgs];
                            for (int i = 0; i < nArgs; i++)
                            {
                                args[i] = (R2RMethod.GenericElementTypes)curParser.GetByte();
                                if (args[i] == R2RMethod.GenericElementTypes.ValueType)
                                {
                                    tokens[i] = curParser.GetByte();
                                    tokens[i] = (tokens[i] >> 2);
                                }
                            }

                            uint id = curParser.GetUnsigned();
                            id = id >> 1;
                            R2RMethod method = new R2RMethod(_image, mdReader, rid, (int)id, args, tokens);
                            if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < nRuntimeFunctions)
                            {
                                isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                            }
                            R2RMethods.Add(method);
                        }
                        curParser = allEntriesEnum.GetNext();
                    }

                    // get the RVAs of the runtime functions for each method
                    int curOffset = 0;
                    foreach (R2RMethod method in R2RMethods)
                    {
                        int runtimeFunctionId = method.EntryPointRuntimeFunctionId;
                        if (runtimeFunctionId == -1)
                        {
                            continue;
                        }
                        curOffset = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize;
                        do
                        {
                            int startRva = NativeReader.ReadInt32(_image, ref curOffset);
                            int endRva   = -1;
                            if (Machine == Machine.Amd64)
                            {
                                endRva = NativeReader.ReadInt32(_image, ref curOffset);
                            }
                            int unwindRva = NativeReader.ReadInt32(_image, ref curOffset);

                            method.RuntimeFunctions.Add(new RuntimeFunction(runtimeFunctionId, startRva, endRva, unwindRva));
                            runtimeFunctionId++;
                        }while (runtimeFunctionId < nRuntimeFunctions && !isEntryPoint[runtimeFunctionId]);
                    }
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Initialize generic method instances with argument types and runtime function indices from InstanceMethodEntrypoints
        /// </summary>
        private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint)
        {
            if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS))
            {
                return;
            }
            R2RSection      instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS];
            int             instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress);
            NativeParser    parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset);
            NativeHashtable instMethodEntryPoints = new NativeHashtable(Image, parser, (uint)(instMethodEntryPointsOffset + instMethodEntryPointSection.Size));

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                SignatureDecoder decoder = new SignatureDecoder(this, (int)curParser.Offset);

                string owningType = null;

                uint methodFlags = decoder.ReadUInt();
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
                {
                    owningType = decoder.ReadTypeSignature();
                }
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_SlotInsteadOfToken) != 0)
                {
                    throw new NotImplementedException();
                }
                EntityHandle methodHandle;
                int          rid = (int)decoder.ReadUInt();
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken) != 0)
                {
                    methodHandle = MetadataTokens.MemberReferenceHandle(rid);
                }
                else
                {
                    methodHandle = MetadataTokens.MethodDefinitionHandle(rid);
                }
                string[] methodTypeArgs = null;
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0)
                {
                    uint typeArgCount = decoder.ReadUInt();
                    methodTypeArgs = new string[typeArgCount];
                    for (int typeArgIndex = 0; typeArgIndex < typeArgCount; typeArgIndex++)
                    {
                        methodTypeArgs[typeArgIndex] = decoder.ReadTypeSignature();
                    }
                }

                string constrainedType = null;
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained) != 0)
                {
                    constrainedType = decoder.ReadTypeSignature();
                }

                int         runtimeFunctionId;
                FixupCell[] fixups;
                GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixups);
                R2RMethod method = new R2RMethod(R2RMethods.Count, this, methodHandle, runtimeFunctionId, owningType, constrainedType, methodTypeArgs, fixups);
                if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < isEntryPoint.Length)
                {
                    isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                }
                R2RMethods.Add(method);
                InstanceMethods.Add(new InstanceMethod(curParser.LowHashcode, method));
                curParser = allEntriesEnum.GetNext();
            }
        }