README.TLS revision 1.1
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.1Sjoerg(2) crt0.o has to call _rtld_tls_static_setup() if _DYNAMIC == NULL.
71.1SjoergThis part is already done if the new src/lib/csu/arch layout is used
81.1Sjoergby the architecture.
91.1Sjoerg
101.1Sjoerg(3) _lwp_makecontext has to set the reserved register or kernel transfer
111.1Sjoergvariable in uc_mcontext to the provided value of 'private'.
121.1Sjoerg
131.1SjoergThis is not possible on the VAX as there is no free space in ucontext_t.
141.1SjoergThis requires either a special version of _lwp_create or versioning
151.1Sjoergeverything using ucontext_t. Debug support depends on getting the data from
161.1Sjoergucontext_t, so the second option is possibly required.
171.1Sjoerg
181.1Sjoerg(4) _lwp_setprivate(2) has to update the same register as
191.1Sjoerg_lwp_makecontext. cpu_lwp_setprivate has to call _lwp_setprivate(2) to
201.1Sjoergreflect the kernel view. cpu_switch has to update the mapping.
211.1Sjoerg
221.1Sjoerg_lwp_setprivate is used for the initial thread, all other threads
231.1Sjoergcreated by libpthread use _lwp_makecontext for this purpose.
241.1Sjoerg
251.1Sjoerg(5) Provide __tls_get_addr and possible other MD functions for dynamic
261.1SjoergTLS offset computation. If such alternative entry points exist (currently
271.1Sjoergonly i386), also add a weak reference to 0 in src/lib/libc/tls/tls.c.
281.1Sjoerg
291.1SjoergThe generic implementation is:
301.1Sjoerg
311.1Sjoerg#include <sys/cdefs.h>
321.1Sjoerg#include <sys/tls.h>
331.1Sjoerg#include <lwp.h>
341.1Sjoerg
351.1Sjoerg/* Weak entry is overriden by ld.elf_so for dynamic linkage */
361.1Sjoergweak_alias(__tls_get_addr, __libc__tls_get_addr)
371.1Sjoerg
381.1Sjoergvoid *
391.1Sjoerg__libc__tls_get_addr(size_t idx[2])
401.1Sjoerg{
411.1Sjoerg	struct tls_tcb *tcb;
421.1Sjoerg
431.1Sjoerg	tcb = _lwp_getprivate();
441.1Sjoerg	return _rtld_tls_get_addr(tcb, idx[0], idx[1]);
451.1Sjoerg}
461.1Sjoerg
471.1SjoergXXX Document optimisations based idx[0]
481.1Sjoerg
491.1Sjoerg(6) Implement the necessary relocation records in mdreloc.c.  There are
501.1Sjoergtypically three relocation types found in dynamic binaries:
511.1Sjoerg
521.1Sjoerg(a) R_TYPE(TLS_DTPOFF): Offset inside the module.  The common TLS code
531.1Sjoergensures that the DTV vector points to offset 0 inside the module TLS block.
541.1SjoergThis is normally def->st_value + rela->r_addend.
551.1Sjoerg
561.1Sjoerg(b) R_TYPE(TLS_DTPMOD): Module index.
571.1Sjoerg
581.1Sjoerg(c) R_TYPE(TLS_TPOFF): Static TLS offset.  The code has to check whether
591.1Sjoergthe static TLS offset for this module has been allocated
601.1Sjoerg(defobj->tls_done) and otherwise call _rtld_tls_offset_allocate().  This
611.1Sjoergmay fail if no static space is available and the object has been pulled
621.1Sjoergin via dlopen(3).
631.1Sjoerg
641.1SjoergFor TLS Variant I, this is typically:
651.1Sjoerg
661.1Sjoergdef->st_value + rela->r_addend + defobj->tlsoffset + sizeof(struct tls_tcb)
671.1Sjoerg
681.1Sjoerge.g. the relocation doesn't include the fixed TCB.
691.1Sjoerg
701.1SjoergFor TLS Variant II, this is typically:
711.1Sjoerg
721.1Sjoergdef->st_value - defobj->tlsoffset + rela->r_addend
731.1Sjoerg
741.1Sjoerge.g. starting offset is counting down from the TCB.
751.1Sjoerg
761.1Sjoerg(7) Implement _lwp_getprivate_fast() in machine/mcontext.h and set
771.1Sjoerg__HAVE___LWP_GETPRIVATE_FAST.
781.1Sjoerg
791.1Sjoerg(8) Test using src/tests/lib/libc/tls.  Make sure with "objdump -R" that
801.1Sjoergt_tls_dynamic has two TPOFF relocations and h_tls_dlopen.so.1 and
811.1Sjoerglibh_tls_dynamic.so.1 have both two DTPMOD and DTPOFF relocations.
82