
On November 15, 2009 07:42:46 Goetz Isenmann wrote:
001e5565 <__hscore_get_errno>: 1e5565: 55 push %ebp 1e5566: 89 e5 mov %esp,%ebp 1e5568: 65 a1 00 00 00 00 mov %gs:0x0,%eax 1e556e: 8b 15 00 00 00 00 mov 0x0,%edx 1e5574: 8b 04 10 mov (%eax,%edx,1),%eax 1e5577: c9 leave 1e5578: c3 ret
The corresponding relocation info is
001e5570 R_386_TLS_IE errno
After some googling, and learning very little, I speclated that simply adding a third line for R_386_TLS_IE with the same action as the first line - just storing value, might work:
case R_386_TLS_IE: *pP = value; break;
This seems to work up to a point. That is I get no crashes in ghci.
According to "ELF Handling For Thread-Local Storage", R_386_TLS_IE "resolves to the absolute address of the GOT [global offset table] slot" that is assigned to the TLS (thread local storage) symbol. http://people.redhat.com/drepper/tls.pdf (middle of page 37) The GOT slot is assigned a R_386_TLS_TPOFF relocation for the symbol. So, what you are suppose to get is: 1- While linking, the linker resolves the R_386_TLS_IE relocation by updating the instruction with the absolute address of the corresponding GOT slot. 2- While loading, the dynamic linker resolves the R_386_TLS_TPOFF relocation by updating the GOT slot to contain the offset of the symbol relative to the TLS pointer (which is stored at %gs:0x0). 3- The program then computes the address of the TLS variable by loading the TLS pointer (the "mov %gs:0x0,%eax" instruction) and adding to it the symbols TLS offset as stored in the GOT table (the updated "mov 0x0,%edx" instruction). Cheers! -Tyson