README.TLS revision 1.4
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.4Sjoerg__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.1Sjoerg(defobj->tls_done) and otherwise call _rtld_tls_offset_allocate().  This
471.1Sjoergmay fail if no static space is available and the object has been pulled
481.1Sjoergin via dlopen(3).
491.1Sjoerg
501.1SjoergFor TLS Variant I, this is typically:
511.1Sjoerg
521.1Sjoergdef->st_value + rela->r_addend + defobj->tlsoffset + sizeof(struct tls_tcb)
531.1Sjoerg
541.1Sjoerge.g. the relocation doesn't include the fixed TCB.
551.1Sjoerg
561.1SjoergFor TLS Variant II, this is typically:
571.1Sjoerg
581.1Sjoergdef->st_value - defobj->tlsoffset + rela->r_addend
591.1Sjoerg
601.1Sjoerge.g. starting offset is counting down from the TCB.
611.1Sjoerg
621.2Sjoerg(6) Implement _lwp_getprivate_fast() in machine/mcontext.h and set
631.3Sjoerg__HAVE___LWP_GETPRIVATE_FAST in machine/types.h.
641.1Sjoerg
651.3Sjoerg(7) Test using src/tests/lib/libc/tls.  Make sure with "objdump -R" that
661.1Sjoergt_tls_dynamic has two TPOFF relocations and h_tls_dlopen.so.1 and
671.1Sjoerglibh_tls_dynamic.so.1 have both two DTPMOD and DTPOFF relocations.
68