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

Uros Bizjak ubizjak@gmail.com
Wed Aug 20 06:02:42 GMT 2025


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

Let's discuss this in GCC Bugzilla.

OTOH, is there a way in glibc to override the default x86_64
{rseq,tcb}-access.h with x32 specific version? Non-x32 targets work
without problems.

Uros.


More information about the Libc-alpha mailing list