SYSTEM Cited by 1 source
ARM64 ISA (AArch64)¶
ARM64 (also called AArch64) is ARM's 64-bit instruction set architecture. A fixed-length 4-byte ISA: every instruction is exactly 32 bits. This is the property most relevant to the 2025-10 Go arm64 compiler bug (sources/2025-10-08-cloudflare-we-found-a-bug-in-gos-arm64-compiler).
Fixed-length + small immediates → decomposed operations¶
Because every opcode must fit in 32 bits, immediate operands are necessarily small:
| Instruction | Immediate bits | Range covered |
|---|---|---|
ADD (immediate) |
12 | 0..4095 (plus optional left-shift-by-12 for 24-bit effective) |
MOV (wide immediate) |
16 | 0..65535 (plus MOVK for wider values) |
When a single opcode can't encode the needed immediate, the
compiler / assembler must decompose the operation into
multiple opcodes. ADD reserves a "shift-left-by-12" bit so
any 24-bit addition can be expressed as:
Other instructions load the immediate into a register first
(via MOVD + MOVK pairs) and then use the register form of
the target operation.
The decomposition creates a race window¶
When the target register is shared runtime-observable state
— most importantly the stack pointer RSP — the intermediate
state after one opcode and before the next is architecturally
indistinguishable from an in-progress instruction. For a
userspace scheduler like Go's that can preempt a goroutine at
any instruction boundary and then walk the stack, this is a
reachable bug window. See
concepts/split-instruction-race-window.
The preemption-safe fix is to build the wide immediate in a scratch register first, then apply it with a single indivisible register-to-register opcode:
Preemption may land before or after the ADD but cannot land
during it.
amd64 by contrast¶
x86-64 is a variable-length ISA. ADD imm32, reg encodes a
full 32-bit immediate directly in one variable-length
instruction. The immediate-encoding limit that forces
decomposition on arm64 does not arise. Hence the Cloudflare
bug was arm64-only; amd64 builds of the same Go programs were
unaffected.
Seen in¶
- sources/2025-10-08-cloudflare-we-found-a-bug-in-gos-arm64-compiler
— canonical wiki instance. Go's arm64 compiler emitted a
split
ADD $n, RSP, RSP; ADD $(m<<12), RSP, RSPepilogue for frames larger than1<<12; async preemption landing between those two opcodes crashed the runtime's stack unwinder.
Related¶
- systems/go-compiler — emitter of the split-ADD (fixed upstream in go1.23.12 / go1.24.6 / go1.25.0).
- systems/go-assembler —
asm7.goimmediate classification (conclass). - concepts/immediate-encoding-limit — the general constraint on fixed-length ISAs.
- concepts/split-instruction-race-window — the failure class this architecture enables.