[PATCH v2] x32: Use THREAD_SELF for RSEQ_* accessors
Uros Bizjak
ubizjak@gmail.com
Sat Aug 23 08:34:06 GMT 2025
On Fri, Aug 22, 2025 at 10:19 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> Use THREAD_SELF to get the %fs register to work around the GCC bug:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121613
>
> with the negative offset from the %fs register. Comparing against the
> asm statements, for RSEQ_GETMEM_ONCE in sched_getcpu:
>
> asm statements C with THREAD_SELF
> endbr64 endbr64
> subl $40, %esp subl $40, %esp
> > movl __rseq_offset(%rip),
> movl %fs:24, %eax movl %fs:24, %eax
> movl %eax, 28(%rsp) movl %eax, 28(%rsp)
> movslq __rseq_offset(%rip), | movl %fs:8, %eax
> movl %fs:4(%rax),%eax | leal 4(%rax,%rdx), %eax
> > movl (%eax), %eax
So, instead of one memory access:
movl %fs:4(%rax),%eax
we now have two:
movl %fs:8, %eax
movl (%eax), %eax
for *every* access to the RSEQ area. This nullifies all optimization
efforts to use direct %fs references to TCB, and is IMO too high a
price to pay for a more readable source. For this workaround, assembly
is hands down a better choice, and the eventual GCC fix will also be
similar: sign-extend the non-const value to a temporary DImode
register
IMO the approach that creates direct %fs reference with assembly
outweighs the slightly more complex source. Also, please note that the
current assembler implementation lacks "memory" clobber, for which I
am preparing a patch.
An alternative approach would be to figure why is __rseq_offset
negative. One would expect that since %fs points to the beginning of
the TCB block, then all offsets from %fs should be positive. Perhaps
the RSEQ area could be placed elsewhere in the TCB block to guarantee
positive offset?
Uros.
More information about the Libc-alpha
mailing list