Windows on AArch64 also provides for hot-patching, but it’s much simpler than on x86

The Old New Thing (Raymond Chen) News

Summary

Raymond Chen explains how Windows on AArch64 implements function hot-patching more simply than on x86, using a 12-byte patch space and a three-instruction trampoline via the xip0 scratch register, noting that pointer authentication (pacibsp) usually guards the function entry.

<p>I have noted in the past that <a title="Why do Windows functions all begin with a pointless MOV EDI, EDI instruction?" href="https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583"> x86-32</a> and <a title="Why don't Windows functions begin with a pointless MOV EDI,EDI instruction on x86-64?" href="https://devblogs.microsoft.com/oldnewthing/20221109-00/?p=107373"> x86-64</a> versions of Windows are careful to start each function with a patch point. But what about AArch64 (known in Windows as arm64)?</p> <p>Windows also inserts patch points for functions on AArch64, but they are much simpler due to the fixed-length instruction set. You don&#8217;t have to worry about patching an instruction when the instruction pointer happens to be in the middle of the byte sequence, because the instruction pointer is <i>never</i> in the middle of the byte sequence. The instruction pointer is always on a multiple of 4.</p> <p>Therefore, there is no special restriction on the first instruction of a function. All instructions meet the requirements of being atomically updatable without risk of the instruction pointer being in the middle of the instruction.</p> <p>Before each function is a patch space of 12 bytes, which is <a title="The AArch64 processor (aka arm64), part 15: Control transfer" href="https://devblogs.microsoft.com/oldnewthing/20220815-00/?p=106975"> exactly enough for a three-instruction trampoline</a>:</p> <pre>; overwrite the patch space with these three instructions adrp xip0, PageStart(replacement) add xip0, xip0, PageOffset(replacement) br xip0 function_entry_point: ; overwrite the function entry point with one instruction br $-12 ; jump to the patch space </pre> <p>The <code>xip0</code> register is <a title="The AArch64 processor (aka arm64), part 1: Introduction" href="https://devblogs.microsoft.com/oldnewthing/20220726-00/?p=106898"> one of the two intra-procedure call scratch registers</a>, and the convention is that this register can be clobbered by any branch instruction. Since the caller had to use a branch instruction to reach <code>function_<wbr />entry_<wbr />point</code> in the first place, it cannot be using <code>xip0</code> for anything, so we are free to clobber <code>xip0</code> as part of our trampoline.</p> <p><b>Bonus chatter</b>: The first instruction at the function entry point is almost certainly <code>pacibsp</code>, the <a title="The AArch64 processor (aka arm64), part 18: Return address protection" href="https://devblogs.microsoft.com/oldnewthing/20220819-00/?p=107020"> pointer authentication instruction for signing the return address</a> to make code more resistant to ROP attacks and attacks that overwrite the return address.</p> <p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260930-00/?p=112744/">Windows on AArch64 also provides for hot-patching, but it&#8217;s much simpler than on x86</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
Original Article
View Cached Full Text

Cached at: 10/01/26, 02:50 PM

# Windows on AArch64 also provides for hot-patching, but it's much simpler than on x86 - The Old New Thing Source: [https://devblogs.microsoft.com/oldnewthing/20260930-00/?p=112744/](https://devblogs.microsoft.com/oldnewthing/20260930-00/?p=112744/) I have noted in the past that[x86\-32](https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583)and[x86\-64](https://devblogs.microsoft.com/oldnewthing/20221109-00/?p=107373)versions of Windows are careful to start each function with a patch point\. But what about AArch64 \(known in Windows as arm64\)? Windows also inserts patch points for functions on AArch64, but they are much simpler due to the fixed\-length instruction set\. You don’t have to worry about patching an instruction when the instruction pointer happens to be in the middle of the byte sequence, because the instruction pointer is*never*in the middle of the byte sequence\. The instruction pointer is always on a multiple of 4\. Therefore, there is no special restriction on the first instruction of a function\. All instructions meet the requirements of being atomically updatable without risk of the instruction pointer being in the middle of the instruction\. Before each function is a patch space of 12 bytes, which is[exactly enough for a three\-instruction trampoline](https://devblogs.microsoft.com/oldnewthing/20220815-00/?p=106975): ``` ; overwrite the patch space with these three instructions adrp xip0, PageStart(replacement) add xip0, xip0, PageOffset(replacement) br xip0 function_entry_point: ; overwrite the function entry point with one instruction br $-12 ; jump to the patch space ``` The`xip0`register is[one of the two intra\-procedure call scratch registers](https://devblogs.microsoft.com/oldnewthing/20220726-00/?p=106898), and the convention is that this register can be clobbered by any branch instruction\. Since the caller had to use a branch instruction to reach`function\_entry\_point`in the first place, it cannot be using`xip0`for anything, so we are free to clobber`xip0`as part of our trampoline\. **Bonus chatter**: The first instruction at the function entry point is almost certainly`pacibsp`, the[pointer authentication instruction for signing the return address](https://devblogs.microsoft.com/oldnewthing/20220819-00/?p=107020)to make code more resistant to ROP attacks and attacks that overwrite the return address\. ### Category ### Topics ## Author ![Raymond Chen](https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2019/02/RaymondChen_5in-150x150.jpg) Raymond has been involved in the evolution of Windows for more than 30 years\. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie\-jeebies\. The Web site spawned a book, coincidentally also titled The Old New Thing \(Addison Wesley 2007\)\. He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information\.

Similar Articles

A compatibility note on the abuse of Windows window class extra bytes

The Old New Thing (Raymond Chen)

Raymond Chen discusses a historical Windows compatibility issue where some 16-bit programs abused window class extra bytes to store private data, and how Microsoft blocked the loophole for 32-bit and 64-bit programs while maintaining backward compatibility.

Windows stack limit checking retrospective, follow-up

The Old New Thing (Raymond Chen)

Raymond Chen follows up on his previous article about stack limit checking on ARM64, addressing a detail about the unconventional use of the x15 register in stack probe functions and comparing register usage across multiple architectures.

Forcing an ARM64X executable to run as a specific architecture

The Old New Thing (Raymond Chen)

The article explains how to force an ARM64X executable to run as a specific architecture on Windows, using the PROC_THREAD_ATTRIBUTE_MACHINE_TYPE attribute to relaunch the process if needed for plug-in compatibility.

Pinball on 64-bit Alpha AXP Windows NT

Lobsters Hottest

An exploration of the history of Windows' built-in Pinball game, the collision detection bug that prevented its inclusion in 64-bit Windows (specifically on Alpha AXP), and recent emulation breakthroughs that allow the rare 64-bit Alpha NT build to run the game.