about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r--sysdeps/unix/sysv/linux/sparc/Makefile4
-rw-r--r--sysdeps/unix/sysv/linux/sparc/rt-sysdep.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/clone.S22
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S26
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/socket.S31
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S16
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h155
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/brk.S8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/clone.S20
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S16
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/socket.S31
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S17
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h176
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sysdep.S1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sysdep.c1
17 files changed, 199 insertions, 336 deletions
diff --git a/sysdeps/unix/sysv/linux/sparc/Makefile b/sysdeps/unix/sysv/linux/sparc/Makefile
index 29e5406348..9cb2a634d5 100644
--- a/sysdeps/unix/sysv/linux/sparc/Makefile
+++ b/sysdeps/unix/sysv/linux/sparc/Makefile
@@ -1 +1,5 @@
 64bit-predefine = __sparc_v9__ __arch64__
+
+ifeq ($(subdir),rt)
+librt-routines += rt-sysdep
+endif
diff --git a/sysdeps/unix/sysv/linux/sparc/rt-sysdep.c b/sysdeps/unix/sysv/linux/sparc/rt-sysdep.c
new file mode 100644
index 0000000000..3ff55952e2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/rt-sysdep.c
@@ -0,0 +1 @@
+#include <sysdep.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
index 95106d149f..f91fc4f629 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
@@ -24,6 +24,7 @@
 #include <asm/errno.h>
 #include <asm/unistd.h>
 #include <tcb-offsets.h>
+#include <sysdep.h>
 
 #define CLONE_VM	0x00000100
 #define CLONE_THREAD	0x00010000
@@ -32,12 +33,11 @@
 	     pid_t *ptid, void *tls, pid_t *ctid); */
 
 	.text
-	.align	4
-	.globl	__clone
-	.type	__clone,@function
-
-__clone:
+ENTRY (__clone)
 	save	%sp,-96,%sp
+	cfi_def_cfa_register(%fp)
+	cfi_window_save
+	cfi_register(%o7, %i7)
 
 	/* sanity check arguments */
 	orcc	%i0,%g0,%g2
@@ -67,21 +67,21 @@ __clone:
 	 tst	%o1
 	bne	__thread_start
 	 nop
-	ret
+	jmpl	%i7 + 8, %g0
 	 restore %o0,%g0,%o0
 
 .Lerror:
 	call	__errno_location
 	 or	%g0,EINVAL,%i0
 	st	%i0,[%o0]
-	ret
+	jmpl	%i7 + 8, %g0
 	 restore %g0,-1,%o0
-
-	.size	__clone, .-__clone
+END(__clone)
 
 	.type	__thread_start,@function
-
 __thread_start:
+	cfi_startproc
+
 #ifdef RESET_PID
 	sethi	%hi(CLONE_THREAD), %l0
 	andcc	%g4, %l0, %g0
@@ -102,6 +102,8 @@ __thread_start:
 	call	_exit,0
 	 nop
 
+	cfi_endproc
+
 	.size	__thread_start, .-__thread_start
 
 weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S b/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
index 27ea9f8912..dbe0872616 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
@@ -19,20 +19,22 @@
 
 #include <sysdep.h>
 
-	.globl __libc_pipe
-ENTRY (__libc_pipe)
-        mov %o0, %o2            /* Save PIPEDES. */
-	mov SYS_ify(pipe),%g1
-	ta 0x10
-	bcs __syscall_error_handler
-	 nop
-	st %o0, [%o2]           /* PIPEDES[0] = %o0; */
-        st %o1, [%o2 + 4]       /* PIPEDES[1] = %o1; */
+	.text
+	.globl		__syscall_error
+ENTRY(__libc_pipe)
+        mov	%o0, %o2            /* Save PIPEDES. */
+	mov	SYS_ify(pipe),%g1
+	ta	0x10
+	bcc	1f
+	 mov	%o7, %g1
+	call	__syscall_error
+	 mov	%g1, %o7
+1:	st	%o0, [%o2]           /* PIPEDES[0] = %o0; */
+        st	%o1, [%o2 + 4]       /* PIPEDES[1] = %o1; */
 	retl
-	 clr %o0
-	SYSCALL_ERROR_HANDLER
+	 clr	%o0
+END(__libc_pipe)
 
-PSEUDO_END (__libc_pipe)
 weak_alias (__libc_pipe, __pipe)
 libc_hidden_def (__pipe)
 weak_alias (__libc_pipe, pipe)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
index 911d5c6b39..71a63d5b79 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
@@ -47,7 +47,7 @@
 # endif
 #endif
 
-.globl __socket
+	.globl		__syscall_error
 ENTRY (__socket)
 
 	/* Drop up to 6 arguments (recvfrom) into the memory allocated by
@@ -76,18 +76,19 @@ ENTRY (__socket)
 	add %sp, 68, %o1		/* arg 2: parameter block */
 	LOADSYSCALL(socketcall)
 	t 0x10
-        bcs __syscall_error_handler
-	 nop
-	retl
+	bcc 1f
+	 mov %o7, %g1
+	call __syscall_error
+	 mov %g1, %o7
+1:	jmpl %o7 + 8, %g0
 	 nop
 
 #if defined NEED_CANCELLATION && defined CENABLE
 .Lsocket_cancel:
-	cfi_startproc
 	save %sp, -96, %sp
-	cfi_def_cfa_register (%fp)
+	cfi_def_cfa_register(%fp)
 	cfi_window_save
-	cfi_register (%o7, %i7)
+	cfi_register(%o7, %i7)
 	CENABLE
 	 nop
 	mov %o0, %l0
@@ -95,18 +96,20 @@ ENTRY (__socket)
 	mov P(SOCKOP_,socket), %o0
 	LOADSYSCALL(socketcall)
 	t 0x10
-	bcs __syscall_error_handler2
+	bcc 1f
 	 mov %o0, %l1
-	CDISABLE
+	CDISABLE;
+	 mov %l0, %o0;
+	call __syscall_error;
+	 mov %l1, %o0;
+	b 1f
+	 mov -1, %l1;
+1:	CDISABLE
 	 mov %l0, %o0
-	jmpl %i7 + 8, %g0
+2:	jmpl %i7 + 8, %g0
 	 restore %g0, %l1, %o0
-	cfi_endproc
-	SYSCALL_ERROR_HANDLER2
 #endif
 
-	SYSCALL_ERROR_HANDLER
-
 END (__socket)
 
 #ifndef NO_WEAK_ALIAS
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
index 3b135c8e86..1610745524 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
@@ -17,8 +17,10 @@
    02111-1307 USA.  */
 
 #include <sysdep.h>
+
 	.text
-ENTRY (syscall)
+	.globl	__syscall_error
+ENTRY(syscall)
 	mov	%o0, %g1
 	mov	%o1, %o0
 	mov	%o2, %o1
@@ -26,10 +28,10 @@ ENTRY (syscall)
 	mov	%o4, %o3
 	mov	%o5, %o4
 	ta	0x10
-	bcs	__syscall_error_handler
-	 nop
-	retl
+	bcc	1f
+	 mov	%o7, %g1
+	call	__syscall_error
+	 mov	%g1, %o7
+1:	retl
 	 nop
-	SYSCALL_ERROR_HANDLER
-
-PSEUDO_END (syscall)
+END(syscall)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
index 45f5c44d5d..c808a97fc5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
@@ -38,131 +38,54 @@
 #undef PSEUDO
 #undef PSEUDO_NOERRNO
 #undef PSEUDO_ERRVAL
+#undef PSEUDO_END
 #undef ENTRY
 #undef END
 #undef LOC
 
-#define ENTRY(name) \
-	.global C_SYMBOL_NAME(name); \
-	.align 4;\
-	C_LABEL(name);\
-	.type name,@function;
+#define ENTRY(name)			\
+	.align	4;			\
+	.global	C_SYMBOL_NAME(name);	\
+	.type	name, @function;	\
+C_LABEL(name)				\
+	cfi_startproc;
 
-#define END(name) \
+#define END(name)			\
+	cfi_endproc;			\
 	.size name, . - name
 
 #define LOC(name)  .L##name
 
-#ifdef LINKER_HANDLES_R_SPARC_WDISP22
-/* Unfortunately, we cannot do this yet.  Linker doesn't seem to
-   handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly .  */
-# define SYSCALL_ERROR_HANDLER_ENTRY(handler)				\
-	.section .gnu.linkonce.t.handler,"ax",@progbits;		\
-	.globl handler;							\
-	.hidden handler;						\
-	.type handler,@function;					\
-handler:
-#else
-# define SYSCALL_ERROR_HANDLER_ENTRY(handler)				\
-	.subsection 3;							\
-handler:
-#endif
-
-#if RTLD_PRIVATE_ERRNO
-# define SYSCALL_ERROR_HANDLER						\
-	.section .gnu.linkonce.t.__sparc_get_pic_l7,"ax",@progbits;	\
-	.globl __sparc_get_pic_l7;					\
-	.hidden __sparc_get_pic_l7;					\
-	.type __sparc_get_pic_l7,@function;				\
-__sparc_get_pic_l7:							\
-	retl;								\
-	 add	%o7, %l7, %l7;						\
-	.previous;							\
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
-	save	%sp,-96,%sp;						\
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7;			\
-	call	__sparc_get_pic_l7;					\
-	 add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7;			\
-	ld	[%l7 + rtld_errno], %l0;				\
-	st	%i0, [%l0];						\
-	jmpl	%i7+8, %g0;						\
-	 restore %g0, -1, %o0;						\
-	.previous;
-#elif USE___THREAD
-# ifndef NOT_IN_libc
-#  define SYSCALL_ERROR_ERRNO __libc_errno
-# else
-#  define SYSCALL_ERROR_ERRNO errno
-# endif
-# ifdef SHARED
-#  define SYSCALL_ERROR_HANDLER						\
-	.section .gnu.linkonce.t.__sparc_get_pic_l7,"ax",@progbits;	\
-	.globl __sparc_get_pic_l7;					\
-	.hidden __sparc_get_pic_l7;					\
-	.type __sparc_get_pic_l7,@function;				\
-__sparc_get_pic_l7:							\
-	retl;								\
-	 add	%o7, %l7, %l7;						\
-	.previous;							\
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
-	save	%sp,-96,%sp;						\
-	sethi	%tie_hi22(SYSCALL_ERROR_ERRNO), %l1;			\
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7;			\
-	call	__sparc_get_pic_l7;					\
-	 add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7;			\
-	add	%l1, %tie_lo10(SYSCALL_ERROR_ERRNO), %l1;		\
-	ld	[%l7 + %l1], %l1, %tie_ld(SYSCALL_ERROR_ERRNO);		\
-	st	%i0, [%g7 + %l1], %tie_add(SYSCALL_ERROR_ERRNO);	\
-	jmpl	%i7+8, %g0;						\
-	 restore %g0, -1, %o0;						\
-	.previous;
-# else
-#  define SYSCALL_ERROR_HANDLER						\
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
-	sethi	%tie_hi22(SYSCALL_ERROR_ERRNO), %g1;			\
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_), %g2;			\
-	add	%g1, %tie_lo10(SYSCALL_ERROR_ERRNO), %g1;		\
-	add	%g2, %lo(_GLOBAL_OFFSET_TABLE_), %g2;			\
-	ld	[%g2 + %g1], %g1, %tie_ld(SYSCALL_ERROR_ERRNO);		\
-	st	%o0, [%g7 + %g1], %tie_add(SYSCALL_ERROR_ERRNO);	\
-	jmpl	%o7+8, %g0;						\
-	 mov	-1, %o0;						\
-	.previous;
-# endif
-#else
-# define SYSCALL_ERROR_HANDLER						\
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
-	.global __errno_location;					\
-        .type   __errno_location,@function;				\
-	save   %sp, -96, %sp;						\
-	call   __errno_location;					\
-	 nop;								\
-	st	%i0, [%o0];						\
-	jmpl	%i7+8, %g0;						\
-	 restore %g0, -1, %o0;						\
-	.previous;
-#endif
-
-#define PSEUDO(name, syscall_name, args)			\
-	.text;							\
-	ENTRY(name);						\
-	LOADSYSCALL(syscall_name);				\
-	ta 0x10;						\
-	bcs __syscall_error_handler;				\
-	 nop;							\
-	SYSCALL_ERROR_HANDLER
-
-#define PSEUDO_NOERRNO(name, syscall_name, args)		\
-	.text;							\
-	ENTRY(name);						\
-	LOADSYSCALL(syscall_name);				\
-	ta 0x10
-
-#define PSEUDO_ERRVAL(name, syscall_name, args)			\
-	.text;							\
-	ENTRY(name);						\
-	LOADSYSCALL(syscall_name);				\
-	ta 0x10
+	/* If the offset to __syscall_error fits into a signed 22-bit
+	 * immediate branch offset, the linker will relax the call into
+	 * a normal branch.
+	 */
+#define PSEUDO(name, syscall_name, args)	\
+	.text;					\
+	.globl		__syscall_error;	\
+ENTRY(name);					\
+	LOADSYSCALL(syscall_name);		\
+	ta		0x10;			\
+	bcc		1f;			\
+	 mov		%o7, %g1;		\
+	call		__syscall_error;	\
+	 mov		%g1, %o7;		\
+1:
+
+#define PSEUDO_NOERRNO(name, syscall_name, args)\
+	.text;					\
+ENTRY(name);					\
+	LOADSYSCALL(syscall_name);		\
+	ta		0x10;
+
+#define PSEUDO_ERRVAL(name, syscall_name, args)	\
+	.text;					\
+ENTRY(name);					\
+	LOADSYSCALL(syscall_name);		\
+	ta		0x10;
+
+#define PSEUDO_END(name)			\
+	END(name)
 
 #else  /* __ASSEMBLER__ */
 
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
index 1fabd11f71..134ce789f7 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
@@ -37,8 +37,11 @@ __curbrk: .skip 8
 #endif
 
 	.text
