README.TLS revision 1.6
11.1SjoergSteps for adding TLS support for a new platform:
21.1Sjoerg
31.1Sjoerg(1) Declare TLS variant in machine/types.h by defining either
41.1Sjoerg__HAVE_TLS_VARIANT_I or __HAVE_TLS_VARIANT_II.
51.1Sjoerg
61.2Sjoerg(2) _lwp_makecontext has to set the reserved register or kernel transfer
71.3Sjoergvariable in uc_mcontext to the provided value of 'private'. See
81.3Sjoergsrc/lib/libc/arch/$PLATFORM/gen/_lwp.c.
91.1Sjoerg
101.1SjoergThis is not possible on the VAX as there is no free space in ucontext_t.
111.1SjoergThis requires either a special version of _lwp_create or versioning
121.1Sjoergeverything using ucontext_t. Debug support depends on getting the data from
131.1Sjoergucontext_t, so the second option is possibly required.
141.1Sjoerg
151.2Sjoerg(3) _lwp_setprivate(2) has to update the same register as
161.4Sjoerg_lwp_makecontext uses for the private area pointer. Normally
171.4Sjoergcpu_lwp_setprivate is provided by MD to reflect the kernel view and
181.4Sjoergenabled by defining __HAVE_CPU_LWP_SETPRIVATE in machine/types.h.
191.4Sjoergcpu_setmcontext is responsible for keeping the MI l_private field
201.4Sjoergsynchronised by calling lwp_setprivate as needed.
211.4Sjoerg
221.4Sjoergcpu_switchto has to update the mapping.
231.1Sjoerg
241.1Sjoerg_lwp_setprivate is used for the initial thread, all other threads
251.1Sjoergcreated by libpthread use _lwp_makecontext for this purpose.
261.1Sjoerg
271.2Sjoerg(4) Provide __tls_get_addr and possible other MD functions for dynamic
281.1SjoergTLS offset computation. If such alternative entry points exist (currently
291.1Sjoergonly i386), also add a weak reference to 0 in src/lib/libc/tls/tls.c.
301.1Sjoerg
311.2SjoergThe generic implementation can be found in tls.c and is used with
321.5Sskrll__HAVE_COMMON___TLS_GET_ADDR. It depends on __lwp_getprivate_fast
331.4Sjoerg(see below).
341.1Sjoerg
351.2Sjoerg(5) Implement the necessary relocation records in mdreloc.c.  There are
361.1Sjoergtypically three relocation types found in dynamic binaries:
371.1Sjoerg
381.1Sjoerg(a) R_TYPE(TLS_DTPOFF): Offset inside the module.  The common TLS code
391.1Sjoergensures that the DTV vector points to offset 0 inside the module TLS block.
401.1SjoergThis is normally def->st_value + rela->r_addend.
411.1Sjoerg
421.1Sjoerg(b) R_TYPE(TLS_DTPMOD): Module index.
431.1Sjoerg
441.1Sjoerg(c) R_TYPE(TLS_TPOFF): Static TLS offset.  The code has to check whether
451.1Sjoergthe static TLS offset for this module has been allocated
461.6Sjoerg(defobj->tls_static) and otherwise call _rtld_tls_offset_allocate().  This
471.1Sjoergmay fail if no static space is available and the object has been pulled
481.6Sjoergin via dlopen(3). It can also fail if the TLS area has already been used
491.6Sjoergvia a global-dynamic allocation.
501.1Sjoerg
511.1SjoergFor TLS Variant I, this is typically:
521.1Sjoerg
531.1Sjoergdef->st_value + rela->r_addend + defobj->tlsoffset + sizeof(struct tls_tcb)
541.1Sjoerg
551.1Sjoerge.g. the relocation doesn't include the fixed TCB.
561.1Sjoerg
571.1SjoergFor TLS Variant II, this is typically:
581.1Sjoerg
591.1Sjoergdef->st_value - defobj->tlsoffset + rela->r_addend
601.1Sjoerg
611.1Sjoerge.g. starting offset is counting down from the TCB.
621.1Sjoerg
631.5Sskrll(6) Implement __lwp_getprivate_fast() in machine/mcontext.h and set
641.3Sjoerg__HAVE___LWP_GETPRIVATE_FAST in machine/types.h.
651.1Sjoerg
661.3Sjoerg(7) Test using src/tests/lib/libc/tls.  Make sure with "objdump -R" that
671.1Sjoergt_tls_dynamic has two TPOFF relocations and h_tls_dlopen.so.1 and
681.1Sjoerglibh_tls_dynamic.so.1 have both two DTPMOD and DTPOFF relocations.
69