[PATCH] Link static C++ tests against libatomic.a if needed
H.J. Lu
hjl.tools@gmail.com
Tue May 5 20:37:38 GMT 2026
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.
More information about the Libc-alpha
mailing list