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