]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
ARM: Consolidate with generic unwinder wrapper code
authorRoland McGrath <roland@hack.frob.com>
Mon, 5 Jan 2015 22:01:49 +0000 (14:01 -0800)
committerRoland McGrath <roland@hack.frob.com>
Mon, 5 Jan 2015 23:42:16 +0000 (15:42 -0800)
ChangeLog
sysdeps/arm/Makefile
sysdeps/arm/arm-unwind-resume.S [new file with mode: 0644]
sysdeps/arm/pt-arm-unwind-resume.S [new file with mode: 0644]
sysdeps/arm/rt-arm-unwind-resume.S [new file with mode: 0644]
sysdeps/arm/unwind-resume.h [new file with mode: 0644]
sysdeps/generic/unwind-resume.h [new file with mode: 0644]
sysdeps/gnu/unwind-resume.c
sysdeps/nptl/unwind-forcedunwind.c
sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c [deleted file]
sysdeps/unix/sysv/linux/arm/unwind-resume.c [deleted file]

index 13448df20a963edc35c8dae6a76f9f5f35c4c8de..262e30015489d3a82e439ecb3ca5ae28a2d14b0f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2015-01-05  Roland McGrath  <roland@hack.frob.com>
+
+       * sysdeps/generic/unwind-resume.h: New file.
+       * sysdeps/gnu/unwind-resume.c: Include it.
+       (libgcc_s_personality): Use PERSONALITY_PROTO macro for the prototype.
+       (__gcc_personality_v0): Likewise, and PERSONALITY_ARGS for the callee
+       argument list.
+       (libgcc_s_resume): Variable renamed to __libgcc_s_resume, made hidden
+       global rather than static.
+       (_Unwind_Resume): Update user.
+       Conditionalize definition on [!HAVE_ARCH_UNWIND_RESUME].
+       (init): Likewise.  Renamed to __libgcc_s_init, made hidden global
+       rather than static.  Add __attribute__ ((cold)).
+       (_Unwind_Resume, __gcc_personality_v0): Update callers.
+       * sysdeps/nptl/unwind-forcedunwind.c: Likewise.
+       * sysdeps/arm/arm-unwind-resume.S: New file.
+       * sysdeps/arm/rt-arm-unwind-resume.S: New file.
+       * sysdeps/arm/pt-arm-unwind-resume.S: New file.
+       * sysdeps/arm/Makefile [$(subdir) = csu]
+       (sysdep_routines, shared-only-routines): Add arm-unwind-resume.
+       [$(subdir) = rt] (librt-sysdep_routines, librt-shared-only-routines):
+       Add rt-arm-unwind-resume.
+       [$(subdir) = nptl]
+       (libpthread-sysdep_routines, libpthread-shared-only-routines):
+       Add pt-arm-unwind-resume.
+       * sysdeps/unix/sysv/linux/arm/unwind-resume.c: File removed.
+       * sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c: File removed.
+
 2015-01-05  Joseph Myers  <joseph@codesourcery.com>
 
        [BZ #17748]
index db60a17671cf4a8b54292500345c612dd4371ac2..f72cce09190c9a15ac6fe5498a4dc473f415daf0 100644 (file)
@@ -50,6 +50,9 @@ shared-only-routines += libc-aeabi_read_tp
 # cantunwind marker.  There's one in start.S.  To make sure we reach it, add
 # unwind tables for __libc_start_main.
 CFLAGS-libc-start.c += -fexceptions
+
+sysdep_routines += arm-unwind-resume
+shared-only-routines += arm-unwind-resume
 endif
 
 ifeq ($(subdir),gmon)
@@ -61,6 +64,11 @@ CFLAGS-backtrace.c += -funwind-tables
 endif
 
 ifeq ($(subdir),rt)
-librt-sysdep_routines += rt-aeabi_unwind_cpp_pr1
-librt-shared-only-routines += rt-aeabi_unwind_cpp_pr1
+librt-sysdep_routines += rt-aeabi_unwind_cpp_pr1 rt-arm-unwind-resume
+librt-shared-only-routines += rt-aeabi_unwind_cpp_pr1 rt-arm-unwind-resume
+endif
+
+ifeq ($(subdir),nptl)
+libpthread-sysdep_routines += pt-arm-unwind-resume
+libpthread-shared-only-routines += pt-arm-unwind-resume
 endif
diff --git a/sysdeps/arm/arm-unwind-resume.S b/sysdeps/arm/arm-unwind-resume.S
new file mode 100644 (file)
index 0000000..d201788
--- /dev/null
@@ -0,0 +1,46 @@
+/* _Unwind_Resume wrapper for ARM EABI.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* This is just implementing exactly what the C version does.
+   We do it in assembly just to ensure that we get an unmolested tail
+   call to the libgcc function, which is necessary for the ARM unwinder.  */
+
+ENTRY (_Unwind_Resume)
+       LDR_HIDDEN (ip, ip, __libgcc_s_resume, 0)
+       cmp     ip, #0
+       beq     1f
+0:     PTR_DEMANGLE (ip, ip, r2, r3)
+       bx      ip
+
+       /* We need to save and restore LR (for our own return address)
+          and R0 (for the argument to _Unwind_Resume) around the call.  */
+1:     push    {r0, lr}
+       cfi_adjust_cfa_offset (8)
+       cfi_rel_offset (r0, 0)
+       cfi_rel_offset (lr, 4)
+       bl      __libgcc_s_init
+       pop     {r0, lr}
+       cfi_adjust_cfa_offset (-8)
+       cfi_restore (r0)
+       cfi_restore (lr)
+
+       LDR_HIDDEN (ip, ip, __libgcc_s_resume, 0)
+       b       0b
+END (_Unwind_Resume)
diff --git a/sysdeps/arm/pt-arm-unwind-resume.S b/sysdeps/arm/pt-arm-unwind-resume.S
new file mode 100644 (file)
index 0000000..7cb555c
--- /dev/null
@@ -0,0 +1,2 @@
+#define __libgcc_s_init        pthread_cancel_init
+#include <arm-unwind-resume.S>
diff --git a/sysdeps/arm/rt-arm-unwind-resume.S b/sysdeps/arm/rt-arm-unwind-resume.S
new file mode 100644 (file)
index 0000000..9144b0c
--- /dev/null
@@ -0,0 +1 @@
+#include <arm-unwind-resume.S>
diff --git a/sysdeps/arm/unwind-resume.h b/sysdeps/arm/unwind-resume.h
new file mode 100644 (file)
index 0000000..1474bb0
--- /dev/null
@@ -0,0 +1,33 @@
+/* Definitions for unwind-resume.c.  ARM (EABI) version.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* The EABI personality routine has a different signature than the
+   canonical one.  These macros tell sysdeps/gnu/unwind*.c how to
+   define __gcc_personality_v0.  */
+#define PERSONALITY_PROTO                       \
+  (_Unwind_State state,                         \
+   struct _Unwind_Exception *ue_header,         \
+   struct _Unwind_Context *context)
+#define PERSONALITY_ARGS                        \
+  (state, ue_header, context)
+
+/* It's vitally important that _Unwind_Resume not have a stack frame; the
+   ARM unwinder relies on register state at entrance.  So we write this in
+   assembly (see arm-unwind-resume.S).  This macro tells the generic code
+   not to provide the generic C definition.  */
+#define HAVE_ARCH_UNWIND_RESUME                 1
diff --git a/sysdeps/generic/unwind-resume.h b/sysdeps/generic/unwind-resume.h
new file mode 100644 (file)
index 0000000..74c1a51
--- /dev/null
@@ -0,0 +1,33 @@
+/* Definitions for unwind-resume.c.  Generic version.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* These describe the arguments to unwinder personality functions,
+   specifically __gcc_personality_v0.  A machine-specific sysdeps
+   file might define them differently.  */
+#define PERSONALITY_PROTO                       \
+  (int version, _Unwind_Action actions,         \
+   _Unwind_Exception_Class exception_class,     \
+   struct _Unwind_Exception *ue_header,         \
+   struct _Unwind_Context *context)
+#define PERSONALITY_ARGS                                        \
+  (version, actions, exception_class, ue_header, context)
+
+/* This is defined nonzero by a machine-specific sysdeps file if
+   _Unwind_Resume is provided separately and thus the generic C
+   version should not be defined.  */
+#define HAVE_ARCH_UNWIND_RESUME                0
index 3f8b1def8fcbdd588147b0fd4957721c386d123d..267949e3a3c6d71c540a018f5eb0378be59204ac 100644 (file)
 #include <unwind.h>
 #include <gnu/lib-names.h>
 #include <sysdep.h>
+#include <unwind-resume.h>
 
-static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
-  __attribute__ ((noreturn));
-static _Unwind_Reason_Code (*libgcc_s_personality)
-  (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
-   struct _Unwind_Context *);
 
-static void
-init (void)
+void (*__libgcc_s_resume) (struct _Unwind_Exception *exc)
+  attribute_hidden __attribute__ ((noreturn));
+
+static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO;
+
+void attribute_hidden __attribute__ ((cold))
+__libgcc_s_init (void)
 {
   void *resume, *personality;
   void *handle;
@@ -43,33 +44,31 @@ init (void)
                   " must be installed for pthread_cancel to work\n");
 
   PTR_MANGLE (resume);
-  libgcc_s_resume = resume;
+  __libgcc_s_resume = resume;
   PTR_MANGLE (personality);
   libgcc_s_personality = personality;
 }
 
