Subversion Repositories Kolibri OS

Rev

Rev 5134 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5134 serge 1
// -*- C++ -*- Exception handling and frame unwind runtime interface routines.
2
// Copyright (C) 2001-2013 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 3, 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
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// .
24
 
25
// This is derived from the C++ ABI for IA-64.  Where we diverge
26
// for cross-architecture compatibility are noted with "@@@".
27
 
28
#ifndef _UNWIND_CXX_H
29
#define _UNWIND_CXX_H 1
30
 
31
// Level 2: C++ ABI
32
 
33
#include 
34
#include 
35
#include 
36
#include "unwind.h"
37
#include 
38
#include 
39
 
40
#ifdef _GLIBCXX_HAVE_SYS_SDT_H
41
#include 
42
/* We only want to use stap probes starting with v3.  Earlier versions
43
   added too much startup cost.  */
44
#if defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
45
#define PROBE2(name, arg1, arg2) STAP_PROBE2 (libstdcxx, name, arg1, arg2)
46
#endif
47
#endif
48
 
49
#ifndef PROBE2
50
#define PROBE2(name, arg1, arg2)
51
#endif
52
 
53
#pragma GCC visibility push(default)
54
 
55
namespace __cxxabiv1
56
{
57
 
58
// A primary C++ exception object consists of a header, which is a wrapper
59
// around an unwind object header with additional C++ specific information,
60
// followed by the exception object itself.
61
 
62
struct __cxa_exception
63
{
64
  // Manage the exception object itself.
65
  std::type_info *exceptionType;
66
  void (_GLIBCXX_CDTOR_CALLABI *exceptionDestructor)(void *);
67
 
68
  // The C++ standard has entertaining rules wrt calling set_terminate
69
  // and set_unexpected in the middle of the exception cleanup process.
70
  std::unexpected_handler unexpectedHandler;
71
  std::terminate_handler terminateHandler;
72
 
73
  // The caught exception stack threads through here.
74
  __cxa_exception *nextException;
75
 
76
  // How many nested handlers have caught this exception.  A negated
77
  // value is a signal that this object has been rethrown.
78
  int handlerCount;
79
 
80
#ifdef __ARM_EABI_UNWINDER__
81
  // Stack of exceptions in cleanups.
82
  __cxa_exception* nextPropagatingException;
83
 
84
  // The nuber of active cleanup handlers for this exception.
85
  int propagationCount;
86
#else
87
  // Cache parsed handler data from the personality routine Phase 1
88
  // for Phase 2 and __cxa_call_unexpected.
89
  int handlerSwitchValue;
90
  const unsigned char *actionRecord;
91
  const unsigned char *languageSpecificData;
92
  _Unwind_Ptr catchTemp;
93
  void *adjustedPtr;
94
#endif
95
 
96
  // The generic exception header.  Must be last.
97
  _Unwind_Exception unwindHeader;
98
};
99
 
100
struct __cxa_refcounted_exception
101
{
102
  // Manage this header.
103
  _Atomic_word referenceCount;
104
  // __cxa_exception must be last, and no padding can be after it.
105
  __cxa_exception exc;
106
};
107
 
108
// A dependent C++ exception object consists of a wrapper around an unwind
109
// object header with additional C++ specific information, containing a pointer
110
// to a primary exception object.
111
 
112
struct __cxa_dependent_exception
113
{
114
  // The primary exception this thing depends on.
115
  void *primaryException;
116
 
117
  // The C++ standard has entertaining rules wrt calling set_terminate
118
  // and set_unexpected in the middle of the exception cleanup process.
119
  std::unexpected_handler unexpectedHandler;
120
  std::terminate_handler terminateHandler;
121
 
122
  // The caught exception stack threads through here.
123
  __cxa_exception *nextException;
124
 
125
  // How many nested handlers have caught this exception.  A negated
126
  // value is a signal that this object has been rethrown.
127
  int handlerCount;
128
 
129
#ifdef __ARM_EABI_UNWINDER__
130
  // Stack of exceptions in cleanups.
131
  __cxa_exception* nextPropagatingException;
132
 
133
  // The nuber of active cleanup handlers for this exception.
134
  int propagationCount;
135
#else
136
  // Cache parsed handler data from the personality routine Phase 1
137
  // for Phase 2 and __cxa_call_unexpected.
138
  int handlerSwitchValue;
139
  const unsigned char *actionRecord;
140
  const unsigned char *languageSpecificData;
141
  _Unwind_Ptr catchTemp;
142
  void *adjustedPtr;
143
#endif
144
 
145
  // The generic exception header.  Must be last.
146
  _Unwind_Exception unwindHeader;
147
};
148
 
149
// Each thread in a C++ program has access to a __cxa_eh_globals object.
150
struct __cxa_eh_globals
151
{
152
  __cxa_exception *caughtExceptions;
153
  unsigned int uncaughtExceptions;
154
#ifdef __ARM_EABI_UNWINDER__
155
  __cxa_exception* propagatingExceptions;
156
#endif
157
};
158
 
159
// @@@ These are not directly specified by the IA-64 C++ ABI.
160
 
161
// Handles re-checking the exception specification if unexpectedHandler
162
// throws, and if bad_exception needs to be thrown.  Called from the
163
// compiler.
164
extern "C" void __cxa_call_unexpected (void *) __attribute__((__noreturn__));
165
extern "C" void __cxa_call_terminate (_Unwind_Exception*) throw ()
166
  __attribute__((__noreturn__));
167
 
168
#ifdef __ARM_EABI_UNWINDER__
169
// Arm EABI specified routines.
170
typedef enum {
171
  ctm_failed = 0,
172
  ctm_succeeded = 1,
173
  ctm_succeeded_with_ptr_to_base = 2
174
} __cxa_type_match_result;
175
extern "C" __cxa_type_match_result __cxa_type_match(_Unwind_Exception*,
176
						    const std::type_info*,
5963 serge 177
						    bool, void**);
5134 serge 178
extern "C" bool __cxa_begin_cleanup (_Unwind_Exception*);
179
extern "C" void __cxa_end_cleanup (void);
180
#endif
181
 
182
// Handles cleanup from transactional memory restart.
183
extern "C" void __cxa_tm_cleanup (void *, void *, unsigned int) throw();
184
 
185
// Invokes given handler, dying appropriately if the user handler was
186
// so inconsiderate as to return.
187
extern void __terminate(std::terminate_handler) throw ()
188
  __attribute__((__noreturn__));
189
extern void __unexpected(std::unexpected_handler)
190
  __attribute__((__noreturn__));
191
 
192
// The current installed user handlers.
193
extern std::terminate_handler __terminate_handler;
194
extern std::unexpected_handler __unexpected_handler;
195
 
196
// These are explicitly GNU C++ specific.
197
 
198
// Acquire the C++ exception header from the C++ object.
199
static inline __cxa_exception *
200
__get_exception_header_from_obj (void *ptr)
201
{
202
  return reinterpret_cast<__cxa_exception *>(ptr) - 1;
203
}
204
 
205
// Acquire the C++ exception header from the generic exception header.
206
static inline __cxa_exception *
207
__get_exception_header_from_ue (_Unwind_Exception *exc)
208
{
209
  return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;
210
}
211
 
212
// Acquire the C++ refcounted exception header from the C++ object.
213
static inline __cxa_refcounted_exception *
214
__get_refcounted_exception_header_from_obj (void *ptr)
215
{
216
  return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1;
217
}
218
 
219
// Acquire the C++ refcounted exception header from the generic exception
220
// header.
221
static inline __cxa_refcounted_exception *
222
__get_refcounted_exception_header_from_ue (_Unwind_Exception *exc)
223
{
224
  return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1;
225
}
226
 
227
static inline __cxa_dependent_exception *
228
__get_dependent_exception_from_ue (_Unwind_Exception *exc)
229
{
230
  return reinterpret_cast<__cxa_dependent_exception *>(exc + 1) - 1;
231
}
232
 
233
#ifdef __ARM_EABI_UNWINDER__
234
static inline bool
235
__is_gxx_exception_class(_Unwind_Exception_Class c)
236
{
237
  // TODO: Take advantage of the fact that c will always be word aligned.
238
  return c[0] == 'G'
239
	 && c[1] == 'N'
240
	 && c[2] == 'U'
241
	 && c[3] == 'C'
242
	 && c[4] == 'C'
243
	 && c[5] == '+'
244
	 && c[6] == '+'
245
	 && (c[7] == '\0' || c[7] == '\x01');
246
}
247
 
248
// Only checks for primary or dependent, but not that it is a C++ exception at
249
// all.
250
static inline bool
251
__is_dependent_exception(_Unwind_Exception_Class c)
252
{
253
  return c[7] == '\x01';
254
}
255
 
256
static inline void
257
__GXX_INIT_PRIMARY_EXCEPTION_CLASS(_Unwind_Exception_Class c)
258
{
259
  c[0] = 'G';
260
  c[1] = 'N';
261
  c[2] = 'U';
262
  c[3] = 'C';
263
  c[4] = 'C';
264
  c[5] = '+';
265
  c[6] = '+';
266
  c[7] = '\0';
267
}
268
 
269
static inline void
270
__GXX_INIT_DEPENDENT_EXCEPTION_CLASS(_Unwind_Exception_Class c)
271
{
272
  c[0] = 'G';
273
  c[1] = 'N';
274
  c[2] = 'U';
275
  c[3] = 'C';
276
  c[4] = 'C';
277
  c[5] = '+';
278
  c[6] = '+';
279
  c[7] = '\x01';
280
}
281
 
282
static inline bool
283
__is_gxx_forced_unwind_class(_Unwind_Exception_Class c)
284
{
285
  return c[0] == 'G'
286
	 && c[1] == 'N'
287
	 && c[2] == 'U'
288
	 && c[3] == 'C'
289
	 && c[4] == 'F'
290
	 && c[5] == 'O'
291
	 && c[6] == 'R'
292
	 && c[7] == '\0';
293
}
294
 
295
static inline void
296
__GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c)
297
{
298
  c[0] = 'G';
299
  c[1] = 'N';
300
  c[2] = 'U';
301
  c[3] = 'C';
302
  c[4] = 'F';
303
  c[5] = 'O';
304
  c[6] = 'R';
305
  c[7] = '\0';
306
}
307
 
