blob: b4172e9d0cdb26b30e8a0963f28768196b70eccc [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 esp; // post-return esp
# uintreg_t ebx; // callee saved registers
# uintreg_t ebp;
# uintreg_t esi;
# uintreg_t edi;
# };
.text
.align 4
.globl setjmp
.type setjmp, @function
setjmp:
movl 4(%esp),%edx # Grab a reference to the jmpbuf passed in
xorl %eax,%eax # Zero out the return value for our first return
popl %ecx # Temporarily grab the return address and adjust %rsp
movl %ecx,(%edx) # Save the return address
movl %esp,4(%edx) # The adjusted %esp is the post-return %esp (see longjmp)
movl %ebx,8(%edx) # Save all the callee saved registers into the jmpbuf
movl %ebp,12(%edx)
movl %esi,16(%edx)
movl %edi,20(%edx)
pushl %ecx # Restore stuff to make the call/return stack happy
ret
.size setjmp,.-setjmp
.text
.align 4
.globl longjmp
.type longjmp, @function
longjmp:
movl 4(%esp),%edx # Grab a reference to the jmpbuf passed in
movl 8(%esp),%eax # Set the return value to val (32-bit int)
movl 20(%edx),%edi # Restore all the callee saved registers from the jmpbuf
movl 16(%edx),%esi
movl 12(%edx),%ebp
movl 8(%edx),%ebx
movl 4(%edx),%esp # Set the post-return %rsp
jmp *(%edx) # Jump back to setjmp callsite (no ret necessary)
.size longjmp,.-longjmp