Hi Ignacy,
I tried v4, but it adds regressions for other architectures.
For example MIPS Little endian running uClibc-ng testsuite.
Any idea? Can you try to reproduce the regressions on your side?
Thanks for the work so far,
Waldemar
Ignacy Gawędzki wrote,
Since librt and libpthread are now integrated into
libc, including
unwind-resume and unwind-forcedunwind implementations of unwind code
makes no sense. Only unwind-forcedunwind is now included with
functions hidden to avoid them overriding the ones from libgcc_s.
* libpthread/nptl/sysdeps/generic/unwind-resume.h: New. Define
generic PERSONALITY_PROTO and PERSONALITY_ARGS and set
HAVE_ARCH_UNWIND_RESUME to 0.
* libpthread/nptl/sysdeps/pthread/unwind-resume.c: Move...
* libpthread/nptl/sysdeps/generic/unwind-resume.c: ... here. Include
generic implementation of _Unwind_Resume on the condition that
!HAVE_ARCH_UNWIND_RESUME. Make functions hidden to prevent them
from overriding libgcc_s's ones.
* libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c: Likewise.
* libpthread/nptl/sysdeps/arm/unwind-resume.h: New. Define
ARM-specific PERSONALITY_PROTO and PERSONALITY_ARGS and set
HAVE_ARCH_UNWIND_RESUME to 1.
* libpthread/nptl/sysdeps/arm/arm-unwind-resume.c,
* libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c,
* libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c: New.
ARM-specific implementations of _Unwind_Resume resp. for libc,
libpthread and librt.
* libpthread/nptl/sysdeps/Makefile.commonarch: Remove both
arm-unwind-resume and rt-arm-unwind-resume from
libpthread_arch_CSRC.
* libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c,
* libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c: Remove.
Signed-off-by: Ignacy Gawędzki <ignacy.gawedzki(a)green-communications.fr>
---
libpthread/nptl/sysdeps/Makefile.commonarch | 1 +
libpthread/nptl/sysdeps/arm/arm-unwind-resume.c | 67 ++++++++
libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c | 2 +
libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c | 1 +
libpthread/nptl/sysdeps/arm/unwind-resume.h | 33 ++++
libpthread/nptl/sysdeps/generic/unwind-resume.c | 75 +++++++++
libpthread/nptl/sysdeps/generic/unwind-resume.h | 33 ++++
.../nptl/sysdeps/pthread/unwind-forcedunwind.c | 49 +++---
libpthread/nptl/sysdeps/pthread/unwind-resume.c | 80 ----------
.../unix/sysv/linux/arm/unwind-forcedunwind.c | 177 ---------------------
.../sysdeps/unix/sysv/linux/arm/unwind-resume.c | 116 --------------
11 files changed, 230 insertions(+), 404 deletions(-)
create mode 100644 libpthread/nptl/sysdeps/arm/arm-unwind-resume.c
create mode 100644 libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c
create mode 100644 libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c
create mode 100644 libpthread/nptl/sysdeps/arm/unwind-resume.h
create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.c
create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.h
delete mode 100644 libpthread/nptl/sysdeps/pthread/unwind-resume.c
delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
diff --git a/libpthread/nptl/sysdeps/Makefile.commonarch
b/libpthread/nptl/sysdeps/Makefile.commonarch
index 7f531f5..c206ac9 100644
--- a/libpthread/nptl/sysdeps/Makefile.commonarch
+++ b/libpthread/nptl/sysdeps/Makefile.commonarch
@@ -18,6 +18,7 @@ endif
libpthread_arch_SSRC := $(filter-out librt-%,$(filter-out libc-%,$(notdir $(wildcard
$(libpthread_arch_DIR)/*.S))))
libpthread_arch_CSRC := $(filter-out librt-%,$(filter-out libc-%,$(notdir $(wildcard
$(libpthread_arch_DIR)/*.c))))
libpthread_arch_CSRC := $(filter-out gen_%,$(libpthread_arch_CSRC))
+libpthread_arch_CSRC := $(filter-out arm-unwind-resume.%
rt-arm-unwind-resume.%,$(libpthread_arch_CSRC))
ifneq ($(TARGET_SUBARCH),)
libpthread_subarch_SSRC := $(notdir $(wildcard $(libpthread_subarch_DIR)/*.S))
diff --git a/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c
b/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c
new file mode 100644
index 0000000..ae55582
--- /dev/null
+++ b/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub(a)redhat.com>om>.
+
+ 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/>. */
+
+/* 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. */
+
+#include <sysdep.h>
+
+__asm__ (
+" .globl _Unwind_Resume\n"
+" .hidden _Unwind_Resume\n"
+" .type _Unwind_Resume, %function\n"
+"_Unwind_Resume:\n"
+" " CFI_SECTIONS (.debug_frame) "\n"
+" " CFI_STARTPROC "\n"
+" stmfd sp!, {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"
+" ldmfd sp!, {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 __libgcc_s_init\n"
+" ldr r3, [r4, r5]\n"
+" b 5b\n"
+" " CFI_ENDPROC "\n"
+" .align 2\n"
+#ifdef __thumb2__
+"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n"
+#else
+"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n"
+#endif
+"2: .word __libgcc_s_resume(GOTOFF)\n"
+" .size _Unwind_Resume, .-_Unwind_Resume\n"
+);
diff --git a/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c
b/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c
new file mode 100644
index 0000000..fd0cec4
--- /dev/null
+++ b/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c
@@ -0,0 +1,2 @@
+__asm__ (".set __libgcc_s_init, pthread_cancel_init");
+#include <arm-unwind-resume.c>
diff --git a/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c
b/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c
new file mode 100644
index 0000000..2641dc5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c
@@ -0,0 +1 @@
+#include <arm-unwind-resume.c>
diff --git a/libpthread/nptl/sysdeps/arm/unwind-resume.h
b/libpthread/nptl/sysdeps/arm/unwind-resume.h
new file mode 100644
index 0000000..736cc83
--- /dev/null
+++ b/libpthread/nptl/sysdeps/arm/unwind-resume.h
@@ -0,0 +1,33 @@
+/* Definitions for unwind-resume.c. ARM (EABI) version.
+ Copyright (C) 2015-2016 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/libpthread/nptl/sysdeps/generic/unwind-resume.c
b/libpthread/nptl/sysdeps/generic/unwind-resume.c
new file mode 100644
index 0000000..cd9df9f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/generic/unwind-resume.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub(a)redhat.com>om>.
+
+ 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/>. */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unwind.h>
+#include <libgcc_s.h>
+#include <unwind-resume.h>
+
+#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY))
+#define __libc_dlsym dlsym
+#define __libc_dlclose dlclose
+
+void (*__libgcc_s_resume) (struct _Unwind_Exception *exc)
+ attribute_hidden __attribute__ ((noreturn));
+
+static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO;
+
+extern
+void abort(void);
+
+void attribute_hidden __attribute__ ((cold))
+__libgcc_s_init(void)
+{
+ void *resume, *personality;
+ void *handle;
+
+ handle = __libc_dlopen (LIBGCC_S_SO);
+
+ if (handle == NULL
+ || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
+ || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) ==
NULL)
+ {
+ fprintf (stderr,
+ LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
+ abort();
+ }
+
+ __libgcc_s_resume = resume;
+ libgcc_s_personality = personality;
+}
+
+#if !HAVE_ARCH_UNWIND_RESUME
+void attribute_hidden
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+ if (__builtin_expect (libgcc_s_resume == NULL, 0))
+ __libgcc_s_init ();
+ __libgcc_s_resume (exc);
+}
+#endif
+
+_Unwind_Reason_Code attribute_hidden
+__gcc_personality_v0 PERSONALITY_PROTO
+{
+ if (__builtin_expect (libgcc_s_personality == NULL, 0))
+ __libgcc_s_init ();
+ return libgcc_s_personality PERSONALITY_ARGS;
+}
diff --git a/libpthread/nptl/sysdeps/generic/unwind-resume.h
b/libpthread/nptl/sysdeps/generic/unwind-resume.h
new file mode 100644
index 0000000..a0dd638
--- /dev/null
+++ b/libpthread/nptl/sysdeps/generic/unwind-resume.h
@@ -0,0 +1,33 @@
+/* Definitions for unwind-resume.c. Generic version.
+ Copyright (C) 2015-2016 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
diff --git a/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c
b/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c
index 6b6ad6f..fd45ce1 100644
--- a/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c
+++ b/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c
@@ -22,16 +22,16 @@
#include <pthreadP.h>
#include <sysdep.h>
#include <libgcc_s.h>
+#include <unwind-resume.h>
#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY))
#define __libc_dlsym dlsym
#define __libc_dlclose dlclose
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 *);
@@ -66,11 +66,12 @@ pthread_cancel_init (void)
#endif
)
{
- printf (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
+ fprintf (stderr,
+ LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
abort();
}
- libgcc_s_resume = resume;
+ __libgcc_s_resume = resume;
libgcc_s_personality = personality;
libgcc_s_forcedunwind = forcedunwind;
libgcc_s_getcfa = getcfa;
@@ -93,55 +94,41 @@ __unwind_freeres (void)
}
}
-void
+#if !HAVE_ARCH_UNWIND_RESUME
+void attribute_hidden
_Unwind_Resume (struct _Unwind_Exception *exc)
{
if (__builtin_expect (libgcc_s_handle == NULL, 0))
pthread_cancel_init ();
- void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume;
- resume (exc);
+ __libgcc_s_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);
-_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)
+_Unwind_Reason_Code attribute_hidden
+__gcc_personality_v0 PERSONALITY_PROTO
{
if (__builtin_expect (libgcc_s_handle == NULL, 0))
pthread_cancel_init ();
- _Unwind_Reason_Code (*personality)
- (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
- struct _Unwind_Context *) = libgcc_s_personality;
- return personality (version, actions, exception_class, ue_header, context);
+ return libgcc_s_personality PERSONALITY_ARGS;
}
-_Unwind_Reason_Code
+_Unwind_Reason_Code attribute_hidden
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
void *stop_argument)
{
if (__builtin_expect (libgcc_s_handle == NULL, 0))
pthread_cancel_init ();
- _Unwind_Reason_Code (*forcedunwind)
- (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *)
- = libgcc_s_forcedunwind;
- return forcedunwind (exc, stop, stop_argument);
+ return libgcc_s_forcedunwind (exc, stop, stop_argument);
}
-_Unwind_Word
+_Unwind_Word attribute_hidden
_Unwind_GetCFA (struct _Unwind_Context *context)
{
if (__builtin_expect (libgcc_s_handle == NULL, 0))
pthread_cancel_init ();
- _Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa;
- return getcfa (context);
+ return libgcc_s_getcfa (context);
}
diff --git a/libpthread/nptl/sysdeps/pthread/unwind-resume.c
b/libpthread/nptl/sysdeps/pthread/unwind-resume.c
deleted file mode 100644
index 3c1ce07..0000000
--- a/libpthread/nptl/sysdeps/pthread/unwind-resume.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek <jakub(a)redhat.com>om>.
-
- 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/>. */
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unwind.h>
-#include <libgcc_s.h>
-
-#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY))
-#define __libc_dlsym dlsym
-#define __libc_dlclose dlclose
-
-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 *);
-
-extern
-void abort(void);
-
-static void
-init (void)
-{
- void *resume, *personality;
- void *handle;
- resume = personality = NULL;
- handle = dlopen (LIBGCC_S_SO, (RTLD_LOCAL | RTLD_LAZY));
-
- if (handle == NULL
- || (resume = dlsym (handle, "_Unwind_Resume")) == NULL
- || (personality = dlsym (handle, "__gcc_personality_v0")) == NULL)
- {
- printf (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
- abort();
- }
-
- libgcc_s_resume = resume;
- libgcc_s_personality = personality;
-}
-
-void
-_Unwind_Resume (struct _Unwind_Exception *exc)
-{
- if (__builtin_expect (libgcc_s_resume == NULL, 0))
- init ();
- libgcc_s_resume (exc);
-}
-
-_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);
-_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)
-{
- if (__builtin_expect (libgcc_s_personality == NULL, 0))
- init ();
- return libgcc_s_personality (version, actions, exception_class,
- ue_header, context);
-}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
deleted file mode 100644
index a6a0515..0000000
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek <jakub(a)redhat.com>om>.
-
- 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/>. */
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <unwind.h>
-#include <pthreadP.h>
-
-#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY))
-#define __libc_dlsym dlsym
-#define __libc_dlclose dlclose
-#define __libc_fatal(x) {/*write(STDERR_FILENO, x, strlen(x));*/ abort();}
-
-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);
- }
-}
-
-#ifdef __thumb__
-void
-_Unwind_Resume (struct _Unwind_Exception *exc)
-{
- if (__builtin_expect (libgcc_s_resume == NULL, 0))
- pthread_cancel_init ();
-
- libgcc_s_resume (exc);
-}
-
-#else
-/* 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. */
-
-__asm__ (
-" .globl _Unwind_Resume\n"
-" .type _Unwind_Resume, %function\n"
-"_Unwind_Resume:\n"
-" .cfi_sections .debug_frame\n"
-" " CFI_STARTPROC "\n"
-" stmfd sp!, {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"
-" ldmfd sp!, {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"
-#ifdef __thumb2__
-"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n"
-#else
-"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n"
-#endif
-"2: .word libgcc_s_resume(GOTOFF)\n"
-" .size _Unwind_Resume, .-_Unwind_Resume\n"
-);
-
-#endif
-
-_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/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
deleted file mode 100644
index e2e2e0b..0000000
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek <jakub(a)redhat.com>om>.
-
- 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/>. */
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <unwind.h>
-
-#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY))
-#define __libc_dlsym dlsym
-#define __libc_dlclose dlclose
-#define __libc_fatal(x) {/*write(STDERR_FILENO, x, strlen(x));*/ abort();}
-
-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;
-}
-#ifdef __thumb__
-void
-_Unwind_Resume (struct _Unwind_Exception *exc)
-{
- if (__builtin_expect (libgcc_s_resume == NULL, 0))
- init ();
- libgcc_s_resume (exc);
-}
-#else
-/* 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. */
-
-__asm__ (
-" .globl _Unwind_Resume\n"
-" .type _Unwind_Resume, %function\n"
-"_Unwind_Resume:\n"
-" " CFI_SECTIONS (.debug_frame) "\n"
-" " CFI_STARTPROC "\n"
-" stmfd sp!, {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"
-" ldmfd sp!, {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"
-#ifdef __thumb2__
-"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n"
-#else
-"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n"
-#endif
-"2: .word libgcc_s_resume(GOTOFF)\n"
-" .size _Unwind_Resume, .-_Unwind_Resume\n"
-);
-#endif
-
-_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);
-}
--
2.7.4