[glibc] arm: Fix main-in-dso with non-BFD linkers (BZ 34098)
Adhemerval Zanella via Glibc-cvs <[email protected]> Wed, 3 Jun 2026 12:29:56 +0000 (GMT)
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=e951752cd0b13e8ec7eae6287b232a3babd28799 commit e951752cd0b13e8ec7eae6287b232a3babd28799 Author: Adhemerval Zanella <[email protected]> Date: Tue Jun 2 15:05:47 2026 -0300 arm: Fix main-in-dso with non-BFD linkers (BZ 34098) Commit c2d6afb4a010 changed the PIC && !SHARED path of start.S (used by crt1.o and rcrt1.o) to load main via a R_ARM_REL32 data relocation. When main is provided by a shared object, BFD ld synthesizes a canonical PLT entry for it, but other linkers (e.g. mold) do not, producing a broken binary that crashes at startup. Follow the aarch64 approach and reference main through a local __wrap_main that tail-calls it with a branch relocation, which every linker turns into a PLT entry. Checked on armv7a-linux-gnueabihf with and without --enable-default-pie. Diff: --- sysdeps/arm/start.S | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sysdeps/arm/start.S b/sysdeps/arm/start.S index 3401daf89d..6b154dc7d3 100644 --- a/sysdeps/arm/start.S +++ b/sysdeps/arm/start.S @@ -105,7 +105,7 @@ _start: /* Let the libc call main and exit with its return code. */ bl __libc_start_main(PLT) # else - ldr a1, .L_main_rel /* Load the relative offset of main. */ + ldr a1, .L_main_rel /* Load the relative offset of __wrap_main. */ adr a4, .L_main_rel /* Load the actual runtime address of the label. */ add a1, a4, a1 /* Add them together to get the absolute address. */ @@ -136,13 +136,24 @@ _start: .word main(GOT) # else .L_main_rel: - .word main - .L_main_rel + .word __wrap_main - .L_main_rel # endif #endif .cantunwind .fnend +#if defined PIC && !defined SHARED +/* When main is not defined in the executable but in a shared library then + a wrapper is needed, because crt1.o and rcrt1.o share this code and the + latter (static PIE) must avoid GOT relocations before __libc_start_main + is called. The branch to main is turned into a PLT entry by every linker, + unlike a REL32 data relocation against main. */ + .type __wrap_main, %function +__wrap_main: + b main +#endif + /* Define a symbol for the first piece of initialized data. */ .data .globl __data_start