OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libstdc++-v3/] [libsupc++/] [unwind-cxx.h] - Blame information for rev 764

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.