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_WEAK_FOR_NATIVE_BRIDGE(setjmp) 75 movl $1,%esi 76 jmp PIC_PLT(sigsetjmp) 77END(setjmp) 78 79ENTRY_WEAK_FOR_NATIVE_BRIDGE(_setjmp) 80 movl $0,%esi 81 jmp PIC_PLT(sigsetjmp) 82END(_setjmp) 83 84// int sigsetjmp(sigjmp_buf env, int save_signal_mask); 85ENTRY_WEAK_FOR_NATIVE_BRIDGE(sigsetjmp) 86 pushq %rdi 87 movq %rsi,%rdi 88 call PIC_PLT(__bionic_setjmp_cookie_get) 89 popq %rdi 90 91 // Record setjmp cookie and whether or not we're saving the signal mask. 92 movq %rax,(_JB_SIGFLAG * 8)(%rdi) 93 pushq %rax 94 95 // Do we need to save the signal mask? 96 testq $1,%rax 97 jz 2f 98 99 // Save current signal mask. 100 pushq %rdi // Push 'env'. 101 // The 'how' argument is ignored if new_mask is NULL. 102 xorq %rsi,%rsi // NULL. 103 leaq (_JB_SIGMASK * 8)(%rdi),%rdx // old_mask. 104 call PIC_PLT(sigprocmask) 105 popq %rdi // Pop 'env'. 106 1072: 108 // Fetch the setjmp cookie and clear the signal flag bit. 109 popq %rax 110 andq $-2,%rax 111 movq (%rsp),%r11 112 113 // Save the callee-save registers. 114 115.macro m_mangle_register reg, offset 116 movq \reg, (\offset * 8)(%rdi) 117 xorq %rax, (\offset * 8)(%rdi) // %rax contains the cookie. 118.endm 119 120 m_mangle_register %rbx, _JB_RBX 121 m_mangle_register %rbp, _JB_RBP 122 m_mangle_register %r12, _JB_R12 123 m_mangle_register %r13, _JB_R13 124 m_mangle_register %r14, _JB_R14 125 m_mangle_register %r15, _JB_R15 126 m_mangle_register %rsp, _JB_RSP 127 m_mangle_register %r11, _JB_PC 128 129 m_calculate_checksum %rax, %rdi 130 movq %rax, (_JB_CHECKSUM * 8)(%rdi) 131 132 xorl %eax,%eax 133 ret 134END(sigsetjmp) 135 136// void siglongjmp(sigjmp_buf env, int value); 137ENTRY_WEAK_FOR_NATIVE_BRIDGE(siglongjmp) 138 movq %rdi,%r12 139 pushq %rsi // Push 'value'. 140 141 m_calculate_checksum %rax, %rdi 142 xorq (_JB_CHECKSUM * 8)(%rdi), %rax 143 jnz 3f 144 145 // Do we need to restore the signal mask? 146 movq (_JB_SIGFLAG * 8)(%rdi), %rdi 147 pushq %rdi // Push cookie 148 testq $1, %rdi 149 jz 2f 150 151 // Restore the signal mask. 152 movq $2,%rdi // SIG_SETMASK. 153 leaq (_JB_SIGMASK * 8)(%r12),%rsi // new_mask. 154 xorq %rdx,%rdx // NULL. 155 call PIC_PLT(sigprocmask) 156 1572: 158 // Fetch the setjmp cookie and clear the signal flag bit. 159 popq %rcx 160 andq $-2, %rcx 161 162 popq %rax // Pop 'value'. 163 164 // Restore the callee-save registers. 165 166.macro m_unmangle_register reg, offset 167 movq (\offset * 8)(%r12), %rdx // Clobbers rdx. 168 xorq %rcx, %rdx // %rcx contains the cookie. 169 // Now it's safe to overwrite the register (http://b/152210274). 170 movq %rdx, \reg 171.endm 172 173 m_unmangle_register %rbx, _JB_RBX 174 m_unmangle_register %rbp, _JB_RBP 175 m_unmangle_register %r13, _JB_R13 176 m_unmangle_register %r14, _JB_R14 177 m_unmangle_register %r15, _JB_R15 178 m_unmangle_register %rsp, _JB_RSP 179 m_unmangle_register %r11, _JB_PC 180 m_unmangle_register %r12, _JB_R12 181 182 // Check the cookie. 183 pushq %rax 184 pushq %r11 185 movq %rcx, %rdi 186 call PIC_PLT(__bionic_setjmp_cookie_check) 187 popq %r11 188 popq %rax 189 190 // Return 1 if value is 0. 191 testl %eax,%eax 192 jnz 1f 193 incl %eax 1941: 195 movq %r11,0(%rsp) 196 ret 197 1983: 199 call PIC_PLT(__bionic_setjmp_checksum_mismatch) 200END(siglongjmp) 201 202ALIAS_SYMBOL_WEAK_FOR_NATIVE_BRIDGE(longjmp, siglongjmp) 203ALIAS_SYMBOL_WEAK_FOR_NATIVE_BRIDGE(_longjmp, siglongjmp) 204