Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 28 Dec 2002 09:27:26 +0000 (09:27 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 28 Dec 2002 09:27:26 +0000 (09:27 +0000)
2002-12-28  Ulrich Drepper  <drepper@redhat.com>

* descr.h (struct pthread): Move header.data.list to the back of the
struct.
* sysdeps/i386/tls.h (tcbhead_t): Move list to the back of the struct.
(MULTIPLE_THREADS_OFFSET): Adjust offset.
(SYSINFO_OFFSEET): Likewise.

2002-12-27  Jakub Jelinek  <jakub@redhat.com>

* sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h (USE_DL_SYSINFO):
Define.
(DL_SYSINFO_DEFAULT): Cast to uintptr_t to avoid warnings.
* sysdeps/unix/sysv/linux/i386/dl-sysdep.h (NEED_DL_SYSINFO,
DL_SYSINFO_DEFAULT, DL_SYSINFO_IMPLEMENTATION): Define.
(USE_DL_SYSINFO): Undef.

2002-12-22  Jakub Jelinek  <jakub@redhat.com>

* Makefile (tests-reverse): Use $(objpfx)../libc.so instead of
$(common-objpfx)libc.so.
* tst-cancel4.c (tf_write, tf_writev): Increase buf sizes so that
it is bigger than pipe buffer size even on arches with bigger
page size.
(tf_usleep): Cast usleep argument to useconds_t to avoid warnings.

36 files changed:
elf/rtld.c
linuxthreads/Makefile
linuxthreads/descr.h
linuxthreads/libc_pthread_init.c
linuxthreads/sysdeps/i386/tls.h
linuxthreads/sysdeps/ia64/tls.h [new file with mode: 0644]
linuxthreads/sysdeps/pthread/bits/libc-lock.h
linuxthreads/sysdeps/sparc/sparc32/tls.h [new file with mode: 0644]
linuxthreads/sysdeps/sparc/sparc64/tls.h [new file with mode: 0644]
linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h [new file with mode: 0644]
linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile [new file with mode: 0644]
linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h [new file with mode: 0644]
linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h [new file with mode: 0644]
linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h [new file with mode: 0644]
linuxthreads/sysdeps/x86_64/tls.h
nptl/ChangeLog
nptl/Makefile
nptl/descr.h
nptl/sysdeps/i386/tls.h
nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h
nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h
nptl/tst-cancel4.c
sysdeps/generic/libc-start.c
sysdeps/generic/libc-tls.c
sysdeps/unix/common/pause.c
sysdeps/unix/sysv/linux/i386/sysdep.h
sysdeps/unix/sysv/linux/ia64/sysdep.h
sysdeps/unix/sysv/linux/sparc/sparc32/pipe.S
sysdeps/unix/sysv/linux/sparc/sparc32/socket.S
sysdeps/unix/sysv/linux/sparc/sparc32/syscall.S
sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S
sysdeps/unix/sysv/linux/sparc/sparc64/socket.S
sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S
sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h

index d510018..b8e7f9a 100644 (file)
@@ -1150,6 +1150,10 @@ of this helper program; chances are you did not intend to run this program.\n\
     /* Assign a module ID.  */
     GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
 
+# ifndef TLS_INIT_TP_EXPENSIVE
+#  define TLS_INIT_TP_EXPENSIVE 0
+# endif
+
   /* We do not initialize any of the TLS functionality unless any of the
      initial modules uses TLS.  This makes dynamic loading of modules with
      TLS impossible, but to support it requires either eagerly doing setup
@@ -1157,7 +1161,7 @@ of this helper program; chances are you did not intend to run this program.\n\
      an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
      used.  Trying to do it lazily is too hairy to try when there could be
      multiple threads (from a non-TLS-using libpthread).  */
-  if (GL(dl_tls_max_dtv_idx) > 0)
+  if (GL(dl_tls_max_dtv_idx) > 0 || !TLS_INIT_TP_EXPENSIVE)
     {
       struct link_map *l;
       size_t nelem;
@@ -1565,8 +1569,12 @@ cannot allocate TLS data structures for initial thread");
      we need it in the memory handling later.  */
   GL(dl_initial_searchlist) = *GL(dl_main_searchlist);
 
+#ifndef NONTLS_INIT_TP
+# define NONTLS_INIT_TP do { } while (0)
+#endif
+
 #ifdef USE_TLS
-  if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD)
+  if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD || !TLS_INIT_TP_EXPENSIVE)
     {
       /* Now that we have completed relocation, the initializer data
         for the TLS blocks has its final values and we can copy them
@@ -1579,7 +1587,9 @@ cannot allocate TLS data structures for initial thread");
       if (__builtin_expect (lossage != NULL, 0))
        _dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
     }
+  else
 #endif
+    NONTLS_INIT_TP;
 
   {
     /* Initialize _r_debug.  */
index e9cbf5e..6425108 100644 (file)
@@ -74,8 +74,12 @@ endif
 librt-tests = ex10 ex11
 tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 $(librt-tests) ex12 ex13 joinrace \
        tststack $(tests-nodelete-$(have-z-nodelete)) ecmutex ex14 ex15 ex16 \
-       ex17 ex18 tst-cancel tst-context bug-sleep
+       ex17 ex18 tst-cancel tst-context bug-sleep \
+       tst-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \
+       tst-cancel6
 test-srcs = tst-signal
+# These tests are linked with libc before libpthread
+tests-reverse += tst-cancel5
 
 ifeq ($(build-static),yes)
 tests += tststatic tst-static-locale
@@ -149,8 +153,12 @@ $(objpfx)libpthread.so: $(libc-link.so) $(common-objpfx)libc_nonshared.a
 # Make sure we link with the thread library.
 ifeq ($(build-shared),yes)
 $(addprefix $(objpfx), \
-  $(filter-out $(tests-static) unload, \
+  $(filter-out $(tests-static) $(tests-reverse) unload, \
     $(tests) $(test-srcs))): $(objpfx)libpthread.so
+# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
+# since otherwise libpthread.so comes before libc.so when linking.
+$(addprefix $(objpfx), $(tests-reverse)): \
+  $(objpfx)../libc.so $(objpfx)libpthread.so
 $(addprefix $(objpfx),$(librt-tests)): $(common-objpfx)rt/librt.so
 $(objpfx)unload: $(common-objpfx)dlfcn/libdl.so
 $(objpfx)unload.out: $(objpfx)libpthread.so
index 94ad893..74ef25e 100644 (file)
@@ -20,6 +20,7 @@
 #include <sched.h>
 #include <setjmp.h>
 #include <signal.h>
+#include <stdint.h>
 #include <sys/types.h>
 #include <hp-timing.h>
 #include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */
@@ -107,6 +108,9 @@ struct _pthread_descr_struct {
       union dtv *dtvp;
       pthread_descr self;      /* Pointer to this structure */
       int multiple_threads;
+#ifdef NEED_DL_SYSINFO
+      uintptr_t sysinfo;
+#endif
     } data;
     void *__padding[16];
   } p_header;
index 901d333..c952b22 100644 (file)
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <locale.h>
+#include <stdlib.h>
 #include <string.h>
 #include <tls.h>
-#include <locale.h>
 #include "internals.h"
 #include <sysdep-cancel.h>
 
index c244801..761a8ca 100644 (file)
 #ifndef _TLS_H
 #define _TLS_H
 
+# include <dl-sysdep.h>
 # include <pt-machine.h>
 
 #ifndef __ASSEMBLER__
 # include <stddef.h>
+# include <stdint.h>
 
 /* Type for the dtv.  */
 typedef union dtv
@@ -39,9 +41,17 @@ typedef struct
                           thread descriptor used by libpthread.  */
   dtv_t *dtv;
   void *self;          /* Pointer to the thread descriptor.  */
+  int multiple_threads;
+#ifdef NEED_DL_SYSINFO
+  uintptr_t sysinfo;
+#endif
 } tcbhead_t;
 #endif
 
