コード例 #1
0
        /// <summary>
        /// Finds all R2RMethods by name/signature/id matching <param>query</param>
        /// </summary>
        /// <param name="r2r">Contains all extracted info about the ReadyToRun image</param>
        /// <param name="query">The name/signature/id to search for</param>
        /// <param name="exact">Specifies exact or partial match</param>
        /// <out name="res">List of all matching methods</out>
        /// <remarks>Case-insensitive and ignores whitespace</remarks>
        public IList <ReadyToRunMethod> FindMethod(ReadyToRunReader r2r, string query, bool exact)
        {
            List <ReadyToRunMethod> res = new List <ReadyToRunMethod>();

            foreach (ReadyToRunMethod method in r2r.Methods.Values.SelectMany(sectionMethods => sectionMethods))
            {
                if (Match(method, query, exact))
                {
                    res.Add(method);
                }
            }
            return(res);
        }
コード例 #2
0
        /// <summary>
        /// Finds all R2RSections by name or value of the ReadyToRunSectionType matching <param>query</param>
        /// </summary>
        /// <param name="r2r">Contains all extracted info about the ReadyToRun image</param>
        /// <param name="query">The name or value to search for</param>
        /// <out name="res">List of all matching sections</out>
        /// <remarks>Case-insensitive</remarks>
        public IList <ReadyToRunSection> FindSection(ReadyToRunReader r2r, string query)
        {
            List <ReadyToRunSection> res = new List <ReadyToRunSection>();

            foreach (ReadyToRunSection section in r2r.ReadyToRunHeader.Sections.Values)
            {
                if (Match(section, query))
                {
                    res.Add(section);
                }
            }
            return(res);
        }
コード例 #3
0
ファイル: R2RDump.cs プロジェクト: lvyitian/runtime
        IEnumerable <MethodInfo> ProducePdbWriterMethods(ReadyToRunReader r2r)
        {
            foreach (var method in _dumper.NormalizedMethods())
            {
                MethodInfo mi = new MethodInfo();
                mi.Name         = method.SignatureString;
                mi.HotRVA       = (uint)method.RuntimeFunctions[0].StartAddress;
                mi.MethodToken  = (uint)MetadataTokens.GetToken(method.MetadataReader, method.MethodHandle);
                mi.AssemblyName = method.MetadataReader.GetString(method.MetadataReader.GetAssemblyDefinition().Name);
                mi.ColdRVA      = 0;

                yield return(mi);
            }
        }
コード例 #4
0
ファイル: R2RDump.cs プロジェクト: lvyitian/runtime
 /// <summary>
 /// Returns the runtime function with id matching <param>rtfQuery</param>
 /// </summary>
 /// <param name="r2r">Contains all extracted info about the ReadyToRun image</param>
 /// <param name="rtfQuery">The name or value to search for</param>
 public RuntimeFunction FindRuntimeFunction(ReadyToRunReader r2r, int rtfQuery)
 {
     foreach (ReadyToRunMethod m in r2r.Methods.Values.SelectMany(sectionMethods => sectionMethods))
     {
         foreach (RuntimeFunction rtf in m.RuntimeFunctions)
         {
             if (rtf.Id == rtfQuery || (rtf.StartAddress >= rtfQuery && rtf.StartAddress + rtf.Size < rtfQuery))
             {
                 return(rtf);
             }
         }
     }
     return(null);
 }
コード例 #5
0
ファイル: R2RDump.cs プロジェクト: snickler/runtime
 /// <summary>
 /// Returns the runtime function with id matching <param>rtfQuery</param>
 /// </summary>
 /// <param name="r2r">Contains all extracted info about the ReadyToRun image</param>
 /// <param name="rtfQuery">The name or value to search for</param>
 public RuntimeFunction FindRuntimeFunction(ReadyToRunReader r2r, int rtfQuery)
 {
     foreach (ReadyToRunMethod m in r2r.Methods)
     {
         foreach (RuntimeFunction rtf in m.RuntimeFunctions)
         {
             if (rtf.Id == rtfQuery || (rtf.StartAddress >= rtfQuery && rtf.StartAddress + rtf.Size < rtfQuery))
             {
                 return rtf;
             }
         }
     }
     return null;
 }
コード例 #6
0
ファイル: R2RDump.cs プロジェクト: vitek-karas/runtime
 IEnumerable <AssemblyInfo> ProduceDebugInfoAssemblies(ReadyToRunReader r2r)
 {
     if (r2r.Composite)
     {
         foreach (KeyValuePair <string, int> kvpRefAssembly in r2r.ManifestReferenceAssemblies.OrderBy(kvp => kvp.Key, StringComparer.OrdinalIgnoreCase))
         {
             yield return(new AssemblyInfo(kvpRefAssembly.Key, r2r.GetAssemblyMvid(kvpRefAssembly.Value)));
         }
     }
     else
     {
         yield return(new AssemblyInfo(r2r.GetGlobalAssemblyName(), r2r.GetAssemblyMvid(0)));
     }
 }
コード例 #7
0
ファイル: ReadyToRunLanguage.cs プロジェクト: xyyhqq/ILSpy
        public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
        {
            PEFile module = method.ParentModule.PEFile;
            ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);

            if (cacheEntry.readyToRunReader == null)
            {
                WriteCommentLine(output, cacheEntry.failureReason);
            }
            else
            {
                ReadyToRunReader reader = cacheEntry.readyToRunReader;
                int bitness             = -1;
                if (reader.Machine == Machine.Amd64)
                {
                    bitness = 64;
                }
                else
                {
                    Debug.Assert(reader.Machine == Machine.I386);
                    bitness = 32;
                }
                if (cacheEntry.methodMap == null)
                {
                    cacheEntry.methodMap = reader.Methods.ToList()
                                           .GroupBy(m => m.MethodHandle)
                                           .ToDictionary(g => g.Key, g => g.ToArray());
                }
                bool showMetadataTokens         = ILSpy.Options.DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens;
                bool showMetadataTokensInBase10 = ILSpy.Options.DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokensInBase10;
#if STRESS
                output = new DummyOutput();
                {
                    foreach (var readyToRunMethod in reader.Methods)
                    {
#else
                if (cacheEntry.methodMap.TryGetValue(method.MetadataToken, out var methods))
                {
                    foreach (var readyToRunMethod in methods)
                    {
#endif
                        foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions)
                        {
                            new ReadyToRunDisassembler(output, reader, runtimeFunction).Disassemble(method.ParentModule.PEFile, bitness, (ulong)runtimeFunction.StartAddress, showMetadataTokens, showMetadataTokensInBase10);
                        }
                    }
                }
            }
        }
コード例 #8
0
ファイル: R2RDiff.cs プロジェクト: yhl533556/runtime
        private bool TryGetMethods(ReadyToRunReader reader, ReadyToRunSection section, out IReadOnlyList <ReadyToRunMethod> methods)
        {
            int assemblyIndex = reader.GetAssemblyIndex(section);

            if (assemblyIndex == -1)
            {
                methods = null;
                return(false);
            }
            else
            {
                methods = reader.ReadyToRunAssemblies[assemblyIndex].Methods;
                return(true);
            }
        }
コード例 #9
0
ファイル: R2RDiff.cs プロジェクト: yhl533556/runtime
        /// <summary>
        /// Read the R2R method map for a given R2R image.
        /// </summary>
        /// <param name="reader">R2R image to scan</param>
        /// <returns></returns>
        private Dictionary <string, int> GetR2RMethodMap(ReadyToRunReader reader, ReadyToRunSection section)
        {
            Dictionary <string, int> methodMap = new Dictionary <string, int>();

            if (TryGetMethods(reader, section, out IReadOnlyList <ReadyToRunMethod> sectionMethods))
            {
                foreach (ReadyToRunMethod method in sectionMethods)
                {
                    int size = method.RuntimeFunctions.Sum(rf => rf.Size);
                    methodMap.Add(method.SignatureString, size);
                }
            }

            return(methodMap);
        }
コード例 #10
0
ファイル: R2RDump.cs プロジェクト: lvyitian/runtime
 // <summary>
 /// For each query in the list of queries, dump all sections by the name or value of the ReadyToRunSectionType enum
 /// </summary>
 /// <param name="r2r">Contains all the extracted info about the ReadyToRun image</param>
 /// <param name="queries">The names/values to search for</param>
 private void QuerySection(ReadyToRunReader r2r, IReadOnlyList <string> queries)
 {
     if (queries.Count > 0)
     {
         _dumper.WriteDivider("R2R Section");
     }
     foreach (string q in queries)
     {
         IList <ReadyToRunSection> res = FindSection(r2r, q);
         _dumper.DumpQueryCount(q, "Sections", res.Count);
         foreach (ReadyToRunSection section in res)
         {
             _dumper.DumpSection(section);
         }
     }
 }
