Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 65f88a8

Browse files
authored
Merge pull request #18357 from acmyu/sections
R2RDump - Dump CompilerIdentifier and ImportSection contents
2 parents 9085013 + 1c98c6e commit 65f88a8

File tree

7 files changed

+381
-38
lines changed

7 files changed

+381
-38
lines changed

src/tools/r2rdump/DisassemblingTypeProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public virtual string GetTypeFromDefinition(MetadataReader reader, TypeDefinitio
4343
if ((definition.Attributes & TypeAttributes.NestedPublic) != 0 || (definition.Attributes & TypeAttributes.NestedFamily) != 0)
4444
{
4545
TypeDefinitionHandle declaringTypeHandle = definition.GetDeclaringType();
46-
return GetTypeFromDefinition(reader, declaringTypeHandle, 0) + "/" + name;
46+
return GetTypeFromDefinition(reader, declaringTypeHandle, 0) + "." + name;
4747
}
4848

4949
return name;

src/tools/r2rdump/NativeArray.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Text;
6+
57
namespace R2RDump
68
{
79
class NativeArray
@@ -10,20 +12,40 @@ class NativeArray
1012
private uint _baseOffset;
1113
private uint _nElements;
1214
private byte _entryIndexSize;
15+
private byte[] _image;
1316

1417
public NativeArray(byte[] image, uint offset)
1518
{
1619
uint val = 0;
1720
_baseOffset = NativeReader.DecodeUnsigned(image, offset, ref val);
1821
_nElements = (val >> 2);
1922
_entryIndexSize = (byte)(val & 3);
23+
_image = image;
2024
}
2125

2226
public uint GetCount()
2327
{
2428
return _nElements;
2529
}
2630

31+
public override string ToString()
32+
{
33+
StringBuilder sb = new StringBuilder();
34+
35+
sb.AppendLine($"NativeArray Size: {_nElements}");
36+
sb.AppendLine($"EntryIndexSize: {_entryIndexSize}");
37+
for (uint i = 0; i < _nElements; i++)
38+
{
39+
int val = 0;
40+
if (TryGetAt(_image, i, ref val))
41+
{
42+
sb.AppendLine($"{i}: {val}");
43+
}
44+
}
45+
46+
return sb.ToString();
47+
}
48+
2749
public bool TryGetAt(byte[] image, uint index, ref int pOffset)
2850
{
2951
if (index >= _nElements)

src/tools/r2rdump/NativeHashtable.cs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Collections.Generic;
6+
using System.Text;
7+
58
namespace R2RDump
69
{
710
struct NativeParser
@@ -10,12 +13,14 @@ struct NativeParser
1013
/// The current index of the image byte array
1114
/// </summary>
1215
public uint Offset { get; set; }
16+
public byte LowHashcode { get; }
1317

1418
byte[] _image;
1519

16-
public NativeParser(byte[] image, uint offset)
20+
public NativeParser(byte[] image, uint offset, byte lowHashcode = 0)
1721
{
1822
Offset = offset;
23+
LowHashcode = lowHashcode;
1924
_image = image;
2025
}
2126

@@ -36,7 +41,8 @@ public uint GetRelativeOffset()
3641

3742
public NativeParser GetParserFromRelativeOffset()
3843
{
39-
return new NativeParser(_image, GetRelativeOffset());
44+
byte lowHashcode = GetByte();
45+
return new NativeParser(_image, GetRelativeOffset(), lowHashcode);
4046
}
4147

4248
public byte GetByte()
@@ -76,8 +82,9 @@ struct NativeHashtable
7682
private uint _baseOffset;
7783
private uint _bucketMask;
7884
private byte _entryIndexSize;
85+
private uint _endOffset;
7986

80-
public NativeHashtable(byte[] image, NativeParser parser)
87+
public NativeHashtable(byte[] image, NativeParser parser, uint endOffset)
8188
{
8289
uint header = parser.GetByte();
8390
_baseOffset = parser.Offset;
@@ -92,6 +99,46 @@ public NativeHashtable(byte[] image, NativeParser parser)
9299
if (entryIndexSize > 2)
93100
throw new System.BadImageFormatException();
94101
_entryIndexSize = entryIndexSize;
102+
103+
_endOffset = endOffset;
104+
}
105+
106+
public override string ToString()
107+
{
108+
StringBuilder sb = new StringBuilder();
109+
110+
SortedDictionary<uint, byte> entries = new SortedDictionary<uint, byte>();
111+
AllEntriesEnumerator allEntriesEnum = EnumerateAllEntries();
112+
NativeParser curParser = allEntriesEnum.GetNext();
113+
while (!curParser.IsNull())
114+
{
115+
entries[curParser.Offset] = curParser.LowHashcode;
116+
curParser = allEntriesEnum.GetNext();
117+
}
118+
entries[_endOffset] = 0;
119+
120+
sb.AppendLine($"NativeHashtable Size: {entries.Count - 1}");
121+
sb.AppendLine($"EntryIndexSize: {_entryIndexSize}");
122+
int curOffset = -1;
123+
foreach (KeyValuePair<uint, byte> entry in entries)
124+
{
125+
int nextOffset = (int)entry.Key;
126+
if (curOffset != -1)
127+
{
128+
for (int i = curOffset; i < nextOffset; i++)
129+
{
130+
sb.Append($"{_image[i]:X2} ");
131+
}
132+
sb.AppendLine();
133+
}
134+
if (nextOffset != _endOffset)
135+
{
136+
sb.Append($"0x{entry.Value:X2} -> ");
137+
}
138+
curOffset = nextOffset;
139+
}
140+
141+
return sb.ToString();
95142
}
96143

97144
//
@@ -132,7 +179,6 @@ public NativeParser GetNext()
132179
{
133180
while (_parser.Offset < _endOffset)
134181
{
135-
byte lowHashcode = _parser.GetByte();
136182
return _parser.GetParserFromRelativeOffset();
137183
}
138184

src/tools/r2rdump/R2RDump.cs

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ class R2RDump
2323
private IReadOnlyList<string> _sections = Array.Empty<string>();
2424
private bool _diff;
2525
private IntPtr _disassembler;
26-
private bool _types;
2726
private bool _unwind;
2827
private bool _gc;
28+
private bool _sectionContents;
2929
private TextWriter _writer;
30+
private Dictionary<R2RSection.SectionType, bool> _selectedSections = new Dictionary<R2RSection.SectionType, bool>();
3031

3132
private R2RDump()
3233
{
@@ -51,10 +52,10 @@ private ArgumentSyntax ParseCommandLine(string[] args)
5152
syntax.DefineOptionList("k|keyword", ref _keywords, "Search method by keyword");
5253
syntax.DefineOptionList("r|runtimefunction", ref _runtimeFunctions, ArgStringToInt, "Get one runtime function by id or relative virtual address");
5354
syntax.DefineOptionList("s|section", ref _sections, "Get section by keyword");
54-
syntax.DefineOption("types", ref _types, "Dump available types");
5555
syntax.DefineOption("unwind", ref _unwind, "Dump unwindInfo");
5656
syntax.DefineOption("gc", ref _gc, "Dump gcInfo and slot table");
57-
syntax.DefineOption("v|verbose", ref verbose, "Dump raw bytes, disassembly, unwindInfo and gcInfo");
57+
syntax.DefineOption("sc", ref _sectionContents, "Dump section contents");
58+
syntax.DefineOption("v|verbose", ref verbose, "Dump raw bytes, disassembly, unwindInfo, gcInfo and section contents");
5859
syntax.DefineOption("diff", ref _diff, "Compare two R2R images (not yet implemented)");
5960
});
6061

@@ -64,6 +65,7 @@ private ArgumentSyntax ParseCommandLine(string[] args)
6465
_disasm = true;
6566
_unwind = true;
6667
_gc = true;
68+
_sectionContents = true;
6769
}
6870

6971
return argSyntax;
@@ -146,6 +148,12 @@ private void DumpSection(R2RReader r2r, R2RSection section)
146148
if (_raw)
147149
{
148150
DumpBytes(r2r, section.RelativeVirtualAddress, (uint)section.Size);
151+
_writer.WriteLine();
152+
}
153+
if (_sectionContents)
154+
{
155+
DumpSectionContents(r2r, section);
156+
_writer.WriteLine();
149157
}
150158
}
151159

@@ -162,7 +170,7 @@ private void DumpMethod(R2RReader r2r, R2RMethod method)
162170
_writer.Write(method.GcInfo);
163171
if (_raw)
164172
{
165-
DumpBytes(r2r, method.GcInfo.Offset, (uint)method.GcInfo.Size);
173+
DumpBytes(r2r, method.GcInfo.Offset, (uint)method.GcInfo.Size, false);
166174
}
167175
}
168176
_writer.WriteLine();
@@ -204,9 +212,11 @@ private void DumpRuntimeFunction(R2RReader r2r, RuntimeFunction rtf)
204212
/// <summary>
205213
/// Prints a formatted string containing a block of bytes from the relative virtual address and size
206214
/// </summary>
207-
public void DumpBytes(R2RReader r2r, int rva, uint size)
215+
public void DumpBytes(R2RReader r2r, int rva, uint size, bool convertToOffset = true)
208216
{
209-
uint start = (uint)r2r.GetOffset(rva);
217+
int start = rva;
218+
if (convertToOffset)
219+
start = r2r.GetOffset(rva);
210220
if (start > r2r.Image.Length || start + size > r2r.Image.Length)
211221
{
212222
throw new IndexOutOfRangeException();
@@ -234,14 +244,76 @@ public void DumpBytes(R2RReader r2r, int rva, uint size)
234244
_writer.WriteLine();
235245
}
236246

237-
private void DumpAvailableTypes(R2RReader r2r)
247+
private void DumpSectionContents(R2RReader r2r, R2RSection section)
238248
{
239-
WriteDivider("Available Types");
240-
foreach (string name in r2r.AvailableTypes)
249+
switch (section.Type)
241250
{
242-
_writer.WriteLine(name);
251+
case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES:
252+
uint availableTypesSectionOffset = (uint)r2r.GetOffset(section.RelativeVirtualAddress);
253+
NativeParser availableTypesParser = new NativeParser(r2r.Image, availableTypesSectionOffset);
254+
NativeHashtable availableTypes = new NativeHashtable(r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size));
255+
_writer.WriteLine(availableTypes.ToString());
256+
257+
foreach (string name in r2r.AvailableTypes)
258+
{
259+
_writer.WriteLine(name);
260+
}
261+
break;
262+
case R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS:
263+
NativeArray methodEntryPoints = new NativeArray(r2r.Image, (uint)r2r.GetOffset(section.RelativeVirtualAddress));
264+
_writer.Write(methodEntryPoints.ToString());
265+
break;
266+
case R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS:
267+
uint instanceSectionOffset = (uint)r2r.GetOffset(section.RelativeVirtualAddress);
268+
NativeParser instanceParser = new NativeParser(r2r.Image, instanceSectionOffset);
269+
NativeHashtable instMethodEntryPoints = new NativeHashtable(r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size));
270+
_writer.Write(instMethodEntryPoints.ToString());
271+
break;
272+
case R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS:
273+
int rtfOffset = r2r.GetOffset(section.RelativeVirtualAddress);
274+
int rtfEndOffset = rtfOffset + section.Size;
275+
int rtfIndex = 0;
276+
while (rtfOffset < rtfEndOffset)
277+
{
278+
uint rva = NativeReader.ReadUInt32(r2r.Image, ref rtfOffset);
279+
_writer.WriteLine($"{rtfIndex}: 0x{rva:X8}");
280+
rtfIndex++;
281+
}
282+
break;
283+
case R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER:
284+
_writer.WriteLine(r2r.CompileIdentifier);
285+
break;
286+
case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS:
287+
foreach (R2RImportSection importSection in r2r.ImportSections)
288+
{
289+
_writer.Write(importSection.ToString());
290+
if (_raw && importSection.Entries.Count != 0)
291+
{
292+
if (importSection.SectionRVA != 0)
293+
{
294+
_writer.WriteLine("Section Bytes:");
295+
DumpBytes(r2r, importSection.SectionRVA, (uint)importSection.SectionSize);
296+
}
297+
if (importSection.SignatureRVA != 0)
298+
{
299+
_writer.WriteLine("Signature Bytes:");
300+
DumpBytes(r2r, importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int));
301+
}
302+
if (importSection.AuxiliaryDataRVA != 0)
303+
{
304+
_writer.WriteLine("AuxiliaryData Bytes:");
305+
DumpBytes(r2r, importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size);
306+
}
307+
}
308+
foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
309+
{
310+
_writer.WriteLine();
311+
_writer.WriteLine(entry.ToString());
312+
}
313+
_writer.WriteLine();
314+
}
315+
break;
243316
}
244-
_writer.WriteLine();
245317
}
246318

247319
// <summary>
@@ -360,11 +432,6 @@ public void Dump(R2RReader r2r)
360432
QueryMethod(r2r, "R2R Methods by Keyword", _keywords, false);
361433
}
362434

363-
if (_types)
364-
{
365-
DumpAvailableTypes(r2r);
366-
}
367-
368435
_writer.WriteLine("=============================================================");
369436
_writer.WriteLine();
370437
}

0 commit comments

Comments
 (0)