From e03576ea2e3d94f55417472aa5d1fc19bacfdf05 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Tue, 28 Jul 2020 11:34:00 -0700 Subject: [PATCH] Fix unwind info decoding --- .../Amd64/UnwindInfo.cs | 25 +++++++++++++------ src/coreclr/src/tools/r2rdump/TextDumper.cs | 13 ++++------ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs index 1c5150bcedaf6d..08241e0a433d11 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Text; namespace ILCompiler.Reflection.ReadyToRun.Amd64 @@ -76,6 +77,19 @@ public UnwindCode(byte[] image, int index, ref int offset) FrameOffset = NativeReader.ReadUInt16(image, ref offset); NextFrameOffset = -1; + if (UnwindOp == UnwindOpCodes.UWOP_ALLOC_LARGE) + { + uint codedSize; + if (OpInfo == 0) + { + codedSize = NativeReader.ReadUInt16(image, ref offset); + } + else if (OpInfo == 1) + { + codedSize = NativeReader.ReadUInt32(image, ref offset); + } + } + IsOpInfo = false; } } @@ -95,7 +109,7 @@ public class UnwindInfo : BaseUnwindInfo public Registers FrameRegister { get; set; } //4 bits public byte FrameOffset { get; set; } //4 bits public UnwindCode[] UnwindCodeArray { get; set; } - public Dictionary> UnwindCodes { get; set; } + public Dictionary UnwindCodes { get; set; } public uint PersonalityRoutineRVA { get; set; } public UnwindInfo() { } @@ -115,7 +129,7 @@ public UnwindInfo(byte[] image, int offset) FrameOffset = (byte)(frameRegisterAndOffset >> 4); UnwindCodeArray = new UnwindCode[CountOfUnwindCodes]; - UnwindCodes = new Dictionary>(); + UnwindCodes = new Dictionary(); for (int i = 0; i < CountOfUnwindCodes; i++) { UnwindCodeArray[i] = new UnwindCode(image, i, ref offset); @@ -123,11 +137,8 @@ public UnwindInfo(byte[] image, int offset) for (int i = 0; i < CountOfUnwindCodes; i++) { ParseUnwindCode(ref i); - if (!UnwindCodes.ContainsKey(UnwindCodeArray[i].CodeOffset)) - { - UnwindCodes[UnwindCodeArray[i].CodeOffset] = new List(); - } - UnwindCodes[UnwindCodeArray[i].CodeOffset].Add(UnwindCodeArray[i]); + Debug.Assert(!UnwindCodes.ContainsKey(UnwindCodeArray[i].CodeOffset)); + UnwindCodes.Add(UnwindCodeArray[i].CodeOffset, UnwindCodeArray[i]); } Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode; diff --git a/src/coreclr/src/tools/r2rdump/TextDumper.cs b/src/coreclr/src/tools/r2rdump/TextDumper.cs index b3bf91845f380d..19aa23f791eae5 100644 --- a/src/coreclr/src/tools/r2rdump/TextDumper.cs +++ b/src/coreclr/src/tools/r2rdump/TextDumper.cs @@ -217,16 +217,13 @@ internal override void DumpDisasm(RuntimeFunction rtf, int imageOffset) if (_r2r.Machine == Machine.Amd64 && ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes.ContainsKey(codeOffset)) { - List codes = ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes[codeOffset]; - foreach (ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode code in codes) + ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode code = ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes[codeOffset]; + _writer.Write($"{indentString}{code.UnwindOp} {code.OpInfoStr}"); + if (code.NextFrameOffset != -1) { - _writer.Write($"{indentString}{code.UnwindOp} {code.OpInfoStr}"); - if (code.NextFrameOffset != -1) - { - _writer.WriteLine($"{indentString}{code.NextFrameOffset}"); - } - _writer.WriteLine(); + _writer.WriteLine($"{indentString}{code.NextFrameOffset}"); } + _writer.WriteLine(); } if (!_options.HideTransitions && rtf.Method.GcInfo?.Transitions != null && rtf.Method.GcInfo.Transitions.TryGetValue(codeOffset, out List transitionsForOffset))