about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2012-09-28 10:51:01 -0700
committerRichard Henderson <rth@twiddle.net>2012-09-28 10:51:01 -0700
commitc18b7473cb88e49d9f59ac2b1d2c68692202313d (patch)
treeb7730742be5192d423c275b972d44e49d413a484
parentb31606c0e1d9f04e2498b7c8262f7de87daa7ce7 (diff)
downloadglibc-c18b7473cb88e49d9f59ac2b1d2c68692202313d.tar.gz
glibc-c18b7473cb88e49d9f59ac2b1d2c68692202313d.tar.xz
glibc-c18b7473cb88e49d9f59ac2b1d2c68692202313d.zip
alpha: Fix all users of SYSCALL_ERROR_HANDLER
The fix begun in 64e65bc1 was incomplete.  Fixed by adding
a new SYSCALL_ERROR_FALLTHRU macro.
-rw-r--r--ports/ChangeLog.alpha19
-rw-r--r--ports/sysdeps/unix/alpha/sysdep.h35
-rw-r--r--ports/sysdeps/unix/sysv/linux/alpha/clone.S79
-rw-r--r--ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h12
-rw-r--r--ports/sysdeps/unix/sysv/linux/alpha/syscall.S11
5 files changed, 79 insertions, 77 deletions
diff --git a/ports/ChangeLog.alpha b/ports/ChangeLog.alpha
index ab807f7d47..672ab652c0 100644
--- a/ports/ChangeLog.alpha
+++ b/ports/ChangeLog.alpha
@@ -1,4 +1,21 @@
-2012-12-13  Richard Henderson  <rth@redhat.com>
+2012-09-28  Richard Henderson  <rth@redhat.com>
+
+	* sysdeps/unix/alpha/sysdep.h (PSEUDO_END): Merge versions and
+	move $syscall_error label...
+	(SYSCALL_ERROR_HANDLER): ... here.
+	(SYSCALL_ERROR_FALLTHRU): New.
+	(PSEUDO_PROF): Split out of ...
+	(PSEUDO_PROLOGUE): ... here.
+	* sysdeps/unix/sysv/linux/alpha/syscall.S (__syscall): Use
+	SYSCALL_ERROR_LABEL and PSEUDO_END.
+	* sysdeps/unix/sysv/linux/alpha/clone.S (__clone): Likewise.
+	Use USEPV_PROF and cfi markup.
+	(thread_start): Use cfi markup and cfi_undefined on ra.
+	* sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h
+	(PSEUDO_PROF): Remove.
+	(PSEUDO): Use SYSCALL_ERROR_FALLTHRU.
+
+2012-09-13  Richard Henderson  <rth@redhat.com>
 
 	* sysdeps/unix/sysv/linux/alpha/setfpucw.c (__setfpucw): Rewrite
 	with the assumption of being used at program startup only.
diff --git a/ports/sysdeps/unix/alpha/sysdep.h b/ports/sysdeps/unix/alpha/sysdep.h
index 4ee0746acc..75c06c9cfd 100644
--- a/ports/sysdeps/unix/alpha/sysdep.h
+++ b/ports/sysdeps/unix/alpha/sysdep.h
@@ -52,13 +52,20 @@
 #define END(sym)	.end sym
 
 #ifdef PROF
+# define PSEUDO_PROF				\
+	.set noat;				\
+	lda	AT, _mcount;			\
+	jsr	AT, (AT), _mcount;		\
+	.set at
+#else
+# define PSEUDO_PROF
+#endif
+
+#ifdef PROF
 # define PSEUDO_PROLOGUE			\
 	.frame sp, 0, ra;			\
 	ldgp	gp,0(pv);			\
-	.set noat;				\
-	lda	AT,_mcount;			\
-	jsr	AT,(AT),_mcount;		\
-	.set at;				\
+	PSEUDO_PROF;				\
 	.prologue 1
 #elif defined PIC
 # define PSEUDO_PROLOGUE			\
@@ -80,16 +87,21 @@
 #if RTLD_PRIVATE_ERRNO
 # define SYSCALL_ERROR_LABEL	$syscall_error
 # define SYSCALL_ERROR_HANDLER			\
