Fix Arm64 disassembler for .NET 10 DMB-prefixed stubs - #3208
Merged
Conversation
.NET 10 prefixes AArch64 precode/stub shapes (at least FixupPrecodeCode_Fixup) with a leading DMB ISH for concurrent stub-patching safety. The existing TryResolvePrecode / TryFollowJumpTrampoline read a fixed 12-byte window and match a 3-instruction pattern, so the barrier caused every prefixed stub to miss. Symptom: after landing on a benchmark-method call site under CsProjCoreToolchain.NetCoreApp10_0 on ARM64, the disassembler stopped instead of chasing into the target, so DisassemblyDiagnoser only recovered the wrapper method (surfacing as failures in tests like CanDisassembleInlinableBenchmarks once the toolchain is bumped to .NET 10). Add TryReadStubHead: read up to 16 bytes, detect DMB ISH (0xD50339BF) at instr0, skip 4 bytes and return an effective parseBase so LDR-literal offset math stays correct. Use it from both stub-parsing entry points; slot addresses now use parseBase instead of address. TryFollowJumpTrampoline's short 'B imm26' path is intentionally left as a 4-byte read since the barrier is only emitted for precode/stub shapes, not JIT-emitted jump trampolines. Verified on Ubuntu 24.04 ARM64 GitHub-hosted runner (.NET SDK 10.0.302 / runtime 10.0.10): the full DisassemblyDiagnoserTests suite passes end-to-end under both InProcessEmit and CsProjCore .NET 10 toolchains.
This was referenced Jul 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3207.
.NET 10 prefixes AArch64 precode/stub shapes (at least
FixupPrecodeCode_Fixup) with a leadingDMB ISHfor concurrent stub-patching safety. The existingTryResolvePrecode/TryFollowJumpTrampolineinArm64Disassembler.csread a fixed 12-byte window and match a 3-instruction pattern, so the barrier caused every prefixed stub to miss.Symptom
After landing on a benchmark-method call site under
CsProjCoreToolchain.NetCoreApp10_0on ARM64, the disassembler stopped chasing instead of following into the target —DisassemblyDiagnoseronly recovered the wrapper method. This surfaces as failures in tests likeCanDisassembleInlinableBenchmarksonce the toolchain is bumped to .NET 10.Fix
Add
TryReadStubHead: read up to 16 bytes, detectDMB ISH(0xD50339BF) atinstr0, skip 4 bytes and return an effectiveparseBaseso LDR-literal offset math stays correct. Use it from both stub-parsing entry points; slot addresses now useparseBaseinstead ofaddress.TryFollowJumpTrampoline's shortB imm26path is intentionally left as a 4-byte read since the barrier is only emitted for precode/stub shapes, not JIT-emitted jump trampolines.Verification
Verified on GitHub-hosted
ubuntu-24.04-armrunner (.NET SDK 10.0.302 / runtime 10.0.10): the fullDisassemblyDiagnoserTestssuite (CanDisassembleAllMethodCalls,CanDisassembleAllMethodCallsUsingFilters,CanDisassembleGenericTypes,CanDisassembleInlinableBenchmarks) passes end-to-end under bothInProcessEmitandCsProjCore.NET 10 toolchains. Run: https://github.com/timcassell/BenchmarkDotNet/actions/runs/30183840865