Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 5 Jan 2003 03:33:36 +0100
From:      Thomas Moestl <tmm@FreeBSD.org>
To:        freebsd-sparc@FreeBSD.org
Subject:   (hopefully) working libc_r for sparc64
Message-ID:  <20030105023336.GD279@crow.dom2ip.de>

next in thread | raw e-mail | index | archive | help

--TakKZr9L6Hm6aLOc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

I think I got libc_r working, after rewriting longjmp() and friends so
that they do not require the corresponding setjmp() to be done in an
ancestor function in the call graph any more, i.e. it can be used to
switch stacks now. This might also get other threading packages to
work, e.g. ruby's integrated thread manager.

I've attached a diff that contains these changes, and also patches to
libc_r to add the necessary MD code. The latter are based on diffs
that des posted to this list some time ago.
To apply this, you will need to do a 'mkdir libc_r/arch/sparc64' in
your src directory before.

It would be nice if people could test these changes a bit, both with
applications that make extensive use of the *jmp() functions and with
libc_r-using programs. Please be aware however that by installing an
experimental libc you might hose your system (although things seem to
work fine for me).

	- Thomas

-- 
Thomas Moestl <tmoestl@gmx.net>	http://www.tu-bs.de/~y0015675/
              <tmm@FreeBSD.org>	http://people.FreeBSD.org/~tmm/
PGP fingerprint: 1C97 A604 2BD0 E492 51D0  9C0F 1FE6 4F1D 419C 776C

--TakKZr9L6Hm6aLOc
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="pthread.diff"
Content-Transfer-Encoding: 8bit

Index: Makefile
===================================================================
RCS file: /ncvs/src/lib/Makefile,v
retrieving revision 1.145
diff -u -r1.145 Makefile
--- Makefile	4 Oct 2002 13:40:39 -0000	1.145
+++ Makefile	5 Jan 2003 01:56:45 -0000
@@ -40,7 +40,7 @@
 _csu=csu
 .endif
 
-.if !defined(NOLIBC_R) && ${MACHINE_ARCH} != ia64 && ${MACHINE_ARCH} != sparc64
+.if !defined(NOLIBC_R) && ${MACHINE_ARCH} != ia64
 _libc_r=	libc_r
 .endif
 
Index: libc/sparc64/gen/_setjmp.S
===================================================================
RCS file: /ncvs/src/lib/libc/sparc64/gen/_setjmp.S,v
retrieving revision 1.4
diff -u -r1.4 _setjmp.S
--- libc/sparc64/gen/_setjmp.S	29 Jun 2002 03:23:51 -0000	1.4
+++ libc/sparc64/gen/_setjmp.S	5 Jan 2003 00:52:21 -0000
@@ -58,42 +58,26 @@
  * will generate a "return(v?v:1)" from
  * the last call to
  *	_setjmp(a)
- * by unwinding the call stack.
+ * by restoring the previous context.
  * The previous signal state is NOT restored.
  */
 
 ENTRY(_setjmp)
 	stx	%sp, [%o0 + _JB_SP]
 	stx	%o7, [%o0 + _JB_PC]
-	stx	%fp, [%o0 + _JB_FP]
 	retl
 	 clr	%o0
 END(_setjmp)
 
-ENTRY(_longjmp)
-	mov	1, %g1
-	movrnz	%o1, %o1, %g1			! compute v ? v : 1
-	mov	%o0, %g2
-	ldx	[%g2 + _JB_FP], %g3		! fetch callers frame
-1:	cmp	%fp, %g3			! compare against desired frame
-	bl,a	1b				! if below,
-	 restore				!    pop frame and loop
-	be,a	2f				! if there,
-	 ldx	[%g2 + _JB_SP], %o0		!    fetch return %sp
-
-.Lbotch:
-	call	CNAME(longjmperror)
-	 nop
-	call	CNAME(abort)
-	 nop
-	illtrap
-
-2:	cmp	%o0, %sp			! %sp must not decrease
-	bge,a	3f
-	 mov	%o0, %sp			! it is OK, put it in place
-	b,a	.Lbotch
-	 nop
-3:	ldx	[%g2 + _JB_PC], %o7		! fetch return address
-	retl
-	 mov	%g1, %o0			! return v ? v : 1;
+	.weak	CNAME(_longjmp)
+	.set	CNAME(_longjmp),CNAME(___longjmp)
+ENTRY(___longjmp)
+	save	%sp, -CCFSZ, %sp
+	flushw
+	ldx	[%i0 + _JB_SP], %fp
+	ldx	[%i0 + _JB_PC], %i7
+	mov	1, %i0
+	movrnz	%i1, %i1, %i0
+	ret
+	 restore
 END(_longjmp)
