xref: /openbsd-src/lib/libc/arch/powerpc64/gen/sigsetjmp.S (revision 83762a71f74848f4d09174ce350838b4204957c5)
1*83762a71Sderaadt/*	$OpenBSD: sigsetjmp.S,v 1.4 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#define JMP_sigflag	0x00
31e11d2af5Sdrahn#define JMP_r1	0x08
32e11d2af5Sdrahn#define JMP_r14	0x10
33e11d2af5Sdrahn#define JMP_r15	0x18
34e11d2af5Sdrahn#define JMP_r16	0x20
35e11d2af5Sdrahn#define JMP_r17	0x28
36e11d2af5Sdrahn#define JMP_r18	0x30
37e11d2af5Sdrahn#define JMP_r19	0x38
38e11d2af5Sdrahn#define JMP_r20	0x40
39e11d2af5Sdrahn#define JMP_r21	0x48
40e11d2af5Sdrahn#define JMP_r22	0x50
41e11d2af5Sdrahn#define JMP_r23	0x58
42e11d2af5Sdrahn#define JMP_r24	0x60
43e11d2af5Sdrahn#define JMP_r25	0x68
44e11d2af5Sdrahn#define JMP_r26	0x70
45e11d2af5Sdrahn#define JMP_r27	0x78
46e11d2af5Sdrahn#define JMP_r28	0x80
47e11d2af5Sdrahn#define JMP_r29	0x88
48e11d2af5Sdrahn#define JMP_r30	0x90
49e11d2af5Sdrahn#define JMP_r31	0x98
50e11d2af5Sdrahn#define JMP_lr  0xa0
51e11d2af5Sdrahn#define JMP_cr  0xa8
52e11d2af5Sdrahn#define JMP_ctr	0xb0
53e11d2af5Sdrahn#define JMP_xer	0xb8
54e11d2af5Sdrahn#define JMP_sig	0xc0
55e11d2af5Sdrahn#define JMP_sigmask   0xc8
56e11d2af5Sdrahn
57e11d2af5Sdrahn
58e11d2af5Sdrahn	.extern	__jmpxor
59e11d2af5Sdrahn
60e11d2af5Sdrahn/* int sigsetjmp(sigjmp_buf env, int savemask) */
61e11d2af5SdrahnENTRY(sigsetjmp)
62911403b1Smortimer	RETGUARD_SETUP(sigsetjmp, %r11)
63e11d2af5Sdrahn	mr	%r5, %r3		/* save jmpbuf addr in r5 */
64e11d2af5Sdrahn	std	%r4, JMP_sigflag(%r5)
65e11d2af5Sdrahn	or.	%r4, %r4, %r4
66e11d2af5Sdrahn	beq	1f
67e11d2af5Sdrahn	li	%r3, 1			/* how = SIG_BLOCK */
68e11d2af5Sdrahn	li	%r4, 0			/* oset = empty */
69e11d2af5Sdrahn	li	%r0, SYS_sigprocmask
70*83762a71Sderaadt99:	sc
71*83762a71Sderaadt	PINSYSCALL(SYS_sigprocmask, 99b)
72e11d2af5Sdrahn	nop
73e11d2af5Sdrahn	std	%r3, JMP_sigmask(5)
748e16d6ccSkettenis1:
75e11d2af5Sdrahn	addis	%r7, %r2, __jmpxor@toc@ha
76e11d2af5Sdrahn	addi	%r7, %r7, __jmpxor@toc@l
77e11d2af5Sdrahn	ld	%r8, 0(%r7)		/* xor for r1 */
78e11d2af5Sdrahn	ld	%r7, 8(%r7)		/* xor for lr, overwrite addr */
79e11d2af5Sdrahn
80e11d2af5Sdrahn	/*	r1, r14-r31 */
81e11d2af5Sdrahn	xor	%r0, %r8, %r1		/* use and overwrite the r1 xor */
82e11d2af5Sdrahn	std	%r0, JMP_r1 (%r5)
83e11d2af5Sdrahn	std	%r14, JMP_r14(%r5)
84e11d2af5Sdrahn	std	%r15, JMP_r15(%r5)
85e11d2af5Sdrahn	std	%r16, JMP_r16(%r5)
86e11d2af5Sdrahn	std	%r17, JMP_r17(%r5)
87e11d2af5Sdrahn	std	%r18, JMP_r18(%r5)
88e11d2af5Sdrahn	std	%r19, JMP_r19(%r5)
89e11d2af5Sdrahn	std	%r20, JMP_r20(%r5)
90e11d2af5Sdrahn	std	%r21, JMP_r21(%r5)
91e11d2af5Sdrahn	std	%r22, JMP_r22(%r5)
92e11d2af5Sdrahn	std	%r23, JMP_r23(%r5)
93e11d2af5Sdrahn	std	%r24, JMP_r24(%r5)
94e11d2af5Sdrahn	std	%r25, JMP_r25(%r5)
95e11d2af5Sdrahn	std	%r26, JMP_r26(%r5)
96e11d2af5Sdrahn	std	%r27, JMP_r27(%r5)
97e11d2af5Sdrahn	std	%r28, JMP_r28(%r5)
98e11d2af5Sdrahn	std	%r29, JMP_r29(%r5)
99e11d2af5Sdrahn	std	%r30, JMP_r30(%r5)
100e11d2af5Sdrahn	std	%r31, JMP_r31(%r5)
101e11d2af5Sdrahn	/* lr, cr, ctr, xer */
102e11d2af5Sdrahn	mflr	%r0
103e11d2af5Sdrahn	xor	%r7, %r0, %r7		/* use and overwrite the lr xor */
104e11d2af5Sdrahn	std	%r7, JMP_lr(%r5)
105e11d2af5Sdrahn	mfcr	%r0
106e11d2af5Sdrahn	std	%r0, JMP_cr(%r5)
107e11d2af5Sdrahn	mfctr	%r0
108e11d2af5Sdrahn	std	%r0, JMP_ctr(%r5)
109e11d2af5Sdrahn	mfctr	%r0
110e11d2af5Sdrahn	mfxer	%r0
111e11d2af5Sdrahn	std	%r0, JMP_xer(%r5)
112e11d2af5Sdrahn	/* f14-f31, fpscr */
113e11d2af5Sdrahn	li %r3, 0
114911403b1Smortimer	RETGUARD_CHECK(sigsetjmp, %r11)
115e11d2af5Sdrahn	blr
116e11d2af5SdrahnEND(sigsetjmp)
117e11d2af5Sdrahn
118e11d2af5Sdrahn
119e11d2af5Sdrahn/* int siglongjmp(sigjmp_buf env, int val) */
120e11d2af5SdrahnENTRY(siglongjmp)
121e11d2af5Sdrahn	mr	%r5, %r3		/* save jmpbuf addr in r5 */
122e11d2af5Sdrahn	mr	%r6, %r4		/* save val in r6 */
123e11d2af5Sdrahn	ld	%r4, JMP_sigflag(%r5)	/* do we need to restore sigmask? */
124e11d2af5Sdrahn	or.	%r4, %r4, %r4
125e11d2af5Sdrahn	beq	1f
126e11d2af5Sdrahn
127e11d2af5Sdrahn	li	%r3, 3			/* how = SIG_SETMASK */
128e11d2af5Sdrahn	ld	%r4, JMP_sigmask(%r5)	/* oset from the jmpbuf */
129e11d2af5Sdrahn	li	%r0, SYS_sigprocmask
130*83762a71Sderaadt98:	sc
131*83762a71Sderaadt	PINSYSCALL(SYS_sigprocmask, 98b)
132e11d2af5Sdrahn1:
133e11d2af5Sdrahn	addis	%r9, %r2, __jmpxor@toc@ha
134e11d2af5Sdrahn	addi	%r9, %r9, __jmpxor@toc@l
135e11d2af5Sdrahn	ld	%r8, 0(%r9)			/* xor for r1 */
136e11d2af5Sdrahn	ld	%r9, 8(%r9)			/* xor for lr, overwrite addr */
137911403b1Smortimer	ld	%r0, JMP_lr(%r5)
138911403b1Smortimer	xor	%r0, %r0, %r9			/* use the lr xor */
139911403b1Smortimer	mtlr	%r0
140911403b1Smortimer	RETGUARD_SETUP(siglongjmp, %r11)
141e11d2af5Sdrahn
142e11d2af5Sdrahn	/* r1, r14-r31 */
143e11d2af5Sdrahn	ld	%r0, JMP_r1(%r5)
144e11d2af5Sdrahn	xor	%r1, %r0, %r8			/* use the r1 xor */
145e11d2af5Sdrahn	ld	%r14, JMP_r14(%r5)
146e11d2af5Sdrahn	ld	%r15, JMP_r15(%r5)
147e11d2af5Sdrahn	ld	%r16, JMP_r16(%r5)
148e11d2af5Sdrahn	ld	%r17, JMP_r17(%r5)
149e11d2af5Sdrahn	ld	%r18, JMP_r18(%r5)
150e11d2af5Sdrahn	ld	%r19, JMP_r19(%r5)
151e11d2af5Sdrahn	ld	%r20, JMP_r20(%r5)
152e11d2af5Sdrahn	ld	%r21, JMP_r21(%r5)
153e11d2af5Sdrahn	ld	%r22, JMP_r22(%r5)
154e11d2af5Sdrahn	ld	%r23, JMP_r23(%r5)
155e11d2af5Sdrahn	ld	%r24, JMP_r24(%r5)
156e11d2af5Sdrahn	ld	%r25, JMP_r25(%r5)
157e11d2af5Sdrahn	ld	%r26, JMP_r26(%r5)
158e11d2af5Sdrahn	ld	%r27, JMP_r27(%r5)
159e11d2af5Sdrahn	ld	%r28, JMP_r28(%r5)
160e11d2af5Sdrahn	ld	%r29, JMP_r29(%r5)
161e11d2af5Sdrahn	ld	%r30, JMP_r30(%r5)
162e11d2af5Sdrahn	ld	%r31, JMP_r31(%r5)
163e11d2af5Sdrahn	/* cr, lr, ctr, xer */
164e11d2af5Sdrahn	ld	%r8, JMP_cr(%r5)		/* overwrite the r1 xor */
165e11d2af5Sdrahn	mtcr	%r8
166e11d2af5Sdrahn	ld	%r9, JMP_ctr(%r5)		/* overwrite the lr xor */
167e11d2af5Sdrahn	mtctr	%r9
168e11d2af5Sdrahn	ld	%r0, JMP_xer(%r5)
169e11d2af5Sdrahn	mtxer	%r0
170e11d2af5Sdrahn	/* floating point is all caller save */
171e11d2af5Sdrahn
172e11d2af5Sdrahn	/* if return val in r6 == 0, return 1, not 0 */
173e11d2af5Sdrahn	mr	%r3, %r6
174e11d2af5Sdrahn	cmpwi	%r6, 0
175911403b1Smortimer	bne	2f
176e11d2af5Sdrahn	li	%r3, 1
177911403b1Smortimer2:
178911403b1Smortimer	RETGUARD_CHECK(siglongjmp, %r11)
179e11d2af5Sdrahn	blr
180e11d2af5SdrahnEND(siglongjmp)
181