diff options
Diffstat (limited to 'libpthread/linuxthreads/sysdeps/unix')
57 files changed, 4883 insertions, 0 deletions
| diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h new file mode 100644 index 000000000..3d3d2219f --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h @@ -0,0 +1,25 @@ +/* Determine whether block of given size can be allocated on the stack or not. +   Copyright (C) 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Library General Public License as +   published by the Free Software Foundation; either version 2 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 +   Library General Public License for more details. + +   You should have received a copy of the GNU Library General Public +   License along with the GNU C Library; see the file COPYING.LIB.  If not, +   see <http://www.gnu.org/licenses/>.  */ + +#include <limits.h> + +__extern_always_inline int __libc_use_alloca (size_t size) +{ +  return (__builtin_expect (size <= PTHREAD_STACK_MIN / 4, 1) +	  || __libc_alloca_cutoff (size)); +} diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c new file mode 100644 index 000000000..69bc0d79a --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c @@ -0,0 +1,88 @@ +/* Handle real-time signal allocation. +   Copyright (C) 1997,98,99,2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@cygnus.com>, 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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <signal.h> + +/* Sanity check.  */ +#if !defined __SIGRTMIN || (__SIGRTMAX - __SIGRTMIN) < 3 +# error "This must not happen" +#endif + +static int current_rtmin; +static int current_rtmax; + +static int initialized; + +#include <testrtsig.h> + +static void +init (void) +{ +  if (!kernel_has_rtsig ()) +    { +      current_rtmin = -1; +      current_rtmax = -1; +    } +  else +    { +      current_rtmin = __SIGRTMIN + 3; +      current_rtmax = __SIGRTMAX; +    } +  initialized = 1; +} + +/* Return number of available real-time signal with highest priority.  */ +int +__libc_current_sigrtmin (void) +{ +  if (!initialized) +    init (); +  return current_rtmin; +} +strong_alias (__libc_current_sigrtmin, __libc_current_sigrtmin_private) +libc_hidden_def (__libc_current_sigrtmin) + +/* Return number of available real-time signal with lowest priority.  */ +int +__libc_current_sigrtmax (void) +{ +  if (!initialized) +    init (); +  return current_rtmax; +} +strong_alias (__libc_current_sigrtmax, __libc_current_sigrtmax_private) +libc_hidden_def (__libc_current_sigrtmax) + +#if 0 +/* Allocate real-time signal with highest/lowest available +   priority.  Please note that we don't use a lock since we assume +   this function to be called at program start.  */ +int +__libc_allocate_rtsig (int high) +{ +  if (!initialized) +    init (); +  if (current_rtmin == -1 || current_rtmin > current_rtmax) +    /* We don't have anymore signal available.  */ +    return -1; + +  return high ? current_rtmin++ : current_rtmax--; +} +strong_alias (__libc_allocate_rtsig, __libc_allocate_rtsig_private) +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c new file mode 100644 index 000000000..0d6da8291 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c @@ -0,0 +1,33 @@ +#include <shlib-compat.h> + +#define aio_cancel64 XXX +#include <aio.h> +#undef aio_cancel64 +#include <errno.h> + +extern __typeof (aio_cancel) __new_aio_cancel; +extern __typeof (aio_cancel) __old_aio_cancel; + +#define aio_cancel	__new_aio_cancel + +#include <sysdeps/pthread/aio_cancel.c> + +#undef aio_cancel +strong_alias (__new_aio_cancel, __new_aio_cancel64); +versioned_symbol (librt, __new_aio_cancel, aio_cancel, GLIBC_2_3); +versioned_symbol (librt, __new_aio_cancel64, aio_cancel64, GLIBC_2_3); + +#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_3) + +#undef ECANCELED +#define aio_cancel	__old_aio_cancel +#define ECANCELED	125 + +#include <sysdeps/pthread/aio_cancel.c> + +#undef aio_cancel +strong_alias (__old_aio_cancel, __old_aio_cancel64); +compat_symbol (librt, __old_aio_cancel, aio_cancel, GLIBC_2_1); +compat_symbol (librt, __old_aio_cancel64, aio_cancel64, GLIBC_2_1); + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h new file mode 100644 index 000000000..001403a19 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h @@ -0,0 +1,91 @@ +/* Minimum guaranteed maximum values for system limits.  Linux/Alpha version. +   Copyright (C) 1993-1998,2000,2002,2003,2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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; see the file COPYING.LIB.  If +   not, see <http://www.gnu.org/licenses/>.  */ + +/* The kernel header pollutes the namespace with the NR_OPEN symbol +   and defines LINK_MAX although filesystems have different maxima.  A +   similar thing is true for OPEN_MAX: the limit can be changed at +   runtime and therefore the macro must not be defined.  Remove this +   after including the header if necessary.  */ +#ifndef NR_OPEN +# define __undef_NR_OPEN +#endif +#ifndef LINK_MAX +# define __undef_LINK_MAX +#endif +#ifndef OPEN_MAX +# define __undef_OPEN_MAX +#endif + +/* The kernel sources contain a file with all the needed information.  */ +#include <linux/limits.h> + +/* Have to remove NR_OPEN?  */ +#ifdef __undef_NR_OPEN +# undef NR_OPEN +# undef __undef_NR_OPEN +#endif +/* Have to remove LINK_MAX?  */ +#ifdef __undef_LINK_MAX +# undef LINK_MAX +# undef __undef_LINK_MAX +#endif +/* Have to remove OPEN_MAX?  */ +#ifdef __undef_OPEN_MAX +# undef OPEN_MAX +# undef __undef_OPEN_MAX +#endif + +/* The number of data keys per process.  */ +#define _POSIX_THREAD_KEYS_MAX	128 +/* This is the value this implementation supports.  */ +#define PTHREAD_KEYS_MAX	1024 + +/* Controlling the iterations of destructors for thread-specific data.  */ +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4 +/* Number of iterations this implementation does.  */ +#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS + +/* The number of threads per process.  */ +#define _POSIX_THREAD_THREADS_MAX	64 +/* This is the value this implementation supports.  */ +#define PTHREAD_THREADS_MAX	16384 + +/* Maximum amount by which a process can descrease its asynchronous I/O +   priority level.  */ +#define AIO_PRIO_DELTA_MAX	20 + +/* Minimum size for a thread.  We are free to choose a reasonable value.  */ +#define PTHREAD_STACK_MIN	24576 + +/* Maximum number of POSIX timers available.  */ +#define TIMER_MAX	256 + +/* Maximum number of timer expiration overruns.  */ +#define DELAYTIMER_MAX	2147483647 + +/* Maximum tty name length.  */ +#define TTY_NAME_MAX		32 + +/* Maximum login name length.  This is arbitrary.  */ +#define LOGIN_NAME_MAX		256 + +/* Maximum host name length.  */ +#define HOST_NAME_MAX		64 + +/* Maximum message queue priority level.  */ +#define MQ_PRIO_MAX		32768 diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h new file mode 100644 index 000000000..6d917e7f5 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h @@ -0,0 +1,65 @@ +/* bits/typesizes.h -- underlying types for *_t.  Linux/Alpha version. +   Copyright (C) 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#ifndef _BITS_TYPES_H +# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead." +#endif + +#ifndef	_BITS_TYPESIZES_H +#define	_BITS_TYPESIZES_H	1 + +/* See <bits/types.h> for the meaning of these macros.  This file exists so +   that <bits/types.h> need not vary across different GNU platforms.  */ + +#define __DEV_T_TYPE		__U64_TYPE +#define __UID_T_TYPE		__U32_TYPE +#define __GID_T_TYPE		__U32_TYPE +#define __INO_T_TYPE		__U32_TYPE +#define __INO64_T_TYPE		__U64_TYPE +#define __MODE_T_TYPE		__U32_TYPE +#define __NLINK_T_TYPE		__U32_TYPE +#define __OFF_T_TYPE		__SLONGWORD_TYPE +#define __OFF64_T_TYPE		__S64_TYPE +#define __PID_T_TYPE		__S32_TYPE +#define __RLIM_T_TYPE		__ULONGWORD_TYPE +#define __RLIM64_T_TYPE		__U64_TYPE +#define	__BLKCNT_T_TYPE		__U32_TYPE +#define	__BLKCNT64_T_TYPE	__U64_TYPE +#define	__FSBLKCNT_T_TYPE	__S32_TYPE +#define	__FSBLKCNT64_T_TYPE	__S64_TYPE +#define	__FSFILCNT_T_TYPE	__U32_TYPE +#define	__FSFILCNT64_T_TYPE	__U64_TYPE +#define	__ID_T_TYPE		__U32_TYPE +#define __CLOCK_T_TYPE		__SLONGWORD_TYPE +#define __TIME_T_TYPE		__SLONGWORD_TYPE +#define __USECONDS_T_TYPE	__U32_TYPE +#define __SUSECONDS_T_TYPE	__S64_TYPE +#define __DADDR_T_TYPE		__S32_TYPE +#define __SWBLK_T_TYPE		__SLONGWORD_TYPE +#define __KEY_T_TYPE		__S32_TYPE +#define __CLOCKID_T_TYPE	__S32_TYPE +#define __TIMER_T_TYPE		__S32_TYPE +#define __BLKSIZE_T_TYPE	__U32_TYPE +#define __FSID_T_TYPE		struct { int __val[2]; } +#define __SSIZE_T_TYPE		__SWORD_TYPE + +/* Number of descriptors that can fit in an `fd_set'.  */ +#define	__FD_SETSIZE		1024 + + +#endif /* bits/typesizes.h */ diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S new file mode 100644 index 000000000..754fc5b1c --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S @@ -0,0 +1,27 @@ +/* Internal sigsuspend system call for LinuxThreads.  Alpha version. +   Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> + +#undef PSEUDO_PREPARE_ARGS +#define PSEUDO_PREPARE_ARGS	ldq	a0, 0(a0); + +	.hidden __pthread_sigsuspend +PSEUDO_NOERRNO(__pthread_sigsuspend, sigsuspend, 1) +	ret +PSEUDO_END_NOERRNO(__pthread_sigsuspend) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h new file mode 100644 index 000000000..8ce43153d --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h @@ -0,0 +1,145 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread + +# ifdef PROF +#  define PSEUDO_PROF				\ +	.set noat;				\ +	lda	AT, _mcount;			\ +	jsr	AT, (AT), _mcount;		\ +	.set at +# else +#  define PSEUDO_PROF +# endif + +/* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END +   besides "ret".  */ + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)			\ +	.globl name;						\ +	.align 4;						\ +	.type name, @function;					\ +	.usepv name, std;					\ +	cfi_startproc;						\ +__LABEL(name)							\ +	ldgp	gp, 0(pv);					\ +	PSEUDO_PROF;						\ +	PSEUDO_PREPARE_ARGS					\ +	SINGLE_THREAD_P(t0);					\ +	bne	t0, $pseudo_cancel;				\ +	lda	v0, SYS_ify(syscall_name);			\ +	call_pal PAL_callsys;					\ +	bne	a3, SYSCALL_ERROR_LABEL;			\ +__LABEL($pseudo_ret)						\ +	.subsection 2;						\ +__LABEL($pseudo_cancel)						\ +	subq	sp, 64, sp;					\ +	cfi_def_cfa_offset(64);					\ +	stq	ra, 0(sp);					\ +	cfi_offset(ra, -64);					\ +	SAVE_ARGS_##args;					\ +	CENABLE;						\ +	LOAD_ARGS_##args;					\ +	lda	v0, SYS_ify(syscall_name);			\ +	call_pal PAL_callsys;					\ +	stq	v0, 8(sp);					\ +	bne	a3, $multi_error;				\ +	CDISABLE;						\ +	ldq	ra, 0(sp);					\ +	ldq	v0, 8(sp);					\ +	addq	sp, 64, sp;					\ +	cfi_remember_state;					\ +	cfi_restore(ra);					\ +	cfi_def_cfa_offset(0);					\ +	ret;							\ +	cfi_restore_state;					\ +__LABEL($multi_error)						\ +	CDISABLE;						\ +	ldq	ra, 0(sp);					\ +	ldq	v0, 8(sp);					\ +	addq	sp, 64, sp;					\ +	cfi_restore(ra);					\ +	cfi_def_cfa_offset(0);					\ +__LABEL($syscall_error)						\ +	SYSCALL_ERROR_HANDLER;					\ +	.previous + +# undef PSEUDO_END +# define PSEUDO_END(sym)					\ +	.subsection 2;						\ +	cfi_endproc;						\ +	.size sym, .-sym + +# define SAVE_ARGS_0	/* Nothing.  */ +# define SAVE_ARGS_1	SAVE_ARGS_0; stq a0, 8(sp) +# define SAVE_ARGS_2	SAVE_ARGS_1; stq a1, 16(sp) +# define SAVE_ARGS_3	SAVE_ARGS_2; stq a2, 24(sp) +# define SAVE_ARGS_4	SAVE_ARGS_3; stq a3, 32(sp) +# define SAVE_ARGS_5	SAVE_ARGS_4; stq a4, 40(sp) +# define SAVE_ARGS_6	SAVE_ARGS_5; stq a5, 48(sp) + +# define LOAD_ARGS_0	/* Nothing.  */ +# define LOAD_ARGS_1	LOAD_ARGS_0; ldq a0, 8(sp) +# define LOAD_ARGS_2	LOAD_ARGS_1; ldq a1, 16(sp) +# define LOAD_ARGS_3	LOAD_ARGS_2; ldq a2, 24(sp) +# define LOAD_ARGS_4	LOAD_ARGS_3; ldq a3, 32(sp) +# define LOAD_ARGS_5	LOAD_ARGS_4; ldq a4, 40(sp) +# define LOAD_ARGS_6	LOAD_ARGS_5; ldq a5, 48(sp) + +# ifdef IS_IN_libpthread +#  define __local_enable_asynccancel	__pthread_enable_asynccancel +#  define __local_disable_asynccancel	__pthread_disable_asynccancel +#  define __local_multiple_threads	__pthread_multiple_threads +# else +#  define __local_enable_asynccancel	__libc_enable_asynccancel +#  define __local_disable_asynccancel	__libc_disable_asynccancel +#  define __local_multiple_threads	__libc_multiple_threads +# endif + +# ifdef __PIC__ +#  define CENABLE	bsr ra, __local_enable_asynccancel !samegp +#  define CDISABLE	bsr ra, __local_disable_asynccancel !samegp +# else +#  define CENABLE	jsr ra, __local_enable_asynccancel; ldgp ra, 0(gp) +#  define CDISABLE	jsr ra, __local_disable_asynccancel; ldgp ra, 0(gp) +# endif + +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#   define SINGLE_THREAD_P \ +  __builtin_expect (__local_multiple_threads == 0, 1) +# elif defined(__PIC__) +#  define SINGLE_THREAD_P(reg)  ldl reg, __local_multiple_threads(gp) !gprel +# else +#  define SINGLE_THREAD_P(reg)					\ +	ldah	reg, __local_multiple_threads(gp) !gprelhigh;	\ +	ldl	reg, __local_multiple_threads(reg) !gprellow +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S new file mode 100644 index 000000000..80fdcc6fb --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S @@ -0,0 +1,69 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + + +#include <sysdep-cancel.h> + +        .align 4 +	.globl	__vfork +	.type	__vfork, @function +	.usepv	__vfork, std +	cfi_startproc +__vfork: +	ldgp	gp, 0(pv) +	PSEUDO_PROF + +#ifdef SHARED +	ldq	t0, __libc_pthread_functions(gp) !gprel +	bne	t0, HIDDEN_JUMPTARGET (fork) !samegp +#else +	.weak	pthread_create +	ldq	t0, pthread_create(gp) !literal +	bne	t0, $do_fork +#endif + +	lda	v0, SYS_ify(vfork) +	call_pal PAL_callsys +	bne	a3, SYSCALL_ERROR_LABEL +	ret + +#ifndef SHARED +	/* Can't tail-call due to possible mismatch between GP in +	   fork and vfork object files.  */ +$do_fork: +	subq	sp, 16, sp +	cfi_adjust_cfa_offset(16) +	stq	ra, 0(sp) +	cfi_offset(ra, -16) +	jsr	ra, HIDDEN_JUMPTARGET (fork) +	ldgp	gp, 0(ra) +	ldq	ra, 0(sp) +	addq	sp, 16, sp +	cfi_restore(ra) +	cfi_adjust_cfa_offset(-16) +	ret + +$syscall_error: +	SYSCALL_ERROR_HANDLER +#endif + +	cfi_endproc +	.size __vfork, .-__vfork + +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h new file mode 100644 index 000000000..2c1eba65f --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h @@ -0,0 +1,129 @@ +/* Copyright (C) 2003, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Phil Blundell <pb@nexus.co.uk>, 2003. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <tls.h> +#include <pt-machine.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread + +/* We push lr onto the stack, so we have to use ldmib instead of ldmia +   to find the saved arguments.  */ +# ifdef __PIC__ +#  undef DOARGS_5 +#  undef DOARGS_6 +#  undef DOARGS_7 +#  define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $8]; +#  define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmib ip, {r4, r5}; +#  define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmib ip, {r4, r5, r6}; +# endif + +# undef PSEUDO_RET +# define PSEUDO_RET						        \ +    ldrcc pc, [sp], $4;						        \ +    ldr	lr, [sp], $4;							\ +    b PLTJMP(SYSCALL_ERROR) + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				\ +  .section ".text";							\ +    PSEUDO_PROLOGUE;							\ +  ENTRY (name);								\ +    SINGLE_THREAD_P;							\ +    bne .Lpseudo_cancel;						\ +    DO_CALL (syscall_name, args);					\ +    cmn r0, $4096;							\ +    RETINSTR(cc, lr);							\ +    b PLTJMP(SYSCALL_ERROR);						\ +  .Lpseudo_cancel:							\ +    str lr, [sp, $-4]!;							\ +    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\ +    CENABLE;								\ +    mov ip, r0;		/* put mask in safe place.  */			\ +    UNDOCARGS_##args;	/* restore syscall args.  */			\ +    swi SYS_ify (syscall_name);	/* do the call.  */			\ +    str r0, [sp, $-4]!; /* save syscall return value.  */		\ +    mov r0, ip;		/* get mask back.  */				\ +    CDISABLE;								\ +    ldr r0, [sp], $4;	/* retrieve return value.  */			\ +    UNDOC2ARGS_##args;	/* fix register damage.  */			\ +    cmn r0, $4096; + +# define DOCARGS_0 +# define UNDOCARGS_0 +# define UNDOC2ARGS_0 + +# define DOCARGS_1	str r0, [sp, #-4]!; +# define UNDOCARGS_1	ldr r0, [sp], #4; +# define UNDOC2ARGS_1 + +# define DOCARGS_2	str r1, [sp, #-4]!; str r0, [sp, #-4]!; +# define UNDOCARGS_2	ldr r0, [sp], #4; ldr r1, [sp], #4; +# define UNDOC2ARGS_2 + +# define DOCARGS_3	str r2, [sp, #-4]!; str r1, [sp, #-4]!; str r0, [sp, #-4]!; +# define UNDOCARGS_3	ldr r0, [sp], #4; ldr r1, [sp], #4; ldr r2, [sp], #4 +# define UNDOC2ARGS_3 + +# define DOCARGS_4	stmfd sp!, {r0-r3} +# define UNDOCARGS_4	ldmfd sp!, {r0-r3} +# define UNDOC2ARGS_4 + +# define DOCARGS_5	stmfd sp!, {r0-r3} +# define UNDOCARGS_5	ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24] +# define UNDOC2ARGS_5   ldr r4, [sp], #20 + +# ifdef IS_IN_libpthread +#  define CENABLE	bl PLTJMP(__pthread_enable_asynccancel) +#  define CDISABLE	bl PLTJMP(__pthread_disable_asynccancel) +#  define __local_multiple_threads __pthread_multiple_threads +# else +#  define CENABLE	bl PLTJMP(__libc_enable_asynccancel) +#  define CDISABLE	bl PLTJMP(__libc_disable_asynccancel) +#  define __local_multiple_threads __libc_multiple_threads +# endif + +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +#  if !defined __PIC__ +#   define SINGLE_THREAD_P						\ +  ldr ip, =__local_multiple_threads;					\ +  ldr ip, [ip];								\ +  teq ip, #0; +#   define PSEUDO_PROLOGUE +#  else +#   define SINGLE_THREAD_P						\ +  ldr ip, 1b;								\ +2:									\ +  ldr ip, [pc, ip];							\ +  teq ip, #0; +#   define PSEUDO_PROLOGUE						\ +  1:  .word __local_multiple_threads - 2f - 8; +#  endif +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S new file mode 100644 index 000000000..3d9e49a0f --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S @@ -0,0 +1,77 @@ +/* Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Philip Blundell <philb@gnu.org>. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep-cancel.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <kernel-features.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) + +#ifdef __NR_vfork + +#ifdef SHARED +	ldr	ip, 1f +	ldr	r0, 2f +3:	add	ip, pc, ip +	ldr	r0, [ip, r0] +#else +	ldr	r0, 1f +#endif +	movs	r0, r0 +	bne	HIDDEN_JUMPTARGET (fork) + +	DO_CALL (vfork, 0) +	cmn	a1, #4096 +	RETINSTR(cc, lr) + +#ifndef __ASSUME_VFORK_SYSCALL +	/* Check if vfork syscall is known at all.  */ +	cmn	a1, #ENOSYS +	bne	PLTJMP(C_SYMBOL_NAME(__syscall_error)) +#endif + +#endif + +#ifndef __ASSUME_VFORK_SYSCALL +	/* If we don't have vfork, fork is close enough.  */ +	DO_CALL (fork, 0) +	cmn	a1, #4096 +	RETINSTR(cc, lr) +#elif !defined __NR_vfork +# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined" +#endif +    	b	PLTJMP(C_SYMBOL_NAME(__syscall_error)) + +#ifdef SHARED +1:	.word	_GLOBAL_OFFSET_TABLE_ - 3b - 8 +2:	.word	__libc_pthread_functions(GOTOFF) +#else +	.weak	pthread_create +1:	.word	pthread_create +#endif + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/execve.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/execve.c new file mode 100644 index 000000000..cae12182f --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/execve.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <errno.h> +#include <unistd.h> + +#include <sysdep.h> +#include <alloca.h> +#include <sys/syscall.h> + +extern int __syscall_execve(const char *file, +			char *const *argv, +			char *const *envp); +extern void __pthread_kill_other_threads_np(void); +weak_extern(__pthread_kill_other_threads_np) + +int +__execve(const char *file, char *const argv[], char *const envp[]) +{ +	/* If this is a threaded application kill all other threads.  */ +	if (__pthread_kill_other_threads_np) +		__pthread_kill_other_threads_np(); +	return INLINE_SYSCALL(execve, 3, file, argv, envp); +} +weak_alias(__execve, execve) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/fork.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/fork.c new file mode 100644 index 000000000..8f954d8d9 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/fork.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <errno.h> +#include <fork.h> +#include <bits/libc-lock.h> + +struct fork_block __fork_block = +{ +  .lock = PTHREAD_MUTEX_INITIALIZER, +  .prepare_list = { &__fork_block.prepare_list, &__fork_block.prepare_list }, +  .parent_list = { &__fork_block.parent_list, &__fork_block.parent_list }, +  .child_list = { &__fork_block.child_list, &__fork_block.child_list } +}; diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/fork.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/fork.h new file mode 100644 index 000000000..8245d9ef0 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/fork.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <list.h> +#include <bits/libc-lock.h> + +struct fork_block +{ +  /* Lock to protect handling of fork handlers.  */ +  __libc_lock_define (, lock); + +  /* Lists of registered fork handlers.  */ +  list_t prepare_list; +  list_t parent_list; +  list_t child_list; +}; + +extern struct fork_block __fork_block attribute_hidden; + +/* Elements of the fork handler lists.  */ +struct fork_handler +{ +  list_t list; +  void (*handler) (void); +  void *dso_handle; +}; + + +/* Function to call to unregister fork handlers.  */ +extern void __unregister_atfork (void *dso_handle) attribute_hidden; +#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle) + + +/* C library side function to register new fork handlers.  */ +extern int __register_atfork (void (*__prepare) (void), +			      void (*__parent) (void), +			      void (*__child) (void), +			      void *dso_handle); + +#ifndef ARCH_FORK +# define ARCH_FORK() __libc_fork() +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c new file mode 100644 index 000000000..0d6da8291 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c @@ -0,0 +1,33 @@ +#include <shlib-compat.h> + +#define aio_cancel64 XXX +#include <aio.h> +#undef aio_cancel64 +#include <errno.h> + +extern __typeof (aio_cancel) __new_aio_cancel; +extern __typeof (aio_cancel) __old_aio_cancel; + +#define aio_cancel	__new_aio_cancel + +#include <sysdeps/pthread/aio_cancel.c> + +#undef aio_cancel +strong_alias (__new_aio_cancel, __new_aio_cancel64); +versioned_symbol (librt, __new_aio_cancel, aio_cancel, GLIBC_2_3); +versioned_symbol (librt, __new_aio_cancel64, aio_cancel64, GLIBC_2_3); + +#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_3) + +#undef ECANCELED +#define aio_cancel	__old_aio_cancel +#define ECANCELED	125 + +#include <sysdeps/pthread/aio_cancel.c> + +#undef aio_cancel +strong_alias (__old_aio_cancel, __old_aio_cancel64); +compat_symbol (librt, __old_aio_cancel, aio_cancel, GLIBC_2_1); +compat_symbol (librt, __old_aio_cancel64, aio_cancel64, GLIBC_2_1); + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h new file mode 100644 index 000000000..e367fb9d8 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h @@ -0,0 +1,26 @@ +/* PA-RISC specific definitions for spinlock initializers. +   Copyright (C) 2000, 2001 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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; see the file COPYING.LIB.  If +   not, see <http://www.gnu.org/licenses/>.  */ + +/* Initial value of a spinlock.  PA-RISC only implements atomic load +   and clear so this must be non-zero. */ +#define __LT_SPINLOCK_INIT 1 + +/* Macros for lock initializers, using the above definition. */ +#define __LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT } +#define __ALT_LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT } +#define __ATOMIC_INITIALIZER { 0, __LT_SPINLOCK_INIT } diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h new file mode 100644 index 000000000..e6b71f441 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h @@ -0,0 +1,72 @@ +/* HP-PARISC macro definitions for mutexes, thread-specific data +   and parameters for malloc. +   Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Carlos O'Donell <carlos@baldric.uwo.ca>, 2003. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#ifndef _MALLOC_MACHINE_H +#define _MALLOC_MACHINE_H + +#undef thread_atfork_static + +#include <atomic.h> +#include <bits/libc-lock.h> + +__libc_lock_define (typedef, mutex_t) + +/* Since our lock structure does not tolerate being initialized to zero, we must +   modify the standard function calls made by malloc */ +#  define mutex_init(m)		\ +	__libc_maybe_call (__pthread_mutex_init, (m, NULL), \ +		(((m)->__m_lock.__spinlock = __LT_SPINLOCK_INIT),(*(int *)(m))) ) +#  define mutex_lock(m)		\ +	__libc_maybe_call (__pthread_mutex_lock, (m), \ +			(__load_and_clear(&((m)->__m_lock.__spinlock)), 0)) +#  define mutex_trylock(m)	\ +	__libc_maybe_call (__pthread_mutex_trylock, (m), \ +			(*(int *)(m) ? 1 : (__load_and_clear(&((m)->__m_lock.__spinlock)), 0))) +#  define mutex_unlock(m)	\ +	__libc_maybe_call (__pthread_mutex_unlock, (m), \ +			(((m)->__m_lock.__spinlock = __LT_SPINLOCK_INIT), (*(int *)(m))) ) + +/* This is defined by newer gcc version unique for each module.  */ +extern void *__dso_handle __attribute__ ((__weak__)); + +#include <fork.h> + +#ifdef SHARED +# define thread_atfork(prepare, parent, child) \ +   __register_atfork (prepare, parent, child, __dso_handle) +#else +# define thread_atfork(prepare, parent, child) \ +   __register_atfork (prepare, parent, child,				      \ +		      &__dso_handle == NULL ? NULL : __dso_handle) +#endif + +/* thread specific data for glibc */ + +#include <bits/libc-tsd.h> + +typedef int tsd_key_t[1];	/* no key data structure, libc magic does it */ +__libc_tsd_define (static, MALLOC)	/* declaration/common definition */ +#define tsd_key_create(key, destr)	((void) (key)) +#define tsd_setspecific(key, data)	__libc_tsd_set (MALLOC, (data)) +#define tsd_getspecific(key, vptr)	((vptr) = __libc_tsd_get (MALLOC)) + +#include <sysdeps/generic/malloc-machine.h> + +#endif /* !defined(_MALLOC_MACHINE_H) */ diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c new file mode 100644 index 000000000..60607ad4f --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c @@ -0,0 +1,108 @@ +/* Special .init and .fini section support for HPPA.  Linuxthreads version. +   Copyright (C) 2001, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it +   and/or 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. + +   In addition to the permissions in the GNU Lesser General Public +   License, the Free Software Foundation gives you unlimited +   permission to link the compiled version of this file with other +   programs, and to distribute those programs without any restriction +   coming from the use of this file.  (The Lesser General Public +   License restrictions do apply in other respects; for example, they +   cover modification of the file, and distribution when not linked +   into another program.) + +   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; see the file COPYING.LIB.  If not, +   see <http://www.gnu.org/licenses/>.  */ + +/* This file is compiled into assembly code which is then munged by a sed +   script into two files: crti.s and crtn.s. + +   * crti.s puts a function prologue at the beginning of the +   .init and .fini sections and defines global symbols for +   those addresses, so they can be called as functions. + +   * crtn.s puts the corresponding function epilogues +   in the .init and .fini sections. */ + +/* If we use the standard C version, the linkage table pointer won't +   be properly preserved due to the splitting up of function prologues +   and epilogues.  Therefore we write these in assembly to make sure +   they do the right thing.  */ + +__asm__ ( +"#include \"defs.h\"\n" +"\n" +"/*@HEADER_ENDS*/\n" +"\n" +"/*@_init_PROLOG_BEGINS*/\n" +"	.section .init\n" +"	.align 4\n" +"	.globl _init\n" +"	.type _init,@function\n" +"_init:\n" +"	stw	%rp,-20(%sp)\n" +"	stwm	%r4,64(%sp)\n" +"	stw	%r19,-32(%sp)\n" +"	bl	__pthread_initialize_minimal,%rp\n" +"	copy	%r19,%r4	/* delay slot */\n" +"	copy	%r4,%r19\n" +"/*@_init_PROLOG_ENDS*/\n" +"\n" +"/*@_init_EPILOG_BEGINS*/\n" +"/* Here is the tail end of _init.  */\n" +"	.section .init\n" +"	ldw	-84(%sp),%rp\n" +"	copy	%r4,%r19\n" +"	bv	%r0(%rp)\n" +"_end_init:\n" +"	ldwm	-64(%sp),%r4\n" +"\n" +"/* Our very own unwind info, because the assembler can't handle\n" +"   functions split into two or more pieces.  */\n" +"	.section .PARISC.unwind,\"a\",@progbits\n" +"	.extern _init\n" +"	.word	_init, _end_init\n" +"	.byte	0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08\n" +"\n" +"/*@_init_EPILOG_ENDS*/\n" +"\n" +"/*@_fini_PROLOG_BEGINS*/\n" +"	.section .fini\n" +"	.align 4\n" +"	.globl _fini\n" +"	.type _fini,@function\n" +"_fini:\n" +"	stw	%rp,-20(%sp)\n" +"	stwm	%r4,64(%sp)\n" +"	stw	%r19,-32(%sp)\n" +"	copy	%r19,%r4\n" +"/*@_fini_PROLOG_ENDS*/\n" +"\n" +"/*@_fini_EPILOG_BEGINS*/\n" +"	.section .fini\n" +"	ldw	-84(%sp),%rp\n" +"	copy	%r4,%r19\n" +"	bv	%r0(%rp)\n" +"_end_fini:\n" +"	ldwm	-64(%sp),%r4\n" +"\n" +"	.section .PARISC.unwind,\"a\",@progbits\n" +"	.extern _fini\n" +"	.word	_fini, _end_fini\n" +"	.byte	0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08\n" +"\n" +"/*@_fini_EPILOG_ENDS*/\n" +"\n" +"/*@TRAILER_BEGINS*/\n" +); diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h new file mode 100644 index 000000000..8a7bd9705 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h @@ -0,0 +1,188 @@ +/* cancellable system calls for Linux/HPPA. +   Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Carlos O'Donell <carlos@baldric.uwo.ca>, 2003. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# ifndef NO_ERROR +#  define NO_ERROR -0x1000 +# endif + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				\ +  ENTRY (name)								\ +    SINGLE_THREAD_P					ASM_LINE_SEP	\ +    cmpib,<> 0,%ret0,Lpseudo_cancel			ASM_LINE_SEP	\ +    nop							ASM_LINE_SEP	\ +    DO_CALL(syscall_name, args)				ASM_LINE_SEP	\ +    /* DONE! */						ASM_LINE_SEP	\ +    bv 0(2)						ASM_LINE_SEP	\ +    nop							ASM_LINE_SEP	\ +  Lpseudo_cancel:					ASM_LINE_SEP	\ +    /* store return ptr */				ASM_LINE_SEP	\ +    stw %rp, -20(%sr0,%sp)				ASM_LINE_SEP	\ +    /* save syscall args */				ASM_LINE_SEP	\ +    PUSHARGS_##args /* MACRO */				ASM_LINE_SEP	\ +    STW_PIC						ASM_LINE_SEP	\ +    CENABLE /* FUNC CALL */				ASM_LINE_SEP	\ +    ldo 64(%sp), %sp					ASM_LINE_SEP	\ +    ldo -64(%sp), %sp					ASM_LINE_SEP	\ +    LDW_PIC						ASM_LINE_SEP	\ +    /* restore syscall args */				ASM_LINE_SEP	\ +    POPARGS_##args					ASM_LINE_SEP	\ +    /* save r4 in arg0 stack slot */			ASM_LINE_SEP	\ +    stw %r4, -36(%sr0,%sp)				ASM_LINE_SEP	\ +    /* save mask from cenable */			ASM_LINE_SEP	\ +    copy %ret0, %r4					ASM_LINE_SEP	\ +    ble 0x100(%sr2,%r0)					ASM_LINE_SEP    \ +    ldi SYS_ify (syscall_name), %r20			ASM_LINE_SEP	\ +    LDW_PIC						ASM_LINE_SEP	\ +    /* pass mask as arg0 to cdisable */			ASM_LINE_SEP	\ +    copy %r4, %r26					ASM_LINE_SEP	\ +    copy %ret0, %r4					ASM_LINE_SEP	\ +    CDISABLE						ASM_LINE_SEP	\ +    ldo 64(%sp), %sp					ASM_LINE_SEP	\ +    ldo -64(%sp), %sp					ASM_LINE_SEP	\ +    LDW_PIC						ASM_LINE_SEP	\ +    /* compare error */					ASM_LINE_SEP	\ +    ldi NO_ERROR,%r1					ASM_LINE_SEP	\ +    /* branch if no error */				ASM_LINE_SEP	\ +    cmpb,>>=,n %r1,%r4,Lpre_end				ASM_LINE_SEP	\ +    nop							ASM_LINE_SEP	\ +    SYSCALL_ERROR_HANDLER				ASM_LINE_SEP	\ +    ldo 64(%sp), %sp					ASM_LINE_SEP	\ +    ldo -64(%sp), %sp					ASM_LINE_SEP	\ +    /* No need to LDW_PIC */				ASM_LINE_SEP	\ +    /* make syscall res value positive */		ASM_LINE_SEP	\ +    sub %r0, %r4, %r4					ASM_LINE_SEP	\ +    /* store into errno location */			ASM_LINE_SEP	\ +    stw %r4, 0(%sr0,%ret0)				ASM_LINE_SEP	\ +    /* return -1 */					ASM_LINE_SEP	\ +    ldo -1(%r0), %ret0					ASM_LINE_SEP	\ +  Lpre_end:						ASM_LINE_SEP	\ +    ldw -20(%sr0,%sp), %rp             			ASM_LINE_SEP	\ +    /* No need to LDW_PIC */				ASM_LINE_SEP	\ +    ldw -36(%sr0,%sp), %r4				ASM_LINE_SEP + +/* Save arguments into our frame */ +# define PUSHARGS_0	/* nothing to do */ +# define PUSHARGS_1	PUSHARGS_0 stw %r26, -36(%sr0,%sp)	ASM_LINE_SEP +# define PUSHARGS_2	PUSHARGS_1 stw %r25, -40(%sr0,%sp)	ASM_LINE_SEP +# define PUSHARGS_3	PUSHARGS_2 stw %r24, -44(%sr0,%sp)	ASM_LINE_SEP +# define PUSHARGS_4	PUSHARGS_3 stw %r23, -48(%sr0,%sp)	ASM_LINE_SEP +# define PUSHARGS_5	PUSHARGS_4 /* Args are on the stack... */ +# define PUSHARGS_6	PUSHARGS_5 + +/* Bring them back from the stack */ +# define POPARGS_0	/* nothing to do */ +# define POPARGS_1	POPARGS_0 ldw -36(%sr0,%sp), %r26	ASM_LINE_SEP +# define POPARGS_2	POPARGS_1 ldw -40(%sr0,%sp), %r25	ASM_LINE_SEP +# define POPARGS_3	POPARGS_2 ldw -44(%sr0,%sp), %r24	ASM_LINE_SEP +# define POPARGS_4	POPARGS_3 ldw -48(%sr0,%sp), %r23	ASM_LINE_SEP +# define POPARGS_5	POPARGS_4 ldw -52(%sr0,%sp), %r22	ASM_LINE_SEP +# define POPARGS_6	POPARGS_5 ldw -54(%sr0,%sp), %r21	ASM_LINE_SEP + +# ifdef IS_IN_libpthread +#  ifdef __PIC__ +#   define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \ +			bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP +#   define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \ +			bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP +#  else +#   define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \ +			bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP +#   define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \ +			bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP +#  endif +# elif !defined NOT_IN_libc +#  ifdef __PIC__ +#   define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \ +			bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP +#   define CDISABLE	.import __libc_disable_asynccancel,code ASM_LINE_SEP \ +			bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP +#  else +#   define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \ +			bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP +#   define CDISABLE	.import __libc_disable_asynccancel,code ASM_LINE_SEP \ +			bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP +#  endif +# else +#  ifdef __PIC__ +#   define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \ +			bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP +#   define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \ +			bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP +#  else +#   define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \ +			bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP +#   define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \ +			bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP +#  endif +# endif + +/* p_header.multiple_threads is +12 from the pthread_descr struct start, +   We could have called __get_cr27() but we really want less overhead */ +# define MULTIPLE_THREADS_OFFSET 0xC + +/* cr27 has been initialized to 0x0 by kernel */ +# define NO_THREAD_CR27 0x0 + +# ifdef IS_IN_libpthread +#  define __local_multiple_threads __pthread_multiple_threads +# elif !defined NOT_IN_libc +#  define __local_multiple_threads __libc_multiple_threads +# else +#  define __local_multiple_threads __librt_multiple_threads +# endif + +# ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; +#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +/* This ALT version requires newer kernel support */ +#  define SINGLE_THREAD_P_MFCTL						\ +	mfctl %cr27, %ret0					ASM_LINE_SEP	\ +	cmpib,= NO_THREAD_CR27,%ret0,Lstp			ASM_LINE_SEP	\ +	nop							ASM_LINE_SEP	\ +	ldw MULTIPLE_THREADS_OFFSET(%sr0,%ret0),%ret0		ASM_LINE_SEP	\ + Lstp:								ASM_LINE_SEP +#  ifdef __PIC__ +/* Slower version uses GOT to get value of __local_multiple_threads */ +#   define SINGLE_THREAD_P							\ +	addil LT%__local_multiple_threads, %r19			ASM_LINE_SEP	\ +	ldw RT%__local_multiple_threads(%sr0,%r1), %ret0	ASM_LINE_SEP	\ +	ldw 0(%sr0,%ret0), %ret0 				ASM_LINE_SEP +#  else +  /* Slow non-pic version using DP */ +#   define SINGLE_THREAD_P								\ +	addil LR%__local_multiple_threads-$global$,%r27  		ASM_LINE_SEP	\ +	ldw RR%__local_multiple_threads-$global$(%sr0,%r1),%ret0	ASM_LINE_SEP +#  endif +# endif +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif +/* !defined NOT_IN_libc || defined IS_IN_libpthread */ diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h new file mode 100644 index 000000000..d330e664e --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h @@ -0,0 +1,186 @@ +/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <tls.h> +#include <pt-machine.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.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)								      \ +    SINGLE_THREAD_P;							      \ +    jne L(pseudo_cancel);						      \ +    DO_CALL (syscall_name, args);					      \ +    cmpl $-4095, %eax;							      \ +    jae SYSCALL_ERROR_LABEL;						      \ +    ret;								      \ +  L(pseudo_cancel):							      \ +    CENABLE								      \ +    SAVE_OLDTYPE_##args							      \ +    PUSHCARGS_##args							      \ +    DOCARGS_##args							      \ +    movl $SYS_ify (syscall_name), %eax;					      \ +    int $0x80								      \ +    POPCARGS_##args;							      \ +    POPSTATE_##args							      \ +    cmpl $-4095, %eax;							      \ +    jae SYSCALL_ERROR_LABEL;						      \ +  L(pseudo_end): + +# define SAVE_OLDTYPE_0	movl %eax, %ecx; +# define SAVE_OLDTYPE_1	SAVE_OLDTYPE_0 +# define SAVE_OLDTYPE_2	pushl %eax; cfi_adjust_cfa_offset (4); +# define SAVE_OLDTYPE_3	SAVE_OLDTYPE_2 +# define SAVE_OLDTYPE_4	SAVE_OLDTYPE_2 +# define SAVE_OLDTYPE_5	SAVE_OLDTYPE_2 + +# define PUSHCARGS_0	/* No arguments to push.  */ +# define DOCARGS_0	/* No arguments to frob.  */ +# define POPCARGS_0	/* No arguments to pop.  */ +# define _PUSHCARGS_0	/* No arguments to push.  */ +# define _POPCARGS_0	/* No arguments to pop.  */ + +# define PUSHCARGS_1	movl %ebx, %edx; cfi_register (ebx, edx); PUSHCARGS_0 +# define DOCARGS_1	_DOARGS_1 (4) +# define POPCARGS_1	POPCARGS_0; movl %edx, %ebx; cfi_restore (ebx); +# define _PUSHCARGS_1	pushl %ebx; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (ebx, 0); _PUSHCARGS_0 +# define _POPCARGS_1	_POPCARGS_0; popl %ebx; \ +			cfi_adjust_cfa_offset (-4); cfi_restore (ebx); + +# define PUSHCARGS_2	PUSHCARGS_1 +# define DOCARGS_2	_DOARGS_2 (12) +# define POPCARGS_2	POPCARGS_1 +# define _PUSHCARGS_2	_PUSHCARGS_1 +# define _POPCARGS_2	_POPCARGS_1 + +# define PUSHCARGS_3	_PUSHCARGS_2 +# define DOCARGS_3	_DOARGS_3 (20) +# define POPCARGS_3	_POPCARGS_3 +# define _PUSHCARGS_3	_PUSHCARGS_2 +# define _POPCARGS_3	_POPCARGS_2 + +# define PUSHCARGS_4	_PUSHCARGS_4 +# define DOCARGS_4	_DOARGS_4 (28) +# define POPCARGS_4	_POPCARGS_4 +# define _PUSHCARGS_4	pushl %esi; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (esi, 0); _PUSHCARGS_3 +# define _POPCARGS_4	_POPCARGS_3; popl %esi; \ +			cfi_adjust_cfa_offset (-4); cfi_restore (esi); + +# define PUSHCARGS_5	_PUSHCARGS_5 +# define DOCARGS_5	_DOARGS_5 (36) +# define POPCARGS_5	_POPCARGS_5 +# define _PUSHCARGS_5	pushl %edi; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (edi, 0); _PUSHCARGS_4 +# define _POPCARGS_5	_POPCARGS_4; popl %edi; \ +			cfi_adjust_cfa_offset (-4); cfi_restore (edi); + +# ifdef IS_IN_libpthread +#  define CENABLE	call __pthread_enable_asynccancel; +#  define CDISABLE	call __pthread_disable_asynccancel +# elif defined IS_IN_librt +#  ifdef __PIC__ +#   define CENABLE	pushl %ebx; \ +			call __i686.get_pc_thunk.bx; \ +			addl     $_GLOBAL_OFFSET_TABLE_, %ebx; \ +			call __librt_enable_asynccancel@PLT; \ +			popl %ebx; +#   define CDISABLE	pushl %ebx; \ +			call __i686.get_pc_thunk.bx; \ +			addl     $_GLOBAL_OFFSET_TABLE_, %ebx; \ +			call __librt_disable_asynccancel@PLT; \ +			popl %ebx; +#  else +#   define CENABLE	call __librt_enable_asynccancel; +#   define CDISABLE	call __librt_disable_asynccancel +#  endif +# else +#  define CENABLE	call __libc_enable_asynccancel; +#  define CDISABLE	call __libc_disable_asynccancel +# endif +# define POPSTATE_0 \ + pushl %eax; cfi_adjust_cfa_offset (4); movl %ecx, %eax; \ + CDISABLE; popl %eax; cfi_adjust_cfa_offset (-4); +# define POPSTATE_1	POPSTATE_0 +# define POPSTATE_2	xchgl (%esp), %eax; CDISABLE; popl %eax; \ +			cfi_adjust_cfa_offset (-4); +# define POPSTATE_3	POPSTATE_2 +# define POPSTATE_4	POPSTATE_3 +# define POPSTATE_5	POPSTATE_4 + +#if !defined NOT_IN_libc +# define __local_multiple_threads __libc_multiple_threads +#elif defined IS_IN_libpthread +# define __local_multiple_threads __pthread_multiple_threads +#else +# define __local_multiple_threads __librt_multiple_threads +#endif + +# ifndef __ASSEMBLER__ +#  if defined FLOATING_STACKS && defined __UCLIBC_HAS_TLS__ && defined __PIC__ +#   define SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \ +				   p_header.data.multiple_threads) == 0, 1) +#  else +extern int __local_multiple_threads +#   if !defined NOT_IN_libc || defined IS_IN_libpthread +  attribute_hidden; +#   else +  ; +#   endif +#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +#  endif +# else +#  if !defined __PIC__ +#   define SINGLE_THREAD_P cmpl $0, __local_multiple_threads +#  elif defined FLOATING_STACKS && defined __UCLIBC_HAS_TLS__ +#   define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET +#  else +#   if !defined NOT_IN_libc || defined IS_IN_libpthread +#    define __SINGLE_THREAD_CMP cmpl $0, __local_multiple_threads@GOTOFF(%ecx) +#   else +#    define __SINGLE_THREAD_CMP \ +  movl __local_multiple_threads@GOT(%ecx), %ecx;\ +  cmpl $0, (%ecx) +#   endif +#   if !defined HAVE_HIDDEN || !defined __UCLIBC_HAS_TLS__ +#    define SINGLE_THREAD_P \ +  SETUP_PIC_REG (cx);				\ +  addl $_GLOBAL_OFFSET_TABLE_, %ecx;		\ +  __SINGLE_THREAD_CMP +#   else +#    define SINGLE_THREAD_P \ +  call __i686.get_pc_thunk.cx;			\ +  addl $_GLOBAL_OFFSET_TABLE_, %ecx;		\ +  __SINGLE_THREAD_CMP +#   endif +#  endif +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S new file mode 100644 index 000000000..83ad9f3b5 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S @@ -0,0 +1,94 @@ +/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Andreas Schwab <schwab@gnu.org>. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep-cancel.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <bits/kernel-features.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) + +#ifdef __NR_vfork + +# ifdef SHARED +#  if !defined HAVE_HIDDEN || !defined __UCLIBC_HAS_TLS__ +	SETUP_PIC_REG (cx) +#  else +	call	__i686.get_pc_thunk.cx +#  endif +	addl	$_GLOBAL_OFFSET_TABLE_, %ecx +	cmpl	$0, __libc_pthread_functions@GOTOFF(%ecx) +# else +	.weak	pthread_create +	movl	$pthread_create, %eax +	testl	%eax, %eax +# endif +	jne	HIDDEN_JUMPTARGET (fork) + +	/* Pop the return PC value into ECX.  */ +	popl	%ecx + +	/* Stuff the syscall number in EAX and enter into the kernel.  */ +	movl	$SYS_ify (vfork), %eax +	int	$0x80 + +	/* Jump to the return PC.  Don't jump directly since this +	   disturbs the branch target cache.  Instead push the return +	   address back on the stack.  */ +	pushl	%ecx + +	cmpl	$-4095, %eax +	/* Branch forward if it failed.  */ +# ifdef __ASSUME_VFORK_SYSCALL +	jae	SYSCALL_ERROR_LABEL +.Lpseudo_end: +# else +	jae	.Lerror +# endif + +	ret + +# ifndef __ASSUME_VFORK_SYSCALL +.Lerror: +	/* Check if vfork syscall is known at all.  */ +	cmpl	$-ENOSYS, %eax +	jne	SYSCALL_ERROR_LABEL +# endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL +	/* If we don't have vfork, fork is close enough.  */ + +	movl	$SYS_ify (fork), %eax +	int	$0x80 +	cmpl	$-4095, %eax +	jae	SYSCALL_ERROR_LABEL +.Lpseudo_end: +	ret +#elif !defined __NR_vfork +# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined" +#endif +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h new file mode 100644 index 000000000..ad12181ff --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h @@ -0,0 +1,91 @@ +/* Minimum guaranteed maximum values for system limits.  Linux/Alpha version. +   Copyright (C) 1993-1998,2000,2002,2003,2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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; see the file COPYING.LIB.  If +   not, see <http://www.gnu.org/licenses/>.  */ + +/* The kernel header pollutes the namespace with the NR_OPEN symbol +   and defines LINK_MAX although filesystems have different maxima.  A +   similar thing is true for OPEN_MAX: the limit can be changed at +   runtime and therefore the macro must not be defined.  Remove this +   after including the header if necessary.  */ +#ifndef NR_OPEN +# define __undef_NR_OPEN +#endif +#ifndef LINK_MAX +# define __undef_LINK_MAX +#endif +#ifndef OPEN_MAX +# define __undef_OPEN_MAX +#endif + +/* The kernel sources contain a file with all the needed information.  */ +#include <linux/limits.h> + +/* Have to remove NR_OPEN?  */ +#ifdef __undef_NR_OPEN +# undef NR_OPEN +# undef __undef_NR_OPEN +#endif +/* Have to remove LINK_MAX?  */ +#ifdef __undef_LINK_MAX +# undef LINK_MAX +# undef __undef_LINK_MAX +#endif +/* Have to remove OPEN_MAX?  */ +#ifdef __undef_OPEN_MAX +# undef OPEN_MAX +# undef __undef_OPEN_MAX +#endif + +/* The number of data keys per process.  */ +#define _POSIX_THREAD_KEYS_MAX	128 +/* This is the value this implementation supports.  */ +#define PTHREAD_KEYS_MAX	1024 + +/* Controlling the iterations of destructors for thread-specific data.  */ +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4 +/* Number of iterations this implementation does.  */ +#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS + +/* The number of threads per process.  */ +#define _POSIX_THREAD_THREADS_MAX	64 +/* This is the value this implementation supports.  */ +#define PTHREAD_THREADS_MAX	16384 + +/* Maximum amount by which a process can descrease its asynchronous I/O +   priority level.  */ +#define AIO_PRIO_DELTA_MAX	20 + +/* Minimum size for a thread.  We are free to choose a reasonable value.  */ +#define PTHREAD_STACK_MIN	196608 + +/* Maximum number of POSIX timers available.  */ +#define TIMER_MAX	256 + +/* Maximum number of timer expiration overruns.  */ +#define DELAYTIMER_MAX	2147483647 + +/* Maximum tty name length.  */ +#define TTY_NAME_MAX		32 + +/* Maximum login name length.  This is arbitrary.  */ +#define LOGIN_NAME_MAX		256 + +/* Maximum host name length.  */ +#define HOST_NAME_MAX		64 + +/* Maximum message queue priority level.  */ +#define MQ_PRIO_MAX		32768 diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h new file mode 100644 index 000000000..88f286145 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <signal.h> +#include <sysdep.h> + +#define ARCH_FORK() INLINE_SYSCALL (clone, 2, SIGCHLD, 0) + +#include_next <fork.h> diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c new file mode 100644 index 000000000..025566587 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c @@ -0,0 +1,141 @@ +/* Special .init and .fini section support for ia64. LinuxThreads version. +   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it +   and/or 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. + +   In addition to the permissions in the GNU Lesser General Public +   License, the Free Software Foundation gives you unlimited +   permission to link the compiled version of this file with other +   programs, and to distribute those programs without any restriction +   coming from the use of this file.  (The Lesser General Public +   License restrictions do apply in other respects; for example, they +   cover modification of the file, and distribution when not linked +   into another program.) + +   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; see the file COPYING.LIB.  If not, +   see <http://www.gnu.org/licenses/>.  */ + +/* This file is compiled into assembly code which is then munged by a sed +   script into two files: crti.s and crtn.s. + +   * crti.s puts a function prologue at the beginning of the +   .init and .fini sections and defines global symbols for +   those addresses, so they can be called as functions. + +   * crtn.s puts the corresponding function epilogues +   in the .init and .fini sections. */ + +#include <stddef.h> + +#ifdef HAVE_INITFINI_ARRAY + +# define INIT_NEW_WAY \ +    ".xdata8 \".init_array\", @fptr(__pthread_initialize_minimal)\n" +# define INIT_OLD_WAY "" +#else +# define INIT_NEW_WAY "" +# define INIT_OLD_WAY \ +	"\n\ +	st8 [r12] = gp, -16\n\ +	br.call.sptk.many b0 = __pthread_initialize_minimal# ;;\n\ +	;;\n\ +	adds r12 = 16, r12\n\ +	;;\n\ +	ld8 gp = [r12]\n\ +	;;\n" +#endif + +__asm__ ("\n\ +\n\ +#include \"defs.h\"\n\ +\n\ +/*@HEADER_ENDS*/\n\ +\n\ +/*@_init_PROLOG_BEGINS*/\n" +	INIT_NEW_WAY +	".section .init\n\ +	.align 16\n\ +	.global _init#\n\ +	.proc _init#\n\ +_init:\n\ +	.prologue\n\ +	.save ar.pfs, r34\n\ +	alloc r34 = ar.pfs, 0, 3, 0, 0\n\ +	.vframe r32\n\ +	mov r32 = r12\n\ +	.save rp, r33\n\ +	mov r33 = b0\n\ +	.body\n\ +	adds r12 = -16, r12\n\ +	;;\n" +	INIT_OLD_WAY +	".endp _init#\n\ +\n\ +/*@_init_PROLOG_ENDS*/\n\ +\n\ +/*@_init_EPILOG_BEGINS*/\n\ +	.section .init\n\ +	.proc _init#\n\ +_init:\n\ +	.prologue\n\ +	.save ar.pfs, r34\n\ +	.vframe r32\n\ +	.save rp, r33\n\ +	.body\n\ +	mov r12 = r32\n\ +	mov ar.pfs = r34\n\ +	mov b0 = r33\n\ +	br.ret.sptk.many b0\n\ +	.endp _init#\n\ +/*@_init_EPILOG_ENDS*/\n\ +\n\ +/*@_fini_PROLOG_BEGINS*/\n\ +	.section .fini\n\ +	.align 16\n\ +	.global _fini#\n\ +	.proc _fini#\n\ +_fini:\n\ +	.prologue\n\ +	.save ar.pfs, r34\n\ +	alloc r34 = ar.pfs, 0, 3, 0, 0\n\ +	.vframe r32\n\ +	mov r32 = r12\n\ +	.save rp, r33\n\ +	mov r33 = b0\n\ +	.body\n\ +	adds r12 = -16, r12\n\ +	;;\n\ +	.endp _fini#\n\ +\n\ +/*@_fini_PROLOG_ENDS*/\n\ +\n\ +/*@_fini_EPILOG_BEGINS*/\n\ +	.section .fini\n\ +	.proc _fini#\n\ +_fini:\n\ +	.prologue\n\ +	.save ar.pfs, r34\n\ +	.vframe r32\n\ +	.save rp, r33\n\ +	.body\n\ +	mov r12 = r32\n\ +	mov ar.pfs = r34\n\ +	mov b0 = r33\n\ +	br.ret.sptk.many b0\n\ +	.endp _fini#\n\ +\n\ +/*@_fini_EPILOG_ENDS*/\n\ +\n\ +/*@TRAILER_BEGINS*/\n\ +	.weak	__gmon_start__#\n\ +"); diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c new file mode 100644 index 000000000..edb08439a --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c @@ -0,0 +1,32 @@ +/* Internal sigsuspend system call for LinuxThreads.  IA64 version. +   Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <errno.h> +#include <signal.h> +#include <unistd.h> + +#include <sysdep.h> +#include <sys/syscall.h> +#include <linuxthreads/internals.h> + +void +__pthread_sigsuspend (const sigset_t *set) +{ +  INTERNAL_SYSCALL_DECL (err); +  INTERNAL_SYSCALL (rt_sigsuspend, err, 2, set, _NSIG / 8); +} diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h new file mode 100644 index 000000000..595644044 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h @@ -0,0 +1,143 @@ +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#include <tls.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# ifdef IS_IN_librt +#  define PSEUDO_NLOCAL		6 +#  define PSEUDO_SAVE_GP	mov loc5 = gp +#  define PSEUDO_RESTORE_GP	mov gp = loc5 +#  define PSEUDO_SAVE_GP_1 +#  define PSEUDO_RESTORE_GP_1	mov gp = loc5 +# else +#  define PSEUDO_NLOCAL		5 +#  define PSEUDO_SAVE_GP +#  define PSEUDO_RESTORE_GP +#  define PSEUDO_SAVE_GP_1	mov loc4 = gp;; +#  define PSEUDO_RESTORE_GP_1	mov gp = loc4 +# endif + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				      \ +.text;									      \ +ENTRY (name)								      \ +     adds r14 = MULTIPLE_THREADS_OFFSET, r13;;				      \ +     ld4 r14 = [r14];							      \ +     mov r15 = SYS_ify(syscall_name);;					      \ +     cmp4.ne p6, p7 = 0, r14;						      \ +(p6) br.cond.spnt .Lpseudo_cancel;;					      \ +     break __BREAK_SYSCALL;;						      \ +     cmp.eq p6,p0=-1,r10;						      \ +(p6) br.cond.spnt.few __syscall_error;					      \ +     ret;;								      \ +     .endp name;							      \ +     .proc __GC_##name;							      \ +     .globl __GC_##name;						      \ +     .hidden __GC_##name;						      \ +__GC_##name:								      \ +.Lpseudo_cancel:							      \ +     .prologue;								      \ +     .regstk args, PSEUDO_NLOCAL, args, 0;				      \ +     .save ar.pfs, loc0;						      \ +     alloc loc0 = ar.pfs, args, PSEUDO_NLOCAL, args, 0;			      \ +     .save rp, loc1;							      \ +     mov loc1 = rp;							      \ +     PSEUDO_SAVE_GP;;							      \ +     .body;								      \ +     CENABLE;;								      \ +     PSEUDO_RESTORE_GP;							      \ +     mov loc2 = r8;							      \ +     COPY_ARGS_##args							      \ +     mov r15 = SYS_ify(syscall_name);					      \ +     break __BREAK_SYSCALL;;						      \ +     mov loc3 = r8;							      \ +     mov loc4 = r10;							      \ +     mov out0 = loc2;							      \ +     CDISABLE;;								      \ +     PSEUDO_RESTORE_GP;							      \ +     cmp.eq p6,p0=-1,loc4;						      \ +(p6) br.cond.spnt.few __syscall_error_##args;				      \ +     mov r8 = loc3;							      \ +     mov rp = loc1;							      \ +     mov ar.pfs = loc0;							      \ +.Lpseudo_end:								      \ +     ret;								      \ +     .endp __GC_##name;							      \ +.section .gnu.linkonce.t.__syscall_error_##args, "ax";			      \ +     .align 32;								      \ +     .proc __syscall_error_##args;					      \ +     .global __syscall_error_##args;					      \ +     .hidden __syscall_error_##args;					      \ +     .size __syscall_error_##args, 64;					      \ +__syscall_error_##args:							      \ +     .prologue;								      \ +     .regstk args, PSEUDO_NLOCAL, args, 0;				      \ +     .save ar.pfs, loc0;						      \ +     .save rp, loc1;							      \ +     .body;								      \ +     PSEUDO_SAVE_GP_1;							      \ +     br.call.sptk.many b0 = __errno_location;;				      \ +     st4 [r8] = loc3;							      \ +     PSEUDO_RESTORE_GP_1;						      \ +     mov rp = loc1;							      \ +     mov r8 = -1;							      \ +     mov ar.pfs = loc0 + +#undef PSEUDO_END +#define PSEUDO_END(name) .endp + +# ifdef IS_IN_libpthread +#  define CENABLE	br.call.sptk.many b0 = __pthread_enable_asynccancel +#  define CDISABLE	br.call.sptk.many b0 = __pthread_disable_asynccancel +# elif !defined NOT_IN_libc +#  define CENABLE	br.call.sptk.many b0 = __libc_enable_asynccancel +#  define CDISABLE	br.call.sptk.many b0 = __libc_disable_asynccancel +# else +#  define CENABLE	br.call.sptk.many b0 = __librt_enable_asynccancel +#  define CDISABLE	br.call.sptk.many b0 = __librt_disable_asynccancel +# endif + +#define COPY_ARGS_0	/* Nothing */ +#define COPY_ARGS_1	COPY_ARGS_0 mov out0 = in0; +#define COPY_ARGS_2	COPY_ARGS_1 mov out1 = in1; +#define COPY_ARGS_3	COPY_ARGS_2 mov out2 = in2; +#define COPY_ARGS_4	COPY_ARGS_3 mov out3 = in3; +#define COPY_ARGS_5	COPY_ARGS_4 mov out4 = in4; +#define COPY_ARGS_6	COPY_ARGS_5 mov out5 = in5; +#define COPY_ARGS_7	COPY_ARGS_6 mov out6 = in6; + +# ifndef __ASSEMBLER__ +#  define SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1) +# else +#  define SINGLE_THREAD_P \ +  adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14 +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S new file mode 100644 index 000000000..9b5fa767f --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S @@ -0,0 +1,53 @@ +/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + + +#include <sysdep-cancel.h> +#define _SIGNAL_H +#include <bits/signum.h> + +/* The following are defined in linux/sched.h, which unfortunately	*/ +/* is not safe for inclusion in an assembly file.			*/ +#define CLONE_VM        0x00000100      /* set if VM shared between processes */ +#define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */ + +/* pid_t vfork(void); */ +/* Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0)	*/ + +ENTRY(__vfork) +#ifdef SHARED +	addl r14 = @gprel(__libc_pthread_functions#), gp;; +#else +	.weak	pthread_create +	addl r14 = @ltoff(@fptr(pthread_create#)), gp;; +#endif +	ld8 r14 = [r14];; +	cmp.ne p6, p7 = 0, r14 +(p6)	br.cond.spnt.few HIDDEN_JUMPTARGET (fork);; +	alloc r2=ar.pfs,0,0,2,0 +	mov out0=CLONE_VM+CLONE_VFORK+SIGCHLD +	mov out1=0		/* Standard sp value.			*/ +	;; +	DO_CALL (SYS_ify (clone)) +	cmp.eq p6,p0=-1,r10 +	;; +(p6)	br.cond.spnt.few __syscall_error +	ret +PSEUDO_END(__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c new file mode 100644 index 000000000..3e04f515f --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c @@ -0,0 +1,34 @@ +/* _longjmp_unwind -- Clean up stack frames unwound by longjmp. +   Copyright (C) 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <setjmp.h> +#include <stddef.h> +#include <bits/libc-lock.h> + +#ifndef SHARED +weak_extern (__pthread_cleanup_upto); +#endif + +void +_longjmp_unwind (jmp_buf env, int val) +{ +  __libc_maybe_call2 (pthread_cleanup_upto, +		      (env->__jmpbuf, __builtin_frame_address (0)), +		      (void) 0); +} +libc_hidden_def(_longjmp_unwind) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h new file mode 100644 index 000000000..54b99d688 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h @@ -0,0 +1,128 @@ +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Andreas Schwab <schwab@suse.de>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.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)								      \ +    SINGLE_THREAD_P;							      \ +    jne .Lpseudo_cancel;						      \ +    DO_CALL (syscall_name, args);					      \ +    cmp.l &-4095, %d0;							      \ +    jcc SYSCALL_ERROR_LABEL;						      \ +    rts;								      \ +  .Lpseudo_cancel:							      \ +    CENABLE;								      \ +    DOCARGS_##args							      \ +    move.l %d0, -(%sp);							      \ +    move.l &SYS_ify (syscall_name), %d0;				      \ +    trap &0;								      \ +    move.l %d0, %d2;							      \ +    CDISABLE;								      \ +    addq.l &4, %sp;							      \ +    move.l %d2, %d0;							      \ +    UNDOCARGS_##args							      \ +    cmp.l &-4095, %d0;							      \ +    jcc SYSCALL_ERROR_LABEL + +# define DOCARGS_0	move.l %d2, -(%sp); +# define _DOCARGS_0(n) +# define UNDOCARGS_0	move.l (%sp)+, %d2; + +# define DOCARGS_1	_DOCARGS_1 (4); DOCARGS_0 +# define _DOCARGS_1(n)	move.l n(%sp), %d1; _DOARGS_0 (n) +# define UNDOCARGS_1	UNDOCARGS_0 + +# define DOCARGS_2	_DOCARGS_2 (8) +# define _DOCARGS_2(n)	move.l %d2, -(%sp); move.l n+4(%sp), %d2;	\ +			_DOCARGS_1 (n) +# define UNDOCARGS_2	UNDOCARGS_1 + +# define DOCARGS_3	_DOCARGS_3 (12) +# define _DOCARGS_3(n)	move.l %d3, -(%sp); move.l n+4(%sp), %d3;	\ +  	 		_DOCARGS_2 (n) +# define UNDOCARGS_3	UNDOCARGS_2; move.l (%sp)+, %d3; + +# define DOCARGS_4	_DOCARGS_4 (16) +# define _DOCARGS_4(n)	move.l %d4, -(%sp); move.l n+4(%sp), %d4;	\ +			_DOCARGS_3 (n) +# define UNDOCARGS_4	UNDOCARGS_3; move.l (%sp)+, %d4; + +# define DOCARGS_5	_DOCARGS_5 (20) +# define _DOCARGS_5(n)	move.l %d5, -(%sp); move.l n+4(%sp), %d5;	\ +			_DOCARGS_4 (n) +# define UNDOCARGS_5	UNDOCARGS_4; move.l (%sp)+, %d5; + +# ifdef IS_IN_libpthread +#  ifdef __PIC__ +#   define CENABLE	jbsr __pthread_enable_asynccancel@PLTPC +#   define CDISABLE	jbsr __pthread_disable_asynccancel@PLTPC +#  else +#   define CENABLE	jbsr __pthread_enable_asynccancel +#   define CDISABLE	jbsr __pthread_disable_asynccancel +#  endif +# elif !defined NOT_IN_libc +#  ifdef __PIC__ +#   define CENABLE	jbsr __libc_enable_asynccancel@PLTPC +#   define CDISABLE	jbsr __libc_disable_asynccancel@PLTPC +#  else +#   define CENABLE	jbsr __libc_enable_asynccancel +#   define CDISABLE	jbsr __libc_disable_asynccancel +#  endif +# else +#  ifdef __PIC__ +#   define CENABLE	jbsr __librt_enable_asynccancel@PLTPC +#   define CDISABLE	jbsr __librt_disable_asynccancel@PLTPC +#  else +#   define CENABLE	jbsr __librt_enable_asynccancel +#   define CDISABLE	jbsr __librt_disable_asynccancel +#  endif +# endif + +# if !defined NOT_IN_libc +#  define __local_multiple_threads __libc_multiple_threads +# elif defined IS_IN_libpthread +#  define __local_multiple_threads __pthread_multiple_threads +# else +#  define __local_multiple_threads __librt_multiple_threads +# endif + +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +#  if !defined __PIC__ +#   define SINGLE_THREAD_P tst.l __local_multiple_threads +#  else +#   define SINGLE_THREAD_P tst.l (__local_multiple_threads, %pc) +#  endif +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S new file mode 100644 index 000000000..2a4d3862c --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S @@ -0,0 +1,83 @@ +/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Andreas Schwab <schwab@gnu.org>. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep-cancel.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <bits/kernel-features.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) + +#ifdef SHARED +	tstl	(__libc_pthread_functions@GOTPC, %pc) +#else +	.weak	pthread_create +	movel	#pthread_create, %d0 +#endif +	jbne	HIDDEN_JUMPTARGET (fork) + +#ifdef __NR_vfork + +	/* Pop the return PC value into A0.  */ +	movel	%sp@+, %a0 + +	/* Stuff the syscall number in D0 and trap into the kernel.  */ +	movel	#SYS_ify (vfork), %d0 +	trap	#0 +	tstl	%d0 +	jmi	.Lerror		/* Branch forward if it failed.  */ + +	/* Jump to the return PC.  */ +	jmp	%a0@ + +.Lerror: +	/* Push back the return PC.  */ +	movel	%a0,%sp@- + +# ifdef __ASSUME_VFORK_SYSCALL +#  ifndef __PIC__ +	jbra	SYSCALL_ERROR_LABEL +#  endif +# else +	/* Check if vfork syscall is known at all.  */ +	movel	#-ENOSYS,%d1 +	cmpl	%d0,%d1 +	jne	SYSCALL_ERROR_LABEL + +# endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL +	/* If we don't have vfork, fork is close enough.  */ + +	movel	#SYS_ify (fork), %d0 +	trap	#0 +	tstl	%d0 +	jmi	SYSCALL_ERROR_LABEL +	rts +#endif + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h new file mode 100644 index 000000000..10c82a61c --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h @@ -0,0 +1,143 @@ +/* system call stubs with cancellation handling.  Linux/MIPS version. +   Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Chris Demetriou of Broadcom Corporation, +   based on work by Guido Guenther <agx@sigxcpu.org>. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif +#include <sys/asm.h> + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +#ifdef __PIC__ +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				      \ +  .align 2;								      \ +  99: move a0, v0; 							      \ +  PTR_LA t9,__syscall_error;					 	      \ +  /* manual cpreturn.  */						      \ +  REG_L gp, STKOFF_GP(sp);						      \ +  RESTORESTK ;								      \ +  jr t9;								      \ +  ENTRY (name)								      \ +    SAVESTK ;								      \ +    .cpsetup t9, STKOFF_GP, name ;					      \ +    .set reorder;							      \ +    SINGLE_THREAD_P(t0);						      \ +    bne zero, t0, L(pseudo_cancel);					      \ +    .set noreorder;							      \ +    li v0, SYS_ify(syscall_name);					      \ +    syscall;								      \ +    .set reorder;							      \ +    bne a3, zero, SYSCALL_ERROR_LABEL;			       		      \ +    /* manual cpreturn.  */						      \ +    REG_L gp, STKOFF_GP(sp);						      \ +    RESTORESTK ;							      \ +    ret;								      \ +  L(pseudo_cancel):							      \ +    REG_S ra, STKOFF_RA(sp);						      \ +    PUSHARGS_##args;			/* save syscall args */	      	      \ +    CENABLE;								      \ +    REG_S v0, STKOFF_SVMSK(sp);		/* save mask */			      \ +    POPARGS_##args;			/* restore syscall args */	      \ +    .set noreorder;							      \ +    li v0, SYS_ify (syscall_name);				      	      \ +    syscall;								      \ +    .set reorder;							      \ +    REG_S v0, STKOFF_SC_V0(sp);		/* save syscall result */             \ +    REG_S a3, STKOFF_SC_ERR(sp);	/* save syscall error flag */	      \ +    REG_L a0, STKOFF_SVMSK(sp);		/* pass mask as arg1 */		      \ +    CDISABLE;								      \ +    REG_L a3, STKOFF_SC_ERR(sp);	/* restore syscall error flag */      \ +    REG_L ra, STKOFF_RA(sp);		/* restore return address */	      \ +    REG_L v0, STKOFF_SC_V0(sp);		/* restore syscall result */          \ +    bne a3, zero, SYSCALL_ERROR_LABEL;					      \ +    /* manual cpreturn.  */						      \ +    REG_L gp, STKOFF_GP(sp);						      \ +    RESTORESTK ;							      \ +  L(pseudo_end): +#endif + +# define PUSHARGS_0	/* nothing to do */ +# define PUSHARGS_1	PUSHARGS_0 REG_S a0, STKOFF_A0(sp); +# define PUSHARGS_2	PUSHARGS_1 REG_S a1, STKOFF_A1(sp); +# define PUSHARGS_3	PUSHARGS_2 REG_S a2, STKOFF_A2(sp); +# define PUSHARGS_4	PUSHARGS_3 REG_S a3, STKOFF_A3(sp); +# define PUSHARGS_5	PUSHARGS_4 REG_S a4, STKOFF_A4(sp); +# define PUSHARGS_6	PUSHARGS_5 REG_S a5, STKOFF_A5(sp); + +# define POPARGS_0	/* nothing to do */ +# define POPARGS_1	POPARGS_0 REG_L a0, STKOFF_A0(sp); +# define POPARGS_2	POPARGS_1 REG_L a1, STKOFF_A1(sp); +# define POPARGS_3	POPARGS_2 REG_L a2, STKOFF_A2(sp); +# define POPARGS_4	POPARGS_3 REG_L a3, STKOFF_A3(sp); +# define POPARGS_5	POPARGS_4 REG_L a4, STKOFF_A4(sp); +# define POPARGS_6	POPARGS_5 REG_L a5, STKOFF_A5(sp); + +/* Save an even number of slots.  Should be 0 if an even number of slots +   are used below, or SZREG if an odd number are used.  */ +# define STK_PAD	SZREG + +/* Place values that we are more likely to use later in this sequence, i.e. +   closer to the SP at function entry.  If you do that, the are more +   likely to already be in your d-cache.  */ +# define STKOFF_A5	(STK_PAD) +# define STKOFF_A4	(STKOFF_A5 + SZREG) +# define STKOFF_A3	(STKOFF_A4 + SZREG) +# define STKOFF_A2	(STKOFF_A3 + SZREG)	/* MT and more args.  */ +# define STKOFF_A1	(STKOFF_A2 + SZREG)	/* MT and 2 args.  */ +# define STKOFF_A0	(STKOFF_A1 + SZREG)	/* MT and 1 arg.  */ +# define STKOFF_RA	(STKOFF_A0 + SZREG)	/* Used if MT.  */ +# define STKOFF_SC_V0	(STKOFF_RA + SZREG)	/* Used if MT.  */ +# define STKOFF_SC_ERR	(STKOFF_SC_V0 + SZREG)	/* Used if MT.  */ +# define STKOFF_SVMSK	(STKOFF_SC_ERR + SZREG)	/* Used if MT.  */ +# define STKOFF_GP	(STKOFF_SVMSK + SZREG)	/* Always used.  */ + +# define STKSPACE	(STKOFF_GP + SZREG) +# define SAVESTK 	PTR_SUBU sp, STKSPACE +# define RESTORESTK 	PTR_ADDU sp, STKSPACE + +# ifdef IS_IN_libpthread +#  define CENABLE	PTR_LA t9, __pthread_enable_asynccancel; jalr t9; +#  define CDISABLE	PTR_LA t9, __pthread_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __pthread_multiple_threads +# elif defined IS_IN_librt +#  define CENABLE	PTR_LA t9, __librt_enable_asynccancel; jalr t9; +#  define CDISABLE	PTR_LA t9, __librt_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __librt_multiple_threads +# else +#  define CENABLE	PTR_LA t9, __libc_enable_asynccancel; jalr t9; +#  define CDISABLE	PTR_LA t9, __libc_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __libc_multiple_threads +# endif + +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +#  define SINGLE_THREAD_P(reg) lw reg, __local_multiple_threads +#endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h new file mode 100644 index 000000000..4e6dec775 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h @@ -0,0 +1,143 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Guido Guenther <agx@sigxcpu.org>, 2003. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +#ifdef __PIC__ +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				      \ +  .align 2;								      \ +  99: move a0, v0; 							      \ +  la t9,__syscall_error;						      \ +  jr t9;								      \ +  ENTRY (name)								      \ +    .set noreorder;							      \ +    .cpload t9;								      \ +    .set reorder;							      \ +    SINGLE_THREAD_P(t0);						      \ +    bne zero, t0, L(pseudo_cancel);					      \ +    .set noreorder;							      \ +    li v0, SYS_ify(syscall_name);					      \ +    syscall;								      \ +    .set reorder;							      \ +    bne a3, zero, SYSCALL_ERROR_LABEL;			       		      \ +    ret;								      \ +  L(pseudo_cancel):							      \ +    SAVESTK_##args;						              \ +    sw ra, 28(sp);							      \ +    sw gp, 32(sp);							      \ +    PUSHARGS_##args;			/* save syscall args */	      	      \ +    CENABLE;								      \ +    lw gp, 32(sp);							      \ +    sw v0, 44(sp);			/* save mask */			      \ +    POPARGS_##args;			/* restore syscall args */	      \ +    .set noreorder;							      \ +    li v0, SYS_ify (syscall_name);				      	      \ +    syscall;								      \ +    .set reorder;							      \ +    sw v0, 36(sp);			/* save syscall result */             \ +    sw a3, 40(sp);			/* save syscall error flag */	      \ +    lw a0, 44(sp);			/* pass mask as arg1 */		      \ +    CDISABLE;								      \ +    lw gp, 32(sp);							      \ +    lw v0, 36(sp);			/* restore syscall result */          \ +    lw a3, 40(sp);			/* restore syscall error flag */      \ +    lw ra, 28(sp);			/* restore return address */	      \ +    RESTORESTK;							              \ +    bne a3, zero, SYSCALL_ERROR_LABEL;					      \ +  L(pseudo_end): +#endif + +# define PUSHARGS_0	/* nothing to do */ +# define PUSHARGS_1	PUSHARGS_0 sw a0, 0(sp); +# define PUSHARGS_2	PUSHARGS_1 sw a1, 4(sp); +# define PUSHARGS_3	PUSHARGS_2 sw a2, 8(sp); +# define PUSHARGS_4	PUSHARGS_3 sw a3, 12(sp); +# define PUSHARGS_5	PUSHARGS_4 /* handeld by SAVESTK_## */ +# define PUSHARGS_6	PUSHARGS_5 +# define PUSHARGS_7	PUSHARGS_6 + +# define POPARGS_0	/* nothing to do */ +# define POPARGS_1	POPARGS_0 lw a0, 0(sp); +# define POPARGS_2	POPARGS_1 lw a1, 4(sp); +# define POPARGS_3	POPARGS_2 lw a2, 8(sp); +# define POPARGS_4	POPARGS_3 lw a3, 12(sp); +# define POPARGS_5	POPARGS_4 /* args already in new stackframe */ +# define POPARGS_6	POPARGS_5 +# define POPARGS_7	POPARGS_6 + + +# define STKSPACE	48 +# define SAVESTK_0 	subu sp, STKSPACE +# define SAVESTK_1      SAVESTK_0 +# define SAVESTK_2      SAVESTK_1 +# define SAVESTK_3      SAVESTK_2 +# define SAVESTK_4      SAVESTK_3 +# define SAVESTK_5      lw t0, 16(sp);		\ +			subu sp, STKSPACE;	\ +			sw t0, 16(sp) + +# define SAVESTK_6      lw t0, 16(sp);		\ +			lw t1, 20(sp);		\ +			subu sp, STKSPACE;	\ +			sw t0, 16(sp);		\ +			sw t1, 20(sp) + +# define SAVESTK_7      lw t0, 16(sp);		\ +			lw t1, 20(sp);		\ +			lw t2, 24(sp);		\ +			subu sp, STKSPACE;	\ +			sw t0, 16(sp);		\ +			sw t1, 20(sp);		\ +			sw t2, 24(sp) + +# define RESTORESTK 	addu sp, STKSPACE + + +# ifdef IS_IN_libpthread +#  define CENABLE	la t9, __pthread_enable_asynccancel; jalr t9; +#  define CDISABLE	la t9, __pthread_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __pthread_multiple_threads +# elif defined IS_IN_librt +#  define CENABLE	la t9, __librt_enable_asynccancel; jalr t9; +#  define CDISABLE	la t9, __librt_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __librt_multiple_threads +# else +#  define CENABLE	la t9, __libc_enable_asynccancel; jalr t9; +#  define CDISABLE	la t9, __libc_disable_asynccancel; jalr t9; +#  define __local_multiple_threads __libc_multiple_threads +# endif + +# ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +# else +#  define SINGLE_THREAD_P(reg) lw reg, __local_multiple_threads +#endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S new file mode 100644 index 000000000..09dcfa683 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S @@ -0,0 +1,104 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +/* vfork() is just a special case of clone().  */ + +#include <sys/asm.h> +#include <sysdep.h> +#include <asm/unistd.h> + +/* int vfork() */ + +	.text +LOCALSZ= 1 +FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK +GPOFF= FRAMESZ-(1*SZREG) +NESTED(__vfork,FRAMESZ,sp) +#ifdef __PIC__ +	SETUP_GP +#endif +	PTR_SUBU sp, FRAMESZ +	SETUP_GP64 (a5, __vfork) +#ifdef __PIC__ +	SAVE_GP (GPOFF) +#endif +#ifdef PROF +# if (_MIPS_SIM != _ABIO32) +	PTR_S		a5, GPOFF(sp) +# endif +	.set		noat +	move		$1, ra +# if (_MIPS_SIM == _ABIO32) +	subu		sp,sp,8 +# endif +	jal		_mcount +	.set		at +# if (_MIPS_SIM != _ABIO32) +	PTR_L		a5, GPOFF(sp) +# endif +#endif + +	/* If libpthread is loaded, we need to call fork instead.  */ +#ifdef SHARED +	PTR_L		a0, __libc_pthread_functions +#else +	.weak		pthread_create +	PTR_LA		a0, pthread_create +#endif + +	PTR_ADDU	sp, FRAMESZ + +	bnez		a0, L(call_fork) + +	li		a0, 0x4112	/* CLONE_VM | CLONE_VFORK | SIGCHLD */ +	move		a1, sp + +	/* Do the system call */ +	li		v0,__NR_clone +	syscall + +	bnez		a3,L(error) + +	/* Successful return from the parent or child.  */ +	RESTORE_GP64 +	ret + +	/* Something bad happened -- no child created.  */ +L(error): +	move		a0, v0 +#ifdef __PIC__ +	PTR_LA		t9, __syscall_error +	RESTORE_GP64 +	jr		t9 +#else +	RESTORE_GP64 +	j		__syscall_error +#endif + +L(call_fork): +#ifdef __PIC__ +	PTR_LA		t9, fork +	RESTORE_GP64 +	jr		t9 +#else +	RESTORE_GP64 +	j		fork +#endif +	END(__vfork) + +libc_hidden_def(__vfork) +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c new file mode 100644 index 000000000..13daefee6 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c @@ -0,0 +1,284 @@ +/* Copyright (C) 2004, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contribute by Ulrich Drepper <drepper@redhat.com>, 2004. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> +#include <pthread.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <sysdep.h> +#include <unistd.h> +#include <sys/socket.h> +#include <not-cancel.h> + + +#ifdef __NR_mq_notify + +/* Defined in the kernel headers: */ +#define NOTIFY_COOKIE_LEN	32	/* Length of the cookie used.  */ +#define NOTIFY_WOKENUP		1	/* Code for notifcation.  */ +#define NOTIFY_REMOVED		2	/* Code for closed message queue +					   of de-notifcation.  */ + + +/* Data structure for the queued notification requests.  */ +union notify_data +{ +  struct +  { +    void (*fct) (union sigval);	/* The function to run.  */ +    union sigval param;		/* The parameter to pass.  */ +    pthread_attr_t *attr;	/* Attributes to create the thread with.  */ +    /* NB: on 64-bit machines the struct as a size of 24 bytes.  Which means +       byte 31 can still be used for returning the status.  */ +  }; +  char raw[NOTIFY_COOKIE_LEN]; +}; + + +/* Keep track of the initialization.  */ +static pthread_once_t once = PTHREAD_ONCE_INIT; + + +/* The netlink socket.  */ +static int netlink_socket = -1; + + +/* Barrier used to make sure data passed to the new thread is not +   resused by the parent.  */ +static pthread_barrier_t notify_barrier; + + +/* Modify the signal mask.  We move this into a separate function so +   that the stack space needed for sigset_t is not deducted from what +   the thread can use.  */ +static int +__attribute__ ((noinline)) +change_sigmask (int how, sigset_t *oss) +{ +  sigset_t ss; +  __sigfillset (&ss); +  return pthread_sigmask (how, &ss, oss); +} + + +/* The function used for the notification.  */ +static void * +notification_function (void *arg) +{ +  /* Copy the function and parameter so that the parent thread can go +     on with its life.  */ +  __volatile__ union notify_data *data = (__volatile__ union notify_data *) arg; +  void (*fct) (union sigval) = data->fct; +  union sigval param = data->param; + +  /* Let the parent go.  */ +  (void) pthread_barrier_wait (¬ify_barrier); + +  /* Make the thread detached.  */ +  (void) pthread_detach (pthread_self ()); + +  /* The parent thread has all signals blocked.  This is probably a +     bit surprising for this thread.  So we unblock all of them.  */ +  (void) change_sigmask (SIG_UNBLOCK, NULL); + +  /* Now run the user code.  */ +  fct (param); + +  /* And we are done.  */ +  return NULL; +} + + +/* Helper thread.  */ +static void * +helper_thread (void *arg) +{ +  while (1) +    { +      union notify_data data; + +      ssize_t n = recv (netlink_socket, &data, sizeof (data), +			MSG_NOSIGNAL | MSG_WAITALL); +      if (n < NOTIFY_COOKIE_LEN) +	continue; + +      if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_WOKENUP) +	{ +	  /* Just create the thread as instructed.  There is no way to +	     report a problem with creating a thread.  */ +	  pthread_t th; +	  if (__builtin_expect (pthread_create (&th, data.attr, +						notification_function, &data) +				== 0, 0)) +	    /* Since we passed a pointer to DATA to the new thread we have +	       to wait until it is done with it.  */ +	    (void) pthread_barrier_wait (¬ify_barrier); +	} +      else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED) +	/* The only state we keep is the copy of the thread attributes.  */ +	free (data.attr); +    } +  return NULL; +} + + +static void +reset_once (void) +{ +  once = PTHREAD_ONCE_INIT; +} + + +static void +init_mq_netlink (void) +{ +  /* This code might be called a second time after fork().  The file +     descriptor is inherited from the parent.  */ +  if (netlink_socket == -1) +    { +      /* Just a normal netlink socket, not bound.  */ +      netlink_socket = socket (AF_NETLINK, SOCK_RAW, 0); +      /* No need to do more if we have no socket.  */ +      if (netlink_socket == -1) +	return; + +      /* Make sure the descriptor is closed on exec.  */ +      fcntl (netlink_socket, F_SETFD, FD_CLOEXEC); +    } + +  int err = 1; + +  /* Initialize the barrier.  */ +  if (__builtin_expect (pthread_barrier_init (¬ify_barrier, NULL, 2) == 0, +			0)) +    { +      /* Create the helper thread.  */ +      pthread_attr_t attr; +      (void) pthread_attr_init (&attr); +      (void) pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); +      /* We do not need much stack space, the bare minimum will be enough.  */ +      (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); + +      /* Temporarily block all signals so that the newly created +	 thread inherits the mask.  */ +      sigset_t oss; +      int have_no_oss = change_sigmask (SIG_BLOCK, &oss); + +      pthread_t th; +      err = pthread_create (&th, &attr, helper_thread, NULL); + +      /* Reset the signal mask.  */ +      if (!have_no_oss) +	pthread_sigmask (SIG_SETMASK, &oss, NULL); + +      (void) pthread_attr_destroy (&attr); + +      if (err == 0) +	{ +	  static smallint added_atfork; + +	  if (added_atfork == 0 +	      && pthread_atfork (NULL, NULL, reset_once) != 0) +	    { +	      /* The child thread will call recv() which is a +		 cancellation point.  */ +	      (void) pthread_cancel (th); +	      err = 1; +	    } +	  else +	    added_atfork = 1; +	} +    } + +  if (err != 0) +    { +      close_not_cancel_no_status (netlink_socket); +      netlink_socket = -1; +    } +} + + +/* Register notification upon message arrival to an empty message queue +   MQDES.  */ +int +mq_notify (mqd_t mqdes, const struct sigevent *notification) +{ +  /* Make sure the type is correctly defined.  */ +  assert (sizeof (union notify_data) == NOTIFY_COOKIE_LEN); + +  /* Special treatment needed for SIGEV_THREAD.  */ +  if (notification == NULL || notification->sigev_notify != SIGEV_THREAD) +    return INLINE_SYSCALL (mq_notify, 2, mqdes, notification); + +  /* The kernel cannot directly start threads.  This will have to be +     done at userlevel.  Since we cannot start threads from signal +     handlers we have to create a dedicated thread which waits for +     notifications for arriving messages and creates threads in +     response.  */ + +  /* Initialize only once.  */ +  pthread_once (&once, init_mq_netlink); + +  /* If we cannot create the netlink socket we cannot provide +     SIGEV_THREAD support.  */ +  if (__builtin_expect (netlink_socket == -1, 0)) +    { +      __set_errno (ENOSYS); +      return -1; +    } + +  /* Create the cookie.  It will hold almost all the state.  */ +  union notify_data data; +  memset (&data, '\0', sizeof (data)); +  data.fct = notification->sigev_notify_function; +  data.param = notification->sigev_value; + +  if (notification->sigev_notify_attributes != NULL) +    { +      /* The thread attribute has to be allocated separately.  */ +      data.attr = (pthread_attr_t *) malloc (sizeof (pthread_attr_t)); +      if (data.attr == NULL) +	return -1; + +      memcpy (data.attr, notification->sigev_notify_attributes, +	      sizeof (pthread_attr_t)); +    } + +  /* Construct the new request.  */ +  struct sigevent se; +  se.sigev_notify = SIGEV_THREAD; +  se.sigev_signo = netlink_socket; +  se.sigev_value.sival_ptr = &data; + +  /* Tell the kernel.  */ +  int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se); + +  /* If it failed, free the allocated memory.  */ +  if (__builtin_expect (retval != 0, 0)) +    free (data.attr); + +  return retval; +} + +#else +# include <rt/mq_notify.c> +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h new file mode 100644 index 000000000..6c3dc12a0 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h @@ -0,0 +1,158 @@ +/* Copyright (C) 2003, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#include <tls.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				\ +  .section ".text";							\ +  ENTRY (name)								\ +    SINGLE_THREAD_P;							\ +    bne- .Lpseudo_cancel;						\ +    DO_CALL (SYS_ify (syscall_name));					\ +    PSEUDO_RET;								\ +  .Lpseudo_cancel:							\ +    stwu 1,-48(1);							\ +    mflr 9;								\ +    stw 9,52(1);							\ +    CGOTSETUP;								\ +    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\ +    CENABLE;								\ +    stw 3,16(1);	/* store CENABLE return value (MASK).  */	\ +    UNDOCARGS_##args;	/* restore syscall args.  */			\ +    DO_CALL (SYS_ify (syscall_name));					\ +    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\ +    stw 3,8(1);								\ +    stw 0,12(1);							\ +    lwz 3,16(1);	/* pass MASK to CDISABLE.  */			\ +    CDISABLE;								\ +    lwz 4,52(1);							\ +    lwz 0,12(1);	/* restore CR/R3. */				\ +    lwz 3,8(1);								\ +    CGOTRESTORE;							\ +    mtlr 4;								\ +    mtcr 0;								\ +    addi 1,1,48; + +# define DOCARGS_0 +# define UNDOCARGS_0 + +# define DOCARGS_1	stw 3,20(1); DOCARGS_0 +# define UNDOCARGS_1	lwz 3,20(1); UNDOCARGS_0 + +# define DOCARGS_2	stw 4,24(1); DOCARGS_1 +# define UNDOCARGS_2	lwz 4,24(1); UNDOCARGS_1 + +# define DOCARGS_3	stw 5,28(1); DOCARGS_2 +# define UNDOCARGS_3	lwz 5,28(1); UNDOCARGS_2 + +# define DOCARGS_4	stw 6,32(1); DOCARGS_3 +# define UNDOCARGS_4	lwz 6,32(1); UNDOCARGS_3 + +# define DOCARGS_5	stw 7,36(1); DOCARGS_4 +# define UNDOCARGS_5	lwz 7,36(1); UNDOCARGS_4 + +# define DOCARGS_6	stw 8,40(1); DOCARGS_5 +# define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5 + +# define CGOTSETUP +# define CGOTRESTORE + +# ifdef IS_IN_libpthread +#  define CENABLE	bl __pthread_enable_asynccancel@local +#  define CDISABLE	bl __pthread_disable_asynccancel@local +# elif !defined NOT_IN_libc +#  define CENABLE	bl __libc_enable_asynccancel@local +#  define CDISABLE	bl __libc_disable_asynccancel@local +# else +#  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel) +#  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel) +#  if defined HAVE_AS_REL16 && defined __PIC__ +#   undef CGOTSETUP +#   define CGOTSETUP							\ +    bcl 20,31,1f;							\ + 1: stw 30,44(1);							\ +    mflr 30;								\ +    addis 30,30,_GLOBAL_OFFSET_TABLE-1b@ha;				\ +    addi 30,30,_GLOBAL_OFFSET_TABLE-1b@l +#   undef CGOTRESTORE +#   define CGOTRESTORE							\ +    lwz 30,44(1) +#  endif +# endif + +# ifdef HAVE_TLS_SUPPORT +#  ifndef __ASSEMBLER__ +#   define SINGLE_THREAD_P						\ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1) +#  else +#   define SINGLE_THREAD_P						\ +  lwz 10,MULTIPLE_THREADS_OFFSET(2);					\ +  cmpwi 10,0 +#  endif +# else +#  if !defined NOT_IN_libc +#   define __local_multiple_threads __libc_multiple_threads +#  else +#   define __local_multiple_threads __librt_multiple_threads +#  endif +#  ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +#  else +#   if !defined __PIC__ +#    define SINGLE_THREAD_P						\ +  lis 10,__local_multiple_threads@ha;					\ +  lwz 10,__local_multiple_threads@l(10);				\ +  cmpwi 10,0 +#   else +#    ifdef HAVE_ASM_PPC_REL16 +#     define SINGLE_THREAD_P						\ +  mflr 9;								\ +  bcl 20,31,1f;								\ +1:mflr 10;								\ +  addis 10,10,__local_multiple_threads-1b@ha;				\ +  lwz 10,__local_multiple_threads-1b@l(10);				\ +  mtlr 9;								\ +  cmpwi 10,0 +#    else +#     define SINGLE_THREAD_P						\ +  mflr 9;								\ +  bl _GLOBAL_OFFSET_TABLE_@local-4;					\ +  mflr 10;								\ +  mtlr 9;								\ +  lwz 10,__local_multiple_threads@got(10);				\ +  lwz 10,0(10);								\ +  cmpwi 10,0 +#    endif +#   endif +#  endif +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S new file mode 100644 index 000000000..4b16829be --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S @@ -0,0 +1,85 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep-cancel.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <bits/kernel-features.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) + +#ifdef __NR_vfork +# ifdef SHARED +	mflr	9 +#  ifdef HAVE_ASM_PPC_REL16 +	bcl	20,31,1f +1:	mflr	10 +	addis	10,10,__libc_pthread_functions-1b@ha +	lwz	10,__libc_pthread_functions-1b@l(10) +	mtlr	9 +#  else +	bl	_GLOBAL_OFFSET_TABLE_@local-4 +	mflr	10 +	mtlr	9 +	lwz	10,__libc_pthread_functions@got(10) +	lwz	10,0(10) +#  endif +# else +	.weak	pthread_create +	lis	10,pthread_create@ha +	la	10,pthread_create@l(10) +# endif + +	cmpwi	10,0 +	bne-	.Lhidden_fork + +	DO_CALL (SYS_ify (vfork)); + +# ifdef __ASSUME_VFORK_SYSCALL +	PSEUDO_RET +# else +	bnslr+ +	/* Check if vfork syscall is known at all.  */ +	cmpwi	r3,ENOSYS +	bne-	.Lsyscall_error + +# endif + +.Lhidden_fork: +	b	HIDDEN_JUMPTARGET(fork) + +#endif + +#ifndef __ASSUME_VFORK_SYSCALL +	/* If we don't have vfork, fork is close enough.  */ + +	DO_CALL (SYS_ify (fork)); +	bnslr+ + +.Lsyscall_error: +	b	__syscall_error@local +#endif + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h new file mode 100644 index 000000000..901982ec8 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h @@ -0,0 +1,126 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#include <tls.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				\ +  .section ".text";							\ +  ENTRY (name)								\ +    SINGLE_THREAD_P;							\ +    bne- .Lpseudo_cancel;						\ +    DO_CALL (SYS_ify (syscall_name));					\ +    PSEUDO_RET;								\ +  .Lpseudo_cancel:							\ +    stdu 1,-128(1);							\ +    mflr 9;								\ +    std  9,128+16(1);							\ +    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\ +    CENABLE;								\ +    std  3,72(1);	/* store CENABLE return value (MASK).  */	\ +    UNDOCARGS_##args;	/* restore syscall args.  */			\ +    DO_CALL (SYS_ify (syscall_name));					\ +    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\ +    std  3,64(1);								\ +    std  0,8(1);							\ +    ld   3,72(1);	/* pass MASK to CDISABLE.  */			\ +    CDISABLE;								\ +    ld   9,128+16(1);							\ +    ld   0,8(1);	/* restore CR/R3. */				\ +    ld   3,64(1);								\ +    mtlr 9;								\ +    mtcr 0;								\ +    addi 1,1,128; + +# define DOCARGS_0 +# define UNDOCARGS_0 + +# define DOCARGS_1	std 3,80(1); DOCARGS_0 +# define UNDOCARGS_1	ld 3,80(1); UNDOCARGS_0 + +# define DOCARGS_2	std 4,88(1); DOCARGS_1 +# define UNDOCARGS_2	ld 4,88(1); UNDOCARGS_1 + +# define DOCARGS_3	std 5,96(1); DOCARGS_2 +# define UNDOCARGS_3	ld 5,96(1); UNDOCARGS_2 + +# define DOCARGS_4	std 6,104(1); DOCARGS_3 +# define UNDOCARGS_4	ld 6,104(1); UNDOCARGS_3 + +# define DOCARGS_5	std 7,112(1); DOCARGS_4 +# define UNDOCARGS_5	ld 7,112(1); UNDOCARGS_4 + +# define DOCARGS_6	std 8,120(1); DOCARGS_5 +# define UNDOCARGS_6	ld 8,120(1); UNDOCARGS_5 + +# ifdef IS_IN_libpthread +#  define CENABLE	bl JUMPTARGET(__pthread_enable_asynccancel) +#  define CDISABLE	bl JUMPTARGET(__pthread_disable_asynccancel) +#  define __local_multiple_threads __pthread_multiple_threads +# elif !defined NOT_IN_libc +#  define CENABLE	bl JUMPTARGET(__libc_enable_asynccancel) +#  define CDISABLE	bl JUMPTARGET(__libc_disable_asynccancel) +#  define __local_multiple_threads __libc_multiple_threads +# else +#  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel); nop +#  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel); nop +#  define __local_multiple_threads __librt_multiple_threads +# endif + +# ifdef HAVE_TLS_SUPPORT +#  ifndef __ASSEMBLER__ +#   define SINGLE_THREAD_P						\ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1) +#  else +#   define SINGLE_THREAD_P						\ +  lwz 10,MULTIPLE_THREADS_OFFSET(13);					\ +  cmpwi 10,0 +#  endif +# else /* !HAVE_TLS_SUPPORT */ +#  ifndef __ASSEMBLER__ +extern int __local_multiple_threads +#   if !defined NOT_IN_libc || defined IS_IN_libpthread +  attribute_hidden; +#   else +  ; +#   endif +#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +#  else +#   define SINGLE_THREAD_P						\ +	.section	".toc","aw";					\ +.LC__local_multiple_threads:;						\ +	.tc __local_multiple_threads[TC],__local_multiple_threads;	\ +  .previous;								\ +  ld    10,.LC__local_multiple_threads@toc(2);				\ +  lwz   10,0(10);							\ +  cmpwi 10,0 +#  endif +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S new file mode 100644 index 000000000..47c91dfd4 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S @@ -0,0 +1,90 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep-cancel.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <bits/kernel-features.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +#ifdef SHARED +	.section	".toc","aw" +.LC0: +	.tc __libc_pthread_functions[TC],__libc_pthread_functions +	.section	".text" +	.align 2 +#endif + +ENTRY (__vfork) + +#ifdef __NR_vfork + +# ifdef SHARED +  ld  10,.LC0@toc(2) +  ld  10,0(10) +  cmpwi  10,0 +  bne-  HIDDEN_JUMPTARGET(fork) +# else +  .weak  pthread_create +	lis  10,pthread_create@highest +	ori  10,10,pthread_create@higher +  sldi 10,10,32 +  oris 10,10,pthread_create@h +  ori  10,10,pthread_create@l +  cmpwi  10,0 +  bne-  .Lhidden_fork +# endif + +	DO_CALL (SYS_ify (vfork)); + +# ifdef __ASSUME_VFORK_SYSCALL +  PSEUDO_RET +# else +  bnslr+ +  /* Check if vfork syscall is known at all.  */ +  cmpdi	r3,ENOSYS +# ifdef SHARED +  bne	JUMPTARGET(__syscall_error) +# else +  bne-  .Lsyscall_error +# endif + +# endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL +	/* If we don't have vfork, fork is close enough.  */ + +	DO_CALL (SYS_ify (fork)); +	PSEUDO_RET +#endif + +# ifndef SHARED +.Lhidden_fork: +	b	HIDDEN_JUMPTARGET(fork) +.Lsyscall_error: +	b	JUMPTARGET(__syscall_error) +# endif + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c new file mode 100644 index 000000000..177256c7f --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c @@ -0,0 +1,70 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix        */ +/* threads for Linux.                                                   */ +/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr)              */ +/*                                                                      */ +/* This program is free software; you can redistribute it and/or        */ +/* modify it under the terms of the GNU Library General Public License  */ +/* as published by the Free Software Foundation; either version 2       */ +/* of the License, or (at your option) any later version.               */ +/*                                                                      */ +/* This program 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 Library General Public License for more details.                 */ + +/* Redefine siglongjmp and longjmp so that they interact correctly +   with cleanup handlers */ +/* Derived from linuxthreads/ptlongjmp.c & added AltiVec/VMX versioning. */ +#include "pthread.h" +#include <setjmp.h> +#include <bits/wordsize.h> +#include <shlib-compat.h> +#if defined SHARED +# if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_3_4) + +/* These functions are not declared anywhere since they shouldn't be +   used at another place but here.  */ +extern void __novmx__libc_siglongjmp (sigjmp_buf env, int val) +     __attribute__ ((noreturn)); +extern void __novmx__libc_longjmp (sigjmp_buf env, int val) +     __attribute__ ((noreturn)); + + +void __novmx_siglongjmp (sigjmp_buf env, int val) +{ +  __novmx__libc_siglongjmp (env, val); +} + +void __novmx_longjmp (jmp_buf env, int val) +{ +  __novmx__libc_longjmp (env, val); +} + +#  if __WORDSIZE == 64 +symbol_version (__novmx_longjmp,longjmp,GLIBC_2.3); +symbol_version (__novmx_siglongjmp,siglongjmp,GLIBC_2.3); +#  else +symbol_version (__novmx_longjmp,longjmp,GLIBC_2.0); +symbol_version (__novmx_siglongjmp,siglongjmp,GLIBC_2.0); +#  endif +# endif  /* SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_3_4) ) */ + +/* These functions are not declared anywhere since they shouldn't be +   used at another place but here.  */ +extern void __vmx__libc_siglongjmp (sigjmp_buf env, int val) +     __attribute__ ((noreturn)); +extern void __vmx__libc_longjmp (sigjmp_buf env, int val) +     __attribute__ ((noreturn)); + +void __vmx_siglongjmp (sigjmp_buf env, int val) +{ +  __vmx__libc_siglongjmp (env, val); +} + +void __vmx_longjmp (jmp_buf env, int val) +{ +  __vmx__libc_longjmp (env, val); +} +default_symbol_version (__vmx_longjmp,longjmp,GLIBC_2.3.4); +default_symbol_version (__vmx_siglongjmp,siglongjmp,GLIBC_2.3.4); +#endif /* SHARED */ diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c new file mode 100644 index 000000000..83f678c8b --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c @@ -0,0 +1,32 @@ +/* Internal sigsuspend system call for LinuxThreads.  Generic Linux version. +   Copyright (C) 2003, 2006 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <errno.h> +#include <signal.h> +#include <unistd.h> + +#include <sys/syscall.h> +#include <linuxthreads/internals.h> + +#include <bits/kernel-features.h> + +void +__pthread_sigsuspend (const sigset_t *set) +{ +  sigsuspend(set); +} diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/raise.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/raise.c new file mode 100644 index 000000000..1e11a4812 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/raise.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1996, 2002, 2003, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <signal.h> +#include <unistd.h> + +#ifndef IS_IN_rtld +# include <bits/libc-lock.h> + +# ifndef SHARED +weak_extern (__pthread_raise) +# endif +#endif + +/* Raise the signal SIG.  */ +int +raise (sig) +     int sig; +{ +#ifdef IS_IN_rtld +  return __kill (__getpid (), sig); +#else +  return __libc_maybe_call2 (pthread_raise, (sig), +			     __kill (__getpid (), sig)); +#endif +} +libc_hidden_def (raise) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c new file mode 100644 index 000000000..338d421e3 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c @@ -0,0 +1,86 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <errno.h> +#include <stdlib.h> +#include "fork.h" + + +int +__register_atfork (prepare, parent, child, dso_handle) +     void (*prepare) (void); +     void (*parent) (void); +     void (*child) (void); +     void *dso_handle; +{ +  struct fork_handler *new_prepare = NULL; +  struct fork_handler *new_parent = NULL; +  struct fork_handler *new_child = NULL; + +  if (prepare != NULL) +    { +      new_prepare = (struct fork_handler *) malloc (sizeof (*new_prepare)); +      if (new_prepare == NULL) +	goto out1; + +      new_prepare->handler = prepare; +      new_prepare->dso_handle = dso_handle; +    } + +  if (parent != NULL) +    { +      new_parent = (struct fork_handler *) malloc (sizeof (*new_parent)); +      if (new_parent == NULL) +	goto out2; + +      new_parent->handler = parent; +      new_parent->dso_handle = dso_handle; +    } + +  if (child != NULL) +    { +      new_child = (struct fork_handler *) malloc (sizeof (*new_child)); +      if (new_child == NULL) +	{ +	  free (new_parent); +	out2: +	  free (new_prepare); +	out1: +	  return errno; +	} + +      new_child->handler = child; +      new_child->dso_handle = dso_handle; +    } + +  /* Get the lock to not conflict with running forks.  */ +  __libc_lock_lock (__fork_block.lock); + +  /* Now that we have all the handlers allocate enqueue them.  */ +  if (new_prepare != NULL) +    list_add_tail (&new_prepare->list, &__fork_block.prepare_list); +  if (new_parent != NULL) +    list_add_tail (&new_parent->list, &__fork_block.parent_list); +  if (new_child != NULL) +    list_add_tail (&new_child->list, &__fork_block.child_list); + +  /* Release the lock.  */ +  __libc_lock_unlock (__fork_block.lock); + +  return 0; +} diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c new file mode 100644 index 000000000..500fff091 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c @@ -0,0 +1,142 @@ +/* Special .init and .fini section support for SH. Linuxthread version. +   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it +   and/or 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. + +   In addition to the permissions in the GNU Lesser General Public +   License, the Free Software Foundation gives you unlimited +   permission to link the compiled version of this file with other +   programs, and to distribute those programs without any restriction +   coming from the use of this file.  (The Lesser General Public +   License restrictions do apply in other respects; for example, they +   cover modification of the file, and distribution when not linked +   into another program.) + +   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; see the file COPYING.LIB.  If not, +   see <http://www.gnu.org/licenses/>.  */ + +/* This file is compiled into assembly code which is then munged by a sed +   script into two files: crti.s and crtn.s. + +   * crti.s puts a function prologue at the beginning of the +   .init and .fini sections and defines global symbols for +   those addresses, so they can be called as functions. + +   * crtn.s puts the corresponding function epilogues +   in the .init and .fini sections. */ + +__asm__ ("\n\ +\n\ +#include \"defs.h\"\n\ +\n\ +/*@HEADER_ENDS*/\n\ +\n\ +/*@TESTS_BEGIN*/\n\ +\n\ +/*@TESTS_END*/\n\ +\n\ +/*@_init_PROLOG_BEGINS*/\n\ +	.section .init\n\ +	.align 5\n\ +	.global	_init\n\ +	.type	_init,@function\n\ +_init:\n\ +	mov.l	r12,@-r15\n\ +	mov.l	r14,@-r15\n\ +	sts.l	pr,@-r15\n\ +	mova	.L22,r0\n\ +	mov.l	.L22,r12\n\ +	add	r0,r12\n\ +	mova	.L24,r0\n\ +	mov.l	.L24,r1\n\ +	add	r0,r1\n\ +	jsr	@r1\n\ +	 nop\n\ +	mova	.L23,r0\n\ +	mov.l	.L23,r1\n\ +	add	r0,r1\n\ +	jsr	@r1\n\ +	 mov	r15,r14\n\ +	bra	1f\n\ +	 nop\n\ +	.align 2\n\ +.L22:\n\ +	.long	_GLOBAL_OFFSET_TABLE_\n\ +.L23:\n\ +	.long	__gmon_start__@PLT\n\ +.L24:\n\ +	.long	__pthread_initialize_minimal@PLT\n\ +1:\n\ +	ALIGN\n\ +	END_INIT\n\ +\n\ +/*@_init_PROLOG_ENDS*/\n\ +\n\ +/*@_init_EPILOG_BEGINS*/\n\ +	.section .init\n\ +	mov	r14,r15\n\ +	lds.l	@r15+,pr\n\ +	mov.l	@r15+,r14\n\ +	rts	\n\ +	mov.l	@r15+,r12\n\ +	END_INIT\n\ +	.section .text\n\ +	.align 5\n\ +	.weak	__gmon_start__\n\ +	.type	__gmon_start__,@function\n\ +__gmon_start__:\n\ +	mov.l	r14,@-r15\n\ +	mov	r15,r14\n\ +	mov	r14,r15\n\ +	rts	\n\ +	mov.l	@r15+,r14\n\ +	\n\ +/*@_init_EPILOG_ENDS*/\n\ +\n\ +/*@_fini_PROLOG_BEGINS*/\n\ +	.section .fini\n\ +	.align 5\n\ +	.global	_fini\n\ +	.type	_fini,@function\n\ +_fini:\n\ +	mov.l	r12,@-r15\n\ +	mov.l	r14,@-r15\n\ +	sts.l	pr,@-r15\n\ +	mova	.L27,r0\n\ +	mov.l	.L27,r12\n\ +	add	r0,r12\n\ +	mov	r15,r14\n\ +	ALIGN\n\ +	END_FINI\n\ +	bra	1f\n\ +	 nop\n\ +	.align	2\n\ +.L27:\n\ +	.long	_GLOBAL_OFFSET_TABLE_\n\ +1:\n\ +/*@_fini_PROLOG_ENDS*/\n\ +\n\ +/*@_fini_EPILOG_BEGINS*/\n\ +	.section .fini\n\ +	mov	r14,r15\n\ +	lds.l	@r15+,pr\n\ +	mov.l	@r15+,r14\n\ +	rts	\n\ +	mov.l	@r15+,r12\n\ +\n\ +	END_FINI\n\ +	\n\ +/*@_fini_EPILOG_ENDS*/\n\ +\n\ +/*@TRAILER_BEGINS*/\n\ +"); diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h new file mode 100644 index 000000000..7d8ced7d7 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h @@ -0,0 +1,23 @@ +/* Determine whether the host has multiple processors.  SH version. +   Copyright (C) 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Library General Public License as +   published by the Free Software Foundation; either version 2 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 +   Library General Public License for more details. + +   You should have received a copy of the GNU Library General Public +   License along with the GNU C Library; see the file COPYING.LIB.  If not, +   see <http://www.gnu.org/licenses/>.  */ + +static __inline__ int +is_smp_system (void) +{ +  return 0; +} diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h new file mode 100644 index 000000000..58c726b20 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h @@ -0,0 +1,226 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#include <tls.h> +#include <pt-machine.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# define _IMM12 #-12 +# define _IMM16 #-16 +# define _IMP16 #16 +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ +  .text; \ +  ENTRY (name); \ +    SINGLE_THREAD_P; \ +    bf .Lpseudo_cancel; \ +    DO_CALL (syscall_name, args); \ +    mov r0,r1; \ +    mov _IMM12,r2; \ +    shad r2,r1; \ +    not r1,r1; \ +    tst r1,r1; \ +    bt .Lsyscall_error; \ +    bra .Lpseudo_end; \ +     nop; \ + .Lpseudo_cancel: \ +    sts.l pr,@-r15; \ +    add _IMM16,r15; \ +    SAVE_ARGS_##args; \ +    CENABLE; \ +    LOAD_ARGS_##args; \ +    add _IMP16,r15; \ +    lds.l @r15+,pr; \ +    DO_CALL(syscall_name, args); \ +    SYSCALL_INST_PAD; \ +    sts.l pr,@-r15; \ +    mov.l r0,@-r15; \ +    CDISABLE; \ +    mov.l @r15+,r0; \ +    lds.l @r15+,pr; \ +    mov r0,r1; \ +    mov _IMM12,r2; \ +    shad r2,r1; \ +    not r1,r1; \ +    tst r1,r1; \ +    bf .Lpseudo_end; \ + .Lsyscall_error: \ +    SYSCALL_ERROR_HANDLER; \ + .Lpseudo_end: + +# undef PSEUDO_END +# define PSEUDO_END(sym) \ +  END (sym) + +# define SAVE_ARGS_0	/* Nothing.  */ +# define SAVE_ARGS_1	SAVE_ARGS_0; mov.l r4,@(0,r15) +# define SAVE_ARGS_2	SAVE_ARGS_1; mov.l r5,@(4,r15) +# define SAVE_ARGS_3	SAVE_ARGS_2; mov.l r6,@(8,r15) +# define SAVE_ARGS_4	SAVE_ARGS_3; mov.l r7,@(12,r15) +# define SAVE_ARGS_5	SAVE_ARGS_4 +# define SAVE_ARGS_6	SAVE_ARGS_5 + +# define LOAD_ARGS_0	/* Nothing.  */ +# define LOAD_ARGS_1	LOAD_ARGS_0; mov.l @(0,r15),r4 +# define LOAD_ARGS_2	LOAD_ARGS_1; mov.l @(4,r15),r5 +# define LOAD_ARGS_3	LOAD_ARGS_2; mov.l @(8,r15),r6 +# define LOAD_ARGS_4	LOAD_ARGS_3; mov.l @(12,r15),r7 +# define LOAD_ARGS_5	LOAD_ARGS_4 +# define LOAD_ARGS_6	LOAD_ARGS_5 + +# ifdef IS_IN_libpthread +#  define __local_enable_asynccancel	__pthread_enable_asynccancel +#  define __local_disable_asynccancel	__pthread_disable_asynccancel +#  define __local_multiple_threads	__pthread_multiple_threads +# elif !defined NOT_IN_libc +#  define __local_enable_asynccancel	__libc_enable_asynccancel +#  define __local_disable_asynccancel	__libc_disable_asynccancel +#  define __local_multiple_threads	__libc_multiple_threads +# else +#  define __local_enable_asynccancel	__librt_enable_asynccancel +#  define __local_disable_asynccancel	__librt_disable_asynccancel +#  define __local_multiple_threads	__librt_multiple_threads +# endif + +# if defined IS_IN_librt && defined __PIC__ +#  define CENABLE \ +	mov.l r12,@-r15; \ +	mov.l 1f,r12; \ +	mova 1f,r0; \ +	add r0,r12; \ +	mov.l 2f,r0; \ +	bsrf r0; \ +	 nop; \ +     0: bra 3f; \ +	 mov r0,r2; \ +	.align 2; \ +     1: .long _GLOBAL_OFFSET_TABLE_; \ +     2: .long __local_enable_asynccancel@PLT - (0b-.); \ +     3: mov.l @r15+,r12 + +#  define CDISABLE \ +	mov.l r12,@-r15; \ +	mov.l 1f,r12; \ +	mova 1f,r0; \ +	add r0,r12; \ +	mov.l 2f,r0; \ +	bsrf r0; \ +	 mov r2,r4; \ +     0: bra 3f; \ +	 nop; \ +	.align 2; \ +     1: .long _GLOBAL_OFFSET_TABLE_; \ +     2: .long __local_disable_asynccancel@PLT - (0b-.); \ +     3: mov.l @r15+,r12 +# else +#  define CENABLE \ +	mov.l 1f,r0; \ +	bsrf r0; \ +	 nop; \ +     0: bra 2f; \ +	 mov r0,r2; \ +	.align 2; \ +     1: .long __local_enable_asynccancel - 0b; \ +     2: + +#  define CDISABLE \ +	mov.l 1f,r0; \ +	bsrf r0; \ +	 mov r2,r4; \ +     0: bra 2f; \ +	 nop; \ +	.align 2; \ +     1: .long __local_disable_asynccancel - 0b; \ +     2: +# endif + +# ifndef __ASSEMBLER__ +#  if defined FLOATING_STACKS && defined __UCLIBC_HAS_TLS__ && defined __PIC__ +#   define SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1) +#  else +extern int __local_multiple_threads attribute_hidden; +#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +#  endif +# else +#  if !defined __PIC__ +#   define SINGLE_THREAD_P \ +	mov.l 1f,r0; \ +	mov.l @r0,r0; \ +	bra 2f; \ +	 tst r0,r0; \ +	.align 2; \ +     1: .long __local_multiple_threads; \ +     2: +#  elif defined FLOATING_STACKS && defined __UCLIBC_HAS_TLS__ +#   define SINGLE_THREAD_P \ +	stc gbr,r0; \ +	mov.w 0f,r1; \ +	sub r1,r0; \ +	mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \ +	bra 1f; \ +	 tst r0,r0; \ +     0: .word TLS_PRE_TCB_SIZE; \ +     1: + +#  else +#   if !defined NOT_IN_libc || defined IS_IN_libpthread +#    define SINGLE_THREAD_P \ +	mov r12,r2; \ +	mov.l 0f,r12; \ +	mova 0f,r0; \ +	add r0,r12; \ +	mov.l 1f,r0; \ +	mov.l @(r0,r12),r0; \ +	mov r2,r12; \ +	bra 2f; \ +	 tst r0,r0; \ +	.align 2; \ +     0: .long _GLOBAL_OFFSET_TABLE_; \ +     1: .long __local_multiple_threads@GOTOFF; \ +     2: +#   else +#    define SINGLE_THREAD_P \ +	mov r12,r2; \ +	mov.l 0f,r12; \ +	mova 0f,r0; \ +	add r0,r12; \ +	mov.l 1f,r0; \ +	mov.l @(r0,r12),r0; \ +	mov.l @r0,r0; \ +	mov r2,r12; \ +	bra 2f; \ +	 tst r0,r0; \ +	.align 2; \ +     0: .long _GLOBAL_OFFSET_TABLE_; \ +     1: .long __local_multiple_threads@GOT; \ +     2: +#   endif +#  endif +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S new file mode 100644 index 000000000..90733119e --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S @@ -0,0 +1,77 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep-cancel.h> +#define _ERRNO_H	1 +#include <bits/errno.h> +#include <sys/syscall.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) +#ifdef SHARED +	mov.l	.Lgot, r1 +	mova	.Lgot, r0 +	add	r0, r1 +	mov.l	.Lpthread_func, r0 +	mov.l	@(r0,r1), r0 +#else +	mov.l	.Lpthread_create, r0 +#endif +	tst	r0, r0 +	bf	.Lhidden_fork + +	mov.w	.L1, r3 +	trapa	#__SH_SYSCALL_TRAP_BASE +	mov     r0, r1 +	mov	#-12, r2 +	shad	r2, r1 +	not	r1, r1			/* r1=0 means r0 = -1 to -4095 */ +	tst	r1, r1			/* i.e. error in linux */ +	bf	.Lpseudo_end +	SYSCALL_ERROR_HANDLER +.Lpseudo_end: +	rts +	 nop +.L1:	.word	__NR_vfork +	.align	2 +#ifdef SHARED +.Lgot: +	.long	_GLOBAL_OFFSET_TABLE_ +.Lpthread_func: +	.long	__libc_pthread_functions@GOTOFF +#else +.Lpthread_create: +	.weak	pthread_create +	.long	pthread_create +#endif + +.Lhidden_fork: +	mov.l	.L2, r1 +	braf	r1 +	 nop +1: +	.align 2 +.L2:	.long	HIDDEN_JUMPTARGET(fork)-1b + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c new file mode 100644 index 000000000..2e09d1ba5 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c @@ -0,0 +1,82 @@ +/* Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <errno.h> +#include <signal.h> +#define __need_NULL +#include <stddef.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bits/libc-lock.h> + +extern int __syscall_rt_sigtimedwait (const sigset_t *, siginfo_t *, +				      const struct timespec *, size_t); + + +/* Return any pending signal or wait for one for the given time.  */ +static __inline__ int +do_sigwait (const sigset_t *set, int *sig) +{ +  int ret; + +  /* XXX The size argument hopefully will have to be changed to the +     real size of the user-level sigset_t.  */ +#ifdef INTERNAL_SYSCALL +  INTERNAL_SYSCALL_DECL (err); +  ret = INTERNAL_SYSCALL (rt_sigtimedwait, err, 4, set, +			  NULL, NULL, _NSIG / 8); +  if (! INTERNAL_SYSCALL_ERROR_P (ret, err)) +    { +      *sig = ret; +      ret = 0; +    } +  else +    ret = INTERNAL_SYSCALL_ERRNO (ret, err); +#else +  ret = INLINE_SYSCALL (rt_sigtimedwait, 4, set, +			NULL, NULL, _NSIG / 8); +  if (ret != -1) +    { +      *sig = ret; +      ret = 0; +    } +  else +    ret = errno; +#endif + +  return ret; +} + +#ifndef SHARED +weak_extern (__pthread_sigwait) +#endif + +int +sigwait (const sigset_t *set, int *sig) +{ +#ifndef NOT_IN_libc +  return __libc_maybe_call2 (pthread_sigwait, (set, sig), +			     do_sigwait (set, sig)); +#else +  return do_sigwait (set, sig); +#endif +} +strong_alias(sigwait, __libc_sigwait) + +/* Cancellation is handled in __pthread_sigwait.  */ +LIBC_CANCEL_HANDLED (); diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/smp.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/smp.h new file mode 100644 index 000000000..6f03b9d55 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/smp.h @@ -0,0 +1,47 @@ +/* Determine whether the host has multiple processors.  Linux version. +   Copyright (C) 1996, 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Library General Public License as +   published by the Free Software Foundation; either version 2 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 +   Library General Public License for more details. + +   You should have received a copy of the GNU Library General Public +   License along with the GNU C Library; see the file COPYING.LIB.  If not, +   see <http://www.gnu.org/licenses/>.  */ + +#include <sys/sysctl.h> + +/* Test whether the machine has more than one processor.  This is not the +   best test but good enough.  More complicated tests would require `malloc' +   which is not available at that time.  */ +static __inline__ int +is_smp_system (void) +{ +  static const int sysctl_args[] = { CTL_KERN, KERN_VERSION }; +  char buf[512]; +  size_t reslen = sizeof (buf); + +  /* Try reading the number using `sysctl' first.  */ +  if (__sysctl ((int *) sysctl_args, +		sizeof (sysctl_args) / sizeof (sysctl_args[0]), +		buf, &reslen, NULL, 0) < 0) +    { +      /* This was not successful.  Now try reading the /proc filesystem.  */ +      int fd = __open ("/proc/sys/kernel/version", O_RDONLY); +      if (__builtin_expect (fd, 0) == -1 +	  || (reslen = __read (fd, buf, sizeof (buf))) <= 0) +	/* This also didn't work.  We give up and say it's a UP machine.  */ +	buf[0] = '\0'; + +      __close (fd); +    } + +  return strstr (buf, "SMP") != NULL; +} diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c new file mode 100644 index 000000000..0d6da8291 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c @@ -0,0 +1,33 @@ +#include <shlib-compat.h> + +#define aio_cancel64 XXX +#include <aio.h> +#undef aio_cancel64 +#include <errno.h> + +extern __typeof (aio_cancel) __new_aio_cancel; +extern __typeof (aio_cancel) __old_aio_cancel; + +#define aio_cancel	__new_aio_cancel + +#include <sysdeps/pthread/aio_cancel.c> + +#undef aio_cancel +strong_alias (__new_aio_cancel, __new_aio_cancel64); +versioned_symbol (librt, __new_aio_cancel, aio_cancel, GLIBC_2_3); +versioned_symbol (librt, __new_aio_cancel64, aio_cancel64, GLIBC_2_3); + +#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_3) + +#undef ECANCELED +#define aio_cancel	__old_aio_cancel +#define ECANCELED	125 + +#include <sysdeps/pthread/aio_cancel.c> + +#undef aio_cancel +strong_alias (__old_aio_cancel, __old_aio_cancel64); +compat_symbol (librt, __old_aio_cancel, aio_cancel, GLIBC_2_1); +compat_symbol (librt, __old_aio_cancel64, aio_cancel64, GLIBC_2_1); + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h new file mode 100644 index 000000000..3f22f8ae3 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h @@ -0,0 +1,91 @@ +/* Minimum guaranteed maximum values for system limits.  Linux/SPARC version. +   Copyright (C) 1993-1998,2000,2002,2003,2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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; see the file COPYING.LIB.  If +   not, see <http://www.gnu.org/licenses/>.  */ + +/* The kernel header pollutes the namespace with the NR_OPEN symbol +   and defines LINK_MAX although filesystems have different maxima.  A +   similar thing is true for OPEN_MAX: the limit can be changed at +   runtime and therefore the macro must not be defined.  Remove this +   after including the header if necessary.  */ +#ifndef NR_OPEN +# define __undef_NR_OPEN +#endif +#ifndef LINK_MAX +# define __undef_LINK_MAX +#endif +#ifndef OPEN_MAX +# define __undef_OPEN_MAX +#endif + +/* The kernel sources contain a file with all the needed information.  */ +#include <linux/limits.h> + +/* Have to remove NR_OPEN?  */ +#ifdef __undef_NR_OPEN +# undef NR_OPEN +# undef __undef_NR_OPEN +#endif +/* Have to remove LINK_MAX?  */ +#ifdef __undef_LINK_MAX +# undef LINK_MAX +# undef __undef_LINK_MAX +#endif +/* Have to remove OPEN_MAX?  */ +#ifdef __undef_OPEN_MAX +# undef OPEN_MAX +# undef __undef_OPEN_MAX +#endif + +/* The number of data keys per process.  */ +#define _POSIX_THREAD_KEYS_MAX	128 +/* This is the value this implementation supports.  */ +#define PTHREAD_KEYS_MAX	1024 + +/* Controlling the iterations of destructors for thread-specific data.  */ +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4 +/* Number of iterations this implementation does.  */ +#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS + +/* The number of threads per process.  */ +#define _POSIX_THREAD_THREADS_MAX	64 +/* This is the value this implementation supports.  */ +#define PTHREAD_THREADS_MAX	16384 + +/* Maximum amount by which a process can descrease its asynchronous I/O +   priority level.  */ +#define AIO_PRIO_DELTA_MAX	20 + +/* Minimum size for a thread.  We are free to choose a reasonable value.  */ +#define PTHREAD_STACK_MIN	24576 + +/* Maximum number of POSIX timers available.  */ +#define TIMER_MAX	256 + +/* Maximum number of timer expiration overruns.  */ +#define DELAYTIMER_MAX	2147483647 + +/* Maximum tty name length.  */ +#define TTY_NAME_MAX		32 + +/* Maximum login name length.  This is arbitrary.  */ +#define LOGIN_NAME_MAX		256 + +/* Maximum host name length.  */ +#define HOST_NAME_MAX		64 + +/* Maximum message queue priority level.  */ +#define MQ_PRIO_MAX		32768 diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h new file mode 100644 index 000000000..3efee0b8d --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h @@ -0,0 +1,65 @@ +/* bits/typesizes.h -- underlying types for *_t.  Linux/SPARC version. +   Copyright (C) 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#ifndef _BITS_TYPES_H +# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead." +#endif + +#ifndef	_BITS_TYPESIZES_H +#define	_BITS_TYPESIZES_H	1 + +/* See <bits/types.h> for the meaning of these macros.  This file exists so +   that <bits/types.h> need not vary across different GNU platforms.  */ + +#define __DEV_T_TYPE		__UQUAD_TYPE +#define __UID_T_TYPE		__U32_TYPE +#define __GID_T_TYPE		__U32_TYPE +#define __INO_T_TYPE		__ULONGWORD_TYPE +#define __INO64_T_TYPE		__UQUAD_TYPE +#define __MODE_T_TYPE		__U32_TYPE +#define __NLINK_T_TYPE		__U32_TYPE +#define __OFF_T_TYPE		__SLONGWORD_TYPE +#define __OFF64_T_TYPE		__SQUAD_TYPE +#define __PID_T_TYPE		__S32_TYPE +#define __RLIM_T_TYPE		__ULONGWORD_TYPE +#define __RLIM64_T_TYPE		__UQUAD_TYPE +#define	__BLKCNT_T_TYPE		__SLONGWORD_TYPE +#define	__BLKCNT64_T_TYPE	__SQUAD_TYPE +#define	__FSBLKCNT_T_TYPE	__ULONGWORD_TYPE +#define	__FSBLKCNT64_T_TYPE	__UQUAD_TYPE +#define	__FSFILCNT_T_TYPE	__ULONGWORD_TYPE +#define	__FSFILCNT64_T_TYPE	__UQUAD_TYPE +#define	__ID_T_TYPE		__U32_TYPE +#define __CLOCK_T_TYPE		__SLONGWORD_TYPE +#define __TIME_T_TYPE		__SLONGWORD_TYPE +#define __USECONDS_T_TYPE	__U32_TYPE +#define __SUSECONDS_T_TYPE	__S32_TYPE +#define __DADDR_T_TYPE		__S32_TYPE +#define __SWBLK_T_TYPE		__SLONGWORD_TYPE +#define __KEY_T_TYPE		__S32_TYPE +#define __CLOCKID_T_TYPE	__S32_TYPE +#define __TIMER_T_TYPE		__S32_TYPE +#define __BLKSIZE_T_TYPE	__SLONGWORD_TYPE +#define __FSID_T_TYPE		struct { int __val[2]; } +#define __SSIZE_T_TYPE		__SWORD_TYPE + +/* Number of descriptors that can fit in an `fd_set'.  */ +#define	__FD_SETSIZE		1024 + + +#endif /* bits/typesizes.h */ diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h new file mode 100644 index 000000000..ce98a3bb9 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h @@ -0,0 +1,20 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include_next <fork.h> + diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h new file mode 100644 index 000000000..bd9bb0d6a --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h @@ -0,0 +1,100 @@ +/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <tls.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.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;								      \ +	 mov SYS_ify(syscall_name), %g1;				      \ +	ta 0x10;							      \ +	bcs __syscall_error_handler;					      \ +	 nop;								      \ +	.subsection 2;							      \ +1:	save %sp, -96, %sp;						      \ +	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;						      \ +	.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; + +# ifdef IS_IN_libpthread +#  define CENABLE	call __pthread_enable_asynccancel +#  define CDISABLE	call __pthread_disable_asynccancel +# elif !defined NOT_IN_libc +#  define CENABLE	call __libc_enable_asynccancel +#  define CDISABLE	call __libc_disable_asynccancel +# else +#  define CENABLE	call __librt_enable_asynccancel +#  define CDISABLE	call __librt_disable_asynccancel +# endif + +#define COPY_ARGS_0	/* Nothing */ +#define COPY_ARGS_1	COPY_ARGS_0 mov %i0, %o0; +#define COPY_ARGS_2	COPY_ARGS_1 mov %i1, %o1; +#define COPY_ARGS_3	COPY_ARGS_2 mov %i2, %o2; +#define COPY_ARGS_4	COPY_ARGS_3 mov %i3, %o3; +#define COPY_ARGS_5	COPY_ARGS_4 mov %i4, %o4; +#define COPY_ARGS_6	COPY_ARGS_5 mov %i5, %o5; + +# ifndef __ASSEMBLER__ +#  define SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \ +				   p_header.data.multiple_threads) == 0, 1) +# else +#  define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1 +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/vfork.S new file mode 100644 index 000000000..ab2286ee8 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/sparc/vfork.S @@ -0,0 +1,64 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep-cancel.h> + +	.text +#ifdef SHARED +.LLGETPC0: +	retl +	 add	%o7, %o0, %o0 +#endif +ENTRY(__vfork) +#ifdef SHARED +	mov	%o7, %o1 +	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %o0 +	call	.LLGETPC0 +	 add	%o0, %lo(_GLOBAL_OFFSET_TABLE_+4), %o0 +	sethi	%hi(__libc_pthread_functions), %o2 +	mov	%o1, %o7 +	or	%o2, %lo(__libc_pthread_functions), %o2 +	ld	[%o0 + %o2], %o2 +	ld	[%o2], %o2 +	cmp	%o2, 0 +#else +	.weak	pthread_create +	sethi	%hi(pthread_create), %o0 +	orcc	%o0, %lo(pthread_create), %o0 +#endif +#if defined SHARED && !defined BROKEN_SPARC_WDISP22 +	bne	HIDDEN_JUMPTARGET(fork) +#else +	bne	1f +#endif +	 mov	__NR_vfork, %g1 +	ta	0x10 +	bcs	__syscall_error_handler +	 nop +	sub	%o1, 1, %o1 +	retl +	 and	%o0, %o1, %o0 +#if !defined SHARED || defined BROKEN_SPARC_WDISP22 +1:	mov	%o7, %g1 +	call	HIDDEN_JUMPTARGET(fork) +	 mov	%g1, %o7 +#endif +	SYSCALL_ERROR_HANDLER +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) +weak_alias (__vfork, vfork) diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c new file mode 100644 index 000000000..4bc83d6cc --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <errno.h> +#include <stdlib.h> +#include "fork.h" + + +void +__unregister_atfork (dso_handle) +     void *dso_handle; +{ +  /* Get the lock to not conflict with running forks.  */ +  __libc_lock_lock (__fork_block.lock); + +  list_t *runp; +  list_t *prevp; + +  list_for_each_prev_safe (runp, prevp, &__fork_block.prepare_list) +    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle) +      list_del (runp); + +  list_for_each_prev_safe (runp, prevp, &__fork_block.parent_list) +    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle) +      list_del (runp); + +  list_for_each_prev_safe (runp, prevp, &__fork_block.child_list) +    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle) +      list_del (runp); + +  /* Release the lock.  */ +  __libc_lock_unlock (__fork_block.lock); +} diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c new file mode 100644 index 000000000..3a0c2afc0 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c @@ -0,0 +1 @@ +#include "../ia64/pt-sigsuspend.c" diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h new file mode 100644 index 000000000..0b05c96f6 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h @@ -0,0 +1,131 @@ +/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep.h> +#include <tls.h> +#include <pt-machine.h> +#ifndef __ASSEMBLER__ +# include <linuxthreads/internals.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)								      \ +    SINGLE_THREAD_P;							      \ +    jne L(pseudo_cancel);						      \ +    DO_CALL (syscall_name, args);					      \ +    cmpq $-4095, %rax;							      \ +    jae SYSCALL_ERROR_LABEL;						      \ +    ret;								      \ +  L(pseudo_cancel):							      \ +    /* Save registers that might get destroyed.  */			      \ +    SAVESTK_##args							      \ +    PUSHARGS_##args							      \ +    CENABLE								      \ +    /* Restore registers.  */						      \ +    POPARGS_##args							      \ +    /* The return value from CENABLE is argument for CDISABLE.  */	      \ +    movq %rax, (%rsp);							      \ +    movl $SYS_ify (syscall_name), %eax;					      \ +    syscall;								      \ +    movq (%rsp), %rdi;							      \ +    /* Save %rax since it's the error code from the syscall.  */	      \ +    movq %rax, 8(%rsp);							      \ +    CDISABLE								      \ +    movq 8(%rsp), %rax;							      \ +    RESTSTK_##args							      \ +    cmpq $-4095, %rax;							      \ +    jae SYSCALL_ERROR_LABEL;						      \ +  L(pseudo_end): + +# define PUSHARGS_0	/* Nothing.  */ +# define PUSHARGS_1	PUSHARGS_0 movq %rdi, 8(%rsp); +# define PUSHARGS_2	PUSHARGS_1 movq %rsi, 16(%rsp); +# define PUSHARGS_3	PUSHARGS_2 movq %rdx, 24(%rsp); +# define PUSHARGS_4	PUSHARGS_3 movq %rcx, 32(%rsp); +# define PUSHARGS_5	PUSHARGS_4 movq %r8, 40(%rsp); +# define PUSHARGS_6	PUSHARGS_5 movq %r9, 48(%rsp); + +# define POPARGS_0	/* Nothing.  */ +# define POPARGS_1	POPARGS_0 movq 8(%rsp), %rdi; +# define POPARGS_2	POPARGS_1 movq 16(%rsp), %rsi; +# define POPARGS_3	POPARGS_2 movq 24(%rsp), %rdx; +# define POPARGS_4	POPARGS_3 movq 32(%rsp), %r10; +# define POPARGS_5	POPARGS_4 movq 40(%rsp), %r8; +# define POPARGS_6	POPARGS_5 movq 48(%rsp), %r9; + +/* We always have to align the stack before calling a function.  */ +# define SAVESTK_0	subq $24, %rsp;cfi_adjust_cfa_offset(24); +# define SAVESTK_1	SAVESTK_0 +# define SAVESTK_2	SAVESTK_1 +# define SAVESTK_3	subq $40, %rsp;cfi_adjust_cfa_offset(40); +# define SAVESTK_4	SAVESTK_3 +# define SAVESTK_5	subq $56, %rsp;cfi_adjust_cfa_offset(56); +# define SAVESTK_6	SAVESTK_5 + +# define RESTSTK_0	addq $24,%rsp;cfi_adjust_cfa_offset(-24); +# define RESTSTK_1	RESTSTK_0 +# define RESTSTK_2	RESTSTK_1 +# define RESTSTK_3	addq $40, %rsp;cfi_adjust_cfa_offset(-40); +# define RESTSTK_4	RESTSTK_3 +# define RESTSTK_5	addq $56, %rsp;cfi_adjust_cfa_offset(-56); +# define RESTSTK_6	RESTSTK_5 + +# ifdef IS_IN_libpthread +#  define CENABLE	call __pthread_enable_asynccancel; +#  define CDISABLE	call __pthread_disable_asynccancel; +#  define __local_multiple_threads __pthread_multiple_threads +# elif !defined NOT_IN_libc +#  define CENABLE	call __libc_enable_asynccancel; +#  define CDISABLE	call __libc_disable_asynccancel; +#  define __local_multiple_threads __libc_multiple_threads +# else +#  define CENABLE	call __librt_enable_asynccancel@plt; +#  define CDISABLE	call __librt_disable_asynccancel@plt; +# endif + +# if defined IS_IN_libpthread || !defined NOT_IN_libc +#  ifndef __ASSEMBLER__ +extern int __local_multiple_threads attribute_hidden; +#   define SINGLE_THREAD_P \ +  __builtin_expect (__local_multiple_threads == 0, 1) +#  else +#   define SINGLE_THREAD_P cmpl $0, __local_multiple_threads(%rip) +#  endif + +# else + +#  ifndef __ASSEMBLER__ +#   define SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ +				   p_header.data.multiple_threads) == 0, 1) +#  else +#   define SINGLE_THREAD_P cmpl $0, %fs:MULTIPLE_THREADS_OFFSET +#  endif + +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow.  */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S new file mode 100644 index 000000000..1a58077c4 --- /dev/null +++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S @@ -0,0 +1,61 @@ +/* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   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, see +   <http://www.gnu.org/licenses/>.  */ + +#include <sysdep-cancel.h> +#define _ERRNO_H	1 +#include <bits/errno.h> + +/* Clone the calling process, but without copying the whole address space. +   The calling process is suspended until the new process exits or is +   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process, +   and the process ID of the new process to the old process.  */ + +ENTRY (__vfork) + +#ifdef SHARED +	cmpq	$0, __libc_pthread_functions(%rip) +#else +	.weak	pthread_create +	movq	$pthread_create, %rax +	testq	%rax, %rax +#endif +	jne	HIDDEN_JUMPTARGET (fork) + +	/* Pop the return PC value into RDI.  We need a register that +	   is preserved by the syscall and that we're allowed to destroy. */ +	popq	%rdi +	cfi_adjust_cfa_offset(-8) + +	/* Stuff the syscall number in RAX and enter into the kernel.  */ +	movl	$SYS_ify (vfork), %eax +	syscall + +	/* Push back the return PC.  */ +	pushq	%rdi +	cfi_adjust_cfa_offset(8) + +	cmpl	$-4095, %eax +	jae SYSCALL_ERROR_LABEL		/* Branch forward if it failed.  */ + +	/* Normal return.  */ +.Lpseudo_end: +	ret + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) | 
