1 // New abi Support -*- C++ -*-
3 // Copyright (C) 2000, 2001, 2003, 2004, 2009 Free Software Foundation, Inc.
5 // This file is part of GCC.
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)
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.
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.
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/>.
26 // Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
31 #include <exception_defines.h>
32 #include "unwind-cxx.h"
38 struct uncatch_exception
41 ~uncatch_exception () { __cxa_begin_catch (&p
->unwindHeader
); }
47 operator=(const uncatch_exception
&);
49 uncatch_exception(const uncatch_exception
&);
52 uncatch_exception::uncatch_exception() : p(0)
54 __cxa_eh_globals
*globals
= __cxa_get_globals_fast ();
56 p
= globals
->caughtExceptions
;
58 globals
->caughtExceptions
= p
->nextException
;
59 globals
->uncaughtExceptions
+= 1;
63 // Allocate and construct array.
65 __cxa_vec_new(std::size_t element_count
,
66 std::size_t element_size
,
67 std::size_t padding_size
,
68 __cxa_cdtor_type constructor
,
69 __cxa_cdtor_type destructor
)
71 return __cxa_vec_new2(element_count
, element_size
, padding_size
,
72 constructor
, destructor
,
73 &operator new[], &operator delete []);
77 __cxa_vec_new2(std::size_t element_count
,
78 std::size_t element_size
,
79 std::size_t padding_size
,
80 __cxa_cdtor_type constructor
,
81 __cxa_cdtor_type destructor
,
82 void *(*alloc
) (std::size_t),
83 void (*dealloc
) (void *))
85 std::size_t size
= element_count
* element_size
+ padding_size
;
86 char *base
= static_cast <char *> (alloc (size
));
93 reinterpret_cast <std::size_t *> (base
)[-1] = element_count
;
94 #ifdef _GLIBCXX_ELTSIZE_IN_COOKIE
95 reinterpret_cast <std::size_t *> (base
)[-2] = element_size
;
100 __cxa_vec_ctor(base
, element_count
, element_size
,
101 constructor
, destructor
);
106 uncatch_exception ue
;
107 dealloc(base
- padding_size
);
109 __throw_exception_again
;
115 __cxa_vec_new3(std::size_t element_count
,
116 std::size_t element_size
,
117 std::size_t padding_size
,
118 __cxa_cdtor_type constructor
,
119 __cxa_cdtor_type destructor
,
120 void *(*alloc
) (std::size_t),
121 void (*dealloc
) (void *, std::size_t))
123 std::size_t size
= element_count
* element_size
+ padding_size
;
124 char *base
= static_cast<char *>(alloc (size
));
130 base
+= padding_size
;
131 reinterpret_cast<std::size_t *>(base
)[-1] = element_count
;
132 #ifdef _GLIBCXX_ELTSIZE_IN_COOKIE
133 reinterpret_cast <std::size_t *> (base
)[-2] = element_size
;
138 __cxa_vec_ctor(base
, element_count
, element_size
,
139 constructor
, destructor
);
144 uncatch_exception ue
;
145 dealloc(base
- padding_size
, size
);
147 __throw_exception_again
;
153 extern "C" __cxa_vec_ctor_return_type
154 __cxa_vec_ctor(void *array_address
,
155 std::size_t element_count
,
156 std::size_t element_size
,
157 __cxa_cdtor_type constructor
,
158 __cxa_cdtor_type destructor
)
161 char *ptr
= static_cast<char *>(array_address
);
166 for (; ix
!= element_count
; ix
++, ptr
+= element_size
)
172 uncatch_exception ue
;
173 __cxa_vec_cleanup(array_address
, ix
, element_size
, destructor
);
175 __throw_exception_again
;
177 _GLIBCXX_CXA_VEC_CTOR_RETURN (array_address
);
180 // Construct an array by copying.
181 extern "C" __cxa_vec_ctor_return_type
182 __cxa_vec_cctor(void *dest_array
,
184 std::size_t element_count
,
185 std::size_t element_size
,
186 __cxa_cdtor_return_type (*constructor
) (void *, void *),
187 __cxa_cdtor_type destructor
)
190 char *dest_ptr
= static_cast<char *>(dest_array
);
191 char *src_ptr
= static_cast<char *>(src_array
);
196 for (; ix
!= element_count
;
197 ix
++, src_ptr
+= element_size
, dest_ptr
+= element_size
)
198 constructor(dest_ptr
, src_ptr
);
203 uncatch_exception ue
;
204 __cxa_vec_cleanup(dest_array
, ix
, element_size
, destructor
);
206 __throw_exception_again
;
208 _GLIBCXX_CXA_VEC_CTOR_RETURN (dest_array
);
213 __cxa_vec_dtor(void *array_address
,
214 std::size_t element_count
,
215 std::size_t element_size
,
216 __cxa_cdtor_type destructor
)
220 char *ptr
= static_cast<char *>(array_address
);
221 std::size_t ix
= element_count
;
223 ptr
+= element_count
* element_size
;
236 uncatch_exception ue
;
237 __cxa_vec_cleanup(array_address
, ix
, element_size
, destructor
);
239 __throw_exception_again
;
244 // Destruct array as a result of throwing an exception.
245 // [except.ctor]/3 If a destructor called during stack unwinding
246 // exits with an exception, terminate is called.
248 __cxa_vec_cleanup(void *array_address
,
249 std::size_t element_count
,
250 std::size_t element_size
,
251 __cxa_cdtor_type destructor
)
255 char *ptr
= static_cast <char *> (array_address
);
256 std::size_t ix
= element_count
;
258 ptr
+= element_count
* element_size
;
275 // Destruct and release array.
277 __cxa_vec_delete(void *array_address
,
278 std::size_t element_size
,
279 std::size_t padding_size
,
280 __cxa_cdtor_type destructor
)
282 __cxa_vec_delete2(array_address
, element_size
, padding_size
,
284 &operator delete []);
288 __cxa_vec_delete2(void *array_address
,
289 std::size_t element_size
,
290 std::size_t padding_size
,
291 __cxa_cdtor_type destructor
,
292 void (*dealloc
) (void *))
297 char* base
= static_cast<char *>(array_address
);
301 std::size_t element_count
= reinterpret_cast<std::size_t *>(base
)[-1];
302 base
-= padding_size
;
305 __cxa_vec_dtor(array_address
, element_count
, element_size
,
311 uncatch_exception ue
;
314 __throw_exception_again
;
321 __cxa_vec_delete3(void *array_address
,
322 std::size_t element_size
,
323 std::size_t padding_size
,
324 __cxa_cdtor_type destructor
,
325 void (*dealloc
) (void *, std::size_t))
330 char* base
= static_cast <char *> (array_address
);
331 std::size_t size
= 0;
335 std::size_t element_count
= reinterpret_cast<std::size_t *> (base
)[-1];
336 base
-= padding_size
;
337 size
= element_count
* element_size
+ padding_size
;
340 __cxa_vec_dtor(array_address
, element_count
, element_size
,
346 uncatch_exception ue
;
349 __throw_exception_again
;
354 } // namespace __cxxabiv1
356 #if defined(__arm__) && defined(__ARM_EABI__)
358 // The ARM C++ ABI requires that the library provide these additional
359 // helper functions. There are placed in this file, despite being
360 // architecture-specifier, so that the compiler can inline the __cxa
361 // functions into these functions as appropriate.
366 __aeabi_vec_ctor_nocookie_nodtor (void *array_address
,
367 abi::__cxa_cdtor_type constructor
,
368 std::size_t element_size
,
369 std::size_t element_count
)
371 return abi::__cxa_vec_ctor (array_address
, element_count
, element_size
,
372 constructor
, /*destructor=*/NULL
);
376 __aeabi_vec_ctor_cookie_nodtor (void *array_address
,
377 abi::__cxa_cdtor_type constructor
,
378 std::size_t element_size
,
379 std::size_t element_count
)
381 if (array_address
== NULL
)
384 array_address
= reinterpret_cast<std::size_t *>(array_address
) + 2;
385 reinterpret_cast<std::size_t *>(array_address
)[-2] = element_size
;
386 reinterpret_cast<std::size_t *>(array_address
)[-1] = element_count
;
387 return abi::__cxa_vec_ctor (array_address
,
388 element_count
, element_size
,
389 constructor
, /*destructor=*/NULL
);
393 __aeabi_vec_cctor_nocookie_nodtor (void *dest_array
,
395 std::size_t element_size
,
396 std::size_t element_count
,
397 void *(*constructor
) (void *, void *))
399 return abi::__cxa_vec_cctor (dest_array
, src_array
,
400 element_count
, element_size
,
405 __aeabi_vec_new_cookie_noctor (std::size_t element_size
,
406 std::size_t element_count
)
408 return abi::__cxa_vec_new(element_count
, element_size
,
409 2 * sizeof (std::size_t),
410 /*constructor=*/NULL
, /*destructor=*/NULL
);
414 __aeabi_vec_new_nocookie (std::size_t element_size
,
415 std::size_t element_count
,
416 abi::__cxa_cdtor_type constructor
)
418 return abi::__cxa_vec_new (element_count
, element_size
, 0, constructor
,
423 __aeabi_vec_new_cookie_nodtor (std::size_t element_size
,
424 std::size_t element_count
,
425 abi::__cxa_cdtor_type constructor
)
427 return abi::__cxa_vec_new(element_count
, element_size
,
428 2 * sizeof (std::size_t),
433 __aeabi_vec_new_cookie(std::size_t element_size
,
434 std::size_t element_count
,
435 abi::__cxa_cdtor_type constructor
,
436 abi::__cxa_cdtor_type destructor
)
438 return abi::__cxa_vec_new (element_count
, element_size
,
439 2 * sizeof (std::size_t),
440 constructor
, destructor
);
445 __aeabi_vec_dtor (void *array_address
,
446 abi::__cxa_cdtor_type destructor
,
447 std::size_t element_size
,
448 std::size_t element_count
)
450 abi::__cxa_vec_dtor (array_address
, element_count
, element_size
,
452 return reinterpret_cast<std::size_t*> (array_address
) - 2;
456 __aeabi_vec_dtor_cookie (void *array_address
,
457 abi::__cxa_cdtor_type destructor
)
462 abi::__cxa_vec_dtor (array_address
,
463 reinterpret_cast<std::size_t *>(array_address
)[-1],
464 reinterpret_cast<std::size_t *>(array_address
)[-2],
466 return reinterpret_cast<std::size_t*> (array_address
) - 2;
471 __aeabi_vec_delete (void *array_address
,
472 abi::__cxa_cdtor_type destructor
)
477 abi::__cxa_vec_delete (array_address
,
478 reinterpret_cast<std::size_t *>(array_address
)[-2],
479 2 * sizeof (std::size_t),
484 __aeabi_vec_delete3 (void *array_address
,
485 abi::__cxa_cdtor_type destructor
,
486 void (*dealloc
) (void *, std::size_t))
491 abi::__cxa_vec_delete3 (array_address
,
492 reinterpret_cast<std::size_t *>(array_address
)[-2],
493 2 * sizeof (std::size_t),
494 destructor
, dealloc
);
498 __aeabi_vec_delete3_nodtor (void *array_address
,
499 void (*dealloc
) (void *, std::size_t))
504 abi::__cxa_vec_delete3 (array_address
,
505 reinterpret_cast<std::size_t *>(array_address
)[-2],
506 2 * sizeof (std::size_t),
507 /*destructor=*/NULL
, dealloc
);
509 } // namespace __aeabiv1
511 #endif // defined(__arm__) && defined(__ARM_EABI__)