Skip to content

Commit 4feeffb

Browse files
committed
[cheriot] Add an R_RISCV_CHERIOT_CCALL reloc
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 add a new reloc that relaxes like R_RISCV_CHERI_CCALL, but relocates via R_RISCV_CHERIOT_COMPARTMENT_HI / R_RISCV_CHERIOT_COMPARTMENT_LO_I.
1 parent cba5428 commit 4feeffb

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

lld/ELF/Arch/RISCV.cpp

+25-5
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
358358
case R_RISCV_CALL:
359359
case R_RISCV_CALL_PLT:
360360
case R_RISCV_CHERI_CCALL:
361+
case R_RISCV_CHERIOT_CCALL:
361362
case R_RISCV_PLT32:
362363
return R_PLT_PC;
363364
case R_RISCV_GOT_HI20:
@@ -504,6 +505,24 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
504505
return;
505506
}
506507

508+
case R_RISCV_CHERIOT_CCALL: {
509+
// Cheriot uses an 11-bit shift on AUIPCC, requiring different relocation
510+
// compared to R_RISCV_CHERI_CCALL.
511+
int64_t hi = SignExtend64(val + 0x800, bits) >> 12;
512+
checkInt(loc, hi, 20, rel);
513+
if (isInt<20>(hi)) {
514+
relocate(loc,
515+
Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_HI, rel.offset,
516+
rel.addend, rel.sym},
517+
val);
518+
relocate(loc + 4,
519+
Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_LO_I,
520+
rel.offset, rel.addend, rel.sym},
521+
val);
522+
}
523+
return;
524+
}
525+
507526
case R_RISCV_CHERI_CAPTAB_PCREL_HI20:
508527
case R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20:
509528
case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20:
@@ -750,15 +769,15 @@ static void initSymbolAnchors() {
750769
}
751770

752771
// Relax R_RISCV_CALL/R_RISCV_CALL_PLT auipc+jalr to c.j, c.jal, or jal.
753-
// Relax R_RISCV_CHERI_CCALL auipcc+cjalr to c.cj, c.cjal, or cjal.
772+
// Relax R_RISCV_CHERI[OT]_CCALL auipcc+cjalr to c.cj, c.cjal, or cjal.
754773
static void relaxCall(const InputSection &sec, size_t i, uint64_t loc,
755774
Relocation &r, uint32_t &remove) {
756775
// We need to emit the correct relocations for CHERI, although the instruction
757776
// encodings are exactly the same with vanilla RISC-V.
758-
auto jalRVCType = (r.type == R_RISCV_CHERI_CCALL) ? R_RISCV_CHERI_RVC_CJUMP
759-
: R_RISCV_RVC_JUMP;
760-
auto jalType = (r.type == R_RISCV_CHERI_CCALL) ? R_RISCV_CHERI_CJAL
761-
: R_RISCV_JAL;
777+
bool isCCall =
778+
(r.type == R_RISCV_CHERI_CCALL) || (r.type == R_RISCV_CHERIOT_CCALL);
779+
auto jalRVCType = (isCCall) ? R_RISCV_CHERI_RVC_CJUMP : R_RISCV_RVC_JUMP;
780+
auto jalType = (isCCall) ? R_RISCV_CHERI_CJAL : R_RISCV_JAL;
762781
const bool rvc = config->eflags & EF_RISCV_RVC;
763782
const Symbol &sym = *r.sym;
764783
const uint64_t insnPair = read64le(sec.content().data() + r.offset);
@@ -967,6 +986,7 @@ static bool relax(InputSection &sec, int pass) {
967986
case R_RISCV_CALL:
968987
case R_RISCV_CALL_PLT:
969988
case R_RISCV_CHERI_CCALL:
989+
case R_RISCV_CHERIOT_CCALL:
970990
if (i + 1 != sec.relocs().size() &&
971991
sec.relocs()[i + 1].type == R_RISCV_RELAX)
972992
relaxCall(sec, i, loc, r, remove);

llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def

+1
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,4 @@ ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_HI, 220)
7171
ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_LO_I, 221)
7272
ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_LO_S, 222)
7373
ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_SIZE, 223)
74+
ELF_RELOC(R_RISCV_CHERIOT_CCALL, 224)

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "llvm/MC/MCELFObjectWriter.h"
1414
#include "llvm/MC/MCFixup.h"
1515
#include "llvm/MC/MCObjectWriter.h"
16+
#include "llvm/MC/MCSubtargetInfo.h"
1617
#include "llvm/MC/MCValue.h"
1718
#include "llvm/Support/ErrorHandling.h"
1819

@@ -97,8 +98,13 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
9798
return ELF::R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20;
9899
case RISCV::fixup_riscv_cjal:
99100
return ELF::R_RISCV_CHERI_CJAL;
100-
case RISCV::fixup_riscv_ccall:
101+
case RISCV::fixup_riscv_ccall: {
102+
const auto *STI = Ctx.getSubtargetInfo();
103+
if (STI->getCPU() == "cheriot" || STI->getTargetTriple().getSubArch() ==
104+
Triple::RISCV32SubArch_cheriot_v1)
105+
return ELF::R_RISCV_CHERIOT_CCALL;
101106
return ELF::R_RISCV_CHERI_CCALL;
107+
}
102108
case RISCV::fixup_riscv_rvc_cjump:
103109
return ELF::R_RISCV_CHERI_RVC_CJUMP;
104110
case RISCV::fixup_riscv_add_8:

0 commit comments

Comments
 (0)