Parse and dump compiler identifier and import sections, move dump section contents...
authorAmy Yu <amycmyu@gmail.com>
Thu, 7 Jun 2018 22:01:23 +0000 (15:01 -0700)
committerAmy Yu <amycmyu@gmail.com>
Tue, 19 Jun 2018 20:26:02 +0000 (13:26 -0700)
src/tools/r2rdump/R2RDump.cs
src/tools/r2rdump/R2RImportSection.cs [new file with mode: 0644]
src/tools/r2rdump/R2RReader.cs

index 22967ba..65d72be 100644 (file)
@@ -148,41 +148,12 @@ namespace R2RDump
             if (_raw)
             {
                 DumpBytes(r2r, section.RelativeVirtualAddress, (uint)section.Size);
+                _writer.WriteLine();
             }
-
             if (_sectionContents)
             {
-                switch (section.Type)
-                {
-                    case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES:
-                        uint availableTypesSectionOffset = (uint)r2r.GetOffset(section.RelativeVirtualAddress);
-                        NativeParser availableTypesParser = new NativeParser(r2r.Image, availableTypesSectionOffset);
-                        NativeHashtable availableTypes = new NativeHashtable(r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size));
-                        _writer.WriteLine(availableTypes.ToString());
-                        DumpAvailableTypes(r2r);
-                        break;
-                    case R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS:
-                        NativeArray methodEntryPoints = new NativeArray(r2r.Image, (uint)r2r.GetOffset(section.RelativeVirtualAddress));
-                        _writer.WriteLine(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.WriteLine(instMethodEntryPoints.ToString());
-                        break;
-                    case R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS:
-                        int offset = r2r.GetOffset(section.RelativeVirtualAddress);
-                        int endOffset = offset + section.Size;
-                        int rtfIndex = 0;
-                        while (offset < endOffset)
-                        {
-                            uint rva = NativeReader.ReadUInt32(r2r.Image, ref offset);
-                            _writer.WriteLine($"{rtfIndex}: 0x{rva:X8}");
-                            rtfIndex++;
-                        }
-                        break;
-                }
+                DumpSectionContents(r2r, section);
+                _writer.WriteLine();
             }
         }
 
@@ -271,13 +242,52 @@ namespace R2RDump
             _writer.WriteLine();
         }
 
-        private void DumpAvailableTypes(R2RReader r2r)
+        private void DumpSectionContents(R2RReader r2r, R2RSection section)
         {
-            foreach (string name in r2r.AvailableTypes)
+            switch (section.Type)
             {
-                _writer.WriteLine(name);
+                case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES:
+                    uint availableTypesSectionOffset = (uint)r2r.GetOffset(section.RelativeVirtualAddress);
+                    NativeParser availableTypesParser = new NativeParser(r2r.Image, availableTypesSectionOffset);
+                    NativeHashtable availableTypes = new NativeHashtable(r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size));
+                    _writer.WriteLine(availableTypes.ToString());
+
+                    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());
+                    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());
+                    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)
+                    {
+                        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);
+                    break;
+                case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS:
+                    foreach (R2RImportSection importSection in r2r.ImportSections)
+                    {
+                        _writer.WriteLine(importSection.ToString());
+                    }
+                    break;
             }
-            _writer.WriteLine();
         }
 
         // <summary>
