[PATCH]: Fix sparc localplt and C++ type testsuite failures.
David Miller
davem@davemloft.net
Mon May 19 20:08:00 GMT 2008
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
>
More information about the Libc-alpha
mailing list