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.gawed...@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 <ja...@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; 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 <ja...@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; 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 <ja...@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; 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 <ja...@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; 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 <ja...@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; 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 > _______________________________________________ devel mailing list devel@uclibc-ng.org http://mailman.uclibc-ng.org/cgi-bin/mailman/listinfo/devel