Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*- Helpers for calling unextected and terminate
  2. // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
  3. // 2011
  4. // Free Software Foundation, Inc.
  5. //
  6. // This file is part of GCC.
  7. //
  8. // GCC is free software; you can redistribute it and/or modify
  9. // it under the terms of the GNU General Public License as published by
  10. // the Free Software Foundation; either version 3, or (at your option)
  11. // any later version.
  12. //
  13. // GCC is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. // GNU General Public License for more details.
  17. //
  18. // Under Section 7 of GPL version 3, you are granted additional
  19. // permissions described in the GCC Runtime Library Exception, version
  20. // 3.1, as published by the Free Software Foundation.
  21.  
  22. // You should have received a copy of the GNU General Public License and
  23. // a copy of the GCC Runtime Library Exception along with this program;
  24. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  25. // <http://www.gnu.org/licenses/>.
  26.  
  27. #include <bits/c++config.h>
  28. #include <cstdlib>
  29. #include <bits/exception_defines.h>
  30. #include "unwind-cxx.h"
  31.  
  32. using namespace __cxxabiv1;
  33.  
  34. #include "unwind-pe.h"
  35.  
  36.  
  37. // Helper routine for when the exception handling code needs to call
  38. // terminate.
  39.  
  40. extern "C" void
  41. __cxa_call_terminate(_Unwind_Exception* ue_header) throw ()
  42. {
  43.  
  44.   if (ue_header)
  45.     {
  46.       // terminate is classed as a catch handler.
  47.       __cxa_begin_catch(ue_header);
  48.  
  49.       // Call the terminate handler that was in effect when we threw this
  50.       // exception.  */
  51.       if (__is_gxx_exception_class(ue_header->exception_class))
  52.         {
  53.           __cxa_exception* xh;
  54.  
  55.           xh = __get_exception_header_from_ue(ue_header);
  56.           __terminate(xh->terminateHandler);
  57.         }
  58.     }
  59.   /* Call the global routine if we don't have anything better.  */
  60.   std::terminate();
  61. }
  62.  
  63.  
  64. #ifdef __ARM_EABI_UNWINDER__
  65. // The ARM EABI __cxa_call_unexpected has the same semantics as the generic
  66. // routine, but the exception specification has a different format.
  67. extern "C" void
  68. __cxa_call_unexpected(void* exc_obj_in)
  69. {
  70.   _Unwind_Exception* exc_obj
  71.     = reinterpret_cast<_Unwind_Exception*>(exc_obj_in);
  72.  
  73.   int rtti_count = 0;
  74.   _Unwind_Word rtti_stride = 0;
  75.   _Unwind_Word* rtti_list = NULL;
  76.   _Unwind_Ptr rtti_base = 0;
  77.   bool foreign_exception;
  78.   std::unexpected_handler unexpectedHandler = NULL;
  79.   std::terminate_handler terminateHandler = NULL;
  80.   __cxa_exception* xh;
  81.   if (__is_gxx_exception_class(exc_obj->exception_class))
  82.     {
  83.       // Save data from the EO, which may be clobbered by _cxa_begin_catch.
  84.       xh = __get_exception_header_from_ue(exc_obj);
  85.       unexpectedHandler = xh->unexpectedHandler;
  86.       terminateHandler = xh->terminateHandler;
  87.       rtti_count = exc_obj->barrier_cache.bitpattern[1];
  88.       rtti_base = (_Unwind_Ptr) exc_obj->barrier_cache.bitpattern[2];
  89.       rtti_stride = exc_obj->barrier_cache.bitpattern[3];
  90.       rtti_list = (_Unwind_Word*) exc_obj->barrier_cache.bitpattern[4];
  91.       foreign_exception = false;
  92.     }
  93.   else
  94.     foreign_exception = true;
  95.  
  96.   /* This must be called after extracting data from the EO, but before
  97.      calling unexpected().   */
  98.   __cxa_begin_catch(exc_obj);
  99.  
  100.   // This function is a handler for our exception argument.  If we exit
  101.   // by throwing a different exception, we'll need the original cleaned up.
  102.   struct end_catch_protect
  103.   {
  104.     end_catch_protect() { }
  105.     ~end_catch_protect() { __cxa_end_catch(); }
  106.   } end_catch_protect_obj;
  107.  
  108.  
  109.   __try
  110.     {
  111.       if (foreign_exception)
  112.         std::unexpected();
  113.       else
  114.         __unexpected(unexpectedHandler);
  115.     }
  116.   __catch(...)
  117.     {
  118.       /* See if the new exception matches the rtti list.  */
  119.       if (foreign_exception)
  120.         std::terminate();
  121.  
  122.       // Get the exception thrown from unexpected.
  123.  
  124.       __cxa_eh_globals* globals = __cxa_get_globals_fast();
  125.       __cxa_exception* new_xh = globals->caughtExceptions;
  126.       void* new_ptr = __get_object_from_ambiguous_exception (new_xh);
  127.       const std::type_info* catch_type;
  128.       int n;
  129.       bool bad_exception_allowed = false;
  130.       const std::type_info& bad_exc = typeid(std::bad_exception);
  131.  
  132.       // Check the new exception against the rtti list
  133.       for (n = 0; n < rtti_count; n++)
  134.         {
  135.           _Unwind_Word offset;
  136.  
  137.           offset = (_Unwind_Word) &rtti_list[n * (rtti_stride >> 2)];
  138.           offset = _Unwind_decode_typeinfo_ptr(rtti_base, offset);
  139.           catch_type = (const std::type_info*) (offset);
  140.  
  141.           if (__cxa_type_match(&new_xh->unwindHeader, catch_type, false,
  142.                                &new_ptr) != ctm_failed)
  143.             __throw_exception_again;
  144.  
  145.           if (catch_type->__do_catch(&bad_exc, 0, 1))
  146.             bad_exception_allowed = true;
  147.         }
  148.  
  149.       // If the exception spec allows std::bad_exception, throw that.
  150. #ifdef __EXCEPTIONS  
  151.       if (bad_exception_allowed)
  152.         throw std::bad_exception();
  153. #endif  
  154.  
  155.       // Otherwise, die.
  156.       __terminate(terminateHandler);
  157.     }
  158. }
  159. #endif // __ARM_EABI_UNWINDER__
  160.