summaryrefslogtreecommitdiff
path: root/src/tools/r2rdump/R2RDump.cs
diff options
context:
space:
mode:
authorTomáš Rylek <trylek@microsoft.com>2018-10-04 21:29:24 +0200
committerGitHub <noreply@github.com>2018-10-04 21:29:24 +0200
commit030e0af89bb897554acef575075c69aaf5176268 (patch)
treeec5d48bdffa8b63e0d011f6b713bd027b235ceaa /src/tools/r2rdump/R2RDump.cs
parente43bc521df71513061c7194efc4af4c70a1b9b42 (diff)
downloadcoreclr-030e0af89bb897554acef575075c69aaf5176268.tar.gz
coreclr-030e0af89bb897554acef575075c69aaf5176268.tar.bz2
coreclr-030e0af89bb897554acef575075c69aaf5176268.zip
R2RDump fixes for dumping method instance entrypoint table (#20243)
R2RDump fixes for dumping method instance entrypoint table While investigating Michal's unit test demonstrating a bug in the CPAOT compiler I found out that R2RDump is broken in multiple aspects w.r.t. instantiated methods. Parsing of the method signatures in the instance entrypoint table was just broken and the R2RMethod was duplicating parts of the signature decoding and name formatting process. I created a new flag "normalize" that requests normalization of various R2R tables in the dump aimed at improving diff quality. I have also noticed and fixed somewhat weird formatting of method signatures. As a slight cleanup I have lumped the various dump flags into a helper class DumpOptions. Last but not least I have renamed "Canon" to "__Canon". Thanks Tomas
Diffstat (limited to 'src/tools/r2rdump/R2RDump.cs')
-rw-r--r--src/tools/r2rdump/R2RDump.cs96
1 files changed, 64 insertions, 32 deletions
diff --git a/src/tools/r2rdump/R2RDump.cs b/src/tools/r2rdump/R2RDump.cs
index 34b86b75ef..0901ee672e 100644
--- a/src/tools/r2rdump/R2RDump.cs
+++ b/src/tools/r2rdump/R2RDump.cs
@@ -6,24 +6,60 @@ using System;
using System.Collections.Generic;
using System.CommandLine;
using System.IO;
+using System.Linq;
+using System.Reflection.Metadata;
+using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace R2RDump
{
+ public class DumpOptions
+ {
+ public bool Raw;
+ public bool Normalize;
+ public bool Header;
+ public bool Disasm;
+ public bool Unwind;
+ public bool GC;
+ public bool SectionContents;
+ }
+
public abstract class Dumper
{
- internal R2RReader _r2r;
- internal TextWriter _writer;
+ protected readonly R2RReader _r2r;
+ protected readonly TextWriter _writer;
+ protected readonly Disassembler _disassembler;
+ protected readonly DumpOptions _options;
- internal bool _raw;
- internal bool _header;
- internal bool _disasm;
- internal Disassembler _disassembler;
- internal bool _unwind;
- internal bool _gc;
- internal bool _sectionContents;
+ public Dumper(R2RReader r2r, TextWriter writer, Disassembler disassembler, DumpOptions options)
+ {
+ _r2r = r2r;
+ _writer = writer;
+ _disassembler = disassembler;
+ _options = options;
+ }
+
+ public IEnumerable<R2RSection> NormalizedSections()
+ {
+ IEnumerable<R2RSection> sections = _r2r.R2RHeader.Sections.Values;
+ if (_options.Normalize)
+ {
+ sections = sections.OrderBy((s) => s.Type);
+ }
+ return sections;
+ }
+
+ public IEnumerable<R2RMethod> NormalizedMethods()
+ {
+ IEnumerable<R2RMethod> methods = _r2r.R2RMethods;
+ if (_options.Normalize)
+ {
+ methods = methods.OrderBy((m) => m.SignatureString);
+ }
+ return methods;
+ }
/// <summary>
/// Run right before printing output
@@ -54,18 +90,13 @@ namespace R2RDump
private bool _help;
private IReadOnlyList<string> _inputFilenames = Array.Empty<string>();
private string _outputFilename = null;
- private bool _xml;
- private bool _raw;
- private bool _header;
- private bool _disasm;
+ private DumpOptions _options = new DumpOptions();
private IReadOnlyList<string> _queries = Array.Empty<string>();
private IReadOnlyList<string> _keywords = Array.Empty<string>();
private IReadOnlyList<int> _runtimeFunctions = Array.Empty<int>();
private IReadOnlyList<string> _sections = Array.Empty<string>();
private bool _diff;
- private bool _unwind;
- private bool _gc;
- private bool _sectionContents;
+ private bool _xml;
private TextWriter _writer;
private Dictionary<R2RSection.SectionType, bool> _selectedSections = new Dictionary<R2RSection.SectionType, bool>();
private Dumper _dumper;
@@ -91,16 +122,17 @@ namespace R2RDump
syntax.DefineOptionList("i|in", ref _inputFilenames, "Input file(s) to dump. Expects them to by ReadyToRun images");
syntax.DefineOption("o|out", ref _outputFilename, "Output file path. Dumps everything to the specified file except help message and exception messages");
syntax.DefineOption("x|xml", ref _xml, "Output in XML format");
- syntax.DefineOption("raw", ref _raw, "Dump the raw bytes of each section or runtime function");
- syntax.DefineOption("header", ref _header, "Dump R2R header");
- syntax.DefineOption("d|disasm", ref _disasm, "Show disassembly of methods or runtime functions");
+ syntax.DefineOption("raw", ref _options.Raw, "Dump the raw bytes of each section or runtime function");
+ syntax.DefineOption("header", ref _options.Header, "Dump R2R header");
+ syntax.DefineOption("d|disasm", ref _options.Disasm, "Show disassembly of methods or runtime functions");
syntax.DefineOptionList("q|query", ref _queries, "Query method by exact name, signature, row id or token");
syntax.DefineOptionList("k|keyword", ref _keywords, "Search method by keyword");
syntax.DefineOptionList("r|runtimefunction", ref _runtimeFunctions, ArgStringToInt, "Get one runtime function by id or relative virtual address");
syntax.DefineOptionList("s|section", ref _sections, "Get section by keyword");
- syntax.DefineOption("unwind", ref _unwind, "Dump unwindInfo");
- syntax.DefineOption("gc", ref _gc, "Dump gcInfo and slot table");
- syntax.DefineOption("sc", ref _sectionContents, "Dump section contents");
+ syntax.DefineOption("unwind", ref _options.Unwind, "Dump unwindInfo");
+ syntax.DefineOption("gc", ref _options.GC, "Dump gcInfo and slot table");
+ syntax.DefineOption("sc", ref _options.SectionContents, "Dump section contents");
+ syntax.DefineOption("n|normalize", ref _options.Normalize, "Normalize dump by sorting the various tables and methods (default = unsorted i.e. file order)");
syntax.DefineOption("v|verbose", ref verbose, "Dump disassembly, unwindInfo, gcInfo and section contents");
syntax.DefineOption("diff", ref _diff, "Compare two R2R images");
syntax.DefineOption("ignoreSensitive", ref _ignoreSensitive, "Ignores sensitive properties in xml dump to avoid failing tests");
@@ -108,10 +140,10 @@ namespace R2RDump
if (verbose)
{
- _disasm = true;
- _unwind = true;
- _gc = true;
- _sectionContents = true;
+ _options.Disasm = true;
+ _options.Unwind = true;
+ _options.GC = true;
+ _options.SectionContents = true;
}
return argSyntax;
@@ -237,14 +269,14 @@ namespace R2RDump
_dumper.WriteDivider("R2R Header");
_dumper.DumpHeader(true);
- if (!_header)
+ if (!_options.Header)
{
_dumper.DumpAllMethods();
}
}
else //dump queried sections, methods and runtimeFunctions
{
- if (_header)
+ if (_options.Header)
{
_dumper.DumpHeader(false);
}
@@ -267,7 +299,7 @@ namespace R2RDump
{
int id;
bool isNum = ArgStringToInt(query, out id);
- bool idMatch = isNum && (method.Rid == id || method.Token == id);
+ bool idMatch = isNum && (method.Rid == id || MetadataTokens.GetRowNumber(method.MetadataReader, method.MethodHandle) == id);
bool sigMatch = false;
if (exact)
@@ -401,7 +433,7 @@ namespace R2RDump
// parse the ReadyToRun image
R2RReader r2r = new R2RReader(filename);
- if (_disasm)
+ if (_options.Disasm)
{
if (r2r.InputArchitectureSupported() && r2r.DisassemblerArchitectureSupported())
{
@@ -415,11 +447,11 @@ namespace R2RDump
if (_xml)
{
- _dumper = new XmlDumper(_ignoreSensitive, r2r, _writer, _raw, _header, _disasm, disassembler, _unwind, _gc, _sectionContents);
+ _dumper = new XmlDumper(_ignoreSensitive, r2r, _writer, disassembler, _options);
}
else
{
- _dumper = new TextDumper(r2r, _writer, _raw, _header, _disasm, disassembler, _unwind, _gc, _sectionContents);
+ _dumper = new TextDumper(r2r, _writer, disassembler, _options);
}
if (!_diff)