aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-12-28 09:27:26 +0000
committerUlrich Drepper <drepper@redhat.com>2002-12-28 09:27:26 +0000
commit131fd126cddad8379741597892cdfcd5cab3a49f (patch)
treeae4e3dc6182f230ae952cd95fecb2ee20948387b /sysdeps
parentca78735936e87a2b72c553636e815bd555c4ef7e (diff)
downloadglibc-131fd126cddad8379741597892cdfcd5cab3a49f.tar
glibc-131fd126cddad8379741597892cdfcd5cab3a49f.tar.gz
glibc-131fd126cddad8379741597892cdfcd5cab3a49f.tar.bz2
glibc-131fd126cddad8379741597892cdfcd5cab3a49f.zip
Update.
2002-12-28 Ulrich Drepper <drepper@redhat.com> * descr.h (struct pthread): Move header.data.list to the back of the struct. * sysdeps/i386/tls.h (tcbhead_t): Move list to the back of the struct. (MULTIPLE_THREADS_OFFSET): Adjust offset. (SYSINFO_OFFSEET): Likewise. 2002-12-27 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h (USE_DL_SYSINFO): Define. (DL_SYSINFO_DEFAULT): Cast to uintptr_t to avoid warnings. * sysdeps/unix/sysv/linux/i386/dl-sysdep.h (NEED_DL_SYSINFO, DL_SYSINFO_DEFAULT, DL_SYSINFO_IMPLEMENTATION): Define. (USE_DL_SYSINFO): Undef. 2002-12-22 Jakub Jelinek <jakub@redhat.com> * Makefile (tests-reverse): Use $(objpfx)../libc.so instead of $(common-objpfx)libc.so. * tst-cancel4.c (tf_write, tf_writev): Increase buf sizes so that it is bigger than pipe buffer size even on arches with bigger page size. (tf_usleep): Cast usleep argument to useconds_t to avoid warnings.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/libc-start.c4
-rw-r--r--sysdeps/generic/libc-tls.c21
-rw-r--r--sysdeps/unix/common/pause.c12
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h5
-rw-r--r--sysdeps/unix/sysv/linux/ia64/sysdep.h101
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S10
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/socket.S7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S28
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h52
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S7
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/socket.S6
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S10
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h50
13 files changed, 222 insertions, 91 deletions
diff --git a/sysdeps/generic/libc-start.c b/sysdeps/generic/libc-start.c
index 5b2728b8ba..b4c29dd3c8 100644
--- a/sysdeps/generic/libc-start.c
+++ b/sysdeps/generic/libc-start.c
@@ -32,7 +32,7 @@ extern void *__libc_stack_end;
#ifndef SHARED
# include <dl-osinfo.h>
extern void __pthread_initialize_minimal (void)
-# if !(USE_TLS - 0)
+# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
__attribute__ ((weak))
# endif
;
@@ -97,7 +97,7 @@ BP_SYM (__libc_start_main) (int (*main) (int, char **, char **),
we need to setup errno. If there is no thread library and we
handle TLS the function is defined in the libc to initialized the
TLS handling. */
-# if !(USE_TLS - 0)
+# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
if (__pthread_initialize_minimal)
# endif
__pthread_initialize_minimal ();
diff --git a/sysdeps/generic/libc-tls.c b/sysdeps/generic/libc-tls.c
index ce1f9d5f07..1461bf8543 100644
--- a/sysdeps/generic/libc-tls.c
+++ b/sysdeps/generic/libc-tls.c
@@ -135,8 +135,13 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
}
if (memsz == 0 && tcbsize <= TLS_INIT_TCB_SIZE)
- /* We do not need a TLS block and no thread descriptor. */
- return;
+ {
+ /* We do not need a TLS block and no thread descriptor. */
+#ifdef NONTLS_INIT_TP
+ NONTLS_INIT_TP;
+#endif
+ return;
+ }
/* We have to set up the TCB block which also (possibly) contains
@@ -249,4 +254,16 @@ __pthread_initialize_minimal (void)
{
__libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
}
+
+#elif defined NONTLS_INIT_TP
+
+/* This is the minimal initialization function used when libpthread is
+ not used. */
+void
+__attribute__ ((weak))
+__pthread_initialize_minimal (void)
+{
+ NONTLS_INIT_TP;
+}
+
#endif
diff --git a/sysdeps/unix/common/pause.c b/sysdeps/unix/common/pause.c
index 9a2e44e996..508a3e0b53 100644
--- a/sysdeps/unix/common/pause.c
+++ b/sysdeps/unix/common/pause.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,7 +18,7 @@
#include <signal.h>
#include <unistd.h>
-
+#include <sysdep-cancel.h>
/* Suspend the process until a signal arrives.
This always returns -1 and sets errno to EINTR. */
@@ -26,6 +26,12 @@
int
__libc_pause (void)
{
- return __sigpause (__sigblock (0), 0);
+ if (SINGLE_THREAD_P)
+ return __sigpause (__sigblock (0), 0);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ int result = __sigpause (__sigblock (0), 0);
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
}
weak_alias (__libc_pause, pause)
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 6478af7f63..25208a00a8 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -24,7 +24,7 @@
#include <sysdeps/unix/i386/sysdep.h>
#include <bp-sym.h>
#include <bp-asm.h>
-/* Defines RTLD_PRIVATE_ERRNO and NEED_DL_SYSINFO. */
+/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
#include <dl-sysdep.h>
#include <tls.h>
@@ -36,7 +36,8 @@
#undef SYS_ify
#define SYS_ify(syscall_name) __NR_##syscall_name
-#if defined NEED_DL_SYSINFO && !defined IS_IN_rtld
+#if defined USE_DL_SYSINFO \
+ && (!defined NOT_IN_libc || defined IS_IN_libpthread)
# define I386_USE_SYSENTER 1
#else
# undef I386_USE_SYSENTER
diff --git a/sysdeps/unix/sysv/linux/ia64/sysdep.h b/sysdeps/unix/sysv/linux/ia64/sysdep.h
index 57f7a7a40b..0a2c1bdc4b 100644
--- a/sysdeps/unix/sysv/linux/ia64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/ia64/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
Based on code originally written by David Mosberger-Tang
@@ -83,7 +83,7 @@
#define PSEUDO(name, syscall_name, args) \
ENTRY(name) \
DO_CALL (SYS_ify(syscall_name)); \
- cmp.eq p6,p0=-1,r10;; \
+ cmp.eq p6,p0=-1,r10; \
(p6) br.cond.spnt.few __syscall_error;
#define DO_CALL(num) \
@@ -102,11 +102,98 @@
#else /* not __ASSEMBLER__ */
-/* Define a macro which expands into the inline wrapper code for a system
- call. */
-#if 0
+/* On IA-64 we have stacked registers for passing arguments. The
+ "out" registers end up being the called function's "in"
+ registers.
+
+ Also, since we have plenty of registers we have two return values
+ from a syscall. r10 is set to -1 on error, whilst r8 contains the
+ (non-negative) errno on error or the return value on success.
+ */
#undef INLINE_SYSCALL
-#define INLINE_SYSCALL(name, nr, args...) __##name (args)
-#endif
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ register long _r8 asm ("r8"); \
+ register long _r10 asm ("r10"); \
+ register long _r15 asm ("r15") = __NR_##name; \
+ long _retval; \
+ LOAD_ARGS_##nr (args); \
+ __asm __volatile ("break %3;;\n\t" \
+ : "=r" (_r8), "=r" (_r10), "=r" (_r15) \
+ : "i" (__BREAK_SYSCALL), "2" (_r15) \
+ ASM_ARGS_##nr \
+ : "memory" ASM_CLOBBERS_##nr); \
+ _retval = _r8; \
+ if (_r10 == -1) \
+ { \
+ __set_errno (_retval); \
+ _retval = -1; \
+ } \
+ _retval; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, nr, args...) \
+ ({ \
+ register long _r8 asm ("r8"); \
+ register long _r10 asm ("r10"); \
+ register long _r15 asm ("r15") = __NR_##name; \
+ long _retval; \
+ LOAD_ARGS_##nr (args); \
+ __asm __volatile ("break %3;;\n\t" \
+ : "=r" (_r8), "=r" (_r10), "=r" (_r15) \
+ : "i" (__BREAK_SYSCALL), "2" (_r15) \
+ ASM_ARGS_##nr \
+ : "memory" ASM_CLOBBERS_##nr); \
+ _retval = _r8; \
+ if (_r10 == -1) \
+ _retval = -_retval; \
+ _retval; })
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -4095UL)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val) (-(val))
+
+#define LOAD_ARGS_0() do { } while (0)
+#define LOAD_ARGS_1(out0) \
+ register long _out0 asm ("out0") = (long) (out0); \
+ LOAD_ARGS_0 ()
+#define LOAD_ARGS_2(out0, out1) \
+ register long _out1 asm ("out1") = (long) (out1); \
+ LOAD_ARGS_1 (out0)
+#define LOAD_ARGS_3(out0, out1, out2) \
+ register long _out2 asm ("out2") = (long) (out2); \
+ LOAD_ARGS_2 (out0, out1)
+#define LOAD_ARGS_4(out0, out1, out2, out3) \
+ register long _out3 asm ("out3") = (long) (out3); \
+ LOAD_ARGS_3 (out0, out1, out2)
+#define LOAD_ARGS_5(out0, out1, out2, out3, out4) \
+ register long _out4 asm ("out4") = (long) (out4); \
+ LOAD_ARGS_4 (out0, out1, out2, out3)
+
+#define ASM_ARGS_0
+#define ASM_ARGS_1 ASM_ARGS_0, "r" (_out0)
+#define ASM_ARGS_2 ASM_ARGS_1, "r" (_out1)
+#define ASM_ARGS_3 ASM_ARGS_2, "r" (_out2)
+#define ASM_ARGS_4 ASM_ARGS_3, "r" (_out3)
+#define ASM_ARGS_5 ASM_ARGS_4, "r" (_out4)
+
+#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0"
+#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1"
+#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2"
+#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3"
+#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4"
+#define ASM_CLOBBERS_5 , "out5", "out6", "out7", \
+ /* Non-stacked integer registers, minus r8, r10, r15. */ \
+ "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \
+ "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \
+ "r28", "r29", "r30", "r31", \
+ /* Predicate registers. */ \
+ "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \
+ /* Non-rotating fp registers. */ \
+ "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ /* Branch registers. */ \
+ "b6", "b7"
#endif /* not __ASSEMBLER__ */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S b/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
index 0136026be6..27ea9f8912 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
@@ -18,19 +18,19 @@
02111-1307 USA. */
#include <sysdep.h>
+
.globl __libc_pipe
ENTRY (__libc_pipe)
mov %o0, %o2 /* Save PIPEDES. */
mov SYS_ify(pipe),%g1
ta 0x10
- bcc,a 2f
- nop
- SYSCALL_ERROR_HANDLER
-2:
+ bcs __syscall_error_handler
+ nop
st %o0, [%o2] /* PIPEDES[0] = %o0; */
st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
retl
- clr %o0
+ clr %o0
+ SYSCALL_ERROR_HANDLER
PSEUDO_END (__libc_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 449d537340..7bc734e38a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
@@ -67,13 +67,12 @@ ENTRY (__socket)
add %sp, 68, %o1 /* arg 2: parameter block */
LOADSYSCALL(socketcall)
t 0x10
-
- bcs,a 1f
+ bcs __syscall_error_handler
nop
retl
nop
-1: SYSCALL_ERROR_HANDLER
+ SYSCALL_ERROR_HANDLER
END (__socket)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
index 08378aba88..3b135c8e86 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1997, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,23 +19,17 @@
#include <sysdep.h>
.text
ENTRY (syscall)
- or %o0,%g0,%g1
- or %o1,%g0,%o0
- or %o2,%g0,%o1
- or %o3,%g0,%o2
- or %o4,%g0,%o3
- or %o5,%g0,%o4
+ mov %o0, %g1
+ mov %o1, %o0
+ mov %o2, %o1
+ mov %o3, %o2
+ mov %o4, %o3
+ mov %o5, %o4
ta 0x10
- bcc 1f
- nop
- save %sp, -96, %sp
- call __errno_location
- nop
- st %i0,[%o0]
- restore
+ bcs __syscall_error_handler
+ nop
retl
- mov -1, %o0
-1:
- ret
+ nop
+ SYSCALL_ERROR_HANDLER
PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
index e3573fd454..e362894e17 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
@@ -31,11 +31,7 @@
#ifdef __ASSEMBLER__
-#ifdef DONT_LOAD_G1
-# define LOADSYSCALL(x)
-#else
-# define LOADSYSCALL(x) mov __NR_##x, %g1
-#endif
+#define LOADSYSCALL(x) mov __NR_##x, %g1
/* Linux/SPARC uses a different trap number */
#undef PSEUDO
@@ -54,6 +50,21 @@
#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; \
@@ -64,6 +75,7 @@ __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; \
@@ -71,17 +83,20 @@ __sparc.get_pic.l7: \
ld [%l7 + errno], %l0; \
st %i0, [%l0]; \
jmpl %i7+8, %g0; \
- restore %g0, -1, %o0;
+ restore %g0, -1, %o0; \
+ .previous;
#else
-# define 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;
+# 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) \
@@ -89,10 +104,9 @@ __sparc.get_pic.l7: \
ENTRY(name); \
LOADSYSCALL(syscall_name); \
ta 0x10; \
- bcc,a 9000f; \
- nop; \
- SYSCALL_ERROR_HANDLER; \
-9000:;
+ bcs __syscall_error_handler; \
+ nop; \
+ SYSCALL_ERROR_HANDLER
#else /* __ASSEMBLER__ */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
index 5c800316d5..5ccedff21a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
@@ -23,14 +23,13 @@ ENTRY (__libc_pipe)
mov %o0, %o2 /* Save PIPEDES. */
LOADSYSCALL(pipe)
ta 0x6d
- bcc,pt %xcc, 2f
+ bcs,pn %xcc, __syscall_error_handler
nop
- SYSCALL_ERROR_HANDLER
-
-2: st %o0, [%o2] /* PIPEDES[0] = %o0; */
+ st %o0, [%o2] /* PIPEDES[0] = %o0; */
st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
retl
clr %o0
+ SYSCALL_ERROR_HANDLER
PSEUDO_END (__libc_pipe)
weak_alias (__libc_pipe, __pipe)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S b/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
index ed490fbaa3..750c1258ed 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
@@ -68,12 +68,12 @@ ENTRY (__socket)
LOADSYSCALL(socketcall)
ta 0x6d
- bcs,pn %xcc, 1f
+ bcs,pn %xcc, __syscall_error_handler
nop
retl
nop
-1: SYSCALL_ERROR_HANDLER
+ SYSCALL_ERROR_HANDLER
END (__socket)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
index 792a3a34da..27bd086206 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -30,11 +30,11 @@ ENTRY (syscall)
ta 0x6d
- bcc,pt %xcc,1f
+ bcs,pn %xcc,__syscall_error_handler
nop
- SYSCALL_ERROR_HANDLER
-
-1: retl
+ retl
nop
+ SYSCALL_ERROR_HANDLER
+
PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
index 10b764712b..a64da1a223 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
@@ -31,11 +31,7 @@
#ifdef __ASSEMBLER__
-#ifdef DONT_LOAD_G1
-# define LOADSYSCALL(x)
-#else
-# define LOADSYSCALL(x) mov __NR_##x, %g1
-#endif
+#define LOADSYSCALL(x) mov __NR_##x, %g1
/* Linux/SPARC uses a different trap number */
#undef PSEUDO
@@ -47,6 +43,21 @@
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; \
@@ -57,6 +68,7 @@ __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; \
@@ -64,17 +76,20 @@ __sparc64.get_pic.l7: \
ldx [%l7 + errno], %l0; \
st %i0, [%l0]; \
jmpl %i7+8, %g0; \
- restore %g0, -1, %o0;
+ restore %g0, -1, %o0; \
+ .previous;
#else
-# define 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;
+# 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) \
@@ -82,10 +97,9 @@ __sparc64.get_pic.l7: \
ENTRY(name); \
LOADSYSCALL(syscall_name); \
ta 0x6d; \
- bcc,pt %xcc, 1f; \
+ bcs,pn %xcc, __syscall_error_handler; \
nop; \
- SYSCALL_ERROR_HANDLER; \
-1:
+ SYSCALL_ERROR_HANDLER
#undef PSEUDO_END
#define PSEUDO_END(name) \