summaryrefslogtreecommitdiffstats
path: root/9/sources/cxx-stl/gabi++/include/cxxabi.h
blob: 6f44bbe36c4e6ebfb568eed445d1169ab50617ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
// Copyright (C) 2011 The Android Open Source Project
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//

#ifndef __GABIXX_CXXABI_H__
#define __GABIXX_CXXABI_H__

#include <exception>
#include <stdint.h>
#include <typeinfo>
#include <unwind.h>

namespace __cxxabiv1
{
  // Derived types of type_info below are based on 2.9.5 of C++ ABI.

  class __shim_type_info : public std::type_info
  {
   public:
    virtual ~__shim_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const = 0;
  };

  // Typeinfo for fundamental types.
  class __fundamental_type_info : public __shim_type_info
  {
  public:
    virtual ~__fundamental_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
  };

  // Typeinfo for array types.
  class __array_type_info : public __shim_type_info
  {
  public:
    virtual ~__array_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
  };

  // Typeinfo for function types.
  class __function_type_info : public __shim_type_info
  {
  public:
    virtual ~__function_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
  };

  // Typeinfo for enum types.
  class __enum_type_info : public __shim_type_info
  {
  public:
    virtual ~__enum_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
  };


  class __class_type_info;

  // Used in __vmi_class_type_info
  struct __base_class_type_info
  {
  public:
    const __class_type_info *__base_type;

    long __offset_flags;

    enum __offset_flags_masks {
      __virtual_mask = 0x1,
      __public_mask = 0x2,
      __offset_shift = 8   // lower 8 bits are flags
    };

    bool is_virtual() const {
      return (__offset_flags & __virtual_mask) != 0;
    }

    bool is_public() const {
      return (__offset_flags & __public_mask) != 0;
    }

    // FIXME: Right-shift of signed integer is implementation dependent.
    // GCC Implement is as signed (as we expect)
    long offset() const {
      return __offset_flags >> __offset_shift;
    }

    long flags() const {
      return __offset_flags & ((1 << __offset_shift) - 1);
    }
  };

  // Helper struct to support catch-clause match
  struct __UpcastInfo {
    enum ContainedStatus {
      unknown = 0,
      has_public_contained,
      has_ambig_or_not_public
    };

    ContainedStatus status;
    const __class_type_info* base_type;
    void* adjustedPtr;
    unsigned int premier_flags;
    bool nullobj_may_conflict;

    __UpcastInfo(const __class_type_info* type);
  };

  // Typeinfo for classes with no bases.
  class __class_type_info : public __shim_type_info
  {
  public:
    virtual ~__class_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;

    enum class_type_info_code {
      CLASS_TYPE_INFO_CODE,
      SI_CLASS_TYPE_INFO_CODE,
      VMI_CLASS_TYPE_INFO_CODE
    };

    virtual class_type_info_code
      code() const { return CLASS_TYPE_INFO_CODE; }

    virtual bool walk_to(const __class_type_info* base_type,
                         void*& adjustedPtr,
                         __UpcastInfo& info) const;

  protected:
    bool self_class_type_match(const __class_type_info* base_type,
                               void*& adjustedPtr,
                               __UpcastInfo& info) const;
  };

  // Typeinfo for classes containing only a single, public, non-virtual base at
  // offset zero.
  class __si_class_type_info : public __class_type_info
  {
  public:
    virtual ~__si_class_type_info();
    const __class_type_info *__base_type;

    virtual __class_type_info::class_type_info_code
      code() const { return SI_CLASS_TYPE_INFO_CODE; }

    virtual bool walk_to(const __class_type_info* base_type,
                         void*& adjustedPtr,
                         __UpcastInfo& info) const;
  };


  // Typeinfo for classes with bases that do not satisfy the
  // __si_class_type_info constraints.
  class __vmi_class_type_info : public __class_type_info
  {
  public:
    virtual ~__vmi_class_type_info();
    unsigned int __flags;
    unsigned int __base_count;
    __base_class_type_info __base_info[1];

    enum __flags_masks {
      __non_diamond_repeat_mask = 0x1,
      __diamond_shaped_mask = 0x2,
    };

    virtual __class_type_info::class_type_info_code
      code() const { return VMI_CLASS_TYPE_INFO_CODE; }

