README.TLS revision 1.1
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) crt0.o has to call _rtld_tls_static_setup() if _DYNAMIC == NULL.
7This part is already done if the new src/lib/csu/arch layout is used
8by the architecture.
9
10(3) _lwp_makecontext has to set the reserved register or kernel transfer
11variable in uc_mcontext to the provided value of 'private'.
12
13This is not possible on the VAX as there is no free space in ucontext_t.
14This requires either a special version of _lwp_create or versioning
15everything using ucontext_t. Debug support depends on getting the data from
16ucontext_t, so the second option is possibly required.
17
18(4) _lwp_setprivate(2) has to update the same register as
19_lwp_makecontext. cpu_lwp_setprivate has to call _lwp_setprivate(2) to
20reflect the kernel view. cpu_switch has to update the mapping.
21
22_lwp_setprivate is used for the initial thread, all other threads
23created by libpthread use _lwp_makecontext for this purpose.
24
25(5) Provide __tls_get_addr and possible other MD functions for dynamic
26TLS offset computation. If such alternative entry points exist (currently
27only i386), also add a weak reference to 0 in src/lib/libc/tls/tls.c.
28
29The generic implementation is:
30
31#include <sys/cdefs.h>
32#include <sys/tls.h>
33#include <lwp.h>
34
35/* Weak entry is overriden by ld.elf_so for dynamic linkage */
36weak_alias(__tls_get_addr, __libc__tls_get_addr)
37
38void *
39__libc__tls_get_addr(size_t idx[2])
40{
41	struct tls_tcb *tcb;
42
43	tcb = _lwp_getprivate();
44	return _rtld_tls_get_addr(tcb, idx[0], idx[1]);
45}
46
47XXX Document optimisations based idx[0]
48
49(6) Implement the necessary relocation records in mdreloc.c.  There are
50typically three relocation types found in dynamic binaries:
51
52(a) R_TYPE(TLS_DTPOFF): Offset inside the module.  The common TLS code
53ensures that the DTV vector points to offset 0 inside the module TLS block.
54This is normally def->st_value + rela->r_addend.
55
56(b) R_TYPE(TLS_DTPMOD): Module index.
57
58(c) R_TYPE(TLS_TPOFF): Static TLS offset.  The code has to check whether
59the static TLS offset for this module has been allocated
60(defobj->tls_done) and otherwise call _rtld_tls_offset_allocate().  This
61may fail if no static space is available and the object has been pulled
62in via dlopen(3).
63
64For TLS Variant I, this is typically:
65
66def->st_value + rela->r_addend + defobj->tlsoffset + sizeof(struct tls_tcb)
67
68e.g. the relocation doesn't include the fixed TCB.
69
70For TLS Variant II, this is typically:
71
72def->st_value - defobj->tlsoffset + rela->r_addend
73
74e.g. starting offset is counting down from the TCB.
75
76(7) Implement _lwp_getprivate_fast() in machine/mcontext.h and set
77__HAVE___LWP_GETPRIVATE_FAST.
78
79(8) Test using src/tests/lib/libc/tls.  Make sure with "objdump -R" that
80t_tls_dynamic has two TPOFF relocations and h_tls_dlopen.so.1 and
81libh_tls_dynamic.so.1 have both two DTPMOD and DTPOFF relocations.
82