about summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/Makefile4
-rw-r--r--nptl/Versions4
-rw-r--r--nptl/forward.c6
-rw-r--r--nptl/nptl-init.c1
-rw-r--r--nptl/pthreadP.h8
-rw-r--r--nptl/pthread_cancel.c10
-rw-r--r--nptl/pthread_exit.c11
-rw-r--r--nptl/unwind.c13
8 files changed, 36 insertions, 21 deletions
diff --git a/nptl/Makefile b/nptl/Makefile
index 323bcc9432..1d3781062c 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -81,6 +81,7 @@ routines = \
   pthread_self \
   pthread_setschedparam \
   pthread_sigmask \
+  unwind \
 
 shared-only-routines = forward
 static-only-routines = pthread_atfork
@@ -211,15 +212,12 @@ libpthread-routines = \
   sem_unlink \
   sem_wait \
   tpp \
-  unwind \
-  unwind-forcedunwind \
   vars \
   version \
 
 libpthread-shared-only-routines = \
   pt-allocrtsig \
   pt-interp \
-  unwind-forcedunwind \
   version \
 
 # Since cancellation handling is in large parts handled using exceptions
diff --git a/nptl/Versions b/nptl/Versions
index 1a7946cf2f..193376c827 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -57,6 +57,7 @@ libc {
   }
   GLIBC_2.3.3 {
     __pthread_cleanup_routine;
+    __pthread_unwind_next;
     pthread_attr_setaffinity_np;
     pthread_getaffinity_np;
   }
@@ -117,6 +118,7 @@ libc {
     __pthread_cond_init; # Used by the C11 threads.
     __pthread_force_elision;
     __pthread_getattr_default_np;
+    __pthread_unwind;
   }
 }
 
@@ -278,7 +280,6 @@ libpthread {
     __pthread_register_cancel_defer;
     __pthread_unregister_cancel;
     __pthread_unregister_cancel_restore;
-    __pthread_unwind_next;
     pthread_attr_getaffinity_np;
     pthread_barrierattr_getpshared;
     pthread_condattr_getclock;
@@ -367,6 +368,5 @@ libpthread {
     __pthread_clock_settime;
     __pthread_get_minstack;
     __pthread_initialize_minimal;
-    __pthread_unwind;
   }
 }
diff --git a/nptl/forward.c b/nptl/forward.c
index 0b607436d4..7a7f54f9d9 100644
--- a/nptl/forward.c
+++ b/nptl/forward.c
@@ -123,9 +123,3 @@ FORWARD (__pthread_setcancelstate, (int state, int *oldstate),
 strong_alias (__pthread_setcancelstate, pthread_setcancelstate)
 
 FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0)
-
-FORWARD_NORETURN (__pthread_unwind,
-                  void attribute_hidden __attribute ((noreturn))
-                  __cleanup_fct_attribute attribute_compat_text_section,
-                  (__pthread_unwind_buf_t *buf), (buf),
-                  __safe_fatal ())
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index b683adb698..124799679b 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -94,7 +94,6 @@ static const struct pthread_functions pthread_functions =
     .ptr___pthread_getspecific = __pthread_getspecific,
     .ptr___pthread_setspecific = __pthread_setspecific,
     .ptr_nthreads = &__nptl_nthreads,
-    .ptr___pthread_unwind = &__pthread_unwind,
     .ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd,
     .ptr__nptl_setxid = __nptl_setxid,
     .ptr_set_robust = __nptl_set_robust
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 75fec43fed..2e66379441 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -271,19 +271,21 @@ extern void __pthread_unwind (__pthread_unwind_buf_t *__buf)
      weak_function
 #endif
      ;
+libc_hidden_proto (__pthread_unwind)
 extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
      __cleanup_fct_attribute __attribute ((__noreturn__))
 #ifndef SHARED
      weak_function
 #endif
      ;
+/* NB: No hidden proto for __pthread_unwind_next: inside glibc, the
+   legacy unwinding mechanism is used.  */
+
+#if IS_IN (libpthread)
 extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
      __cleanup_fct_attribute;
 extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
      __cleanup_fct_attribute;
-#if IS_IN (libpthread)
-hidden_proto (__pthread_unwind)
-hidden_proto (__pthread_unwind_next)
 hidden_proto (__pthread_register_cancel)
 hidden_proto (__pthread_unregister_cancel)
 # ifdef SHARED
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index a011d72fa1..060484cdc8 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -23,6 +23,9 @@
 #include <atomic.h>
 #include <sysdep.h>
 #include <unistd.h>
+#include <unwind-link.h>
+#include <stdio.h>
+#include <gnu/lib-names.h>
 
 int
 __pthread_cancel (pthread_t th)
@@ -36,7 +39,12 @@ __pthread_cancel (pthread_t th)
 
 #ifdef SHARED
   /* Trigger an error if libgcc_s cannot be loaded.  */
-  __pthread_unwind_link_get ();
+  {
+    struct unwind_link *unwind_link = __libc_unwind_link_get ();
+    if (unwind_link == NULL)
+      __libc_fatal (LIBGCC_S_SO
+		    " must be installed for pthread_cancel to work\n");
+  }
 #endif
   int result = 0;
   int oldval;
diff --git a/nptl/pthread_exit.c b/nptl/pthread_exit.c
index 4afc406268..aed8c12e17 100644
--- a/nptl/pthread_exit.c
+++ b/nptl/pthread_exit.c
@@ -18,11 +18,20 @@
 
 #include <stdlib.h>
 #include "pthreadP.h"
-
+#include <unwind-link.h>
+#include <stdio.h>
+#include <gnu/lib-names.h>
 
 void
 __pthread_exit (void *value)
 {
+  {
+    struct unwind_link *unwind_link = __libc_unwind_link_get ();
+    if (unwind_link == NULL)
+      __libc_fatal (LIBGCC_S_SO
+                    " must be installed for pthread_exit to work\n");
+  }
+
   THREAD_SETMEM (THREAD_SELF, result, value);
 
   __do_cancel ();
diff --git a/nptl/unwind.c b/nptl/unwind.c
index 9c7ed7d7ca..f50997f728 100644
--- a/nptl/unwind.c
+++ b/nptl/unwind.c
@@ -25,6 +25,7 @@
 #include "pthreadP.h"
 #include <libc-diag.h>
 #include <jmpbuf-unwind.h>
+#include <shlib-compat.h>
 
 #ifdef _STACK_GROWS_DOWN
 # define FRAME_LEFT(frame, other, adj) \
@@ -134,15 +135,19 @@ __pthread_unwind (__pthread_unwind_buf_t *buf)
   /* We better do not get here.  */
   abort ();
 }
-hidden_def (__pthread_unwind)
-
+libc_hidden_def (__pthread_unwind)
 
 void
 __cleanup_fct_attribute __attribute ((noreturn))
-__pthread_unwind_next (__pthread_unwind_buf_t *buf)
+___pthread_unwind_next (__pthread_unwind_buf_t *buf)
 {
   struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
 
   __pthread_unwind ((__pthread_unwind_buf_t *) ibuf->priv.data.prev);
 }
-hidden_def (__pthread_unwind_next)
+versioned_symbol (libc, ___pthread_unwind_next, __pthread_unwind_next,
+		  GLIBC_2_34);
+#if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_3_3, GLIBC_2_34)
+compat_symbol (libpthread, ___pthread_unwind_next, __pthread_unwind_next,
+	       GLIBC_2_3_3);
+#endif