xref: /openbsd-src/lib/libc/arch/powerpc64/gen/setjmp.S (revision 83762a71f74848f4d09174ce350838b4204957c5)
1*83762a71Sderaadt/*	$OpenBSD: setjmp.S,v 1.5 2023/12/10 16:45:52 deraadt Exp $ */
2e11d2af5Sdrahn/*
3e11d2af5Sdrahn * Copyright (c) 2020 Dale Rahn. All rights reserved.
4e11d2af5Sdrahn *
5e11d2af5Sdrahn *
6e11d2af5Sdrahn * Redistribution and use in source and binary forms, with or without
7e11d2af5Sdrahn * modification, are permitted provided that the following conditions
8e11d2af5Sdrahn * are met:
9e11d2af5Sdrahn * 1. Redistributions of source code must retain the above copyright
10e11d2af5Sdrahn *    notice, this list of conditions and the following disclaimer.
11e11d2af5Sdrahn * 2. Redistributions in binary form must reproduce the above copyright
12e11d2af5Sdrahn *    notice, this list of conditions and the following disclaimer in the
13e11d2af5Sdrahn *    documentation and/or other materials provided with the distribution.
14e11d2af5Sdrahn *
15e11d2af5Sdrahn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16e11d2af5Sdrahn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17e11d2af5Sdrahn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18e11d2af5Sdrahn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19e11d2af5Sdrahn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20e11d2af5Sdrahn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21e11d2af5Sdrahn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22e11d2af5Sdrahn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23e11d2af5Sdrahn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24e11d2af5Sdrahn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25e11d2af5Sdrahn */
26e11d2af5Sdrahn
27e11d2af5Sdrahn#include "SYS.h"
28e11d2af5Sdrahn#include <machine/asm.h>
29e11d2af5Sdrahn
30e11d2af5Sdrahn/* int setjmp(jmp_buf env) */
31e11d2af5Sdrahn
32e11d2af5Sdrahn#define JMP_r1	0x08
33e11d2af5Sdrahn#define JMP_r14	0x10
34e11d2af5Sdrahn#define JMP_r15	0x18
35e11d2af5Sdrahn#define JMP_r16	0x20
36e11d2af5Sdrahn#define JMP_r17	0x28
37e11d2af5Sdrahn#define JMP_r18	0x30
38e11d2af5Sdrahn#define JMP_r19	0x38
39e11d2af5Sdrahn#define JMP_r20	0x40
40e11d2af5Sdrahn#define JMP_r21	0x48
41e11d2af5Sdrahn#define JMP_r22	0x50
42e11d2af5Sdrahn#define JMP_r23	0x58
43e11d2af5Sdrahn#define JMP_r24	0x60
44e11d2af5Sdrahn#define JMP_r25	0x68
45e11d2af5Sdrahn#define JMP_r26	0x70
46e11d2af5Sdrahn#define JMP_r27	0x78
47e11d2af5Sdrahn#define JMP_r28	0x80
48e11d2af5Sdrahn#define JMP_r29	0x88
49e11d2af5Sdrahn#define JMP_r30	0x90
50e11d2af5Sdrahn#define JMP_r31	0x98
51e11d2af5Sdrahn#define JMP_lr  0xa0
52e11d2af5Sdrahn#define JMP_cr  0xa8
53e11d2af5Sdrahn#define JMP_ctr	0xb0
54e11d2af5Sdrahn#define JMP_xer	0xb8
55e11d2af5Sdrahn#define JMP_sig	0xc0
56e11d2af5Sdrahn
57e11d2af5Sdrahn	.section	.openbsd.randomdata,"aw",@progbits
58e11d2af5Sdrahn	.balign	4
59e11d2af5Sdrahn	.globl	__jmpxor
60e11d2af5Sdrahn	.hidden	__jmpxor
61e11d2af5Sdrahn__jmpxor:
62e11d2af5Sdrahn	.zero	8*2		# (r1, lr)
63e11d2af5Sdrahn	END(__jmpxor)
64e11d2af5Sdrahn	.type	__jmpxor,@object
65e11d2af5Sdrahn
66e11d2af5Sdrahn
67e11d2af5Sdrahn/* int setjmp(jmp_buf env); */
68e11d2af5SdrahnENTRY(setjmp)
69e11d2af5Sdrahn	mr	%r5, %r3		/* save jmpbuf addr in r5 */
70e11d2af5Sdrahn	li	%r3, 1			/* how = SIG_BLOCK */
71e11d2af5Sdrahn	li	%r4, 0			/* oset = empty */
72e11d2af5Sdrahn	li	%r0, SYS_sigprocmask
73*83762a71Sderaadt99:	sc
74*83762a71Sderaadt	PINSYSCALL(SYS_sigprocmask, 99b)
75e11d2af5Sdrahn	std	%r3, JMP_sig(%r5)
76b1b45171Skettenis	b	1f
77e11d2af5Sdrahn	nop
78e11d2af5Sdrahn
79e11d2af5SdrahnENTRY(_setjmp)
80e11d2af5Sdrahn	mr	%r5, %r3		/* save jmpbuf addr in r5 */
81b1b45171Skettenis1:
82edea1d57Smortimer	RETGUARD_SETUP(setjmp, %r11)
83e11d2af5Sdrahn	addis	%r7, %r2, __jmpxor@toc@ha
84e11d2af5Sdrahn	addi	%r7, %r7, __jmpxor@toc@l
85e11d2af5Sdrahn	ld	%r0, 0(%r7)		/* xor for r1 */
86e11d2af5Sdrahn	ld	%r7, 8(%r7)		/* xor for lr, overwrite addr */
87e11d2af5Sdrahn
88e11d2af5Sdrahn	/* r1, r14-r31 */
89e11d2af5Sdrahn	xor	%r0, %r0, %r1		/* use and overwrite the r1 xor */
90e11d2af5Sdrahn	std	%r0, JMP_r1(%r5)
91e11d2af5Sdrahn	std	%r14, JMP_r14(%r5)
92e11d2af5Sdrahn	std	%r15, JMP_r15(%r5)
93e11d2af5Sdrahn	std	%r16, JMP_r16(%r5)
94e11d2af5Sdrahn	std	%r17, JMP_r17(%r5)
95e11d2af5Sdrahn	std	%r18, JMP_r18(%r5)
96e11d2af5Sdrahn	std	%r19, JMP_r19(%r5)
97e11d2af5Sdrahn	std	%r20, JMP_r20(%r5)
98e11d2af5Sdrahn	std	%r21, JMP_r21(%r5)
99e11d2af5Sdrahn	std	%r22, JMP_r22(%r5)
100e11d2af5Sdrahn	std	%r23, JMP_r23(%r5)
101e11d2af5Sdrahn	std	%r24, JMP_r24(%r5)
102e11d2af5Sdrahn	std	%r25, JMP_r25(%r5)
103e11d2af5Sdrahn	std	%r26, JMP_r26(%r5)
104e11d2af5Sdrahn	std	%r27, JMP_r27(%r5)
105e11d2af5Sdrahn	std	%r28, JMP_r28(%r5)
106e11d2af5Sdrahn	std	%r29, JMP_r29(%r5)
107e11d2af5Sdrahn	std	%r30, JMP_r30(%r5)
108e11d2af5Sdrahn	std	%r31, JMP_r31(%r5)
109e11d2af5Sdrahn	/* lr, cr, ctr, xer */
110e11d2af5Sdrahn	mflr	%r6
111e11d2af5Sdrahn	xor 	%r7, %r6, %r7		/* use and overwrite the lr xor */
112e11d2af5Sdrahn	std	%r7, JMP_lr(%r5)
113e11d2af5Sdrahn	mfcr	%r0
114b1b45171Skettenis	std	%r0, JMP_cr(%r5)
115e11d2af5Sdrahn	mfctr	%r0
116e11d2af5Sdrahn	std	%r0, JMP_ctr(%r5)
117e11d2af5Sdrahn	mfxer	%r0
118e11d2af5Sdrahn	std	%r0, JMP_xer(%r5)
119e11d2af5Sdrahn	/* floating point is all caller save */
120e11d2af5Sdrahn	li	%r3, 0
121edea1d57Smortimer	RETGUARD_CHECK(setjmp, %r11)
122e11d2af5Sdrahn	blr
123e11d2af5SdrahnEND(_setjmp)
124e11d2af5SdrahnEND(setjmp)
125e11d2af5Sdrahn
126e11d2af5Sdrahn
127e11d2af5Sdrahn/* void longjmp(jmp_buf env, int val); */
128e11d2af5SdrahnENTRY(longjmp)
129e11d2af5Sdrahn	mr	%r5, %r3		/* save jmpbuf addr in r5 */
130e11d2af5Sdrahn	mr	%r6, %r4		/* save val in r6 */
131e11d2af5Sdrahn	li	%r3, 3			/* how = SIG_SETMASK */
132e11d2af5Sdrahn	ld	%r4, JMP_sig(%r5)	/* oset from the jmpbuf */
133e11d2af5Sdrahn	li	%r0, SYS_sigprocmask
134*83762a71Sderaadt98:	sc
135*83762a71Sderaadt	PINSYSCALL(SYS_sigprocmask, 98b)
136e11d2af5Sdrahn	nop
137e11d2af5Sdrahn	b	1f
138e11d2af5Sdrahn	nop
139e11d2af5Sdrahn
140e11d2af5Sdrahn/* _longjmp(jmp_buf env, int val); */
141e11d2af5Sdrahn
142e11d2af5SdrahnENTRY(_longjmp)
143e11d2af5Sdrahn	mr	%r5, %r3			/* save jmpbuf addr in r5 */
144e11d2af5Sdrahn	mr	%r6, %r4			/* save val in r6 */
145e11d2af5Sdrahn1:
146e11d2af5Sdrahn	addis	%r9, %r2, __jmpxor@toc@ha
147e11d2af5Sdrahn	addi	%r9, %r9, __jmpxor@toc@l
148e11d2af5Sdrahn	ld	%r8, 0(%r9)			/* xor for r1 */
149e11d2af5Sdrahn	ld	%r9, 8(%r9)			/* xor for lr, overwrite addr */
150edea1d57Smortimer	ld	%r0, JMP_lr(%r5)
151edea1d57Smortimer	xor	%r0, %r0, %r9			/* use the lr xor */
152edea1d57Smortimer	mtlr	%r0
153edea1d57Smortimer	RETGUARD_SETUP(longjmp, %r11)
154e11d2af5Sdrahn
155e11d2af5Sdrahn	/* r1, r14-r31 */
156e11d2af5Sdrahn	ld	%r0, JMP_r1(%r5)
157e11d2af5Sdrahn	xor	%r1, %r0, %r8			/* use the r1 xor */
158e11d2af5Sdrahn	ld	%r14, JMP_r14(%r5)
159e11d2af5Sdrahn	ld	%r15, JMP_r15(%r5)
160e11d2af5Sdrahn	ld	%r16, JMP_r16(%r5)
161e11d2af5Sdrahn	ld	%r17, JMP_r17(%r5)
162e11d2af5Sdrahn	ld	%r18, JMP_r18(%r5)
163e11d2af5Sdrahn	ld	%r19, JMP_r19(%r5)
164e11d2af5Sdrahn	ld	%r20, JMP_r20(%r5)
165e11d2af5Sdrahn	ld	%r21, JMP_r21(%r5)
166e11d2af5Sdrahn	ld	%r22, JMP_r22(%r5)
167e11d2af5Sdrahn	ld	%r23, JMP_r23(%r5)
168e11d2af5Sdrahn	ld	%r24, JMP_r24(%r5)
169e11d2af5Sdrahn	ld	%r25, JMP_r25(%r5)
170e11d2af5Sdrahn	ld	%r26, JMP_r26(%r5)
171e11d2af5Sdrahn	ld	%r27, JMP_r27(%r5)
172e11d2af5Sdrahn	ld	%r28, JMP_r28(%r5)
173e11d2af5Sdrahn	ld	%r29, JMP_r29(%r5)
174e11d2af5Sdrahn	ld	%r30, JMP_r30(%r5)
175e11d2af5Sdrahn	ld	%r31, JMP_r31(%r5)
176e11d2af5Sdrahn	/* cr, lr, ctr, xer */
177e11d2af5Sdrahn	ld	%r8, JMP_cr(%r5)		/* overwrite the r1 xor */
178e11d2af5Sdrahn	mtcr	%r8
179e11d2af5Sdrahn	ld	%r9, JMP_ctr(%r5)		/* overwrite the lr xor */
180e11d2af5Sdrahn	mtctr	%r9
181e11d2af5Sdrahn	ld	%r0, JMP_xer(%r5)
182e11d2af5Sdrahn	mtxer	%r0
183e11d2af5Sdrahn	/* floating point is all caller save */
184e11d2af5Sdrahn
185e11d2af5Sdrahn	/* if return val in r6 == 0, return 1, not 0 */
186e11d2af5Sdrahn	mr	%r3, %r6
187e11d2af5Sdrahn	cmpwi	%r6, 0
188edea1d57Smortimer	bne	2f
189e11d2af5Sdrahn	li	%r3, 1
190edea1d57Smortimer2:
191edea1d57Smortimer	RETGUARD_CHECK(longjmp, %r11)
192e11d2af5Sdrahn	blr
193e11d2af5SdrahnEND(_longjmp)
194e11d2af5SdrahnEND(longjmp)
195