README.TLS revision 1.3
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.1Sjoerg_lwp_makecontext. cpu_lwp_setprivate has to call _lwp_setprivate(2) to 171.1Sjoergreflect the kernel view. cpu_switch has to update the mapping. 181.1Sjoerg 191.1Sjoerg_lwp_setprivate is used for the initial thread, all other threads 201.1Sjoergcreated by libpthread use _lwp_makecontext for this purpose. 211.1Sjoerg 221.2Sjoerg(4) Provide __tls_get_addr and possible other MD functions for dynamic 231.1SjoergTLS offset computation. If such alternative entry points exist (currently 241.1Sjoergonly i386), also add a weak reference to 0 in src/lib/libc/tls/tls.c. 251.1Sjoerg 261.2SjoergThe generic implementation can be found in tls.c and is used with 271.2Sjoerg__HAVE_COMMON___TLS_GET_ADDR. It depends on ___lwp_getprivate_fast. 281.1Sjoerg 291.2Sjoerg(5) Implement the necessary relocation records in mdreloc.c. There are 301.1Sjoergtypically three relocation types found in dynamic binaries: 311.1Sjoerg 321.1Sjoerg(a) R_TYPE(TLS_DTPOFF): Offset inside the module. The common TLS code 331.1Sjoergensures that the DTV vector points to offset 0 inside the module TLS block. 341.1SjoergThis is normally def->st_value + rela->r_addend. 351.1Sjoerg 361.1Sjoerg(b) R_TYPE(TLS_DTPMOD): Module index. 371.1Sjoerg 381.1Sjoerg(c) R_TYPE(TLS_TPOFF): Static TLS offset. The code has to check whether 391.1Sjoergthe static TLS offset for this module has been allocated 401.1Sjoerg(defobj->tls_done) and otherwise call _rtld_tls_offset_allocate(). This 411.1Sjoergmay fail if no static space is available and the object has been pulled 421.1Sjoergin via dlopen(3). 431.1Sjoerg 441.1SjoergFor TLS Variant I, this is typically: 451.1Sjoerg 461.1Sjoergdef->st_value + rela->r_addend + defobj->tlsoffset + sizeof(struct tls_tcb) 471.1Sjoerg 481.1Sjoerge.g. the relocation doesn't include the fixed TCB. 491.1Sjoerg 501.1SjoergFor TLS Variant II, this is typically: 511.1Sjoerg 521.1Sjoergdef->st_value - defobj->tlsoffset + rela->r_addend 531.1Sjoerg 541.1Sjoerge.g. starting offset is counting down from the TCB. 551.1Sjoerg 561.2Sjoerg(6) Implement _lwp_getprivate_fast() in machine/mcontext.h and set 571.3Sjoerg__HAVE___LWP_GETPRIVATE_FAST in machine/types.h. 581.1Sjoerg 591.3Sjoerg(7) Test using src/tests/lib/libc/tls. Make sure with "objdump -R" that 601.1Sjoergt_tls_dynamic has two TPOFF relocations and h_tls_dlopen.so.1 and 611.1Sjoerglibh_tls_dynamic.so.1 have both two DTPMOD and DTPOFF relocations. 62