    virtual bool walk_to(const __class_type_info* base_type,
                         void*& adjustedPtr,
                         __UpcastInfo& info) const;
  };

  class __pbase_type_info : public __shim_type_info
  {
  public:
    virtual ~__pbase_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
    unsigned int __flags;
    const __shim_type_info* __pointee;

    enum __masks {
      __const_mask = 0x1,
      __volatile_mask = 0x2,
      __restrict_mask = 0x4,
      __incomplete_mask = 0x8,
      __incomplete_class_mask = 0x10
    };


    virtual bool can_catch_typeinfo_wrapper(const __shim_type_info* thrown_type,
                                            void*& adjustedPtr,
                                            unsigned tracker) const;

  protected:
    enum __constness_tracker_status {
      first_time_init = 0x1,
      keep_constness = 0x2,
      after_gap = 0x4         // after one non-const qualified,
                              // we cannot face const again in future
    };

  private:
    bool can_catch_ptr(const __pbase_type_info *thrown_type,
                       void *&adjustedPtr,
                       unsigned tracker) const;

    // Return true if making decision done.
    virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
                                  void*& adjustedPtr,
                                  unsigned tracker,
                                  bool& result) const = 0;
  };

  class __pointer_type_info : public __pbase_type_info
  {
  public:
    virtual ~__pointer_type_info();

  private:
    virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
                                  void*& adjustedPtr,
                                  unsigned tracker,
                                  bool& result) const;
  };

  class __pointer_to_member_type_info : public __pbase_type_info
  {
  public:
    __class_type_info* __context;

    virtual ~__pointer_to_member_type_info();

  private:
    virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
                                  void*& adjustedPtr,
                                  unsigned tracker,
                                  bool& result) const;
  };


  extern "C" {

    // Compatible with GNU C++
    const uint64_t __gxx_exception_class = 0x474E5543432B2B00LL; // GNUCC++\0

    // TODO: Support dependent exception
    // TODO: Support C++0x exception propagation
    // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
    struct __cxa_exception {
      size_t referenceCount;

      std::type_info* exceptionType;
      void (*exceptionDestructor)(void*);
      std::unexpected_handler unexpectedHandler;
      std::terminate_handler terminateHandler;
      __cxa_exception* nextException;

      int handlerCount;
#ifdef __arm__
      /**
       * ARM EHABI requires the unwind library to keep track of exceptions
       * during cleanups.  These support nesting, so we need to keep a list of
       * them.
       */
      __cxa_exception* nextCleanup;
      int cleanupCount;
#endif
      int handlerSwitchValue;
      const uint8_t* actionRecord;
      const uint8_t* languageSpecificData;
      void* catchTemp;
      void* adjustedPtr;

      _Unwind_Exception unwindHeader; // must be last
    };

    struct __cxa_eh_globals {
      __cxa_exception* caughtExceptions;
      unsigned int uncaughtExceptions;
#ifdef __arm__
      __cxa_exception* cleanupExceptions;
#endif
    };

    struct __cxa_thread_info {
      std::unexpected_handler unexpectedHandler;
      std::terminate_handler terminateHandler;
      _Unwind_Exception* currentCleanup;

      __cxa_eh_globals globals;
    };

    __cxa_eh_globals* __cxa_get_globals();
    __cxa_eh_globals* __cxa_get_globals_fast();

    void* __cxa_allocate_exception(size_t thrown_size);
    void __cxa_free_exception(void* thrown_exception);

    void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*));
    void __cxa_rethrow();

    void* __cxa_begin_catch(void* exceptionObject);
    void __cxa_end_catch();

    bool __cxa_begin_cleanup(_Unwind_Exception*);
    void __cxa_end_cleanup();

    void __cxa_bad_cast();
    void __cxa_bad_typeid();

    void* __cxa_get_exception_ptr(void* exceptionObject);

    void __cxa_pure_virtual();

    // Missing libcxxabi functions.
    bool __cxa_uncaught_exception() throw();
    void __cxa_decrement_exception_refcount(void* exceptionObject) throw();
    void __cxa_increment_exception_refcount(void* exceptionObject) throw();
    void __cxa_rethrow_primary_exception(void* exceptionObject);
    void* __cxa_current_primary_exception() throw();

  } // extern "C"

} // namespace __cxxabiv1

namespace abi = __cxxabiv1;

#endif /* defined(__GABIXX_CXXABI_H__) */