diff --git a/src/tools/r2rdump/R2RImportSection.cs b/src/tools/r2rdump/R2RImportSection.cs
new file mode 100644 (file)
index 0000000..39f816b
--- /dev/null
@@ -0,0 +1,77 @@
+// 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 System;
+using System.Text;
+
+namespace R2RDump
+{
+    struct R2RImportSection
+    {
+        public enum ImportSectionType
+        {
+            READYTORUN_IMPORT_SECTION_TYPE_UNKNOWN = 0,
+        };
+
+        public enum ImportSectionFlags
+        {
+            READYTORUN_IMPORT_SECTION_FLAGS_EAGER = 0x0001,
+        };
+
+        /// <summary>
+        /// Section containing values to be fixed up
+        /// </summary>
+        public int SectionRVA { get; }
+        public int SectionSize { get; }
+
+        /// <summary>
+        /// One or more of ImportSectionFlags
+        /// </summary>
+        public ushort Flags { get; }
+
+        /// <summary>
+        /// One of ImportSectionType
+        /// </summary>
+        public ImportSectionType Type { get; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public byte EntrySize { get; }
+
+        /// <summary>
+        /// RVA of optional signature descriptors
+        /// </summary>
+        public int Signatures { get; }
+
+        /// <summary>
+        /// RVA of optional auxiliary data (typically GC info)
+        /// </summary>
+        public int AuxiliaryData { get; }
+
+        public R2RImportSection(int rva, int size, ushort flags, byte type, byte entrySize, int sig, int data)
+        {
+            SectionRVA = rva;
+            SectionSize = size;
+            Flags = flags;
+            Type = (ImportSectionType)type;
+            EntrySize = entrySize;
+            Signatures = sig;
+            AuxiliaryData = data;
+        }
+
+        public override string ToString()
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.AppendLine($"SectionRVA: 0x{SectionRVA:X8}");
+            sb.AppendLine($"SectionSize: {SectionSize} bytes");
+            sb.AppendLine($"Flags: {Enum.GetName(typeof(ImportSectionFlags), Flags)}({Flags})");
+            sb.AppendLine($"Type: {Type}");
+            sb.AppendLine($"EntrySize: {EntrySize}");
+            sb.AppendLine($"Signatures: 0x{Signatures:X8}");
+            sb.AppendLine($"AuxiliaryData: {AuxiliaryData}");
+            return sb.ToString();
+        }
+    }
+}
index 97fe57c..7e32a7e 100644 (file)
@@ -76,7 +76,14 @@ namespace R2RDump
         /// <summary>
         /// The available types from READYTORUN_SECTION_AVAILABLE_TYPES
         /// </summary>
-        public List<string> AvailableTypes { get; }
+        public IList<string> AvailableTypes { get; }
+
+        /// <summary>
+        /// The compile identifier string from READYTORUN_SECTION_COMPILER_IDENTIFIER
+        /// </summary>
+        public string CompileIdentifier { get; }
+
+        public IList<R2RImportSection> ImportSections { get; }
 
         /// <summary>
         /// Initializes the fields of the R2RHeader and R2RMethods
@@ -129,6 +136,11 @@ namespace R2RDump
 
                     AvailableTypes = new List<string>();
                     ParseAvailableTypes();
+
+                    CompileIdentifier = ParseCompilerIdentifier();
+
+                    ImportSections = new List<R2RImportSection>();
+                    ParseImportSections();
                 }
             }
         }
@@ -272,6 +284,33 @@ namespace R2RDump
             }
         }
 
+        private string ParseCompilerIdentifier()
+        {
+            R2RSection compilerIdentifierSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER];
+            byte[] identifier = new byte[compilerIdentifierSection.Size];
+            int identifierOffset = GetOffset(compilerIdentifierSection.RelativeVirtualAddress);
+            Array.Copy(Image, identifierOffset, identifier, 0, compilerIdentifierSection.Size);
+            return Encoding.UTF8.GetString(identifier);
+        }
+
+        private void ParseImportSections()
+        {
+            R2RSection importSectionsSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS];
+            int offset = GetOffset(importSectionsSection.RelativeVirtualAddress);
+            int endOffset = offset + importSectionsSection.Size;
+            while (offset < endOffset)
+            {
+                int rva = NativeReader.ReadInt32(Image, ref offset);
+                int size = NativeReader.ReadInt32(Image, ref offset);
+                ushort flags = NativeReader.ReadUInt16(Image, ref offset);
+                byte type = NativeReader.ReadByte(Image, ref offset);
+                byte entrySize = NativeReader.ReadByte(Image, ref offset);
+                int sig = NativeReader.ReadInt32(Image, ref offset);
+                int data = NativeReader.ReadInt32(Image, ref offset);
+                ImportSections.Add(new R2RImportSection(rva, size, flags, type, entrySize, sig, data));
+            }
+        }
+
         /// <summary>
         /// Get the index in the image byte array corresponding to the RVA
         /// </summary>