* commit '1cb009fb5eb513e838085d75617db676fcfa7aa7': [MIPS] Fix setjmp signals
This commit is contained in:
		@@ -1,3 +1,30 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2014-2015 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 | 
					 * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -94,23 +121,31 @@
 | 
				
			|||||||
#include <private/bionic_asm.h>
 | 
					#include <private/bionic_asm.h>
 | 
				
			||||||
#include <machine/setjmp.h>
 | 
					#include <machine/setjmp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* On Mips32, jmpbuf begins with optional 4-byte filler so that
 | 
					/* jmpbuf is declared to users as an array of longs, which is only
 | 
				
			||||||
 *  all saved FP regs are aligned on 8-byte boundary, despite this whole
 | 
					 * 4-byte aligned in 32-bit builds.  The Mips jmpbuf begins with a
 | 
				
			||||||
 *  struct being mis-declared to users as an array of (4-byte) longs.
 | 
					 * dynamically-sized 0- or 4-byte unused filler so that double-prec FP regs
 | 
				
			||||||
 *  All the following offsets are then from the rounded-up base addr
 | 
					 * are saved to 8-byte-aligned mem cells.
 | 
				
			||||||
 | 
					 * All the following jmpbuf offsets are from the rounded-DOWN base addr.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Fields of same size on all MIPS abis: */
 | 
					/* Fields of same size on all MIPS abis: */
 | 
				
			||||||
#define	SC_MAGIC        (0*4)		/* 4 bytes, identify jmpbuf */
 | 
					/*     	field:		byte offset:	size:						*/
 | 
				
			||||||
#define	SC_MASK		(1*4)		/* 4 bytes, saved signal mask */
 | 
					/*     	dynam filler	(0*4)		   0-4 bytes of rounddown filler, DON'T TOUCH!!
 | 
				
			||||||
#define	SC_FPSR		(2*4)		/* 4 bytes, floating point control/status reg */
 | 
											often overlays user storage!!		*/
 | 
				
			||||||
/*     	filler2		(3*4)		   4 bytes, pad to 8-byte boundary */
 | 
					#define	SC_MAGIC_OFFSET	(1*4)		/* 4 bytes, identify jmpbuf, first actual field */
 | 
				
			||||||
 | 
					#define	SC_FLAG_OFFSET	(2*4)		/* 4 bytes, savesigs flag */
 | 
				
			||||||
 | 
					#define	SC_FPSR_OFFSET	(3*4)		/* 4 bytes, floating point control/status reg */
 | 
				
			||||||
 | 
					/* following fields are 8-byte aligned */
 | 
				
			||||||
 | 
					#define	SC_MASK_OFFSET	(4*4)		/* 16 bytes, mips32/mips64 version of sigset_t */
 | 
				
			||||||
 | 
					#define	SC_SPARE_OFFSET	(8*4)		/* 8 bytes, reserved for future uses */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */
 | 
					/* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */
 | 
				
			||||||
#define	SC_REGS_SAVED	12		/* ra,gp,sp,s0-s8 */
 | 
					#define	SC_REGS_OFFSET	(10*4)		/* SC_REGS_BYTES */
 | 
				
			||||||
#define	SC_REGS		(4*4)		/* SC_REGS_SAVED*REGSZ bytes */
 | 
					#define	SC_REGS_SAVED	12 /*regs*/	/* ra,s0-s8,gp,sp */
 | 
				
			||||||
 | 
					#define	SC_REGS_BYTES   (SC_REGS_SAVED*REGSZ)
 | 
				
			||||||
 | 
					#define	SC_REGS		SC_REGS_OFFSET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Floating pt registers are 8-bytes on all abis,
 | 
					/* Double floating pt registers are 8-bytes on all abis,
 | 
				
			||||||
 * but the number of saved fp regs varies for o32/n32 versus n64 abis:
 | 
					 * but the number of saved fp regs varies for o32/n32 versus n64 abis:
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,22 +155,20 @@
 | 
				
			|||||||
#define	SC_FPREGS_SAVED	6  /* even fp regs f20,f22,f24,f26,f28,f30 */
 | 
					#define	SC_FPREGS_SAVED	6  /* even fp regs f20,f22,f24,f26,f28,f30 */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define	SC_FPREGS	(SC_REGS + SC_REGS_SAVED*REGSZ)  /* SC_FPREGS_SAVED*REGSZ_FP bytes */
 | 
					#define	SC_FPREGS_OFFSET (SC_REGS_OFFSET + SC_REGS_BYTES)  /* SC_FPREGS_BYTES */
 | 
				
			||||||
 | 
					#define	SC_FPREGS_BYTES (SC_FPREGS_SAVED*REGSZ_FP)
 | 
				
			||||||
 | 
					#define	SC_FPREGS	SC_FPREGS_OFFSET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define	SC_BYTES	(SC_FPREGS + SC_FPREGS_SAVED*REGSZ_FP)
 | 
					#define	SC_TOTAL_BYTES	(SC_FPREGS_OFFSET + SC_FPREGS_BYTES)
 | 
				
			||||||
