]>
Commit | Line | Data |
---|---|---|
52a11cbf | 1 | // -*- C++ -*- Exception handling routines for throwing. |
6d419a6e | 2 | // Copyright (C) 2001, 2003, 2008 Free Software Foundation, Inc. |
52a11cbf | 3 | // |
cbecceb9 | 4 | // This file is part of GCC. |
52a11cbf | 5 | // |
cbecceb9 | 6 | // GCC is free software; you can redistribute it and/or modify |
52a11cbf RH |
7 | // it under the terms of the GNU General Public License as published by |
8 | // the Free Software Foundation; either version 2, or (at your option) | |
9 | // any later version. | |
10 | // | |
cbecceb9 | 11 | // GCC is distributed in the hope that it will be useful, |
52a11cbf RH |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | // | |
16 | // You should have received a copy of the GNU General Public License | |
cbecceb9 | 17 | // along with GCC; see the file COPYING. If not, write to |
83f51799 KC |
18 | // the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
19 | // Boston, MA 02110-1301, USA. | |
52a11cbf RH |
20 | |
21 | // As a special exception, you may use this file as part of a free software | |
22 | // library without restriction. Specifically, if other files instantiate | |
23 | // templates or use macros or inline functions from this file, or you compile | |
24 | // this file and link it with other files to produce an executable, this | |
25 | // file does not by itself cause the resulting executable to be covered by | |
26 | // the GNU General Public License. This exception does not however | |
27 | // invalidate any other reasons why the executable file might be covered by | |
28 | // the GNU General Public License. | |
29 | ||
52a11cbf RH |
30 | #include <bits/c++config.h> |
31 | #include "unwind-cxx.h" | |
32 | ||
52a11cbf RH |
33 | using namespace __cxxabiv1; |
34 | ||
35 | ||
36 | static void | |
37 | __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) | |
38 | { | |
6d419a6e | 39 | // This cleanup is set only for primaries. |
52a11cbf RH |
40 | __cxa_exception *header = __get_exception_header_from_ue (exc); |
41 | ||
6d419a6e | 42 | // We only want to be called through _Unwind_DeleteException. |
cb94b155 | 43 | // _Unwind_DeleteException in the HP-UX IA64 libunwind library |
6d419a6e | 44 | // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT |
cb94b155 SE |
45 | // like the GCC _Unwind_DeleteException function does. |
46 | if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) | |
52a11cbf RH |
47 | __terminate (header->terminateHandler); |
48 | ||
6d419a6e PC |
49 | if (__gnu_cxx::__exchange_and_add_dispatch (&header->referenceCount, -1) == 0) |
50 | { | |
51 | if (header->exceptionDestructor) | |
52 | header->exceptionDestructor (header + 1); | |
52a11cbf | 53 | |
6d419a6e PC |
54 | __cxa_free_exception (header + 1); |
55 | } | |
52a11cbf RH |
56 | } |
57 | ||
58 | ||
59 | extern "C" void | |
723acbd5 MM |
60 | __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, |
61 | void (*dest) (void *)) | |
52a11cbf | 62 | { |
6d419a6e | 63 | // Definitely a primary. |
52a11cbf | 64 | __cxa_exception *header = __get_exception_header_from_obj (obj); |
6d419a6e | 65 | header->referenceCount = 0; |
52a11cbf RH |
66 | header->exceptionType = tinfo; |
67 | header->exceptionDestructor = dest; | |
68 | header->unexpectedHandler = __unexpected_handler; | |
69 | header->terminateHandler = __terminate_handler; | |
6d419a6e | 70 | __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->unwindHeader.exception_class); |
52a11cbf RH |
71 | header->unwindHeader.exception_cleanup = __gxx_exception_cleanup; |
72 | ||
3d7c150e | 73 | #ifdef _GLIBCXX_SJLJ_EXCEPTIONS |
52a11cbf RH |
74 | _Unwind_SjLj_RaiseException (&header->unwindHeader); |
75 | #else | |
76 | _Unwind_RaiseException (&header->unwindHeader); | |
77 | #endif | |
78 | ||
79 | // Some sort of unwinding error. Note that terminate is a handler. | |
80 | __cxa_begin_catch (&header->unwindHeader); | |
81 | std::terminate (); | |
82 | } | |
83 | ||
84 | extern "C" void | |
723acbd5 | 85 | __cxxabiv1::__cxa_rethrow () |
52a11cbf RH |
86 | { |
87 | __cxa_eh_globals *globals = __cxa_get_globals (); | |
88 | __cxa_exception *header = globals->caughtExceptions; | |
89 | ||
39609077 RH |
90 | globals->uncaughtExceptions += 1; |
91 | ||
52a11cbf RH |
92 | // Watch for luser rethrowing with no active exception. |
93 | if (header) | |
94 | { | |
95 | // Tell __cxa_end_catch this is a rethrow. | |
617a1b71 | 96 | if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) |
a944ceb9 RH |
97 | globals->caughtExceptions = 0; |
98 | else | |
99 | header->handlerCount = -header->handlerCount; | |
52a11cbf | 100 | |
3d7c150e | 101 | #ifdef _GLIBCXX_SJLJ_EXCEPTIONS |
a944ceb9 | 102 | _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); |
ed0d100f | 103 | #else |
1dcca6f3 | 104 | #if defined(_LIBUNWIND_STD_ABI) |
ed0d100f | 105 | _Unwind_RaiseException (&header->unwindHeader); |
52a11cbf | 106 | #else |
a944ceb9 | 107 | _Unwind_Resume_or_Rethrow (&header->unwindHeader); |
ed0d100f | 108 | #endif |
52a11cbf RH |
109 | #endif |
110 | ||
111 | // Some sort of unwinding error. Note that terminate is a handler. | |
112 | __cxa_begin_catch (&header->unwindHeader); | |
113 | } | |
114 | std::terminate (); | |
115 | } |