Ejemplo n.º 1
0
///  Called by __cxa_rethrow().
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
#if LIBCXXABI_ARM_EHABI
  _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), "
                       "private_1=%ld\n",
                       exception_object,
                       (long)exception_object->unwinder_cache.reserved1);
#else
  _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), "
                       "private_1=%ld\n",
                       exception_object,
                       (long)exception_object->private_1);
#endif

#if LIBCXXABI_ARM_EHABI
  // _Unwind_RaiseException on EHABI will always set the reserved1 field to 0,
  // which is in the same position as private_1 below.
  return _Unwind_RaiseException(exception_object);
#else
  // If this is non-forced and a stopping place was found, then this is a
  // re-throw.
  // Call _Unwind_RaiseException() as if this was a new exception
  if (exception_object->private_1 == 0) {
    return _Unwind_RaiseException(exception_object);
    // Will return if there is no catch clause, so that __cxa_rethrow can call
    // std::terminate().
  }

  // Call through to _Unwind_Resume() which distiguishes between forced and
  // regular exceptions.
  _Unwind_Resume(exception_object);
  _LIBUNWIND_ABORT("_Unwind_Resume_or_Rethrow() called _Unwind_RaiseException()"
                   " which unexpectedly returned");
#endif
}
Ejemplo n.º 2
0
/*
After constructing the exception object with the throw argument value,
the generated code calls the __cxa_throw runtime library routine. This
routine never returns.

The __cxa_throw routine will do the following:

* Obtain the __cxa_exception header from the thrown exception object address,
which can be computed as follows: 
 __cxa_exception *header = ((__cxa_exception *) thrown_exception - 1); 
* Save the current unexpected_handler and terminate_handler in the __cxa_exception header.
* Save the tinfo and dest arguments in the __cxa_exception header. 
* Set the exception_class field in the unwind header. This is a 64-bit value
representing the ASCII string "XXXXC++\0", where "XXXX" is a
vendor-dependent string. That is, for implementations conforming to this
ABI, the low-order 4 bytes of this 64-bit value will be "C++\0".
* Increment the uncaught_exception flag. 
* Call _Unwind_RaiseException in the system unwind library, Its argument is the
pointer to the thrown exception, which __cxa_throw itself received as an argument.
__Unwind_RaiseException begins the process of stack unwinding, described
in Section 2.5. In special cases, such as an inability to find a
handler, _Unwind_RaiseException may return. In that case, __cxa_throw
will call terminate, assuming that there was no handler for the
exception.
*/
LIBCXXABI_NORETURN
void 
__cxa_throw(void* thrown_object, std::type_info* tinfo, void (*dest)(void*))
{
    __cxa_eh_globals *globals = __cxa_get_globals();
    __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);

    exception_header->unexpectedHandler = std::get_unexpected();
    exception_header->terminateHandler  = std::get_terminate();
    exception_header->exceptionType = tinfo;
    exception_header->exceptionDestructor = dest;
    setExceptionClass(&exception_header->unwindHeader);
    exception_header->referenceCount = 1;  // This is a newly allocated exception, no need for thread safety.
    globals->uncaughtExceptions += 1;   // Not atomically, since globals are thread-local

    exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
#if __arm__
    _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
#else
    _Unwind_RaiseException(&exception_header->unwindHeader);
#endif
    //  This only happens when there is no handler, or some unexpected unwinding
    //     error happens.
    failed_throw(exception_header);
}
PROTECTED _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exception_object)
{
  struct _Unwind_Context context;
  unw_context_t uc;

  if (exception_object->private_1)
    {
      int ret;
      /* ANDROID support update. */
      int destroy_map = 1;

      unw_map_local_create ();

      if (_Unwind_InitContext (&context, &uc) < 0)
        ret = _URC_FATAL_PHASE2_ERROR;
      else
        ret = _Unwind_Phase2 (exception_object, &context, &destroy_map);

      if (destroy_map)
        unw_map_local_destroy ();

      return ret;
      /* End ANDROID support. */
    }
  else
    return _Unwind_RaiseException (exception_object);
}
Ejemplo n.º 4
0
/*
    If thrown_object is not null, allocate, initialize and throw a dependent
    exception.
*/
void
__cxa_rethrow_primary_exception(void* thrown_object)
{
    if ( thrown_object != NULL )
    {
        // thrown_object guaranteed to be native because
        //   __cxa_current_primary_exception returns NULL for foreign exceptions
        __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
        __cxa_dependent_exception* dep_exception_header =
            static_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception());
        dep_exception_header->primaryException = thrown_object;
        __cxa_increment_exception_refcount(thrown_object);
        dep_exception_header->exceptionType = exception_header->exceptionType;
        dep_exception_header->unexpectedHandler = std::get_unexpected();
        dep_exception_header->terminateHandler = std::get_terminate();
        setDependentExceptionClass(&dep_exception_header->unwindHeader);
        __cxa_get_globals()->uncaughtExceptions += 1;
        dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup;
#if __arm__
        _Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader);
