diff options
Diffstat (limited to 'linuxthreads/sysdeps/unix/sysv/linux')
85 files changed, 6265 insertions, 0 deletions
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/Implies b/linuxthreads/sysdeps/unix/sysv/linux/Implies new file mode 100644 index 0000000000..f1b3e8939c --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/Implies @@ -0,0 +1 @@ +pthread diff --git a/linuxthreads/sysdeps/unix/sysv/linux/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/Makefile new file mode 100644 index 0000000000..38c6cbc1af --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),linuxthreads) +sysdep_routines += register-atfork unregister-atfork +endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/Versions b/linuxthreads/sysdeps/unix/sysv/linux/Versions new file mode 100644 index 0000000000..6cd3dbe372 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/Versions @@ -0,0 +1,5 @@ +libc { + GLIBC_2.3.2 { + __register_atfork; + } +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h b/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h new file mode 100644 index 0000000000..f62f7d6e9f --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h @@ -0,0 +1,26 @@ +/* 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <limits.h> + +extern inline int __libc_use_alloca (size_t size) +{ + return (__builtin_expect (size <= PTHREAD_STACK_MIN / 4, 1) + || __libc_alloca_cutoff (size)); +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c b/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c new file mode 100644 index 0000000000..af1581a4c3 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c @@ -0,0 +1,87 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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) + +/* 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); diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/alpha/Makefile new file mode 100644 index 0000000000..e03aee99fc --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),linuxthreads) +libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask +endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/Versions b/linuxthreads/sysdeps/unix/sysv/linux/alpha/Versions new file mode 100644 index 0000000000..d102772482 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/Versions @@ -0,0 +1,6 @@ +libpthread { + GLIBC_2.3.3 { + # Changed PTHREAD_STACK_MIN. + pthread_attr_setstack; pthread_attr_setstacksize; + } +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c b/linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c new file mode 100644 index 0000000000..0d6da82919 --- /dev/null +++ b/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/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h b/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h new file mode 100644 index 0000000000..96893c59da --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h @@ -0,0 +1,92 @@ +/* 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h b/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h new file mode 100644 index 0000000000..a2724885e2 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h @@ -0,0 +1,66 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S b/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S new file mode 100644 index 0000000000..91e5c86782 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S @@ -0,0 +1,28 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h new file mode 100644 index 0000000000..9ea779e0d5 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h @@ -0,0 +1,146 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S new file mode 100644 index 0000000000..cfaae10606 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S @@ -0,0 +1,70 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +#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/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h new file mode 100644 index 0000000000..019bd54913 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h @@ -0,0 +1,145 @@ +/* Copyright (C) 2003 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.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_INT; \ + bne .Lpseudo_cancel; \ + DO_CALL (syscall_name, args); \ + cmn r0, $4096; \ + PSEUDO_RET_MOV; \ + .Lpseudo_cancel: \ + MAYBE_SAVE_LR; \ + 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_INT \ + ldr ip, =__local_multiple_threads; \ + ldr ip, [ip]; \ + teq ip, #0; +# define SINGLE_THREAD_P SINGLE_THREAD_P_INT +# define MAYBE_SAVE_LR \ + str lr, [sp, $-4]!; +# define PSEUDO_RET_MOV \ + RETINSTR(cc, lr); \ + b PLTJMP(SYSCALL_ERROR) +# define PSEUDO_PROLOGUE +# else +# define SINGLE_THREAD_P_PIC(reg) \ + ldr ip, 1b; \ + ldr reg, 2b; \ +3: \ + add ip, pc, ip; \ + ldr ip, [ip, reg]; \ + teq ip, #0; +# define SINGLE_THREAD_P_INT \ + str lr, [sp, $-4]!; \ + SINGLE_THREAD_P_PIC(lr) +# define SINGLE_THREAD_P \ + SINGLE_THREAD_P_INT; \ + ldr lr, [sp], $4 +# define PSEUDO_PROLOGUE \ + 1: .word _GLOBAL_OFFSET_TABLE_ - 3f - 8; \ + 2: .word __local_multiple_threads(GOTOFF); +# define MAYBE_SAVE_LR /* lr already saved */ +# define PSEUDO_RET_MOV PSEUDO_RET +# 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/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S new file mode 100644 index 0000000000..2708c701eb --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S @@ -0,0 +1,80 @@ +/* Copyright (C) 1999, 2002, 2003 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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. */ + + PSEUDO_PROLOGUE + +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) + + swi __NR_vfork + 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. */ + swi __NR_fork + 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/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h b/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h new file mode 100644 index 0000000000..ed6c3c589b --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h @@ -0,0 +1,92 @@ +/* Minimum guaranteed maximum values for system limits. Linux 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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 16384 + +/* 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/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h b/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h new file mode 100644 index 0000000000..71b7e74649 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h @@ -0,0 +1,181 @@ +/* Define POSIX options for Linux. + Copyright (C) 1996-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; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _POSIX_OPT_H +#define _POSIX_OPT_H 1 + +/* Job control is supported. */ +#define _POSIX_JOB_CONTROL 1 + +/* Processes have a saved set-user-ID and a saved set-group-ID. */ +#define _POSIX_SAVED_IDS 1 + +/* Priority scheduling is supported. */ +#define _POSIX_PRIORITY_SCHEDULING 200112L + +/* Synchronizing file data is supported. */ +#define _POSIX_SYNCHRONIZED_IO 200112L + +/* The fsync function is present. */ +#define _POSIX_FSYNC 200112L + +/* Mapping of files to memory is supported. */ +#define _POSIX_MAPPED_FILES 200112L + +/* Locking of all memory is supported. */ +#define _POSIX_MEMLOCK 200112L + +/* Locking of ranges of memory is supported. */ +#define _POSIX_MEMLOCK_RANGE 200112L + +/* Setting of memory protections is supported. */ +#define _POSIX_MEMORY_PROTECTION 200112L + +/* Only root can change owner of file. */ +#define _POSIX_CHOWN_RESTRICTED 1 + +/* `c_cc' member of 'struct termios' structure can be disabled by + using the value _POSIX_VDISABLE. */ +#define _POSIX_VDISABLE '\0' + +/* Filenames are not silently truncated. */ +#define _POSIX_NO_TRUNC 1 + +/* X/Open realtime support is available. */ +#define _XOPEN_REALTIME 1 + +/* X/Open realtime thread support is available. */ +#define _XOPEN_REALTIME_THREADS 1 + +/* XPG4.2 shared memory is supported. */ +#define _XOPEN_SHM 1 + +/* Tell we have POSIX threads. */ +#define _POSIX_THREADS 200112L + +/* We have the reentrant functions described in POSIX. */ +#define _POSIX_REENTRANT_FUNCTIONS 1 +#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L + +/* We provide priority scheduling for threads. */ +#define _POSIX_THREAD_PRIORITY_SCHEDULING 200112L + +/* We support user-defined stack sizes. */ +#define _POSIX_THREAD_ATTR_STACKSIZE 200112L + +/* We support user-defined stacks. */ +#define _POSIX_THREAD_ATTR_STACKADDR 200112L + +/* We support POSIX.1b semaphores, but only the non-shared form for now. */ +#define _POSIX_SEMAPHORES 200112L + +/* Real-time signals are supported. */ +#define _POSIX_REALTIME_SIGNALS 200112L + +/* We support asynchronous I/O. */ +#define _POSIX_ASYNCHRONOUS_IO 200112L +#define _POSIX_ASYNC_IO 1 +/* Alternative name for Unix98. */ +#define _LFS_ASYNCHRONOUS_IO 1 +/* Support for prioritization is also available. */ +#define _POSIX_PRIORITIZED_IO 200112L + +/* The LFS support in asynchronous I/O is also available. */ +#define _LFS64_ASYNCHRONOUS_IO 1 + +/* The rest of the LFS is also available. */ +#define _LFS_LARGEFILE 1 +#define _LFS64_LARGEFILE 1 +#define _LFS64_STDIO 1 + +/* POSIX shared memory objects are implemented. */ +#define _POSIX_SHARED_MEMORY_OBJECTS 200112L + +/* CPU-time clocks support needs to be checked at runtime. */ +#define _POSIX_CPUTIME 0 + +/* Clock support in threads must be also checked at runtime. */ +#define _POSIX_THREAD_CPUTIME 0 + +/* GNU libc provides regular expression handling. */ +#define _POSIX_REGEXP 1 + +/* Reader/Writer locks are available. */ +#define _POSIX_READER_WRITER_LOCKS 200112L + +/* We have a POSIX shell. */ +#define _POSIX_SHELL 1 + +/* We support the Timeouts option. */ +#define _POSIX_TIMEOUTS 200112L + +/* We support spinlocks. */ +#define _POSIX_SPIN_LOCKS 200112L + +/* The `spawn' function family is supported. */ +#define _POSIX_SPAWN 200112L + +/* We have POSIX timers. */ +#define _POSIX_TIMERS 200112L + +/* The barrier functions are available. */ +#define _POSIX_BARRIERS 200112L + +/* POSIX message queues are available. */ +#define _POSIX_MESSAGE_PASSING 200112L + +/* Thread process-shared synchronization is not supported. */ +#define _POSIX_THREAD_PROCESS_SHARED -1 + +/* The monotonic clock might be available. */ +#define _POSIX_MONOTONIC_CLOCK 0 + +/* The clock selection interfaces are not available. */ +#define _POSIX_CLOCK_SELECTION -1 + +/* Advisory information interfaces are available. */ +#define _POSIX_ADVISORY_INFO 200112L + +/* IPv6 support is available. */ +#define _POSIX_IPV6 200112L + +/* Raw socket support is available. */ +#define _POSIX_RAW_SOCKETS 200112L + +/* We have at least one terminal. */ +#define _POSIX2_CHAR_TERM 200112L + +/* Neither process nor thread sporadic server interfaces is available. */ +#define _POSIX_SPORADIC_SERVER -1 +#define _POSIX_THREAD_SPORADIC_SERVER -1 + +/* trace.h is not available. */ +#define _POSIX_TRACE -1 +#define _POSIX_TRACE_EVENT_FILTER -1 +#define _POSIX_TRACE_INHERIT -1 +#define _POSIX_TRACE_LOG -1 + +/* Typed memory objects are not available. */ +#define _POSIX_TYPED_MEMORY_OBJECTS -1 + +/* No support for priority inheritance or protection. */ +#define _POSIX_THREAD_PRIO_INHERIT -1 +#define _POSIX_THREAD_PRIO_PROTECT -1 + +#endif /* posix_opt.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h b/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h new file mode 100644 index 0000000000..960bde18a9 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h @@ -0,0 +1,38 @@ +/* Signal handling function for threaded programs. + Copyright (C) 1998, 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; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _BITS_SIGTHREAD_H +#define _BITS_SIGTHREAD_H 1 + +#if !defined _SIGNAL_H && !defined _PTHREAD_H +# error "Never include this file directly. Use <pthread.h> instead" +#endif + +/* Functions for handling signals. */ + +/* Modify the signal mask for the calling thread. The arguments have + the same meaning as for sigprocmask(2). */ +extern int pthread_sigmask (int __how, + __const __sigset_t *__restrict __newmask, + __sigset_t *__restrict __oldmask)__THROW; + +/* Send signal SIGNO to the given thread. */ +extern int pthread_kill (pthread_t __threadid, int __signo) __THROW; + +#endif /* bits/sigthread.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/execve.c b/linuxthreads/sysdeps/unix/sysv/linux/execve.c new file mode 100644 index 0000000000..9fa912b90d --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/execve.c @@ -0,0 +1,73 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <unistd.h> + +#include <sysdep.h> +#include <alloca.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +extern int __syscall_execve (const char *__unbounded file, + char *__unbounded const *__unbounded argv, + char *__unbounded const *__unbounded envp); +extern void __pthread_kill_other_threads_np (void); +weak_extern (__pthread_kill_other_threads_np) + + +int +__execve (file, argv, envp) + 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 (); +#if __BOUNDED_POINTERS__ + { + char *const *v; + int i; + char *__unbounded *__unbounded ubp_argv; + char *__unbounded *__unbounded ubp_envp; + char *__unbounded *__unbounded ubp_v; + + for (v = argv; *v; v++) + ; + i = v - argv + 1; + ubp_argv = (char *__unbounded *__unbounded) alloca (sizeof (*ubp_argv) * i); + for (v = argv, ubp_v = ubp_argv; --i; v++, ubp_v++) + *ubp_v = CHECK_STRING (*v); + *ubp_v = 0; + + for (v = envp; *v; v++) + ; + i = v - envp + 1; + ubp_envp = (char *__unbounded *__unbounded) alloca (sizeof (*ubp_envp) * i); + for (v = envp, ubp_v = ubp_envp; --i; v++, ubp_v++) + *ubp_v = CHECK_STRING (*v); + *ubp_v = 0; + + return INLINE_SYSCALL (execve, 3, CHECK_STRING (file), ubp_argv, ubp_envp); + } +#else + return INLINE_SYSCALL (execve, 3, file, argv, envp); +#endif +} +weak_alias (__execve, execve) diff --git a/linuxthreads/sysdeps/unix/sysv/linux/fork.c b/linuxthreads/sysdeps/unix/sysv/linux/fork.c new file mode 100644 index 0000000000..00eb787093 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/fork.c @@ -0,0 +1,43 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <fork.h> +#include <bits/libc-lock.h> + +#ifndef SHARED +weak_extern (__pthread_fork); +#endif + +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 } +}; + +pid_t +__libc_fork (void) +{ + return __libc_maybe_call2 (pthread_fork, (&__fork_block), ARCH_FORK ()); +} +weak_alias (__libc_fork, __fork) +libc_hidden_def (__fork) +weak_alias (__libc_fork, fork) diff --git a/linuxthreads/sysdeps/unix/sysv/linux/fork.h b/linuxthreads/sysdeps/unix/sysv/linux/fork.h new file mode 100644 index 0000000000..76708e3e39 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/fork.h @@ -0,0 +1,60 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <list.h> +#include <bits/libc-lock.h> +#include <sysdep.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); +libc_hidden_proto (__register_atfork) + +#ifndef ARCH_FORK +# define ARCH_FORK() INLINE_SYSCALL (fork, 0) +#endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c b/linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c new file mode 100644 index 0000000000..0d6da82919 --- /dev/null +++ b/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/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h b/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h new file mode 100644 index 0000000000..9b13400286 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h @@ -0,0 +1,27 @@ +/* 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h b/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h new file mode 100644 index 0000000000..817cf59222 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h @@ -0,0 +1,73 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c new file mode 100644 index 0000000000..27f850cf8f --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c @@ -0,0 +1,109 @@ +/* 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, + write to the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h new file mode 100644 index 0000000000..134977e074 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h @@ -0,0 +1,189 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h b/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h new file mode 100644 index 0000000000..5355310ccd --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h @@ -0,0 +1,64 @@ +/* System-specific settings for dynamic linker code. IA-32 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _DL_SYSDEP_H +#define _DL_SYSDEP_H 1 + +/* This macro must be defined to either 0 or 1. + + If 1, then an errno global variable hidden in ld.so will work right with + all the errno-using libc code compiled for ld.so, and there is never a + need to share the errno location with libc. This is appropriate only if + all the libc functions that ld.so uses are called without PLT and always + get the versions linked into ld.so rather than the libc ones. */ + +#ifdef IS_IN_rtld +# define RTLD_PRIVATE_ERRNO 1 +#else +# define RTLD_PRIVATE_ERRNO 0 +#endif + +/* Traditionally system calls have been made using int $0x80. A + second method was introduced which, if possible, will use the + sysenter/syscall instructions. To signal the presence and where to + find the code the kernel passes an AT_SYSINFO value in the + auxiliary vector to the application. + sysenter/syscall is not useful on i386 through i586, but the dynamic + linker and dl code in libc.a has to be able to load i686 compiled + libraries. */ +#define NEED_DL_SYSINFO 1 +#undef USE_DL_SYSINFO + +#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__ +extern void _dl_sysinfo_int80 (void) attribute_hidden; +# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80 +# define DL_SYSINFO_IMPLEMENTATION \ + asm (".text\n\t" \ + ".type _dl_sysinfo_int80,@function\n\t" \ + ".hidden _dl_sysinfo_int80\n" \ + CFI_STARTPROC "\n" \ + "_dl_sysinfo_int80:\n\t" \ + "int $0x80;\n\t" \ + "ret;\n\t" \ + CFI_ENDPROC "\n" \ + ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80\n\t" \ + ".previous"); +#endif + +#endif /* dl-sysdep.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h new file mode 100644 index 0000000000..7865f7165e --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h @@ -0,0 +1,179 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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); \ + 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; +# 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; PUSHCARGS_0 +# define DOCARGS_1 _DOARGS_1 (4) +# define POPCARGS_1 POPCARGS_0; movl %edx, %ebx +# define _PUSHCARGS_1 pushl %ebx; L(PUSHBX2): _PUSHCARGS_0 +# define _POPCARGS_1 _POPCARGS_0; popl %ebx; L(POPBX2): + +# 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; L(PUSHSI2): _PUSHCARGS_3 +# define _POPCARGS_4 _POPCARGS_3; popl %esi; L(POPSI2): + +# define PUSHCARGS_5 _PUSHCARGS_5 +# define DOCARGS_5 _DOARGS_5 (36) +# define POPCARGS_5 _POPCARGS_5 +# define _PUSHCARGS_5 pushl %edi; L(PUSHDI2): _PUSHCARGS_4 +# define _POPCARGS_5 _POPCARGS_4; popl %edi; L(POPDI2): + +# 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; movl %ecx, %eax; CDISABLE; popl %eax; +# define POPSTATE_1 POPSTATE_0 +# define POPSTATE_2 xchgl (%esp), %eax; CDISABLE; popl %eax; +# define POPSTATE_3 POPSTATE_2 +# define POPSTATE_4 POPSTATE_2 +# define POPSTATE_5 POPSTATE_2 + +#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 && USE___THREAD && 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 && USE___THREAD +# 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 || !USE___THREAD +# 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/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S new file mode 100644 index 0000000000..c7a120d239 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S @@ -0,0 +1,95 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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 +# if !defined HAVE_HIDDEN || !USE___THREAD + 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/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile new file mode 100644 index 0000000000..e03aee99fc --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),linuxthreads) +libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask +endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/Versions b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Versions new file mode 100644 index 0000000000..d102772482 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Versions @@ -0,0 +1,6 @@ +libpthread { + GLIBC_2.3.3 { + # Changed PTHREAD_STACK_MIN. + pthread_attr_setstack; pthread_attr_setstacksize; + } +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h new file mode 100644 index 0000000000..629b1f89c1 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h @@ -0,0 +1,92 @@ +/* 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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/linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h new file mode 100644 index 0000000000..27d5fdfbf5 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h @@ -0,0 +1,49 @@ +/* System-specific settings for dynamic linker code. IA-64 version. + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _DL_SYSDEP_H +#define _DL_SYSDEP_H 1 + +#define NEED_DL_SYSINFO 1 +#undef USE_DL_SYSINFO + +#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__ +/* Don't declare this as a function---we want it's entry-point, not + it's function descriptor... */ +extern int _dl_sysinfo_break attribute_hidden; +# define DL_SYSINFO_DEFAULT ((uintptr_t) &_dl_sysinfo_break) +# define DL_SYSINFO_IMPLEMENTATION \ + asm (".text\n\t" \ + ".hidden _dl_sysinfo_break\n\t" \ + ".proc _dl_sysinfo_break\n\t" \ + "_dl_sysinfo_break:\n\t" \ + ".prologue\n\t" \ + ".altrp b6\n\t" \ + ".body\n\t" \ + "break 0x100000;\n\t" \ + "br.ret.sptk.many b6;\n\t" \ + ".endp _dl_sysinfo_break" \ + ".previous"); +#endif + +/* _dl_argv cannot be attribute_relro, because _dl_start_user + might write into it after _dl_start returns. */ +#define DL_ARGV_NOT_RELRO 1 + +#endif /* dl-sysdep.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h new file mode 100644 index 0000000000..30a0cc1918 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h @@ -0,0 +1,25 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <signal.h> +#include <sysdep.h> + +#define ARCH_FORK() INLINE_SYSCALL (clone, 2, SIGCHLD, 0) + +#include_next <fork.h> diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c new file mode 100644 index 0000000000..85fd33f4a8 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c @@ -0,0 +1,140 @@ +/* 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, + write to the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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\ + .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\ + .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/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c new file mode 100644 index 0000000000..0b96e3d5bd --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c @@ -0,0 +1,33 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h new file mode 100644 index 0000000000..dd9637d2b5 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h @@ -0,0 +1,144 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S new file mode 100644 index 0000000000..54acedad4c --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S @@ -0,0 +1,54 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +#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/linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c b/linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c new file mode 100644 index 0000000000..4b90315707 --- /dev/null +++ b/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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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); +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h new file mode 100644 index 0000000000..bb798e40d6 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h @@ -0,0 +1,129 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S new file mode 100644 index 0000000000..49b8a3c0ac --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S @@ -0,0 +1,84 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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 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/linuxthreads/sysdeps/unix/sysv/linux/mips/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/mips/Makefile new file mode 100644 index 0000000000..56eeecc789 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/mips/Makefile @@ -0,0 +1,3 @@ +# pull in __syscall_error routine +libpthread-routines += sysdep + diff --git a/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h new file mode 100644 index 0000000000..fc51774252 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h @@ -0,0 +1,144 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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: \ + 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/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h new file mode 100644 index 0000000000..1fff782397 --- /dev/null +++ b/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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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: 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/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c b/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c new file mode 100644 index 0000000000..e9c2b6e79a --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c @@ -0,0 +1,287 @@ +/* Copyright (C) 2004 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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. */ + if (fcntl (netlink_socket, F_SETFD, FD_CLOEXEC) != 0) + goto errout; + } + + 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 int 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) + { + errout: + 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 <sysdeps/generic/mq_notify.c> +#endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile new file mode 100644 index 0000000000..e98c9bd866 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile @@ -0,0 +1,2 @@ +# pull in __syscall_error routine +libpthread-routines += sysdep diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Versions b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Versions new file mode 100644 index 0000000000..326307c30c --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Versions @@ -0,0 +1,5 @@ +libpthread { + GLIBC_2.3.4 { + longjmp; siglongjmp; + } +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h new file mode 100644 index 0000000000..0ee10c1c3a --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h @@ -0,0 +1,131 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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); \ + 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); \ + 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 + +# ifdef IS_IN_libpthread +# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel) +# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel) +# elif !defined NOT_IN_libc +# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel) +# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel) +# else +# define CENABLE bl JUMPTARGET(__librt_enable_asynccancel) +# define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel) +# 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 +# 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 + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow. */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S new file mode 100644 index 0000000000..ee6254a950 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S @@ -0,0 +1,78 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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 + mflr 9 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr 10 + mtlr 9 + lwz 10,__libc_pthread_functions@got(10) + lwz 10,0(10) +# 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 JUMPTARGET(__syscall_error) +#endif + +PSEUDO_END (__vfork) +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h new file mode 100644 index 0000000000..0c74676766 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h @@ -0,0 +1,127 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S new file mode 100644 index 0000000000..b408e31b7b --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S @@ -0,0 +1,91 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c new file mode 100644 index 0000000000..177256c7fb --- /dev/null +++ b/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/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c new file mode 100644 index 0000000000..5528c55ca5 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c @@ -0,0 +1,56 @@ +/* Internal sigsuspend system call for LinuxThreads. Generic Linux 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <signal.h> +#include <unistd.h> + +#include <sysdep.h> +#include <sys/syscall.h> +#include <linuxthreads/internals.h> + +#include "kernel-features.h" + +void +__pthread_sigsuspend (const sigset_t *set) +{ + INTERNAL_SYSCALL_DECL (err); +#if !__ASSUME_REALTIME_SIGNALS + static int __pthread_missing_rt_sigs; + +# ifdef __NR_rt_sigsuspend + /* First try the RT signals. */ + if (!__pthread_missing_rt_sigs) + { + /* XXX The size argument hopefully will have to be changed to the + real size of the user-level sigset_t. */ + int r; + r = INTERNAL_SYSCALL (rt_sigsuspend, err, 2, set, _NSIG / 8); + if (INTERNAL_SYSCALL_ERRNO (r, err) != ENOSYS) + return; + + __pthread_missing_rt_sigs = 1; + } +# endif + + INTERNAL_SYSCALL (sigsuspend, err, 3, 0, 0, set->__val[0]); +#else + INTERNAL_SYSCALL (rt_sigsuspend, err, 2, set, _NSIG / 8); +#endif +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/raise.c b/linuxthreads/sysdeps/unix/sysv/linux/raise.c new file mode 100644 index 0000000000..9dad2b2697 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/raise.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1996, 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <signal.h> +#include <unistd.h> +#include <bits/libc-lock.h> + +#ifndef SHARED +weak_extern (__pthread_raise) +#endif + +/* Raise the signal SIG. */ +int +raise (sig) + int sig; +{ + return __libc_maybe_call2 (pthread_raise, (sig), + __kill (__getpid (), sig)); +} +libc_hidden_def (raise) +weak_alias (raise, gsignal) diff --git a/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c b/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c new file mode 100644 index 0000000000..e4490e73e9 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c @@ -0,0 +1,88 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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; +} +libc_hidden_def (__register_atfork) diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/bits/typesizes.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/bits/typesizes.h new file mode 100644 index 0000000000..bee7639f06 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/bits/typesizes.h @@ -0,0 +1,72 @@ +/* bits/typesizes.h -- underlying types for *_t. Linux/s390 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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 __UWORD_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 __SLONGWORD_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]; } +#if defined __GNUC__ && __GNUC__ <= 2 +/* Compatibility with g++ 2.95.x. */ +#define __SSIZE_T_TYPE __SWORD_TYPE +#else +/* size_t is unsigned long int on s390 -m31. */ +#define __SSIZE_T_TYPE __SLONGWORD_TYPE +#endif + +/* Number of descriptors that can fit in an `fd_set'. */ +#define __FD_SETSIZE 1024 + + +#endif /* bits/typesizes.h */ diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c new file mode 100644 index 0000000000..b7d901c4c6 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c @@ -0,0 +1,154 @@ +/* Special .init and .fini section support for S/390. + 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. + + 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, + write to the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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\ +#include \"defs.h\"\n\ +\n\ +/*@HEADER_ENDS*/\n\ +\n\ +/*@TESTS_BEGIN*/\n\ +\n\ +/*@TESTS_END*/\n\ +\n\ +/*@_init_PROLOG_BEGINS*/\n\ +\n\ + .section .init\n\ +#NO_APP\n\ + .align 4\n\ +.globl _init\n\ + .type _init,@function\n\ +_init:\n\ +# leaf function 0\n\ +# automatics 0\n\ +# outgoing args 0\n\ +# need frame pointer 0\n\ +# call alloca 0\n\ +# has varargs 0\n\ +# incoming args (stack) 0\n\ +# function length 36\n\ + STM 6,15,24(15)\n\ + BRAS 13,.LTN1_0\n\ +.LT1_0:\n\ +.LC13:\n\ + .long __pthread_initialize_minimal@PLT-.LT1_0\n\ +.LC14:\n\ + .long __gmon_start__@GOT\n\ +.LC15:\n\ + .long _GLOBAL_OFFSET_TABLE_-.LT1_0\n\ +.LTN1_0:\n\ + LR 1,15\n\ + AHI 15,-96\n\ + ST 1,0(15)\n\ + L 12,.LC15-.LT1_0(13)\n\ + AR 12,13\n\ + L 1,.LC13-.LT1_0(13)\n\ + LA 1,0(1,13)\n\ + BASR 14,1\n\ + L 1,.LC14-.LT1_0(13)\n\ + L 1,0(1,12)\n\ + LTR 1,1\n\ + JE .L22\n\ + BASR 14,1\n\ +.L22:\n\ +#APP\n\ + .align 4,0x07\n\ + END_INIT\n\ +\n\ +/*@_init_PROLOG_ENDS*/\n\ +\n\ +/*@_init_EPILOG_BEGINS*/\n\ + .align 4\n\ + .section .init\n\ +#NO_APP\n\ + .align 4\n\ + L 4,152(15)\n\ + LM 6,15,120(15)\n\ + BR 4\n\ +#APP\n\ + END_INIT\n\ +\n\ +/*@_init_EPILOG_ENDS*/\n\ +\n\ +/*@_fini_PROLOG_BEGINS*/\n\ + .section .fini\n\ +#NO_APP\n\ + .align 4\n\ +.globl _fini\n\ + .type _fini,@function\n\ +_fini:\n\ +# leaf function 0\n\ +# automatics 0\n\ +# outgoing args 0\n\ +# need frame pointer 0\n\ +# call alloca 0\n\ +# has varargs 0\n\ +# incoming args (stack) 0\n\ +# function length 30\n\ + STM 6,15,24(15)\n\ + BRAS 13,.LTN2_0\n\ +.LT2_0:\n\ +.LC17:\n\ + .long _GLOBAL_OFFSET_TABLE_-.LT2_0\n\ +.LTN2_0:\n\ + LR 1,15\n\ + AHI 15,-96\n\ + ST 1,0(15)\n\ + L 12,.LC17-.LT2_0(13)\n\ + AR 12,13\n\ +#APP\n\ + .align 4,0x07\n\ + END_FINI\n\ +\n\ +/*@_fini_PROLOG_ENDS*/\n\ +\n\ +/*@_fini_EPILOG_BEGINS*/\n\ + .align 4\n\ + .section .fini\n\ +#NO_APP\n\ + .align 4\n\ + L 4,152(15)\n\ + LM 6,15,120(15)\n\ + BR 4\n\ +#APP\n\ + END_FINI\n\ +\n\ +/*@_fini_EPILOG_ENDS*/\n\ +\n\ +/*@TRAILER_BEGINS*/\ +"); diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h new file mode 100644 index 0000000000..06f7aed7dc --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h @@ -0,0 +1,137 @@ +/* Copyright (C) 2003, 2004 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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 + +# if !defined NOT_IN_libc || defined IS_IN_libpthread + +# define PSEUDO_CANCEL(name, syscall_name, args) \ +L(pseudo_cancel): \ + STM_##args \ + stm %r12,%r15,48(%r15); \ + lr %r14,%r15; \ + ahi %r15,-96; \ + st %r14,0(%r15); \ + basr %r13,0; \ +0: l %r1,1f-0b(%r13); \ + bas %r14,0(%r1,%r13); \ + lr %r0,%r2; \ + LM_##args \ + DO_CALL(syscall_name, args); \ + l %r1,2f-0b(%r13); \ + lr %r12,%r2; \ + lr %r2,%r0; \ + bas %r14,0(%r1,%r13); \ + lr %r2,%r12; \ + lm %r12,%r15,48+96(%r15); \ + j L(pseudo_check); \ +1: .long CENABLE-0b; \ +2: .long CDISABLE-0b; + +# else /* !libc.so && !libpthread.so */ + +# define PSEUDO_CANCEL(name, syscall_name, args) \ +L(pseudo_cancel): \ + STM_##args \ + stm %r11,%r15,44(%r15); \ + lr %r14,%r15; \ + ahi %r15,-96; \ + st %r14,0(%r15); \ + basr %r13,0; \ +0: l %r12,3f-0b(%r13); \ + l %r1,1f-0b(%r13); \ + la %r12,0(%r12,%r13); \ + bas %r14,0(%r1,%r13); \ + lr %r0,%r2; \ + LM_##args \ + DO_CALL(syscall_name, args); \ + l %r1,2f-0b(%r13); \ + lr %r11,%r2; \ + lr %r2,%r0; \ + bas %r14,0(%r1,%r13); \ + lr %r2,%r11; \ + lm %r11,%r15,44+96(%r15); \ + j L(pseudo_check); \ +1: .long CENABLE@PLT-0b; \ +2: .long CDISABLE@PLT-0b; \ +3: .long _GLOBAL_OFFSET_TABLE_-0b; + +# endif + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ + .text; \ +PSEUDO_CANCEL(name, syscall_name, args) \ +ENTRY(name) \ + SINGLE_THREAD_P(%r1) \ + jne L(pseudo_cancel); \ + DO_CALL(syscall_name, args); \ +L(pseudo_check): \ + lhi %r4,-4095; \ + clr %r2,%r4; \ + jnl SYSCALL_ERROR_LABEL; \ +L(pseudo_end): + +# ifdef IS_IN_libpthread +# define CENABLE __pthread_enable_asynccancel +# define CDISABLE __pthread_disable_asynccancel +# elif !defined NOT_IN_libc +# define CENABLE __libc_enable_asynccancel +# define CDISABLE __libc_disable_asynccancel +# else +# define CENABLE __librt_enable_asynccancel +# define CDISABLE __librt_disable_asynccancel +# endif + +#define STM_0 /* Nothing */ +#define STM_1 st %r2,8(%r15); +#define STM_2 stm %r2,%r3,8(%r15); +#define STM_3 stm %r2,%r4,8(%r15); +#define STM_4 stm %r2,%r5,8(%r15); +#define STM_5 stm %r2,%r5,8(%r15); + +#define LM_0 /* Nothing */ +#define LM_1 l %r2,8+96(%r15); +#define LM_2 lm %r2,%r3,8+96(%r15); +#define LM_3 lm %r2,%r4,8+96(%r15); +#define LM_4 lm %r2,%r5,8+96(%r15); +#define LM_5 lm %r2,%r5,8+96(%r15); + +# ifndef __ASSEMBLER__ +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + p_header.data.multiple_threads) == 0, 1) +# else +# define SINGLE_THREAD_P(reg) \ + ear reg,%a0; \ + icm reg,15,MULTIPLE_THREADS_OFFSET(reg); +# endif + +#elif !defined __ASSEMBLER__ + +/* This code should never be used but we define it anyhow. */ +# define SINGLE_THREAD_P (1) + +#endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S new file mode 100644 index 0000000000..6dfeca86d4 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S @@ -0,0 +1,69 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com> + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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) + basr %r1,0 +0: +#ifdef SHARED + al %r1,4f-0b(%r1) + l %r1,0(%r1) + ltr %r1,%r1 +#else + icm %r1,15,4f-0b(%r1) +#endif + jne 1f + + /* Do vfork system call. */ + svc SYS_ify (vfork) + + /* Check for error. */ + lhi %r4,-4095 + clr %r2,%r4 + jnl SYSCALL_ERROR_LABEL + + /* Normal return. */ + br %r14 +1: + basr %r1,0 +2: + al %r1,3f-2b(%r1) + br %r1 +3: + .long HIDDEN_JUMPTARGET(__fork)-2b +4: +#ifdef SHARED + .long __libc_pthread_functions-0b +#else + .weak pthread_create + .long pthread_create +#endif +PSEUDO_END(__vfork) + +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c new file mode 100644 index 0000000000..540443e6a3 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c @@ -0,0 +1,137 @@ +/* Special .init and .fini section support for 64 bit S/390. + Copyright (C) 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + 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, + write to the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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\ +#include \"defs.h\"\n\ +\n\ +/*@HEADER_ENDS*/\n\ +\n\ +/*@TESTS_BEGIN*/\n\ +\n\ +/*@TESTS_END*/\n\ +\n\ +/*@_init_PROLOG_BEGINS*/\n\ +\n\ + .section .init\n\ +#NO_APP\n\ + .align 4\n\ +.globl _init\n\ + .type _init,@function\n\ +_init:\n\ +# leaf function 0\n\ +# automatics 0\n\ +# outgoing args 0\n\ +# need frame pointer 0\n\ +# call alloca 0\n\ +# has varargs 0\n\ +# incoming args (stack) 0\n\ +# function length 36\n\ + STMG 6,15,48(15)\n\ + LGR 1,15\n\ + AGHI 15,-160\n\ + STG 1,0(15)\n\ + LARL 12,_GLOBAL_OFFSET_TABLE_\n\ + BRASL 14,__pthread_initialize_minimal@PLT\n\ + LARL 1,__gmon_start__@GOTENT\n\ + LG 1,0(1)\n\ + LTGR 1,1\n\ + JE .L22\n\ + BASR 14,1\n\ +.L22:\n\ +#APP\n\ + .align 4,0x07\n\ + END_INIT\n\ +\n\ +/*@_init_PROLOG_ENDS*/\n\ +\n\ +/*@_init_EPILOG_BEGINS*/\n\ + .align 4\n\ + .section .init\n\ +#NO_APP\n\ + .align 4\n\ + LG 4,272(15)\n\ + LMG 6,15,208(15)\n\ + BR 4\n\ +#APP\n\ + END_INIT\n\ +\n\ +/*@_init_EPILOG_ENDS*/\n\ +\n\ +/*@_fini_PROLOG_BEGINS*/\n\ + .section .fini\n\ +#NO_APP\n\ + .align 4\n\ +.globl _fini\n\ + .type _fini,@function\n\ +_fini:\n\ +# leaf function 0\n\ +# automatics 0\n\ +# outgoing args 0\n\ +# need frame pointer 0\n\ +# call alloca 0\n\ +# has varargs 0\n\ +# incoming args (stack) 0\n\ +# function length 30\n\ + STMG 6,15,48(15)\n\ + LGR 1,15\n\ + AGHI 15,-160\n\ + STG 1,0(15)\n\ + LARL 12,_GLOBAL_OFFSET_TABLE_\n\ +#APP\n\ + .align 4,0x07\n\ + END_FINI\n\ +\n\ +/*@_fini_PROLOG_ENDS*/\n\ +\n\ +/*@_fini_EPILOG_BEGINS*/\n\ + .align 4\n\ + .section .fini\n\ +#NO_APP\n\ + .align 4\n\ + LG 4,272(15)\n\ + LMG 6,15,208(15)\n\ + BR 4\n\ +#APP\n\ + END_FINI\n\ +\n\ +/*@_fini_EPILOG_ENDS*/\n\ +\n\ +/*@TRAILER_BEGINS*/\n\ + "); diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-sigsuspend.c new file mode 100644 index 0000000000..d57283ad23 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-sigsuspend.c @@ -0,0 +1 @@ +#include "../../ia64/pt-sigsuspend.c" diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h new file mode 100644 index 0000000000..f71ef3f689 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2003, 2004 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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) \ + .text; \ +L(pseudo_cancel): \ + STM_##args \ + stmg %r13,%r15,104(%r15); \ + lgr %r14,%r15; \ + aghi %r15,-160; \ + stg %r14,0(%r15); \ + brasl %r14,CENABLE; \ + lgr %r0,%r2; \ + LM_##args \ + DO_CALL(syscall_name, args); \ + lgr %r13,%r2; \ + lgr %r2,%r0; \ + brasl %r14,CDISABLE; \ + lgr %r2,%r13; \ + lmg %r13,%r15,104+160(%r15); \ + j L(pseudo_check); \ +ENTRY(name) \ + SINGLE_THREAD_P \ + jne L(pseudo_cancel); \ + DO_CALL(syscall_name, args); \ +L(pseudo_check): \ + lghi %r4,-4095; \ + clgr %r2,%r4; \ + jgnl SYSCALL_ERROR_LABEL; \ +L(pseudo_end): + +# ifdef IS_IN_libpthread +# define CENABLE __pthread_enable_asynccancel +# define CDISABLE __pthread_disable_asynccancel +# define __local_multiple_threads __pthread_multiple_threads +# elif !defined NOT_IN_libc +# define CENABLE __libc_enable_asynccancel +# define CDISABLE __libc_disable_asynccancel +# define __local_multiple_threads __libc_multiple_threads +# else +# define CENABLE __librt_enable_asynccancel@PLT +# define CDISABLE __librt_disable_asynccancel@PLT +# endif + +#define STM_0 /* Nothing */ +#define STM_1 stg %r2,16(%r15); +#define STM_2 stmg %r2,%r3,16(%r15); +#define STM_3 stmg %r2,%r4,16(%r15); +#define STM_4 stmg %r2,%r5,16(%r15); +#define STM_5 stmg %r2,%r5,16(%r15); + +#define LM_0 /* Nothing */ +#define LM_1 lg %r2,16+160(%r15); +#define LM_2 lmg %r2,%r3,16+160(%r15); +#define LM_3 lmg %r2,%r4,16+160(%r15); +#define LM_4 lmg %r2,%r5,16+160(%r15); +#define LM_5 lmg %r2,%r5,16+160(%r15); + +# if !defined NOT_IN_libc || defined IS_IN_libpthread +# 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 \ + larl %r1,__local_multiple_threads; \ + icm %r0,15,0(%r1); +# 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 \ + ear %r1,%a0; \ + sllg %r1,%r1,32; \ + ear %r1,%a1; \ + icm %r1,15,MULTIPLE_THREADS_OFFSET(%r1); +# 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/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S new file mode 100644 index 0000000000..199f0017ff --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S @@ -0,0 +1,54 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com> + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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 + larl %r1,__libc_pthread_functions + lg %r1,0(%r1) +#else + .weak pthread_create + larl %r1,pthread_create +#endif + ltgr %r1,%r1 + jgne HIDDEN_JUMPTARGET(__fork) + + /* Do vfork system call. */ + svc SYS_ify (vfork) + + /* Check for error. */ + lghi %r4,-4095 + clgr %r2,%r4 + jgnl SYSCALL_ERROR_LABEL + + /* Normal return. */ + br %r14 +PSEUDO_END(__vfork) + +libc_hidden_def (__vfork) + +weak_alias (__vfork, vfork) diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c new file mode 100644 index 0000000000..1cdb98f0f7 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c @@ -0,0 +1,143 @@ +/* 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, + write to the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h b/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h new file mode 100644 index 0000000000..2c0cbe99ac --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h @@ -0,0 +1,24 @@ +/* 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +static inline int +is_smp_system (void) +{ + return 0; +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h new file mode 100644 index 0000000000..03c6fedbfe --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h @@ -0,0 +1,227 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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 && USE___THREAD && 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 && USE___THREAD +# 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/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S new file mode 100644 index 0000000000..f230c01226 --- /dev/null +++ b/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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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 + 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 #0x10 + 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/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c b/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c new file mode 100644 index 0000000000..fdec09455a --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c @@ -0,0 +1,88 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <signal.h> +#define __need_NULL +#include <stddef.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> +#include <bits/libc-lock.h> + +extern int __syscall_rt_sigtimedwait (const sigset_t *__unbounded, siginfo_t *__unbounded, + const struct timespec *__unbounded, 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, CHECK_SIGSET (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, CHECK_SIGSET (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 (set, sig) + 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 +} +libc_hidden_def (__sigwait) +weak_alias (__sigwait, sigwait) +strong_alias (__sigwait, __libc_sigwait) + +/* Cancellation is handled in __pthread_sigwait. */ +LIBC_CANCEL_HANDLED (); diff --git a/linuxthreads/sysdeps/unix/sysv/linux/smp.h b/linuxthreads/sysdeps/unix/sysv/linux/smp.h new file mode 100644 index 0000000000..81289294b4 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/smp.h @@ -0,0 +1,48 @@ +/* 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/sparc/Versions b/linuxthreads/sysdeps/unix/sysv/linux/sparc/Versions new file mode 100644 index 0000000000..d102772482 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/Versions @@ -0,0 +1,6 @@ +libpthread { + GLIBC_2.3.3 { + # Changed PTHREAD_STACK_MIN. + pthread_attr_setstack; pthread_attr_setstacksize; + } +} diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c b/linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c new file mode 100644 index 0000000000..0d6da82919 --- /dev/null +++ b/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/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h new file mode 100644 index 0000000000..27ffa668f4 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h @@ -0,0 +1,92 @@ +/* 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h new file mode 100644 index 0000000000..7e4253789c --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h @@ -0,0 +1,66 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h new file mode 100644 index 0000000000..793cb1d5f9 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h @@ -0,0 +1,34 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#define ARCH_FORK() \ +({ \ + register long __o0 __asm__ ("o0"); \ + register long __o1 __asm__ ("o1"); \ + register long __g1 __asm__ ("g1") = __NR_fork; \ + __asm __volatile (__SYSCALL_STRING \ + : "=r" (__g1), "=r" (__o0), "=r" (__o1) \ + : "0" (__g1) \ + : __SYSCALL_CLOBBERS); \ + __o0 == -1 ? __o0 : (__o0 & (__o1 - 1)); \ +}) + +#include_next <fork.h> diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h new file mode 100644 index 0000000000..dd3f52a989 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h @@ -0,0 +1,102 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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) \ + .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/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S new file mode 100644 index 0000000000..132da67a14 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S @@ -0,0 +1,65 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile new file mode 100644 index 0000000000..90203051ae --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile @@ -0,0 +1,5 @@ +# glibc makefile fragment for linuxthreads on sparc/sparc64. + +ifeq ($(subdir),linuxthreads) +libpthread-routines += ptw-sigprocmask +endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/pt-sigsuspend.c new file mode 100644 index 0000000000..d57283ad23 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/pt-sigsuspend.c @@ -0,0 +1 @@ +#include "../../ia64/pt-sigsuspend.c" diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h new file mode 100644 index 0000000000..80834292e5 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h @@ -0,0 +1,101 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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) \ + .text; \ +ENTRY(name) \ + ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1; \ + brnz,pn %g1, 1f; \ + mov SYS_ify(syscall_name), %g1; \ + ta 0x6d; \ + bcs,pn %xcc, __syscall_error_handler; \ + nop; \ + .subsection 2; \ +1: save %sp, -192, %sp; \ + CENABLE; \ + nop; \ + mov %o0, %l0; \ + COPY_ARGS_##args \ + mov SYS_ify(syscall_name), %g1; \ + ta 0x6d; \ + bcs,pn %xcc, __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/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S new file mode 100644 index 0000000000..8a6d2771e8 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep-cancel.h> + +#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 + ldx [%o0 + %o2], %o2 + ldx [%o2], %o0 +#else + .weak pthread_create + sethi %hi(pthread_create), %o0 + or %o0, %lo(pthread_create), %o0 +#endif +#if defined SHARED && !defined BROKEN_SPARC_WDISP22 + cmp %o0, 0 + bne HIDDEN_JUMPTARGET(__fork) +#else + brnz,pn %o0, 1f +#endif + mov __NR_vfork, %g1 + ta 0x6d + bcs,pn %xcc, __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/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c b/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c new file mode 100644 index 0000000000..dad273fdf5 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c @@ -0,0 +1,49 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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/linuxthreads/sysdeps/unix/sysv/linux/x86_64/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/Makefile new file mode 100644 index 0000000000..b5e5d5d480 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/Makefile @@ -0,0 +1,4 @@ +ifeq ($(subdir),linuxthreads) +CFLAGS-pt-initfini.s = -g0 -fPIC -fno-inline-functions \ + -fno-asynchronous-unwind-tables $(fno-unit-at-a-time) +endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c new file mode 100644 index 0000000000..3a0c2afc0f --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c @@ -0,0 +1 @@ +#include "../ia64/pt-sigsuspend.c" diff --git a/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h new file mode 100644 index 0000000000..742dbeb0de --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h @@ -0,0 +1,132 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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); \ + movq $SYS_ify (syscall_name), %rax; \ + 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/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S new file mode 100644 index 0000000000..25d1d3f96a --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S @@ -0,0 +1,62 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#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) |