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   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