blob: 93cf0ee943d704ba727fffb74ee65fbcc681fb4d [file] [log] [blame] [edit]
# Kernel implementations for setjmp/longjmp.
#
# int setjmp(struct jmpbuf *env);
# void longjmp(struct jmpbuf *env, int val);
# The jmpbuf struct is defined as below:
# struct jmpbuf {
# uintptr_t retaddr; // return address
# uintreg_t rsp; // post-return rsp
# uintreg_t rbx;
# uintreg_t rbp;
# uintreg_t r12;
# uintreg_t r13;
# uintreg_t r14;
# uintreg_t r15;
# };
.text
.align 4
.globl setjmp
.type setjmp, @function
setjmp:
xorl %eax,%eax # Zero out the return value for our first return
pop %rsi # Temporarily grab the return address and adjust %rsp
movq %rsi,(%rdi) # Save the return address
movq %rsp,8(%rdi) # The adjusted %rsp is the post-return %rsp (see longjmp)
movq %rbx,16(%rdi) # Save all the callee saved registers into the jmpbuf
movq %rbp,24(%rdi)
movq %r12,32(%rdi)
movq %r13,40(%rdi)
movq %r14,48(%rdi)
movq %r15,56(%rdi)
push %rsi # Restore stuff to make the call/return stack happy
ret
.size setjmp,.-setjmp
.text
.align 4
.globl longjmp
.type longjmp, @function
longjmp:
movl %esi,%eax # Set the return value to val (32-bit int)
movq 56(%rdi),%r15 # Restore all the callee saved registers from the jmpbuf
movq 48(%rdi),%r14
movq 40(%rdi),%r13
movq 32(%rdi),%r12
movq 24(%rdi),%rbp
movq 16(%rdi),%rbx
movq 8(%rdi),%rsp # Set the post-return %rsp
jmp *(%rdi) # Jump back to setjmp callsite (no ret necessary)
.size longjmp,.-longjmp