Skip to content

Commit 56ae94c

Browse files
authored
ILCompiler.Reflection.ReadyToRun encapsulate image state (#117446)
* Wrap byte[] using NativeReader * update R2RDump to use new primitives
1 parent 4031c97 commit 56ae94c

25 files changed

+558
-539
lines changed

src/coreclr/.nuget/ILCompiler.Reflection.ReadyToRun.Experimental/ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212

1313
<ItemGroup>
1414
<PackageFile Include="$(RuntimeBinDir)ILCompiler.Reflection.ReadyToRun.dll">
15-
<TargetPath>\lib\netstandard2.0\</TargetPath>
15+
<TargetPath>\lib\$(NetCoreAppMinimum)\</TargetPath>
1616
</PackageFile>
1717
<Dependency Include="System.Reflection.Metadata">
1818
<Version>$(SystemReflectionMetadataVersion)</Version>
19-
<TargetFramework>netstandard2.0</TargetFramework>
19+
<TargetFramework>$(NetCoreAppMinimum)</TargetFramework>
2020
<Exclude>Build,Analyzers</Exclude>
2121
</Dependency>
2222
</ItemGroup>

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs

Lines changed: 63 additions & 63 deletions
Large diffs are not rendered by default.

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -104,33 +104,33 @@ public GcSlotTable() { }
104104
/// <summary>
105105
/// based on <a href="https://github.com/dotnet/runtime/blob/main/src/coreclr/vm/gcinfodecoder.cpp">GcSlotDecoder::DecodeSlotTable</a>
106106
/// </summary>
107-
public GcSlotTable(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, ref int bitOffset)
107+
public GcSlotTable(NativeReader imageReader, Machine machine, GcInfoTypes gcInfoTypes, ref int bitOffset)
108108
{
109109
_machine = machine;
110110

111-
if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0)
111+
if (imageReader.ReadBits(1, ref bitOffset) != 0)
112112
{
113-
NumRegisters = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_REGISTERS_ENCBASE, ref bitOffset);
113+
NumRegisters = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_REGISTERS_ENCBASE, ref bitOffset);
114114
}
115-
if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0)
115+
if (imageReader.ReadBits(1, ref bitOffset) != 0)
116116
{
117-
NumStackSlots = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_STACK_SLOTS_ENCBASE, ref bitOffset);
118-
NumUntracked = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_UNTRACKED_SLOTS_ENCBASE, ref bitOffset);
117+
NumStackSlots = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_STACK_SLOTS_ENCBASE, ref bitOffset);
118+
NumUntracked = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.NUM_UNTRACKED_SLOTS_ENCBASE, ref bitOffset);
119119
}
120120
NumSlots = NumRegisters + NumStackSlots + NumUntracked;
121121

122122
GcSlots = new List<GcSlot>();
123123
if (NumRegisters > 0)
124124
{
125-
DecodeRegisters(image, gcInfoTypes, ref bitOffset);
125+
DecodeRegisters(imageReader, gcInfoTypes, ref bitOffset);
126126
}
127127
if (NumStackSlots > 0)
128128
{
129-
DecodeStackSlots(image, machine, gcInfoTypes, NumStackSlots, false, ref bitOffset);
129+
DecodeStackSlots(imageReader, machine, gcInfoTypes, NumStackSlots, false, ref bitOffset);
130130
}
131131
if (NumUntracked > 0)
132132
{
133-
DecodeStackSlots(image, machine, gcInfoTypes, NumUntracked, true, ref bitOffset);
133+
DecodeStackSlots(imageReader, machine, gcInfoTypes, NumUntracked, true, ref bitOffset);
134134
}
135135
}
136136

@@ -150,50 +150,50 @@ public override string ToString()
150150
return sb.ToString();
151151
}
152152

153-
private void DecodeRegisters(byte[] image, GcInfoTypes gcInfoTypes, ref int bitOffset)
153+
private void DecodeRegisters(NativeReader imageReader, GcInfoTypes gcInfoTypes, ref int bitOffset)
154154
{
155155
// We certainly predecode the first register
156-
uint regNum = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_ENCBASE, ref bitOffset);
157-
GcSlotFlags flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset);
156+
uint regNum = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_ENCBASE, ref bitOffset);
157+
GcSlotFlags flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset);
158158
GcSlots.Add(new GcSlot(GcSlots.Count, (int)regNum, null, flags));
159159

