1183724Ssos// -*- C++ -*- Exception handling routines for throwing.
2183724Ssos// Copyright (C) 2001, 2003 Free Software Foundation, Inc.
3183724Ssos//
4183724Ssos// This file is part of GCC.
5183724Ssos//
6183724Ssos// GCC is free software; you can redistribute it and/or modify
7183724Ssos// it under the terms of the GNU General Public License as published by
8183724Ssos// the Free Software Foundation; either version 2, or (at your option)
9183724Ssos// any later version.
10183724Ssos//
11183724Ssos// GCC is distributed in the hope that it will be useful,
12183724Ssos// but WITHOUT ANY WARRANTY; without even the implied warranty of
13183724Ssos// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14183724Ssos// GNU General Public License for more details.
15183724Ssos//
16183724Ssos// You should have received a copy of the GNU General Public License
17183724Ssos// along with GCC; see the file COPYING.  If not, write to
18183724Ssos// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19183724Ssos// Boston, MA 02110-1301, USA.
20183724Ssos
21183724Ssos// As a special exception, you may use this file as part of a free software
22183724Ssos// library without restriction.  Specifically, if other files instantiate
23183724Ssos// templates or use macros or inline functions from this file, or you compile
24183724Ssos// this file and link it with other files to produce an executable, this
25183724Ssos// file does not by itself cause the resulting executable to be covered by
26183724Ssos// the GNU General Public License.  This exception does not however
27183724Ssos// invalidate any other reasons why the executable file might be covered by
28183724Ssos// the GNU General Public License.
29183724Ssos
30183724Ssos#include <bits/c++config.h>
31183724Ssos#include "unwind-cxx.h"
32183724Ssos
33183724Ssosusing namespace __cxxabiv1;
34183724Ssos
35183724Ssos
36183724Ssosstatic void
37183724Ssos__gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc)
38183724Ssos{
39183724Ssos  __cxa_exception *header = __get_exception_header_from_ue (exc);
40183724Ssos
41183724Ssos  // If we haven't been caught by a foreign handler, then this is
42183724Ssos  // some sort of unwind error.  In that case just die immediately.
43183724Ssos  // _Unwind_DeleteException in the HP-UX IA64 libunwind library
44183724Ssos  //  returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT
45183724Ssos  // like the GCC _Unwind_DeleteException function does.
46183724Ssos  if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)
47183724Ssos    __terminate (header->terminateHandler);
48183724Ssos
49183724Ssos  if (header->exceptionDestructor)
50183724Ssos    header->exceptionDestructor (header + 1);
51183724Ssos
52183724Ssos  __cxa_free_exception (header + 1);
53183724Ssos}
54183724Ssos
55183724Ssos
56200171Smavextern "C" void
57200171Smav__cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
58183724Ssos			 void (*dest) (void *))
59183724Ssos{
60183724Ssos  __cxa_exception *header = __get_exception_header_from_obj (obj);
61183724Ssos  header->exceptionType = tinfo;
62183724Ssos  header->exceptionDestructor = dest;
63183724Ssos  header->unexpectedHandler = __unexpected_handler;
64183724Ssos  header->terminateHandler = __terminate_handler;
65183724Ssos  __GXX_INIT_EXCEPTION_CLASS(header->unwindHeader.exception_class);
66233717Smarius  header->unwindHeader.exception_cleanup = __gxx_exception_cleanup;
67242908Sdim
68183724Ssos#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
69199322Smav  _Unwind_SjLj_RaiseException (&header->unwindHeader);
70240199Smav#else
71199322Smav  _Unwind_RaiseException (&header->unwindHeader);
72199322Smav#endif
73199322Smav
74183724Ssos  // Some sort of unwinding error.  Note that terminate is a handler.
75183724Ssos  __cxa_begin_catch (&header->unwindHeader);
76183724Ssos  std::terminate ();
77183724Ssos}
78183724Ssos
79183724Ssosextern "C" void
80183724Ssos__cxxabiv1::__cxa_rethrow ()
81183724Ssos{
82183724Ssos  __cxa_eh_globals *globals = __cxa_get_globals ();
83183724Ssos  __cxa_exception *header = globals->caughtExceptions;
84200171Smav
85200171Smav  globals->uncaughtExceptions += 1;
86183724Ssos
87183724Ssos  // Watch for luser rethrowing with no active exception.
88183724Ssos  if (header)
89194893Smav    {
90183724Ssos      // Tell __cxa_end_catch this is a rethrow.
91183724Ssos      if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
92183724Ssos	globals->caughtExceptions = 0;
93183724Ssos      else
94183724Ssos	header->handlerCount = -header->handlerCount;
95183724Ssos
96199322Smav#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
97183724Ssos      _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader);
98183724Ssos#else
99183724Ssos#if defined(_LIBUNWIND_STD_ABI)
100183724Ssos      _Unwind_RaiseException (&header->unwindHeader);
101183724Ssos#else
102183724Ssos      _Unwind_Resume_or_Rethrow (&header->unwindHeader);
103183724Ssos#endif
104183724Ssos#endif
105183724Ssos
106183724Ssos      // Some sort of unwinding error.  Note that terminate is a handler.
107183724Ssos      __cxa_begin_catch (&header->unwindHeader);
108200171Smav    }
109188769Smav  std::terminate ();
110183724Ssos}
111183724Ssos