Linker and Libraries Guide

SPARC: Thread-Local Variable Access

On SPARC, the following code sequence models are available for accessing thread-local variables.

SPARC: 32-bit and 64-bit General Dynamic (GD)

This code sequence is the most general, and can be included in both shared objects and dynamic executables. This code sequence can also reference an external TLS variable in either a shared object or dynamic executable.

Table 8–2 SPARC: 32-bit and 64-bit General Dynamic Thread-Local Variable Access Codes

Code Sequence 

Initial Relocations 

Symbol 

# %l7 - initialized to GOT pointer

0x00 sethi %hi(@dtlndx(x)), %o0
0x04 add   %o0,%lo(@dtlndx(x)),%o0
0x08 add   %l7, %o0, %o0
0x0c call  x@TLSPLT
 
# %o0 - contains address of TLS variable
 
 
R_SPARC_TLS_GD_HI22
R_SPARC_TLS_GD_LO22
R_SPARC_TLS_GD_ADD
R_SPARC_TLS_GD_CALL
 
 
x
x
x
x
 

Outstanding Relocations: 32-bit 

Symbol 

GOT[n]
GOT[n + 1]
R_SPARC_TLS_DTPMOD32
R_SPARC_TLS_DTPOFF32
x
x
 

Outstanding Relocations: 64-bit 

Symbol 

GOT[n]
GOT[n + 1]
R_SPARC_TLS_DTPMOD64
R_SPARC_TLS_DTPOFF64
x
x

The sethi, and add instructions generate R_SPARC_TLS_GD_HI22 and R_SPARC_TLS_GD_LO10 relocations respectively. These relocations instruct the link-editor to allocate space in the global offset table to hold a TLS_index structure for variable x. The link-editor processes this relocation by substituting the GOT-relative offset for the new GOT entry.

Since the load object index and TLS block index for x are not known until runtime, the link-editor places the R_SPARC_TLS_DTPMOD32 and R_SPARC_TLS_DPTOFF32 relocations against the GOT for processing by the runtime linker.

The add instruction causes the generation of the R_SPARC_TLS_GD_ADD relocation. This relocation is used only if the GD code sequence is changed to another sequence by the link-editor.

The call instruction generates the R_SPARC_TLS_GD_CALL relocation. This relocation instructs the link-editor to bind the call to the __tls_get_addr() function, and associates the call instruction with the GD code sequence.


Note –

The add instruction must appear before the call instruction. It cannot be placed into the delay slot for the call. This is required as the code-transformations that can occur later require a known order.

The register used as the GOT-pointer for the add instruction tagged by the R_SPARC_TLS_GD_ADD relocation, must be the first register in the add instruction. This permits the link-editor to identify the GOT-pointer register during a code transformation.


SPARC: 32-bit and 64-bit 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 within 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 referenced via the LD code sequence.

Table 8–3 SPARC: 32-bit and 64-bit Local Dynamic Thread-Local Variable Access Codes

Code Sequence 

Initial Relocations 

Symbol 

# %l7 - initialized to GOT pointer

0x00 sethi %hi(@tmndx(x1)), %o0
0x04 add   %o0,%lo(@tmndx(x1)),%o0
0x08 add   %l7, %o0, %o0
0x0c call  x@TLSPLT

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

0x10 sethi %hi(@dtpoff(x1)), %l1
0x14 xor   %l1, %lo(@dtpoff(x1)), %l1
0x18 add   %o0, %l1, %l1

# %l1 - contains address of local TLS variable x1

0x20 sethi %hi(@dtpoff(x2)), %l2
0x24 xor   %l2, %lo(@dtpoff(x2)), %l2
0x28 add   %o0, %l2, %l2

# %l2 - contains address of local TLS variable x2
 
 
R_SPARC_TLS_LDM_HI22
R_SPARC_TLS_LDM_LO10
R_SPARC_TLS_LDM_ADD
R_SPARC_TLS_LDM_CALL
 
 
 
R_SPARC_TLS_LDO_HIX22
R_SPARC_TLS_LDO_LOX10
R_SPARC_TLS_LDO_ADD
 
 
 
R_SPARC_TLS_LDO_HIX22
R_SPARC_TLS_LDO_LOX10
R_SPARC_TLS_LDO_ADD
 
 
x1
x1
x1
x1
 
 
 
x1
x1
x1
 
 
 
x2
x2
x2
 

Outstanding Relocations: 32-bit 

Symbol 

GOT[n]
GOT[n + 1]
R_SPARC_TLS_DTPMOD32
<none>
x1
 

Outstanding Relocations: 64-bit 

Symbol 

GOT[n]
GOT[n + 1]
R_SPARC_TLS_DTPMOD64
<none>
x1

