January 27, 2026
Code can’t jump? Bring the thunks
Handling Long Branches
When your code can’t jump, the linker calls a rideshare
TLDR: Branches can’t always reach their targets, so linkers add tiny detours (thunks) to make far jumps work. Veterans reminisce about manual fixes, newbies are surprised by the linker’s “silent magic,” and a renamed blog link sparks small but spirited link‑rot drama.
Long story short: programs sometimes try to “jump” farther than the chip allows, and things break. This post explains how compilers, assemblers, and linkers tag‑team to fix those “out of range” jumps with tiny detours called thunks. Think of it as your code calling an Uber when the bridge is out. The wow moment for the crowd? AArch64 can’t jump beyond roughly 128MB, while x86‑64 can leap a whopping 2GB, which is why your PC rarely panics about this. Cue the long‑jump Olympics jokes. Old‑school devs rolled in with war stories: stevekemp got slammed by Z80 limits and spent hours reshuffling code like a programmer Tetris champion. Newer folks like kccqzy were stunned that linkers secretly patch faraway calls—no error, just silent rescue—sparking a mini‑debate over “magical fixes” versus “fail loudly.” Meanwhile, netule dropped the real drama: the blog post got renamed and the link changed, triggering classic link‑rot jokes and frantic bookmarking. The vibe: veterans nod knowingly, newbies gasp, and everyone laughs at the idea of tiny “thunk goblins” quietly fixing your app at night. It’s nerdy, but delightfully messy—just how we like it.
Key Points
- •PC-relative branch instructions have limited ranges; distant targets can cause “relocation out of range” without special handling.
- •Compilers, assemblers, and linkers share responsibility: compiler relaxes intra-function branches; assembler handles intra-section; linker resolves cross-section/object with thunks.
- •Architectures have different branch limits (e.g., AArch64 ±128MiB unconditional, ±1MiB conditional; RISC-V jal ±1MiB; x86-64 near jumps ±2GiB).
- •Per-architecture mechanisms include range extension thunks, veneers, interworking (e.g., TOC/NOTOC), and specific relocation types guiding linker behavior.
- •x86-64 rarely needs thunks due to ±2GiB near-jump range; some linkers (including lld) do not implement range extension thunks for x86-64 and SPARC.