<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Static TLS for i386: addend ignored"
   href="https://llvm.org/bugs/show_bug.cgi?id=29068">29068</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Static TLS for i386: addend ignored
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>lld
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>other
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>release blocker
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>ELF
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>ed@80386.nl
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider the following piece of code:

#include <stdio.h>

_Thread_local struct {
  int x, y, z;
} var = { .x = 12, .y = 34, .z = 56 };

void print(int);

int main() {
  print(var.y);
}

Compiling it for i686 will yield the following main() function (abbreviated):

main:
        movl    %gs:0, %eax
        pushl   var@NTPOFF+4(%eax)
        calll   print
        addl    $4, %esp
        xorl    %eax, %eax
        retl

Now, changing the call to print() to var.z, we get:

main:
        movl    %gs:0, %eax
        pushl   var@NTPOFF+8(%eax)
        calll   print
        addl    $4, %esp
        xorl    %eax, %eax
        retl

This is all good. Now this is where the interesting part starts. If we link it
into a simple executable, we always generate the following code (as in, it
doesn't matter if var.y or var.z is used):

00014750 <main>:
   14750:       65 a1 00 00 00 00       mov    %gs:0x0,%eax
   14756:       ff b0 dc ff ff ff       pushl  -0x24(%eax)
   1475c:       e8 0f 00 00 00          call   14770 <print>
   14761:       83 c4 04                add    $0x4,%esp
   14764:       31 c0                   xor    %eax,%eax
   14766:       c3                      ret

The value that is passed to print() is equal to twelve. In other words, the
linker completely ignores the addend of the relocation, always making it use
the first element in the structure.

I'll debug this issue in more detail. Marking this as a blocker for LLVM 3.9,
as it makes PIE effectively broken when used in non-PIE code on i386. The issue
is both present in trunk and 3.9rc1.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>