Esempio n. 1
0
        /// <summary>
        /// Dumps disassembly and register liveness
        /// </summary>
        internal override void DumpDisasm(RuntimeFunction rtf, int imageOffset)
        {
            string indentString = new string(' ', _disassembler.MnemonicIndentation);
            int    codeOffset   = rtf.CodeOffset;
            int    rtfOffset    = 0;

            while (rtfOffset < rtf.Size)
            {
                string instr;
                int    instrSize = _disassembler.GetInstruction(rtf, imageOffset, rtfOffset, out instr);

                if (_r2r.Machine == Machine.Amd64 && ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).CodeOffsetToUnwindCodeIndex.TryGetValue(codeOffset, out int unwindCodeIndex))
                {
                    ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode code = ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes[unwindCodeIndex];
                    _writer.Write($"{indentString}{code.UnwindOp} {code.OpInfoStr}");
                    if (code.NextFrameOffset != -1)
                    {
                        _writer.WriteLine($"{indentString}{code.NextFrameOffset}");
                    }
                    _writer.WriteLine();
                }

                BaseGcInfo gcInfo = (_options.HideTransitions ? null : rtf.Method?.GcInfo);
                if (gcInfo != null && gcInfo.Transitions.TryGetValue(codeOffset, out List <BaseGcTransition> transitionsForOffset))
                {
                    string[] formattedTransitions = new string[transitionsForOffset.Count];
                    for (int transitionIndex = 0; transitionIndex < formattedTransitions.Length; transitionIndex++)
                    {
                        formattedTransitions[transitionIndex] = transitionsForOffset[transitionIndex].ToString();
                    }
                    if (_options.Normalize)
                    {
                        Array.Sort(formattedTransitions);
                    }
                    foreach (string transition in formattedTransitions)
                    {
                        _writer.WriteLine($"{indentString}{transition}");
                    }
                }

                /* According to https://msdn.microsoft.com/en-us/library/ck9asaa9.aspx and src/vm/gcinfodecoder.cpp
                 * UnwindCode and GcTransition CodeOffsets are encoded with a -1 adjustment (that is, it's the offset of the start of the next instruction)
                 */
                _writer.Write(instr);

                rtfOffset  += instrSize;
                codeOffset += instrSize;
            }
        }
Esempio n. 2
0
        public static void WriteTo(this RuntimeFunction theThis, TextWriter writer, DumpOptions options)
        {
            if (!options.Naked)
            {
                writer.WriteLine($"Id: {theThis.Id}");
                writer.WriteLine($"StartAddress: 0x{theThis.StartAddress:X8}");
            }
            if (theThis.Size == -1)
            {
                writer.WriteLine("Size: Unavailable");
            }
            else
            {
                writer.WriteLine($"Size: {theThis.Size} bytes");
            }
            if (!options.Naked)
            {
                writer.WriteLine($"UnwindRVA: 0x{theThis.UnwindRVA:X8}");
            }
            if (theThis.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";
                }
                writer.WriteLine($"Version:            {amd64UnwindInfo.Version}");
                writer.WriteLine($"Flags:              0x{amd64UnwindInfo.Flags:X2}{parsedFlags}");
                writer.WriteLine($"SizeOfProlog:       0x{amd64UnwindInfo.SizeOfProlog:X4}");
                writer.WriteLine($"CountOfUnwindCodes: {amd64UnwindInfo.CountOfUnwindCodes}");
                writer.WriteLine($"FrameRegister:      {((amd64UnwindInfo.FrameRegister == 0) ? "None" : amd64UnwindInfo.FrameRegister.ToString())}");
                writer.WriteLine($"FrameOffset:        0x{amd64UnwindInfo.FrameOffset}");
                if (!options.Naked)
                {
                    writer.WriteLine($"PersonalityRVA:     0x{amd64UnwindInfo.PersonalityRoutineRVA:X4}");
                }

                for (int unwindCodeIndex = 0; unwindCodeIndex < amd64UnwindInfo.CountOfUnwindCodes; unwindCodeIndex++)
                {
                    ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode unwindCode = amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex];
                    writer.Write($"UnwindCode[{unwindCode.Index}]: ");
                    writer.Write($"CodeOffset 0x{unwindCode.CodeOffset:X4} ");
                    writer.Write($"FrameOffset 0x{unwindCode.FrameOffset:X4} ");
                    writer.Write($"NextOffset 0x{unwindCode.NextFrameOffset} ");
                    writer.Write($"Op {unwindCode.OpInfoStr}");
                    writer.WriteLine();
                }
            }
            writer.WriteLine();

            if (theThis.EHInfo != null)
            {
                writer.WriteLine($@"EH info @ {theThis.EHInfo.RelativeVirtualAddress:X4}, #clauses = {theThis.EHInfo.EHClauses.Count}");
                theThis.EHInfo.WriteTo(writer);
                writer.WriteLine();
            }

            if (theThis.DebugInfo != null)
            {
                theThis.DebugInfo.WriteTo(writer, options);
            }
        }