Index: libc/sparc64/gen/setjmp.S
===================================================================
RCS file: /ncvs/src/lib/libc/sparc64/gen/setjmp.S,v
retrieving revision 1.3
diff -u -r1.3 setjmp.S
--- libc/sparc64/gen/setjmp.S	29 Jun 2002 03:23:51 -0000	1.3
+++ libc/sparc64/gen/setjmp.S	5 Jan 2003 00:45:56 -0000
@@ -70,7 +70,6 @@
 	restore
 	stx	%sp, [%o0 + _JB_SP]
 	stx	%o7, [%o0 + _JB_PC]
-	stx	%fp, [%o0 + _JB_FP]
 	retl
 	 clr	%o0
 END(setjmp)
@@ -79,34 +78,15 @@
 	.set	CNAME(longjmp),CNAME(__longjmp)
 ENTRY(__longjmp)
 	save	%sp, -CCFSZ, %sp
+	flushw
 	mov	SIG_SETMASK, %o0
 	add	%i0, _JB_SIGMASK, %o1
 	call	CNAME(sigprocmask)
 	 clr	%o2
-	restore
-	mov	1, %g1
-	movrnz	%o1, %o1, %g1
-	mov	%o0, %g2
-	ldx	[%g2 + _JB_FP], %g3
-1:	cmp	%fp, %g3
-	bl,a	1b
+	ldx	[%i0 + _JB_SP], %fp
+	ldx	[%i0 + _JB_PC], %i7
+	mov	1, %i0
+	movrnz	%i1, %i1, %i0
+	ret
 	 restore
-	be,a	2f
-	 ldx	[%g2 + _JB_SP], %o0
-
-.Lbotch:
-	call	CNAME(longjmperror)
-	 nop
-	call	CNAME(abort)
-	 nop
-	illtrap
-
-2:	cmp	%o0, %sp
-	bge,a	3f
-	 mov	%o0, %sp
-	b,a	.Lbotch
-	 nop
-3:	ldx	[%g2 + _JB_PC], %o7
-	retl
-	 mov	%g1, %o0
 END(__longjmp)
Index: libc/sparc64/gen/sigsetjmp.S
===================================================================
RCS file: /ncvs/src/lib/libc/sparc64/gen/sigsetjmp.S,v
retrieving revision 1.4
diff -u -r1.4 sigsetjmp.S
--- libc/sparc64/gen/sigsetjmp.S	29 Jun 2002 03:23:51 -0000	1.4
+++ libc/sparc64/gen/sigsetjmp.S	4 Jan 2003 21:16:29 -0000
@@ -43,7 +43,9 @@
 	 stx	%o1, [%o0 + _JB_SIGFLAG]
 END(sigsetjmp)
 
-ENTRY(siglongjmp)
+	.weak CNAME(siglongjmp);
+	.set CNAME(siglongjmp),CNAME(__siglongjmp);
+ENTRY(__siglongjmp)
 	PIC_PROLOGUE(%o3, %o2)
 	SET(CNAME(longjmp), %o2, %o3)
 	SET(CNAME(_longjmp), %o2, %o4)
@@ -51,4 +53,4 @@
 	movrnz	%o2, %o3, %o4
 	jmp	%o4
 	 nop