+#ifdef NEED_DL_SYSINFO
+/* Offset of the SYSINFO element in tcbhead_t.  */
+# define SYSINFO_OFFSET 24
+#endif
 
 /* We can support TLS only if the floating-stack support is available.
    However, we want to compile in the support and test at runtime whether
@@ -174,6 +184,12 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK(                                                  \
   TLS_DO_MODIFY_LDT ((descr), 0)
 #  endif
 
+#if defined NEED_DL_SYSINFO && defined SHARED
+# define INIT_SYSINFO \
+  head->sysinfo = GL(dl_sysinfo)
+#else
+# define INIT_SYSINFO
+#endif
 
 /* Code to initially initialize the thread pointer.  This might need
    special attention since 'errno' is not yet available and if the
@@ -189,9 +205,14 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK(                                                  \
     /* For now the thread descriptor is at the same address.  */             \
     head->self = _descr;                                                     \
                                                                              \
+    INIT_SYSINFO;                                                            \
     TLS_SETUP_GS_SEGMENT (_descr, secondcall);                               \
   })
 
+/* Indicate that dynamic linker shouldn't try to initialize TLS even
+   when no PT_TLS segments are found in the program and libraries
+   it is linked against.  */
+#  define TLS_INIT_TP_EXPENSIVE 1
 
 /* Return the address of the dtv for the current thread.  */
 #  define THREAD_DTV() \
diff --git a/linuxthreads/sysdeps/ia64/tls.h b/linuxthreads/sysdeps/ia64/tls.h
new file mode 100644 (file)
index 0000000..c270795
--- /dev/null
@@ -0,0 +1,64 @@
+/* Definitions for thread-local data handling.  linuxthreads/IA-64 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 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+
+/* FIXME: Only temporary.  When TLS is supported on IA-64,
+   pthread_descr struct needs to be immediately below r13 and
+   at r13 a struct { dtv_t *dtv; void *private; }.  */
+typedef struct
+{
+  void *tcb;           /* Pointer to the TCB.  Not necessary the
+                          thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;          /* Pointer to the thread descriptor.  */
+  int multiple_threads;
+} tcbhead_t;
+#endif /* __ASSEMBLER__ */
+
+#undef USE_TLS
+
+#if USE_TLS
+
+#else
+
+#define NONTLS_INIT_TP \
+  do {                                                                 \
+    static const tcbhead_t nontls_init_tp                      \
+      = { .multiple_threads = 0 };                             \
+    __thread_self = (__typeof (__thread_self)) &nontls_init_tp;        \
+  } while (0)
+
+#endif /* USE_TLS */
+
+#endif /* tls.h */
index 217b0be..cb839fa 100644 (file)
@@ -97,7 +97,7 @@ typedef pthread_key_t __libc_key_t;
 #if defined _LIBC && defined IS_IN_libpthread
 # define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS
 #else
