The x18 register
osfmk/arm64/locore.s
125 mov x18, #0
193 * This may mutate x18.
198 mrs x18, TTBR0_EL1
199 orr x18, x18, #(1 << TTBR_ASID_SHIFT)
200 msr TTBR0_EL1, x18
215 MOV64 x18, TCR_EL1_BOOT
216 msr TCR_EL1, x18
228 * This may mutate x18.
237 mrs x18, TPIDR_EL1
238 ldr x18, [x18, ACT_CPUDATAP]
239 ldr x18, [x18, CPU_EXC_VECTORS]
244 ldr x18, [x18, #($1 << 3)]
245 br x18
325 * Clobbers x18, NZCV.
329 * We need two registers to do a compare but only have x18 free without
335 mrs x18, ELR_EL1
340 cmp x18, x19 /* HS if at or above (suspect), LO if below (safe) */
348 ccmp x18, x19, #0b0010 /* C/HS */, HS
351 msr ELR_EL1, x18
352 mov x18, #0
363 * (out) x18: The unauthenticated CPU_EXCEPSTACK_TOP used for the comparison or
370 mrs x18, TPIDR_EL1 // Get thread pointer
373 * Return zero in x18 to indicate that we failed to execute the check.
375 cbz x18, Lskip_stack_check_\@
376 ldr x18, [x18, ACT_CPUDATAP]
377 cbz x18, \invalid_stack_label // If thread context is set, cpu data should be too
378 ldr x18, [x18, CPU_EXCEPSTACK_TOP]
379 cmp sp, x18
381 sub x18, x18, EXCEPSTACK_SIZE_NUM // Find bottom of exception stack
382 cmp sp, x18
384 add x18, x18, EXCEPSTACK_SIZE_NUM // Return stack top in x18
602 * Did we fail to execute the stack check (x18=0)?
615 ccmp x18, xzr, #0b0000 /* !Z/NE */, LO
620 * check (x18=0), something is wrong (TPIDR is corrupted?).
623 cbz x18, EXT(el1_sp1_synchronous_vector_long_spill_failed)
628 * the unauthenticated value (x18) for the stack pointer bounds check.
634 cmp x0, x18
730 mov x18, #0 // Zero x18 to avoid leaking data to user SS
904 mov x18, #0
1535 * Restore x18 only if the task has the entitlement that allows
1537 * once we use x18 for something more global.
1540 * that uses x18 as one of the global use cases (and will reset
1541 * x18 later down below).
1544 * as those are another use case, one where x18 must be preserved.
1547 mov x18, #0
1548 tbz w0, ARM_MACHINE_THREAD_PRESERVE_X18_SHIFT, Lexception_return_restore_registers
1551 ldr x18, [sp, SS64_X18]
1681 // Skip x18 - already restored or trashed above (below with __ARM_KERNEL_PROTECT__)
1706 MOV64 x18, TCR_EL1_USER
1707 msr TCR_EL1, x18
1718 mrs x18, TTBR0_EL1
1719 bic x18, x18, #(1 << TTBR_ASID_SHIFT)
1720 msr TTBR0_EL1, x18
1721 mov x18, #0
osfmk/arm64/start.s
osfmk/arm64/sleh.c
584 "\t x16: 0x%016llx x17: 0x%016llx x18: 0x%016llx x19: 0x%016llx\n"
osfmk/arm64/pcb.c
495 thread->machine.arm_machine_flags &= ~(ARM_MACHINE_THREAD_PRESERVE_X18);
507 * context switch path implicitly switches x18 regardless
509 thread->machine.arm_machine_flags |= ARM_MACHINE_THREAD_PRESERVE_X18;
514 thread->machine.arm_machine_flags |= ARM_MACHINE_THREAD_PRESERVE_X18;
525 * x18 for user threads. (Except for devices with
527 * x18.)
529 thread->machine.arm_machine_flags |= ARM_MACHINE_THREAD_PRESERVE_X18;
osfmk/arm64/machine_task.c
320 IOTaskHasEntitlement(task, "com.apple.private.custom-x18-abi") ||
328 * Those were allowed to use x18 for their purposes on Apple Silicon.
338 * trying to use x18 on a device where that's just not
343 *error_msg = "process has entitlement that indicates custom x18 ABI usage, not available on this device";
osfmk/arm64/exception_asm.h
182 stp x18, x19, [x0, SS64_X18]
osfmk/arm64/dbgwrap.c
277 * we've already saved off and then store that register in the DTR. I've chosen x18
281 instr = (0x91U << 24) | (31 << 5) | 18; // mov x18, sp
283 instr = (0xD51U << 20) | (2 << 19) | (3 << 16) | (4 << 8) | 18; // msr DBGDTR0, x18
290 instr = (0xD53U << 20) | (1 << 19) | (3 << 16) | (4 << 12) | (5 << 8) | (1 << 5) | 18; // mrs x18, DLR_EL0
292 instr = (0xD51U << 20) | (2 << 19) | (3 << 16) | (4 << 8) | 18; // msr DBGDTR0, x18
298 instr = (0xD53U << 20) | (1 << 19) | (3 << 16) | (4 << 12) | (5 << 8) | 18; // mrs x18, DSPSR_EL0
300 instr = (0xD51U << 20) | (2 << 19) | (3 << 16) | (4 << 8) | 18; // msr DBGDTR0, x18