mirror of https://github.com/ipxe/ipxe.git
[libc] Add x86_64 versions of setjmp() and longjmp()
None of the x86_64 builds currently have any way of invoking these functions. They are included only to avoid introducing unnecessary architecture-specific dependencies into the self-test suite. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/35/merge
parent
00ff3d8bb3
commit
fb2bedcff3
|
@ -40,6 +40,7 @@ endif
|
|||
|
||||
# x86_64-specific directories containing source files
|
||||
#
|
||||
SRCDIRS += arch/x86_64/core
|
||||
SRCDIRS += arch/x86_64/prefix
|
||||
|
||||
# Include common x86 Makefile
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
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
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef _SETJMP_H
|
||||
#define _SETJMP_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** A jump buffer */
|
||||
typedef struct {
|
||||
/** Saved return address */
|
||||
uint64_t retaddr;
|
||||
/** Saved stack pointer */
|
||||
uint64_t stack;
|
||||
/** Saved %rbx */
|
||||
uint64_t rbx;
|
||||
/** Saved %rbp */
|
||||
uint64_t rbp;
|
||||
/** Saved %r12 */
|
||||
uint64_t r12;
|
||||
/** Saved %r13 */
|
||||
uint64_t r13;
|
||||
/** Saved %r14 */
|
||||
uint64_t r14;
|
||||
/** Saved %r15 */
|
||||
uint64_t r15;
|
||||
} jmp_buf[1];
|
||||
|
||||
extern int __asmcall __attribute__ (( returns_twice ))
|
||||
setjmp ( jmp_buf env );
|
||||
|
||||
extern void __asmcall __attribute__ (( noreturn ))
|
||||
longjmp ( jmp_buf env, int val );
|
||||
|
||||
#endif /* _SETJMP_H */
|
Loading…
Reference in New Issue