public unsafe static string GetCodeBlock(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] 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) { 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; } 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}"); }
internal unsafe override void DumpDisasm(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image, XmlNode parentNode = null) { 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) { string instr; int instrSize = CoreDisTools.GetInstruction(Disasm, rtf, imageOffset, rtfOffset, image, out instr); _writer.Write(instr); if (transitions.ContainsKey(codeOffset)) { _writer.WriteLine($"\t\t\t\t{transitions[codeOffset].GetSlotState(slotTable)}"); } CoreDisTools.ClearOutputBuffer(); rtfOffset += instrSize; codeOffset += instrSize; } }
public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion) { Offset = offset; _gcInfoTypes = new GcInfoTypes(machine); SecurityObjectStackSlot = -1; GSCookieStackSlot = -1; PSPSymStackSlot = -1; SecurityObjectStackSlot = -1; GenericsInstContextStackSlot = -1; StackBaseRegister = 0xffffffff; SizeOfEditAndContinuePreservedArea = 0xffffffff; ReversePInvokeFrameStackSlot = -1; Version = ReadyToRunVersionToGcInfoVersion(majorVersion); int bitOffset = offset * 8; int startBitOffset = bitOffset; ParseHeaderFlags(image, ref bitOffset); if (Version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND) // IsReturnKindAvailable { int returnKindBits = (_slimHeader) ? _gcInfoTypes.SIZE_OF_RETURN_KIND_SLIM : _gcInfoTypes.SIZE_OF_RETURN_KIND_FAT; ReturnKind = (ReturnKinds)NativeReader.ReadBits(image, returnKindBits, ref bitOffset); } CodeLength = _gcInfoTypes.DenormalizeCodeLength((int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.CODE_LENGTH_ENCBASE, ref bitOffset)); if (_hasGSCookie) { uint normPrologSize = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; uint normEpilogSize = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset); ValidRangeStart = normPrologSize; ValidRangeEnd = (uint)CodeLength - normEpilogSize; } else if (_hasSecurityObject || _hasGenericsInstContext) { ValidRangeStart = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; ValidRangeEnd = ValidRangeStart + 1; } if (_hasSecurityObject) { SecurityObjectStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.SECURITY_OBJECT_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasGSCookie) { GSCookieStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.GS_COOKIE_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasPSPSym) { PSPSymStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.PSP_SYM_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasGenericsInstContext) { GenericsInstContextStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasStackBaseRegister && !_slimHeader) { StackBaseRegister = _gcInfoTypes.DenormalizeStackBaseRegister(NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.STACK_BASE_REGISTER_ENCBASE, ref bitOffset)); } if (_hasSizeOfEditAndContinuePreservedArea) { SizeOfEditAndContinuePreservedArea = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE, ref bitOffset); } if (_hasReversePInvokeFrame) { ReversePInvokeFrameStackSlot = NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.REVERSE_PINVOKE_FRAME_ENCBASE, ref bitOffset); } // FIXED_STACK_PARAMETER_SCRATCH_AREA (this macro is always defined in _gcInfoTypes.h) if (!_slimHeader) { SizeOfStackOutgoingAndScratchArea = _gcInfoTypes.DenormalizeSizeOfStackArea(NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.SIZE_OF_STACK_AREA_ENCBASE, ref bitOffset)); } // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED (this macro is always defined in _gcInfoTypes.h) NumSafePoints = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NUM_SAFE_POINTS_ENCBASE, ref bitOffset); if (!_slimHeader) { NumInterruptibleRanges = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NUM_INTERRUPTIBLE_RANGES_ENCBASE, ref bitOffset); } // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED (this macro is always defined in _gcInfoTypes.h) SafePointOffsets = EnumerateSafePoints(image, ref bitOffset); uint numBitsPerOffset = GcInfoTypes.CeilOfLog2(CodeLength); bitOffset += (int)(NumSafePoints * numBitsPerOffset); InterruptibleRanges = EnumerateInterruptibleRanges(image, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA1_ENCBASE, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA2_ENCBASE, ref bitOffset); SlotTable = new GcSlotTable(image, machine, _gcInfoTypes, ref bitOffset); Transitions = GetTranstions(image, ref bitOffset); Size = bitOffset - startBitOffset; _machine = machine; }