#define	SC_LONGS	(SC_BYTES/REGSZ)
 | 
					#define	SC_TOTAL_LONGS	(SC_TOTAL_BYTES/REGSZ)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __LP64__
 | 
					#if SC_TOTAL_LONGS > _JBLEN
 | 
				
			||||||
/* SC_LONGS is 22, so _JBLEN should be 22 or larger */
 | 
					#error _JBLEN is too small
 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
/* SC_LONGS is 28, but must also allocate dynamic-roundup filler.
 | 
					 | 
				
			||||||
   so _JBLEN should be 29 or larger */
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * _setjmp, _longjmp (restoring signal state)
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
 | 
					 *  GPOFF and FRAMESIZE must be the same for all setjmp/longjmp routines
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -145,30 +178,33 @@ A0OFF= FRAMESZ-3*REGSZ
 | 
				
			|||||||
GPOFF= FRAMESZ-2*REGSZ
 | 
					GPOFF= FRAMESZ-2*REGSZ
 | 
				
			||||||
RAOFF= FRAMESZ-1*REGSZ
 | 
					RAOFF= FRAMESZ-1*REGSZ
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NON_LEAF(setjmp, FRAMESZ, ra)
 | 
					NON_LEAF(sigsetjmp, FRAMESZ, ra)
 | 
				
			||||||
	.mask	0x80000000, RAOFF
 | 
						.mask	0x80000000, RAOFF
 | 
				
			||||||
	PTR_SUBU sp, FRAMESZ			# allocate stack frame
 | 
						PTR_SUBU sp, FRAMESZ			# allocate stack frame
 | 
				
			||||||
	SETUP_GP64(GPOFF, setjmp)
 | 
						SETUP_GP64(GPOFF, sigsetjmp)
 | 
				
			||||||
	SAVE_GP(GPOFF)
 | 
						SAVE_GP(GPOFF)
 | 
				
			||||||
	.set	reorder
 | 
						.set	reorder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setjmp_common:
 | 
				
			||||||
#ifndef __LP64__
 | 
					#ifndef __LP64__
 | 
				
			||||||
	addiu   a0, 7				# roundup jmpbuf addr to 8-byte boundary
 | 
					 | 
				
			||||||
	li	t0, ~7
 | 
						li	t0, ~7
 | 
				
			||||||
	and     a0, t0
 | 
						and	a0, t0				# round jmpbuf addr DOWN to 8-byte boundary
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
						sw	a1, SC_FLAG_OFFSET(a0)		# save savesigs flag
 | 
				
			||||||
 | 
						beqz	a1, 1f				# do saving of signal mask?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	REG_S	ra, RAOFF(sp)			# save state
 | 
						REG_S	ra, RAOFF(sp)			# spill state
 | 
				
			||||||
	REG_S	a0, A0OFF(sp)
 | 
						REG_S	a0, A0OFF(sp)
 | 
				
			||||||
	move	a0, zero			# get current signal mask
 | 
						# call sigprocmask(int how ignored, sigset_t* null, sigset_t* SC_MASK(a0)):
 | 
				
			||||||
	jal	sigblock
 | 
						LA	a2, SC_MASK_OFFSET(a0)		# gets current signal mask
 | 
				
			||||||
 | 
						li	a0, 0				# how; ignored when new mask is null
 | 
				
			||||||
 | 
						li	a1, 0				# null new mask
 | 
				
			||||||
 | 
						jal	sigprocmask			# get current signal mask
 | 
				
			||||||
	REG_L	a0, A0OFF(sp)
 | 
						REG_L	a0, A0OFF(sp)
 | 
				
			||||||
	REG_L	ra, RAOFF(sp)
 | 
						REG_L	ra, RAOFF(sp)
 | 
				
			||||||
 | 
					1:
 | 
				
			||||||
	REG_S	v0, SC_MASK(a0)			# save sc_mask = sigblock(0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	li	v0, 0xACEDBADE			# sigcontext magic number
 | 
						li	v0, 0xACEDBADE			# sigcontext magic number
 | 
				
			||||||
	sw	v0, SC_MAGIC(a0)
 | 
						sw	v0, SC_MAGIC_OFFSET(a0)
 | 
				
			||||||
	# callee-saved long-sized regs:
 | 
						# callee-saved long-sized regs:
 | 
				
			||||||
	REG_S	ra, SC_REGS+0*REGSZ(a0)
 | 
						REG_S	ra, SC_REGS+0*REGSZ(a0)
 | 
				
			||||||
	REG_S	s0, SC_REGS+1*REGSZ(a0)
 | 
						REG_S	s0, SC_REGS+1*REGSZ(a0)
 | 
				
			||||||
