eh_catch.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // -*- C++ -*- Exception handling routines for catching.
  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 <cstdlib>
  24. #include "unwind-cxx.h"
  25. using namespace __cxxabiv1;
  26. extern "C" void *
  27. __cxxabiv1::__cxa_get_exception_ptr(void *exc_obj_in) _GLIBCXX_NOTHROW
  28. {
  29. _Unwind_Exception *exceptionObject
  30. = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
  31. return __gxx_caught_object(exceptionObject);
  32. }
  33. extern "C" void *
  34. __cxxabiv1::__cxa_begin_catch (void *exc_obj_in) _GLIBCXX_NOTHROW
  35. {
  36. _Unwind_Exception *exceptionObject
  37. = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
  38. __cxa_eh_globals *globals = __cxa_get_globals ();
  39. __cxa_exception *prev = globals->caughtExceptions;
  40. __cxa_exception *header = __get_exception_header_from_ue (exceptionObject);
  41. void* objectp;
  42. // Foreign exceptions can't be stacked here. If the exception stack is
  43. // empty, then fine. Otherwise we really have no choice but to terminate.
  44. // Note that this use of "header" is a lie. It's fine so long as we only
  45. // examine header->unwindHeader though.
  46. if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
  47. {
  48. if (prev != 0)
  49. std::terminate ();
  50. // Remember for end_catch and rethrow.
  51. globals->caughtExceptions = header;
  52. // ??? No sensible value to return; we don't know what the
  53. // object is, much less where it is in relation to the header.
  54. return 0;
  55. }
  56. int count = header->handlerCount;
  57. // Count is less than zero if this exception was rethrown from an
  58. // immediately enclosing region.
  59. if (count < 0)
  60. count = -count + 1;
  61. else
  62. count += 1;
  63. header->handlerCount = count;
  64. globals->uncaughtExceptions -= 1;
  65. if (header != prev)
  66. {
  67. header->nextException = prev;
  68. globals->caughtExceptions = header;
  69. }
  70. objectp = __gxx_caught_object(exceptionObject);
  71. PROBE2 (catch, objectp, header->exceptionType);
  72. #ifdef __ARM_EABI_UNWINDER__
  73. _Unwind_Complete(exceptionObject);
  74. #endif
  75. return objectp;
  76. }
  77. extern "C" void
  78. __cxxabiv1::__cxa_end_catch ()
  79. {
  80. __cxa_eh_globals *globals = __cxa_get_globals_fast ();
  81. __cxa_exception *header = globals->caughtExceptions;
  82. // A rethrow of a foreign exception will be removed from the
  83. // the exception stack immediately by __cxa_rethrow.
  84. if (!header)
  85. return;
  86. // A foreign exception couldn't have been stacked (see above),
  87. // so by definition processing must be complete.
  88. if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
  89. {
  90. globals->caughtExceptions = 0;
  91. _Unwind_DeleteException (&header->unwindHeader);
  92. return;
  93. }
  94. int count = header->handlerCount;
  95. if (count < 0)
  96. {
  97. // This exception was rethrown. Decrement the (inverted) catch
  98. // count and remove it from the chain when it reaches zero.
  99. if (++count == 0)
  100. globals->caughtExceptions = header->nextException;
  101. }
  102. else if (--count == 0)
  103. {
  104. // Handling for this exception is complete. Destroy the object.
  105. globals->caughtExceptions = header->nextException;
  106. _Unwind_DeleteException (&header->unwindHeader);
  107. return;
  108. }
  109. else if (count < 0)
  110. // A bug in the exception handling library or compiler.
  111. std::terminate ();
  112. header->handlerCount = count;
  113. }
  114. bool
  115. std::uncaught_exception() throw()
  116. {
  117. #if __cpp_exceptions
  118. __cxa_eh_globals *globals = __cxa_get_globals ();
  119. return globals->uncaughtExceptions != 0;
  120. #else
  121. return false;
  122. #endif
  123. }
  124. int
  125. std::uncaught_exceptions() throw()
  126. {
  127. #if __cpp_exceptions
  128. __cxa_eh_globals *globals = __cxa_get_globals ();
  129. return globals->uncaughtExceptions;
  130. #else
  131. return 0;
  132. #endif
  133. }