Hi all,
While reviewing the patches to upstream lld, it is brought up
(
https://reviews.llvm.org/D39322?id=120794#inline-344646) that there
can be an alternative design of R_RISCV_PCREL_LO12 where the distance
to the corresponding PCREL_HI20 can be stored in the addend (as
opposed to using labels to link both together).
Given:
L1:
auipc a0, %pcrel_hi(foo)
lw a1, %pcrel_lo(L1)(a0)
Currently, the assembler produces two relocations (as described at
https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#pc-relative-symbol-addresses):
Offset Type Symbol + Addend
0 R_RISCV_PCREL_HI20 foo + 0
4 R_RISCV_PCREL_LO12_I L1 + 0
To perform the R_RISCV_PCREL_LO12_I relocation, the linker has to
first find the label "L1", search the relocation entries for the
R_RISCV_PCREL_HI20 at "L1", and then search for the symbol "foo" to
obtain the address.
With the alternative design, the assembler would produce:
Offset Type Symbol + Addend
0 R_RISCV_PCREL_HI20 foo + 0
4 R_RISCV_PCREL_LO12_I foo + 4
The assembler knows the offset between HI20/LO12 pair can fill it into
the addend of LO12. Now the linker only needs to find the symbol "foo"
and the address calculation can modified as:
P = address of LO12
S = address of symbol
P' = P - A # address of auipc
hi20 = (S - P' + 0x800) >> 12
lo12 = S - P' - hi20 << 12
This allows the LO12 to be computed independently, and additionally it
also eliminates one search in the symbol table and another in the
relocation table. This does comes complicate linker relaxation, as the
linker now also has to update the addend of LO12 after adjusting
symbol addresses.
I understand it may be too late to change the ABI so the new design
would have to use a new relocation number. Any thoughts?
--
Chih-Mao Chen (PkmX)
Software R&D, Andes Technology