Esempio n. 3
0
        public static void WriteTo(this RuntimeFunction theThis, TextWriter writer, DumpOptions options)
        {
            if (!options.Naked)
            {
                writer.WriteLine($"Id: {theThis.Id}");
                writer.WriteLine($"StartAddress: 0x{theThis.StartAddress:X8}");
            }
            if (theThis.Size == -1)
            {
                writer.WriteLine("Size: Unavailable");
            }
            else
            {
                writer.WriteLine($"Size: {theThis.Size} bytes");
            }
            if (!options.Naked)
            {
                writer.WriteLine($"UnwindRVA: 0x{theThis.UnwindRVA:X8}");
            }
            if (theThis.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";
                }
                writer.WriteLine($"Version:            {amd64UnwindInfo.Version}");
                writer.WriteLine($"Flags:              0x{amd64UnwindInfo.Flags:X2}{parsedFlags}");
                writer.WriteLine($"SizeOfProlog:       0x{amd64UnwindInfo.SizeOfProlog:X4}");
                writer.WriteLine($"CountOfUnwindCodes: {amd64UnwindInfo.CountOfUnwindCodes}");
                writer.WriteLine($"FrameRegister:      {amd64UnwindInfo.FrameRegister}");
                writer.WriteLine($"FrameOffset:        0x{amd64UnwindInfo.FrameOffset}");
                if (!options.Naked)
                {
                    writer.WriteLine($"PersonalityRVA:     0x{amd64UnwindInfo.PersonalityRoutineRVA:X4}");
                }

                for (int unwindCodeIndex = 0; unwindCodeIndex < amd64UnwindInfo.CountOfUnwindCodes; unwindCodeIndex++)
                {
                    ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode unwindCode = amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex];
                    writer.Write($"UnwindCode[{unwindCode.Index}]: ");
                    writer.Write($"CodeOffset 0x{unwindCode.CodeOffset:X4} ");
                    writer.Write($"FrameOffset 0x{unwindCode.FrameOffset:X4} ");
                    writer.Write($"NextOffset 0x{unwindCode.NextFrameOffset} ");
                    writer.Write($"Op {unwindCode.OpInfoStr}");
                    writer.WriteLine();
                }
            }
            writer.WriteLine();

            if (theThis.Method.GcInfo is ILCompiler.Reflection.ReadyToRun.Amd64.GcInfo gcInfo)
            {
                writer.WriteLine("GC info:");
                writer.WriteLine($@"    Version:                           {gcInfo.Version}");
                writer.WriteLine($@"    ReturnKind:                        {gcInfo.ReturnKind}");
                writer.WriteLine($@"    ValidRangeStart:                   0x{gcInfo.ValidRangeStart:X4}");
                writer.WriteLine($@"    ValidRangeEnd:                     0x{gcInfo.ValidRangeEnd:X4}");
                writer.WriteLine($@"    SecurityObjectStackSlot:           0x{gcInfo.SecurityObjectStackSlot:X4}");
                writer.WriteLine($@"    GSCookieStackSlot:                 0x{gcInfo.GSCookieStackSlot:X4}");
                writer.WriteLine($@"    PSPSymStackSlot:                   0x{gcInfo.PSPSymStackSlot:X4}");
                writer.WriteLine($@"    GenericsInstContextStackSlot:      0x{gcInfo.GenericsInstContextStackSlot:X4}");
                writer.WriteLine($@"    StackBaseRegister:                 {gcInfo.StackBaseRegister}");
                writer.WriteLine($@"    SizeOfENCPreservedArea:            0x{gcInfo.SizeOfEditAndContinuePreservedArea:X4}");
                writer.WriteLine($@"    ReversePInvokeFrameStackSlot:      0x{gcInfo.ReversePInvokeFrameStackSlot:X4}");
                writer.WriteLine($@"    SizeOfStackOutgoingAndScratchArea: 0x{gcInfo.SizeOfStackOutgoingAndScratchArea:X4}");
                writer.WriteLine($@"    NumSafePoints:                     {gcInfo.NumSafePoints}");
                writer.WriteLine($@"    NumInterruptibleRanges:            {gcInfo.NumInterruptibleRanges}");

                writer.WriteLine($@"    SafePointOffsets: {gcInfo.SafePointOffsets.Count}");
                foreach (ILCompiler.Reflection.ReadyToRun.Amd64.GcInfo.SafePointOffset safePoint in gcInfo.SafePointOffsets)
                {
                    writer.WriteLine($@"        Index: {safePoint.Index,2}; Value: 0x{safePoint.Value:X4}");
                    if (gcInfo.LiveSlotsAtSafepoints != null)
                    {
                        writer.WriteLine($@"        Live slots: {String.Join(", ", gcInfo.LiveSlotsAtSafepoints[safePoint.Index])}");
                    }
                }

                writer.WriteLine($@"    InterruptibleRanges: {gcInfo.InterruptibleRanges.Count}");
                foreach (ILCompiler.Reflection.ReadyToRun.Amd64.InterruptibleRange range in gcInfo.InterruptibleRanges)
                {
                    writer.WriteLine($@"        Index: {range.Index,2}; StartOffset: 0x{range.StartOffset:X4}; StopOffset: 0x{range.StopOffset:X4}");
                }

                writer.WriteLine("    SlotTable:");
                writer.WriteLine($@"        NumRegisters:  {gcInfo.SlotTable.NumRegisters}");
                writer.WriteLine($@"        NumStackSlots: {gcInfo.SlotTable.NumStackSlots}");
                writer.WriteLine($@"        NumUntracked:  {gcInfo.SlotTable.NumUntracked}");
                writer.WriteLine($@"        NumSlots:      {gcInfo.SlotTable.NumSlots}");
                writer.WriteLine($@"        GcSlots:       {gcInfo.SlotTable.GcSlots.Count}");
                foreach (ILCompiler.Reflection.ReadyToRun.Amd64.GcSlotTable.GcSlot slot in gcInfo.SlotTable.GcSlots)
                {
                    writer.WriteLine($@"            Index: {slot.Index,2}; RegisterNumber: {slot.RegisterNumber,2}; Flags: {slot.Flags}");
                }
                writer.WriteLine();
            }

            if (theThis.EHInfo != null)
            {
                writer.WriteLine($@"EH info @ {theThis.EHInfo.EHInfoRVA:X4}, #clauses = {theThis.EHInfo.EHClauses.Length}");
                theThis.EHInfo.WriteTo(writer);
                writer.WriteLine();
            }

            if (theThis.DebugInfo != null)
            {
                theThis.DebugInfo.WriteTo(writer, options);
            }
        }