Browse Source

Merge pull request #1 from cshung/public/dev/andrewau/refactoring

Improving the code
pull/2043/head
Edward Kazuya Carlson 5 years ago committed by GitHub
parent
commit
4c733e9c0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs
  2. 25
      ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml
  3. 14
      ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
  4. 8
      ILSpy.ReadyToRun/ReadyToRunOptions.cs

44
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -33,8 +33,8 @@ using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Solution; using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TextView;
using ILCompiler.Reflection.ReadyToRun; using ILCompiler.Reflection.ReadyToRun;
using ILCompiler.Reflection.ReadyToRun.Amd64;
namespace ICSharpCode.ILSpy.ReadyToRun namespace ICSharpCode.ILSpy.ReadyToRun
{ {
@ -103,20 +103,20 @@ namespace ICSharpCode.ILSpy.ReadyToRun
output.WriteLine("; " + comment); output.WriteLine("; " + comment);
} }
private Dictionary<ulong, ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode> WriteUnwindInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output) private Dictionary<ulong, UnwindCode> WriteUnwindInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output)
{ {
IReadOnlyList<RuntimeFunction> runTimeList = readyToRunMethod.RuntimeFunctions; IReadOnlyList<RuntimeFunction> runTimeList = readyToRunMethod.RuntimeFunctions;
Dictionary<ulong, ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode> unwindCodes = new Dictionary<ulong, ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode>(); Dictionary<ulong, UnwindCode> unwindCodes = new Dictionary<ulong, UnwindCode>();
foreach (RuntimeFunction i in runTimeList) { foreach (RuntimeFunction i in runTimeList) {
if (i.UnwindInfo is ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo amd64UnwindInfo) { if (i.UnwindInfo is UnwindInfo amd64UnwindInfo) {
string parsedFlags = ""; string parsedFlags = "";
if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_EHANDLER) != 0) { if ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_EHANDLER) != 0) {
parsedFlags += " EHANDLER"; parsedFlags += " EHANDLER";
} }
if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_UHANDLER) != 0) { if ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_UHANDLER) != 0) {
parsedFlags += " UHANDLER"; parsedFlags += " UHANDLER";
} }
if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_CHAININFO) != 0) { if ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_CHAININFO) != 0) {
parsedFlags += " CHAININFO"; parsedFlags += " CHAININFO";
} }
if (parsedFlags.Length == 0) { if (parsedFlags.Length == 0) {
@ -138,10 +138,9 @@ namespace ICSharpCode.ILSpy.ReadyToRun
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; Dictionary<ulong, UnwindCode> unwindInfo = null;
if (ReadyToRunOptions.GetIsChecked(null)) { if (ReadyToRunOptions.GetIsShowUnwindInfo(null) && bitness == 64) {
unwindInfo = WriteUnwindInfo(readyToRunMethod, output); unwindInfo = WriteUnwindInfo(readyToRunMethod, output);
WriteCommentLine(output, unwindInfo.ToString());
} }
byte[] codeBytes = new byte[runtimeFunction.Size]; byte[] codeBytes = new byte[runtimeFunction.Size];
@ -149,7 +148,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i]; codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
} }
// TODO: Decorate the disassembly with Unwind, GC and debug info // TODO: Decorate the disassembly with GC and debug info
var codeReader = new ByteArrayCodeReader(codeBytes); var codeReader = new ByteArrayCodeReader(codeBytes);
var decoder = Decoder.Create(bitness, codeReader); var decoder = Decoder.Create(bitness, codeReader);
decoder.IP = address; decoder.IP = address;
@ -198,11 +197,24 @@ namespace ICSharpCode.ILSpy.ReadyToRun
output.Write(" "); output.Write(" ");
output.Write(" "); output.Write(" ");
output.Write(tempOutput.ToStringAndReset()); output.Write(tempOutput.ToStringAndReset());
int importCellAddress = (int)instr.IPRelativeMemoryAddress; DecorateUnwindInfo(output, unwindInfo, baseInstrIP, instr);
if (unwindInfo!= null && unwindInfo.ContainsKey(instr.IP - baseInstrIP)) { DecorateCallSite(currentFile, output, reader, showMetadataTokens, showMetadataTokensInBase10, instr);
ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode unwindCode = unwindInfo[instr.IP - baseInstrIP]; }
output.Write($" ; UnwindCode: OpCode: {unwindCode.UnwindOp} Op: {unwindCode.OpInfoStr}"); output.WriteLine();
}
private static void DecorateUnwindInfo(ITextOutput output, Dictionary<ulong, UnwindCode> unwindInfo, ulong baseInstrIP, Instruction instr)
{
ulong nextInstructionOffset = instr.IP + (ulong)instr.Length - baseInstrIP;
if (unwindInfo != null && unwindInfo.ContainsKey(nextInstructionOffset)) {
UnwindCode unwindCode = unwindInfo[nextInstructionOffset];
output.Write($" ; {unwindCode.UnwindOp}({unwindCode.OpInfoStr})");
} }
}
private static void DecorateCallSite(PEFile currentFile, ITextOutput output, ReadyToRunReader reader, bool showMetadataTokens, bool showMetadataTokensInBase10, Instruction instr)
{
int importCellAddress = (int)instr.IPRelativeMemoryAddress;
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];
@ -239,8 +251,6 @@ namespace ICSharpCode.ILSpy.ReadyToRun
output.WriteLine(); output.WriteLine();
} }
} }
output.WriteLine();
}
public override RichText GetRichTextTooltip(IEntity entity) public override RichText GetRichTextTooltip(IEntity entity)
{ {

25
ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml

@ -2,16 +2,19 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel> <StackPanel>
<StackPanel Orientation="Horizontal"> <Grid ShowGridLines="False">
<StackPanel Orientation="Vertical"> <Grid.ColumnDefinitions>
<TextBlock>Disassembly Format</TextBlock> <ColumnDefinition></ColumnDefinition>
<TextBlock>Show Unwind Info</TextBlock> <ColumnDefinition></ColumnDefinition>
</StackPanel> </Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical"> <Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding DisassemblyFormats}" SelectedItem="{Binding DisassemblyFormat}"/> <RowDefinition></RowDefinition>
<CheckBox IsChecked="{Binding IsChecked}"></CheckBox> <RowDefinition></RowDefinition>
</Grid.RowDefinitions>
</StackPanel> <TextBlock Grid.Row="0" Grid.Column="0">Disassembly Format</TextBlock>
</StackPanel> <ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding DisassemblyFormats}" SelectedItem="{Binding DisassemblyFormat}"/>
<TextBlock Grid.Row="1" Grid.Column="0">Show Unwind Info</TextBlock>
<CheckBox Grid.Row="1" Grid.Column="1" IsChecked="{Binding IsShowUnwindInfo}"></CheckBox>
</Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

14
ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs

@ -35,7 +35,7 @@ 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); s.IsShowUnwindInfo = ReadyToRunOptions.GetIsShowUnwindInfo(settings);
this.DataContext = s; this.DataContext = s;
} }
@ -48,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.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsChecked); ReadyToRunOptions.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsShowUnwindInfo);
} }
} }
@ -60,14 +60,14 @@ namespace ICSharpCode.ILSpy.ReadyToRun
} }
} }
private bool isChecked; private bool isShowUnwindInfo;
public bool IsChecked { public bool IsShowUnwindInfo {
get { get {
return isChecked; return isShowUnwindInfo;
} }
set { set {
isChecked = value; isShowUnwindInfo = value;
OnPropertyChanged(nameof(IsChecked)); OnPropertyChanged(nameof(IsShowUnwindInfo));
} }
} }

8
ILSpy.ReadyToRun/ReadyToRunOptions.cs

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

Loading…
Cancel
Save