diff --git a/libc/arch-arm/bionic/_setjmp.S b/libc/arch-arm/bionic/_setjmp.S index 51dfc0af7..7dcc79334 100644 --- a/libc/arch-arm/bionic/_setjmp.S +++ b/libc/arch-arm/bionic/_setjmp.S @@ -77,7 +77,7 @@ ENTRY(_longjmp) ldr r2, .L_setjmp_magic ldr r3, [r0, #(_JB_MAGIC * 4)] teq r2, r3 - bne botch + blne longjmperror /* Restore floating-point registers */ add r2, r0, #(_JB_FLOAT_BASE * 4) @@ -93,17 +93,11 @@ ENTRY(_longjmp) /* Validate sp and r14 */ teq sp, #0 teqne r14, #0 - beq botch + bleq longjmperror /* Set return value */ mov r0, r1 teq r0, #0x00000000 moveq r0, #0x00000001 bx lr - - /* validation failed, die die die. */ -botch: - bl longjmperror - bl abort - b . - 8 /* Cannot get here */ END(_longjmp) diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S index 435ef8650..7bf2aed07 100644 --- a/libc/arch-arm/bionic/setjmp.S +++ b/libc/arch-arm/bionic/setjmp.S @@ -91,7 +91,7 @@ ENTRY(longjmp) ldr r2, .Lsetjmp_magic ldr r3, [r0, #(_JB_MAGIC * 4)] teq r2, r3 - bne botch + blne longjmperror /* Fetch signal mask */ ldr r2, [r0, #(_JB_SIGMASK * 4)] @@ -127,19 +127,12 @@ ENTRY(longjmp) /* Validate sp and r14 */ teq sp, #0 teqne r14, #0 - beq botch + bleq longjmperror /* Set return value */ - mov r0, r1 teq r0, #0x00000000 moveq r0, #0x00000001 bx lr mov r15, r14 - - /* validation failed, die die die. */ -botch: - bl longjmperror - bl abort - b . - 8 /* Cannot get here */ END(longjmp) diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk index bb6ca6303..ba78871c7 100644 --- a/libc/arch-arm64/arm64.mk +++ b/libc/arch-arm64/arm64.mk @@ -35,10 +35,8 @@ libc_openbsd_src_files_arm64 += \ libc_bionic_src_files_arm64 += \ arch-arm64/bionic/__bionic_clone.S \ arch-arm64/bionic/_exit_with_stack_teardown.S \ - arch-arm64/bionic/_setjmp.S \ arch-arm64/bionic/setjmp.S \ arch-arm64/bionic/__set_tls.c \ - arch-arm64/bionic/sigsetjmp.S \ arch-arm64/bionic/syscall.S \ arch-arm64/bionic/vfork.S \ diff --git a/libc/arch-arm64/bionic/_setjmp.S b/libc/arch-arm64/bionic/_setjmp.S deleted file mode 100644 index e11ef68c3..000000000 --- a/libc/arch-arm64/bionic/_setjmp.S +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -/* - * C library - _setjmp, _longjmp - * - * _longjmp(jmp_buf state, int value) - * will generate a "return(v)" from the last call to _setjmp(state) by restoring - * registers from the stack. The previous signal state is NOT restored. - * - * NOTE: x0 return value - * x9-x15 temporary registers - */ - -ENTRY(_setjmp) - /* store magic number */ - ldr w9, .L_setjmp_magic - str w9, [x0, #(_JB_MAGIC * 4)] - - /* store core registers */ - mov x10, sp - stp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)] - stp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)] - stp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)] - stp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)] - stp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)] - stp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)] - str x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)] - - /* store floating point registers */ - stp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)] - stp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)] - stp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)] - stp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)] - - mov w0, wzr - ret -END(_setjmp) - -.L_setjmp_magic: - .word _JB_MAGIC__SETJMP - -ENTRY(_longjmp) - /* check magic */ - ldr w9, .L_setjmp_magic - ldr w10, [x0, #(_JB_MAGIC * 4)] - cmp w9, w10 - b.ne .L_fail - - /* restore core registers */ - ldp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)] - mov sp, x10 - ldp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)] - ldp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)] - ldp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)] - ldp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)] - ldp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)] - ldr x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)] - - /* restore floating point registers */ - ldp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)] - ldp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)] - ldp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)] - ldp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)] - - /* validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0) */ - tst x30, #3 - b.ne .L_fail - mov x10, sp - tst x10, #15 - b.ne .L_fail - - /* set return value */ - cmp w1, wzr - csinc w0, w1, wzr, ne - ret - - /* validation failed, die die die */ -.L_fail: - bl longjmperror - bl abort - b . - 8 /* Cannot get here */ -END(_longjmp) diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S index 35815a6e5..8aeb95a71 100644 --- a/libc/arch-arm64/bionic/setjmp.S +++ b/libc/arch-arm64/bionic/setjmp.S @@ -27,97 +27,151 @@ */ #include -#include -/* - * C library - _setjmp, _longjmp - * - * _longjmp(jmp_buf state, int value) - * will generate a "return(v)" from the last call to _setjmp(state) by restoring - * registers from the stack. The previous signal state is NOT restored. - * - * NOTE: x0 return value - * x9-x15 temporary registers - */ +// _JBLEN is the size of a jmp_buf in longs(64bit on AArch64). +#define _JBLEN 32 + +// According to AARCH64 PCS document we need to save the following +// registers: +// +// Core x19 - x30, sp (see section 5.1.1) +// VFP d8 - d15 (see section 5.1.2) +// +// NOTE: All the registers saved here will have 64bit vales (except FPSR). +// AAPCS mandates that the higher part of q registers do not need to +// be saved by the callee. +// + +// The structure of jmp_buf for AArch64: +// +// NOTE: _JBLEN is the size of jmp_buf in longs(64bit on AArch64)! The table +// below computes the offsets in words(32bit). +// +// word name description +// 0 magic magic number +// 1 sigmask signal mask (not used with _setjmp / _longjmp) +// 2 core_base base of core registers (x19-x30, sp) +// 28 float_base base of float registers (d8-d15) +// 44 reserved reserved entries (room to grow) +// 64 +// +// +// NOTE: The instructions that load/store core/vfp registers expect 8-byte +// alignment. Contrary to the previous setjmp header for ARM we do not +// need to save status/control registers for VFP (it is not a +// requirement for setjmp). +// + +#define _JB_MAGIC 0 +#define _JB_SIGMASK (_JB_MAGIC+1) +#define _JB_CORE_BASE (_JB_SIGMASK+1) +#define _JB_FLOAT_BASE (_JB_CORE_BASE + (31-19+1)*2) + +.L_setjmp_magic_signal_mask_n: .word 0x53657200 +.L_setjmp_magic_signal_mask_y: .word 0x53657201 ENTRY(setjmp) - /* block all signals an retrieve signal mask */ - stp x0, x30, [sp, #-16]! - - mov x0, xzr - bl sigblock - mov w1, w0 - - ldp x0, x30, [sp], #16 - - /* store signal mask */ - str w1, [x0, #(_JB_SIGMASK *4)] - - /* store magic number */ - ldr w9, .L_setjmp_magic - str w9, [x0, #(_JB_MAGIC * 4)] - - /* store core registers */ - mov x10, sp - stp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)] - stp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)] - stp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)] - stp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)] - stp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)] - stp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)] - str x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)] - - /* store floating point registers */ - stp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)] - stp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)] - stp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)] - stp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)] - - mov w0, wzr - ret + mov w1, #1 + b sigsetjmp END(setjmp) -.L_setjmp_magic: - .word _JB_MAGIC__SETJMP +ENTRY(_setjmp) + mov w1, #0 + b sigsetjmp +END(_setjmp) -ENTRY(longjmp) - /* check magic */ - ldr w9, .L_setjmp_magic - ldr w10, [x0, #(_JB_MAGIC * 4)] - cmp w9, w10 - b.ne .L_fail +// int sigsetjmp(sigjmp_buf env, int save_signal_mask); +ENTRY(sigsetjmp) + // Do we need to save the signal mask? + ldr w9, .L_setjmp_magic_signal_mask_n + cbz w1, 1f - /* restore core registers */ - ldp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)] - mov sp, x10 - ldp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)] - ldp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)] - ldp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)] - ldp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)] - ldp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)] - ldr x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)] + // Get current signal mask. + stp x0, x30, [sp, #-16]! + mov x0, xzr + bl sigblock + mov w1, w0 + ldp x0, x30, [sp], #16 - /* restore floating point registers */ - ldp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)] - ldp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)] - ldp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)] - ldp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)] + // Save signal mask. + str w1, [x0, #(_JB_SIGMASK * 4)] - /* validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0) */ - tst x30, #3 - b.ne .L_fail - mov x10, sp - tst x10, #15 - b.ne .L_fail + ldr w9, .L_setjmp_magic_signal_mask_y - /* set return value */ - cmp w1, wzr - csinc w0, w1, wzr, ne - ret +1: + // Save magic number. + str w9, [x0, #(_JB_MAGIC * 4)] - /* validation failed, die die die */ -.L_fail: - bl longjmperror - bl abort - b . - 8 /* Cannot get here */ -END(longjmp) + // Save core registers. + mov x10, sp + stp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)] + stp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)] + stp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)] + stp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)] + stp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)] + stp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)] + str x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)] + + // Save floating point registers. + stp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)] + stp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)] + stp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)] + stp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)] + + mov w0, wzr + ret +END(sigsetjmp) + +// void siglongjmp(sigjmp_buf env, int value); +ENTRY(siglongjmp) + // Check magic. + ldr w10, [x0, #(_JB_MAGIC * 4)] + ldr w9, .L_setjmp_magic_signal_mask_n + cmp w9, w10 + b.eq 1f + ldr w9, .L_setjmp_magic_signal_mask_y + cmp w9, w10 + b.ne longjmperror + + // Restore signal mask. + stp x0, x30, [sp, #-16]! + mov x19, x1 + ldr w0, [x0, #(_JB_SIGMASK * 4)] + bl sigsetmask + ldp x0, x30, [sp], #16 + mov x1, x19 + +1: + // Restore core registers. + ldp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)] + mov sp, x10 + ldp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)] + ldp x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)] + ldp x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)] + ldp x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)] + ldp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)] + ldr x19, [x0, #(_JB_CORE_BASE * 4 + 16 * 6)] + + // Restore floating point registers. + ldp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)] + ldp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)] + ldp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)] + ldp d8, d9, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)] + + // Validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0). + tst x30, #3 + b.ne longjmperror + mov x10, sp + tst x10, #15 + b.ne longjmperror + + // Set return value. + cmp w1, wzr + csinc w0, w1, wzr, ne + ret +END(siglongjmp) + + .globl longjmp + .equ longjmp, siglongjmp + .globl _longjmp + .equ _longjmp, siglongjmp diff --git a/libc/arch-arm64/bionic/sigsetjmp.S b/libc/arch-arm64/bionic/sigsetjmp.S deleted file mode 100644 index be7cecb79..000000000 --- a/libc/arch-arm64/bionic/sigsetjmp.S +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include - -/* - * int sigsetjmp(sigjmp_buf env, int savesigs); - * void siglongjmp(sigjmp_buf env, int val); - */ - -ENTRY(sigsetjmp) - cbz w1, _setjmp - b setjmp -END(sigsetjmp) - -.L_setjmp_magic: - .word _JB_MAGIC__SETJMP - -ENTRY(siglongjmp) - ldr w2, .L_setjmp_magic - ldr w3, [x0] - cmp w2, w3 - b.eq _longjmp - b longjmp -END(siglongjmp) diff --git a/libc/arch-arm64/include/machine/setjmp.h b/libc/arch-arm64/include/machine/setjmp.h index 1c237da56..27c2fe51e 100644 --- a/libc/arch-arm64/include/machine/setjmp.h +++ b/libc/arch-arm64/include/machine/setjmp.h @@ -26,48 +26,5 @@ * SUCH DAMAGE. */ -/* - * machine/setjmp.h: machine dependent setjmp-related information. - */ - -/* _JBLEN is the size of a jmp_buf in longs(64bit on AArch64) */ +/* _JBLEN is the size of a jmp_buf in longs (64bit on AArch64) */ #define _JBLEN 32 - -/* According to AARCH64 PCS document we need to save the following - * registers: - * - * Core x19 - x30, sp (see section 5.1.1) - * VFP d8 - d15 (see section 5.1.2) - * - * NOTE: All the registers saved here will have 64bit vales (except FPSR). - * AAPCS mandates that the higher part of q registers does not need to - * be saveved by the callee. - */ - -/* The structure of jmp_buf for AArch64: - * - * NOTE: _JBLEN is the size of jmp_buf in longs(64bit on AArch64)! The table - * below computes the offsets in words(32bit). - * - * word name description - * 0 magic magic number - * 1 sigmask signal mask (not used with _setjmp / _longjmp) - * 2 core_base base of core registers (x19-x30, sp) - * 28 float_base base of float registers (d8-d15) - * 44 reserved reserved entries (room to grow) - * 64 - * - * - * NOTE: The instructions that load/store core/vfp registers expect 8-byte - * alignment. Contrary to the previous setjmp header for ARM we do not - * need to save status/control registers for VFP (it is not a - * requirement for setjmp). - */ - -#define _JB_MAGIC 0 -#define _JB_SIGMASK (_JB_MAGIC+1) -#define _JB_CORE_BASE (_JB_SIGMASK+1) -#define _JB_FLOAT_BASE (_JB_CORE_BASE + (31-19+1)*2) - -#define _JB_MAGIC__SETJMP 0x53657200 -#define _JB_MAGIC_SETJMP 0x53657201