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