[PATCH 34/59] x86: Fix THREAD_GSCOPE_RESET_FLAG build on clang
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Mon Oct 20 19:18:49 GMT 2025
On 20/10/25 16:09, Uros Bizjak wrote:
> On Mon, Oct 20, 2025 at 8:47 PM Adhemerval Zanella Netto
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>>
>> On 19/10/25 12:21, Uros Bizjak wrote:
>>>
>>>
>>> On 10/17/25 21:13, Adhemerval Zanella wrote:
>>>> clang does not support __seg_fs in asm constraint.
>>>> ---
>>>> sysdeps/x86_64/nptl/tls.h | 21 +++++++++++++++++----
>>>> 1 file changed, 17 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
>>>> index abfeb88054..2c4b9aaa80 100644
>>>> --- a/sysdeps/x86_64/nptl/tls.h
>>>> +++ b/sysdeps/x86_64/nptl/tls.h
>>>> @@ -198,13 +198,26 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
>>>> # define THREAD_GSCOPE_FLAG_UNUSED 0
>>>> # define THREAD_GSCOPE_FLAG_USED 1
>>>> # define THREAD_GSCOPE_FLAG_WAIT 2
>>>> +
>>>> +/* clang does not support __seg_fs in asm constraint. */
>>>> +# ifdef __clang__
>>>> +# define XCHGL_GSCOPE(__r) \
>>>> + asm volatile ("xchgl %0, %%fs:%P1" \
>>>> + : "=r" (__r) \
>>>> + : "i" (offsetof (struct pthread, header.gscope_flag)), \
>>>> + "0" (THREAD_GSCOPE_FLAG_UNUSED))
>>>
>>> This needs a "memory" clobber, because this asm hides memory access
>>> from the compiler. Please see the "memory" special clobber argument
>>> section in [1].
>>>
>>> Also, please use the "c" operand modifier instead of "P". Clang allows
>>> "c" with "i" constraint and also checks that operand fits "c".
>>
>> Ack.
>>
>>>
>>> Clang accepts __seg_fs prefixed addresses, it just "forgets" to emit %fs: prefix in the generated code. While this could be considered a bug with clang, the simplest solution is to just conditionally put "%%fs:" prefix in the asm template for clang.
>>
>> We also need to use a 'i' constraint, clang does not accept 'm' witha
>> '((struct pthread __seg_fs *)0)->header.gscope_flag'.
>
> Hm, it works for me, at least for the following testcase:
>
> --cut here--
> struct pthread
> {
> struct
> {
> int multiple_threads;
> int gscope_flag;
> } header;
> void *__padding[24];
> };
>
> int baz(void)
> {
> int __res;
> asm volatile ("xchgl %%fs:%1, %0"
> : "=r" (__res)
> : "m" (((struct pthread __seg_fs *)0)->header.gscope_flag),
> "0" (0));
> return __res;
> }
> --cut here--
>
> $ clang -O2 -c tcbc.c
> $ objdump -dr tcbc.o
>
> 0000000000000000 <baz>:
> 0: 31 c0 xor %eax,%eax
> 2: 64 87 04 25 04 00 00 xchg %eax,%fs:0x4
> 9: 00
> a: c3 ret
>
> $ clang --version
> clang version 20.1.8 (Fedora 20.1.8-4.fc42)
> Target: x86_64-redhat-linux-gnu
Indeed, it was not working on my side due a wrong constraint for '%1'.
I will update the patch.
More information about the Libc-alpha
mailing list