I'm working on a setjmp
/longjmp
custom implementation for x86-64 systems which saves the whole context of the CPU (namely, all xmm, fpu stack, etc; not only callee-save registers). This is written directly in assembly.
The code works fine in minimal examples (when calling it directly from an assembly source). The problem arises when using it with C code, due to the way parameters are passed to the homebrew setjmp
/longjmp
functions. In fact, SysV ABI for x64_64 systems dictates that arguments should be passed via registers (if they are at most 6). The signature of my functions are:
long long set_jmp(exec_context_t *env);
__attribute__ ((__noreturn__)) void long_jmp(exec_context_t *env, long long val);
Of course, this cannot work as is. In fact, when I enter set_jmp
, rdi
and rsi
have already been clobbered to keep a pointer to env
and val
. The same applies to long_jmp
with respect to rdi
.
Is there any way to force GCC, e.g. by relying on some attribute, to force argument passing via stack? This would be much more elegant than wrapping set_jmp
and long_jmp
with some define which manually pushes the clobbered registers on stack, so as to retrieve them later.