@@ -181,9 +217,9 @@ NON_LEAF(setjmp, FRAMESZ, ra)
 | 
				
			|||||||
	REG_S	s7, SC_REGS+8*REGSZ(a0)
 | 
						REG_S	s7, SC_REGS+8*REGSZ(a0)
 | 
				
			||||||
	REG_S	s8, SC_REGS+9*REGSZ(a0)
 | 
						REG_S	s8, SC_REGS+9*REGSZ(a0)
 | 
				
			||||||
	REG_L	v0, GPOFF(sp)
 | 
						REG_L	v0, GPOFF(sp)
 | 
				
			||||||
	REG_S	v0, SC_REGS+10*REGSZ(a0)
 | 
						REG_S	v0, SC_REGS+10*REGSZ(a0)	# save gp
 | 
				
			||||||
	PTR_ADDU v0, sp, FRAMESZ
 | 
						PTR_ADDU v0, sp, FRAMESZ
 | 
				
			||||||
	REG_S	v0, SC_REGS+11*REGSZ(a0)
 | 
						REG_S	v0, SC_REGS+11*REGSZ(a0)	# save orig sp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfc1	v0, $31
 | 
						cfc1	v0, $31
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -199,7 +235,7 @@ NON_LEAF(setjmp, FRAMESZ, ra)
 | 
				
			|||||||
	s.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
 | 
						s.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	# callee-saved fp regs on mips o32 ABI are
 | 
						# callee-saved fp regs on mips o32 ABI are
 | 
				
			||||||
	#   the even-numbered fp regs $f20,$f22,...$f30
 | 
						#   the even-numbered double fp regs $f20,$f22,...$f30
 | 
				
			||||||
	s.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
 | 
						s.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
 | 
				
			||||||
	s.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
 | 
						s.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
 | 
				
			||||||
	s.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
 | 
						s.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
 | 
				
			||||||
@@ -207,37 +243,68 @@ NON_LEAF(setjmp, FRAMESZ, ra)
 | 
				
			|||||||
	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
 | 
						s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
 | 
				
			||||||
	s.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
 | 
						s.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	sw	v0, SC_FPSR(a0)
 | 
						sw	v0, SC_FPSR_OFFSET(a0)
 | 
				
			||||||
	move	v0, zero
 | 
						move	v0, zero
 | 
				
			||||||
	RESTORE_GP64
 | 
						RESTORE_GP64
 | 
				
			||||||
	PTR_ADDU sp, FRAMESZ
 | 
						PTR_ADDU sp, FRAMESZ
 | 
				
			||||||
	j	ra
 | 
						j	ra
 | 
				
			||||||