-END(siglongjmp)
+END(__siglongjmp)
Index: libc_r/uthread/pthread_private.h
===================================================================
RCS file: /ncvs/src/lib/libc_r/uthread/pthread_private.h,v
retrieving revision 1.76
diff -u -r1.76 pthread_private.h
--- libc_r/uthread/pthread_private.h	13 Nov 2002 18:13:26 -0000	1.76
+++ libc_r/uthread/pthread_private.h	5 Jan 2003 01:59:21 -0000
@@ -67,6 +67,7 @@
  * address in a jmp_buf context.
  *
  * XXX - These need to be moved into architecture dependent support files.
+ * XXX - These need to be documented so porters know what's required.
  */
 #if	defined(__i386__)
 #define	GET_STACK_JB(jb)	((unsigned long)((jb)[0]._jb[2]))
@@ -101,6 +102,34 @@
 	(jb)[0]._jb[R_RA + 4] = (long)(ra);		\
 	(jb)[0]._jb[R_T12 + 4] = (long)(ra);		\
 } while (0)
+#elif	defined(__sparc64__)
+#include <machine/frame.h>
+
+#define	CCFSZ	sizeof (struct frame)
+
+#define	GET_STACK_JB(jb)				\
+	((unsigned long)((jb)[0]._jb[_JB_SP]) + SPOFF)
+#define	GET_STACK_SJB(sjb)				\
+	((unsigned long)((sjb)[0]._sjb[_JB_SP]) + SPOFF)
+#define	GET_STACK_UC(ucp)				\
+	((ucp)->uc_mcontext.mc_sp + SPOFF)
+/*
+ * XXX: sparc64 _longjmp() expects a register window on the stack
+ * at the given position, so we must make sure that the space where
+ * it is expected is readable. Subtracting the frame size here works
+ * because the SET_STACK macros are only used to set up new stacks
+ * or signal stacks, but it is a bit dirty.
+ */
+#define	SET_STACK_JB(jb, stk)				\
+	(jb)[0]._jb[_JB_SP] = (long)(stk - SPOFF - CCFSZ)
+#define	SET_STACK_SJB(sjb, stk)				\
+	(sjb)[0]._sjb[_JB_SP] = (long)(stk - SPOFF - CCFSZ)
+#define	SET_STACK_UC(ucp, stk)				\
+	(ucp)->uc_mcontext.mc_sp = (unsigned long)(stk - SPOFF - CCFSZ)
+#define	FP_SAVE_UC(ucp)		/* XXX */
+#define	FP_RESTORE_UC(ucp)	/* XXX */
+#define SET_RETURN_ADDR_JB(jb, ra)			\
+	(jb)[0]._jb[_JB_PC] = (long)(ra - 8)
 #else
 #error "Don't recognize this architecture!"
 #endif
--- /dev/null	Sun Jan  5 03:00:01 2003
+++ libc_r/arch/sparc64/_atomic_lock.S	Sat Jan  4 21:46:19 2003
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2002 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <machine/asm.h>
+
+__FBSDID("$FreeBSD$");
+
+/*
+ * long _atomic_lock(long *)
+ *
+ * Atomically acquire a lock by storing a non-zero value in its
+ * location, provided it is not already locked.  Note that we only use
+ * the first byte of the location provided.
+ */
+ENTRY(_atomic_lock)
+	ldstub	[%o0], %o1
+	membar	#LoadLoad | #StoreStore
+	retl
+	 mov	%o1, %o0
+END(_atomic_lock)
Index: usr.sbin/Makefile
===================================================================
RCS file: /ncvs/src/usr.sbin/Makefile,v
retrieving revision 1.240
diff -u -r1.240 Makefile
--- usr.sbin/Makefile	30 Dec 2002 10:13:16 -0000	1.240
+++ usr.sbin/Makefile	5 Jan 2003 02:29:38 -0000
@@ -135,7 +135,7 @@
 	iptest
 .endif
 
-.if !defined(NOLIBC_R) && ${MACHINE_ARCH} != "ia64" && ${MACHINE_ARCH} != "sparc64"
+.if !defined(NOLIBC_R) && ${MACHINE_ARCH} != "ia64"
 SUBDIR+=pppctl
 .endif
 

--TakKZr9L6Hm6aLOc--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-sparc" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030105023336.GD279>