Subversion Repositories Kolibri OS

Rev

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

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