コード例 #11
0
ファイル: R2RDump.cs プロジェクト: lvyitian/runtime
 // <summary>
 /// For each query in the list of queries, dump all methods matching the query by name, signature or id
 /// </summary>
 /// <param name="r2r">Contains all the extracted info about the ReadyToRun image</param>
 /// <param name="title">The title to print, "R2R Methods by Query" or "R2R Methods by Keyword"</param>
 /// <param name="queries">The keywords/ids to search for</param>
 /// <param name="exact">Specifies whether to look for methods with names/signatures/ids matching the method exactly or partially</param>
 private void QueryMethod(ReadyToRunReader r2r, string title, IReadOnlyList <string> queries, bool exact)
 {
     if (queries.Count > 0)
     {
         _dumper.WriteDivider(title);
     }
     foreach (string q in queries)
     {
         IList <ReadyToRunMethod> res = FindMethod(r2r, q, exact);
         _dumper.DumpQueryCount(q, "Methods", res.Count);
         foreach (ReadyToRunMethod method in res)
         {
             _dumper.DumpMethod(method);
         }
     }
 }
コード例 #12
0
ファイル: R2RDump.cs プロジェクト: lvyitian/runtime
        // <summary>
        /// For each query in the list of queries, dump a runtime function by id.
        /// The method containing the runtime function gets outputted, along with the single runtime function that was searched
        /// </summary>
        /// <param name="r2r">Contains all the extracted info about the ReadyToRun image</param>
        /// <param name="queries">The ids to search for</param>
        private void QueryRuntimeFunction(ReadyToRunReader r2r, IEnumerable <string> queries)
        {
            if (queries.Any())
            {
                _dumper.WriteDivider("Runtime Functions");
            }
            foreach (string q in queries)
            {
                RuntimeFunction rtf = FindRuntimeFunction(r2r, ArgStringToInt(q));

                if (rtf == null)
                {
                    WriteWarning("Unable to find by id " + q);
                    continue;
                }
                _dumper.DumpQueryCount(q.ToString(), "Runtime Function", 1);
                _dumper.DumpRuntimeFunction(rtf);
            }
        }
コード例 #13
0
        public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
        {
            PEFile module = method.ParentModule.PEFile;
            ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);

            if (cacheEntry.readyToRunReader == null)
            {
                WriteCommentLine(output, cacheEntry.failureReason);
            }
            else
            {
                ReadyToRunReader reader = cacheEntry.readyToRunReader;
                int bitness             = -1;
                if (reader.Machine == Machine.Amd64)
                {
                    bitness = 64;
                }
                else
                {
                    Debug.Assert(reader.Machine == Machine.I386);
                    bitness = 32;
                }
                foreach (ReadyToRunMethod readyToRunMethod in reader.Methods)
                {
                    if (readyToRunMethod.MethodHandle == method.MetadataToken)
                    {
                        // TODO: Indexing
                        foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions)
                        {
                            WriteCommentLine(output, readyToRunMethod.SignatureString);
                            byte[] code = new byte[runtimeFunction.Size];
                            for (int i = 0; i < runtimeFunction.Size; i++)
                            {
                                code[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
                            }
                            Disassemble(output, code, bitness, (ulong)runtimeFunction.StartAddress);
                            output.WriteLine();
                        }
                    }
                }
            }
        }
コード例 #14
0
        public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
        {
            PEFile module = assembly.GetPEFileAsync().GetAwaiter().GetResult();
            ReadyToRunReaderCacheEntry cacheEntry = GetReader(assembly, module);

            if (cacheEntry.readyToRunReader == null)
            {
                WriteCommentLine(output, cacheEntry.failureReason);
            }
            else
            {
                ReadyToRunReader reader = cacheEntry.readyToRunReader;
                WriteCommentLine(output, reader.Machine.ToString());
                WriteCommentLine(output, reader.OperatingSystem.ToString());
                WriteCommentLine(output, reader.CompilerIdentifier);
                WriteCommentLine(output, "TODO - display more header information");
            }

            return(base.DecompileAssembly(assembly, output, options));
        }
コード例 #15
0
ファイル: ReadyToRunLanguage.cs プロジェクト: ysmianji/ILSpy
        public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
        {
            PEFile module = method.ParentModule.PEFile;
            ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);

            if (cacheEntry.readyToRunReader == null)
            {
                WriteCommentLine(output, cacheEntry.failureReason);
            }
            else
            {
                ReadyToRunReader reader = cacheEntry.readyToRunReader;
                int bitness             = -1;
                if (reader.Machine == Machine.Amd64)
                {
                    bitness = 64;
                }
                else
                {
                    Debug.Assert(reader.Machine == Machine.I386);
                    bitness = 32;
                }
                if (cacheEntry.methodMap == null)
                {
                    cacheEntry.methodMap = reader.Methods.Values
                                           .SelectMany(m => m)
                                           .GroupBy(m => m.MethodHandle)
                                           .ToDictionary(g => g.Key, g => g.ToArray());
                }
                if (cacheEntry.methodMap.TryGetValue(method.MetadataToken, out var methods))
                {
                    foreach (var readyToRunMethod in methods)
                    {
                        foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions)
                        {
                            Disassemble(output, reader, readyToRunMethod, runtimeFunction, bitness, (ulong)runtimeFunction.StartAddress);
                        }
                    }
                }
            }
        }