160160
for (int i = 1; i < NumRegisters; i++)
161161
{
162162
if ((uint)flags != 0)
163163
{
164-
regNum = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_ENCBASE, ref bitOffset);
165-
flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset);
164+
regNum = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_ENCBASE, ref bitOffset);
165+
flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset);
166166
}
167167
else
168168
{
169-
uint regDelta = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.REGISTER_DELTA_ENCBASE, ref bitOffset) + 1;
169+
uint regDelta = imageReader.DecodeVarLengthUnsigned(gcInfoTypes.REGISTER_DELTA_ENCBASE, ref bitOffset) + 1;
170170
regNum += regDelta;
171171
}
172172
GcSlots.Add(new GcSlot(GcSlots.Count, (int)regNum, null, flags));
173173
}
174174
}
175175

176-
private void DecodeStackSlots(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, uint nSlots, bool isUntracked, ref int bitOffset)
176+
private void DecodeStackSlots(NativeReader imageReader, Machine machine, GcInfoTypes gcInfoTypes, uint nSlots, bool isUntracked, ref int bitOffset)
177177
{
178178
// We have stack slots left and more room to predecode
179-
GcStackSlotBase spBase = (GcStackSlotBase)NativeReader.ReadBits(image, 2, ref bitOffset);
180-
int normSpOffset = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset);
179+
GcStackSlotBase spBase = (GcStackSlotBase)imageReader.ReadBits(2, ref bitOffset);
180+
int normSpOffset = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset);
181181
int spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset);
182-
GcSlotFlags flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset);
182+
GcSlotFlags flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset);
183183
GcSlots.Add(new GcSlot(GcSlots.Count, -1, new GcStackSlot(spOffset, spBase), flags, isUntracked));
184184

