/* * Copyright (c) 2011-2018 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #define JMP_r19_20 #0x00 #define JMP_r21_22 #0x10 #define JMP_r23_24 #0x20 #define JMP_r25_26 #0x30 #define JMP_r27_28 #0x40 #define JMP_fp_lr #0x50 #define JMP_sp_rsvd #0x60 /* second field is reserved/unused */ #define JMP_d8_d9 #0x70 #define JMP_d10_d11 #0x80 #define JMP_d12_d13 #0x90 #define JMP_d14_d15 #0xA0 #define JMP_sigmask #0xB0 #define JMP_sigflag #0xB8 #define JMP_sigonstack #0xBC /* whether the thread is on sigaltstack or not */ #define STACK_SSFLAGS 16 // offsetof(stack_t, ss_flags) #include #include /* int _setjmp(jmp_buf env); */ ENTRY_POINT(__setjmp) mov x12, sp _OS_PTR_MUNGE_TOKEN(x16, x16) _OS_PTR_MUNGE(x10, fp, x16) _OS_PTR_MUNGE(x11, lr, x16) _OS_PTR_MUNGE(x12, x12, x16) stp x19, x20, [x0, JMP_r19_20] stp x21, x22, [x0, JMP_r21_22] stp x23, x24, [x0, JMP_r23_24] stp x25, x26, [x0, JMP_r25_26] stp x27, x28, [x0, JMP_r27_28] stp x10, x11, [x0, JMP_fp_lr] str x12, [x0, JMP_sp_rsvd] stp d8, d9, [x0, JMP_d8_d9] stp d10, d11, [x0, JMP_d10_d11] stp d12, d13, [x0, JMP_d12_d13] stp d14, d15, [x0, JMP_d14_d15] mov w0, #0 ret /* void _longjmp(jmp_buf env, int val); */ ENTRY_POINT(__longjmp) ldp x19, x20, [x0, JMP_r19_20] ldp x21, x22, [x0, JMP_r21_22] ldp x23, x24, [x0, JMP_r23_24] ldp x25, x26, [x0, JMP_r25_26] ldp x27, x28, [x0, JMP_r27_28] ldp x10, x11, [x0, JMP_fp_lr] ldr x12, [x0, JMP_sp_rsvd] ldp d8, d9, [x0, JMP_d8_d9] ldp d10, d11, [x0, JMP_d10_d11] ldp d12, d13, [x0, JMP_d12_d13] ldp d14, d15, [x0, JMP_d14_d15] _OS_PTR_MUNGE_TOKEN(x16, x16) _OS_PTR_UNMUNGE(fp, x10, x16) _OS_PTR_UNMUNGE(lr, x11, x16) _OS_PTR_UNMUNGE(x12, x12, x16) ldrb w16, [sp] /* probe to detect absolutely corrupt stack pointers */ mov sp, x12 cmp w1, #0 csinc w0, w1, wzr, ne ret /* int sigsetjmp(sigjmp_buf env, int savemask); */ ENTRY_POINT(_sigsetjmp) str w1, [x0, JMP_sigflag] cbnz w1, 1f b __setjmp 1: /* else, fall through */ /* int setjmp(jmp_buf env); */ ENTRY_POINT(_setjmp) stp x21, lr, [x0] // Store x21 and lr in jmpbuf (for now) mov x21, x0 // x21 = x0 // Save the sigmask orr w0, wzr, #0x1 // x0 = how = SIG_BLOCK mov x1, #0 // x1 = set = 0 add x2, x21, JMP_sigmask // x2 = oset = (x21 + JMP_sigmask) CALL_EXTERNAL(_sigprocmask) // Get current sigaltstack status sub sp, sp, #32 // 24 bytes for a stack_t on the stack, +8 for alignment of stack mov x0, xzr // x0 = ss = NULL mov x1, sp // x1 = oss = the place on the stack where the stack_t is located CALL_EXTERNAL(___sigaltstack) // sigaltstack(NULL, oss) ldr w0, [sp, STACK_SSFLAGS] // w0 = ss flags from stack_t str w0, [x21, JMP_sigonstack] // *(x21 + JMP_sigonstack) = w0 add sp, sp, #32 // Reset sp mov x0, x21 // x0 = x21 ldp x21, lr, [x0] b __setjmp /* void siglongjmp(sigjmp_buf env, int val); */ ENTRY_POINT(_siglongjmp) ldr w8, [x0, JMP_sigflag] cbnz w8, 1f b __longjmp 1: /* else, fall through */ /* void longjmp(jmp_buf env, int val); */ ENTRY_POINT(_longjmp) sub sp, sp, #16 mov x21, x0 // x21/x22 will be restored by __longjmp mov x22, x1 // Restore the signal mask ldr x8, [x21, JMP_sigmask] // restore the signal mask str x8, [sp, #8] orr w0, wzr, #0x3 // SIG_SETMASK add x1, sp, #8 // set mov x2, #0 // oset CALL_EXTERNAL(_sigprocmask) // Restore the sigaltstack status ldr x0, [x21, JMP_sigonstack] // x0 = saved sigonstack info CALL_EXTERNAL(__sigunaltstack) mov x0, x21 mov x1, x22 add sp, sp, #16 b __longjmp