Use ADRP/LDR pairs for ARM64 64-bit indirect address loads in crossgen2#121352
Use ADRP/LDR pairs for ARM64 64-bit indirect address loads in crossgen2#121352jkoritzinsky merged 9 commits intomainfrom
Conversation
…itJMP to use ADRP/LDR pair Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
|
@copilot You should also edit the implementation of ImportThunk.EmitCode(NodeFactory, ref ARM64Emitter, bool) to reference the ModuleImport node in the same way:
|
…ences Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Updated in commit 8c37adf:
The changes eliminate all DIR64 relocations in the TEXT section for ARM64 targets. |
...oreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportThunk.cs
Outdated
Show resolved
Hide resolved
|
/azp run runtime-coreclr r2r |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull Request Overview
This pull request modernizes ARM64 code generation in the ReadyToRun compiler by replacing PC-relative addressing with ADRP/LDR instruction pairs for accessing module imports. The change eliminates the need for embedded 64-bit relocations and alignment requirements, resulting in more efficient and position-independent code generation.
Key changes:
- Replaced PC-relative LDR instructions with ADRP/LDR pairs for loading module pointers
- Introduced a new relocation type
IMAGE_REL_BASED_ARM64_PAGEOFFSET_12Lspecifically for LDR instructions with scaled immediate offsets - Removed ARM64 from architectures requiring special symbol offset handling for non-Eager import thunks
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| Target_ARM64/ImportThunk.cs | Replaced PC-relative loads with ADRP/LDR pairs for module import access |
| ImportThunk.cs | Removed ARM64 from architectures requiring symbol offset adjustments |
| Relocation.cs | Added new relocation type and helper functions for LDR instruction encoding |
| ARM64Emitter.cs | Added EmitADRP and symbol-based EmitLDR methods, updated EmitJMP for indirection cells |
| PEObjectWriter.cs | Added handling for new ARM64_PAGEOFFSET_12L relocation type |
| MachObjectWriter.cs | Added support for new relocation type in Mach-O format, corrected IsPCRelative logic |
| ElfObjectWriter.cs | Mapped new relocation type to ELF R_AARCH64_LDST64_ABS_LO12_NC |
| CoffObjectWriter.cs | Mapped new relocation type to COFF IMAGE_REL_ARM64_PAGEOFFSET_12L |
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs
Outdated
Show resolved
Hide resolved
…n.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
...aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_ARM64/ImportThunk.cs
Outdated
Show resolved
Hide resolved
...aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_ARM64/ImportThunk.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_ARM64/ARM64Emitter.cs
Outdated
Show resolved
Hide resolved
|
/ba-g android timeouts |
They now match the ARM64 model we just moved to in dotnet#121352 Also, clean up the ARM64 emitter while we're at it.
Summary: Add ARM64 ADRP/LDR pair support for crossgen2
This PR adds support for the
IMAGE_REL_BASED_ARM64_PAGEOFFSET_12Lrelocation type and converts ARM64 indirect address loads in crossgen2 to use ADRP/LDR pairs instead of PC-relative LDR with DIR64 relocations.Problem
The previous implementation used PC-relative LDR instructions with 64-bit absolute address relocations (DIR64) in the TEXT section. This violates the W^X (Write XOR Execute) security model enforced by Apple's linkers, preventing the generation of Mach-O images for ARM64 targets (as identified in PR #120454).
Solution
Replaced the problematic pattern with ADRP/LDR pairs that use RIP-relative addressing:
ldr x12, [PC+offset]+ DIR64 relocationadrp x12, symbol(PAGE21) +ldr x12, [x12, #page_offset](PAGEOFF12L)Implementation Checklist
Relocation.cs - Core relocation support
GetArm64Rel12Ldr()andPutArm64Rel12Ldr()helper functionsWriteValue(),ReadValue(), andGetSize()methodsARM64Emitter.cs - Emitter updates
EmitADRP()method for ADRP instruction with PAGE21 relocationEmitLDR(Register, Register, ISymbolNode)overload for LDR with PAGEOFFSET_12LEmitJMP()for indirection cells to use ADRP/LDR pair (eliminates DIR64)ImportThunk (ReadyToRun) - R2R thunk updates
EmitCode()to use ADRP/LDR pairs for ModuleImport references_symbolOffsetto 8 for ARM64ObjectWriter integration
IMAGE_REL_ARM64_PAGEOFFSET_12LR_AARCH64_LDST64_ABS_LO12_NC(reloc type 286)ARM64_RELOC_PAGEOFF12Build & Test
Technical Details
LDR Instruction Encoding
For 64-bit LDR instructions, the immediate value represents offset/8:
Relocation Types
IMAGE_REL_BASED_ARM64_PAGEBASE_REL21(0x81): ADRP instruction, 21-bit page-aligned offsetIMAGE_REL_BASED_ARM64_PAGEOFFSET_12L(0x83): LDR instruction, 12-bit page offsetImpact
✅ Enables Mach-O image generation for ARM64 targets (macOS, iOS)
✅ Improves security by complying with W^X requirements
✅ Maintains compatibility with existing COFF (Windows) and ELF (Linux) formats
✅ Uses RIP-relative addressing instead of absolute addresses
Files Changed
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cssrc/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_ARM64/ARM64Emitter.cssrc/coreclr/tools/Common/Compiler/ObjectWriter/CoffObjectWriter.cssrc/coreclr/tools/Common/Compiler/ObjectWriter/ElfObjectWriter.cssrc/coreclr/tools/Common/Compiler/ObjectWriter/MachObjectWriter.cssrc/coreclr/tools/Common/Compiler/ObjectWriter/PEObjectWriter.cssrc/coreclr/tools/aot/ILCompiler.ReadyToRun/.../Target_ARM64/ImportThunk.cssrc/coreclr/tools/aot/ILCompiler.ReadyToRun/.../ImportThunk.csOriginal prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.