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?
Asked
Active
Viewed 290 times
1
-
1Is 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 Answers
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.

Topi Karvonen
- 45
- 6
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