1

I am writing a kernel and I need to self relocate above 0x7FFFFFFF. To do that, I need to refer, using absolute addressing, to the beginning and end of my kernel and to a symbol, where execution continues after the relocation. I have been unable to figure out any way to do this. Can it be done? Is there a workaround?

  • 1
    Is it still a 32 bit address? Use `lui` and `addi` and `%lo` and `%hi` if you are using gnu binutils. See the [manual](https://sourceware.org/binutils/docs/as/RISC_002dV_002dModifiers.html) – Jester Dec 21 '20 at 19:48
  • @Jester. It is, but in riscv64 lui/addi pair can only address as high as 0x7FFFFFFF, because the lui immediate is sign extended. – Topi Karvonen Dec 21 '20 at 20:31
  • That shouldn't matter, `%hi` and `%lo` do the right thing to produce the correct result. – Jester Dec 21 '20 at 20:47
  • @Jester. The linker gives an out-of-range-error in this case, as it should. For example if one tried to lui t0, 0xc0000 on riscv64, t0 would contain 0xFFFF_FFFF_C000_0000. – Topi Karvonen Dec 21 '20 at 21:12
  • Looks like indeed it only works if the assembler can resolve it. If it needs to emit a relocation entry the linker in fact complains. – Jester Dec 21 '20 at 21:16

2 Answers2

0

The only way I found was to take the load address and subtract this from the destination address. You can then add this offset to any relative address to get the absolute address.

0

Workaround: Place a 64-bit constant (the address) after the code, then get the address by "ld" instruction. The solution can be written as follows:

# Use load instruction get address of _symbol
ld t1, symbol_addr
jr t1
...
# A large pc for _symbol
_symbol:
    nop
    ...
.data
# symbol_addr equals to the address of _symbol
symbol_addr: .dowrd _symbol

The data symbol_addr will be calculated automatically as the address of _symbol, which maybe a large address, then use "ld" instruction to load the symbol_addr, register 't1' equals to symbol_addr and "jr" instruction will works.

Similiar question:How can I load the address of a symbol by absolute addressing in RISC-V 64?

sven
  • 86
  • 6