]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libcxxrt/exception.cc
Import libc++ / libcxxrt into base. Not build by default yet (use
[FreeBSD/FreeBSD.git] / contrib / libcxxrt / exception.cc
1 #include <stdlib.h>
2 #include <dlfcn.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdint.h>
6 #include <pthread.h>
7 #include "typeinfo.h"
8 #include "dwarf_eh.h"
9 #include "cxxabi.h"
10
11 using namespace ABI_NAMESPACE;
12
13 /**
14  * Saves the result of the landing pad that we have found.  For ARM, this is
15  * stored in the generic unwind structure, while on other platforms it is
16  * stored in the C++ exception.
17  */
18 static void saveLandingPad(struct _Unwind_Context *context,
19                            struct _Unwind_Exception *ucb,
20                            struct __cxa_exception *ex,
21                            int selector,
22                            dw_eh_ptr_t landingPad)
23 {
24 #ifdef __arm__
25         // On ARM, we store the saved exception in the generic part of the structure
26         ucb->barrier_cache.sp = _Unwind_GetGR(context, 13);
27         ucb->barrier_cache.bitpattern[1] = (uint32_t)selector;
28         ucb->barrier_cache.bitpattern[3] = (uint32_t)landingPad;
29 #endif
30         // Cache the results for the phase 2 unwind, if we found a handler
31         // and this is not a foreign exception.  
32         if (ex)
33         {
34                 ex->handlerSwitchValue = selector;
35                 ex->catchTemp = landingPad;
36         }
37 }
38
39 /**
40  * Loads the saved landing pad.  Returns 1 on success, 0 on failure.
41  */
42 static int loadLandingPad(struct _Unwind_Context *context,
43                           struct _Unwind_Exception *ucb,
44                           struct __cxa_exception *ex,
45                           unsigned long *selector,
46                           dw_eh_ptr_t *landingPad)
47 {
48 #ifdef __arm__
49         *selector = ucb->barrier_cache.bitpattern[1];
50         *landingPad = (dw_eh_ptr_t)ucb->barrier_cache.bitpattern[3];
51         return 1;
52 #else
53         if (ex)
54         {
55                 *selector = ex->handlerSwitchValue;
56                 *landingPad = (dw_eh_ptr_t)ex->catchTemp;
57                 return 0;
58         }
59         return 0;
60 #endif
61 }
62
63 static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex,
64                                                     struct _Unwind_Context *context)
65 {
66 #ifdef __arm__
67         if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; }
68 #endif
69         return _URC_CONTINUE_UNWIND;
70 }
71
72
73 extern "C" void __cxa_free_exception(void *thrown_exception);
74 extern "C" void __cxa_free_dependent_exception(void *thrown_exception);
75 extern "C" void* __dynamic_cast(const void *sub,
76                                 const __class_type_info *src,
77                                 const __class_type_info *dst,
78                                 ptrdiff_t src2dst_offset);
79
80 /**
81  * The type of a handler that has been found.
82  */
83 typedef enum
84 {
85         /** No handler. */
86         handler_none,
87         /**
88          * A cleanup - the exception will propagate through this frame, but code
89          * must be run when this happens.
90          */
91         handler_cleanup,
92         /**
93          * A catch statement.  The exception will not propagate past this frame
94          * (without an explicit rethrow).
95          */
96         handler_catch
97 } handler_type;
98
99 /**
100  * Per-thread info required by the runtime.  We store a single structure
101  * pointer in thread-local storage, because this tends to be a scarce resource
102  * and it's impolite to steal all of it and not leave any for the rest of the
103  * program.
104  *
105  * Instances of this structure are allocated lazily - at most one per thread -
106  * and are destroyed on thread termination.
107  */
108 struct __cxa_thread_info
109 {
110         /** The termination handler for this thread. */
111         terminate_handler terminateHandler;
112         /** The unexpected exception handler for this thread. */
113         unexpected_handler unexpectedHandler;
114         /**
115          * The number of emergency buffers held by this thread.  This is 0 in
116          * normal operation - the emergency buffers are only used when malloc()
117          * fails to return memory for allocating an exception.  Threads are not
118          * permitted to hold more than 4 emergency buffers (as per recommendation
119          * in ABI spec [3.3.1]).
120          */
121         int emergencyBuffersHeld;
122         /**
123          * The exception currently running in a cleanup.
124          */
125         _Unwind_Exception *currentCleanup;
126         /**
127          * The public part of this structure, accessible from outside of this
128          * module.
129          */
130         __cxa_eh_globals globals;
131 };
132 /**
133  * Dependent exception.  This 
134  */
135 struct __cxa_dependent_exception
136 {
137 #if __LP64__
138         void *primaryException;
139 #endif
140         std::type_info *exceptionType;
141         void (*exceptionDestructor) (void *); 
142         unexpected_handler unexpectedHandler;
143         terminate_handler terminateHandler;
144         __cxa_exception *nextException;
145         int handlerCount;
146 #ifdef __arm__
147         _Unwind_Exception *nextCleanup;
148         int cleanupCount;
149 #endif
150         int handlerSwitchValue;
151         const char *actionRecord;
152         const char *languageSpecificData;
153         void *catchTemp;
154         void *adjustedPtr;
155 #if !__LP64__
156         void *primaryException;
157 #endif
158         _Unwind_Exception unwindHeader;
159 };
160
161
162 namespace std
163 {
164         void unexpected();
165         class exception
166         {
167                 public:
168                         virtual ~exception() throw();
169                         virtual const char* what() const throw();
170         };
171
172 }
173
174 extern "C" std::type_info *__cxa_current_exception_type();
175
176 /**
177  * Class of exceptions to distinguish between this and other exception types.
178  *
179  * The first four characters are the vendor ID.  Currently, we use GNUC,
180  * because we aim for ABI-compatibility with the GNU implementation, and
181  * various checks may test for equality of the class, which is incorrect.
182  */
183 static const uint64_t exception_class =
184         EXCEPTION_CLASS('G', 'N', 'U', 'C', 'C', '+', '+', '\0');
185 /**
186  * Class used for dependent exceptions.  
187  */
188 static const uint64_t dependent_exception_class =
189         EXCEPTION_CLASS('G', 'N', 'U', 'C', 'C', '+', '+', '\x01');
190 /**
191  * The low four bytes of the exception class, indicating that we conform to the
192  * Itanium C++ ABI.  This is currently unused, but should be used in the future
193  * if we change our exception class, to allow this library and libsupc++ to be
194  * linked to the same executable and both to interoperate.
195  */
196 static const uint32_t abi_exception_class = 
197         GENERIC_EXCEPTION_CLASS('C', '+', '+', '\0');
198
199 static bool isCXXException(uint64_t cls)
200 {
201         return (cls == exception_class) || (cls == dependent_exception_class);
202 }
203
204 static bool isDependentException(uint64_t cls)
205 {
206         return cls == dependent_exception_class;
207 }
208
209 static __cxa_exception *exceptionFromPointer(void *ex)
210 {
211         return (__cxa_exception*)((char*)ex -
212                         offsetof(struct __cxa_exception, unwindHeader));
213 }
214 static __cxa_exception *realExceptionFromException(__cxa_exception *ex)
215 {
216         if (!isDependentException(ex->unwindHeader.exception_class)) { return ex; }
217         return ((__cxa_exception*)(((__cxa_dependent_exception*)ex)->primaryException))-1;
218 }
219
220
221 namespace std
222 {
223         // Forward declaration of standard library terminate() function used to
224         // abort execution.
225         void terminate(void);
226 }
227
228 using namespace ABI_NAMESPACE;
229
230
231
232 /** The global termination handler. */
233 static terminate_handler terminateHandler = abort;
234 /** The global unexpected exception handler. */
235 static unexpected_handler unexpectedHandler = std::terminate;
236
237 /** Key used for thread-local data. */
238 static pthread_key_t eh_key;
239
240
241 /**
242  * Cleanup function, allowing foreign exception handlers to correctly destroy
243  * this exception if they catch it.
244  */
245 static void exception_cleanup(_Unwind_Reason_Code reason, 
246                               struct _Unwind_Exception *ex)
247 {
248         __cxa_free_exception((void*)ex);
249 }
250 static void dependent_exception_cleanup(_Unwind_Reason_Code reason, 
251                               struct _Unwind_Exception *ex)
252 {
253
254         __cxa_free_dependent_exception((void*)ex);
255 }
256
257 /**
258  * Recursively walk a list of exceptions and delete them all in post-order.
259  */
260 static void free_exception_list(__cxa_exception *ex)
261 {
262         if (0 != ex->nextException)
263         {
264                 free_exception_list(ex->nextException);
265         }
266         // __cxa_free_exception() expects to be passed the thrown object, which
267         // immediately follows the exception, not the exception itself
268         __cxa_free_exception(ex+1);
269 }
270
271 /**
272  * Cleanup function called when a thread exists to make certain that all of the
273  * per-thread data is deleted.
274  */
275 static void thread_cleanup(void* thread_info)
276 {
277         __cxa_thread_info *info = (__cxa_thread_info*)thread_info;
278         if (info->globals.caughtExceptions)
279         {
280                 free_exception_list(info->globals.caughtExceptions);
281         }
282         free(thread_info);
283 }
284
285
286 /**
287  * Once control used to protect the key creation.
288  */
289 static pthread_once_t once_control = PTHREAD_ONCE_INIT;
290
291 /**
292  * Initialise eh_key.
293  */
294 static void init_key(void)
295 {
296         pthread_key_create(&eh_key, thread_cleanup);
297 }
298
299 /**
300  * Returns the thread info structure, creating it if it is not already created.
301  */
302 static __cxa_thread_info *thread_info()
303 {
304         pthread_once(&once_control, init_key);
305         __cxa_thread_info *info = (__cxa_thread_info*)pthread_getspecific(eh_key);
306         if (0 == info)
307         {
308                 info = (__cxa_thread_info*)calloc(1, sizeof(__cxa_thread_info));
309                 pthread_setspecific(eh_key, info);
310         }
311         return info;
312 }
313 /**
314  * Fast version of thread_info().  May fail if thread_info() is not called on
315  * this thread at least once already.
316  */
317 static __cxa_thread_info *thread_info_fast()
318 {
319         return (__cxa_thread_info*)pthread_getspecific(eh_key);
320 }
321 /**
322  * ABI function returning the __cxa_eh_globals structure.
323  */
324 extern "C" __cxa_eh_globals *ABI_NAMESPACE::__cxa_get_globals(void)
325 {
326         return &(thread_info()->globals);
327 }
328 /**
329  * Version of __cxa_get_globals() assuming that __cxa_get_globals() has already
330  * been called at least once by this thread.
331  */
332 extern "C" __cxa_eh_globals *ABI_NAMESPACE::__cxa_get_globals_fast(void)
333 {
334         return &(thread_info_fast()->globals);
335 }
336
337 /**
338  * An emergency allocation reserved for when malloc fails.  This is treated as
339  * 16 buffers of 1KB each.
340  */
341 static char emergency_buffer[16384];
342 /**
343  * Flag indicating whether each buffer is allocated.
344  */
345 static bool buffer_allocated[16];
346 /**
347  * Lock used to protect emergency allocation.
348  */
349 static pthread_mutex_t emergency_malloc_lock = PTHREAD_MUTEX_INITIALIZER;
350 /**
351  * Condition variable used to wait when two threads are both trying to use the
352  * emergency malloc() buffer at once.
353  */
354 static pthread_cond_t emergency_malloc_wait = PTHREAD_COND_INITIALIZER;
355
356 /**
357  * Allocates size bytes from the emergency allocation mechanism, if possible.
358  * This function will fail if size is over 1KB or if this thread already has 4
359  * emergency buffers.  If all emergency buffers are allocated, it will sleep
360  * until one becomes available.
361  */
362 static char *emergency_malloc(size_t size)
363 {
364         if (size > 1024) { return 0; }
365
366         __cxa_thread_info *info = thread_info();
367         // Only 4 emergency buffers allowed per thread!
368         if (info->emergencyBuffersHeld > 3) { return 0; }
369
370         pthread_mutex_lock(&emergency_malloc_lock);
371         int buffer = -1;
372         while (buffer < 0)
373         {
374                 // While we were sleeping on the lock, another thread might have free'd
375                 // enough memory for us to use, so try the allocation again - no point
376                 // using the emergency buffer if there is some real memory that we can
377                 // use...
378                 void *m = calloc(1, size);
379                 if (0 != m)
380                 {
381                         pthread_mutex_unlock(&emergency_malloc_lock);
382                         return (char*)m;
383                 }
384                 for (int i=0 ; i<16 ; i++)
385                 {
386                         if (!buffer_allocated[i])
387                         {
388                                 buffer = i;
389                                 buffer_allocated[i] = true;
390                                 break;
391                         }
392                 }
393                 // If there still isn't a buffer available, then sleep on the condition
394                 // variable.  This will be signalled when another thread releases one
395                 // of the emergency buffers.
396                 if (buffer < 0)
397                 {
398                         pthread_cond_wait(&emergency_malloc_wait, &emergency_malloc_lock);
399                 }
400         }
401         pthread_mutex_unlock(&emergency_malloc_lock);
402         info->emergencyBuffersHeld++;
403         return emergency_buffer + (1024 * buffer);
404 }
405
406 /**
407  * Frees a buffer returned by emergency_malloc().
408  *
409  * Note: Neither this nor emergency_malloc() is particularly efficient.  This
410  * should not matter, because neither will be called in normal operation - they
411  * are only used when the program runs out of memory, which should not happen
412  * often.
413  */
414 static void emergency_malloc_free(char *ptr)
415 {
416         int buffer = -1;
417         // Find the buffer corresponding to this pointer.
418         for (int i=0 ; i<16 ; i++)
419         {
420                 if (ptr == (void*)(emergency_buffer + (1024 * i)))
421                 {
422                         buffer = i;
423                         break;
424                 }
425         }
426         assert(buffer > 0 &&
427                "Trying to free something that is not an emergency buffer!");
428         // emergency_malloc() is expected to return 0-initialized data.  We don't
429         // zero the buffer when allocating it, because the static buffers will
430         // begin life containing 0 values.
431         memset((void*)ptr, 0, 1024);
432         // Signal the condition variable to wake up any threads that are blocking
433         // waiting for some space in the emergency buffer
434         pthread_mutex_lock(&emergency_malloc_lock);
435         // In theory, we don't need to do this with the lock held.  In practice,
436         // our array of bools will probably be updated using 32-bit or 64-bit
437         // memory operations, so this update may clobber adjacent values.
438         buffer_allocated[buffer] = false;
439         pthread_cond_signal(&emergency_malloc_wait);
440         pthread_mutex_unlock(&emergency_malloc_lock);
441 }
442
443 static char *alloc_or_die(size_t size)
444 {
445         char *buffer = (char*)calloc(1, size);
446
447         // If calloc() doesn't want to give us any memory, try using an emergency
448         // buffer.
449         if (0 == buffer)
450         {
451                 buffer = emergency_malloc(size);
452                 // This is only reached if the allocation is greater than 1KB, and
453                 // anyone throwing objects that big really should know better.  
454                 if (0 == buffer)
455                 {
456                         fprintf(stderr, "Out of memory attempting to allocate exception\n");
457                         std::terminate();
458                 }
459         }
460         return buffer;
461 }
462 static void free_exception(char *e)
463 {
464         // If this allocation is within the address range of the emergency buffer,
465         // don't call free() because it was not allocated with malloc()
466         if ((e > emergency_buffer) &&
467             (e < (emergency_buffer + sizeof(emergency_buffer))))
468         {
469                 emergency_malloc_free(e);
470         }
471         else
472         {
473                 free(e);
474         }
475 }
476
477 /**
478  * Allocates an exception structure.  Returns a pointer to the space that can
479  * be used to store an object of thrown_size bytes.  This function will use an
480  * emergency buffer if malloc() fails, and may block if there are no such
481  * buffers available.
482  */
483 extern "C" void *__cxa_allocate_exception(size_t thrown_size)
484 {
485         size_t size = thrown_size + sizeof(__cxa_exception);
486         char *buffer = alloc_or_die(size);
487         return buffer+sizeof(__cxa_exception);
488 }
489
490 extern "C" void *__cxa_allocate_dependent_exception(void)
491 {
492         size_t size = sizeof(__cxa_dependent_exception);
493         char *buffer = alloc_or_die(size);
494         return buffer+sizeof(__cxa_dependent_exception);
495 }
496
497 /**
498  * __cxa_free_exception() is called when an exception was thrown in between
499  * calling __cxa_allocate_exception() and actually throwing the exception.
500  * This happens when the object's copy constructor throws an exception.
501  *
502  * In this implementation, it is also called by __cxa_end_catch() and during
503  * thread cleanup.
504  */
505 extern "C" void __cxa_free_exception(void *thrown_exception)
506 {
507         __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
508         // Free the object that was thrown, calling its destructor
509         if (0 != ex->exceptionDestructor)
510         {
511                 try
512                 {
513                         ex->exceptionDestructor(thrown_exception);
514                 }
515                 catch(...)
516                 {
517                         // FIXME: Check that this is really what the spec says to do.
518                         std::terminate();
519                 }
520         }
521
522         free_exception((char*)ex);
523 }
524
525 static void releaseException(__cxa_exception *exception)
526 {
527         if (isDependentException(exception->unwindHeader.exception_class))
528         {
529                 __cxa_free_dependent_exception(exception+1);
530                 return;
531         }
532         if (__sync_sub_and_fetch(&exception->referenceCount, 1) == 0)
533         {
534                 // __cxa_free_exception() expects to be passed the thrown object,
535                 // which immediately follows the exception, not the exception
536                 // itself
537                 __cxa_free_exception(exception+1);
538         }
539 }
540
541 void __cxa_free_dependent_exception(void *thrown_exception)
542 {
543         __cxa_dependent_exception *ex = ((__cxa_dependent_exception*)thrown_exception) - 1;
544         assert(isDependentException(ex->unwindHeader.exception_class));
545         if (ex->primaryException)
546         {
547                 releaseException(realExceptionFromException((__cxa_exception*)ex));
548         }
549         free_exception((char*)ex);
550 }
551
552 /**
553  * Callback function used with _Unwind_Backtrace().
554  *
555  * Prints a stack trace.  Used only for debugging help.
556  *
557  * Note: As of FreeBSD 8.1, dladd() still doesn't work properly, so this only
558  * correctly prints function names from public, relocatable, symbols.
559  */
560 static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c)
561 {
562         Dl_info myinfo;
563         int mylookup =
564                 dladdr((void*)(uintptr_t)__cxa_current_exception_type, &myinfo);
565         void *ip = (void*)_Unwind_GetIP(context);
566         Dl_info info;
567         if (dladdr(ip, &info) != 0)
568         {
569                 if (mylookup == 0 || strcmp(info.dli_fname, myinfo.dli_fname) != 0)
570                 {
571                         printf("%p:%s() in %s\n", ip, info.dli_sname, info.dli_fname);
572                 }
573         }
574         return _URC_CONTINUE_UNWIND;
575 }
576
577 /**
578  * Report a failure that occurred when attempting to throw an exception.
579  *
580  * If the failure happened by falling off the end of the stack without finding
581  * a handler, prints a back trace before aborting.
582  */
583 static void report_failure(_Unwind_Reason_Code err, __cxa_exception *thrown_exception)
584 {
585         switch (err)
586         {
587                 default: break;
588                 case _URC_FATAL_PHASE1_ERROR:
589                         fprintf(stderr, "Fatal error during phase 1 unwinding\n");
590                         break;
591 #ifndef __arm__
592                 case _URC_FATAL_PHASE2_ERROR:
593                         fprintf(stderr, "Fatal error during phase 2 unwinding\n");
594                         break;
595 #endif
596                 case _URC_END_OF_STACK:
597                         fprintf(stderr, "Terminating due to uncaught exception %p", 
598                                         (void*)thrown_exception);
599                         thrown_exception = realExceptionFromException(thrown_exception);
600                         static const __class_type_info *e_ti =
601                                 static_cast<const __class_type_info*>(&typeid(std::exception));
602                         const __class_type_info *throw_ti =
603                                 dynamic_cast<const __class_type_info*>(thrown_exception->exceptionType);
604                         if (throw_ti)
605                         {
606                                 std::exception *e =
607                                         (std::exception*)e_ti->cast_to((void*)(thrown_exception+1),
608                                                         throw_ti);
609                                 if (e)
610                                 {
611                                         fprintf(stderr, " '%s'", e->what());
612                                 }
613                         }
614
615                         size_t bufferSize = 128;
616                         char *demangled = (char*)malloc(bufferSize);
617                         const char *mangled = thrown_exception->exceptionType->name();
618                         int status;
619                         demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status);
620                         fprintf(stderr, " of type %s\n", 
621                                 status == 0 ? (const char*)demangled : mangled);
622                         if (status == 0) { free(demangled); }
623                         // Print a back trace if no handler is found.
624                         // TODO: Make this optional
625                         _Unwind_Backtrace(trace, 0);
626                         break;
627         }
628         std::terminate();
629 }
630
631 static void throw_exception(__cxa_exception *ex)
632 {
633         __cxa_thread_info *info = thread_info();
634         ex->unexpectedHandler = info->unexpectedHandler;
635         if (0 == ex->unexpectedHandler)
636         {
637                 ex->unexpectedHandler = unexpectedHandler;
638         }
639         ex->terminateHandler  = info->terminateHandler;
640         if (0 == ex->terminateHandler)
641         {
642                 ex->terminateHandler = terminateHandler;
643         }
644         info->globals.uncaughtExceptions++;
645
646         _Unwind_Reason_Code err = _Unwind_RaiseException(&ex->unwindHeader);
647         // The _Unwind_RaiseException() function should not return, it should
648         // unwind the stack past this function.  If it does return, then something
649         // has gone wrong.
650         report_failure(err, ex);
651 }
652
653
654 /**
655  * ABI function for throwing an exception.  Takes the object to be thrown (the
656  * pointer returned by __cxa_allocate_exception()), the type info for the
657  * pointee, and the destructor (if there is one) as arguments.
658  */
659 extern "C" void __cxa_throw(void *thrown_exception,
660                             std::type_info *tinfo,
661                             void(*dest)(void*))
662 {
663         __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
664
665         ex->referenceCount = 1;
666         ex->exceptionType = tinfo;
667         
668         ex->exceptionDestructor = dest;
669         
670         ex->unwindHeader.exception_class = exception_class;
671         ex->unwindHeader.exception_cleanup = exception_cleanup;
672
673         throw_exception(ex);
674 }
675
676 extern "C" void __cxa_rethrow_primary_exception(void* thrown_exception)
677 {
678         if (NULL == thrown_exception) { return; }
679
680         __cxa_exception *original = exceptionFromPointer(thrown_exception);
681         __cxa_dependent_exception *ex = ((__cxa_dependent_exception*)__cxa_allocate_dependent_exception())-1;
682
683         ex->primaryException = thrown_exception;
684         __cxa_increment_exception_refcount(thrown_exception);
685
686         ex->exceptionType = original->exceptionType;
687         ex->unwindHeader.exception_class = dependent_exception_class;
688         ex->unwindHeader.exception_cleanup = dependent_exception_cleanup;
689
690         throw_exception((__cxa_exception*)ex);
691 }
692
693 extern "C" void *__cxa_current_primary_exception(void)
694 {
695         __cxa_eh_globals* globals = __cxa_get_globals();
696         __cxa_exception *ex = globals->caughtExceptions;
697
698         if (0 == ex) { return NULL; }
699         ex = realExceptionFromException(ex);
700         __sync_fetch_and_add(&ex->referenceCount, 1);
701         return ex + 1;
702 }
703
704 extern "C" void __cxa_increment_exception_refcount(void* thrown_exception)
705 {
706         if (NULL == thrown_exception) { return; }
707         __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
708         if (isDependentException(ex->unwindHeader.exception_class)) { return; }
709         __sync_fetch_and_add(&ex->referenceCount, 1);
710 }
711 extern "C" void __cxa_decrement_exception_refcount(void* thrown_exception)
712 {
713         if (NULL == thrown_exception) { return; }
714         __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
715         releaseException(ex);
716 }
717
718 /**
719  * ABI function.  Rethrows the current exception.  Does not remove the
720  * exception from the stack or decrement its handler count - the compiler is
721  * expected to set the landing pad for this function to the end of the catch
722  * block, and then call _Unwind_Resume() to continue unwinding once
723  * __cxa_end_catch() has been called and any cleanup code has been run.
724  */
725 extern "C" void __cxa_rethrow()
726 {
727         __cxa_eh_globals *globals = __cxa_get_globals();
728         // Note: We don't remove this from the caught list here, because
729         // __cxa_end_catch will be called when we unwind out of the try block.  We
730         // could probably make this faster by providing an alternative rethrow
731         // function and ensuring that all cleanup code is run before calling it, so
732         // we can skip the top stack frame when unwinding.
733         __cxa_exception *ex = globals->caughtExceptions;
734
735         if (0 == ex)
736         {
737                 fprintf(stderr,
738                         "Attempting to rethrow an exception that doesn't exist!\n");
739                 std::terminate();
740         }
741
742         assert(ex->handlerCount > 0 && "Rethrowing uncaught exception!");
743
744         // ex->handlerCount will be decremented in __cxa_end_catch in enclosing
745         // catch block
746         
747         // Make handler count negative. This will tell __cxa_end_catch that
748         // exception was rethrown and exception object should not be destroyed
749         // when handler count become zero
750         ex->handlerCount = -ex->handlerCount;
751
752         // Continue unwinding the stack with this exception.  This should unwind to
753         // the place in the caller where __cxa_end_catch() is called.  The caller
754         // will then run cleanup code and bounce the exception back with
755         // _Unwind_Resume().
756         _Unwind_Reason_Code err = _Unwind_Resume_or_Rethrow(&ex->unwindHeader);
757         report_failure(err, ex);
758 }
759
760 /**
761  * Returns the type_info object corresponding to the filter.
762  */
763 static std::type_info *get_type_info_entry(_Unwind_Context *context,
764                                            dwarf_eh_lsda *lsda,
765                                            int filter)
766 {
767         // Get the address of the record in the table.
768         dw_eh_ptr_t record = lsda->type_table - 
769                 dwarf_size_of_fixed_size_field(lsda->type_table_encoding)*filter;
770         //record -= 4;
771         dw_eh_ptr_t start = record;
772         // Read the value, but it's probably an indirect reference...
773         int64_t offset = read_value(lsda->type_table_encoding, &record);
774
775         // (If the entry is 0, don't try to dereference it.  That would be bad.)
776         if (offset == 0) { return 0; }
777
778         // ...so we need to resolve it
779         return (std::type_info*)resolve_indirect_value(context,
780                         lsda->type_table_encoding, offset, start);
781 }
782
783
784
785 /**
786  * Checks the type signature found in a handler against the type of the thrown
787  * object.  If ex is 0 then it is assumed to be a foreign exception and only
788  * matches cleanups.
789  */
790 static bool check_type_signature(__cxa_exception *ex,
791                                  const std::type_info *type,
792                                  void *&adjustedPtr)
793 {
794         // TODO: For compatibility with the GNU implementation, we should move this
795         // out into a __do_catch() virtual function in std::type_info
796         void *exception_ptr = (void*)(ex+1);
797     const std::type_info *ex_type = ex->exceptionType;
798
799         const __pointer_type_info *ptr_type =
800                 dynamic_cast<const __pointer_type_info*>(ex_type);
801         if (0 != ptr_type)
802         {
803                 exception_ptr = *(void**)exception_ptr;
804         }
805         // Always match a catchall, even with a foreign exception
806         //
807         // Note: A 0 here is a catchall, not a cleanup, so we return true to
808         // indicate that we found a catch.
809         //
810         // TODO: Provide a class for matching against foreign exceptions.  This is
811         // already done in libobjc2, allowing C++ exceptions to be boxed as
812         // Objective-C objects.  We should do something similar, allowing foreign
813         // exceptions to be wrapped in a C++ exception and delivered.
814         if (0 == type)
815         {
816                 if (ex)
817                 {
818                         adjustedPtr = exception_ptr;
819                 }
820                 return true;
821         }
822
823         if (0 == ex) { return false; }
824
825         const __pointer_type_info *target_ptr_type =
826                 dynamic_cast<const __pointer_type_info*>(type);
827
828         if (0 != ptr_type && 0 != target_ptr_type)
829         {
830                 if (ptr_type->__flags & ~target_ptr_type->__flags)
831                 {
832                         // Handler pointer is less qualified
833                         return false;
834                 }
835
836                 // Special case for void* handler.  
837                 if(*target_ptr_type->__pointee == typeid(void))
838                 {
839                         adjustedPtr = exception_ptr;
840                         return true;
841                 }
842
843                 ex_type = ptr_type->__pointee;
844                 type = target_ptr_type->__pointee;
845         }
846
847         // If the types are the same, no casting is needed.
848         if (*type == *ex_type)
849         {
850                 adjustedPtr = exception_ptr;
851                 return true;
852         }
853
854         const __class_type_info *cls_type =
855                 dynamic_cast<const __class_type_info*>(ex_type);
856         const __class_type_info *target_cls_type =
857                 dynamic_cast<const __class_type_info*>(type);
858
859         if (0 != cls_type &&
860                 0 != target_cls_type &&
861                 cls_type->can_cast_to(target_cls_type))
862         {
863                 adjustedPtr = cls_type->cast_to(exception_ptr, target_cls_type);
864                 return true;
865         }
866         return false;
867 }
868 /**
869  * Checks whether the exception matches the type specifiers in this action
870  * record.  If the exception only matches cleanups, then this returns false.
871  * If it matches a catch (including a catchall) then it returns true.
872  *
873  * The selector argument is used to return the selector that is passed in the
874  * second exception register when installing the context.
875  */
876 static handler_type check_action_record(_Unwind_Context *context,
877                                         dwarf_eh_lsda *lsda,
878                                         dw_eh_ptr_t action_record,
879                                         __cxa_exception *ex,
880                                         unsigned long *selector,
881                                         void *&adjustedPtr)
882 {
883         if (!action_record) { return handler_cleanup; }
884         handler_type found = handler_none;
885         while (action_record)
886         {
887                 int filter = read_sleb128(&action_record);
888                 dw_eh_ptr_t action_record_offset_base = action_record;
889                 int displacement = read_sleb128(&action_record);
890                 action_record = displacement ? 
891                         action_record_offset_base + displacement : 0;
892                 // We only check handler types for C++ exceptions - foreign exceptions
893                 // are only allowed for cleanup.
894                 if (filter > 0 && 0 != ex)
895                 {
896                         std::type_info *handler_type = get_type_info_entry(context, lsda, filter);
897                         if (check_type_signature(ex, handler_type, adjustedPtr))
898                         {
899                                 *selector = filter;
900                                 return handler_catch;
901                         }
902                 }
903                 else if (filter < 0 && 0 != ex)
904                 {
905                         bool matched = false;
906                         *selector = filter;
907 #ifdef __arm__
908                         filter++;
909                         std::type_info *handler_type = get_type_info_entry(context, lsda, filter--);
910                         while (handler_type)
911                         {
912                                 if (check_type_signature(ex, handler_type, adjustedPtr))
913                                 {
914                                         matched = true;
915                                         break;
916                                 }
917                                 handler_type = get_type_info_entry(context, lsda, filter--);
918                         }
919 #else
920                         unsigned char *type_index = ((unsigned char*)lsda->type_table - filter - 1);
921                         while (*type_index)
922                         {
923                                 std::type_info *handler_type = get_type_info_entry(context, lsda, *(type_index++));
924                                 // If the exception spec matches a permitted throw type for
925                                 // this function, don't report a handler - we are allowed to
926                                 // propagate this exception out.
927                                 if (check_type_signature(ex, handler_type, adjustedPtr))
928                                 {
929                                         matched = true;
930                                         break;
931                                 }
932                         }
933 #endif
934                         if (matched) { continue; }
935                         // If we don't find an allowed exception spec, we need to install
936                         // the context for this action.  The landing pad will then call the
937                         // unexpected exception function.  Treat this as a catch
938                         return handler_catch;
939                 }
940                 else if (filter == 0)
941                 {
942                         *selector = filter;
943                         found = handler_cleanup;
944                 }
945         }
946         return found;
947 }
948
949 static void pushCleanupException(_Unwind_Exception *exceptionObject,
950                                  __cxa_exception *ex)
951 {
952 #ifdef __arm__
953         __cxa_thread_info *info = thread_info_fast();
954         if (ex)
955         {
956                 ex->cleanupCount++;
957                 if (ex->cleanupCount > 1)
958                 {
959                         assert(exceptionObject == info->currentCleanup);
960                         return;
961                 }
962                 ex->nextCleanup = info->currentCleanup;
963         }
964         info->currentCleanup = exceptionObject;
965 #endif
966 }
967
968 /**
969  * The exception personality function.  This is referenced in the unwinding
970  * DWARF metadata and is called by the unwind library for each C++ stack frame
971  * containing catch or cleanup code.
972  */
973 extern "C"
974 BEGIN_PERSONALITY_FUNCTION(__gxx_personality_v0)
975         // This personality function is for version 1 of the ABI.  If you use it
976         // with a future version of the ABI, it won't know what to do, so it
977         // reports a fatal error and give up before it breaks anything.
978         if (1 != version)
979         {
980                 return _URC_FATAL_PHASE1_ERROR;
981         }
982         __cxa_exception *ex = 0;
983         __cxa_exception *realEx = 0;
984
985         // If this exception is throw by something else then we can't make any
986         // assumptions about its layout beyond the fields declared in
987         // _Unwind_Exception.
988         bool foreignException = !isCXXException(exceptionClass);
989
990         // If this isn't a foreign exception, then we have a C++ exception structure
991         if (!foreignException)
992         {
993                 ex = exceptionFromPointer(exceptionObject);
994                 realEx = realExceptionFromException(ex);
995         }
996
997         unsigned char *lsda_addr =
998                 (unsigned char*)_Unwind_GetLanguageSpecificData(context);
999
1000         // No LSDA implies no landing pads - try the next frame
1001         if (0 == lsda_addr) { return continueUnwinding(exceptionObject, context); }
1002
1003         // These two variables define how the exception will be handled.
1004         dwarf_eh_action action = {0};
1005         unsigned long selector = 0;
1006         
1007         // During the search phase, we do a complete lookup.  If we return
1008         // _URC_HANDLER_FOUND, then the phase 2 unwind will call this function with
1009         // a _UA_HANDLER_FRAME action, telling us to install the handler frame.  If
1010         // we return _URC_CONTINUE_UNWIND, we may be called again later with a
1011         // _UA_CLEANUP_PHASE action for this frame.
1012         //
1013         // The point of the two-stage unwind allows us to entirely avoid any stack
1014         // unwinding if there is no handler.  If there are just cleanups found,
1015         // then we can just panic call an abort function.
1016         //
1017         // Matching a handler is much more expensive than matching a cleanup,
1018         // because we don't need to bother doing type comparisons (or looking at
1019         // the type table at all) for a cleanup.  This means that there is no need
1020         // to cache the result of finding a cleanup, because it's (quite) quick to
1021         // look it up again from the action table.
1022         if (actions & _UA_SEARCH_PHASE)
1023         {
1024                 struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr);
1025
1026                 if (!dwarf_eh_find_callsite(context, &lsda, &action))
1027                 {
1028                         // EH range not found. This happens if exception is thrown and not
1029                         // caught inside a cleanup (destructor).  We should call
1030                         // terminate() in this case.  The catchTemp (landing pad) field of
1031                         // exception object will contain null when personality function is
1032                         // called with _UA_HANDLER_FRAME action for phase 2 unwinding.  
1033                         return _URC_HANDLER_FOUND;
1034                 }
1035
1036                 handler_type found_handler = check_action_record(context, &lsda,
1037                                 action.action_record, realEx, &selector, ex->adjustedPtr);
1038                 // If there's no action record, we've only found a cleanup, so keep
1039                 // searching for something real
1040                 if (found_handler == handler_catch)
1041                 {
1042                         // Cache the results for the phase 2 unwind, if we found a handler
1043                         // and this is not a foreign exception.
1044                         if (ex)
1045                         {
1046                                 saveLandingPad(context, exceptionObject, ex, selector, action.landing_pad);
1047                                 ex->languageSpecificData = (const char*)lsda_addr;
1048                                 ex->actionRecord = (const char*)action.action_record;
1049                                 // ex->adjustedPtr is set when finding the action record.
1050                         }
1051                         return _URC_HANDLER_FOUND;
1052                 }
1053                 return continueUnwinding(exceptionObject, context);
1054         }
1055
1056
1057         // If this is a foreign exception, we didn't have anywhere to cache the
1058         // lookup stuff, so we need to do it again.  If this is either a forced
1059         // unwind, a foreign exception, or a cleanup, then we just install the
1060         // context for a cleanup.
1061         if (!(actions & _UA_HANDLER_FRAME))
1062         {
1063                 // cleanup
1064                 struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr);
1065                 dwarf_eh_find_callsite(context, &lsda, &action);
1066                 if (0 == action.landing_pad) { return continueUnwinding(exceptionObject, context); }
1067                 handler_type found_handler = check_action_record(context, &lsda,
1068                                 action.action_record, realEx, &selector, ex->adjustedPtr);
1069                 // Ignore handlers this time.
1070                 if (found_handler != handler_cleanup) { return continueUnwinding(exceptionObject, context); }
1071                 pushCleanupException(exceptionObject, ex);
1072         }
1073         else if (foreignException)
1074         {
1075                 struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr);
1076                 dwarf_eh_find_callsite(context, &lsda, &action);
1077                 check_action_record(context, &lsda, action.action_record, realEx,
1078                                 &selector, ex->adjustedPtr);
1079         }
1080         else if (ex->catchTemp == 0)
1081         {
1082                 // Uncaught exception in cleanup, calling terminate
1083                 std::terminate();
1084         }
1085         else
1086         {
1087                 // Restore the saved info if we saved some last time.
1088                 loadLandingPad(context, exceptionObject, ex, &selector, &action.landing_pad);
1089                 ex->catchTemp = 0;
1090                 ex->handlerSwitchValue = 0;
1091         }
1092
1093
1094         _Unwind_SetIP(context, (unsigned long)action.landing_pad);
1095         _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
1096                       (unsigned long)exceptionObject);
1097         _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), selector);
1098
1099         return _URC_INSTALL_CONTEXT;
1100 }
1101
1102 /**
1103  * ABI function called when entering a catch statement.  The argument is the
1104  * pointer passed out of the personality function.  This is always the start of
1105  * the _Unwind_Exception object.  The return value for this function is the
1106  * pointer to the caught exception, which is either the adjusted pointer (for
1107  * C++ exceptions) of the unadjusted pointer (for foreign exceptions).
1108  */
1109 #if __GNUC__ > 3 && __GNUC_MINOR__ > 2
1110 extern "C" void *__cxa_begin_catch(void *e) throw()
1111 #else
1112 extern "C" void *__cxa_begin_catch(void *e)
1113 #endif
1114 {
1115         // Decrement the uncaught exceptions count
1116         __cxa_eh_globals *globals = __cxa_get_globals();
1117         globals->uncaughtExceptions--;
1118         _Unwind_Exception *exceptionObject = (_Unwind_Exception*)e;
1119
1120         if (isCXXException(exceptionObject->exception_class))
1121         {
1122                 __cxa_exception *ex =  exceptionFromPointer(exceptionObject);
1123
1124                 if (ex->handlerCount == 0)
1125                 {
1126                         // Add this to the front of the list of exceptions being handled
1127                         // and increment its handler count so that it won't be deleted
1128                         // prematurely.
1129                         ex->nextException = globals->caughtExceptions;
1130                         globals->caughtExceptions = ex;
1131                 }
1132
1133                 if (ex->handlerCount < 0)
1134                 {
1135                         // Rethrown exception is catched before end of catch block.
1136                         // Clear the rethrow flag (make value positive) - we are allowed
1137                         // to delete this exception at the end of the catch block, as long
1138                         // as it isn't thrown again later.
1139                         
1140                         // Code pattern:
1141                         //
1142                         // try {
1143                         //     throw x;
1144                         // }
1145                         // catch() {
1146                         //     try {
1147                         //         throw;
1148                         //     }
1149                         //     catch() {
1150                         //         __cxa_begin_catch() <- we are here
1151                         //     }
1152                         // }
1153                         ex->handlerCount = -ex->handlerCount + 1;
1154                 }
1155                 else
1156                 {
1157                         ex->handlerCount++;
1158                 }
1159                 
1160                 return ex->adjustedPtr;
1161         }
1162         // exceptionObject is the pointer to the _Unwind_Exception within the
1163         // __cxa_exception.  The throw object is after this
1164         return ((char*)exceptionObject + sizeof(_Unwind_Exception));
1165 }
1166
1167
1168
1169 /**
1170  * ABI function called when exiting a catch block.  This will free the current
1171  * exception if it is no longer referenced in other catch blocks.
1172  */
1173 extern "C" void __cxa_end_catch()
1174 {
1175         // We can call the fast version here because the slow version is called in
1176         // __cxa_throw(), which must have been called before we end a catch block
1177         __cxa_eh_globals *globals = __cxa_get_globals_fast();
1178         __cxa_exception *ex = globals->caughtExceptions;
1179
1180         assert(0 != ex && "Ending catch when no exception is on the stack!");
1181
1182         bool deleteException = true;
1183
1184         if (ex->handlerCount < 0)
1185         {
1186                 // exception was rethrown. Exception should not be deleted even if
1187                 // handlerCount become zero.
1188                 // Code pattern:
1189                 // try {
1190                 //     throw x;
1191                 // }
1192                 // catch() {
1193                 //     {
1194                 //         throw;
1195                 //     }
1196                 //     cleanup {
1197                 //         __cxa_end_catch();   <- we are here
1198                 //     }
1199                 // }
1200                 //
1201                 
1202                 ex->handlerCount++;
1203                 deleteException = false;
1204         }
1205         else
1206         {
1207                 ex->handlerCount--;
1208         }
1209
1210         if (ex->handlerCount == 0)
1211         {
1212                 globals->caughtExceptions = ex->nextException;
1213                 if (deleteException)
1214                 {
1215                         releaseException(ex);
1216                 }
1217         }
1218 }
1219
1220 /**
1221  * ABI function.  Returns the type of the current exception.
1222  */
1223 extern "C" std::type_info *__cxa_current_exception_type()
1224 {
1225         __cxa_eh_globals *globals = __cxa_get_globals();
1226         __cxa_exception *ex = globals->caughtExceptions;
1227         return ex ? ex->exceptionType : 0;
1228 }
1229
1230 /**
1231  * ABI function, called when an exception specification is violated.
1232  *
1233  * This function does not return.
1234  */
1235 extern "C" void __cxa_call_unexpected(void*exception) 
1236 {
1237         _Unwind_Exception *exceptionObject = (_Unwind_Exception*)exception;
1238         if (exceptionObject->exception_class == exception_class)
1239         {
1240                 __cxa_exception *ex =  exceptionFromPointer(exceptionObject);
1241                 if (ex->unexpectedHandler)
1242                 {
1243                         ex->unexpectedHandler();
1244                         // Should not be reached.  
1245                         abort();
1246                 }
1247         }
1248         std::unexpected();
1249         // Should not be reached.  
1250         abort();
1251 }
1252
1253 /**
1254  * ABI function, returns the adjusted pointer to the exception object.
1255  */
1256 extern "C" void *__cxa_get_exception_ptr(void *exceptionObject)
1257 {
1258         return exceptionFromPointer(exceptionObject)->adjustedPtr;
1259 }
1260
1261 /**
1262  * As an extension, we provide the ability for the unexpected and terminate
1263  * handlers to be thread-local.  We default to the standards-compliant
1264  * behaviour where they are global.
1265  */
1266 static bool thread_local_handlers = false;
1267
1268
1269 namespace pathscale
1270 {
1271         /**
1272          * Sets whether unexpected and terminate handlers should be thread-local.
1273          */
1274         void set_use_thread_local_handlers(bool flag) throw()
1275         {
1276                 thread_local_handlers = flag;
1277         }
1278         /**
1279          * Sets a thread-local unexpected handler.  
1280          */
1281         unexpected_handler set_unexpected(unexpected_handler f) throw()
1282         {
1283                 static __cxa_thread_info *info = thread_info();
1284                 unexpected_handler old = info->unexpectedHandler;
1285                 info->unexpectedHandler = f;
1286                 return old;
1287         }
1288         /**
1289          * Sets a thread-local terminate handler.  
1290          */
1291         terminate_handler set_terminate(terminate_handler f) throw()
1292         {
1293                 static __cxa_thread_info *info = thread_info();
1294                 terminate_handler old = info->terminateHandler;
1295                 info->terminateHandler = f;
1296                 return old;
1297         }
1298 }
1299
1300 namespace std
1301 {
1302         /**
1303          * Sets the function that will be called when an exception specification is
1304          * violated.
1305          */
1306         unexpected_handler set_unexpected(unexpected_handler f) throw()
1307         {
1308                 if (thread_local_handlers) { return pathscale::set_unexpected(f); }
1309
1310                 return __sync_lock_test_and_set(&unexpectedHandler, f);
1311         }
1312         /**
1313          * Sets the function that is called to terminate the program.
1314          */
1315         terminate_handler set_terminate(terminate_handler f) throw()
1316         {
1317                 if (thread_local_handlers) { return pathscale::set_terminate(f); }
1318                 return __sync_lock_test_and_set(&terminateHandler, f);
1319         }
1320         /**
1321          * Terminates the program, calling a custom terminate implementation if
1322          * required.
1323          */
1324         void terminate()
1325         {
1326                 static __cxa_thread_info *info = thread_info_fast();
1327                 if (0 != info && 0 != info->terminateHandler)
1328                 {
1329                         info->terminateHandler();
1330                         // Should not be reached - a terminate handler is not expected to
1331                         // return.
1332                         abort();
1333                 }
1334                 terminateHandler();
1335         }
1336         /**
1337          * Called when an unexpected exception is encountered (i.e. an exception
1338          * violates an exception specification).  This calls abort() unless a
1339          * custom handler has been set..
1340          */
1341         void unexpected()
1342         {
1343                 static __cxa_thread_info *info = thread_info_fast();
1344                 if (0 != info && 0 != info->unexpectedHandler)
1345                 {
1346                         info->unexpectedHandler();
1347                         // Should not be reached - a terminate handler is not expected to
1348                         // return.
1349                         abort();
1350                 }
1351                 unexpectedHandler();
1352         }
1353         /**
1354          * Returns whether there are any exceptions currently being thrown that
1355          * have not been caught.  This can occur inside a nested catch statement.
1356          */
1357         bool uncaught_exception() throw()
1358         {
1359                 __cxa_thread_info *info = thread_info();
1360                 return info->globals.uncaughtExceptions != 0;
1361         }
1362         /**
1363          * Returns the current unexpected handler.
1364          */
1365         unexpected_handler get_unexpected() throw()
1366         {
1367                 __cxa_thread_info *info = thread_info();
1368                 if (info->unexpectedHandler)
1369                 {
1370                         return info->unexpectedHandler;
1371                 }
1372                 return unexpectedHandler;
1373         }
1374         /**
1375          * Returns the current terminate handler.
1376          */
1377         terminate_handler get_terminate() throw()
1378         {
1379                 __cxa_thread_info *info = thread_info();
1380                 if (info->terminateHandler)
1381                 {
1382                         return info->terminateHandler;
1383                 }
1384                 return terminateHandler;
1385         }
1386 }
1387 #ifdef __arm__
1388 extern "C" _Unwind_Exception *__cxa_get_cleanup(void)
1389 {
1390         __cxa_thread_info *info = thread_info_fast();
1391         _Unwind_Exception *exceptionObject = info->currentCleanup;
1392         if (isCXXException(exceptionObject->exception_class))
1393         {
1394                 __cxa_exception *ex =  exceptionFromPointer(exceptionObject);
1395                 ex->cleanupCount--;
1396                 if (ex->cleanupCount == 0)
1397                 {
1398                         info->currentCleanup = ex->nextCleanup;
1399                         ex->nextCleanup = 0;
1400                 }
1401         }
1402         else
1403         {
1404                 info->currentCleanup = 0;
1405         }
1406         return exceptionObject;
1407 }
1408
1409 asm (
1410 ".pushsection .text.__cxa_end_cleanup    \n"
1411 ".global __cxa_end_cleanup               \n"
1412 ".type __cxa_end_cleanup, \"function\"   \n"
1413 "__cxa_end_cleanup:                      \n"
1414 "       push {r1, r2, r3, r4}                \n"
1415 "       bl __cxa_get_cleanup                 \n"
1416 "       push {r1, r2, r3, r4}                \n"
1417 "       b _Unwind_Resume                     \n"
1418 "       bl abort                             \n"
1419 ".popsection                             \n"
1420 );
1421 #endif