-# ifdef __PIC__
+# if defined __PIC__ || (defined _LIBC && defined SHARED)
 #  define __libc_maybe_call(FUNC, ARGS, ELSE) \
   (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
                     _fn != NULL ? (*_fn) ARGS : ELSE; }))
@@ -106,7 +106,7 @@ typedef pthread_key_t __libc_key_t;
   (FUNC != NULL ? FUNC ARGS : ELSE)
 # endif
 #endif
-#if defined _LIBC && !defined NOT_IN_libc && defined __PIC__
+#if defined _LIBC && !defined NOT_IN_libc && defined SHARED
 # define __libc_maybe_call2(FUNC, ARGS, ELSE) \
   ({__libc_pthread_functions.ptr_##FUNC != NULL \
     ? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; })
diff --git a/linuxthreads/sysdeps/sparc/sparc32/tls.h b/linuxthreads/sysdeps/sparc/sparc32/tls.h
new file mode 100644 (file)
index 0000000..1b316d0
--- /dev/null
@@ -0,0 +1,61 @@
+/* Definitions for thread-local data handling.  linuxthreads/sparc32 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 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+typedef struct
+{
+  void *tcb;           /* Pointer to the TCB.  Not necessary the
+                          thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;          /* Pointer to the thread descriptor.  */
+  int multiple_threads;
+} tcbhead_t;
+
+#endif /* __ASSEMBLER__ */
+
+#undef USE_TLS
+
+#if USE_TLS
+
+#else
+
+#define NONTLS_INIT_TP \
+  do {                                                                 \
+    static const tcbhead_t nontls_init_tp                      \
+      = { .multiple_threads = 0 };                             \
+    __thread_self = (__typeof (__thread_self)) &nontls_init_tp;        \
+  } while (0)
+
+#endif /* USE_TLS */
+
+#endif /* tls.h */
diff --git a/linuxthreads/sysdeps/sparc/sparc64/tls.h b/linuxthreads/sysdeps/sparc/sparc64/tls.h
new file mode 100644 (file)
index 0000000..039ad2b
--- /dev/null
@@ -0,0 +1,61 @@
+/* Definitions for thread-local data handling.  linuxthreads/sparc64 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 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+typedef struct
+{
+  void *tcb;           /* Pointer to the TCB.  Not necessary the
+                          thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;          /* Pointer to the thread descriptor.  */
+  int multiple_threads;
+} tcbhead_t;
+
+#endif /* __ASSEMBLER__ */
+
+#undef USE_TLS
+
+#if USE_TLS
+
+#else
+
+#define NONTLS_INIT_TP \
+  do {                                                                 \
+    static const tcbhead_t nontls_init_tp                      \
+      = { .multiple_threads = 0 };                             \
+    __thread_self = (__typeof (__thread_self)) &nontls_init_tp;        \
+  } while (0)
+
+#endif /* USE_TLS */
+
+#endif /* tls.h */
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 (file)
index 0000000..ac19ac7
--- /dev/null
@@ -0,0 +1,60 @@
+/* System-specific settings for dynamic linker code.  IA-32 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 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 (".type _dl_sysinfo_int80,@function\n\t"                               \
+       ".hidden _dl_sysinfo_int80\n"                                         \
+       "_dl_sysinfo_int80:\n\t"                                                      \
+       "int $0x80;\n\t"                                                              \
+       "ret;\n\t"                                                            \
+       ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80");
+#endif
+
+#endif /* dl-sysdep.h */
index 30be0b9..d449527 100644 (file)
@@ -25,7 +25,7 @@
 #endif
 
 #if defined FLOATING_STACKS && USE___THREAD
