From fd0d89b253d3cb677b03bcf615c6c47f520f7bba Mon Sep 17 00:00:00 2001 From: plupiman Date: Fri, 19 Jun 2020 16:01:47 -0700 Subject: [PATCH 1/7] Added UnwindInfo as an optional printout --- ILSpy.ReadyToRun/ReadyToRunLanguage.cs | 44 +++++++++++++++++++ ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml | 11 ++++- ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs | 15 ++++++- ILSpy.ReadyToRun/ReadyToRunOptions.cs | 18 +++++++- 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs index 3bb34ee04..07ea593ea 100644 --- a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs +++ b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs @@ -103,9 +103,47 @@ namespace ICSharpCode.ILSpy.ReadyToRun output.WriteLine("; " + comment); } + private Dictionary WriteUnwindInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output) + { + IReadOnlyList runTimeList = readyToRunMethod.RuntimeFunctions; + Dictionary unwindCodes = new Dictionary(); + 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) { WriteCommentLine(output, readyToRunMethod.SignatureString); + Dictionary unwindInfo = null; + if (ReadyToRunOptions.GetIsChecked(null)) { + 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]; @@ -133,6 +171,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun formatter.Options.DigitSeparator = "`"; formatter.Options.FirstOperandCharIndex = 10; var tempOutput = new StringOutput(); + ulong baseInstrIP = instructions[0].IP; foreach (var instr in instructions) { int byteBaseIndex = (int)(instr.IP - address); if (runtimeFunction.DebugInfo != null) { @@ -160,6 +199,10 @@ namespace ICSharpCode.ILSpy.ReadyToRun 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]; @@ -190,6 +233,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun output.WriteLine(reader.ImportCellNames[importCellAddress]); break; } + output.WriteLine(); } else { output.WriteLine(); diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml index 9920b8344..1548792ee 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml +++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml @@ -3,8 +3,15 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - Disassembly Format - + + Disassembly Format + Show Unwind Info + + + + + + \ No newline at end of file diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs index ddbd6aed4..26e5821c7 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs +++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs @@ -35,6 +35,8 @@ namespace ICSharpCode.ILSpy.ReadyToRun { Options s = new Options(); s.DisassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(settings); + s.IsChecked = ReadyToRunOptions.GetIsChecked(settings); + this.DataContext = s; } @@ -46,7 +48,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun public void Save(XElement root) { 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; public string DisassemblyFormat { diff --git a/ILSpy.ReadyToRun/ReadyToRunOptions.cs b/ILSpy.ReadyToRun/ReadyToRunOptions.cs index 6ee672880..d0f263288 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptions.cs +++ b/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"); section.SetAttributeValue("DisassemblyFormat", disassemblyFormat); + section.SetAttributeValue("IsChecked", isChecked); XElement existingElement = root.Element(ns + "ReadyToRunOptions"); if (existingElement != null) { @@ -54,5 +69,6 @@ namespace ICSharpCode.ILSpy.ReadyToRun root.Add(section); } } + } } From 116b377250363b5734cf5820dd36f201d9b4453f Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Sat, 20 Jun 2020 10:36:45 -0700 Subject: [PATCH 2/7] Improving the code --- ILSpy.ReadyToRun/ReadyToRunLanguage.cs | 112 ++++++++++-------- ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml | 25 ++-- ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs | 14 +-- ILSpy.ReadyToRun/ReadyToRunOptions.cs | 8 +- 4 files changed, 86 insertions(+), 73 deletions(-) diff --git a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs index 07ea593ea..b273cfba7 100644 --- a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs +++ b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs @@ -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 output.WriteLine("; " + comment); } - private Dictionary WriteUnwindInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output) + private Dictionary WriteUnwindInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output) { IReadOnlyList runTimeList = readyToRunMethod.RuntimeFunctions; - Dictionary unwindCodes = new Dictionary(); + Dictionary unwindCodes = new Dictionary(); 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 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 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 unwindInfo = null; - if (ReadyToRunOptions.GetIsChecked(null)) { + Dictionary 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 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 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) diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml index 1548792ee..42840bee7 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml +++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml @@ -2,16 +2,19 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - - - Disassembly Format - Show Unwind Info - - - - - - - + + + + + + + + + + Disassembly Format + + Show Unwind Info + + \ No newline at end of file diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs index 26e5821c7..218ddb054 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs +++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs @@ -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 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 } } - 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)); } } diff --git a/ILSpy.ReadyToRun/ReadyToRunOptions.cs b/ILSpy.ReadyToRun/ReadyToRunOptions.cs index d0f263288..2317112b0 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptions.cs +++ b/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) { 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 } } - 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) { From 7970c2f1b3d19441b7d2b8ef982616e09881167f Mon Sep 17 00:00:00 2001 From: plupiman Date: Tue, 23 Jun 2020 13:22:47 -0700 Subject: [PATCH 3/7] merging --- ILSpy.ReadyToRun/ReadyToRunLanguage.cs | 84 +++++++++++++++++++ ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml | 5 +- ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs | 15 +++- ILSpy.ReadyToRun/ReadyToRunOptions.cs | 21 ++++- 4 files changed, 121 insertions(+), 4 deletions(-) diff --git a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs index b273cfba7..187f1b8e9 100644 --- a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs +++ b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs @@ -103,7 +103,88 @@ namespace ICSharpCode.ILSpy.ReadyToRun output.WriteLine("; " + comment); } + private void WriteDebugInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output) + { + IReadOnlyList runTimeList = readyToRunMethod.RuntimeFunctions; + foreach (RuntimeFunction runtimeFunction in runTimeList) { + DebugInfo debugInfo = runtimeFunction.DebugInfo; + if (debugInfo.BoundsList.Count > 0) + output.WriteLine("Debug Info"); + + output.WriteLine(" Bounds:"); + for (int i = 0; i < debugInfo.BoundsList.Count; ++i) { + output.Write(" "); + output.Write($"Native Offset: 0x{debugInfo.BoundsList[i].NativeOffset:X}, "); + if (debugInfo.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.NoMapping) { + output.Write("NoMapping"); + } else if (debugInfo.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.Prolog) { + output.Write("Prolog"); + } else if (debugInfo.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.Epilog) { + output.Write("Epilog"); + } else { + output.WriteLine($"IL Offset: 0x{debugInfo.BoundsList[i].ILOffset:x4}"); + } + output.Write($", Srouce Types: {debugInfo.BoundsList[i].SourceTypes}"); + output.WriteLine(); + } + output.WriteLine(""); + + if (debugInfo.VariablesList.Count > 0) + output.WriteLine(" Variable Locations:"); + + for (int i = 0; i < debugInfo.VariablesList.Count; ++i) { + var varLoc = debugInfo.VariablesList[i]; + output.WriteLine($" Variable Number: {varLoc.VariableNumber}"); + output.WriteLine($" Start Offset: 0x{varLoc.StartOffset:X}"); + output.WriteLine($" End Offset: 0x{varLoc.EndOffset:X}"); + output.WriteLine($" Loc Type: {varLoc.VariableLocation.VarLocType}"); + + switch (varLoc.VariableLocation.VarLocType) { + case VarLocType.VLT_REG: + case VarLocType.VLT_REG_FP: + case VarLocType.VLT_REG_BYREF: + output.WriteLine($" Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); + break; + case VarLocType.VLT_STK: + case VarLocType.VLT_STK_BYREF: + output.WriteLine($" Base Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); + output.WriteLine($" Stack Offset: {varLoc.VariableLocation.Data2}"); + break; + case VarLocType.VLT_REG_REG: + output.WriteLine($" Register 1: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); + output.WriteLine($" Register 2: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data2)}"); + break; + case VarLocType.VLT_REG_STK: + output.WriteLine($" Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); + output.WriteLine($" Base Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data2)}"); + output.WriteLine($" Stack Offset: {varLoc.VariableLocation.Data3}"); + break; + case VarLocType.VLT_STK_REG: + output.WriteLine($" Stack Offset: {varLoc.VariableLocation.Data1}"); + output.WriteLine($" Base Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data2)}"); + output.WriteLine($" Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data3)}"); + break; + case VarLocType.VLT_STK2: + output.WriteLine($" Base Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); + output.WriteLine($" Stack Offset: {varLoc.VariableLocation.Data2}"); + break; + case VarLocType.VLT_FPSTK: + output.WriteLine($" Offset: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); + break; + case VarLocType.VLT_FIXED_VA: + output.WriteLine($" Offset: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); + break; + default: + throw new BadImageFormatException("Unexpected var loc type"); + } + + output.WriteLine(""); + } + } + } + private Dictionary WriteUnwindInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output) + { IReadOnlyList runTimeList = readyToRunMethod.RuntimeFunctions; Dictionary unwindCodes = new Dictionary(); @@ -143,6 +224,9 @@ namespace ICSharpCode.ILSpy.ReadyToRun unwindInfo = WriteUnwindInfo(readyToRunMethod, output); } + if (ReadyToRunOptions.GetIsShowDebugInfo(null)) { + WriteDebugInfo(readyToRunMethod, output); + } byte[] codeBytes = new byte[runtimeFunction.Size]; for (int i = 0; i < runtimeFunction.Size; i++) { codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i]; diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml index 42840bee7..8f2922197 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml +++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml @@ -10,11 +10,14 @@ + Disassembly Format Show Unwind Info - + Show Debug Info + + \ No newline at end of file diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs index 218ddb054..3285434ee 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs +++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs @@ -36,6 +36,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun Options s = new Options(); s.DisassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(settings); s.IsShowUnwindInfo = ReadyToRunOptions.GetIsShowUnwindInfo(settings); + s.IsShowDebugInfo = ReadyToRunOptions.GetIsShowDebugInfo(settings); this.DataContext = s; } @@ -48,7 +49,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun public void Save(XElement root) { Options s = (Options)this.DataContext; - ReadyToRunOptions.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsShowUnwindInfo); + ReadyToRunOptions.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsShowUnwindInfo, s.IsShowDebugInfo); } } @@ -71,6 +72,18 @@ namespace ICSharpCode.ILSpy.ReadyToRun } } + + private bool isShowDebugInfo; + public bool IsShowDebugInfo { + get { + return isShowDebugInfo; + } + set { + isShowDebugInfo = value; + OnPropertyChanged(nameof(isShowDebugInfo)); + } + } + private string disassemblyFormat; public string DisassemblyFormat { diff --git a/ILSpy.ReadyToRun/ReadyToRunOptions.cs b/ILSpy.ReadyToRun/ReadyToRunOptions.cs index 2317112b0..40877901e 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptions.cs +++ b/ILSpy.ReadyToRun/ReadyToRunOptions.cs @@ -43,12 +43,14 @@ namespace ICSharpCode.ILSpy.ReadyToRun } public static bool GetIsShowUnwindInfo(ILSpySettings settings) + { if (settings == null) { settings = ILSpySettings.Load(); } XElement e = settings[ns + "ReadyToRunOptions"]; XAttribute a = e.Attribute("IsShowUnwindInfo"); + if (a == null) { return false; } else { @@ -56,12 +58,12 @@ namespace ICSharpCode.ILSpy.ReadyToRun } } - public static void SetDisassemblyOptions(XElement root, string disassemblyFormat, bool IsShowUnwindInfo) + public static void SetDisassemblyOptions(XElement root, string disassemblyFormat, bool IsShowUnwindInfo, bool IsShowDebugInfo) { XElement section = new XElement(ns + "ReadyToRunOptions"); section.SetAttributeValue("DisassemblyFormat", disassemblyFormat); section.SetAttributeValue("IsShowUnwindInfo", IsShowUnwindInfo); - + section.SetAttributeValue("IsShowDebugInfo", IsShowDebugInfo); XElement existingElement = root.Element(ns + "ReadyToRunOptions"); if (existingElement != null) { existingElement.ReplaceWith(section); @@ -70,5 +72,20 @@ namespace ICSharpCode.ILSpy.ReadyToRun } } + public static bool GetIsShowDebugInfo(ILSpySettings settings) + { + if (settings == null) { + settings = ILSpySettings.Load(); + } + XElement e = settings[ns + "ReadyToRunOptions"]; + XAttribute a = e.Attribute("IsShowDebugInfo"); + if (a == null) { + return false; + } else { + return (bool)a; + } + } + } + } From 06519b5cb06f8905a8590bdd579604fa69e1e460 Mon Sep 17 00:00:00 2001 From: plupiman Date: Tue, 23 Jun 2020 17:49:55 -0700 Subject: [PATCH 4/7] fixing double dictionary entry bug --- ILSpy.ReadyToRun/ReadyToRunLanguage.cs | 131 ++++-------------- ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs | 14 +- 2 files changed, 25 insertions(+), 120 deletions(-) diff --git a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs index 187f1b8e9..0cbef4902 100644 --- a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs +++ b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs @@ -103,114 +103,33 @@ namespace ICSharpCode.ILSpy.ReadyToRun output.WriteLine("; " + comment); } - private void WriteDebugInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output) - { - IReadOnlyList runTimeList = readyToRunMethod.RuntimeFunctions; - foreach (RuntimeFunction runtimeFunction in runTimeList) { - DebugInfo debugInfo = runtimeFunction.DebugInfo; - if (debugInfo.BoundsList.Count > 0) - output.WriteLine("Debug Info"); - - output.WriteLine(" Bounds:"); - for (int i = 0; i < debugInfo.BoundsList.Count; ++i) { - output.Write(" "); - output.Write($"Native Offset: 0x{debugInfo.BoundsList[i].NativeOffset:X}, "); - if (debugInfo.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.NoMapping) { - output.Write("NoMapping"); - } else if (debugInfo.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.Prolog) { - output.Write("Prolog"); - } else if (debugInfo.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.Epilog) { - output.Write("Epilog"); - } else { - output.WriteLine($"IL Offset: 0x{debugInfo.BoundsList[i].ILOffset:x4}"); - } - output.Write($", Srouce Types: {debugInfo.BoundsList[i].SourceTypes}"); - output.WriteLine(); - } - output.WriteLine(""); - - if (debugInfo.VariablesList.Count > 0) - output.WriteLine(" Variable Locations:"); - - for (int i = 0; i < debugInfo.VariablesList.Count; ++i) { - var varLoc = debugInfo.VariablesList[i]; - output.WriteLine($" Variable Number: {varLoc.VariableNumber}"); - output.WriteLine($" Start Offset: 0x{varLoc.StartOffset:X}"); - output.WriteLine($" End Offset: 0x{varLoc.EndOffset:X}"); - output.WriteLine($" Loc Type: {varLoc.VariableLocation.VarLocType}"); - switch (varLoc.VariableLocation.VarLocType) { - case VarLocType.VLT_REG: - case VarLocType.VLT_REG_FP: - case VarLocType.VLT_REG_BYREF: - output.WriteLine($" Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); - break; - case VarLocType.VLT_STK: - case VarLocType.VLT_STK_BYREF: - output.WriteLine($" Base Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); - output.WriteLine($" Stack Offset: {varLoc.VariableLocation.Data2}"); - break; - case VarLocType.VLT_REG_REG: - output.WriteLine($" Register 1: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); - output.WriteLine($" Register 2: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data2)}"); - break; - case VarLocType.VLT_REG_STK: - output.WriteLine($" Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); - output.WriteLine($" Base Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data2)}"); - output.WriteLine($" Stack Offset: {varLoc.VariableLocation.Data3}"); - break; - case VarLocType.VLT_STK_REG: - output.WriteLine($" Stack Offset: {varLoc.VariableLocation.Data1}"); - output.WriteLine($" Base Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data2)}"); - output.WriteLine($" Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data3)}"); - break; - case VarLocType.VLT_STK2: - output.WriteLine($" Base Register: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); - output.WriteLine($" Stack Offset: {varLoc.VariableLocation.Data2}"); - break; - case VarLocType.VLT_FPSTK: - output.WriteLine($" Offset: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); - break; - case VarLocType.VLT_FIXED_VA: - output.WriteLine($" Offset: {DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1)}"); - break; - default: - throw new BadImageFormatException("Unexpected var loc type"); - } - - output.WriteLine(""); - } - } - } - private Dictionary WriteUnwindInfo(ReadyToRunMethod readyToRunMethod, ITextOutput output) + private Dictionary WriteUnwindInfo(RuntimeFunction runtimeFunction, ITextOutput output) { - IReadOnlyList runTimeList = readyToRunMethod.RuntimeFunctions; Dictionary unwindCodes = new Dictionary(); - foreach (RuntimeFunction i in runTimeList) { - if (i.UnwindInfo is UnwindInfo amd64UnwindInfo) { - string parsedFlags = ""; - if ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_EHANDLER) != 0) { - parsedFlags += " EHANDLER"; - } - if ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_UHANDLER) != 0) { - parsedFlags += " UHANDLER"; - } - if ((amd64UnwindInfo.Flags & (int)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]); + if (runtimeFunction.UnwindInfo is UnwindInfo amd64UnwindInfo) { + string parsedFlags = ""; + if ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_EHANDLER) != 0) { + parsedFlags += " EHANDLER"; + } + if ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_UHANDLER) != 0) { + parsedFlags += " UHANDLER"; + } + if ((amd64UnwindInfo.Flags & (int)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((ulong)(amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex].CodeOffset), amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex]); - } } } return unwindCodes; @@ -221,12 +140,10 @@ namespace ICSharpCode.ILSpy.ReadyToRun WriteCommentLine(output, readyToRunMethod.SignatureString); Dictionary unwindInfo = null; if (ReadyToRunOptions.GetIsShowUnwindInfo(null) && bitness == 64) { - unwindInfo = WriteUnwindInfo(readyToRunMethod, output); + unwindInfo = WriteUnwindInfo(runtimeFunction, output); } - if (ReadyToRunOptions.GetIsShowDebugInfo(null)) { - WriteDebugInfo(readyToRunMethod, output); - } + byte[] codeBytes = new byte[runtimeFunction.Size]; for (int i = 0; i < runtimeFunction.Size; i++) { codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i]; @@ -289,7 +206,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun private static void DecorateUnwindInfo(ITextOutput output, Dictionary unwindInfo, ulong baseInstrIP, Instruction instr) { - ulong nextInstructionOffset = instr.IP + (ulong)instr.Length - baseInstrIP; + ulong nextInstructionOffset = instr.NextIP; if (unwindInfo != null && unwindInfo.ContainsKey(nextInstructionOffset)) { UnwindCode unwindCode = unwindInfo[nextInstructionOffset]; output.Write($" ; {unwindCode.UnwindOp}({unwindCode.OpInfoStr})"); diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs index 3285434ee..3e81b1c7c 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs +++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs @@ -36,7 +36,6 @@ namespace ICSharpCode.ILSpy.ReadyToRun Options s = new Options(); s.DisassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(settings); s.IsShowUnwindInfo = ReadyToRunOptions.GetIsShowUnwindInfo(settings); - s.IsShowDebugInfo = ReadyToRunOptions.GetIsShowDebugInfo(settings); this.DataContext = s; } @@ -49,7 +48,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun public void Save(XElement root) { Options s = (Options)this.DataContext; - ReadyToRunOptions.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsShowUnwindInfo, s.IsShowDebugInfo); + ReadyToRunOptions.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsShowUnwindInfo); } } @@ -73,17 +72,6 @@ namespace ICSharpCode.ILSpy.ReadyToRun } - private bool isShowDebugInfo; - public bool IsShowDebugInfo { - get { - return isShowDebugInfo; - } - set { - isShowDebugInfo = value; - OnPropertyChanged(nameof(isShowDebugInfo)); - } - } - private string disassemblyFormat; public string DisassemblyFormat { From 1afac33a007a66cdffc8d69bb3ec09abd7663162 Mon Sep 17 00:00:00 2001 From: plupiman Date: Tue, 23 Jun 2020 17:56:43 -0700 Subject: [PATCH 5/7] fixing debugInfo --- ILSpy.ReadyToRun/ReadyToRunOptions.cs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/ILSpy.ReadyToRun/ReadyToRunOptions.cs b/ILSpy.ReadyToRun/ReadyToRunOptions.cs index 40877901e..5eddd6789 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptions.cs +++ b/ILSpy.ReadyToRun/ReadyToRunOptions.cs @@ -58,12 +58,11 @@ namespace ICSharpCode.ILSpy.ReadyToRun } } - public static void SetDisassemblyOptions(XElement root, string disassemblyFormat, bool IsShowUnwindInfo, bool IsShowDebugInfo) + public static void SetDisassemblyOptions(XElement root, string disassemblyFormat, bool IsShowUnwindInfo) { XElement section = new XElement(ns + "ReadyToRunOptions"); section.SetAttributeValue("DisassemblyFormat", disassemblyFormat); section.SetAttributeValue("IsShowUnwindInfo", IsShowUnwindInfo); - section.SetAttributeValue("IsShowDebugInfo", IsShowDebugInfo); XElement existingElement = root.Element(ns + "ReadyToRunOptions"); if (existingElement != null) { existingElement.ReplaceWith(section); @@ -72,19 +71,6 @@ namespace ICSharpCode.ILSpy.ReadyToRun } } - public static bool GetIsShowDebugInfo(ILSpySettings settings) - { - if (settings == null) { - settings = ILSpySettings.Load(); - } - XElement e = settings[ns + "ReadyToRunOptions"]; - XAttribute a = e.Attribute("IsShowDebugInfo"); - if (a == null) { - return false; - } else { - return (bool)a; - } - } } From 9af5a34991ea6e6aa5edbccd1b57a5af59ab78c1 Mon Sep 17 00:00:00 2001 From: Edward Kazuya Carlson Date: Tue, 23 Jun 2020 22:12:13 -0400 Subject: [PATCH 6/7] Update ILSpy.ReadyToRun/ReadyToRunLanguage.cs Co-authored-by: Andrew Au --- ILSpy.ReadyToRun/ReadyToRunLanguage.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs index 0cbef4902..f29c5ce73 100644 --- a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs +++ b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs @@ -206,7 +206,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun private static void DecorateUnwindInfo(ITextOutput output, Dictionary unwindInfo, ulong baseInstrIP, Instruction instr) { - ulong nextInstructionOffset = instr.NextIP; + ulong nextInstructionOffset = instr.NextIP - baseInstrIP; if (unwindInfo != null && unwindInfo.ContainsKey(nextInstructionOffset)) { UnwindCode unwindCode = unwindInfo[nextInstructionOffset]; output.Write($" ; {unwindCode.UnwindOp}({unwindCode.OpInfoStr})"); @@ -313,4 +313,4 @@ namespace ICSharpCode.ILSpy.ReadyToRun public Dictionary methodMap; } } -} \ No newline at end of file +} From 79b24e26fa49725550eb24a3b3b39f644fffa600 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 24 Jun 2020 14:28:49 +0200 Subject: [PATCH 7/7] Clean up XAML of ReadyToRunOptionPage and use Margin="3" everywhere. --- ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml | 36 ++++++++++------------ 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml index 8f2922197..188f52994 100644 --- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml +++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml @@ -1,23 +1,21 @@  - - - - - - - - - - - - Disassembly Format - - Show Unwind Info - - Show Debug Info - - - + + + + + + + + + + + Disassembly Format + + Show Unwind Info + + Show Debug Info + + \ No newline at end of file