Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*- Exception handling routines for throwing.
  2. // Copyright (C) 2001-2015 Free Software Foundation, Inc.
  3. //
  4. // This file is part of GCC.
  5. //
  6. // GCC is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10. //
  11. // GCC is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15. //
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. #include <bits/c++config.h>
  26. #include "unwind-cxx.h"
  27.  
  28. using namespace __cxxabiv1;
  29.  
  30.  
  31. static void
  32. __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc)
  33. {
  34.   // This cleanup is set only for primaries.
  35.   __cxa_refcounted_exception *header
  36.     = __get_refcounted_exception_header_from_ue (exc);
  37.  
  38.   // We only want to be called through _Unwind_DeleteException.
  39.   // _Unwind_DeleteException in the HP-UX IA64 libunwind library
  40.   // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT
  41.   // like the GCC _Unwind_DeleteException function does.
  42.   if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)
  43.     __terminate (header->exc.terminateHandler);
  44.  
  45. #if ATOMIC_INT_LOCK_FREE > 1
  46.   if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0)
  47.     {
  48. #endif
  49.       if (header->exc.exceptionDestructor)
  50.         header->exc.exceptionDestructor (header + 1);
  51.  
  52.       __cxa_free_exception (header + 1);
  53. #if ATOMIC_INT_LOCK_FREE > 1
  54.     }
  55. #endif
  56. }
  57.  
  58.  
  59. extern "C" void
  60. __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
  61.                          void (_GLIBCXX_CDTOR_CALLABI *dest) (void *))
  62. {
  63.   PROBE2 (throw, obj, tinfo);
  64.  
  65.   __cxa_eh_globals *globals = __cxa_get_globals ();
  66.   globals->uncaughtExceptions += 1;
  67.  
  68.   // Definitely a primary.
  69.   __cxa_refcounted_exception *header
  70.     = __get_refcounted_exception_header_from_obj (obj);
  71.   header->referenceCount = 1;
  72.   header->exc.exceptionType = tinfo;
  73.   header->exc.exceptionDestructor = dest;
  74.   header->exc.unexpectedHandler = std::get_unexpected ();
  75.   header->exc.terminateHandler = std::get_terminate ();
  76.   __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class);
  77.   header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup;
  78.  
  79. #ifdef _GLIBCXX_SJLJ_EXCEPTIONS
  80.   _Unwind_SjLj_RaiseException (&header->exc.unwindHeader);
  81. #else
  82.   _Unwind_RaiseException (&header->exc.unwindHeader);
  83. #endif
  84.  
  85.   // Some sort of unwinding error.  Note that terminate is a handler.
  86.   __cxa_begin_catch (&header->exc.unwindHeader);
  87.   std::terminate ();
  88. }
  89.  
  90. extern "C" void
  91. __cxxabiv1::__cxa_rethrow ()
  92. {
  93.   __cxa_eh_globals *globals = __cxa_get_globals ();
  94.   __cxa_exception *header = globals->caughtExceptions;
  95.  
  96.   globals->uncaughtExceptions += 1;
  97.  
  98.   // Watch for luser rethrowing with no active exception.
  99.   if (header)
  100.     {
  101.       // Tell __cxa_end_catch this is a rethrow.
  102.       if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
  103.         globals->caughtExceptions = 0;
  104.       else
  105.         {
  106.           header->handlerCount = -header->handlerCount;
  107.           // Only notify probe for C++ exceptions.
  108.           PROBE2 (rethrow, __get_object_from_ambiguous_exception(header),
  109.                   header->exceptionType);
  110.         }
  111.  
  112. #ifdef _GLIBCXX_SJLJ_EXCEPTIONS
  113.       _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader);
  114. #else
  115. #if defined(_LIBUNWIND_STD_ABI)
  116.       _Unwind_RaiseException (&header->unwindHeader);
  117. #else
  118.       _Unwind_Resume_or_Rethrow (&header->unwindHeader);
  119. #endif
  120. #endif
  121.  
  122.       // Some sort of unwinding error.  Note that terminate is a handler.
  123.       __cxa_begin_catch (&header->unwindHeader);
  124.     }
  125.   std::terminate ();
  126. }
  127.