This patch is part of implementing initial RISC-V support in BOLT.
I understand from other discussions (e.g. D127842, D98560) that JITLink
might be preferred over RuntimeDyld in general. However, since BOLT
still uses RuntimeDyld, adding minimal RISC-V support to it seems the
easiest way forward for now.
The following relocations are implemented:
- R_RISCV_CALL(_PLT)
- R_RISCV_GOT_HI20
- R_RISCV_PCREL_HI20
- R_RISCV_PCREL_LO12_I
- R_RISCV_32_PCREL
- R_RISCV_ADD32
- R_RISCV_SUB32
Most are fairly straightforward. The exception is R_RISCV_PCREL_LO12_I,
which is a relocation that refers to a corresponding *HI20 one (i.e.,
the symbol it refers to points to an instruction with a *HI20
relocation). In order to implement this, a member (PCRelHIRelocs) was
added to the RuntimeDyldELF class that maps offsets with a *HI20
relocation to their target address. Whenever a LO12 relocations is
encountered, this map is queried in order to find its target. Note that
this assumes that *HI20 relocations are processed before the
corresponding LO12 one. This seems to hold for my test cases but I'm not
entirely sure if this is actually guaranteed.
This patch also contains test cases for all relocations. However, there
is an issue with testing R_RISCV_32_PCREL: llvm-mc only emits this for
.eh_frame sections and uses unnamed symbols there. Since the symbol
lookup in RuntimeDyld seems to be based only on symbol names, these
symbols don't get resolved properly (Value is always 0).
This is not really a problem for the initial BOLT bring-up since we can
test on code that doesn't need .eh_frames. However, since GCC's startup
code contains them, we need to handle them somehow.
Note that I have included a (disabled) test case for R_RISCV_32_PCREL
relocations that passes if llvm-mc is modified to use section-relative
relocations in .eh_frame. I'm not sure if it makes sense to keep it in
this patch though.