The first sethi and add instructions generate R_SPARC_TLS_LDM_HI22 and R_SPARC_TLS_LDM_LO10 relocations respectively. These relocations instruct the link-editor to allocate space in the global offset table to hold a TLS_index structure for the current object. The link-editor processes this relocation by substituting the GOT-relative offset for the new GOT entry.

Since the load object index is not known until runtime, a R_SPARC_TLS_DTPMOD32 relocation is created, and the ti_tlsoffset field of the TLS_index structure is zero filled.

The second add and the call instruction are tagged with the R_SPARC_TLS_LDM_ADD and R_SPARC_TLS_LDM_CALL relocations respectively.

The following sethi and or instructions generate the R_SPARC_LDO_HIX22 and R_SPARC_TLS_LDO_LOX10 relocations, respectively. The TLS offset for each local symbol is known at link-edit time, therefore these values are filled in directly. The add instruction is tagged with the R_SPARC_TLS_LDO_ADD relocation.

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.


Note –

The register containing the TLS object address in the add instruction tagged by the R_SPARC_TLS_LDO_ADD must be the first register in the instruction sequence. This permits the link-editor to identify the register during a code transformation.


SPARC: 32-bit Initial Executable (IE)

This code sequence can only be used in a dynamic executable. It can reference a TLS variable defined in either the executable or any shared libraries loaded at process startup. This model can not reference TLS variables from shared libraries loaded after process startup.

Table 8–4 SPARC: 32-bit Initial Executable Thread-Local Variable Access Codes

Code Sequence 

Initial Relocations 

Symbol 

# %l7 - initialized to GOT pointer

0x00 sethi %hi(@tpoff(x)), %o0
0x04 or    %o0,%lo(@tpoff(x)),%o0
0x08 ld    [%l7 + %o0], %o0
0x0c add   %g7, %o0, %o0
 
# %o0 - contains address of TLS variable
 
 
R_SPARC_TLS_IE_HI22
R_SPARC_TLS_IE_LO10
R_SPARC_TLS_IE_LD
R_SPARC_TLS_IE_ADD
 
 
x
x
x
x
 

Outstanding Relocations 

Symbol 

GOT[n]
R_SPARC_TLS_TPOFF32
x

The sethi and or instructions generate R_SPARC_TLS_IE_HI22 and R_SPARC_TLS_IE_LO10 relocations, respectively. These relocations instruct the link-editor to create space in the global offset table to store the static TLS offset for symbol x. A R_SPARC_TLS_TPOFF32 relocation is left outstanding against the GOT for the runtime linker to fill in with the negative static TLS offset for symbol x. The ld and the add instructions are tagged with the R_SPARC_TLS_IE_LD and R_SPARC_TLS_IE_ADD relocations respectively.


Note –

The register used as the GOT-pointer for the add instruction tagged by the R_SPARC_TLS_IE_ADD relocation must be the first register in the instruction. This permits the link-editor to identify the GOT-pointer register during a code transformation.


SPARC: 64-bit Initial Executable (IE)

This sequence is identical to the SPARC 32–bit sequence, except that an ldx instruction is used to load the 64–bit address instead of an ld instruction.

Table 8–5 SPARC: 64-bit Initial Executable Thread-Local Variable Access Codes

Code Sequence 

Initial Relocations 

Symbol 

# %l7 - initialized to GOT pointer

0x00 sethi %hi(@tpoff(x)), %o0
0x04 or    %o0,%lo(@tpoff(x)),%o0
0x08 ldx   [%l7 + %o0], %o0
0x0c add   %g7, %o0, %o0
 
# %o0 - contains address of TLS variable
 
 
R_SPARC_TLS_IE_HI22
R_SPARC_TLS_IE_LO10
R_SPARC_TLS_IE_LD
R_SPARC_TLS_IE_ADD
 
 
x
x
x
x
 

Outstanding Relocations 

Symbol 

GOT[n]
R_SPARC_TLS_TPOFF64
x

SPARC: 32-bit and 64-bit Local Executable (LE)

This code sequence can only be used from within a dynamic executable to reference a TLS variable defined within the executable. If this is the case, the static tlsoffset is known at link-edit time and no runtime relocations are required.

Table 8–6 SPARC: 32-bit and 64-bit Local Executable Thread-Local Variable Access Codes

Code Sequence 

Initial Relocations 

Symbol 

0x00 sethi %hix(@tpoff(x)), %o0
0x04 xor   %o0,%lo(@tpoff(x)),%o0
0x08 add   %g7, %o0, %o0
 
# %o0 - contains address of TLS variable
R_SPARC_TLS_LE_HIX22
R_SPARC_TLS_LE_LOX10
<none>
x
x

The sethi and or instructions generate R_SPARC_TLS_LE_HIX22 and R_SPARC_TLS_LE_LOX10 relocations respectively. The link-editor binds these relocations directly to the static TLS offset for the symbol defined in the executable. No relocation processing is required at runtime.