Linker and Libraries Guide

x86: Local Dynamic (LD)

This code sequence can be used in either a shared object or dynamic executable. This sequence is used when referencing a TLS variable bound to the same object as the reference. Because the dynamic tlsoffset can be bound at link-edit time, only one call to ___tls_get_addr() is required per function call for all symbols which are referenced via the LD code sequence.

Table 8–9 x86: Local Dynamic Thread-Local Variable Access Codes

Code Sequence 

Initial Relocations 

Symbol 

0x00 leal  x1@tlsldm(%ebx), %eax
0x06 call  x@tlsldmplt

# %eax - contains address of TLS block of current object

0x10 leal x1@dtpoff(%eax), %edx

# %edx - contains address of local TLS variable x1

0x20 leal x2@dtpoff(%eax), %edx

# %edx - contains address of local TLS variable x2
R_386_TLS_LDM
R_386_TLS_LDM_PLT
 
 
 
R_386_TLS_LDO_32
 
 
 
R_386_TLS_LDO_32
x1
x1
 
 
 
x1
 
 
 
x2
 

Outstanding Relocations 

Symbol 

GOT[n]
GOT[n + 1]
R_386_TLS_DTPMOD32
<none>
x

The first leal instruction generates a R_386_TLS_LDM relocation that instructs the link-editor to allocate space in the global offset table to hold a TLS_index structure for the current object. The link-editor process this relocation by substituting the GOT-relative offset for the new linkage table entry.

Since the load object index is not known until runtime, aR_386_TLS_DTPMOD32 relocation is created, and the ti_tlsoffset field of the structure is zero filled. The call instruction is tagged with the R_386_TLS_LDM_PLT relocation.

The TLS offset for each local symbol is known at link-edit time so the link-editor fills these values in directly.

When a procedure references more then one local symbol, the compiler generates code to obtain the base address of the TLS block once. This base address is then used to calculate the address of each symbol without a separate library call.