chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / debian / patches / hurd-i386 / local-tls-support.diff
1 TLS support
2
3 ---
4  csu/libc-start.c                        |    2 +
5  hurd/hurdfault.c                        |    2 +
6  hurd/hurdsig.c                          |    4 +-
7  mach/mach.h                             |    3 +
8  mach/setup-thread.c                     |   30 +++++++++++++++-
9  ports/sysdeps/mach/alpha/thread_state.h |    1 
10  sysdeps/generic/thread_state.h          |    1 
11  sysdeps/mach/hurd/bits/libc-lock.h      |    3 +
12  sysdeps/mach/hurd/bits/libc-tsd.h       |   35 ------------------
13  sysdeps/mach/hurd/fork.c                |    7 +++
14  sysdeps/mach/hurd/i386/init-first.c     |   60 +++++++++++++++++++-------------
15  sysdeps/mach/hurd/i386/tls.h            |   55 ++++++++++++++++++++++++-----
16  sysdeps/mach/hurd/i386/tlsdesc.sym      |   17 +++++++++
17  sysdeps/mach/hurd/i386/trampoline.c     |    2 -
18  sysdeps/mach/hurd/profil.c              |    2 +
19  sysdeps/mach/hurd/setitimer.c           |    3 +
20  sysdeps/mach/hurd/tls.h                 |    2 +
21  sysdeps/mach/i386/thread_state.h        |   11 +++++
22  sysdeps/mach/powerpc/thread_state.h     |    1 
23  sysdeps/mach/thread_state.h             |    3 +
24  20 files changed, 169 insertions(+), 75 deletions(-)
25
26 --- a/csu/libc-start.c
27 +++ b/csu/libc-start.c
28 @@ -140,10 +140,12 @@
29    /* Performe IREL{,A} relocations.  */
30    __libc_csu_irel ();
31  
32 +#ifndef __GNU__
33    /* Initialize the thread library at least a bit since the libgcc
34       functions are using thread functions if these are available and
35       we need to setup errno.  */
36    __pthread_initialize_minimal ();
37 +#endif
38  
39    /* Set up the stack checker's canary.  */
40    uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
41 --- a/hurd/hurdfault.c
42 +++ b/hurd/hurdfault.c
43 @@ -206,6 +206,8 @@
44    /* This state will be restored when we fault.
45       It runs the function above.  */
46    memset (&state, 0, sizeof state);
47 +
48 +  MACHINE_THREAD_STATE_FIX_NEW (&state);
49    MACHINE_THREAD_STATE_SET_PC (&state, faulted);
50    MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack);
51  
52 --- a/hurd/hurdsig.c
53 +++ b/hurd/hurdsig.c
54 @@ -1268,6 +1268,8 @@
55                                  (vm_address_t *) &__hurd_sigthread_stack_base,
56                                  &stacksize);
57        assert_perror (err);
58 +      err = __mach_setup_tls (_hurd_msgport_thread);
59 +      assert_perror (err);
60  
61        __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
62        __hurd_sigthread_variables =
63 @@ -1276,8 +1278,6 @@
64         __libc_fatal ("hurd: Can't allocate threadvars for signal thread\n");
65        memset (__hurd_sigthread_variables, 0,
66               __hurd_threadvar_max * sizeof (unsigned long int));
67 -      __hurd_sigthread_variables[_HURD_THREADVAR_LOCALE]
68 -       = (unsigned long int) &_nl_global_locale;
69  
70        /* Reinitialize the MiG support routines so they will use a per-thread
71          variable for the cached reply port.  */
72 --- a/mach/mach.h
73 +++ b/mach/mach.h
74 @@ -101,5 +101,8 @@
75                                  vm_address_t *stack_base,
76                                  vm_size_t *stack_size);
77  
78 +/* Give THREAD a TLS area.  */
79 +kern_return_t __mach_setup_tls (thread_t thread);
80 +kern_return_t mach_setup_tls (thread_t thread);
81  
82  #endif /* mach.h */
83 --- a/mach/setup-thread.c
84 +++ b/mach/setup-thread.c
85 @@ -20,6 +20,7 @@
86  #include <thread_state.h>
87  #include <string.h>
88  #include <mach/machine/vm_param.h>
89 +#include <ldsodefs.h>
90  #include "sysdep.h"            /* Defines stack direction.  */
91  
92  #define        STACK_SIZE      (16 * 1024 * 1024) /* 16MB, arbitrary.  */
93 @@ -73,8 +74,35 @@
94    if (error = __vm_protect (task, stack, __vm_page_size, 0, VM_PROT_NONE))
95      return error;
96  
97 -  return __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
98 +  return __thread_set_state (thread, MACHINE_NEW_THREAD_STATE_FLAVOR,
99                              (natural_t *) &ts, tssize);
100  }
101  
102  weak_alias (__mach_setup_thread, mach_setup_thread)
103 +
104 +/* Give THREAD a TLS area.  */
105 +kern_return_t
106 +__mach_setup_tls (thread_t thread)
107 +{
108 +  kern_return_t error;
109 +  struct machine_thread_state ts;
110 +  mach_msg_type_number_t tssize = MACHINE_THREAD_STATE_COUNT;
111 +  tcbhead_t *tcb;
112 +
113 +  if (error = __thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR,
114 +                            (natural_t *) &ts, &tssize))
115 +    return error;
116 +  assert (tssize == MACHINE_THREAD_STATE_COUNT);
117 +
118 +  tcb = _dl_allocate_tls(NULL);
119 +  if (!tcb)
120 +    return KERN_RESOURCE_SHORTAGE;
121 +
122 +  _hurd_tls_new(thread, &ts, tcb);
123 +
124 +  error = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
125 +                            (natural_t *) &ts, tssize);
126 +  return error;
127 +}
128 +
129 +weak_alias (__mach_setup_tls, mach_setup_tls)
130 --- a/sysdeps/generic/thread_state.h
131 +++ b/sysdeps/generic/thread_state.h
132 @@ -23,6 +23,7 @@
133  
134  /* Replace <machine> with "i386" or "mips" or whatever.  */
135  
136 +#define MACHINE_NEW_THREAD_STATE_FLAVOR        <machine>_NEW_THREAD_STATE
137  #define MACHINE_THREAD_STATE_FLAVOR    <machine>_THREAD_STATE
138  #define MACHINE_THREAD_STATE_COUNT     <machine>_THREAD_STATE_COUNT
139  
140 --- a/ports/sysdeps/mach/alpha/thread_state.h
141 +++ b/ports/sysdeps/mach/alpha/thread_state.h
142 @@ -19,6 +19,7 @@
143  
144  #include <mach/machine/thread_status.h>
145  
146 +#define MACHINE_NEW_THREAD_STATE_FLAVOR        ALPHA_THREAD_STATE
147  #define MACHINE_THREAD_STATE_FLAVOR    ALPHA_THREAD_STATE
148  #define MACHINE_THREAD_STATE_COUNT     ALPHA_THREAD_STATE_COUNT
149  
150 --- a/sysdeps/mach/hurd/bits/libc-tsd.h
151 +++ /dev/null
152 @@ -1,35 +0,0 @@
153 -/* libc-internal interface for thread-specific data.  Hurd version.
154 -   Copyright (C) 1998,2002,2008 Free Software Foundation, Inc.
155 -   This file is part of the GNU C Library.
156 -
157 -   The GNU C Library is free software; you can redistribute it and/or
158 -   modify it under the terms of the GNU Lesser General Public
159 -   License as published by the Free Software Foundation; either
160 -   version 2.1 of the License, or (at your option) any later version.
161 -
162 -   The GNU C Library is distributed in the hope that it will be useful,
163 -   but WITHOUT ANY WARRANTY; without even the implied warranty of
164 -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
165 -   Lesser General Public License for more details.
166 -
167 -   You should have received a copy of the GNU Lesser General Public
168 -   License along with the GNU C Library; if not, write to the Free
169 -   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
170 -   02111-1307 USA.  */
171 -
172 -#ifndef _BITS_LIBC_TSD_H
173 -#define _BITS_LIBC_TSD_H 1
174 -
175 -#include <hurd/threadvar.h>
176 -
177 -#define __libc_tsd_define(CLASS, TYPE, KEY) /* nothing, always have threadvars */
178 -
179 -#define __libc_tsd_address(TYPE, KEY) \
180 -  ((TYPE *) __hurd_threadvar_location (_HURD_THREADVAR_##KEY))
181 -
182 -#define __libc_tsd_get(TYPE, KEY) \
183 -  (*__libc_tsd_address (TYPE, KEY))
184 -#define __libc_tsd_set(TYPE, KEY, VALUE) \
185 -  (*__libc_tsd_address (TYPE, KEY) = (VALUE))
186 -
187 -#endif /* bits/libc-tsd.h */
188 --- a/sysdeps/mach/hurd/fork.c
189 +++ b/sysdeps/mach/hurd/fork.c
190 @@ -523,6 +523,11 @@
191  #endif
192        MACHINE_THREAD_STATE_SET_PC (&state,
193                                    (unsigned long int) _hurd_msgport_receive);
194 +
195 +      /* Do special thread setup for TLS if needed.  */
196 +      if (err = _hurd_tls_fork (sigthread, _hurd_msgport_thread, &state))
197 +       LOSE;
198 +
199        if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR,
200                                     (natural_t *) &state, statecount))
201         LOSE;
202 @@ -533,7 +538,7 @@
203        _hurd_longjmp_thread_state (&state, env, 1);
204  
205        /* Do special thread setup for TLS if needed.  */
206 -      if (err = _hurd_tls_fork (thread, &state))
207 +      if (err = _hurd_tls_fork (thread, __mach_thread_self (), &state))
208         LOSE;
209  
210        if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
211 --- a/sysdeps/mach/hurd/i386/init-first.c
212 +++ b/sysdeps/mach/hurd/i386/init-first.c
213 @@ -104,10 +104,6 @@
214    char **argv = &arg0;
215    char **envp = &argv[argc + 1];
216    struct hurd_startup_data *d;
217 -#ifndef SHARED
218 -  extern ElfW(Phdr) *_dl_phdr;
219 -  extern size_t _dl_phnum;
220 -#endif
221  
222    while (*envp)
223      ++envp;
224 @@ -118,27 +114,9 @@
225       data block; the argument strings start there.  */
226    if ((void *) d == argv[0])
227      {
228 -#ifndef SHARED
229 -      /* We may need to see our own phdrs, e.g. for TLS setup.
230 -         Try the usual kludge to find the headers without help from
231 -        the exec server.  */
232 -      extern const void _start;
233 -      const ElfW(Ehdr) *const ehdr = &_start;
234 -      _dl_phdr = (ElfW(Phdr) *) ((const void *) ehdr + ehdr->e_phoff);
235 -      _dl_phnum = ehdr->e_phnum;
236 -      assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
237 -#endif
238        return;
239      }
240  
241 -#ifndef SHARED
242 -  __libc_enable_secure = d->flags & EXEC_SECURE;
243 -
244 -  _dl_phdr = (ElfW(Phdr) *) d->phdr;
245 -  _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
246 -  assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
247 -#endif
248 -
249    _hurd_init_dtable = d->dtable;
250    _hurd_init_dtablesize = d->dtablesize;
251  
252 @@ -172,13 +150,16 @@
253    char **envp = &argv[argc + 1];
254    struct hurd_startup_data *d;
255    unsigned long int threadvars[_HURD_THREADVAR_MAX];
256 +#ifndef SHARED
257 +  extern ElfW(Phdr) *_dl_phdr;
258 +  extern size_t _dl_phnum;
259 +#endif
260  
261    /* Provide temporary storage for thread-specific variables on the
262       startup stack so the cthreads initialization code can use them
263       for malloc et al, or so we can use malloc below for the real
264       threadvars array.  */
265    memset (threadvars, 0, sizeof threadvars);
266 -  threadvars[_HURD_THREADVAR_LOCALE] = (unsigned long int) &_nl_global_locale;
267    __hurd_threadvar_stack_offset = (unsigned long int) threadvars;
268  
269    /* Since the cthreads initialization code uses malloc, and the
270 @@ -192,6 +173,39 @@
271      ++envp;
272    d = (void *) ++envp;
273  
274 +  /* If we are the bootstrap task started by the kernel,
275 +     then after the environment pointers there is no Hurd
276 +     data block; the argument strings start there.  */
277 +  if ((void *) d == argv[0])
278 +    {
279 +#ifndef SHARED
280 +      /* We may need to see our own phdrs, e.g. for TLS setup.
281 +         Try the usual kludge to find the headers without help from
282 +        the exec server.  */
283 +      extern const void __executable_start;
284 +      const ElfW(Ehdr) *const ehdr = &__executable_start;
285 +      _dl_phdr = (ElfW(Phdr) *) ((const void *) ehdr + ehdr->e_phoff);
286 +      _dl_phnum = ehdr->e_phnum;
287 +      assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
288 +#endif
289 +    }
290 +  else
291 +    {
292 +#ifndef SHARED
293 +      __libc_enable_secure = d->flags & EXEC_SECURE;
294 +
295 +      _dl_phdr = (ElfW(Phdr) *) d->phdr;
296 +      _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
297 +      assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
298 +#endif
299 +    }
300 +
301 +#ifndef SHARED
302 +  /* We need to setup TLS before starting sigthread */
303 +  extern void __pthread_initialize_minimal(void);
304 +  __pthread_initialize_minimal();
305 +#endif
306 +
307    /* The user might have defined a value for this, to get more variables.
308       Otherwise it will be zero on startup.  We must make sure it is set
309       properly before before cthreads initialization, so cthreads can know
310 --- a/sysdeps/mach/hurd/i386/tls.h
311 +++ b/sysdeps/mach/hurd/i386/tls.h
312 @@ -31,6 +31,8 @@
313  
314  # ifndef __ASSEMBLER__
315  
316 +#include <pthread/pthread.h>
317 +
318  /* Use i386-specific RPCs to arrange that %gs segment register prefix
319     addresses the TCB in each thread.  */
320  # include <mach/i386/mach_i386.h>
321 @@ -72,7 +74,7 @@
322  
323        /* Get the first available selector.  */
324        int sel = -1;
325 -      error_t err = __i386_set_gdt (tcb->self, &sel, desc);
326 +      kern_return_t err = __i386_set_gdt (tcb->self, &sel, desc);
327        if (err == MIG_BAD_ID)
328         {
329           /* Old kernel, use a per-thread LDT.  */
330 @@ -96,16 +98,16 @@
331        /* Fetch the selector set by the first call.  */
332        int sel;
333        asm ("mov %%gs, %w0" : "=q" (sel) : "0" (0));
334 -      if (__builtin_expect (sel, 0x50) & 4) /* LDT selector */
335 +      if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */
336         {
337 -         error_t err = __i386_set_ldt (tcb->self, sel, &desc, 1);
338 +         kern_return_t err = __i386_set_ldt (tcb->self, sel, &desc, 1);
339           assert_perror (err);
340           if (err)
341             return "i386_set_ldt failed";
342         }
343        else
344         {
345 -         error_t err = __i386_set_gdt (tcb->self, &sel, desc);
346 +         kern_return_t err = __i386_set_gdt (tcb->self, &sel, desc);
347           assert_perror (err);
348           if (err)
349             return "i386_set_gdt failed";
350 @@ -142,9 +144,40 @@
351  
352  #include <mach/machine/thread_status.h>
353  
354 -/* Set up TLS in the new thread of a fork child, copying from our own.  */
355 -static inline error_t __attribute__ ((unused))
356 -_hurd_tls_fork (thread_t child, struct i386_thread_state *state)
357 +/* Set up TLS in the new thread of a fork child, copying from the original.  */
358 +static inline kern_return_t __attribute__ ((unused))
359 +_hurd_tls_fork (thread_t child, thread_t orig, struct i386_thread_state *state)
360 +{
361 +  /* Fetch the selector set by _hurd_tls_init.  */
362 +  int sel;
363 +  asm ("mov %%gs, %w0" : "=q" (sel) : "0" (0));
364 +  if (sel == state->ds)                /* _hurd_tls_init was never called.  */
365 +    return 0;
366 +
367 +  struct descriptor desc, *_desc = &desc;
368 +  int err;
369 +  unsigned int count;
370 +
371 +  if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */
372 +    err = __i386_get_ldt (orig, sel, 1, &_desc, &count);
373 +  else
374 +    err = __i386_get_gdt (orig, sel, &desc);
375 +
376 +  assert_perror (err);
377 +  if (err)
378 +    return err;
379 +
380 +  if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */
381 +    err = __i386_set_ldt (child, sel, &desc, 1);
382 +  else
383 +    err = __i386_set_gdt (child, &sel, desc);
384 +
385 +  state->gs = sel;
386 +  return err;
387 +}
388 +
389 +static inline kern_return_t __attribute__ ((unused))
390 +_hurd_tls_new (thread_t child, struct i386_thread_state *state, tcbhead_t *tcb)
391  {
392    /* Fetch the selector set by _hurd_tls_init.  */
393    int sel;
394 @@ -152,11 +185,13 @@
395    if (sel == state->ds)                /* _hurd_tls_init was never called.  */
396      return 0;
397  
398 -  tcbhead_t *const tcb = THREAD_SELF;
399    HURD_TLS_DESC_DECL (desc, tcb);
400 -  error_t err;
401 +  kern_return_t err;
402 +
403 +  tcb->tcb = tcb;
404 +  tcb->self = child;
405  
406 -  if (__builtin_expect (sel, 0x50) & 4) /* LDT selector */
407 +  if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */
408      err = __i386_set_ldt (child, sel, &desc, 1);
409    else
410      err = __i386_set_gdt (child, &sel, desc);
411 --- a/sysdeps/mach/hurd/i386/trampoline.c
412 +++ b/sysdeps/mach/hurd/i386/trampoline.c
413 @@ -65,7 +65,7 @@
414                   sizeof (state->basic));
415           memcpy (&state->fpu, &ss->context->sc_i386_float_state,
416                   sizeof (state->fpu));
417 -         state->set |= (1 << i386_THREAD_STATE) | (1 << i386_FLOAT_STATE);
418 +         state->set |= (1 << i386_REGS_SEGS_STATE) | (1 << i386_FLOAT_STATE);
419         }
420      }
421  
422 --- a/sysdeps/mach/hurd/profil.c
423 +++ b/sysdeps/mach/hurd/profil.c
424 @@ -69,6 +69,8 @@
425        if (! err)
426         err = __mach_setup_thread (__mach_task_self (), profile_thread,
427                                    &profile_waiter, NULL, NULL);
428 +      if (! err)
429 +       err = __mach_setup_tls(profile_thread);
430      }
431    else
432      err = 0;
433 --- a/sysdeps/mach/hurd/setitimer.c
434 +++ b/sysdeps/mach/hurd/setitimer.c
435 @@ -223,11 +223,12 @@
436             return __hurd_fail (err);
437           _hurd_itimer_thread_stack_base = 0; /* Anywhere.  */
438           _hurd_itimer_thread_stack_size = __vm_page_size; /* Small stack.  */
439 -         if (err = __mach_setup_thread (__mach_task_self (),
440 +         if ((err = __mach_setup_thread (__mach_task_self (),
441                                          _hurd_itimer_thread,
442                                          &timer_thread,
443                                          &_hurd_itimer_thread_stack_base,
444                                          &_hurd_itimer_thread_stack_size))
445 +             || (err = __mach_setup_tls(_hurd_itimer_thread)))
446             {
447               __thread_terminate (_hurd_itimer_thread);
448               _hurd_itimer_thread = MACH_PORT_NULL;
449 --- a/sysdeps/mach/i386/thread_state.h
450 +++ b/sysdeps/mach/i386/thread_state.h
451 @@ -19,7 +19,8 @@
452  
453  #include <mach/machine/thread_status.h>
454  
455 -#define MACHINE_THREAD_STATE_FLAVOR    i386_THREAD_STATE
456 +#define MACHINE_NEW_THREAD_STATE_FLAVOR        i386_THREAD_STATE
457 +#define MACHINE_THREAD_STATE_FLAVOR    i386_REGS_SEGS_STATE
458  #define MACHINE_THREAD_STATE_COUNT     i386_THREAD_STATE_COUNT
459  
460  #define machine_thread_state i386_thread_state
461 @@ -28,6 +29,14 @@
462  #define SP uesp
463  #define SYSRETURN eax
464  
465 +#define MACHINE_THREAD_STATE_FIX_NEW(ts) do { \
466 +       asm ("mov %%cs, %w0" : "=q" ((ts)->cs)); \
467 +       asm ("mov %%ds, %w0" : "=q" ((ts)->ds)); \
468 +       asm ("mov %%es, %w0" : "=q" ((ts)->es)); \
469 +       asm ("mov %%fs, %w0" : "=q" ((ts)->fs)); \
470 +       asm ("mov %%gs, %w0" : "=q" ((ts)->gs)); \
471 +} while(0)
472 +
473  struct machine_thread_all_state
474    {
475      int set;                   /* Mask of bits (1 << FLAVOR).  */
476 --- a/sysdeps/mach/powerpc/thread_state.h
477 +++ b/sysdeps/mach/powerpc/thread_state.h
478 @@ -19,6 +19,7 @@
479  
480  #include <mach/machine/thread_status.h>
481  
482 +#define MACHINE_NEW_THREAD_STATE_FLAVOR        PPC_THREAD_STATE
483  #define MACHINE_THREAD_STATE_FLAVOR    PPC_THREAD_STATE
484  #define MACHINE_THREAD_STATE_COUNT     PPC_THREAD_STATE_COUNT
485  
486 --- a/sysdeps/mach/thread_state.h
487 +++ b/sysdeps/mach/thread_state.h
488 @@ -38,6 +38,9 @@
489    ((ts)->SP = (unsigned long int) (stack) + (size))
490  #endif
491  #endif
492 +#ifndef MACHINE_THREAD_STATE_FIX_NEW
493 +#define MACHINE_THREAD_STATE_FIX_NEW(ts)
494 +#endif
495  
496  /* These functions are of use in machine-dependent signal trampoline
497     implementations.  */
498 --- a/sysdeps/mach/hurd/bits/libc-lock.h
499 +++ b/sysdeps/mach/hurd/bits/libc-lock.h
500 @@ -21,6 +21,9 @@
501  #define _BITS_LIBC_LOCK_H 1
502  
503  #if (_LIBC - 0) || (_CTHREADS_ - 0)
504 +#if (_LIBC - 0)
505 +#include <tls.h>
506 +#endif
507  #include <cthreads.h>
508  #include <hurd/threadvar.h>
509  
510 --- a/sysdeps/mach/hurd/tls.h
511 +++ b/sysdeps/mach/hurd/tls.h
512 @@ -23,7 +23,9 @@
513  #if defined HAVE_TLS_SUPPORT && !defined __ASSEMBLER__
514  
515  # include <stddef.h>
516 +# include <stdint.h>
517  # include <stdbool.h>
518 +# include <sysdep.h>
519  # include <mach/mig_errors.h>
520  # include <mach.h>
521  
522 --- /dev/null
523 +++ b/sysdeps/mach/hurd/i386/tlsdesc.sym
524 @@ -0,0 +1,17 @@
525 +#include <stddef.h>
526 +#include <sysdep.h>
527 +#include <tls.h>
528 +#include <link.h>
529 +#include <dl-tlsdesc.h>
530 +
531 +--
532 +
533 +-- Abuse tls.h macros to derive offsets relative to the thread register.
534 +
535 +DTV_OFFSET                     offsetof(tcbhead_t, dtv)
536 +
537 +TLSDESC_ARG                    offsetof(struct tlsdesc, arg)
538 +
539 +TLSDESC_GEN_COUNT              offsetof(struct tlsdesc_dynamic_arg, gen_count)
540 +TLSDESC_MODID                  offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module)
541 +TLSDESC_MODOFF                 offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset)