From ff1a3d4b772871f98cc1d4bd69468860f4ea44eb Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 20 Nov 2025 15:51:28 -0600 Subject: [PATCH] [CHERIoT] Fix a crash regression in R_RISCV_CHERIOT_CCALL handling. Add a testcase to make sure we don't regress it again. --- lld/ELF/Arch/RISCV.cpp | 20 +- .../ELF/cheri/Inputs/cheriot-ccall-spacer.s | 1040 +++++++++++++++++ lld/test/ELF/cheri/cheriot-ccall.s | 27 + 3 files changed, 1079 insertions(+), 8 deletions(-) create mode 100644 lld/test/ELF/cheri/Inputs/cheriot-ccall-spacer.s create mode 100644 lld/test/ELF/cheri/cheriot-ccall.s diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index e1b38ce6de79..c329965f56a4 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -495,14 +495,18 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { int64_t hi = SignExtend64(val + 0x800, bits) >> 12; checkInt(ctx, loc, hi, 20, rel); if (isInt<20>(hi)) { - relocateNoSym(loc, - ctx.arg.isCheriot ? R_RISCV_CHERIOT_COMPARTMENT_HI - : R_RISCV_PCREL_HI20, - val); - relocateNoSym(loc + 4, - ctx.arg.isCheriot ? R_RISCV_CHERIOT_COMPARTMENT_LO_I - : R_RISCV_PCREL_LO12_I, - val); + relocate(loc, + Relocation{R_NONE, + ctx.arg.isCheriot ? R_RISCV_CHERIOT_COMPARTMENT_HI + : R_RISCV_PCREL_HI20, + 0, 0, rel.sym}, + val); + relocate(loc + 4, + Relocation{R_NONE, + ctx.arg.isCheriot ? R_RISCV_CHERIOT_COMPARTMENT_LO_I + : R_RISCV_PCREL_LO12_I, + 0, 0, rel.sym}, + val); } return; } diff --git a/lld/test/ELF/cheri/Inputs/cheriot-ccall-spacer.s b/lld/test/ELF/cheri/Inputs/cheriot-ccall-spacer.s new file mode 100644 index 000000000000..4976fd992f66 --- /dev/null +++ b/lld/test/ELF/cheri/Inputs/cheriot-ccall-spacer.s @@ -0,0 +1,1040 @@ + + .option norvc + .text + .p2align 4 + .global spacer +spacer: + j 1f + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp +1: + cret + + .global start2 +start2: + j 2f + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp + unimp +2: + wfi + j 2 diff --git a/lld/test/ELF/cheri/cheriot-ccall.s b/lld/test/ELF/cheri/cheriot-ccall.s new file mode 100644 index 000000000000..56658c8664ff --- /dev/null +++ b/lld/test/ELF/cheri/cheriot-ccall.s @@ -0,0 +1,27 @@ +# RUN: llvm-mc -triple riscv32-unknown-unknown --mcpu=cheriot %s -filetype=obj -o %t1.o +# RUN: llvm-mc -triple riscv32-unknown-unknown -mcpu=cheriot %S/Inputs/cheriot-ccall-spacer.s -filetype=obj -o %t2.o +# RUN: ld.lld %t1.o %t2.o -Bstatic -X --no-relax -o %t3.o +# RUN: llvm-objdump -d %t3.o | FileCheck %s + +# Test that Cheriot's 11-bit AUIPCC shifts are correctly calculated. +# Originally reported as https://github.com/CHERIoT-Platform/llvm-project/issues/106 + +# CHECK-LABEL: 000110e0 : +# CHECK-NEXT: 110e0: 00001317 ct.auipcc t1, 0x1 +# CHECK-NEXT: 110e4: 01830067 ct.cjr 0x18(t1) + +# CHECK-LABEL: 000110f0 : +# CHECK-NEXT: 110f0: 0050006f j 0x118f4 +# CHECK: 118f4: 00008067 ct.cret + +# CHECK-LABEL: 000118f8 : +# CHECK-NEXT: 118f8: 0050006f j 0x120fc +# CHECK: 120fc: 10500073 wfi +# CHECK-NEXT: 12100: 0020006f j 0x12102 + + .attribute 4, 16 + .attribute 5, "rv32e2p0_m2p0_c2p0_zmmul1p0_zca1p0_xcheri0p0_xcheriot1p0_xcheripurecap0p0" + .text + .p2align 2 +start: + ct.ctail start2