9.32.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)