308
static inline void*
309
__gxx_caught_object(_Unwind_Exception* eo)
310
{
311
  return (void*)eo->barrier_cache.bitpattern[0];
312
}
313
#else // !__ARM_EABI_UNWINDER__
314
// This is the primary exception class we report -- "GNUCC++\0".
315
const _Unwind_Exception_Class __gxx_primary_exception_class
316
= ((((((((_Unwind_Exception_Class) 'G'
317
	 << 8 | (_Unwind_Exception_Class) 'N')
318
	<< 8 | (_Unwind_Exception_Class) 'U')
319
       << 8 | (_Unwind_Exception_Class) 'C')
320
      << 8 | (_Unwind_Exception_Class) 'C')
321
     << 8 | (_Unwind_Exception_Class) '+')
322
    << 8 | (_Unwind_Exception_Class) '+')
323
   << 8 | (_Unwind_Exception_Class) '\0');
324
 
325
// This is the dependent (from std::rethrow_exception) exception class we report
326
// "GNUCC++\x01"
327
const _Unwind_Exception_Class __gxx_dependent_exception_class
328
= ((((((((_Unwind_Exception_Class) 'G'
329
	 << 8 | (_Unwind_Exception_Class) 'N')
330
	<< 8 | (_Unwind_Exception_Class) 'U')
331
       << 8 | (_Unwind_Exception_Class) 'C')
332
      << 8 | (_Unwind_Exception_Class) 'C')
333
     << 8 | (_Unwind_Exception_Class) '+')
334
    << 8 | (_Unwind_Exception_Class) '+')
335
   << 8 | (_Unwind_Exception_Class) '\x01');
