[MCJIT] TLS relocation design

Folks,

I’d like to start discussing the path forward for adding TLS support to MCJT. The relevant bug is http://llvm.org/bugs/show_bug.cgi?id=21431.

Since the ABI for TLS is really defined by the C library, it seems like we need to define a flexible interface that would allow RuntimeDyld to request whatever information it needs. We could then implement the most common schemes on platforms that we care about, but we should be sure that the interface we define is general enough to nor require rewriting as new platforms are added to MCJIT (I’m particularly looking at COFF/Windows support here). Thus, I’d like to get a sense of how the different TLS implementations work and what kind of API a potential TLSImplementation class would have to provide

As noted in the bug report, I have an implementation implementation of this for ELF/x86_64, so I’ll start by describing what was necessary to get that running (I did this a year ago, so this is my best recollection). For starters, this link describes the general ELF ABI much better than I could (it has illustrations!): http://www.akkadia.org/drepper/tls.pdf.

Now, the relocation in question is R_X86_64_TLSGD (this is for the general dynamic tls model, I didn’t investigate anything else. To process the relocation, we need to add two GOT entries, one for the dynamic module id and one for the offset in that dynamic module’s TLS block. I had originally hoped that there was a dlsym like API that would give me this information, but unfortunately, there is not (and this is where the hacky part comes in). Instead what I do is dlsym the symbol and then manually go trough all the dynamic modules for the current thread (using the dtv, which I happen to know is at pthread_self()[1] on glibc - this could probably be done by going through the TLS segment registers, though I didn’t manage to do it back when I implemented this) and compute the information by picking the first dynamic module whose TLS block starts before the address we got back from dlsym (also giving us the offset). This works well, but feels very hacky and is probably horribly dependent on the C library used.

Thus it seems, for ELF, all that’s required of a potential TLS implementation class is a TLSdlsym that gives us the module and offset information. I’d like to find out what we need to handle Darwin and Windows (does somebody have a good reference that describes the TLS scheme on these platforms). Perhaps we can also talk to the C library maintainers to get an API that gives us this information directly.

Thanks,
Keno

As noted in the bug report, I have an implementation implementation of this
for ELF/x86_64, so I'll start by describing what was necessary to get that
running (I did this a year ago, so this is my best recollection). For
starters, this link describes the general ELF ABI much better than I could
(it has illustrations!): http://www.akkadia.org/drepper/tls.pdf.

It's been a while since I knew this stuff well, but that looks like
it's describing the old version of TLS. A more optimised specification
has been created since (and it's what AArch64 uses exclusively as far
as I'm aware). This looks like the documentation I read before:
http://www.fsfla.org/~lxoliva/writeups/TLS/RFC-TLSDESC-x86.txt

Thus it seems, for ELF, all that's required of a potential TLS
implementation class is a `TLSdlsym` that gives us the module and offset
information. I'd like to find out what we need to handle Darwin and Windows
(does somebody have a good reference that describes the TLS scheme on these
platforms). Perhaps we can also talk to the C library maintainers to get an
API that gives us this information directly.

I think Darwin's is currently a fairly thin wrapper around the
pthread_key_* functions. It's mostly undocumented, unfortunately, and
I'm not sure I ever knew exactly what the linker & dynamic loader's
responsibilities were.

Cheers.

Tim.

Alright, having looked into COFF, it seems that on Windows you can only access TLS in the current module (executable or shared library). Seems like a big limitation, but I guess it makes it easier on us, since we don’t need to do much to support it. I think I now have a pretty good understanding of the different TLS schemes in use. I’ll try to come up with an outline of an API and post a patch for review.