XMLSerialize gc transitions and section contents
authorAmy Yu <amycmyu@gmail.com>
Wed, 20 Jun 2018 00:57:52 +0000 (17:57 -0700)
committerAmy Yu <amycmyu@gmail.com>
Tue, 26 Jun 2018 22:04:10 +0000 (15:04 -0700)
src/tools/r2rdump/GCInfo.cs
src/tools/r2rdump/R2RDump.cs
src/tools/r2rdump/R2RImportSection.cs

index 5e44e8f..cf51c8b 100644 (file)
@@ -6,6 +6,7 @@ using System;
 using System.Collections.Generic;
 using System.Reflection.PortableExecutable;
 using System.Text;
+using System.Xml.Serialization;
 
 namespace R2RDump
 {
@@ -126,7 +127,8 @@ namespace R2RDump
         public GcSlotTable SlotTable { get; set; }
         public int Size { get; set; }
         public int Offset { get; set; }
-        public Dictionary<int, GcTransition> Transitions { get; set; }
+        [XmlIgnore]
+        public Dictionary<int, GcTransition> Transitions { get; }
 
         public GcInfo() { }
 
index 6546ed6..1e6ccf6 100644 (file)
@@ -229,6 +229,8 @@ namespace R2RDump
                     XmlNode gcNode = _xmlDocument.CreateNode("element", "GcInfo", "");
                     methodNode.AppendChild(gcNode);
                     Serialize(method.GcInfo, gcNode);
+
+                    Serialize(new List<GcInfo.GcTransition>(method.GcInfo.Transitions.Values), gcNode);
                 }
                 else
                 {
@@ -271,7 +273,7 @@ namespace R2RDump
 
             if (_disasm)
             {
-                string disassembly = CoreDisTools.GetCodeBlock(_disassembler, rtf.StartAddress, r2r.GetOffset(rtf.StartAddress), r2r.Image, rtf.Size);
+                string disassembly = CoreDisTools.GetCodeBlock(_disassembler, rtf, r2r.GetOffset(rtf.StartAddress), r2r.Image);
                 if (_xml)
                 {
                     AddXMLNode("Disassembly", disassembly, rtfNode);
@@ -363,14 +365,8 @@ namespace R2RDump
             SkipLine();
         }
 
-        private void DumpSectionContents(R2RReader r2r, R2RSection section, XmlNode parentNode)
+        private void DumpSectionContents(R2RReader r2r, R2RSection section, XmlNode contentsNode)
         {
-            XmlNode contentsNode = null;
-            if (_xml)
-            {
-                contentsNode = _xmlDocument.CreateNode("element", "Contents", "");
-                parentNode.AppendChild(contentsNode);
-            }
             switch (section.Type)
             {
                 case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES:
@@ -382,70 +378,119 @@ namespace R2RDump
                         _writer.WriteLine(availableTypes.ToString());
                     }
 
-                    foreach (string name in r2r.AvailableTypes)
+                    if (_xml)
                     {
-                        if (_xml)
-                        {
-                            AddXMLNode("AvailableType", name, contentsNode);
-                        }
-                        else
+                        Serialize(r2r.AvailableTypes, contentsNode);
+                    }
+                    else
+                    {
+                        foreach (string name in r2r.AvailableTypes)
                         {
                             _writer.WriteLine(name);
                         }
                     }
                     break;
                 case R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS:
-                    NativeArray methodEntryPoints = new NativeArray(r2r.Image, (uint)r2r.GetOffset(section.RelativeVirtualAddress));
-                    _writer.Write(methodEntryPoints.ToString());
+                    if (!_xml)
+                    {
+                        NativeArray methodEntryPoints = new NativeArray(r2r.Image, (uint)r2r.GetOffset(section.RelativeVirtualAddress));
+                        _writer.Write(methodEntryPoints.ToString());
+                    }
                     break;
                 case R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS:
-                    uint instanceSectionOffset = (uint)r2r.GetOffset(section.RelativeVirtualAddress);
-                    NativeParser instanceParser = new NativeParser(r2r.Image, instanceSectionOffset);
-                    NativeHashtable instMethodEntryPoints = new NativeHashtable(r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size));
-                    _writer.Write(instMethodEntryPoints.ToString());
+                    if (!_xml)
+                    {
+                        uint instanceSectionOffset = (uint)r2r.GetOffset(section.RelativeVirtualAddress);
+                        NativeParser instanceParser = new NativeParser(r2r.Image, instanceSectionOffset);
+                        NativeHashtable instMethodEntryPoints = new NativeHashtable(r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size));
+                        _writer.Write(instMethodEntryPoints.ToString());
+                    }
                     break;
                 case R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS:
-                    int rtfOffset = r2r.GetOffset(section.RelativeVirtualAddress);
-                    int rtfEndOffset = rtfOffset + section.Size;
-                    int rtfIndex = 0;
-                    while (rtfOffset < rtfEndOffset)
+                    if (!_xml)
                     {
-                        uint rva = NativeReader.ReadUInt32(r2r.Image, ref rtfOffset);
-                        _writer.WriteLine($"{rtfIndex}: 0x{rva:X8}");
-                        rtfIndex++;
+                        int rtfOffset = r2r.GetOffset(section.RelativeVirtualAddress);
+                        int rtfEndOffset = rtfOffset + section.Size;
+                        int rtfIndex = 0;
+                        while (rtfOffset < rtfEndOffset)
+                        {
+                            uint rva = NativeReader.ReadUInt32(r2r.Image, ref rtfOffset);
+                            _writer.WriteLine($"{rtfIndex}: 0x{rva:X8}");
+                            rtfIndex++;
+                        }
                     }
                     break;
                 case R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER:
-                    _writer.WriteLine(r2r.CompileIdentifier);
+                    if (!_xml)
+                    {
+                        _writer.WriteLine(r2r.CompileIdentifier);
+                    }
                     break;
                 case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS:
                     foreach (R2RImportSection importSection in r2r.ImportSections)
                     {
-                        _writer.Write(importSection.ToString());
+                        if (_xml)
+                        {
+                            Serialize(importSection, contentsNode);
+                        }
+                        else
+                        {
+                            _writer.Write(importSection.ToString());
+                        }
                         if (_raw && importSection.Entries.Count != 0)
                         {
                             if (importSection.SectionRVA != 0)
                             {
-                                _writer.WriteLine("Section Bytes:");
-                                DumpBytes(r2r, importSection.SectionRVA, (uint)importSection.SectionSize);
+                                XmlNode bytesNode = null;
+                                if (_xml)
+                                {
+                                    bytesNode = _xmlDocument.CreateNode("element", "SectionBytes", "");
+                                    contentsNode.AppendChild(bytesNode);
+                                }
+                                else
+                                {
+                                    _writer.WriteLine("Section Bytes:");
+                                }
+                                DumpBytes(r2r, importSection.SectionRVA, (uint)importSection.SectionSize, bytesNode);
                             }
                             if (importSection.SignatureRVA != 0)
                             {
-                                _writer.WriteLine("Signature Bytes:");
-                                DumpBytes(r2r, importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int));
+                                XmlNode bytesNode = null;
+                                if (_xml)
+                                {
+                                    bytesNode = _xmlDocument.CreateNode("element", "SignatureBytes", "");
+                                    contentsNode.AppendChild(bytesNode);
+                                }
+                                else
+                                {
+                                    _writer.WriteLine("Signature Bytes:");
+                                }
+                                DumpBytes(r2r, importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int), bytesNode);
                             }
                             if (importSection.AuxiliaryDataRVA != 0)
                             {
-                                _writer.WriteLine("AuxiliaryData Bytes:");
-                                DumpBytes(r2r, importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size);
+                                XmlNode bytesNode = null;
+                                if (_xml)
+                                {
+                                    bytesNode = _xmlDocument.CreateNode("element", "AuxiliaryDataBytes", "");
+                                    contentsNode.AppendChild(bytesNode);
+                                }
+                                else
+                                {
+                                    _writer.WriteLine("AuxiliaryData Bytes:");
+                                }
+                                DumpBytes(r2r, importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size, bytesNode);
                             }
                         }
