1/* 2 * Copyright (c) 2001 Wasabi Systems, Inc. 3 * All rights reserved. 4 * 5 * Written by Frank van der Linden for Wasabi Systems, Inc. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed for the NetBSD Project by 18 * Wasabi Systems, Inc. 19 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 20 * or promote products derived from this software without specific prior 21 * written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36#include <private/bionic_asm.h> 37 38 39// The internal structure of a jmp_buf is totally private. 40// Current layout (changes from release to release): 41// 42// word name description 43// 0 rbx registers 44// 1 rbp 45// 2 r12 46// 3 r13 47// 4 r14 48// 5 r15 49// 6 rsp 50// 7 pc 51// 8 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit 52// 9 sigmask signal mask (includes rt signals as well) 53// 10 checksum checksum of the core registers, to give better error messages. 54 55#define _JB_RBX 0 56#define _JB_RBP 1 57#define _JB_R12 2 58#define _JB_R13 3 59#define _JB_R14 4 60#define _JB_R15 5 61#define _JB_RSP 6 62#define _JB_PC 7 63#define _JB_SIGFLAG 8 64#define _JB_SIGMASK 9 65#define _JB_CHECKSUM 10 66 67.macro m_calculate_checksum dst, src 68 movq $0, \dst 69 .irp i,0,1,2,3,4,5,6,7 70 xorq (\i*8)(\src), \dst 71 .endr 72.endm 73 74ENTRY(setjmp) 75__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(setjmp) 76 movl $1,%esi 77 jmp PIC_PLT(sigsetjmp) 78END(setjmp) 79 80ENTRY(_setjmp) 81__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_setjmp) 82 movl $0,%esi 83 jmp PIC_PLT(sigsetjmp) 84END(_setjmp) 85 86// int sigsetjmp(sigjmp_buf env, int save_signal_mask); 87ENTRY(sigsetjmp) 88__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(sigsetjmp) 89 pushq %rdi 90 movq %rsi,%rdi 91 call PIC_PLT(__bionic_setjmp_cookie_get) 92 popq %rdi 93 94 // Record setjmp cookie and whether or not we're saving the signal mask. 95 movq %rax,(_JB_SIGFLAG * 8)(%rdi) 96 pushq %rax 97 98 // Do we need to save the signal mask? 99 testq $1,%rax 100 jz 2f 101 102 // Save current signal mask. 103 pushq %rdi // Push 'env'. 104 // The 'how' argument is ignored if new_mask is NULL. 105 xorq %rsi,%rsi // NULL. 106 leaq (_JB_SIGMASK * 8)(%rdi),%rdx // old_mask. 107 call PIC_PLT(sigprocmask) 108 popq %rdi // Pop 'env'. 109 1102: 111 // Fetch the setjmp cookie and clear the signal flag bit. 112 popq %rax 113 andq $-2,%rax 114 movq (%rsp),%r11 115 116 // Save the callee-save registers. 117 118.macro m_mangle_register reg, offset 119 movq \reg, (\offset * 8)(%rdi) 120 xorq %rax, (\offset * 8)(%rdi) // %rax contains the cookie. 121.endm 122 123 m_mangle_register %rbx, _JB_RBX 124 m_mangle_register %rbp, _JB_RBP 125 m_mangle_register %r12, _JB_R12 126 m_mangle_register %r13, _JB_R13 127 m_mangle_register %r14, _JB_R14 128 m_mangle_register %r15, _JB_R15 129 m_mangle_register %rsp, _JB_RSP 130 m_mangle_register %r11, _JB_PC 131 132 m_calculate_checksum %rax, %rdi 133 movq %rax, (_JB_CHECKSUM * 8)(%rdi) 134 135 xorl %eax,%eax 136 ret 137END(sigsetjmp) 138 139// void siglongjmp(sigjmp_buf env, int value); 140ENTRY(siglongjmp) 141__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(siglongjmp) 142 movq %rdi,%r12 143 pushq %rsi // Push 'value'. 144 145 m_calculate_checksum %rax, %rdi 146 xorq (_JB_CHECKSUM * 8)(%rdi), %rax 147 jnz 3f 148 149 // Do we need to restore the signal mask? 150 movq (_JB_SIGFLAG * 8)(%rdi), %rdi 151 pushq %rdi // Push cookie 152 testq $1, %rdi 153 jz 2f 154 155 // Restore the signal mask. 156 movq $2,%rdi // SIG_SETMASK. 157 leaq (_JB_SIGMASK * 8)(%r12),%rsi // new_mask. 158 xorq %rdx,%rdx // NULL. 159 call PIC_PLT(sigprocmask) 160 1612: 162 // Fetch the setjmp cookie and clear the signal flag bit. 163 popq %rcx 164 andq $-2, %rcx 165 166 popq %rax // Pop 'value'. 167 168 // Restore the callee-save registers. 169 170.macro m_unmangle_register reg, offset 171 movq (\offset * 8)(%r12), %rdx // Clobbers rdx. 172 xorq %rcx, %rdx // %rcx contains the cookie. 173 // Now it's safe to overwrite the register (http://b/152210274). 174 movq %rdx, \reg 175.endm 176 177 m_unmangle_register %rbx, _JB_RBX 178 m_unmangle_register %rbp, _JB_RBP 179 m_unmangle_register %r13, _JB_R13 180 m_unmangle_register %r14, _JB_R14 181 m_unmangle_register %r15, _JB_R15 182 m_unmangle_register %rsp, _JB_RSP 183 m_unmangle_register %r11, _JB_PC 184 m_unmangle_register %r12, _JB_R12 185 186 // Check the cookie. 187 pushq %rax 188 pushq %r11 189 movq %rcx, %rdi 190 call PIC_PLT(__bionic_setjmp_cookie_check) 191 popq %r11 192 popq %rax 193 194 // Return 1 if value is 0. 195 testl %eax,%eax 196 jnz 1f 197 incl %eax 1981: 199 movq %r11,0(%rsp) 200 ret 201 2023: 203 call PIC_PLT(__bionic_setjmp_checksum_mismatch) 204END(siglongjmp) 205 206ALIAS_SYMBOL(longjmp, siglongjmp) 207__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(longjmp) 208ALIAS_SYMBOL(_longjmp, siglongjmp) 209__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_longjmp) 210