From patchwork Thu Feb 13 17:07:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 38039 Received: (qmail 49377 invoked by alias); 13 Feb 2020 17:08:16 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 49242 invoked by uid 89); 13 Feb 2020 17:08:14 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=hardening X-HELO: us-smtp-1.mimecast.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1581613688; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+uM7lOZiZA6hK88IFpVG3PLhQjDhrMs4bz8n+FDTm+g=; b=WTj+dXL2TkkS5OVysf2Olb1s/xFpMu1g8hGtQ14fSXtbZ/3Ziu60MyaVF4LO8w7Tj5byS/ 3Wro6RuDzE2r8v7eXzE87pQT/FgHlWlZlM1HhvT7NuqSVjP8bDRJ5PTRzCTc/kvRm0wu31 bTbmIWTkQ6TQFDmW9XNyWdmc9BRnpMg= From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH 01/11] Implement for dynamically loading the libgcc_s unwinder In-Reply-To: References: X-From-Line: ff9409cbde9e0608ddbbd8cc169e00497d924228 Mon Sep 17 00:00:00 2001 Message-Id: Date: Thu, 13 Feb 2020 18:07:50 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com This will be used to consolidate the libgcc_s access for backtrace and pthread_cancel. Unlike the backtrace implementations, it provides some hardening based on pointer mangling. --- malloc/set-freeres.c | 5 + misc/Makefile | 2 +- misc/Versions | 1 + misc/unwind-link.c | 149 +++++++++++++++++++ sysdeps/alpha/arch-unwind-link.h | 27 ++++ sysdeps/arm/arch-unwind-link.h | 34 +++++ sysdeps/generic/arch-unwind-link.h | 32 ++++ sysdeps/generic/unwind-link.h | 99 ++++++++++++ sysdeps/i386/arch-unwind-link.h | 38 +++++ sysdeps/ia64/arch-unwind-link.h | 31 ++++ sysdeps/m68k/arch-unwind-link.h | 34 +++++ sysdeps/m68k/m680x0/arch-unwind-link.h | 26 ++++ sysdeps/mach/hurd/fork.c | 3 + sysdeps/mips/arch-unwind-link.h | 27 ++++ sysdeps/nptl/fork.c | 3 + sysdeps/powerpc/powerpc32/arch-unwind-link.h | 27 ++++ sysdeps/s390/arch-unwind-link.h | 27 ++++ sysdeps/sh/arch-unwind-link.h | 27 ++++ sysdeps/sparc/arch-unwind-link.h | 27 ++++ 19 files changed, 618 insertions(+), 1 deletion(-) create mode 100644 misc/unwind-link.c create mode 100644 sysdeps/alpha/arch-unwind-link.h create mode 100644 sysdeps/arm/arch-unwind-link.h create mode 100644 sysdeps/generic/arch-unwind-link.h create mode 100644 sysdeps/generic/unwind-link.h create mode 100644 sysdeps/i386/arch-unwind-link.h create mode 100644 sysdeps/ia64/arch-unwind-link.h create mode 100644 sysdeps/m68k/arch-unwind-link.h create mode 100644 sysdeps/m68k/m680x0/arch-unwind-link.h create mode 100644 sysdeps/mips/arch-unwind-link.h create mode 100644 sysdeps/powerpc/powerpc32/arch-unwind-link.h create mode 100644 sysdeps/s390/arch-unwind-link.h create mode 100644 sysdeps/sh/arch-unwind-link.h create mode 100644 sysdeps/sparc/arch-unwind-link.h diff --git a/malloc/set-freeres.c b/malloc/set-freeres.c index aa80eb64b8..a80cd301a1 100644 --- a/malloc/set-freeres.c +++ b/malloc/set-freeres.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "../libio/libioP.h" @@ -56,6 +57,10 @@ __libc_freeres (void) if (&__libpthread_freeres != NULL) __libpthread_freeres (); +#ifdef SHARED + __libc_unwind_link_freeres (); +#endif + for (p = symbol_set_first_element (__libc_freeres_ptrs); !symbol_set_end_p (__libc_freeres_ptrs, p); ++p) free (*p); diff --git a/misc/Makefile b/misc/Makefile index e0465980c7..aae52412ef 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -72,7 +72,7 @@ routines := brk sbrk sstk ioctl \ fgetxattr flistxattr fremovexattr fsetxattr getxattr \ listxattr lgetxattr llistxattr lremovexattr lsetxattr \ removexattr setxattr getauxval ifunc-impl-list makedev \ - allocate_once + allocate_once unwind-link generated += tst-error1.mtrace tst-error1-mem.out \ tst-allocate_once.mtrace tst-allocate_once-mem.out diff --git a/misc/Versions b/misc/Versions index e749582369..a9cfe3b912 100644 --- a/misc/Versions +++ b/misc/Versions @@ -169,5 +169,6 @@ libc { __mmap; __munmap; __mprotect; __sched_get_priority_min; __sched_get_priority_max; __libc_allocate_once_slow; + __libc_unwind_link_get; } } diff --git a/misc/unwind-link.c b/misc/unwind-link.c new file mode 100644 index 0000000000..49076f8a59 --- /dev/null +++ b/misc/unwind-link.c @@ -0,0 +1,149 @@ +/* Dynamic loading of the libgcc unwinder. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifdef SHARED + +#include +#include +#include +#include +#include + +/* Statically allocate the object, so that we do not have to deal with + malloc failure. __libc_unwind_link_get must not fail if libgcc_s + has already been loaded by other means. */ +static struct unwind_link global; + +/* dlopen handle. Also used for the double-checked locking idiom. */ +static void *global_libgcc_handle; + +/* We cannot use __libc_once because the pthread_once implementation + may depend on unwinding. */ +__libc_lock_define (static, lock); + +struct unwind_link * +__libc_unwind_link_get (void) +{ + /* Double-checked locking idiom. Synchronizes with the release MO + store at the end of this function. */ + if (atomic_load_acquire (&global_libgcc_handle) != NULL) + return &global; + + /* Initialize a copy of the data, so that we do not need about + unlocking in case the dynamic loader somehow triggers + unwinding. */ + void *local_libgcc_handle = __libc_dlopen (LIBGCC_S_SO); + if (local_libgcc_handle == NULL) + { + __libc_lock_unlock (lock); + return NULL; + } + + struct unwind_link local; + local.ptr__Unwind_Backtrace + = __libc_dlsym (local_libgcc_handle, "_Unwind_Backtrace"); + local.ptr__Unwind_ForcedUnwind + = __libc_dlsym (local_libgcc_handle, "_Unwind_ForcedUnwind"); + local.ptr__Unwind_GetCFA + = __libc_dlsym (local_libgcc_handle, "_Unwind_GetCFA"); +#if UNWIND_LINK_GETIP + local.ptr__Unwind_GetIP + = __libc_dlsym (local_libgcc_handle, "_Unwind_GetIP"); +#endif + local.ptr__Unwind_Resume + = __libc_dlsym (local_libgcc_handle, "_Unwind_Resume"); +#if UNWIND_LINK_FRAME_STATE_FOR + local.ptr___frame_state_for + = __libc_dlsym (local_libgcc_handle, "__frame_state_for"); +#endif + local.ptr_personality + = __libc_dlsym (local_libgcc_handle, "__gcc_personality_v0"); + UNWIND_LINK_EXTRA_INIT + + /* If a symbol is missing, libgcc_s has somehow been corrupted. */ + assert (local.ptr__Unwind_Backtrace != NULL); + assert (local.ptr__Unwind_ForcedUnwind != NULL); + assert (local.ptr__Unwind_GetCFA != NULL); +#if UNWIND_LINK_GETIP + assert (local.ptr__Unwind_GetIP != NULL); +#endif + assert (local.ptr__Unwind_Resume != NULL); + assert (local.ptr_personality != NULL); + +#ifdef PTR_MANGLE + PTR_MANGLE (local.ptr__Unwind_Backtrace); + PTR_MANGLE (local.ptr__Unwind_ForcedUnwind); + PTR_MANGLE (local.ptr__Unwind_GetCFA); +# if UNWIND_LINK_GETIP + PTR_MANGLE (local.ptr__Unwind_GetIP); +# endif + PTR_MANGLE (local.ptr__Unwind_Resume); +# if UNWIND_LINK_FRAME_STATE_FOR + PTR_MANGLE (local.ptr___frame_state_for); +# endif + PTR_MANGLE (local.ptr_personality); +#endif + + __libc_lock_lock (lock); + if (atomic_load_relaxed (&global_libgcc_handle) != NULL) + /* This thread lost the race. Clean up. */ + __libc_dlclose (local_libgcc_handle); + else + { + global = local; + + /* Completes the double-checked locking idiom. */ + atomic_store_release (&global_libgcc_handle, local_libgcc_handle); + } + + __libc_lock_unlock (lock); + return &global; +} +libc_hidden_def (__libc_unwind_link_get) + +void +__libc_unwind_link_after_fork (void) +{ + if (__libc_lock_trylock (lock) == 0) + /* The lock was not acquired during the fork. This covers both + the initialized and uninitialized case. */ + __libc_lock_unlock (lock); + else + { + /* Initialization was in progress in another thread. + Reinitialize the lock. */ + __libc_lock_init (lock); + global_libgcc_handle = NULL; + } +} + +void __libc_freeres_fn_section +__libc_unwind_link_freeres (void) +{ + if (__libc_lock_trylock (lock) == 0) + { + if (global_libgcc_handle != NULL) + { + __libc_dlclose (global_libgcc_handle ); + global_libgcc_handle = NULL; + } + __libc_lock_unlock (lock); + } +} + +#endif /* SHARED */ diff --git a/sysdeps/alpha/arch-unwind-link.h b/sysdeps/alpha/arch-unwind-link.h new file mode 100644 index 0000000000..998e47c949 --- /dev/null +++ b/sysdeps/alpha/arch-unwind-link.h @@ -0,0 +1,27 @@ +/* Dynamic loading of the libgcc unwinder. alpha customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_FRAME_STATE_FOR 1 +#define UNWIND_LINK_EXTRA_FIELDS +#define UNWIND_LINK_EXTRA_INIT + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/arm/arch-unwind-link.h b/sysdeps/arm/arch-unwind-link.h new file mode 100644 index 0000000000..b16a94e02a --- /dev/null +++ b/sysdeps/arm/arch-unwind-link.h @@ -0,0 +1,34 @@ +/* Dynamic loading of the libgcc unwinder. Arm customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +/* On arm, _Unwind_GetIP is a macro. */ +#define UNWIND_LINK_GETIP 0 + +#define UNWIND_LINK_FRAME_STATE_FOR 0 +#define UNWIND_LINK_EXTRA_FIELDS \ + __typeof (_Unwind_VRS_Get) *ptr__Unwind_VRS_Get; +#define UNWIND_LINK_EXTRA_INIT \ + local.ptr__Unwind_VRS_Get \ + = __libc_dlsym (local_libgcc_handle, "_Unwind_VRS_Get"); \ + assert (local.ptr__Unwind_VRS_Get != NULL); \ + PTR_MANGLE (local.ptr__Unwind_VRS_Get); + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/generic/arch-unwind-link.h b/sysdeps/generic/arch-unwind-link.h new file mode 100644 index 0000000000..f63a3f7a7d --- /dev/null +++ b/sysdeps/generic/arch-unwind-link.h @@ -0,0 +1,32 @@ +/* Dynamic loading of the libgcc unwinder. Generic version of parameters. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +/* The _Unwind_GetIP function is supported. */ +#define UNWIND_LINK_GETIP 1 + +/* The __frame_state_for function is needed and re-exported from glibc. */ +#define UNWIND_LINK_FRAME_STATE_FOR 0 + +/* There are no extra fields in struct unwind_link in the generic version. */ +#define UNWIND_LINK_EXTRA_FIELDS +#define UNWIND_LINK_EXTRA_INIT + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/generic/unwind-link.h b/sysdeps/generic/unwind-link.h new file mode 100644 index 0000000000..56488e997d --- /dev/null +++ b/sysdeps/generic/unwind-link.h @@ -0,0 +1,99 @@ +/* Dynamic loading of the libgcc unwinder. Generic version. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _UNWIND_LINK_H +#define _UNWIND_LINK_H + +#include + +#ifdef SHARED + +#include +#include +#include + +#if UNWIND_LINK_FRAME_STATE_FOR +struct frame_state; +#endif + +struct unwind_link +{ + __typeof (_Unwind_Backtrace) *ptr__Unwind_Backtrace; + __typeof (_Unwind_ForcedUnwind) *ptr__Unwind_ForcedUnwind; + __typeof (_Unwind_GetCFA) *ptr__Unwind_GetCFA; +# if UNWIND_LINK_GETIP + __typeof (_Unwind_GetIP) *ptr__Unwind_GetIP; +# endif + __typeof (_Unwind_Resume) *ptr__Unwind_Resume; +#if UNWIND_LINK_FRAME_STATE_FOR + struct frame_state *(*ptr___frame_state_for) (void *, struct frame_state *); +#endif + _Unwind_Reason_Code (*ptr_personality) PERSONALITY_PROTO; + UNWIND_LINK_EXTRA_FIELDS +}; + +/* Return a pointer to the implementation, or NULL on failure. */ +struct unwind_link *__libc_unwind_link_get (void); +libc_hidden_proto (__libc_unwind_link_get) + +/* UNWIND_LINK_PTR returns the stored function pointer NAME from the + cached unwind link OBJ (which was previously returned by + __libc_unwind_link_get). */ +# ifdef PTR_DEMANGLE +# define UNWIND_LINK_PTR(obj, name, ...) \ + ({ \ + __typeof ((obj)->ptr_##name) __unwind_fptr = (obj)->ptr_##name; \ + PTR_DEMANGLE (__unwind_fptr); \ + __unwind_fptr; \ + }) +# else /* !PTR_DEMANGLE */ +# define UNWIND_LINK_PTR(obj, name, ...) ((obj)->ptr_##name) +# endif + +/* Called from fork, in the new subprocess. */ +void __libc_unwind_link_after_fork (void); + +/* Called from __libc_freeres. */ +void __libc_unwind_link_freeres (void) attribute_hidden; + +#else /* !SHARED */ + +/* Dummy implementation so that the code can be shared with the SHARED + version. */ +struct unwind_link; +static inline struct unwind_link * +__libc_unwind_link_get (void) +{ + /* Return something that is not a null pointer, so that error checks + succeed. */ + return (struct unwind_link *) 1; +} + +/* Directly call the static implementation. */ +# define UNWIND_LINK_PTR(obj, name, ...) \ + ((void) (obj), &name) + +static inline void +__libc_unwind_link_after_fork (void) +{ + /* No need to clean up if the unwinder is statically linked. */ +} + +#endif /* !SHARED */ + +#endif /* _UNWIND_LINK_H */ diff --git a/sysdeps/i386/arch-unwind-link.h b/sysdeps/i386/arch-unwind-link.h new file mode 100644 index 0000000000..bc9c3a1f97 --- /dev/null +++ b/sysdeps/i386/arch-unwind-link.h @@ -0,0 +1,38 @@ +/* Dynamic loading of the libgcc unwinder. i386 customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_FRAME_STATE_FOR 1 +#define UNWIND_LINK_EXTRA_FIELDS \ + __typeof (_Unwind_GetGR) *ptr__Unwind_GetGR; +#define UNWIND_LINK_EXTRA_INIT_SHARED \ + local.ptr__Unwind_GetGR \ + = __libc_dlsym (local_libgcc_handle, "_Unwind_GetGR"); \ + assert (local.ptr__Unwind_GetGR != NULL); +#ifdef PTR_MANGLE +# define UNWIND_LINK_EXTRA_INIT \ + UNWIND_LINK_EXTRA_INIT_SHARED \ + PTR_MANGLE (local.ptr__Unwind_GetGR); +#else +# define UNWIND_LINK_EXTRA_INIT UNWIND_LINK_EXTRA_INIT_SHARED +#endif + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/ia64/arch-unwind-link.h b/sysdeps/ia64/arch-unwind-link.h new file mode 100644 index 0000000000..570b711dcd --- /dev/null +++ b/sysdeps/ia64/arch-unwind-link.h @@ -0,0 +1,31 @@ +/* Dynamic loading of the libgcc unwinder. ia64 customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_FRAME_STATE_FOR 1 +#define UNWIND_LINK_EXTRA_FIELDS \ + __typeof (_Unwind_GetBSP) *ptr__Unwind_GetBSP; +#define UNWIND_LINK_EXTRA_INIT \ + local.ptr__Unwind_GetBSP \ + = __libc_dlsym (local_libgcc_handle, "_Unwind_GetBSP"); \ + assert (local.ptr__Unwind_GetBSP != NULL); \ + PTR_MANGLE (local.ptr__Unwind_GetBSP); + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/m68k/arch-unwind-link.h b/sysdeps/m68k/arch-unwind-link.h new file mode 100644 index 0000000000..e0105140ed --- /dev/null +++ b/sysdeps/m68k/arch-unwind-link.h @@ -0,0 +1,34 @@ +/* Dynamic loading of the libgcc unwinder. m68k customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_EXTRA_FIELDS \ + __typeof (_Unwind_GetGR) *ptr__Unwind_GetGR; +#define UNWIND_LINK_EXTRA_INIT \ + local.ptr__Unwind_GetGR \ + = __libc_dlsym (local_libgcc_handle, "_Unwind_GetGR"); \ + assert (local.ptr__Unwind_GetGR != NULL); \ + PTR_MANGLE (local.ptr__Unwind_GetGR); + +/* This is overriden by the m680x0 variant. */ +#define UNWIND_LINK_FRAME_STATE_FOR 0 + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/m68k/m680x0/arch-unwind-link.h b/sysdeps/m68k/m680x0/arch-unwind-link.h new file mode 100644 index 0000000000..1adbf23c79 --- /dev/null +++ b/sysdeps/m68k/m680x0/arch-unwind-link.h @@ -0,0 +1,26 @@ +/* Dynamic loading of the libgcc unwinder. Baseline m68k customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H + +#include + +#undef UNWIND_LINK_FRAME_STATE_FOR +#define UNWIND_LINK_FRAME_STATE_FOR 1 + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c index 32783069ec..1d4819ed53 100644 --- a/sysdeps/mach/hurd/fork.c +++ b/sysdeps/mach/hurd/fork.c @@ -28,6 +28,7 @@ #include "hurdmalloc.h" /* XXX */ #include #include +#include #undef __fork @@ -662,6 +663,8 @@ __fork (void) __sigemptyset (&_hurd_global_sigstate->pending); __sigemptyset (&ss->pending); + __libc_unwind_link_after_fork (); + /* Release malloc locks. */ _hurd_malloc_fork_child (); call_function_static_weak (__malloc_fork_unlock_child); diff --git a/sysdeps/mips/arch-unwind-link.h b/sysdeps/mips/arch-unwind-link.h new file mode 100644 index 0000000000..9835c0f9d6 --- /dev/null +++ b/sysdeps/mips/arch-unwind-link.h @@ -0,0 +1,27 @@ +/* Dynamic loading of the libgcc unwinder. MIPS customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_FRAME_STATE_FOR 1 +#define UNWIND_LINK_EXTRA_FIELDS +#define UNWIND_LINK_EXTRA_INIT + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c index f5cf88d68c..19e8381bb1 100644 --- a/sysdeps/nptl/fork.c +++ b/sysdeps/nptl/fork.c @@ -32,6 +32,7 @@ #include #include #include +#include static void fresetlockfiles (void) @@ -112,6 +113,8 @@ __libc_fork (void) /* Reset the lock state in the multi-threaded case. */ if (multiple_threads) { + __libc_unwind_link_after_fork (); + /* Release malloc locks. */ call_function_static_weak (__malloc_fork_unlock_child); diff --git a/sysdeps/powerpc/powerpc32/arch-unwind-link.h b/sysdeps/powerpc/powerpc32/arch-unwind-link.h new file mode 100644 index 0000000000..6a87daaa88 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/arch-unwind-link.h @@ -0,0 +1,27 @@ +/* Dynamic loading of the libgcc unwinder. powerpc customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_FRAME_STATE_FOR 1 +#define UNWIND_LINK_EXTRA_FIELDS +#define UNWIND_LINK_EXTRA_INIT + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/s390/arch-unwind-link.h b/sysdeps/s390/arch-unwind-link.h new file mode 100644 index 0000000000..c50b7f2f0d --- /dev/null +++ b/sysdeps/s390/arch-unwind-link.h @@ -0,0 +1,27 @@ +/* Dynamic loading of the libgcc unwinder. S/390 customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_FRAME_STATE_FOR 1 +#define UNWIND_LINK_EXTRA_FIELDS +#define UNWIND_LINK_EXTRA_INIT + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/sh/arch-unwind-link.h b/sysdeps/sh/arch-unwind-link.h new file mode 100644 index 0000000000..519c224093 --- /dev/null +++ b/sysdeps/sh/arch-unwind-link.h @@ -0,0 +1,27 @@ +/* Dynamic loading of the libgcc unwinder. SH customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_FRAME_STATE_FOR 1 +#define UNWIND_LINK_EXTRA_FIELDS +#define UNWIND_LINK_EXTRA_INIT + +#endif /* _ARCH_UNWIND_LINK_H */ diff --git a/sysdeps/sparc/arch-unwind-link.h b/sysdeps/sparc/arch-unwind-link.h new file mode 100644 index 0000000000..4b7e2f160d --- /dev/null +++ b/sysdeps/sparc/arch-unwind-link.h @@ -0,0 +1,27 @@ +/* Dynamic loading of the libgcc unwinder. SPARC customization. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _ARCH_UNWIND_LINK_H +#define _ARCH_UNWIND_LINK_H + +#define UNWIND_LINK_GETIP 1 +#define UNWIND_LINK_FRAME_STATE_FOR 1 +#define UNWIND_LINK_EXTRA_FIELDS +#define UNWIND_LINK_EXTRA_INIT + +#endif /* _ARCH_UNWIND_LINK_H */