@@ -141,45 +141,63 @@ public void Feed(Arm64Instruction instruction)
141141
142142 internal class Arm64Disassembler : ClrMdV2Disassembler
143143 {
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
159145 {
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 ) ;
165175
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 ) ;
172182
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+ }
179190 }
180191
192+ private static readonly Dictionary < Version , RuntimeSpecificData > runtimeSpecificData = new ( ) ;
193+
181194 protected override IEnumerable < Asm > Decode ( byte [ ] code , ulong startAddress , State state , int depth , ClrMethod currentMethod , DisassemblySyntax syntax )
182195 {
196+ if ( ! runtimeSpecificData . TryGetValue ( state . RuntimeVersion , out RuntimeSpecificData data ) )
197+ {
198+ runtimeSpecificData . Add ( state . RuntimeVersion , data = new RuntimeSpecificData ( state ) ) ;
199+ }
200+
183201 const Arm64DisassembleMode disassembleMode = Arm64DisassembleMode . Arm ;
184202 using ( CapstoneArm64Disassembler disassembler = CapstoneDisassembler . CreateArm64Disassembler ( disassembleMode ) )
185203 {
@@ -210,21 +228,21 @@ protected override IEnumerable<Asm> Decode(byte[] code, ulong startAddress, Stat
210228
211229 if ( state . Runtime . DataTarget . DataReader . Read ( address , buffer ) == buffer . Length )
212230 {
213- if ( buffer . SequenceEqual ( callCountingStubTemplate ) )
231+ if ( buffer . SequenceEqual ( data . callCountingStubTemplate ) )
214232 {
215233 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 ) ;
217235 }
218- else if ( buffer . SequenceEqual ( stubPrecodeTemplate ) )
236+ else if ( buffer . SequenceEqual ( data . stubPrecodeTemplate ) )
219237 {
220238 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 ) ;
222240 isPrestubMD = true ;
223241 }
224- else if ( buffer . SequenceEqual ( fixupPrecodeTemplate ) )
242+ else if ( buffer . SequenceEqual ( data . fixupPrecodeTemplate ) )
225243 {
226244 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 ) ;
228246 isPrestubMD = true ;
229247 }
230248 }
0 commit comments