Skip to content

Commit 24ed857

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 264de73 commit 24ed857

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

lld/ELF/Arch/RISCV.cpp

+30-5
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
367367
case R_RISCV_CALL:
368368
case R_RISCV_CALL_PLT:
369369
case R_RISCV_CHERI_CCALL:
370+
case R_RISCV_CHERIOT_CCALL:
370371
case R_RISCV_PLT32:
371372
return R_PLT_PC;
372373
case R_RISCV_GOT_HI20:
@@ -523,6 +524,24 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
523524
return;
524525
}
525526

527+
case R_RISCV_CHERIOT_CCALL: {
528+
// Cheriot uses an 11-bit shift on AUIPCC, requiring different relocation
529+
// compared to R_RISCV_CHERI_CCALL.
530+
int64_t hi = SignExtend64(val + 0x800, bits) >> 12;
531+
checkInt(loc, hi, 20, rel);
532+
if (isInt<20>(hi)) {
533+
relocate(loc,
534+
Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_HI, rel.offset,
535+
rel.addend, rel.sym},
536+
val);
537+
relocate(loc + 4,
538+
Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_LO_I,
539+
rel.offset, rel.addend, rel.sym},
540+
val);
541+
}
542+
return;
543+
}
544+
526545
case R_RISCV_CHERI_CAPTAB_PCREL_HI20:
527546
case R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20:
528547
case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20:
@@ -895,15 +914,15 @@ void elf::initSymbolAnchors() {
895914
}
896915

897916
// Relax R_RISCV_CALL/R_RISCV_CALL_PLT auipc+jalr to c.j, c.jal, or jal.
898-
// Relax R_RISCV_CHERI_CCALL auipcc+cjalr to c.cj, c.cjal, or cjal.
917+
// Relax R_RISCV_CHERI[OT]_CCALL auipcc+cjalr to c.cj, c.cjal, or cjal.
899918
static void relaxCall(const InputSection &sec, size_t i, uint64_t loc,
900919
Relocation &r, uint32_t &remove) {
901920
// We need to emit the correct relocations for CHERI, although the instruction
902921
// encodings are exactly the same with vanilla RISC-V.
903-
auto jalRVCType = (r.type == R_RISCV_CHERI_CCALL) ? R_RISCV_CHERI_RVC_CJUMP
904-
: R_RISCV_RVC_JUMP;
905-
auto jalType = (r.type == R_RISCV_CHERI_CCALL) ? R_RISCV_CHERI_CJAL
906-
: R_RISCV_JAL;
922+
bool isCCall =
923+
(r.type == R_RISCV_CHERI_CCALL) || (r.type == R_RISCV_CHERIOT_CCALL);
924+
auto jalRVCType = (isCCall) ? R_RISCV_CHERI_RVC_CJUMP : R_RISCV_RVC_JUMP;
925+
auto jalType = (isCCall) ? R_RISCV_CHERI_CJAL : R_RISCV_JAL;
907926
const bool rvc = getEFlags(sec.file) & EF_RISCV_RVC;
908927
const Symbol &sym = *r.sym;
909928
const uint64_t insnPair = read64le(sec.content().data() + r.offset);
@@ -1120,7 +1139,13 @@ static bool relax(InputSection &sec, int pass) {
11201139
case R_RISCV_CALL:
11211140
case R_RISCV_CALL_PLT:
11221141
case R_RISCV_CHERI_CCALL:
1142+
<<<<<<< HEAD
11231143
if (relaxable(relocs, i))
1144+
=======
1145+
case R_RISCV_CHERIOT_CCALL:
1146+
if (i + 1 != sec.relocs().size() &&
1147+
sec.relocs()[i + 1].type == R_RISCV_RELAX)
1148+
>>>>>>> 4feeffbf8ec3 ([cheriot] Add an R_RISCV_CHERIOT_CCALL reloc)
11241149
relaxCall(sec, i, loc, r, remove);
11251150
break;
11261151
case R_RISCV_TPREL_HI20:

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

+1
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,4 @@ ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_HI, 220)
7777
ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_LO_I, 221)
7878
ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_LO_S, 222)
7979
ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_SIZE, 223)
80+
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

@@ -105,8 +106,13 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
105106
return ELF::R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20;
106107
case RISCV::fixup_riscv_cjal:
107108
return ELF::R_RISCV_CHERI_CJAL;
108-
case RISCV::fixup_riscv_ccall:
109+
case RISCV::fixup_riscv_ccall: {
110+
const auto *STI = Ctx.getSubtargetInfo();
111+
if (STI->getCPU() == "cheriot" || STI->getTargetTriple().getSubArch() ==
112+
Triple::RISCV32SubArch_cheriot_v1)
113+
return ELF::R_RISCV_CHERIOT_CCALL;
109114
return ELF::R_RISCV_CHERI_CCALL;
115+
}
110116
case RISCV::fixup_riscv_rvc_cjump:
111117
return ELF::R_RISCV_CHERI_RVC_CJUMP;
112118
case RISCV::fixup_riscv_cheriot_compartment_hi:

0 commit comments

Comments
 (0)