+$syscall_error:					\
 	stl	v0, rtld_errno(gp)	!gprel;	\
 	lda	v0, -1;				\
 	ret
+# define SYSCALL_ERROR_FALLTHRU
 #elif defined(PIC)
-# define SYSCALL_ERROR_LABEL	__syscall_error !samegp
+# define SYSCALL_ERROR_LABEL		__syscall_error !samegp
 # define SYSCALL_ERROR_HANDLER
+# define SYSCALL_ERROR_FALLTHRU		br SYSCALL_ERROR_LABEL
 #else
-# define SYSCALL_ERROR_LABEL	$syscall_error
-# define SYSCALL_ERROR_HANDLER \
-	jmp	$31, __syscall_error
+# define SYSCALL_ERROR_LABEL		$syscall_error
+# define SYSCALL_ERROR_HANDLER			\
+$syscall_error:					\
+	jmp $31, __syscall_error
+# define SYSCALL_ERROR_FALLTHRU
 #endif /* RTLD_PRIVATE_ERRNO */
 
 /* Overridden by specific syscalls.  */
@@ -108,14 +120,9 @@ __LABEL(name)					\
 	bne	a3, SYSCALL_ERROR_LABEL
 
 #undef PSEUDO_END
-#if defined(PIC) && !RTLD_PRIVATE_ERRNO
-# define PSEUDO_END(sym)  END(sym)
-#else
-# define PSEUDO_END(sym)			\
-$syscall_error:					\
+#define PSEUDO_END(sym)				\
 	SYSCALL_ERROR_HANDLER;			\
 	END(sym)
-#endif
 
 #define PSEUDO_NOERRNO(name, syscall_name, args)	\
 	.globl name;					\
diff --git a/ports/sysdeps/unix/sysv/linux/alpha/clone.S b/ports/sysdeps/unix/sysv/linux/alpha/clone.S
index 1c6c8d6b7e..b92b6c2e79 100644
--- a/ports/sysdeps/unix/sysv/linux/alpha/clone.S
+++ b/ports/sysdeps/unix/sysv/linux/alpha/clone.S
@@ -35,89 +35,84 @@
    we don't bother checking FLAGS.  */
 
         .text
-ENTRY(__clone)
+	.align	4
+	.globl	__clone
+	.ent	__clone
+	.usepv	__clone, USEPV_PROF
+
+	cfi_startproc
+__clone:
 #ifdef PROF
 	ldgp	gp,0(pv)
-	.set noat
 	lda	AT, _mcount
 	jsr	AT, (AT), _mcount
-	.set at
-	.prologue 1
-#else
-	.prologue 0
 #endif
 
 	/* Sanity check arguments.  */
-	ldiq	v0,EINVAL
-	beq	a0,$error		/* no NULL function pointers */
-	beq	a1,$error		/* no NULL stack pointers */
+	ldiq	v0, EINVAL
+	beq	a0, SYSCALL_ERROR_LABEL	/* no NULL function pointers */
+	beq	a1, SYSCALL_ERROR_LABEL	/* no NULL stack pointers */
 
 	/* Save the fn ptr and arg on the new stack.  */
-	subq	a1,32,a1
-	stq	a0,0(a1)
-	stq	a3,8(a1)
+	subq	a1, 32, a1
+	stq	a0, 0(a1)
+	stq	a3, 8(a1)
 #ifdef RESET_PID
-	stq	a2,16(a1)
+	stq	a2, 16(a1)
 #endif
 
 	/* The syscall is of the form clone(flags, usp, ptid, ctid, tls).
 	   Shift the flags, ptid, ctid, tls arguments into place; the
 	   child_stack argument is already correct.  */
-	mov	a2,a0
-	mov	a4,a2
-	ldq	a3,0(sp)
-	mov	a5,a4
+	mov	a2, a0
+	mov	a4, a2
+	ldq	a3, 0(sp)
+	mov	a5, a4
 
 	/* Do the system call.  */
-	ldiq	v0,__NR_clone
+	ldiq	v0, __NR_clone
 	call_pal PAL_callsys
 