-# define MULTIPLE_THREADS_OFFSET       12
+# define MULTIPLE_THREADS_OFFSET       20
 #endif
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile
new file mode 100644 (file)
index 0000000..e03aee9
--- /dev/null
@@ -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/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
new file mode 100644 (file)
index 0000000..d74c044
--- /dev/null
@@ -0,0 +1,118 @@
+/* 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>
+#include <tls.h>
+#ifndef ASSEMBLER
+# include <linuxthreads/internals.h>
+#endif
+
+#define MULTIPLE_THREADS_OFFSET        40
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# 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;;                                                                   \
+.Lpseudo_cancel:                                                             \
+     .prologue;                                                                      \
+     .regstk args, 5, args, 0;                                               \
+     .save ar.pfs, loc0;                                                     \
+     alloc loc0 = ar.pfs, args, 5, args, 0;                                  \
+     .save rp, loc1;                                                         \
+     mov loc1 = rp;;                                                         \
+     .body;                                                                  \
+     CENABLE;;                                                               \
+     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;;                                                                      \
+     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 name;                                                             \
+.section .gnu.linkonce.t.__syscall_error_##args, "ax";                       \
+     .align 32;                                                                      \
+     .proc __syscall_error_##args;                                           \
+     .global __syscall_error_##args;                                         \
+     .hidden __syscall_error_##args;                                         \
+__syscall_error_##args:                                                              \
+     .prologue;                                                                      \
+     .regstk args, 5, args, 0;                                               \
+     .save ar.pfs, loc0;                                                     \
+     .save rp, loc1;                                                         \
+     .body;                                                                  \
+     mov loc4 = r1;;                                                         \
+     br.call.sptk.many b0 = __errno_location;;                               \
+     st4 [r8] = loc3;                                                        \
+     mov r1 = loc4;                                                          \
+     mov rp = loc1;                                                          \
+     mov r8 = -1;                                                            \
+     mov ar.pfs = loc0
+
+# ifdef IS_IN_libpthread
+#  define CENABLE      br.call.sptk.many b0 = __pthread_enable_asynccancel
+#  define CDISABLE     br.call.sptk.many b0 = __pthread_disable_asynccancel
+# else
+#  define CENABLE      br.call.sptk.many b0 = __libc_enable_asynccancel
+#  define CDISABLE     br.call.sptk.many b0 = __libc_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_header.data.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/sparc/sparc32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
new file mode 100644 (file)
index 0000000..ff03f63
--- /dev/null
@@ -0,0 +1,99 @@
+/* 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>
+#include <tls.h>
+#ifndef ASSEMBLER
+# include <linuxthreads/internals.h>
+#endif
+
+#define MULTIPLE_THREADS_OFFSET        20
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)                                    \
+       .text;                                                                \
+ENTRY(name)                                                                  \
+       ld [%g6 + 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;                                  \
+       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
+# else
+#  define CENABLE      call __libc_enable_asynccancel
+#  define CDISABLE     call __libc_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 [%g6 + 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/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
new file mode 100644 (file)
index 0000000..8b9585d
--- /dev/null
@@ -0,0 +1,98 @@
+/* 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>
+#include <tls.h>
+#ifndef ASSEMBLER
+# include <linuxthreads/internals.h>
+#endif
+
+#define MULTIPLE_THREADS_OFFSET        40
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)                                    \
+       .text;                                                                \
+ENTRY(name)                                                                  \
+       ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1;                              \
+       brz,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;                                  \
+       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
+# else
+#  define CENABLE      call __libc_enable_asynccancel
+#  define CDISABLE     call __libc_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 [%g6 + 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
index a649898..67e20b2 100644 (file)
@@ -109,6 +109,11 @@ typedef struct
     _result ? "cannot set %fs base address for thread-local storage" : 0;     \
   })
 
+/* Indicate that dynamic linker shouldn't try to initialize TLS even
+   when no PT_TLS segments are found in the program and libraries
+   it is linked against.  */
+#  define TLS_INIT_TP_EXPENSIVE 1
+
 /* Return the address of the dtv for the current thread.  */
 #  define THREAD_DTV() \
   ({ struct _pthread_descr_struct *__descr;                                  \
index fdfcf7c..e9beee6 100644 (file)
@@ -1,3 +1,29 @@
+2002-12-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * descr.h (struct pthread): Move header.data.list to the back of the
+       struct.
+       * sysdeps/i386/tls.h (tcbhead_t): Move list to the back of the struct.
+       (MULTIPLE_THREADS_OFFSET): Adjust offset.
+       (SYSINFO_OFFSEET): Likewise.
+
+2002-12-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h (USE_DL_SYSINFO):
+       Define.
+       (DL_SYSINFO_DEFAULT): Cast to uintptr_t to avoid warnings.
+       * sysdeps/unix/sysv/linux/i386/dl-sysdep.h (NEED_DL_SYSINFO,
+       DL_SYSINFO_DEFAULT, DL_SYSINFO_IMPLEMENTATION): Define.
+       (USE_DL_SYSINFO): Undef.
+
+2002-12-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (tests-reverse): Use $(objpfx)../libc.so instead of
+       $(common-objpfx)libc.so.
+       * tst-cancel4.c (tf_write, tf_writev): Increase buf sizes so that
+       it is bigger than pipe buffer size even on arches with bigger
+       page size.
+       (tf_usleep): Cast usleep argument to useconds_t to avoid warnings.
+
 2002-12-25  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S: Implement
index 33b5e9a..198f2b3 100644 (file)
@@ -217,8 +217,10 @@ $(addprefix $(objpfx), \
     $(tests) $(test-srcs))): $(objpfx)libpthread.so \
                             $(objpfx)libpthread_nonshared.a
 $(objpfx)tst-unload: $(common-objpfx)dlfcn/libdl.so
+# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
+# since otherwise libpthread.so comes before libc.so when linking.
 $(addprefix $(objpfx), $(tests-reverse)): \
-  $(common-objpfx)libc.so $(objpfx)libpthread.so \
+  $(objpfx)../libc.so $(objpfx)libpthread.so \
   $(objpfx)libpthread_nonshared.a
 $(addprefix $(objpfx),$(tests-static)): $(objpfx)libpthread.a
 else
index 734d339..883078b 100644 (file)
@@ -66,11 +66,11 @@ struct pthread
                                    the address of this thread descriptor.  */
       union dtv *dtvp;
       struct pthread *self;       /* Pointer to this structure */
-      list_t list;
       int multiple_threads;
 #ifdef NEED_DL_SYSINFO
       uintptr_t sysinfo;
 #endif
+      list_t list;
     } data;
     void *__padding[16];
   } header;
index 984094c..4f8ddb2 100644 (file)
@@ -42,9 +42,9 @@ typedef struct
                           thread descriptor used by libpthread.  */
   dtv_t *dtv;
   void *self;          /* Pointer to the thread descriptor.  */
-  list_t list;
   int multiple_threads;
   uintptr_t sysinfo;
+  list_t list;
 } tcbhead_t;
 #endif
 
@@ -62,11 +62,11 @@ typedef struct
 #define STACK_ALIGN    16
 
 /* Offset of the MULTIPLE_THREADS element in tcbhead_t.  */
-#define MULTIPLE_THREADS_OFFSET 20
+#define MULTIPLE_THREADS_OFFSET 12
 
 #ifdef NEED_DL_SYSINFO
 /* Offset of the SYSINFO element in tcbhead_t.  */
