diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index 675595f682a75..ef792ac505e36 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -358,6 +358,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s, case R_RISCV_CALL: case R_RISCV_CALL_PLT: case R_RISCV_CHERI_CCALL: + case R_RISCV_CHERIOT_CCALL: case R_RISCV_PLT32: return R_PLT_PC; case R_RISCV_GOT_HI20: @@ -504,6 +505,24 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { return; } + case R_RISCV_CHERIOT_CCALL: { + // Cheriot uses an 11-bit shift on AUIPCC, requiring different relocation + // compared to R_RISCV_CHERI_CCALL. + int64_t hi = SignExtend64(val + 0x800, bits) >> 12; + checkInt(loc, hi, 20, rel); + if (isInt<20>(hi)) { + relocate(loc, + Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_HI, rel.offset, + rel.addend, rel.sym}, + val); + relocate(loc + 4, + Relocation{rel.expr, R_RISCV_CHERIOT_COMPARTMENT_LO_I, + rel.offset, rel.addend, rel.sym}, + val); + } + return; + } + case R_RISCV_CHERI_CAPTAB_PCREL_HI20: case R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20: case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20: @@ -750,15 +769,15 @@ static void initSymbolAnchors() { } // Relax R_RISCV_CALL/R_RISCV_CALL_PLT auipc+jalr to c.j, c.jal, or jal. -// Relax R_RISCV_CHERI_CCALL auipcc+cjalr to c.cj, c.cjal, or cjal. +// Relax R_RISCV_CHERI[OT]_CCALL auipcc+cjalr to c.cj, c.cjal, or cjal. static void relaxCall(const InputSection &sec, size_t i, uint64_t loc, Relocation &r, uint32_t &remove) { // We need to emit the correct relocations for CHERI, although the instruction // encodings are exactly the same with vanilla RISC-V. - auto jalRVCType = (r.type == R_RISCV_CHERI_CCALL) ? R_RISCV_CHERI_RVC_CJUMP - : R_RISCV_RVC_JUMP; - auto jalType = (r.type == R_RISCV_CHERI_CCALL) ? R_RISCV_CHERI_CJAL - : R_RISCV_JAL; + bool isCCall = + (r.type == R_RISCV_CHERI_CCALL) || (r.type == R_RISCV_CHERIOT_CCALL); + auto jalRVCType = (isCCall) ? R_RISCV_CHERI_RVC_CJUMP : R_RISCV_RVC_JUMP; + auto jalType = (isCCall) ? R_RISCV_CHERI_CJAL : R_RISCV_JAL; const bool rvc = config->eflags & EF_RISCV_RVC; const Symbol &sym = *r.sym; const uint64_t insnPair = read64le(sec.content().data() + r.offset); @@ -967,6 +986,7 @@ static bool relax(InputSection &sec, int pass) { case R_RISCV_CALL: case R_RISCV_CALL_PLT: case R_RISCV_CHERI_CCALL: + case R_RISCV_CHERIOT_CCALL: if (i + 1 != sec.relocs().size() && sec.relocs()[i + 1].type == R_RISCV_RELAX) relaxCall(sec, i, loc, r, remove); diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def index 391b746169b08..dca20f4a7ef1c 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def @@ -71,3 +71,4 @@ ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_HI, 220) ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_LO_I, 221) ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_LO_S, 222) ELF_RELOC(R_RISCV_CHERIOT_COMPARTMENT_SIZE, 223) +ELF_RELOC(R_RISCV_CHERIOT_CCALL, 224) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp index 91d340087dcac..d4c0417466878 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -13,6 +13,7 @@ #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" @@ -97,8 +98,13 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx, return ELF::R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20; case RISCV::fixup_riscv_cjal: return ELF::R_RISCV_CHERI_CJAL; - case RISCV::fixup_riscv_ccall: + case RISCV::fixup_riscv_ccall: { + const auto *STI = Ctx.getSubtargetInfo(); + if (STI->getCPU() == "cheriot" || STI->getTargetTriple().getSubArch() == + Triple::RISCV32SubArch_cheriot_v1) + return ELF::R_RISCV_CHERIOT_CCALL; return ELF::R_RISCV_CHERI_CCALL; + } case RISCV::fixup_riscv_rvc_cjump: return ELF::R_RISCV_CHERI_RVC_CJUMP; case RISCV::fixup_riscv_add_8: