Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*- Exception handling and frame unwind runtime interface routines.
  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. // This is derived from the C++ ABI for IA-64.  Where we diverge
  26. // for cross-architecture compatibility are noted with "@@@".
  27.  
  28. #ifndef _UNWIND_CXX_H
  29. #define _UNWIND_CXX_H 1
  30.  
  31. // Level 2: C++ ABI
  32.  
  33. #include <typeinfo>
  34. #include <exception>
  35. #include <cstddef>
  36. #include "unwind.h"
  37. #include <bits/atomic_word.h>
  38. #include <cxxabi.h>
  39.  
  40. #ifdef _GLIBCXX_HAVE_SYS_SDT_H
  41. #include <sys/sdt.h>
  42. /* We only want to use stap probes starting with v3.  Earlier versions
  43.    added too much startup cost.  */
  44. #if defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
  45. #define PROBE2(name, arg1, arg2) STAP_PROBE2 (libstdcxx, name, arg1, arg2)
  46. #endif
  47. #endif
  48.  
  49. #ifndef PROBE2
  50. #define PROBE2(name, arg1, arg2)
  51. #endif
  52.  
  53. #pragma GCC visibility push(default)
  54.  
  55. namespace __cxxabiv1
  56. {
  57.  
  58. // A primary C++ exception object consists of a header, which is a wrapper
  59. // around an unwind object header with additional C++ specific information,
  60. // followed by the exception object itself.
  61.  
  62. struct __cxa_exception
  63. {
  64.   // Manage the exception object itself.
  65.   std::type_info *exceptionType;
  66.   void (_GLIBCXX_CDTOR_CALLABI *exceptionDestructor)(void *);
  67.  
  68.   // The C++ standard has entertaining rules wrt calling set_terminate
  69.   // and set_unexpected in the middle of the exception cleanup process.
  70.   std::unexpected_handler unexpectedHandler;
  71.   std::terminate_handler terminateHandler;
  72.  
  73.   // The caught exception stack threads through here.
  74.   __cxa_exception *nextException;
  75.  
  76.   // How many nested handlers have caught this exception.  A negated
  77.   // value is a signal that this object has been rethrown.
  78.   int handlerCount;
  79.  
  80. #ifdef __ARM_EABI_UNWINDER__
  81.   // Stack of exceptions in cleanups.
  82.   __cxa_exception* nextPropagatingException;
  83.  
  84.   // The number of active cleanup handlers for this exception.
  85.   int propagationCount;
  86. #else
  87.   // Cache parsed handler data from the personality routine Phase 1
  88.   // for Phase 2 and __cxa_call_unexpected.
  89.   int handlerSwitchValue;
  90.   const unsigned char *actionRecord;
  91.   const unsigned char *languageSpecificData;
  92.   _Unwind_Ptr catchTemp;
  93.   void *adjustedPtr;
  94. #endif
  95.  
  96.   // The generic exception header.  Must be last.
  97.   _Unwind_Exception unwindHeader;
  98. };
  99.  
  100. struct __cxa_refcounted_exception
  101. {
  102.   // Manage this header.
  103.   _Atomic_word referenceCount;
  104.   // __cxa_exception must be last, and no padding can be after it.
  105.   __cxa_exception exc;
  106. };
  107.  
  108. // A dependent C++ exception object consists of a wrapper around an unwind
  109. // object header with additional C++ specific information, containing a pointer
  110. // to a primary exception object.
  111.  
  112. struct __cxa_dependent_exception
  113. {
  114.   // The primary exception this thing depends on.
  115.   void *primaryException;
  116.  
  117.   // Unused member to get similar layout to __cxa_exception, otherwise the
  118.   // alignment requirements of _Unwind_Exception would require padding bytes
  119.   // before the unwindHeader member.
  120.   void (_GLIBCXX_CDTOR_CALLABI *__padding)(void *);
  121.  
  122.   // The C++ standard has entertaining rules wrt calling set_terminate
  123.   // and set_unexpected in the middle of the exception cleanup process.
  124.   std::unexpected_handler unexpectedHandler;
  125.   std::terminate_handler terminateHandler;
  126.  
  127.   // The caught exception stack threads through here.
  128.   __cxa_exception *nextException;
  129.  
  130.   // How many nested handlers have caught this exception.  A negated
  131.   // value is a signal that this object has been rethrown.
  132.   int handlerCount;
  133.  
  134. #ifdef __ARM_EABI_UNWINDER__
  135.   // Stack of exceptions in cleanups.
  136.   __cxa_exception* nextPropagatingException;
  137.  
  138.   // The number of active cleanup handlers for this exception.
  139.   int propagationCount;
  140. #else
  141.   // Cache parsed handler data from the personality routine Phase 1
  142.   // for Phase 2 and __cxa_call_unexpected.
  143.   int handlerSwitchValue;
  144.   const unsigned char *actionRecord;
  145.   const unsigned char *languageSpecificData;
  146.   _Unwind_Ptr catchTemp;
  147.   void *adjustedPtr;
  148. #endif
  149.  
  150.   // The generic exception header.  Must be last.
  151.   _Unwind_Exception unwindHeader;
  152. };
  153.  
  154. // Each thread in a C++ program has access to a __cxa_eh_globals object.
  155. struct __cxa_eh_globals
  156. {
  157.   __cxa_exception *caughtExceptions;
  158.   unsigned int uncaughtExceptions;
  159. #ifdef __ARM_EABI_UNWINDER__
  160.   __cxa_exception* propagatingExceptions;
  161. #endif
  162. };
  163.  
  164. // @@@ These are not directly specified by the IA-64 C++ ABI.
  165.  
  166. // Handles re-checking the exception specification if unexpectedHandler
  167. // throws, and if bad_exception needs to be thrown.  Called from the
  168. // compiler.
  169. extern "C" void __cxa_call_unexpected (void *) __attribute__((__noreturn__));
  170. extern "C" void __cxa_call_terminate (_Unwind_Exception*) throw ()
  171.   __attribute__((__noreturn__));
  172.  
  173. #ifdef __ARM_EABI_UNWINDER__
  174. // Arm EABI specified routines.
  175. typedef enum {
  176.   ctm_failed = 0,
  177.   ctm_succeeded = 1,
  178.   ctm_succeeded_with_ptr_to_base = 2
  179. } __cxa_type_match_result;
  180. extern "C" __cxa_type_match_result __cxa_type_match(_Unwind_Exception*,
  181.                                                     const std::type_info*,
  182.                                                     bool, void**);
  183. extern "C" bool __cxa_begin_cleanup (_Unwind_Exception*);
  184. extern "C" void __cxa_end_cleanup (void);
  185. #endif
  186.  
  187. // Handles cleanup from transactional memory restart.
  188. extern "C" void __cxa_tm_cleanup (void *, void *, unsigned int) throw();
  189.  
  190. // Invokes given handler, dying appropriately if the user handler was
  191. // so inconsiderate as to return.
  192. extern void __terminate(std::terminate_handler) throw ()
  193.   __attribute__((__noreturn__));
  194. extern void __unexpected(std::unexpected_handler)
  195.   __attribute__((__noreturn__));
  196.  
  197. // The current installed user handlers.
  198. extern std::terminate_handler __terminate_handler;
  199. extern std::unexpected_handler __unexpected_handler;
  200.  
  201. // These are explicitly GNU C++ specific.
  202.  
  203. // Acquire the C++ exception header from the C++ object.
  204. static inline __cxa_exception *
  205. __get_exception_header_from_obj (void *ptr)
  206. {
  207.   return reinterpret_cast<__cxa_exception *>(ptr) - 1;
  208. }
  209.  
  210. // Acquire the C++ exception header from the generic exception header.
  211. static inline __cxa_exception *
  212. __get_exception_header_from_ue (_Unwind_Exception *exc)
  213. {
  214.   return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;
  215. }
  216.  
  217. // Acquire the C++ refcounted exception header from the C++ object.
  218. static inline __cxa_refcounted_exception *
  219. __get_refcounted_exception_header_from_obj (void *ptr)
  220. {
  221.   return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1;
  222. }
  223.  
  224. // Acquire the C++ refcounted exception header from the generic exception
  225. // header.
  226. static inline __cxa_refcounted_exception *
  227. __get_refcounted_exception_header_from_ue (_Unwind_Exception *exc)
  228. {
  229.   return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1;
  230. }
  231.  
  232. static inline __cxa_dependent_exception *
  233. __get_dependent_exception_from_ue (_Unwind_Exception *exc)
  234. {
  235.   return reinterpret_cast<__cxa_dependent_exception *>(exc + 1) - 1;
  236. }
  237.  
  238. #ifdef __ARM_EABI_UNWINDER__
  239. static inline bool
  240. __is_gxx_exception_class(_Unwind_Exception_Class c)
  241. {
  242.   // TODO: Take advantage of the fact that c will always be word aligned.
  243.   return c[0] == 'G'
  244.          && c[1] == 'N'
  245.          && c[2] == 'U'
  246.          && c[3] == 'C'
  247.          && c[4] == 'C'
  248.          && c[5] == '+'
  249.          && c[6] == '+'
  250.          && (c[7] == '\0' || c[7] == '\x01');
  251. }
  252.  
  253. // Only checks for primary or dependent, but not that it is a C++ exception at
  254. // all.
  255. static inline bool
  256. __is_dependent_exception(_Unwind_Exception_Class c)
  257. {
  258.   return c[7] == '\x01';
  259. }
  260.  
  261. static inline void
  262. __GXX_INIT_PRIMARY_EXCEPTION_CLASS(_Unwind_Exception_Class c)
  263. {
  264.   c[0] = 'G';
  265.   c[1] = 'N';
  266.   c[2] = 'U';
  267.   c[3] = 'C';
  268.   c[4] = 'C';
  269.   c[5] = '+';
  270.   c[6] = '+';
  271.   c[7] = '\0';
  272. }
  273.  
  274. static inline void
  275. __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(_Unwind_Exception_Class c)
  276. {
  277.   c[0] = 'G';
  278.   c[1] = 'N';
  279.   c[2] = 'U';
  280.   c[3] = 'C';
  281.   c[4] = 'C';
  282.   c[5] = '+';
  283.   c[6] = '+';
  284.   c[7] = '\x01';
  285. }
  286.  
  287. static inline bool
  288. __is_gxx_forced_unwind_class(_Unwind_Exception_Class c)
  289. {
  290.   return c[0] == 'G'
  291.          && c[1] == 'N'
  292.          && c[2] == 'U'
  293.          && c[3] == 'C'
  294.          && c[4] == 'F'
  295.          && c[5] == 'O'
  296.          && c[6] == 'R'
  297.          && c[7] == '\0';
  298. }
  299.  
  300. static inline void
  301. __GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c)
  302. {
  303.   c[0] = 'G';
  304.   c[1] = 'N';
  305.   c[2] = 'U';
  306.   c[3] = 'C';
  307.   c[4] = 'F';
  308.   c[5] = 'O';
  309.   c[6] = 'R';
  310.   c[7] = '\0';
  311. }
  312.  
  313. static inline void*
  314. __gxx_caught_object(_Unwind_Exception* eo)
  315. {
  316.   return (void*)eo->barrier_cache.bitpattern[0];
  317. }
  318. #else // !__ARM_EABI_UNWINDER__
  319. // This is the primary exception class we report -- "GNUCC++\0".
  320. const _Unwind_Exception_Class __gxx_primary_exception_class
  321. = ((((((((_Unwind_Exception_Class) 'G'
  322.          << 8 | (_Unwind_Exception_Class) 'N')
  323.         << 8 | (_Unwind_Exception_Class) 'U')
  324.        << 8 | (_Unwind_Exception_Class) 'C')
  325.       << 8 | (_Unwind_Exception_Class) 'C')
  326.      << 8 | (_Unwind_Exception_Class) '+')
  327.     << 8 | (_Unwind_Exception_Class) '+')
  328.    << 8 | (_Unwind_Exception_Class) '\0');
  329.  
  330. // This is the dependent (from std::rethrow_exception) exception class we report
  331. // "GNUCC++\x01"
  332. const _Unwind_Exception_Class __gxx_dependent_exception_class
  333. = ((((((((_Unwind_Exception_Class) 'G'
  334.          << 8 | (_Unwind_Exception_Class) 'N')
  335.         << 8 | (_Unwind_Exception_Class) 'U')
  336.        << 8 | (_Unwind_Exception_Class) 'C')
  337.       << 8 | (_Unwind_Exception_Class) 'C')
  338.      << 8 | (_Unwind_Exception_Class) '+')
  339.     << 8 | (_Unwind_Exception_Class) '+')
  340.    << 8 | (_Unwind_Exception_Class) '\x01');
  341.  
  342. static inline bool
  343. __is_gxx_exception_class(_Unwind_Exception_Class c)
  344. {
  345.   return c == __gxx_primary_exception_class
  346.       || c == __gxx_dependent_exception_class;
  347. }
  348.  
  349. // Only checks for primary or dependent, but not that it is a C++ exception at
  350. // all.
  351. static inline bool
  352. __is_dependent_exception(_Unwind_Exception_Class c)
  353. {
  354.   return (c & 1);
  355. }
  356.  
  357. #define __GXX_INIT_PRIMARY_EXCEPTION_CLASS(c) c = __gxx_primary_exception_class
  358. #define __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(c) \
  359.   c = __gxx_dependent_exception_class
  360.  
  361. // GNU C++ personality routine, Version 0.
  362. extern "C" _Unwind_Reason_Code __gxx_personality_v0
  363.      (int, _Unwind_Action, _Unwind_Exception_Class,
  364.       struct _Unwind_Exception *, struct _Unwind_Context *);
  365.  
  366. // GNU C++ sjlj personality routine, Version 0.
  367. extern "C" _Unwind_Reason_Code __gxx_personality_sj0
  368.      (int, _Unwind_Action, _Unwind_Exception_Class,
  369.       struct _Unwind_Exception *, struct _Unwind_Context *);
  370.  
  371. static inline void*
  372. __gxx_caught_object(_Unwind_Exception* eo)
  373. {
  374.   // Bad as it looks, this actually works for dependent exceptions too.
  375.   __cxa_exception* header = __get_exception_header_from_ue (eo);
  376.   return header->adjustedPtr;
  377. }
  378. #endif // !__ARM_EABI_UNWINDER__
  379.  
  380. static inline void*
  381. __get_object_from_ue(_Unwind_Exception* eo) throw()
  382. {
  383.   return __is_dependent_exception (eo->exception_class) ?
  384.     __get_dependent_exception_from_ue (eo)->primaryException :
  385.     eo + 1;
  386. }
  387.  
  388. static inline void *
  389. __get_object_from_ambiguous_exception(__cxa_exception *p_or_d) throw()
  390. {
  391.         return __get_object_from_ue (&p_or_d->unwindHeader);
  392. }
  393.  
  394.  
  395. } /* namespace __cxxabiv1 */
  396.  
  397. #pragma GCC visibility pop
  398.  
  399. #endif // _UNWIND_CXX_H
  400.