コード例 #16
0
ファイル: R2RDiff.cs プロジェクト: z77ma/runtime
        private IEnumerable <ReadyToRunMethod> TryGetMethods(ReadyToRunReader reader, int moduleIndex)
        {
            List <ReadyToRunMethod> methods = new List <ReadyToRunMethod>();

            switch (moduleIndex)
            {
            case InvalidModule:
                break;

            case AllModules:
                methods.AddRange(reader.InstanceMethods.Select(im => im.Method));
                foreach (ReadyToRunAssembly assembly in reader.ReadyToRunAssemblies)
                {
                    methods.AddRange(assembly.Methods);
                }
                break;

            default:
                methods.AddRange(reader.ReadyToRunAssemblies[moduleIndex].Methods);
                break;
            }
            return(methods);
        }
コード例 #17
0
 /// <summary>
 /// Store the left and right file and output writer.
 /// </summary>
 /// <param name="leftFile">Left R2R file</param>
 /// <param name="rightFile">Right R2R file</param>
 /// <param name="writer">Output writer to receive the diff</param>
 public R2RDiff(ReadyToRunReader leftFile, ReadyToRunReader rightFile, TextWriter writer)
 {
     _leftFile  = leftFile;
     _rightFile = rightFile;
     _writer    = writer;
 }
コード例 #18
0
ファイル: R2RDump.cs プロジェクト: lvyitian/runtime
        /// <summary>
        /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image
        /// </summary>
        /// <param name="r2r">The structure containing the info of the ReadyToRun image</param>
        public void Dump(ReadyToRunReader r2r)
        {
            _dumper.Begin();
            bool standardDump = !(_options.EntryPoints || _options.CreatePDB);

            if (_options.Header && standardDump)
            {
                _dumper.WriteDivider("R2R Header");
                _dumper.DumpHeader(true);
            }

            bool haveQuery = false;

            if (_options.Section != null)
            {
                haveQuery = true;
                QuerySection(r2r, _options.Section);
            }

            if (_options.RuntimeFunction != null)
            {
                haveQuery = true;
                QueryRuntimeFunction(r2r, _options.RuntimeFunction);
            }

            if (_options.Query != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Query", _options.Query, true);
            }

            if (_options.Keyword != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false);
            }

            if (!haveQuery)
            {
                // Dump all sections and methods if no queries specified
                if (_options.EntryPoints)
                {
                    _dumper.DumpEntryPoints();
                }

                if (_options.CreatePDB)
                {
                    string pdbPath = _options.PdbPath;
                    if (String.IsNullOrEmpty(pdbPath))
                    {
                        pdbPath = Path.GetDirectoryName(r2r.Filename);
                    }
                    var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None);
                    pdbWriter.WritePDBData(r2r.Filename, ProducePdbWriterMethods(r2r));
                }

                if (!_options.Header && standardDump)
                {
                    _dumper.DumpAllMethods();
                }
            }

            _dumper.End();
        }
