FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) .text .code64 /* Must match jmp_buf structure layout */ .struct 0 env_retaddr: .quad 0 env_stack: .quad 0 env_rbx: .quad 0 env_rbp: .quad 0 env_r12: .quad 0 env_r13: .quad 0 env_r14: .quad 0 env_r15: .quad 0 .previous /* * Save stack context for non-local goto */ .globl setjmp setjmp: /* Save return address */ movq 0(%rsp), %rax movq %rax, env_retaddr(%rdi) /* Save stack pointer */ movq %rsp, env_stack(%rdi) /* Save other registers */ movq %rbx, env_rbx(%rdi) movq %rbp, env_rbp(%rdi) movq %r12, env_r12(%rdi) movq %r13, env_r13(%rdi) movq %r14, env_r14(%rdi) movq %r15, env_r15(%rdi) /* Return 0 when returning as setjmp() */ xorq %rax, %rax ret .size setjmp, . - setjmp /* * Non-local jump to a saved stack context */ .globl longjmp longjmp: /* Get result in %rax */ movq %rsi, %rax /* Force result to non-zero */ testq %rax, %rax jnz 1f incq %rax 1: /* Restore stack pointer */ movq env_stack(%rdi), %rsp /* Restore other registers */ movq env_rbx(%rdi), %rbx movq env_rbp(%rdi), %rbp movq env_r12(%rdi), %r12 movq env_r13(%rdi), %r13 movq env_r14(%rdi), %r14 movq env_r15(%rdi), %r15 /* Replace return address on the new stack */ popq %rcx /* discard */ pushq env_retaddr(%rdi) /* Return to setjmp() caller */ ret .size longjmp, . - longjmp