xref: /dragonfly/lib/libc/x86_64/sys/getcontext.S (revision 279dd846)
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 <asmcontext.h>
38
39	/*
40	 * This function is special-cased because the context it saves
41	 * includes a stale stack context (because it returns before the
42	 * caller presumably makes the call to setcontext()).
43	 */
44	.weak	getcontext
45	.set	getcontext,_getcontext
46ENTRY(_getcontext)
47	/*
48	 * Retrieve the current signal mask and save it in &ucp->uc_sigmask.
49	 */
50	pushq	%rdi			/* save ucontext_t pointer passed */
51	movq	%rdi,%rdx
52	addq	$UC_SIGMASK,%rdx	/* pointer to signal mask */
53	movq	$0,%rsi
54	movq	$SIG_BLOCK,%rdi
55	call    PIC_PLT(CNAME(_sigprocmask))
56	/*
57	 * Save what we need because our stack context is going stale.
58	 */
59	popq	%rdi
60	movq	%rdi,%r9
61	movq	(%rsp),%r8		/* save return PC in %r9 */
62	addq	$UC_MCONTEXT,%rdi
63	call	PIC_PLT(CNAME(get_mcontext))	/* returns non-zero on resume */
64	cmpl	$0,%eax				/* return type is int */
65	je	2f
66	/*
67	 * On resume, resave the stale return pc and restore the signal
68	 * mask (signals are blocked right now from the setcontext call).
69	 */
70	movq	%r8,(%rsp)		/* re-save the return PC */
71	movq	%r9,%rsi
72	addq	$UC_SIGMASK,%rsi
73        movq    $0,%rdx
74	movq	$SIG_SETMASK,%rdi
75	call	PIC_PLT(CNAME(_sigprocmask))	/* retrieve & save signal mask */
762:
77	movl	$0,%eax			/* return success */
78	ret
791:
80	pushq	%rsi
81#ifdef PIC
82	movq	PIC_GOT(HIDENAME(cerror)),%rdx
83	jmp	*%rdx
84#else
85	jmp	HIDENAME(cerror)
86#endif
87END(_getcontext)
88