[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<int, GcInfo.GcTransition> 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)
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);
}
public IList<string> AvailableTypes { get; }
/// <summary>
- /// The compile identifier string from READYTORUN_SECTION_COMPILER_IDENTIFIER
+ /// The compiler identifier string from READYTORUN_SECTION_COMPILER_IDENTIFIER
/// </summary>
- public string CompileIdentifier { get; }
+ public string CompilerIdentifier { get; }
public IList<R2RImportSection> ImportSections { get; }
AvailableTypes = new List<string>();
ParseAvailableTypes();
- CompileIdentifier = ParseCompilerIdentifier();
+ CompilerIdentifier = ParseCompilerIdentifier();
ImportSections = new List<R2RImportSection>();
ParseImportSections();
if (_raw)
{
- DumpBytes(method.GcInfo.Offset, (uint)method.GcInfo.Size, null, false);
+ DumpBytes(method.GcInfo.Offset, (uint)method.GcInfo.Size, null, "", false);
}
}
SkipLine();
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)
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<int, GcInfo.GcTransition> 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;
+ }
+ }
+
/// <summary>
/// Prints a formatted string containing a block of bytes from the relative virtual address and size
/// </summary>
- 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)
}
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)
methodNode.AppendChild(gcNode);
Serialize(method.GcInfo, gcNode);
- foreach (KeyValuePair<int, GcInfo.GcTransition> 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);
}
}
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)
}
}
+ internal unsafe override void DumpDisasm(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image, XmlNode parentNode)
+ {
+ int rtfOffset = 0;
+ int codeOffset = rtf.CodeOffset;
+ Dictionary<int, GcInfo.GcTransition> 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;
+ }
+ }
+
/// <summary>
/// Prints a formatted string containing a block of bytes from the relative virtual address and size
/// </summary>
- 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)
{
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)
}
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)
{
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)