336
 
337
static inline bool
338
__is_gxx_exception_class(_Unwind_Exception_Class c)
339
{
340
  return c == __gxx_primary_exception_class
341
      || c == __gxx_dependent_exception_class;
342
}
343
 
344
// Only checks for primary or dependent, but not that it is a C++ exception at
345
// all.
346
static inline bool
347
__is_dependent_exception(_Unwind_Exception_Class c)
348
{
349
  return (c & 1);
350
}
351
 
352
#define __GXX_INIT_PRIMARY_EXCEPTION_CLASS(c) c = __gxx_primary_exception_class
353
#define __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(c) \
354
  c = __gxx_dependent_exception_class
355
 
356
// GNU C++ personality routine, Version 0.
357
extern "C" _Unwind_Reason_Code __gxx_personality_v0
358
     (int, _Unwind_Action, _Unwind_Exception_Class,
359
      struct _Unwind_Exception *, struct _Unwind_Context *);
360
 
361
// GNU C++ sjlj personality routine, Version 0.
362
extern "C" _Unwind_Reason_Code __gxx_personality_sj0
363
     (int, _Unwind_Action, _Unwind_Exception_Class,
364
      struct _Unwind_Exception *, struct _Unwind_Context *);
365
 
366
static inline void*
367
__gxx_caught_object(_Unwind_Exception* eo)
368
{
369
  // Bad as it looks, this actually works for dependent exceptions too.
370
  __cxa_exception* header = __get_exception_header_from_ue (eo);
371
  return header->adjustedPtr;
372
}
373
#endif // !__ARM_EABI_UNWINDER__
374
 
375
static inline void*
376
__get_object_from_ue(_Unwind_Exception* eo) throw()
377
{
378
  return __is_dependent_exception (eo->exception_class) ?
379
    __get_dependent_exception_from_ue (eo)->primaryException :
380
    eo + 1;
381
}
382
 
383
static inline void *
384
__get_object_from_ambiguous_exception(__cxa_exception *p_or_d) throw()
385
{
386
	return __get_object_from_ue (&p_or_d->unwindHeader);
387
}
388
 
389
 
390
} /* namespace __cxxabiv1 */
391
 
392
#pragma GCC visibility pop
393
 
394
#endif // _UNWIND_CXX_H