diff options
| author | austinf <austinf@localhost> | 2009-03-19 07:29:30 +0000 | 
|---|---|---|
| committer | austinf <austinf@localhost> | 2009-03-19 07:29:30 +0000 | 
| commit | 2ea44632aac286a927069a1fb1f979db23c0b3c4 (patch) | |
| tree | 405585f334c03e95c106924c03ed4642f80874a0 /libpthread/nptl/sysdeps/unix/sysv | |
| parent | d38a60ef0325122761dea450cc163ac036d896e7 (diff) | |
| download | uClibc-alpine-2ea44632aac286a927069a1fb1f979db23c0b3c4.tar.bz2 uClibc-alpine-2ea44632aac286a927069a1fb1f979db23c0b3c4.tar.xz  | |
sparc32 nptl functional
 * pulled updated asm and headers from glibc for sparc32 
 * probably no cancellation support yet
 * no shared TLS relocs yet, since ldso is hosed on sparc still
 
 note: didn't use TARGET_SUBARCH method of includes since that would cause 
 other parts of libc to fail currently. Will need to be fixed later.
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv')
16 files changed, 347 insertions, 146 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in index b2b901a1a..82b47b691 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in @@ -51,7 +51,7 @@ endif  ifeq ($(TARGET_ARCH),sparc)  libpthread_CSRC += lowlevellock.c  libc_CSRC += libc-lowlevellock.c -librt_CSRC := mq_notify.c  +librt_CSRC := mq_notify.c __syscall_error.c  endif  ifeq ($(TARGET_ARCH),sh) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c b/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c new file mode 100644 index 000000000..5e109a83b --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c @@ -0,0 +1,18 @@ +/* Wrapper for setting errno. + * + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <errno.h> +#include <features.h> + +/* This routine is jumped to by all the syscall handlers, to stash + * an error number into errno.  */ +int __syscall_error(int err_no) attribute_hidden; +int __syscall_error(int err_no) +{ +	__set_errno(err_no); +	return -1; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/createthread.c index 9defac619..9149efe58 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/createthread.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/createthread.c @@ -21,4 +21,4 @@  #define TLS_VALUE pd  /* Get the real implementation.	 */ -#include <nptl/sysdeps/pthread/createthread.c> +#include <sysdeps/pthread/createthread.c> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile new file mode 100644 index 000000000..43a6fad84 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile @@ -0,0 +1,13 @@ +# Makefile for uClibc NPTL +# +# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +top_srcdir=../../../../../../../ +top_builddir=../../../../../../../ +all: objs +include $(top_builddir)Rules.mak +include Makefile.arch +include $(top_srcdir)Makerules diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch new file mode 100644 index 000000000..6a0d2b51d --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch @@ -0,0 +1,58 @@ +# Makefile for uClibc NPTL +# +# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +libpthread_SSRC = pt-vfork.S clone.S +libpthread_CSRC = pthread_once.c + +libc_a_CSRC = fork.c +libc_a_SSRC = clone.S vfork.S + +CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 +ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y) +CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__ +endif + +ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD + +CFLAGS-pthread_once.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 + + +ASFLAGS-clone.S = -D_LIBC_REENTRANT +ASFLAGS-vfork.S = -D_LIBC_REENTRANT + +ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y) +#Needed to use the correct SYSCALL_ERROR_HANDLER +ASFLAGS-clone.S += -DUSE___THREAD +ASFLAGS-vfork.S += -DUSE___THREAD +endif + +CFLAGS += $(SSP_ALL_CFLAGS) +#CFLAGS:=$(CFLAGS:-O1=-O2) + +LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/sparc +LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/sparc + +LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC)) +LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC)) + +libpthread-a-y += $(LINUX_ARCH_OBJ) +libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS) + +libpthread-nomulti-y+=$(LINUX_ARCH_OBJS) + +LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC)) +LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC)) + +libc-static-y+=$(LIBC_LINUX_ARCH_OBJ) +libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS) + +libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ) + +objclean-y+=nptl_linux_arch_clean + +nptl_linux_arch_clean: +	$(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S new file mode 100644 index 000000000..dfc5e8261 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S @@ -0,0 +1,5 @@ +#if defined(__arch64__) +#include "./sparc64/clone.S" +#else +#include "./sparc32/clone.S" +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h index 4626aec52..4db6fb0b4 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.     This file is part of the GNU C Library.     Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. @@ -24,33 +24,28 @@  #include <sys/param.h>  #include <bits/pthreadtypes.h>  #include <atomic.h> +#include <sysdep.h>  #define FUTEX_WAIT		0  #define FUTEX_WAKE		1  #define FUTEX_REQUEUE		3  #define FUTEX_CMP_REQUEUE	4 +#define FUTEX_WAKE_OP		5 +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)  /* Initializer for compatibility lock.	*/  #define LLL_MUTEX_LOCK_INITIALIZER (0)  #define lll_futex_wait(futexp, val) \ -  ({									      \ -    INTERNAL_SYSCALL_DECL (__err);					      \ -    long int __ret;							      \ -									      \ -    __ret = INTERNAL_SYSCALL (futex, __err, 4,				      \ -			      (futexp), FUTEX_WAIT, (val), 0);		      \ -    __ret;								      \ -  }) +  lll_futex_timed_wait (futexp, val, NULL)  #define lll_futex_timed_wait(futexp, val, timespec) \    ({									      \      INTERNAL_SYSCALL_DECL (__err);					      \      long int __ret;							      \ -									      \ -    __ret = INTERNAL_SYSCALL (futex, __err, 4,				      \ -			      (futexp), FUTEX_WAIT, (val), (timespec));	      \ +    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		  \ +			      FUTEX_WAIT, (val), (timespec));			      \      __ret;								      \    }) @@ -58,9 +53,8 @@    ({									      \      INTERNAL_SYSCALL_DECL (__err);					      \      long int __ret;							      \ -									      \ -    __ret = INTERNAL_SYSCALL (futex, __err, 4,				      \ -			      (futexp), FUTEX_WAKE, (nr), 0);		      \ +    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \ +			      FUTEX_WAKE, (nr), 0);					      \      __ret;								      \    }) @@ -69,70 +63,115 @@    ({									      \      INTERNAL_SYSCALL_DECL (__err);					      \      long int __ret;							      \ -									      \ -    __ret = INTERNAL_SYSCALL (futex, __err, 6,				      \ -			      (futexp), FUTEX_CMP_REQUEUE, (nr_wake),	      \ -			      (nr_move), (mutex), (val));		      \ +    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \ +			      FUTEX_CMP_REQUEUE, (nr_wake), (nr_move), (mutex), (val));	      \      INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \    }) +#define lll_robust_dead(futexv) \ +  do									      \ +    {									      \ +      int *__futexp = &(futexv);					      \ +      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \ +      lll_futex_wake (__futexp, 1);				      \ +    }									      \ +  while (0) + +/* Returns non-zero if error happened, zero if success.  */  #ifdef __sparc32_atomic_do_lock -#error SPARC < v9 does not support compare and swap which is essential for futex based locking +/* Avoid FUTEX_WAKE_OP if supporting pre-v9 CPUs.  */ +# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) 1 +#else +# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \ +  ({									      \ +    INTERNAL_SYSCALL_DECL (__err);					      \ +    long int __ret;							      \ +									      \ +    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \ +			      FUTEX_WAKE_OP,    \ +			      (nr_wake), (nr_wake2), (futexp2),		      \ +			      FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);		      \ +    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \ +  })  #endif  static inline int  __attribute__ ((always_inline)) -__lll_mutex_trylock (int *futex) +__lll_trylock (int *futex)  { -  return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0; +  return atomic_compare_and_exchange_val_24_acq (futex, 1, 0) != 0;  } -#define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex)) +#define lll_mutex_trylock(futex) __lll_trylock (&(futex))  static inline int  __attribute__ ((always_inline)) -__lll_mutex_cond_trylock (int *futex) +__lll_cond_trylock (int *futex)  { -  return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0; +  return atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0;  } -#define lll_mutex_cond_trylock(futex) __lll_mutex_cond_trylock (&(futex)) +#define lll_mutex_cond_trylock(futex) __lll_cond_trylock (&(futex)) +static inline int +__attribute__ ((always_inline)) +__lll_robust_trylock (int *futex, int id) +{ +  return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0; +} +#define lll_robust_trylock(futex, id) \ +  __lll_robust_trylock (&(futex), id) -extern void __lll_lock_wait (int *futex) attribute_hidden; +extern void __lll_lock_wait (int *futex) attribute_hidden; +extern int __lll_robust_lock_wait (int *futex) attribute_hidden;  static inline void  __attribute__ ((always_inline)) -__lll_mutex_lock (int *futex) +__lll_lock (int *futex)  { -  int val = atomic_compare_and_exchange_val_acq (futex, 1, 0); +  int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);    if (__builtin_expect (val != 0, 0)) -    __lll_lock_wait (futex); +    { +	__lll_lock_wait (futex); +    }  } -#define lll_mutex_lock(futex) __lll_mutex_lock (&(futex)) +#define lll_mutex_lock(futex) __lll_lock (&(futex)) +static inline int +__attribute__ ((always_inline)) +__lll_robust_lock (int *futex, int id) +{ +  int result = 0; +  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) +    result = __lll_robust_lock_wait (futex); +  return result; +} +#define lll_robust_lock(futex, id) \ +  __lll_robust_lock (&(futex), id)  static inline void  __attribute__ ((always_inline)) -__lll_mutex_cond_lock (int *futex) +__lll_cond_lock (int *futex)  { -  int val = atomic_compare_and_exchange_val_acq (futex, 2, 0); +  int val = atomic_compare_and_exchange_val_24_acq (futex, 2, 0);    if (__builtin_expect (val != 0, 0))      __lll_lock_wait (futex);  } -#define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex)) +#define lll_mutex_cond_lock(futex) __lll_cond_lock (&(futex)) +#define lll_robust_cond_lock(futex, id) \ +  __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS) -extern int __lll_timedlock_wait (int *futex, const struct timespec *) -     attribute_hidden; +extern int __lll_timedlock_wait (int *futex, const struct timespec *) attribute_hidden; +extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *) attribute_hidden;  static inline int  __attribute__ ((always_inline)) -__lll_mutex_timedlock (int *futex, const struct timespec *abstime) +__lll_timedlock (int *futex, const struct timespec *abstime)  { -  int val = atomic_compare_and_exchange_val_acq (futex, 1, 0); +  int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);    int result = 0;    if (__builtin_expect (val != 0, 0)) @@ -140,43 +179,56 @@ __lll_mutex_timedlock (int *futex, const struct timespec *abstime)    return result;  }  #define lll_mutex_timedlock(futex, abstime) \ -  __lll_mutex_timedlock (&(futex), abstime) +  __lll_timedlock (&(futex), abstime) + +static inline int +__attribute__ ((always_inline)) +__lll_robust_timedlock (int *futex, const struct timespec *abstime, +			int id) +{ +  int result = 0; +  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) +    result = __lll_robust_timedlock_wait (futex, abstime); +  return result; +} +#define lll_robust_timedlock(futex, abstime, id) \ +  __lll_robust_timedlock (&(futex), abstime, id)  #define lll_mutex_unlock(lock) \    ((void) ({								      \      int *__futex = &(lock);						      \ -    int __val = atomic_exchange_rel (__futex, 0);			      \ +    int __val = atomic_exchange_24_rel (__futex, 0);			      \      if (__builtin_expect (__val > 1, 0))				      \ -      lll_futex_wake (__futex, 1);					      \ +      lll_futex_wake (__futex, 1);				      \    })) -#define lll_mutex_unlock_force(lock) \ +#define lll_robust_unlock(lock) \    ((void) ({								      \      int *__futex = &(lock);						      \ -    (void) atomic_exchange_rel (__futex, 0);				      \ -    lll_futex_wake (__futex, 1);					      \ +    int __val = atomic_exchange_rel (__futex, 0);			      \ +    if (__builtin_expect (__val & FUTEX_WAITERS, 0))			      \ +      lll_futex_wake (__futex, 1);				      \    }))  #define lll_mutex_islocked(futex) \    (futex != 0) -  /* We have a separate internal lock implementation which is not tied -   to binary compatibility.  We can use the lll_mutex_*.  */ +   to binary compatibility.  */  /* Type for lock object.  */  typedef int lll_lock_t; -extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; -  /* Initializers for lock.  */  #define LLL_LOCK_INITIALIZER		(0)  #define LLL_LOCK_INITIALIZER_LOCKED	(1) -#define lll_trylock(futex)	lll_mutex_trylock (futex) -#define lll_lock(futex)		lll_mutex_lock (futex) -#define lll_unlock(futex)	lll_mutex_unlock (futex) -#define lll_islocked(futex)	lll_mutex_islocked (futex) +extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; + +#define lll_trylock(lock)	lll_mutex_trylock (lock) +#define lll_lock(lock)		lll_mutex_lock (lock) +#define lll_unlock(lock)	lll_mutex_unlock (lock) +#define lll_islocked(lock)	lll_mutex_islocked (lock)  /* The kernel notifies a process with uses CLONE_CLEARTID via futex @@ -184,12 +236,12 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;     thread ID while the clone is running and is reset to zero     afterwards.	*/  #define lll_wait_tid(tid) \ -  do						\ -    {						\ -      __typeof (tid) __tid;			\ -      while ((__tid = (tid)) != 0)		\ -	lll_futex_wait (&(tid), __tid);		\ -    }						\ +  do							\ +    {							\ +      __typeof (tid) __tid;				\ +      while ((__tid = (tid)) != 0)			\ +	lll_futex_wait (&(tid), __tid);	\ +    }							\    while (0)  extern int __lll_timedwait_tid (int *, const struct timespec *) @@ -203,26 +255,4 @@ extern int __lll_timedwait_tid (int *, const struct timespec *)      __res;						\    }) - -/* Conditional variable handling.  */ - -extern void __lll_cond_wait (pthread_cond_t *cond) -     attribute_hidden; -extern int __lll_cond_timedwait (pthread_cond_t *cond, -				 const struct timespec *abstime) -     attribute_hidden; -extern void __lll_cond_wake (pthread_cond_t *cond) -     attribute_hidden; -extern void __lll_cond_broadcast (pthread_cond_t *cond) -     attribute_hidden; - -#define lll_cond_wait(cond) \ -  __lll_cond_wait (cond) -#define lll_cond_timedwait(cond, abstime) \ -  __lll_cond_timedwait (cond, abstime) -#define lll_cond_wake(cond) \ -  __lll_cond_wake (cond) -#define lll_cond_broadcast(cond) \ -  __lll_cond_broadcast (cond) -  #endif	/* lowlevellock.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/not-cancel.h deleted file mode 100644 index acf1a617e..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/not-cancel.h +++ /dev/null @@ -1 +0,0 @@ -#include "../i386/not-cancel.h" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S new file mode 100644 index 000000000..e8705c54b --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S @@ -0,0 +1,5 @@ +#if defined(__arch64__) +#include "sparc64/pt-vfork.S" +#else +#include "sparc32/pt-vfork.S" +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S index da6197c00..a6142aafe 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S @@ -1,2 +1,2 @@  #define RESET_PID -#include <sysdeps/unix/sysv/linux/sparc/sparc32/clone.S> +#include <libc/sysdeps/linux/sparc/clone.S> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S index 55229c9e6..fb01242b5 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S @@ -21,6 +21,7 @@  #include <tcb-offsets.h>  	.text +	.globl		__syscall_error  ENTRY(__vfork)  	ld	[%g7 + PID], %o5  	sub	%g0, %o5, %o4 @@ -28,15 +29,17 @@ ENTRY(__vfork)  	LOADSYSCALL(vfork)  	ta	0x10 -	bcs,a	__syscall_error_handler -	 st	%o5, [%g7 + PID] -	SYSCALL_ERROR_HANDLER -	sub	%o1, 1, %o1 +	bcc	2f +	 mov	%o7, %g1 +	st	%o5, [%g7 + PID] +	call	__syscall_error +	 mov	%g1, %o7 +2:	sub	%o1, 1, %o1  	andcc	%o0, %o1, %o0  	bne,a	1f  	 st	%o5, [%g7 + PID]  1:	retl  	 nop +END(__vfork) -PSEUDO_END (__vfork)  weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h index 5edf4b377..ad650d040 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h @@ -17,64 +17,56 @@     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     02111-1307 USA.  */ -#include <sysdep.h>  #include <tls.h> +#include <sysdep.h>  #ifndef __ASSEMBLER__ -# include <nptl/pthreadP.h> +# include <pthreadP.h>  #endif  #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt  # undef PSEUDO -# define PSEUDO(name, syscall_name, args)				      \ -	.text;								      \ -ENTRY(name)								      \ -	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;			      \ -	cmp %g1, 0;							      \ -	bne 1f;								      \ -.type	__##syscall_name##_nocancel,@function;				      \ -.globl	__##syscall_name##_nocancel;					      \ -__##syscall_name##_nocancel:						      \ -	 mov SYS_ify(syscall_name), %g1;				      \ -	ta 0x10;							      \ -	bcs __syscall_error_handler;					      \ -	 nop;								      \ -.size	__##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	      \ -	.subsection 2;							      \ -	cfi_startproc;							      \ -1:	save %sp, -96, %sp;						      \ -	cfi_def_cfa_register (%fp);					      \ -	cfi_window_save;						      \ -	cfi_register (%o7, %i7);					      \ -	CENABLE;							      \ -	 nop;								      \ -	mov %o0, %l0;							      \ -	COPY_ARGS_##args						      \ -	mov SYS_ify(syscall_name), %g1;					      \ -	ta 0x10;							      \ -	bcs __syscall_error_handler2;					      \ -	 mov %o0, %l1;							      \ -	CDISABLE;							      \ -	 mov %l0, %o0;							      \ -	jmpl %i7 + 8, %g0;						      \ -	 restore %g0, %l1, %o0;						      \ -	cfi_endproc;							      \ -	.previous;							      \ -	SYSCALL_ERROR_HANDLER						      \ -	SYSCALL_ERROR_HANDLER2 - -#define SYSCALL_ERROR_HANDLER2						      \ -SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2)			      \ -	.global __errno_location;					      \ -        .type   __errno_location,@function;				      \ -	CDISABLE;							      \ -	 mov	%l0, %o0;						      \ -	call	__errno_location;					      \ -	 nop;								      \ -	st	%l1, [%o0];						      \ -	jmpl	%i7 + 8, %g0;						      \ -	 restore %g0, -1, %o0;						      \ -	.previous; +# define PSEUDO(name, syscall_name, args)   \ +        .text;                  \ +    .globl      __syscall_error;    \ +ENTRY(name)                 \ +    ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\ +    cmp %g1, 0;             \ +    bne 1f;                 \ +.type   __##syscall_name##_nocancel,@function;  \ +.globl  __##syscall_name##_nocancel;        \ +__##syscall_name##_nocancel:            \ +     mov SYS_ify(syscall_name), %g1;    \ +    ta 0x10;                \ +    bcc 8f;                 \ +     mov %o7, %g1;              \ +    call __syscall_error;           \ +     mov %g1, %o7;              \ +8:  jmpl %o7 + 8, %g0;          \ +     nop;                   \ +.size   __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\ +1:  save %sp, -96, %sp;         \ +    cfi_def_cfa_register(%fp);      \ +    cfi_window_save;            \ +    cfi_register(%o7, %i7);         \ +    CENABLE;                \ +     nop;                   \ +    mov %o0, %l0;               \ +    COPY_ARGS_##args            \ +    mov SYS_ify(syscall_name), %g1;     \ +    ta 0x10;                \ +    bcc 1f;                 \ +     mov %o0, %l1;              \ +    CDISABLE;               \ +     mov %l0, %o0;              \ +    call __syscall_error;           \ +     mov %l1, %o0;              \ +    b 2f;                   \ +     mov -1, %l1;               \ +1:  CDISABLE;               \ +     mov %l0, %o0;              \ +2:  jmpl %i7 + 8, %g0;          \ +     restore %g0, %l1, %o0;  # ifdef IS_IN_libpthread  #  define CENABLE	call __pthread_enable_asynccancel diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S index d804f0c4b..1a3827789 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S @@ -21,6 +21,7 @@  #include <tcb-offsets.h>  	.text +	.globl		__syscall_error  ENTRY(__vfork)  	ld	[%g7 + PID], %o5  	cmp	%o5, 0 @@ -31,16 +32,18 @@ ENTRY(__vfork)  	LOADSYSCALL(vfork)  	ta	0x10 -	bcs,a	__syscall_error_handler -	 st	%o5, [%g7 + PID] -	SYSCALL_ERROR_HANDLER -	sub	%o1, 1, %o1 +	bcc	2f +	 mov	%o7, %g1 +	st	%o5, [%g7 + PID] +	call	__syscall_error +	 mov	%g1, %o7 +2:	sub	%o1, 1, %o1  	andcc	%o0, %o1, %o0  	bne,a	1f  	 st	%o5, [%g7 + PID]  1:	retl  	 nop +END(__vfork) -PSEUDO_END (__vfork) -hidden_def (__vfork) +hidden_def (vfork)  weak_alias (__vfork, vfork) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h new file mode 100644 index 000000000..5be9beb92 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h @@ -0,0 +1,5 @@ +#if defined(__arch64__) +#include "sparc64/sysdep-cancel.h" +#else +#include "sparc32/sysdep-cancel.h" +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep.h new file mode 100644 index 000000000..744e587a3 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep.h @@ -0,0 +1,65 @@ +#ifndef _LINUX_SPARC_SYSDEP_H +#define _LINUX_SPARC_SYSDEP_H 1 + +#include <sysdeps/unix/sysdep.h> + +#undef ENTRY +#undef END + +#ifdef __ASSEMBLER__ + +#define LOADSYSCALL(x) mov __NR_##x, %g1 + +#define ENTRY(name)                 \ +    .align 4;                       \ +    .global C_SYMBOL_NAME(name);    \ +    .type   name, @function;        \ +C_LABEL(name)                       \ +    cfi_startproc; + +#define END(name)                   \ +    cfi_endproc;                    \ +    .size name, . - name + +#define LOC(name) .L##name + +	/* If the offset to __syscall_error fits into a signed 22-bit +	 * immediate branch offset, the linker will relax the call into +	 * a normal branch. +	 */ +#undef PSEUDO +#undef PSEUDO_END +#undef PSEUDO_NOERRNO +#undef PSEUDO_ERRVAL + +#define PSEUDO(name, syscall_name, args)	\ +	.text;					\ +	.globl		__syscall_error;	\ +ENTRY(name);					\ +	LOADSYSCALL(syscall_name);		\ +	ta		0x10;			\ +	bcc		1f;			\ +	 mov		%o7, %g1;		\ +	call		__syscall_error;	\ +	 mov		%g1, %o7;		\ +1: + +#define PSEUDO_NOERRNO(name, syscall_name, args)\ +	.text;					\ +ENTRY(name);					\ +	LOADSYSCALL(syscall_name);		\ +	ta		0x10; + +#define PSEUDO_ERRVAL(name, syscall_name, args)	\ +	.text;					\ +ENTRY(name);					\ +	LOADSYSCALL(syscall_name);		\ +	ta		0x10; + +#define PSEUDO_END(name)			\ +	END(name) + + +#endif + +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S new file mode 100644 index 000000000..160cd0b10 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S @@ -0,0 +1,5 @@ +#if defined(__arch64__) +#include "sparc64/vfork.S" +#else +#include "sparc32/vfork.S" +#endif  | 
