Previous: OpenRISC-Regs, Up: OpenRISC-Syntax


9.33.1.3 Relocations

ELF relocations are available as defined in the OpenRISC architecture specification.

R_OR1K_HI_16_IN_INSN is obtained using ‘hi’ and R_OR1K_LO_16_IN_INSN and R_OR1K_SLO16 are obtained using ‘lo’. For signed offsets R_OR1K_AHI16 is obtained from ‘ha’. For example:

     l.movhi r5, hi(symbol)
     l.ori   r5, r5, lo(symbol)
     
     l.movhi r5, ha(symbol)
     l.addi  r5, r5, lo(symbol)

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

The PC relative relocation R_OR1K_GOTPC_HI16 can be obtained by enclosing an operand inside of ‘gotpchi’. Likewise, the R_OR1K_GOTPC_LO16 relocation can be obtained using ‘gotpclo’. These are mostly used when assembling PIC code. For example, the standard PIC sequence on OpenRISC to get the base of the global offset table, PC relative, into a register, can be performed as:

     l.jal   0x8
      l.movhi r17, gotpchi(_GLOBAL_OFFSET_TABLE_-4)
     l.ori   r17, r17, gotpclo(_GLOBAL_OFFSET_TABLE_+0)
     l.add   r17, r17, r9

Several relocations exist to allow the link editor to perform GOT data references. The R_OR1K_GOT16 relocation can obtained by enclosing an operand inside of ‘got’. For example, assuming the GOT base is in register r17.

     l.lwz   r19, got(a)(r17)
     l.lwz   r21, 0(r19)

Also, several relocations exist for local GOT references. The R_OR1K_GOTOFF_AHI16 relocation can obtained by enclosing an operand inside of ‘gotoffha’. Likewise, R_OR1K_GOTOFF_LO16 and R_OR1K_GOTOFF_SLO16 can be obtained by enclosing an operand inside of ‘gotofflo’. For example, assuming the GOT base is in register rl7:

     l.movhi r19, gotoffha(symbol)
     l.add   r19, r19, r17
     l.lwz   r19, gotofflo(symbol)(r19)

The above PC relative relocations use a l.jal (jump) instruction and reading of the link register to load the PC. OpenRISC also supports page offset PC relative locations without a jump instruction using the l.adrp instruction. By default the l.adrp instruction will create an R_OR1K_PCREL_PG21 relocation. Likewise, BFD_RELOC_OR1K_LO13 and BFD_RELOC_OR1K_SLO13 can be obtained by enclosing an operand inside of ‘po’. For example:

     l.adrp  r3, symbol
     l.ori   r4, r3, po(symbol)
     l.lbz   r5, po(symbol)(r3)
     l.sb    po(symbol)(r3), r6

Likewise the page offset relocations can be used with GOT references. The relocation R_OR1K_GOT_PG21 can be obtained by enclosing an l.adrp immediate operand inside of ‘got’. Likewise, R_OR1K_GOT_LO13 can be obtained by enclosing an operand inside of ‘gotpo’. For example to load the value of a GOT symbol into register ‘r5’ we can do:

     l.adrp  r17, got(_GLOBAL_OFFSET_TABLE_)
     l.lwz   r5, gotpo(symbol)(r17)

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

Here are some example TLS model sequences.

First, General Dynamic:

     l.movhi r17, tlsgdhi(symbol)
     l.ori   r17, r17, tlsgdlo(symbol)
     l.add   r17, r17, r16
     l.or    r3, r17, r17
     l.jal   plt(__tls_get_addr)
      l.nop

Initial Exec:

     l.movhi r17, gottpoffhi(symbol)
     l.add   r17, r17, r16
     l.lwz   r17, gottpofflo(symbol)(r17)
     l.add   r17, r17, r10
     l.lbs   r17, 0(r17)

And finally, Local Exec:

     l.movhi r17, tpoffha(symbol)
     l.add   r17, r17, r10
     l.addi  r17, r17, tpofflo(symbol)
     l.lbs   r17, 0(r17)