Browse Source

[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>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
fb2bedcff3
3 changed files with 100 additions and 0 deletions
  1. 1
    0
      src/arch/x86_64/Makefile
  2. 65
    0
      src/arch/x86_64/core/setjmp.S
  3. 34
    0
      src/arch/x86_64/include/setjmp.h

+ 1
- 0
src/arch/x86_64/Makefile View File

@@ -40,6 +40,7 @@ endif
40 40
 
41 41
 # x86_64-specific directories containing source files
42 42
 #
43
+SRCDIRS		+= arch/x86_64/core
43 44
 SRCDIRS		+= arch/x86_64/prefix
44 45
 
45 46
 # Include common x86 Makefile

+ 65
- 0
src/arch/x86_64/core/setjmp.S View File

@@ -0,0 +1,65 @@
1
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
2
+
3
+	.text
4
+	.code64
5
+
6
+	/* Must match jmp_buf structure layout */
7
+	.struct	0
8
+env_retaddr:	.quad	0
9
+env_stack:	.quad	0
10
+env_rbx:	.quad	0
11
+env_rbp:	.quad	0
12
+env_r12:	.quad	0
13
+env_r13:	.quad	0
14
+env_r14:	.quad	0
15
+env_r15:	.quad	0
16
+	.previous
17
+
18
+/*
19
+ * Save stack context for non-local goto
20
+ */
21
+	.globl	setjmp
22
+setjmp:
23
+	/* Save return address */
24
+	movq	0(%rsp), %rax
25
+	movq	%rax, env_retaddr(%rdi)
26
+	/* Save stack pointer */
27
+	movq	%rsp, env_stack(%rdi)
28
+	/* Save other registers */
29
+	movq	%rbx, env_rbx(%rdi)
30
+	movq	%rbp, env_rbp(%rdi)
31
+	movq	%r12, env_r12(%rdi)
32
+	movq	%r13, env_r13(%rdi)
33
+	movq	%r14, env_r14(%rdi)
34
+	movq	%r15, env_r15(%rdi)
35
+	/* Return 0 when returning as setjmp() */
36
+	xorq	%rax, %rax
37
+	ret
38
+	.size	setjmp, . - setjmp
39
+
40
+/*
41
+ * Non-local jump to a saved stack context
42
+ */
43
+	.globl	longjmp
44
+longjmp:
45
+	/* Get result in %rax */
46
+	movq	%rsi, %rax
47
+	/* Force result to non-zero */
48
+	testq	%rax, %rax
49
+	jnz	1f
50
+	incq	%rax
51
+1:	/* Restore stack pointer */
52
+	movq	env_stack(%rdi), %rsp
53
+	/* Restore other registers */
54
+	movq	env_rbx(%rdi), %rbx
55
+	movq	env_rbp(%rdi), %rbp
56
+	movq	env_r12(%rdi), %r12
57
+	movq	env_r13(%rdi), %r13
58
+	movq	env_r14(%rdi), %r14
59
+	movq	env_r15(%rdi), %r15
60
+	/* Replace return address on the new stack */
61
+	popq	%rcx	/* discard */
62
+	pushq	env_retaddr(%rdi)
63
+	/* Return to setjmp() caller */
64
+	ret
65
+	.size	longjmp, . - longjmp

+ 34
- 0
src/arch/x86_64/include/setjmp.h View File

@@ -0,0 +1,34 @@
1
+#ifndef _SETJMP_H
2
+#define _SETJMP_H
3
+
4
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
5
+
6
+#include <stdint.h>
7
+
8
+/** A jump buffer */
9
+typedef struct {
10
+	/** Saved return address */
11
+	uint64_t retaddr;
12
+	/** Saved stack pointer */
13
+	uint64_t stack;
14
+	/** Saved %rbx */
15
+	uint64_t rbx;
16
+	/** Saved %rbp */
17
+	uint64_t rbp;
18
+	/** Saved %r12 */
19
+	uint64_t r12;
20
+	/** Saved %r13 */
21
+	uint64_t r13;
22
+	/** Saved %r14 */
23
+	uint64_t r14;
24
+	/** Saved %r15 */
25
+	uint64_t r15;
26
+} jmp_buf[1];
27
+
28
+extern int __asmcall __attribute__ (( returns_twice ))
29
+setjmp ( jmp_buf env );
30
+
31
+extern void __asmcall __attribute__ (( noreturn ))
32
+longjmp ( jmp_buf env, int val );
33
+
34
+#endif /* _SETJMP_H */

Loading…
Cancel
Save