@@ -141,45 +141,63 @@ public void Feed(Arm64Instruction instruction)
141
141
142
142
internal class Arm64Disassembler : ClrMdV2Disassembler
143
143
{
144
- // See dotnet/runtime src/coreclr/vm/arm64/thunktemplates.asm/.S for the stub code
145
- // ldr x9, DATA_SLOT(CallCountingStub, RemainingCallCountCell)
146
- // ldrh w10, [x9]
147
- // subs w10, w10, #0x1
148
- private static byte [ ] callCountingStubTemplate = new byte [ 12 ] { 0x09 , 0x00 , 0x00 , 0x58 , 0x2a , 0x01 , 0x40 , 0x79 , 0x4a , 0x05 , 0x00 , 0x71 } ;
149
- // ldr x10, DATA_SLOT(StubPrecode, Target)
150
- // ldr x12, DATA_SLOT(StubPrecode, MethodDesc)
151
- // br x10
152
- private static byte [ ] stubPrecodeTemplate = new byte [ 12 ] { 0x4a , 0x00 , 0x00 , 0x58 , 0xec , 0x00 , 0x00 , 0x58 , 0x40 , 0x01 , 0x1f , 0xd6 } ;
153
- // ldr x11, DATA_SLOT(FixupPrecode, Target)
154
- // br x11
155
- // ldr x12, DATA_SLOT(FixupPrecode, MethodDesc)
156
- private static byte [ ] fixupPrecodeTemplate = new byte [ 12 ] { 0x0b , 0x00 , 0x00 , 0x58 , 0x60 , 0x01 , 0x1f , 0xd6 , 0x0c , 0x00 , 0x00 , 0x58 } ;
157
-
158
- static Arm64Disassembler ( )
144
+ internal sealed class RuntimeSpecificData
159
145
{
160
- // The stubs code depends on the current OS memory page size, so we need to update the templates to reflect that
161
- int pageSizeShifted = Environment . SystemPageSize / 32 ;
162
- // Calculate the ldr x9, #offset instruction with offset based on the page size
163
- callCountingStubTemplate [ 1 ] = ( byte ) ( pageSizeShifted & 0xff ) ;
164
- callCountingStubTemplate [ 2 ] = ( byte ) ( pageSizeShifted >> 8 ) ;
146
+ // See dotnet/runtime src/coreclr/vm/arm64/thunktemplates.asm/.S for the stub code
147
+ // ldr x9, DATA_SLOT(CallCountingStub, RemainingCallCountCell)
148
+ // ldrh w10, [x9]
149
+ // subs w10, w10, #0x1
150
+ internal readonly byte [ ] callCountingStubTemplate = new byte [ 12 ] { 0x09 , 0x00 , 0x00 , 0x58 , 0x2a , 0x01 , 0x40 , 0x79 , 0x4a , 0x05 , 0x00 , 0x71 } ;
151
+ // ldr x10, DATA_SLOT(StubPrecode, Target)
152
+ // ldr x12, DATA_SLOT(StubPrecode, MethodDesc)
153
+ // br x10
154
+ internal readonly byte [ ] stubPrecodeTemplate = new byte [ 12 ] { 0x4a , 0x00 , 0x00 , 0x58 , 0xec , 0x00 , 0x00 , 0x58 , 0x40 , 0x01 , 0x1f , 0xd6 } ;
155
+ // ldr x11, DATA_SLOT(FixupPrecode, Target)
156
+ // br x11
157
+ // ldr x12, DATA_SLOT(FixupPrecode, MethodDesc)
158
+ internal readonly byte [ ] fixupPrecodeTemplate = new byte [ 12 ] { 0x0b , 0x00 , 0x00 , 0x58 , 0x60 , 0x01 , 0x1f , 0xd6 , 0x0c , 0x00 , 0x00 , 0x58 } ;
159
+ internal readonly ulong stubPageSize ;
160
+
161
+ internal RuntimeSpecificData ( State state )
162
+ {
163
+ stubPageSize = ( ulong ) Environment . SystemPageSize ;
164
+ if ( state . RuntimeVersion . Major >= 8 )
165
+ {
166
+ // In .NET 8, the stub page size was changed to min 16kB
167
+ stubPageSize = Math . Max ( stubPageSize , 16384 ) ;
168
+ }
169
+
170
+ // The stubs code depends on the current OS memory page size, so we need to update the templates to reflect that
171
+ ulong pageSizeShifted = stubPageSize / 32 ;
172
+ // Calculate the ldr x9, #offset instruction with offset based on the page size
173
+ callCountingStubTemplate [ 1 ] = ( byte ) ( pageSizeShifted & 0xff ) ;
174
+ callCountingStubTemplate [ 2 ] = ( byte ) ( pageSizeShifted >> 8 ) ;
165
175
166
- // Calculate the ldr x10, #offset instruction with offset based on the page size
167
- stubPrecodeTemplate [ 1 ] = ( byte ) ( pageSizeShifted & 0xff ) ;
168
- stubPrecodeTemplate [ 2 ] = ( byte ) ( pageSizeShifted >> 8 ) ;
169
- // Calculate the ldr x12, #offset instruction with offset based on the page size
170
- stubPrecodeTemplate [ 5 ] = ( byte ) ( ( pageSizeShifted - 1 ) & 0xff ) ;
171
- stubPrecodeTemplate [ 6 ] = ( byte ) ( ( pageSizeShifted - 1 ) >> 8 ) ;
176
+ // Calculate the ldr x10, #offset instruction with offset based on the page size
177
+ stubPrecodeTemplate [ 1 ] = ( byte ) ( pageSizeShifted & 0xff ) ;
178
+ stubPrecodeTemplate [ 2 ] = ( byte ) ( pageSizeShifted >> 8 ) ;
179
+ // Calculate the ldr x12, #offset instruction with offset based on the page size
180
+ stubPrecodeTemplate [ 5 ] = ( byte ) ( ( pageSizeShifted - 1 ) & 0xff ) ;
181
+ stubPrecodeTemplate [ 6 ] = ( byte ) ( ( pageSizeShifted - 1 ) >> 8 ) ;
172
182
173
- // Calculate the ldr x11, #offset instruction with offset based on the page size
174
- fixupPrecodeTemplate [ 1 ] = ( byte ) ( pageSizeShifted & 0xff ) ;
175
- fixupPrecodeTemplate [ 2 ] = ( byte ) ( pageSizeShifted >> 8 ) ;
176
- // Calculate the ldr x12, #offset instruction with offset based on the page size
177
- fixupPrecodeTemplate [ 9 ] = ( byte ) ( pageSizeShifted & 0xff ) ;
178
- fixupPrecodeTemplate [ 10 ] = ( byte ) ( pageSizeShifted >> 8 ) ;
183
+ // Calculate the ldr x11, #offset instruction with offset based on the page size
184
+ fixupPrecodeTemplate [ 1 ] = ( byte ) ( pageSizeShifted & 0xff ) ;
185
+ fixupPrecodeTemplate [ 2 ] = ( byte ) ( pageSizeShifted >> 8 ) ;
186
+ // Calculate the ldr x12, #offset instruction with offset based on the page size
187
+ fixupPrecodeTemplate [ 9 ] = ( byte ) ( pageSizeShifted & 0xff ) ;
188
+ fixupPrecodeTemplate [ 10 ] = ( byte ) ( pageSizeShifted >> 8 ) ;
189
+ }
179
190
}
180
191
192
+ private static readonly Dictionary < Version , RuntimeSpecificData > runtimeSpecificData = new ( ) ;
193
+
181
194
protected override IEnumerable < Asm > Decode ( byte [ ] code , ulong startAddress , State state , int depth , ClrMethod currentMethod , DisassemblySyntax syntax )
182
195
{
196
+ if ( ! runtimeSpecificData . TryGetValue ( state . RuntimeVersion , out RuntimeSpecificData data ) )
197
+ {
198
+ runtimeSpecificData . Add ( state . RuntimeVersion , data = new RuntimeSpecificData ( state ) ) ;
199
+ }
200
+
183
201
const Arm64DisassembleMode disassembleMode = Arm64DisassembleMode . Arm ;
184
202
using ( CapstoneArm64Disassembler disassembler = CapstoneDisassembler . CreateArm64Disassembler ( disassembleMode ) )
185
203
{
@@ -210,21 +228,21 @@ protected override IEnumerable<Asm> Decode(byte[] code, ulong startAddress, Stat
210
228
211
229
if ( state . Runtime . DataTarget . DataReader . Read ( address , buffer ) == buffer . Length )
212
230
{
213
- if ( buffer . SequenceEqual ( callCountingStubTemplate ) )
231
+ if ( buffer . SequenceEqual ( data . callCountingStubTemplate ) )
214
232
{
215
233
const ulong TargetMethodAddressSlotOffset = 8 ;
216
- address = state . Runtime . DataTarget . DataReader . ReadPointer ( address + ( ulong ) Environment . SystemPageSize + TargetMethodAddressSlotOffset ) ;
234
+ address = state . Runtime . DataTarget . DataReader . ReadPointer ( address + data . stubPageSize + TargetMethodAddressSlotOffset ) ;
217
235
}
218
- else if ( buffer . SequenceEqual ( stubPrecodeTemplate ) )
236
+ else if ( buffer . SequenceEqual ( data . stubPrecodeTemplate ) )
219
237
{
220
238
const ulong MethodDescSlotOffset = 0 ;
221
- address = state . Runtime . DataTarget . DataReader . ReadPointer ( address + ( ulong ) Environment . SystemPageSize + MethodDescSlotOffset ) ;
239
+ address = state . Runtime . DataTarget . DataReader . ReadPointer ( address + data . stubPageSize + MethodDescSlotOffset ) ;
222
240
isPrestubMD = true ;
223
241
}
224
- else if ( buffer . SequenceEqual ( fixupPrecodeTemplate ) )
242
+ else if ( buffer . SequenceEqual ( data . fixupPrecodeTemplate ) )
225
243
{
226
244
const ulong MethodDescSlotOffset = 8 ;
227
- address = state . Runtime . DataTarget . DataReader . ReadPointer ( address + ( ulong ) Environment . SystemPageSize + MethodDescSlotOffset ) ;
245
+ address = state . Runtime . DataTarget . DataReader . ReadPointer ( address + data . stubPageSize + MethodDescSlotOffset ) ;
228
246
isPrestubMD = true ;
229
247
}
230
248
}
0 commit comments