separate __tls_get_addr implementation from dynamic linker/init_tls

such separation serves multiple purposes:

- by having the common path for __tls_get_addr alone in its own
  function with a tail call to the slow case, code generation is
  greatly improved.

- by having __tls_get_addr in it own file, it can be replaced on a
  per-arch basis as needed, for optimization or ABI-specific purposes.

- by removing __tls_get_addr from __init_tls.c, a few bytes of code
  are shaved off of static binaries (which are unlikely to use this
  function unless the linker messed up).
This commit is contained in:
Rich Felker 2014-06-19 02:59:44 -04:00
commit 5ba238e1e4
3 changed files with 23 additions and 11 deletions

View file

@ -0,0 +1,17 @@
#include <stddef.h>
#include "pthread_impl.h"
#include "libc.h"
void *__tls_get_new(size_t *) ATTR_LIBC_VISIBILITY;
void *__tls_get_addr(size_t *v)
{
pthread_t self = __pthread_self();
#ifdef SHARED
if (v[0]<=(size_t)self->dtv[0])
return (char *)self->dtv[v[0]]+v[1];
return __tls_get_new(v);
#else
return (char *)self->dtv[1]+v[1];
#endif
}