-# define SYSINFO_OFFSET 24
+# define SYSINFO_OFFSET 16
 #endif
 
 
index 0eb5f32..5e59962 100644 (file)
@@ -1,4 +1,4 @@
-/* System-specific settings for dynamic linker code.  Generic version.
+/* System-specific settings for dynamic linker code.  IA-32 version.
    Copyright (C) 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 
 #define RTLD_CORRECT_DYNAMIC_WEAK      1
 
+
+/* 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 (".type _dl_sysinfo_int80,@function\n\t"                               \
+       ".hidden _dl_sysinfo_int80\n"                                         \
+       "_dl_sysinfo_int80:\n\t"                                                      \
+       "int $0x80;\n\t"                                                              \
+       "ret;\n\t"                                                            \
+       ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80");
+#endif
+
 #endif /* dl-sysdep.h */
index f0d4ac7..d7328fe 100644 (file)
@@ -1,4 +1,4 @@
-/* System-specific settings for dynamic linker code.  Generic version.
+/* System-specific settings for dynamic linker code.  IA-32 version.
    Copyright (C) 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    find the code the kernel passes an AT_SYSINFO value in the
    auxiliary vector to the application.  */
 #define NEED_DL_SYSINFO        1
+#define USE_DL_SYSINFO 1
 
 #if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
 extern void _dl_sysinfo_int80 (void) attribute_hidden;
-# define DL_SYSINFO_DEFAULT _dl_sysinfo_int80
+# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80
 # define DL_SYSINFO_IMPLEMENTATION \
   asm (".type _dl_sysinfo_int80,@function\n\t"                               \
        ".hidden _dl_sysinfo_int80\n"                                         \
index 371f2f7..7ab7bd6 100644 (file)
@@ -113,7 +113,7 @@ tf_write  (void *arg)
       exit (1);
     }
 
-  char buf[10000];
+  char buf[100000];
   memset (buf, '\0', sizeof (buf));
   ssize_t s = write (fds[1], buf, sizeof (buf));
 
@@ -133,7 +133,7 @@ tf_writev  (void *arg)
       exit (1);
     }
 
-  char buf[10000];
+  char buf[100000];
   memset (buf, '\0', sizeof (buf));
   struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
   ssize_t s = writev (fds[1], iov, 1);
@@ -172,7 +172,7 @@ tf_usleep (void *arg)
       exit (1);
     }
 
-  usleep (ULONG_MAX);
+  usleep ((useconds_t) ULONG_MAX);
 
   printf ("%s: usleep returns\n", __FUNCTION__);
 
index 5b2728b..b4c29dd 100644 (file)
@@ -32,7 +32,7 @@ extern void *__libc_stack_end;
 #ifndef SHARED
 # include <dl-osinfo.h>
 extern void __pthread_initialize_minimal (void)
-# if !(USE_TLS - 0)
+# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
      __attribute__ ((weak))
 # endif
      ;
@@ -97,7 +97,7 @@ BP_SYM (__libc_start_main) (int (*main) (int, char **, char **),
      we need to setup errno.  If there is no thread library and we
      handle TLS the function is defined in the libc to initialized the
      TLS handling.  */
-# if !(USE_TLS - 0)
+# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
   if (__pthread_initialize_minimal)
 # endif
     __pthread_initialize_minimal ();
index ce1f9d5..1461bf8 100644 (file)
@@ -135,8 +135,13 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
        }
 
   if (memsz == 0 && tcbsize <= TLS_INIT_TCB_SIZE)
-    /* We do not need a TLS block and no thread descriptor.  */
-    return;
+    {
+      /* We do not need a TLS block and no thread descriptor.  */
+#ifdef NONTLS_INIT_TP
+      NONTLS_INIT_TP;
+#endif
+      return;
+    }
 
 
   /* We have to set up the TCB block which also (possibly) contains
@@ -249,4 +254,16 @@ __pthread_initialize_minimal (void)
 {
   __libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
 }
+
+#elif defined NONTLS_INIT_TP
+
+/* This is the minimal initialization function used when libpthread is
+   not used.  */
+void
+__attribute__ ((weak))
+__pthread_initialize_minimal (void)
+{
+  NONTLS_INIT_TP;
+}
+
 #endif
index 9a2e44e..508a3e0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 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
@@ -18,7 +18,7 @@
 
 #include <signal.h>
 #include <unistd.h>
-
+#include <sysdep-cancel.h>
 
 /* Suspend the process until a signal arrives.
    This always returns -1 and sets errno to EINTR.  */
 int
 __libc_pause (void)
 {
-  return __sigpause (__sigblock (0), 0);
+  if (SINGLE_THREAD_P)
+    return __sigpause (__sigblock (0), 0);
+
+  int oldtype = LIBC_CANCEL_ASYNC ();
+  int result = __sigpause (__sigblock (0), 0);
+  LIBC_CANCEL_RESET (oldtype);
+  return result;
 }
 weak_alias (__libc_pause, pause)
index 6478af7..25208a0 100644 (file)
@@ -24,7 +24,7 @@
 #include <sysdeps/unix/i386/sysdep.h>
 #include <bp-sym.h>
 #include <bp-asm.h>
-/* Defines RTLD_PRIVATE_ERRNO and NEED_DL_SYSINFO.  */
+/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
 #include <dl-sysdep.h>
 #include <tls.h>
 
