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);