http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066

            Bug ID: 58066
           Summary: GCC mis-compiles access to TLS variable with -fPIC on
                    x86_64
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ppluzhnikov at google dot com

Google ref: b/10151411

Reproduced with current trunk, but is broken since at least gcc-4.3.1.

On Linux/x86_64, libstdc++.so.6 __cxa_get_globals looks like so:

Dump of assembler code for function __cxa_get_globals:
   0x00000000000cb430 <+0>:     lea    0x233131(%rip),%rdi
   0x00000000000cb437 <+7>:     callq  0x4f570 <__tls_get_addr@plt>
   0x00000000000cb43c <+12>:    add    $0x0,%rax
   0x00000000000cb442 <+18>:    retq   

This calls external function __tls_get_addr with mis-aligned stack.
__tls_get_addr may itself call malloc, and malloc is user-replaceable,
and may assume that stack is properly aligned (and crash when it isn't).

Trivial test case:


static __thread char ccc;
extern "C" void* __cxa_get_globals() throw()
{
 return &ccc;
}

  g++ -fPIC -S -O2 t.cc

results in:

__cxa_get_globals:
       leaq    _ZL3ccc@tlsld(%rip), %rdi
       call    __tls_get_addr@PLT
       addq    $_ZL3ccc@dtpoff, %rax
       ret



Ian Lance Taylor says:

  There is code in the i386 backend that is designed to avoid this.
  However, it appears to have only been fully implemented for the GNU2 TLS
  descriptor style ...

  I suspect that the right fix is to add the line

     ix86_tls_descriptor_calls_expanded_in_cfun = true;

  to tls_global_dynamic_64_<mode> and tls_local_dynamic_base_64_<mode>
  in gcc/config/i386/i386.md.

Reply via email to