[PATCH 1/5] string: Add fallback implementation for ctz/clz

Cristian Rodríguez cristian@rodriguez.im
Wed Sep 10 15:38:33 GMT 2025


On Mon, Sep 1, 2025 at 4:21 PM Adhemerval Zanella Netto
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 01/09/25 14:51, Adhemerval Zanella Netto wrote:
> >
> >
> > On 01/09/25 14:09, Cristian Rodríguez wrote:
> >> On Mon, Sep 1, 2025 at 11:40 AM Adhemerval Zanella Netto
> >> <adhemerval.zanella@linaro.org> wrote:
> >>
> >>> I found on s390x that calling the libgcc builtin is not fully supported without
> >>> setting up TLS because the builtin could be built with stack-protection enabled.
> >>> It might happen on other ABIs that uses the generic strchrnul implementation and
> >>> relying on libgcc for __builtin_c[t,l]z.
> >>
> >> Huh..what? everything else I have seen assumes this builtins are unsequenced..
> >> is this hiding a bug somewhere?
> >
> > I am not sure, but using the tst-assert-startup-static test from patchset:
> >
> > $ qemu-s390x -g 1234 elf/tst-assert-startup-static
> > [...]
> >
> > $ gdb-multiarch
> > [...]
> > (gdb) target remote localhost:1234
> > [...]
> > _start () at ../sysdeps/s390/s390-64/start.S:65
> > 65            la      %r4,8(%r15)             # get argv
> > (gdb) c
> > Continuing.
> >
> > Program received signal SIGSEGV, Segmentation fault.
> > 0x000002aa000972b6 in __clzdi2 (x=<optimized out>) at /home/azanella/toolchain/src/gcc/libgcc/libgcc2.c:692
> > 692     return ret;
> > (gdb) bt
> > #0  0x000002aa000972b6 in __clzdi2 (x=<optimized out>) at /home/azanella/toolchain/src/gcc/libgcc/libgcc2.c:692
> > #1  0x000002aa00014f2a in clz (c=<optimized out>) at ../sysdeps/generic/string-fzi.h:60
> > #2  index_first (c=<optimized out>) at ../sysdeps/generic/string-fzi.h:115
> > #3  index_first_zero_eq (x1=<optimized out>, x2=<optimized out>) at ../sysdeps/generic/string-fzc.h:59
> > #4  __strchrnul_c (str=<optimized out>, c_in=<optimized out>) at ../string/strchrnul.c:51
> > #5  0x000002aa0000a0e6 in __libc_message_impl (fmt=fmt@entry=0x2aa000a1eee "Fatal glibc error: %s:%s (%s): assertion failed: %s\n")
> >     at ../sysdeps/posix/libc_fatal.c:77
> > #6  0x000002aa00009338 in __libc_assert_fail (assertion=assertion@entry=0x2aa000a5ef6 "error",
> >     file=file@entry=0x2aa000a1d80 "tst-assert-startup-static.c", line=line@entry=28,
> >     function=function@entry=0x2aa000a1d9c <__func__.0> "__tunables_init") at __libc_assert_fail.c:31
> > #7  0x000002aa0000820e in __tunables_init (env=<optimized out>) at tst-assert-startup-static.c:28
> > #8  0x000002aa00008ab8 in __libc_start_main_impl (main=0x2aa00008104 <__wrap_main>, argc=1, argv=0x200007ffb38, init=<optimized out>,
> >     fini=<optimized out>, rtld_fini=0x0, stack_end=0x200007ffa80) at ../csu/libc-start.c:267
> > #9  0x000002aa00008102 in _start () at ../sysdeps/s390/s390-64/start.S:101
> > (gdb) disas
> > Dump of assembler code for function __clzdi2:
> >    0x000002aa00097260 <+0>:   lghi    %r1,56
> >    0x000002aa00097264 <+4>:   lghi    %r3,7
> >    0x000002aa00097268 <+8>:   srlg    %r4,%r2,0(%r1)
> >    0x000002aa0009726e <+14>:  tmll    %r4,255
> >    0x000002aa00097272 <+18>:  jne     0x2aa0009729e <__clzdi2+62>
> >    0x000002aa00097276 <+22>:  aghi    %r1,-8
> >    0x000002aa0009727a <+26>:  brctg   %r3,0x2aa00097268 <__clzdi2+8>
> >    0x000002aa0009727e <+30>:  larl    %r5,0x2aa000d0ed8
> >    0x000002aa00097284 <+36>:  lghi    %r0,64
> >    0x000002aa00097288 <+40>:  lg      %r1,0(%r5)
> >    0x000002aa0009728e <+46>:  llgc    %r2,0(%r2,%r1)
> >    0x000002aa00097294 <+52>:  sgr     %r0,%r2
> >    0x000002aa00097298 <+56>:  lgfr    %r2,%r0
> >    0x000002aa0009729c <+60>:  br      %r14
> >    0x000002aa0009729e <+62>:  lgr     %r2,%r4
> >    0x000002aa000972a2 <+66>:  larl    %r5,0x2aa000d0ed8
> >    0x000002aa000972a8 <+72>:  lghi    %r0,64
> >    0x000002aa000972ac <+76>:  sgr     %r0,%r1
> >    0x000002aa000972b0 <+80>:  lg      %r1,0(%r5)
> > => 0x000002aa000972b6 <+86>:  llgc    %r2,0(%r2,%r1)
> >    0x000002aa000972bc <+92>:  sgr     %r0,%r2
> >    0x000002aa000972c0 <+96>:  lgfr    %r2,%r0
> >    0x000002aa000972c4 <+100>: br      %r14
> > End of assembler dump.
> > (gdb) i r r2 r1
> > r2             0x80                128
> > r1             0xbe148             778568
> > (gdb) p &__clz_tab
> > $1 = (const UQItype (*)[256]) 0x2aa000be148 <__clz_tab>
> >
> > Digging into further, it seems that for s390 we need to self-relocate it first
> > before being able to access __clz_tab.
>
> And this is due static-pie, where extern symbol access in positionindependent
> code usually involves GOT indirection which needs RELATIVE relocs.  The __clzdi2
> and __clz_tab are in different TU:

Will this fix it?
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=f50cff9766c5e42e1f5d20fe3e6c135601341663
right?


More information about the Libc-alpha mailing list