private void DecodeStackSlots(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, uint nSlots, bool isUntracked, ref int bitOffset) { // We have stack slots left and more room to predecode GcStackSlotBase spBase = (GcStackSlotBase)NativeReader.ReadBits(image, 2, ref bitOffset); int normSpOffset = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); int spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); GcSlotFlags flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); GcSlots.Add(new GcSlot(GcSlots.Count, -1, new GcStackSlot(spOffset, spBase), flags, isUntracked)); for (int i = 1; i < nSlots; i++) { spBase = (GcStackSlotBase)NativeReader.ReadBits(image, 2, ref bitOffset); if ((uint)flags != 0) { normSpOffset = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); } else { int normSpOffsetDelta = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_DELTA_ENCBASE, ref bitOffset); normSpOffset += normSpOffsetDelta; spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); } GcSlots.Add(new GcSlot(GcSlots.Count, -1, new GcStackSlot(spOffset, spBase), flags, isUntracked)); } }
public GcSlot(int index, string reg, int beginOffs, int endOffs, int varOffs, int lowBits, GcSlotFlags flags) { Index = index; Register = $"E{reg}P"; StackOffset = varOffs; LowBits = lowBits; Flags = flags; BeginOffset = beginOffs; EndOffset = endOffs; }
public GcSlot(int index, string reg, int stkOffs, int lowBits, GcSlotFlags flags) { Index = index; Register = reg; StackOffset = stkOffs; LowBits = lowBits; Flags = flags; BeginOffset = -1; EndOffset = -1; }
public GcSlot(int index, int registerNumber, GcStackSlot stack, GcSlotFlags flags, bool isUntracked = false) { Index = index; RegisterNumber = registerNumber; StackSlot = stack; Flags = flags; if (isUntracked) { Flags |= GcSlotFlags.GC_SLOT_UNTRACKED; } }
public GcSlot(int registerNumber, GcStackSlot stack, GcSlotFlags flags, bool isUntracked = false) { RegisterNumber = registerNumber; StackSlot = stack; if (isUntracked) { Flags = GcSlotFlags.GC_SLOT_UNTRACKED; } else { Flags = flags; } }
public override GcSlotFlags WriteTo(StringBuilder sb, Machine machine, GcSlotFlags prevFlags) { if (prevFlags != Flags) { sb.Append(Flags.ToString()); sb.Append(' '); } if (StackSlot != null) { sb.Append(StackSlot.ToString()); } else { sb.Append(GetRegisterName(RegisterNumber, machine)); } return(Flags); }
private void DecodeRegisters(byte[] image, GcInfoTypes gcInfoTypes, ref int bitOffset) { // We certainly predecode the first register uint regNum = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_ENCBASE, ref bitOffset); GcSlotFlags flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); GcSlots.Add(new GcSlot(GcSlots.Count, (int)regNum, null, flags)); for (int i = 1; i < NumRegisters; i++) { if ((uint)flags != 0) { regNum = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_ENCBASE, ref bitOffset); flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); } else { uint regDelta = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_DELTA_ENCBASE, ref bitOffset) + 1; regNum += regDelta; } GcSlots.Add(new GcSlot(GcSlots.Count, (int)regNum, null, flags)); } }
public override string ToString() { StringBuilder sb = new StringBuilder(); sb.AppendLine($" Version: {Version}"); sb.AppendLine($" CodeLength: {CodeLength}"); sb.AppendLine($" ReturnKind: {Enum.GetName(typeof(ReturnKinds), ReturnKind)}"); sb.AppendLine($" ValidRangeStart: {ValidRangeStart}"); sb.AppendLine($" ValidRangeEnd: {ValidRangeEnd}"); if (SecurityObjectStackSlot != -1) { sb.AppendLine($" SecurityObjectStackSlot: caller.sp{SecurityObjectStackSlot:+#;-#;+0}"); } if (GSCookieStackSlot != -1) { sb.AppendLine($" GSCookieStackSlot: caller.sp{GSCookieStackSlot:+#;-#;+0}"); sb.AppendLine($" GS cookie valid range: [{ValidRangeStart};{ValidRangeEnd})"); } if (PSPSymStackSlot != -1) { if (_machine == Machine.Amd64) { sb.AppendLine($" PSPSymStackSlot: initial.sp{PSPSymStackSlot:+#;-#;+0}"); } else { sb.AppendLine($" PSPSymStackSlot: caller.sp{PSPSymStackSlot:+#;-#;+0}"); } } if (GenericsInstContextStackSlot != -1) { sb.AppendLine($" GenericsInstContextStackSlot: caller.sp{GenericsInstContextStackSlot:+#;-#;+0}"); } if (_machine == Machine.Amd64) { if (StackBaseRegister != 0xffffffff) { sb.AppendLine($" StackBaseRegister: {(Amd64.Registers)StackBaseRegister}"); } sb.AppendLine($" Wants Report Only Leaf: {_wantsReportOnlyLeaf}"); } else if (_machine == Machine.ArmThumb2 || _machine == Machine.Arm64) { if (StackBaseRegister != 0xffffffff) { if (_machine == Machine.ArmThumb2) { sb.AppendLine($" StackBaseRegister: {(Arm.Registers)StackBaseRegister}"); } else { sb.AppendLine($" StackBaseRegister: {(Arm64.Registers)StackBaseRegister}"); } } sb.AppendLine($" Has Tailcalls: {_wantsReportOnlyLeaf}"); } sb.AppendLine($" Size of parameter area: 0x{SizeOfStackOutgoingAndScratchArea:X}"); if (SizeOfEditAndContinuePreservedArea != 0xffffffff) { sb.AppendLine($" SizeOfEditAndContinuePreservedArea: 0x{SizeOfEditAndContinuePreservedArea:X}"); } if (ReversePInvokeFrameStackSlot != -1) { sb.AppendLine($" ReversePInvokeFrameStackSlot: {ReversePInvokeFrameStackSlot}"); } sb.AppendLine($" NumSafePoints: {NumSafePoints}"); sb.AppendLine($" NumInterruptibleRanges: {NumInterruptibleRanges}"); sb.AppendLine($" SafePointOffsets:"); foreach (SafePointOffset offset in SafePointOffsets) { IEnumerable <BaseGcSlot> liveSlotsForOffset = (LiveSlotsAtSafepoints != null ? LiveSlotsAtSafepoints[offset.Index] : Enumerable.Empty <BaseGcSlot>()); sb.Append($" 0x{offset.Value:X4}: "); bool haveLiveSlots = false; GcSlotFlags slotFlags = GcSlotFlags.GC_SLOT_INVALID; foreach (BaseGcSlot slot in liveSlotsForOffset) { if (haveLiveSlots) { sb.Append("; "); } else { haveLiveSlots = true; } slotFlags = slot.WriteTo(sb, _machine, slotFlags); } if (!haveLiveSlots) { sb.Append("no live slots"); } sb.AppendLine(); } sb.AppendLine($" InterruptibleRanges:"); foreach (InterruptibleRange range in InterruptibleRanges) { sb.AppendLine($" start:{range.StartOffset}, end:{range.StopOffset}"); } sb.AppendLine($" SlotTable:"); sb.Append(SlotTable.ToString()); sb.AppendLine($" Size: {Size} bytes"); return(sb.ToString()); }
public abstract GcSlotFlags WriteTo(StringBuilder sb, Machine machine, GcSlotFlags prevFlags);
public GcSlot(int registerNumber, GcStackSlot stack, GcSlotFlags flags) { RegisterNumber = registerNumber; StackSlot = stack; Flags = flags; }