Subject: Re: compiling sparc fails...
To: None <port-sparc@netbsd.org>
From: Valeriy E. Ushakov <uwe@stderr.spb.ru>
List: port-sparc
Date: 10/08/2007 04:03:08
--z6Eq5LdranGa6ru8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sun, Oct 07, 2007 at 23:11:54 +0400, Valeriy E. Ushakov wrote:
> Date: Sun, 7 Oct 2007 23:11:54 +0400
> From: "Valeriy E. Ushakov" <uwe@stderr.spb.ru>
> To: current-users@netbsd.org
> Cc: port-sparc@netbsd.org
> Subject: Re: compiling sparc fails...
> Mail-Followup-To: current-users@netbsd.org, port-sparc@netbsd.org
> 
> On Sun, Oct 07, 2007 at 14:49:32 +0200, Kurt Schreiner wrote:
> 
> >       build  libc/libc.so.12.153
> > libc_pic.a(__clone.so): In function `__clone':
> > /u/NetBSD/src/lib/libc/arch/sparc/sys/__clone.S:(.text+0x60): relocation truncated to fit: R_SPARC_GOT13 against symbol `_exit' defined in .text section in libc_pic.a(_exit.so)
> > libc_pic.a(sigsetjmp.so): In function `__sigsetjmp14':
> > /u/NetBSD/src/lib/libc/arch/sparc/gen/sigsetjmp.S:(.text+0x2c): relocation truncated to fit: R_SPARC_GOT13 against symbol `_setjmp' defined in .text section in libc_pic.a(_setjmp.so)
> > libc_pic.a(compat_sigsetjmp.so): In function `sigsetjmp':
> > /u/NetBSD/src/lib/libc/compat/arch/sparc/gen/compat_sigsetjmp.S:(.text+0x2c): relocation truncated to fit: R_SPARC_GOT13 against symbol `_setjmp' defined in .text section in libc_pic.a(_setjmp.so)
> > collect2: ld returned 1 exit status
> 
> I guess we are now overflowing GOT and GOT13 reloc is no longer enough
> to reach some of the elements.  I think the asm code that triggers
> this shall be rewritten.  By the looks of it, it tries to be clever
> and use jump for a tail call but plain "call" is much faster, doesn't
> require setup, doesn't have offset limitations and ifdef PIC can go
> away.

Attached patch makes sparc libc compile but I cannot easily test it at
the moment.

It converts handwritten asm from -fpic code to -fPIC code.  While
there I've also killed redundant PIC ifdefs in setjmp.S - sparc call
instruction is piccy by itself (asm generates either R_SPARC_WDISP30
or R_SPARC_WPLT30 relocs for calls depending on -KPIC automatically).

Does someone have currentish current handy and can test this patch
easily? (running setjmp regression tests is a bonus :)

SY, Uwe
-- 
uwe@stderr.spb.ru                       |       Zu Grunde kommen
http://snark.ptc.spbu.ru/~uwe/          |       Ist zu Grunde gehen

--z6Eq5LdranGa6ru8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="libc-asm-fPIC.diff"

Index: arch/sparc/SYS.h
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/SYS.h,v
retrieving revision 1.16
diff -u -r1.16 SYS.h
--- arch/sparc/SYS.h	20 May 2005 23:56:15 -0000	1.16
+++ arch/sparc/SYS.h	7 Oct 2007 23:41:50 -0000
@@ -60,7 +60,8 @@
 #ifdef PIC
 #define CALL(name)				\
 	PIC_PROLOGUE(%g1, %g2);			\
-	ld	[%g1 + name], %g2;		\
+	set	name, %g2;			\
+	ld	[%g1 + %g2], %g2;		\
 	jmp	%g2;				\
 	 nop
 #else
Index: arch/sparc/gen/setjmp.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/gen/setjmp.S,v
retrieving revision 1.10
diff -u -r1.10 setjmp.S
--- arch/sparc/gen/setjmp.S	28 Dec 2006 10:02:43 -0000	1.10
+++ arch/sparc/gen/setjmp.S	7 Oct 2007 23:41:50 -0000
@@ -59,34 +59,17 @@
 
 ENTRY(__setjmp14)
 	save	%sp, -CCFSZ, %sp
-#ifdef PIC
-	PIC_PROLOGUE(%l0,%o0)	! %l0 = _GLOBAL_OFFSET_TABLE
-#endif
 	/*
 	 * local vars on stack: struct sigstack foo @ offset 0x48
 	 * Note: sc_g1 is not used; sc_o0 is set in longjmp()
 	 */
-#ifdef PIC
-	ld	[%l0 + _C_LABEL(__sigprocmask14)], %g2
-#endif
 	mov	1, %o0		/* SIG_BLOCK */
 	add	%i0, 32, %o2	/* build sigcontext sc.sc_mask */
-#ifdef PIC
-	call	%g2
-#else
 	call	_C_LABEL(__sigprocmask14)
-#endif
 	 clr	%o1		/* sigprocmask(SIG_BLOCK, NULL, &sc.sc_mask) */
 
