about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/sparc/sparc32
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/sparc/sparc32')
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Dist4
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Implies3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Makefile12
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/chown.c2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/clone.S46
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.c64
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h75
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/nldbl-abi.h8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S26
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c6
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c6
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/socket.S39
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9b/Implies1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S16
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h177
18 files changed, 171 insertions, 318 deletions
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Dist b/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
deleted file mode 100644
index 66f771a161..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/Dist
+++ /dev/null
@@ -1,4 +0,0 @@
-clone.S
-kernel_stat.h
-setfsuid.c
-setfsgid.c
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Implies b/sysdeps/unix/sysv/linux/sparc/sparc32/Implies
new file mode 100644
index 0000000000..efda9d27c0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Implies
@@ -0,0 +1,3 @@
+# These supply the ABI compatibility for when long double was double.
+ieee754/ldbl-64-128
+ieee754/ldbl-opt
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile
index 05fd8523b7..cd1b3fb793 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile
@@ -4,8 +4,18 @@ LD += -melf32_sparc
 
 # When I get this to work, this is the right thing
 ifeq ($(subdir),elf)
-CFLAGS-rtld.c += -mv8
+CFLAGS-rtld.c += -mcpu=v8
 #rtld-routines += dl-sysdepsparc
 sysdep-others += lddlibc4
 install-bin += lddlibc4
 endif   # elf
+
+ifeq ($(subdir),math)
+# These 2 routines are normally in libgcc{.a,_s.so.1}.
+# However, sparc32 -mlong-double-128 libgcc relies on
+# glibc providing _Q_* routines and without these files
+# glibc relies on __multc3/__divtc3 only provided
+# by libgcc if configured with -mlong-double-128.
+# Provide these routines here as well.
+libm-routines += multc3 divtc3
+endif   # math
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/chown.c b/sysdeps/unix/sysv/linux/sparc/sparc32/chown.c
index 1961622564..374131695c 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/chown.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/chown.c
@@ -1 +1 @@
-#include <sysdeps/unix/sysv/linux/m68k/chown.c>
+#include <sysdeps/unix/sysv/linux/sh/chown.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
index 66cdbf3ca7..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,19 +33,26 @@
 	     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 */
-	tst	%i0
+	orcc	%i0,%g0,%g2
 	be	.Lerror
 	 orcc	%i1,%g0,%o1
 	be	.Lerror
 	 mov	%i2,%o0
+
+	/* The child_stack is the top of the stack, allocate one
+	   whole stack frame from that as this is what the kernel
+	   expects.  */
+	sub	%o1, 96, %o1
+	mov	%i3, %g3
+	mov	%i2, %g4
+
 	/* ptid */
 	mov	%i4,%o2
 	/* tls */
@@ -59,39 +67,43 @@ __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	%i2, %l0, %g0
+	andcc	%g4, %l0, %g0
 	bne	1f
-	 andcc	%i2, CLONE_VM, %g0
+	 andcc	%g4, CLONE_VM, %g0
 	bne,a	2f
 	 mov	-1,%o0
 	set	__NR_getpid,%g1
 	ta	0x10
-2:	st	%o0,[%g7 + PID]
+2:
+	st	%o0,[%g7 + PID]
 	st	%o0,[%g7 + TID]
 1:
 #endif
-	call	%i0
-	 mov	%i3,%o0
+	mov	%g0, %fp	/* terminate backtrace */
+	call	%g2
+	 mov	%g3,%o0
 	call	_exit,0
 	 nop
 
+	cfi_endproc
+
 	.size	__thread_start, .-__thread_start
 
-weak_alias(__clone, clone)
+weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.c b/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.c
deleted file mode 100644
index e9042d9717..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Data for Linux/sparc32 version of processor capability information.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-/* This information must be kept in sync with the _DL_HWCAP_COUNT
-   definition in procinfo.h.
-
-   If anything should be added here check whether the size of each string
-   is still ok with the given array size.
-
-   All the #ifdefs in the definitions ar equite irritating but
-   necessary if we want to avoid duplicating the information.  There
-   are three different modes:
-
-   - PROCINFO_DECL is defined.  This means we are only interested in
-     declarations.
-
-   - PROCINFO_DECL is not defined:
-
-     + if SHARED is defined the file is included in an array
-       initializer.  The .element = { ... } syntax is needed.
-
-     + if SHARED is not defined a normal array initialization is
-       needed.
-  */
-
-#ifndef PROCINFO_CLASS
-#define PROCINFO_CLASS
-#endif
-
-#if !defined PROCINFO_DECL && defined SHARED
-  ._dl_sparc32_cap_flags
-#else
-PROCINFO_CLASS const char _dl_sparc32_cap_flags[6][7]
-#endif
-#ifndef PROCINFO_DECL
-= {
-    "flush", "stbar", "swap", "muldiv", "v9", "ultra3"
-  }
-#endif
-#if !defined SHARED || defined PROCINFO_DECL
-;
-#else
-,
-#endif
-
-#undef PROCINFO_DECL
-#undef PROCINFO_CLASS
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h b/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h
deleted file mode 100644
index 82a94fca9c..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/dl-procinfo.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Linux/sparc32 version of processor capability information handling macros.
-   Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jj@ultra.linux.cz>, 1999.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#ifndef _DL_PROCINFO_H
-#define _DL_PROCINFO_H	1
-
-#include <ldsodefs.h>
-
-#define _DL_HWCAP_COUNT 6
-
-static inline int
-__attribute__ ((unused))
-_dl_procinfo (int word)
-{
-  int i;
-
-  _dl_printf ("AT_HWCAP:   ");
-
-  for (i = 0; i < _DL_HWCAP_COUNT; ++i)
-    if (word & (1 << i))
-      _dl_printf (" %s", GLRO(dl_sparc32_cap_flags)[i]);
-
-  _dl_printf ("\n");
-
-  return 0;
-}
-
-static inline const char *
-__attribute__ ((unused))
-_dl_hwcap_string (int idx)
-{
-  return GLRO(dl_sparc32_cap_flags)[idx];
-};
-
-static inline int
-__attribute__ ((unused, always_inline))
-_dl_string_hwcap (const char *str)
-{
-  int i;
-  for (i = 0; i < _DL_HWCAP_COUNT; i++)
-    {
-      if (strcmp (str, GLRO(dl_sparc32_cap_flags) [i]) == 0)
-	return i;
-    }
-  return -1;
-};
-
-#define HWCAP_IMPORTANT (HWCAP_SPARC_V9|HWCAP_SPARC_ULTRA3)
-
-/* There are no different platforms defined.  */
-#define _dl_platform_string(idx) ""
-
-/* There're no platforms to filter out.  */
-#define _DL_HWCAP_PLATFORM 0
-
-#define _dl_string_platform(str) (-1)
-
-#endif /* dl-procinfo.h */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c b/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c
new file mode 100644
index 0000000000..dfed76aeb4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fchownat.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies b/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies
new file mode 100644
index 0000000000..dbcd1e9e6f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies
@@ -0,0 +1,2 @@
+# We must list this here to move it ahead of the ldbl-opt code.
+sparc/sparc32/fpu
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c b/sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c
new file mode 100644
index 0000000000..0f8b3135d8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/nldbl-abi.h b/sysdeps/unix/sysv/linux/sparc/sparc32/nldbl-abi.h
new file mode 100644
index 0000000000..bd985cc59c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/nldbl-abi.h
@@ -0,0 +1,8 @@
+/* ABI version for long double switch.
+   This is used by the Versions and math_ldbl_opt.h files in
+   sysdeps/ieee754/ldbl-opt/.  It gives the ABI version where
+   long double == double was replaced with proper long double
+   for libm *l functions and libc functions using long double.  */
+
+#define NLDBL_VERSION			GLIBC_2.4
+#define LONG_DOUBLE_COMPAT_VERSION	GLIBC_2_4
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/semctl.c b/sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c
index b28f009b06..64d47b34c5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c
@@ -1,6 +1,6 @@
 /* Semctl for architectures where word sized unions are passed indirectly
-   Copyright (C) 1995, 1997, 1998, 2000, 2002, 2003, 2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1995,1997,1998,2000,2002,2003,2004,2006
+   	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
 
@@ -28,7 +28,7 @@
 #include <string.h>
 #include <sys/syscall.h>
 
-#include "kernel-features.h"
+#include <kernel-features.h>
 #include <shlib-compat.h>
 
 struct __old_semid_ds
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
index 7fb6459d77..3be801a932 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
@@ -1,5 +1,5 @@
 /* POSIX.1 sigaction call for Linux/SPARC.
-   Copyright (C) 1997,1998,1999,2000,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1997-2000,2002,2003,2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx), 1997.
 
@@ -132,6 +132,10 @@ __libc_sigaction (int sig, __const struct sigaction *act,
 }
 libc_hidden_def (__libc_sigaction)
 
+#ifdef WRAPPER_INCLUDE
+# include WRAPPER_INCLUDE
+#endif
+
 #ifndef LIBC_SIGACTION
 weak_alias (__libc_sigaction, __sigaction);
 libc_hidden_weak (__sigaction)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
index 3c12278e6a..71a63d5b79 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
@@ -40,10 +40,14 @@
    The .S files for the other calls just #define socket and #include this.  */
 
 #ifndef __socket
-#define __socket P(__,socket)
+# ifndef NO_WEAK_ALIAS
+#  define __socket P(__,socket)
+# else
+#  define __socket socket
+# endif
 #endif
 
-.globl __socket
+	.globl		__syscall_error
 ENTRY (__socket)
 
 	/* Drop up to 6 arguments (recvfrom) into the memory allocated by
@@ -72,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
@@ -91,18 +96,22 @@ 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
 weak_alias (__socket, socket)
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9b/Implies b/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9b/Implies
deleted file mode 100644
index 17ed964f79..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9b/Implies
+++ /dev/null
@@ -1 +0,0 @@
-unix/sysv/linux/sparc/sparc32/sparcv9
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 29c5158b9f..c808a97fc5 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, January 1997.
 
@@ -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__ */
 
@@ -214,4 +137,24 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)			\
 
 #endif	/* __ASSEMBLER__ */
 
+/* Pointer mangling support.  */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+   earlier than the descriptor is initialized.  */
+#else
+# ifdef __ASSEMBLER__
+#  define PTR_MANGLE(dreg, reg, tmpreg) \
+  ld	[%g7 + POINTER_GUARD], tmpreg; \
+  xor	reg, tmpreg, dreg
+#  define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg)
+#  define PTR_MANGLE2(dreg, reg, tmpreg) \
+  xor	reg, tmpreg, dreg
+#  define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg)
+# else
+#  define PTR_MANGLE(var) \
+  (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+#  define PTR_DEMANGLE(var)     PTR_MANGLE (var)
+# endif
+#endif
+
 #endif /* linux/sparc/sysdep.h */