as: OpenRISC-Relocs
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:
* 'R_OR1K_TLS_GD_HI16' is requested using 'tlsgdhi'.
* 'R_OR1K_TLS_GD_LO16' is requested using 'tlsgdlo'.
* 'R_OR1K_TLS_GD_PG21' is requested using 'tldgd'.
* 'R_OR1K_TLS_GD_LO13' is requested using 'tlsgdpo'.
* 'R_OR1K_TLS_LDM_HI16' is requested using 'tlsldmhi'.
* 'R_OR1K_TLS_LDM_LO16' is requested using 'tlsldmlo'.
* 'R_OR1K_TLS_LDM_PG21' is requested using 'tldldm'.
* 'R_OR1K_TLS_LDM_LO13' is requested using 'tlsldmpo'.
* 'R_OR1K_TLS_LDO_HI16' is requested using 'dtpoffhi'.
* 'R_OR1K_TLS_LDO_LO16' is requested using 'dtpofflo'.
* 'R_OR1K_TLS_IE_HI16' is requested using 'gottpoffhi'.
* 'R_OR1K_TLS_IE_AHI16' is requested using 'gottpoffha'.
* 'R_OR1K_TLS_IE_LO16' is requested using 'gottpofflo'.
* 'R_OR1K_TLS_IE_PG21' is requested using 'gottp'.
* 'R_OR1K_TLS_IE_LO13' is requested using 'gottppo'.
* 'R_OR1K_TLS_LE_HI16' is requested using 'tpoffhi'.
* 'R_OR1K_TLS_LE_AHI16' is requested using 'tpoffha'.
* 'R_OR1K_TLS_LE_LO16' is requested using 'tpofflo'.
* 'R_OR1K_TLS_LE_SLO16' also is requested using 'tpofflo' depending
on the instruction format.
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)