This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: Fix sparc localplt and C++ type testsuite failures.


This patch addresses the localplt and C++ type checking failures on
sparc.

The first part of the change reworks how system calls are emitted on
sparc.  Previously we emitted stubs on the error path, out of line,
that invoked a call to __errno_location from the inline asm.  This
doesn't get wrapped and renamed properly, so we'd get bogus non-local
PLT entries for __errno_location in the shared libraries.

I tried to wrap them using CPP string pasting and other tricks to get
the symbol name right in these inline assembler strings, but the
amount of ifdefs became messy, complicated, and after trying for two
straight days I could not get all cases to work correctly all at once.

Therefore, I decided to rewrite these things to use the style and
methods employed by the powerpc port.  I record the condition code
state in register %o2, and this is what goes into the "err" variable
used by the macros.  The outer code checks that to see if we got an
error or not, and acts appropriately.

I did, in fact, consider the reasons why we used the out-of-line stubs
and after looking over the code I conclude that in practice those
reasons no longer apply these days.

The idea was to make it so that code which called the inline syscall
macros would not need a stack frame, and thus could still be a leaf
function.  In the stub we grab a register window around the
__errno_location call.  We also move these stubs out of line into a
seperate section.

But when I looked at the code using this stuff, it either:

1) Made other calls or made stack references, such that a stack
   frame was needed anyways.

2) Referenced global data, and therefore need to setup the PIC
   register, which also requires allocation of a stack frame.

And also, the initial-exec TLS sequence emitted by the __set_error()
macro C code is about the same size as the special stubs we had on
sparc.  Futhermore, GCC moves the code out of line for us because of
the use of __builtin_expect() in the error case.

Next, I went through the long-double-128bit math library code that was
calling foo() instead of __foo() routines inside of libm.so, and fixed
those up.

Also, the sparc64 brk assembler implementations were very difficult to
rework to get rid of the localplt references.  I am rather certain
that this code was written in assembler this way when we didn't have
the inline syscall macros.  Therefore, I removed the brk assembler and
we instead make use the x86_64 C implementation.

Subsequently, I added the necessary localplt data files for sparc and
sparc64.

Finally, I added c++ type data files for the various sparc64*
variants.

Tested on sparcv9b-linux-gnu and sparc64b-linux-gnu

Please apply, thanks.

toplevel

2008-05-07  David S. Miller  <davem@davemloft.net>

	* sysdeps/ieee754/ldbl-128/e_j0l.c (__ieee751_j0l): Use	__finitel.
	(__ieee754_y0l): Likewise.
	* sysdeps/ieee754/ldbl-128/e_j1l.c (__ieee754_j1l): Likewise.
	(__ieee754_y1l): Likewise.
	* sysdeps/ieee754/ldbl-128/s_expm1l.c (__expm1l): Use __ldexpl.
	* sysdeps/ieee754/ldbl-128/s_log1pl.c: Kill bogus prototypes for
	frexpl and ldexpl.  math_private.h provides then and the latter
	is not even used.
	(__log1pl): Use __frexpl.
	* sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S: Use HIDDEN_JUMPTARGET.
	* sysdeps/unix/sysv/linux/sparc/sparc64/brk.S: Delete.
	* sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S: Delete.
	* sysdeps/unix/sysv/linux/sparc/sparc64/brk.c: New file.
	* sysdeps/unix/sysv/linux/sparc/sysdep.h: Rewrite syscall macros to set the
	errno inline instead of using stubs that call __errno_location.  We transfer
	the condition code setting out of the inline asm using %o2.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (__SYSCALL_STRING,
	__CLONE_SYSCALL_STRING): Update to match those changes.
	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h (__SYSCALL_STRING,
	__CLONE_SYSCALL_STRING): Likewise.
	* scripts/data/localplt-sparc-linux-gnu.data: New file.
	* scripts/data/localplt-sparc64-linux-gnu.data: Likewise.
	* scripts/data/localplt-sparc64b-linux-gnu.data: Likewise.
	* scripts/data/localplt-sparc64v-linux-gnu.data: Likewise.
	* scripts/data/localplt-sparc64v2-linux-gnu.data: Likewise.
	* scripts/data/c++-types-sparc64b-linux-gnu.data: Likewise.
	* scripts/data/c++-types-sparc64v-linux-gnu.data: Likewise.
	* scripts/data/c++-types-sparc64v2-linux-gnu.data: Likewise.

nptl/

2008-05-07  David S. Miller  <davem@davemloft.net>

	* nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_futex_timed_wait,
	lll_futex_wake): Check INTERNAL_SYSCALL return for errors using
	INTERNAL_SYSCALL_ERROR_P.
