From 1e3842446d661cb7dcfc6c197150f6f883bd2b1d Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Mon, 16 Dec 2019 15:13:53 -0800 Subject: [PATCH] R2RDump changes to allow separation of presentation from parsing (#267) --- .../Amd64/GcInfo.cs | 2 +- .../Amd64/GcSlotTable.cs | 2 +- .../Amd64/GcTransition.cs | 2 +- .../Amd64/Registers.cs | 2 +- .../Amd64/UnwindInfo.cs | 5 +- .../Arm/Registers.cs | 2 +- .../Arm/UnwindInfo.cs | 2 +- .../Arm64/Registers.cs | 2 +- .../Arm64/UnwindInfo.cs | 2 +- .../ILCompiler.Reflection.ReadyToRun}/DebugInfo.cs | 112 +------ .../DebugInfoTypes.cs | 43 ++- .../DisassemblingTypeProvider.cs | 2 +- .../ILCompiler.Reflection.ReadyToRun}/EHInfo.cs | 2 +- .../GCInfoTypes.cs | 2 +- .../ILCompiler.Reflection.ReadyToRun}/GCRefMap.cs | 48 +-- .../IAssemblyResolver.cs | 15 + .../ILCompiler.Reflection.ReadyToRun.csproj | 27 ++ .../NativeArray.cs | 5 +- .../NativeHashtable.cs | 11 +- .../NativeReader.cs | 5 +- .../NibbleReader.cs | 2 +- .../ILCompiler.Reflection.ReadyToRun}/R2RHeader.cs | 5 +- .../R2RImportSection.cs | 20 +- .../ILCompiler.Reflection.ReadyToRun}/R2RMethod.cs | 154 +--------- .../ILCompiler.Reflection.ReadyToRun}/R2RReader.cs | 38 +-- .../R2RSection.cs | 12 +- .../R2RSignature.cs | 20 +- .../TransitionBlock.cs | 2 +- .../x86/CallPattern.cs | 2 +- .../x86/GcInfo.cs | 2 +- .../x86/GcSlotTable.cs | 2 +- .../x86/GcTransition.cs | 2 +- .../x86/InfoHdr.cs | 2 +- .../x86/Registers.cs | 2 +- .../x86/UnwindInfo.cs | 2 +- src/coreclr/src/tools/r2rdump/CoreDisTools.cs | 1 + src/coreclr/src/tools/r2rdump/Extensions.cs | 321 +++++++++++++++++++++ src/coreclr/src/tools/r2rdump/R2RDiff.cs | 1 + src/coreclr/src/tools/r2rdump/R2RDump.cs | 3 +- src/coreclr/src/tools/r2rdump/R2RDump.csproj | 6 +- src/coreclr/src/tools/r2rdump/TextDumper.cs | 13 +- src/coreclr/src/tools/r2rdump/XmlDumper.cs | 9 +- 42 files changed, 498 insertions(+), 416 deletions(-) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Amd64/GcInfo.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Amd64/GcSlotTable.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Amd64/GcTransition.cs (98%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Amd64/Registers.cs (94%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Amd64/UnwindInfo.cs (98%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Arm/Registers.cs (95%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Arm/UnwindInfo.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Arm64/Registers.cs (93%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/Arm64/UnwindInfo.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/DebugInfo.cs (58%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/DebugInfoTypes.cs (72%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/DisassemblingTypeProvider.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/EHInfo.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/GCInfoTypes.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/GCRefMap.cs (72%) create mode 100644 src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/IAssemblyResolver.cs create mode 100644 src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/NativeArray.cs (95%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/NativeHashtable.cs (96%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/NativeReader.cs (98%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/NibbleReader.cs (98%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/R2RHeader.cs (96%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/R2RImportSection.cs (88%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/R2RMethod.cs (55%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/R2RReader.cs (96%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/R2RSection.cs (83%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/R2RSignature.cs (98%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/TransitionBlock.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/x86/CallPattern.cs (98%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/x86/GcInfo.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/x86/GcSlotTable.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/x86/GcTransition.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/x86/InfoHdr.cs (99%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/x86/Registers.cs (95%) rename src/coreclr/src/tools/{r2rdump => crossgen2/ILCompiler.Reflection.ReadyToRun}/x86/UnwindInfo.cs (95%) create mode 100644 src/coreclr/src/tools/r2rdump/Extensions.cs diff --git a/src/coreclr/src/tools/r2rdump/Amd64/GcInfo.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/Amd64/GcInfo.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs index 72a0afe..c610e4c 100644 --- a/src/coreclr/src/tools/r2rdump/Amd64/GcInfo.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs @@ -9,7 +9,7 @@ using System.Reflection.PortableExecutable; using System.Text; using System.Xml.Serialization; -namespace R2RDump.Amd64 +namespace ILCompiler.Reflection.ReadyToRun.Amd64 { public class GcInfo : BaseGcInfo { diff --git a/src/coreclr/src/tools/r2rdump/Amd64/GcSlotTable.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/Amd64/GcSlotTable.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs index be77aa5..b675961 100644 --- a/src/coreclr/src/tools/r2rdump/Amd64/GcSlotTable.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs @@ -9,7 +9,7 @@ using System.Reflection.PortableExecutable; using System.Text; using System.Xml.Serialization; -namespace R2RDump.Amd64 +namespace ILCompiler.Reflection.ReadyToRun.Amd64 { public class GcSlotTable { diff --git a/src/coreclr/src/tools/r2rdump/Amd64/GcTransition.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcTransition.cs similarity index 98% rename from src/coreclr/src/tools/r2rdump/Amd64/GcTransition.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcTransition.cs index 26d629f..723efc6 100644 --- a/src/coreclr/src/tools/r2rdump/Amd64/GcTransition.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/GcTransition.cs @@ -8,7 +8,7 @@ using System.Reflection.PortableExecutable; using System.Text; using System.Xml.Serialization; -namespace R2RDump.Amd64 +namespace ILCompiler.Reflection.ReadyToRun.Amd64 { public struct InterruptibleRange { diff --git a/src/coreclr/src/tools/r2rdump/Amd64/Registers.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/Registers.cs similarity index 94% rename from src/coreclr/src/tools/r2rdump/Amd64/Registers.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/Registers.cs index cc1cad3..d6b105d 100644 --- a/src/coreclr/src/tools/r2rdump/Amd64/Registers.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/Registers.cs @@ -6,7 +6,7 @@ using System; using System.Collections.Generic; using System.Text; -namespace R2RDump.Amd64 +namespace ILCompiler.Reflection.ReadyToRun.Amd64 { /// /// based on src\gcdump\gcdumpnonx86.cpp GetRegName diff --git a/src/coreclr/src/tools/r2rdump/Amd64/UnwindInfo.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs similarity index 98% rename from src/coreclr/src/tools/r2rdump/Amd64/UnwindInfo.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs index 50b422e..5dadd46 100644 --- a/src/coreclr/src/tools/r2rdump/Amd64/UnwindInfo.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Text; using System.Xml.Serialization; -namespace R2RDump.Amd64 +namespace ILCompiler.Reflection.ReadyToRun.Amd64 { /// /// based on src\inc\win64unwind.h _UNWIND_OP_CODES @@ -239,7 +239,8 @@ namespace R2RDump.Amd64 code.NextFrameOffset = (int)offset * 16; if ((UnwindCodeArray[i].FrameOffset & 0xF0000000) != 0) { - R2RDump.WriteWarning("Illegal unwindInfo unscaled offset: too large"); + // TODO (refactoring) - what should we do? + // R2RDump.WriteWarning("Illegal unwindInfo unscaled offset: too large"); } } break; diff --git a/src/coreclr/src/tools/r2rdump/Arm/Registers.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm/Registers.cs similarity index 95% rename from src/coreclr/src/tools/r2rdump/Arm/Registers.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm/Registers.cs index 2985633..fa69063 100644 --- a/src/coreclr/src/tools/r2rdump/Arm/Registers.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm/Registers.cs @@ -6,7 +6,7 @@ using System; using System.Collections.Generic; using System.Text; -namespace R2RDump.Arm +namespace ILCompiler.Reflection.ReadyToRun.Arm { /// /// based on src/jit/unwindarm.cpp mapRegNumToDwarfReg diff --git a/src/coreclr/src/tools/r2rdump/Arm/UnwindInfo.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/Arm/UnwindInfo.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs index 6248a7b..5eea415 100644 --- a/src/coreclr/src/tools/r2rdump/Arm/UnwindInfo.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs @@ -5,7 +5,7 @@ using System.Text; using System.Xml.Serialization; -namespace R2RDump.Arm +namespace ILCompiler.Reflection.ReadyToRun.Arm { public class Epilog { diff --git a/src/coreclr/src/tools/r2rdump/Arm64/Registers.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm64/Registers.cs similarity index 93% rename from src/coreclr/src/tools/r2rdump/Arm64/Registers.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm64/Registers.cs index d205808..c4e545b 100644 --- a/src/coreclr/src/tools/r2rdump/Arm64/Registers.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm64/Registers.cs @@ -6,7 +6,7 @@ using System; using System.Collections.Generic; using System.Text; -namespace R2RDump.Arm64 +namespace ILCompiler.Reflection.ReadyToRun.Arm64 { public enum Registers { diff --git a/src/coreclr/src/tools/r2rdump/Arm64/UnwindInfo.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/Arm64/UnwindInfo.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs index 1d126d4..5c1f31f 100644 --- a/src/coreclr/src/tools/r2rdump/Arm64/UnwindInfo.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs @@ -5,7 +5,7 @@ using System.Text; using System.Xml.Serialization; -namespace R2RDump.Arm64 +namespace ILCompiler.Reflection.ReadyToRun.Arm64 { public class Epilog { diff --git a/src/coreclr/src/tools/r2rdump/DebugInfo.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs similarity index 58% rename from src/coreclr/src/tools/r2rdump/DebugInfo.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs index b8e5987..490f405 100644 --- a/src/coreclr/src/tools/r2rdump/DebugInfo.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs @@ -9,7 +9,7 @@ using System.IO; using System.Reflection.PortableExecutable; using System.Text; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// Represents the debug information for a single method in the ready-to-run image. @@ -21,12 +21,10 @@ namespace R2RDump private List _boundsList = new List(); private List _variablesList = new List(); private Machine _machine; - private bool _normalize; - public DebugInfo(byte[] image, int offset, Machine machine, bool normalize) + public DebugInfo(byte[] image, int offset, Machine machine) { _machine = machine; - _normalize = normalize; // Get the id of the runtime function from the NativeArray uint lookback = 0; @@ -55,83 +53,14 @@ namespace R2RDump } } - public void WriteTo(TextWriter writer, DumpOptions dumpOptions) - { - if (_boundsList.Count > 0) - writer.WriteLine("Debug Info"); - - writer.WriteLine("\tBounds:"); - for (int i = 0; i < _boundsList.Count; ++i) - { - writer.Write('\t'); - if (!dumpOptions.Naked) - { - writer.Write($"Native Offset: 0x{_boundsList[i].NativeOffset:X}, "); - } - writer.WriteLine($"IL Offset: 0x{_boundsList[i].ILOffset:X}, Source Types: {_boundsList[i].SourceTypes}"); - } - - writer.WriteLine(""); - - if (_variablesList.Count > 0) - writer.WriteLine("\tVariable Locations:"); - - for (int i = 0; i < _variablesList.Count; ++i) - { - var varLoc = _variablesList[i]; - writer.WriteLine($"\tVariable Number: {varLoc.VariableNumber}"); - writer.WriteLine($"\tStart Offset: 0x{varLoc.StartOffset:X}"); - writer.WriteLine($"\tEnd Offset: 0x{varLoc.EndOffset:X}"); - writer.WriteLine($"\tLoc Type: {varLoc.VariableLocation.VarLocType}"); - - switch (varLoc.VariableLocation.VarLocType) - { - case VarLocType.VLT_REG: - case VarLocType.VLT_REG_FP: - case VarLocType.VLT_REG_BYREF: - writer.WriteLine($"\tRegister: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}"); - break; - case VarLocType.VLT_STK: - case VarLocType.VLT_STK_BYREF: - writer.WriteLine($"\tBase Register: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}"); - writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data2}"); - break; - case VarLocType.VLT_REG_REG: - writer.WriteLine($"\tRegister 1: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}"); - writer.WriteLine($"\tRegister 2: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data2)}"); - break; - case VarLocType.VLT_REG_STK: - writer.WriteLine($"\tRegister: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}"); - writer.WriteLine($"\tBase Register: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data2)}"); - writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data3}"); - break; - case VarLocType.VLT_STK_REG: - writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data1}"); - writer.WriteLine($"\tBase Register: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data2)}"); - writer.WriteLine($"\tRegister: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data3)}"); - break; - case VarLocType.VLT_STK2: - writer.WriteLine($"\tBase Register: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}"); - writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data2}"); - break; - case VarLocType.VLT_FPSTK: - writer.WriteLine($"\tOffset: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}"); - break; - case VarLocType.VLT_FIXED_VA: - writer.WriteLine($"\tOffset: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}"); - break; - default: - throw new BadImageFormatException("Unexpected var loc type"); - } - - writer.WriteLine(""); - } - } + public List BoundsList => _boundsList; + public List VariablesList => _variablesList; + public Machine Machine => _machine; /// /// Convert a register number in debug info into a machine-specific register /// - private static string GetPlatformSpecificRegister(Machine machine, int regnum) + public static string GetPlatformSpecificRegister(Machine machine, int regnum) { switch (machine) { @@ -233,35 +162,6 @@ namespace R2RDump entry.VariableLocation = varLoc; _variablesList.Add(entry); } - - if (_normalize) - { - _variablesList.Sort(CompareNativeVarInfo); - } - } - - private static int CompareNativeVarInfo(NativeVarInfo left, NativeVarInfo right) - { - if (left.VariableNumber < right.VariableNumber) - { - return -1; - } - else if (left.VariableNumber > right.VariableNumber) - { - return 1; - } - else if (left.StartOffset < right.StartOffset) - { - return -1; - } - else if (left.StartOffset > right.StartOffset) - { - return 1; - } - else - { - return 0; - } } private int ReadEncodedStackOffset(NibbleReader reader) diff --git a/src/coreclr/src/tools/r2rdump/DebugInfoTypes.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs similarity index 72% rename from src/coreclr/src/tools/r2rdump/DebugInfoTypes.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs index a1f4b33..deeec87 100644 --- a/src/coreclr/src/tools/r2rdump/DebugInfoTypes.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs @@ -3,17 +3,18 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { - struct DebugInfoBoundsEntry + public struct DebugInfoBoundsEntry { public uint NativeOffset; public uint ILOffset; public SourceTypes SourceTypes; } - struct NativeVarInfo + public struct NativeVarInfo { public uint StartOffset; public uint EndOffset; @@ -22,7 +23,7 @@ namespace R2RDump } [Flags] - enum SourceTypes + public enum SourceTypes { /// /// Indicates that no other options apply @@ -50,7 +51,7 @@ namespace R2RDump CallInstruction = 0x10 } - enum MappingTypes : int + public enum MappingTypes : int { NoMapping = -1, Prolog = -2, @@ -58,7 +59,7 @@ namespace R2RDump MaxMappingValue = Epilog } - enum ImplicitILArguments + public enum ImplicitILArguments { VarArgsHandle = -1, ReturnBuffer = -2, @@ -67,7 +68,7 @@ namespace R2RDump Max = Unknown } - enum VarLocType + public enum VarLocType { VLT_REG, // variable is in a register VLT_REG_BYREF, // address of the variable is in a register @@ -85,7 +86,7 @@ namespace R2RDump VLT_INVALID, } - struct VarLoc + public struct VarLoc { public VarLocType VarLocType; // What's stored in the Data# fields changes based on VarLocType and will be @@ -94,4 +95,30 @@ namespace R2RDump public int Data2; public int Data3; } + public class NativeVarInfoComparer : IComparer + { + public int Compare(NativeVarInfo left, NativeVarInfo right) + { + if (left.VariableNumber < right.VariableNumber) + { + return -1; + } + else if (left.VariableNumber > right.VariableNumber) + { + return 1; + } + else if (left.StartOffset < right.StartOffset) + { + return -1; + } + else if (left.StartOffset > right.StartOffset) + { + return 1; + } + else + { + return 0; + } + } + } } diff --git a/src/coreclr/src/tools/r2rdump/DisassemblingTypeProvider.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DisassemblingTypeProvider.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/DisassemblingTypeProvider.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DisassemblingTypeProvider.cs index 2a83e50..0351429 100644 --- a/src/coreclr/src/tools/r2rdump/DisassemblingTypeProvider.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DisassemblingTypeProvider.cs @@ -9,7 +9,7 @@ using System.Reflection; using System.Reflection.Metadata; using System.Text; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { public class DisassemblingGenericContext { diff --git a/src/coreclr/src/tools/r2rdump/EHInfo.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/EHInfo.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/EHInfo.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/EHInfo.cs index 82d5108..e4e02eb 100644 --- a/src/coreclr/src/tools/r2rdump/EHInfo.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/EHInfo.cs @@ -11,7 +11,7 @@ using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; using System.Text; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// If COR_ILMETHOD_SECT_HEADER::Kind() = CorILMethod_Sect_EHTable then the attribute diff --git a/src/coreclr/src/tools/r2rdump/GCInfoTypes.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/GCInfoTypes.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/GCInfoTypes.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/GCInfoTypes.cs index 2dcdce6..d740c8b 100644 --- a/src/coreclr/src/tools/r2rdump/GCInfoTypes.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/GCInfoTypes.cs @@ -6,7 +6,7 @@ using System; using System.Reflection.PortableExecutable; using System.Text; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// based on src\inc\gcinfotypes.h infoHdrAdjustConstants diff --git a/src/coreclr/src/tools/r2rdump/GCRefMap.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/GCRefMap.cs similarity index 72% rename from src/coreclr/src/tools/r2rdump/GCRefMap.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/GCRefMap.cs index ebd2bff..e1d19bd 100644 --- a/src/coreclr/src/tools/r2rdump/GCRefMap.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/GCRefMap.cs @@ -8,7 +8,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.IO; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { public enum CORCOMPILE_GCREFMAP_TOKENS { @@ -50,52 +50,6 @@ namespace R2RDump StackPop = stackPop; Entries = entries; } - - public void WriteTo(TextWriter writer) - { - if (StackPop != InvalidStackPop) - { - writer.Write(@"POP(0x{StackPop:X}) "); - } - for (int entryIndex = 0; entryIndex < Entries.Length; entryIndex++) - { - GCRefMapEntry entry = Entries[entryIndex]; - if (entryIndex == 0 || entry.Token != Entries[entryIndex - 1].Token) - { - if (entryIndex != 0) - { - writer.Write(") "); - } - switch (entry.Token) - { - case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_REF: - writer.Write("R"); - break; - case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_INTERIOR: - writer.Write("I"); - break; - case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_METHOD_PARAM: - writer.Write("M"); - break; - case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_TYPE_PARAM: - writer.Write("T"); - break; - case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_VASIG_COOKIE: - writer.Write("V"); - break; - default: - throw new NotImplementedException(); - } - writer.Write("("); - } - else - { - writer.Write(" "); - } - writer.Write($"{entry.Offset:X2}"); - } - writer.Write(")"); - } } /// diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/IAssemblyResolver.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/IAssemblyResolver.cs new file mode 100644 index 0000000..b58344c --- /dev/null +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/IAssemblyResolver.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ILCompiler.Reflection.ReadyToRun +{ + public interface IAssemblyResolver + { + string FindAssembly(string name, string filename); + // TODO (refactoring) - signature formatting options should be independent of assembly resolver + bool Naked { get; } + bool SignatureBinary { get; } + bool InlineSignatureBinary { get; } + } +} diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj new file mode 100644 index 0000000..efdbb9c --- /dev/null +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj @@ -0,0 +1,27 @@ + + + ILCompiler.Reflection.ReadyToRun + 1.0.0.0 + true + Library + AnyCPU + Open + true + netstandard2.0 + false + 8002,NU1701 + win-x64;win-x86 + $(BinDir) + + + + + 1.6.0 + + + + + + + + diff --git a/src/coreclr/src/tools/r2rdump/NativeArray.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeArray.cs similarity index 95% rename from src/coreclr/src/tools/r2rdump/NativeArray.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeArray.cs index 0e62085..a7d03d4 100644 --- a/src/coreclr/src/tools/r2rdump/NativeArray.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeArray.cs @@ -4,13 +4,14 @@ using System.Text; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// based on NativeFormat::NativeArray /// - class NativeArray + public class NativeArray { + // TODO (refactoring) - all these Native* class should be private private const int _blockSize = 16; private uint _baseOffset; private uint _nElements; diff --git a/src/coreclr/src/tools/r2rdump/NativeHashtable.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs similarity index 96% rename from src/coreclr/src/tools/r2rdump/NativeHashtable.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs index 6547d6a..abfd966 100644 --- a/src/coreclr/src/tools/r2rdump/NativeHashtable.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs @@ -5,13 +5,14 @@ using System.Collections.Generic; using System.Text; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// based on NativeFormat::NativeParser /// - struct NativeParser + public struct NativeParser { + // TODO (refactoring) - all these Native* class should be private /// /// The current index of the image byte array /// @@ -82,8 +83,9 @@ namespace R2RDump /// /// based on NativeFormat::NativeHashtable /// - struct NativeHashtable + public struct NativeHashtable { + // TODO (refactoring) - all these Native* class should be private private byte[] _image; private uint _baseOffset; private uint _bucketMask; @@ -242,8 +244,9 @@ namespace R2RDump /// /// based on NativeFormat::NativeHashtable /// - struct NativeCuckooFilter + public struct NativeCuckooFilter { + // TODO (refactoring) - all these Native* class should be private private byte[] _image; private int _filterStartOffset; private int _filterEndOffset; diff --git a/src/coreclr/src/tools/r2rdump/NativeReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeReader.cs similarity index 98% rename from src/coreclr/src/tools/r2rdump/NativeReader.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeReader.cs index cb5023d..8e60b42 100644 --- a/src/coreclr/src/tools/r2rdump/NativeReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NativeReader.cs @@ -6,10 +6,11 @@ using System; using System.Collections.Generic; using System.Text; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { - class NativeReader + public class NativeReader { + // TODO (refactoring) - all these Native* class should be private private const int BITS_PER_BYTE = 8; private const int BITS_PER_SIZE_T = 32; diff --git a/src/coreclr/src/tools/r2rdump/NibbleReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs similarity index 98% rename from src/coreclr/src/tools/r2rdump/NibbleReader.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs index 0f5ac7c..45b51d3 100644 --- a/src/coreclr/src/tools/r2rdump/NibbleReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// Helper to read memory by 4-bit (half-byte) nibbles as is used for encoding diff --git a/src/coreclr/src/tools/r2rdump/R2RHeader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RHeader.cs similarity index 96% rename from src/coreclr/src/tools/r2rdump/R2RHeader.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RHeader.cs index 1c39e29..7b73cc6 100644 --- a/src/coreclr/src/tools/r2rdump/R2RHeader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RHeader.cs @@ -8,7 +8,7 @@ using System.Text; using Internal.ReadyToRunConstants; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// based on src/inc/readytorun.h READYTORUN_HEADER @@ -88,7 +88,8 @@ namespace R2RDump var sectionType = (R2RSection.SectionType)type; if (!Enum.IsDefined(typeof(R2RSection.SectionType), type)) { - R2RDump.WriteWarning("Invalid ReadyToRun section type"); + // TODO (refactoring) - what should we do? + // R2RDump.WriteWarning("Invalid ReadyToRun section type"); } Sections[sectionType] = new R2RSection(sectionType, NativeReader.ReadInt32(image, ref curOffset), diff --git a/src/coreclr/src/tools/r2rdump/R2RImportSection.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RImportSection.cs similarity index 88% rename from src/coreclr/src/tools/r2rdump/R2RImportSection.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RImportSection.cs index 65f266e..dc4e123 100644 --- a/src/coreclr/src/tools/r2rdump/R2RImportSection.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RImportSection.cs @@ -10,7 +10,7 @@ using System.Xml.Serialization; using Internal.CorConstants; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// based on src/inc/readytorun.h READYTORUN_IMPORT_SECTION @@ -41,24 +41,6 @@ namespace R2RDump SignatureRVA = signatureRVA; Signature = signature; } - - public void WriteTo(TextWriter writer, DumpOptions options) - { - if (!options.Naked) - { - writer.Write($"+{StartOffset:X4}"); - writer.Write($" ({StartRVA:X4})"); - writer.Write($" Section: 0x{Section:X8}"); - writer.Write($" SignatureRVA: 0x{SignatureRVA:X8}"); - writer.Write(" "); - } - writer.Write(Signature); - if (GCRefMap != null) - { - writer.Write(" -- "); - GCRefMap.WriteTo(writer); - } - } } [XmlAttribute("Index")] diff --git a/src/coreclr/src/tools/r2rdump/R2RMethod.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RMethod.cs similarity index 55% rename from src/coreclr/src/tools/r2rdump/R2RMethod.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RMethod.cs index 8070311..47e353c 100644 --- a/src/coreclr/src/tools/r2rdump/R2RMethod.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RMethod.cs @@ -12,7 +12,7 @@ using System.Reflection.Metadata.Ecma335; using System.Text; using System.Xml.Serialization; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { public abstract class BaseUnwindInfo { @@ -141,126 +141,6 @@ namespace R2RDump method.GcInfo = gcInfo; EHInfo = ehInfo; } - - public void WriteTo(TextWriter writer, DumpOptions options) - { - if (!options.Naked) - { - writer.WriteLine($"Id: {Id}"); - writer.WriteLine($"StartAddress: 0x{StartAddress:X8}"); - } - if (Size == -1) - { - writer.WriteLine("Size: Unavailable"); - } - else - { - writer.WriteLine($"Size: {Size} bytes"); - } - if (!options.Naked) - { - writer.WriteLine($"UnwindRVA: 0x{UnwindRVA:X8}"); - } - if (UnwindInfo is Amd64.UnwindInfo amd64UnwindInfo) - { - string parsedFlags = ""; - if ((amd64UnwindInfo.Flags & (int)Amd64.UnwindFlags.UNW_FLAG_EHANDLER) != 0) - { - parsedFlags += " EHANDLER"; - } - if ((amd64UnwindInfo.Flags & (int)Amd64.UnwindFlags.UNW_FLAG_UHANDLER) != 0) - { - parsedFlags += " UHANDLER"; - } - if ((amd64UnwindInfo.Flags & (int)Amd64.UnwindFlags.UNW_FLAG_CHAININFO) != 0) - { - parsedFlags += " CHAININFO"; - } - if (parsedFlags.Length == 0) - { - parsedFlags = " NHANDLER"; - } - writer.WriteLine($"Version: {amd64UnwindInfo.Version}"); - writer.WriteLine($"Flags: 0x{amd64UnwindInfo.Flags:X2}{parsedFlags}"); - writer.WriteLine($"SizeOfProlog: 0x{amd64UnwindInfo.SizeOfProlog:X4}"); - writer.WriteLine($"CountOfUnwindCodes: {amd64UnwindInfo.CountOfUnwindCodes}"); - writer.WriteLine($"FrameRegister: {amd64UnwindInfo.FrameRegister}"); - writer.WriteLine($"FrameOffset: 0x{amd64UnwindInfo.FrameOffset}"); - if (!options.Naked) - { - writer.WriteLine($"PersonalityRVA: 0x{amd64UnwindInfo.PersonalityRoutineRVA:X4}"); - } - - for (int unwindCodeIndex = 0; unwindCodeIndex < amd64UnwindInfo.CountOfUnwindCodes; unwindCodeIndex++) - { - Amd64.UnwindCode unwindCode = amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex]; - writer.Write($"UnwindCode[{unwindCode.Index}]: "); - writer.Write($"CodeOffset 0x{unwindCode.CodeOffset:X4} "); - writer.Write($"FrameOffset 0x{unwindCode.FrameOffset:X4} "); - writer.Write($"NextOffset 0x{unwindCode.NextFrameOffset} "); - writer.Write($"Op {unwindCode.OpInfoStr}"); - writer.WriteLine(); - } - } - writer.WriteLine(); - - if (Method.GcInfo is Amd64.GcInfo gcInfo) - { - writer.WriteLine("GC info:"); - writer.WriteLine($@" Version: {gcInfo.Version}"); - writer.WriteLine($@" ReturnKind: {gcInfo.ReturnKind}"); - writer.WriteLine($@" ValidRangeStart: 0x{gcInfo.ValidRangeStart:X4}"); - writer.WriteLine($@" ValidRangeEnd: 0x{gcInfo.ValidRangeEnd:X4}"); - writer.WriteLine($@" SecurityObjectStackSlot: 0x{gcInfo.SecurityObjectStackSlot:X4}"); - writer.WriteLine($@" GSCookieStackSlot: 0x{gcInfo.GSCookieStackSlot:X4}"); - writer.WriteLine($@" PSPSymStackSlot: 0x{gcInfo.PSPSymStackSlot:X4}"); - writer.WriteLine($@" GenericsInstContextStackSlot: 0x{gcInfo.GenericsInstContextStackSlot:X4}"); - writer.WriteLine($@" StackBaseRegister: {gcInfo.StackBaseRegister}"); - writer.WriteLine($@" SizeOfENCPreservedArea: 0x{gcInfo.SizeOfEditAndContinuePreservedArea:X4}"); - writer.WriteLine($@" ReversePInvokeFrameStackSlot: 0x{gcInfo.ReversePInvokeFrameStackSlot:X4}"); - writer.WriteLine($@" SizeOfStackOutgoingAndScratchArea: 0x{gcInfo.SizeOfStackOutgoingAndScratchArea:X4}"); - writer.WriteLine($@" NumSafePoints: {gcInfo.NumSafePoints}"); - writer.WriteLine($@" NumInterruptibleRanges: {gcInfo.NumInterruptibleRanges}"); - - writer.WriteLine($@" SafePointOffsets: {gcInfo.SafePointOffsets.Count}"); - foreach (Amd64.GcInfo.SafePointOffset safePoint in gcInfo.SafePointOffsets) - { - writer.WriteLine($@" Index: {safePoint.Index,2}; Value: 0x{safePoint.Value:X4}"); - if (gcInfo.LiveSlotsAtSafepoints != null) - writer.WriteLine($@" Live slots: {String.Join(", ", gcInfo.LiveSlotsAtSafepoints[safePoint.Index])}"); - } - - writer.WriteLine($@" InterruptibleRanges: {gcInfo.InterruptibleRanges.Count}"); - foreach (Amd64.InterruptibleRange range in gcInfo.InterruptibleRanges) - { - writer.WriteLine($@" Index: {range.Index,2}; StartOffset: 0x{range.StartOffset:X4}; StopOffset: 0x{range.StopOffset:X4}"); - } - - writer.WriteLine(" SlotTable:"); - writer.WriteLine($@" NumRegisters: {gcInfo.SlotTable.NumRegisters}"); - writer.WriteLine($@" NumStackSlots: {gcInfo.SlotTable.NumStackSlots}"); - writer.WriteLine($@" NumUntracked: {gcInfo.SlotTable.NumUntracked}"); - writer.WriteLine($@" NumSlots: {gcInfo.SlotTable.NumSlots}"); - writer.WriteLine($@" GcSlots: {gcInfo.SlotTable.GcSlots.Count}"); - foreach (Amd64.GcSlotTable.GcSlot slot in gcInfo.SlotTable.GcSlots) - { - writer.WriteLine($@" Index: {slot.Index,2}; RegisterNumber: {slot.RegisterNumber,2}; Flags: {slot.Flags}"); - } - writer.WriteLine(); - } - - if (EHInfo != null) - { - writer.WriteLine($@"EH info @ {EHInfo.EHInfoRVA:X4}, #clauses = {EHInfo.EHClauses.Length}"); - EHInfo.WriteTo(writer); - writer.WriteLine(); - } - - if (DebugInfo != null) - { - DebugInfo.WriteTo(writer, options); - } - } } public class R2RMethod @@ -427,37 +307,5 @@ namespace R2RDump SignatureString = sb.ToString(); } - - public void WriteTo(TextWriter writer, DumpOptions options) - { - writer.WriteLine(SignatureString); - - writer.WriteLine($"Handle: 0x{MetadataTokens.GetToken(MetadataReader, MethodHandle):X8}"); - writer.WriteLine($"Rid: {MetadataTokens.GetRowNumber(MetadataReader, MethodHandle)}"); - if (!options.Naked) - { - writer.WriteLine($"EntryPointRuntimeFunctionId: {EntryPointRuntimeFunctionId}"); - } - writer.WriteLine($"Number of RuntimeFunctions: {RuntimeFunctions.Count}"); - if (Fixups != null) - { - writer.WriteLine($"Number of fixups: {Fixups.Count()}"); - IEnumerable fixups = Fixups; - if (options.Normalize) - { - fixups = fixups.OrderBy((fc) => fc.Signature); - } - - foreach (FixupCell cell in fixups) - { - writer.Write(" "); - if (!options.Naked) - { - writer.Write($"TableIndex {cell.TableIndex}, Offset {cell.CellOffset:X4}: "); - } - writer.WriteLine(cell.Signature); - } - } - } } } diff --git a/src/coreclr/src/tools/r2rdump/R2RReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RReader.cs similarity index 96% rename from src/coreclr/src/tools/r2rdump/R2RReader.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RReader.cs index c934882..d7ae54d 100644 --- a/src/coreclr/src/tools/r2rdump/R2RReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RReader.cs @@ -15,7 +15,7 @@ using System.Xml.Serialization; using Internal.CorConstants; using Internal.ReadyToRunConstants; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// This structure represents a single precode fixup cell decoded from the @@ -80,10 +80,9 @@ namespace R2RDump public class EcmaMetadataReader { - /// - /// Option are used to specify details of signature formatting. - /// - public readonly DumpOptions Options; + protected IAssemblyResolver _assemblyResolver; + protected Dictionary _assemblyCache; + /// /// Underlying PE image reader is used to access raw PE structures like header @@ -132,9 +131,10 @@ namespace R2RDump /// PE image /// List of reference assemblies from the R2R metadata manifest /// The Cor header flag must be ILLibrary - public unsafe EcmaMetadataReader(DumpOptions options, string filename, List manifestReferenceAssemblies) + public unsafe EcmaMetadataReader(IAssemblyResolver assemblyResolver, string filename, List manifestReferenceAssemblies) { - Options = options; + _assemblyResolver = assemblyResolver; + _assemblyCache = new Dictionary(); Filename = filename; ManifestReferenceAssemblies = manifestReferenceAssemblies; Image = File.ReadAllBytes(filename); @@ -178,15 +178,15 @@ namespace R2RDump } EcmaMetadataReader ecmaReader; - if (!Options.AssemblyCache.TryGetValue(name, out ecmaReader)) + if (!_assemblyCache.TryGetValue(name, out ecmaReader)) { - string assemblyPath = Options.FindAssembly(name, Filename); + string assemblyPath = _assemblyResolver.FindAssembly(name, Filename); if (assemblyPath == null) { throw new Exception($"Missing reference assembly: {name}"); } - ecmaReader = new EcmaMetadataReader(Options, assemblyPath, ManifestReferenceAssemblies); - Options.AssemblyCache.Add(name, ecmaReader); + ecmaReader = new EcmaMetadataReader(_assemblyResolver, assemblyPath, ManifestReferenceAssemblies); + _assemblyCache.Add(name, ecmaReader); } return ecmaReader; } @@ -274,8 +274,8 @@ namespace R2RDump /// /// PE image /// The Cor header flag must be ILLibrary - public unsafe R2RReader(DumpOptions options, string filename) - : base(options, filename, new List()) + public unsafe R2RReader(IAssemblyResolver assemblyResolver, string filename) + : base(assemblyResolver, filename, new List()) { IsR2R = ((PEReader.PEHeaders.CorHeader.Flags & CorFlags.ILLibrary) != 0); if (!IsR2R) @@ -470,7 +470,7 @@ namespace R2RDump NativeParser curParser = allEntriesEnum.GetNext(); while (!curParser.IsNull()) { - SignatureDecoder decoder = new SignatureDecoder(Options, this, (int)curParser.Offset); + SignatureDecoder decoder = new SignatureDecoder(_assemblyResolver, this, (int)curParser.Offset); MetadataReader mdReader = MetadataReader; string owningType = null; @@ -595,13 +595,15 @@ namespace R2RDump } EHInfo ehInfo = null; - EHInfoLocation ehInfoLocation; if (EHLookupTable != null && EHLookupTable.RuntimeFunctionToEHInfoMap.TryGetValue(startRva, out ehInfoLocation)) { ehInfo = new EHInfo(this, ehInfoLocation.EHInfoRVA, startRva, GetOffset(ehInfoLocation.EHInfoRVA), ehInfoLocation.ClauseCount); } + DebugInfo debugInfo; + _runtimeFunctionToDebugInfo.TryGetValue(runtimeFunctionId, out debugInfo); + RuntimeFunction rtf = new RuntimeFunction( runtimeFunctionId, startRva, @@ -612,7 +614,7 @@ namespace R2RDump unwindInfo, gcInfo, ehInfo, - _runtimeFunctionToDebugInfo.GetValueOrDefault(runtimeFunctionId)); + debugInfo); method.RuntimeFunctions.Add(rtf); runtimeFunctionId++; @@ -736,7 +738,7 @@ namespace R2RDump long section = NativeReader.ReadInt64(Image, ref sectionOffset); uint sigRva = NativeReader.ReadUInt32(Image, ref signatureOffset); int sigOffset = GetOffset((int)sigRva); - string cellName = MetadataNameFormatter.FormatSignature(Options, this, sigOffset); + string cellName = MetadataNameFormatter.FormatSignature(_assemblyResolver, this, sigOffset); entries.Add(new R2RImportSection.ImportSectionEntry(entries.Count, entryOffset, entryOffset + rva, section, sigRva, cellName)); ImportCellNames.Add(rva + entrySize * i, cellName); } @@ -770,7 +772,7 @@ namespace R2RDump continue; } - var debugInfo = new DebugInfo(Image, offset, Machine, Options.Normalize); + var debugInfo = new DebugInfo(Image, offset, Machine); _runtimeFunctionToDebugInfo.Add((int)i, debugInfo); } } diff --git a/src/coreclr/src/tools/r2rdump/R2RSection.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RSection.cs similarity index 83% rename from src/coreclr/src/tools/r2rdump/R2RSection.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RSection.cs index 0eca7e9..3b54cbb 100644 --- a/src/coreclr/src/tools/r2rdump/R2RSection.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RSection.cs @@ -8,7 +8,7 @@ using System.IO; using System.Text; using System.Xml.Serialization; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { public struct R2RSection { @@ -55,16 +55,6 @@ namespace R2RDump Size = size; } - public void WriteTo(TextWriter writer, DumpOptions options) - { - writer.WriteLine($"Type: {Enum.GetName(typeof(SectionType), Type)} ({Type:D})"); - if (!options.Naked) - { - writer.WriteLine($"RelativeVirtualAddress: 0x{RelativeVirtualAddress:X8}"); - } - writer.WriteLine($"Size: {Size} bytes"); - } - public override string ToString() { throw new NotImplementedException(); diff --git a/src/coreclr/src/tools/r2rdump/R2RSignature.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RSignature.cs similarity index 98% rename from src/coreclr/src/tools/r2rdump/R2RSignature.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RSignature.cs index b08e507..40a2bd3 100644 --- a/src/coreclr/src/tools/r2rdump/R2RSignature.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RSignature.cs @@ -10,7 +10,7 @@ using System.Text; using Internal.CorConstants; using Internal.ReadyToRunConstants; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { /// /// Helper class for converting metadata tokens into their textual representation. @@ -39,9 +39,9 @@ namespace R2RDump return formatter.EmitHandleName(handle, namespaceQualified, owningTypeOverride, signaturePrefix); } - public static string FormatSignature(DumpOptions options, EcmaMetadataReader ecmaReader, int imageOffset) + public static string FormatSignature(IAssemblyResolver assemblyResolver, EcmaMetadataReader ecmaReader, int imageOffset) { - SignatureDecoder decoder = new SignatureDecoder(options, ecmaReader, imageOffset); + SignatureDecoder decoder = new SignatureDecoder(assemblyResolver, ecmaReader, imageOffset); string result = decoder.ReadR2RSignature(); return result; } @@ -358,7 +358,7 @@ namespace R2RDump /// /// Dump options are used to specify details of signature formatting. /// - private readonly DumpOptions _options; + private readonly IAssemblyResolver _options; /// /// Byte array representing the R2R PE file read from disk. @@ -381,7 +381,7 @@ namespace R2RDump /// Dump options and paths /// EcmaMetadataReader object representing the PE file containing the ECMA metadata /// Signature offset within the PE file byte array - public SignatureDecoder(DumpOptions options, EcmaMetadataReader ecmaReader, int offset) + public SignatureDecoder(IAssemblyResolver options, EcmaMetadataReader ecmaReader, int offset) { _ecmaReader = ecmaReader; _options = options; @@ -398,7 +398,7 @@ namespace R2RDump /// Signature to parse /// Signature offset within the signature byte array /// Top-level signature context reader - public SignatureDecoder(DumpOptions options, EcmaMetadataReader ecmaReader, byte[] signature, int offset, EcmaMetadataReader contextReader) + public SignatureDecoder(IAssemblyResolver options, EcmaMetadataReader ecmaReader, byte[] signature, int offset, EcmaMetadataReader contextReader) { _ecmaReader = ecmaReader; _options = options; @@ -559,7 +559,7 @@ namespace R2RDump return builder.ToString(); } - private void EmitInlineSignatureBinaryFrom(StringBuilder builder, int startOffset) + private void EmitInlineSignatureBinaryForm(StringBuilder builder, int startOffset) { EmitInlineSignatureBinaryBytes(builder, _offset - startOffset); } @@ -589,7 +589,7 @@ namespace R2RDump { int startOffset = _offset; uint value = ReadUInt(); - EmitInlineSignatureBinaryFrom(builder, startOffset); + EmitInlineSignatureBinaryForm(builder, startOffset); return value; } @@ -597,7 +597,7 @@ namespace R2RDump { int startOffset = _offset; int value = ReadInt(); - EmitInlineSignatureBinaryFrom(builder, startOffset); + EmitInlineSignatureBinaryForm(builder, startOffset); return value; } @@ -605,7 +605,7 @@ namespace R2RDump { int startOffset = _offset; uint value = ReadToken(); - EmitInlineSignatureBinaryFrom(builder, startOffset); + EmitInlineSignatureBinaryForm(builder, startOffset); return value; } diff --git a/src/coreclr/src/tools/r2rdump/TransitionBlock.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/TransitionBlock.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs index 46a1724..28deb28 100644 --- a/src/coreclr/src/tools/r2rdump/TransitionBlock.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs @@ -8,7 +8,7 @@ using System.Reflection.PortableExecutable; using System.Runtime.InteropServices; using System.IO; -namespace R2RDump +namespace ILCompiler.Reflection.ReadyToRun { public abstract class TransitionBlock { diff --git a/src/coreclr/src/tools/r2rdump/x86/CallPattern.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/CallPattern.cs similarity index 98% rename from src/coreclr/src/tools/r2rdump/x86/CallPattern.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/CallPattern.cs index 15a1dba..982095f 100644 --- a/src/coreclr/src/tools/r2rdump/x86/CallPattern.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/CallPattern.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace R2RDump.x86 +namespace ILCompiler.Reflection.ReadyToRun.x86 { class CallPattern { diff --git a/src/coreclr/src/tools/r2rdump/x86/GcInfo.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/x86/GcInfo.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs index da1f074..4e4762a 100644 --- a/src/coreclr/src/tools/r2rdump/x86/GcInfo.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs @@ -8,7 +8,7 @@ using System.Reflection.PortableExecutable; using System.Text; using System.Xml.Serialization; -namespace R2RDump.x86 +namespace ILCompiler.Reflection.ReadyToRun.x86 { public class GcInfo : BaseGcInfo { diff --git a/src/coreclr/src/tools/r2rdump/x86/GcSlotTable.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/x86/GcSlotTable.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs index fd72da5..7983bfb 100644 --- a/src/coreclr/src/tools/r2rdump/x86/GcSlotTable.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs @@ -8,7 +8,7 @@ using System.Reflection.PortableExecutable; using System.Text; using System.Xml.Serialization; -namespace R2RDump.x86 +namespace ILCompiler.Reflection.ReadyToRun.x86 { public class GcSlotTable { diff --git a/src/coreclr/src/tools/r2rdump/x86/GcTransition.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcTransition.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/x86/GcTransition.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcTransition.cs index a103d74..2b21370 100644 --- a/src/coreclr/src/tools/r2rdump/x86/GcTransition.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/GcTransition.cs @@ -6,7 +6,7 @@ using System; using System.Collections.Generic; using System.Text; -namespace R2RDump.x86 +namespace ILCompiler.Reflection.ReadyToRun.x86 { public enum Action { diff --git a/src/coreclr/src/tools/r2rdump/x86/InfoHdr.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs similarity index 99% rename from src/coreclr/src/tools/r2rdump/x86/InfoHdr.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs index a36b3d9..9d457fb 100644 --- a/src/coreclr/src/tools/r2rdump/x86/InfoHdr.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Text; using System.Xml.Serialization; -namespace R2RDump.x86 +namespace ILCompiler.Reflection.ReadyToRun.x86 { /// /// based on src\inc\gcinfotypes.h InfoHdrSmall diff --git a/src/coreclr/src/tools/r2rdump/x86/Registers.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/Registers.cs similarity index 95% rename from src/coreclr/src/tools/r2rdump/x86/Registers.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/Registers.cs index 69763b0..b38f653 100644 --- a/src/coreclr/src/tools/r2rdump/x86/Registers.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/Registers.cs @@ -6,7 +6,7 @@ using System; using System.Collections.Generic; using System.Text; -namespace R2RDump.x86 +namespace ILCompiler.Reflection.ReadyToRun.x86 { /// /// based on src\gcdump\i386\gcdumpx86.cpp RegName diff --git a/src/coreclr/src/tools/r2rdump/x86/UnwindInfo.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs similarity index 95% rename from src/coreclr/src/tools/r2rdump/x86/UnwindInfo.cs rename to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs index 60fe13d..5f4a329 100644 --- a/src/coreclr/src/tools/r2rdump/x86/UnwindInfo.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs @@ -5,7 +5,7 @@ using System.Text; using System.Xml.Serialization; -namespace R2RDump.x86 +namespace ILCompiler.Reflection.ReadyToRun.x86 { /// /// based on src\inc\win64unwind.h _UNWIND_INFO diff --git a/src/coreclr/src/tools/r2rdump/CoreDisTools.cs b/src/coreclr/src/tools/r2rdump/CoreDisTools.cs index 5fad8f4..69ae7f6 100644 --- a/src/coreclr/src/tools/r2rdump/CoreDisTools.cs +++ b/src/coreclr/src/tools/r2rdump/CoreDisTools.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using ILCompiler.Reflection.ReadyToRun; using System; using System.Collections.Generic; using System.Reflection.PortableExecutable; diff --git a/src/coreclr/src/tools/r2rdump/Extensions.cs b/src/coreclr/src/tools/r2rdump/Extensions.cs new file mode 100644 index 0000000..c359bc2 --- /dev/null +++ b/src/coreclr/src/tools/r2rdump/Extensions.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using ILCompiler.Reflection.ReadyToRun; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection.Metadata.Ecma335; +using System.Text; + +namespace R2RDump +{ + internal static class Extensions + { + public static void WriteTo(this DebugInfo theThis, TextWriter writer, DumpOptions dumpOptions) + { + if (theThis.BoundsList.Count > 0) + writer.WriteLine("Debug Info"); + + writer.WriteLine("\tBounds:"); + for (int i = 0; i < theThis.BoundsList.Count; ++i) + { + writer.Write('\t'); + if (!dumpOptions.Naked) + { + writer.Write($"Native Offset: 0x{theThis.BoundsList[i].NativeOffset:X}, "); + } + writer.WriteLine($"IL Offset: 0x{theThis.BoundsList[i].ILOffset:X}, Source Types: {theThis.BoundsList[i].SourceTypes}"); + } + + writer.WriteLine(""); + + if (dumpOptions.Normalize) + { + theThis.VariablesList.Sort(new NativeVarInfoComparer()); + } + + if (theThis.VariablesList.Count > 0) + writer.WriteLine("\tVariable Locations:"); + + for (int i = 0; i < theThis.VariablesList.Count; ++i) + { + var varLoc = theThis.VariablesList[i]; + writer.WriteLine($"\tVariable Number: {varLoc.VariableNumber}"); + writer.WriteLine($"\tStart Offset: 0x{varLoc.StartOffset:X}"); + writer.WriteLine($"\tEnd Offset: 0x{varLoc.EndOffset:X}"); + writer.WriteLine($"\tLoc Type: {varLoc.VariableLocation.VarLocType}"); + + switch (varLoc.VariableLocation.VarLocType) + { + case VarLocType.VLT_REG: + case VarLocType.VLT_REG_FP: + case VarLocType.VLT_REG_BYREF: + writer.WriteLine($"\tRegister: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}"); + break; + case VarLocType.VLT_STK: + case VarLocType.VLT_STK_BYREF: + writer.WriteLine($"\tBase Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}"); + writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data2}"); + break; + case VarLocType.VLT_REG_REG: + writer.WriteLine($"\tRegister 1: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}"); + writer.WriteLine($"\tRegister 2: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data2)}"); + break; + case VarLocType.VLT_REG_STK: + writer.WriteLine($"\tRegister: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}"); + writer.WriteLine($"\tBase Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data2)}"); + writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data3}"); + break; + case VarLocType.VLT_STK_REG: + writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data1}"); + writer.WriteLine($"\tBase Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data2)}"); + writer.WriteLine($"\tRegister: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data3)}"); + break; + case VarLocType.VLT_STK2: + writer.WriteLine($"\tBase Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}"); + writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data2}"); + break; + case VarLocType.VLT_FPSTK: + writer.WriteLine($"\tOffset: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}"); + break; + case VarLocType.VLT_FIXED_VA: + writer.WriteLine($"\tOffset: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}"); + break; + default: + throw new BadImageFormatException("Unexpected var loc type"); + } + + writer.WriteLine(""); + } + } + + public static void WriteTo(this R2RImportSection.ImportSectionEntry theThis, TextWriter writer, DumpOptions options) + { + if (!options.Naked) + { + writer.Write($"+{theThis.StartOffset:X4}"); + writer.Write($" ({theThis.StartRVA:X4})"); + writer.Write($" Section: 0x{theThis.Section:X8}"); + writer.Write($" SignatureRVA: 0x{theThis.SignatureRVA:X8}"); + writer.Write(" "); + } + writer.Write(theThis.Signature); + if (theThis.GCRefMap != null) + { + writer.Write(" -- "); + theThis.GCRefMap.WriteTo(writer); + } + } + + public static void WriteTo(this R2RSection theThis, TextWriter writer, DumpOptions options) + { + writer.WriteLine($"Type: {Enum.GetName(typeof(R2RSection.SectionType), theThis.Type)} ({theThis.Type:D})"); + if (!options.Naked) + { + writer.WriteLine($"RelativeVirtualAddress: 0x{theThis.RelativeVirtualAddress:X8}"); + } + writer.WriteLine($"Size: {theThis.Size} bytes"); + } + + public static void WriteTo(this R2RMethod theThis, TextWriter writer, DumpOptions options) + { + writer.WriteLine(theThis.SignatureString); + + writer.WriteLine($"Handle: 0x{MetadataTokens.GetToken(theThis.MetadataReader, theThis.MethodHandle):X8}"); + writer.WriteLine($"Rid: {MetadataTokens.GetRowNumber(theThis.MetadataReader, theThis.MethodHandle)}"); + if (!options.Naked) + { + writer.WriteLine($"EntryPointRuntimeFunctionId: {theThis.EntryPointRuntimeFunctionId}"); + } + writer.WriteLine($"Number of RuntimeFunctions: {theThis.RuntimeFunctions.Count}"); + if (theThis.Fixups != null) + { + writer.WriteLine($"Number of fixups: {theThis.Fixups.Count()}"); + IEnumerable fixups = theThis.Fixups; + if (options.Normalize) + { + fixups = fixups.OrderBy((fc) => fc.Signature); + } + + foreach (FixupCell cell in fixups) + { + writer.Write(" "); + if (!options.Naked) + { + writer.Write($"TableIndex {cell.TableIndex}, Offset {cell.CellOffset:X4}: "); + } + writer.WriteLine(cell.Signature); + } + } + } + + public static void WriteTo(this RuntimeFunction theThis, TextWriter writer, DumpOptions options) + { + if (!options.Naked) + { + writer.WriteLine($"Id: {theThis.Id}"); + writer.WriteLine($"StartAddress: 0x{theThis.StartAddress:X8}"); + } + if (theThis.Size == -1) + { + writer.WriteLine("Size: Unavailable"); + } + else + { + writer.WriteLine($"Size: {theThis.Size} bytes"); + } + if (!options.Naked) + { + writer.WriteLine($"UnwindRVA: 0x{theThis.UnwindRVA:X8}"); + } + if (theThis.UnwindInfo is ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo amd64UnwindInfo) + { + string parsedFlags = ""; + if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_EHANDLER) != 0) + { + parsedFlags += " EHANDLER"; + } + if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_UHANDLER) != 0) + { + parsedFlags += " UHANDLER"; + } + if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_CHAININFO) != 0) + { + parsedFlags += " CHAININFO"; + } + if (parsedFlags.Length == 0) + { + parsedFlags = " NHANDLER"; + } + writer.WriteLine($"Version: {amd64UnwindInfo.Version}"); + writer.WriteLine($"Flags: 0x{amd64UnwindInfo.Flags:X2}{parsedFlags}"); + writer.WriteLine($"SizeOfProlog: 0x{amd64UnwindInfo.SizeOfProlog:X4}"); + writer.WriteLine($"CountOfUnwindCodes: {amd64UnwindInfo.CountOfUnwindCodes}"); + writer.WriteLine($"FrameRegister: {amd64UnwindInfo.FrameRegister}"); + writer.WriteLine($"FrameOffset: 0x{amd64UnwindInfo.FrameOffset}"); + if (!options.Naked) + { + writer.WriteLine($"PersonalityRVA: 0x{amd64UnwindInfo.PersonalityRoutineRVA:X4}"); + } + + for (int unwindCodeIndex = 0; unwindCodeIndex < amd64UnwindInfo.CountOfUnwindCodes; unwindCodeIndex++) + { + ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode unwindCode = amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex]; + writer.Write($"UnwindCode[{unwindCode.Index}]: "); + writer.Write($"CodeOffset 0x{unwindCode.CodeOffset:X4} "); + writer.Write($"FrameOffset 0x{unwindCode.FrameOffset:X4} "); + writer.Write($"NextOffset 0x{unwindCode.NextFrameOffset} "); + writer.Write($"Op {unwindCode.OpInfoStr}"); + writer.WriteLine(); + } + } + writer.WriteLine(); + + if (theThis.Method.GcInfo is ILCompiler.Reflection.ReadyToRun.Amd64.GcInfo gcInfo) + { + writer.WriteLine("GC info:"); + writer.WriteLine($@" Version: {gcInfo.Version}"); + writer.WriteLine($@" ReturnKind: {gcInfo.ReturnKind}"); + writer.WriteLine($@" ValidRangeStart: 0x{gcInfo.ValidRangeStart:X4}"); + writer.WriteLine($@" ValidRangeEnd: 0x{gcInfo.ValidRangeEnd:X4}"); + writer.WriteLine($@" SecurityObjectStackSlot: 0x{gcInfo.SecurityObjectStackSlot:X4}"); + writer.WriteLine($@" GSCookieStackSlot: 0x{gcInfo.GSCookieStackSlot:X4}"); + writer.WriteLine($@" PSPSymStackSlot: 0x{gcInfo.PSPSymStackSlot:X4}"); + writer.WriteLine($@" GenericsInstContextStackSlot: 0x{gcInfo.GenericsInstContextStackSlot:X4}"); + writer.WriteLine($@" StackBaseRegister: {gcInfo.StackBaseRegister}"); + writer.WriteLine($@" SizeOfENCPreservedArea: 0x{gcInfo.SizeOfEditAndContinuePreservedArea:X4}"); + writer.WriteLine($@" ReversePInvokeFrameStackSlot: 0x{gcInfo.ReversePInvokeFrameStackSlot:X4}"); + writer.WriteLine($@" SizeOfStackOutgoingAndScratchArea: 0x{gcInfo.SizeOfStackOutgoingAndScratchArea:X4}"); + writer.WriteLine($@" NumSafePoints: {gcInfo.NumSafePoints}"); + writer.WriteLine($@" NumInterruptibleRanges: {gcInfo.NumInterruptibleRanges}"); + + writer.WriteLine($@" SafePointOffsets: {gcInfo.SafePointOffsets.Count}"); + foreach (ILCompiler.Reflection.ReadyToRun.Amd64.GcInfo.SafePointOffset safePoint in gcInfo.SafePointOffsets) + { + writer.WriteLine($@" Index: {safePoint.Index,2}; Value: 0x{safePoint.Value:X4}"); + if (gcInfo.LiveSlotsAtSafepoints != null) + writer.WriteLine($@" Live slots: {String.Join(", ", gcInfo.LiveSlotsAtSafepoints[safePoint.Index])}"); + } + + writer.WriteLine($@" InterruptibleRanges: {gcInfo.InterruptibleRanges.Count}"); + foreach (ILCompiler.Reflection.ReadyToRun.Amd64.InterruptibleRange range in gcInfo.InterruptibleRanges) + { + writer.WriteLine($@" Index: {range.Index,2}; StartOffset: 0x{range.StartOffset:X4}; StopOffset: 0x{range.StopOffset:X4}"); + } + + writer.WriteLine(" SlotTable:"); + writer.WriteLine($@" NumRegisters: {gcInfo.SlotTable.NumRegisters}"); + writer.WriteLine($@" NumStackSlots: {gcInfo.SlotTable.NumStackSlots}"); + writer.WriteLine($@" NumUntracked: {gcInfo.SlotTable.NumUntracked}"); + writer.WriteLine($@" NumSlots: {gcInfo.SlotTable.NumSlots}"); + writer.WriteLine($@" GcSlots: {gcInfo.SlotTable.GcSlots.Count}"); + foreach (ILCompiler.Reflection.ReadyToRun.Amd64.GcSlotTable.GcSlot slot in gcInfo.SlotTable.GcSlots) + { + writer.WriteLine($@" Index: {slot.Index,2}; RegisterNumber: {slot.RegisterNumber,2}; Flags: {slot.Flags}"); + } + writer.WriteLine(); + } + + if (theThis.EHInfo != null) + { + writer.WriteLine($@"EH info @ {theThis.EHInfo.EHInfoRVA:X4}, #clauses = {theThis.EHInfo.EHClauses.Length}"); + theThis.EHInfo.WriteTo(writer); + writer.WriteLine(); + } + + if (theThis.DebugInfo != null) + { + theThis.DebugInfo.WriteTo(writer, options); + } + } + + public static void WriteTo(this GCRefMap theThis, TextWriter writer) + { + if (theThis.StackPop != GCRefMap.InvalidStackPop) + { + writer.Write(@"POP(0x{StackPop:X}) "); + } + for (int entryIndex = 0; entryIndex < theThis.Entries.Length; entryIndex++) + { + GCRefMapEntry entry = theThis.Entries[entryIndex]; + if (entryIndex == 0 || entry.Token != theThis.Entries[entryIndex - 1].Token) + { + if (entryIndex != 0) + { + writer.Write(") "); + } + switch (entry.Token) + { + case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_REF: + writer.Write("R"); + break; + case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_INTERIOR: + writer.Write("I"); + break; + case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_METHOD_PARAM: + writer.Write("M"); + break; + case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_TYPE_PARAM: + writer.Write("T"); + break; + case CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_VASIG_COOKIE: + writer.Write("V"); + break; + default: + throw new NotImplementedException(); + } + writer.Write("("); + } + else + { + writer.Write(" "); + } + writer.Write($"{entry.Offset:X2}"); + } + writer.Write(")"); + } + } +} diff --git a/src/coreclr/src/tools/r2rdump/R2RDiff.cs b/src/coreclr/src/tools/r2rdump/R2RDiff.cs index 7cbda55..27684ac 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDiff.cs +++ b/src/coreclr/src/tools/r2rdump/R2RDiff.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using ILCompiler.Reflection.ReadyToRun; using System; using System.Collections.Generic; using System.IO; diff --git a/src/coreclr/src/tools/r2rdump/R2RDump.cs b/src/coreclr/src/tools/r2rdump/R2RDump.cs index 95b2fbc..b0b3119 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDump.cs +++ b/src/coreclr/src/tools/r2rdump/R2RDump.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using ILCompiler.Reflection.ReadyToRun; using System; using System.Collections.Generic; using System.CommandLine; @@ -15,7 +16,7 @@ using System.Xml; namespace R2RDump { - public class DumpOptions + public class DumpOptions : IAssemblyResolver { public FileInfo[] In { get; set; } public FileInfo Out { get; set; } diff --git a/src/coreclr/src/tools/r2rdump/R2RDump.csproj b/src/coreclr/src/tools/r2rdump/R2RDump.csproj index 74e7908..84290c0 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDump.csproj +++ b/src/coreclr/src/tools/r2rdump/R2RDump.csproj @@ -15,11 +15,6 @@ - - - - - 1.0.1-prerelease-00005 @@ -29,5 +24,6 @@ 1.6.0 + diff --git a/src/coreclr/src/tools/r2rdump/TextDumper.cs b/src/coreclr/src/tools/r2rdump/TextDumper.cs index 6c157f9..4203e58 100644 --- a/src/coreclr/src/tools/r2rdump/TextDumper.cs +++ b/src/coreclr/src/tools/r2rdump/TextDumper.cs @@ -1,4 +1,9 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using ILCompiler.Reflection.ReadyToRun; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -189,10 +194,10 @@ namespace R2RDump string instr; int instrSize = _disassembler.GetInstruction(rtf, imageOffset, rtfOffset, out instr); - if (_r2r.Machine == Machine.Amd64 && ((Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes.ContainsKey(codeOffset)) + if (_r2r.Machine == Machine.Amd64 && ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes.ContainsKey(codeOffset)) { - List codes = ((Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes[codeOffset]; - foreach (Amd64.UnwindCode code in codes) + List codes = ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes[codeOffset]; + foreach (ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode code in codes) { _writer.Write($"{indentString}{code.UnwindOp} {code.OpInfoStr}"); if (code.NextFrameOffset != -1) diff --git a/src/coreclr/src/tools/r2rdump/XmlDumper.cs b/src/coreclr/src/tools/r2rdump/XmlDumper.cs index 06f840d..31b537c 100644 --- a/src/coreclr/src/tools/r2rdump/XmlDumper.cs +++ b/src/coreclr/src/tools/r2rdump/XmlDumper.cs @@ -1,4 +1,9 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using ILCompiler.Reflection.ReadyToRun; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -209,7 +214,7 @@ namespace R2RDump if (_options.Raw) { - DumpBytes(rtf.UnwindRVA, (uint)((Amd64.UnwindInfo)rtf.UnwindInfo).Size, unwindNode); + DumpBytes(rtf.UnwindRVA, (uint)((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).Size, unwindNode); } } } -- 2.7.4