]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/x86_64/__start_context.S
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / x86_64 / __start_context.S
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.
4
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.
9
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.
14
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/>. */
18
19 #include <sysdep.h>
20
21 #if SHSTK_ENABLED
22 # include <asm/prctl.h>
23 # include "ucontext_i.h"
24
25 /* Use CALL to push __start_context onto the new stack as well as the new
26 shadow stack. RDI points to ucontext:
27 Incoming:
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.
31 Outgoing:
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.
35 */
36
37 ENTRY(__push___start_context)
38 /* Save the pointer to ucontext. */
39 movq %rdi, %r9
40 /* Get the original shadow stack pointer. */
41 rdsspq %r8
42 /* Save the original stack pointer. */
43 movq %rsp, %rdx
44 /* Load the top of the new stack into RSI. */
45 movq oRSP(%rdi), %rsi
46 /* Add 8 bytes to RSI since CALL will push the 8-byte return
47 address onto stack. */
48 leaq 8(%rsi), %rsp
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]. */
55 syscall
56 testq %rax, %rax
57 jne L(hlt) /* This should never happen. */
58
59 /* Get the size of the new shadow stack. */
60 movq 8(%rsi), %rdi
61
62 /* Get the base address of the new shadow stack. */
63 movq (%rsi), %rsi
64
65 /* Use the restore stoken to restore the new shadow stack. */
66 rstorssp -8(%rsi, %rdi)
67
68 /* Save the restore token on the original shadow stack. */
69 saveprevssp
70
71 /* Push the address of "jmp __start_context" onto the new stack
72 as well as the new shadow stack. */
73 call 1f
74 jmp __start_context
75 1:
76
77 /* Get the new shadow stack pointer. */
78 rdsspq %rdi
79
80 /* Use the restore stoken to restore the original shadow stack. */
81 rstorssp -8(%r8)
82
83 /* Save the restore token on the new shadow stack. */
84 saveprevssp
85
86 /* Store the new shadow stack pointer in __ssp[0]. */
87 movq %rdi, oSSP(%r9)
88
89 /* Restore the original stack. */
90 mov %rdx, %rsp
91 ret
92 END(__push___start_context)
93 #endif
94
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. */
100
101
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. */
106 movq %rbx, %rsp
107
108 /* Don't use pop here so that stack is aligned to 16 bytes. */
109 movq (%rsp), %rdi /* This is the next context. */
110 testq %rdi, %rdi
111 je 2f /* If it is zero exit. */
112
113 call __setcontext
114 /* If this returns (which can happen if the syscall fails) we'll
115 exit the program with the return error value (-1). */
116 movq %rax,%rdi
117
118 2:
119 call HIDDEN_JUMPTARGET(exit)
120 /* The 'exit' call should never return. In case it does cause
121 the process to terminate. */
122 L(hlt):
123 hlt
124 END(__start_context)