xref: /dragonfly/lib/libc/x86_64/sys/getcontext.S (revision 3851e4b8)
1/*
2 * Copyright (c) 2006 The DragonFly Project.  All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in
15 *    the documentation and/or other materials provided with the
16 *    distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 *    contributors may be used to endorse or promote products derived
19 *    from this software without specific, prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36#include <machine/asm.h>
37#include <cpu/specialreg.h>
38#include <asmcontext.h>
39
40	/*
41	 * This function is special-cased because the context it saves
42	 * includes a stale stack context (because it returns before the
43	 * caller presumably makes the call to setcontext()).
44	 */
45	.weak	getcontext
46	.set	getcontext,_getcontext
47ENTRY(_getcontext)
48	/*
49	 * Retrieve the current signal mask and save it in &ucp->uc_sigmask.
50	 */
51	pushq	%rdi			/* save ucontext_t pointer passed */
52	movq	%rdi,%rdx
53	addq	$UC_SIGMASK,%rdx	/* pointer to signal mask */
54	movq	$0,%rsi
55	movq	$SIG_BLOCK,%rdi
56	call    PIC_PLT(CNAME(_sigprocmask))
57	/*
58	 * Save what we need because our stack context is going stale.
59	 */
60	popq	%rdi
61	movq	$0,UC_LINK(%rdi)	/* make sure UC_LINK is clear */
62	movq	%rdi,%r9		/* save ucontext in %r9 */
63	movq	(%rsp),%r8		/* save return PC in %r8 */
64	addq	$UC_MCONTEXT,%rdi
65
66	movq	$0,MC_ONSTACK(%rdi)	/*	MC_ONSTACK(%rdi)	*/
67	movq	%rdi,MC_RDI(%rdi)
68	movq	%rsi,MC_RSI(%rdi)
69	movq	%rdx,MC_RDX(%rdi)
70	movq	%r8,MC_R8(%rdi)
71	movq	%r9,MC_R9(%rdi)
72	/* movq	%rax,MC_RAX(%rdi) - not needed, replaced below */
73	movq	%rbx,MC_RBX(%rdi)
74	/* movq %rcx,MC_RCX(%rdi) - not needed, scratch */
75	movq	%rbp,MC_RBP(%rdi)
76	movq	%r10,MC_R10(%rdi)
77	movq	%r11,MC_R11(%rdi)
78	movq	%r12,MC_R12(%rdi)
79	movq	%r13,MC_R13(%rdi)
80	movq	%r14,MC_R14(%rdi)
81	movq	%r15,MC_R15(%rdi)
82	/*	MC_TRAPNO(%rdi)	*/
83	/*	MC_ADDR(%rdi)	*/
84	/*	MC_FLAGS(%rdi)	*/
85	/*	MC_ERR(%rdi)	*/
86	/*	MC_RIP(%rdi)	- see below */
87	/*	MC_CS(%rdi)	*/
88	movq	$KUCSEL,MC_CS(%rdi)
89
90	pushfq
91	popq	MC_RFLAGS(%rdi)
92	/*	MC_RSP(%rdi)	- see below */
93	movq	$KUDSEL,MC_SS(%rdi)
94
95	/*
96	 * FP registers are scratch, do not save or restore, but make
97	 * sure the context can be restored by a signal handler (where
98	 * they might not be) by properly initializing the FP control
99	 * fields.
100	 */
101	movl	$_MC_FPOWNED_NONE,MC_OWNEDFP(%rdi)
102	movl	$_MC_FPFMT_NODEV,MC_FPFORMAT(%rdi)
103#if 0
104	movl	$_MC_FPFMT_YMM,MC_FPFORMAT(%rdi)
105	movq	%rdi,%rsi
106	movq	$CPU_XFEATURE_X87 | CPU_XFEATURE_SSE | CPU_XFEATURE_YMM,%rax
107	movq	$0,%rdx
108	xsave	MC_FPREGS(%rsi)
109	movq	%rsi,%rdi
110#endif
111
112	/*
113	 * Saved stack pointer as if we had returned from this
114	 * procedure.
115	 */
116	movq	%rsp,MC_RSP(%rdi)
117	addq	$8,MC_RSP(%rdi)
118
119	/*
120	 * Save rflags
121	 * XXX
122	 */
123
124	/*
125	 * Saved instruction pointer as if we had returned from
126	 * this procedure.
127	 */
128	movq	(%rsp),%rdx
129	movq	%rdx,MC_RIP(%rdi)
130
131	/*
132	 * On restore as if procedure returned the value 1
133	 */
134	movq	$1,MC_RAX(%rdi)
135
136	/*
137	 * Set MC_LEN
138	 */
139	movl    $SIZEOF_MCONTEXT_T,MC_LEN(%rdi)
140
141	/*
142	 * Return 0
143	 */
144	subq	%rax,%rax
145	ret
146
147#if 0
1481:
149	pushq	%rsi
150#ifdef PIC
151	movq	PIC_GOT(HIDENAME(cerror)),%rdx
152	jmp	*%rdx
153#else
154	jmp	HIDENAME(cerror)
155#endif
156#endif
157END(_getcontext)
158
159	.section .note.GNU-stack,"",%progbits
160