コード例 #19
0
        private void Disassemble(PEFile currentFile, ITextOutput output, ReadyToRunReader reader, ReadyToRunMethod readyToRunMethod, RuntimeFunction runtimeFunction, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)
        {
            // TODO: Decorate the disassembly with GCInfo
            WriteCommentLine(output, readyToRunMethod.SignatureString);

            Dictionary <ulong, UnwindCode> unwindInfo = null;

            if (ReadyToRunOptions.GetIsShowUnwindInfo(null) && bitness == 64)
            {
                unwindInfo = WriteUnwindInfo(runtimeFunction, output);
            }

            bool isShowDebugInfo = ReadyToRunOptions.GetIsShowDebugInfo(null);
            Dictionary <VarLocType, HashSet <ValueTuple <DebugInfo, NativeVarInfo> > > debugInfo = null;

            if (isShowDebugInfo)
            {
                debugInfo = WriteDebugInfo(readyToRunMethod, output);
            }

            byte[] codeBytes = new byte[runtimeFunction.Size];
            for (int i = 0; i < runtimeFunction.Size; i++)
            {
                codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
            }

            var codeReader = new ByteArrayCodeReader(codeBytes);
            var decoder    = Decoder.Create(bitness, codeReader);

            decoder.IP = address;
            ulong endRip = decoder.IP + (uint)codeBytes.Length;

            var instructions = new InstructionList();

            while (decoder.IP < endRip)
            {
                decoder.Decode(out instructions.AllocUninitializedElement());
            }

            string    disassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(null);
            Formatter formatter         = null;

            if (disassemblyFormat.Equals(ReadyToRunOptions.intel))
            {
                formatter = new NasmFormatter();
            }
            else
            {
                Debug.Assert(disassemblyFormat.Equals(ReadyToRunOptions.gas));
                formatter = new GasFormatter();
            }
            formatter.Options.DigitSeparator        = "`";
            formatter.Options.FirstOperandCharIndex = 10;
            var   tempOutput  = new StringOutput();
            ulong baseInstrIP = instructions[0].IP;

            foreach (var instr in instructions)
            {
                int byteBaseIndex = (int)(instr.IP - address);
                if (isShowDebugInfo && runtimeFunction.DebugInfo != null)
                {
                    foreach (var bound in runtimeFunction.DebugInfo.BoundsList)
                    {
                        if (bound.NativeOffset == byteBaseIndex)
                        {
                            if (bound.ILOffset == (uint)DebugInfoBoundsType.Prolog)
                            {
                                WriteCommentLine(output, "Prolog");
                            }
                            else if (bound.ILOffset == (uint)DebugInfoBoundsType.Epilog)
                            {
                                WriteCommentLine(output, "Epilog");
                            }
                            else
                            {
                                WriteCommentLine(output, $"IL_{bound.ILOffset:x4}");
                            }
                        }
                    }
                }
                formatter.Format(instr, tempOutput);
                output.Write(instr.IP.ToString("X16"));
                output.Write(" ");
                int instrLen = instr.Length;
                for (int i = 0; i < instrLen; i++)
                {
                    output.Write(codeBytes[byteBaseIndex + i].ToString("X2"));
                }
                int missingBytes = 10 - instrLen;
                for (int i = 0; i < missingBytes; i++)
                {
                    output.Write("  ");
                }
                output.Write(" ");
                output.Write(tempOutput.ToStringAndReset());
                DecorateUnwindInfo(output, unwindInfo, baseInstrIP, instr);
                DecorateDebugInfo(output, instr, debugInfo, baseInstrIP);
                DecorateCallSite(currentFile, output, reader, showMetadataTokens, showMetadataTokensInBase10, instr);
            }
            output.WriteLine();
        }
コード例 #20
0
 public ReadyToRunDisassembler(ITextOutput output, ReadyToRunReader reader, RuntimeFunction runtimeFunction)
 {
     this.output          = output;
     this.reader          = reader;
     this.runtimeFunction = runtimeFunction;
 }
コード例 #21
0
ファイル: R2RDump.cs プロジェクト: vitek-karas/runtime
        /// <summary>
        /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image
        /// </summary>
        /// <param name="r2r">The structure containing the info of the ReadyToRun image</param>
        public void Dump(ReadyToRunReader r2r)
        {
            _dumper.Begin();
            bool standardDump = !(_options.EntryPoints || _options.CreatePDB || _options.CreatePerfmap);

            if (_options.Header && standardDump)
            {
                _dumper.WriteDivider("R2R Header");
                _dumper.DumpHeader(true);
            }

            bool haveQuery = false;

            if (_options.Section != null)
            {
                haveQuery = true;
                QuerySection(r2r, _options.Section);
            }

            if (_options.RuntimeFunction != null)
            {
                haveQuery = true;
                QueryRuntimeFunction(r2r, _options.RuntimeFunction);
            }

            if (_options.Query != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Query", _options.Query, true);
            }

            if (_options.Keyword != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false);
            }

            if (!haveQuery)
            {
                // Dump all sections and methods if no queries specified
                if (_options.EntryPoints)
                {
                    _dumper.DumpEntryPoints();
                }

                TargetArchitecture architecture = r2r.Machine switch
                {
                    Machine.I386 => TargetArchitecture.X86,
                    Machine.Amd64 => TargetArchitecture.X64,
                    Machine.ArmThumb2 => TargetArchitecture.ARM,
                    Machine.Arm64 => TargetArchitecture.ARM64,
                    _ => throw new NotImplementedException(r2r.Machine.ToString()),
                };
                TargetOS os = r2r.OperatingSystem switch
                {
                    OperatingSystem.Windows => TargetOS.Windows,
                    OperatingSystem.Linux => TargetOS.Linux,
                    OperatingSystem.Apple => TargetOS.OSX,
                    OperatingSystem.FreeBSD => TargetOS.FreeBSD,
                    OperatingSystem.NetBSD => TargetOS.FreeBSD,
                    _ => throw new NotImplementedException(r2r.OperatingSystem.ToString()),
                };
                TargetDetails details = new TargetDetails(architecture, os, TargetAbi.CoreRT);

                if (_options.CreatePDB)
                {
                    string pdbPath = _options.PdbPath;
                    if (String.IsNullOrEmpty(pdbPath))
                    {
                        pdbPath = Path.GetDirectoryName(r2r.Filename);
                    }
                    var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None, details);
                    pdbWriter.WritePDBData(r2r.Filename, ProduceDebugInfoMethods(r2r));
                }

                if (_options.CreatePerfmap)
                {
                    string perfmapPath = _options.PerfmapPath;
                    if (string.IsNullOrEmpty(perfmapPath))
                    {
                        perfmapPath = Path.ChangeExtension(r2r.Filename, ".r2rmap");
                    }
                    PerfMapWriter.Write(perfmapPath, _options.PerfmapFormatVersion, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), details);
                }

                if (standardDump)
                {
                    _dumper.DumpAllMethods();
                    _dumper.DumpFixupStats();
                }
            }

            _dumper.End();
        }
