setjmp.S revision 2342e643d4c998ae314d03d207f703c1cc5159e4
14906e5653c57d49f94940f28556009a88c42a583Elliott Hughes/*
24906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * Copyright (c) 2001 Wasabi Systems, Inc.
34906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * All rights reserved.
44906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *
54906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * Written by Frank van der Linden for Wasabi Systems, Inc.
64906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *
74906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * Redistribution and use in source and binary forms, with or without
84906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * modification, are permitted provided that the following conditions
94906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * are met:
104906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * 1. Redistributions of source code must retain the above copyright
114906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *    notice, this list of conditions and the following disclaimer.
124906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * 2. Redistributions in binary form must reproduce the above copyright
134906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *    notice, this list of conditions and the following disclaimer in the
144906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *    documentation and/or other materials provided with the distribution.
154906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * 3. All advertising materials mentioning features or use of this software
164906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *    must display the following acknowledgement:
174906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *      This product includes software developed for the NetBSD Project by
184906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *      Wasabi Systems, Inc.
194906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * 4. The name of Wasabi Systems, Inc. may not be used to endorse
204906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *    or promote products derived from this software without specific prior
214906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *    written permission.
224906e5653c57d49f94940f28556009a88c42a583Elliott Hughes *
234906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
244906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
254906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
264906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
274906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
284906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
294906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
304906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
314906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
324906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
334906e5653c57d49f94940f28556009a88c42a583Elliott Hughes * POSSIBILITY OF SUCH DAMAGE.
344906e5653c57d49f94940f28556009a88c42a583Elliott Hughes */
354906e5653c57d49f94940f28556009a88c42a583Elliott Hughes
36851e68a2402fa414544e66650e09dfdaac813e51Elliott Hughes#include <private/bionic_asm.h>
374906e5653c57d49f94940f28556009a88c42a583Elliott Hughes
388d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes// These are only the callee-saved registers. Code calling setjmp
398d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes// will expect the rest to be clobbered anyway.
408d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
418d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_RBX 0
428d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_RBP 1
438d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_R12 2
448d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_R13 3
458d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_R14 4
468d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_R15 5
478d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_RSP 6
488d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_PC 7
498d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_SIGFLAG 8
508d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_SIGMASK 9
511c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes#define _JB_SIGMASK_RT 10 // sigprocmask will write here too.
524906e5653c57d49f94940f28556009a88c42a583Elliott Hughes
532342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao#define MANGLE_REGISTERS 1
542342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao.macro m_mangle_registers reg
552342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao#if MANGLE_REGISTERS
562342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  xorq \reg,%rbx
572342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  xorq \reg,%rbp
582342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  xorq \reg,%r12
592342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  xorq \reg,%r13
602342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  xorq \reg,%r14
612342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  xorq \reg,%r15
622342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  xorq \reg,%rsp
632342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  xorq \reg,%r11
642342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao#endif
652342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao.endm
662342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao
672342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao.macro m_unmangle_registers reg
682342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  m_mangle_registers \reg
692342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao.endm
702342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao
712342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao
724906e5653c57d49f94940f28556009a88c42a583Elliott HughesENTRY(setjmp)
738d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movl $1,%esi
748d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  jmp PIC_PLT(sigsetjmp)
75507cfe2e10a6c4ad61b9638820ba10bfe881a18cChristopher FerrisEND(setjmp)
764906e5653c57d49f94940f28556009a88c42a583Elliott Hughes
778d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesENTRY(_setjmp)
788d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movl $0,%esi
798d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  jmp PIC_PLT(sigsetjmp)
808d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesEND(_setjmp)
818d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
828d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
838d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesENTRY(sigsetjmp)
842342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  pushq %rdi
852342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  movq %rsi,%rdi
862342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  call PIC_PLT(__bionic_setjmp_cookie_get)
872342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  popq %rdi
882342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao
892342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  // Record setjmp cookie and whether or not we're saving the signal mask.
902342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  movq %rax,(_JB_SIGFLAG * 8)(%rdi)
912342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  pushq %rax
928d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
938d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  // Do we need to save the signal mask?
942342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  testq $1,%rax
958d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  jz 2f
968d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
971c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  // Save current signal mask.
981c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  pushq %rdi // Push 'env'.
991c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  // The 'how' argument is ignored if new_mask is NULL.
1001c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  xorq %rsi,%rsi // NULL.
1011c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  leaq (_JB_SIGMASK * 8)(%rdi),%rdx // old_mask.
1021c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  call PIC_PLT(sigprocmask)
1031c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  popq %rdi // Pop 'env'.
1048d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
1058d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes2:
1068d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  // Save the callee-save registers.
1072342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  popq %rax
1082342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  andq $-2,%rax
1098d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (%rsp),%r11
1102342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  m_mangle_registers %rax
1118d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %rbx,(_JB_RBX * 8)(%rdi)
1128d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %rbp,(_JB_RBP * 8)(%rdi)
1138d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %r12,(_JB_R12 * 8)(%rdi)
1148d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %r13,(_JB_R13 * 8)(%rdi)
1158d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %r14,(_JB_R14 * 8)(%rdi)
1168d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %r15,(_JB_R15 * 8)(%rdi)
1178d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %rsp,(_JB_RSP * 8)(%rdi)
1188d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %r11,(_JB_PC  * 8)(%rdi)
1192342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  m_unmangle_registers %rax
1208d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
1218d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  xorl %eax,%eax
1228d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  ret
1238d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesEND(sigsetjmp)
1248d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
1258d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes// void siglongjmp(sigjmp_buf env, int value);
1268d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesENTRY(siglongjmp)
1278d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %rdi,%r12
1288d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  pushq %rsi // Push 'value'.
1298d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
1308d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  // Do we need to restore the signal mask?
1312342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  movq (_JB_SIGFLAG * 8)(%rdi), %rdi
1322342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  pushq %rdi // Push cookie
1332342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  testq $1, %rdi
1348d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  jz 2f
1358d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
1368d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  // Restore the signal mask.
1371c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  movq $2,%rdi // SIG_SETMASK.
1381c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  leaq (_JB_SIGMASK * 8)(%r12),%rsi // new_mask.
1391c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  xorq %rdx,%rdx // NULL.
1401c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes  call PIC_PLT(sigprocmask)
1418d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
1428d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes2:
1432342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  // Fetch the setjmp cookie and clear the signal flag bit.
1442342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  popq %rcx
1452342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  andq $-2, %rcx
1462342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao
1478d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  popq %rax // Pop 'value'.
1488d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
1498d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  // Restore the callee-save registers.
1508d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (_JB_RBX * 8)(%r12),%rbx
1518d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (_JB_RBP * 8)(%r12),%rbp
1528d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (_JB_R13 * 8)(%r12),%r13
1538d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (_JB_R14 * 8)(%r12),%r14
1548d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (_JB_R15 * 8)(%r12),%r15
1558d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (_JB_RSP * 8)(%r12),%rsp
1568d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (_JB_PC  * 8)(%r12),%r11
1578d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq (_JB_R12 * 8)(%r12),%r12
1582342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  m_unmangle_registers %rcx
1592342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao
1602342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  // Check the cookie.
1612342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  pushq %rax
1622342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  movq %rcx, %rdi
1632342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  call PIC_PLT(__bionic_setjmp_cookie_check)
1642342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  popq %rax
1658d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
1662342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao  // Return 1 if value is 0.
1678d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  testl %eax,%eax
1688d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  jnz 1f
1698d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  incl %eax
1708d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes1:
1718d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  movq %r11,0(%rsp)
1728d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes  ret
1738d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesEND(siglongjmp)
1748d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes
17524958514b92c9b9e111223e4e4c56ef1a52b6403Christopher FerrisALIAS_SYMBOL(longjmp, siglongjmp)
17624958514b92c9b9e111223e4e4c56ef1a52b6403Christopher FerrisALIAS_SYMBOL(_longjmp, siglongjmp)
177