Subversion Repositories Kolibri OS

Rev

Rev 5134 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. // -*- C++ -*- The GNU C++ exception personality routine.
  2. // Copyright (C) 2001-2013 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 <cstdlib>
  27. #include <bits/exception_defines.h>
  28. #include <cxxabi.h>
  29. #include "unwind-cxx.h"
  30.  
  31.  
  32. using namespace __cxxabiv1;
  33.  
  34. #include "unwind-pe.h"
  35.  
  36. struct lsda_header_info
  37. {
  38.   _Unwind_Ptr Start;
  39.   _Unwind_Ptr LPStart;
  40.   _Unwind_Ptr ttype_base;
  41.   const unsigned char *TType;
  42.   const unsigned char *action_table;
  43.   unsigned char ttype_encoding;
  44.   unsigned char call_site_encoding;
  45. };
  46.  
  47. static const unsigned char *
  48. parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
  49.                    lsda_header_info *info)
  50. {
  51.   _uleb128_t tmp;
  52.   unsigned char lpstart_encoding;
  53.  
  54.   info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
  55.  
  56.   // Find @LPStart, the base to which landing pad offsets are relative.
  57.   lpstart_encoding = *p++;
  58.   if (lpstart_encoding != DW_EH_PE_omit)
  59.     p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
  60.   else
  61.     info->LPStart = info->Start;
  62.  
  63.   // Find @TType, the base of the handler and exception spec type data.
  64.   info->ttype_encoding = *p++;
  65.   if (info->ttype_encoding != DW_EH_PE_omit)
  66.     {
  67. #if _GLIBCXX_OVERRIDE_TTYPE_ENCODING
  68.       /* Older ARM EABI toolchains set this value incorrectly, so use a
  69.          hardcoded OS-specific format.  */
  70.       info->ttype_encoding = _GLIBCXX_OVERRIDE_TTYPE_ENCODING;
  71. #endif
  72.       p = read_uleb128 (p, &tmp);
  73.       info->TType = p + tmp;
  74.     }
  75.   else
  76.     info->TType = 0;
  77.  
  78.   // The encoding and length of the call-site table; the action table
  79.   // immediately follows.
  80.   info->call_site_encoding = *p++;
  81.   p = read_uleb128 (p, &tmp);
  82.   info->action_table = p + tmp;
  83.  
  84.   return p;
  85. }
  86.  
  87. // Return an element from a type table.
  88.  
  89. static const std::type_info *
  90. get_ttype_entry (lsda_header_info *info, _uleb128_t i)
  91. {
  92.   _Unwind_Ptr ptr;
  93.  
  94.   i *= size_of_encoded_value (info->ttype_encoding);
  95.   read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
  96.                                 info->TType - i, &ptr);
  97.  
  98.   return reinterpret_cast<const std::type_info *>(ptr);
  99. }
  100.  
  101. #ifdef __ARM_EABI_UNWINDER__
  102.  
  103. // The ABI provides a routine for matching exception object types.
  104. typedef _Unwind_Control_Block _throw_typet;
  105. #define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \
  106.   (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \
  107.    != ctm_failed)
  108.  
  109. // Return true if THROW_TYPE matches one if the filter types.
  110.  
  111. static bool
  112. check_exception_spec(lsda_header_info* info, _throw_typet* throw_type,
  113.                      void* thrown_ptr, _sleb128_t filter_value)
  114. {
  115.   const _uleb128_t* e = ((const _uleb128_t*) info->TType)
  116.                           - filter_value - 1;
  117.  
  118.   while (1)
  119.     {
  120.       const std::type_info* catch_type;
  121.       _uleb128_t tmp;
  122.  
  123.       tmp = *e;
  124.      
  125.       // Zero signals the end of the list.  If we've not found
  126.       // a match by now, then we've failed the specification.
  127.       if (tmp == 0)
  128.         return false;
  129.  
  130.       tmp = _Unwind_decode_typeinfo_ptr(info->ttype_base, (_Unwind_Word) e);
  131.  
  132.       // Match a ttype entry.
  133.       catch_type = reinterpret_cast<const std::type_info*>(tmp);
  134.  
  135.       // ??? There is currently no way to ask the RTTI code about the
  136.       // relationship between two types without reference to a specific
  137.       // object.  There should be; then we wouldn't need to mess with
  138.       // thrown_ptr here.
  139.       if (get_adjusted_ptr(catch_type, throw_type, &thrown_ptr))
  140.         return true;
  141.  
  142.       // Advance to the next entry.
  143.       e++;
  144.     }
  145. }
  146.  
  147.  
  148. // Save stage1 handler information in the exception object
  149.  
  150. static inline void
  151. save_caught_exception(struct _Unwind_Exception* ue_header,
  152.                       struct _Unwind_Context* context,
  153.                       void* thrown_ptr,
  154.                       int handler_switch_value,
  155.                       const unsigned char* language_specific_data,
  156.                       _Unwind_Ptr landing_pad,
  157.                       const unsigned char* action_record
  158.                         __attribute__((__unused__)))
  159. {
  160.     ue_header->barrier_cache.sp = _Unwind_GetGR(context, UNWIND_STACK_REG);
  161.     ue_header->barrier_cache.bitpattern[0] = (_uw) thrown_ptr;
  162.     ue_header->barrier_cache.bitpattern[1]
  163.       = (_uw) handler_switch_value;
  164.     ue_header->barrier_cache.bitpattern[2]
  165.       = (_uw) language_specific_data;
  166.     ue_header->barrier_cache.bitpattern[3] = (_uw) landing_pad;
  167. }
  168.  
  169.  
  170. // Restore the catch handler data saved during phase1.
  171.  
  172. static inline void
  173. restore_caught_exception(struct _Unwind_Exception* ue_header,
  174.                          int& handler_switch_value,
  175.                          const unsigned char*& language_specific_data,
  176.                          _Unwind_Ptr& landing_pad)
  177. {
  178.   handler_switch_value = (int) ue_header->barrier_cache.bitpattern[1];
  179.   language_specific_data =
  180.     (const unsigned char*) ue_header->barrier_cache.bitpattern[2];
  181.   landing_pad = (_Unwind_Ptr) ue_header->barrier_cache.bitpattern[3];
  182. }
  183.  
  184. #define CONTINUE_UNWINDING \
  185.   do                                                            \
  186.     {                                                           \
  187.       if (__gnu_unwind_frame(ue_header, context) != _URC_OK)    \
  188.         return _URC_FAILURE;                                    \
  189.       return _URC_CONTINUE_UNWIND;                              \
  190.     }                                                           \
  191.   while (0)
  192.  
  193. // Return true if the filter spec is empty, ie throw().
  194.  
  195. static bool
  196. empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value)
  197. {
  198.   const _Unwind_Word* e = ((const _Unwind_Word*) info->TType)
  199.                           - filter_value - 1;
  200.  
  201.   return *e == 0;
  202. }
  203.  
  204. #else
  205. typedef const std::type_info _throw_typet;
  206.  
  207.  
  208. // Given the thrown type THROW_TYPE, pointer to a variable containing a
  209. // pointer to the exception object THROWN_PTR_P and a type CATCH_TYPE to
  210. // compare against, return whether or not there is a match and if so,
  211. // update *THROWN_PTR_P.
  212.  
  213. static bool
  214. get_adjusted_ptr (const std::type_info *catch_type,
  215.                   const std::type_info *throw_type,
  216.                   void **thrown_ptr_p)
  217. {
  218.   void *thrown_ptr = *thrown_ptr_p;
  219.  
  220.   // Pointer types need to adjust the actual pointer, not
  221.   // the pointer to pointer that is the exception object.
  222.   // This also has the effect of passing pointer types
  223.   // "by value" through the __cxa_begin_catch return value.
  224.   if (throw_type->__is_pointer_p ())
  225.     thrown_ptr = *(void **) thrown_ptr;
  226.  
  227.   if (catch_type->__do_catch (throw_type, &thrown_ptr, 1))
  228.     {
  229.       *thrown_ptr_p = thrown_ptr;
  230.       return true;
  231.     }
  232.  
  233.   return false;
  234. }
  235.  
  236. // Return true if THROW_TYPE matches one if the filter types.
  237.  
  238. static bool
  239. check_exception_spec(lsda_header_info* info, _throw_typet* throw_type,
  240.                       void* thrown_ptr, _sleb128_t filter_value)
  241. {
  242.   const unsigned char *e = info->TType - filter_value - 1;
  243.  
  244.   while (1)
  245.     {
  246.       const std::type_info *catch_type;
  247.       _uleb128_t tmp;
  248.  
  249.       e = read_uleb128 (e, &tmp);
  250.  
  251.       // Zero signals the end of the list.  If we've not found
  252.       // a match by now, then we've failed the specification.
  253.       if (tmp == 0)
  254.         return false;
  255.  
  256.       // Match a ttype entry.
  257.       catch_type = get_ttype_entry (info, tmp);
  258.  
  259.       // ??? There is currently no way to ask the RTTI code about the
  260.       // relationship between two types without reference to a specific
  261.       // object.  There should be; then we wouldn't need to mess with
  262.       // thrown_ptr here.
  263.       if (get_adjusted_ptr (catch_type, throw_type, &thrown_ptr))
  264.         return true;
  265.     }
  266. }
  267.  
  268.  
  269. // Save stage1 handler information in the exception object
  270.  
  271. static inline void
  272. save_caught_exception(struct _Unwind_Exception* ue_header,
  273.                       struct _Unwind_Context* context
  274.                         __attribute__((__unused__)),
  275.                       void* thrown_ptr,
  276.                       int handler_switch_value,
  277.                       const unsigned char* language_specific_data,
  278.                       _Unwind_Ptr landing_pad __attribute__((__unused__)),
  279.                       const unsigned char* action_record)
  280. {
  281.   __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
  282.  
  283.   xh->handlerSwitchValue = handler_switch_value;
  284.   xh->actionRecord = action_record;
  285.   xh->languageSpecificData = language_specific_data;
  286.   xh->adjustedPtr = thrown_ptr;
  287.  
  288.   // ??? Completely unknown what this field is supposed to be for.
  289.   // ??? Need to cache TType encoding base for call_unexpected.
  290.   xh->catchTemp = landing_pad;
  291. }
  292.  
  293.  
  294. // Restore the catch handler information saved during phase1.
  295.  
  296. static inline void
  297. restore_caught_exception(struct _Unwind_Exception* ue_header,
  298.                          int& handler_switch_value,
  299.                          const unsigned char*& language_specific_data,
  300.                          _Unwind_Ptr& landing_pad)
  301. {
  302.   __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
  303.   handler_switch_value = xh->handlerSwitchValue;
  304.   language_specific_data = xh->languageSpecificData;
  305.   landing_pad = (_Unwind_Ptr) xh->catchTemp;
  306. }
  307.  
  308. #define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
  309.  
  310. // Return true if the filter spec is empty, ie throw().
  311.  
  312. static bool
  313. empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value)
  314. {
  315.   const unsigned char *e = info->TType - filter_value - 1;
  316.   _uleb128_t tmp;
  317.  
  318.   e = read_uleb128 (e, &tmp);
  319.   return tmp == 0;
  320. }
  321.  
  322. #endif // !__ARM_EABI_UNWINDER__
  323.  
  324. namespace __cxxabiv1
  325. {
  326.  
  327. // Using a different personality function name causes link failures
  328. // when trying to mix code using different exception handling models.
  329. #ifdef _GLIBCXX_SJLJ_EXCEPTIONS
  330. #define PERSONALITY_FUNCTION    __gxx_personality_sj0
  331. #define __builtin_eh_return_data_regno(x) x
  332. #elif defined(__SEH__) && !defined (_GLIBCXX_SJLJ_EXCEPTIONS)
  333. #define PERSONALITY_FUNCTION    __gxx_personality_imp
  334. #else
  335. #define PERSONALITY_FUNCTION    __gxx_personality_v0
  336. #endif
  337.  
  338. #if defined (__SEH__) && !defined (_GLIBCXX_SJLJ_EXCEPTIONS)
  339. static
  340. #else
  341. extern "C"
  342. #endif
  343. _Unwind_Reason_Code
  344. #ifdef __ARM_EABI_UNWINDER__
  345. PERSONALITY_FUNCTION (_Unwind_State state,
  346.                       struct _Unwind_Exception* ue_header,
  347.                       struct _Unwind_Context* context)
  348. #else
  349. PERSONALITY_FUNCTION (int version,
  350.                       _Unwind_Action actions,
  351.                       _Unwind_Exception_Class exception_class,
  352.                       struct _Unwind_Exception *ue_header,
  353.                       struct _Unwind_Context *context)
  354. #endif
  355. {
  356.   enum found_handler_type
  357.   {
  358.     found_nothing,
  359.     found_terminate,
  360.     found_cleanup,
  361.     found_handler
  362.   } found_type;
  363.  
  364.   lsda_header_info info;
  365.   const unsigned char *language_specific_data;
  366.   const unsigned char *action_record;
  367.   const unsigned char *p;
  368.   _Unwind_Ptr landing_pad, ip;
  369.   int handler_switch_value;
  370.   void* thrown_ptr = 0;
  371.   bool foreign_exception;
  372.   int ip_before_insn = 0;
  373.  
  374. #ifdef __ARM_EABI_UNWINDER__
  375.   _Unwind_Action actions;
  376.  
  377.   switch (state & _US_ACTION_MASK)
  378.     {
  379.     case _US_VIRTUAL_UNWIND_FRAME:
  380.       actions = _UA_SEARCH_PHASE;
  381.       break;
  382.  
  383.     case _US_UNWIND_FRAME_STARTING:
  384.       actions = _UA_CLEANUP_PHASE;
  385.       if (!(state & _US_FORCE_UNWIND)
  386.           && ue_header->barrier_cache.sp == _Unwind_GetGR(context,
  387.                                                           UNWIND_STACK_REG))
  388.         actions |= _UA_HANDLER_FRAME;
  389.       break;
  390.  
  391.     case _US_UNWIND_FRAME_RESUME:
  392.       CONTINUE_UNWINDING;
  393.       break;
  394.  
  395.     default:
  396.       std::abort();
  397.     }
  398.   actions |= state & _US_FORCE_UNWIND;
  399.  
  400.   // We don't know which runtime we're working with, so can't check this.
  401.   // However the ABI routines hide this from us, and we don't actually need
  402.   // to know.
  403.   foreign_exception = false;
  404.  
  405.   // The dwarf unwinder assumes the context structure holds things like the
  406.   // function and LSDA pointers.  The ARM implementation caches these in
  407.   // the exception header (UCB).  To avoid rewriting everything we make a
  408.   // virtual scratch register point at the UCB.
  409.   ip = (_Unwind_Ptr) ue_header;
  410.   _Unwind_SetGR(context, UNWIND_POINTER_REG, ip);
  411. #else
  412.   __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
  413.  
  414.   // Interface version check.
  415.   if (version != 1)
  416.     return _URC_FATAL_PHASE1_ERROR;
  417.   foreign_exception = !__is_gxx_exception_class(exception_class);
  418. #endif
  419.  
  420.   // Shortcut for phase 2 found handler for domestic exception.
  421.   if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)
  422.       && !foreign_exception)
  423.     {
  424.       restore_caught_exception(ue_header, handler_switch_value,
  425.                                language_specific_data, landing_pad);
  426.       found_type = (landing_pad == 0 ? found_terminate : found_handler);
  427.       goto install_context;
  428.     }
  429.  
  430.   language_specific_data = (const unsigned char *)
  431.     _Unwind_GetLanguageSpecificData (context);
  432.  
  433.   // If no LSDA, then there are no handlers or cleanups.
  434.   if (! language_specific_data)
  435.     CONTINUE_UNWINDING;
  436.  
  437.   // Parse the LSDA header.
  438.   p = parse_lsda_header (context, language_specific_data, &info);
  439.   info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
  440. #ifdef _GLIBCXX_HAVE_GETIPINFO
  441.   ip = _Unwind_GetIPInfo (context, &ip_before_insn);
  442. #else
  443.   ip = _Unwind_GetIP (context);
  444. #endif
  445.   if (! ip_before_insn)
  446.     --ip;
  447.   landing_pad = 0;
  448.   action_record = 0;
  449.   handler_switch_value = 0;
  450.  
  451. #ifdef _GLIBCXX_SJLJ_EXCEPTIONS
  452.   // The given "IP" is an index into the call-site table, with two
  453.   // exceptions -- -1 means no-action, and 0 means terminate.  But
  454.   // since we're using uleb128 values, we've not got random access
  455.   // to the array.
  456.   if ((int) ip < 0)
  457.     return _URC_CONTINUE_UNWIND;
  458.   else if (ip == 0)
  459.     {
  460.       // Fall through to set found_terminate.
  461.     }
  462.   else
  463.     {
  464.       _uleb128_t cs_lp, cs_action;
  465.       do
  466.         {
  467.           p = read_uleb128 (p, &cs_lp);
  468.           p = read_uleb128 (p, &cs_action);
  469.         }
  470.       while (--ip);
  471.  
  472.       // Can never have null landing pad for sjlj -- that would have
  473.       // been indicated by a -1 call site index.
  474.       landing_pad = cs_lp + 1;
  475.       if (cs_action)
  476.         action_record = info.action_table + cs_action - 1;
  477.       goto found_something;
  478.     }
  479. #else
  480.   // Search the call-site table for the action associated with this IP.
  481.   while (p < info.action_table)
  482.     {
  483.       _Unwind_Ptr cs_start, cs_len, cs_lp;
  484.       _uleb128_t cs_action;
  485.  
  486.       // Note that all call-site encodings are "absolute" displacements.
  487.       p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
  488.       p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
  489.       p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
  490.       p = read_uleb128 (p, &cs_action);
  491.  
  492.       // The table is sorted, so if we've passed the ip, stop.
  493.       if (ip < info.Start + cs_start)
  494.         p = info.action_table;
  495.       else if (ip < info.Start + cs_start + cs_len)
  496.         {
  497.           if (cs_lp)
  498.             landing_pad = info.LPStart + cs_lp;
  499.           if (cs_action)
  500.             action_record = info.action_table + cs_action - 1;
  501.           goto found_something;
  502.         }
  503.     }
  504. #endif // _GLIBCXX_SJLJ_EXCEPTIONS
  505.  
  506.   // If ip is not present in the table, call terminate.  This is for
  507.   // a destructor inside a cleanup, or a library routine the compiler
  508.   // was not expecting to throw.
  509.   found_type = found_terminate;
  510.   goto do_something;
  511.  
  512.  found_something:
  513.   if (landing_pad == 0)
  514.     {
  515.       // If ip is present, and has a null landing pad, there are
  516.       // no cleanups or handlers to be run.
  517.       found_type = found_nothing;
  518.     }
  519.   else if (action_record == 0)
  520.     {
  521.       // If ip is present, has a non-null landing pad, and a null
  522.       // action table offset, then there are only cleanups present.
  523.       // Cleanups use a zero switch value, as set above.
  524.       found_type = found_cleanup;
  525.     }
  526.   else
  527.     {
  528.       // Otherwise we have a catch handler or exception specification.
  529.  
  530.       _sleb128_t ar_filter, ar_disp;
  531.       const std::type_info* catch_type;
  532.       _throw_typet* throw_type;
  533.       bool saw_cleanup = false;
  534.       bool saw_handler = false;
  535.  
  536. #ifdef __ARM_EABI_UNWINDER__
  537.       // ??? How does this work - more importantly, how does it interact with
  538.       // dependent exceptions?
  539.       throw_type = ue_header;
  540.       if (actions & _UA_FORCE_UNWIND)
  541.         {
  542.           __GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class);
  543.         }
  544.       else if (!foreign_exception)
  545.         thrown_ptr = __get_object_from_ue (ue_header);
  546. #else
  547. #ifdef __GXX_RTTI
  548.       // During forced unwinding, match a magic exception type.
  549.       if (actions & _UA_FORCE_UNWIND)
  550.         {
  551.           throw_type = &typeid(abi::__forced_unwind);
  552.         }
  553.       // With a foreign exception class, there's no exception type.
  554.       // ??? What to do about GNU Java and GNU Ada exceptions?
  555.       else if (foreign_exception)
  556.         {
  557.           throw_type = &typeid(abi::__foreign_exception);
  558.         }
  559.       else
  560. #endif
  561.         {
  562.           thrown_ptr = __get_object_from_ue (ue_header);
  563.           throw_type = __get_exception_header_from_obj
  564.             (thrown_ptr)->exceptionType;
  565.         }
  566. #endif
  567.  
  568.       while (1)
  569.         {
  570.           p = action_record;
  571.           p = read_sleb128 (p, &ar_filter);
  572.           read_sleb128 (p, &ar_disp);
  573.  
  574.           if (ar_filter == 0)
  575.             {
  576.               // Zero filter values are cleanups.
  577.               saw_cleanup = true;
  578.             }
  579.           else if (ar_filter > 0)
  580.             {
  581.               // Positive filter values are handlers.
  582.               catch_type = get_ttype_entry (&info, ar_filter);
  583.  
  584.               // Null catch type is a catch-all handler; we can catch foreign
  585.               // exceptions with this.  Otherwise we must match types.
  586.               if (! catch_type
  587.                   || (throw_type
  588.                       && get_adjusted_ptr (catch_type, throw_type,
  589.                                            &thrown_ptr)))
  590.                 {
  591.                   saw_handler = true;
  592.                   break;
  593.                 }
  594.             }
  595.           else
  596.             {
  597.               // Negative filter values are exception specifications.
  598.               // ??? How do foreign exceptions fit in?  As far as I can
  599.               // see we can't match because there's no __cxa_exception
  600.               // object to stuff bits in for __cxa_call_unexpected to use.
  601.               // Allow them iff the exception spec is non-empty.  I.e.
  602.               // a throw() specification results in __unexpected.
  603.               if ((throw_type
  604.                    && !(actions & _UA_FORCE_UNWIND)
  605.                    && !foreign_exception)
  606.                   ? ! check_exception_spec (&info, throw_type, thrown_ptr,
  607.                                             ar_filter)
  608.                   : empty_exception_spec (&info, ar_filter))
  609.                 {
  610.                   saw_handler = true;
  611.                   break;
  612.                 }
  613.             }
  614.  
  615.           if (ar_disp == 0)
  616.             break;
  617.           action_record = p + ar_disp;
  618.         }
  619.  
  620.       if (saw_handler)
  621.         {
  622.           handler_switch_value = ar_filter;
  623.           found_type = found_handler;
  624.         }
  625.       else
  626.         found_type = (saw_cleanup ? found_cleanup : found_nothing);
  627.     }
  628.  
  629.  do_something:
  630.    if (found_type == found_nothing)
  631.      CONTINUE_UNWINDING;
  632.  
  633.   if (actions & _UA_SEARCH_PHASE)
  634.     {
  635.       if (found_type == found_cleanup)
  636.         CONTINUE_UNWINDING;
  637.  
  638.       // For domestic exceptions, we cache data from phase 1 for phase 2.
  639.       if (!foreign_exception)
  640.         {
  641.           save_caught_exception(ue_header, context, thrown_ptr,
  642.                                 handler_switch_value, language_specific_data,
  643.                                 landing_pad, action_record);
  644.         }
  645.       return _URC_HANDLER_FOUND;
  646.     }
  647.  
  648.  install_context:
  649.  
  650.   // We can't use any of the cxa routines with foreign exceptions,
  651.   // because they all expect ue_header to be a struct __cxa_exception.
  652.   // So in that case, call terminate or unexpected directly.
  653.   if ((actions & _UA_FORCE_UNWIND)
  654.       || foreign_exception)
  655.     {
  656.       if (found_type == found_terminate)
  657.         std::terminate ();
  658.       else if (handler_switch_value < 0)
  659.         {
  660.           __try
  661.             { std::unexpected (); }
  662.           __catch(...)
  663.             { std::terminate (); }
  664.         }
  665.     }
  666.   else
  667.     {
  668.       if (found_type == found_terminate)
  669.         __cxa_call_terminate(ue_header);
  670.  
  671.       // Cache the TType base value for __cxa_call_unexpected, as we won't
  672.       // have an _Unwind_Context then.
  673.       if (handler_switch_value < 0)
  674.         {
  675.           parse_lsda_header (context, language_specific_data, &info);
  676.           info.ttype_base = base_of_encoded_value (info.ttype_encoding,
  677.                                                    context);
  678.  
  679. #ifdef __ARM_EABI_UNWINDER__
  680.           const _Unwind_Word* e;
  681.           _Unwind_Word n;
  682.          
  683.           e = ((const _Unwind_Word*) info.TType) - handler_switch_value - 1;
  684.           // Count the number of rtti objects.
  685.           n = 0;
  686.           while (e[n] != 0)
  687.             n++;
  688.  
  689.           // Count.
  690.           ue_header->barrier_cache.bitpattern[1] = n;
  691.           // Base
  692.           ue_header->barrier_cache.bitpattern[2] = info.ttype_base;
  693.           // Stride.
  694.           ue_header->barrier_cache.bitpattern[3] = 4;
  695.           // List head.
  696.           ue_header->barrier_cache.bitpattern[4] = (_Unwind_Word) e;
  697. #else
  698.           xh->catchTemp = base_of_encoded_value (info.ttype_encoding, context);
  699. #endif
  700.         }
  701.     }
  702.  
  703.   /* For targets with pointers smaller than the word size, we must extend the
  704.      pointer, and this extension is target dependent.  */
  705.   _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
  706.                  __builtin_extend_pointer (ue_header));
  707.   _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
  708.                  handler_switch_value);
  709.   _Unwind_SetIP (context, landing_pad);
  710. #ifdef __ARM_EABI_UNWINDER__
  711.   if (found_type == found_cleanup)
  712.     __cxa_begin_cleanup(ue_header);
  713. #endif
  714.   return _URC_INSTALL_CONTEXT;
  715. }
  716.  
  717. /* The ARM EABI implementation of __cxa_call_unexpected is in a
  718.    different file so that the personality routine (PR) can be used
  719.    standalone.  The generic routine shared datastructures with the PR
  720.    so it is most convenient to implement it here.  */
  721. #ifndef __ARM_EABI_UNWINDER__
  722. extern "C" void
  723. __cxa_call_unexpected (void *exc_obj_in)
  724. {
  725.   _Unwind_Exception *exc_obj
  726.     = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
  727.  
  728.   __cxa_begin_catch (exc_obj);
  729.  
  730.   // This function is a handler for our exception argument.  If we exit
  731.   // by throwing a different exception, we'll need the original cleaned up.
  732.   struct end_catch_protect
  733.   {
  734.     end_catch_protect() { }
  735.     ~end_catch_protect() { __cxa_end_catch(); }
  736.   } end_catch_protect_obj;
  737.  
  738.   lsda_header_info info;
  739.   __cxa_exception *xh = __get_exception_header_from_ue (exc_obj);
  740.   const unsigned char *xh_lsda;
  741.   _Unwind_Sword xh_switch_value;
  742.   std::terminate_handler xh_terminate_handler;
  743.  
  744.   // If the unexpectedHandler rethrows the exception (e.g. to categorize it),
  745.   // it will clobber data about the current handler.  So copy the data out now.
  746.   xh_lsda = xh->languageSpecificData;
  747.   xh_switch_value = xh->handlerSwitchValue;
  748.   xh_terminate_handler = xh->terminateHandler;
  749.   info.ttype_base = (_Unwind_Ptr) xh->catchTemp;
  750.  
  751.   __try
  752.     { __unexpected (xh->unexpectedHandler); }
  753.   __catch(...)
  754.     {
  755.       // Get the exception thrown from unexpected.
  756.  
  757.       __cxa_eh_globals *globals = __cxa_get_globals_fast ();
  758.       __cxa_exception *new_xh = globals->caughtExceptions;
  759.       void *new_ptr = __get_object_from_ambiguous_exception (new_xh);
  760.  
  761.       // We don't quite have enough stuff cached; re-parse the LSDA.
  762.       parse_lsda_header (0, xh_lsda, &info);
  763.  
  764.       // If this new exception meets the exception spec, allow it.
  765.       if (check_exception_spec (&info, __get_exception_header_from_obj
  766.                                   (new_ptr)->exceptionType,
  767.                                 new_ptr, xh_switch_value))
  768.         { __throw_exception_again; }
  769.  
  770.       // If the exception spec allows std::bad_exception, throw that.
  771.       // We don't have a thrown object to compare against, but since
  772.       // bad_exception doesn't have virtual bases, that's OK; just pass 0.
  773. #if defined(__EXCEPTIONS) && defined(__GXX_RTTI)
  774.       const std::type_info &bad_exc = typeid (std::bad_exception);
  775.       if (check_exception_spec (&info, &bad_exc, 0, xh_switch_value))
  776.         throw std::bad_exception();
  777. #endif  
  778.  
  779.       // Otherwise, die.
  780.       __terminate (xh_terminate_handler);
  781.     }
  782. }
  783. #endif
  784.  
  785. #if defined (__SEH__) && !defined (_GLIBCXX_SJLJ_EXCEPTIONS)
  786. extern "C"
  787. EXCEPTION_DISPOSITION
  788. __gxx_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame,
  789.                         PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
  790. {
  791.   return _GCC_specific_handler (ms_exc, this_frame, ms_orig_context,
  792.                                 ms_disp, __gxx_personality_imp);
  793. }
  794. #endif /* SEH */
  795.  
  796. } // namespace __cxxabiv1
  797.