コード例 #22
0
ファイル: ReadyToRunLanguage.cs プロジェクト: ysmianji/ILSpy
        private void Disassemble(ITextOutput output, ReadyToRunReader reader, ReadyToRunMethod readyToRunMethod, RuntimeFunction runtimeFunction, int bitness, ulong address)
        {
            WriteCommentLine(output, readyToRunMethod.SignatureString);
            byte[] codeBytes = new byte[runtimeFunction.Size];
            for (int i = 0; i < runtimeFunction.Size; i++)
            {
                codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
            }

            // TODO: Decorate the disassembly with Unwind, GC and debug info
            var codeReader = new ByteArrayCodeReader(codeBytes);
            var decoder    = Decoder.Create(bitness, codeReader);

            decoder.IP = address;
            ulong endRip = decoder.IP + (uint)codeBytes.Length;

            var instructions = new InstructionList();

            while (decoder.IP < endRip)
            {
                decoder.Decode(out instructions.AllocUninitializedElement());
            }

            string    disassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(null);
            Formatter formatter         = null;

            if (disassemblyFormat.Equals(ReadyToRunOptions.intel))
            {
                formatter = new NasmFormatter();
            }
            else
            {
                Debug.Assert(disassemblyFormat.Equals(ReadyToRunOptions.gas));
                formatter = new GasFormatter();
            }
            formatter.Options.DigitSeparator        = "`";
            formatter.Options.FirstOperandCharIndex = 10;
            var tempOutput = new StringOutput();

            foreach (var instr in instructions)
            {
                int byteBaseIndex = (int)(instr.IP - address);
                foreach (var bound in runtimeFunction.DebugInfo.BoundsList)
                {
                    if (bound.NativeOffset == byteBaseIndex)
                    {
                        if (bound.ILOffset == (uint)DebugInfoBoundsType.Prolog)
                        {
                            WriteCommentLine(output, "Prolog");
                        }
                        else if (bound.ILOffset == (uint)DebugInfoBoundsType.Epilog)
                        {
                            WriteCommentLine(output, "Epilog");
                        }
                        else
                        {
                            WriteCommentLine(output, $"IL_{bound.ILOffset:x4}");
                        }
                    }
                }
                formatter.Format(instr, tempOutput);
                output.Write(instr.IP.ToString("X16"));
                output.Write(" ");
                int instrLen = instr.Length;
                for (int i = 0; i < instrLen; i++)
                {
                    output.Write(codeBytes[byteBaseIndex + i].ToString("X2"));
                }
                int missingBytes = 10 - instrLen;
                for (int i = 0; i < missingBytes; i++)
                {
                    output.Write("  ");
                }
                output.Write(" ");
                output.WriteLine(tempOutput.ToStringAndReset());
            }
            output.WriteLine();
        }