#else
        _Unwind_RaiseException(&dep_exception_header->unwindHeader);
#endif
        // Some sort of unwinding error.  Note that terminate is a handler.
        __cxa_begin_catch(&dep_exception_header->unwindHeader);
    }
    // If we return client will call terminate()
}
Ejemplo n.º 5
0
void
objc_exception_throw (id exception)
{
  struct ObjcException *header = calloc (1, sizeof (*header));

  memcpy (&header->base.exception_class, &__objc_exception_class,
	  sizeof (__objc_exception_class));
  header->base.exception_cleanup = __objc_exception_cleanup;
  header->value = exception;

#ifdef SJLJ_EXCEPTIONS
  _Unwind_SjLj_RaiseException (&header->base);
#else
  _Unwind_RaiseException (&header->base);
#endif

  /* No exception handler was installed.  Call the uncaught exception
     handler if any is defined.  */
  if (__objc_uncaught_exception_handler != 0)
    {
      (*__objc_uncaught_exception_handler) (exception);
    }

  abort ();
}
Ejemplo n.º 6
0
void __cilkrts_c_resume_except (_Unwind_Exception *exc)
{
#if DEBUG_EXCEPTIONS
    fprintf(stderr, "resume exception %p\n", exc);
#endif
    _Unwind_Reason_Code why = _Unwind_RaiseException(exc);
    __cilkrts_bug ("Cilk runtime error: failed to reinstate suspended exception %p (%d)\n", exc, why);
}
void __cxa_throw(void* thrown_exception,
                 struct type_info *tinfo,
                 void (*dest)(void*))
{
    printf("__cxa_throw called\n");

    __cxa_exception *header = ((__cxa_exception *) thrown_exception - 1);
    _Unwind_RaiseException(&header->unwindHeader);

    // __cxa_throw never returns
    printf("no one handled __cxa_throw, terminate!\n");
    exit(0);
}
Ejemplo n.º 8
0
int main()
{
    ex.exception_class = ((uint64_t)'mymy' << 32) | (uint64_t)'exex'; 
	ex.exception_cleanup = NULL;
	ex.private_1 = 0;
	ex.private_2 = 0;

	_Unwind_Reason_Code result = _Unwind_RaiseException(&ex);
	
	if ( result == _URC_END_OF_STACK )
		return 0;
	else
		return 1;
}
Ejemplo n.º 9
0
void
objc_exception_throw (id value)
{
  struct ObjcException *header = calloc (1, sizeof (*header));
  __OBJC_INIT_EXCEPTION_CLASS(header->base.exception_class);
  header->base.exception_cleanup = __objc_exception_cleanup;
  header->value = value;

#ifdef SJLJ_EXCEPTIONS
  _Unwind_SjLj_RaiseException (&header->base);
#else
  _Unwind_RaiseException (&header->base);
#endif

  /* Some sort of unwinding error.  */
  abort ();
}
Ejemplo n.º 10
0
/*  This routine can rethrow native or foreign exceptions.
If the exception is native:
* marks the exception object on top of the caughtExceptions stack 
  (in an implementation-defined way) as being rethrown. 
* If the caughtExceptions stack is empty, it calls terminate() 
  (see [C++FDIS] [except.throw], 15.1.8). 
* It then calls _Unwind_RaiseException which should not return
   (terminate if it does).
  Note:  exception_header may be masquerading as a __cxa_dependent_exception
         and that's ok.
*/
LIBCXXABI_NORETURN
void
__cxa_rethrow()
{
    __cxa_eh_globals* globals = __cxa_get_globals();
    __cxa_exception* exception_header = globals->caughtExceptions;
    if (NULL == exception_header)
        std::terminate();      // throw; called outside of a exception handler
    bool native_exception = isOurExceptionClass(&exception_header->unwindHeader);
    if (native_exception)
    {
        //  Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch)
        exception_header->handlerCount = -exception_header->handlerCount;
        globals->uncaughtExceptions += 1;
        //  __cxa_end_catch will remove this exception from the caughtExceptions stack if necessary
    }
    else  // this is a foreign exception
    {
        // The only way to communicate to __cxa_end_catch that we've rethrown
        //   a foreign exception, so don't delete us, is to pop the stack here
        //   which must be empty afterwards.  Then __cxa_end_catch will do
        //   nothing
        globals->caughtExceptions = 0;
    }
#if __arm__
    _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
#else
    _Unwind_RaiseException(&exception_header->unwindHeader);
#endif

    //  If we get here, some kind of unwinding error has occurred.
    //  There is some weird code generation bug happening with 
    //     Apple clang version 4.0 (tags/Apple/clang-418.0.2) (based on LLVM 3.1svn)
    //     If we call failed_throw here.  Turns up with -O2 or higher, and -Os.
    __cxa_begin_catch(&exception_header->unwindHeader);
    if (native_exception)
        std::__terminate(exception_header->terminateHandler);
    // Foreign exception: can't get exception_header->terminateHandler
    std::terminate();
}
Ejemplo n.º 11
0
void
__go_unwind_stack ()
{
  struct _Unwind_Exception *hdr;

  hdr = ((struct _Unwind_Exception *)
	 __go_alloc (sizeof (struct _Unwind_Exception)));
  __builtin_memcpy (&hdr->exception_class, &__go_exception_class,
		    sizeof hdr->exception_class);
  hdr->exception_cleanup = NULL;

  runtime_g ()->exception = hdr;

#ifdef __USING_SJLJ_EXCEPTIONS__
  _Unwind_SjLj_RaiseException (hdr);
#else
  _Unwind_RaiseException (hdr);
#endif

  /* Raising an exception should not return.  */
  abort ();
}
Ejemplo n.º 12
0
void
objc_exception_throw (id value)
{
  struct ObjcException *header = calloc (1, sizeof (*header));
  
  memcpy (&header->base.exception_class, &__objc_exception_class,
	  sizeof (__objc_exception_class));
  header->base.exception_cleanup = __objc_exception_cleanup;
  header->value = value;

#ifdef SJLJ_EXCEPTIONS
  _Unwind_SjLj_RaiseException (&header->base);
#else
  _Unwind_RaiseException (&header->base);
#endif

  /* Some sort of unwinding error.  */
  if (_objc_unexpected_exception != 0)
    {
      (*_objc_unexpected_exception) (value);
    }
  abort ();
}
Ejemplo n.º 13
0
/* Raise DWARF2 exception. */
static void err_raise_ext(int errcode)
{
  static_uex.exception_class = LJ_UEXCLASS_MAKE(errcode);
  static_uex.exception_cleanup = NULL;
  _Unwind_RaiseException(&static_uex);
}
Ejemplo n.º 14
0
_Unwind_Reason_Code
__gnat_Unwind_RaiseException (_Unwind_Exception *e)
{
  return _Unwind_RaiseException (e);
}
Ejemplo n.º 15
0
void
__go_check_defer (_Bool *frame)
{
  G *g;
  struct _Unwind_Exception *hdr;

  g = runtime_g ();

  if (g == NULL)
    {
      /* Some other language has thrown an exception.  We know there
	 are no defer handlers, so there is nothing to do.  */
    }
  else if (g->isforeign)
    {
      Panic *n;
      _Bool recovered;

      /* Some other language has thrown an exception.  We need to run
	 the local defer handlers.  If they call recover, we stop
	 unwinding the stack here.  */

      n = (Panic *) __go_alloc (sizeof (Panic));

      n->arg.__type_descriptor = NULL;
      n->arg.__object = NULL;
      n->recovered = 0;
      n->isforeign = 1;
      n->next = g->_panic;
      g->_panic = n;

      while (1)
	{
	  Defer *d;
	  void (*pfn) (void *);

	  d = g->_defer;
	  if (d == NULL || d->frame != frame || d->pfn == 0)
	    break;

	  pfn = (void (*) (void *)) d->pfn;
	  g->_defer = d->next;

	  (*pfn) (d->arg);

	  if (runtime_m () != NULL)
	    runtime_freedefer (d);

	  if (n->recovered)
	    {
	      /* The recover function caught the panic thrown by some
		 other language.  */
	      break;
	    }
	}

      recovered = n->recovered;
      g->_panic = n->next;
      __go_free (n);

      if (recovered)
	{
	  /* Just return and continue executing Go code.  */
	  *frame = 1;
	  return;
	}

      /* We are panicing through this function.  */
      *frame = 0;
    }
  else if (g->_defer != NULL
	   && g->_defer->pfn == 0
	   && g->_defer->frame == frame)
    {
      Defer *d;

      /* This is the defer function which called recover.  Simply
	 return to stop the stack unwind, and let the Go code continue
	 to execute.  */
      d = g->_defer;
      g->_defer = d->next;

      if (runtime_m () != NULL)
	runtime_freedefer (d);

      /* We are returning from this function.  */
      *frame = 1;

      return;
    }

  /* This is some other defer function.  It was already run by the
     call to panic, or just above.  Rethrow the exception.  */

  hdr = (struct _Unwind_Exception *) g->exception;

#ifdef __USING_SJLJ_EXCEPTIONS__
  _Unwind_SjLj_Resume_or_Rethrow (hdr);
#else
#if defined(_LIBUNWIND_STD_ABI)
  _Unwind_RaiseException (hdr);
#else
  _Unwind_Resume_or_Rethrow (hdr);
#endif
#endif

  /* Rethrowing the exception should not return.  */
  abort();
}
Ejemplo n.º 16
0
static void err_raise_ext(int errcode)
{
  memset(&static_uex, 0, sizeof(static_uex));
  static_uex.exclass = LJ_UEXCLASS_MAKE(errcode);
  _Unwind_RaiseException(&static_uex);
}
Ejemplo n.º 17
0
int _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) {
	return _Unwind_RaiseException(exception_object);
}