GCC Newspaper
OCTOBER 6, 2026
Date
/
Architectures
Components
Topics
News & Policy
Other
gcc/x86

Darwin x86_64 lazy resolver stub clobbers now respect no_caller_saved_registers.

Darwin x86_64 lazy linking stub clobbers are now overridden by the no_caller_saved_registers attribute.

On Darwin x86_64 systems prior to Darwin21, lazy symbol resolution uses a stub that overwrites registers d10 and d11. This commit ensures that if a function is explicitly marked with no_caller_saved_registers, this attribute takes precedence over the stub’s register clobbering. This prevents unexpected register corruption when users specify this function attribute.

In Details

On Darwin x86_64, the dynamic linker's lazy symbol resolution mechanism involves a stub routine that clobbers d10 and d11. This behavior is in conflict with the no_caller_saved_registers function attribute, which signifies that a function must not modify any caller-saved registers. The ix86_expand_call function in i386-expand.cc now queries this attribute and overrides the stub's register reservation if the attribute is set. This check is performed on a hot path but testing showed no significant compile-time overhead.

For Context
Lazy symbol resolution
A dynamic linking technique where symbols are resolved (i.e., their addresses are found) only when they are first called, rather than resolving all symbols when the program starts. This can improve startup time for applications that use many dynamic libraries but call only a few functions from each.
Stub
In dynamic linking, a small piece of code that acts as an intermediary. For lazy resolution, a stub might contain code to find the actual function address and then jump to it, updating the caller's reference.
Clobber
In compiler optimization and assembly, 'clobber' refers to a register or memory location whose contents are modified by a function or instruction. A function that clobbers a register is one that changes its value.
Caller-saved registers
CPU registers whose values a function is allowed to change without preserving them. The caller of the function is responsible for saving these registers if their values are needed after the function returns. Also known as volatile registers.
no_caller_saved_registers
A function attribute that instructs the compiler not to preserve any caller-saved registers within that function. This implies the function will not modify these registers, allowing for potential optimizations.
x86_64
The 64-bit version of the x86 instruction set architecture. It is widely used in modern desktop and server processors.
Darwin21
Refers to a specific version of Apple's Darwin operating system, likely corresponding to macOS Monterey. Later versions of Darwin have different dynamic linker behaviors.
Filed Under: x86darwinlinkingoptimization