Supporting emulated tls

Johannes Pfau nospam at example.com
Mon Mar 19 08:57:29 PDT 2012


Am Mon, 19 Mar 2012 10:40:25 +0100
schrieb Jacob Carlborg <doob at me.com>:

> On 2012-03-19 09:15, Johannes Pfau wrote:
> > Am Sun, 18 Mar 2012 21:57:57 +0100
> > schrieb Jacob Carlborg<doob at me.com>:
> >
> >> On 2012-03-18 12:32, Johannes Pfau wrote:
> >>> I thought about supporting emulated tls a little. The GCC emutls.c
> >>> implementation currently can't work with the gc, as every TLS
> >>> variable is allocated individually and therefore we don't have a
> >>> contiguous memory region for the gc. I think these are the
> >>> possible solutions:
> >>
> >> Why not use the native TLS implementation when available and roll
> >> our own, like DMD on Mac OS X, when none exists?
> >
> > That's what we (mostly) do right now. We have 2 issues:
> >
> > * Our own, emulated TLS support is implemented in GCC. This means
> > it's also used in C, which is great. Also GCC's emulated tls needs
> >    absolutely no special features in the runtime linker, compile
> > time linker or language frontends. It's very portable and works
> > with all weird combinations of dynamic libraries, dlopen, etc.
> >    But it has one quirk: It doesn't allocate TLS memory in a
> > contiguous way, every tls variable is allocated using malloc. This
> > means we can't pass a range to the GC for the tls variables. So we
> > can't support this emutls in the GC.
> 
> Ok, I see.
> 
> > * The other issue with native TLS is that using bracketing with
> >    __tls_beg and __tls_end has corner cases where it doesn't work.
> > We'd need an alternative to locate the TLS memory addresses and TLS
> > sizes. But there's no standard or public API to do that.
> 
> On Mac OS X they are actually not needed. Don't know about other
> platforms.
> 
> >> BTW, I think it would be possible to emulate TLS in a very similar
> >> way to how it's implemented natively for ELF.
> >>
> >
> > I don't think it's that easy. For example, how would you assign
> > module ids? For native TLS this is partially done by the compile
> > time linker (for the main application and libraries that are always
> > loaded), but if no native TLS is available, we can't rely on the
> > linker to do that. We also need some way to get the current module
> > id in running code.
> 
> As I understand it, in the native ELF implementation, assembly is
> used to access the current module id, this is for FreeBSD:
> 
> http://people.freebsd.org/~marcel/tls.html
> 
> This is how ___tls_get_addr is implemented on FreeBSD ELF i386:
> 
> https://bitbucket.org/freebsd/freebsd-head/src/4e8f50fe2f05/libexec/rtld-elf/i386/reloc.c#cl-355

Yep and the module id is part of the tls_index parameter. That pointer
is a pointer into the GOT. The initial values of that GOT entry are
undefined, they are filled in by the runtime linker. We could probably
emulate all that, but it seems a little complicated to me. If we can
get the current emutls to work, that be awesome even if it's slow.
Proper native TLS support is easier to implement in the runtime linker
anyway.

> > And how do we get the TLS initialization data? If we placed it into
> > an array, like DMD does on OSX, we could use dlsym for dlopened
> > libraries, but what about initially loaded libraries?
> 
> In the same way it's done in the native implementation. Isn't it 
> possible to access all loaded libraries?

The only way to access all loaded library is dl_iterate_phdr. But I'm
not sure if it provides all necessary information.

> 
> > Say you have application 'app', which depends on 'liba' and 'libb'.
> > All of these have TLS data. Maybe we could implement something using
> > dl_iterate_phdr, but that's a nonstandard extension.
> 
> Ok. Mac OS X has this a function called 
> "_dyld_register_func_for_add_image", I guess other OS'es don't have a 
> corresponding function? In general all this stuff very low level and 
> nonstandard.

Some C libraries might provide a similar API, but there's no guarantee
such an API is available.

> 
> https://developer.apple.com/library/mac/#documentation/developertools/Reference/MachOReference/Reference/reference.html#jumpTo_53
> 
> > Compare that to GCC's emulation, which is probably slow, but 'just
> > works' everywhere (except for the GC :-( ).
> 
> Yeah, that's a big advantage.
> 
> In general I was hoping that the work done by the dynamic loader to 
> setup TLS could be moved to druntime.
> 

That'd be nice, but I think the runtime linker doesn't export all
necessary information.



More information about the D.gnu mailing list