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