+#if !HAVE_ARCH_UNWIND_RESUME
 void
 _Unwind_Resume (struct _Unwind_Exception *exc)
 {
-  if (__glibc_unlikely (libgcc_s_resume == NULL))
-    init ();
+  if (__glibc_unlikely (__libgcc_s_resume == NULL))
+    __libgcc_s_init ();
 
-  __typeof (libgcc_s_resume) resume = libgcc_s_resume;
+  __typeof (__libgcc_s_resume) resume = __libgcc_s_resume;
   PTR_DEMANGLE (resume);
   (*resume) (exc);
 }
+#endif
 
 _Unwind_Reason_Code
-__gcc_personality_v0 (int version, _Unwind_Action actions,
-                     _Unwind_Exception_Class exception_class,
-                      struct _Unwind_Exception *ue_header,
-                      struct _Unwind_Context *context)
+__gcc_personality_v0 PERSONALITY_PROTO
 {
   if (__glibc_unlikely (libgcc_s_personality == NULL))
-    init ();
+    __libgcc_s_init ();
 
   __typeof (libgcc_s_personality) personality = libgcc_s_personality;
   PTR_DEMANGLE (personality);
-
-  return (*personality) (version, actions, exception_class, ue_header, context);
+  return (*personality) PERSONALITY_ARGS;
 }
index 4c8ef972a33bc96db4d0ea45455775ed88404097..55768a549141f50ac282087a57831897c839d23c 100644 (file)
 #include <pthreadP.h>
 #include <sysdep.h>
 #include <gnu/lib-names.h>
+#include <unwind-resume.h>
 
 static void *libgcc_s_handle;
-static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
-static _Unwind_Reason_Code (*libgcc_s_personality)
-  (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
-   struct _Unwind_Context *);
+void (*__libgcc_s_resume) (struct _Unwind_Exception *exc)
+  attribute_hidden __attribute__ ((noreturn));
+static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO;
 static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
   (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
 static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
@@ -64,7 +64,7 @@ pthread_cancel_init (void)
     __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
 
   PTR_MANGLE (resume);
-  libgcc_s_resume = resume;
+  __libgcc_s_resume = resume;
   PTR_MANGLE (personality);
   libgcc_s_personality = personality;
   PTR_MANGLE (forcedunwind);
@@ -90,6 +90,7 @@ __unwind_freeres (void)
     }
 }
 
+#if !HAVE_ARCH_UNWIND_RESUME
 void
 _Unwind_Resume (struct _Unwind_Exception *exc)
 {
@@ -98,27 +99,23 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
   else
     atomic_read_barrier ();
 
-  void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume;
+  void (*resume) (struct _Unwind_Exception *exc) = __libgcc_s_resume;
   PTR_DEMANGLE (resume);
   resume (exc);
 }
+#endif
 
 _Unwind_Reason_Code
