CHERIoT-Platform / llvm-project

Fork of LLVM adding CHERIoT, based on the CHERI LLVM fork
4 stars 6 forks source link

Capability structs passed as variadic arguments attempt to use illegal LC.DDC instruction #36

Closed djlowther closed 4 months ago

djlowther commented 4 months ago

Structs containing capabilities are not handled correctly when passed by value as variadic arguments. For example:

#include <stdarg.h>

typedef struct {
   void * a;
   int b;
   char c[4];
} bar_t;

extern int onward(void*, int, char*);

int foo(va_list ap) {
    bar_t x = va_arg(ap, bar_t);
    return onward(x.a, x.b, x.c);
}

compiles (with -std=c2x -nostdlib -target riscv32-unknown-unknown -mcpu=cheriot -mabi=cheriot -mxcheri-rvc -mrelax -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -fno-exceptions -fno-asynchronous-unwind-tables -S and using the stdarg.h header from the cheriot-rtos project) to:

foo:
        cincoffset      csp, csp, -32
        csc     cra, 24(csp)
        cgetaddr        a1, ca0
        addi    a1, a1, 7
        andi    a1, a1, -8
        csetaddr        ca0, ca0, a1
        clw     a0, 0(ca0)
        lc.ddc  ca1, (a0)
        cincoffset      ca2, csp, 8
        csetbounds      ca2, ca2, 16
        csc     ca1, 0(ca2)
        addi    a0, a0, 8
        lc.ddc  ca0, (a0)
        csc     ca0, 8(ca2)
        clc     ca0, 8(csp)
        clw     a1, 16(csp)
        cincoffset      ca2, ca2, 12
        ccall   onward
        clc     cra, 24(csp)
        cincoffset      csp, csp, 32
        cret

In particular, it uses the LC.DDC instruction which is invalid on CHERIoT as a purecap-only architecture. Structs which do not contain capabilities appear to be handled correctly.

davidchisnall commented 4 months ago

Thanks, that's a great test case, I'll look into it.