-                        foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
+                        if (!_xml)
                         {
+                            foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
+                            {
+                                _writer.WriteLine();
+                                _writer.WriteLine(entry.ToString());
+                            }
                             _writer.WriteLine();
-                            _writer.WriteLine(entry.ToString());
                         }
-                        _writer.WriteLine();
                     }
                     break;
             }
index e91ef34..4f591df 100644 (file)
@@ -24,6 +24,7 @@ namespace R2RDump
 
         public enum CorCompileImportFlags
         {
+            CORCOMPILE_IMPORT_FLAGS_UNKNOWN = 0x0000,
             CORCOMPILE_IMPORT_FLAGS_EAGER = 0x0001,   // Section at module load time.
             CORCOMPILE_IMPORT_FLAGS_CODE = 0x0002,   // Section contains code.
             CORCOMPILE_IMPORT_FLAGS_PCODE = 0x0004,   // Section contains pointers to code.
@@ -31,9 +32,9 @@ namespace R2RDump
 
         public struct ImportSectionEntry
         {
-            public long Section { get; }
-            public uint SignatureRVA { get; }
-            public uint Signature { get; }
+            public long Section { get; set; }
+            public uint SignatureRVA { get; set; }
+            public uint Signature { get; set; }
             public ImportSectionEntry(long section, uint signatureRVA, uint signature)
             {
                 Section = section;
@@ -54,35 +55,35 @@ namespace R2RDump
         /// <summary>
         /// Section containing values to be fixed up
         /// </summary>
-        public int SectionRVA { get; }
-        public int SectionSize { get; }
+        public int SectionRVA { get; set; }
+        public int SectionSize { get; set; }
 
         /// <summary>
         /// One or more of ImportSectionFlags
         /// </summary>
-        public CorCompileImportFlags Flags { get; }
+        public CorCompileImportFlags Flags { get; set; }
 
         /// <summary>
         /// One of ImportSectionType
         /// </summary>
-        public CorCompileImportType Type { get; }
+        public CorCompileImportType Type { get; set; }
 
         /// <summary>
         /// 
         /// </summary>
-        public byte EntrySize { get; }
+        public byte EntrySize { get; set; }
 
         /// <summary>
         /// RVA of optional signature descriptors
         /// </summary>
-        public int SignatureRVA { get; }
-        public List<ImportSectionEntry> Entries { get; }
+        public int SignatureRVA { get; set; }
+        public List<ImportSectionEntry> Entries { get; set; }
 
         /// <summary>
         /// RVA of optional auxiliary data (typically GC info)
         /// </summary>
-        public int AuxiliaryDataRVA { get; }
-        public GcInfo AuxiliaryData { get; }
+        public int AuxiliaryDataRVA { get; set; }
+        public GcInfo AuxiliaryData { get; set; }
 
         public R2RImportSection(byte[] image, int rva, int size, CorCompileImportFlags flags, byte type, byte entrySize, int signatureRVA, List<ImportSectionEntry> entries, int auxDataRVA, int auxDataOffset, Machine machine, ushort majorVersion)
         {