コード例 #23
0
ファイル: R2RDump.cs プロジェクト: lvyitian/runtime
        private int Run()
        {
            Disassembler disassembler = null;

            try
            {
                if (_options.In == null || _options.In.Length == 0)
                {
                    throw new ArgumentException("Input filename must be specified (--in <file>)");
                }

                if (_options.Diff && _options.In.Length < 2)
                {
                    throw new ArgumentException("Need at least 2 input files in diff mode");
                }

                if (_options.Naked && _options.Raw)
                {
                    throw new ArgumentException("The option '--naked' is incompatible with '--raw'");
                }

                Dumper previousDumper = null;

                foreach (FileInfo filename in _options.In)
                {
                    // parse the ReadyToRun image
                    ReadyToRunReader r2r = new ReadyToRunReader(_options, filename.FullName);

                    if (_options.Disasm)
                    {
                        if (r2r.InputArchitectureSupported() && r2r.DisassemblerArchitectureSupported())
                        {
                            disassembler = new Disassembler(r2r, _options);
                        }
                        else
                        {
                            throw new ArgumentException($"The architecture of input file {filename} ({r2r.Machine.ToString()}) or the architecture of the disassembler tools ({System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString()}) is not supported.");
                        }
                    }


                    if (!_options.Diff)
                    {
                        // output the ReadyToRun info
                        _dumper = new TextDumper(r2r, _writer, disassembler, _options);
                        Dump(r2r);
                    }
                    else
                    {
                        string perFileOutput = filename.FullName + ".common-methods.r2r";
                        _dumper = new TextDumper(r2r, new StreamWriter(perFileOutput, append: false, _encoding), disassembler, _options);
                        if (previousDumper != null)
                        {
                            new R2RDiff(previousDumper, _dumper, _writer).Run();
                        }
                        previousDumper?.Writer?.Flush();
                        previousDumper = _dumper;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: " + e.ToString());
                if (e is ArgumentException)
                {
                    Console.WriteLine();
                }
                return(1);
            }
            finally
            {
                if (disassembler != null)
                {
                    disassembler.Dispose();
                }
                // flush output stream
                _dumper?.Writer?.Flush();
                _writer?.Flush();
            }

            return(0);
        }
コード例 #24
0
 /// <summary>
 /// Store the R2R reader and construct the disassembler for the appropriate architecture.
 /// </summary>
 /// <param name="reader"></param>
 public Disassembler(ReadyToRunReader reader, DumpOptions options)
 {
     _reader  = reader;
     _options = options;
     _disasm  = CoreDisTools.GetDisasm(_reader.Machine);
 }
コード例 #25
0
ファイル: TextDumper.cs プロジェクト: lvyitian/runtime
 public TextDumper(ReadyToRunReader r2r, TextWriter writer, Disassembler disassembler, DumpOptions options)
     : base(r2r, writer, disassembler, options)
 {
 }
コード例 #26
0
ファイル: R2RDump.cs プロジェクト: snickler/runtime
        /// <summary>
        /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image
        /// </summary>
        /// <param name="r2r">The structure containing the info of the ReadyToRun image</param>
        public void Dump(ReadyToRunReader r2r)
        {
            _dumper.Begin();
            bool standardDump = !(_options.EntryPoints || _options.CreatePDB || _options.CreatePerfmap);

            if (_options.Header && standardDump)
            {
                _dumper.WriteDivider("R2R Header");
                _dumper.DumpHeader(true);
            }

            bool haveQuery = false;
            if (_options.Section != null)
            {
                haveQuery = true;
                QuerySection(r2r, _options.Section);
            }

            if (_options.RuntimeFunction != null)
            {
                haveQuery = true;
                QueryRuntimeFunction(r2r, _options.RuntimeFunction);
            }

            if (_options.Query != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Query", _options.Query, true);
            }

            if (_options.Keyword != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false);
            }

            if (!haveQuery)
            {
                // Dump all sections and methods if no queries specified
                if (_options.EntryPoints)
                {
                    _dumper.DumpEntryPoints();
                }

                if (_options.CreatePDB)
                {
                    string pdbPath = _options.PdbPath;
                    if (String.IsNullOrEmpty(pdbPath))
                    {
                        pdbPath = Path.GetDirectoryName(r2r.Filename);
                    }
                    var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None);
                    pdbWriter.WritePDBData(r2r.Filename, ProduceDebugInfoMethods(r2r));
                }

                if (_options.CreatePerfmap)
                {
                    string perfmapPath = _options.PerfmapPath;
                    if (string.IsNullOrEmpty(perfmapPath))
                    {
                        perfmapPath = Path.ChangeExtension(r2r.Filename, ".r2rmap");
                    }
                    // TODO: can't seem to find any place that surfaces the ABI. This is for debugging purposes, so may not be as relevant to be correct.
                    TargetDetails details = new TargetDetails(r2r.TargetArchitecture, r2r.TargetOperatingSystem, TargetAbi.CoreRT);
                    PerfMapWriter.Write(perfmapPath, _options.PerfmapFormatVersion, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), details);
                }

                if (standardDump)
                {
                    _dumper.DumpAllMethods();
                    _dumper.DumpFixupStats();
                }
            }

            _dumper.End();
        }