-#ifdef PIC
-	ld	[%l0 + _C_LABEL(__sigaltstack14)], %g2
-#endif
 	add	%sp, 0x48, %o1	/* (foo being in arg dump area) */
-#ifdef PIC
-	call	%g2
-#else
 	call	_C_LABEL(__sigaltstack14)
-#endif
 	 clr	%o0		/* sigstack(NULL, &foo) */
 
 	ld	[%sp + 0x48 + 8], %o0	/* foo.ss_flags */
Index: arch/sparc/gen/sigsetjmp.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/gen/sigsetjmp.S,v
retrieving revision 1.5
diff -u -r1.5 sigsetjmp.S
--- arch/sparc/gen/sigsetjmp.S	15 Oct 2005 22:11:22 -0000	1.5
+++ arch/sparc/gen/sigsetjmp.S	7 Oct 2007 23:41:50 -0000
@@ -35,29 +35,44 @@
 #ifdef PIC
 
 ENTRY(__sigsetjmp14)
-	PIC_PROLOGUE(%g1,%g2)	! %g1 = _GLOBAL_OFFSET_TABLE
-	cmp %o1,0
-	st %o1,[%o0+56]		! jmpbuf[JBLEN]
-	bne,a 1f
-	ld [%g1+_C_LABEL(__setjmp14)], %g1	! if (%o1 != 0) goto __setjmp14;
-	ld [%g1+_C_LABEL(_setjmp)], %g1	! else goto __setjmp;
-1:
+	PIC_PROLOGUE(%g1, %g2)		! %g1 = _GLOBAL_OFFSET_TABLE
+	tst	%o1
+	bnz	1f
+	 st	%o1, [%o0 + 56]		! jmpbuf[JBLEN] = savemask
+
+	!! if (savemask == 0) goto _setjmp
+	set	_C_LABEL(_setjmp), %g2
+	ld	[%g1 + %g2], %g1
 	jmp %g1
-	nop
+	 nop
+
+	!! if (savemask != 0) goto setjmp
+1:	set	_C_LABEL(__setjmp14), %g2
+	ld	[%g1 + %g2], %g1
+	jmp %g1
+	 nop
+
 
 ENTRY(__siglongjmp14)
-	PIC_PROLOGUE(%g1,%g2)	! %g1 = _GLOBAL_OFFSET_TABLE
-	ld [%o0+56],%g2		! jmpbuf[JBLEN]
-	cmp %g2,0
-	bne,a 1f
-	ld [%g1+_C_LABEL(__longjmp14)], %g1	 ! if (%g2 != 0) goto __longjmp14;
-	ld [%g1+_C_LABEL(_longjmp)], %g1 ! else goto __longjmp;
-1:
+	PIC_PROLOGUE(%g1, %g2)		! %g1 = _GLOBAL_OFFSET_TABLE
+	ld	[%o0 + 56], %g2		! restoremask = jmpbuf[JBLEN]
+	tst	%g2
+	bnz	1f
+	 nop
+
+	!! if (restoremask == 0) goto _longjmp
+	set	_C_LABEL(_longjmp), %g2
+	ld	[%g1 + %g2], %g1
 	jmp %g1
-	nop
-	unimp 0
+	 nop
+
+	!! if (restoremask != 0) goto longjmp
+1:	set	_C_LABEL(__longjmp14), %g2
+	ld	[%g1 + %g2], %g1
+	jmp %g1
+	 nop
 
-#else /* PIC */
+#else /* !PIC */
 
 ENTRY(__sigsetjmp14)
 	cmp %o1,0
@@ -75,4 +90,4 @@
 	ba,a _C_LABEL(__longjmp14)
 	unimp 0
 
-#endif /* PIC */
+#endif /* !PIC */
Index: arch/sparc/sys/brk.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/sys/brk.S,v
retrieving revision 1.11
diff -u -r1.11 brk.S
--- arch/sparc/sys/brk.S	26 Dec 2003 11:21:48 -0000	1.11
+++ arch/sparc/sys/brk.S	7 Oct 2007 23:41:50 -0000
@@ -62,7 +62,8 @@
 ENTRY(_brk)
 #ifdef PIC
 	PIC_PROLOGUE(%o5,%o4)
-	ld	[%o5 + _C_LABEL(__minbrk)], %o4
+	set	_C_LABEL(__minbrk), %o4
+	ld	[%o5 + %o4], %o4
 	ld	[%o4], %o1		! %o1 = minbrk
 	cmp	%o1, %o0		! if (minbrk > %o0)
 	bgu,a	0f
Index: arch/sparc/sys/cerror.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/sys/cerror.S,v
retrieving revision 1.9
diff -u -r1.9 cerror.S
--- arch/sparc/sys/cerror.S	28 Dec 2006 10:02:43 -0000	1.9
+++ arch/sparc/sys/cerror.S	7 Oct 2007 23:41:50 -0000
@@ -59,7 +59,8 @@
 	.globl	_C_LABEL(errno)
 #ifdef PIC
 FUNC(CERROR)
-	ld	[%g1 + _C_LABEL(errno)], %g1
+	set	_C_LABEL(errno), %g2
+	ld	[%g1 + %g2], %g1
 	st	%o0, [%g1]
 	mov	-1, %o0
 	retl
