diff options
author | Amy Yu <amycmyu@gmail.com> | 2018-06-15 17:07:41 -0700 |
---|---|---|
committer | Amy Yu <amycmyu@gmail.com> | 2018-06-15 17:20:47 -0700 |
commit | c77c97e4d08ad8cafdae00128496b214dc2a2098 (patch) | |
tree | 1ca1134c463b15fae89e34b11cb8d6f59bec50c5 /src | |
parent | 1df3d7978e69166fa366c5788d114acf1c743d70 (diff) | |
download | coreclr-c77c97e4d08ad8cafdae00128496b214dc2a2098.tar.gz coreclr-c77c97e4d08ad8cafdae00128496b214dc2a2098.tar.bz2 coreclr-c77c97e4d08ad8cafdae00128496b214dc2a2098.zip |
Interweave gcslot liveness with disasm
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/r2rdump/CoreDisTools.cs | 38 | ||||
-rw-r--r-- | src/tools/r2rdump/GCInfo.cs | 34 | ||||
-rw-r--r-- | src/tools/r2rdump/R2RDump.cs | 9 | ||||
-rw-r--r-- | src/tools/r2rdump/R2RMethod.cs | 5 | ||||
-rw-r--r-- | src/tools/r2rdump/R2RReader.cs | 5 |
5 files changed, 67 insertions, 24 deletions
diff --git a/src/tools/r2rdump/CoreDisTools.cs b/src/tools/r2rdump/CoreDisTools.cs index 16fef7e848..ad3b7b45e4 100644 --- a/src/tools/r2rdump/CoreDisTools.cs +++ b/src/tools/r2rdump/CoreDisTools.cs @@ -3,8 +3,10 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.Reflection.PortableExecutable; using System.Runtime.InteropServices; +using System.Text; namespace R2RDump { @@ -38,18 +40,36 @@ namespace R2RDump [DllImport("coredistools.dll")] public static extern void FinishDisasm(IntPtr Disasm); - public unsafe static string GetCodeBlock(IntPtr Disasm, int Address, int Offset, byte[] image, int Size) + public unsafe static string GetCodeBlock(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image) { - int len; - fixed (byte* p = image) + StringBuilder sb = new StringBuilder(); + + int rtfOffset = 0; + int codeOffset = rtf.CodeOffset; + Dictionary<int, GcInfo.GcTransition> transitions = rtf.Method.GcInfo.Transitions; + GcSlotTable slotTable = rtf.Method.GcInfo.SlotTable; + while (rtfOffset < rtf.Size) { - IntPtr ptr = (IntPtr)(p + Offset); - len = DumpInstruction(Disasm, (ulong)Address, ptr, Size); //DumpCodeBlock(Disasm, (ulong)Address, ptr, Size); + int instrSize = 1; + fixed (byte* p = image) + { + IntPtr ptr = (IntPtr)(p + imageOffset + rtfOffset); + instrSize = DumpInstruction(Disasm, (ulong)(rtf.StartAddress + rtfOffset), ptr, rtf.Size); + } + IntPtr pBuffer = GetOutputBuffer(); + string instr = Marshal.PtrToStringAnsi(pBuffer); + + sb.Append(instr); + if (transitions.ContainsKey(codeOffset)) + { + sb.AppendLine($"\t\t\t\t{transitions[codeOffset].GetSlotState(slotTable)}"); + } + + ClearOutputBuffer(); + rtfOffset += instrSize; + codeOffset += instrSize; } - IntPtr pBuffer = GetOutputBuffer(); - string buffer = Marshal.PtrToStringAnsi(pBuffer); - ClearOutputBuffer(); - return buffer; + return sb.ToString(); } public static IntPtr GetDisasm(Machine machine) diff --git a/src/tools/r2rdump/GCInfo.cs b/src/tools/r2rdump/GCInfo.cs index e924d408c7..04422862e3 100644 --- a/src/tools/r2rdump/GCInfo.cs +++ b/src/tools/r2rdump/GCInfo.cs @@ -48,6 +48,7 @@ namespace R2RDump public int SlotId { get; } public bool IsLive { get; } public int ChunkId { get; } + public GcTransition(int codeOffset, int slotId, bool isLive, int chunkId) { CodeOffset = codeOffset; @@ -68,6 +69,23 @@ namespace R2RDump return sb.ToString(); } + public string GetSlotState(GcSlotTable slotTable) + { + GcSlotTable.GcSlot slot = slotTable.GcSlots[SlotId]; + string slotStr = ""; + if (slot.StackSlot == null) + { + slotStr = Enum.GetName(typeof(Amd64Registers), slot.RegisterNumber); + } + else + { + slotStr = $"sp{slot.StackSlot.SpOffset:+#;-#;+0}"; + } + string isLiveStr = "live"; + if (!IsLive) + isLiveStr = "dead"; + return $"{slotStr} is {isLiveStr}"; + } } private const int GCINFO_VERSION = 2; @@ -107,7 +125,7 @@ namespace R2RDump public GcSlotTable SlotTable { get; } public int Size { get; } public int Offset { get; } - public IList<GcTransition> Transitions { get; } + public Dictionary<int, GcTransition> Transitions { get; } public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion) { @@ -283,7 +301,7 @@ namespace R2RDump sb.AppendLine($"{tab}SlotTable:"); sb.Append(SlotTable.ToString()); sb.AppendLine($"{tab}Transitions:"); - foreach (GcTransition trans in Transitions) + foreach (GcTransition trans in Transitions.Values) { sb.AppendLine(trans.ToString()); } @@ -359,7 +377,7 @@ namespace R2RDump return (readyToRunMajorVersion == 1) ? 1 : GCINFO_VERSION; } - public IList<GcTransition> GetTranstions(byte[] image, ref int bitOffset) + public Dictionary<int, GcTransition> GetTranstions(byte[] image, ref int bitOffset) { int totalInterruptibleLength = 0; if (NumInterruptibleRanges == 0) @@ -378,7 +396,7 @@ namespace R2RDump int numBitsPerPointer = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset); if (numBitsPerPointer == 0) { - return new List<GcTransition>(); + return new Dictionary<int, GcTransition>(); } int[] chunkPointers = new int[numChunks]; @@ -437,9 +455,8 @@ namespace R2RDump } transitions.Sort((s1, s2) => s1.CodeOffset.CompareTo(s2.CodeOffset)); - UpdateTransitionCodeOffset(transitions); - return transitions; + return UpdateTransitionCodeOffset(transitions); } private uint GetNumCouldBeLiveSlots(byte[] image, ref int bitOffset) @@ -507,8 +524,9 @@ namespace R2RDump return slotId; } - private void UpdateTransitionCodeOffset(List<GcTransition> transitions) + private Dictionary<int, GcTransition> UpdateTransitionCodeOffset(List<GcTransition> transitions) { + Dictionary<int, GcTransition> updatedTransitions = new Dictionary<int, GcTransition>(); int cumInterruptibleLength = 0; using (IEnumerator<InterruptibleRange> interruptibleRangesIter = InterruptibleRanges.GetEnumerator()) { @@ -527,8 +545,10 @@ namespace R2RDump codeOffset = transition.CodeOffset + (int)currentRange.StartOffset - cumInterruptibleLength; } transition.CodeOffset = codeOffset; + updatedTransitions[codeOffset] = transition; } } + return updatedTransitions; } } } diff --git a/src/tools/r2rdump/R2RDump.cs b/src/tools/r2rdump/R2RDump.cs index be5c893196..2e2c27cdf2 100644 --- a/src/tools/r2rdump/R2RDump.cs +++ b/src/tools/r2rdump/R2RDump.cs @@ -178,15 +178,12 @@ namespace R2RDump /// </summary> private void DumpRuntimeFunction(R2RReader r2r, RuntimeFunction rtf) { + _writer.Write($"{rtf}"); if (_disasm) { - _writer.WriteLine($"Id: {rtf.Id}"); - _writer.Write(CoreDisTools.GetCodeBlock(_disassembler, rtf.StartAddress, r2r.GetOffset(rtf.StartAddress), r2r.Image, rtf.Size)); - } - else - { - _writer.Write($"{rtf}"); + _writer.Write(CoreDisTools.GetCodeBlock(_disassembler, rtf, r2r.GetOffset(rtf.StartAddress), r2r.Image)); } + if (_raw) { _writer.WriteLine("Raw Bytes:"); diff --git a/src/tools/r2rdump/R2RMethod.cs b/src/tools/r2rdump/R2RMethod.cs index 356d1eb98d..78e90af9c3 100644 --- a/src/tools/r2rdump/R2RMethod.cs +++ b/src/tools/r2rdump/R2RMethod.cs @@ -38,6 +38,8 @@ namespace R2RDump /// </summary> public int UnwindRVA { get; } + public int CodeOffset { get; set; } + /// <summary> /// The method that this runtime function belongs to /// </summary> @@ -45,7 +47,7 @@ namespace R2RDump public UnwindInfo UnwindInfo { get; } - public RuntimeFunction(int id, int startRva, int endRva, int unwindRva, R2RMethod method, UnwindInfo unwindInfo, GcInfo gcInfo) + public RuntimeFunction(int id, int startRva, int endRva, int unwindRva, int codeOffset, R2RMethod method, UnwindInfo unwindInfo, GcInfo gcInfo) { Id = id; StartAddress = startRva; @@ -60,6 +62,7 @@ namespace R2RDump { Size = gcInfo.CodeLength; } + CodeOffset = codeOffset; method.GcInfo = gcInfo; } diff --git a/src/tools/r2rdump/R2RReader.cs b/src/tools/r2rdump/R2RReader.cs index 566928c5de..f0f43fcca7 100644 --- a/src/tools/r2rdump/R2RReader.cs +++ b/src/tools/r2rdump/R2RReader.cs @@ -208,6 +208,7 @@ namespace R2RDump continue; curOffset = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize; GcInfo gcInfo = null; + int codeOffset = 0; do { int startRva = NativeReader.ReadInt32(Image, ref curOffset); @@ -225,8 +226,10 @@ namespace R2RDump gcInfo = new GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion); } - method.RuntimeFunctions.Add(new RuntimeFunction(runtimeFunctionId, startRva, endRva, unwindRva, method, unwindInfo, gcInfo)); + RuntimeFunction rtf = new RuntimeFunction(runtimeFunctionId, startRva, endRva, unwindRva, codeOffset, method, unwindInfo, gcInfo); + method.RuntimeFunctions.Add(rtf); runtimeFunctionId++; + codeOffset += rtf.Size; } while (runtimeFunctionId < isEntryPoint.Length && !isEntryPoint[runtimeFunctionId]); } |