mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 05:50:14 +00:00
Implement <unwind-link.h> for dynamically loading the libgcc_s unwinder
This will be used to consolidate the libgcc_s access for backtrace and pthread_cancel. Unlike the existing backtrace implementations, it provides some hardening based on pointer mangling. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
parent
764e9a0334
commit
9fc813e1a3
@ -23,7 +23,7 @@
|
|||||||
#include <gnu/lib-names.h>
|
#include <gnu/lib-names.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unwind.h>
|
#include <unwind.h>
|
||||||
#include <unwind-arch.h>
|
#include <unwind-link.h>
|
||||||
|
|
||||||
struct trace_arg
|
struct trace_arg
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <set-hooks.h>
|
#include <set-hooks.h>
|
||||||
#include <libc-internal.h>
|
#include <libc-internal.h>
|
||||||
|
#include <unwind-link.h>
|
||||||
|
|
||||||
#include "../nss/nsswitch.h"
|
#include "../nss/nsswitch.h"
|
||||||
#include "../libio/libioP.h"
|
#include "../libio/libioP.h"
|
||||||
@ -61,6 +62,10 @@ __libc_freeres (void)
|
|||||||
if (&__libpthread_freeres != NULL)
|
if (&__libpthread_freeres != NULL)
|
||||||
__libpthread_freeres ();
|
__libpthread_freeres ();
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
__libc_unwind_link_freeres ();
|
||||||
|
#endif
|
||||||
|
|
||||||
for (p = symbol_set_first_element (__libc_freeres_ptrs);
|
for (p = symbol_set_first_element (__libc_freeres_ptrs);
|
||||||
!symbol_set_end_p (__libc_freeres_ptrs, p); ++p)
|
!symbol_set_end_p (__libc_freeres_ptrs, p); ++p)
|
||||||
free (*p);
|
free (*p);
|
||||||
|
@ -73,7 +73,7 @@ routines := brk sbrk sstk ioctl \
|
|||||||
fgetxattr flistxattr fremovexattr fsetxattr getxattr \
|
fgetxattr flistxattr fremovexattr fsetxattr getxattr \
|
||||||
listxattr lgetxattr llistxattr lremovexattr lsetxattr \
|
listxattr lgetxattr llistxattr lremovexattr lsetxattr \
|
||||||
removexattr setxattr getauxval ifunc-impl-list makedev \
|
removexattr setxattr getauxval ifunc-impl-list makedev \
|
||||||
allocate_once fd_to_filename single_threaded
|
allocate_once fd_to_filename single_threaded unwind-link
|
||||||
|
|
||||||
generated += tst-error1.mtrace tst-error1-mem.out \
|
generated += tst-error1.mtrace tst-error1-mem.out \
|
||||||
tst-allocate_once.mtrace tst-allocate_once-mem.out
|
tst-allocate_once.mtrace tst-allocate_once-mem.out
|
||||||
|
@ -172,5 +172,6 @@ libc {
|
|||||||
__mmap; __munmap; __mprotect;
|
__mmap; __munmap; __mprotect;
|
||||||
__sched_get_priority_min; __sched_get_priority_max;
|
__sched_get_priority_min; __sched_get_priority_max;
|
||||||
__libc_allocate_once_slow;
|
__libc_allocate_once_slow;
|
||||||
|
__libc_unwind_link_get;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
145
misc/unwind-link.c
Normal file
145
misc/unwind-link.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <gnu/lib-names.h>
|
||||||
|
#include <unwind-link.h>
|
||||||
|
#include <libc-lock.h>
|
||||||
|
|
||||||
|
/* 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 (global_libgcc_handle != NULL)
|
||||||
|
{
|
||||||
|
__libc_dlclose (global_libgcc_handle );
|
||||||
|
global_libgcc_handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SHARED */
|
28
sysdeps/alpha/unwind-arch.h
Normal file
28
sysdeps/alpha/unwind-arch.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. alpha customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#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_FRAME_ADJUSTMENT 0
|
||||||
|
#define UNWIND_LINK_EXTRA_FIELDS
|
||||||
|
#define UNWIND_LINK_EXTRA_INIT
|
||||||
|
|
||||||
|
#endif /* _ARCH_UNWIND_LINK_H */
|
35
sysdeps/arm/unwind-arch.h
Normal file
35
sysdeps/arm/unwind-arch.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. Arm customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#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_FRAME_ADJUSTMENT 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 */
|
@ -1,5 +1,5 @@
|
|||||||
/* Return backtrace of current program state. Arch-specific bits.
|
/* Dynamic loading of the libgcc unwinder. Generic version of parameters.
|
||||||
Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -16,15 +16,20 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<https://www.gnu.org/licenses/>. */
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#ifndef _UNWIND_ARCH_H
|
#ifndef _ARCH_UNWIND_LINK_H
|
||||||
#define _UNWIND_ARCH_H
|
#define _ARCH_UNWIND_LINK_H
|
||||||
|
|
||||||
#include <unwind.h>
|
/* The _Unwind_GetIP function is supported. */
|
||||||
|
#define UNWIND_LINK_GETIP 1
|
||||||
|
|
||||||
static inline void *
|
/* The __frame_state_for function is needed and re-exported from glibc. */
|
||||||
unwind_arch_adjustment (void *prev, void *addr)
|
#define UNWIND_LINK_FRAME_STATE_FOR 0
|
||||||
{
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
/* No adjustment of the is needed. */
|
||||||
|
#define UNWIND_LINK_FRAME_ADJUSTMENT 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 */
|
||||||
|
106
sysdeps/generic/unwind-link.h
Normal file
106
sysdeps/generic/unwind-link.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. Generic version.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef _UNWIND_LINK_H
|
||||||
|
#define _UNWIND_LINK_H
|
||||||
|
|
||||||
|
#include <unwind.h>
|
||||||
|
#include <unwind-arch.h>
|
||||||
|
|
||||||
|
#if !UNWIND_LINK_FRAME_ADJUSTMENT
|
||||||
|
static inline void *
|
||||||
|
unwind_arch_adjustment (void *prev, void *addr)
|
||||||
|
{
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
# include <sysdep.h>
|
||||||
|
# include <unwind-resume.h>
|
||||||
|
|
||||||
|
# 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 */
|
39
sysdeps/i386/unwind-arch.h
Normal file
39
sysdeps/i386/unwind-arch.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. i386 customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#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_FRAME_ADJUSTMENT 0
|
||||||
|
#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 */
|
32
sysdeps/ia64/unwind-arch.h
Normal file
32
sysdeps/ia64/unwind-arch.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. ia64 customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef _ARCH_UNWIND_LINK_H
|
||||||
|
|
||||||
|
#define UNWIND_LINK_GETIP 1
|
||||||
|
#define UNWIND_LINK_FRAME_STATE_FOR 1
|
||||||
|
#define UNWIND_LINK_FRAME_ADJUSTMENT 0
|
||||||
|
#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 */
|
26
sysdeps/m68k/m680x0/unwind-arch.h
Normal file
26
sysdeps/m68k/m680x0/unwind-arch.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. Baseline m68k customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef _ARCH_UNWIND_LINK_H
|
||||||
|
|
||||||
|
#include <sysdeps/m68k/unwind-arch.h>
|
||||||
|
|
||||||
|
#undef UNWIND_LINK_FRAME_STATE_FOR
|
||||||
|
#define UNWIND_LINK_FRAME_STATE_FOR 1
|
||||||
|
|
||||||
|
#endif /* _ARCH_UNWIND_LINK_H */
|
35
sysdeps/m68k/unwind-arch.h
Normal file
35
sysdeps/m68k/unwind-arch.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. m68k customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef _ARCH_UNWIND_LINK_H
|
||||||
|
#define _ARCH_UNWIND_LINK_H
|
||||||
|
|
||||||
|
#define UNWIND_LINK_GETIP 1
|
||||||
|
#define UNWIND_LINK_FRAME_ADJUSTMENT 0
|
||||||
|
#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 */
|
@ -29,6 +29,7 @@
|
|||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#include <malloc/malloc-internal.h>
|
#include <malloc/malloc-internal.h>
|
||||||
#include <nss/nss_database.h>
|
#include <nss/nss_database.h>
|
||||||
|
#include <unwind-link.h>
|
||||||
|
|
||||||
#undef __fork
|
#undef __fork
|
||||||
|
|
||||||
@ -667,6 +668,8 @@ __fork (void)
|
|||||||
__sigemptyset (&_hurd_global_sigstate->pending);
|
__sigemptyset (&_hurd_global_sigstate->pending);
|
||||||
__sigemptyset (&ss->pending);
|
__sigemptyset (&ss->pending);
|
||||||
|
|
||||||
|
__libc_unwind_link_after_fork ();
|
||||||
|
|
||||||
/* Release malloc locks. */
|
/* Release malloc locks. */
|
||||||
_hurd_malloc_fork_child ();
|
_hurd_malloc_fork_child ();
|
||||||
call_function_static_weak (__malloc_fork_unlock_child);
|
call_function_static_weak (__malloc_fork_unlock_child);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Return backtrace of current program state. Arch-specific bits.
|
/* Dynamic loading of the libgcc unwinder. MIPS customization.
|
||||||
Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
@ -16,10 +16,17 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<https://www.gnu.org/licenses/>. */
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#ifndef _UNWIND_ARCH_H
|
#ifndef _ARCH_UNWIND_LINK_H
|
||||||
#define _UNWIND_ARCH_H
|
#define _ARCH_UNWIND_LINK_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#define UNWIND_LINK_GETIP 1
|
||||||
|
#define UNWIND_LINK_FRAME_STATE_FOR 1
|
||||||
|
#define UNWIND_LINK_FRAME_ADJUSTMENT 1
|
||||||
|
#define UNWIND_LINK_EXTRA_FIELDS
|
||||||
|
#define UNWIND_LINK_EXTRA_INIT
|
||||||
|
|
||||||
/* MIPS fallback code handle a frame where its FDE can not be obtained
|
/* MIPS fallback code handle a frame where its FDE can not be obtained
|
||||||
(for instance a signal frame) by reading the kernel allocated signal frame
|
(for instance a signal frame) by reading the kernel allocated signal frame
|
||||||
@ -49,7 +56,7 @@ unwind_arch_adjustment (void *prev, void *addr)
|
|||||||
|
|
||||||
24021061 li v0, 0x1061 (rt_sigreturn)
|
24021061 li v0, 0x1061 (rt_sigreturn)
|
||||||
0000000c syscall
|
0000000c syscall
|
||||||
or
|
or
|
||||||
24021017 li v0, 0x1017 (sigreturn)
|
24021017 li v0, 0x1017 (sigreturn)
|
||||||
0000000c syscall */
|
0000000c syscall */
|
||||||
if (pc[1] != 0x0000000c)
|
if (pc[1] != 0x0000000c)
|
||||||
@ -64,4 +71,4 @@ unwind_arch_adjustment (void *prev, void *addr)
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* _ARCH_UNWIND_LINK_H */
|
@ -33,6 +33,7 @@
|
|||||||
#include <futex-internal.h>
|
#include <futex-internal.h>
|
||||||
#include <malloc/malloc-internal.h>
|
#include <malloc/malloc-internal.h>
|
||||||
#include <nss/nss_database.h>
|
#include <nss/nss_database.h>
|
||||||
|
#include <unwind-link.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fresetlockfiles (void)
|
fresetlockfiles (void)
|
||||||
@ -116,6 +117,8 @@ __libc_fork (void)
|
|||||||
/* Reset the lock state in the multi-threaded case. */
|
/* Reset the lock state in the multi-threaded case. */
|
||||||
if (multiple_threads)
|
if (multiple_threads)
|
||||||
{
|
{
|
||||||
|
__libc_unwind_link_after_fork ();
|
||||||
|
|
||||||
/* Release malloc locks. */
|
/* Release malloc locks. */
|
||||||
call_function_static_weak (__malloc_fork_unlock_child);
|
call_function_static_weak (__malloc_fork_unlock_child);
|
||||||
|
|
||||||
|
28
sysdeps/powerpc/powerpc32/unwind-arch.h
Normal file
28
sysdeps/powerpc/powerpc32/unwind-arch.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. powerpc customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#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_FRAME_ADJUSTMENT 0
|
||||||
|
#define UNWIND_LINK_EXTRA_FIELDS
|
||||||
|
#define UNWIND_LINK_EXTRA_INIT
|
||||||
|
|
||||||
|
#endif /* _ARCH_UNWIND_LINK_H */
|
28
sysdeps/s390/unwind-arch.h
Normal file
28
sysdeps/s390/unwind-arch.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. S/390 customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#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_FRAME_ADJUSTMENT 0
|
||||||
|
#define UNWIND_LINK_EXTRA_FIELDS
|
||||||
|
#define UNWIND_LINK_EXTRA_INIT
|
||||||
|
|
||||||
|
#endif /* _ARCH_UNWIND_LINK_H */
|
28
sysdeps/sh/unwind-arch.h
Normal file
28
sysdeps/sh/unwind-arch.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. SH customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#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_FRAME_ADJUSTMENT 0
|
||||||
|
#define UNWIND_LINK_EXTRA_FIELDS
|
||||||
|
#define UNWIND_LINK_EXTRA_INIT
|
||||||
|
|
||||||
|
#endif /* _ARCH_UNWIND_LINK_H */
|
28
sysdeps/sparc/unwind-arch.h
Normal file
28
sysdeps/sparc/unwind-arch.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* Dynamic loading of the libgcc unwinder. SPARC customization.
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#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_FRAME_ADJUSTMENT 0
|
||||||
|
#define UNWIND_LINK_EXTRA_FIELDS
|
||||||
|
#define UNWIND_LINK_EXTRA_INIT
|
||||||
|
|
||||||
|
#endif /* _ARCH_UNWIND_LINK_H */
|
Loading…
Reference in New Issue
Block a user