eh_call.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // -*- C++ -*- Helpers for calling unextected and terminate
  2. // Copyright (C) 2001-2022 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. // You should have received a copy of the GNU General Public License and
  20. // a copy of the GCC Runtime Library Exception along with this program;
  21. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  22. // <http://www.gnu.org/licenses/>.
  23. #include <bits/c++config.h>
  24. #include <cstdlib>
  25. #include <bits/exception_defines.h>
  26. #include "unwind-cxx.h"
  27. using namespace __cxxabiv1;
  28. #include "unwind-pe.h"
  29. // Helper routine for when the exception handling code needs to call
  30. // terminate.
  31. extern "C" void
  32. __cxa_call_terminate(_Unwind_Exception* ue_header) throw ()
  33. {
  34. if (ue_header)
  35. {
  36. // terminate is classed as a catch handler.
  37. __cxa_begin_catch(ue_header);
  38. // Call the terminate handler that was in effect when we threw this
  39. // exception. */
  40. if (__is_gxx_exception_class(ue_header->exception_class))
  41. {
  42. __cxa_exception* xh;
  43. xh = __get_exception_header_from_ue(ue_header);
  44. __terminate(xh->terminateHandler);
  45. }
  46. }
  47. /* Call the global routine if we don't have anything better. */
  48. std::terminate();
  49. }
  50. #ifdef __ARM_EABI_UNWINDER__
  51. // The ARM EABI __cxa_call_unexpected has the same semantics as the generic
  52. // routine, but the exception specification has a different format.
  53. extern "C" void
  54. __cxa_call_unexpected(void* exc_obj_in)
  55. {
  56. _Unwind_Exception* exc_obj
  57. = reinterpret_cast<_Unwind_Exception*>(exc_obj_in);
  58. int rtti_count = 0;
  59. _Unwind_Word rtti_stride = 0;
  60. _Unwind_Word* rtti_list = NULL;
  61. _Unwind_Ptr rtti_base = 0;
  62. bool foreign_exception;
  63. std::unexpected_handler unexpectedHandler = NULL;
  64. std::terminate_handler terminateHandler = NULL;
  65. __cxa_exception* xh;
  66. if (__is_gxx_exception_class(exc_obj->exception_class))
  67. {
  68. // Save data from the EO, which may be clobbered by _cxa_begin_catch.
  69. xh = __get_exception_header_from_ue(exc_obj);
  70. unexpectedHandler = xh->unexpectedHandler;
  71. terminateHandler = xh->terminateHandler;
  72. rtti_count = exc_obj->barrier_cache.bitpattern[1];
  73. rtti_base = (_Unwind_Ptr) exc_obj->barrier_cache.bitpattern[2];
  74. rtti_stride = exc_obj->barrier_cache.bitpattern[3];
  75. rtti_list = (_Unwind_Word*) exc_obj->barrier_cache.bitpattern[4];
  76. foreign_exception = false;
  77. }
  78. else
  79. foreign_exception = true;
  80. /* This must be called after extracting data from the EO, but before
  81. calling unexpected(). */
  82. __cxa_begin_catch(exc_obj);
  83. // This function is a handler for our exception argument. If we exit
  84. // by throwing a different exception, we'll need the original cleaned up.
  85. struct end_catch_protect
  86. {
  87. end_catch_protect() { }
  88. ~end_catch_protect() { __cxa_end_catch(); }
  89. } end_catch_protect_obj;
  90. __try
  91. {
  92. if (foreign_exception)
  93. std::unexpected();
  94. else
  95. __unexpected(unexpectedHandler);
  96. }
  97. __catch(...)
  98. {
  99. /* See if the new exception matches the rtti list. */
  100. if (foreign_exception)
  101. std::terminate();
  102. // Get the exception thrown from unexpected.
  103. __cxa_eh_globals* globals = __cxa_get_globals_fast();
  104. __cxa_exception* new_xh = globals->caughtExceptions;
  105. void* new_ptr = __get_object_from_ambiguous_exception (new_xh);
  106. const std::type_info* catch_type;
  107. int n;
  108. bool bad_exception_allowed __attribute__((unused)) = false;
  109. const std::type_info& bad_exc = typeid(std::bad_exception);
  110. // Check the new exception against the rtti list
  111. for (n = 0; n < rtti_count; n++)
  112. {
  113. _Unwind_Word offset;
  114. offset = (_Unwind_Word) &rtti_list[n * (rtti_stride >> 2)];
  115. offset = _Unwind_decode_typeinfo_ptr(rtti_base, offset);
  116. catch_type = (const std::type_info*) (offset);
  117. if (__cxa_type_match(&new_xh->unwindHeader, catch_type, false,
  118. &new_ptr) != ctm_failed)
  119. { __throw_exception_again; }
  120. // If the exception spec allows std::bad_exception, throw that.
  121. // We don't have a thrown object to compare against, but since
  122. // bad_exception doesn't have virtual bases, that's OK; just pass NULL.
  123. void* obj = NULL;
  124. if (catch_type->__do_catch(&bad_exc, &obj, 1))
  125. bad_exception_allowed = true;
  126. }
  127. // If the exception spec allows std::bad_exception, throw that.
  128. #if __cpp_exceptions
  129. if (bad_exception_allowed)
  130. throw std::bad_exception();
  131. #endif
  132. // Otherwise, die.
  133. __terminate(terminateHandler);
  134. }
  135. }
  136. #endif // __ARM_EABI_UNWINDER__