namespace R2RDump
{
- class GcInfo
+ public class GcInfo
{
private enum GcInfoHeaderFlags
{
public struct InterruptibleRange
{
- public uint StartOffset { get; }
- public uint StopOffset { get; }
+ public uint StartOffset { get; set; }
+ public uint StopOffset { get; set; }
public InterruptibleRange(uint start, uint stop)
{
StartOffset = start;
_wantsReportOnlyLeaf = ((headerFlags & GcInfoHeaderFlags.GC_INFO_WANTS_REPORT_ONLY_LEAF) != 0);
}
- private IEnumerable<uint> EnumerateSafePoints(byte[] image, ref int bitOffset)
+ private List<uint> EnumerateSafePoints(byte[] image, ref int bitOffset)
{
List<uint> safePoints = new List<uint>();
uint numBitsPerOffset = GcInfoTypes.CeilOfLog2(CodeLength);
return safePoints;
}
- private IEnumerable<InterruptibleRange> EnumerateInterruptibleRanges(byte[] image, int interruptibleRangeDelta1EncBase, int interruptibleRangeDelta2EncBase, ref int bitOffset)
+ private List<InterruptibleRange> EnumerateInterruptibleRanges(byte[] image, int interruptibleRangeDelta1EncBase, int interruptibleRangeDelta2EncBase, ref int bitOffset)
{
List<InterruptibleRange> ranges = new List<InterruptibleRange>();
uint lastinterruptibleRangeStopOffset = 0;
namespace R2RDump
{
- class GcInfoTypes
+ public class GcInfoTypes
{
private Machine _target;
public class GcStackSlot
{
- public int SpOffset { get; }
- public GcStackSlotBase Base { get; }
+ public int SpOffset { get; set; }
+ public GcStackSlotBase Base { get; set; }
+
+ public GcStackSlot() { }
+
public GcStackSlot(int spOffset, GcStackSlotBase stackSlotBase)
{
SpOffset = spOffset;
namespace R2RDump
{
- class GcSlotTable
+ public class GcSlotTable
{
public struct GcSlot
{
- public int RegisterNumber { get; }
- public GcStackSlot StackSlot { get; }
- public GcSlotFlags Flags { get; }
+ public int RegisterNumber { get; set; }
+ public GcStackSlot StackSlot { get; set; }
+ public GcSlotFlags Flags { get; set; }
public GcSlot(int registerNumber, GcStackSlot stack, GcSlotFlags flags, bool isUntracked = false)
{
}
}
- public uint NumRegisters { get; }
- public uint NumStackSlots { get; }
- public uint NumUntracked { get; }
- public uint NumSlots { get; }
- public List<GcSlot> GcSlots { get; }
+ public uint NumRegisters { get; set; }
+ public uint NumStackSlots { get; set; }
+ public uint NumUntracked { get; set; }
+ public uint NumSlots { get; set; }
+ public List<GcSlot> GcSlots { get; set; }
+
+ public GcSlotTable() { }
public GcSlotTable(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, ref int bitOffset)
{
namespace R2RDump
{
- class R2RHeader
+ public class R2RHeader
{
[Flags]
public enum ReadyToRunFlag
/// <summary>
/// RVA to the begining of the ReadyToRun header
/// </summary>
- public int RelativeVirtualAddress { get; }
+ public int RelativeVirtualAddress { get; set; }
/// <summary>
/// Size of the ReadyToRun header
/// </summary>
- public int Size { get; }
+ public int Size { get; set; }
/// <summary>
/// Signature of the header in string and hex formats
/// </summary>
- public string SignatureString { get; }
- public uint Signature { get; }
+ public string SignatureString { get; set; }
+ public uint Signature { get; set; }
/// <summary>
/// The ReadyToRun version
/// </summary>
- public ushort MajorVersion { get; }
- public ushort MinorVersion { get; }
+ public ushort MajorVersion { get; set; }
+ public ushort MinorVersion { get; set; }
/// <summary>
/// Flags in the header
/// eg. PLATFORM_NEUTRAL_SOURCE, SKIP_TYPE_VALIDATION
/// </summary>
- public uint Flags { get; }
+ public uint Flags { get; set; }
/// <summary>
/// The ReadyToRun section RVAs and sizes
/// </summary>
- public Dictionary<R2RSection.SectionType, R2RSection> Sections { get; }
+ public IDictionary<R2RSection.SectionType, R2RSection> Sections { get; }
+
+ public R2RHeader() { }
/// <summary>
/// Initializes the fields of the R2RHeader
byte[] signature = new byte[sizeof(uint)];
Array.Copy(image, curOffset, signature, 0, sizeof(uint));
- SignatureString = System.Text.Encoding.UTF8.GetString(signature);
+ SignatureString = Encoding.UTF8.GetString(signature).Replace("\0", string.Empty); ;
Signature = NativeReader.ReadUInt32(image, ref curOffset);
if (Signature != READYTORUN_SIGNATURE)
{
namespace R2RDump
{
- struct R2RImportSection
+ public struct R2RImportSection
{
public enum CorCompileImportType
{
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
+using System.Xml.Serialization;
namespace R2RDump
{
}
- class RuntimeFunction
+ public class RuntimeFunction
{
/// <summary>
/// The index of the runtime function
/// </summary>
- public int Id { get; }
+ public int Id { get; set; }
/// <summary>
/// The relative virtual address to the start of the code block
/// </summary>
- public int StartAddress { get; }
+ public int StartAddress { get; set; }
/// <summary>
/// The size of the code block in bytes
/// The EndAddress field in the runtime functions section is conditional on machine type
/// Size is -1 for images without the EndAddress field
/// </remarks>
- public int Size { get; }
+ public int Size { get; set; }
/// <summary>
/// The relative virtual address to the unwind info
/// </summary>
- public int UnwindRVA { get; }
+ public int UnwindRVA { get; set; }
public int CodeOffset { get; set; }
public BaseUnwindInfo UnwindInfo { get; }
+ public RuntimeFunction() { }
+
public RuntimeFunction(int id, int startRva, int endRva, int unwindRva, int codeOffset, R2RMethod method, BaseUnwindInfo unwindInfo, GcInfo gcInfo)
{
Id = id;
}
}
- class R2RMethod
+ public class R2RMethod
{
private const int _mdtMethodDef = 0x06000000;
/// <summary>
/// The name of the method
/// </summary>
- public string Name { get; }
+ public string Name { get; set; }
/// <summary>
/// The signature with format: namespace.class.methodName<S, T, ...>(S, T, ...)
/// </summary>
- public string SignatureString { get; }
+ public string SignatureString { get; set; }
- public bool IsGeneric { get; }
+ public bool IsGeneric { get; set; }
public MethodSignature<string> Signature { get; }
/// <summary>
/// The type that the method belongs to
/// </summary>
- public string DeclaringType { get; }
+ public string DeclaringType { get; set; }
/// <summary>
/// The token of the method consisting of the table code (0x06) and row id
/// </summary>
- public uint Token { get; }
+ public uint Token { get; set; }
/// <summary>
/// The row id of the method
/// </summary>
- public uint Rid { get; }
+ public uint Rid { get; set; }
/// <summary>
/// All the runtime functions of this method
/// <summary>
/// The id of the entrypoint runtime function
/// </summary>
- public int EntryPointRuntimeFunctionId { get; }
+ public int EntryPointRuntimeFunctionId { get; set; }
+ [XmlIgnore]
public GcInfo GcInfo { get; set; }
/// <summary>
Array = 0x1d,
};
+ public R2RMethod() { }
+
/// <summary>
/// Extracts the method signature from the metadata by rid
/// </summary>
E15 = 15,
}
- class R2RReader
+ public class R2RReader
{
private readonly PEReader _peReader;
private readonly MetadataReader _mdReader;
/// <summary>
/// Name of the image file
/// </summary>
- public string Filename { get; }
+ public string Filename { get; set; }
/// <summary>
/// True if the image is ReadyToRun
/// </summary>
- public bool IsR2R { get; }
+ public bool IsR2R { get; set; }
/// <summary>
/// The type of target machine
/// </summary>
- public Machine Machine { get; }
+ public Machine Machine { get; set; }
/// <summary>
/// The preferred address of the first byte of image when loaded into memory;
/// must be a multiple of 64K.
/// </summary>
- public ulong ImageBase { get; }
+ public ulong ImageBase { get; set; }
/// <summary>
/// The ReadyToRun header
public IList<R2RImportSection> ImportSections { get; }
+ public unsafe R2RReader() { }
+
/// <summary>
/// Initializes the fields of the R2RHeader and R2RMethods
/// </summary>
byte[] identifier = new byte[compilerIdentifierSection.Size];
int identifierOffset = GetOffset(compilerIdentifierSection.RelativeVirtualAddress);
Array.Copy(Image, identifierOffset, identifier, 0, compilerIdentifierSection.Size);
- return Encoding.UTF8.GetString(identifier);
+ return Encoding.UTF8.GetString(identifier).Replace("\0", string.Empty);
}
private void ParseImportSections()
namespace R2RDump
{
- struct R2RSection
+ public struct R2RSection
{
public enum SectionType
{
/// <summary>
/// The ReadyToRun section type
/// </summary>
- public SectionType Type { get; }
+ public SectionType Type { get; set; }
/// <summary>
/// The RVA to the section
/// </summary>
- public int RelativeVirtualAddress { get; }
+ public int RelativeVirtualAddress { get; set; }
/// <summary>
/// The size of the section
/// </summary>
- public int Size { get; }
+ public int Size { get; set; }
public R2RSection(SectionType type, int rva, int size)
{