I had already implemented thread-local storage support for simple statically linked binaries, which worked fine like this:
- Create a copy of the TLS master for each thread
- Put the address of the self-referencing user-thread-object which resides right after the TLS content into an GDT entry
- Write the index of the GDT entry into the GS register
test.bin
Code: Select all
__thread int foo = 12;
int main(int argc, char** argv)
{
foo = 5;
errno = 4;
mySharedLibraryFunction();
}
Code: Select all
__thread int bar = 25;
void mySharedLibraryFunction()
{
bar = 3;
errno = 12;
}
- For "foo" everything seems to work normally, reading and writing it.
- The executable contains a relocation entry for "errno":
Code: Select all
08049660 0000010e R_386_TLS_TPOFF 00000000 errno
- My "libc.so" also contains a relocation entry for "errno":
Code: Select all
000385e0 00004e23 R_386_TLS_DTPMOD3 00000000 errno 000385e4 00004e24 R_386_TLS_DTPOFF3 00000000 errno
- My shared library contains relocation entries for "errno" and "bar":
Code: Select all
000017e4 00000123 R_386_TLS_DTPMOD3 00000000 errno 000017e8 00000124 R_386_TLS_DTPOFF3 00000000 errno 000017ec 00000923 R_386_TLS_DTPMOD3 00000000 bar 000017f0 00000924 R_386_TLS_DTPOFF3 00000000 bar
- In runtime, when the shared library tries to write "errno" or "bar", a function called "___tls_get_addr" is called for which I have created a stub but not yet found out what it's supposed to do...
But what are the relocation entries supposed to be filled with? I can't just put some fixed address in there because it would have to change when switching threads...
Also I guess "__tls_get_addr" is called at runtime to get the TLS location for the current thread, but what exactly should it return?
Thankful for any help already!
Greets