From 9d79e0377b08773ec4f7ec38479b1563606f7ef7 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 22 Jul 2003 23:56:53 +0000 Subject: Update. * include/stdio.h (__libc_fatal): Add libc_hidden_proto. * include/dlfcn.h (__libc_dlopen_mode, __libc_dlsym, __libc_dlclose): Likewise. * elf/dl-libc.c (__libc_dlopen_mode, __libc_dlsym, __libc_dlclose): Add libc_hidden_def. * sysdeps/generic/libc_fatal.c (__libc_fatal): Likewise. * sysdeps/posix/libc_fatal.c (__libc_fatal): Likewise. * sysdeps/unix/sysv/linux/libc_fatal.c (__libc_fatal): Likewise. * elf/Versions (libc): Export __libc_dlopen_mode@@GLIBC_PRIVATE, __libc_dlsym@@GLIBC_PRIVATE and __libc_dlclose@@GLIBC_PRIVATE. * libio/Versions (libc): Export __libc_fatal@@GLIBC_PRIVATE. * sysdeps/generic/unwind-dw2.c: Readd #ifs removed during last change. * sysdeps/generic/unwind.inc: Removed. --- ChangeLog | 15 ++ elf/Versions | 1 + elf/dl-libc.c | 3 + include/dlfcn.h | 3 + include/stdio.h | 1 + libio/Versions | 4 + linuxthreads/ChangeLog | 19 ++ nptl/ChangeLog | 18 ++ nptl/Makefile | 5 +- nptl/pthreadP.h | 3 + nptl/pthread_cancel.c | 3 + nptl/sysdeps/pthread/Makefile | 7 +- nptl/sysdeps/pthread/createthread.c | 6 +- nptl/sysdeps/pthread/rt-unwind-resume.c | 1 + nptl/sysdeps/pthread/unwind-resume.c | 64 +++++++ nptl/unwind-forcedunwind.c | 93 ++++++++++ sysdeps/generic/libc_fatal.c | 3 +- sysdeps/generic/unwind-dw2.c | 9 +- sysdeps/generic/unwind.inc | 309 -------------------------------- sysdeps/posix/libc_fatal.c | 1 + sysdeps/unix/sysv/linux/libc_fatal.c | 1 + 21 files changed, 251 insertions(+), 318 deletions(-) create mode 100644 nptl/sysdeps/pthread/rt-unwind-resume.c create mode 100644 nptl/sysdeps/pthread/unwind-resume.c create mode 100644 nptl/unwind-forcedunwind.c delete mode 100644 sysdeps/generic/unwind.inc diff --git a/ChangeLog b/ChangeLog index 5d37f12141..e7d3dcb6fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2003-07-22 Jakub Jelinek + * include/stdio.h (__libc_fatal): Add libc_hidden_proto. + * include/dlfcn.h (__libc_dlopen_mode, __libc_dlsym, __libc_dlclose): + Likewise. + * elf/dl-libc.c (__libc_dlopen_mode, __libc_dlsym, __libc_dlclose): + Add libc_hidden_def. + * sysdeps/generic/libc_fatal.c (__libc_fatal): Likewise. + * sysdeps/posix/libc_fatal.c (__libc_fatal): Likewise. + * sysdeps/unix/sysv/linux/libc_fatal.c (__libc_fatal): Likewise. + * elf/Versions (libc): Export __libc_dlopen_mode@@GLIBC_PRIVATE, + __libc_dlsym@@GLIBC_PRIVATE and __libc_dlclose@@GLIBC_PRIVATE. + * libio/Versions (libc): Export __libc_fatal@@GLIBC_PRIVATE. + * sysdeps/generic/unwind-dw2.c: Readd #ifs removed during last + change. + * sysdeps/generic/unwind.inc: Removed. + * include/resolv.h (__resp): Declare. Define to __libc_resp if in libc.so. (_res): If USE___THREAD, define to (*__resp). diff --git a/elf/Versions b/elf/Versions index 1b8e9baf6f..7b0799958b 100644 --- a/elf/Versions +++ b/elf/Versions @@ -22,6 +22,7 @@ libc { _dl_open; _dl_close; _dl_addr; _dl_sym; _dl_vsym; _dl_open_hook; + __libc_dlopen_mode; __libc_dlsym; __libc_dlclose; } } diff --git a/elf/dl-libc.c b/elf/dl-libc.c index 8fd98f08e7..557d2c3241 100644 --- a/elf/dl-libc.c +++ b/elf/dl-libc.c @@ -173,6 +173,7 @@ __libc_dlopen_mode (const char *name, int mode) return (void *) args.map; #endif } +libc_hidden_def (__libc_dlopen_mode) void * __libc_dlsym (void *map, const char *name) @@ -188,6 +189,7 @@ __libc_dlsym (void *map, const char *name) return (dlerror_run (do_dlsym, &args) ? NULL : (void *) (DL_SYMBOL_ADDRESS (args.loadbase, args.ref))); } +libc_hidden_def (__libc_dlsym) int __libc_dlclose (void *map) @@ -198,6 +200,7 @@ __libc_dlclose (void *map) #endif return dlerror_run (do_dlclose, map); } +libc_hidden_def (__libc_dlclose) libc_freeres_fn (free_mem) diff --git a/include/dlfcn.h b/include/dlfcn.h index f0af0fc0f1..31231cb282 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -14,6 +14,9 @@ extern void *__dlvsym (void *__handle, __const char *__name, extern void *__libc_dlopen_mode (__const char *__name, int __mode); extern void *__libc_dlsym (void *__map, __const char *__name); extern int __libc_dlclose (void *__map); +libc_hidden_proto (__libc_dlopen_mode) +libc_hidden_proto (__libc_dlsym) +libc_hidden_proto (__libc_dlclose) /* Locate shared object containing the given address. */ #ifdef ElfW diff --git a/include/stdio.h b/include/stdio.h index 63e49f0969..c46c7cd5f6 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -108,6 +108,7 @@ libc_hidden_proto (fwrite_unlocked) libc_hidden_proto (fgets_unlocked) libc_hidden_proto (fputs_unlocked) libc_hidden_proto (open_memstream) +libc_hidden_proto (__libc_fatal) # endif diff --git a/libio/Versions b/libio/Versions index ea043064ff..c870494872 100644 --- a/libio/Versions +++ b/libio/Versions @@ -145,4 +145,8 @@ libc { # w* wprintf; wscanf; } + GLIBC_PRIVATE { + # Used by NPTL and librt + __libc_fatal; + } } diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 128cb1f8ad..9a495170b7 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,22 @@ +2003-07-22 Jakub Jelinek + + * descr.h (struct _pthread_descr_struct): Provide p_res member + even if USE_TLS && HAVE___THREAD. + * sysdeps/pthread/res-state.c (__res_state): Return __resp + if USE___THREAD. + * manager.c: Include resolv.h. + (pthread_start_thread): Initialize __resp. + * libc-tls-loc.c (__res_state): Return __resp. + * Makefile (tests): Add tst-_res1. + (modules-names, extra-objs, test-extras, test-modules): Add support + for test modules. + ($(objpfx)tst-_res1mod2.so): Depend on $(objpfx)tst-_res1mod1.so. + ($(objpfx)tst-_res1): Depend on $(objpfx)tst-_res1mod2.so and + -lpthread. + * tst-_res1.c: New test. + * tst-_res1mod1.c: New test. + * tst-_res1mod2.c: New test. + 2003-07-20 Ulrich Drepper * sysdeps/pthread/bits/libc-lock.h: Define __libc_cleanup_push and diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 8d36515b7c..00f9062f1f 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,23 @@ 2003-07-22 Jakub Jelinek + * sysdeps/pthread/unwind-resume.c: New file. + * sysdeps/pthread/Makefile (routines, shared-only-routines): Add + unwind-resume in csu subdir. + (CFLAGS-unwind-resume.c, CFLAGS-rt-unwind-resume.c): Compile with + exceptions. + (librt-sysdep_routines, librt-shared-only-routines): Add + rt-unwind-resume. + * sysdeps/pthread/rt-unwind-resume.c: New file. + * unwind-forcedunwind.c: New file. + * Makefile (libpthread-routines): Add unwind-forcedunwind. + (libpthread-shared-only-routines): Likewise. + (CFLAGS-unwind-forcedunwind.c): Compile with exceptions. + * pthreadP.h (pthread_cancel_init): New prototype. + * pthread_cancel.c (pthread_cancel): Call pthread_cancel_init. + + * sysdeps/pthread/createthread.c (do_thread, create_thread): Make + attr argument const struct pthread_attr *. + * res.c (__res_state): Return __resp. * descr.h: Include resolv.h. (struct pthread): Add res field. diff --git a/nptl/Makefile b/nptl/Makefile index 6cf30c440f..f40ec8d554 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -118,9 +118,9 @@ libpthread-routines = init events version \ pthread_kill_other_threads \ pthread_getaffinity pthread_setaffinity \ pthread_attr_getaffinity pthread_attr_setaffinity \ - cleanup_routine + cleanup_routine unwind-forcedunwind -libpthread-shared-only-routines = version pt-allocrtsig +libpthread-shared-only-routines = version pt-allocrtsig unwind-forcedunwind libpthread-static-only-routines = pthread_atfork libpthread-nonshared = pthread_atfork @@ -135,6 +135,7 @@ CFLAGS-pthread_atfork.c = -DNOT_IN_libc CFLAGS-init.c = -fexceptions -fasynchronous-unwind-tables # The unwind code itself, CFLAGS-unwind.c = -fexceptions +CFLAGS-unwind-forcedunwind.c = -fexceptions -fasynchronous-unwind-tables # The following three functions must be async-cancel safe. CFLAGS-pthread_cancel.c = -fexceptions -fasynchronous-unwind-tables diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 30983216c8..a8cefabc4c 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -129,6 +129,9 @@ hidden_proto (__pthread_unwind) hidden_proto (__pthread_unwind_next) hidden_proto (__pthread_register_cancel) hidden_proto (__pthread_unregister_cancel) +# ifdef SHARED +extern void attribute_hidden pthread_cancel_init (void); +# endif #endif diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c index 9e3dfda6b3..1523da82aa 100644 --- a/nptl/pthread_cancel.c +++ b/nptl/pthread_cancel.c @@ -36,6 +36,9 @@ pthread_cancel (th) /* Not a valid thread handle. */ return ESRCH; +#ifdef SHARED + pthread_cancel_init (); +#endif int result = 0; int oldval; int newval; diff --git a/nptl/sysdeps/pthread/Makefile b/nptl/sysdeps/pthread/Makefile index 58cfbb38ef..aac94065eb 100644 --- a/nptl/sysdeps/pthread/Makefile +++ b/nptl/sysdeps/pthread/Makefile @@ -19,6 +19,9 @@ ifeq ($(subdir),csu) CFLAGS-libc-start.c += -I../nptl +routines += unwind-resume +shared-only-routines += unwind-resume +CFLAGS-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables endif ifeq ($(subdir),nptl) @@ -26,9 +29,11 @@ libpthread-sysdep_routines += errno-loc endif ifeq ($(subdir),rt) -librt-sysdep_routines += timer_routines librt-cancellation +librt-sysdep_routines += timer_routines librt-cancellation rt-unwind-resume +librt-shared-only-routines += rt-unwind-resume CPPFLAGS-timer_routines.c = -I../nptl CFLAGS-librt-cancellation.c += -fexceptions -fasynchronous-unwind-tables +CFLAGS-rt-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables ifeq (yes,$(build-shared)) $(objpfx)tst-timer: $(objpfx)librt.so $(shared-thread-library) diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c index 6e8f5cda90..5aa0d89f90 100644 --- a/nptl/sysdeps/pthread/createthread.c +++ b/nptl/sysdeps/pthread/createthread.c @@ -48,8 +48,8 @@ int *__libc_multiple_threads_ptr attribute_hidden; static int -do_clone (struct pthread *pd, struct pthread_attr *attr, int clone_flags, - int (*fct) (void *), STACK_VARIABLES_PARMS) +do_clone (struct pthread *pd, const struct pthread_attr *attr, + int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS) { #ifdef PREPARE_CREATE PREPARE_CREATE; @@ -121,7 +121,7 @@ do_clone (struct pthread *pd, struct pthread_attr *attr, int clone_flags, static int -create_thread (struct pthread *pd, struct pthread_attr *attr, +create_thread (struct pthread *pd, const struct pthread_attr *attr, STACK_VARIABLES_PARMS) { #ifdef TLS_TCB_AT_TP diff --git a/nptl/sysdeps/pthread/rt-unwind-resume.c b/nptl/sysdeps/pthread/rt-unwind-resume.c new file mode 100644 index 0000000000..743e675d4d --- /dev/null +++ b/nptl/sysdeps/pthread/rt-unwind-resume.c @@ -0,0 +1 @@ +#include diff --git a/nptl/sysdeps/pthread/unwind-resume.c b/nptl/sysdeps/pthread/unwind-resume.c new file mode 100644 index 0000000000..088f4c6f6c --- /dev/null +++ b/nptl/sysdeps/pthread/unwind-resume.c @@ -0,0 +1,64 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek . + + 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include + +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 *); + +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; +} + +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) +{ + if (__builtin_expect (libgcc_s_personality == NULL, 0)) + init (); + return libgcc_s_personality (version, actions, exception_class, + ue_header, context); +} diff --git a/nptl/unwind-forcedunwind.c b/nptl/unwind-forcedunwind.c new file mode 100644 index 0000000000..9c10932a31 --- /dev/null +++ b/nptl/unwind-forcedunwind.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek . + + 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, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include + +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 *); +static _Unwind_Reason_Code (*libgcc_s_forcedunwind) + (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); +static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *); + +void +pthread_cancel_init (void) +{ + void *resume, *personality, *forcedunwind, *getcfa; + void *handle; + + if (__builtin_expect (libgcc_s_getcfa != NULL, 1)) + 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) + __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; +} + +void +_Unwind_Resume (struct _Unwind_Exception *exc) +{ + if (__builtin_expect (libgcc_s_resume == NULL, 0)) + pthread_cancel_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) +{ + if (__builtin_expect (libgcc_s_personality == NULL, 0)) + pthread_cancel_init (); + return libgcc_s_personality (version, actions, exception_class, + 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/sysdeps/generic/libc_fatal.c b/sysdeps/generic/libc_fatal.c index a6632391e5..be23849829 100644 --- a/sysdeps/generic/libc_fatal.c +++ b/sysdeps/generic/libc_fatal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 1997, 2003 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 @@ -28,3 +28,4 @@ __libc_fatal (message) abort (); } +libc_hidden_def (__libc_fatal) diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c index 89f9d59f23..2e013cb2e1 100644 --- a/sysdeps/generic/unwind-dw2.c +++ b/sysdeps/generic/unwind-dw2.c @@ -72,8 +72,10 @@ struct _Unwind_Context _Unwind_Word args_size; }; +#ifndef _LIBC /* Byte size of every register managed by these routines. */ static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS]; +#endif /* The result of interpreting the frame unwind info for a frame. @@ -321,7 +323,7 @@ extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context, return ret ? ret : p; } - +#ifndef _LIBC /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL onto the stack to start. */ @@ -721,7 +723,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end, abort (); return stack[stack_elt]; } - +#endif /* Decode DWARF 2 call frame information. Takes pointers the instruction sequence to decode, current register information and @@ -1059,6 +1061,8 @@ __frame_state_for (void *pc_target, struct frame_state *state_in) return state_in; } +#ifndef _LIBC + static void uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) { @@ -1282,4 +1286,5 @@ uw_identify_context (struct _Unwind_Context *context) #include "unwind.inc" +#endif /* _LIBC */ #endif /* !USING_SJLJ_EXCEPTIONS */ diff --git a/sysdeps/generic/unwind.inc b/sysdeps/generic/unwind.inc deleted file mode 100644 index 7ec65e903b..0000000000 --- a/sysdeps/generic/unwind.inc +++ /dev/null @@ -1,309 +0,0 @@ -/* Exception handling and frame unwind runtime interface routines. -*- C -*- - Copyright (C) 2001 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - GCC 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 General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING. If not, write to the Free - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This is derived from the C++ ABI for IA-64. Where we diverge - for cross-architecture compatibility are noted with "@@@". - This file is included from unwind-dw2.c or unwind-ia64.c. */ - -/* Subroutine of _Unwind_RaiseException also invoked from _Unwind_Resume. - - Unwind the stack calling the personality routine to find both the - exception handler and intermediary cleanup code. We'll only locate - the first such frame here. Cleanup code will call back into - _Unwind_Resume and we'll continue Phase 2 there. */ - -static _Unwind_Reason_Code -_Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc, - struct _Unwind_Context *context) -{ - _Unwind_Reason_Code code; - - while (1) - { - _Unwind_FrameState fs; - int match_handler; - - code = uw_frame_state_for (context, &fs); - - /* Identify when we've reached the designated handler context. */ - match_handler = (uw_identify_context (context) == exc->private_2 - ? _UA_HANDLER_FRAME : 0); - - if (code != _URC_NO_REASON) - /* Some error encountered. Usually the unwinder doesn't - diagnose these and merely crashes. */ - return _URC_FATAL_PHASE2_ERROR; - - /* Unwind successful. Run the personality routine, if any. */ - if (fs.personality) - { - code = (*fs.personality) (1, _UA_CLEANUP_PHASE | match_handler, - exc->exception_class, exc, context); - if (code == _URC_INSTALL_CONTEXT) - break; - if (code != _URC_CONTINUE_UNWIND) - return _URC_FATAL_PHASE2_ERROR; - } - - /* Don't let us unwind past the handler context. */ - if (match_handler) - abort (); - - uw_update_context (context, &fs); - } - - return code; -} - -/* Raise an exception, passing along the given exception object. */ -#ifndef _LIBC -_Unwind_Reason_Code -_Unwind_RaiseException(struct _Unwind_Exception *exc) -{ - struct _Unwind_Context this_context, cur_context; - _Unwind_Reason_Code code; - - /* Set up this_context to describe the current stack frame. */ - uw_init_context (&this_context); - cur_context = this_context; - - /* Phase 1: Search. Unwind the stack, calling the personality routine - with the _UA_SEARCH_PHASE flag set. Do not modify the stack yet. */ - while (1) - { - _Unwind_FrameState fs; - - /* Set up fs to describe the FDE for the caller of cur_context. The - first time through the loop, that means __cxa_throw. */ - code = uw_frame_state_for (&cur_context, &fs); - - if (code == _URC_END_OF_STACK) - /* Hit end of stack with no handler found. */ - return _URC_END_OF_STACK; - - if (code != _URC_NO_REASON) - /* Some error encountered. Ususally the unwinder doesn't - diagnose these and merely crashes. */ - return _URC_FATAL_PHASE1_ERROR; - - /* Unwind successful. Run the personality routine, if any. */ - if (fs.personality) - { - code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class, - exc, &cur_context); - if (code == _URC_HANDLER_FOUND) - break; - else if (code != _URC_CONTINUE_UNWIND) - return _URC_FATAL_PHASE1_ERROR; - } - - /* Update cur_context to describe the same frame as fs. */ - uw_update_context (&cur_context, &fs); - } - - /* Indicate to _Unwind_Resume and associated subroutines that this - is not a forced unwind. Further, note where we found a handler. */ - exc->private_1 = 0; - exc->private_2 = uw_identify_context (&cur_context); - - cur_context = this_context; - code = _Unwind_RaiseException_Phase2 (exc, &cur_context); - if (code != _URC_INSTALL_CONTEXT) - return code; - - uw_install_context (&this_context, &cur_context); -} -#endif - - -/* Subroutine of _Unwind_ForcedUnwind also invoked from _Unwind_Resume. */ - -static _Unwind_Reason_Code -_Unwind_ForcedUnwind_Phase2(struct _Unwind_Exception *exc, - struct _Unwind_Context *context) -{ - _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1; - void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2; - _Unwind_Reason_Code code, stop_code; - - while (1) - { - _Unwind_FrameState fs; - int action; - - /* Set up fs to describe the FDE for the caller of cur_context. */ - code = uw_frame_state_for (context, &fs); - if (code != _URC_NO_REASON && code != _URC_END_OF_STACK) - return _URC_FATAL_PHASE2_ERROR; - - /* Unwind successful. */ - action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE; - if (code == _URC_END_OF_STACK) - action |= _UA_END_OF_STACK; - stop_code = (*stop) (1, action, exc->exception_class, exc, - context, stop_argument); - if (stop_code != _URC_NO_REASON) - return _URC_FATAL_PHASE2_ERROR; - - /* Stop didn't want to do anything. Invoke the personality - handler, if applicable, to run cleanups. */ - if (code == _URC_END_OF_STACK) - break; - - if (fs.personality) - { - code = (*fs.personality) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE, - exc->exception_class, exc, context); - if (code == _URC_INSTALL_CONTEXT) - break; - if (code != _URC_CONTINUE_UNWIND) - return _URC_FATAL_PHASE2_ERROR; - } - - /* Update cur_context to describe the same frame as fs. */ - uw_update_context (context, &fs); - } - - return code; -} - - -/* Raise an exception for forced unwinding. */ -#ifndef _LIBC -_Unwind_Reason_Code -_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, - _Unwind_Stop_Fn stop, void * stop_argument) -{ - struct _Unwind_Context this_context, cur_context; - _Unwind_Reason_Code code; - - uw_init_context (&this_context); - cur_context = this_context; - - exc->private_1 = (_Unwind_Ptr) stop; - exc->private_2 = (_Unwind_Ptr) stop_argument; - - code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context); - if (code != _URC_INSTALL_CONTEXT) - return code; - - uw_install_context (&this_context, &cur_context); -} -#endif - - -/* Resume propagation of an existing exception. This is used after - e.g. executing cleanup code, and not to implement rethrowing. */ - -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{ - struct _Unwind_Context this_context, cur_context; - _Unwind_Reason_Code code; - - uw_init_context (&this_context); - cur_context = this_context; - - /* Choose between continuing to process _Unwind_RaiseException - or _Unwind_ForcedUnwind. */ - if (exc->private_1 == 0) - code = _Unwind_RaiseException_Phase2 (exc, &cur_context); - else - code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context); - - if (code != _URC_INSTALL_CONTEXT) - abort (); - - uw_install_context (&this_context, &cur_context); -} - - -/* Resume propagation of an FORCE_UNWIND exception, or to rethrow - a normal exception that was handled. */ -#ifndef _LIBC -_Unwind_Reason_Code -_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc) -{ - struct _Unwind_Context this_context, cur_context; - _Unwind_Reason_Code code; - - /* Choose between continuing to process _Unwind_RaiseException - or _Unwind_ForcedUnwind. */ - if (exc->private_1 == 0) - return _Unwind_RaiseException (exc); - - uw_init_context (&this_context); - cur_context = this_context; - - code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context); - - if (code != _URC_INSTALL_CONTEXT) - abort (); - - uw_install_context (&this_context, &cur_context); -} -#endif - - -/* A convenience function that calls the exception_cleanup field. */ -#ifndef _LIBC -void -_Unwind_DeleteException (struct _Unwind_Exception *exc) -{ - if (exc->exception_cleanup) - (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc); -} -#endif - - -/* Perform stack backtrace through unwind data. */ -#ifndef _LIBC -_Unwind_Reason_Code -_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument) -{ - struct _Unwind_Context context; - _Unwind_Reason_Code code; - - uw_init_context (&context); - - while (1) - { - _Unwind_FrameState fs; - - /* Set up fs to describe the FDE for the caller of context. */ - code = uw_frame_state_for (&context, &fs); - if (code != _URC_NO_REASON && code != _URC_END_OF_STACK) - return _URC_FATAL_PHASE1_ERROR; - - /* Call trace function. */ - if ((*trace) (&context, trace_argument) != _URC_NO_REASON) - return _URC_FATAL_PHASE1_ERROR; - - /* We're done at end of stack. */ - if (code == _URC_END_OF_STACK) - break; - - /* Update context to describe the same frame as fs. */ - uw_update_context (&context, &fs); - } - - return code; -} -#endif diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c index e240afa5a7..7e45174708 100644 --- a/sysdeps/posix/libc_fatal.c +++ b/sysdeps/posix/libc_fatal.c @@ -56,3 +56,4 @@ __libc_fatal (message) abort (); } +libc_hidden_def (__libc_fatal) diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c index bb4d61a836..46347bb20e 100644 --- a/sysdeps/unix/sysv/linux/libc_fatal.c +++ b/sysdeps/unix/sysv/linux/libc_fatal.c @@ -57,3 +57,4 @@ __libc_fatal (message) /* Try for ever and ever. */ ABORT_INSTRUCTION; } +libc_hidden_def (__libc_fatal) -- cgit 1.4.1