1 // -*- C++ -*- Manage the thread-local exception globals. 2 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2011 3 // Free Software Foundation, Inc. 4 // 5 // This file is part of GCC. 6 // 7 // GCC is free software; you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License as published by 9 // the Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 // 12 // GCC is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 #include <bits/c++config.h> 27 #include <exception> 28 #include <cstdlib> 29 #include "cxxabi.h" 30 #include "unwind-cxx.h" 31 #include "bits/gthr.h" 32 33 #if _GLIBCXX_HOSTED 34 using std::free; 35 using std::malloc; 36 #else 37 // In a freestanding environment, these functions may not be 38 // available -- but for now, we assume that they are. 39 extern "C" void *malloc (std::size_t); 40 extern "C" void free(void *); 41 #endif 42 43 using namespace __cxxabiv1; 44 45 #if _GLIBCXX_HAVE_TLS 46 47 namespace 48 { 49 abi::__cxa_eh_globals* 50 get_global() _GLIBCXX_NOTHROW 51 { 52 static __thread abi::__cxa_eh_globals global; 53 return &global; 54 } 55 } // anonymous namespace 56 57 extern "C" __cxa_eh_globals* 58 __cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW 59 { return get_global(); } 60 61 extern "C" __cxa_eh_globals* 62 __cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW 63 { return get_global(); } 64 65 66 #else 67 68 // Single-threaded fallback buffer. 69 static __cxa_eh_globals eh_globals; 70 71 #if __GTHREADS 72 73 static void 74 eh_globals_dtor(void* ptr) 75 { 76 if (ptr) 77 { 78 __cxa_eh_globals* g = reinterpret_cast<__cxa_eh_globals*>(ptr); 79 __cxa_exception* exn = g->caughtExceptions; 80 __cxa_exception* next; 81 while (exn) 82 { 83 next = exn->nextException; 84 _Unwind_DeleteException(&exn->unwindHeader); 85 exn = next; 86 } 87 free(ptr); 88 } 89 } 90 91 struct __eh_globals_init 92 { 93 __gthread_key_t _M_key; 94 bool _M_init; 95 96 __eh_globals_init() : _M_init(false) 97 { 98 if (__gthread_active_p()) 99 _M_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0; 100 } 101 102 ~__eh_globals_init() 103 { 104 if (_M_init) 105 __gthread_key_delete(_M_key); 106 _M_init = false; 107 } 108 }; 109 110 static __eh_globals_init init; 111 112 extern "C" __cxa_eh_globals* 113 __cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW 114 { 115 __cxa_eh_globals* g; 116 if (init._M_init) 117 g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key)); 118 else 119 g = &eh_globals; 120 return g; 121 } 122 123 extern "C" __cxa_eh_globals* 124 __cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW 125 { 126 __cxa_eh_globals* g; 127 if (init._M_init) 128 { 129 g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key)); 130 if (!g) 131 { 132 void* v = malloc(sizeof(__cxa_eh_globals)); 133 if (v == 0 || __gthread_setspecific(init._M_key, v) != 0) 134 std::terminate(); 135 g = static_cast<__cxa_eh_globals*>(v); 136 g->caughtExceptions = 0; 137 g->uncaughtExceptions = 0; 138 #ifdef __ARM_EABI_UNWINDER__ 139 g->propagatingExceptions = 0; 140 #endif 141 } 142 } 143 else 144 g = &eh_globals; 145 return g; 146 } 147 148 #else 149 150 extern "C" __cxa_eh_globals* 151 __cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW 152 { return &eh_globals; } 153 154 extern "C" __cxa_eh_globals* 155 __cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW 156 { return &eh_globals; } 157 158 #endif 159 160 #endif 161