# Long branches in compilers, assemblers, and linkers

DevFeed: [Long branches in compilers, assemblers, and linkers](<https://devfeed.tech/articles/long-branches-in-compilers-assemblers-and-linkers-31133.md>)

Original publisher: [Read original article](<https://maskray.me/blog/long-branches-in-compilers-assemblers-and-linkers>)

Published: 2026-01-25T08:00:00Z

Content type: article

Language: en

Sources: [MaskRay](<https://devfeed.tech/sources/maskray.md>)

Topics: [toolchain](<https://devfeed.tech/topics/toolchain.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [Assembly](<https://devfeed.tech/topics/assembly.md>)

Tags: [architectures](<https://devfeed.tech/tags/architectures.md>), [article](<https://devfeed.tech/tags/article.md>), [assembler](<https://devfeed.tech/tags/assembler.md>), [binutils](<https://devfeed.tech/tags/binutils.md>), [compilers](<https://devfeed.tech/tags/compilers.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [linker](<https://devfeed.tech/tags/linker.md>), [llvm](<https://devfeed.tech/tags/llvm.md>), [toolchain](<https://devfeed.tech/tags/toolchain.md>)

## AI overview

This article explains how compilers, assemblers, and linkers handle branch instructions whose PC-relative targets exceed the supported range. It describes the division of responsibility across toolchain stages and compares branch-range limitations across architectures, including AArch32, AArch64, and LoongArch.

## Source excerpt

Branch instructions on most architectures use PC-relative addressing with a limited range. When the target is too far away, the branch becomes "out of range" and requires special handling. Consider a large binary where main() at address 0x10000 calls foo() at address 0x8010000-over 128MiB away. On AArch64, the bl instruction can only reach ±128MiB, so this call cannot be encoded directly. Without proper handling, the linker would fail with an error like "relocation out of range." The toolchain must handle this transparently to produce correct executables. This article explores how compilers, assemblers, and linkers work together to solve the long branch problem. Compiler (IR to assembly): Handles branches within a function that exceed the range of conditional branch instructions Assembler (assembly to relocatable file): Handles branches within a section where the distance is known at assembly time Linker: Handles cross-section and cross-object branches discovered during final layout