@@ -36,7 +36,8 @@
 #undef SYS_ify
 #define SYS_ify(syscall_name)  __NR_##syscall_name
 
-#if defined NEED_DL_SYSINFO && !defined IS_IN_rtld
+#if defined USE_DL_SYSINFO \
+    && (!defined NOT_IN_libc || defined IS_IN_libpthread)
 # define I386_USE_SYSENTER     1
 #else
 # undef I386_USE_SYSENTER
index 57f7a7a..0a2c1bd 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
    Based on code originally written by David Mosberger-Tang
@@ -83,7 +83,7 @@
 #define        PSEUDO(name, syscall_name, args)        \
   ENTRY(name)                                  \
     DO_CALL (SYS_ify(syscall_name));           \
-       cmp.eq p6,p0=-1,r10;;                   \
+       cmp.eq p6,p0=-1,r10;                    \
 (p6)   br.cond.spnt.few __syscall_error;
 
 #define DO_CALL(num)                           \
 
 #else /* not __ASSEMBLER__ */
 
-/* Define a macro which expands into the inline wrapper code for a system
-   call.  */
-#if 0
+/* On IA-64 we have stacked registers for passing arguments.  The
+   "out" registers end up being the called function's "in"
+   registers.
+
+   Also, since we have plenty of registers we have two return values
+   from a syscall.  r10 is set to -1 on error, whilst r8 contains the
+   (non-negative) errno on error or the return value on success.
+ */
 #undef INLINE_SYSCALL
-#define INLINE_SYSCALL(name, nr, args...)      __##name (args)
-#endif
+#define INLINE_SYSCALL(name, nr, args...)                      \
+  ({                                                           \
+    register long _r8 asm ("r8");                              \
+    register long _r10 asm ("r10");                            \
+    register long _r15 asm ("r15") = __NR_##name;              \
+    long _retval;                                              \
+    LOAD_ARGS_##nr (args);                                     \
+    __asm __volatile ("break %3;;\n\t"                         \
+                      : "=r" (_r8), "=r" (_r10), "=r" (_r15)   \
+                      : "i" (__BREAK_SYSCALL), "2" (_r15)      \
+                       ASM_ARGS_##nr                           \
+                      : "memory" ASM_CLOBBERS_##nr);           \
+    _retval = _r8;                                             \
+    if (_r10 == -1)                                            \
+      {                                                                \
+        __set_errno (_retval);                                 \
+        _retval = -1;                                          \
+      }                                                                \
+    _retval; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, nr, args...)                    \
+  ({                                                           \
+    register long _r8 asm ("r8");                              \
+    register long _r10 asm ("r10");                            \
+    register long _r15 asm ("r15") = __NR_##name;              \
+    long _retval;                                              \
+    LOAD_ARGS_##nr (args);                                     \
+    __asm __volatile ("break %3;;\n\t"                         \
+                      : "=r" (_r8), "=r" (_r10), "=r" (_r15)   \
+                      : "i" (__BREAK_SYSCALL), "2" (_r15)      \
+                       ASM_ARGS_##nr                           \
+                      : "memory" ASM_CLOBBERS_##nr);           \
+    _retval = _r8;                                             \
+    if (_r10 == -1)                                            \
+      _retval = -_retval;                                      \
+    _retval; })
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val)  ((unsigned long) (val) >= -4095UL)
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val)    (-(val))
+
+#define LOAD_ARGS_0()   do { } while (0)
+#define LOAD_ARGS_1(out0)                              \
+  register long _out0 asm ("out0") = (long) (out0);    \
+  LOAD_ARGS_0 ()
+#define LOAD_ARGS_2(out0, out1)                                \
+  register long _out1 asm ("out1") = (long) (out1);    \
+  LOAD_ARGS_1 (out0)
+#define LOAD_ARGS_3(out0, out1, out2)                  \
+  register long _out2 asm ("out2") = (long) (out2);    \
+  LOAD_ARGS_2 (out0, out1)
+#define LOAD_ARGS_4(out0, out1, out2, out3)            \
+  register long _out3 asm ("out3") = (long) (out3);    \
+  LOAD_ARGS_3 (out0, out1, out2)
+#define LOAD_ARGS_5(out0, out1, out2, out3, out4)      \
+  register long _out4 asm ("out4") = (long) (out4);    \
+  LOAD_ARGS_4 (out0, out1, out2, out3)
+
+#define ASM_ARGS_0
+#define ASM_ARGS_1      ASM_ARGS_0, "r" (_out0)
+#define ASM_ARGS_2      ASM_ARGS_1, "r" (_out1)
+#define ASM_ARGS_3      ASM_ARGS_2, "r" (_out2)
+#define ASM_ARGS_4      ASM_ARGS_3, "r" (_out3)
+#define ASM_ARGS_5      ASM_ARGS_4, "r" (_out4)
+
+#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0"
+#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1"
+#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2"
+#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3"
+#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4"
+#define ASM_CLOBBERS_5 , "out5", "out6", "out7",                       \
+  /* Non-stacked integer registers, minus r8, r10, r15.  */            \
+  "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18",   \
+  "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27",       \
+  "r28", "r29", "r30", "r31",                                          \
+  /* Predicate registers.  */                                          \
+  "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",    \
+  /* Non-rotating fp registers.  */                                    \
+  "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",    \
+  /* Branch registers.  */                                             \
+  "b6", "b7"
 
 #endif /* not __ASSEMBLER__ */
index 0136026..27ea9f8 100644 (file)
    02111-1307 USA.  */
 
 #include <sysdep.h>
+
        .globl __libc_pipe
 ENTRY (__libc_pipe)
         mov %o0, %o2            /* Save PIPEDES. */
        mov SYS_ify(pipe),%g1
        ta 0x10
-       bcc,a 2f
-       nop
-       SYSCALL_ERROR_HANDLER
-2:
+       bcs __syscall_error_handler
+        nop
        st %o0, [%o2]           /* PIPEDES[0] = %o0; */
         st %o1, [%o2 + 4]       /* PIPEDES[1] = %o1; */
        retl
-       clr %o0
+        clr %o0
+       SYSCALL_ERROR_HANDLER
 
 PSEUDO_END (__libc_pipe)
 weak_alias (__libc_pipe, __pipe)
index 449d537..7bc734e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
 
@@ -67,13 +67,12 @@ ENTRY (__socket)
        add %sp, 68, %o1                /* arg 2: parameter block */
        LOADSYSCALL(socketcall)
        t 0x10
-
-        bcs,a 1f
+        bcs __syscall_error_handler
         nop
        retl
         nop
 
-1:     SYSCALL_ERROR_HANDLER
+       SYSCALL_ERROR_HANDLER
 
 END (__socket)
 
index 08378ab..3b135c8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1997, 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
 #include <sysdep.h>
        .text
 ENTRY (syscall)
-       or      %o0,%g0,%g1
-       or      %o1,%g0,%o0
-       or      %o2,%g0,%o1
-       or      %o3,%g0,%o2
-       or      %o4,%g0,%o3
-       or      %o5,%g0,%o4
+       mov     %o0, %g1
+       mov     %o1, %o0
+       mov     %o2, %o1
+       mov     %o3, %o2
+       mov     %o4, %o3
+       mov     %o5, %o4
        ta      0x10
-       bcc     1f
-       nop
-       save %sp, -96, %sp
-       call __errno_location
-       nop
-       st %i0,[%o0]
-       restore
+       bcs     __syscall_error_handler
+        nop
        retl
-       mov -1, %o0
-1:
-       ret
+        nop
+       SYSCALL_ERROR_HANDLER
 
 PSEUDO_END (syscall)
index e3573fd..e362894 100644 (file)
 
 #ifdef __ASSEMBLER__
 
-#ifdef DONT_LOAD_G1
-# define LOADSYSCALL(x)
-#else
-# define LOADSYSCALL(x) mov __NR_##x, %g1
-#endif
+#define LOADSYSCALL(x) mov __NR_##x, %g1
 
 /* Linux/SPARC uses a different trap number */
 #undef PSEUDO
 
 #define LOC(name)  .L##name
 
+#ifdef LINKER_HANDLES_R_SPARC_WDISP22
+/* Unfortunately, we cannot do this yet.  Linker doesn't seem to
+   handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly .  */
+# define SYSCALL_ERROR_HANDLER_ENTRY(handler)                          \
+       .section .gnu.linkonce.t.handler,"ax",@progbits;                \
+       .globl handler;                                                 \
+       .hidden handler;                                                \
+       .type handler,@function;                                        \
+handler:
+#else
+# define SYSCALL_ERROR_HANDLER_ENTRY(handler)                          \
+       .subsection 3;                                                  \
+handler:
+#endif
+
 #if RTLD_PRIVATE_ERRNO
 # define SYSCALL_ERROR_HANDLER                                         \
        .section .gnu.linkonce.t.__sparc.get_pic.l7,"ax",@progbits;     \
@@ -64,6 +75,7 @@ __sparc.get_pic.l7:                                                   \
        retl;                                                           \
         add    %o7, %l7, %l7;                                          \
        .previous;                                                      \
+SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                   \
        save    %sp,-96,%sp;                                            \
        sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), %l7;                      \
        call    __sparc.get_pic.l7;                                     \
