I understand that compiler-rt and llvm-libc doesn’t have the software shadow call stack (SW SCS) support for RISC-V yet.
Were there any prior efforts on implementing the required support? I couldn’t find any references related to the prior efforts.
Also, none of glibc/newlib/picolibc/musl libraries have the software shadow call stack support for RISC-V yet. I know that patches to support hardware shadow call stack (HW SCS) in glibc are under review but, well, that’s for HW SCS support.
While SW SCS support for RISC-V is added a while ago in LLVM, what is blocking to implement the required run-time/library support for it?
Is it because we now need to bump up the setjmp/longjmp’s jmp_buf size to accommodate GP (x3) register save/restore and that breaks ABI? Are there any other challenges or it’s just that no one had the time to go ahead and actually implement it?
Since the zicfilp and zicfiss extensions are ratified recently, are people trying to move to using HW SCS rather than waiting for complete SW SCS support?
What is the way forward for baremetal use cases that require SW SCS capability, but the hardware doesn’t implement zicfiss extension?
As far as I am aware, we provide no runtime support for any shadow call stack implementation for any target, and not just RISC-V. Setting up SCS normally involves setting things up correctly during thread creation. Both Android(bionic) and Fuchsia(musl fork) support Shadow Call Stacks in their runtime implementations, and you’re free to use those as the basis for your own, modulo any licensing concerns.
For RISC-V the ABI is simple, the X3 (gp) register must be reserved as a platform reg (e.g. not used for gp relaxation or otherwise used by the compiler), and then when threads are created(or in startup code), the register must be set to a valid region in memory prior to thread start. Any other ABI details for RISC-V are outlined in the RISC-V psABI GitHub - riscv-non-isa/riscv-elf-psabi-doc: A RISC-V ELF psABI Document . LLVM has no plans (and AFAICT no viable method) to support a runtime implementation as part of compiler-rt for RISC-V or for any other target architecture (or platform).
As mentioned in the RISC-V Sync, llvm-libc may want to support SCS at some point down the line, but that is likely not going to be any time soon. There are a number of other things that should be supported before a SCS would be considered ready to deploy, though I don’t think anyone would be opposed to someone working toward that support.
Thanks for the reply, @ilovepi, and sharing those details. They are really helpful.
Could you please share more on the following?
Is it because, to start with, compiler-rt isn’t the right place for SCS run-time or it will involve heavy lifting to implement it in compiler-rt?
Were there any previous discussions on the below topic? If yes, could you please share links to those discussions, if there any and available in the public domain? I couldn’t find any related threads.
Basically, yes. we can’t really set up a SCS and keep it sane if the platform isn’t reserving the register globally, and I don’t think any of our runtimes mess with thread creation. SafeStack is in a different situation, since that doesn’t affect the ABI (except maybe how you manage the unsafe stack pointer) and some runtime hooks would work fine w/o breaking unwinding or any other functionality. Fuchsia and Android store the unsafe stack pointer relative to fs/gs on x86_64, and we both only use SafeStack when SCS is not an option.
On Fuchsia, SCS requires support both in pthreads and in the dynamic linker. I think other platforms require similar cooperation, but I could be wrong about them, so take that with a grain of salt.
llvm-libc is maturing, but is still quite new. Many parts of the library are in a functional, but not production quality state. @michaelrj-google can speak more authoritatively about the precise situation in llvm-libc.
Hi, LLVM-libc lead maintainer here. Short version: We don’t have shadow call stack right now on any platform. I’m fine with adding it, but it’s not a thing we’ve prioritized.
I’m pretty sure shadow call stack has been discussed but I couldn’t find any reference in the LLVM-libc meeting notes (Monthly LLVM libc meeting) so it was probably just casually.
LLVM-libc has most of pthreads and setjmp/longjmp implemented and I don’t think an ABI break would be a problem for those currently. If someone wanted to contribute SCS support it should be doable, the first step would probably be to put up an RFC with a detailed plan of how it would be implemented and get feedback from the community.