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