1 /* Copyright (C) 2002-2019 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Andreas Jaeger <aj@suse.de>, 2002.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
22 # include <asm/prctl.h>
23 # include "ucontext_i.h"
25 /* Use CALL to push __start_context onto the new stack as well as the new
26 shadow stack. RDI points to ucontext:
28 __ssp[0]: The original caller's shadow stack pointer.
29 __ssp[1]: The size of the new shadow stack.
30 __ssp[2]: The size of the new shadow stack.
32 __ssp[0]: The new shadow stack pointer.
33 __ssp[1]: The base address of the new shadow stack.
34 __ssp[2]: The size of the new shadow stack.
37 ENTRY(__push___start_context)
38 /* Save the pointer to ucontext. */
40 /* Get the original shadow stack pointer. */
42 /* Save the original stack pointer. */
44 /* Load the top of the new stack into RSI. */
46 /* Add 8 bytes to RSI since CALL will push the 8-byte return
47 address onto stack. */
49 /* Allocate the new shadow stack. The size of the new shadow
50 stack is passed in __ssp[1]. */
51 lea (oSSP + 8)(%rdi), %RSI_LP
52 movl $ARCH_CET_ALLOC_SHSTK, %edi
53 movl $__NR_arch_prctl, %eax
54 /* The new shadow stack base is returned in __ssp[1]. */
57 jne L(hlt) /* This should never happen. */
59 /* Get the size of the new shadow stack. */
62 /* Get the base address of the new shadow stack. */
65 /* Use the restore stoken to restore the new shadow stack. */
66 rstorssp -8(%rsi, %rdi)
68 /* Save the restore token on the original shadow stack. */
71 /* Push the address of "jmp __start_context" onto the new stack
72 as well as the new shadow stack. */
77 /* Get the new shadow stack pointer. */
80 /* Use the restore stoken to restore the original shadow stack. */
83 /* Save the restore token on the new shadow stack. */
86 /* Store the new shadow stack pointer in __ssp[0]. */
89 /* Restore the original stack. */
92 END(__push___start_context)
95 /* This is the helper code which gets called if a function which is
96 registered with 'makecontext' returns. In this case we have to
97 install the context listed in the uc_link element of the context
98 'makecontext' manipulated at the time of the 'makecontext' call.
99 If the pointer is NULL the process must terminate. */
102 ENTRY(__start_context)
103 /* This removes the parameters passed to the function given to
104 'makecontext' from the stack. RBX contains the address
105 on the stack pointer for the next context. */
108 /* Don't use pop here so that stack is aligned to 16 bytes. */
109 movq (%rsp), %rdi /* This is the next context. */
111 je 2f /* If it is zero exit. */
114 /* If this returns (which can happen if the syscall fails) we'll
115 exit the program with the return error value (-1). */
119 call HIDDEN_JUMPTARGET(exit)
120 /* The 'exit' call should never return. In case it does cause
121 the process to terminate. */