-ENTRY(__brk)
+ENTRY (__brk)
 	save	%sp, -192, %sp
+	cfi_def_cfa_register(%fp)
+	cfi_window_save
+	cfi_register(%o7, %i7)
 #ifdef PIC
 1:	call	2f
 	sethi	%hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
@@ -90,7 +93,6 @@ ENTRY(__brk)
 	sub	%g0, 1, %i0
 	jmpl	%i7+8, %g0
 	 restore
-
-	.size __brk, .-__brk
+END (__brk)
 
 weak_alias (__brk, brk)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
index 0e1025ff6a..ebfce9e2c5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
@@ -23,6 +23,7 @@
 #include <asm/errno.h>
 #include <asm/unistd.h>
 #include <tcb-offsets.h>
+#include <sysdep.h>
 
 #define CLONE_VM	0x00000100
 #define CLONE_THREAD	0x00010000
@@ -34,12 +35,12 @@
 	.register	%g3,#scratch
 
 	.text
-	.align	4
-	.globl	__clone
-	.type	__clone,@function
 
-__clone:
+ENTRY (__clone)
 	save	%sp, -192, %sp
+	cfi_def_cfa_register(%fp)
+	cfi_window_save
+	cfi_register(%o7, %i7)
 
 	/* sanity check arguments */
 	brz,pn	%i0, 99f		/* fn non-NULL? */
@@ -65,7 +66,7 @@ __clone:
 	 nop
 	brnz,pn	%o1, __thread_start
 	 nop
-	ret
+	jmpl	%i7 + 8, %g0
 	 restore %o0, %g0, %o0
 99:
 #ifndef _LIBC_REENTRANT
@@ -88,12 +89,13 @@ __clone:
 	 nop
 	st	%i0, [%o0]
 #endif
-	ret
+	jmpl	%i7 + 8, %g0
 	 restore %g0,-1,%o0
-	.size __clone, .-__clone
+END(__clone)
 
 	.type __thread_start,@function
 __thread_start:
+	cfi_startproc
 #ifdef RESET_PID
 	sethi	%hi(CLONE_THREAD), %l0
 	andcc	%g4, %l0, %g0
@@ -112,6 +114,8 @@ __thread_start:
 	 mov	%g3,%o0
 	call	_exit,0
 	 nop
-	.size __thread_start, .-__thread_start
+	cfi_endproc
+
+	.size	__thread_start, .-__thread_start
 
 weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
index 5ccedff21a..14f244e628 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
@@ -19,18 +19,22 @@
 
 #include <sysdep.h>
 
