LibreOffice Module bridges (master)  1
unwind-cxx.h
Go to the documentation of this file.
1 // -*- C++ -*- Exception handling and frame unwind runtime interface routines.
2 // Copyright (C) 2001 Free Software Foundation, Inc.
3 //
4 // This file is part of GCC.
5 //
6 // GCC is free software; you can redistribute it and/or modify
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 //
11 // GCC is distributed in the hope that it will be useful,
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
17 // along with GCC; see the file COPYING. If not, write to
18 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 // Boston, MA 02110-1301, USA.
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 
30 // This is derived from the C++ ABI for IA-64. Where we diverge
31 // for cross-architecture compatibility are noted with "@@@".
32 
33 #ifndef _UNWIND_CXX_H
34 #define _UNWIND_CXX_H 1
35 
36 // Level 2: C++ ABI
37 
38 #include <typeinfo>
39 #include <exception>
40 
41 #include <stddef.h>
42 #include "unwind.h"
43 
44 
45 typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
46 typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
47 typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
48 typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
49 typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
50 typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
51 
52 #pragma GCC visibility push(default)
53 
54 namespace __cxxabiv1
55 {
56 
57 // A C++ exception object consists of a header, which is a wrapper around
58 // an unwind object header with additional C++ specific information,
59 // followed by the exception object itself.
60 
62 {
63 #if __LP64__
64 #if 0
65  // This is a new field added with LLVM 10
66  // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
67  // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility". The HACK in
68  // fillUnoException (bridges/source/cpp_uno/gcc3_macosx_x86-64/except.cxx) tries to find out at
69  // runtime whether a __cxa_exception has this member. Once we can be sure that we only run
70  // against new libcxxabi that has this member, we can drop the "#if 0" here and drop the hack
71  // in fillUnoException.
72 
73  // Now _Unwind_Exception is marked with __attribute__((aligned)),
74  // which implies __cxa_exception is also aligned. Insert padding
75  // in the beginning of the struct, rather than before unwindHeader.
76  void *reserve;
77 #endif
78 
79  // This is a new field to support C++ 0x exception_ptr.
80  // For binary compatibility it is at the start of this
81  // struct which is prepended to the object thrown in
82  // __cxa_allocate_exception.
83  size_t referenceCount;
84 #endif
85  // Manage the exception object itself.
86  std::type_info *exceptionType;
88 
89  // The C++ standard has entertaining rules wrt calling set_terminate
90  // and set_unexpected in the middle of the exception cleanup process.
91  void (*unexpectedHandler)(); // std::unexpected_handler dropped from C++17
92  std::terminate_handler terminateHandler;
93 
94  // The caught exception stack threads through here.
96 
97  // How many nested handlers have caught this exception. A negated
98  // value is a signal that this object has been rethrown.
100 
101 #ifdef __ARM_EABI_UNWINDER__
102  // Stack of exceptions in cleanups.
103  __cxa_exception* nextPropagatingException;
104 
105  // The number of active cleanup handlers for this exception.
106  int propagationCount;
107 #else
108  // Cache parsed handler data from the personality routine Phase 1
109  // for Phase 2 and __cxa_call_unexpected.
111  const unsigned char *actionRecord;
112  const unsigned char *languageSpecificData;
113  _Unwind_Ptr catchTemp;
114  void *adjustedPtr;
115 #endif
116 #if !__LP64__
117  // This is a new field to support C++ 0x exception_ptr.
118  // For binary compatibility it is placed where the compiler
119  // previously adding padded to 64-bit align unwindHeader.
121 #endif
122 
123  // The generic exception header. Must be last.
124  _Unwind_Exception unwindHeader;
125 };
126 
127 // Each thread in a C++ program has access to a __cxa_eh_globals object.
129 {
131  unsigned int uncaughtExceptions;
132 #ifdef __ARM_EABI_UNWINDER__
133  __cxa_exception* propagatingExceptions;
134 #endif
135 };
136 
137 
138 // The __cxa_eh_globals for the current thread can be obtained by using
139 // either of the following functions. The "fast" version assumes at least
140 // one prior call of __cxa_get_globals has been made from the current
141 // thread, so no initialization is necessary.
142 extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
143 extern "C" __cxa_eh_globals *__cxa_get_globals_fast () throw();
144 
145 // Allocate memory for the exception plus the thrown object.
146 extern "C" void *__cxa_allocate_exception(size_t thrown_size) throw();
147 
148 // Free the space allocated for the exception.
149 extern "C" void __cxa_free_exception(void *thrown_exception) throw();
150 
151 #pragma GCC visibility push(hidden)
152 extern "C" void *__cxa_allocate_dependent_exception() throw();
153 extern "C" void __cxa_free_dependent_exception(void *thrown_exception) throw();
154 #pragma GCC visibility pop
155 
156 // Throw the exception.
157 extern "C" void __cxa_throw (void *thrown_exception,
158  std::type_info *tinfo,
159  void (*dest) (void *))
160  __attribute__((noreturn));
161 
162 // Used to implement exception handlers.
163 extern "C" void *__cxa_get_exception_ptr (void *) throw();
164 extern "C" void *__cxa_begin_catch (void *) throw();
165 extern "C" void __cxa_end_catch ();
166 extern "C" void __cxa_rethrow () __attribute__((noreturn));
167 
168 // These facilitate code generation for recurring situations.
169 extern "C" void __cxa_bad_cast ();
170 extern "C" void __cxa_bad_typeid ();
171 
172 // @@@ These are not directly specified by the IA-64 C++ ABI.
173 
174 // Handles re-checking the exception specification if unexpectedHandler
175 // throws, and if bad_exception needs to be thrown. Called from the
176 // compiler.
177 extern "C" void __cxa_call_unexpected (void *) __attribute__((noreturn));
178 extern "C" void __cxa_call_terminate (void*) __attribute__((noreturn));
179 
180 #ifdef __ARM_EABI_UNWINDER__
181 // Arm EABI specified routines.
182 typedef enum {
183  ctm_failed = 0,
184  ctm_succeeded = 1,
185  ctm_succeeded_with_ptr_to_base = 2
186 } __cxa_type_match_result;
187 extern "C" bool __cxa_type_match(_Unwind_Exception*, const std::type_info*,
188  bool, void**);
189 extern "C" void __cxa_begin_cleanup (_Unwind_Exception*);
190 extern "C" void __cxa_end_cleanup (void);
191 #endif
192 
193 // These are explicitly GNU C++ specific.
194 
195 // Acquire the C++ exception header from the C++ object.
196 static inline __cxa_exception *
198 {
199  return reinterpret_cast<__cxa_exception *>(ptr) - 1;
200 }
201 
202 // Acquire the C++ exception header from the generic exception header.
203 static inline __cxa_exception *
204 __get_exception_header_from_ue (_Unwind_Exception *exc)
205 {
206  return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;
207 }
208 
209 #ifdef __ARM_EABI_UNWINDER__
210 static inline bool
211 __is_gxx_exception_class(_Unwind_Exception_Class c)
212 {
213  // TODO: Take advantage of the fact that c will always be word aligned.
214  return c[0] == 'G'
215  && c[1] == 'N'
216  && c[2] == 'U'
217  && c[3] == 'C'
218  && c[4] == 'C'
219  && c[5] == '+'
220  && c[6] == '+';
221 }
222 
223 static inline void
224 __GXX_INIT_EXCEPTION_CLASS(_Unwind_Exception_Class c)
225 {
226  c[0] = 'G';
227  c[1] = 'N';
228  c[2] = 'U';
229  c[3] = 'C';
230  c[4] = 'C';
231  c[5] = '+';
232  c[6] = '+';
233  c[7] = '\0';
234 }
235 
236 static inline void*
237 __gxx_caught_object(_Unwind_Exception* eo)
238 {
239  return (void*)eo->barrier_cache.bitpattern[0];
240 }
241 #else // !__ARM_EABI_UNWINDER__
242 // This is the exception class we report -- "GNUCC++\0".
243 const _Unwind_Exception_Class __gxx_exception_class
244 = ((((((((_Unwind_Exception_Class) 'G'
245  << 8 | (_Unwind_Exception_Class) 'N')
246  << 8 | (_Unwind_Exception_Class) 'U')
247  << 8 | (_Unwind_Exception_Class) 'C')
248  << 8 | (_Unwind_Exception_Class) 'C')
249  << 8 | (_Unwind_Exception_Class) '+')
250  << 8 | (_Unwind_Exception_Class) '+')
251  << 8 | (_Unwind_Exception_Class) '\0');
252 
253 static inline bool
254 __is_gxx_exception_class(_Unwind_Exception_Class c)
255 {
256  return (c & ((_Unwind_Exception_Class)~0 << 8)) == __gxx_exception_class;
257 }
258 
259 #define __GXX_INIT_EXCEPTION_CLASS(c) c = __gxx_exception_class
260 
261 // GNU C++ personality routine, Version 0.
263  (int, _Unwind_Action, _Unwind_Exception_Class,
264  struct _Unwind_Exception *, struct _Unwind_Context *);
265 
266 // GNU C++ sjlj personality routine, Version 0.
268  (int, _Unwind_Action, _Unwind_Exception_Class,
269  struct _Unwind_Exception *, struct _Unwind_Context *);
270 
271 static inline void*
272 __gxx_caught_object(_Unwind_Exception* eo)
273 {
275  return header->adjustedPtr;
276 }
277 #endif // !__ARM_EABI_UNWINDER__
278 
279 } /* namespace __cxxabiv1 */
280 
281 #pragma GCC visibility pop
282 
283 #endif // _UNWIND_CXX_H
const _Unwind_Exception_Class __gxx_exception_class
Definition: unwind-cxx.h:244
void __cxa_bad_cast()
void __cxa_free_dependent_exception(void *thrown_exception)
void __cxa_bad_typeid()
_Unwind_Exception unwindHeader
Definition: unwind-cxx.h:124
static __cxa_exception * __get_exception_header_from_ue(_Unwind_Exception *exc)
Definition: unwind-cxx.h:204
const sal_Int8 header[]
__cxa_eh_globals * __cxa_get_globals_fast()
unsigned int uncaughtExceptions
Definition: unwind-cxx.h:131
unsigned _Unwind_Word __attribute__((__mode__(__word__)))
Definition: unwind-cxx.h:45
void * __cxa_begin_catch(void *)
#define __GXX_INIT_EXCEPTION_CLASS(c)
Definition: unwind-cxx.h:259
void __cxa_rethrow() __attribute__((noreturn))
void __cxa_call_unexpected(void *) __attribute__((noreturn))
const unsigned char * languageSpecificData
Definition: unwind-cxx.h:112
void * __cxa_allocate_exception(size_t thrown_size)
void __cxa_end_catch()
static __cxa_exception * __get_exception_header_from_obj(void *ptr)
Definition: unwind-cxx.h:197
void __cxa_free_exception(void *thrown_exception)
__cxa_eh_globals * __cxa_get_globals()
void(* exceptionDestructor)(void *)
Definition: unwind-cxx.h:87
std::type_info * exceptionType
Definition: unwind-cxx.h:86
static bool __is_gxx_exception_class(_Unwind_Exception_Class c)
Definition: unwind-cxx.h:254
const unsigned char * actionRecord
Definition: unwind-cxx.h:111
void * __cxa_get_exception_ptr(void *)
std::terminate_handler terminateHandler
Definition: unwind-cxx.h:92
_Unwind_Reason_Code __gxx_personality_sj0(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, struct _Unwind_Context *)
__cxa_exception * caughtExceptions
Definition: unwind-cxx.h:130
static void * __gxx_caught_object(_Unwind_Exception *eo)
Definition: unwind-cxx.h:272
void * __cxa_allocate_dependent_exception()
void __cxa_call_terminate(void *) __attribute__((noreturn))
void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void(*dest)(void *)) __attribute__((noreturn))
__cxa_exception * nextException
Definition: unwind-cxx.h:95
_Unwind_Reason_Code __gxx_personality_v0(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, struct _Unwind_Context *)
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo