Browse Source

Improving the code

pull/2043/head
Andrew Au 5 years ago
parent
commit
116b377250
  1. 112
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs
  2. 25
      ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml
  3. 14
      ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
  4. 8
      ILSpy.ReadyToRun/ReadyToRunOptions.cs

112
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -33,8 +33,8 @@ using ICSharpCode.Decompiler.IL; @@ -33,8 +33,8 @@ using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TextView;
using ILCompiler.Reflection.ReadyToRun;
using ILCompiler.Reflection.ReadyToRun.Amd64;
namespace ICSharpCode.ILSpy.ReadyToRun
{
@ -103,20 +103,20 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -103,20 +103,20 @@ namespace ICSharpCode.ILSpy.ReadyToRun
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;
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) {
if (i.UnwindInfo is ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo amd64UnwindInfo) {
if (i.UnwindInfo is UnwindInfo amd64UnwindInfo) {
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";
}
if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_UHANDLER) != 0) {
if ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_UHANDLER) != 0) {
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";
}
if (parsedFlags.Length == 0) {
@ -128,7 +128,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -128,7 +128,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
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]);
}
}
}
@ -138,18 +138,17 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -138,18 +138,17 @@ 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)
{
WriteCommentLine(output, readyToRunMethod.SignatureString);
Dictionary<ulong, ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode> unwindInfo = null;
if (ReadyToRunOptions.GetIsChecked(null)) {
Dictionary<ulong, UnwindCode> unwindInfo = null;
if (ReadyToRunOptions.GetIsShowUnwindInfo(null) && bitness == 64) {
unwindInfo = WriteUnwindInfo(readyToRunMethod, output);
WriteCommentLine(output, unwindInfo.ToString());
}
byte[] codeBytes = new byte[runtimeFunction.Size];
for (int i = 0; i < runtimeFunction.Size; 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 decoder = Decoder.Create(bitness, codeReader);
decoder.IP = address;
@ -198,48 +197,59 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -198,48 +197,59 @@ namespace ICSharpCode.ILSpy.ReadyToRun
output.Write(" ");
output.Write(" ");
output.Write(tempOutput.ToStringAndReset());
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)) {
output.Write(" ; ");
ReadyToRunSignature signature = reader.ImportSignatures[(int)instr.IPRelativeMemoryAddress];
switch(signature) {
case MethodDefEntrySignature methodDefSignature:
var methodDefToken = MetadataTokens.EntityHandle(unchecked((int)methodDefSignature.MethodDefToken));
if (showMetadataTokens) {
if (showMetadataTokensInBase10) {
output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken)}) ", "metadata");
} else {
output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken):X8}) ", "metadata");
}
DecorateUnwindInfo(output, unwindInfo, baseInstrIP, instr);
DecorateCallSite(currentFile, output, reader, showMetadataTokens, showMetadataTokensInBase10, instr);
}
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)) {
output.Write(" ; ");
ReadyToRunSignature signature = reader.ImportSignatures[(int)instr.IPRelativeMemoryAddress];
switch (signature) {
case MethodDefEntrySignature methodDefSignature:
var methodDefToken = MetadataTokens.EntityHandle(unchecked((int)methodDefSignature.MethodDefToken));
if (showMetadataTokens) {
if (showMetadataTokensInBase10) {
output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken)}) ", "metadata");
} else {
output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken):X8}) ", "metadata");
}
methodDefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
break;
case MethodRefEntrySignature methodRefSignature:
var methodRefToken = MetadataTokens.EntityHandle(unchecked((int)methodRefSignature.MethodRefToken));
if (showMetadataTokens) {
if (showMetadataTokensInBase10) {
output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken)}) ", "metadata");
} else {
output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken):X8}) ", "metadata");
}
}
methodDefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
break;
case MethodRefEntrySignature methodRefSignature:
var methodRefToken = MetadataTokens.EntityHandle(unchecked((int)methodRefSignature.MethodRefToken));
if (showMetadataTokens) {
if (showMetadataTokensInBase10) {
output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken)}) ", "metadata");
} else {
output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken):X8}) ", "metadata");
}
methodRefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
break;
default:
output.WriteLine(reader.ImportCellNames[importCellAddress]);
break;
}
output.WriteLine();
} else {
output.WriteLine();
}
methodRefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
break;
default:
output.WriteLine(reader.ImportCellNames[importCellAddress]);
break;
}
output.WriteLine();
} else {
output.WriteLine();
}
output.WriteLine();
}
public override RichText GetRichTextTooltip(IEntity entity)

25
ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml

@ -2,16 +2,19 @@ @@ -2,16 +2,19 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<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>
<Grid ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0">Disassembly Format</TextBlock>
<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>
</UserControl>

14
ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs

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

8
ILSpy.ReadyToRun/ReadyToRunOptions.cs

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

Loading…
Cancel
Save