-ENTRY (__libc_pipe)
+	.text
+
+	.globl	__syscall_error
+ENTRY(__libc_pipe)
 	mov	%o0, %o2		/* Save PIPEDES. */
 	LOADSYSCALL(pipe)
 	ta	0x6d
-	bcs,pn	%xcc, __syscall_error_handler
-	 nop
-	st	%o0, [%o2]		/* PIPEDES[0] = %o0; */
+	bcc,pt	%xcc, 1f
+	 mov	%o7, %g1
+	call	__syscall_error
+	 mov	%g1, %o7
+1:	st	%o0, [%o2]		/* PIPEDES[0] = %o0; */
 	st	%o1, [%o2 + 4]		/* PIPEDES[1] = %o1; */
 	retl
 	 clr	%o0
-	SYSCALL_ERROR_HANDLER
-PSEUDO_END (__libc_pipe)
+END(__libc_pipe)
 
 weak_alias (__libc_pipe, __pipe)
 libc_hidden_def (__pipe)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S b/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S
index 4e0bc96d22..90d47c18fa 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S
@@ -24,12 +24,15 @@
 .weak setcontext
 ENTRY(setcontext)
 
-	mov	1, %o1
+	ba,pt	%xcc, 1f
+	 mov	1, %o1
+
+END(setcontext)
 
 /* int __setcontext(ucontext_t *ctx, int restoremask); */
 ENTRY(__setcontext)
 
-	ldx	[%o0 + UC_SIGMASK], %o2
+1:	ldx	[%o0 + UC_SIGMASK], %o2
 	stx	%o2, [%o0 + __UC_SIGMASK]
 	ta	0x6f
 
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S
index 1a9359af5b..ab1690bb42 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S
@@ -39,7 +39,8 @@ libc_hidden_def (_setjmp)
 /* int setjmp(jmp_buf) */
 
 ENTRY(setjmp)
-	set	1, %o1
+	ba,pt	%xcc, __sigsetjmp_local
+	 set	1, %o1
 END(setjmp)
 
 /* int __sigsetjmp(jmp_buf, savemask)  */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S b/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
index 7a8b205538..353705b4ac 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
@@ -47,8 +47,8 @@
 # endif
 #endif
 
-.globl __socket
-ENTRY (__socket)
+	.globl	__syscall_error
+ENTRY(__socket)
 
 	/* Drop up to 6 arguments (recvfrom) into the memory allocated by
 	   the caller for varargs, since that's really what we have.  */
@@ -77,14 +77,15 @@ ENTRY (__socket)
 	LOADSYSCALL(socketcall)
 	ta	0x6d
 
-	bcs,pn	%xcc, __syscall_error_handler
-	 nop
-	retl
+	bcc,pt	%xcc, 1f
+	 mov	%o7, %g1
+	call	__syscall_error
+	 mov	%g1, %o7
+1:	retl
 	 nop
 
 #if defined NEED_CANCELLATION && defined CENABLE
 .Lsocket_cancel:
-	cfi_startproc
 	save	%sp, -160, %sp
 	cfi_def_cfa_register (%fp)
 	cfi_window_save
@@ -97,19 +98,21 @@ ENTRY (__socket)
 	LOADSYSCALL(socketcall)
 	ta	0x6d
 
-	bcs,pn	%xcc, __syscall_error_handler2
+	bcc,pt	%xcc, 1f
 	 mov	%o0, %l1
-	CDISABLE
+	CDISABLE;
+	 mov	%l0, %o0;
+	call	__syscall_error;
+	 mov	%l1, %o0;
+	ba,pt	%xcc, 2f
+	 mov	-1, %l1;
+1:	CDISABLE
 	 mov	%l0, %o0
-	jmpl	%i7 + 8, %g0
+2:	jmpl	%i7 + 8, %g0
 	 restore %g0, %l1, %o0
-	cfi_endproc
-	SYSCALL_ERROR_HANDLER2
 #endif
 
-	SYSCALL_ERROR_HANDLER
-
-END (__socket)
+END(__socket)
 
 #ifndef NO_WEAK_ALIAS
 weak_alias (__socket, socket)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
