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

Uros Bizjak ubizjak@gmail.com
Wed Aug 20 12:01:30 GMT 2025


On Wed, Aug 20, 2025 at 8:02 AM Uros Bizjak <ubizjak@gmail.com> wrote:
>
> On Wed, Aug 20, 2025 at 5:19 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > On Tue, Aug 19, 2025 at 8:06 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >
> > > On Sun, Aug 17, 2025 at 8:50 AM Uros Bizjak <ubizjak@gmail.com> wrote:
> > > >
> > > > Use __seg_fs named address space qualifiers to cast NPTL accessors
> > > > to %fs: prefixed addresses.  Use volatile access only where
> > > > strictly necessary.
> > > >
> > > > Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
> > > > Cc: H.J.Lu <hjl.tools@gmail.com>
> > > > Cc: Florian Weimer <fweimer@redhat.com>
> > > > Cc: Carlos O'Donell <carlos@redhat.com>
> > > > ---
> > > >  sysdeps/x86_64/nptl/rseq-access.h |  82 ++++++++-----------
> > > >  sysdeps/x86_64/nptl/tcb-access.h  | 127 ++++++++----------------------
> > > >  2 files changed, 66 insertions(+), 143 deletions(-)
> > > >
> > > > diff --git a/sysdeps/x86_64/nptl/rseq-access.h b/sysdeps/x86_64/nptl/rseq-access.h
> > > > index bc966b2972..214cb96797 100644
> > > > --- a/sysdeps/x86_64/nptl/rseq-access.h
> > > > +++ b/sysdeps/x86_64/nptl/rseq-access.h
> > > > @@ -16,34 +16,38 @@
> > > >     License along with the GNU C Library; if not, see
> > > >     <https://www.gnu.org/licenses/>.  */
> > > >
> > > > +/* Read member of the RSEQ area directly.  */
> > > > +#define RSEQ_GETMEM(member) \
> > > > +  ({                                                                         \
> > > > +     _Static_assert (sizeof (RSEQ_SELF()->member) == 1                       \
> > > > +                    || sizeof (RSEQ_SELF()->member) == 4                     \
> > > > +                    || sizeof (RSEQ_SELF()->member) == 8,                    \
> > > > +                    "size of rseq data");                                    \
> > > > +     (*(__typeof (RSEQ_SELF()->member) __seg_fs *)                           \
> > > > +      (__rseq_offset + offsetof (struct rseq_area, member)));                \
> >
> > info: __rseq_offset: -192
> >
> > %fs + negative offset doesn't work for x32.
>
> That is unfortunate, and also means that named address space handling
> is fundamentally broken in GCC for x32:
>
> --cut here--
> extern const long __rseq_offset;
>
> struct rseq_area
> {
>   int a;
>   int b;
>   int c;
> };
>
> int read_rseq (void)
> {
>   int val = (*(volatile int __seg_fs *)
>          (__rseq_offset + __builtin_offsetof (struct rseq_area, c)));
>   return val;
> }
> --cut here--
>
> gcc -O2 -mx32:
>
> read_rseq:
>        movl    __rseq_offset(%rip), %eax
>        movl    %fs:8(%eax), %eax
>        ret

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?

Uros.


More information about the Libc-alpha mailing list