@@ -71,17 +83,20 @@ __sparc.get_pic.l7:                                                 \
        ld      [%l7 + errno], %l0;                                     \
        st      %i0, [%l0];                                             \
        jmpl    %i7+8, %g0;                                             \
-        restore %g0, -1, %o0;
+        restore %g0, -1, %o0;                                          \
+       .previous;
 #else
-# define SYSCALL_ERROR_HANDLER                                 \
-       .global __errno_location;                               \
-        .type   __errno_location,@function;                    \
-       save   %sp, -96, %sp;                                   \
-       call   __errno_location;                                \
-        nop;                                                   \
-       st      %i0, [%o0];                                     \
-       jmpl    %i7+8, %g0;                                     \
-        restore %g0, -1, %o0;
+# define SYSCALL_ERROR_HANDLER                                         \
+SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                   \
+       .global __errno_location;                                       \
+        .type   __errno_location,@function;                            \
+       save   %sp, -96, %sp;                                           \
+       call   __errno_location;                                        \
+        nop;                                                           \
+       st      %i0, [%o0];                                             \
+       jmpl    %i7+8, %g0;                                             \
+        restore %g0, -1, %o0;                                          \
+       .previous;
 #endif
 
 #define PSEUDO(name, syscall_name, args)                       \
@@ -89,10 +104,9 @@ __sparc.get_pic.l7:                                                 \
        ENTRY(name);                                            \
        LOADSYSCALL(syscall_name);                              \
        ta 0x10;                                                \
