* 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.
This commit is contained in:
Ulrich Drepper 2003-07-22 23:56:53 +00:00
parent 0e9d624072
commit 9d79e0377b
21 changed files with 251 additions and 318 deletions

View file

@ -1,5 +1,20 @@
2003-07-22 Jakub Jelinek <jakub@redhat.com>
* 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).

View file

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

View file

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

View file

@ -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

View file

@ -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

View file

@ -145,4 +145,8 @@ libc {
# w*
wprintf; wscanf;
}
GLIBC_PRIVATE {
# Used by NPTL and librt
__libc_fatal;
}
}

View file

@ -1,3 +1,22 @@
2003-07-22 Jakub Jelinek <jakub@redhat.com>
* 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 <drepper@redhat.com>
* sysdeps/pthread/bits/libc-lock.h: Define __libc_cleanup_push and

View file

@ -1,5 +1,23 @@
2003-07-22 Jakub Jelinek <jakub@redhat.com>
* 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.

View file

@ -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

View file

@ -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

View file

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

View file

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

View file

@ -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

View file

@ -0,0 +1 @@
#include <unwind-resume.c>

View file

@ -0,0 +1,64 @@
/* 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,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <dlfcn.h>
#include <stdio.h>
#include <unwind.h>
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);
}

View file

@ -0,0 +1,93 @@
/* 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,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <dlfcn.h>
#include <stdio.h>
#include <unwind.h>
#include <pthreadP.h>
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);
}

View file

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

View file

@ -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 */

View file

@ -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

View file

@ -56,3 +56,4 @@ __libc_fatal (message)
abort ();
}
libc_hidden_def (__libc_fatal)

View file

@ -57,3 +57,4 @@ __libc_fatal (message)
/* Try for ever and ever. */
ABORT_INSTRUCTION;
}
libc_hidden_def (__libc_fatal)