Module Name:    src
Committed By:   martin
Date:           Wed Apr 27 21:08:48 UTC 2011

Modified Files:
        src/lib/libc/arch/sparc64/gen: longjmp.c setjmp.S sigsetjmp.S

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/lib/libc/arch/sparc64/gen/longjmp.c
cvs rdiff -u -r1.7 -r1.8 src/lib/libc/arch/sparc64/gen/setjmp.S
cvs rdiff -u -r1.8 -r1.9 src/lib/libc/arch/sparc64/gen/sigsetjmp.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/arch/sparc64/gen/longjmp.c
diff -u src/lib/libc/arch/sparc64/gen/longjmp.c:1.2 src/lib/libc/arch/sparc64/gen/longjmp.c:1.3
--- src/lib/libc/arch/sparc64/gen/longjmp.c:1.2	Mon Apr 28 20:22:57 2008
+++ src/lib/libc/arch/sparc64/gen/longjmp.c	Wed Apr 27 21:08:48 2011
@@ -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 @@
 	__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 @@
 	/* 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 @@
 	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;

Index: src/lib/libc/arch/sparc64/gen/setjmp.S
diff -u src/lib/libc/arch/sparc64/gen/setjmp.S:1.7 src/lib/libc/arch/sparc64/gen/setjmp.S:1.8
--- src/lib/libc/arch/sparc64/gen/setjmp.S:1.7	Sun Oct 16 17:15:38 2005
+++ src/lib/libc/arch/sparc64/gen/setjmp.S	Wed Apr 27 21:08:48 2011
@@ -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 @@
 	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

Index: src/lib/libc/arch/sparc64/gen/sigsetjmp.S
diff -u src/lib/libc/arch/sparc64/gen/sigsetjmp.S:1.8 src/lib/libc/arch/sparc64/gen/sigsetjmp.S:1.9
--- src/lib/libc/arch/sparc64/gen/sigsetjmp.S:1.8	Sun Oct 16 17:15:38 2005
+++ src/lib/libc/arch/sparc64/gen/sigsetjmp.S	Wed Apr 27 21:08:48 2011
@@ -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(__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(__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(__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(__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

Reply via email to