-       bcc,a 9000f;                                            \
-       nop;                                                    \
-       SYSCALL_ERROR_HANDLER;                                  \
-9000:;
+       bcs __syscall_error_handler;                            \
+        nop;                                                   \
+       SYSCALL_ERROR_HANDLER
 
 #else  /* __ASSEMBLER__ */
 
index 5c80031..5ccedff 100644 (file)
@@ -23,14 +23,13 @@ ENTRY (__libc_pipe)
        mov     %o0, %o2                /* Save PIPEDES. */
        LOADSYSCALL(pipe)
        ta      0x6d
-       bcc,pt  %xcc, 2f
+       bcs,pn  %xcc, __syscall_error_handler
         nop
-       SYSCALL_ERROR_HANDLER
-
-2:     st      %o0, [%o2]              /* PIPEDES[0] = %o0; */
+       st      %o0, [%o2]              /* PIPEDES[0] = %o0; */
        st      %o1, [%o2 + 4]          /* PIPEDES[1] = %o1; */
        retl
         clr    %o0
+       SYSCALL_ERROR_HANDLER
 PSEUDO_END (__libc_pipe)
 
 weak_alias (__libc_pipe, __pipe)
index ed490fb..750c125 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
 
@@ -68,12 +68,12 @@ ENTRY (__socket)
        LOADSYSCALL(socketcall)
        ta      0x6d
 
-        bcs,pn %xcc, 1f
+       bcs,pn  %xcc, __syscall_error_handler
         nop
        retl
         nop
 
-1:     SYSCALL_ERROR_HANDLER
+       SYSCALL_ERROR_HANDLER
 
 END (__socket)
 
index 792a3a3..27bd086 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1999, 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
@@ -30,11 +30,11 @@ ENTRY (syscall)
 
        ta      0x6d
 
-       bcc,pt %xcc,1f
+       bcs,pn %xcc,__syscall_error_handler
         nop
-       SYSCALL_ERROR_HANDLER
-
-1:     retl
+       retl
         nop
 
+       SYSCALL_ERROR_HANDLER
+
 PSEUDO_END (syscall)
index 10b7647..a64da1a 100644 (file)
 
 #ifdef __ASSEMBLER__
 
-#ifdef DONT_LOAD_G1
-# define LOADSYSCALL(x)
-#else
-# define LOADSYSCALL(x) mov __NR_##x, %g1
-#endif
+#define LOADSYSCALL(x) mov __NR_##x, %g1
 
 /* Linux/SPARC uses a different trap number */
 #undef PSEUDO
        C_LABEL(name);                                                  \
        .type name,@function;
 
+#ifdef LINKER_HANDLES_R_SPARC_WDISP22
+/* Unfortunately, we cannot do this yet.  Linker doesn't seem to
+   handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly .  */
+# define SYSCALL_ERROR_HANDLER_ENTRY(handler)                          \
+       .section .gnu.linkonce.t.handler,"ax",@progbits;                \
+       .globl handler;                                                 \
+       .hidden handler;                                                \
+       .type handler,@function;                                        \
+handler:
+#else
+# define SYSCALL_ERROR_HANDLER_ENTRY(handler)                          \
+       .subsection 3;                                                  \
+handler:
+#endif
+
 #if RTLD_PRIVATE_ERRNO
 # define SYSCALL_ERROR_HANDLER                                         \
        .section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits;   \
@@ -57,6 +68,7 @@ __sparc64.get_pic.l7:                                                 \
        retl;                                                           \
         add    %o7, %l7, %l7;                                          \
        .previous;                                                      \
+SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                   \
        save    %sp, -192, %sp;                                         \
        sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), %l7;                      \
        call    __sparc64.get_pic.l7;                                   \
@@ -64,17 +76,20 @@ __sparc64.get_pic.l7:                                                       \
        ldx     [%l7 + errno], %l0;                                     \
        st      %i0, [%l0];                                             \
        jmpl    %i7+8, %g0;                                             \
-        restore %g0, -1, %o0;
+        restore %g0, -1, %o0;                                          \
+       .previous;
 #else
-# define SYSCALL_ERROR_HANDLER                                 \
-       .global __errno_location;                               \
-       .type   __errno_location,@function;                     \
-       save    %sp, -192, %sp;                                 \
-       call    __errno_location;                               \
-        nop;                                                   \
-       st      %i0, [%o0];                                     \
-       jmpl    %i7+8, %g0;                                     \
-        restore %g0, -1, %o0;
+# define SYSCALL_ERROR_HANDLER                                         \
+SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                   \
+       .global __errno_location;                                       \
+       .type   __errno_location,@function;                             \
+       save    %sp, -192, %sp;                                         \
+       call    __errno_location;                                       \
+        nop;                                                           \
+       st      %i0, [%o0];                                             \
+       jmpl    %i7+8, %g0;                                             \
+        restore %g0, -1, %o0;                                          \
+       .previous;
 #endif
 
 #define PSEUDO(name, syscall_name, args)                               \
@@ -82,10 +97,9 @@ __sparc64.get_pic.l7:                                                        \
        ENTRY(name);                                                    \
        LOADSYSCALL(syscall_name);                                      \
        ta      0x6d;                                                   \
-       bcc,pt  %xcc, 1f;                                               \
+       bcs,pn  %xcc, __syscall_error_handler;                          \
         nop;                                                           \
-       SYSCALL_ERROR_HANDLER;                                          \
-1:
+       SYSCALL_ERROR_HANDLER
 
 #undef PSEUDO_END
 #define PSEUDO_END(name)                                               \