This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug inline-asm/66631] inability to clobber segment regs makes tls problematic
- From: "stsp at users dot sourceforge.net" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 22 Jun 2015 23:11:29 +0000
- Subject: [Bug inline-asm/66631] inability to clobber segment regs makes tls problematic
- Auto-submitted: auto-generated
- References: <bug-66631-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66631
--- Comment #3 from Stas Sergeev <stsp at users dot sourceforge.net> ---
The signal handler needs to do the following things:
1. Restore segment registers (init_handler() func)
2. Increment thread-local var (fault_cnt)
3. Do stuff including reads of fault_cnt var
Being thread-local, fault_cnt var is being accessed
with the help of FS, but FS is only valid after the
call to init_handler().
Since fault_cnt is marked as volatile, gcc does not
move the access to it above the init_handler() call,
so that part is fine. What is NOT fine is this:
0x00000000004438d4 <+20>: mov %fs:0x0,%rbp <-- (bad) TLS
access
0x00000000004438dd <+29>: push %rbx
0x00000000004438de <+30>: add $0xffffffffffffff80,%rsp
0x00000000004438e2 <+34>: callq 0x4441b0 <init_handler> <-- FS now
valid
0x00000000004438e7 <+39>: mov 0x35070a(%rip),%rbx # 0x793ff8
0x00000000004438ee <+46>: mov 0x0(%rbp,%rbx,1),%eax <-- STACK
FAULT
As you can see, gcc moved some TLS access above init_handler(),
which results in a stack fault later when trying to read from
fault_cnt.
To prevent moving any TLS access around init_handler(), I need
to do the following:
asm volatile("":::"fs");
but this gives a compilation error.
Is the explanation clear?