Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/arch/sparc/gen Save a few global registers during s...
details: https://anonhg.NetBSD.org/src/rev/554699ab4925
branches: trunk
changeset: 764684:554699ab4925
user: martin <martin%NetBSD.org@localhost>
date: Sat Apr 30 23:41:12 2011 +0000
description:
Save a few global registers during set/longjmp - at least the application
registers and the only currently used system register (%g7).
Sparc now passes the setjmp tests (and should be able to build perl again).
diffstat:
lib/libc/arch/sparc/gen/_setjmp.S | 16 ++++++++++++++--
lib/libc/arch/sparc/gen/longjmp.c | 29 +++++++++++++++++++++++++----
lib/libc/arch/sparc/gen/setjmp.S | 10 ++++++----
3 files changed, 45 insertions(+), 10 deletions(-)
diffs (145 lines):
diff -r 30ab083892c3 -r 554699ab4925 lib/libc/arch/sparc/gen/_setjmp.S
--- a/lib/libc/arch/sparc/gen/_setjmp.S Sat Apr 30 23:39:08 2011 +0000
+++ b/lib/libc/arch/sparc/gen/_setjmp.S Sat Apr 30 23:41:12 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: _setjmp.S,v 1.8 2008/04/28 20:22:57 martin Exp $ */
+/* $NetBSD: _setjmp.S,v 1.9 2011/04/30 23:41:12 martin Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
#include <machine/trap.h>
#if defined(LIBC_SCCS) && !defined(lint)
-RCSID("$NetBSD: _setjmp.S,v 1.8 2008/04/28 20:22:57 martin Exp $")
+RCSID("$NetBSD: _setjmp.S,v 1.9 2011/04/30 23:41:12 martin Exp $")
#endif /* LIBC_SCCS and not lint */
/*
@@ -47,6 +47,12 @@
*/
ENTRY(_setjmp)
+ /* store important globals, sigsetjmp compatible */
+ st %g3, [%o0 + 16]
+ st %g2, [%o0 + 24]
+ st %g4, [%o0 + 48]
+ st %g7, [%o0 + 52]
+
st %sp, [%o0+0] /* store caller's stack pointer */
st %o7, [%o0+4] /* and the return pc */
retl
@@ -60,6 +66,12 @@
0:
t ST_FLUSHWIN ! flush register windows out to the stack
+ /* restore globals */
+ ld [%o0 + 16], %g3
+ ld [%o0 + 24], %g2
+ ld [%o0 + 48], %g4
+ ld [%o0 + 52], %g7
+
/*
* We restore the saved stack pointer to %fp, then issue
* a `restore' instruction which will reload the register
diff -r 30ab083892c3 -r 554699ab4925 lib/libc/arch/sparc/gen/longjmp.c
--- a/lib/libc/arch/sparc/gen/longjmp.c Sat Apr 30 23:39:08 2011 +0000
+++ b/lib/libc/arch/sparc/gen/longjmp.c Sat Apr 30 23:41:12 2011 +0000
@@ -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/30 23:41:12 martin Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -35,11 +35,27 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
+#include <stddef.h>
#define __LIBC12_SOURCE__
#include <setjmp.h>
#include <compat/include/setjmp.h>
+struct __jmp_buf_regs_t {
+ __greg_t g4;
+ __greg_t g7;
+ __greg_t save_mask;
+};
+
+/*
+ * setjmp.S uses hard coded offsets into the jump_buf,
+ * make sure any changes cause a compile failure here
+ */
+__CTASSERT(56 == offsetof(struct __jmp_buf_regs_t,save_mask) +
+ sizeof(struct sigcontext));
+__CTASSERT(sizeof(sigjmp_buf) >= sizeof(struct __jmp_buf_regs_t) +
+ sizeof(struct sigcontext));
+
/*
* Use setcontext to reload the stack pointer, program counter <pc,npc>, and
* set the return value in %o0. The %i and %l registers will be reloaded
@@ -49,14 +65,15 @@
__longjmp14(jmp_buf env, int val)
{
struct sigcontext *sc = (void *)env;
+ struct __jmp_buf_regs_t *r = (void*)&sc[1];
ucontext_t uc;
/* Ensure non-zero SP */
if (sc->sc_sp == 0)
goto err;
- /* Initialise the fields we're going to use */
- uc.uc_link = 0;
+ /* Initialise the context */
+ memset(&uc, 0, sizeof(uc));
/*
* Set _UC_{SET,CLR}STACK according to SS_ONSTACK.
@@ -71,8 +88,12 @@
/* Extract PSR, PC, NPC and SP from jmp_buf */
uc.uc_mcontext.__gregs[_REG_PSR] = sc->sc_psr;
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_O6] = sc->sc_sp;
+ uc.uc_mcontext.__gregs[_REG_G2] = sc->sc_g1;
+ uc.uc_mcontext.__gregs[_REG_G3] = sc->sc_npc;
+ uc.uc_mcontext.__gregs[_REG_G4] = r->g4;
+ uc.uc_mcontext.__gregs[_REG_G7] = r->g7;
/* Set the return value; make sure it's non-zero */
uc.uc_mcontext.__gregs[_REG_O0] = (val != 0 ? val : 1);
diff -r 30ab083892c3 -r 554699ab4925 lib/libc/arch/sparc/gen/setjmp.S
--- a/lib/libc/arch/sparc/gen/setjmp.S Sat Apr 30 23:39:08 2011 +0000
+++ b/lib/libc/arch/sparc/gen/setjmp.S Sat Apr 30 23:41:12 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: setjmp.S,v 1.11 2007/10/08 13:06:00 uwe Exp $ */
+/* $NetBSD: setjmp.S,v 1.12 2011/04/30 23:41:13 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -40,7 +40,7 @@
#if 0
.asciz "@(#)setjmp.s 8.1 (Berkeley) 6/4/93"
#else
- RCSID("$NetBSD: setjmp.S,v 1.11 2007/10/08 13:06:00 uwe Exp $")
+ RCSID("$NetBSD: setjmp.S,v 1.12 2011/04/30 23:41:13 martin Exp $")
#endif
#endif /* LIBC_SCCS and not lint */
@@ -78,9 +78,11 @@
st %fp, [%i0 + 8] /* sc.sc_sp = (caller's) sp */
add %i7, 8, %o0
st %o0, [%i0 + 12] /* sc.sc_pc = return_pc */
- add %i7, 12, %o0
- st %o0, [%i0 + 16] /* sc.sc_npc = return_pc + 4 */
+ st %g3, [%i0 + 16] /* sc.sc_npc */
st %g0, [%i0 + 20] /* sc.sc_psr = (clean psr) */
+ st %g2, [%i0 + 24]
+ st %g4, [%i0 + 48]
+ st %g7, [%i0 + 52]
ret /* return 0 */
restore %g0, %g0, %o0
Home |
Main Index |
Thread Index |
Old Index