index 27bd086206..27487d8ed9 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
@@ -19,8 +19,8 @@
 #include <sysdep.h>
 	.text
 
-ENTRY (syscall)
-
+	.globl	__syscall_error
+ENTRY(syscall)
 	mov	%o0,%g1
 	mov	%o1,%o0
 	mov	%o2,%o1
@@ -30,11 +30,10 @@ ENTRY (syscall)
 
 	ta	0x6d
 
-	bcs,pn %xcc,__syscall_error_handler
-	 nop
-	retl
+	bcc,pt	%xcc, 1f
+	 mov	%o7, %g1
+	call	__syscall_error
+	 mov	%g1, %o7
+1:	retl
 	 nop
-
-	SYSCALL_ERROR_HANDLER
-
-PSEUDO_END (syscall)
+END(syscall)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
index dfc38f151a..f156f9241a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
@@ -49,142 +49,52 @@
 #undef PSEUDO
 #undef PSEUDO_NOERRNO
 #undef PSEUDO_ERRVAL
-#undef ENTRY
-
-#define ENTRY(name)							\
-	.global C_SYMBOL_NAME(name);					\
-	.align 2;							\
-	C_LABEL(name);							\
-	.type name,@function;
-
-#ifdef LINKER_HANDLES_R_SPARC_WDISP22
-/* Unfortunately, we cannot do this yet.  Linker doesn't seem to
-   handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly .  */
-# define SYSCALL_ERROR_HANDLER_ENTRY(handler)				\
-	.section .gnu.linkonce.t.handler,"ax",@progbits;		\
-	.globl handler;							\
-	.hidden handler;						\
-	.type handler,@function;					\
-handler:
-#else
-# define SYSCALL_ERROR_HANDLER_ENTRY(handler)				\
-	.subsection 3;							\
-handler:
-#endif
-
-#if RTLD_PRIVATE_ERRNO
-# define SYSCALL_ERROR_HANDLER						\
-	.section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits;	\
-	.globl __sparc64.get_pic.l7;					\
-	.hidden __sparc64.get_pic.l7;					\
-	.type __sparc64.get_pic.l7,@function;				\
-__sparc64.get_pic.l7:							\
-	retl;								\
-	 add	%o7, %l7, %l7;						\
-	.previous;							\
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
-	save	%sp, -192, %sp;						\
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7;			\
-	call	__sparc64.get_pic.l7;					\
-	 add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7;			\
-	sethi	%hi(rtld_errno), %g1;					\
-	or	%g1, %lo(rtld_errno), %g1;				\
-	ldx	[%l7 + %g1], %l0;					\
-	st	%i0, [%l0];						\
-	jmpl	%i7+8, %g0;						\
-	 restore %g0, -1, %o0;						\
-	.previous;
-#elif USE___THREAD
-# ifndef NOT_IN_libc
-#  define SYSCALL_ERROR_ERRNO __libc_errno
-# else
-#  define SYSCALL_ERROR_ERRNO errno
-# endif
-# ifdef SHARED
-#  define SYSCALL_ERROR_HANDLER						\
-	.section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits;	\
-	.globl __sparc64.get_pic.l7;					\
-	.hidden __sparc64.get_pic.l7;					\
-	.type __sparc64.get_pic.l7,@function;				\
-__sparc64.get_pic.l7:							\
-	retl;								\
-	 add	%o7, %l7, %l7;						\
-	.previous;							\
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
-	save	%sp,-192,%sp;						\
-	sethi	%tie_hi22(SYSCALL_ERROR_ERRNO), %l1;			\
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7;			\
-	call	__sparc64.get_pic.l7;					\
-	 add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7;			\
-	add	%l1, %tie_lo10(SYSCALL_ERROR_ERRNO), %l1;		\
-	ldx	[%l7 + %l1], %l1, %tie_ldx(SYSCALL_ERROR_ERRNO);	\
-	st	%i0, [%g7 + %l1], %tie_add(SYSCALL_ERROR_ERRNO);	\
-	jmpl	%i7+8, %g0;						\
-	 restore %g0, -1, %o0;						\
-	.previous;
-# else
-#  define SYSCALL_ERROR_HANDLER						\
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
-	sethi	%tie_hi22(SYSCALL_ERROR_ERRNO), %g1;			\
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_), %g4;			\
-	add	%g1, %tie_lo10(SYSCALL_ERROR_ERRNO), %g1;		\
-	add	%g4, %lo(_GLOBAL_OFFSET_TABLE_), %g4;			\
-	ldx	[%g4 + %g1], %g1, %tie_ldx(SYSCALL_ERROR_ERRNO);	\
-	st	%o0, [%g7 + %g1], %tie_add(SYSCALL_ERROR_ERRNO);	\
-	jmpl	%o7+8, %g0;						\
-	 mov	-1, %o0;						\
-	.previous;
-# endif
-#else
-# define SYSCALL_ERROR_HANDLER						\
-SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
-	.global __errno_location;					\
-	.type   __errno_location,@function;				\
-	save	%sp, -192, %sp;						\
-	call	__errno_location;					\
-	 nop;								\
-	st	%i0, [%o0];						\
-	jmpl	%i7+8, %g0;						\
-	 restore %g0, -1, %o0;						\
-	.previous;
-#endif
-
-#define PSEUDO(name, syscall_name, args)				\
-	.text;								\
-	ENTRY(name);							\
-	LOADSYSCALL(syscall_name);					\
-	ta	0x6d;							\
-	bcs,pn	%xcc, __syscall_error_handler;				\
-	 nop;								\
-	SYSCALL_ERROR_HANDLER
-
-#define PSEUDO_NOERRNO(name, syscall_name, args)			\
-	.text;								\
-	ENTRY(name);							\
-	LOADSYSCALL(syscall_name);					\
-	ta	0x6d
-
-#define PSEUDO_ERRVAL(name, syscall_name, args)				\
-	.text;								\
-	ENTRY(name);							\
-	LOADSYSCALL(syscall_name);					\
-	ta	0x6d
-
 #undef PSEUDO_END