Index: arch/sparc/sys/ptrace.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/sys/ptrace.S,v
retrieving revision 1.7
diff -u -r1.7 ptrace.S
--- arch/sparc/sys/ptrace.S	8 Jan 2006 20:03:19 -0000	1.7
+++ arch/sparc/sys/ptrace.S	7 Oct 2007 23:41:50 -0000
@@ -56,7 +56,8 @@
 #else
 #ifdef PIC
 	PIC_PROLOGUE(%g1,%g2)
-	ld	[%g1 + _C_LABEL(errno)], %g1
+	set	_C_LABEL(errno), %g2
+	ld	[%g1 + %g2], %g1
 	st	%g0, [%g1]
 #else
 	sethi	%hi(_C_LABEL(errno)), %g1
Index: arch/sparc/sys/sbrk.S
===================================================================
RCS file: /cvsroot/src/lib/libc/arch/sparc/sys/sbrk.S,v
retrieving revision 1.9
diff -u -r1.9 sbrk.S
--- arch/sparc/sys/sbrk.S	7 Aug 2003 16:42:26 -0000	1.9
+++ arch/sparc/sys/sbrk.S	7 Oct 2007 23:41:50 -0000
@@ -60,7 +60,8 @@
 ENTRY(_sbrk)
 #ifdef PIC
 	PIC_PROLOGUE(%o5,%o4)
-	ld	[%o5 + CURBRK], %o2
+	set	CURBRK, %o2
+	ld	[%o5 + %o2], %o2
 	ld	[%o2], %o3			! %o3 = old break
 	add	%o3, %o0, %o4			! %o4 = new break
 	mov	%o4, %o0			! copy for syscall
Index: compat/arch/sparc/gen/compat_sigsetjmp.S
===================================================================
RCS file: /cvsroot/src/lib/libc/compat/arch/sparc/gen/compat_sigsetjmp.S,v
retrieving revision 1.1
diff -u -r1.1 compat_sigsetjmp.S
--- compat/arch/sparc/gen/compat_sigsetjmp.S	15 Oct 2005 22:11:22 -0000	1.1
+++ compat/arch/sparc/gen/compat_sigsetjmp.S	7 Oct 2007 23:41:50 -0000
@@ -35,29 +35,44 @@
 #ifdef PIC
 
 ENTRY(sigsetjmp)
-	PIC_PROLOGUE(%g1,%g2)	! %g1 = _GLOBAL_OFFSET_TABLE
-	cmp %o1,0
-	st %o1,[%o0+40]		! jmpbuf[JBLEN]
-	bne,a 1f
-	ld [%g1+_C_LABEL(setjmp)], %g1	! if (%o1 != 0) goto _setjmp;
-	ld [%g1+_C_LABEL(_setjmp)], %g1	! else goto __setjmp;
-1:
+	PIC_PROLOGUE(%g1, %g2)		! %g1 = _GLOBAL_OFFSET_TABLE
+	tst	%o1
+	bnz	1f
+	 st	%o1, [%o0 + 56]		! jmpbuf[JBLEN] = savemask
+
+	!! if (savemask == 0) goto _setjmp
+	set	_C_LABEL(_setjmp), %g2
+	ld	[%g1 + %g2], %g1
 	jmp %g1
-	nop
+	 nop
+
+	!! if (savemask != 0) goto setjmp
+1:	set	_C_LABEL(setjmp), %g2
+	ld	[%g1 + %g2], %g1
+	jmp %g1
+	 nop
+
 
 ENTRY(siglongjmp)
-	PIC_PROLOGUE(%g1,%g2)	! %g1 = _GLOBAL_OFFSET_TABLE
-	ld [%o0+40],%g2		! jmpbuf[JBLEN]
-	cmp %g2,0
-	bne,a 1f
-	ld [%g1+_C_LABEL(longjmp)], %g1	 ! if (%g2 != 0) goto _longjmp;
-	ld [%g1+_C_LABEL(_longjmp)], %g1 ! else goto __longjmp;
-1:
+	PIC_PROLOGUE(%g1, %g2)		! %g1 = _GLOBAL_OFFSET_TABLE
+	ld	[%o0 + 56], %g2		! restoremask = jmpbuf[JBLEN]
+	tst	%g2
+	bnz	1f
+	 nop
+
+	!! if (restoremask == 0) goto _longjmp
+	set	_C_LABEL(_longjmp), %g2
+	ld	[%g1 + %g2], %g1
 	jmp %g1
-	nop
-	unimp 0
+	 nop
+
+	!! if (restoremask != 0) goto longjmp
+1:	set	_C_LABEL(longjmp), %g2
+	ld	[%g1 + %g2], %g1
+	jmp %g1
+	 nop
 
-#else /* PIC */
+#else /* !PIC */
 
 ENTRY(sigsetjmp)
 	cmp %o1,0
@@ -75,4 +90,4 @@
 	ba,a _C_LABEL(longjmp)
 	unimp 0
 
-#endif /* PIC */
+#endif /* !PIC */

--z6Eq5LdranGa6ru8--