From: Amy Yu Date: Tue, 26 Jun 2018 21:11:46 +0000 (-0700) Subject: Dump disasm line by line, changes to dumping bytes to xml, fix X-Git-Tag: submit/tizen/20210909.063632~11030^2~4506^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=db8d67d4755bfffa8f188ff4e4e15874fa071fe5;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Dump disasm line by line, changes to dumping bytes to xml, fix compilerIdentifier typo Commit migrated from https://github.com/dotnet/coreclr/commit/cbbd3d6482231aac216500c3947267e4a89fbb8a --- diff --git a/src/coreclr/src/tools/r2rdump/CoreDisTools.cs b/src/coreclr/src/tools/r2rdump/CoreDisTools.cs index 6070e43..a84046d 100644 --- a/src/coreclr/src/tools/r2rdump/CoreDisTools.cs +++ b/src/coreclr/src/tools/r2rdump/CoreDisTools.cs @@ -42,36 +42,17 @@ namespace R2RDump [DllImport(_dll)] public static extern void FinishDisasm(IntPtr Disasm); - public unsafe static string GetCodeBlock(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image) + public unsafe static int GetInstruction(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, int rtfOffset, byte[] image, out string instr) { - StringBuilder sb = new StringBuilder(); - - int rtfOffset = 0; - int codeOffset = rtf.CodeOffset; - Dictionary transitions = rtf.Method.GcInfo.Transitions; - GcSlotTable slotTable = rtf.Method.GcInfo.SlotTable; - while (rtfOffset < rtf.Size) + int instrSize = 1; + fixed (byte* p = image) { - int instrSize = 1; - fixed (byte* p = image) - { - IntPtr ptr = (IntPtr)(p + imageOffset + rtfOffset); - instrSize = DumpInstruction(Disasm, (ulong)(rtf.StartAddress + rtfOffset), ptr, rtf.Size); - } - IntPtr pBuffer = GetOutputBuffer(); - string instr = Marshal.PtrToStringAnsi(pBuffer); - - sb.Append(instr); - if (transitions.ContainsKey(codeOffset)) - { - sb.AppendLine($"\t\t\t\t{transitions[codeOffset].GetSlotState(slotTable)}"); - } - - ClearOutputBuffer(); - rtfOffset += instrSize; - codeOffset += instrSize; + IntPtr ptr = (IntPtr)(p + imageOffset + rtfOffset); + instrSize = DumpInstruction(Disasm, (ulong)(rtf.StartAddress + rtfOffset), ptr, rtf.Size); } - return sb.ToString(); + IntPtr pBuffer = GetOutputBuffer(); + instr = Marshal.PtrToStringAnsi(pBuffer); + return instrSize; } public static IntPtr GetDisasm(Machine machine) diff --git a/src/coreclr/src/tools/r2rdump/R2RDump.cs b/src/coreclr/src/tools/r2rdump/R2RDump.cs index 9a0062b..659bc31 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDump.cs +++ b/src/coreclr/src/tools/r2rdump/R2RDump.cs @@ -34,7 +34,8 @@ namespace R2RDump abstract internal void DumpAllMethods(); abstract internal void DumpMethod(R2RMethod method, XmlNode parentNode = null); abstract internal void DumpRuntimeFunction(RuntimeFunction rtf, XmlNode parentNode = null); - abstract internal void DumpBytes(int rva, uint size, XmlNode parentNode = null, bool convertToOffset = true); + abstract internal unsafe void DumpDisasm(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image, XmlNode parentNode = null); + abstract internal void DumpBytes(int rva, uint size, XmlNode parentNode = null, string name = "Raw", bool convertToOffset = true); abstract internal void DumpSectionContents(R2RSection section, XmlNode parentNode = null); abstract internal XmlNode DumpQueryCount(string q, string title, int count); } diff --git a/src/coreclr/src/tools/r2rdump/R2RReader.cs b/src/coreclr/src/tools/r2rdump/R2RReader.cs index 026d7cc..d365f87 100644 --- a/src/coreclr/src/tools/r2rdump/R2RReader.cs +++ b/src/coreclr/src/tools/r2rdump/R2RReader.cs @@ -79,9 +79,9 @@ namespace R2RDump public IList AvailableTypes { get; } /// - /// The compile identifier string from READYTORUN_SECTION_COMPILER_IDENTIFIER + /// The compiler identifier string from READYTORUN_SECTION_COMPILER_IDENTIFIER /// - public string CompileIdentifier { get; } + public string CompilerIdentifier { get; } public IList ImportSections { get; } @@ -142,7 +142,7 @@ namespace R2RDump AvailableTypes = new List(); ParseAvailableTypes(); - CompileIdentifier = ParseCompilerIdentifier(); + CompilerIdentifier = ParseCompilerIdentifier(); ImportSections = new List(); ParseImportSections(); diff --git a/src/coreclr/src/tools/r2rdump/TextDumper.cs b/src/coreclr/src/tools/r2rdump/TextDumper.cs index f444f0d..7cfb98b 100644 --- a/src/coreclr/src/tools/r2rdump/TextDumper.cs +++ b/src/coreclr/src/tools/r2rdump/TextDumper.cs @@ -126,7 +126,7 @@ namespace R2RDump if (_raw) { - DumpBytes(method.GcInfo.Offset, (uint)method.GcInfo.Size, null, false); + DumpBytes(method.GcInfo.Offset, (uint)method.GcInfo.Size, null, "", false); } } SkipLine(); @@ -147,8 +147,7 @@ namespace R2RDump if (_disasm) { - string disassembly = CoreDisTools.GetCodeBlock(_disassembler, rtf, _r2r.GetOffset(rtf.StartAddress), _r2r.Image); - _writer.Write(disassembly); + DumpDisasm(_disassembler, rtf, _r2r.GetOffset(rtf.StartAddress), _r2r.Image); } if (_raw) @@ -168,10 +167,33 @@ namespace R2RDump SkipLine(); } + internal unsafe override void DumpDisasm(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image, XmlNode parentNode = null) + { + int rtfOffset = 0; + int codeOffset = rtf.CodeOffset; + Dictionary transitions = rtf.Method.GcInfo.Transitions; + GcSlotTable slotTable = rtf.Method.GcInfo.SlotTable; + while (rtfOffset < rtf.Size) + { + string instr; + int instrSize = CoreDisTools.GetInstruction(Disasm, rtf, imageOffset, rtfOffset, image, out instr); + + _writer.Write(instr); + if (transitions.ContainsKey(codeOffset)) + { + _writer.WriteLine($"\t\t\t\t{transitions[codeOffset].GetSlotState(slotTable)}"); + } + + CoreDisTools.ClearOutputBuffer(); + rtfOffset += instrSize; + codeOffset += instrSize; + } + } + /// /// Prints a formatted string containing a block of bytes from the relative virtual address and size /// - internal override void DumpBytes(int rva, uint size, XmlNode parentNode = null, bool convertToOffset = true) + internal override void DumpBytes(int rva, uint size, XmlNode parentNode = null, string name = "Raw", bool convertToOffset = true) { int start = rva; if (convertToOffset) @@ -241,7 +263,7 @@ namespace R2RDump } break; case R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER: - _writer.WriteLine(_r2r.CompileIdentifier); + _writer.WriteLine(_r2r.CompilerIdentifier); break; case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS: foreach (R2RImportSection importSection in _r2r.ImportSections) diff --git a/src/coreclr/src/tools/r2rdump/XmlDumper.cs b/src/coreclr/src/tools/r2rdump/XmlDumper.cs index 52c28f4..8604adb 100644 --- a/src/coreclr/src/tools/r2rdump/XmlDumper.cs +++ b/src/coreclr/src/tools/r2rdump/XmlDumper.cs @@ -122,14 +122,14 @@ namespace R2RDump methodNode.AppendChild(gcNode); Serialize(method.GcInfo, gcNode); - foreach (KeyValuePair transition in method.GcInfo.Transitions) + foreach (GcInfo.GcTransition transition in method.GcInfo.Transitions.Values) { Serialize(transition, gcNode); } if (_raw) { - DumpBytes(method.GcInfo.Offset, (uint)method.GcInfo.Size, methodNode, false); + DumpBytes(method.GcInfo.Offset, (uint)method.GcInfo.Size, gcNode, "Raw", false); } } @@ -155,8 +155,7 @@ namespace R2RDump if (_disasm) { - string disassembly = CoreDisTools.GetCodeBlock(_disassembler, rtf, _r2r.GetOffset(rtf.StartAddress), _r2r.Image); - AddXMLNode("Disassembly", disassembly, rtfNode); + DumpDisasm(_disassembler, rtf, _r2r.GetOffset(rtf.StartAddress), _r2r.Image, rtfNode); } if (_raw) @@ -177,10 +176,33 @@ namespace R2RDump } } + internal unsafe override void DumpDisasm(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image, XmlNode parentNode) + { + int rtfOffset = 0; + int codeOffset = rtf.CodeOffset; + Dictionary transitions = rtf.Method.GcInfo.Transitions; + GcSlotTable slotTable = rtf.Method.GcInfo.SlotTable; + while (rtfOffset < rtf.Size) + { + string instr; + int instrSize = CoreDisTools.GetInstruction(Disasm, rtf, imageOffset, rtfOffset, image, out instr); + + AddXMLNode("offset"+codeOffset, instr, parentNode); + if (transitions.ContainsKey(codeOffset)) + { + AddXMLNode("Transition", transitions[codeOffset].GetSlotState(slotTable), parentNode); + } + + CoreDisTools.ClearOutputBuffer(); + rtfOffset += instrSize; + codeOffset += instrSize; + } + } + /// /// Prints a formatted string containing a block of bytes from the relative virtual address and size /// - internal override void DumpBytes(int rva, uint size, XmlNode parentNode, bool convertToOffset = true) + internal override void DumpBytes(int rva, uint size, XmlNode parentNode, string name = "Raw", bool convertToOffset = true) { int start = rva; if (convertToOffset) @@ -198,29 +220,9 @@ namespace R2RDump { sb.Append($" {_r2r.Image[start + i]:X2}"); } - AddXMLNode("Raw", sb.ToString(), parentNode); + AddXMLNode(name, sb.ToString(), parentNode); return; } - - _writer.Write(" "); - if (rva % 16 != 0) - { - int floor = rva / 16 * 16; - _writer.Write($"{floor:X8}:"); - _writer.Write(new String(' ', (rva - floor) * 3)); - } - for (uint i = 0; i < size; i++) - { - if ((rva + i) % 16 == 0) - { - _writer.Write($"{rva + i:X8}:"); - } - _writer.Write($" {_r2r.Image[start + i]:X2}"); - if ((rva + i) % 16 == 15 && i != size - 1) - { - _writer.Write(" "); - } - } } internal override void DumpSectionContents(R2RSection section, XmlNode parentNode) @@ -249,7 +251,7 @@ namespace R2RDump } break; case R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER: - AddXMLNode("CompileIdentifier", _r2r.CompileIdentifier, contentsNode); + AddXMLNode("CompilerIdentifier", _r2r.CompilerIdentifier, contentsNode); break; case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS: foreach (R2RImportSection importSection in _r2r.ImportSections) @@ -259,15 +261,15 @@ namespace R2RDump { if (importSection.SectionRVA != 0) { - DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize, contentsNode); + DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize, contentsNode, "SectionBytes"); } if (importSection.SignatureRVA != 0) { - DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int), contentsNode); + DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int), contentsNode, "SignatureBytes"); } if (importSection.AuxiliaryDataRVA != 0) { - DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size, contentsNode); + DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size, contentsNode, "AuxiliaryDataBytes"); } } foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)