* commit 'd276faae7c82cd139e984275b325edc4dbe313f3': Clean up the arm64 setjmp.
This commit is contained in:
		@@ -77,7 +77,7 @@ ENTRY(_longjmp)
 | 
				
			|||||||
	ldr	r2, .L_setjmp_magic
 | 
						ldr	r2, .L_setjmp_magic
 | 
				
			||||||
	ldr	r3, [r0, #(_JB_MAGIC * 4)]
 | 
						ldr	r3, [r0, #(_JB_MAGIC * 4)]
 | 
				
			||||||
	teq	r2, r3
 | 
						teq	r2, r3
 | 
				
			||||||
	bne	botch
 | 
						blne	longjmperror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Restore floating-point registers */
 | 
						/* Restore floating-point registers */
 | 
				
			||||||
	add     r2, r0, #(_JB_FLOAT_BASE * 4)
 | 
						add     r2, r0, #(_JB_FLOAT_BASE * 4)
 | 
				
			||||||
@@ -93,17 +93,11 @@ ENTRY(_longjmp)
 | 
				
			|||||||
	/* Validate sp and r14 */
 | 
						/* Validate sp and r14 */
 | 
				
			||||||
	teq	sp, #0
 | 
						teq	sp, #0
 | 
				
			||||||
	teqne	r14, #0
 | 
						teqne	r14, #0
 | 
				
			||||||
	beq	botch
 | 
						bleq	longjmperror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set return value */
 | 
						/* Set return value */
 | 
				
			||||||
	mov	r0, r1
 | 
						mov	r0, r1
 | 
				
			||||||
	teq	r0, #0x00000000
 | 
						teq	r0, #0x00000000
 | 
				
			||||||
	moveq	r0, #0x00000001
 | 
						moveq	r0, #0x00000001
 | 
				
			||||||
	bx      lr
 | 
						bx      lr
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* validation failed, die die die. */
 | 
					 | 
				
			||||||
botch:
 | 
					 | 
				
			||||||
	bl	longjmperror
 | 
					 | 
				
			||||||
	bl	abort
 | 
					 | 
				
			||||||
	b	. - 8		/* Cannot get here */
 | 
					 | 
				
			||||||
END(_longjmp)
 | 
					END(_longjmp)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,7 +91,7 @@ ENTRY(longjmp)
 | 
				
			|||||||
	ldr	r2, .Lsetjmp_magic
 | 
						ldr	r2, .Lsetjmp_magic
 | 
				
			||||||
	ldr	r3, [r0, #(_JB_MAGIC * 4)]
 | 
						ldr	r3, [r0, #(_JB_MAGIC * 4)]
 | 
				
			||||||
	teq	r2, r3
 | 
						teq	r2, r3
 | 
				
			||||||
	bne	botch
 | 
						blne	longjmperror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Fetch signal mask */
 | 
						/* Fetch signal mask */
 | 
				
			||||||
	ldr	r2, [r0, #(_JB_SIGMASK * 4)]
 | 
						ldr	r2, [r0, #(_JB_SIGMASK * 4)]
 | 
				
			||||||
@@ -127,19 +127,12 @@ ENTRY(longjmp)
 | 
				
			|||||||
	/* Validate sp and r14 */
 | 
						/* Validate sp and r14 */
 | 
				
			||||||
	teq	sp, #0
 | 
						teq	sp, #0
 | 
				
			||||||
	teqne	r14, #0
 | 
						teqne	r14, #0
 | 
				
			||||||
	beq	botch
 | 
						bleq	longjmperror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set return value */
 | 
						/* Set return value */
 | 
				
			||||||
 | 
					 | 
				
			||||||
	mov	r0, r1
 | 
						mov	r0, r1
 | 
				
			||||||
	teq	r0, #0x00000000
 | 
						teq	r0, #0x00000000
 | 
				
			||||||
	moveq	r0, #0x00000001
 | 
						moveq	r0, #0x00000001
 | 
				
			||||||
        bx      lr
 | 
					        bx      lr
 | 
				
			||||||
	mov	r15, r14
 | 
						mov	r15, r14
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* validation failed, die die die. */
 | 
					 | 
				
			||||||
botch:
 | 
					 | 
				
			||||||
	bl	longjmperror
 | 
					 | 
				
			||||||
	bl	abort
 | 
					 | 
				
			||||||
	b	. - 8		/* Cannot get here */
 | 
					 | 
				
			||||||
END(longjmp)
 | 
					END(longjmp)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,10 +35,8 @@ libc_openbsd_src_files_arm64 += \
 | 
				
			|||||||
libc_bionic_src_files_arm64 += \
 | 
					libc_bionic_src_files_arm64 += \
 | 
				
			||||||
    arch-arm64/bionic/__bionic_clone.S \
 | 
					    arch-arm64/bionic/__bionic_clone.S \
 | 
				
			||||||
    arch-arm64/bionic/_exit_with_stack_teardown.S \
 | 
					    arch-arm64/bionic/_exit_with_stack_teardown.S \
 | 
				
			||||||
    arch-arm64/bionic/_setjmp.S \
 | 
					 | 
				
			||||||
    arch-arm64/bionic/setjmp.S \
 | 
					    arch-arm64/bionic/setjmp.S \
 | 
				
			||||||
    arch-arm64/bionic/__set_tls.c \
 | 
					    arch-arm64/bionic/__set_tls.c \
 | 
				
			||||||
    arch-arm64/bionic/sigsetjmp.S \
 | 
					 | 
				
			||||||
    arch-arm64/bionic/syscall.S \
 | 
					    arch-arm64/bionic/syscall.S \
 | 
				
			||||||
    arch-arm64/bionic/vfork.S \
 | 
					    arch-arm64/bionic/vfork.S \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 <private/bionic_asm.h>
 | 
					 | 
				
			||||||
#include <machine/setjmp.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * 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)
 | 
					 | 
				
			||||||
@@ -27,37 +27,82 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
#include <machine/setjmp.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// _JBLEN is the size of a jmp_buf in longs(64bit on AArch64).
 | 
				
			||||||
 * C library - _setjmp, _longjmp
 | 
					#define _JBLEN 32
 | 
				
			||||||
 *
 | 
					
 | 
				
			||||||
 * _longjmp(jmp_buf state, int value)
 | 
					// According to AARCH64 PCS document we need to save the following
 | 
				
			||||||
 * will generate a "return(v)" from the last call to _setjmp(state) by restoring
 | 
					// registers:
 | 
				
			||||||
 * registers from the stack. The previous signal state is NOT restored.
 | 
					//
 | 
				
			||||||
 *
 | 
					// Core     x19 - x30, sp (see section 5.1.1)
 | 
				
			||||||
 * NOTE: x0 return value
 | 
					// VFP      d8 - d15 (see section 5.1.2)
 | 
				
			||||||
 *       x9-x15 temporary registers
 | 
					//
 | 
				
			||||||
 */
 | 
					// 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)
 | 
					ENTRY(setjmp)
 | 
				
			||||||
    /* block all signals an retrieve signal mask */
 | 
					  mov w1, #1
 | 
				
			||||||
    stp     x0, x30, [sp, #-16]!
 | 
					  b sigsetjmp
 | 
				
			||||||
 | 
					END(setjmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENTRY(_setjmp)
 | 
				
			||||||
 | 
					  mov w1, #0
 | 
				
			||||||
 | 
					  b sigsetjmp
 | 
				
			||||||
 | 
					END(_setjmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Get current signal mask.
 | 
				
			||||||
 | 
					  stp x0, x30, [sp, #-16]!
 | 
				
			||||||
  mov x0, xzr
 | 
					  mov x0, xzr
 | 
				
			||||||
  bl sigblock
 | 
					  bl sigblock
 | 
				
			||||||
  mov w1, w0
 | 
					  mov w1, w0
 | 
				
			||||||
 | 
					 | 
				
			||||||
  ldp x0, x30, [sp], #16
 | 
					  ldp x0, x30, [sp], #16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* store signal mask */
 | 
					  // Save signal mask.
 | 
				
			||||||
    str     w1, [x0, #(_JB_SIGMASK *4)]
 | 
					  str w1, [x0, #(_JB_SIGMASK * 4)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* store magic number */
 | 
					  ldr w9, .L_setjmp_magic_signal_mask_y
 | 
				
			||||||
    ldr     w9, .L_setjmp_magic
 | 
					
 | 
				
			||||||
 | 
					1:
 | 
				
			||||||
 | 
					  // Save magic number.
 | 
				
			||||||
  str w9, [x0, #(_JB_MAGIC * 4)]
 | 
					  str w9, [x0, #(_JB_MAGIC * 4)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* store core registers */
 | 
					  // Save core registers.
 | 
				
			||||||
  mov x10, sp
 | 
					  mov x10, sp
 | 
				
			||||||
  stp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
 | 
					  stp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
 | 
				
			||||||
  stp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
 | 
					  stp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
 | 
				
			||||||
@@ -67,7 +112,7 @@ ENTRY(setjmp)
 | 
				
			|||||||
  stp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
 | 
					  stp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
 | 
				
			||||||
  str x19,      [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
 | 
					  str x19,      [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* store floating point registers */
 | 
					  // Save floating point registers.
 | 
				
			||||||
  stp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
 | 
					  stp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
 | 
				
			||||||
  stp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
 | 
					  stp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
 | 
				
			||||||
  stp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
 | 
					  stp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
 | 
				
			||||||
@@ -75,19 +120,29 @@ ENTRY(setjmp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  mov w0, wzr
 | 
					  mov w0, wzr
 | 
				
			||||||
  ret
 | 
					  ret
 | 
				
			||||||
END(setjmp)
 | 
					END(sigsetjmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.L_setjmp_magic:
 | 
					// void siglongjmp(sigjmp_buf env, int value);
 | 
				
			||||||
    .word   _JB_MAGIC__SETJMP
 | 
					ENTRY(siglongjmp)
 | 
				
			||||||
 | 
					  // Check magic.
 | 
				
			||||||
ENTRY(longjmp)
 | 
					 | 
				
			||||||
    /* check magic */
 | 
					 | 
				
			||||||
    ldr     w9, .L_setjmp_magic
 | 
					 | 
				
			||||||
  ldr w10, [x0, #(_JB_MAGIC * 4)]
 | 
					  ldr w10, [x0, #(_JB_MAGIC * 4)]
 | 
				
			||||||
 | 
					  ldr w9, .L_setjmp_magic_signal_mask_n
 | 
				
			||||||
  cmp w9, w10
 | 
					  cmp w9, w10
 | 
				
			||||||
    b.ne    .L_fail
 | 
					  b.eq 1f
 | 
				
			||||||
 | 
					  ldr w9, .L_setjmp_magic_signal_mask_y
 | 
				
			||||||
 | 
					  cmp w9, w10
 | 
				
			||||||
 | 
					  b.ne longjmperror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* restore core registers */
 | 
					  // 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)]
 | 
					  ldp x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
 | 
				
			||||||
  mov sp, x10
 | 
					  mov sp, x10
 | 
				
			||||||
  ldp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
 | 
					  ldp x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
 | 
				
			||||||
@@ -97,27 +152,26 @@ ENTRY(longjmp)
 | 
				
			|||||||
  ldp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
 | 
					  ldp x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
 | 
				
			||||||
  ldr x19,      [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
 | 
					  ldr x19,      [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* restore floating point registers */
 | 
					  // Restore floating point registers.
 | 
				
			||||||
  ldp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
 | 
					  ldp d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
 | 
				
			||||||
  ldp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
 | 
					  ldp d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
 | 
				
			||||||
  ldp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
 | 
					  ldp d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
 | 
				
			||||||
  ldp d8,  d9,  [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
 | 
					  ldp d8,  d9,  [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0) */
 | 
					  // Validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0).
 | 
				
			||||||
  tst x30, #3
 | 
					  tst x30, #3
 | 
				
			||||||
    b.ne    .L_fail
 | 
					  b.ne longjmperror
 | 
				
			||||||
  mov x10, sp
 | 
					  mov x10, sp
 | 
				
			||||||
  tst x10, #15
 | 
					  tst x10, #15
 | 
				
			||||||
    b.ne    .L_fail
 | 
					  b.ne longjmperror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* set return value */
 | 
					  // Set return value.
 | 
				
			||||||
  cmp w1, wzr
 | 
					  cmp w1, wzr
 | 
				
			||||||
  csinc w0, w1, wzr, ne
 | 
					  csinc w0, w1, wzr, ne
 | 
				
			||||||
  ret
 | 
					  ret
 | 
				
			||||||
 | 
					END(siglongjmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* validation failed, die die die */
 | 
					  .globl longjmp
 | 
				
			||||||
.L_fail:
 | 
					  .equ longjmp, siglongjmp
 | 
				
			||||||
    bl      longjmperror
 | 
					  .globl _longjmp
 | 
				
			||||||
    bl      abort
 | 
					  .equ _longjmp, siglongjmp
 | 
				
			||||||
    b       . - 8       /* Cannot get here */
 | 
					 | 
				
			||||||
END(longjmp)
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 <private/bionic_asm.h>
 | 
					 | 
				
			||||||
#include <machine/setjmp.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * 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)
 | 
					 | 
				
			||||||
@@ -26,48 +26,5 @@
 | 
				
			|||||||
 * SUCH DAMAGE.
 | 
					 * SUCH DAMAGE.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/* _JBLEN is the size of a jmp_buf in longs (64bit on AArch64) */
 | 
				
			||||||
 * machine/setjmp.h: machine dependent setjmp-related information.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* _JBLEN is the size of a jmp_buf in longs(64bit on AArch64) */
 | 
					 | 
				
			||||||
#define _JBLEN 32
 | 
					#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
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user