-	bne	a3,$error
-	beq	v0,thread_start
+	bne	a3, SYSCALL_ERROR_LABEL
+	beq	v0, thread_start
 
 	/* Successful return from the parent.  */
 	ret
 
-	/* Something bad happened -- no child created.  */
-$error:
-#ifndef PROF
-	br	gp,1f
-1:	ldgp	gp,0(gp)
-#endif
-	SYSCALL_ERROR_HANDLER
-
-	END(__clone)
+PSEUDO_END(__clone)
+	cfi_endproc
 
 /* Load up the arguments to the function.  Put this block of code in
    its own function so that we can terminate the stack trace with our
    debug info.  */
 
 	.ent thread_start
+	cfi_startproc
 thread_start:
-	.frame	fp,0,fp,0
 	mov	0, fp
-	.prologue 0
+	cfi_def_cfa_register(fp)
+	cfi_undefined(ra)
 
 #ifdef RESET_PID
 	/* Check and see if we need to reset the PID.  */
-	ldq	t0,16(sp)
-	lda	t1,CLONE_THREAD
-	and	t0,t1,t2
-	beq	t2,2f
+	ldq	t0, 16(sp)
+	lda	t1, CLONE_THREAD
+	and	t0, t1, t2
+	beq	t2, 2f
 1:
 #endif
 
 	/* Load up the arguments.  */
-	ldq	pv,0(sp)
-	ldq	a0,8(sp)
-	addq	sp,32,sp
+	ldq	pv, 0(sp)
+	ldq	a0, 8(sp)
+	addq	sp, 32, sp
 
 	/* Call the user's function.  */
-	jsr	ra,(pv)
-	ldgp	gp,0(ra)
+	jsr	ra, (pv)
+	ldgp	gp, 0(ra)
 
 	/* Call _exit rather than doing it inline for breakpoint purposes.  */
-	mov	v0,a0
+	mov	v0, a0
 #ifdef PIC
 	bsr	ra, HIDDEN_JUMPTARGET(_exit)	!samegp
 #else
@@ -142,7 +137,7 @@ thread_start:
 	stl	v0, TID_OFFSET(s0)
 	br	1b
 #endif
-
+	cfi_endproc
 	.end thread_start
 
 weak_alias (__clone, clone)
diff --git a/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h b/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h
index 04c7af472c..e6795d98f6 100644
--- a/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h
+++ b/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h
@@ -23,16 +23,6 @@
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
 
-# ifdef PROF
-#  define PSEUDO_PROF				\
-	.set noat;				\
-	lda	AT, _mcount;			\
-	jsr	AT, (AT), _mcount;		\
-	.set at
-# else
-#  define PSEUDO_PROF
-# endif
-
 /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END
    besides "ret".  */
 
@@ -88,7 +78,7 @@ __LABEL($multi_error)						\
 	addq	sp, 64, sp;					\
 	cfi_restore(ra);					\
 	cfi_def_cfa_offset(0);					\
-__LABEL($syscall_error)						\
+	SYSCALL_ERROR_FALLTHRU;					\
 	SYSCALL_ERROR_HANDLER;					\
 	cfi_endproc;						\
 	.previous
diff --git a/ports/sysdeps/unix/sysv/linux/alpha/syscall.S b/ports/sysdeps/unix/sysv/linux/alpha/syscall.S
index 830b10acb6..5cec3800e7 100644
--- a/ports/sysdeps/unix/sysv/linux/alpha/syscall.S
+++ b/ports/sysdeps/unix/sysv/linux/alpha/syscall.S
@@ -62,16 +62,9 @@ LEAF(__syscall, 0)
 	ldq	a5,0(sp)	/* arg6 -> a5 */
 
 	call_pal PAL_callsys	/* Invoke system call */
-	bne	a3, $error
+	bne	a3, SYSCALL_ERROR_LABEL
 	ret
 
-$error:
-#ifndef PROF
-	br	gp, 2f
-2:	ldgp	gp, 0(gp)
-#endif
-	SYSCALL_ERROR_HANDLER
-
-END(__syscall)
+PSEUDO_END(__syscall)
 
 weak_alias (__syscall, syscall)