I do not quite understand what you want. However, assembler sequences (for ARMv6 + and capable kernel):
mrc p15, 0, rX, c13, c0, 2 @ get the user r/w register
This is called TPIDRURW in some ARM manuals. Your TLS tables / structure should be allocated from this value (probably a pointer). Using mcr is faster, but you can also call an assistant (see below) if you do not install HWCAP_TLS in your ELF (which can be used on all ARM processors supported by Linux).
The purpose of the 0xffff0fe8 address seems to be that you can use these 4 bytes instead of using the above assembler directly with ( rX == r0 ), as it may be different from somewhere in the machine.
It depends on the type of CPU. There is a helper helper on the @ 0xffff0fe0 vector page in entry-armv.S ; it is in the process / thread structure if the hardware does not support it. The documentation is in kernel_user_helpers.txt
Usage example:
typedef void * (__kuser_get_tls_t)(void); #define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0) void foo() { void *tls = __kuser_get_tls(); printf("TLS = %p\n", tls); }
You make a system call to install TLS stuff. clone is a way to set up a thread context. thread_info contains the entire register for the thread; it can share a millimeter (memory or process memory view) with another task_struct . That is, the thread_info thread has a tp_value for each thread created.
Here is a description of the implementation of ARM. The ELF / nptl / glibc and Linux kernel are involved (and / or search terms to explore more). Syscall for get_tls() was probably too expensive, and the current trunk has an auxiliary vector page (displayed by all threads / processes).
Some sources are glibc, tls-macros.h , tlsdesc.c , etc. Most likely, the full / short answer will depend on the version,
- Your processor is ARM.
- Linux kernel
- Your glibc.
- Your compiler (and flags!).