diff options
Diffstat (limited to 'libpthread/nptl/unwind.c')
-rw-r--r-- | libpthread/nptl/unwind.c | 176 |
1 files changed, 0 insertions, 176 deletions
diff --git a/libpthread/nptl/unwind.c b/libpthread/nptl/unwind.c deleted file mode 100644 index 56a423815..000000000 --- a/libpthread/nptl/unwind.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@redhat.com> - and Richard Henderson <rth@redhat.com>, 2003. - - 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <setjmp.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "pthreadP.h" -#include "jmpbuf-unwind.h" - -#ifdef HAVE_FORCED_UNWIND - -#ifdef _STACK_GROWS_DOWN -# define FRAME_LEFT(frame, other, adj) \ - ((uintptr_t) frame - adj >= (uintptr_t) other - adj) -#elif _STACK_GROWS_UP -# define FRAME_LEFT(frame, other, adj) \ - ((uintptr_t) frame - adj <= (uintptr_t) other - adj) -#else -# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" -#endif - -static _Unwind_Reason_Code -unwind_stop (int version, _Unwind_Action actions, - _Unwind_Exception_Class exc_class, - struct _Unwind_Exception *exc_obj, - struct _Unwind_Context *context, void *stop_parameter) -{ - struct pthread_unwind_buf *buf = stop_parameter; - struct pthread *self = THREAD_SELF; - struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup); - int do_longjump = 0; - - /* Adjust all pointers used in comparisons, so that top of thread's - stack is at the top of address space. Without that, things break - if stack is allocated above the main stack. */ - uintptr_t adj = (uintptr_t) self->stackblock + self->stackblock_size; - - /* Do longjmp if we're at "end of stack", aka "end of unwind data". - We assume there are only C frame without unwind data in between - here and the jmp_buf target. Otherwise simply note that the CFA - of a function is NOT within it's stack frame; it's the SP of the - previous frame. */ - if ((actions & _UA_END_OF_STACK) - || ! _JMPBUF_CFA_UNWINDS_ADJ (buf->cancel_jmp_buf[0].jmp_buf, context, - adj)) - do_longjump = 1; - - if (__builtin_expect (curp != NULL, 0)) - { - /* Handle the compatibility stuff. Execute all handlers - registered with the old method which would be unwound by this - step. */ - struct _pthread_cleanup_buffer *oldp = buf->priv.data.cleanup; - void *cfa = (void *) _Unwind_GetCFA (context); - - if (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp, adj))) - { - do - { - /* Pointer to the next element. */ - struct _pthread_cleanup_buffer *nextp = curp->__prev; - - /* Call the handler. */ - curp->__routine (curp->__arg); - - /* To the next. */ - curp = nextp; - } - while (curp != oldp - && (do_longjump || FRAME_LEFT (cfa, curp, adj))); - - /* Mark the current element as handled. */ - THREAD_SETMEM (self, cleanup, curp); - } - } - - if (do_longjump) - __libc_unwind_longjmp ((struct __jmp_buf_tag *) buf->cancel_jmp_buf, 1); - - return _URC_NO_REASON; -} - - -static void -unwind_cleanup (_Unwind_Reason_Code reason, struct _Unwind_Exception *exc) -{ - /* When we get here a C++ catch block didn't rethrow the object. We - cannot handle this case and therefore abort. */ -# define STR_N_LEN(str) str, strlen (str) - INTERNAL_SYSCALL_DECL (err); - INTERNAL_SYSCALL (write, err, 3, STDERR_FILENO, - STR_N_LEN ("FATAL: exception not rethrown\n")); - abort (); -} - -#endif /* have forced unwind */ - - -void -__cleanup_fct_attribute __attribute ((noreturn)) -__pthread_unwind (__pthread_unwind_buf_t *buf) -{ - struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf; - struct pthread *self = THREAD_SELF; - -#ifdef HAVE_FORCED_UNWIND - /* This is not a catchable exception, so don't provide any details about - the exception type. We do need to initialize the field though. */ - THREAD_SETMEM (self, exc.exception_class, 0); - THREAD_SETMEM (self, exc.exception_cleanup, unwind_cleanup); - - _Unwind_ForcedUnwind (&self->exc, unwind_stop, ibuf); -#else - /* Handle the compatibility stuff first. Execute all handlers - registered with the old method. We don't execute them in order, - instead, they will run first. */ - struct _pthread_cleanup_buffer *oldp = ibuf->priv.data.cleanup; - struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup); - - if (curp != oldp) - { - do - { - /* Pointer to the next element. */ - struct _pthread_cleanup_buffer *nextp = curp->__prev; - - /* Call the handler. */ - curp->__routine (curp->__arg); - - /* To the next. */ - curp = nextp; - } - while (curp != oldp); - - /* Mark the current element as handled. */ - THREAD_SETMEM (self, cleanup, curp); - } - - /* We simply jump to the registered setjmp buffer. */ - __libc_unwind_longjmp ((struct __jmp_buf_tag *) ibuf->cancel_jmp_buf, 1); -#endif - /* NOTREACHED */ - - /* We better do not get here. */ - abort (); -} -hidden_def (__pthread_unwind) - - -void -__cleanup_fct_attribute __attribute ((noreturn)) -__pthread_unwind_next (__pthread_unwind_buf_t *buf) -{ - struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf; - - __pthread_unwind ((__pthread_unwind_buf_t *) ibuf->priv.data.prev); -} -hidden_def (__pthread_unwind_next) |