[PATCH] alpha: Use a comdat group for the shared divide-by-zero handler [BZ #20543]
H.J. Lu
hjl.tools@gmail.com
Sun Sep 6 22:06:12 GMT 2026
On Mon, Sep 7, 2026 at 5:12 AM Matt Turner <mattst88@gmail.com> wrote:
>
> DO_DIVBYZERO placed __divbyzero in .gnu.linkonce.t.divbyzero so that,
> when building the PIC libc.so, every divide routine's copy collapses to
> one. .gnu.linkonce is a pre-comdat-group GNU convention that no current
> toolchain emits and that upstream lld has declined to support in full
> generality, since a linked-to section from outside a group is not valid
> ELF and every non-GNU-as producer has used SHT_GROUP comdat groups
> instead for 25+ years.
>
> BZ #20543 tracked this migration across glibc; i386's PIC-thunk section
> was converted, but alpha's divide-by-zero handler was missed. Switch it
> to the same "axG",@progbits,<sym>,comdat idiom already used by the i386
> and sparc PIC-thunk sections, so it is deduplicated via a real ELF group
> rather than section-name matching.
>
> Divide routines reach the handler via `beq Y, DIVBYZERO`, a 21-bit
> word-displacement branch (+-4MB range). The old .gnu.linkonce.t.* name
> put the section in the default linker script's last .text bucket,
> guaranteeing it trailed all other code; .text.__divbyzero lands one
> bucket earlier alongside other .text.* input sections, so "last in
> .text" is no longer guaranteed (PIC libc.so only; libc.a keeps per-file
> copies). Measured on an alpha-unknown-linux-gnu build, __divbyzero
> landed a few hundred bytes from the end of a ~1.6MB .text. An
> out-of-range branch would fail the link with "relocation truncated to
> fit" rather than produce a silently broken libc.
>
> ---
> Signed-off-by: Matt Turner <mattst88@gmail.com>
> ---
> sysdeps/alpha/div_libc.h | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/sysdeps/alpha/div_libc.h b/sysdeps/alpha/div_libc.h
> index c34f2190b1..cc569b8c84 100644
> --- a/sysdeps/alpha/div_libc.h
> +++ b/sysdeps/alpha/div_libc.h
> @@ -79,15 +79,15 @@
> #define FRAME 64
>
> /* Code fragment to generate an integer divide-by-zero fault. When
> - building libc.so, we arrange for there to be one copy of this code
> - placed late in the dso, such that all branches are forward. When
> - building libc.a, we use multiple copies to avoid having an out of
> - range branch. Users should jump to DIVBYZERO. */
> + building libc.so, we arrange for there to be one copy of this code,
> + shared by all the divide routines via a comdat group. When building
> + libc.a, we use multiple copies to avoid having an out of range branch.
> + Users should jump to DIVBYZERO. */
>
> .macro DO_DIVBYZERO
> #ifdef PIC
> #define DIVBYZERO __divbyzero
> - .section .gnu.linkonce.t.divbyzero, "ax", @progbits
> + .section .text.__divbyzero, "axG", @progbits, __divbyzero, comdat
> .globl __divbyzero
> .type __divbyzero, @function
> .usepv __divbyzero, no
>
> ---
> base-commit: fe03757f67e25bc8fea1473572beb30a05508d08
> change-id: 20260906-alpha-divbyzero-comdat-57dcad012598
>
> Best regards,
> --
> Matt Turner <mattst88@gmail.com>
>
LGTM.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
Thanks.
--
H.J.
More information about the Libc-alpha
mailing list