-#define PSEUDO_END(name)						\
-	.size name,.-name
-
-#undef PSEUDO_END_NOERRNO
-#define PSEUDO_END_NOERRNO(name)					\
-	.size name,.-name
+#undef ENTRY
+#undef END
 
-#undef PSEUDO_END_ERRVAL
-#define PSEUDO_END_ERRVAL(name)						\
-	.size name,.-name
+#define ENTRY(name)			\
+	.align	4;			\
+	.global	C_SYMBOL_NAME(name);	\
+	.type	name, @function;	\
+C_LABEL(name)				\
+	cfi_startproc;
+
+#define END(name)			\
+	cfi_endproc;			\
+	.size name, . - name
+
+	/* If the offset to __syscall_error fits into a signed 22-bit
+	 * immediate branch offset, the linker will relax the call into
+	 * a normal branch.
+	 */
+#define PSEUDO(name, syscall_name, args)	\
+	.text;					\
+	.globl		__syscall_error;	\
+ENTRY(name);					\
+	LOADSYSCALL(syscall_name);		\
+	ta		0x6d;			\
+	bcc,pt		%xcc, 1f;		\
+	 mov		%o7, %g1;		\
+	call		__syscall_error;	\
+	 mov		%g1, %o7;		\
+1:
+
+#define	PSEUDO_NOERRNO(name, syscall_name, args)\
+	.text;					\
+ENTRY(name);					\
+	LOADSYSCALL(syscall_name);		\
+	ta		0x6d;
+
+#define	PSEUDO_ERRVAL(name, syscall_name, args) \
+	.text;					\
+ENTRY(name);					\
+	LOADSYSCALL(syscall_name);		\
+	ta		0x6d;
+
+#define PSEUDO_END(name)			\
+	END(name)
 
-#undef END
-#define END(name)							\
-	.size name,.-name
 
 /* Careful here!  This "ret" define can interfere; use jmpl if unsure.  */
 #define ret		retl; nop
diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.S b/sysdeps/unix/sysv/linux/sparc/sysdep.S
deleted file mode 100644
index b031238ceb..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sysdep.S
+++ /dev/null
@@ -1 +0,0 @@
-/* Nothing to do here.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.c b/sysdeps/unix/sysv/linux/sparc/sysdep.c
new file mode 100644
index 0000000000..f86414570d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sysdep.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/powerpc/sysdep.c>