Browse Source

Added UnwindInfo as an optional printout

pull/2043/head
plupiman 5 years ago
parent
commit
fd0d89b253
  1. 44
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs
  2. 11
      ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml
  3. 15
      ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
  4. 18
      ILSpy.ReadyToRun/ReadyToRunOptions.cs

44
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -103,9 +103,47 @@ namespace ICSharpCode.ILSpy.ReadyToRun
output.WriteLine("; " + comment); output.WriteLine("; " + comment);
} }
private Dictionary<ulong, ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode> WriteUnwindInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output)
{
IReadOnlyList<RuntimeFunction> runTimeList = readyToRunMethod.RuntimeFunctions;
Dictionary<ulong, ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode> unwindCodes = new Dictionary<ulong, ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode>();
foreach (RuntimeFunction i in runTimeList) {
if (i.UnwindInfo is ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo amd64UnwindInfo) {
string parsedFlags = "";
if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_EHANDLER) != 0) {
parsedFlags += " EHANDLER";
}
if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_UHANDLER) != 0) {
parsedFlags += " UHANDLER";
}
if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_CHAININFO) != 0) {
parsedFlags += " CHAININFO";
}
if (parsedFlags.Length == 0) {
parsedFlags = " NHANDLER";
}
WriteCommentLine(output, $"UnwindInfo:");
WriteCommentLine(output, $"Version: {amd64UnwindInfo.Version}");
WriteCommentLine(output, $"Flags: 0x{amd64UnwindInfo.Flags:X2}{parsedFlags}");
WriteCommentLine(output, $"FrameRegister: {((amd64UnwindInfo.FrameRegister == 0) ? "none" : amd64UnwindInfo.FrameRegister.ToString())}");
for (int unwindCodeIndex = 0; unwindCodeIndex < amd64UnwindInfo.CountOfUnwindCodes; unwindCodeIndex++) {
unwindCodes.Add(amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex].CodeOffset, amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex]);
}
}
}
return unwindCodes;
}
private void Disassemble(PEFile currentFile, ITextOutput output, ReadyToRunReader reader, ReadyToRunMethod readyToRunMethod, RuntimeFunction runtimeFunction, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10) private void Disassemble(PEFile currentFile, ITextOutput output, ReadyToRunReader reader, ReadyToRunMethod readyToRunMethod, RuntimeFunction runtimeFunction, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)
{ {
WriteCommentLine(output, readyToRunMethod.SignatureString); WriteCommentLine(output, readyToRunMethod.SignatureString);
Dictionary<ulong, ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode> unwindInfo = null;
if (ReadyToRunOptions.GetIsChecked(null)) {
unwindInfo = WriteUnwindInfo(readyToRunMethod, output);
WriteCommentLine(output, unwindInfo.ToString());
}
byte[] codeBytes = new byte[runtimeFunction.Size]; byte[] codeBytes = new byte[runtimeFunction.Size];
for (int i = 0; i < runtimeFunction.Size; i++) { for (int i = 0; i < runtimeFunction.Size; i++) {
codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i]; codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
@ -133,6 +171,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
formatter.Options.DigitSeparator = "`"; formatter.Options.DigitSeparator = "`";
formatter.Options.FirstOperandCharIndex = 10; formatter.Options.FirstOperandCharIndex = 10;
var tempOutput = new StringOutput(); var tempOutput = new StringOutput();
ulong baseInstrIP = instructions[0].IP;
foreach (var instr in instructions) { foreach (var instr in instructions) {
int byteBaseIndex = (int)(instr.IP - address); int byteBaseIndex = (int)(instr.IP - address);
if (runtimeFunction.DebugInfo != null) { if (runtimeFunction.DebugInfo != null) {
@ -160,6 +199,10 @@ namespace ICSharpCode.ILSpy.ReadyToRun
output.Write(" "); output.Write(" ");
output.Write(tempOutput.ToStringAndReset()); output.Write(tempOutput.ToStringAndReset());
int importCellAddress = (int)instr.IPRelativeMemoryAddress; int importCellAddress = (int)instr.IPRelativeMemoryAddress;
if (unwindInfo!= null && unwindInfo.ContainsKey(instr.IP - baseInstrIP)) {
ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode unwindCode = unwindInfo[instr.IP - baseInstrIP];
output.Write($" ; UnwindCode: OpCode: {unwindCode.UnwindOp} Op: {unwindCode.OpInfoStr}");
}
if (instr.IsCallNearIndirect && reader.ImportCellNames.ContainsKey(importCellAddress)) { if (instr.IsCallNearIndirect && reader.ImportCellNames.ContainsKey(importCellAddress)) {
output.Write(" ; "); output.Write(" ; ");
ReadyToRunSignature signature = reader.ImportSignatures[(int)instr.IPRelativeMemoryAddress]; ReadyToRunSignature signature = reader.ImportSignatures[(int)instr.IPRelativeMemoryAddress];
@ -190,6 +233,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
output.WriteLine(reader.ImportCellNames[importCellAddress]); output.WriteLine(reader.ImportCellNames[importCellAddress]);
break; break;
} }
output.WriteLine(); output.WriteLine();
} else { } else {
output.WriteLine(); output.WriteLine();

11
ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml

@ -3,8 +3,15 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel> <StackPanel>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock>Disassembly Format</TextBlock> <StackPanel Orientation="Vertical">
<ComboBox ItemsSource="{Binding DisassemblyFormats}" SelectedItem="{Binding DisassemblyFormat}"/> <TextBlock>Disassembly Format</TextBlock>
<TextBlock>Show Unwind Info</TextBlock>
</StackPanel>
<StackPanel Orientation="Vertical">
<ComboBox ItemsSource="{Binding DisassemblyFormats}" SelectedItem="{Binding DisassemblyFormat}"/>
<CheckBox IsChecked="{Binding IsChecked}"></CheckBox>
</StackPanel>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

15
ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs

@ -35,6 +35,8 @@ namespace ICSharpCode.ILSpy.ReadyToRun
{ {
Options s = new Options(); Options s = new Options();
s.DisassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(settings); s.DisassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(settings);
s.IsChecked = ReadyToRunOptions.GetIsChecked(settings);
this.DataContext = s; this.DataContext = s;
} }
@ -46,7 +48,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public void Save(XElement root) public void Save(XElement root)
{ {
Options s = (Options)this.DataContext; Options s = (Options)this.DataContext;
ReadyToRunOptions.SetDisassemblyFormat(root, s.DisassemblyFormat); ReadyToRunOptions.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsChecked);
} }
} }
@ -58,6 +60,17 @@ namespace ICSharpCode.ILSpy.ReadyToRun
} }
} }
private bool isChecked;
public bool IsChecked {
get {
return isChecked;
}
set {
isChecked = value;
OnPropertyChanged(nameof(IsChecked));
}
}
private string disassemblyFormat; private string disassemblyFormat;
public string DisassemblyFormat { public string DisassemblyFormat {

18
ILSpy.ReadyToRun/ReadyToRunOptions.cs

@ -42,10 +42,25 @@ namespace ICSharpCode.ILSpy.ReadyToRun
} }
} }
public static void SetDisassemblyFormat(XElement root, string disassemblyFormat) public static bool GetIsChecked(ILSpySettings settings)
{
if (settings == null) {
settings = ILSpySettings.Load();
}
XElement e = settings[ns + "ReadyToRunOptions"];
XAttribute a = e.Attribute("IsChecked");
if (a == null) {
return false;
} else {
return (bool)a;
}
}
public static void SetDisassemblyOptions(XElement root, string disassemblyFormat, bool isChecked)
{ {
XElement section = new XElement(ns + "ReadyToRunOptions"); XElement section = new XElement(ns + "ReadyToRunOptions");
section.SetAttributeValue("DisassemblyFormat", disassemblyFormat); section.SetAttributeValue("DisassemblyFormat", disassemblyFormat);
section.SetAttributeValue("IsChecked", isChecked);
XElement existingElement = root.Element(ns + "ReadyToRunOptions"); XElement existingElement = root.Element(ns + "ReadyToRunOptions");
if (existingElement != null) { if (existingElement != null) {
@ -54,5 +69,6 @@ namespace ICSharpCode.ILSpy.ReadyToRun
root.Add(section); root.Add(section);
} }
} }
} }
} }

Loading…
Cancel
Save