setjmp.S revision c244fcb8a3396f94976a56379cce144c4451c3d4
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 38c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao 39c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// The internal structure of a jmp_buf is totally private. 40c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// Current layout (changes from release to release): 41c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 42c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// word name description 43c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 0 rbx registers 44c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 1 rbp 45c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 2 r12 46c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 3 r13 47c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 4 r14 48c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 5 r15 49c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 6 rsp 50c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 7 pc 51c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 8 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit 52c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 9 sigmask signal mask (includes rt signals as well) 53c244fcb8a3396f94976a56379cce144c4451c3d4Josh Gao// 10 reserved 548d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 558d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_RBX 0 568d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_RBP 1 578d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_R12 2 588d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_R13 3 598d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_R14 4 608d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_R15 5 618d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_RSP 6 628d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_PC 7 638d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_SIGFLAG 8 648d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes#define _JB_SIGMASK 9 654906e5653c57d49f94940f28556009a88c42a583Elliott Hughes 662342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao#define MANGLE_REGISTERS 1 672342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao.macro m_mangle_registers reg 682342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao#if MANGLE_REGISTERS 692342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao xorq \reg,%rbx 702342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao xorq \reg,%rbp 712342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao xorq \reg,%r12 722342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao xorq \reg,%r13 732342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao xorq \reg,%r14 742342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao xorq \reg,%r15 752342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao xorq \reg,%rsp 762342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao xorq \reg,%r11 772342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao#endif 782342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao.endm 792342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao 802342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao.macro m_unmangle_registers reg 812342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao m_mangle_registers \reg 822342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao.endm 832342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao 842342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao 854906e5653c57d49f94940f28556009a88c42a583Elliott HughesENTRY(setjmp) 868d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movl $1,%esi 878d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes jmp PIC_PLT(sigsetjmp) 88507cfe2e10a6c4ad61b9638820ba10bfe881a18cChristopher FerrisEND(setjmp) 894906e5653c57d49f94940f28556009a88c42a583Elliott Hughes 908d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesENTRY(_setjmp) 918d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movl $0,%esi 928d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes jmp PIC_PLT(sigsetjmp) 938d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesEND(_setjmp) 948d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 958d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes// int sigsetjmp(sigjmp_buf env, int save_signal_mask); 968d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesENTRY(sigsetjmp) 972342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao pushq %rdi 982342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao movq %rsi,%rdi 992342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao call PIC_PLT(__bionic_setjmp_cookie_get) 1002342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao popq %rdi 1012342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao 1022342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao // Record setjmp cookie and whether or not we're saving the signal mask. 1032342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao movq %rax,(_JB_SIGFLAG * 8)(%rdi) 1042342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao pushq %rax 1058d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1068d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes // Do we need to save the signal mask? 1072342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao testq $1,%rax 1088d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes jz 2f 1098d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1101c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes // Save current signal mask. 1111c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes pushq %rdi // Push 'env'. 1121c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes // The 'how' argument is ignored if new_mask is NULL. 1131c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes xorq %rsi,%rsi // NULL. 1141c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes leaq (_JB_SIGMASK * 8)(%rdi),%rdx // old_mask. 1151c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes call PIC_PLT(sigprocmask) 1161c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes popq %rdi // Pop 'env'. 1178d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1188d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes2: 1198d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes // Save the callee-save registers. 1202342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao popq %rax 1212342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao andq $-2,%rax 1228d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (%rsp),%r11 1232342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao m_mangle_registers %rax 1248d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %rbx,(_JB_RBX * 8)(%rdi) 1258d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %rbp,(_JB_RBP * 8)(%rdi) 1268d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %r12,(_JB_R12 * 8)(%rdi) 1278d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %r13,(_JB_R13 * 8)(%rdi) 1288d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %r14,(_JB_R14 * 8)(%rdi) 1298d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %r15,(_JB_R15 * 8)(%rdi) 1308d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %rsp,(_JB_RSP * 8)(%rdi) 1318d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %r11,(_JB_PC * 8)(%rdi) 1322342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao m_unmangle_registers %rax 1338d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1348d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes xorl %eax,%eax 1358d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes ret 1368d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesEND(sigsetjmp) 1378d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1388d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes// void siglongjmp(sigjmp_buf env, int value); 1398d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesENTRY(siglongjmp) 1408d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %rdi,%r12 1418d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes pushq %rsi // Push 'value'. 1428d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1438d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes // Do we need to restore the signal mask? 1442342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao movq (_JB_SIGFLAG * 8)(%rdi), %rdi 1452342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao pushq %rdi // Push cookie 1462342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao testq $1, %rdi 1478d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes jz 2f 1488d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1498d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes // Restore the signal mask. 1501c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes movq $2,%rdi // SIG_SETMASK. 1511c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes leaq (_JB_SIGMASK * 8)(%r12),%rsi // new_mask. 1521c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes xorq %rdx,%rdx // NULL. 1531c0c0ede573e3caf86b6fc395ba933bfb7235afaElliott Hughes call PIC_PLT(sigprocmask) 1548d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1558d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes2: 1562342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao // Fetch the setjmp cookie and clear the signal flag bit. 1572342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao popq %rcx 1582342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao andq $-2, %rcx 1592342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao 1608d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes popq %rax // Pop 'value'. 1618d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1628d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes // Restore the callee-save registers. 1638d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (_JB_RBX * 8)(%r12),%rbx 1648d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (_JB_RBP * 8)(%r12),%rbp 1658d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (_JB_R13 * 8)(%r12),%r13 1668d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (_JB_R14 * 8)(%r12),%r14 1678d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (_JB_R15 * 8)(%r12),%r15 1688d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (_JB_RSP * 8)(%r12),%rsp 1698d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (_JB_PC * 8)(%r12),%r11 1708d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq (_JB_R12 * 8)(%r12),%r12 1712342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao m_unmangle_registers %rcx 1722342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao 1732342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao // Check the cookie. 1742342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao pushq %rax 1758dbf02d76a245c102e11442305dd5393c4051dbbJosh Gao pushq %r11 1762342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao movq %rcx, %rdi 1772342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao call PIC_PLT(__bionic_setjmp_cookie_check) 1788dbf02d76a245c102e11442305dd5393c4051dbbJosh Gao popq %r11 1792342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao popq %rax 1808d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 1812342e643d4c998ae314d03d207f703c1cc5159e4Josh Gao // Return 1 if value is 0. 1828d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes testl %eax,%eax 1838d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes jnz 1f 1848d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes incl %eax 1858d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes1: 1868d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes movq %r11,0(%rsp) 1878d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes ret 1888d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott HughesEND(siglongjmp) 1898d4c55cc741c4107f8a0fba16e5c178c9feb5d81Elliott Hughes 19024958514b92c9b9e111223e4e4c56ef1a52b6403Christopher FerrisALIAS_SYMBOL(longjmp, siglongjmp) 19124958514b92c9b9e111223e4e4c56ef1a52b6403Christopher FerrisALIAS_SYMBOL(_longjmp, siglongjmp) 192