END(setjmp)
 | 
					END(sigsetjmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NON_LEAF(longjmp, FRAMESZ, ra)
 | 
					
 | 
				
			||||||
 | 
					# Alternate entry points:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NON_LEAF(setjmp, FRAMESZ, ra)
 | 
				
			||||||
	.mask	0x80000000, RAOFF
 | 
						.mask	0x80000000, RAOFF
 | 
				
			||||||
	PTR_SUBU sp, FRAMESZ
 | 
						PTR_SUBU sp, FRAMESZ
 | 
				
			||||||
	SETUP_GP64(GPOFF, longjmp)
 | 
						SETUP_GP64(GPOFF, setjmp)		# can't share sigsetjmp's gp code
 | 
				
			||||||
 | 
						SAVE_GP(GPOFF)
 | 
				
			||||||
 | 
						.set	reorder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						li	a1, 1				# save/restore signals state
 | 
				
			||||||
 | 
						b	setjmp_common			# tail call
 | 
				
			||||||
 | 
					END(setjmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NON_LEAF(_setjmp, FRAMESZ, ra)
 | 
				
			||||||
 | 
						.mask	0x80000000, RAOFF
 | 
				
			||||||
 | 
						PTR_SUBU sp, FRAMESZ
 | 
				
			||||||
 | 
						SETUP_GP64(GPOFF, _setjmp)		# can't share sigsetjmp's gp code
 | 
				
			||||||
 | 
						SAVE_GP(GPOFF)
 | 
				
			||||||
 | 
						.set	reorder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						li	a1, 0				# don't save/restore signals
 | 
				
			||||||
 | 
						b	setjmp_common			# tail call
 | 
				
			||||||
 | 
					END(_setjmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NON_LEAF(siglongjmp, FRAMESZ, ra)
 | 
				
			||||||
 | 
						.mask	0x80000000, RAOFF
 | 
				
			||||||
 | 
						PTR_SUBU sp, FRAMESZ
 | 
				
			||||||
 | 
						SETUP_GP64(GPOFF, siglongjmp)
 | 
				
			||||||
	SAVE_GP(GPOFF)
 | 
						SAVE_GP(GPOFF)
 | 
				
			||||||
	.set	reorder
 | 
						.set	reorder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __LP64__
 | 
					#ifndef __LP64__
 | 
				
			||||||
	addiu	a0, 7				# roundup jmpbuf addr to 8-byte boundary
 | 
					 | 
				
			||||||
	li	t0, ~7
 | 
						li	t0, ~7
 | 
				
			||||||
	and	a0, t0
 | 
						and	a0, t0				# round jmpbuf addr DOWN to 8-byte boundary
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
						lw	v0, SC_MAGIC_OFFSET(a0)
 | 
				
			||||||
	REG_S	a1, A1OFF(sp)
 | 
					 | 
				
			||||||
	REG_S	a0, A0OFF(sp)
 | 
					 | 
				
			||||||
	lw	a0, SC_MASK(a0)
 | 
					 | 
				
			||||||
	jal	sigsetmask
 | 
					 | 
				
			||||||
	REG_L	a0, A0OFF(sp)
 | 
					 | 
				
			||||||
	REG_L	a1, A1OFF(sp)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lw	v0, SC_MAGIC(a0)
 | 
					 | 
				
			||||||
	li	t0, 0xACEDBADE
 | 
						li	t0, 0xACEDBADE
 | 
				
			||||||
	bne	v0, t0, longjmp_botch		# jump if error
 | 
						bne	v0, t0, longjmp_botch		# jump if error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lw	t0, SC_FLAG_OFFSET(a0)		# get savesigs flag
 | 
				
			||||||
 | 
						beqz	t0, 1f				# restore signal mask?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_S	a1, A1OFF(sp)			# temp spill
 | 
				
			||||||
 | 
						REG_S	a0, A0OFF(sp)
 | 
				
			||||||
 | 
					        # call sigprocmask(int how SIG_SETMASK, sigset_t* SC_MASK(a0), sigset_t* null):
 | 
				
			||||||
 | 
						LA	a1, SC_MASK_OFFSET(a0)		# signals being restored
 | 
				
			||||||
 | 
						li	a0, 3				# mips SIG_SETMASK
 | 
				
			||||||
 | 
						li	a2, 0				# null
 | 
				
			||||||
 | 
						jal	sigprocmask			# restore signal mask
 | 
				
			||||||
 | 
						REG_L	a0, A0OFF(sp)
 | 
				
			||||||
 | 
						REG_L	a1, A1OFF(sp)
 | 
				
			||||||
 | 
					1:
 | 
				
			||||||
	# callee-saved long-sized regs:
 | 
						# callee-saved long-sized regs:
 | 
				
			||||||
	REG_L	ra, SC_REGS+0*REGSZ(a0)
 | 
						REG_L	ra, SC_REGS+0*REGSZ(a0)
 | 
				
			||||||
	REG_L	s0, SC_REGS+1*REGSZ(a0)
 | 
						REG_L	s0, SC_REGS+1*REGSZ(a0)
 | 
				
			||||||
@@ -252,8 +319,8 @@ NON_LEAF(longjmp, FRAMESZ, ra)
 | 
				
			|||||||
	REG_L	gp, SC_REGS+10*REGSZ(a0)
 | 
						REG_L	gp, SC_REGS+10*REGSZ(a0)
 | 
				
			||||||
	REG_L	sp, SC_REGS+11*REGSZ(a0)
 | 
						REG_L	sp, SC_REGS+11*REGSZ(a0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lw	v0, SC_FPSR(a0)
 | 
						lw	v0, SC_FPSR_OFFSET(a0)
 | 
				
			||||||
	ctc1	v0, $31
 | 
						ctc1	v0, $31			# restore old fr mode before fp values
 | 
				
			||||||
#ifdef __LP64__
 | 
					#ifdef __LP64__
 | 
				
			||||||
	# callee-saved fp regs on mips n64 ABI are $f24..$f31
 | 
						# callee-saved fp regs on mips n64 ABI are $f24..$f31
 | 
				
			||||||
	l.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
 | 
						l.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
 | 
				
			||||||
@@ -266,7 +333,7 @@ NON_LEAF(longjmp, FRAMESZ, ra)
 | 
				
			|||||||
	l.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
 | 
						l.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	# callee-saved fp regs on mips o32 ABI are
 | 
						# callee-saved fp regs on mips o32 ABI are
 | 
				
			||||||
	#   the even-numbered fp regs $f20,$f22,...$f30
 | 
						#   the even-numbered double fp regs $f20,$f22,...$f30
 | 
				
			||||||
	l.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
 | 
						l.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
 | 
				
			||||||
	l.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
 | 
						l.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
 | 
				
			||||||
	l.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
 | 
						l.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
 | 
				
			||||||
@@ -278,192 +345,19 @@ NON_LEAF(longjmp, FRAMESZ, ra)
 | 
				
			|||||||
	li	a1, 1			# never return 0!
 | 
						li	a1, 1			# never return 0!
 | 
				
			||||||
1:
 | 
					1:
 | 
				
			||||||
	move	v0, a1
 | 
						move	v0, a1
 | 
				
			||||||
	j	ra
 | 
						j	ra			# return to setjmp call site
 | 
				
			||||||
 | 
					
 | 
				
			||||||
longjmp_botch:
 | 
					longjmp_botch:
 | 
				
			||||||
	jal	longjmperror
 | 
						jal	longjmperror
 | 
				
			||||||
	jal	abort
 | 
						jal	abort
 | 
				
			||||||
	RESTORE_GP64
 | 
					 | 
				
			||||||
	PTR_ADDU sp, FRAMESZ
 | 
					 | 
				
			||||||
END(longjmp)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * _setjmp, _longjmp (not restoring signal state)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *  GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FRAMESZ= MKFSIZ(0,4)
 | 
					 | 
				
			||||||
GPOFF= FRAMESZ-2*REGSZ
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LEAF(_setjmp, FRAMESZ)
 | 
					 | 
				
			||||||
	PTR_SUBU sp, FRAMESZ
 | 
					 | 
				
			||||||
	SETUP_GP64(GPOFF, _setjmp)
 | 
					 | 
				
			||||||
	SAVE_GP(GPOFF)
 | 
					 | 
				
			||||||
	.set	reorder
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __LP64__
 | 
					 | 
				
			||||||
	addiu   a0, 7				# roundup jmpbuf addr to 8-byte boundary
 | 
					 | 
				
			||||||
	li      t0, ~7
 | 
					 | 
				
			||||||
	and     a0, t0
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# SC_MASK is unused here
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	li	v0, 0xACEDBADE			# sigcontext magic number
 | 
					 | 
				
			||||||
	sw	v0, SC_MAGIC(a0)
 | 
					 | 
				
			||||||
	# callee-saved long-sized regs:
 | 
					 | 
				
			||||||
	REG_S	ra, SC_REGS+0*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s0, SC_REGS+1*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s1, SC_REGS+2*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s2, SC_REGS+3*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s3, SC_REGS+4*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s4, SC_REGS+5*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s5, SC_REGS+6*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s6, SC_REGS+7*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s7, SC_REGS+8*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_S	s8, SC_REGS+9*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	v0, GPOFF(sp)
 | 
					 | 
				
			||||||
	REG_S	v0, SC_REGS+10*REGSZ(a0)
 | 
					 | 
				
			||||||
	PTR_ADDU v0, sp, FRAMESZ
 | 
					 | 
				
			||||||
	REG_S	v0, SC_REGS+11*REGSZ(a0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cfc1	v0, $31
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __LP64__
 | 
					 | 
				
			||||||
	# callee-saved fp regs on mips n64 ABI are $f24..$f31
 | 
					 | 
				
			||||||
	s.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f25, SC_FPREGS+1*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f26, SC_FPREGS+2*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f27, SC_FPREGS+3*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f29, SC_FPREGS+5*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f30, SC_FPREGS+6*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	# callee-saved fp regs on mips o32 ABI are
 | 
					 | 
				
			||||||
	#   the even-numbered fp regs $f20,$f22,...$f30
 | 
					 | 
				
			||||||
	s.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f26, SC_FPREGS+3*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	s.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	sw	v0, SC_FPSR(a0)
 | 
					 | 
				
			||||||
	move	v0, zero
 | 
					 | 
				
			||||||
	RESTORE_GP64
 | 
					 | 
				
			||||||
	PTR_ADDU sp, FRAMESZ
 | 
					 | 
				
			||||||
	j	ra
 | 
					 | 
				
			||||||
END(_setjmp)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LEAF(_longjmp, FRAMESZ)
 | 
					 | 
				
			||||||
	PTR_SUBU sp, FRAMESZ
 | 
					 | 
				
			||||||
	SETUP_GP64(GPOFF, _longjmp)
 | 
					 | 
				
			||||||
	SAVE_GP(GPOFF)
 | 
					 | 
				
			||||||
	.set	reorder
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __LP64__
 | 
					 | 
				
			||||||
	addiu	a0, 7				# roundup jmpbuf addr to 8-byte boundary
 | 
					 | 
				
			||||||
	li      t0, ~7
 | 
					 | 
				
			||||||
	and	a0, t0
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# SC_MASK is unused here
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lw	v0, SC_MAGIC(a0)
 | 
					 | 
				
			||||||
	li	t0, 0xACEDBADE
 | 
					 | 
				
			||||||
	bne	v0, t0, _longjmp_botch			# jump if error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# callee-saved long-sized regs:
 | 
					 | 
				
			||||||
	REG_L	ra, SC_REGS+0*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s0, SC_REGS+1*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s1, SC_REGS+2*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s2, SC_REGS+3*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s3, SC_REGS+4*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s4, SC_REGS+5*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s5, SC_REGS+6*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s6, SC_REGS+7*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s7, SC_REGS+8*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	s8, SC_REGS+9*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	gp, SC_REGS+10*REGSZ(a0)
 | 
					 | 
				
			||||||
	REG_L	sp, SC_REGS+11*REGSZ(a0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lw	v0, SC_FPSR(a0)
 | 
					 | 
				
			||||||
	ctc1	v0, $31
 | 
					 | 
				
			||||||
#ifdef __LP64__
 | 
					 | 
				
			||||||
	# callee-saved fp regs on mips n64 ABI are $f24..$f31
 | 
					 | 
				
			||||||
	l.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f25, SC_FPREGS+1*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f26, SC_FPREGS+2*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f27, SC_FPREGS+3*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f29, SC_FPREGS+5*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f30, SC_FPREGS+6*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	# callee-saved fp regs on mips o32 ABI are
 | 
					 | 
				
			||||||
	#   the even-numbered fp regs $f20,$f22,...$f30
 | 
					 | 
				
			||||||
	l.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f26, SC_FPREGS+3*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
	l.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	bne	a1, zero, 1f
 | 
					 | 
				
			||||||
	li	a1, 1			# never return 0!
 | 
					 | 
				
			||||||
1:
 | 
					 | 
				
			||||||
	move	v0, a1
 | 
					 | 
				
			||||||
	j	ra
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_longjmp_botch:
 | 
					 | 
				
			||||||
	jal	longjmperror
 | 
					 | 
				
			||||||
	jal	abort
 | 
					 | 
				
			||||||
	RESTORE_GP64
 | 
					 | 
				
			||||||
	PTR_ADDU sp, FRAMESZ
 | 
					 | 
				
			||||||
END(_longjmp)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * trampolines for sigsetjmp and  siglongjmp save and restore mask.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
FRAMESZ= MKFSIZ(1,1)
 | 
					 | 
				
			||||||
GPOFF= FRAMESZ-2*REGSZ
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LEAF(sigsetjmp, FRAMESZ)
 | 
					 | 
				
			||||||
	PTR_SUBU sp, FRAMESZ
 | 
					 | 
				
			||||||
	SETUP_GP64(GPOFF, sigsetjmp)
 | 
					 | 
				
			||||||
	.set	reorder
 | 
					 | 
				
			||||||
	sw	a1, _JBLEN*REGSZ(a0)		# save "savemask"
 | 
					 | 
				
			||||||
	bne	a1, 0x0, 1f			# do saving of signal mask?
 | 
					 | 
				
			||||||
	LA	t9, _setjmp
 | 
					 | 
				
			||||||
	RESTORE_GP64
 | 
					 | 
				
			||||||
	PTR_ADDU sp, FRAMESZ
 | 
					 | 
				
			||||||
	jr t9
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1:	LA	t9, setjmp
 | 
					 | 
				
			||||||
	RESTORE_GP64
 | 
					 | 
				
			||||||
	PTR_ADDU sp, FRAMESZ
 | 
					 | 
				
			||||||
	jr t9
 | 
					 | 
				
			||||||
END(sigsetjmp)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LEAF(siglongjmp, FRAMESZ)
 | 
					 | 
				
			||||||
	PTR_SUBU sp, FRAMESZ
 | 
					 | 
				
			||||||
	SETUP_GP64(GPOFF, siglongjmp)
 | 
					 | 
				
			||||||
	.set	reorder
 | 
					 | 
				
			||||||
	lw	t0, _JBLEN*REGSZ(a0)		# get "savemask"
 | 
					 | 
				
			||||||
	bne	t0, 0x0, 1f			# restore signal mask?
 | 
					 | 
				
			||||||
	LA	t9, _longjmp
 | 
					 | 
				
			||||||
	RESTORE_GP64
 | 
					 | 
				
			||||||
	PTR_ADDU sp, FRAMESZ
 | 
					 | 
				
			||||||
	jr	t9
 | 
					 | 
				
			||||||
1:
 | 
					 | 
				
			||||||
	LA	t9, longjmp
 | 
					 | 
				
			||||||
	RESTORE_GP64
 | 
					 | 
				
			||||||
	PTR_ADDU sp, FRAMESZ
 | 
					 | 
				
			||||||
	jr	t9
 | 
					 | 
				
			||||||
END(siglongjmp)
 | 
					END(siglongjmp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.globl	longjmp
 | 
				
			||||||
 | 
						.type	longjmp, @function
 | 
				
			||||||
 | 
						.equ	longjmp, siglongjmp	# alias for siglongjmp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.globl	_longjmp
 | 
				
			||||||
 | 
						.type	_longjmp, @function
 | 
				
			||||||
 | 
						.equ	_longjmp, siglongjmp	# alias for siglongjmp
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,9 +6,10 @@
 | 
				
			|||||||
#define _MIPS_SETJMP_H_
 | 
					#define _MIPS_SETJMP_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __LP64__
 | 
					#ifdef __LP64__
 | 
				
			||||||
#define	_JBLEN	22		/* size, in 8-byte longs, of a mips64 jmp_buf */
 | 
					#define	_JBLEN	25	/* size, in 8-byte longs, of a mips64 jmp_buf/sigjmp_buf */
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define	_JBLEN	29		/* size, in 4-byte longs, of a mips32 jmp_buf */
 | 
					#define	_JBLEN	157	/* historical size, in 4-byte longs, of a mips32 jmp_buf */
 | 
				
			||||||
 | 
								/* actual used size is 34 */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !_MIPS_SETJMP_H_ */
 | 
					#endif /* !_MIPS_SETJMP_H_ */
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user