---
 nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h  |    4 +-
 scripts/data/c++-types-sparc64b-linux-gnu.data     |   67 ++++++
 scripts/data/c++-types-sparc64v-linux-gnu.data     |   67 ++++++
 scripts/data/c++-types-sparc64v2-linux-gnu.data    |   67 ++++++
 scripts/data/localplt-sparc-linux-gnu.data         |   18 ++
 scripts/data/localplt-sparc64-linux-gnu.data       |   20 ++
 scripts/data/localplt-sparc64b-linux-gnu.data      |   20 ++
 scripts/data/localplt-sparc64v-linux-gnu.data      |   20 ++
 scripts/data/localplt-sparc64v2-linux-gnu.data     |   20 ++
 sysdeps/ieee754/ldbl-128/e_j0l.c                   |    4 +-
 sysdeps/ieee754/ldbl-128/e_j1l.c                   |    4 +-
 sysdeps/ieee754/ldbl-128/s_expm1l.c                |    2 +-
 sysdeps/ieee754/ldbl-128/s_log1pl.c                |    9 +-
 sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S |    2 +-
 sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h     |   51 ++----
 sysdeps/unix/sysv/linux/sparc/sparc64/brk.S        |   98 ---------
 sysdeps/unix/sysv/linux/sparc/sparc64/brk.c        |    1 +
 sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S     |    1 -
 sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h     |   39 ++---
 sysdeps/unix/sysv/linux/sparc/sysdep.h             |  217 +++++++++-----------
 20 files changed, 435 insertions(+), 296 deletions(-)
 create mode 100644 scripts/data/c++-types-sparc64b-linux-gnu.data
 create mode 100644 scripts/data/c++-types-sparc64v-linux-gnu.data
 create mode 100644 scripts/data/c++-types-sparc64v2-linux-gnu.data
 create mode 100644 scripts/data/localplt-sparc-linux-gnu.data
 create mode 100644 scripts/data/localplt-sparc64-linux-gnu.data
 create mode 100644 scripts/data/localplt-sparc64b-linux-gnu.data
 create mode 100644 scripts/data/localplt-sparc64v-linux-gnu.data
 create mode 100644 scripts/data/localplt-sparc64v2-linux-gnu.data
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/brk.c
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S

diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 754a0f5..0fd9c48 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -82,7 +82,7 @@
     __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
 			      __lll_private_flag (FUTEX_WAIT, private),	      \
 			      (val), (timespec));			      \
-    __ret;								      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret;		      \
   })
 
 #define lll_futex_wake(futexp, nr, private) \
@@ -93,7 +93,7 @@
     __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
 			      __lll_private_flag (FUTEX_WAKE, private),	      \
 			      (nr), 0);					      \
-    __ret;								      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret;		      \
   })
 
 /* Returns non-zero if error happened, zero if success.  */
