Separate copies of thread-local data that have been allocated at compile-time, must be associated with individual threads of execution. To provide this data, TLS sections are used to specify the size and initial contents. The compilation environment allocates TLS in sections that are identified with the SHF_TLS flag. These sections provide initialized TLS and uninitialized TLS based on how the storage is declared.
An initialized thread-local variable is allocated in a .tdata, or .tdata1 section. This initialization can require relocation.
An uninitialized thread-local variable is defined as a COMMON symbol. The resulting allocation is made in a .tbss section.
The uninitialized section is allocated immediately following any initialized sections, subject to padding for proper alignment. Together, the combined sections form a TLS template that is used to allocate TLS whenever a new thread is created. The initialized portion of this template is called the TLS initialization image. All relocations that are generated as a result of initialized thread-local variables are applied to this template. The relocated values are used when a new thread requires the initial values.
TLS symbols have the symbol type STT_TLS. These symbols are assigned offsets relative to the beginning of the TLS template. The actual virtual address that is associated with these symbols is irrelevant. The address refers only to the template, and not to the per-thread copy of each data item. In dynamic executables and shared objects, the st_value field of a STT_TLS symbol contains the assigned TLS offset for defined symbols. This field contains zero for undefined symbols.
Several relocations are defined to support access to TLS. See SPARC: Thread-Local Storage Relocation Types, 32-bit x86: Thread-Local Storage Relocation Types and x64: Thread-Local Storage Relocation Types. TLS relocations typically reference symbols of type STT_TLS. TLS relocations can also reference local section symbols in association with a GOT entry. In this case, the assigned TLS offset is stored in the associated GOT entry.
For relocations against static TLS items, the relocation address is encoded as a negative offset from the end of the static TLS template. This offset is calculated by first rounding the template size to the nearest 8-byte boundary in a 32-bit object, and to the nearest 16-byte boundary in a 64-bit object. This rounding ensures that the static TLS template is suitably aligned for any use.
In dynamic executables and shared objects, a PT_TLS program entry describes a TLS template. This template has the following members.
Table 8-1 ELF PT_TLS Program Header Entry