README.TLS revision 1.6
1Steps for adding TLS support for a new platform:
2
3(1) Declare TLS variant in machine/types.h by defining either
4__HAVE_TLS_VARIANT_I or __HAVE_TLS_VARIANT_II.
5
6(2) _lwp_makecontext has to set the reserved register or kernel transfer
7variable in uc_mcontext to the provided value of 'private'. See
8src/lib/libc/arch/$PLATFORM/gen/_lwp.c.
9
10This is not possible on the VAX as there is no free space in ucontext_t.
11This requires either a special version of _lwp_create or versioning
12everything using ucontext_t. Debug support depends on getting the data from
13ucontext_t, so the second option is possibly required.
14
15(3) _lwp_setprivate(2) has to update the same register as
16_lwp_makecontext uses for the private area pointer. Normally
17cpu_lwp_setprivate is provided by MD to reflect the kernel view and
18enabled by defining __HAVE_CPU_LWP_SETPRIVATE in machine/types.h.
19cpu_setmcontext is responsible for keeping the MI l_private field
20synchronised by calling lwp_setprivate as needed.
21
22cpu_switchto has to update the mapping.
23
24_lwp_setprivate is used for the initial thread, all other threads
25created by libpthread use _lwp_makecontext for this purpose.
26
27(4) Provide __tls_get_addr and possible other MD functions for dynamic
28TLS offset computation. If such alternative entry points exist (currently
29only i386), also add a weak reference to 0 in src/lib/libc/tls/tls.c.
30
31The generic implementation can be found in tls.c and is used with
32__HAVE_COMMON___TLS_GET_ADDR. It depends on __lwp_getprivate_fast
33(see below).
34
35(5) Implement the necessary relocation records in mdreloc.c.  There are
36typically three relocation types found in dynamic binaries:
37
38(a) R_TYPE(TLS_DTPOFF): Offset inside the module.  The common TLS code
39ensures that the DTV vector points to offset 0 inside the module TLS block.
40This is normally def->st_value + rela->r_addend.
41
42(b) R_TYPE(TLS_DTPMOD): Module index.
43
44(c) R_TYPE(TLS_TPOFF): Static TLS offset.  The code has to check whether
45the static TLS offset for this module has been allocated
46(defobj->tls_static) and otherwise call _rtld_tls_offset_allocate().  This
47may fail if no static space is available and the object has been pulled
48in via dlopen(3). It can also fail if the TLS area has already been used
49via a global-dynamic allocation.
50
51For TLS Variant I, this is typically:
52
53def->st_value + rela->r_addend + defobj->tlsoffset + sizeof(struct tls_tcb)
54
55e.g. the relocation doesn't include the fixed TCB.
56
57For TLS Variant II, this is typically:
58
59def->st_value - defobj->tlsoffset + rela->r_addend
60
61e.g. starting offset is counting down from the TCB.
62
63(6) Implement __lwp_getprivate_fast() in machine/mcontext.h and set
64__HAVE___LWP_GETPRIVATE_FAST in machine/types.h.
65
66(7) Test using src/tests/lib/libc/tls.  Make sure with "objdump -R" that
67t_tls_dynamic has two TPOFF relocations and h_tls_dlopen.so.1 and
68libh_tls_dynamic.so.1 have both two DTPMOD and DTPOFF relocations.
69