blob: 92bd5a9a877241e0da0e2504e66d67fce07ca195 [file] [log] [blame]
Elliott Hughes4906e562013-10-04 14:55:30 -07001/*
2 * Copyright (c) 2001 Wasabi Systems, Inc.
3 * All rights reserved.
4 *
5 * Written by Frank van der Linden for Wasabi Systems, Inc.
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 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed for the NetBSD Project by
18 * Wasabi Systems, Inc.
19 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
20 * or promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
Elliott Hughes851e68a2014-02-19 16:53:20 -080036#include <private/bionic_asm.h>
Elliott Hughes4906e562013-10-04 14:55:30 -070037
Josh Gaoc244fcb2016-03-29 14:34:03 -070038
39// The internal structure of a jmp_buf is totally private.
40// Current layout (changes from release to release):
41//
42// word name description
43// 0 rbx registers
44// 1 rbp
45// 2 r12
46// 3 r13
47// 4 r14
48// 5 r15
49// 6 rsp
50// 7 pc
51// 8 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit
52// 9 sigmask signal mask (includes rt signals as well)
53// 10 reserved
Elliott Hughes8d4c55c2014-12-05 16:25:50 -080054
55#define _JB_RBX 0
56#define _JB_RBP 1
57#define _JB_R12 2
58#define _JB_R13 3
59#define _JB_R14 4
60#define _JB_R15 5
61#define _JB_RSP 6
62#define _JB_PC 7
63#define _JB_SIGFLAG 8
64#define _JB_SIGMASK 9
Elliott Hughes4906e562013-10-04 14:55:30 -070065
Josh Gao2342e642015-09-16 18:42:45 -070066#define MANGLE_REGISTERS 1
67.macro m_mangle_registers reg
68#if MANGLE_REGISTERS
69 xorq \reg,%rbx
70 xorq \reg,%rbp
71 xorq \reg,%r12
72 xorq \reg,%r13
73 xorq \reg,%r14
74 xorq \reg,%r15
75 xorq \reg,%rsp
76 xorq \reg,%r11
77#endif
78.endm
79
80.macro m_unmangle_registers reg
81 m_mangle_registers \reg
82.endm
83
84
Elliott Hughes4906e562013-10-04 14:55:30 -070085ENTRY(setjmp)
Elliott Hughes8d4c55c2014-12-05 16:25:50 -080086 movl $1,%esi
87 jmp PIC_PLT(sigsetjmp)
Christopher Ferris507cfe22013-11-19 13:45:27 -080088END(setjmp)
Elliott Hughes4906e562013-10-04 14:55:30 -070089
Elliott Hughes8d4c55c2014-12-05 16:25:50 -080090ENTRY(_setjmp)
91 movl $0,%esi
92 jmp PIC_PLT(sigsetjmp)
93END(_setjmp)
Elliott Hughes4906e562013-10-04 14:55:30 -070094
Elliott Hughes8d4c55c2014-12-05 16:25:50 -080095// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
96ENTRY(sigsetjmp)
Josh Gao2342e642015-09-16 18:42:45 -070097 pushq %rdi
98 movq %rsi,%rdi
99 call PIC_PLT(__bionic_setjmp_cookie_get)
100 popq %rdi
101
102 // Record setjmp cookie and whether or not we're saving the signal mask.
103 movq %rax,(_JB_SIGFLAG * 8)(%rdi)
104 pushq %rax
Elliott Hughes4906e562013-10-04 14:55:30 -0700105
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800106 // Do we need to save the signal mask?
Josh Gao2342e642015-09-16 18:42:45 -0700107 testq $1,%rax
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800108 jz 2f
109
Elliott Hughes1c0c0ed2014-12-05 22:24:49 -0800110 // Save current signal mask.
111 pushq %rdi // Push 'env'.
112 // The 'how' argument is ignored if new_mask is NULL.
113 xorq %rsi,%rsi // NULL.
114 leaq (_JB_SIGMASK * 8)(%rdi),%rdx // old_mask.
115 call PIC_PLT(sigprocmask)
116 popq %rdi // Pop 'env'.
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800117
1182:
119 // Save the callee-save registers.
Josh Gao2342e642015-09-16 18:42:45 -0700120 popq %rax
121 andq $-2,%rax
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800122 movq (%rsp),%r11
Josh Gao2342e642015-09-16 18:42:45 -0700123 m_mangle_registers %rax
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800124 movq %rbx,(_JB_RBX * 8)(%rdi)
125 movq %rbp,(_JB_RBP * 8)(%rdi)
126 movq %r12,(_JB_R12 * 8)(%rdi)
127 movq %r13,(_JB_R13 * 8)(%rdi)
128 movq %r14,(_JB_R14 * 8)(%rdi)
129 movq %r15,(_JB_R15 * 8)(%rdi)
130 movq %rsp,(_JB_RSP * 8)(%rdi)
131 movq %r11,(_JB_PC * 8)(%rdi)
Josh Gao2342e642015-09-16 18:42:45 -0700132 m_unmangle_registers %rax
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800133
134 xorl %eax,%eax
135 ret
136END(sigsetjmp)
137
138// void siglongjmp(sigjmp_buf env, int value);
139ENTRY(siglongjmp)
140 movq %rdi,%r12
141 pushq %rsi // Push 'value'.
142
143 // Do we need to restore the signal mask?
Josh Gao2342e642015-09-16 18:42:45 -0700144 movq (_JB_SIGFLAG * 8)(%rdi), %rdi
145 pushq %rdi // Push cookie
146 testq $1, %rdi
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800147 jz 2f
148
149 // Restore the signal mask.
Elliott Hughes1c0c0ed2014-12-05 22:24:49 -0800150 movq $2,%rdi // SIG_SETMASK.
151 leaq (_JB_SIGMASK * 8)(%r12),%rsi // new_mask.
152 xorq %rdx,%rdx // NULL.
153 call PIC_PLT(sigprocmask)
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800154
1552:
Josh Gao2342e642015-09-16 18:42:45 -0700156 // Fetch the setjmp cookie and clear the signal flag bit.
157 popq %rcx
158 andq $-2, %rcx
159
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800160 popq %rax // Pop 'value'.
161
162 // Restore the callee-save registers.
163 movq (_JB_RBX * 8)(%r12),%rbx
164 movq (_JB_RBP * 8)(%r12),%rbp
165 movq (_JB_R13 * 8)(%r12),%r13
166 movq (_JB_R14 * 8)(%r12),%r14
167 movq (_JB_R15 * 8)(%r12),%r15
168 movq (_JB_RSP * 8)(%r12),%rsp
169 movq (_JB_PC * 8)(%r12),%r11
170 movq (_JB_R12 * 8)(%r12),%r12
Josh Gao2342e642015-09-16 18:42:45 -0700171 m_unmangle_registers %rcx
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800172
Josh Gao2342e642015-09-16 18:42:45 -0700173 // Check the cookie.
174 pushq %rax
Josh Gao8dbf02d2015-10-07 13:51:59 -0700175 pushq %r11
Josh Gao2342e642015-09-16 18:42:45 -0700176 movq %rcx, %rdi
177 call PIC_PLT(__bionic_setjmp_cookie_check)
Josh Gao8dbf02d2015-10-07 13:51:59 -0700178 popq %r11
Josh Gao2342e642015-09-16 18:42:45 -0700179 popq %rax
180
181 // Return 1 if value is 0.
Elliott Hughes8d4c55c2014-12-05 16:25:50 -0800182 testl %eax,%eax
183 jnz 1f
184 incl %eax
1851:
186 movq %r11,0(%rsp)
187 ret
188END(siglongjmp)
189
Christopher Ferris24958512015-03-25 09:12:00 -0700190ALIAS_SYMBOL(longjmp, siglongjmp)
191ALIAS_SYMBOL(_longjmp, siglongjmp)