1/*	$OpenBSD: setjmp.S,v 1.12 2023/12/10 16:45:51 deraadt Exp $	*/
2
3/*-
4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "SYS.h"
37
38	.section	.openbsd.randomdata,"aw",@progbits
39	.align	4
40.L__jmpxor
41	.zero	4*2		; (r2/rp, r30/sp)
42
43/*
44 * C library -- setjmp, longjmp
45 *
46 *	longjmp(a,v)
47 * will generate a "return(v)" from
48 * the last call to
49 *	setjmp(a)
50 * by restoring registers from the stack,
51 * and a struct sigcontext, see <signal.h>
52 */
53
54ENTRY(sigsetjmp, 64)
55	sub,<>	%r0, %arg1, %r0
56	b	.L_setjmp$dosaves
57	 stw	%arg1, 44(%arg0)	; last of reserved words
58
59ALTENTRY(setjmp)
60	copy	%arg0, %arg2		; save jmpbuf in %arg2
61
62	ldi	1, %arg0		; how = SIG_BLOCK
63	copy	%r0, %arg1		; set = empty
64	stw	%rp, HPPA_FRAME_ERP(%sr0,%sp)
65	ldil	L%SYSCALLGATE, %r1
6699:	ble	4(%sr7, %r1)
67	PINSYSCALL(SYS_sigprocmask, 99b)
68	 ldi	SYS_sigprocmask, %t1
69	ldw	HPPA_FRAME_ERP(%sr0,%sp), %rp
70
71	copy	%arg2, %arg0		; restore jmpbuf to %arg0
72	stw	%ret0, 4(%arg0)		; mask
73
74ALTENTRY(_setjmp)
75.L_setjmp$dosaves
76#ifdef __PIC__
77	addil	LT%.L__jmpxor, %r19
78	ldw	RT%.L__jmpxor(%r1), %t2
79#else
80	ldil	L%.L__jmpxor, %t1
81	ldo	R%.L__jmpxor(%t1), %t2
82#endif
83	ldw	0(%t2), %t1		; xor for r2/rp
84	ldw	4(%t2), %t2		; xor for r30/sp, overwrite address
85
86	xor	%sp, %t2, %t2
87	stw	%t2, 12(%arg0)		; sc.sc_sp = %sp
88	xor	%rp, %t1, %t1
89	stw	%t1, 20(%arg0)		; sc.sc_pcoqh = %rp
90	copy	%r0, %t1
91	copy	%r0, %t2
92
93	/* We store all callee-saved registers after the sigcontext. */
94	ldo	48(%arg0), %r1		; offset to after sc
95	stwm	%r3, 4(%r1)
96	stwm	%r4, 4(%r1)
97	stwm	%r5, 4(%r1)
98	stwm	%r6, 4(%r1)
99	stwm	%r7, 4(%r1)
100	stwm	%r8, 4(%r1)
101	stwm	%r9, 4(%r1)
102	stwm	%r10, 4(%r1)
103	stwm	%r11, 4(%r1)
104	stwm	%r12, 4(%r1)
105	stwm	%r13, 4(%r1)
106	stwm	%r14, 4(%r1)
107	stwm	%r15, 4(%r1)
108	stwm	%r16, 4(%r1)
109	stwm	%r17, 4(%r1)
110	stwm	%r18, 4(%r1)
111
112	/* Return 0. */
113	bv	%r0(%rp)
114	 copy	%r0, %ret0
115EXIT(sigsetjmp)
116	.size _setjmp, . - _setjmp
117	.size setjmp, . - setjmp
118
119ENTRY(siglongjmp,64)
120	ldw	44(%arg0), %arg2
121	sub,<>	%r0, %arg2, %r0
122	b	.L_longjmp$restores
123	 nop
124
125ALTENTRY(longjmp)
126	copy	%arg1, %arg3		; save val in %arg3
127	copy	%arg0, %arg2		; save jmpbuf in %arg2
128
129	ldw	4(%arg0), %arg1		; set from jumpbuf
130	ldi	3, %arg0		; how = SIG_SETMASK
131	stw	%rp, HPPA_FRAME_ERP(%sr0,%sp)
132	ldil	L%SYSCALLGATE, %r1
13398:	ble	4(%sr7, %r1)
134	PINSYSCALL(SYS_sigprocmask, 98b)
135	 ldi	SYS_sigprocmask, %t1
136	ldw	HPPA_FRAME_ERP(%sr0,%sp), %rp
137
138	copy	%arg2, %arg0		; restore jmpbuf to %arg0
139	copy	%arg3, %arg1		; restore val to %arg1
140
141ALTENTRY(_longjmp)
142.L_longjmp$restores
143	/* restore callee-saved registers */
144	ldo	48(%arg0), %r1
145	ldwm	4(%r1), %r3
146	ldwm	4(%r1), %r4
147	ldwm	4(%r1), %r5
148	ldwm	4(%r1), %r6
149	ldwm	4(%r1), %r7
150	ldwm	4(%r1), %r8
151	ldwm	4(%r1), %r9
152	ldwm	4(%r1), %r10
153	ldwm	4(%r1), %r11
154	ldwm	4(%r1), %r12
155	ldwm	4(%r1), %r13
156	ldwm	4(%r1), %r14
157	ldwm	4(%r1), %r15
158	ldwm	4(%r1), %r16
159	ldwm	4(%r1), %r17
160	ldwm	4(%r1), %r18
161
162	/* restore the rest */
163#ifdef __PIC__
164	addil	LT%.L__jmpxor, %r19
165	ldw	RT%.L__jmpxor(%r1), %t2
166#else
167	ldil	L%.L__jmpxor, t1
168	ldo	R%.L__jmpxor(t1), t2
169#endif
170	ldw	0(t2), t1		; xor for r2/rp
171	ldw	4(t2), t2		; xor for r30/sp, overwrite address
172
173	ldw	12(%arg0), %r1
174	xor	%r1, %t2, %sp
175	ldw	20(%arg0), %r1
176	xor	%r1, %t1, %rp
177	copy	%r0, %t1		; overwrite the cookies
178	copy	%r0, %t2
179	sub,<>	%arg1, %r0, %r0
180	ldo	1(%arg1), %arg1
181	bv	%r0(%rp)
182	 copy	%arg1, %ret0
183EXIT(siglongjmp)
184	.size _longjmp, . - _longjmp
185	.size longjmp, . - longjmp
186
187	.end
188