Fix offsets used in the assembly code to save global registers into a
jmp_buf, add a compile time assert to catch this kind of divergence in the C code. Move the fixed "%npc = %pc + 4" computation to longjmp, this frees the sigcontext sc_npc value. Use this space to save the savemask for siglongjmp (we have run out of space behind the globals). Fixes the tests/lib/libc/setjmp/t_threadjmp tests, and also hopefully fixes PR port-sparc64/44902.
This commit is contained in:
parent
fe857470e2
commit
d21307a5d2
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: longjmp.c,v 1.2 2008/04/28 20:22:57 martin Exp $ */
|
||||
/* $NetBSD: longjmp.c,v 1.3 2011/04/27 21:08:48 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -36,6 +36,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define __LIBC12_SOURCE__
|
||||
#include <setjmp.h>
|
||||
|
@ -45,6 +46,13 @@ typedef struct {
|
|||
__greg_t __glob[5];
|
||||
} __jmp_buf_regs_t;
|
||||
|
||||
/*
|
||||
* setjmp.S uses hard coded offsets into the jump_buf,
|
||||
* make sure any changes cause a compile failure here
|
||||
*/
|
||||
__CTASSERT(0x68 == offsetof(__jmp_buf_regs_t,__glob[4])+
|
||||
sizeof(struct sigcontext));
|
||||
|
||||
void
|
||||
__longjmp14(jmp_buf env, int val)
|
||||
{
|
||||
|
@ -72,7 +80,7 @@ __longjmp14(jmp_buf env, int val)
|
|||
/* Fill other registers */
|
||||
uc.uc_mcontext.__gregs[_REG_CCR] = sc->sc_tstate;
|
||||
uc.uc_mcontext.__gregs[_REG_PC] = sc->sc_pc;
|
||||
uc.uc_mcontext.__gregs[_REG_nPC] = sc->sc_npc;
|
||||
uc.uc_mcontext.__gregs[_REG_nPC] = sc->sc_pc+4;
|
||||
uc.uc_mcontext.__gregs[_REG_G1] = sc->sc_g1;
|
||||
uc.uc_mcontext.__gregs[_REG_G2] = sc->sc_o0;
|
||||
uc.uc_mcontext.__gregs[_REG_G3] = r->__glob[0];
|
||||
|
@ -82,6 +90,7 @@ __longjmp14(jmp_buf env, int val)
|
|||
uc.uc_mcontext.__gregs[_REG_G7] = r->__glob[4];
|
||||
uc.uc_mcontext.__gregs[_REG_O6] = sc->sc_sp;
|
||||
|
||||
|
||||
/* Make return value non-zero */
|
||||
if (val == 0)
|
||||
val = 1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: setjmp.S,v 1.7 2005/10/16 17:15:38 christos Exp $ */
|
||||
/* $NetBSD: setjmp.S,v 1.8 2011/04/27 21:08:48 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
.asciz "@(#)setjmp.s 8.1 (Berkeley) 6/4/93"
|
||||
#else
|
||||
RCSID("$NetBSD: setjmp.S,v 1.7 2005/10/16 17:15:38 christos Exp $")
|
||||
RCSID("$NetBSD: setjmp.S,v 1.8 2011/04/27 21:08:48 martin Exp $")
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -118,19 +118,17 @@ ENTRY(__setjmp14)
|
|||
stx %fp, [%i0 + 0x08] /* sc.sc_sp = sp */
|
||||
add %i7, 8, %o0
|
||||
stx %o0, [%i0 + 0x10] /* sc.sc_pc = return_pc */
|
||||
add %i7, 12, %o0
|
||||
stx %o0, [%i0 + 0x18] /* sc.sc_npc = return_pc + 4 */
|
||||
stx %g0, [%i0 + 0x20] /* sc.sc_tstate = (clean ccr) */
|
||||
stx %l1, [%i0 + 0x28] /* sc.sc_g1 */
|
||||
stx %l2, [%i0 + 0x30] /* sc.sc_o0, set in longjmp, use as %g2 */
|
||||
/* 0x38 */ /* sc.sc_mask was already saved above */
|
||||
/* 0x38: 4x32bit */ /* sc.sc_mask was already saved above */
|
||||
|
||||
/* save additional registers needed to fill a complete mcontext */
|
||||
stx %l3, [%i0 + 0x40]
|
||||
stx %l4, [%i0 + 0x48]
|
||||
stx %l5, [%i0 + 0x50]
|
||||
stx %l6, [%i0 + 0x58]
|
||||
stx %l7, [%i0 + 0x60]
|
||||
stx %l3, [%i0 + 0x48]
|
||||
stx %l4, [%i0 + 0x50] /* adjust asserts in longjmp.c */
|
||||
stx %l5, [%i0 + 0x58] /* if you change any of these */
|
||||
stx %l6, [%i0 + 0x60] /* offsets! */
|
||||
stx %l7, [%i0 + 0x68]
|
||||
|
||||
ret /* return 0 */
|
||||
restore %g0, 0, %o0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sigsetjmp.S,v 1.8 2005/10/16 17:15:38 christos Exp $ */
|
||||
/* $NetBSD: sigsetjmp.S,v 1.9 2011/04/27 21:08:48 martin Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Paul Kranenburg
|
||||
* All rights reserved.
|
||||
|
@ -32,12 +32,17 @@
|
|||
|
||||
#include "SYS.h"
|
||||
|
||||
/*
|
||||
* We use the sc_npc field inside the sigcontext to store the save mask
|
||||
*/
|
||||
#define MASK_OFFSET 0x18
|
||||
|
||||
#ifdef PIC
|
||||
#ifdef BIGPIC
|
||||
|
||||
ENTRY(__sigsetjmp14)
|
||||
PIC_PROLOGUE(%g1,%o2) ! %g1 = _GLOBAL_OFFSET_TABLE
|
||||
st %o1,[%o0+0x68] ! jmpbuf[JBLEN]
|
||||
st %o1,[%o0+MASK_OFFSET] ! jmp_buf.sc.sc_npc
|
||||
sethi %hi(_C_LABEL(__setjmp14)), %o2
|
||||
sethi %hi(_C_LABEL(_setjmp)), %o3
|
||||
or %o2, %lo(_C_LABEL(__setjmp14)), %o2
|
||||
|
@ -51,7 +56,7 @@ ENTRY(__sigsetjmp14)
|
|||
|
||||
ENTRY(__siglongjmp14)
|
||||
PIC_PROLOGUE(%g1,%o2) ! %g1 = _GLOBAL_OFFSET_TABLE
|
||||
ld [%o0+0x68], %o2 ! jmpbuf[JBLEN]
|
||||
ld [%o0+MASK_OFFSET], %o2 ! jmp_buf.sc.sc_npc
|
||||
sethi %hi(_C_LABEL(__longjmp14)), %o3
|
||||
sethi %hi(_C_LABEL(_longjmp)), %o4
|
||||
or %o3, %lo(_C_LABEL(__longjmp14)), %o3
|
||||
|
@ -68,7 +73,7 @@ ENTRY(__siglongjmp14)
|
|||
ENTRY(__sigsetjmp14)
|
||||
PIC_PROLOGUE(%g1,%o2) ! %g1 = _GLOBAL_OFFSET_TABLE
|
||||
cmp %o1,0
|
||||
st %o1,[%o0+0x68] ! jmpbuf[JBLEN]
|
||||
st %o1,[%o0+MASK_OFFSET] ! jmp_buf.sc.sc_npc
|
||||
bne,a 1f
|
||||
ldx [%g1+_C_LABEL(__setjmp14)], %g1 ! if (%o1 != 0) goto __setjmp;
|
||||
ldx [%g1+_C_LABEL(_setjmp)], %g1 ! else goto _setjmp;
|
||||
|
@ -78,7 +83,7 @@ ENTRY(__sigsetjmp14)
|
|||
|
||||
ENTRY(__siglongjmp14)
|
||||
PIC_PROLOGUE(%g1,%o2) ! %g1 = _GLOBAL_OFFSET_TABLE
|
||||
ld [%o0+0x68],%o2 ! jmpbuf[JBLEN]
|
||||
ld [%o0+MASK_OFFSET],%o2 ! jmp_buf.sc.sc_npc
|
||||
cmp %o2,0
|
||||
bne,a 1f
|
||||
ldx [%g1+_C_LABEL(__longjmp14)], %g1 ! if (%o2 != 0) goto __longjmp;
|
||||
|
@ -93,12 +98,12 @@ ENTRY(__siglongjmp14)
|
|||
ENTRY(__sigsetjmp14)
|
||||
cmp %o1,0
|
||||
be _C_LABEL(_setjmp)
|
||||
st %o1,[%o0+0x68] ! jmpbuf[JBLEN]
|
||||
st %o1,[%o0+MASK_OFFSET] ! jmp_buf.sc.sc_npc
|
||||
ba,a _C_LABEL(__setjmp14)
|
||||
unimp 0
|
||||
|
||||
ENTRY(__siglongjmp14)
|
||||
ld [%o0+0x68],%g1
|
||||
ld [%o0+MASK_OFFSET],%g1
|
||||
cmp %g1,0
|
||||
be _C_LABEL(_longjmp)
|
||||
nop
|
||||
|
|
Loading…
Reference in New Issue