Skip to content

Commit d024322

Browse files
committed
[cheriot] If a R_RISCV_CHERI_CCALL relocation survives relocation, remap it to CHERIOT compartment relocs.
This is needed because Cheriot uses 11-bit shifts on AUIPCC (differing from normal RISC-V CHERI), and requires that the HI and LO relocs offset the target in the same direction. This is meant to be handled for all of Cheriot via R_RISCV_CHERIOT_COMPARTMENT_HI and R_RISCV_CHERIOT_COMPARTMENT_LO_I, but that is complicated by the simultaneous need to relax calls in (almost) all situations, which requires using R_RISCV_CHERI_CCALL. The solution is to preserve R_RISCV_CHERI_CCALL through relaxation, but then to remap it onto R_RISCV_CHERIOT_COMPARTMENT_HI / R_RISCV_CHERIOT_COMPARTMENT_LO_I during relocation. This gets us relaxation in the common case, and correct offsetting in the scenario where relaxation fails.
1 parent 9e30f3b commit d024322

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,21 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
498498
int64_t hi = SignExtend64(val + 0x800, bits) >> 12;
499499
checkInt(loc, hi, 20, rel);
500500
if (isInt<20>(hi)) {
501+
// FIXME: Is there a better way to test for cheriot here?
502+
if (type == R_RISCV_CHERI_CCALL && config->isCheriAbi &&
503+
config->emachine == EM_RISCV && config->capabilitySize == 8) {
504+
// CHERIOT uses an 11-bit shift on AUIPCC, requiring special handling.
505+
relocate(loc,
506+
Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_HI,
507+
rel.offset, rel.addend, rel.sym},
508+
val);
509+
relocate(loc + 4,
510+
Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_LO_I,
511+
rel.offset, rel.addend, rel.sym},
512+
val);
513+
return;
514+
}
515+
501516
relocateNoSym(loc, R_RISCV_PCREL_HI20, val);
502517
relocateNoSym(loc + 4, R_RISCV_PCREL_LO12_I, val);
503518
}

0 commit comments

Comments
 (0)