xref: /dragonfly/lib/libc/x86_64/sys/getcontext.S (revision bc27e030)
11b773b6eSMarkus Pfeiffer/*
21b773b6eSMarkus Pfeiffer * Copyright (c) 2006 The DragonFly Project.  All rights reserved.
31b773b6eSMarkus Pfeiffer *
41b773b6eSMarkus Pfeiffer * This code is derived from software contributed to The DragonFly Project
51b773b6eSMarkus Pfeiffer * by Matthew Dillon <dillon@backplane.com>
61b773b6eSMarkus Pfeiffer *
71b773b6eSMarkus Pfeiffer * Redistribution and use in source and binary forms, with or without
81b773b6eSMarkus Pfeiffer * modification, are permitted provided that the following conditions
91b773b6eSMarkus Pfeiffer * are met:
101b773b6eSMarkus Pfeiffer *
111b773b6eSMarkus Pfeiffer * 1. Redistributions of source code must retain the above copyright
121b773b6eSMarkus Pfeiffer *    notice, this list of conditions and the following disclaimer.
131b773b6eSMarkus Pfeiffer * 2. Redistributions in binary form must reproduce the above copyright
141b773b6eSMarkus Pfeiffer *    notice, this list of conditions and the following disclaimer in
151b773b6eSMarkus Pfeiffer *    the documentation and/or other materials provided with the
161b773b6eSMarkus Pfeiffer *    distribution.
171b773b6eSMarkus Pfeiffer * 3. Neither the name of The DragonFly Project nor the names of its
181b773b6eSMarkus Pfeiffer *    contributors may be used to endorse or promote products derived
191b773b6eSMarkus Pfeiffer *    from this software without specific, prior written permission.
201b773b6eSMarkus Pfeiffer *
211b773b6eSMarkus Pfeiffer * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
221b773b6eSMarkus Pfeiffer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
231b773b6eSMarkus Pfeiffer * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
241b773b6eSMarkus Pfeiffer * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
251b773b6eSMarkus Pfeiffer * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
261b773b6eSMarkus Pfeiffer * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
271b773b6eSMarkus Pfeiffer * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
281b773b6eSMarkus Pfeiffer * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
291b773b6eSMarkus Pfeiffer * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
301b773b6eSMarkus Pfeiffer * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
311b773b6eSMarkus Pfeiffer * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
321b773b6eSMarkus Pfeiffer * SUCH DAMAGE.
331b773b6eSMarkus Pfeiffer *
341b773b6eSMarkus Pfeiffer */
351b773b6eSMarkus Pfeiffer
361b773b6eSMarkus Pfeiffer#include <machine/asm.h>
3763261abbSMatthew Dillon#include <cpu/specialreg.h>
381b773b6eSMarkus Pfeiffer#include <asmcontext.h>
391b773b6eSMarkus Pfeiffer
401b773b6eSMarkus Pfeiffer	/*
411b773b6eSMarkus Pfeiffer	 * This function is special-cased because the context it saves
421b773b6eSMarkus Pfeiffer	 * includes a stale stack context (because it returns before the
431b773b6eSMarkus Pfeiffer	 * caller presumably makes the call to setcontext()).
441b773b6eSMarkus Pfeiffer	 */
451b773b6eSMarkus Pfeiffer	.weak	getcontext
461b773b6eSMarkus Pfeiffer	.set	getcontext,_getcontext
471b773b6eSMarkus PfeifferENTRY(_getcontext)
481b773b6eSMarkus Pfeiffer	/*
491b773b6eSMarkus Pfeiffer	 * Retrieve the current signal mask and save it in &ucp->uc_sigmask.
501b773b6eSMarkus Pfeiffer	 */
511b773b6eSMarkus Pfeiffer	pushq	%rdi			/* save ucontext_t pointer passed */
521b773b6eSMarkus Pfeiffer	movq	%rdi,%rdx
531b773b6eSMarkus Pfeiffer	addq	$UC_SIGMASK,%rdx	/* pointer to signal mask */
541b773b6eSMarkus Pfeiffer	movq	$0,%rsi
551b773b6eSMarkus Pfeiffer	movq	$SIG_BLOCK,%rdi
561b773b6eSMarkus Pfeiffer	call    PIC_PLT(CNAME(_sigprocmask))
571b773b6eSMarkus Pfeiffer	/*
581b773b6eSMarkus Pfeiffer	 * Save what we need because our stack context is going stale.
591b773b6eSMarkus Pfeiffer	 */
601b773b6eSMarkus Pfeiffer	popq	%rdi
6163261abbSMatthew Dillon	movq	$0,UC_LINK(%rdi)	/* make sure UC_LINK is clear */
6263261abbSMatthew Dillon	movq	%rdi,%r9		/* save ucontext in %r9 */
6363261abbSMatthew Dillon	movq	(%rsp),%r8		/* save return PC in %r8 */
641b773b6eSMarkus Pfeiffer	addq	$UC_MCONTEXT,%rdi
6563261abbSMatthew Dillon
6663261abbSMatthew Dillon	movq	$0,MC_ONSTACK(%rdi)	/*	MC_ONSTACK(%rdi)	*/
6763261abbSMatthew Dillon	movq	%rdi,MC_RDI(%rdi)
6863261abbSMatthew Dillon	movq	%rsi,MC_RSI(%rdi)
6963261abbSMatthew Dillon	movq	%rdx,MC_RDX(%rdi)
7063261abbSMatthew Dillon	movq	%r8,MC_R8(%rdi)
7163261abbSMatthew Dillon	movq	%r9,MC_R9(%rdi)
7263261abbSMatthew Dillon	/* movq	%rax,MC_RAX(%rdi) - not needed, replaced below */
7363261abbSMatthew Dillon	movq	%rbx,MC_RBX(%rdi)
7463261abbSMatthew Dillon	/* movq %rcx,MC_RCX(%rdi) - not needed, scratch */
7563261abbSMatthew Dillon	movq	%rbp,MC_RBP(%rdi)
7663261abbSMatthew Dillon	movq	%r10,MC_R10(%rdi)
7763261abbSMatthew Dillon	movq	%r11,MC_R11(%rdi)
7863261abbSMatthew Dillon	movq	%r12,MC_R12(%rdi)
7963261abbSMatthew Dillon	movq	%r13,MC_R13(%rdi)
8063261abbSMatthew Dillon	movq	%r14,MC_R14(%rdi)
8163261abbSMatthew Dillon	movq	%r15,MC_R15(%rdi)
8263261abbSMatthew Dillon	/*	MC_TRAPNO(%rdi)	*/
8363261abbSMatthew Dillon	/*	MC_ADDR(%rdi)	*/
8463261abbSMatthew Dillon	/*	MC_FLAGS(%rdi)	*/
8563261abbSMatthew Dillon	/*	MC_ERR(%rdi)	*/
8663261abbSMatthew Dillon	/*	MC_RIP(%rdi)	- see below */
8763261abbSMatthew Dillon	/*	MC_CS(%rdi)	*/
8863261abbSMatthew Dillon	movq	$KUCSEL,MC_CS(%rdi)
8963261abbSMatthew Dillon
9063261abbSMatthew Dillon	pushfq
9163261abbSMatthew Dillon	popq	MC_RFLAGS(%rdi)
9263261abbSMatthew Dillon	/*	MC_RSP(%rdi)	- see below */
9363261abbSMatthew Dillon	movq	$KUDSEL,MC_SS(%rdi)
9463261abbSMatthew Dillon
951b773b6eSMarkus Pfeiffer	/*
9663261abbSMatthew Dillon	 * FP registers are scratch, do not save or restore, but make
9763261abbSMatthew Dillon	 * sure the context can be restored by a signal handler (where
9863261abbSMatthew Dillon	 * they might not be) by properly initializing the FP control
9963261abbSMatthew Dillon	 * fields.
1001b773b6eSMarkus Pfeiffer	 */
10163261abbSMatthew Dillon	movl	$_MC_FPOWNED_NONE,MC_OWNEDFP(%rdi)
10263261abbSMatthew Dillon	movl	$_MC_FPFMT_NODEV,MC_FPFORMAT(%rdi)
103*bc27e030SMatthew Dillon#if 0
10463261abbSMatthew Dillon	movl	$_MC_FPFMT_YMM,MC_FPFORMAT(%rdi)
10563261abbSMatthew Dillon	movq	%rdi,%rsi
10663261abbSMatthew Dillon	movq	$CPU_XFEATURE_X87 | CPU_XFEATURE_SSE | CPU_XFEATURE_YMM,%rax
1071b773b6eSMarkus Pfeiffer	movq	$0,%rdx
10863261abbSMatthew Dillon	xsave	MC_FPREGS(%rsi)
10963261abbSMatthew Dillon	movq	%rsi,%rdi
110*bc27e030SMatthew Dillon#endif
11163261abbSMatthew Dillon
11263261abbSMatthew Dillon	/*
11363261abbSMatthew Dillon	 * Saved stack pointer as if we had returned from this
11463261abbSMatthew Dillon	 * procedure.
11563261abbSMatthew Dillon	 */
11663261abbSMatthew Dillon	movq	%rsp,MC_RSP(%rdi)
11763261abbSMatthew Dillon	addq	$8,MC_RSP(%rdi)
11863261abbSMatthew Dillon
11963261abbSMatthew Dillon	/*
12063261abbSMatthew Dillon	 * Save rflags
12163261abbSMatthew Dillon	 * XXX
12263261abbSMatthew Dillon	 */
12363261abbSMatthew Dillon
12463261abbSMatthew Dillon	/*
12563261abbSMatthew Dillon	 * Saved instruction pointer as if we had returned from
12663261abbSMatthew Dillon	 * this procedure.
12763261abbSMatthew Dillon	 */
12863261abbSMatthew Dillon	movq	(%rsp),%rdx
12963261abbSMatthew Dillon	movq	%rdx,MC_RIP(%rdi)
13063261abbSMatthew Dillon
13163261abbSMatthew Dillon	/*
13263261abbSMatthew Dillon	 * On restore as if procedure returned the value 1
13363261abbSMatthew Dillon	 */
13463261abbSMatthew Dillon	movq	$1,MC_RAX(%rdi)
13563261abbSMatthew Dillon
13663261abbSMatthew Dillon	/*
13763261abbSMatthew Dillon	 * Set MC_LEN
13863261abbSMatthew Dillon	 */
13963261abbSMatthew Dillon	movl    $SIZEOF_MCONTEXT_T,MC_LEN(%rdi)
14063261abbSMatthew Dillon
14163261abbSMatthew Dillon	/*
14263261abbSMatthew Dillon	 * Return 0
14363261abbSMatthew Dillon	 */
14463261abbSMatthew Dillon	subq	%rax,%rax
1451b773b6eSMarkus Pfeiffer	ret
14663261abbSMatthew Dillon
14763261abbSMatthew Dillon#if 0
1481b773b6eSMarkus Pfeiffer1:
1491b773b6eSMarkus Pfeiffer	pushq	%rsi
1501b773b6eSMarkus Pfeiffer#ifdef PIC
1511b773b6eSMarkus Pfeiffer	movq	PIC_GOT(HIDENAME(cerror)),%rdx
1521b773b6eSMarkus Pfeiffer	jmp	*%rdx
1531b773b6eSMarkus Pfeiffer#else
1541b773b6eSMarkus Pfeiffer	jmp	HIDENAME(cerror)
1551b773b6eSMarkus Pfeiffer#endif
15663261abbSMatthew Dillon#endif
1571b773b6eSMarkus PfeifferEND(_getcontext)
1588b927cb7SJohn Marino
1598b927cb7SJohn Marino	.section .note.GNU-stack,"",%progbits
160