コード例 #27
0
ファイル: R2RDiff.cs プロジェクト: z77ma/runtime
        private static Dictionary <string, ReadyToRunImportSection.ImportSectionEntry> GetImports(ReadyToRunReader reader)
        {
            var result           = new Dictionary <string, ReadyToRunImportSection.ImportSectionEntry>();
            var signatureOptions = new SignatureFormattingOptions()
            {
                Naked = true
            };

            foreach (ReadyToRunImportSection section in reader.ImportSections)
            {
                foreach (ReadyToRunImportSection.ImportSectionEntry entry in section.Entries)
                {
                    result[entry.Signature.ToString(signatureOptions)] = entry;
                }
            }
            return(result);
        }
コード例 #28
0
        private void Disassemble(PEFile currentFile, ITextOutput output, ReadyToRunReader reader, ReadyToRunMethod readyToRunMethod, RuntimeFunction runtimeFunction, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)
        {
            WriteCommentLine(output, readyToRunMethod.SignatureString);
            byte[] codeBytes = new byte[runtimeFunction.Size];
            for (int i = 0; i < runtimeFunction.Size; i++)
            {
                codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
            }

            // TODO: Decorate the disassembly with Unwind, GC and debug info
            var codeReader = new ByteArrayCodeReader(codeBytes);
            var decoder    = Decoder.Create(bitness, codeReader);

            decoder.IP = address;
            ulong endRip = decoder.IP + (uint)codeBytes.Length;

            var instructions = new InstructionList();

            while (decoder.IP < endRip)
            {
                decoder.Decode(out instructions.AllocUninitializedElement());
            }

            string    disassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(null);
            Formatter formatter         = null;

            if (disassemblyFormat.Equals(ReadyToRunOptions.intel))
            {
                formatter = new NasmFormatter();
            }
            else
            {
                Debug.Assert(disassemblyFormat.Equals(ReadyToRunOptions.gas));
                formatter = new GasFormatter();
            }
            formatter.Options.DigitSeparator        = "`";
            formatter.Options.FirstOperandCharIndex = 10;
            var tempOutput = new StringOutput();

            foreach (var instr in instructions)
            {
                int byteBaseIndex = (int)(instr.IP - address);
                if (runtimeFunction.DebugInfo != null)
                {
                    foreach (var bound in runtimeFunction.DebugInfo.BoundsList)
                    {
                        if (bound.NativeOffset == byteBaseIndex)
                        {
                            if (bound.ILOffset == (uint)DebugInfoBoundsType.Prolog)
                            {
                                WriteCommentLine(output, "Prolog");
                            }
                            else if (bound.ILOffset == (uint)DebugInfoBoundsType.Epilog)
                            {
                                WriteCommentLine(output, "Epilog");
                            }
                            else
                            {
                                WriteCommentLine(output, $"IL_{bound.ILOffset:x4}");
                            }
                        }
                    }
                }
                formatter.Format(instr, tempOutput);
                output.Write(instr.IP.ToString("X16"));
                output.Write(" ");
                int instrLen = instr.Length;
                for (int i = 0; i < instrLen; i++)
                {
                    output.Write(codeBytes[byteBaseIndex + i].ToString("X2"));
                }
                int missingBytes = 10 - instrLen;
                for (int i = 0; i < missingBytes; i++)
                {
                    output.Write("  ");
                }
                output.Write(" ");
                output.Write(tempOutput.ToStringAndReset());
                int importCellAddress = (int)instr.IPRelativeMemoryAddress;
                if (instr.IsCallNearIndirect && reader.ImportCellNames.ContainsKey(importCellAddress))
                {
                    output.Write(" ; ");
                    ReadyToRunSignature signature = reader.ImportSignatures[(int)instr.IPRelativeMemoryAddress];
                    switch (signature)
                    {
                    case MethodDefEntrySignature methodDefSignature:
                        var methodDefToken = MetadataTokens.EntityHandle(unchecked ((int)methodDefSignature.MethodDefToken));
                        if (showMetadataTokens)
                        {
                            if (showMetadataTokensInBase10)
                            {
                                output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken)}) ", "metadata");
                            }
                            else
                            {
                                output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken):X8}) ", "metadata");
                            }
                        }
                        methodDefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
                        break;

                    case MethodRefEntrySignature methodRefSignature:
                        var methodRefToken = MetadataTokens.EntityHandle(unchecked ((int)methodRefSignature.MethodRefToken));
                        if (showMetadataTokens)
                        {
                            if (showMetadataTokensInBase10)
                            {
                                output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken)}) ", "metadata");
                            }
                            else
                            {
                                output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken):X8}) ", "metadata");
                            }
                        }
                        methodRefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
                        break;

                    default:
                        output.WriteLine(reader.ImportCellNames[importCellAddress]);
                        break;
                    }
                    output.WriteLine();
                }
                else
                {
                    output.WriteLine();
                }
            }
            output.WriteLine();
        }