akaros/kern/arch/x86/setjmp64.S
<<
>>
Prefs
   1# Kernel implementations for a slim setjmp/longjmp.
   2#
   3# int setjmp(struct jmpbuf *env);
   4# void longjmp(struct jmpbuf *env, int val);
   5#
   6# Callers *must* clobber all callee-saved registers first, e.g.:
   7#       asm volatile ("" : : : "rbx", "r12", "r13", "r14", "r15");
   8
   9# The jmpbuf struct is defined as below:
  10# struct jmpbuf {
  11#       uintptr_t retaddr; // return address
  12#       uintreg_t rsp;     // post-return rsp
  13#       uintreg_t rbp;
  14# };
  15
  16.text
  17.align 4
  18.globl slim_setjmp
  19.type slim_setjmp, @function
  20slim_setjmp:
  21        xorl %eax,%eax     # Zero out the return value for our first return
  22        pop  %rsi          # Temporarily grab the return address and adjust %rsp
  23        movq %rsi,(%rdi)   # Save the return address
  24        movq %rsp,8(%rdi)  # The adjusted %rsp is the post-return %rsp
  25                           # (see longjmp)
  26        movq %rbp,16(%rdi)
  27        push %rsi          # Restore stuff to make the call/return stack happy
  28        ret
  29
  30.size slim_setjmp,.-slim_setjmp
  31
  32.text
  33.align 4
  34.globl longjmp
  35.type longjmp, @function
  36longjmp:
  37        movl %esi,%eax     # Set the return value to val (32-bit int)
  38        movq 16(%rdi),%rbp
  39        movq 8(%rdi),%rsp  # Set the post-return %rsp
  40        jmp *(%rdi)        # Jump back to setjmp callsite (no ret necessary)
  41
  42.size longjmp,.-longjmp
  43