185185
for (int i = 1; i < nSlots; i++)
186186
{
187-
spBase = (GcStackSlotBase)NativeReader.ReadBits(image, 2, ref bitOffset);
187+
spBase = (GcStackSlotBase)imageReader.ReadBits(2, ref bitOffset);
188188
if ((uint)flags != 0)
189189
{
190-
normSpOffset = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset);
190+
normSpOffset = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset);
191191
spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset);
192-
flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset);
192+
flags = (GcSlotFlags)imageReader.ReadBits(2, ref bitOffset);
193193
}
194194
else
195195
{
196-
int normSpOffsetDelta = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_DELTA_ENCBASE, ref bitOffset);
196+
int normSpOffsetDelta = imageReader.DecodeVarLengthSigned(gcInfoTypes.STACK_SLOT_DELTA_ENCBASE, ref bitOffset);
197197
normSpOffset += normSpOffsetDelta;
198198
spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset);
199199
}

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ public UnwindCode() { }
6161
/// <summary>
6262
/// Unwind code parsing is based on <a href="https://github.com/dotnet/runtime/blob/main/src/coreclr/jit/unwindamd64.cpp">src\jit\unwindamd64.cpp</a> DumpUnwindInfo
6363
/// </summary>
64-
public UnwindCode(byte[] image, ref int frameOffset, ref int offset)
64+
public UnwindCode(NativeReader imageReader, ref int frameOffset, ref int offset)
6565
{
66-
CodeOffset = NativeReader.ReadByte(image, ref offset);
67-
byte op = NativeReader.ReadByte(image, ref offset);
66+
CodeOffset = imageReader.ReadByte(ref offset);
67+
byte op = imageReader.ReadByte(ref offset);
6868
UnwindOp = (UnwindOpCodes)(op & 15);
6969
OpInfo = (byte)(op >> 4);
7070

@@ -83,13 +83,13 @@ public UnwindCode(byte[] image, ref int frameOffset, ref int offset)
8383
if (OpInfo == 0)
8484
{
8585
OpInfoStr += "Scaled small";
86-
NextFrameOffset = 8 * NativeReader.ReadUInt16(image, ref offset);
86+
NextFrameOffset = 8 * imageReader.ReadUInt16(ref offset);
8787
}
8888
else if (OpInfo == 1)
8989
{
9090
OpInfoStr += "Unscaled large";
91-
uint nextOffset = NativeReader.ReadUInt16(image, ref offset);
92-
NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset);
91+
uint nextOffset = imageReader.ReadUInt16(ref offset);
92+
NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset);
9393
}
9494
else
9595
{
@@ -104,43 +104,43 @@ public UnwindCode(byte[] image, ref int frameOffset, ref int offset)
104104
OpInfoStr = $"Unused({OpInfo})";
105105
break;
106106
case UnwindOpCodes.UWOP_SET_FPREG_LARGE:
107+
{
108+
OpInfoStr = $"Unused({OpInfo})";
109+
uint nextOffset = imageReader.ReadUInt16(ref offset);
110+
nextOffset = ((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset);
111+
NextFrameOffset = (int)nextOffset * 16;
112+
if ((NextFrameOffset & 0xF0000000) != 0)
107113
{
108-
OpInfoStr = $"Unused({OpInfo})";
109-
uint nextOffset = NativeReader.ReadUInt16(image, ref offset);
110-
nextOffset = ((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset);
111-
NextFrameOffset = (int)nextOffset * 16;
112-
if ((NextFrameOffset & 0xF0000000) != 0)
113-
{
114-
throw new BadImageFormatException("Warning: Illegal unwindInfo unscaled offset: too large");
115-
}
114+
throw new BadImageFormatException("Warning: Illegal unwindInfo unscaled offset: too large");
116115
}
117-
break;
116+
}
117+
break;
118118
case UnwindOpCodes.UWOP_SAVE_NONVOL:
119-
{
120-
OpInfoStr = $"{(Registers)OpInfo}({OpInfo})";
121-
NextFrameOffset = NativeReader.ReadUInt16(image, ref offset) * 8;
122-
}
123-
break;
119+
{
120+
OpInfoStr = $"{(Registers)OpInfo}({OpInfo})";
121+
NextFrameOffset = imageReader.ReadUInt16(ref offset) * 8;
122+
}
123+
break;
124124
case UnwindOpCodes.UWOP_SAVE_NONVOL_FAR:
125-
{
126-
OpInfoStr = $"{(Registers)OpInfo}({OpInfo})";
127-
uint nextOffset = NativeReader.ReadUInt16(image, ref offset);
128-
NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset);
129-
}
130-
break;
125+
{
126+
OpInfoStr = $"{(Registers)OpInfo}({OpInfo})";
127+
uint nextOffset = imageReader.ReadUInt16(ref offset);
128+
NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset);
129+
}
130+
break;
131131
case UnwindOpCodes.UWOP_SAVE_XMM128:
132-
{
133-
OpInfoStr = $"XMM{OpInfo}({OpInfo})";
134-
NextFrameOffset = (int)NativeReader.ReadUInt16(image, ref offset) * 16;
135-
}
136-
break;
132+
{
133+
OpInfoStr = $"XMM{OpInfo}({OpInfo})";
134+
NextFrameOffset = (int)imageReader.ReadUInt16(ref offset) * 16;
135+
}
136+
break;
137137
case UnwindOpCodes.UWOP_SAVE_XMM128_FAR:
138-
{
139-
OpInfoStr = $"XMM{OpInfo}({OpInfo})";
140-
uint nextOffset = NativeReader.ReadUInt16(image, ref offset);
141-
NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset);
142-
}
143-
break;
138+
{
139+
OpInfoStr = $"XMM{OpInfo}({OpInfo})";
140+
uint nextOffset = imageReader.ReadUInt16(ref offset);
141+
NextFrameOffset = (int)((uint)(imageReader.ReadUInt16(ref offset) << 16) | nextOffset);
142+
}
143+
break;
144144
default:
145145
throw new NotImplementedException(UnwindOp.ToString());
146146
}
@@ -172,14 +172,14 @@ public UnwindInfo() { }
172172
/// <summary>
173173
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapcode.cpp">ZapUnwindData::Save</a>
174174
/// </summary>
175-
public UnwindInfo(byte[] image, int offset)
175+
public UnwindInfo(NativeReader imageReader, int offset)
176176
{
177-
byte versionAndFlags = NativeReader.ReadByte(image, ref offset);
177+
byte versionAndFlags = imageReader.ReadByte(ref offset);
178178
Version = (byte)(versionAndFlags & 7);
179179
Flags = (byte)(versionAndFlags >> 3);
180-
SizeOfProlog = NativeReader.ReadByte(image, ref offset);
181-
CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset);
182-
byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset);
180+
SizeOfProlog = imageReader.ReadByte(ref offset);
181+
CountOfUnwindCodes = imageReader.ReadByte(ref offset);
182+
byte frameRegisterAndOffset = imageReader.ReadByte(ref offset);
183183
FrameRegister = (Registers)(frameRegisterAndOffset & 15);
184184
FrameOffset = (byte)(frameRegisterAndOffset >> 4);
185185

