cat > bug.d << CODE
int bar;
int foo()
{
return bar;
}
CODE
dmd -m32 -c -fPIC bug.d
readelf -r bug.o
----
0000000b 0000160f R_386_TLS_IE 00000000 _D3foo3bari
----
This TLS relocation uses the 'initial exec' model, which is not suited for PIC code. It should use the 'general dynamic' model (R_386_TLS_GD).
Reference http://www.akkadia.org/drepper/tls.pdf
Comment #1 by code — 2014-02-06T17:47:07Z
I was already able to fix the relocation type and make the compiler call __tls_get_addr.
https://github.com/MartinNowak/dmd/commits/fix12092
Now I'm stuck!
The code sequence to load the __tls_get_addr argument is incorrect. It ought to use a LEA with SIB addressing to leave patch room for the linker. Instead it just uses a simple LEA.
Should be:
13: 8d 04 1d 00 00 00 00 lea 0x0(,%ebx,1),%eax
1a: e8 fc ff ff ff call 1b <foo+0x1b>
Is:
17: 8d 81 00 00 00 00 lea 0x0(%ecx),%eax
1d: e8 fc ff ff ff call 1e <_D3foo3fooFZi+0x1e>