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