Example #1
0
        public string GetSlotState(GcSlotTable slotTable, Machine machine)
        {
            GcSlotTable.GcSlot slot    = slotTable.GcSlots[SlotId];
            string             slotStr = "";

            if (slot.StackSlot == null)
            {
                Type regType = typeof(Amd64.Registers);
                if (machine == Machine.ArmThumb2)
                {
                    regType = typeof(Arm.Registers);
                }
                else
                {
                    regType = typeof(Arm64.Registers);
                }
                slotStr = Enum.GetName(regType, slot.RegisterNumber);
            }
            else
            {
                slotStr = $"sp{slot.StackSlot.SpOffset:+#;-#;+0}";
            }
            string isLiveStr = "live";

            if (!IsLive)
            {
                isLiveStr = "dead";
            }
            return($"{slotStr} is {isLiveStr}");
        }
Example #2
0
 public GcTransition(int codeOffset, int slotId, bool isLive, int chunkId, GcSlotTable slotTable, Machine machine)
 {
     CodeOffset = codeOffset;
     SlotId     = slotId;
     IsLive     = isLive;
     ChunkId    = chunkId;
     SlotState  = GetSlotState(slotTable, machine);
 }
Example #3
0
        public string GetSlotState(GcSlotTable slotTable)
        {
            GcSlotTable.GcSlot slot    = slotTable.GcSlots[SlotId];
            string             slotStr = "";

            if (slot.StackSlot == null)
            {
                slotStr = Enum.GetName(typeof(Registers), slot.RegisterNumber);
            }
            else
            {
                slotStr = $"sp{slot.StackSlot.SpOffset:+#;-#;+0}";
            }
            string isLiveStr = "live";

            if (!IsLive)
            {
                isLiveStr = "dead";
            }
            return($"{slotStr} is {isLiveStr}");
        }
Example #4
0
        public string GetSlotState(GcSlotTable slotTable, Machine machine)
        {
            GcSlotTable.GcSlot slot    = slotTable.GcSlots[SlotId];
            string             slotStr = "";

            if (slot.StackSlot == null)
            {
                Type regType;
                switch (machine)
                {
                case Machine.ArmThumb2:
                    regType = typeof(Arm.Registers);
                    break;

                case Machine.Arm64:
                    regType = typeof(Arm64.Registers);
                    break;

                case Machine.Amd64:
                    regType = typeof(Amd64.Registers);
                    break;

                default:
                    throw new NotImplementedException();
                }
                slotStr = Enum.GetName(regType, slot.RegisterNumber);
            }
            else
            {
                slotStr = $"sp{slot.StackSlot.SpOffset:+#;-#;+0}";
            }
            string isLiveStr = "live";

            if (!IsLive)
            {
                isLiveStr = "dead";
            }
            return($"{slotStr} is {isLiveStr}");
        }
Example #5
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/vm/gcinfodecoder.cpp">GcInfoDecoder::GcInfoDecoder</a>
        /// </summary>
        public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion)
        {
            Offset       = offset;
            _gcInfoTypes = new GcInfoTypes(machine);
            _machine     = 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;
        }