-__gcc_personality_v0 (int version, _Unwind_Action actions,
-                     _Unwind_Exception_Class exception_class,
-                     struct _Unwind_Exception *ue_header,
-                     struct _Unwind_Context *context)
+__gcc_personality_v0 PERSONALITY_PROTO
 {
   if (__glibc_unlikely (libgcc_s_handle == NULL))
     pthread_cancel_init ();
   else
     atomic_read_barrier ();
 
-  _Unwind_Reason_Code (*personality)
-    (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
-     struct _Unwind_Context *) = libgcc_s_personality;
+  __typeof (libgcc_s_personality) personality = libgcc_s_personality;
   PTR_DEMANGLE (personality);
-  return personality (version, actions, exception_class, ue_header, context);
+  return (*personality) PERSONALITY_ARGS;
 }
 
 _Unwind_Reason_Code
diff --git a/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
deleted file mode 100644 (file)
index fab705e..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <unwind.h>
-#include <pthreadP.h>
-
-static void *libgcc_s_handle;
-static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
-  __attribute_used__;
-static _Unwind_Reason_Code (*libgcc_s_personality)
-  (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
-static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
-  (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
-static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
-
-void
-__attribute_noinline__
-pthread_cancel_init (void)
-{
-  void *resume, *personality, *forcedunwind, *getcfa;
-  void *handle;
-
-  if (__builtin_expect (libgcc_s_handle != NULL, 1))
-    {
-      /* Force gcc to reload all values.  */
-      asm volatile ("" ::: "memory");
-      return;
-    }
-
-  handle = __libc_dlopen ("libgcc_s.so.1");
-
-  if (handle == NULL
-      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
-      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
-      || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
-        == NULL
-      || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
-#ifdef ARCH_CANCEL_INIT
-      || ARCH_CANCEL_INIT (handle)
-#endif
-      )
-    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");
-
-  libgcc_s_resume = resume;
-  libgcc_s_personality = personality;
-  libgcc_s_forcedunwind = forcedunwind;
-  libgcc_s_getcfa = getcfa;
-  /* Make sure libgcc_s_getcfa is written last.  Otherwise,
-     pthread_cancel_init might return early even when the pointer the
-     caller is interested in is not initialized yet.  */
-  atomic_write_barrier ();
-  libgcc_s_handle = handle;
-}
-
-void
-__libc_freeres_fn_section
-__unwind_freeres (void)
-{
-  void *handle = libgcc_s_handle;
-  if (handle != NULL)
-    {
-      libgcc_s_handle = NULL;
-      __libc_dlclose (handle);
-    }
-}
-
-/* It's vitally important that _Unwind_Resume not have a stack frame; the
-   ARM unwinder relies on register state at entrance.  So we write this in
-   assembly.  */
-
-#define STR1(S) #S
-#define STR(S)  STR1(S)
-
-asm (
-"      .globl  _Unwind_Resume\n"
-"      .type   _Unwind_Resume, %function\n"
-"_Unwind_Resume:\n"
-"      .cfi_sections .debug_frame\n"
-"      " CFI_STARTPROC "\n"
-"      push    {r4, r5, r6, lr}\n"
-"      " CFI_ADJUST_CFA_OFFSET (16)" \n"
-"      " CFI_REL_OFFSET (r4, 0) "\n"
-"      " CFI_REL_OFFSET (r5, 4) "\n"
-"      " CFI_REL_OFFSET (r6, 8) "\n"
-"      " CFI_REL_OFFSET (lr, 12) "\n"
-"      " CFI_REMEMBER_STATE "\n"
-"      ldr     r4, 1f\n"
-"      ldr     r5, 2f\n"
-"3:    add     r4, pc, r4\n"
-"      ldr     r3, [r4, r5]\n"
-"      mov     r6, r0\n"
-"      cmp     r3, #0\n"
-"      beq     4f\n"
-"5:    mov     r0, r6\n"
-"      pop     {r4, r5, r6, lr}\n"
-"      " CFI_ADJUST_CFA_OFFSET (-16) "\n"
-"      " CFI_RESTORE (r4) "\n"
-"      " CFI_RESTORE (r5) "\n"
-"      " CFI_RESTORE (r6) "\n"
-"      " CFI_RESTORE (lr) "\n"
-"      bx      r3\n"
-"      " CFI_RESTORE_STATE "\n"
-"4:    bl      pthread_cancel_init\n"
-"      ldr     r3, [r4, r5]\n"
-"      b       5b\n"
-"      " CFI_ENDPROC "\n"
-"      .align 2\n"
-"1:    .word   _GLOBAL_OFFSET_TABLE_ - 3b - " STR (PC_OFS) "\n"
-"2:    .word   libgcc_s_resume(GOTOFF)\n"
-"      .size   _Unwind_Resume, .-_Unwind_Resume\n"
-);
-
-_Unwind_Reason_Code
-__gcc_personality_v0 (_Unwind_State state,
-                     struct _Unwind_Exception *ue_header,
-                     struct _Unwind_Context *context)
-{
-  if (__builtin_expect (libgcc_s_personality == NULL, 0))
-    pthread_cancel_init ();
-
-  return libgcc_s_personality (state, ue_header, context);
-}
-
-_Unwind_Reason_Code
-_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
-                     void *stop_argument)
-{
-  if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
-    pthread_cancel_init ();
-
-  return libgcc_s_forcedunwind (exc, stop, stop_argument);
-}
-
-_Unwind_Word
-_Unwind_GetCFA (struct _Unwind_Context *context)
-{
-  if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
-    pthread_cancel_init ();
-
-  return libgcc_s_getcfa (context);
-}
diff --git a/sysdeps/unix/sysv/linux/arm/unwind-resume.c b/sysdeps/unix/sysv/linux/arm/unwind-resume.c
deleted file mode 100644 (file)
index 1a1e2df..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <unwind.h>
-
-static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
-  __attribute_used__;
-static _Unwind_Reason_Code (*libgcc_s_personality)
-  (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
-
-static void init (void) __attribute_used__;
-
-static void
-init (void)
-{
-  void *resume, *personality;
-  void *handle;
-
-  handle = __libc_dlopen ("libgcc_s.so.1");
-
-  if (handle == NULL
-      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
-      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
-    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");
-
-  libgcc_s_resume = resume;
-  libgcc_s_personality = personality;
-}
-
-/* It's vitally important that _Unwind_Resume not have a stack frame; the
-   ARM unwinder relies on register state at entrance.  So we write this in
-   assembly.  */
-
-#define STR1(S) #S
-#define STR(S)  STR1(S)
-
-asm (
-"      .globl  _Unwind_Resume\n"
-"      .type   _Unwind_Resume, %function\n"
-"_Unwind_Resume:\n"
-"      .cfi_sections .debug_frame\n"
-"      " CFI_STARTPROC "\n"
-"      push    {r4, r5, r6, lr}\n"
-"      " CFI_ADJUST_CFA_OFFSET (16)" \n"
-"      " CFI_REL_OFFSET (r4, 0) "\n"
-"      " CFI_REL_OFFSET (r5, 4) "\n"
-"      " CFI_REL_OFFSET (r6, 8) "\n"
-"      " CFI_REL_OFFSET (lr, 12) "\n"
-"      " CFI_REMEMBER_STATE "\n"
-"      ldr     r4, 1f\n"
-"      ldr     r5, 2f\n"
-"3:    add     r4, pc, r4\n"
-"      ldr     r3, [r4, r5]\n"
-"      mov     r6, r0\n"
-"      cmp     r3, #0\n"
-"      beq     4f\n"
-"5:    mov     r0, r6\n"
-"      pop     {r4, r5, r6, lr}\n"
-"      " CFI_ADJUST_CFA_OFFSET (-16) "\n"
-"      " CFI_RESTORE (r4) "\n"
-"      " CFI_RESTORE (r5) "\n"
-"      " CFI_RESTORE (r6) "\n"
-"      " CFI_RESTORE (lr) "\n"
-"      bx      r3\n"
-"      " CFI_RESTORE_STATE "\n"
-"4:    bl      init\n"
-"      ldr     r3, [r4, r5]\n"
-"      b       5b\n"
-"      " CFI_ENDPROC "\n"
-"      .align 2\n"
-"1:    .word   _GLOBAL_OFFSET_TABLE_ - 3b - " STR (PC_OFS) "\n"
-"2:    .word   libgcc_s_resume(GOTOFF)\n"
-"      .size   _Unwind_Resume, .-_Unwind_Resume\n"
-);
-
-_Unwind_Reason_Code
-__gcc_personality_v0 (_Unwind_State state,
-                     struct _Unwind_Exception *ue_header,
-                     struct _Unwind_Context *context)
-{
-  if (__builtin_expect (libgcc_s_personality == NULL, 0))
-    init ();
-  return libgcc_s_personality (state, ue_header, context);
-}