diff --git a/scripts/data/c++-types-sparc64b-linux-gnu.data b/scripts/data/c++-types-sparc64b-linux-gnu.data
new file mode 100644
index 0000000..5a04f49
--- /dev/null
+++ b/scripts/data/c++-types-sparc64b-linux-gnu.data
@@ -0,0 +1,67 @@
+blkcnt64_t:l
+blkcnt_t:l
+blksize_t:l
+caddr_t:Pc
+clockid_t:i
+clock_t:l
+daddr_t:i
+dev_t:m
+fd_mask:l
+fsblkcnt64_t:m
+fsblkcnt_t:m
+fsfilcnt64_t:m
+fsfilcnt_t:m
+fsid_t:8__fsid_t
+gid_t:j
+id_t:j
+ino64_t:m
+ino_t:m
+int16_t:s
+int32_t:i
+int64_t:l
+int8_t:a
+intptr_t:l
+key_t:i
+loff_t:l
+mode_t:j
+nlink_t:j
+off64_t:l
+off_t:l
+pid_t:i
+pthread_attr_t:14pthread_attr_t
+pthread_barrier_t:17pthread_barrier_t
+pthread_barrierattr_t:21pthread_barrierattr_t
+pthread_cond_t:14pthread_cond_t
+pthread_condattr_t:18pthread_condattr_t
+pthread_key_t:j
+pthread_mutex_t:15pthread_mutex_t
+pthread_mutexattr_t:19pthread_mutexattr_t
+pthread_once_t:i
+pthread_rwlock_t:16pthread_rwlock_t
+pthread_rwlockattr_t:20pthread_rwlockattr_t
+pthread_spinlock_t:i
+pthread_t:m
+quad_t:l
+register_t:l
+rlim64_t:m
+rlim_t:m
+sigset_t:10__sigset_t
+size_t:m
+socklen_t:j
+ssize_t:l
+suseconds_t:i
+time_t:l
+u_char:h
+uid_t:j
+uint:j
+u_int:j
+u_int16_t:t
+u_int32_t:j
+u_int64_t:m
+u_int8_t:h
+ulong:m
+u_long:m
+u_quad_t:m
+useconds_t:j
+ushort:t
+u_short:t
diff --git a/scripts/data/c++-types-sparc64v-linux-gnu.data b/scripts/data/c++-types-sparc64v-linux-gnu.data
new file mode 100644
index 0000000..5a04f49
--- /dev/null
+++ b/scripts/data/c++-types-sparc64v-linux-gnu.data
@@ -0,0 +1,67 @@
+blkcnt64_t:l
+blkcnt_t:l
+blksize_t:l
+caddr_t:Pc
+clockid_t:i
+clock_t:l
+daddr_t:i
+dev_t:m
+fd_mask:l
+fsblkcnt64_t:m
+fsblkcnt_t:m
+fsfilcnt64_t:m
+fsfilcnt_t:m
+fsid_t:8__fsid_t
+gid_t:j
+id_t:j
+ino64_t:m
+ino_t:m
+int16_t:s
+int32_t:i
+int64_t:l
+int8_t:a
+intptr_t:l
+key_t:i
+loff_t:l
+mode_t:j
+nlink_t:j
+off64_t:l
+off_t:l
+pid_t:i
+pthread_attr_t:14pthread_attr_t
+pthread_barrier_t:17pthread_barrier_t
+pthread_barrierattr_t:21pthread_barrierattr_t
+pthread_cond_t:14pthread_cond_t
+pthread_condattr_t:18pthread_condattr_t
+pthread_key_t:j
+pthread_mutex_t:15pthread_mutex_t
+pthread_mutexattr_t:19pthread_mutexattr_t
+pthread_once_t:i
+pthread_rwlock_t:16pthread_rwlock_t
+pthread_rwlockattr_t:20pthread_rwlockattr_t
+pthread_spinlock_t:i
+pthread_t:m
+quad_t:l
+register_t:l
+rlim64_t:m
+rlim_t:m
+sigset_t:10__sigset_t
+size_t:m
+socklen_t:j
+ssize_t:l
+suseconds_t:i
+time_t:l
+u_char:h
+uid_t:j
+uint:j
+u_int:j
+u_int16_t:t
+u_int32_t:j
+u_int64_t:m
+u_int8_t:h
+ulong:m
+u_long:m
+u_quad_t:m
+useconds_t:j
+ushort:t
+u_short:t
diff --git a/scripts/data/c++-types-sparc64v2-linux-gnu.data b/scripts/data/c++-types-sparc64v2-linux-gnu.data
new file mode 100644
index 0000000..5a04f49
--- /dev/null
+++ b/scripts/data/c++-types-sparc64v2-linux-gnu.data
@@ -0,0 +1,67 @@
+blkcnt64_t:l
+blkcnt_t:l
+blksize_t:l
+caddr_t:Pc
+clockid_t:i
+clock_t:l
+daddr_t:i
+dev_t:m
+fd_mask:l
+fsblkcnt64_t:m
+fsblkcnt_t:m
+fsfilcnt64_t:m
+fsfilcnt_t:m
+fsid_t:8__fsid_t
+gid_t:j
+id_t:j
+ino64_t:m
+ino_t:m
+int16_t:s
+int32_t:i
+int64_t:l
+int8_t:a
+intptr_t:l
+key_t:i
+loff_t:l
+mode_t:j
+nlink_t:j
+off64_t:l
+off_t:l
+pid_t:i
+pthread_attr_t:14pthread_attr_t
+pthread_barrier_t:17pthread_barrier_t
+pthread_barrierattr_t:21pthread_barrierattr_t
+pthread_cond_t:14pthread_cond_t
+pthread_condattr_t:18pthread_condattr_t
+pthread_key_t:j
+pthread_mutex_t:15pthread_mutex_t
+pthread_mutexattr_t:19pthread_mutexattr_t
+pthread_once_t:i
+pthread_rwlock_t:16pthread_rwlock_t
+pthread_rwlockattr_t:20pthread_rwlockattr_t
+pthread_spinlock_t:i
+pthread_t:m
+quad_t:l
+register_t:l
+rlim64_t:m
+rlim_t:m
+sigset_t:10__sigset_t
+size_t:m
+socklen_t:j
+ssize_t:l
+suseconds_t:i
+time_t:l
+u_char:h
+uid_t:j
+uint:j
+u_int:j
+u_int16_t:t
+u_int32_t:j
+u_int64_t:m
+u_int8_t:h
+ulong:m
+u_long:m
+u_quad_t:m
+useconds_t:j
+ushort:t
+u_short:t
diff --git a/scripts/data/localplt-sparc-linux-gnu.data b/scripts/data/localplt-sparc-linux-gnu.data
new file mode 100644
index 0000000..5ceed16
--- /dev/null
+++ b/scripts/data/localplt-sparc-linux-gnu.data
@@ -0,0 +1,18 @@
+libc.so: _Q_add
+libc.so: _Q_div
+libc.so: _Q_feq
+libc.so: _Q_fge
+libc.so: _Q_fle
+libc.so: _Q_flt
+libc.so: _Q_fne
+libc.so: _Q_itoq
+libc.so: _Q_mul
+libc.so: _Q_sub
+libc.so: _Unwind_Find_FDE
+libc.so: calloc
+libc.so: ffs
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+libm.so: matherr
diff --git a/scripts/data/localplt-sparc64-linux-gnu.data b/scripts/data/localplt-sparc64-linux-gnu.data
new file mode 100644
index 0000000..5e6e42d
--- /dev/null
+++ b/scripts/data/localplt-sparc64-linux-gnu.data
@@ -0,0 +1,20 @@
+libc.so: _Qp_add
+libc.so: _Qp_div
+libc.so: _Qp_feq
+libc.so: _Qp_fge
+libc.so: _Qp_fle
+libc.so: _Qp_flt
+libc.so: _Qp_fne
+libc.so: _Qp_itoq
+libc.so: _Qp_mul
+libc.so: _Qp_qtod
+libc.so: _Qp_sub
+libc.so: _Qp_xtoq
+libc.so: _Unwind_Find_FDE
+libc.so: calloc
+libc.so: ffs
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+libm.so: matherr
diff --git a/scripts/data/localplt-sparc64b-linux-gnu.data b/scripts/data/localplt-sparc64b-linux-gnu.data
new file mode 100644
index 0000000..5e6e42d
--- /dev/null
+++ b/scripts/data/localplt-sparc64b-linux-gnu.data
@@ -0,0 +1,20 @@
+libc.so: _Qp_add
+libc.so: _Qp_div
+libc.so: _Qp_feq
+libc.so: _Qp_fge
+libc.so: _Qp_fle
+libc.so: _Qp_flt
+libc.so: _Qp_fne
+libc.so: _Qp_itoq
+libc.so: _Qp_mul
+libc.so: _Qp_qtod
+libc.so: _Qp_sub
+libc.so: _Qp_xtoq
+libc.so: _Unwind_Find_FDE
+libc.so: calloc
+libc.so: ffs
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+libm.so: matherr
diff --git a/scripts/data/localplt-sparc64v-linux-gnu.data b/scripts/data/localplt-sparc64v-linux-gnu.data
new file mode 100644
index 0000000..5e6e42d
--- /dev/null
+++ b/scripts/data/localplt-sparc64v-linux-gnu.data
@@ -0,0 +1,20 @@
+libc.so: _Qp_add
+libc.so: _Qp_div
+libc.so: _Qp_feq
+libc.so: _Qp_fge
+libc.so: _Qp_fle
+libc.so: _Qp_flt
+libc.so: _Qp_fne
+libc.so: _Qp_itoq
+libc.so: _Qp_mul
+libc.so: _Qp_qtod
+libc.so: _Qp_sub
+libc.so: _Qp_xtoq
+libc.so: _Unwind_Find_FDE
+libc.so: calloc
+libc.so: ffs
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+libm.so: matherr
diff --git a/scripts/data/localplt-sparc64v2-linux-gnu.data b/scripts/data/localplt-sparc64v2-linux-gnu.data
new file mode 100644
index 0000000..5e6e42d
--- /dev/null
+++ b/scripts/data/localplt-sparc64v2-linux-gnu.data
@@ -0,0 +1,20 @@
+libc.so: _Qp_add
+libc.so: _Qp_div
+libc.so: _Qp_feq
+libc.so: _Qp_fge
+libc.so: _Qp_fle
+libc.so: _Qp_flt
+libc.so: _Qp_fne
+libc.so: _Qp_itoq
+libc.so: _Qp_mul
+libc.so: _Qp_qtod
+libc.so: _Qp_sub
+libc.so: _Qp_xtoq
+libc.so: _Unwind_Find_FDE
+libc.so: calloc
+libc.so: ffs
+libc.so: free
+libc.so: malloc
+libc.so: memalign
+libc.so: realloc
+libm.so: matherr
diff --git a/sysdeps/ieee754/ldbl-128/e_j0l.c b/sysdeps/ieee754/ldbl-128/e_j0l.c
index f235372..bcd57e2 100644
--- a/sysdeps/ieee754/ldbl-128/e_j0l.c
+++ b/sysdeps/ieee754/ldbl-128/e_j0l.c
@@ -679,7 +679,7 @@ __ieee754_j0l (long double x)
 {
   long double xx, xinv, z, p, q, c, s, cc, ss;
 
-  if (! finitel (x))
+  if (! __finitel (x))
     {
       if (x != x)
 	return x;
@@ -816,7 +816,7 @@ long double
 {
   long double xx, xinv, z, p, q, c, s, cc, ss;
 
-  if (! finitel (x))
+  if (! __finitel (x))
     {
       if (x != x)
 	return x;
diff --git a/sysdeps/ieee754/ldbl-128/e_j1l.c b/sysdeps/ieee754/ldbl-128/e_j1l.c
index 7ec073d..7b73e2e 100644
--- a/sysdeps/ieee754/ldbl-128/e_j1l.c
+++ b/sysdeps/ieee754/ldbl-128/e_j1l.c
@@ -685,7 +685,7 @@ __ieee754_j1l (long double x)
 {
   long double xx, xinv, z, p, q, c, s, cc, ss;
 
-  if (! finitel (x))
+  if (! __finitel (x))
     {
       if (x != x)
 	return x;
@@ -823,7 +823,7 @@ __ieee754_y1l (long double x)
 {
   long double xx, xinv, z, p, q, c, s, cc, ss;
 
-  if (! finitel (x))
+  if (! __finitel (x))
     {
       if (x != x)
 	return x;
diff --git a/sysdeps/ieee754/ldbl-128/s_expm1l.c b/sysdeps/ieee754/ldbl-128/s_expm1l.c
index f373e1e..78bbe65 100644
--- a/sysdeps/ieee754/ldbl-128/s_expm1l.c
+++ b/sysdeps/ieee754/ldbl-128/s_expm1l.c
@@ -153,7 +153,7 @@ __expm1l (long double x)
   exp(x) - 1 = 2^k (qx + 1) - 1
              = 2^k qx + 2^k - 1.  */
 
-  px = ldexpl (1.0L, k);
+  px = __ldexpl (1.0L, k);
   x = px * qx + (px - 1.0);
   return x;
 }
diff --git a/sysdeps/ieee754/ldbl-128/s_log1pl.c b/sysdeps/ieee754/ldbl-128/s_log1pl.c
index 64d5146..defbe76 100644
--- a/sysdeps/ieee754/ldbl-128/s_log1pl.c
+++ b/sysdeps/ieee754/ldbl-128/s_log1pl.c
@@ -120,13 +120,6 @@ static const long double maxlog = 1.1356523406294143949491931077970764891253E4L;
 static const long double big = 2e4932L;
 static const long double zero = 0.0L;
 
-#if 1
-/* Make sure these are prototyped.  */
-long double frexpl (long double, int *);
-long double ldexpl (long double, int);
-#endif
-
-
 long double
 __log1pl (long double xm1)
 {
@@ -160,7 +153,7 @@ __log1pl (long double xm1)
   /* Separate mantissa from exponent.  */
 
   /* Use frexp used so that denormal numbers will be handled properly.  */
-  x = frexpl (x, &e);
+  x = __frexpl (x, &e);
 
   /* Logarithm using log(x) = z + z^3 P(z^2)/Q(z^2),
      where z = 2(x-1)/x+1).  */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S b/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S
index 33e40ac..a38cd30 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S
@@ -111,7 +111,7 @@ ENTRY(__start_context)
 	 mov	%g1, %o0
 	/* If this returns (which can happen if the syscall fails) we'll
 	   exit the program with the return error value (-1).  */
-1:	call	exit
+1:	call	HIDDEN_JUMPTARGET(exit)
 	 nop
 	/* The 'exit' call should never return.  In case it does cause
 	   the process to terminate.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
index c808a97..ef72e03 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
@@ -89,44 +89,23 @@ ENTRY(name);					\
 
 #else  /* __ASSEMBLER__ */
 
-#define __SYSCALL_STRING						\
-	"ta	0x10;"							\
-	"bcs	2f;"							\
-	" nop;"								\
-	"1:"								\
-	".subsection 2;"						\
-	"2:"								\
-	"save	%%sp, -192, %%sp;"					\
-	"call	__errno_location;"					\
-	" nop;"								\
-	"st	%%i0,[%%o0];"						\
-	"ba	1b;"							\
-	" restore %%g0, -1, %%o0;"					\
-	".previous;"
-
-#define __CLONE_SYSCALL_STRING						\
-	"ta	0x10;"							\
-	"bcs	2f;"							\
-	" sub	%%o1, 1, %%o1;"						\
-	"and	%%o0, %%o1, %%o0;"					\
-	"1:"								\
-	".subsection 2;"						\
-	"2:"								\
-	"save	%%sp, -192, %%sp;"					\
-	"call	__errno_location;"					\
-	" nop;"								\
-	"st	%%i0, [%%o0];"						\
-	"ba	1b;"							\
-	" restore %%g0, -1, %%o0;"					\
-	".previous;"
-
-#define __INTERNAL_SYSCALL_STRING					\
-	"ta	0x10;"							\
-	"bcs,a	1f;"							\
-	" sub	%%g0, %%o0, %%o0;"					\
+#define __SYSCALL_STRING			\
+	"ta	0x10;"				\
+	"clr	%%o2;"				\
+	"bcs,a	1f;"				\
+	" mov	1, %%o2;"			\
 	"1:"
 
-#define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6",		\
+#define __CLONE_SYSCALL_STRING			\
+	"ta	0x10;"				\
+	"clr	%%o2;"				\
+	"bcs,a	1f;"				\
+	" mov	1, %%o2;"			\
+	"sub	%%o1, 1, %%o1;"			\
+	"and	%%o0, %%o1, %%o0;"		\
+	"1:"
+
+#define __SYSCALL_CLOBBERS \
 	"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",			\
 	"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",		\
 	"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",		\
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
deleted file mode 100644
index 134ce78..0000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
-
-   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.  */
-
-/* __brk is a special syscall under Linux since it never returns an
-   error.  Instead, the error condition is indicated by returning the old
-   break value (instead of the new, requested one).  */
-
-#include <sysdep.h>
-#define _ERRNO_H
-#include <bits/errno.h>
-
-#ifdef PIC
-.section .bss
-	.align 8
-	.globl __curbrk
-__curbrk: .skip 8
-	.type __curbrk,@object
-	.size __curbrk,8
-#else
-.common __curbrk, 8, 8
-#endif
-
-	.text
-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
-2:	or	%l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
-	add	%l7, %o7, %l7
-#endif
-
-	LOADSYSCALL(brk)
-	mov	%i0, %o0
-
-	ta	0x6d
-
-	/* All the ways we can fail... */
-	bcs,pn	%xcc, .Lerr1
-	 nop
-	brz,pt	%i0, .Lok
-	 subcc	%i0, %o0, %g0
-	bne,pn	%xcc, .Lerr0
-	 nop
-
-	/* Update __curbrk and return cleanly.  */
-.Lok:	sethi	%hi(__curbrk), %g1
-	or	%g1, %lo(__curbrk), %g1
-#ifdef PIC
-	ldx	[%l7+%g1], %g1
-#endif
-	stx	%o0, [%g1]
-	mov	%g0, %i0
-
-	/* Don't use "ret" cause the preprocessor will eat it.  */
-	jmpl	%i7+8, %g0
-	 restore
-	
-	/* What a horrible way to die.  */
-.Lerr0:	set	ENOMEM, %o0
-.Lerr1:
-#ifndef _LIBC_REENTRANT
-	sethi	%hi(errno), %g1
-	or	%g1, %lo(errno), %g1
-#ifdef PIC
-	ldx	[%l7+%g1], %g1
-#endif
-	st	%o0, [%g1]
-#else
-	call	__errno_location
-	 mov	%o0,%l1
-	st	%l1, [%o0]
-#endif
-	sub	%g0, 1, %i0
-	jmpl	%i7+8, %g0
-	 restore
-END (__brk)
-
-weak_alias (__brk, brk)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.c b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.c
new file mode 100644
index 0000000..1577ab5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.c
@@ -0,0 +1 @@
+#include "../../x86_64/brk.c"
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S b/sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S
deleted file mode 100644
index eeb9654..0000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/dl-brk.S
+++ /dev/null
@@ -1 +0,0 @@
-#include <brk.S>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
index f156f92..77611c8 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
@@ -106,36 +106,23 @@ ENTRY(name);					\
 
 #else  /* __ASSEMBLER__ */
 
-#define __SYSCALL_STRING						\
-	"ta	0x6d;"							\
-	"bcc,pt	%%xcc, 1f;"						\
-	" nop;"								\
-	"save	%%sp, -192, %%sp;"					\
-	"call	__errno_location;"					\
-	" nop;"								\
-	"st	%%i0,[%%o0];"						\
-	"restore %%g0, -1, %%o0;"					\
+#define __SYSCALL_STRING			\
+	"ta		0x6d;"			\
+	"clr		%%o2;"			\
+	"bcs,a,pn	%%xcc, 1f;"		\
+	" mov		1, %%o2;"		\
 	"1:"
 
-#define __CLONE_SYSCALL_STRING						\
-	"ta	0x6d;"							\
-	"bcc,pt	%%xcc, 1f;"						\
-	" sub	%%o1, 1, %%o1;"						\
-	"save	%%sp, -192, %%sp;"					\
-	"call	__errno_location;"					\
-	" mov	-1, %%i1;"						\
-	"st	%%i0,[%%o0];"						\
-	"restore %%g0, -1, %%o0;"					\
-	"1:"								\
-	"and	%%o0, %%o1, %%o0"
-
-#define __INTERNAL_SYSCALL_STRING					\
-	"ta	0x6d;"							\
-	"bcs,a,pt %%xcc, 1f;"						\
-	" sub	%%g0, %%o0, %%o0;"					\
+#define __CLONE_SYSCALL_STRING			\
+	"ta		0x6d;"			\
+	"clr		%%o2;"			\
+	"bcs,a,pn	%%xcc, 1f;"		\
+	" mov		1, %%o2;"		\
+	"sub		%%o1, 1, %%o1;"		\
+	"and		%%o0, %%o1, %%o0;"	\
 	"1:"
 
-#define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6",		\
+#define __SYSCALL_CLOBBERS \
 	"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",			\
 	"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",		\
 	"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",		\
diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sysdep.h
index 101638a..254b3eb 100644
--- a/sysdeps/unix/sysv/linux/sparc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sysdep.h
@@ -20,135 +20,114 @@
 #ifndef _LINUX_SPARC_SYSDEP_H
 #define _LINUX_SPARC_SYSDEP_H 1
 
-#undef INLINE_SYSCALL
-#define INLINE_SYSCALL(name, nr, args...) \
-  inline_syscall##nr(__SYSCALL_STRING, __NR_##name, args)
-
 #undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
-
-#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
-  inline_syscall##nr(__INTERNAL_SYSCALL_STRING, __NR_##name, args)
-
-#undef INTERNAL_SYSCALL_NCS
-#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
-  inline_syscall##nr(__INTERNAL_SYSCALL_STRING, name, args)
+# define INTERNAL_SYSCALL_DECL(err) long int err
 
 #undef INTERNAL_SYSCALL_ERROR_P
 #define INTERNAL_SYSCALL_ERROR_P(val, err) \
-  ((unsigned long) (val) >= -515L)
-
-#undef INTERNAL_SYSCALL_ERRNO
-#define INTERNAL_SYSCALL_ERRNO(val, err)	(-(val))
-
-#define inline_syscall0(string,name,dummy...)				\
-({									\
-	register long __o0 __asm__ ("o0");				\
-	register long __g1 __asm__ ("g1") = name;			\
-	__asm __volatile (string : "=r" (__g1), "=r" (__o0) :		\
-			  "0" (__g1) :					\
-			  __SYSCALL_CLOBBERS);				\
-	__o0;								\
-})
-
-#define inline_syscall1(string,name,arg1)				\
-({									\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __g1 __asm__ ("g1") = name;			\
-	__asm __volatile (string : "=r" (__g1), "=r" (__o0) :		\
-			  "0" (__g1), "1" (__o0) :			\
-			  __SYSCALL_CLOBBERS);				\
-	__o0;								\
-})
-
-#define inline_syscall2(string,name,arg1,arg2)				\
-({									\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __g1 __asm__ ("g1") = name;			\
-	__asm __volatile (string : "=r" (__g1), "=r" (__o0) :		\
-			  "0" (__g1), "1" (__o0), "r" (__o1) :		\
-			  __SYSCALL_CLOBBERS);				\
-	__o0;								\
-})
+  ((void) (val), __builtin_expect ((err) != 0, 0))
+
+# undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err)     (val)
+
+# define LOADARGS_0(name, dummy) \
+	g1 = name
+# define LOADARGS_1(name, __arg1) \
+	long int arg1 = (long int) (__arg1); \
+	LOADARGS_0(name, 0); \
+	o0 = arg1
+# define LOADARGS_2(name, __arg1, __arg2) \
+	long int arg2 = (long int) (__arg2); \
+	LOADARGS_1(name, __arg1); \
+	o1 = arg2
+# define LOADARGS_3(name, __arg1, __arg2, __arg3)   \
+	long int arg3 = (long int) (__arg3); \
+	LOADARGS_2(name, __arg1, __arg2);     \
+	o2 = arg3
+# define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
+	long int arg4 = (long int) (__arg4); \
+	LOADARGS_3(name, __arg1, __arg2, __arg3); \
+	o3 = arg4
+# define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
+	long int arg5 = (long int) (__arg5); \
+	LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
+	o4 = arg5
+# define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
+	long int arg6 = (long int) (__arg6); \
+	LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
+	o5 = arg6
+
+# define ASM_INPUT_0 "0" (g1)
+# define ASM_INPUT_1 ASM_INPUT_0, "1" (o0)
+# define ASM_INPUT_2 ASM_INPUT_1, "2" (o1)
+# define ASM_INPUT_3 ASM_INPUT_2, "3" (o2)
+# define ASM_INPUT_4 ASM_INPUT_3, "4" (o3)
+# define ASM_INPUT_5 ASM_INPUT_4, "5" (o4)
+# define ASM_INPUT_6 ASM_INPUT_5, "6" (o5)
+
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...)			\
+  ({									\
+    register long int g1  __asm__ ("g1");				\
+    register long int o0  __asm__ ("o0");				\
+    register long int o1  __asm__ ("o1");				\
+    register long int o2  __asm__ ("o2");				\
+    register long int o3  __asm__ ("o3");				\
+    register long int o4  __asm__ ("o4");				\
+    register long int o5  __asm__ ("o5");				\
+    LOADARGS_##nr(name, args);						\
+    __asm__ __volatile__						\
+      (__SYSCALL_STRING							\
+       : "=&r" (g1),							\
+	 "=&r" (o0), "=&r" (o1), "=&r" (o2),  "=&r" (o3),  "=&r" (o4),	\
+	 "=&r" (o5)							\
+       : ASM_INPUT_##nr							\
+       : __SYSCALL_CLOBBERS);						\
+    err = o2;								\
+    o0;									\
+  })
+
+# undef INTERNAL_SYSCALL
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
+  INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
 
-#define inline_syscall3(string,name,arg1,arg2,arg3)			\
-({									\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __g1 __asm__ ("g1") = name;			\
-	__asm __volatile (string : "=r" (__g1), "=r" (__o0) :		\
-			  "0" (__g1), "1" (__o0), "r" (__o1),		\
-			  "r" (__o2) :					\
-			  __SYSCALL_CLOBBERS);				\
-	__o0;								\
-})
-
-#define inline_syscall4(string,name,arg1,arg2,arg3,arg4)		\
-({									\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __o3 __asm__ ("o3") = (long)(arg4);		\
-	register long __g1 __asm__ ("g1") = name;			\
-	__asm __volatile (string : "=r" (__g1), "=r" (__o0) :		\
-			  "0" (__g1), "1" (__o0), "r" (__o1),		\
-			  "r" (__o2), "r" (__o3) :			\
-			  __SYSCALL_CLOBBERS);				\
-	__o0;								\
-})
-
-#define inline_syscall5(string,name,arg1,arg2,arg3,arg4,arg5)		\
-({									\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __o3 __asm__ ("o3") = (long)(arg4);		\
-	register long __o4 __asm__ ("o4") = (long)(arg5);		\
-	register long __g1 __asm__ ("g1") = name;			\
-	__asm __volatile (string : "=r" (__g1), "=r" (__o0) :		\
-			  "0" (__g1), "1" (__o0), "r" (__o1),		\
-			  "r" (__o2), "r" (__o3), "r" (__o4) :		\
-			  __SYSCALL_CLOBBERS);				\
-	__o0;								\
-})
-
-#define inline_syscall6(string,name,arg1,arg2,arg3,arg4,arg5,arg6)	\
-({									\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __o3 __asm__ ("o3") = (long)(arg4);		\
-	register long __o4 __asm__ ("o4") = (long)(arg5);		\
-	register long __o5 __asm__ ("o5") = (long)(arg6);		\
-	register long __g1 __asm__ ("g1") = name;			\
-	__asm __volatile (string : "=r" (__g1), "=r" (__o0) :		\
-			  "0" (__g1), "1" (__o0), "r" (__o1),		\
-			  "r" (__o2), "r" (__o3), "r" (__o4),		\
-			  "r" (__o5) :					\
-			  __SYSCALL_CLOBBERS);				\
-	__o0;								\
-})
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+  ({									\
+    INTERNAL_SYSCALL_DECL (sc_err);					\
+    long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args);	\
+    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))			\
+      {									\
+	__set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));		\
+	sc_ret = -1L;							\
+      }									\
+    sc_ret;								\
+  })
 
 #define INLINE_CLONE_SYSCALL(arg1,arg2,arg3,arg4,arg5)			\
 ({									\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __o3 __asm__ ("o3") = (long)(arg4);		\
-	register long __o4 __asm__ ("o4") = (long)(arg5);		\
-	register long __g1 __asm__ ("g1") = __NR_clone;			\
-	__asm __volatile (__CLONE_SYSCALL_STRING :			\
-			  "=r" (__g1), "=r" (__o0), "=r" (__o1)	:	\
-			  "0" (__g1), "1" (__o0), "2" (__o1),		\
-			  "r" (__o2), "r" (__o3), "r" (__o4) :		\
-			  __SYSCALL_CLOBBERS);				\
-	__o0;								\
+    register long int g1  __asm__ ("g1");				\
+    register long int o0  __asm__ ("o0");				\
+    register long int o1  __asm__ ("o1");				\
+    register long int o2  __asm__ ("o2");				\
+    register long int o3  __asm__ ("o3");				\
+    register long int o4  __asm__ ("o4");				\
+    register long int o5  __asm__ ("o5");				\
+    LOADARGS_5(__NR_clone, arg1, arg2, arg3, arg4, arg5);		\
+    __asm __volatile__							\
+      (__CLONE_SYSCALL_STRING						\
+       : "=&r" (g1),							\
+	 "=&r" (o0), "=&r" (o1), "=&r" (o2),  "=&r" (o3),  "=&r" (o4),	\
+	 "=&r" (o5)							\
+       : ASM_INPUT_5							\
+       : __SYSCALL_CLOBBERS);						\
+    if (INTERNAL_SYSCALL_ERROR_P (o0, o2))				\
+      {									\
+	__set_errno (INTERNAL_SYSCALL_ERRNO (o0, o2));			\
+	o0 = -1L;							\
+      }									\
+    o0;									\
 })
 
-
 #ifdef __ASSEMBLER__
 # define JUMPTARGET(sym) sym
 #endif
-- 
1.5.5.1.57.g5909c


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]