diff --git a/src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj b/src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj index 0480327017db55..7d202885cc77c5 100644 --- a/src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj +++ b/src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj @@ -12,11 +12,11 @@ - \lib\netstandard2.0\ + \lib\$(NetCoreAppMinimum)\ $(SystemReflectionMetadataVersion) - netstandard2.0 + $(NetCoreAppMinimum) Build,Analyzers diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs index 3170dadd9dcafd..e162ae0569e02f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs @@ -87,7 +87,7 @@ public GcInfo() { } /// /// based on GcInfoDecoder::GcInfoDecoder /// - public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion, ushort minorVersion) + public GcInfo(NativeReader imageReader, int offset, Machine machine, ushort majorVersion, ushort minorVersion) { Offset = offset; Version = ReadyToRunVersionToGcInfoVersion(majorVersion, minorVersion); @@ -106,98 +106,98 @@ public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion, us int bitOffset = offset * 8; - ParseHeaderFlags(image, ref bitOffset); + ParseHeaderFlags(imageReader, ref bitOffset); if (Version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND && Version <= MAX_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); + ReturnKind = (ReturnKinds)imageReader.ReadBits(returnKindBits, ref bitOffset); } - CodeLength = _gcInfoTypes.DenormalizeCodeLength((int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.CODE_LENGTH_ENCBASE, ref bitOffset)); + CodeLength = _gcInfoTypes.DenormalizeCodeLength((int)imageReader.DecodeVarLengthUnsigned(_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_EPILOG_SIZE_ENCBASE, ref bitOffset); + uint normPrologSize = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; + uint normEpilogSize = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NORM_EPILOG_SIZE_ENCBASE, ref bitOffset); ValidRangeStart = _gcInfoTypes.DenormalizeCodeOffset(normPrologSize); ValidRangeEnd = (uint)CodeLength - _gcInfoTypes.DenormalizeCodeOffset(normEpilogSize); } else if (_hasSecurityObject || _hasGenericsInstContext) { - uint normValidRangeStart = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; + uint normValidRangeStart = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1; ValidRangeStart = _gcInfoTypes.DenormalizeCodeOffset(normValidRangeStart); ValidRangeEnd = ValidRangeStart + 1; } if (_hasSecurityObject) { - SecurityObjectStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.SECURITY_OBJECT_STACK_SLOT_ENCBASE, ref bitOffset)); + SecurityObjectStackSlot = _gcInfoTypes.DenormalizeStackSlot(imageReader.DecodeVarLengthSigned(_gcInfoTypes.SECURITY_OBJECT_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasGSCookie) { - GSCookieStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.GS_COOKIE_STACK_SLOT_ENCBASE, ref bitOffset)); + GSCookieStackSlot = _gcInfoTypes.DenormalizeStackSlot(imageReader.DecodeVarLengthSigned(_gcInfoTypes.GS_COOKIE_STACK_SLOT_ENCBASE, ref bitOffset)); } if (_hasPSPSym) { - PSPSymStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.PSP_SYM_STACK_SLOT_ENCBASE, ref bitOffset)); + PSPSymStackSlot = _gcInfoTypes.DenormalizeStackSlot(imageReader.DecodeVarLengthSigned(_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)); + GenericsInstContextStackSlot = _gcInfoTypes.DenormalizeStackSlot(imageReader.DecodeVarLengthSigned(_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)); + StackBaseRegister = _gcInfoTypes.DenormalizeStackBaseRegister(imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.STACK_BASE_REGISTER_ENCBASE, ref bitOffset)); } if (_hasSizeOfEditAndContinuePreservedArea) { - SizeOfEditAndContinuePreservedArea = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE, ref bitOffset); + SizeOfEditAndContinuePreservedArea = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE, ref bitOffset); } if (_hasReversePInvokeFrame) { - ReversePInvokeFrameStackSlot = NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.REVERSE_PINVOKE_FRAME_ENCBASE, ref bitOffset); + ReversePInvokeFrameStackSlot = imageReader.DecodeVarLengthSigned(_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)); + SizeOfStackOutgoingAndScratchArea = _gcInfoTypes.DenormalizeSizeOfStackArea(imageReader.DecodeVarLengthUnsigned(_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); + NumSafePoints = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NUM_SAFE_POINTS_ENCBASE, ref bitOffset); if (!_slimHeader) { - NumInterruptibleRanges = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NUM_INTERRUPTIBLE_RANGES_ENCBASE, ref bitOffset); + NumInterruptibleRanges = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.NUM_INTERRUPTIBLE_RANGES_ENCBASE, ref bitOffset); } // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED (this macro is always defined in _gcInfoTypes.h) - SafePointOffsets = EnumerateSafePoints(image, ref bitOffset); + SafePointOffsets = EnumerateSafePoints(imageReader, ref bitOffset); - InterruptibleRanges = EnumerateInterruptibleRanges(image, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA1_ENCBASE, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA2_ENCBASE, ref bitOffset); + InterruptibleRanges = EnumerateInterruptibleRanges(imageReader, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA1_ENCBASE, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA2_ENCBASE, ref bitOffset); - SlotTable = new GcSlotTable(image, machine, _gcInfoTypes, ref bitOffset); + SlotTable = new GcSlotTable(imageReader, machine, _gcInfoTypes, ref bitOffset); if (SlotTable.NumSlots > 0) { if (NumSafePoints > 0) { // Partially interruptible code - LiveSlotsAtSafepoints = GetLiveSlotsAtSafepoints(image, ref bitOffset); + LiveSlotsAtSafepoints = GetLiveSlotsAtSafepoints(imageReader, ref bitOffset); } else { // Fully interruptible code - Transitions = GetTransitions(image, ref bitOffset); + Transitions = GetTransitions(imageReader, ref bitOffset); } } @@ -326,18 +326,18 @@ public override string ToString() /// /// based on GcInfoDecoder::GcInfoDecoder /// - private void ParseHeaderFlags(byte[] image, ref int bitOffset) + private void ParseHeaderFlags(NativeReader imageReader, ref int bitOffset) { GcInfoHeaderFlags headerFlags; - _slimHeader = (NativeReader.ReadBits(image, 1, ref bitOffset) == 0); + _slimHeader = (imageReader.ReadBits(1, ref bitOffset) == 0); if (_slimHeader) { - headerFlags = NativeReader.ReadBits(image, 1, ref bitOffset) == 1 ? GcInfoHeaderFlags.GC_INFO_HAS_STACK_BASE_REGISTER : 0; + headerFlags = imageReader.ReadBits(1, ref bitOffset) == 1 ? GcInfoHeaderFlags.GC_INFO_HAS_STACK_BASE_REGISTER : 0; } else { int numFlagBits = (int)((Version == 1) ? GcInfoHeaderFlags.GC_INFO_FLAGS_BIT_SIZE_VERSION_1 : GcInfoHeaderFlags.GC_INFO_FLAGS_BIT_SIZE); - headerFlags = (GcInfoHeaderFlags)NativeReader.ReadBits(image, numFlagBits, ref bitOffset); + headerFlags = (GcInfoHeaderFlags)imageReader.ReadBits(numFlagBits, ref bitOffset); } _hasSecurityObject = (headerFlags & GcInfoHeaderFlags.GC_INFO_HAS_SECURITY_OBJECT) != 0; @@ -353,13 +353,13 @@ private void ParseHeaderFlags(byte[] image, ref int bitOffset) _wantsReportOnlyLeaf = ((headerFlags & GcInfoHeaderFlags.GC_INFO_WANTS_REPORT_ONLY_LEAF) != 0); } - private List EnumerateSafePoints(byte[] image, ref int bitOffset) + private List EnumerateSafePoints(NativeReader imageReader, ref int bitOffset) { List safePoints = new List(); uint numBitsPerOffset = GcInfoTypes.CeilOfLog2((int)_gcInfoTypes.NormalizeCodeOffset((uint)CodeLength)); for (int i = 0; i < NumSafePoints; i++) { - uint normOffset = (uint)NativeReader.ReadBits(image, (int)numBitsPerOffset, ref bitOffset); + uint normOffset = (uint)imageReader.ReadBits((int)numBitsPerOffset, ref bitOffset); safePoints.Add(new SafePointOffset(i, _gcInfoTypes.DenormalizeCodeOffset(normOffset))); } return safePoints; @@ -368,15 +368,15 @@ private List EnumerateSafePoints(byte[] image, ref int bitOffse /// /// based on beginning of GcInfoDecoder::EnumerateLiveSlots /// - private List EnumerateInterruptibleRanges(byte[] image, int interruptibleRangeDelta1EncBase, int interruptibleRangeDelta2EncBase, ref int bitOffset) + private List EnumerateInterruptibleRanges(NativeReader imageReader, int interruptibleRangeDelta1EncBase, int interruptibleRangeDelta2EncBase, ref int bitOffset) { List ranges = new List(); uint normLastinterruptibleRangeStopOffset = 0; for (uint i = 0; i < NumInterruptibleRanges; i++) { - uint normStartDelta = NativeReader.DecodeVarLengthUnsigned(image, interruptibleRangeDelta1EncBase, ref bitOffset); - uint normStopDelta = NativeReader.DecodeVarLengthUnsigned(image, interruptibleRangeDelta2EncBase, ref bitOffset) + 1; + uint normStartDelta = imageReader.DecodeVarLengthUnsigned(interruptibleRangeDelta1EncBase, ref bitOffset); + uint normStopDelta = imageReader.DecodeVarLengthUnsigned(interruptibleRangeDelta2EncBase, ref bitOffset) + 1; uint normRangeStartOffset = normLastinterruptibleRangeStopOffset + normStartDelta; uint normRangeStopOffset = normRangeStartOffset + normStopDelta; @@ -411,7 +411,7 @@ private int ReadyToRunVersionToGcInfoVersion(int readyToRunMajorVersion, int rea return 4; } - private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bitOffset) + private List> GetLiveSlotsAtSafepoints(NativeReader imageReader, ref int bitOffset) { // For each safe point, enumerates a list of GC slots that are alive at that point var result = new List>(); @@ -423,9 +423,9 @@ private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bi uint numBitsPerOffset = 0; // Duplicate the encoder's heuristic to determine if we have indirect live // slot table (similar to the chunk pointers) - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { - numBitsPerOffset = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset) + 1; + numBitsPerOffset = imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset) + 1; Debug.Assert(numBitsPerOffset != 0); } @@ -441,20 +441,20 @@ private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bi { bitOffset += (int)(numBitsPerOffset * safePointIndex); - uint liveStatesOffset = (uint)NativeReader.ReadBits(image, (int)numBitsPerOffset, ref bitOffset); + uint liveStatesOffset = (uint)imageReader.ReadBits((int)numBitsPerOffset, ref bitOffset); uint liveStatesStart = (uint)((offsetTablePos + NumSafePoints * numBitsPerOffset + 7) & (~7)); bitOffset = (int)(liveStatesStart + liveStatesOffset); - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { // RLE encoded - bool skip = NativeReader.ReadBits(image, 1, ref bitOffset) == 0; + bool skip = imageReader.ReadBits(1, ref bitOffset) == 0; bool report = true; - uint readSlots = NativeReader.DecodeVarLengthUnsigned(image, + uint readSlots = imageReader.DecodeVarLengthUnsigned( skip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset); skip = !skip; while (readSlots < numSlots) { - uint cnt = NativeReader.DecodeVarLengthUnsigned(image, + uint cnt = imageReader.DecodeVarLengthUnsigned( skip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset) + 1; if (report) { @@ -492,7 +492,7 @@ private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bi for (uint slotIndex = 0; slotIndex < numSlots; slotIndex++) { - bool isLive = NativeReader.ReadBits(image, 1, ref bitOffset) != 0; + bool isLive = imageReader.ReadBits(1, ref bitOffset) != 0; if (isLive) { int trackedSlotIndex = 0; @@ -520,7 +520,7 @@ private List> GetLiveSlotsAtSafepoints(byte[] image, ref int bi /// /// based on end of GcInfoDecoder::EnumerateLiveSlots and GcInfoEncoder::Build /// - private Dictionary> GetTransitions(byte[] image, ref int bitOffset) + private Dictionary> GetTransitions(NativeReader imageReader, ref int bitOffset) { int totalInterruptibleLength = 0; if (NumInterruptibleRanges == 0) @@ -532,7 +532,7 @@ private Dictionary> GetTransitions(byte[] image, ref foreach (InterruptibleRange range in InterruptibleRanges) { uint normStart = _gcInfoTypes.NormalizeCodeOffset(range.StartOffset); - uint normStop = _gcInfoTypes.NormalizeCodeOffset(range.StopOffset); + uint normStop = _gcInfoTypes.NormalizeCodeOffset(range.StopOffset); totalInterruptibleLength += (int)(normStop - normStart); } } @@ -541,7 +541,7 @@ private Dictionary> GetTransitions(byte[] image, ref return new Dictionary>(); int numChunks = (totalInterruptibleLength + _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK - 1) / _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK; - int numBitsPerPointer = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset); + int numBitsPerPointer = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset); if (numBitsPerPointer == 0) { return new Dictionary>(); @@ -551,7 +551,7 @@ private Dictionary> GetTransitions(byte[] image, ref int[] chunkPointers = new int[numChunks]; for (int i = 0; i < numChunks; i++) { - chunkPointers[i] = NativeReader.ReadBits(image, numBitsPerPointer, ref bitOffset); + chunkPointers[i] = imageReader.ReadBits(numBitsPerPointer, ref bitOffset); } // Offset to m_Info2 containing all the info on register liveness, which starts at the next byte @@ -572,16 +572,16 @@ private Dictionary> GetTransitions(byte[] image, ref int couldBeLiveOffset = bitOffset; // points to the couldBeLive bit array (array of bits indicating the slot changed state in the chunk) int slotId = 0; - bool fSimple = (NativeReader.ReadBits(image, 1, ref couldBeLiveOffset) == 0); + bool fSimple = (imageReader.ReadBits(1, ref couldBeLiveOffset) == 0); bool fSkipFirst = false; int couldBeLiveCnt = 0; if (!fSimple) { - fSkipFirst = (NativeReader.ReadBits(image, 1, ref couldBeLiveOffset) == 0); + fSkipFirst = (imageReader.ReadBits(1, ref couldBeLiveOffset) == 0); slotId = -1; } - uint numCouldBeLiveSlots = GetNumCouldBeLiveSlots(image, ref bitOffset); // count the number of set bits in the couldBeLive array + uint numCouldBeLiveSlots = GetNumCouldBeLiveSlots(imageReader, ref bitOffset); // count the number of set bits in the couldBeLive array int finalStateOffset = bitOffset; // points to the finalState bit array (array of bits indicating if the slot is live at the end of the chunk) bitOffset += (int)numCouldBeLiveSlots; // points to the array of code offsets @@ -590,16 +590,16 @@ private Dictionary> GetTransitions(byte[] image, ref for (int i = 0; i < numCouldBeLiveSlots; i++) { // get the index of the next couldBeLive slot - slotId = GetNextSlotId(image, fSimple, fSkipFirst, slotId, ref couldBeLiveCnt, ref couldBeLiveOffset); + slotId = GetNextSlotId(imageReader, fSimple, fSkipFirst, slotId, ref couldBeLiveCnt, ref couldBeLiveOffset); // set the liveAtEnd for the slot at slotId bool isLive = !liveAtEnd[slotId]; - liveAtEnd[slotId] = (NativeReader.ReadBits(image, 1, ref finalStateOffset) != 0); + liveAtEnd[slotId] = (imageReader.ReadBits(1, ref finalStateOffset) != 0); // Read all the code offsets where the slot at slotId changed state - while (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + while (imageReader.ReadBits(1, ref bitOffset) != 0) { - int transitionOffset = NativeReader.ReadBits(image, _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK_LOG2, ref bitOffset) + normChunkBaseCodeOffset; + int transitionOffset = imageReader.ReadBits(_gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK_LOG2, ref bitOffset) + normChunkBaseCodeOffset; transitions.Add(new GcTransition(transitionOffset, slotId, isLive, currentChunk, SlotTable, _machine)); isLive = !isLive; } @@ -612,20 +612,20 @@ private Dictionary> GetTransitions(byte[] image, ref return UpdateTransitionCodeOffset(transitions); } - private uint GetNumCouldBeLiveSlots(byte[] image, ref int bitOffset) + private uint GetNumCouldBeLiveSlots(NativeReader imageReader, ref int bitOffset) { uint numCouldBeLiveSlots = 0; uint numTracked = SlotTable.NumTracked; - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { // RLE encoded - bool fSkip = (NativeReader.ReadBits(image, 1, ref bitOffset) == 0); + bool fSkip = (imageReader.ReadBits(1, ref bitOffset) == 0); bool fReport = true; - uint readSlots = NativeReader.DecodeVarLengthUnsigned(image, fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset); + uint readSlots = imageReader.DecodeVarLengthUnsigned(fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset); fSkip = !fSkip; while (readSlots < numTracked) { - uint cnt = NativeReader.DecodeVarLengthUnsigned(image, fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset) + 1; + uint cnt = imageReader.DecodeVarLengthUnsigned(fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset) + 1; if (fReport) { numCouldBeLiveSlots += cnt; @@ -644,7 +644,7 @@ private uint GetNumCouldBeLiveSlots(byte[] image, ref int bitOffset) if ((slot.Flags & GcSlotFlags.GC_SLOT_UNTRACKED) != 0) break; - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) numCouldBeLiveSlots++; } } @@ -652,12 +652,12 @@ private uint GetNumCouldBeLiveSlots(byte[] image, ref int bitOffset) return numCouldBeLiveSlots; } - private int GetNextSlotId(byte[] image, bool fSimple, bool fSkipFirst, int slotId, ref int couldBeLiveCnt, ref int couldBeLiveOffset) + private int GetNextSlotId(NativeReader imageReader, bool fSimple, bool fSkipFirst, int slotId, ref int couldBeLiveCnt, ref int couldBeLiveOffset) { if (fSimple) { // Get the slotId by iterating through the couldBeLive bit array. The slotId is the index of the next set bit - while (NativeReader.ReadBits(image, 1, ref couldBeLiveOffset) == 0) + while (imageReader.ReadBits(1, ref couldBeLiveOffset) == 0) slotId++; } else if (couldBeLiveCnt > 0) @@ -668,15 +668,15 @@ private int GetNextSlotId(byte[] image, bool fSimple, bool fSkipFirst, int slotI // We need to find a new run else if (fSkipFirst) { - int tmp = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE, ref couldBeLiveOffset) + 1; + int tmp = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE, ref couldBeLiveOffset) + 1; slotId += tmp; - couldBeLiveCnt = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref couldBeLiveOffset); + couldBeLiveCnt = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref couldBeLiveOffset); } else { - int tmp = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref couldBeLiveOffset) + 1; + int tmp = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref couldBeLiveOffset) + 1; slotId += tmp; - couldBeLiveCnt = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE, ref couldBeLiveOffset); + couldBeLiveCnt = (int)imageReader.DecodeVarLengthUnsigned(_gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE, ref couldBeLiveOffset); } return slotId; } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs index d5ac7048589c29..bd633fbbc9e406 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs @@ -104,33 +104,33 @@ public GcSlotTable() { } /// /// based on GcSlotDecoder::DecodeSlotTable /// - public GcSlotTable(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, ref int bitOffset) + public GcSlotTable(NativeReader imageReader, Machine machine, GcInfoTypes gcInfoTypes, ref int bitOffset) { _machine = machine; - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { - NumRegisters = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_REGISTERS_ENCBASE, ref bitOffset); + NumRegisters = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_REGISTERS_ENCBASE, ref bitOffset); } - if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0) + if (imageReader.ReadBits(1, ref bitOffset) != 0) { - NumStackSlots = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_STACK_SLOTS_ENCBASE, ref bitOffset); - NumUntracked = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_UNTRACKED_SLOTS_ENCBASE, ref bitOffset); + NumStackSlots = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_STACK_SLOTS_ENCBASE, ref bitOffset); + NumUntracked = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_UNTRACKED_SLOTS_ENCBASE, ref bitOffset); } NumSlots = NumRegisters + NumStackSlots + NumUntracked; GcSlots = new List(); if (NumRegisters > 0) { - DecodeRegisters(image, gcInfoTypes, ref bitOffset); + DecodeRegisters(imageReader, gcInfoTypes, ref bitOffset); } if (NumStackSlots > 0) { - DecodeStackSlots(image, machine, gcInfoTypes, NumStackSlots, false, ref bitOffset); + DecodeStackSlots(imageReader, machine, gcInfoTypes, NumStackSlots, false, ref bitOffset); } if (NumUntracked > 0) { - DecodeStackSlots(image, machine, gcInfoTypes, NumUntracked, true, ref bitOffset); + DecodeStackSlots(imageReader, machine, gcInfoTypes, NumUntracked, true, ref bitOffset); } } @@ -150,50 +150,50 @@ public override string ToString() return sb.ToString(); } - private void DecodeRegisters(byte[] image, GcInfoTypes gcInfoTypes, ref int bitOffset) + private void DecodeRegisters(NativeReader imageReader, 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); + uint regNum = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_ENCBASE, ref bitOffset); + GcSlotFlags flags = (GcSlotFlags)imageReader.ReadBits(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); + regNum = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_ENCBASE, ref bitOffset); + flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset); } else { - uint regDelta = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_DELTA_ENCBASE, ref bitOffset) + 1; + uint regDelta = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_DELTA_ENCBASE, ref bitOffset) + 1; regNum += regDelta; } GcSlots.Add(new GcSlot(GcSlots.Count, (int)regNum, null, flags)); } } - private void DecodeStackSlots(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, uint nSlots, bool isUntracked, ref int bitOffset) + private void DecodeStackSlots(NativeReader imageReader, 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); + GcStackSlotBase spBase = (GcStackSlotBase)imageReader.ReadBits(2, ref bitOffset); + int normSpOffset = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); int spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); - GcSlotFlags flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); + GcSlotFlags flags = (GcSlotFlags)imageReader.ReadBits(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); + spBase = (GcStackSlotBase)imageReader.ReadBits(2, ref bitOffset); if ((uint)flags != 0) { - normSpOffset = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); + normSpOffset = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset); spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); - flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset); + flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset); } else { - int normSpOffsetDelta = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_DELTA_ENCBASE, ref bitOffset); + int normSpOffsetDelta = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_DELTA_ENCBASE, ref bitOffset); normSpOffset += normSpOffsetDelta; spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset); } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs index 8cc66d025abbdf..9b89b3b5755d55 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs @@ -61,10 +61,10 @@ public UnwindCode() { } /// /// Unwind code parsing is based on src\jit\unwindamd64.cpp DumpUnwindInfo /// - public UnwindCode(byte[] image, ref int frameOffset, ref int offset) + public UnwindCode(NativeReader imageReader, ref int frameOffset, ref int offset) { - CodeOffset = NativeReader.ReadByte(image, ref offset); - byte op = NativeReader.ReadByte(image, ref offset); + CodeOffset = imageReader.ReadByte(ref offset); + byte op = imageReader.ReadByte(ref offset); UnwindOp = (UnwindOpCodes)(op & 15); OpInfo = (byte)(op >> 4); @@ -83,13 +83,13 @@ public UnwindCode(byte[] image, ref int frameOffset, ref int offset) if (OpInfo == 0) { OpInfoStr += "Scaled small"; - NextFrameOffset = 8 * NativeReader.ReadUInt16(image, ref offset); + NextFrameOffset = 8 * imageReader.ReadUInt16(ref offset); } else if (OpInfo == 1) { OpInfoStr += "Unscaled large"; - uint nextOffset = NativeReader.ReadUInt16(image, ref offset); - NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset); + uint nextOffset = imageReader.ReadUInt16(ref offset); + NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset); } else { @@ -104,43 +104,43 @@ public UnwindCode(byte[] image, ref int frameOffset, ref int offset) OpInfoStr = $"Unused({OpInfo})"; break; case UnwindOpCodes.UWOP_SET_FPREG_LARGE: + { + OpInfoStr = $"Unused({OpInfo})"; + uint nextOffset = imageReader.ReadUInt16(ref offset); + nextOffset = ((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset); + NextFrameOffset = (int)nextOffset * 16; + if ((NextFrameOffset & 0xF0000000) != 0) { - OpInfoStr = $"Unused({OpInfo})"; - uint nextOffset = NativeReader.ReadUInt16(image, ref offset); - nextOffset = ((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset); - NextFrameOffset = (int)nextOffset * 16; - if ((NextFrameOffset & 0xF0000000) != 0) - { - throw new BadImageFormatException("Warning: Illegal unwindInfo unscaled offset: too large"); - } + throw new BadImageFormatException("Warning: Illegal unwindInfo unscaled offset: too large"); } - break; + } + break; case UnwindOpCodes.UWOP_SAVE_NONVOL: - { - OpInfoStr = $"{(Registers)OpInfo}({OpInfo})"; - NextFrameOffset = NativeReader.ReadUInt16(image, ref offset) * 8; - } - break; + { + OpInfoStr = $"{(Registers)OpInfo}({OpInfo})"; + NextFrameOffset = imageReader.ReadUInt16(ref offset) * 8; + } + break; case UnwindOpCodes.UWOP_SAVE_NONVOL_FAR: - { - OpInfoStr = $"{(Registers)OpInfo}({OpInfo})"; - uint nextOffset = NativeReader.ReadUInt16(image, ref offset); - NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset); - } - break; + { + OpInfoStr = $"{(Registers)OpInfo}({OpInfo})"; + uint nextOffset = imageReader.ReadUInt16(ref offset); + NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset); + } + break; case UnwindOpCodes.UWOP_SAVE_XMM128: - { - OpInfoStr = $"XMM{OpInfo}({OpInfo})"; - NextFrameOffset = (int)NativeReader.ReadUInt16(image, ref offset) * 16; - } - break; + { + OpInfoStr = $"XMM{OpInfo}({OpInfo})"; + NextFrameOffset = (int)imageReader.ReadUInt16(ref offset) * 16; + } + break; case UnwindOpCodes.UWOP_SAVE_XMM128_FAR: - { - OpInfoStr = $"XMM{OpInfo}({OpInfo})"; - uint nextOffset = NativeReader.ReadUInt16(image, ref offset); - NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset); - } - break; + { + OpInfoStr = $"XMM{OpInfo}({OpInfo})"; + uint nextOffset = imageReader.ReadUInt16(ref offset); + NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset); + } + break; default: throw new NotImplementedException(UnwindOp.ToString()); } @@ -172,14 +172,14 @@ public UnwindInfo() { } /// /// based on ZapUnwindData::Save /// - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { - byte versionAndFlags = NativeReader.ReadByte(image, ref offset); + byte versionAndFlags = imageReader.ReadByte(ref offset); Version = (byte)(versionAndFlags & 7); Flags = (byte)(versionAndFlags >> 3); - SizeOfProlog = NativeReader.ReadByte(image, ref offset); - CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset); - byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset); + SizeOfProlog = imageReader.ReadByte(ref offset); + CountOfUnwindCodes = imageReader.ReadByte(ref offset); + byte frameRegisterAndOffset = imageReader.ReadByte(ref offset); FrameRegister = (Registers)(frameRegisterAndOffset & 15); FrameOffset = (byte)(frameRegisterAndOffset >> 4); @@ -190,7 +190,7 @@ public UnwindInfo(byte[] image, int offset) int endOffset = offset + sizeOfUnwindCodes; while (offset < endOffset) { - UnwindCode unwindCode = new UnwindCode(image, ref frameOffset, ref offset); + UnwindCode unwindCode = new UnwindCode(imageReader, ref frameOffset, ref offset); CodeOffsetToUnwindCodeIndex.Add(unwindCode.CodeOffset, UnwindCodes.Count); UnwindCodes.Add(unwindCode); } @@ -201,7 +201,7 @@ public UnwindInfo(byte[] image, int offset) // Personality routine RVA must be at 4-aligned address offset += alignmentPad; - PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset); + PersonalityRoutineRVA = imageReader.ReadUInt32(ref offset); } public override string ToString() diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs index 5a7d919910fe7b..4e6d81167f206b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs @@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { uint startOffset = (uint)offset; - int dw = NativeReader.ReadInt32(image, ref offset); + int dw = imageReader.ReadInt32(ref offset); CodeWords = ExtractBits(dw, 28, 4); EpilogCount = ExtractBits(dw, 23, 5); FBit = ExtractBits(dw, 22, 1); @@ -92,7 +92,7 @@ public UnwindInfo(byte[] image, int offset) { // We have an extension word specifying a larger number of Code Words or Epilog Counts // than can be specified in the header word. - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); ExtendedCodeWords = ExtractBits(dw, 16, 8); ExtendedEpilogCount = ExtractBits(dw, 0, 16); } @@ -106,7 +106,7 @@ public UnwindInfo(byte[] image, int offset) { for (int scope = 0; scope < EpilogCount; scope++) { - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); Epilogs[scope] = new Epilog(scope, dw, startOffset); epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs index c44e7c80833531..5809959d13aca8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs @@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { uint startOffset = (uint)offset; - int dw = NativeReader.ReadInt32(image, ref offset); + int dw = imageReader.ReadInt32(ref offset); CodeWords = ExtractBits(dw, 27, 5); EpilogCount = ExtractBits(dw, 22, 5); EBit = ExtractBits(dw, 21, 1); @@ -91,7 +91,7 @@ public UnwindInfo(byte[] image, int offset) { // We have an extension word specifying a larger number of Code Words or Epilog Counts // than can be specified in the header word. - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); ExtendedCodeWords = ExtractBits(dw, 16, 8); ExtendedEpilogCount = ExtractBits(dw, 0, 16); } @@ -105,7 +105,7 @@ public UnwindInfo(byte[] image, int offset) { for (int scope = 0; scope < EpilogCount; scope++) { - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); Epilogs[scope] = new Epilog(scope, dw, startOffset); epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs index f570dffdca505b..7dc7efc344570d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs @@ -92,12 +92,12 @@ private void EnsureInitialized() _boundsList = new List(); _variablesList = new List(); Machine machine = _readyToRunReader.Machine; - byte[] image = _readyToRunReader.Image; + NativeReader imageReader = _readyToRunReader.ImageReader; _machine = machine; // Get the id of the runtime function from the NativeArray uint lookback = 0; - uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback); + uint debugInfoOffset = imageReader.DecodeUnsigned((uint)offset, ref lookback); if (lookback != 0) { @@ -105,7 +105,7 @@ private void EnsureInitialized() debugInfoOffset = (uint)offset - lookback; } - NibbleReader reader = new NibbleReader(image, (int)debugInfoOffset); + NibbleReader reader = new NibbleReader(imageReader, (int)debugInfoOffset); uint boundsByteCount = reader.ReadUInt(); uint variablesByteCount = reader.ReadUInt(); int boundsOffset = reader.GetNextByteOffset(); @@ -113,23 +113,23 @@ private void EnsureInitialized() if (boundsByteCount > 0) { - ParseBounds(image, boundsOffset); + ParseBounds(imageReader, boundsOffset); } if (variablesByteCount > 0) { - ParseNativeVarInfo(image, variablesOffset); + ParseNativeVarInfo(imageReader, variablesOffset); } } - private void ParseBounds(byte[] image, int offset) + private void ParseBounds(NativeReader imageReader, int offset) { // Bounds info contains (Native Offset, IL Offset, flags) // - Sorted by native offset (so use a delta encoding for that). // - IL offsets aren't sorted, but they should be close to each other (so a signed delta encoding) // They may also include a sentinel value from MappingTypes. // - flags is 3 independent bits. - NibbleReader reader = new NibbleReader(image, offset); + NibbleReader reader = new NibbleReader(imageReader, offset); uint boundsEntryCount = reader.ReadUInt(); Debug.Assert(boundsEntryCount > 0); @@ -145,14 +145,14 @@ private void ParseBounds(byte[] image, int offset) } } - private void ParseNativeVarInfo(byte[] image, int offset) + private void ParseNativeVarInfo(NativeReader imageReader, int offset) { // Each Varinfo has a: // - native start +End offset. We can use a delta for the end offset. // - Il variable number. These are usually small. // - VarLoc information. This is a tagged variant. // The entries aren't sorted in any particular order. - NibbleReader reader = new NibbleReader(image, offset); + NibbleReader reader = new NibbleReader(imageReader, offset); uint nativeVarCount = reader.ReadUInt(); for (int i = 0; i < nativeVarCount; ++i) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj index f60794a8abf0be..71981555136054 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj @@ -7,8 +7,7 @@ AnyCPU Open true - - netstandard2.0 + $(NetCoreAppMinimum) false $(NoWarn);8002;NU1701 win-x64;win-x86 @@ -16,11 +15,6 @@ AnyCPU;x64 AnyCPU false - - false diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection.cs index c67582623af7fc..4d3a6ea4fc8ad6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection.cs @@ -24,14 +24,14 @@ public override string ToString() StringBuilder sb = new StringBuilder(); int iiOffset = _startOffset; - int sizeOfInlineIndex = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); + int sizeOfInlineIndex = _r2r.ImageReader.ReadInt32(ref iiOffset); int inlineIndexEndOffset = iiOffset + sizeOfInlineIndex; while (iiOffset < inlineIndexEndOffset) { - int inlineeRid = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); - int inlinersOffset = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); + int inlineeRid = _r2r.ImageReader.ReadInt32(ref iiOffset); + int inlinersOffset = _r2r.ImageReader.ReadInt32(ref iiOffset); sb.AppendLine($"Inliners for inlinee {RidToMethodDef(inlineeRid):X8}:"); - var inlinersReader = new NibbleReader(_r2r.Image, inlineIndexEndOffset + inlinersOffset); + var inlinersReader = new NibbleReader(_r2r.ImageReader, inlineIndexEndOffset + inlinersOffset); uint sameModuleCount = inlinersReader.ReadUInt(); int baseRid = 0; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection2.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection2.cs index 46399743450124..036c771e1bb215 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection2.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/InliningInfoSection2.cs @@ -23,8 +23,8 @@ public override string ToString() { StringBuilder sb = new StringBuilder(); - NativeParser parser = new NativeParser(_r2r.Image, (uint)_startOffset); - NativeHashtable hashtable = new NativeHashtable(_r2r.Image, parser, (uint)_endOffset); + NativeParser parser = new NativeParser(_r2r.ImageReader, (uint)_startOffset); + NativeHashtable hashtable = new NativeHashtable(_r2r.ImageReader, parser, (uint)_endOffset); var enumerator = hashtable.EnumerateAllEntries(); diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/LoongArch64/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/LoongArch64/UnwindInfo.cs index 98fe6cbfdde3e1..803c565092d12e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/LoongArch64/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/LoongArch64/UnwindInfo.cs @@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { uint startOffset = (uint)offset; - int dw = NativeReader.ReadInt32(image, ref offset); + int dw = imageReader.ReadInt32(ref offset); CodeWords = ExtractBits(dw, 27, 5); EpilogCount = ExtractBits(dw, 22, 5); EBit = ExtractBits(dw, 21, 1); @@ -91,7 +91,7 @@ public UnwindInfo(byte[] image, int offset) { // We have an extension word specifying a larger number of Code Words or Epilog Counts // than can be specified in the header word. - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); ExtendedCodeWords = ExtractBits(dw, 16, 8); ExtendedEpilogCount = ExtractBits(dw, 0, 16); } @@ -105,7 +105,7 @@ public UnwindInfo(byte[] image, int offset) { for (int scope = 0; scope < EpilogCount; scope++) { - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); Epilogs[scope] = new Epilog(scope, dw, startOffset); epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeArray.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeArray.cs index 7a9008100a23b5..d241e5c76d2296 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeArray.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeArray.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.IO; using System.Text; namespace ILCompiler.Reflection.ReadyToRun @@ -10,20 +11,21 @@ namespace ILCompiler.Reflection.ReadyToRun /// public class NativeArray { - // TODO (refactoring) - all these Native* class should be private private const int _blockSize = 16; + + private NativeReader _reader; private uint _baseOffset; private uint _nElements; private byte _entryIndexSize; - private byte[] _image; - public NativeArray(byte[] image, uint offset) + public NativeArray(NativeReader reader, uint offset) { + _reader = reader; + uint val = 0; - _baseOffset = NativeReader.DecodeUnsigned(image, offset, ref val); + _baseOffset = _reader.DecodeUnsigned(offset, ref val); _nElements = (val >> 2); _entryIndexSize = (byte)(val & 3); - _image = image; } public uint GetCount() @@ -40,7 +42,7 @@ public override string ToString() for (uint i = 0; i < _nElements; i++) { int val = 0; - if (TryGetAt(_image, i, ref val)) + if (TryGetAt(i, ref val)) { sb.AppendLine($"{i}: {val}"); } @@ -49,7 +51,7 @@ public override string ToString() return sb.ToString(); } - public bool TryGetAt(byte[] image, uint index, ref int pOffset) + public bool TryGetAt(uint index, ref int pOffset) { if (index >= _nElements) return false; @@ -58,24 +60,24 @@ public bool TryGetAt(byte[] image, uint index, ref int pOffset) if (_entryIndexSize == 0) { int i = (int)(_baseOffset + (index / _blockSize)); - offset = NativeReader.ReadByte(image, ref i); + offset = _reader.ReadByte(ref i); } else if (_entryIndexSize == 1) { int i = (int)(_baseOffset + 2 * (index / _blockSize)); - offset = NativeReader.ReadUInt16(image, ref i); + offset = _reader.ReadUInt16(ref i); } else { int i = (int)(_baseOffset + 4 * (index / _blockSize)); - offset = NativeReader.ReadUInt32(image, ref i); + offset = _reader.ReadUInt32(ref i); } offset += _baseOffset; for (uint bit = _blockSize >> 1; bit > 0; bit >>= 1) { uint val = 0; - uint offset2 = NativeReader.DecodeUnsigned(image, offset, ref val); + uint offset2 = _reader.DecodeUnsigned(offset, ref val); if ((index & bit) != 0) { if ((val & 2) != 0) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs index efeeaf18584087..846a60e22d965c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeHashtable.cs @@ -18,18 +18,18 @@ public struct NativeParser public uint Offset { get; set; } public byte LowHashcode { get; } - byte[] _image; + NativeReader _imageReader; - public NativeParser(byte[] image, uint offset, byte lowHashcode = 0) + public NativeParser(NativeReader imageReader, uint offset, byte lowHashcode = 0) { Offset = offset; LowHashcode = lowHashcode; - _image = image; + _imageReader = imageReader; } public bool IsNull() { - return _image == null; + return _imageReader == null; } public uint GetRelativeOffset() @@ -37,7 +37,7 @@ public uint GetRelativeOffset() uint pos = Offset; int delta = 0; - Offset = NativeReader.DecodeSigned(_image, Offset, ref delta); + Offset = _imageReader.DecodeSigned(Offset, ref delta); return pos + (uint)delta; } @@ -45,13 +45,13 @@ public uint GetRelativeOffset() public NativeParser GetParserFromRelativeOffset() { byte lowHashcode = GetByte(); - return new NativeParser(_image, GetRelativeOffset(), lowHashcode); + return new NativeParser(_imageReader, GetRelativeOffset(), lowHashcode); } public byte GetByte() { int off = (int)Offset; - byte val = NativeReader.ReadByte(_image, ref off); + byte val = _imageReader.ReadByte(ref off); Offset += 1; return val; } @@ -59,7 +59,7 @@ public byte GetByte() public uint GetCompressedData() { int off = (int)Offset; - uint val = NativeReader.ReadCompressedData(_image, ref off); + uint val = _imageReader.ReadCompressedData(ref off); Offset = (uint)off; return val; } @@ -67,14 +67,14 @@ public uint GetCompressedData() public uint GetUnsigned() { uint value = 0; - Offset = NativeReader.DecodeUnsigned(_image, Offset, ref value); + Offset = _imageReader.DecodeUnsigned(Offset, ref value); return value; } public int GetSigned() { int value = 0; - Offset = NativeReader.DecodeSigned(_image, Offset, ref value); + Offset = _imageReader.DecodeSigned(Offset, ref value); return value; } } @@ -85,17 +85,17 @@ public int GetSigned() public struct NativeHashtable { // TODO (refactoring) - all these Native* class should be private - private byte[] _image; + private NativeReader _imageReader; private uint _baseOffset; private uint _bucketMask; private byte _entryIndexSize; private uint _endOffset; - public NativeHashtable(byte[] image, NativeParser parser, uint endOffset) + public NativeHashtable(NativeReader imageReader, NativeParser parser, uint endOffset) { uint header = parser.GetByte(); _baseOffset = parser.Offset; - _image = image; + _imageReader = imageReader; int numberOfBucketsShift = (int)(header >> 2); if (numberOfBucketsShift > 31) @@ -134,7 +134,7 @@ public override string ToString() { for (int i = curOffset; i < nextOffset; i++) { - sb.Append($"{_image[i]:X2} "); + sb.Append($"{_imageReader[i]:X2} "); } sb.AppendLine(); } @@ -205,24 +205,24 @@ private NativeParser GetParserForBucket(uint bucket, out uint endOffset) if (_entryIndexSize == 0) { int bucketOffset = (int)(_baseOffset + bucket); - start = NativeReader.ReadByte(_image, ref bucketOffset); - end = NativeReader.ReadByte(_image, ref bucketOffset); + start = _imageReader.ReadByte(ref bucketOffset); + end = _imageReader.ReadByte(ref bucketOffset); } else if (_entryIndexSize == 1) { int bucketOffset = (int)(_baseOffset + 2 * bucket); - start = NativeReader.ReadUInt16(_image, ref bucketOffset); - end = NativeReader.ReadUInt16(_image, ref bucketOffset); + start = _imageReader.ReadUInt16(ref bucketOffset); + end = _imageReader.ReadUInt16(ref bucketOffset); } else { int bucketOffset = (int)(_baseOffset + 4 * bucket); - start = NativeReader.ReadUInt32(_image, ref bucketOffset); - end = NativeReader.ReadUInt32(_image, ref bucketOffset); + start = _imageReader.ReadUInt32(ref bucketOffset); + end = _imageReader.ReadUInt32(ref bucketOffset); } endOffset = end + _baseOffset; - return new NativeParser(_image, _baseOffset + start); + return new NativeParser(_imageReader, _baseOffset + start); } public Enumerator Lookup(int hashcode) @@ -246,13 +246,13 @@ public AllEntriesEnumerator EnumerateAllEntries() public struct NativeCuckooFilter { // TODO (refactoring) - all these Native* class should be private - private byte[] _image; + private NativeReader _imageReader; private int _filterStartOffset; private int _filterEndOffset; - public NativeCuckooFilter(byte[] image, int filterStartOffset, int filterEndOffset) + public NativeCuckooFilter(NativeReader imageReader, int filterStartOffset, int filterEndOffset) { - _image = image; + _imageReader = imageReader; _filterStartOffset = filterStartOffset; _filterEndOffset = filterEndOffset; @@ -271,7 +271,7 @@ private IEnumerable GetBuckets() ushort[] bucket = new ushort[8]; for (int i = 0; i < bucket.Length; i++) { - bucket[i] = NativeReader.ReadUInt16(_image, ref offset); + bucket[i] = _imageReader.ReadUInt16(ref offset); } yield return bucket; } @@ -283,7 +283,7 @@ public override string ToString() sb.AppendLine($"NativeCuckooFilter Size: {(_filterEndOffset - _filterStartOffset) / 16}"); int bucket = 0; - foreach (ushort [] bucketContents in GetBuckets()) + foreach (ushort[] bucketContents in GetBuckets()) { sb.Append($"Bucket: {bucket} ["); for (int i = 0; i < 8; i++) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs index 2805a24d139ab0..44d6c238005318 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs @@ -2,122 +2,137 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Buffers.Binary; using System.Collections.Generic; +using System.IO; using System.Text; namespace ILCompiler.Reflection.ReadyToRun { - public class NativeReader + public class NativeReader(Stream backingStream, bool littleEndian = true) { - // TODO (refactoring) - all these Native* class should be private private const int BITS_PER_BYTE = 8; private const int BITS_PER_SIZE_T = 32; + private readonly Stream _backingStream = backingStream; + private readonly bool _littleEndian = littleEndian; + + /// + /// Reads a byte from the image at the specified index + /// + public int this[int index] + { + get => ReadByte(ref index); + } + + /// + /// Reads a span of bytes from the image at the specified start index + /// + /// Starting index of the value + /// Span to be filled with the read bytes + /// + /// The gets incremented by the size of the buffer + /// + public void ReadSpanAt(ref int start, Span buffer) + { + if (start < 0 || start + buffer.Length > _backingStream.Length) + throw new ArgumentOutOfRangeException(nameof(start), "Start index is out of bounds"); + + _backingStream.Seek(start, SeekOrigin.Begin); + _backingStream.Read(buffer); + start += buffer.Length; + } + /// /// Extracts a 64bit value from the image byte array /// - /// PE image /// Starting index of the value /// /// The gets incremented by the size of the value /// - public static long ReadInt64(byte[] image, ref int start) + public long ReadInt64(ref int start) { - int size = sizeof(long); - byte[] bytes = new byte[size]; - Array.Copy(image, start, bytes, 0, size); - start += size; - return BitConverter.ToInt64(bytes, 0); + Span bytes = stackalloc byte[sizeof(long)]; + ReadSpanAt(ref start, bytes); + return _littleEndian ? BinaryPrimitives.ReadInt64LittleEndian(bytes) : BinaryPrimitives.ReadInt64BigEndian(bytes); } // /// Extracts a 32bit value from the image byte array /// - /// PE image /// Starting index of the value /// /// The gets incremented by the size of the value /// - public static int ReadInt32(byte[] image, ref int start) + public int ReadInt32(ref int start) { - int size = sizeof(int); - byte[] bytes = new byte[size]; - Array.Copy(image, start, bytes, 0, size); - start += size; - return BitConverter.ToInt32(bytes, 0); + Span bytes = stackalloc byte[sizeof(int)]; + ReadSpanAt(ref start, bytes); + return _littleEndian ? BinaryPrimitives.ReadInt32LittleEndian(bytes) : BinaryPrimitives.ReadInt32BigEndian(bytes); } // /// Extracts an unsigned 32bit value from the image byte array /// - /// PE image /// Starting index of the value /// /// The gets incremented by the size of the value /// - public static uint ReadUInt32(byte[] image, ref int start) + public uint ReadUInt32(ref int start) { - int size = sizeof(int); - byte[] bytes = new byte[size]; - Array.Copy(image, start, bytes, 0, size); - start += size; - return (uint)BitConverter.ToInt32(bytes, 0); + Span bytes = stackalloc byte[sizeof(uint)]; + ReadSpanAt(ref start, bytes); + return _littleEndian ? BinaryPrimitives.ReadUInt32LittleEndian(bytes) : BinaryPrimitives.ReadUInt32BigEndian(bytes); } // /// Extracts an unsigned 16bit value from the image byte array /// - /// PE image /// Starting index of the value /// /// The gets incremented by the size of the value /// - public static ushort ReadUInt16(byte[] image, ref int start) + public ushort ReadUInt16(ref int start) { - int size = sizeof(short); - byte[] bytes = new byte[size]; - Array.Copy(image, start, bytes, 0, size); - start += size; - return (ushort)BitConverter.ToInt16(bytes, 0); + Span bytes = stackalloc byte[sizeof(ushort)]; + ReadSpanAt(ref start, bytes); + return _littleEndian ? BinaryPrimitives.ReadUInt16LittleEndian(bytes) : BinaryPrimitives.ReadUInt16BigEndian(bytes); } // /// Extracts byte from the image byte array /// - /// PE image /// Start index of the value /// /// The gets incremented by the size of the value /// - public static byte ReadByte(byte[] image, ref int start) + public byte ReadByte(ref int start) { - byte val = image[start]; - start += sizeof(byte); - return val; + Span bytes = stackalloc byte[sizeof(byte)]; + ReadSpanAt(ref start, bytes); + return bytes[0]; } // /// Extracts bits from the image byte array /// - /// PE image /// Number of bits to read /// Start bit of the value /// /// The gets incremented by /// - public static int ReadBits(byte[] image, int numBits, ref int bitOffset) + public int ReadBits(int numBits, ref int bitOffset) { int start = bitOffset / BITS_PER_BYTE; int bits = bitOffset % BITS_PER_BYTE; - int val = image[start] >> bits; + int val = ReadByte(ref start) >> bits; bits += numBits; while (bits > BITS_PER_BYTE) { - start++; bits -= BITS_PER_BYTE; if (bits > 0) { - int extraBits = image[start] << (numBits - bits); + int extraBits = ReadByte(ref start) << (numBits - bits); val ^= extraBits; } } @@ -130,19 +145,18 @@ public static int ReadBits(byte[] image, int numBits, ref int bitOffset) /// Decode variable length numbers /// based on src\inc\gcinfodecoder.h DecodeVarLengthUnsigned /// - /// PE image /// Number of bits to read /// Start bit of the value /// /// The gets incremented by the size of the value /// - public static uint DecodeVarLengthUnsigned(byte[] image, int len, ref int bitOffset) + public uint DecodeVarLengthUnsigned(int len, ref int bitOffset) { uint numEncodings = (uint)(1 << len); uint result = 0; for (int shift = 0; ; shift += len) { - uint currentChunk = (uint)ReadBits(image, len + 1, ref bitOffset); + uint currentChunk = (uint)ReadBits(len + 1, ref bitOffset); result |= (currentChunk & (numEncodings - 1)) << shift; if ((currentChunk & numEncodings) == 0) { @@ -155,13 +169,13 @@ public static uint DecodeVarLengthUnsigned(byte[] image, int len, ref int bitOff // /// based on src\inc\gcinfodecoder.h DecodeVarLengthSigned /// - public static int DecodeVarLengthSigned(byte[] image, int len, ref int bitOffset) + public int DecodeVarLengthSigned(int len, ref int bitOffset) { int numEncodings = (1 << len); int result = 0; for (int shift = 0; ; shift += len) { - int currentChunk = ReadBits(image, len + 1, ref bitOffset); + int currentChunk = ReadBits(len + 1, ref bitOffset); result |= (currentChunk & (numEncodings - 1)) << shift; if ((currentChunk & numEncodings) == 0) { @@ -177,13 +191,13 @@ public static int DecodeVarLengthSigned(byte[] image, int len, ref int bitOffset // /// based on src\vm\nativeformatreader.h DecodeUnsigned /// - public static uint DecodeUnsigned(byte[] image, uint offset, ref uint pValue) + public uint DecodeUnsigned(uint offset, ref uint pValue) { - if (offset >= image.Length) + if (offset >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); int off = (int)offset; - uint val = ReadByte(image, ref off); + uint val = ReadByte(ref off); if ((val & 1) == 0) { @@ -192,37 +206,37 @@ public static uint DecodeUnsigned(byte[] image, uint offset, ref uint pValue) } else if ((val & 2) == 0) { - if (offset + 1 >= image.Length) + if (offset + 1 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 2) | - ((uint)ReadByte(image, ref off) << 6); + ((uint)ReadByte(ref off) << 6); offset += 2; } else if ((val & 4) == 0) { - if (offset + 2 >= image.Length) + if (offset + 2 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 3) | - ((uint)ReadByte(image, ref off) << 5) | - ((uint)ReadByte(image, ref off) << 13); + ((uint)ReadByte(ref off) << 5) | + ((uint)ReadByte(ref off) << 13); offset += 3; } else if ((val & 8) == 0) { - if (offset + 3 >= image.Length) + if (offset + 3 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 4) | - ((uint)ReadByte(image, ref off) << 4) | - ((uint)ReadByte(image, ref off) << 12) | - ((uint)ReadByte(image, ref off) << 20); + ((uint)ReadByte(ref off) << 4) | + ((uint)ReadByte(ref off) << 12) | + ((uint)ReadByte(ref off) << 20); offset += 4; } else if ((val & 16) == 0) { - pValue = ReadUInt32(image, ref off); + pValue = ReadUInt32(ref off); offset += 5; } else @@ -236,13 +250,13 @@ public static uint DecodeUnsigned(byte[] image, uint offset, ref uint pValue) // /// based on src\vm\nativeformatreader.h DecodeSigned /// - public static uint DecodeSigned(byte[] image, uint offset, ref int pValue) + public uint DecodeSigned(uint offset, ref int pValue) { - if (offset >= image.Length) + if (offset >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); int off = (int)offset; - int val = ReadByte(image, ref off); + int val = ReadByte(ref off); if ((val & 1) == 0) { @@ -251,37 +265,37 @@ public static uint DecodeSigned(byte[] image, uint offset, ref int pValue) } else if ((val & 2) == 0) { - if (offset + 1 >= image.Length) + if (offset + 1 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 2) | - (ReadByte(image, ref off) << 6); + (ReadByte(ref off) << 6); offset += 2; } else if ((val & 4) == 0) { - if (offset + 2 >= image.Length) + if (offset + 2 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 3) | - (ReadByte(image, ref off) << 5) | - (ReadByte(image, ref off) << 13); + (ReadByte(ref off) << 5) | + (ReadByte(ref off) << 13); offset += 3; } else if ((val & 8) == 0) { - if (offset + 3 >= image.Length) + if (offset + 3 >= _backingStream.Length) throw new System.BadImageFormatException("offset out of bounds"); pValue = (val >> 4) | - (ReadByte(image, ref off) << 4) | - (ReadByte(image, ref off) << 12) | - (ReadByte(image, ref off) << 20); + (ReadByte(ref off) << 4) | + (ReadByte(ref off) << 12) | + (ReadByte(ref off) << 20); offset += 4; } else if ((val & 16) == 0) { - pValue = ReadInt32(image, ref off); + pValue = ReadInt32(ref off); offset += 5; } else @@ -295,10 +309,10 @@ public static uint DecodeSigned(byte[] image, uint offset, ref int pValue) // /// based on src\debug\daccess\nidump.cpp DacSigUncompressData and DacSigUncompressBigData /// - public static uint ReadCompressedData(byte[] image, ref int start) + public uint ReadCompressedData(ref int start) { int off = start; - uint data = ReadUInt32(image, ref off); + uint data = ReadUInt32(ref off); if ((data & 0x80) == 0x00) { start++; @@ -306,15 +320,15 @@ public static uint ReadCompressedData(byte[] image, ref int start) } if ((data & 0xC0) == 0x80) // 10?? ???? { - data = (uint)((ReadByte(image, ref start) & 0x3f) << 8); - data |= ReadByte(image, ref start); + data = (uint)((ReadByte(ref start) & 0x3f) << 8); + data |= ReadByte(ref start); } else // 110? ???? { - data = (uint)(ReadByte(image, ref start) & 0x1f) << 24; - data |= (uint)ReadByte(image, ref start) << 16; - data |= (uint)ReadByte(image, ref start) << 8; - data |= ReadByte(image, ref start); + data = (uint)(ReadByte(ref start) & 0x1f) << 24; + data |= (uint)ReadByte(ref start) << 16; + data |= (uint)ReadByte(ref start) << 8; + data |= ReadByte(ref start); } return data; } @@ -322,15 +336,15 @@ public static uint ReadCompressedData(byte[] image, ref int start) /// /// based on src\inc\gcdecoder.cpp decodeUnsigned /// - public static uint DecodeUnsignedGc(byte[] image, ref int start) + public uint DecodeUnsignedGc(ref int start) { int size = 1; - byte data = image[start++]; + byte data = ReadByte(ref start); uint value = (uint)data & 0x7f; while ((data & 0x80) != 0) { size++; - data = image[start++]; + data = ReadByte(ref start); value <<= 7; value += (uint)data & 0x7f; } @@ -340,16 +354,16 @@ public static uint DecodeUnsignedGc(byte[] image, ref int start) /// /// based on src\inc\gcdecoder.cpp decodeSigned /// - public static int DecodeSignedGc(byte[] image, ref int start) + public int DecodeSignedGc(ref int start) { int size = 1; - byte data = image[start++]; + byte data = ReadByte(ref start); byte first = data; int value = data & 0x3f; while ((data & 0x80) != 0) { size++; - data = image[start++]; + data = ReadByte(ref start); value <<= 7; value += data & 0x7f; } @@ -362,10 +376,10 @@ public static int DecodeSignedGc(byte[] image, ref int start) /// /// based on src\inc\gcdecoder.cpp decodeUDelta /// - public static uint DecodeUDelta(byte[] image, ref int start, uint lastValue) + public uint DecodeUDelta(ref int start, uint lastValue) { - uint delta = DecodeUnsignedGc(image, ref start); + uint delta = DecodeUnsignedGc(ref start); return lastValue + delta; } } -} +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs index 7a024ed33445b5..26d4599b6a44b2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NibbleReader.cs @@ -16,9 +16,9 @@ class NibbleReader private const byte NoNextNibble = 0xFF; /// - /// Byte array representing the PE file. + /// NativeReader representing the PE file. /// - private byte[] _image; + private NativeReader _imageReader; /// /// Offset within the image. @@ -30,9 +30,9 @@ class NibbleReader /// private byte _nextNibble; - public NibbleReader(byte[] image, int offset) + public NibbleReader(NativeReader imageReader, int offset) { - _image = image; + _imageReader = imageReader; _offset = offset; _nextNibble = NoNextNibble; } @@ -47,7 +47,7 @@ public byte ReadNibble() } else { - _nextNibble = _image[_offset++]; + _nextNibble = _imageReader.ReadByte(ref _offset); result = (byte)(_nextNibble & 0x0F); _nextNibble >>= 4; } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs index 173ece1227ef29..dcecc214111bdf 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs @@ -22,16 +22,12 @@ public class ComponentAssembly public readonly int AssemblyHeaderRVA; public readonly int AssemblyHeaderSize; - public ComponentAssembly(byte[] image, ref int curOffset) + public ComponentAssembly(NativeReader imageReader, ref int curOffset) { - CorHeaderRVA = BitConverter.ToInt32(image, curOffset); - curOffset += sizeof(int); - CorHeaderSize = BitConverter.ToInt32(image, curOffset); - curOffset += sizeof(int); - AssemblyHeaderRVA = BitConverter.ToInt32(image, curOffset); - curOffset += sizeof(int); - AssemblyHeaderSize = BitConverter.ToInt32(image, curOffset); - curOffset += sizeof(int); + CorHeaderRVA = imageReader.ReadInt32(ref curOffset); + CorHeaderSize = imageReader.ReadInt32(ref curOffset); + AssemblyHeaderRVA = imageReader.ReadInt32(ref curOffset); + AssemblyHeaderSize = imageReader.ReadInt32(ref curOffset); } } @@ -55,32 +51,32 @@ public ReadyToRunCoreHeader() { } - public ReadyToRunCoreHeader(byte[] image, ref int curOffset) + public ReadyToRunCoreHeader(NativeReader imageReader, ref int curOffset) { - ParseCoreHeader(image, ref curOffset); + ParseCoreHeader(imageReader, ref curOffset); } /// /// Parse core header fields common to global R2R file header and per assembly headers in composite R2R images. /// - /// PE image + /// PE Image reader /// Index in the image byte array to the start of the ReadyToRun core header - public void ParseCoreHeader(byte[] image, ref int curOffset) + public void ParseCoreHeader(NativeReader imageReader, ref int curOffset) { - Flags = NativeReader.ReadUInt32(image, ref curOffset); - int nSections = NativeReader.ReadInt32(image, ref curOffset); + Flags = imageReader.ReadUInt32(ref curOffset); + int nSections = imageReader.ReadInt32(ref curOffset); Sections = new Dictionary(); for (int i = 0; i < nSections; i++) { - int type = NativeReader.ReadInt32(image, ref curOffset); + int type = imageReader.ReadInt32(ref curOffset); var sectionType = (ReadyToRunSectionType)type; if (!Enum.IsDefined(typeof(ReadyToRunSectionType), type)) { throw new BadImageFormatException("Warning: Invalid ReadyToRun section type"); } - int sectionStartRva = NativeReader.ReadInt32(image, ref curOffset); - int sectionLength = NativeReader.ReadInt32(image, ref curOffset); + int sectionStartRva = imageReader.ReadInt32(ref curOffset); + int sectionLength = imageReader.ReadInt32(ref curOffset); Sections[sectionType] = new ReadyToRunSection(sectionType, sectionStartRva, sectionLength); } } @@ -124,28 +120,29 @@ public ReadyToRunHeader() { } /// /// Initializes the fields of the R2RHeader /// - /// PE image + /// PE Image reader /// Relative virtual address of the ReadyToRun header /// Index in the image byte array to the start of the ReadyToRun header /// The signature must be 0x00525452 - public ReadyToRunHeader(byte[] image, int rva, int curOffset) + public ReadyToRunHeader(NativeReader imageReader, int rva, int curOffset) { RelativeVirtualAddress = rva; int startOffset = curOffset; byte[] signature = new byte[sizeof(uint) - 1]; // -1 removes the null character at the end of the cstring - Array.Copy(image, curOffset, signature, 0, sizeof(uint) - 1); + imageReader.ReadSpanAt(ref curOffset, signature); + curOffset = startOffset; SignatureString = Encoding.UTF8.GetString(signature); - Signature = NativeReader.ReadUInt32(image, ref curOffset); + Signature = imageReader.ReadUInt32(ref curOffset); if (Signature != READYTORUN_SIGNATURE) { throw new System.BadImageFormatException("Incorrect R2R header signature: " + SignatureString); } - MajorVersion = NativeReader.ReadUInt16(image, ref curOffset); - MinorVersion = NativeReader.ReadUInt16(image, ref curOffset); + MajorVersion = imageReader.ReadUInt16(ref curOffset); + MinorVersion = imageReader.ReadUInt16(ref curOffset); - ParseCoreHeader(image, ref curOffset); + ParseCoreHeader(imageReader, ref curOffset); Size = curOffset - startOffset; } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs index 67f581e8d8dfe6..10ab13a6e9eaad 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs @@ -399,32 +399,32 @@ public ReadyToRunMethod( switch (MethodHandle.Kind) { case HandleKind.MethodDefinition: + { + MethodDefinition methodDef = ComponentReader.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle); + if (methodDef.RelativeVirtualAddress != 0) { - MethodDefinition methodDef = ComponentReader.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle); - if (methodDef.RelativeVirtualAddress != 0) + MethodBodyBlock mbb = ComponentReader.ImageReader.GetMethodBody(methodDef.RelativeVirtualAddress); + if (!mbb.LocalSignature.IsNil) { - MethodBodyBlock mbb = ComponentReader.ImageReader.GetMethodBody(methodDef.RelativeVirtualAddress); - if (!mbb.LocalSignature.IsNil) - { - StandaloneSignature ss = ComponentReader.MetadataReader.GetStandaloneSignature(mbb.LocalSignature); - LocalSignature = ss.DecodeLocalSignature(typeProvider, genericContext); - } + StandaloneSignature ss = ComponentReader.MetadataReader.GetStandaloneSignature(mbb.LocalSignature); + LocalSignature = ss.DecodeLocalSignature(typeProvider, genericContext); } - Name = ComponentReader.MetadataReader.GetString(methodDef.Name); - Signature = methodDef.DecodeSignature(typeProvider, genericContext); - owningTypeHandle = methodDef.GetDeclaringType(); - genericParams = methodDef.GetGenericParameters(); } - break; + Name = ComponentReader.MetadataReader.GetString(methodDef.Name); + Signature = methodDef.DecodeSignature(typeProvider, genericContext); + owningTypeHandle = methodDef.GetDeclaringType(); + genericParams = methodDef.GetGenericParameters(); + } + break; case HandleKind.MemberReference: - { - MemberReference memberRef = ComponentReader.MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle); - Name = ComponentReader.MetadataReader.GetString(memberRef.Name); - Signature = memberRef.DecodeMethodSignature(typeProvider, genericContext); - owningTypeHandle = memberRef.Parent; - } - break; + { + MemberReference memberRef = ComponentReader.MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle); + Name = ComponentReader.MetadataReader.GetString(memberRef.Name); + Signature = memberRef.DecodeMethodSignature(typeProvider, genericContext); + owningTypeHandle = memberRef.Parent; + } + break; default: throw new NotImplementedException(); @@ -492,13 +492,13 @@ private void EnsureInitialized() int gcInfoOffset = _readyToRunReader.CompositeReader.GetOffset(GcInfoRva); if (_readyToRunReader.Machine == Machine.I386) { - _gcInfo = new x86.GcInfo(_readyToRunReader.Image, gcInfoOffset); + _gcInfo = new x86.GcInfo(_readyToRunReader.ImageReader, gcInfoOffset); } else { // Arm, Arm64, LoongArch64 and RISCV64 use the same GcInfo format as Amd64 _gcInfo = new Amd64.GcInfo( - _readyToRunReader.Image, + _readyToRunReader.ImageReader, gcInfoOffset, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion, @@ -527,7 +527,7 @@ private void EnsureFixupCells() return; } _fixupCells = new List(); - NibbleReader reader = new NibbleReader(_readyToRunReader.Image, _fixupOffset.Value); + NibbleReader reader = new NibbleReader(_readyToRunReader.ImageReader, _fixupOffset.Value); // The following algorithm has been loosely ported from CoreCLR, // src\vm\ceeload.inl, BOOL Module::FixupDelayListAux @@ -585,7 +585,7 @@ private void ParseRuntimeFunctions(bool partial) curOffset = coldOffset; runtimeFunctionId = coldRuntimeFunctionId; } - int startRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset); + int startRva = _readyToRunReader.ImageReader.ReadInt32(ref curOffset); if (_readyToRunReader.Machine == Machine.ArmThumb2) { // The low bit of this address is set since the function contains thumb code. @@ -595,35 +595,35 @@ private void ParseRuntimeFunctions(bool partial) int endRva = -1; if (_readyToRunReader.Machine == Machine.Amd64) { - endRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset); + endRva = _readyToRunReader.ImageReader.ReadInt32(ref curOffset); } - int unwindRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset); + int unwindRva = _readyToRunReader.ImageReader.ReadInt32(ref curOffset); int unwindOffset = _readyToRunReader.CompositeReader.GetOffset(unwindRva); BaseUnwindInfo unwindInfo = null; if (_readyToRunReader.Machine == Machine.I386) { - unwindInfo = new x86.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new x86.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.Amd64) { - unwindInfo = new Amd64.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new Amd64.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.ArmThumb2) { - unwindInfo = new Arm.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new Arm.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.Arm64) { - unwindInfo = new Arm64.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new Arm64.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.LoongArch64) { - unwindInfo = new LoongArch64.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new LoongArch64.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } else if (_readyToRunReader.Machine == Machine.RiscV64) { - unwindInfo = new RiscV64.UnwindInfo(_readyToRunReader.Image, unwindOffset); + unwindInfo = new RiscV64.UnwindInfo(_readyToRunReader.ImageReader, unwindOffset); } if (i == 0 && unwindInfo != null) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 3dc6cbb9aae659..1838593a20fe25 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -141,8 +141,14 @@ public sealed class ReadyToRunReader /// Byte array containing the ReadyToRun image /// public byte[] Image { get; private set; } + private PinningReference ImagePin; + /// + /// NativeReader to read the image contents + /// + public NativeReader ImageReader { get; private set; } + /// /// Name of the image file /// @@ -407,6 +413,7 @@ public ReadyToRunReader(IAssemblyResolver assemblyResolver, IAssemblyMetadata me CompositeReader = peReader; Filename = filename; Image = ConvertToArray(content); + ImageReader = new NativeReader(new MemoryStream(Image)); Initialize(metadata); } @@ -433,6 +440,7 @@ public unsafe ReadyToRunReader(IAssemblyResolver assemblyResolver, string filena _assemblyResolver = assemblyResolver; Filename = filename; Image = ConvertToArray(content); + ImageReader = new NativeReader(new MemoryStream(Image)); Initialize(metadata: null); } @@ -484,6 +492,7 @@ private unsafe void Initialize(IAssemblyMetadata metadata) if (CompositeReader == null) { Image ??= File.ReadAllBytes(Filename); + ImageReader = new NativeReader(new MemoryStream(Image)); byte[] image = Image; ImagePin = new PinningReference(image); CompositeReader = new PEReader(Unsafe.As>(ref image)); @@ -492,6 +501,7 @@ private unsafe void Initialize(IAssemblyMetadata metadata) { ImmutableArray content = CompositeReader.GetEntireImage().GetContent(); Image = Unsafe.As, byte[]>(ref content); + ImageReader = new NativeReader(new MemoryStream(Image)); ImagePin = new PinningReference(Image); } @@ -560,7 +570,7 @@ internal void EnsureMethods() for (int i = 0; i < count; i++) { - mHotColdMap.Add(new List { NativeReader.ReadInt32(Image, ref hotColdMapOffset), NativeReader.ReadInt32(Image, ref hotColdMapOffset) }); + mHotColdMap.Add(new List { ImageReader.ReadInt32(ref hotColdMapOffset), ImageReader.ReadInt32(ref hotColdMapOffset) }); } for (int i = 0; i < count - 1; i++) @@ -687,7 +697,7 @@ private unsafe void EnsureHeader() // Initialize R2RHeader Debug.Assert(_readyToRunHeaderRVA != 0); int r2rHeaderOffset = GetOffset(_readyToRunHeaderRVA); - _readyToRunHeader = new ReadyToRunHeader(Image, _readyToRunHeaderRVA, r2rHeaderOffset); + _readyToRunHeader = new ReadyToRunHeader(ImageReader, _readyToRunHeaderRVA, r2rHeaderOffset); FindOwnerCompositeExecutable(); @@ -716,11 +726,11 @@ private void EnsureDebugInfo() int debugInfoSectionOffset = GetOffset(debugInfoSection.RelativeVirtualAddress); - NativeArray debugInfoArray = new NativeArray(Image, (uint)debugInfoSectionOffset); + NativeArray debugInfoArray = new NativeArray(ImageReader, (uint)debugInfoSectionOffset); for (uint i = 0; i < debugInfoArray.GetCount(); ++i) { int offset = 0; - if (!debugInfoArray.TryGetAt(Image, i, ref offset)) + if (!debugInfoArray.TryGetAt(i, ref offset)) { continue; } @@ -837,13 +847,13 @@ private void ParseMethodDefEntrypointsSection(ReadyToRunSection section, IAssemb { int assemblyIndex = GetAssemblyIndex(section); int methodDefEntryPointsOffset = GetOffset(section.RelativeVirtualAddress); - NativeArray methodEntryPoints = new NativeArray(Image, (uint)methodDefEntryPointsOffset); + NativeArray methodEntryPoints = new NativeArray(ImageReader, (uint)methodDefEntryPointsOffset); uint nMethodEntryPoints = methodEntryPoints.GetCount(); for (uint rid = 1; rid <= nMethodEntryPoints; rid++) { int offset = 0; - if (methodEntryPoints.TryGetAt(Image, rid - 1, ref offset)) + if (methodEntryPoints.TryGetAt(rid - 1, ref offset)) { EntityHandle methodHandle = MetadataTokens.MethodDefinitionHandle((int)rid); int runtimeFunctionId; @@ -870,13 +880,13 @@ private void ParseMethodDefEntrypointsSection(ReadyToRunSection section, IAssemb private void ParseMethodDefEntrypointsSectionCustom(IR2RSignatureTypeProvider provider, Dictionary foundMethods, ReadyToRunSection section, IAssemblyMetadata metadataReader) { int methodDefEntryPointsOffset = GetOffset(section.RelativeVirtualAddress); - NativeArray methodEntryPoints = new NativeArray(Image, (uint)methodDefEntryPointsOffset); + NativeArray methodEntryPoints = new NativeArray(ImageReader, (uint)methodDefEntryPointsOffset); uint nMethodEntryPoints = methodEntryPoints.GetCount(); for (uint rid = 1; rid <= nMethodEntryPoints; rid++) { int offset = 0; - if (methodEntryPoints.TryGetAt(Image, rid - 1, ref offset)) + if (methodEntryPoints.TryGetAt(rid - 1, ref offset)) { EntityHandle methodHandle = MetadataTokens.MethodDefinitionHandle((int)rid); int runtimeFunctionId; @@ -901,8 +911,8 @@ private void ParseInstanceMethodEntrypointsCustom(); int availableTypesOffset = GetOffset(availableTypesSection.RelativeVirtualAddress); - NativeParser parser = new NativeParser(Image, (uint)availableTypesOffset); - NativeHashtable availableTypes = new NativeHashtable(Image, parser, (uint)(availableTypesOffset + availableTypesSection.Size)); + NativeParser parser = new NativeParser(ImageReader, (uint)availableTypesOffset); + NativeHashtable availableTypes = new NativeHashtable(ImageReader, parser, (uint)(availableTypesOffset + availableTypesSection.Size)); NativeHashtable.AllEntriesEnumerator allEntriesEnum = availableTypes.EnumerateAllEntries(); NativeParser curParser = allEntriesEnum.GetNext(); while (!curParser.IsNull()) @@ -1396,10 +1406,10 @@ private void ParseComponentAssemblies() for (int assemblyIndex = 0; assemblyIndex < numberOfAssemblyHeaderRVAs; assemblyIndex++) { - ComponentAssembly assembly = new ComponentAssembly(Image, ref offset); + ComponentAssembly assembly = new ComponentAssembly(ImageReader, ref offset); int headerOffset = GetOffset(assembly.AssemblyHeaderRVA); - ReadyToRunCoreHeader assemblyHeader = new ReadyToRunCoreHeader(Image, ref headerOffset); + ReadyToRunCoreHeader assemblyHeader = new ReadyToRunCoreHeader(ImageReader, ref headerOffset); _readyToRunAssemblyHeaders.Add(assemblyHeader); _readyToRunAssemblies.Add(new ReadyToRunAssembly(this)); } @@ -1439,13 +1449,13 @@ private void EnsureImportSections() int endOffset = offset + importSectionsSection.Size; while (offset < endOffset) { - int rva = NativeReader.ReadInt32(Image, ref offset); + int rva = ImageReader.ReadInt32(ref offset); int sectionOffset = GetOffset(rva); int startOffset = sectionOffset; - int size = NativeReader.ReadInt32(Image, ref offset); - ReadyToRunImportSectionFlags flags = (ReadyToRunImportSectionFlags)NativeReader.ReadUInt16(Image, ref offset); - ReadyToRunImportSectionType type = (ReadyToRunImportSectionType)NativeReader.ReadByte(Image, ref offset); - byte entrySize = NativeReader.ReadByte(Image, ref offset); + int size = ImageReader.ReadInt32(ref offset); + ReadyToRunImportSectionFlags flags = (ReadyToRunImportSectionFlags)ImageReader.ReadUInt16(ref offset); + ReadyToRunImportSectionType type = (ReadyToRunImportSectionType)ImageReader.ReadByte(ref offset); + byte entrySize = ImageReader.ReadByte(ref offset); if (entrySize == 0) { switch (Machine) @@ -1471,7 +1481,7 @@ private void EnsureImportSections() { entryCount = size / entrySize; } - int signatureRVA = NativeReader.ReadInt32(Image, ref offset); + int signatureRVA = ImageReader.ReadInt32(ref offset); int signatureOffset = 0; if (signatureRVA != 0) @@ -1482,15 +1492,15 @@ private void EnsureImportSections() for (int i = 0; i < entryCount; i++) { int entryOffset = sectionOffset - startOffset; - long section = NativeReader.ReadInt64(Image, ref sectionOffset); - uint sigRva = NativeReader.ReadUInt32(Image, ref signatureOffset); + long section = ImageReader.ReadInt64(ref sectionOffset); + uint sigRva = ImageReader.ReadUInt32(ref signatureOffset); int sigOffset = GetOffset((int)sigRva); ReadyToRunSignature signature = MetadataNameFormatter.FormatSignature(_assemblyResolver, this, sigOffset); entries.Add(new ReadyToRunImportSection.ImportSectionEntry(entries.Count, entryOffset, entryOffset + rva, section, sigRva, signature)); _importSignatures.Add(rva + entrySize * i, signature); } - int auxDataRVA = NativeReader.ReadInt32(Image, ref offset); + int auxDataRVA = ImageReader.ReadInt32(ref offset); int auxDataOffset = 0; if (auxDataRVA != 0) { @@ -1539,13 +1549,13 @@ private void GetRuntimeFunctionIndexFromOffset(int offset, out int runtimeFuncti // get the id of the entry point runtime function from the MethodEntryPoints NativeArray uint id = 0; // the RUNTIME_FUNCTIONS index - offset = (int)NativeReader.DecodeUnsigned(Image, (uint)offset, ref id); + offset = (int)ImageReader.DecodeUnsigned((uint)offset, ref id); if ((id & 1) != 0) { if ((id & 2) != 0) { uint val = 0; - NativeReader.DecodeUnsigned(Image, (uint)offset, ref val); + ImageReader.DecodeUnsigned((uint)offset, ref val); offset -= (int)val; } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/RiscV64/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/RiscV64/UnwindInfo.cs index 34411efe8e2ca7..34d14ca6ae04a1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/RiscV64/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/RiscV64/UnwindInfo.cs @@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { uint startOffset = (uint)offset; - int dw = NativeReader.ReadInt32(image, ref offset); + int dw = imageReader.ReadInt32(ref offset); CodeWords = ExtractBits(dw, 27, 5); EpilogCount = ExtractBits(dw, 22, 5); EBit = ExtractBits(dw, 21, 1); @@ -91,7 +91,7 @@ public UnwindInfo(byte[] image, int offset) { // We have an extension word specifying a larger number of Code Words or Epilog Counts // than can be specified in the header word. - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); ExtendedCodeWords = ExtractBits(dw, 16, 8); ExtendedEpilogCount = ExtractBits(dw, 0, 16); } @@ -105,7 +105,7 @@ public UnwindInfo(byte[] image, int offset) { for (int scope = 0; scope < EpilogCount; scope++) { - dw = NativeReader.ReadInt32(image, ref offset); + dw = imageReader.ReadInt32(ref offset); Epilogs[scope] = new Epilog(scope, dw, startOffset); epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs index 7b6f466c2f1a3b..d7e6f5a9cd7bd1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcInfo.cs @@ -21,30 +21,30 @@ public GcInfo() { } /// /// based on GCDump::DumpGCTable /// - public GcInfo(byte[] image, int offset) + public GcInfo(NativeReader imageReader, int offset) { Offset = offset; - CodeLength = (int)NativeReader.DecodeUnsignedGc(image, ref offset); + CodeLength = (int)imageReader.DecodeUnsignedGc(ref offset); - Header = InfoHdrDecoder.DecodeHeader(image, ref offset, CodeLength); + Header = InfoHdrDecoder.DecodeHeader(imageReader, ref offset, CodeLength); - NoGCRegions = new NoGcRegionTable(image, Header, ref offset); + NoGCRegions = new NoGcRegionTable(imageReader, Header, ref offset); - SlotTable = new GcSlotTable(image, Header, ref offset); + SlotTable = new GcSlotTable(imageReader, Header, ref offset); Transitions = new Dictionary>(); if (Header.Interruptible) { - GetTransitionsFullyInterruptible(image, ref offset); + GetTransitionsFullyInterruptible(imageReader, ref offset); } else if (Header.EbpFrame) { - GetTransitionsEbpFrame(image, ref offset); + GetTransitionsEbpFrame(imageReader, ref offset); } else { - GetTransitionsNoEbp(image, ref offset); + GetTransitionsNoEbp(imageReader, ref offset); } Size = offset - Offset; @@ -79,7 +79,7 @@ private void AddNewTransition(BaseGcTransition transition) Transitions[transition.CodeOffset].Add(transition); } - private void ArgEncoding(byte[] image, ref uint isPop, ref uint argOffs, ref uint argCnt, ref uint curOffs, ref bool isThis, ref bool iptr) + private void ArgEncoding(NativeReader imageReader, ref uint isPop, ref uint argOffs, ref uint argCnt, ref uint curOffs, ref bool isThis, ref bool iptr) { if (isPop != 0) { @@ -101,7 +101,7 @@ private void ArgEncoding(byte[] image, ref uint isPop, ref uint argOffs, ref uin /// /// based on GCDump::DumpGCTable /// - private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) + private void GetTransitionsFullyInterruptible(NativeReader imageReader, ref int offset) { uint argCnt = 0; bool isThis = false; @@ -112,7 +112,7 @@ private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) { uint isPop; uint argOffs; - uint val = image[offset++]; + uint val = imageReader.ReadByte(ref offset); if ((val & 0x80) == 0) { @@ -143,7 +143,7 @@ private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) curOffs += (val & 0x07); isPop = (val & 0x40); - ArgEncoding(image, ref isPop, ref argOffs, ref argCnt, ref curOffs, ref isThis, ref iptr); + ArgEncoding(imageReader, ref isPop, ref argOffs, ref argCnt, ref curOffs, ref isThis, ref iptr); continue; } @@ -177,21 +177,21 @@ private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) iptr = true; break; case 0xB8: - val = NativeReader.DecodeUnsignedGc(image, ref offset); + val = imageReader.DecodeUnsignedGc(ref offset); curOffs += val; break; case 0xF8: case 0xFC: isPop = val & 0x04; - argOffs = NativeReader.DecodeUnsignedGc(image, ref offset); - ArgEncoding(image, ref isPop, ref argOffs, ref argCnt, ref curOffs, ref isThis, ref iptr); + argOffs = imageReader.DecodeUnsignedGc(ref offset); + ArgEncoding(imageReader, ref isPop, ref argOffs, ref argCnt, ref curOffs, ref isThis, ref iptr); break; case 0xFD: - argOffs = NativeReader.DecodeUnsignedGc(image, ref offset); + argOffs = imageReader.DecodeUnsignedGc(ref offset); AddNewTransition(new GcTransitionPointer((int)curOffs, argOffs, argCnt, Action.KILL, Header.EbpFrame)); break; case 0xF9: - argOffs = NativeReader.DecodeUnsignedGc(image, ref offset); + argOffs = imageReader.DecodeUnsignedGc(ref offset); argCnt += argOffs; break; default: @@ -203,7 +203,7 @@ private void GetTransitionsFullyInterruptible(byte[] image, ref int offset) /// /// based on GCDump::DumpGCTable /// - private void GetTransitionsEbpFrame(byte[] image, ref int offset) + private void GetTransitionsEbpFrame(NativeReader imageReader, ref int offset) { while (true) { @@ -218,7 +218,7 @@ private void GetTransitionsEbpFrame(byte[] image, ref int offset) uint curOffs = 0; // Get the next byte and check for a 'special' entry - uint encType = image[offset++]; + uint encType = imageReader.ReadByte(ref offset); GcTransitionCall transition = null; switch (encType) @@ -259,50 +259,50 @@ private void GetTransitionsEbpFrame(byte[] image, ref int offset) { // A small call entry curOffs += (val & 0x7F); - val = image[offset++]; + val = imageReader.ReadByte(ref offset); regMask = val >> 5; argMask = val & 0x1F; } break; case 0xFD: // medium encoding - argMask = image[offset++]; - val = image[offset++]; + argMask = imageReader.ReadByte(ref offset); + val = imageReader.ReadByte(ref offset); argMask |= (val & 0xF0) << 4; - nxt = image[offset++]; + nxt = imageReader.ReadByte(ref offset); curOffs += (val & 0x0F) + ((nxt & 0x1F) << 4); regMask = nxt >> 5; // EBX,ESI,EDI break; case 0xF9: // medium encoding with byrefs - curOffs += image[offset++]; - val = image[offset++]; + curOffs += imageReader.ReadByte(ref offset); + val = imageReader.ReadByte(ref offset); argMask = val & 0x1F; regMask = val >> 5; - val = image[offset++]; + val = imageReader.ReadByte(ref offset); byrefArgMask = val & 0x1F; byrefRegMask = val >> 5; break; case 0xFE: // large encoding case 0xFA: // large encoding with byrefs - val = image[offset++]; + val = imageReader.ReadByte(ref offset); regMask = val & 0x7; byrefRegMask = val >> 4; - curOffs += NativeReader.ReadUInt32(image, ref offset); - argMask = NativeReader.ReadUInt32(image, ref offset); + curOffs += imageReader.ReadUInt32(ref offset); + argMask = imageReader.ReadUInt32(ref offset); if (encType == 0xFA) // read byrefArgMask { - byrefArgMask = NativeReader.ReadUInt32(image, ref offset); + byrefArgMask = imageReader.ReadUInt32(ref offset); } break; case 0xFB: // huge encoding - val = image[offset++]; + val = imageReader.ReadByte(ref offset); regMask = val & 0x7; byrefRegMask = val >> 4; - curOffs = NativeReader.ReadUInt32(image, ref offset); - argCnt = NativeReader.ReadUInt32(image, ref offset); - argTabSize = NativeReader.ReadUInt32(image, ref offset); + curOffs = imageReader.ReadUInt32(ref offset); + argCnt = imageReader.ReadUInt32(ref offset); + argTabSize = imageReader.ReadUInt32(ref offset); argOffset = offset; offset += (int)argTabSize; break; @@ -326,7 +326,7 @@ argMask ... bitmask of pushed pointer arguments { do { - val = NativeReader.DecodeUnsignedGc(image, ref argOffset); + val = imageReader.DecodeUnsignedGc(ref argOffset); uint stkOffs = val & ~byref_OFFSET_FLAG; uint lowBit = val & byref_OFFSET_FLAG; @@ -346,7 +346,7 @@ argMask ... bitmask of pushed pointer arguments /// /// based on GCDump::DumpGCTable /// - private void SaveCallTransition(byte[] image, ref int offset, uint val, uint curOffs, uint callRegMask, bool callPndTab, uint callPndTabCnt, uint callPndMask, uint lastSkip, ref uint imask) + private void SaveCallTransition(NativeReader imageReader, ref int offset, uint val, uint curOffs, uint callRegMask, bool callPndTab, uint callPndTabCnt, uint callPndMask, uint lastSkip, ref uint imask) { uint iregMask, iargMask; iregMask = imask & 0xF; @@ -359,7 +359,7 @@ private void SaveCallTransition(byte[] image, ref int offset, uint val, uint cur { for (int i = 0; i < callPndTabCnt; i++) { - uint pndOffs = NativeReader.DecodeUnsignedGc(image, ref offset); + uint pndOffs = imageReader.DecodeUnsignedGc(ref offset); uint stkOffs = val & ~byref_OFFSET_FLAG; uint lowBit = val & byref_OFFSET_FLAG; @@ -377,7 +377,7 @@ private void SaveCallTransition(byte[] image, ref int offset, uint val, uint cur imask = lastSkip = 0; } - private void GetTransitionsNoEbp(byte[] image, ref int offset) + private void GetTransitionsNoEbp(NativeReader imageReader, ref int offset) { uint curOffs = 0; uint lastSkip = 0; @@ -385,7 +385,7 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) for (; ; ) { - uint val = image[offset++]; + uint val = imageReader.ReadByte(ref offset); if ((val & 0x80) == 0) { @@ -400,7 +400,7 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) else { // push 00100000 [pushCount] ESP push multiple items - uint pushCount = NativeReader.DecodeUnsignedGc(image, ref offset); + uint pushCount = imageReader.DecodeUnsignedGc(ref offset); AddNewTransition(new GcTransitionRegister((int)curOffs, Registers.ESP, Action.PUSH, false, false, (int)pushCount)); } } @@ -414,7 +414,7 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) // // skip 01000000 [Delta] Skip arbitrary sized delta // - skip = NativeReader.DecodeUnsignedGc(image, ref offset); + skip = imageReader.DecodeUnsignedGc(ref offset); curOffs += skip; lastSkip = skip; } @@ -450,7 +450,7 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) // CallPattern.DecodeCallPattern((val & 0x7f), out callArgCnt, out callRegMask, out callPndMask, out lastSkip); curOffs += lastSkip; - SaveCallTransition(image, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); + SaveCallTransition(imageReader, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); break; case 5: @@ -459,12 +459,12 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) // ArgMask=MMM Delta=commonDelta[DD] // callRegMask = val & 0xf; // EBP,EBX,ESI,EDI - val = image[offset++]; + val = imageReader.ReadByte(ref offset); callPndMask = (val & 0x7); callArgCnt = (val >> 3) & 0x7; lastSkip = CallPattern.callCommonDelta[val >> 6]; curOffs += lastSkip; - SaveCallTransition(image, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); + SaveCallTransition(imageReader, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); break; case 6: // @@ -472,16 +472,16 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) // Call ArgCnt,RegMask=RRR,ArgMask // callRegMask = val & 0xf; // EBP,EBX,ESI,EDI - callArgCnt = NativeReader.DecodeUnsignedGc(image, ref offset); - callPndMask = NativeReader.DecodeUnsignedGc(image, ref offset); - SaveCallTransition(image, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); + callArgCnt = imageReader.DecodeUnsignedGc(ref offset); + callPndMask = imageReader.DecodeUnsignedGc(ref offset); + SaveCallTransition(imageReader, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); break; case 7: switch (val & 0x0C) { case 0x00: // iptr 11110000 [IPtrMask] Arbitrary Interior Pointer Mask - imask = NativeReader.DecodeUnsignedGc(image, ref offset); + imask = imageReader.DecodeUnsignedGc(ref offset); AddNewTransition(new IPtrMask((int)curOffs, imask)); break; @@ -490,16 +490,16 @@ private void GetTransitionsNoEbp(byte[] image, ref int offset) break; case 0x08: - val = image[offset++]; + val = imageReader.ReadByte(ref offset); callRegMask = val & 0xF; imask = val >> 4; - lastSkip = NativeReader.ReadUInt32(image, ref offset); + lastSkip = imageReader.ReadUInt32(ref offset); curOffs += lastSkip; - callArgCnt = NativeReader.ReadUInt32(image, ref offset); - callPndTabCnt = NativeReader.ReadUInt32(image, ref offset); - callPndTabSize = NativeReader.ReadUInt32(image, ref offset); + callArgCnt = imageReader.ReadUInt32(ref offset); + callPndTabCnt = imageReader.ReadUInt32(ref offset); + callPndTabSize = imageReader.ReadUInt32(ref offset); callPndTab = true; - SaveCallTransition(image, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); + SaveCallTransition(imageReader, ref offset, val, curOffs, callRegMask, callPndTab, callPndTabCnt, callPndMask, lastSkip, ref imask); break; case 0x0C: return; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs index 534780b671834f..b4cf2795031d57 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/GcSlotTable.cs @@ -98,12 +98,12 @@ public override string ToString() public GcSlotTable() { } - public GcSlotTable(byte[] image, InfoHdrSmall header, ref int offset) + public GcSlotTable(NativeReader imageReader, InfoHdrSmall header, ref int offset) { GcSlots = new List(); - DecodeUntracked(image, header, ref offset); - DecodeFrameVariableLifetimeTable(image, header, ref offset); + DecodeUntracked(imageReader, header, ref offset); + DecodeFrameVariableLifetimeTable(imageReader, header, ref offset); } public override string ToString() @@ -124,7 +124,7 @@ public override string ToString() /// /// based on GCDump::DumpGCTable /// - private void DecodeUntracked(byte[] image, InfoHdrSmall header, ref int offset) + private void DecodeUntracked(NativeReader imageReader, InfoHdrSmall header, ref int offset) { uint calleeSavedRegs = 0; if (header.DoubleAlign) @@ -144,7 +144,7 @@ private void DecodeUntracked(byte[] image, InfoHdrSmall header, ref int offset) char reg = header.EbpFrame ? 'B' : 'S'; - stkOffsDelta = NativeReader.DecodeSignedGc(image, ref offset); + stkOffsDelta = imageReader.DecodeSignedGc(ref offset); int stkOffs = lastStkOffs - stkOffsDelta; lastStkOffs = stkOffs; @@ -165,15 +165,15 @@ private void DecodeUntracked(byte[] image, InfoHdrSmall header, ref int offset) /// /// based on GCDump::DumpGCTable /// - private void DecodeFrameVariableLifetimeTable(byte[] image, InfoHdrSmall header, ref int offset) + private void DecodeFrameVariableLifetimeTable(NativeReader imageReader, InfoHdrSmall header, ref int offset) { uint count = header.VarPtrTableSize; uint curOffs = 0; while (count-- > 0) { - uint varOffs = NativeReader.DecodeUnsignedGc(image, ref offset); - uint begOffs = NativeReader.DecodeUDelta(image, ref offset, curOffs); - uint endOffs = NativeReader.DecodeUDelta(image, ref offset, begOffs); + uint varOffs = imageReader.DecodeUnsignedGc(ref offset); + uint begOffs = imageReader.DecodeUDelta(ref offset, curOffs); + uint endOffs = imageReader.DecodeUDelta(ref offset, begOffs); uint lowBits = varOffs & 0x3; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs index b18706b7661dc2..7f2a22465f4a0d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/InfoHdr.cs @@ -158,7 +158,8 @@ public override string ToString() } }; - public class InfoHdrDecoder { + public class InfoHdrDecoder + { private const uint HAS_VARPTR = 0xFFFFFFFF; private const uint HAS_UNTRACKED = 0xFFFFFFFF; @@ -181,14 +182,14 @@ public static InfoHdrSmall GetInfoHdr(byte encoding) /// Initialize the GcInfo header /// based on src\inc\gcdecoder.cpp DecodeHeader and GCDump::DumpInfoHdr /// - public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLength) + public static InfoHdrSmall DecodeHeader(NativeReader imageReader, ref int offset, int codeLength) { - byte nextByte = image[offset++]; + byte nextByte = imageReader.ReadByte(ref offset); byte encoding = (byte)(nextByte & 0x7f); InfoHdrSmall header = GetInfoHdr(encoding); while ((nextByte & (uint)InfoHdrAdjustConstants.MORE_BYTES_TO_FOLLOW) != 0) { - nextByte = image[offset++]; + nextByte = imageReader.ReadByte(ref offset); encoding = (byte)(nextByte & (uint)InfoHdrAdjustConstants.ADJ_ENCODING_MAX); if (encoding < (uint)InfoHdrAdjust.NEXT_FOUR_START) @@ -284,7 +285,7 @@ public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLe break; case (byte)InfoHdrAdjust.NEXT_OPCODE: - nextByte = image[offset++]; + nextByte = imageReader.ReadByte(ref offset); encoding = (byte)(nextByte & (int)InfoHdrAdjustConstants.ADJ_ENCODING_MAX); // encoding here always corresponds to codes in InfoHdrAdjust2 set if (encoding <= (int)InfoHdrAdjustConstants.SET_RET_KIND_MAX) @@ -347,29 +348,29 @@ public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLe if (header.UntrackedCnt == HAS_UNTRACKED) { header.HasArgTabOffset = true; - header.UntrackedCnt = NativeReader.DecodeUnsignedGc(image, ref offset); + header.UntrackedCnt = imageReader.DecodeUnsignedGc(ref offset); } if (header.VarPtrTableSize == HAS_VARPTR) { header.HasArgTabOffset = true; - header.VarPtrTableSize = NativeReader.DecodeUnsignedGc(image, ref offset); + header.VarPtrTableSize = imageReader.DecodeUnsignedGc(ref offset); } if (header.GsCookieOffset == HAS_GS_COOKIE_OFFSET) { - header.GsCookieOffset = NativeReader.DecodeUnsignedGc(image, ref offset); + header.GsCookieOffset = imageReader.DecodeUnsignedGc(ref offset); } if (header.SyncStartOffset == HAS_SYNC_OFFSET) { - header.SyncStartOffset = NativeReader.DecodeUnsignedGc(image, ref offset); - header.SyncEndOffset = NativeReader.DecodeUnsignedGc(image, ref offset); + header.SyncStartOffset = imageReader.DecodeUnsignedGc(ref offset); + header.SyncEndOffset = imageReader.DecodeUnsignedGc(ref offset); } if (header.RevPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET) { - header.RevPInvokeOffset = NativeReader.DecodeUnsignedGc(image, ref offset); + header.RevPInvokeOffset = imageReader.DecodeUnsignedGc(ref offset); } if (header.NoGCRegionCnt == HAS_NOGCREGIONS) { - header.NoGCRegionCnt = NativeReader.DecodeUnsignedGc(image, ref offset); + header.NoGCRegionCnt = imageReader.DecodeUnsignedGc(ref offset); } header.Epilogs = new List(); @@ -379,7 +380,7 @@ public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLe for (int i = 0; i < header.EpilogCount; i++) { - offs = NativeReader.DecodeUDelta(image, ref offset, offs); + offs = imageReader.DecodeUDelta(ref offset, offs); header.Epilogs.Add((int)offs); } } @@ -391,7 +392,7 @@ public static InfoHdrSmall DecodeHeader(byte[] image, ref int offset, int codeLe if (header.HasArgTabOffset) { - header.ArgTabOffset = NativeReader.DecodeUnsignedGc(image, ref offset); + header.ArgTabOffset = imageReader.DecodeUnsignedGc(ref offset); } return header; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/NoGcRegionTable.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/NoGcRegionTable.cs index 4dcc332cb7ce73..96123c94a69d39 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/NoGcRegionTable.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/NoGcRegionTable.cs @@ -23,7 +23,7 @@ public NoGcRegion(uint offset, uint size) public override string ToString() { - return $" [{Offset:04X}-{Offset+Size:04X})\n"; + return $" [{Offset:04X}-{Offset + Size:04X})\n"; } } @@ -31,15 +31,15 @@ public override string ToString() public NoGcRegionTable() { } - public NoGcRegionTable(byte[] image, InfoHdrSmall header, ref int offset) + public NoGcRegionTable(NativeReader imageReader, InfoHdrSmall header, ref int offset) { Regions = new List((int)header.NoGCRegionCnt); uint count = header.NoGCRegionCnt; while (count-- > 0) { - uint regionOffset = NativeReader.DecodeUnsignedGc(image, ref offset); - uint regionSize = NativeReader.DecodeUnsignedGc(image, ref offset); + uint regionOffset = imageReader.DecodeUnsignedGc(ref offset); + uint regionSize = imageReader.DecodeUnsignedGc(ref offset); Regions.Add(new NoGcRegion(regionOffset, regionSize)); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs index 6c699eec54bc14..8f5d1245026796 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/x86/UnwindInfo.cs @@ -14,10 +14,10 @@ public class UnwindInfo : BaseUnwindInfo public UnwindInfo() { } - public UnwindInfo(byte[] image, int offset) + public UnwindInfo(NativeReader imageReader, int offset) { int startOffset = offset; - FunctionLength = NativeReader.DecodeUnsignedGc(image, ref offset); + FunctionLength = imageReader.DecodeUnsignedGc(ref offset); Size = offset - startOffset; } diff --git a/src/coreclr/tools/r2rdump/TextDumper.cs b/src/coreclr/tools/r2rdump/TextDumper.cs index 9f2c462ddaa347..60cd0fb09ba35d 100644 --- a/src/coreclr/tools/r2rdump/TextDumper.cs +++ b/src/coreclr/tools/r2rdump/TextDumper.cs @@ -346,8 +346,8 @@ public override void DumpSectionContents(ReadyToRunSection section) if (!_model.Naked) { uint availableTypesSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); - NativeParser availableTypesParser = new NativeParser(_r2r.Image, availableTypesSectionOffset); - NativeHashtable availableTypes = new NativeHashtable(_r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size)); + NativeParser availableTypesParser = new NativeParser(_r2r.ImageReader, availableTypesSectionOffset); + NativeHashtable availableTypes = new NativeHashtable(_r2r.ImageReader, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size)); _writer.WriteLine(availableTypes.ToString()); } @@ -364,7 +364,7 @@ public override void DumpSectionContents(ReadyToRunSection section) case ReadyToRunSectionType.MethodDefEntryPoints: if (!_model.Naked) { - NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress)); + NativeArray methodEntryPoints = new NativeArray(_r2r.ImageReader, (uint)_r2r.GetOffset(section.RelativeVirtualAddress)); _writer.Write(methodEntryPoints.ToString()); } @@ -382,8 +382,8 @@ public override void DumpSectionContents(ReadyToRunSection section) if (!_model.Naked) { uint instanceSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress); - NativeParser instanceParser = new NativeParser(_r2r.Image, instanceSectionOffset); - NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size)); + NativeParser instanceParser = new NativeParser(_r2r.ImageReader, instanceSectionOffset); + NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.ImageReader, instanceParser, (uint)(instanceSectionOffset + section.Size)); _writer.Write(instMethodEntryPoints.ToString()); _writer.WriteLine(); } @@ -400,13 +400,13 @@ public override void DumpSectionContents(ReadyToRunSection section) _writer.WriteLine("-----------------------------------------"); while (rtfOffset < rtfEndOffset) { - int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); + int startRva = _r2r.ImageReader.ReadInt32(ref rtfOffset); int endRva = -1; if (_r2r.Machine == Machine.Amd64) { - endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); + endRva = _r2r.ImageReader.ReadInt32(ref rtfOffset); } - int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset); + int unwindRva = _r2r.ImageReader.ReadInt32(ref rtfOffset); string endRvaText = (endRva != -1 ? endRva.ToString("x8") : " "); _writer.WriteLine($"{rtfIndex,7} | {startRva:X8} | {endRvaText} | {unwindRva:X8}"); rtfIndex++; @@ -488,7 +488,7 @@ public override void DumpSectionContents(ReadyToRunSection section) case ReadyToRunSectionType.AttributePresence: int attributesStartOffset = _r2r.GetOffset(section.RelativeVirtualAddress); int attributesEndOffset = attributesStartOffset + section.Size; - NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.Image, attributesStartOffset, attributesEndOffset); + NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.ImageReader, attributesStartOffset, attributesEndOffset); _writer.WriteLine("Attribute presence filter"); _writer.WriteLine(attributes.ToString()); break; @@ -524,80 +524,80 @@ public override void DumpSectionContents(ReadyToRunSection section) int hotColdMapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); for (int i = 0; i < count; i++) { - _writer.Write(NativeReader.ReadInt32(_r2r.Image, ref hotColdMapOffset)); + _writer.Write(_r2r.ImageReader.ReadInt32(ref hotColdMapOffset)); _writer.Write(","); - _writer.WriteLine(NativeReader.ReadInt32(_r2r.Image, ref hotColdMapOffset)); + _writer.WriteLine(_r2r.ImageReader.ReadInt32(ref hotColdMapOffset)); } break; case ReadyToRunSectionType.MethodIsGenericMap: + { + int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); + int mapDone = section.Size + mapOffset; + int countMethods = _r2r.ImageReader.ReadInt32(ref mapOffset); + int curMethod = 1; + while ((curMethod <= countMethods) && mapDone > mapOffset) { - int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); - int mapDone = section.Size + mapOffset; - int countMethods = NativeReader.ReadInt32(_r2r.Image, ref mapOffset); - int curMethod = 1; - while ((curMethod <= countMethods) && mapDone > mapOffset) - { - byte curByte = NativeReader.ReadByte(_r2r.Image, ref mapOffset); - for (int i = 0; i < 8 && (curMethod <= countMethods); i++) - { - bool isGeneric = (curByte & 0x80) == 0x80; - _writer.WriteLine($"{curMethod | 0x06000000:x8} : {isGeneric}"); - curByte <<= 1; - curMethod++; - } - } - if (curMethod != (countMethods + 1)) + byte curByte = _r2r.ImageReader.ReadByte(ref mapOffset); + for (int i = 0; i < 8 && (curMethod <= countMethods); i++) { - Program.WriteWarning("MethodIsGenericMap malformed"); - System.Diagnostics.Debug.Fail("MethodIsGenericMap malformed"); + bool isGeneric = (curByte & 0x80) == 0x80; + _writer.WriteLine($"{curMethod | 0x06000000:x8} : {isGeneric}"); + curByte <<= 1; + curMethod++; } - break; } + if (curMethod != (countMethods + 1)) + { + Program.WriteWarning("MethodIsGenericMap malformed"); + System.Diagnostics.Debug.Fail("MethodIsGenericMap malformed"); + } + break; + } case ReadyToRunSectionType.EnclosingTypeMap: + { + int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); + int mapDone = section.Size + mapOffset; + uint countTypes = checked((uint)((section.Size / 2 - 1))); // 2 bytes per nested type. This data structure is only used for IL images where there are <= 0xFFFE types. + if (countTypes != _r2r.ImageReader.ReadUInt16(ref mapOffset)) { - int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); - int mapDone = section.Size + mapOffset; - uint countTypes = checked((uint)((section.Size / 2 - 1))); // 2 bytes per nested type. This data structure is only used for IL images where there are <= 0xFFFE types. - if (countTypes != NativeReader.ReadUInt16(_r2r.Image, ref mapOffset)) - { - Program.WriteWarning("EnclosingTypeMap malformed"); - System.Diagnostics.Debug.Fail("EnclosingTypeMap malformed"); - } - int curType = 1; - while (curType <= (countTypes + 1)) - { - _writer.WriteLine($"{curType | 0x02000000:x8} : {NativeReader.ReadUInt16(_r2r.Image, ref mapOffset) | 0x02000000:x8}"); - curType++; - } - break; + Program.WriteWarning("EnclosingTypeMap malformed"); + System.Diagnostics.Debug.Fail("EnclosingTypeMap malformed"); } + int curType = 1; + while (curType <= (countTypes + 1)) + { + _writer.WriteLine($"{curType | 0x02000000:x8} : {_r2r.ImageReader.ReadUInt16(ref mapOffset) | 0x02000000:x8}"); + curType++; + } + break; + } case ReadyToRunSectionType.TypeGenericInfoMap: + { + int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); + int mapDone = section.Size + mapOffset; + int countTypes = _r2r.ImageReader.ReadInt32(ref mapOffset); + int curType = 1; + while ((curType <= countTypes) && mapDone > mapOffset) { - int mapOffset = _r2r.GetOffset(section.RelativeVirtualAddress); - int mapDone = section.Size + mapOffset; - int countTypes = NativeReader.ReadInt32(_r2r.Image, ref mapOffset); - int curType = 1; - while ((curType <= countTypes) && mapDone > mapOffset) + byte curByte = _r2r.ImageReader.ReadByte(ref mapOffset); + for (int i = 0; i < 2 && (curType <= countTypes); i++) { - byte curByte = NativeReader.ReadByte(_r2r.Image, ref mapOffset); - for (int i = 0; i < 2 && (curType <= countTypes); i++) - { - var genericInfo = (ReadyToRunTypeGenericInfo)((curByte & 0xF0) >> 4); - bool hasConstraints = genericInfo.HasFlag(ReadyToRunTypeGenericInfo.HasConstraints); - bool hasVariance = genericInfo.HasFlag(ReadyToRunTypeGenericInfo.HasVariance); - var genericCount = (ReadyToRunGenericInfoGenericCount)(genericInfo & ReadyToRunTypeGenericInfo.GenericCountMask); - _writer.WriteLine($"{curType | 0x06000000:x8} : GenericArgumentCount: {genericCount} HasVariance {hasVariance} HasConstraints {hasConstraints}"); - curByte <<= 4; - curType++; - } - } - if (curType != (countTypes + 1)) - { - Program.WriteWarning("TypeGenericInfoMap malformed"); - System.Diagnostics.Debug.Fail("TypeGenericInfoMap malformed"); + var genericInfo = (ReadyToRunTypeGenericInfo)((curByte & 0xF0) >> 4); + bool hasConstraints = genericInfo.HasFlag(ReadyToRunTypeGenericInfo.HasConstraints); + bool hasVariance = genericInfo.HasFlag(ReadyToRunTypeGenericInfo.HasVariance); + var genericCount = (ReadyToRunGenericInfoGenericCount)(genericInfo & ReadyToRunTypeGenericInfo.GenericCountMask); + _writer.WriteLine($"{curType | 0x06000000:x8} : GenericArgumentCount: {genericCount} HasVariance {hasVariance} HasConstraints {hasConstraints}"); + curByte <<= 4; + curType++; } - break; } + if (curType != (countTypes + 1)) + { + Program.WriteWarning("TypeGenericInfoMap malformed"); + System.Diagnostics.Debug.Fail("TypeGenericInfoMap malformed"); + } + break; + } default: _writer.WriteLine("Unsupported section type {0}", section.Type); @@ -619,7 +619,8 @@ public override void DumpFixupStats() var sortedFixupCounts = _r2r.Methods.Where(m => m.Fixups != null) .SelectMany(m => m.Fixups) .GroupBy(f => f.Signature.FixupKind) - .Select(group => new { + .Select(group => new + { FixupKind = group.Key, Count = group.Count() }).OrderByDescending(x => x.Count);