##### 9.36.3.4 Relocations

ELF relocations are available as defined in the 32-bit and 64-bit Sparc ELF specifications.

`R_SPARC_HI22` is obtained using ‘`%hi`’ and `R_SPARC_LO10` is obtained using ‘`%lo`’. Likewise `R_SPARC_HIX22` is obtained from ‘`%hix`’ and `R_SPARC_LOX10` is obtained using ‘`%lox`’. For example:

         sethi %hi(symbol), %g1
         or    %g1, %lo(symbol), %g1

         sethi %hix(symbol), %g1
         xor   %g1, %lox(symbol), %g1

These “high” mnemonics extract bits 31:10 of their operand, and the “low” mnemonics extract bits 9:0 of their operand.

V9 code model relocations can be requested as follows:

- `R_SPARC_HH22` is requested using ‘`%hh`’. It can also be generated using ‘`%uhi`’.
- `R_SPARC_HM10` is requested using ‘`%hm`’. It can also be generated using ‘`%ulo`’.
- `R_SPARC_LM22` is requested using ‘`%lm`’.
- `R_SPARC_H44` is requested using ‘`%h44`’.
- `R_SPARC_M44` is requested using ‘`%m44`’.
- `R_SPARC_L44` is requested using ‘`%l44`’.

The PC relative relocation `R_SPARC_PC22` can be obtained by enclosing an operand inside of ‘`%pc22`’. Likewise, the `R_SPARC_PC10` relocation can be obtained using ‘`%pc10`’. These are mostly used when assembling PIC code. For example, the standard PIC sequence on Sparc to get the base of the global offset table, PC relative, into a register, can be performed as:

         sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %l7
         add   %l7, %pc10(_GLOBAL_OFFSET_TABLE_+4), %l7

Several relocations exist to allow the link editor to potentially optimize GOT data references. The `R_SPARC_GOTDATA_OP_HIX22` relocation can obtained by enclosing an operand inside of ‘`%gdop_hix22`’. The `R_SPARC_GOTDATA_OP_LOX10` relocation can obtained by enclosing an operand inside of ‘`%gdop_lox10`’. Likewise, `R_SPARC_GOTDATA_OP` can be obtained by enclosing an operand inside of ‘`%gdop`’. For example, assuming the GOT base is in register `%l7`:

         sethi %gdop_hix22(symbol), %l1
         xor   %l1, %gdop_lox10(symbol), %l1
         ld    [%l7 + %l1], %l2, %gdop(symbol)

There are many relocations that can be requested for access to thread local storage variables. All of the Sparc TLS mnemonics are supported:

- `R_SPARC_TLS_GD_HI22` is requested using ‘`%tgd_hi22`’.
- `R_SPARC_TLS_GD_LO10` is requested using ‘`%tgd_lo10`’.
- `R_SPARC_TLS_GD_ADD` is requested using ‘`%tgd_add`’.
- `R_SPARC_TLS_GD_CALL` is requested using ‘`%tgd_call`’.
- `R_SPARC_TLS_LDM_HI22` is requested using ‘`%tldm_hi22`’.
- `R_SPARC_TLS_LDM_LO10` is requested using ‘`%tldm_lo10`’.
- `R_SPARC_TLS_LDM_ADD` is requested using ‘`%tldm_add`’.
- `R_SPARC_TLS_LDM_CALL` is requested using ‘`%tldm_call`’.
- `R_SPARC_TLS_LDO_HIX22` is requested using ‘`%tldo_hix22`’.
- `R_SPARC_TLS_LDO_LOX10` is requested using ‘`%tldo_lox10`’.
- `R_SPARC_TLS_LDO_ADD` is requested using ‘`%tldo_add`’.
- `R_SPARC_TLS_IE_HI22` is requested using ‘`%tie_hi22`’.
- `R_SPARC_TLS_IE_LO10` is requested using ‘`%tie_lo10`’.
- `R_SPARC_TLS_IE_LD` is requested using ‘`%tie_ld`’.
- `R_SPARC_TLS_IE_LDX` is requested using ‘`%tie_ldx`’.
- `R_SPARC_TLS_IE_ADD` is requested using ‘`%tie_add`’.
- `R_SPARC_TLS_LE_HIX22` is requested using ‘`%tle_hix22`’.
- `R_SPARC_TLS_LE_LOX10` is requested using ‘`%tle_lox10`’.

Here are some example TLS model sequences.

First, General Dynamic:

         sethi  %tgd_hi22(symbol), %l1
         add    %l1, %tgd_lo10(symbol), %l1
         add    %l7, %l1, %o0, %tgd_add(symbol)
         call   __tls_get_addr, %tgd_call(symbol)
         nop

Local Dynamic:

         sethi  %tldm_hi22(symbol), %l1
         add    %l1, %tldm_lo10(symbol), %l1
         add    %l7, %l1, %o0, %tldm_add(symbol)
         call   __tls_get_addr, %tldm_call(symbol)
         nop

         sethi  %tldo_hix22(symbol), %l1
         xor    %l1, %tldo_lox10(symbol), %l1
         add    %o0, %l1, %l1, %tldo_add(symbol)

Initial Exec:

         sethi  %tie_hi22(symbol), %l1
         add    %l1, %tie_lo10(symbol), %l1
         ld     [%l7 + %l1], %o0, %tie_ld(symbol)
         add    %g7, %o0, %o0, %tie_add(symbol)

         sethi  %tie_hi22(symbol), %l1
         add    %l1, %tie_lo10(symbol), %l1
         ldx    [%l7 + %l1], %o0, %tie_ldx(symbol)
         add    %g7, %o0, %o0, %tie_add(symbol)

And finally, Local Exec:

         sethi  %tle_hix22(symbol), %l1
         add    %l1, %tle_lox10(symbol), %l1
         add    %g7, %l1, %l1

When assembling for 64-bit, and a secondary constant addend is specified in an address expression that would normally generate an `R_SPARC_LO10` relocation, the assembler will emit an `R_SPARC_OLO10` instead.