[PATCH] Link static C++ tests against libatomic.a if needed
H.J. Lu
hjl.tools@gmail.com
Tue May 5 20:44:07 GMT 2026
On Wed, May 6, 2026 at 4:37 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Tue, May 5, 2026 at 11:24 PM Adhemerval Zanella Netto
> <adhemerval.zanella@linaro.org> wrote:
> >
> >
> >
> > On 05/05/26 11:08, H.J. Lu wrote:
> > > On Tue, May 5, 2026 at 8:36 PM Adhemerval Zanella Netto
> > > <adhemerval.zanella@linaro.org> wrote:
> > >>
> > >>
> > >>
> > >> On 05/05/26 09:33, H.J. Lu wrote:
> > >>> On Tue, May 5, 2026 at 8:27 PM Adhemerval Zanella Netto
> > >>> <adhemerval.zanella@linaro.org> wrote:
> > >>>>
> > >>>>
> > >>>>
> > >>>> On 04/05/26 22:50, H.J. Lu wrote:
> > >>>>> On Tue, May 5, 2026 at 9:42 AM Sam James <sam@gentoo.org> wrote:
> > >>>>>>
> > >>>>>> "H.J. Lu" <hjl.tools@gmail.com> writes:
> > >>>>>>
> > >>>>>>> On Mon, May 4, 2026 at 10:33 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >>>>>>>>
> > >>>>>>>> Define cxx-static-link-libatomic to -latomic if DT_NEEDED entries in
> > >>>>>>>> libstdc++.so include libatomic.so. Update link-extra-libs-static to
> > >>>>>>>> include $(cxx-static-link-libatomic) if -lstdc++ is used.
> > >>>>>>>>
> > >>>>>>>> Tested with sparcv8-linux-gnu-leon3 and sparcv9-linux-gnu using
> > >>>>>>>> uild-many-glibcs.py. This fixes BZ #34121.
> > >>>>>>>>
> > >>>>>>>
> > >>>>>>> FWIW, sparc g++ does pass -latomic_asneeded to ld. But glibc tests
> > >>>>>>> are built with -nostdlib -nostartfiles using gcc, not g++.
> > >>>>>>
> > >>>>>> https://inbox.sourceware.org/gcc-patches/CACb0b4m+ex47Tpyp1qvW9+0p4onyEvsfXeXE_4zZrteMO5q5EQ@mail.gmail.com/
> > >>>>>>
> > >>>>>> I don't remember what happened with that, there were a few issues with
> > >>>>>> the libatomic autolinking so I lost track.
> > >>>>>
> > >>>>> One way to fix the gcc is to create libstdc++.a as linker script, similar to
> > >>>>>
> > >>>>> [hjl@gnu-tgl-3 x86-glibc]$ cat /usr/lib64/libm.a
> > >>>>> /* GNU ld script
> > >>>>> */
> > >>>>> OUTPUT_FORMAT(elf64-x86-64)
> > >>>>> GROUP ( /usr/lib64/libm-2.43.a /usr/lib64/libmvec.a )
> > >>>>> [hjl@gnu-tgl-3 x86-glibc]$
> > >>>>>
> > >>>>> to include libatomic.a in libstdc++.a if needed. But I don't know if it works
> > >>>>> everywhere.
> > >>>>>
> > >>>>
> > >>>> It seems gcc-16 has another issue, it also fails on building glibc after a bootstrap
> > >>>> with build-many-glibcs.py with:
> > >>>>
> > >>>> [..-m32 -mlong-double-128 -mcpu=v9 -o /home/azanella/Projects/glibc/build/sparcv9-linux-gnu-gcc16/support/links-dso-program -pie -Wl,-O1 -nostdlib -nostartfiles [...]
> > >>>> [...]/sparc64-linux-gnu/sparc64-glibc-linux-gnu/bin/ld: [...]/sparc64-linux-gnu/bin/../lib/gcc/sparc64-glibc-linux-gnu/16.1.1/../../../../sparc64-glibc-linux-gnu/lib/../lib/libstdc++.so: undefined reference to `__atomic_fetch_add_4@LIBATOMIC_1.0'
> > >>>> [...]//sparc64-glibc-lisparc64-linux-gnunux-gnu/bin/ld: [...]/sparc64-linux-gnu/bin/../lib/gcc/sparc64-glibc-linux-gnu/16.1.1/../../../../sparc64-glibc-linux-gnu/lib/../lib/libstdc++.so: undefined reference to `__atomic_fetch_sub_4@LIBATOMIC_1.0'
> > >>>>
> > >>>> And dumping the linker invocation, it shows another issue:
> > >>>>
> > >>>> ld: warning: libatomic.so.1, needed by [...]/sparc64-linux-gnu/bin/../lib/gcc/sparc64-glibc-linux-gnu/16.1.1/../../../../sparc64-glibc-linux-gnu/lib/../lib/libstdc++.so, not found (try using -rpath or -rpath-link)
> > >>>
> > >>> Which version of binutils are you using? Binutils master branch works
> > >>> for me for sparc64-glibc-linux-gnu.
> > >>
> > >> It is a pretty recent one:
> > >>
> > >> $ ./bin/sparc64-glibc-linux-gnu-ld -v
> > >> GNU ld (GNU Binutils) 2.46.0.20260504
> > >
> > > For some reason, my ld works:
> > >
> > > $ ./install/compilers/sparc64-linux-gnu/bin/sparc64-glibc-linux-gnu-ld -V
> > > GNU ld (GNU Binutils) 2.46.50.20260503
> > > Supported emulations:
> > > elf64_sparc
> > > elf32_sparc
> > >
> > > Please try the enclosed patch. If it works for you, I will change it
> > > for both dynamic and static C++ executables.
> > >
> >
> > I still think the resulting libstdc++ being linked against libatomic.so is
> > gcc build issue due some missing flags (sparcv9 should have all required C11
> > atomic instruction that gcc should not be required to use libatomic).
> >
> > And I think we will need to evaluate better if an ABI does require libatomic
> > for some reason. One of the reason we remove sparcv8 and older was exactly
> > because the ISA lacks proper atomic operations.
>
> [hjl@gnu-zen4-1 bin]$ cat /tmp/x.cc
> struct S { int i; char p[1024]; };
>
> int
> main ()
> {
> struct S *p = (struct S *) __builtin_malloc (__builtin_offsetof
> (struct S, p) + 64);
> p->i = 5;
> asm volatile ("" : "+r" (p) : : "memory");
> __atomic_fetch_add ((int *) p, 5, __ATOMIC_RELAXED);
> asm volatile ("" : "+r" (p) : : "memory");
> if (p->i != 10)
> __builtin_abort ();
> __builtin_free (p);
> return 0;
> }
> [hjl@gnu-zen4-1 bin]$ ./sparc64-glibc-linux-gnu-gcc -c -O2 -o /tmp/x.o /tmp/x.cc
> [hjl@gnu-zen4-1 bin]$ readelf -sW /tmp/x.o
>
> Symbol table '.symtab' contains 15 entries:
> Num: Value Size Type Bind Vis Ndx Name
> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS x.cc
> 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
> 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2 .data
> 4: 0000000000000000 0 SECTION LOCAL DEFAULT 3 .bss
> 5: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .text.startup
> 6: 0000000000000000 0 SECTION LOCAL DEFAULT 7 .note.GNU-stack
> 7: 0000000000000000 0 SECTION LOCAL DEFAULT 8 .eh_frame
> 8: 0000000000000000 0 SECTION LOCAL DEFAULT 6 .comment
> 9: 0000000000000000 100 FUNC GLOBAL DEFAULT 4 main
> 10: 0000000000000002 0 REGISTER GLOBAL DEFAULT UND
> 11: 0000000000000003 0 REGISTER GLOBAL DEFAULT UND
> 12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND malloc
> 13: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND free
> 14: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND abort
> [hjl@gnu-zen4-1 bin]$ ./sparc64-glibc-linux-gnu-gcc -c -O2 -o /tmp/x.o
> /tmp/x.cc -m32
> [hjl@gnu-zen4-1 bin]$ readelf -sW /tmp/x.o
>
> Symbol table '.symtab' contains 14 entries:
> Num: Value Size Type Bind Vis Ndx Name
> 0: 00000000 0 NOTYPE LOCAL DEFAULT UND
> 1: 00000000 0 FILE LOCAL DEFAULT ABS x.cc
> 2: 00000000 0 SECTION LOCAL DEFAULT 1 .text
> 3: 00000000 0 SECTION LOCAL DEFAULT 2 .data
> 4: 00000000 0 SECTION LOCAL DEFAULT 3 .bss
> 5: 00000000 0 SECTION LOCAL DEFAULT 4 .text.startup
> 6: 00000000 0 SECTION LOCAL DEFAULT 7 .note.GNU-stack
> 7: 00000000 0 SECTION LOCAL DEFAULT 8 .eh_frame
> 8: 00000000 0 SECTION LOCAL DEFAULT 6 .comment
> 9: 00000000 88 FUNC GLOBAL DEFAULT 4 main
> 10: 00000000 0 NOTYPE GLOBAL DEFAULT UND malloc
> 11: 00000000 0 NOTYPE GLOBAL DEFAULT UND __atomic_fetch_add_4
> 12: 00000000 0 NOTYPE GLOBAL DEFAULT UND free
> 13: 00000000 0 NOTYPE GLOBAL DEFAULT UND abort
> [hjl@gnu-zen4-1 bin]$
>
> -m32 defaults to
>
> -mptr32 -mno-stack-bias -mlong-double-64 -mcpu=cypress
>
> Does -mcpu=cypress support __atomic_fetch_add_4?
>
> --
> H.J.
Even if sparcv9-linux-gnu glibc is compiled with -m32 -mcpu=v9,
the 32-bit libstdc++ is compiled with -mcpu=cypress.
--
H.J.
More information about the Libc-alpha
mailing list