ELF relocations are available as defined in the OpenRISC architecture specification.
R_OR1K_HI_16_IN_INSN is obtained using ‘hi’ 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
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_SLO16 can be obtained by enclosing an operand inside of ‘gotofflo’. For example, assuming the GOT base is in register
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_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_HI16is requested using ‘tlsgdhi’.
R_OR1K_TLS_GD_LO16is requested using ‘tlsgdlo’.
R_OR1K_TLS_GD_PG21is requested using ‘tldgd’.
R_OR1K_TLS_GD_LO13is requested using ‘tlsgdpo’.
R_OR1K_TLS_LDM_HI16is requested using ‘tlsldmhi’.
R_OR1K_TLS_LDM_LO16is requested using ‘tlsldmlo’.
R_OR1K_TLS_LDM_PG21is requested using ‘tldldm’.
R_OR1K_TLS_LDM_LO13is requested using ‘tlsldmpo’.
R_OR1K_TLS_LDO_HI16is requested using ‘dtpoffhi’.
R_OR1K_TLS_LDO_LO16is requested using ‘dtpofflo’.
R_OR1K_TLS_IE_HI16is requested using ‘gottpoffhi’.
R_OR1K_TLS_IE_AHI16is requested using ‘gottpoffha’.
R_OR1K_TLS_IE_LO16is requested using ‘gottpofflo’.
R_OR1K_TLS_IE_PG21is requested using ‘gottp’.
R_OR1K_TLS_IE_LO13is requested using ‘gottppo’.
R_OR1K_TLS_LE_HI16is requested using ‘tpoffhi’.
R_OR1K_TLS_LE_AHI16is requested using ‘tpoffha’.
R_OR1K_TLS_LE_LO16is requested using ‘tpofflo’.
R_OR1K_TLS_LE_SLO16also 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
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)