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]

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


From: David Miller <davem@davemloft.net>
Date: Thu, 08 May 2008 16:02:19 -0700 (PDT)

Ping?

> [ repost with the non-sparc bits removed ]
> 
> 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.
> 
> 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-08  David S. Miller  <davem@davemloft.net>
> 
> 	* 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-08  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/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 +++++++++-----------
>  16 files changed, 429 insertions(+), 283 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/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]