@@ -190,7 +190,7 @@ public UnwindInfo(byte[] image, int offset)
190190
int endOffset = offset + sizeOfUnwindCodes;
191191
while (offset < endOffset)
192192
{
193-
UnwindCode unwindCode = new UnwindCode(image, ref frameOffset, ref offset);
193+
UnwindCode unwindCode = new UnwindCode(imageReader, ref frameOffset, ref offset);
194194
CodeOffsetToUnwindCodeIndex.Add(unwindCode.CodeOffset, UnwindCodes.Count);
195195
UnwindCodes.Add(unwindCode);
196196
}
@@ -201,7 +201,7 @@ public UnwindInfo(byte[] image, int offset)
201201

202202
// Personality routine RVA must be at 4-aligned address
203203
offset += alignmentPad;
204-
PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset);
204+
PersonalityRoutineRVA = imageReader.ReadUInt32(ref offset);
205205
}
206206

207207
public override string ToString()

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm/UnwindInfo.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo
7575

7676
public UnwindInfo() { }
7777

78-
public UnwindInfo(byte[] image, int offset)
78+
public UnwindInfo(NativeReader imageReader, int offset)
7979
{
8080
uint startOffset = (uint)offset;
8181

82-
int dw = NativeReader.ReadInt32(image, ref offset);
82+
int dw = imageReader.ReadInt32(ref offset);
8383
CodeWords = ExtractBits(dw, 28, 4);
8484
EpilogCount = ExtractBits(dw, 23, 5);
8585
FBit = ExtractBits(dw, 22, 1);
@@ -92,7 +92,7 @@ public UnwindInfo(byte[] image, int offset)
9292
{
9393
// We have an extension word specifying a larger number of Code Words or Epilog Counts
9494
// than can be specified in the header word.
95-
dw = NativeReader.ReadInt32(image, ref offset);
95+
dw = imageReader.ReadInt32(ref offset);
9696
ExtendedCodeWords = ExtractBits(dw, 16, 8);
9797
ExtendedEpilogCount = ExtractBits(dw, 0, 16);
9898
}
@@ -106,7 +106,7 @@ public UnwindInfo(byte[] image, int offset)
106106
{
107107
for (int scope = 0; scope < EpilogCount; scope++)
108108
{
109-
dw = NativeReader.ReadInt32(image, ref offset);
109+
dw = imageReader.ReadInt32(ref offset);
110110
Epilogs[scope] = new Epilog(scope, dw, startOffset);
111111
epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes
112112
}

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Arm64/UnwindInfo.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ public class UnwindInfo : BaseUnwindInfo
7575

7676
public UnwindInfo() { }
7777

78-
public UnwindInfo(byte[] image, int offset)
78+
public UnwindInfo(NativeReader imageReader, int offset)
7979
{
8080
uint startOffset = (uint)offset;
8181

82-
int dw = NativeReader.ReadInt32(image, ref offset);
82+
int dw = imageReader.ReadInt32(ref offset);
8383
CodeWords = ExtractBits(dw, 27, 5);
8484
EpilogCount = ExtractBits(dw, 22, 5);
8585
EBit = ExtractBits(dw, 21, 1);
@@ -91,7 +91,7 @@ public UnwindInfo(byte[] image, int offset)
9191
{
9292
// We have an extension word specifying a larger number of Code Words or Epilog Counts
9393
// than can be specified in the header word.
94-
dw = NativeReader.ReadInt32(image, ref offset);
94+
dw = imageReader.ReadInt32(ref offset);
9595
ExtendedCodeWords = ExtractBits(dw, 16, 8);
9696
ExtendedEpilogCount = ExtractBits(dw, 0, 16);
9797
}
@@ -105,7 +105,7 @@ public UnwindInfo(byte[] image, int offset)
105105
{
106106
for (int scope = 0; scope < EpilogCount; scope++)
107107
{
108-
dw = NativeReader.ReadInt32(image, ref offset);
108+
dw = imageReader.ReadInt32(ref offset);
109109
Epilogs[scope] = new Epilog(scope, dw, startOffset);
110110
epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes
111111
}

0 commit comments

Comments
 (0)