xref: /dragonfly/lib/libc/x86_64/sys/getcontext.S (revision bc27e030834ccf1dc91bd4bba5a4a187c165ac64)
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