diff mbox

[uclibc-ng-devel,RFC,v4,1/1] libpthread: Fix inclusion of unwind code.

Message ID 1475777758-23306-2-git-send-email-ignacy.gawedzki@green-communications.fr
State Accepted
Headers show

Commit Message

Ignacy Gawędzki Oct. 6, 2016, 6:15 p.m. UTC
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@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

Comments

Waldemar Brodkorb Oct. 13, 2016, 10:44 a.m. UTC | #1
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@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@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 <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; 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@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 <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; 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@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
>
Ignacy Gawędzki Oct. 13, 2016, 3:17 p.m. UTC | #2
On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
> 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?

I just tried by building a buildroot toolchain for mipsel.  So far
make check fails even without my patch telling me that it doesn't know
how to make target test/Makefile, needed by termios.

Could you please send me your .config for mipsel that fails the make
check?

Thanks,

Ignacy
Ignacy Gawędzki Oct. 13, 2016, 3:32 p.m. UTC | #3
On Thu, Oct 13, 2016 at 05:17:32PM +0200, thus spake Ignacy Gawedzki:
> On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
> > 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?
> 
> I just tried by building a buildroot toolchain for mipsel.  So far
> make check fails even without my patch telling me that it doesn't know
> how to make target test/Makefile, needed by termios.

It looks just like make check doesn't work with a separate build
directory (make O=/path/to/somewhere/else check).  Do you confirm?

Cheers,

Ignacy
Ignacy Gawędzki Oct. 13, 2016, 4:10 p.m. UTC | #4
On Thu, Oct 13, 2016 at 05:32:35PM +0200, thus spake Ignacy Gawedzki:
> On Thu, Oct 13, 2016 at 05:17:32PM +0200, thus spake Ignacy Gawedzki:
> > On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
> > > 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?
> > 
> > I just tried by building a buildroot toolchain for mipsel.  So far
> > make check fails even without my patch telling me that it doesn't know
> > how to make target test/Makefile, needed by termios.
> 
> It looks just like make check doesn't work with a separate build
> directory (make O=/path/to/somewhere/else check).  Do you confirm?

I fixed a few things in test/Makefile and test/Rules.mak (patch
coming soon) and it looks like make check now works with a separate
build directory.  But still, I'm getting errors in test/math regarding
__builtin_isfinite and the like not getting floating-point arguments.
To me it looks like the test code is wrong, but I may be wrong myself.

Any idea how to fix that?
Ignacy Gawędzki Oct. 13, 2016, 6:23 p.m. UTC | #5
On Thu, Oct 13, 2016 at 06:10:15PM +0200, thus spake Ignacy Gawedzki:
> On Thu, Oct 13, 2016 at 05:32:35PM +0200, thus spake Ignacy Gawedzki:
> > On Thu, Oct 13, 2016 at 05:17:32PM +0200, thus spake Ignacy Gawedzki:
> > > On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
> > > > 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?
> > > 
> > > I just tried by building a buildroot toolchain for mipsel.  So far
> > > make check fails even without my patch telling me that it doesn't know
> > > how to make target test/Makefile, needed by termios.
> > 
> > It looks just like make check doesn't work with a separate build
> > directory (make O=/path/to/somewhere/else check).  Do you confirm?
> 
> I fixed a few things in test/Makefile and test/Rules.mak (patch
> coming soon) and it looks like make check now works with a separate
> build directory.  But still, I'm getting errors in test/math regarding
> __builtin_isfinite and the like not getting floating-point arguments.
> To me it looks like the test code is wrong, but I may be wrong myself.
> 
> Any idea how to fix that?

Okay, apart from the fact that you're not supposed to call isfinite
nor isnormal with anything except floating point arguments (tests in
glibc do this by using intermediate variables initialized with the
integer literals), and should cast those literals explicitly to FLOAT,
I discovered that I can disable glibc tests by passing UCLIBC_ONLY=1
(these errors were triggered by my local native glibc). :/

But still, some tests that run a mipsel binary using qemu-mipsel fail
miserably.  Some because they just assume the binary is run natively
(as test/crypt which defines a WRAPPER variable to run the binary
using env), which is simply not working when SIMULATOR_uclibc equals
some qemu binary.  Some other because of reasons unknown to me at this
time: test/unistd/clone (somehow the child processes seem to be
un-wait4-able with qemu).

I'd *really* like to reproduce the failed tests because of my patch,
but without any more information (actual uclibc-ng's .config,
buildroot's .config, exact way to run the testsuite for mipsel on an
amd64 machine), I'm fighting with unrelated problems so far.
Waldemar Brodkorb Oct. 13, 2016, 7:19 p.m. UTC | #6
Hi Ignacy,
Ignacy Gawędzki wrote,

> On Thu, Oct 13, 2016 at 06:10:15PM +0200, thus spake Ignacy Gawedzki:
> > On Thu, Oct 13, 2016 at 05:32:35PM +0200, thus spake Ignacy Gawedzki:
> > > On Thu, Oct 13, 2016 at 05:17:32PM +0200, thus spake Ignacy Gawedzki:
> > > > On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
> > > > > 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?
> > > > 
> > > > I just tried by building a buildroot toolchain for mipsel.  So far
> > > > make check fails even without my patch telling me that it doesn't know
> > > > how to make target test/Makefile, needed by termios.
> > > 
> > > It looks just like make check doesn't work with a separate build
> > > directory (make O=/path/to/somewhere/else check).  Do you confirm?
> > 
> > I fixed a few things in test/Makefile and test/Rules.mak (patch
> > coming soon) and it looks like make check now works with a separate
> > build directory.  But still, I'm getting errors in test/math regarding
> > __builtin_isfinite and the like not getting floating-point arguments.
> > To me it looks like the test code is wrong, but I may be wrong myself.
> > 
> > Any idea how to fix that?
> 
> Okay, apart from the fact that you're not supposed to call isfinite
> nor isnormal with anything except floating point arguments (tests in
> glibc do this by using intermediate variables initialized with the
> integer literals), and should cast those literals explicitly to FLOAT,
> I discovered that I can disable glibc tests by passing UCLIBC_ONLY=1
> (these errors were triggered by my local native glibc). :/
> 
> But still, some tests that run a mipsel binary using qemu-mipsel fail
> miserably.  Some because they just assume the binary is run natively
> (as test/crypt which defines a WRAPPER variable to run the binary
> using env), which is simply not working when SIMULATOR_uclibc equals
> some qemu binary.  Some other because of reasons unknown to me at this
> time: test/unistd/clone (somehow the child processes seem to be
> un-wait4-able with qemu).
> 
> I'd *really* like to reproduce the failed tests because of my patch,
> but without any more information (actual uclibc-ng's .config,
> buildroot's .config, exact way to run the testsuite for mipsel on an
> amd64 machine), I'm fighting with unrelated problems so far.

Sorry I visited ELCE 2016 in Berlin, so I had no time to give you
the required information.
I will sent you buildroot instructions later.

If you want you can try it with my embedded-test script (you need
mksh and qemu installed):
git clone git://git.embedded-test.org/git/embedded-test
cd embedded-test
git clone git://git.uclibc-ng.org/git/uclibc-ng
mksh embedded-test.sh --arch=mipsel --libc=uclibc-ng \
  --libc-source=uclibc-ng --test=libc

Only 3 tests should fail.
Then apply your patch and run it again, it will automatically
do a complete clean build.

best regards
 Waldemar
Ignacy Gawędzki Oct. 15, 2016, 11:57 a.m. UTC | #7
On Thu, Oct 13, 2016 at 09:19:19PM +0200, thus spake Waldemar Brodkorb:
> If you want you can try it with my embedded-test script (you need
> mksh and qemu installed):
> git clone git://git.embedded-test.org/git/embedded-test
> cd embedded-test
> git clone git://git.uclibc-ng.org/git/uclibc-ng
> mksh embedded-test.sh --arch=mipsel --libc=uclibc-ng \
>   --libc-source=uclibc-ng --test=libc
> 
> Only 3 tests should fail.
> Then apply your patch and run it again, it will automatically
> do a complete clean build.

Okay I did this several times yesterday.  On the first attempts, 11
tests failed without my patch vs. 12 with it.  The additional test
that failed with my patch was nptl/tst-cancelx10.  I started
investigating what could possibly go wrong and tried several things,
from running the binary with qemu-mipsel to logging into the vm used
for tests and running the test from there.  It seemed at first that
with my patch the binary got killed with SIGABRT.  I re-ran
embedded-test.sh several times in the process and at some point
noticed that the SHA-1 for openadk is not the same.  Since that
moment, I re-ran embedded-test.sh with a pristine setup in both cases
(with and without my patch).  Now in both cases I have 11 failed tests
and nptl/tst-cancelx10 doesn't fail.

So I'm wondering whether anything in openadk could have changed in the
meantime that makes the tests work well in both cases.

Could you please run the tests again yourself to check this?

Cheers,

Ignacy
Waldemar Brodkorb Oct. 16, 2016, 3:45 p.m. UTC | #8
Hi,
Ignacy Gawędzki wrote,

> On Thu, Oct 13, 2016 at 09:19:19PM +0200, thus spake Waldemar Brodkorb:
> > If you want you can try it with my embedded-test script (you need
> > mksh and qemu installed):
> > git clone git://git.embedded-test.org/git/embedded-test
> > cd embedded-test
> > git clone git://git.uclibc-ng.org/git/uclibc-ng
> > mksh embedded-test.sh --arch=mipsel --libc=uclibc-ng \
> >   --libc-source=uclibc-ng --test=libc
> > 
> > Only 3 tests should fail.
> > Then apply your patch and run it again, it will automatically
> > do a complete clean build.
> 
> Okay I did this several times yesterday.  On the first attempts, 11
> tests failed without my patch vs. 12 with it.  The additional test
> that failed with my patch was nptl/tst-cancelx10.  I started
> investigating what could possibly go wrong and tried several things,
> from running the binary with qemu-mipsel to logging into the vm used
> for tests and running the test from there.  It seemed at first that
> with my patch the binary got killed with SIGABRT.  I re-ran
> embedded-test.sh several times in the process and at some point
> noticed that the SHA-1 for openadk is not the same.  Since that
> moment, I re-ran embedded-test.sh with a pristine setup in both cases
> (with and without my patch).  Now in both cases I have 11 failed tests
> and nptl/tst-cancelx10 doesn't fail.
> 
> So I'm wondering whether anything in openadk could have changed in the
> meantime that makes the tests work well in both cases.
> 
> Could you please run the tests again yourself to check this?

I tested again. With uClibc-ng master i get exactly 3 errors.
Tried three times.

With your patch I get sometime 11 or 12 errors. Seems a timeout
issue. 

What version of Qemu are you using?

qemu-system-mips -version                                                                                                    
QEMU emulator version 2.6.1, Copyright (c) 2003-2008 Fabrice Bellard

We recently had issues with the testsuite build without the full gcc
and I thinking of separating the testsuite to its own project.

OpenADK does not change between runs of embedded-test as long as
you don't use --update.

Are you sure you use uClibc-ng fresh checkout and referencing the
directory with --libc-source? 1.0.18 release would have 11/12
errors, which is the fallback when no special directory is used.

best regards
 Waldemar
Ignacy Gawędzki Oct. 16, 2016, 7:55 p.m. UTC | #9
On Sun, Oct 16, 2016 at 05:45:40PM +0200, thus spake Waldemar Brodkorb:
> I tested again. With uClibc-ng master i get exactly 3 errors.
> Tried three times.

I was using d4d4f37 and my patch applied on top of it.

> 
> With your patch I get sometime 11 or 12 errors. Seems a timeout
> issue. 
> 
> What version of Qemu are you using?
> 
> qemu-system-mips -version                                                                                                    
> QEMU emulator version 2.6.1, Copyright (c) 2003-2008 Fabrice Bellard

I'm using 2.5.0.

> 
> We recently had issues with the testsuite build without the full gcc
> and I thinking of separating the testsuite to its own project.
> 
> OpenADK does not change between runs of embedded-test as long as
> you don't use --update.

Yes, but I ran my tests in two copies of embedded-test.git, and most
probably the second one cloned a more recent version of openadk.

> Are you sure you use uClibc-ng fresh checkout and referencing the
> directory with --libc-source? 1.0.18 release would have 11/12
> errors, which is the fallback when no special directory is used.

As I said, I used d4d4f37 and not strictly origin/master.  But I
otherwise used the command line you gave me, including --libc-source.

I will re-run the tests with origin/master and my patch on top of it.

Cheers,

Ignacy
Waldemar Brodkorb Oct. 16, 2016, 8:01 p.m. UTC | #10
Hi,
Ignacy Gawędzki wrote,

> On Sun, Oct 16, 2016 at 05:45:40PM +0200, thus spake Waldemar Brodkorb:
> > I tested again. With uClibc-ng master i get exactly 3 errors.
> > Tried three times.
> 
> I was using d4d4f37 and my patch applied on top of it.
> 
> > 
> > With your patch I get sometime 11 or 12 errors. Seems a timeout
> > issue. 
> > 
> > What version of Qemu are you using?
> > 
> > qemu-system-mips -version                                                                                                    
> > QEMU emulator version 2.6.1, Copyright (c) 2003-2008 Fabrice Bellard
> 
> I'm using 2.5.0.
> 
> > 
> > We recently had issues with the testsuite build without the full gcc
> > and I thinking of separating the testsuite to its own project.
> > 
> > OpenADK does not change between runs of embedded-test as long as
> > you don't use --update.
> 
> Yes, but I ran my tests in two copies of embedded-test.git, and most
> probably the second one cloned a more recent version of openadk.
> 
> > Are you sure you use uClibc-ng fresh checkout and referencing the
> > directory with --libc-source? 1.0.18 release would have 11/12
> > errors, which is the fallback when no special directory is used.
> 
> As I said, I used d4d4f37 and not strictly origin/master.  But I
> otherwise used the command line you gave me, including --libc-source.

But 17ad14e5780533db90171e16b95dbeda4e81ffb0 contains a workaround
for exactly the seen problem.
 
> I will re-run the tests with origin/master and my patch on top of it.

Okay, thanks.
 Waldemar
Ignacy Gawędzki Oct. 17, 2016, 1:40 p.m. UTC | #11
On Sun, Oct 16, 2016 at 10:01:30PM +0200, thus spake Waldemar Brodkorb:
> > As I said, I used d4d4f37 and not strictly origin/master.  But I
> > otherwise used the command line you gave me, including --libc-source.
> 
> But 17ad14e5780533db90171e16b95dbeda4e81ffb0 contains a workaround
> for exactly the seen problem.
>  
> > I will re-run the tests with origin/master and my patch on top of it.

I found a few interesting things.  The test binaries are compiled by
openadk with the "initial" GCC and not the "final" one.  The
difference is that the implementation of the unwinder code is then
taken from libgcc.a.  I get the same behavior if I explicitly add this
library to the list of objects to link into the test binary.  With a
final version of GCC, the implementation is taken from libgcc_s.so as
it should and the behavior is maybe not ideal but to me it looks far
better (is that because the initial GCC doesn't really implement any
unwinder code?).

The reason why this works without my patch is that the implementation
of the unwinder code is then linked dynamically from libc.so, which,
as I've said previously, is not supposed to be used by code from
outside the lib itself.

I haven't had time yet to look into openadk in order to understand why
it's not using the final GCC to build the tests.  Do you have any
idea?
Ignacy Gawędzki Oct. 17, 2016, 1:52 p.m. UTC | #12
On Mon, Oct 17, 2016 at 03:40:04PM +0200, thus spake Ignacy Gawedzki:
> On Sun, Oct 16, 2016 at 10:01:30PM +0200, thus spake Waldemar Brodkorb:
> > > As I said, I used d4d4f37 and not strictly origin/master.  But I
> > > otherwise used the command line you gave me, including --libc-source.
> > 
> > But 17ad14e5780533db90171e16b95dbeda4e81ffb0 contains a workaround
> > for exactly the seen problem.
> >  
> > > I will re-run the tests with origin/master and my patch on top of it.
> 
> I found a few interesting things.  The test binaries are compiled by
> openadk with the "initial" GCC and not the "final" one.  The
> difference is that the implementation of the unwinder code is then
> taken from libgcc.a.  I get the same behavior if I explicitly add this
> library to the list of objects to link into the test binary.  With a
> final version of GCC, the implementation is taken from libgcc_s.so as
> it should and the behavior is maybe not ideal but to me it looks far
> better (is that because the initial GCC doesn't really implement any
> unwinder code?).

BTW, the initial GCC is built with --disable-threads.  Could that
possibly be the reason some of the tests in nptl fail?
Waldemar Brodkorb Oct. 17, 2016, 6:56 p.m. UTC | #13
Hi Ignacy,
Ignacy Gawędzki wrote,

> On Sun, Oct 16, 2016 at 10:01:30PM +0200, thus spake Waldemar Brodkorb:
> > > As I said, I used d4d4f37 and not strictly origin/master.  But I
> > > otherwise used the command line you gave me, including --libc-source.
> > 
> > But 17ad14e5780533db90171e16b95dbeda4e81ffb0 contains a workaround
> > for exactly the seen problem.
> >  
> > > I will re-run the tests with origin/master and my patch on top of it.
> 
> I found a few interesting things.  The test binaries are compiled by
> openadk with the "initial" GCC and not the "final" one.  The
> difference is that the implementation of the unwinder code is then
> taken from libgcc.a.  I get the same behavior if I explicitly add this
> library to the list of objects to link into the test binary.  With a
> final version of GCC, the implementation is taken from libgcc_s.so as
> it should and the behavior is maybe not ideal but to me it looks far
> better (is that because the initial GCC doesn't really implement any
> unwinder code?).
> 
> The reason why this works without my patch is that the implementation
> of the unwinder code is then linked dynamically from libc.so, which,
> as I've said previously, is not supposed to be used by code from
> outside the lib itself.
> 
> I haven't had time yet to look into openadk in order to understand why
> it's not using the final GCC to build the tests.  Do you have any
> idea?

Because it is compiled as part of the toolchain.
I think it is similary done in Buildroot.

I sent a proposal to the list, how we might fix these kind of issues
in the future.

best regards
 Waldemar
Waldemar Brodkorb Nov. 30, 2016, 5:40 a.m. UTC | #14
Hi Ignacy,
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.

I tested the patch and I think I will push it in the next days.

Sorry that it took a while, but the removal of the test suite
took a while. Now the test suite is compiled as a normal software
package and not with the initial gcc. 
Therefore no regressions seen with your patch.

Any other news to the patch?

best regards
 Waldemar
Ignacy Gawędzki Nov. 30, 2016, 8:21 a.m. UTC | #15
On Wed, Nov 30, 2016 at 06:40:01AM +0100, thus spake Waldemar Brodkorb:
> Hi Ignacy,

Hi 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.
> 
> I tested the patch and I think I will push it in the next days.

Nice.

> Sorry that it took a while, but the removal of the test suite
> took a while. Now the test suite is compiled as a normal software
> package and not with the initial gcc.

That's definitely the right way to go.

> Therefore no regressions seen with your patch.

I'm happy to hear that. =)

> Any other news to the patch?

No.  We've been using it on uClibc-ng 1.0.18 in-house for weeks
without any noticeable problem.

Regards,

Ignacy
diff mbox

Patch

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@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 <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; 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@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 <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; 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@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);
-}