Hand-written in assembly in libc, setjmp+longjmp

Also, if your goal is to support GCC, it has much worse support for __attribute__((naked)); it supports it for x86 and RISC-V but not AArch64, unlike Clang which supports all three. So you may still find you need to write it in assembly.