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
|
# x86_64-specific directories containing source files
|
||||||
#
|
#
|
||||||
|
SRCDIRS += arch/x86_64/core
|
||||||
SRCDIRS += arch/x86_64/prefix
|
SRCDIRS += arch/x86_64/prefix
|
||||||
|
|
||||||
# Include common x86 Makefile
|
# 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