[PATCH 2/2] x86_64: Use __seg_fs qualifiers in NPTL accessors

Uros Bizjak ubizjak@gmail.com
Wed Aug 20 12:46:00 GMT 2025


On Wed, Aug 20, 2025 at 2:30 PM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Uros Bizjak:
>
> > Hm, the original approach does this:
> >
> >        asm volatile ("movl %%fs:%P1(%q2),%0"
> >                       : "=r" (__value)
> >                       : "i" (offsetof (struct rseq_area, member)),
> >                         "r" ((long long int) __rseq_offset));
> >
> > Won't this also segfault with negative __rseq_offset?
>
> It works because it's sign-extending into an r register.  Only the
> loaded quantity is 32 bits.  This was changed in:
>
> commit 0b6ad02b33448c0b8b6fdd781dffad329d1f0f7d
> Author: H.J. Lu <hjl.tools@gmail.com>
> Date:   Sat Jan 11 22:57:02 2025 +0800
>
>     x86-64: Cast __rseq_offset to long long int [BZ #32543]
>
>     commit 494d65129ed5ae1154b75cc189bbdde5e9ecf1df
>     Author: Michael Jeanson <mjeanson@efficios.com>
>     Date:   Thu Aug 1 10:35:34 2024 -0400
>
>         nptl: Introduce <rseq-access.h> for RSEQ_* accessors
>
>     added things like
>
>            asm volatile ("movl %%fs:%P1(%q2),%0"                                  \
>                          : "=r" (__value)                                         \
>                          : "i" (offsetof (struct rseq_area, member)),             \
>                            "r" (__rseq_offset));                                  \
>
>     But this doesn't work for x32 when __rseq_offset is negative since the
>     address is computed as
>
>     FS + 32-bit to 64-bit zero extension of __rseq_offset
>     + offsetof (struct rseq_area, member)
>
>     Cast __rseq_offset to long long int
>
>                            "r" ((long long int) __rseq_offset));                  \
>
>     to sign-extend 32-bit __rseq_offset to 64-bit.  This is a no-op for x86-64
>     since x86-64 __rseq_offset is 64-bit.  This fixes BZ #32543.
>
>     Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
>     Reviewed-by: Florian Weimer <fweimer@redhat.com>
>
> You could move this implementation into
> sysdeps/unix/sysv/linux/x86_64/x32/rseq-access.h.  But the other
> architectures should move out …/nptl/… for consistency.

Thanks for your explanation, now these %q assembler operand overrides
make perfect sense. IMO, x32 is just weird w.r.t. address segment
overrides. With named address spaces, the compiler is free to cache
the address in the register (or apply other address calculation
optimizations), so even tcb-access.h should remain implemented in
assembler for x32.

BTW: The GCC PR is at [1].

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121613

Thanks,
Uros.


More information about the Libc-alpha mailing list