[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