using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.Amd64
+namespace ILCompiler.Reflection.ReadyToRun.Amd64
{
public class GcInfo : BaseGcInfo
{
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.Amd64
+namespace ILCompiler.Reflection.ReadyToRun.Amd64
{
public class GcSlotTable
{
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.Amd64
+namespace ILCompiler.Reflection.ReadyToRun.Amd64
{
public struct InterruptibleRange
{
using System.Collections.Generic;
using System.Text;
-namespace R2RDump.Amd64
+namespace ILCompiler.Reflection.ReadyToRun.Amd64
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/gcdump/gcdumpnonx86.cpp">src\gcdump\gcdumpnonx86.cpp</a> GetRegName
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.Amd64
+namespace ILCompiler.Reflection.ReadyToRun.Amd64
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/win64unwind.h">src\inc\win64unwind.h</a> _UNWIND_OP_CODES
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;
using System.Collections.Generic;
using System.Text;
-namespace R2RDump.Arm
+namespace ILCompiler.Reflection.ReadyToRun.Arm
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/jit/unwindarm.cpp">src/jit/unwindarm.cpp</a> mapRegNumToDwarfReg
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.Arm
+namespace ILCompiler.Reflection.ReadyToRun.Arm
{
public class Epilog
{
using System.Collections.Generic;
using System.Text;
-namespace R2RDump.Arm64
+namespace ILCompiler.Reflection.ReadyToRun.Arm64
{
public enum Registers
{
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.Arm64
+namespace ILCompiler.Reflection.ReadyToRun.Arm64
{
public class Epilog
{
using System.Reflection.PortableExecutable;
using System.Text;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// Represents the debug information for a single method in the ready-to-run image.
private List<DebugInfoBoundsEntry> _boundsList = new List<DebugInfoBoundsEntry>();
private List<NativeVarInfo> _variablesList = new List<NativeVarInfo>();
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;
}
}
- 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<DebugInfoBoundsEntry> BoundsList => _boundsList;
+ public List<NativeVarInfo> VariablesList => _variablesList;
+ public Machine Machine => _machine;
/// <summary>
/// Convert a register number in debug info into a machine-specific register
/// </summary>
- private static string GetPlatformSpecificRegister(Machine machine, int regnum)
+ public static string GetPlatformSpecificRegister(Machine machine, int regnum)
{
switch (machine)
{
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)
// 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;
}
[Flags]
- enum SourceTypes
+ public enum SourceTypes
{
/// <summary>
/// Indicates that no other options apply
CallInstruction = 0x10
}
- enum MappingTypes : int
+ public enum MappingTypes : int
{
NoMapping = -1,
Prolog = -2,
MaxMappingValue = Epilog
}
- enum ImplicitILArguments
+ public enum ImplicitILArguments
{
VarArgsHandle = -1,
ReturnBuffer = -2,
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
VLT_INVALID,
}
- struct VarLoc
+ public struct VarLoc
{
public VarLocType VarLocType;
// What's stored in the Data# fields changes based on VarLocType and will be
public int Data2;
public int Data3;
}
+ public class NativeVarInfoComparer : IComparer<NativeVarInfo>
+ {
+ 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;
+ }
+ }
+ }
}
using System.Reflection.Metadata;
using System.Text;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
public class DisassemblingGenericContext
{
using System.Reflection.PortableExecutable;
using System.Text;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// If COR_ILMETHOD_SECT_HEADER::Kind() = CorILMethod_Sect_EHTable then the attribute
using System.Reflection.PortableExecutable;
using System.Text;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/gcinfotypes.h">src\inc\gcinfotypes.h</a> infoHdrAdjustConstants
using System.Runtime.InteropServices;
using System.IO;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
public enum CORCOMPILE_GCREFMAP_TOKENS
{
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(")");
- }
}
/// <summary>
--- /dev/null
+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; }
+ }
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <AssemblyName>ILCompiler.Reflection.ReadyToRun</AssemblyName>
+ <AssemblyVersion>1.0.0.0</AssemblyVersion>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <OutputType>Library</OutputType>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyKey>Open</AssemblyKey>
+ <IsDotNetFrameworkProductAssembly>true</IsDotNetFrameworkProductAssembly>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <CLSCompliant>false</CLSCompliant>
+ <NoWarn>8002,NU1701</NoWarn>
+ <RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>
+ <OutputPath>$(BinDir)</OutputPath>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.Reflection.Metadata">
+ <Version>1.6.0</Version>
+ </PackageReference>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="..\..\Common\Internal\Runtime\CorConstants.cs" Link="Common\CorConstants.cs" />
+ <Compile Include="..\..\Common\Internal\Runtime\ReadyToRunConstants.cs" Link="Common\ReadyToRunConstants.cs" />
+ </ItemGroup>
+</Project>
using System.Text;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/vm/nativeformatreader.h">NativeFormat::NativeArray</a>
/// </summary>
- 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;
using System.Collections.Generic;
using System.Text;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/vm/nativeformatreader.h">NativeFormat::NativeParser</a>
/// </summary>
- struct NativeParser
+ public struct NativeParser
{
+ // TODO (refactoring) - all these Native* class should be private
/// <summary>
/// The current index of the image byte array
/// </summary>
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/vm/nativeformatreader.h">NativeFormat::NativeHashtable</a>
/// </summary>
- struct NativeHashtable
+ public struct NativeHashtable
{
+ // TODO (refactoring) - all these Native* class should be private
private byte[] _image;
private uint _baseOffset;
private uint _bucketMask;
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/vm/nativeformatreader.h">NativeFormat::NativeHashtable</a>
/// </summary>
- struct NativeCuckooFilter
+ public struct NativeCuckooFilter
{
+ // TODO (refactoring) - all these Native* class should be private
private byte[] _image;
private int _filterStartOffset;
private int _filterEndOffset;
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;
// 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
{
/// <summary>
/// Helper to read memory by 4-bit (half-byte) nibbles as is used for encoding
using Internal.ReadyToRunConstants;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/readytorun.h">src/inc/readytorun.h</a> READYTORUN_HEADER
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),
using Internal.CorConstants;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/readytorun.h">src/inc/readytorun.h</a> READYTORUN_IMPORT_SECTION
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")]
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
public abstract class BaseUnwindInfo
{
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
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<FixupCell> 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);
- }
- }
- }
}
}
using Internal.CorConstants;
using Internal.ReadyToRunConstants;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// This structure represents a single precode fixup cell decoded from the
public class EcmaMetadataReader
{
- /// <summary>
- /// Option are used to specify details of signature formatting.
- /// </summary>
- public readonly DumpOptions Options;
+ protected IAssemblyResolver _assemblyResolver;
+ protected Dictionary<string, EcmaMetadataReader> _assemblyCache;
+
/// <summary>
/// Underlying PE image reader is used to access raw PE structures like header
/// <param name="filename">PE image</param>
/// <param name="manifestReferenceAssemblies">List of reference assemblies from the R2R metadata manifest</param>
/// <exception cref="BadImageFormatException">The Cor header flag must be ILLibrary</exception>
- public unsafe EcmaMetadataReader(DumpOptions options, string filename, List<string> manifestReferenceAssemblies)
+ public unsafe EcmaMetadataReader(IAssemblyResolver assemblyResolver, string filename, List<string> manifestReferenceAssemblies)
{
- Options = options;
+ _assemblyResolver = assemblyResolver;
+ _assemblyCache = new Dictionary<string, EcmaMetadataReader>();
Filename = filename;
ManifestReferenceAssemblies = manifestReferenceAssemblies;
Image = File.ReadAllBytes(filename);
}
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;
}
/// </summary>
/// <param name="filename">PE image</param>
/// <exception cref="BadImageFormatException">The Cor header flag must be ILLibrary</exception>
- public unsafe R2RReader(DumpOptions options, string filename)
- : base(options, filename, new List<string>())
+ public unsafe R2RReader(IAssemblyResolver assemblyResolver, string filename)
+ : base(assemblyResolver, filename, new List<string>())
{
IsR2R = ((PEReader.PEHeaders.CorHeader.Flags & CorFlags.ILLibrary) != 0);
if (!IsR2R)
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;
}
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,
unwindInfo,
gcInfo,
ehInfo,
- _runtimeFunctionToDebugInfo.GetValueOrDefault(runtimeFunctionId));
+ debugInfo);
method.RuntimeFunctions.Add(rtf);
runtimeFunctionId++;
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);
}
continue;
}
- var debugInfo = new DebugInfo(Image, offset, Machine, Options.Normalize);
+ var debugInfo = new DebugInfo(Image, offset, Machine);
_runtimeFunctionToDebugInfo.Add((int)i, debugInfo);
}
}
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
public struct R2RSection
{
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();
using Internal.CorConstants;
using Internal.ReadyToRunConstants;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
/// <summary>
/// Helper class for converting metadata tokens into their textual representation.
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;
}
/// <summary>
/// Dump options are used to specify details of signature formatting.
/// </summary>
- private readonly DumpOptions _options;
+ private readonly IAssemblyResolver _options;
/// <summary>
/// Byte array representing the R2R PE file read from disk.
/// <param name="options">Dump options and paths</param>
/// <param name="ecmaReader">EcmaMetadataReader object representing the PE file containing the ECMA metadata</param>
/// <param name="offset">Signature offset within the PE file byte array</param>
- public SignatureDecoder(DumpOptions options, EcmaMetadataReader ecmaReader, int offset)
+ public SignatureDecoder(IAssemblyResolver options, EcmaMetadataReader ecmaReader, int offset)
{
_ecmaReader = ecmaReader;
_options = options;
/// <param name="signature">Signature to parse</param>
/// <param name="offset">Signature offset within the signature byte array</param>
/// <param name="contextReader">Top-level signature context reader</param>
- 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;
return builder.ToString();
}
- private void EmitInlineSignatureBinaryFrom(StringBuilder builder, int startOffset)
+ private void EmitInlineSignatureBinaryForm(StringBuilder builder, int startOffset)
{
EmitInlineSignatureBinaryBytes(builder, _offset - startOffset);
}
{
int startOffset = _offset;
uint value = ReadUInt();
- EmitInlineSignatureBinaryFrom(builder, startOffset);
+ EmitInlineSignatureBinaryForm(builder, startOffset);
return value;
}
{
int startOffset = _offset;
int value = ReadInt();
- EmitInlineSignatureBinaryFrom(builder, startOffset);
+ EmitInlineSignatureBinaryForm(builder, startOffset);
return value;
}
{
int startOffset = _offset;
uint value = ReadToken();
- EmitInlineSignatureBinaryFrom(builder, startOffset);
+ EmitInlineSignatureBinaryForm(builder, startOffset);
return value;
}
using System.Runtime.InteropServices;
using System.IO;
-namespace R2RDump
+namespace ILCompiler.Reflection.ReadyToRun
{
public abstract class TransitionBlock
{
using System.Collections.Generic;
using System.Text;
-namespace R2RDump.x86
+namespace ILCompiler.Reflection.ReadyToRun.x86
{
class CallPattern
{
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.x86
+namespace ILCompiler.Reflection.ReadyToRun.x86
{
public class GcInfo : BaseGcInfo
{
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.x86
+namespace ILCompiler.Reflection.ReadyToRun.x86
{
public class GcSlotTable
{
using System.Collections.Generic;
using System.Text;
-namespace R2RDump.x86
+namespace ILCompiler.Reflection.ReadyToRun.x86
{
public enum Action
{
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.x86
+namespace ILCompiler.Reflection.ReadyToRun.x86
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/gcinfotypes.h">src\inc\gcinfotypes.h</a> InfoHdrSmall
using System.Collections.Generic;
using System.Text;
-namespace R2RDump.x86
+namespace ILCompiler.Reflection.ReadyToRun.x86
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/gcdump/i386/gcdumpx86.cpp">src\gcdump\i386\gcdumpx86.cpp</a> RegName
using System.Text;
using System.Xml.Serialization;
-namespace R2RDump.x86
+namespace ILCompiler.Reflection.ReadyToRun.x86
{
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/win64unwind.h">src\inc\win64unwind.h</a> _UNWIND_INFO
// 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;
--- /dev/null
+// 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<FixupCell> 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(")");
+ }
+ }
+}
// 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;
// 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;
namespace R2RDump
{
- public class DumpOptions
+ public class DumpOptions : IAssemblyResolver
{
public FileInfo[] In { get; set; }
public FileInfo Out { get; set; }
</PropertyGroup>
<ItemGroup>
- <Compile Include="..\Common\Internal\Runtime\CorConstants.cs" Link="Common\CorConstants.cs" />
- <Compile Include="..\Common\Internal\Runtime\ReadyToRunConstants.cs" Link="Common\ReadyToRunConstants.cs" />
- </ItemGroup>
-
- <ItemGroup>
<PackageReference Include="Microsoft.NETCore.CoreDisTools">
<Version>1.0.1-prerelease-00005</Version>
</PackageReference>
<PackageReference Include="System.Reflection.Metadata">
<Version>1.6.0</Version>
</PackageReference>
+ <ProjectReference Include="..\crossgen2\ILCompiler.Reflection.ReadyToRun\ILCompiler.Reflection.ReadyToRun.csproj" />
</ItemGroup>
</Project>
-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;
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<Amd64.UnwindCode> codes = ((Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes[codeOffset];
- foreach (Amd64.UnwindCode code in codes)
+ List<ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode> 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)
-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;
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);
}
}
}