OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libstdc++-v3/] [libsupc++/] [eh_personality.cc] - Diff between revs 816 and 826

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 816 Rev 826
// -*- C++ -*- The GNU C++ exception personality routine.
// -*- C++ -*- The GNU C++ exception personality routine.
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
// Free Software Foundation, Inc.
// Free Software Foundation, Inc.
//
//
// This file is part of GCC.
// This file is part of GCC.
//
//
// GCC is free software; you can redistribute it and/or modify
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
// any later version.
//
//
// GCC is distributed in the hope that it will be useful,
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// GNU General Public License for more details.
//
//
// Under Section 7 of GPL version 3, you are granted additional
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// 3.1, as published by the Free Software Foundation.
 
 
// You should have received a copy of the GNU General Public License and
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.
// <http://www.gnu.org/licenses/>.
 
 
#include <bits/c++config.h>
#include <bits/c++config.h>
#include <cstdlib>
#include <cstdlib>
#include <exception_defines.h>
#include <exception_defines.h>
#include <cxxabi.h>
#include <cxxabi.h>
#include "unwind-cxx.h"
#include "unwind-cxx.h"
 
 
using namespace __cxxabiv1;
using namespace __cxxabiv1;
 
 
#ifdef __ARM_EABI_UNWINDER__
#ifdef __ARM_EABI_UNWINDER__
#define NO_SIZE_OF_ENCODED_VALUE
#define NO_SIZE_OF_ENCODED_VALUE
#endif
#endif
 
 
#include "unwind-pe.h"
#include "unwind-pe.h"
 
 


struct lsda_header_info
struct lsda_header_info
{
{
  _Unwind_Ptr Start;
  _Unwind_Ptr Start;
  _Unwind_Ptr LPStart;
  _Unwind_Ptr LPStart;
  _Unwind_Ptr ttype_base;
  _Unwind_Ptr ttype_base;
  const unsigned char *TType;
  const unsigned char *TType;
  const unsigned char *action_table;
  const unsigned char *action_table;
  unsigned char ttype_encoding;
  unsigned char ttype_encoding;
  unsigned char call_site_encoding;
  unsigned char call_site_encoding;
};
};
 
 
static const unsigned char *
static const unsigned char *
parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
                   lsda_header_info *info)
                   lsda_header_info *info)
{
{
  _uleb128_t tmp;
  _uleb128_t tmp;
  unsigned char lpstart_encoding;
  unsigned char lpstart_encoding;
 
 
  info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
  info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
 
 
  // Find @LPStart, the base to which landing pad offsets are relative.
  // Find @LPStart, the base to which landing pad offsets are relative.
  lpstart_encoding = *p++;
  lpstart_encoding = *p++;
  if (lpstart_encoding != DW_EH_PE_omit)
  if (lpstart_encoding != DW_EH_PE_omit)
    p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
    p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
  else
  else
    info->LPStart = info->Start;
    info->LPStart = info->Start;
 
 
  // Find @TType, the base of the handler and exception spec type data.
  // Find @TType, the base of the handler and exception spec type data.
  info->ttype_encoding = *p++;
  info->ttype_encoding = *p++;
  if (info->ttype_encoding != DW_EH_PE_omit)
  if (info->ttype_encoding != DW_EH_PE_omit)
    {
    {
      p = read_uleb128 (p, &tmp);
      p = read_uleb128 (p, &tmp);
      info->TType = p + tmp;
      info->TType = p + tmp;
    }
    }
  else
  else
    info->TType = 0;
    info->TType = 0;
 
 
  // The encoding and length of the call-site table; the action table
  // The encoding and length of the call-site table; the action table
  // immediately follows.
  // immediately follows.
  info->call_site_encoding = *p++;
  info->call_site_encoding = *p++;
  p = read_uleb128 (p, &tmp);
  p = read_uleb128 (p, &tmp);
  info->action_table = p + tmp;
  info->action_table = p + tmp;
 
 
  return p;
  return p;
}
}
 
 
#ifdef __ARM_EABI_UNWINDER__
#ifdef __ARM_EABI_UNWINDER__
 
 
// Return an element from a type table.
// Return an element from a type table.
 
 
static const std::type_info*
static const std::type_info*
get_ttype_entry(lsda_header_info* info, _uleb128_t i)
get_ttype_entry(lsda_header_info* info, _uleb128_t i)
{
{
  _Unwind_Ptr ptr;
  _Unwind_Ptr ptr;
 
 
  ptr = (_Unwind_Ptr) (info->TType - (i * 4));
  ptr = (_Unwind_Ptr) (info->TType - (i * 4));
  ptr = _Unwind_decode_target2(ptr);
  ptr = _Unwind_decode_target2(ptr);
 
 
  return reinterpret_cast<const std::type_info *>(ptr);
  return reinterpret_cast<const std::type_info *>(ptr);
}
}
 
 
// The ABI provides a routine for matching exception object types.
// The ABI provides a routine for matching exception object types.
typedef _Unwind_Control_Block _throw_typet;
typedef _Unwind_Control_Block _throw_typet;
#define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \
#define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \
  (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \
  (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \
   != ctm_failed)
   != ctm_failed)
 
 
// Return true if THROW_TYPE matches one if the filter types.
// Return true if THROW_TYPE matches one if the filter types.
 
 
static bool
static bool
check_exception_spec(lsda_header_info* info, _throw_typet* throw_type,
check_exception_spec(lsda_header_info* info, _throw_typet* throw_type,
                     void* thrown_ptr, _sleb128_t filter_value)
                     void* thrown_ptr, _sleb128_t filter_value)
{
{
  const _uleb128_t* e = ((const _uleb128_t*) info->TType)
  const _uleb128_t* e = ((const _uleb128_t*) info->TType)
                          - filter_value - 1;
                          - filter_value - 1;
 
 
  while (1)
  while (1)
    {
    {
      const std::type_info* catch_type;
      const std::type_info* catch_type;
      _uleb128_t tmp;
      _uleb128_t tmp;
 
 
      tmp = *e;
      tmp = *e;
 
 
      // Zero signals the end of the list.  If we've not found
      // Zero signals the end of the list.  If we've not found
      // a match by now, then we've failed the specification.
      // a match by now, then we've failed the specification.
      if (tmp == 0)
      if (tmp == 0)
        return false;
        return false;
 
 
      tmp = _Unwind_decode_target2((_Unwind_Word) e);
      tmp = _Unwind_decode_target2((_Unwind_Word) e);
 
 
      // Match a ttype entry.
      // Match a ttype entry.
      catch_type = reinterpret_cast<const std::type_info*>(tmp);
      catch_type = reinterpret_cast<const std::type_info*>(tmp);
 
 
      // ??? There is currently no way to ask the RTTI code about the
      // ??? There is currently no way to ask the RTTI code about the
      // relationship between two types without reference to a specific
      // relationship between two types without reference to a specific
      // object.  There should be; then we wouldn't need to mess with
      // object.  There should be; then we wouldn't need to mess with
      // thrown_ptr here.
      // thrown_ptr here.
      if (get_adjusted_ptr(catch_type, throw_type, &thrown_ptr))
      if (get_adjusted_ptr(catch_type, throw_type, &thrown_ptr))
        return true;
        return true;
 
 
      // Advance to the next entry.
      // Advance to the next entry.
      e++;
      e++;
    }
    }
}
}
 
 
 
 
// Save stage1 handler information in the exception object
// Save stage1 handler information in the exception object
 
 
static inline void
static inline void
save_caught_exception(struct _Unwind_Exception* ue_header,
save_caught_exception(struct _Unwind_Exception* ue_header,
                      struct _Unwind_Context* context,
                      struct _Unwind_Context* context,
                      void* thrown_ptr,
                      void* thrown_ptr,
                      int handler_switch_value,
                      int handler_switch_value,
                      const unsigned char* language_specific_data,
                      const unsigned char* language_specific_data,
                      _Unwind_Ptr landing_pad,
                      _Unwind_Ptr landing_pad,
                      const unsigned char* action_record
                      const unsigned char* action_record
                        __attribute__((__unused__)))
                        __attribute__((__unused__)))
{
{
    ue_header->barrier_cache.sp = _Unwind_GetGR(context, 13);
    ue_header->barrier_cache.sp = _Unwind_GetGR(context, 13);
    ue_header->barrier_cache.bitpattern[0] = (_uw) thrown_ptr;
    ue_header->barrier_cache.bitpattern[0] = (_uw) thrown_ptr;
    ue_header->barrier_cache.bitpattern[1]
    ue_header->barrier_cache.bitpattern[1]
      = (_uw) handler_switch_value;
      = (_uw) handler_switch_value;
    ue_header->barrier_cache.bitpattern[2]
    ue_header->barrier_cache.bitpattern[2]
      = (_uw) language_specific_data;
      = (_uw) language_specific_data;
    ue_header->barrier_cache.bitpattern[3] = (_uw) landing_pad;
    ue_header->barrier_cache.bitpattern[3] = (_uw) landing_pad;
}
}
 
 
 
 
// Restore the catch handler data saved during phase1.
// Restore the catch handler data saved during phase1.
 
 
static inline void
static inline void
restore_caught_exception(struct _Unwind_Exception* ue_header,
restore_caught_exception(struct _Unwind_Exception* ue_header,
                         int& handler_switch_value,
                         int& handler_switch_value,
                         const unsigned char*& language_specific_data,
                         const unsigned char*& language_specific_data,
                         _Unwind_Ptr& landing_pad)
                         _Unwind_Ptr& landing_pad)
{
{
  handler_switch_value = (int) ue_header->barrier_cache.bitpattern[1];
  handler_switch_value = (int) ue_header->barrier_cache.bitpattern[1];
  language_specific_data =
  language_specific_data =
    (const unsigned char*) ue_header->barrier_cache.bitpattern[2];
    (const unsigned char*) ue_header->barrier_cache.bitpattern[2];
  landing_pad = (_Unwind_Ptr) ue_header->barrier_cache.bitpattern[3];
  landing_pad = (_Unwind_Ptr) ue_header->barrier_cache.bitpattern[3];
}
}
 
 
#define CONTINUE_UNWINDING \
#define CONTINUE_UNWINDING \
  do                                                            \
  do                                                            \
    {                                                           \
    {                                                           \
      if (__gnu_unwind_frame(ue_header, context) != _URC_OK)    \
      if (__gnu_unwind_frame(ue_header, context) != _URC_OK)    \
        return _URC_FAILURE;                                    \
        return _URC_FAILURE;                                    \
      return _URC_CONTINUE_UNWIND;                              \
      return _URC_CONTINUE_UNWIND;                              \
    }                                                           \
    }                                                           \
  while (0)
  while (0)
 
 
// Return true if the filter spec is empty, ie throw().
// Return true if the filter spec is empty, ie throw().
 
 
static bool
static bool
empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value)
empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value)
{
{
  const _Unwind_Word* e = ((const _Unwind_Word*) info->TType)
  const _Unwind_Word* e = ((const _Unwind_Word*) info->TType)
                          - filter_value - 1;
                          - filter_value - 1;
 
 
  return *e == 0;
  return *e == 0;
}
}
 
 
#else
#else
typedef const std::type_info _throw_typet;
typedef const std::type_info _throw_typet;
 
 
 
 
// Return an element from a type table.
// Return an element from a type table.
 
 
static const std::type_info *
static const std::type_info *
get_ttype_entry (lsda_header_info *info, _uleb128_t i)
get_ttype_entry (lsda_header_info *info, _uleb128_t i)
{
{
  _Unwind_Ptr ptr;
  _Unwind_Ptr ptr;
 
 
  i *= size_of_encoded_value (info->ttype_encoding);
  i *= size_of_encoded_value (info->ttype_encoding);
  read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
  read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
                                info->TType - i, &ptr);
                                info->TType - i, &ptr);
 
 
  return reinterpret_cast<const std::type_info *>(ptr);
  return reinterpret_cast<const std::type_info *>(ptr);
}
}
 
 
// Given the thrown type THROW_TYPE, pointer to a variable containing a
// Given the thrown type THROW_TYPE, pointer to a variable containing a
// pointer to the exception object THROWN_PTR_P and a type CATCH_TYPE to
// pointer to the exception object THROWN_PTR_P and a type CATCH_TYPE to
// compare against, return whether or not there is a match and if so,
// compare against, return whether or not there is a match and if so,
// update *THROWN_PTR_P.
// update *THROWN_PTR_P.
 
 
static bool
static bool
get_adjusted_ptr (const std::type_info *catch_type,
get_adjusted_ptr (const std::type_info *catch_type,
                  const std::type_info *throw_type,
                  const std::type_info *throw_type,
                  void **thrown_ptr_p)
                  void **thrown_ptr_p)
{
{
  void *thrown_ptr = *thrown_ptr_p;
  void *thrown_ptr = *thrown_ptr_p;
 
 
  // Pointer types need to adjust the actual pointer, not
  // Pointer types need to adjust the actual pointer, not
  // the pointer to pointer that is the exception object.
  // the pointer to pointer that is the exception object.
  // This also has the effect of passing pointer types
  // This also has the effect of passing pointer types
  // "by value" through the __cxa_begin_catch return value.
  // "by value" through the __cxa_begin_catch return value.
  if (throw_type->__is_pointer_p ())
  if (throw_type->__is_pointer_p ())
    thrown_ptr = *(void **) thrown_ptr;
    thrown_ptr = *(void **) thrown_ptr;
 
 
  if (catch_type->__do_catch (throw_type, &thrown_ptr, 1))
  if (catch_type->__do_catch (throw_type, &thrown_ptr, 1))
    {
    {
      *thrown_ptr_p = thrown_ptr;
      *thrown_ptr_p = thrown_ptr;
      return true;
      return true;
    }
    }
 
 
  return false;
  return false;
}
}
 
 
// Return true if THROW_TYPE matches one if the filter types.
// Return true if THROW_TYPE matches one if the filter types.
 
 
static bool
static bool
check_exception_spec(lsda_header_info* info, _throw_typet* throw_type,
check_exception_spec(lsda_header_info* info, _throw_typet* throw_type,
                      void* thrown_ptr, _sleb128_t filter_value)
                      void* thrown_ptr, _sleb128_t filter_value)
{
{
  const unsigned char *e = info->TType - filter_value - 1;
  const unsigned char *e = info->TType - filter_value - 1;
 
 
  while (1)
  while (1)
    {
    {
      const std::type_info *catch_type;
      const std::type_info *catch_type;
      _uleb128_t tmp;
      _uleb128_t tmp;
 
 
      e = read_uleb128 (e, &tmp);
      e = read_uleb128 (e, &tmp);
 
 
      // Zero signals the end of the list.  If we've not found
      // Zero signals the end of the list.  If we've not found
      // a match by now, then we've failed the specification.
      // a match by now, then we've failed the specification.
      if (tmp == 0)
      if (tmp == 0)
        return false;
        return false;
 
 
      // Match a ttype entry.
      // Match a ttype entry.
      catch_type = get_ttype_entry (info, tmp);
      catch_type = get_ttype_entry (info, tmp);
 
 
      // ??? There is currently no way to ask the RTTI code about the
      // ??? There is currently no way to ask the RTTI code about the
      // relationship between two types without reference to a specific
      // relationship between two types without reference to a specific
      // object.  There should be; then we wouldn't need to mess with
      // object.  There should be; then we wouldn't need to mess with
      // thrown_ptr here.
      // thrown_ptr here.
      if (get_adjusted_ptr (catch_type, throw_type, &thrown_ptr))
      if (get_adjusted_ptr (catch_type, throw_type, &thrown_ptr))
        return true;
        return true;
    }
    }
}
}
 
 
 
 
// Save stage1 handler information in the exception object
// Save stage1 handler information in the exception object
 
 
static inline void
static inline void
save_caught_exception(struct _Unwind_Exception* ue_header,
save_caught_exception(struct _Unwind_Exception* ue_header,
                      struct _Unwind_Context* context
                      struct _Unwind_Context* context
                        __attribute__((__unused__)),
                        __attribute__((__unused__)),
                      void* thrown_ptr,
                      void* thrown_ptr,
                      int handler_switch_value,
                      int handler_switch_value,
                      const unsigned char* language_specific_data,
                      const unsigned char* language_specific_data,
                      _Unwind_Ptr landing_pad __attribute__((__unused__)),
                      _Unwind_Ptr landing_pad __attribute__((__unused__)),
                      const unsigned char* action_record)
                      const unsigned char* action_record)
{
{
  __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
  __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
 
 
  xh->handlerSwitchValue = handler_switch_value;
  xh->handlerSwitchValue = handler_switch_value;
  xh->actionRecord = action_record;
  xh->actionRecord = action_record;
  xh->languageSpecificData = language_specific_data;
  xh->languageSpecificData = language_specific_data;
  xh->adjustedPtr = thrown_ptr;
  xh->adjustedPtr = thrown_ptr;
 
 
  // ??? Completely unknown what this field is supposed to be for.
  // ??? Completely unknown what this field is supposed to be for.
  // ??? Need to cache TType encoding base for call_unexpected.
  // ??? Need to cache TType encoding base for call_unexpected.
  xh->catchTemp = landing_pad;
  xh->catchTemp = landing_pad;
}
}
 
 
 
 
// Restore the catch handler information saved during phase1.
// Restore the catch handler information saved during phase1.
 
 
static inline void
static inline void
restore_caught_exception(struct _Unwind_Exception* ue_header,
restore_caught_exception(struct _Unwind_Exception* ue_header,
                         int& handler_switch_value,
                         int& handler_switch_value,
                         const unsigned char*& language_specific_data,
                         const unsigned char*& language_specific_data,
                         _Unwind_Ptr& landing_pad)
                         _Unwind_Ptr& landing_pad)
{
{
  __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
  __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
  handler_switch_value = xh->handlerSwitchValue;
  handler_switch_value = xh->handlerSwitchValue;
  language_specific_data = xh->languageSpecificData;
  language_specific_data = xh->languageSpecificData;
  landing_pad = (_Unwind_Ptr) xh->catchTemp;
  landing_pad = (_Unwind_Ptr) xh->catchTemp;
}
}
 
 
#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
 
 
// Return true if the filter spec is empty, ie throw().
// Return true if the filter spec is empty, ie throw().
 
 
static bool
static bool
empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value)
empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value)
{
{
  const unsigned char *e = info->TType - filter_value - 1;
  const unsigned char *e = info->TType - filter_value - 1;
  _uleb128_t tmp;
  _uleb128_t tmp;
 
 
  e = read_uleb128 (e, &tmp);
  e = read_uleb128 (e, &tmp);
  return tmp == 0;
  return tmp == 0;
}
}
 
 
#endif // !__ARM_EABI_UNWINDER__
#endif // !__ARM_EABI_UNWINDER__
 
 
namespace __cxxabiv1
namespace __cxxabiv1
{
{
 
 
// Using a different personality function name causes link failures
// Using a different personality function name causes link failures
// when trying to mix code using different exception handling models.
// when trying to mix code using different exception handling models.
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
#define PERSONALITY_FUNCTION    __gxx_personality_sj0
#define PERSONALITY_FUNCTION    __gxx_personality_sj0
#define __builtin_eh_return_data_regno(x) x
#define __builtin_eh_return_data_regno(x) x
#else
#else
#define PERSONALITY_FUNCTION    __gxx_personality_v0
#define PERSONALITY_FUNCTION    __gxx_personality_v0
#endif
#endif
 
 
extern "C" _Unwind_Reason_Code
extern "C" _Unwind_Reason_Code
#ifdef __ARM_EABI_UNWINDER__
#ifdef __ARM_EABI_UNWINDER__
PERSONALITY_FUNCTION (_Unwind_State state,
PERSONALITY_FUNCTION (_Unwind_State state,
                      struct _Unwind_Exception* ue_header,
                      struct _Unwind_Exception* ue_header,
                      struct _Unwind_Context* context)
                      struct _Unwind_Context* context)
#else
#else
PERSONALITY_FUNCTION (int version,
PERSONALITY_FUNCTION (int version,
                      _Unwind_Action actions,
                      _Unwind_Action actions,
                      _Unwind_Exception_Class exception_class,
                      _Unwind_Exception_Class exception_class,
                      struct _Unwind_Exception *ue_header,
                      struct _Unwind_Exception *ue_header,
                      struct _Unwind_Context *context)
                      struct _Unwind_Context *context)
#endif
#endif
{
{
  enum found_handler_type
  enum found_handler_type
  {
  {
    found_nothing,
    found_nothing,
    found_terminate,
    found_terminate,
    found_cleanup,
    found_cleanup,
    found_handler
    found_handler
  } found_type;
  } found_type;
 
 
  lsda_header_info info;
  lsda_header_info info;
  const unsigned char *language_specific_data;
  const unsigned char *language_specific_data;
  const unsigned char *action_record;
  const unsigned char *action_record;
  const unsigned char *p;
  const unsigned char *p;
  _Unwind_Ptr landing_pad, ip;
  _Unwind_Ptr landing_pad, ip;
  int handler_switch_value;
  int handler_switch_value;
  void* thrown_ptr = 0;
  void* thrown_ptr = 0;
  bool foreign_exception;
  bool foreign_exception;
  int ip_before_insn = 0;
  int ip_before_insn = 0;
 
 
#ifdef __ARM_EABI_UNWINDER__
#ifdef __ARM_EABI_UNWINDER__
  _Unwind_Action actions;
  _Unwind_Action actions;
 
 
  switch (state & _US_ACTION_MASK)
  switch (state & _US_ACTION_MASK)
    {
    {
    case _US_VIRTUAL_UNWIND_FRAME:
    case _US_VIRTUAL_UNWIND_FRAME:
      actions = _UA_SEARCH_PHASE;
      actions = _UA_SEARCH_PHASE;
      break;
      break;
 
 
    case _US_UNWIND_FRAME_STARTING:
    case _US_UNWIND_FRAME_STARTING:
      actions = _UA_CLEANUP_PHASE;
      actions = _UA_CLEANUP_PHASE;
      if (!(state & _US_FORCE_UNWIND)
      if (!(state & _US_FORCE_UNWIND)
          && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13))
          && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13))
        actions |= _UA_HANDLER_FRAME;
        actions |= _UA_HANDLER_FRAME;
      break;
      break;
 
 
    case _US_UNWIND_FRAME_RESUME:
    case _US_UNWIND_FRAME_RESUME:
      CONTINUE_UNWINDING;
      CONTINUE_UNWINDING;
      break;
      break;
 
 
    default:
    default:
      std::abort();
      std::abort();
    }
    }
  actions |= state & _US_FORCE_UNWIND;
  actions |= state & _US_FORCE_UNWIND;
 
 
  // We don't know which runtime we're working with, so can't check this.
  // We don't know which runtime we're working with, so can't check this.
  // However the ABI routines hide this from us, and we don't actually need
  // However the ABI routines hide this from us, and we don't actually need
  // to know.
  // to know.
  foreign_exception = false;
  foreign_exception = false;
 
 
  // The dwarf unwinder assumes the context structure holds things like the
  // The dwarf unwinder assumes the context structure holds things like the
  // function and LSDA pointers.  The ARM implementation caches these in
  // function and LSDA pointers.  The ARM implementation caches these in
  // the exception header (UCB).  To avoid rewriting everything we make the
  // the exception header (UCB).  To avoid rewriting everything we make the
  // virtual IP register point at the UCB.
  // virtual IP register point at the UCB.
  ip = (_Unwind_Ptr) ue_header;
  ip = (_Unwind_Ptr) ue_header;
  _Unwind_SetGR(context, 12, ip);
  _Unwind_SetGR(context, 12, ip);
#else
#else
  __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
  __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
 
 
  // Interface version check.
  // Interface version check.
  if (version != 1)
  if (version != 1)
    return _URC_FATAL_PHASE1_ERROR;
    return _URC_FATAL_PHASE1_ERROR;
  foreign_exception = !__is_gxx_exception_class(exception_class);
  foreign_exception = !__is_gxx_exception_class(exception_class);
#endif
#endif
 
 
  // Shortcut for phase 2 found handler for domestic exception.
  // Shortcut for phase 2 found handler for domestic exception.
  if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)
  if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)
      && !foreign_exception)
      && !foreign_exception)
    {
    {
      restore_caught_exception(ue_header, handler_switch_value,
      restore_caught_exception(ue_header, handler_switch_value,
                               language_specific_data, landing_pad);
                               language_specific_data, landing_pad);
      found_type = (landing_pad == 0 ? found_terminate : found_handler);
      found_type = (landing_pad == 0 ? found_terminate : found_handler);
      goto install_context;
      goto install_context;
    }
    }
 
 
  language_specific_data = (const unsigned char *)
  language_specific_data = (const unsigned char *)
    _Unwind_GetLanguageSpecificData (context);
    _Unwind_GetLanguageSpecificData (context);
 
 
  // If no LSDA, then there are no handlers or cleanups.
  // If no LSDA, then there are no handlers or cleanups.
  if (! language_specific_data)
  if (! language_specific_data)
    CONTINUE_UNWINDING;
    CONTINUE_UNWINDING;
 
 
  // Parse the LSDA header.
  // Parse the LSDA header.
  p = parse_lsda_header (context, language_specific_data, &info);
  p = parse_lsda_header (context, language_specific_data, &info);
  info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
  info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
#ifdef _GLIBCXX_HAVE_GETIPINFO
#ifdef _GLIBCXX_HAVE_GETIPINFO
  ip = _Unwind_GetIPInfo (context, &ip_before_insn);
  ip = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
#else
  ip = _Unwind_GetIP (context);
  ip = _Unwind_GetIP (context);
#endif
#endif
  if (! ip_before_insn)
  if (! ip_before_insn)
    --ip;
    --ip;
  landing_pad = 0;
  landing_pad = 0;
  action_record = 0;
  action_record = 0;
  handler_switch_value = 0;
  handler_switch_value = 0;
 
 
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
  // The given "IP" is an index into the call-site table, with two
  // The given "IP" is an index into the call-site table, with two
  // exceptions -- -1 means no-action, and 0 means terminate.  But
  // exceptions -- -1 means no-action, and 0 means terminate.  But
  // since we're using uleb128 values, we've not got random access
  // since we're using uleb128 values, we've not got random access
  // to the array.
  // to the array.
  if ((int) ip < 0)
  if ((int) ip < 0)
    return _URC_CONTINUE_UNWIND;
    return _URC_CONTINUE_UNWIND;
  else if (ip == 0)
  else if (ip == 0)
    {
    {
      // Fall through to set found_terminate.
      // Fall through to set found_terminate.
    }
    }
  else
  else
    {
    {
      _uleb128_t cs_lp, cs_action;
      _uleb128_t cs_lp, cs_action;
      do
      do
        {
        {
          p = read_uleb128 (p, &cs_lp);
          p = read_uleb128 (p, &cs_lp);
          p = read_uleb128 (p, &cs_action);
          p = read_uleb128 (p, &cs_action);
        }
        }
      while (--ip);
      while (--ip);
 
 
      // Can never have null landing pad for sjlj -- that would have
      // Can never have null landing pad for sjlj -- that would have
      // been indicated by a -1 call site index.
      // been indicated by a -1 call site index.
      landing_pad = cs_lp + 1;
      landing_pad = cs_lp + 1;
      if (cs_action)
      if (cs_action)
        action_record = info.action_table + cs_action - 1;
        action_record = info.action_table + cs_action - 1;
      goto found_something;
      goto found_something;
    }
    }
#else
#else
  // Search the call-site table for the action associated with this IP.
  // Search the call-site table for the action associated with this IP.
  while (p < info.action_table)
  while (p < info.action_table)
    {
    {
      _Unwind_Ptr cs_start, cs_len, cs_lp;
      _Unwind_Ptr cs_start, cs_len, cs_lp;
      _uleb128_t cs_action;
      _uleb128_t cs_action;
 
 
      // Note that all call-site encodings are "absolute" displacements.
      // Note that all call-site encodings are "absolute" displacements.
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
      p = read_uleb128 (p, &cs_action);
      p = read_uleb128 (p, &cs_action);
 
 
      // The table is sorted, so if we've passed the ip, stop.
      // The table is sorted, so if we've passed the ip, stop.
      if (ip < info.Start + cs_start)
      if (ip < info.Start + cs_start)
        p = info.action_table;
        p = info.action_table;
      else if (ip < info.Start + cs_start + cs_len)
      else if (ip < info.Start + cs_start + cs_len)
        {
        {
          if (cs_lp)
          if (cs_lp)
            landing_pad = info.LPStart + cs_lp;
            landing_pad = info.LPStart + cs_lp;
          if (cs_action)
          if (cs_action)
            action_record = info.action_table + cs_action - 1;
            action_record = info.action_table + cs_action - 1;
          goto found_something;
          goto found_something;
        }
        }
    }
    }
#endif // _GLIBCXX_SJLJ_EXCEPTIONS
#endif // _GLIBCXX_SJLJ_EXCEPTIONS
 
 
  // If ip is not present in the table, call terminate.  This is for
  // If ip is not present in the table, call terminate.  This is for
  // a destructor inside a cleanup, or a library routine the compiler
  // a destructor inside a cleanup, or a library routine the compiler
  // was not expecting to throw.
  // was not expecting to throw.
  found_type = found_terminate;
  found_type = found_terminate;
  goto do_something;
  goto do_something;
 
 
 found_something:
 found_something:
  if (landing_pad == 0)
  if (landing_pad == 0)
    {
    {
      // If ip is present, and has a null landing pad, there are
      // If ip is present, and has a null landing pad, there are
      // no cleanups or handlers to be run.
      // no cleanups or handlers to be run.
      found_type = found_nothing;
      found_type = found_nothing;
    }
    }
  else if (action_record == 0)
  else if (action_record == 0)
    {
    {
      // If ip is present, has a non-null landing pad, and a null
      // If ip is present, has a non-null landing pad, and a null
      // action table offset, then there are only cleanups present.
      // action table offset, then there are only cleanups present.
      // Cleanups use a zero switch value, as set above.
      // Cleanups use a zero switch value, as set above.
      found_type = found_cleanup;
      found_type = found_cleanup;
    }
    }
  else
  else
    {
    {
      // Otherwise we have a catch handler or exception specification.
      // Otherwise we have a catch handler or exception specification.
 
 
      _sleb128_t ar_filter, ar_disp;
      _sleb128_t ar_filter, ar_disp;
      const std::type_info* catch_type;
      const std::type_info* catch_type;
      _throw_typet* throw_type;
      _throw_typet* throw_type;
      bool saw_cleanup = false;
      bool saw_cleanup = false;
      bool saw_handler = false;
      bool saw_handler = false;
 
 
#ifdef __ARM_EABI_UNWINDER__
#ifdef __ARM_EABI_UNWINDER__
      // ??? How does this work - more importantly, how does it interact with
      // ??? How does this work - more importantly, how does it interact with
      // dependent exceptions?
      // dependent exceptions?
      throw_type = ue_header;
      throw_type = ue_header;
      if (actions & _UA_FORCE_UNWIND)
      if (actions & _UA_FORCE_UNWIND)
        {
        {
          __GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class);
          __GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class);
        }
        }
      else if (!foreign_exception)
      else if (!foreign_exception)
        thrown_ptr = __get_object_from_ue (ue_header);
        thrown_ptr = __get_object_from_ue (ue_header);
#else
#else
#ifdef __GXX_RTTI
#ifdef __GXX_RTTI
      // During forced unwinding, match a magic exception type.
      // During forced unwinding, match a magic exception type.
      if (actions & _UA_FORCE_UNWIND)
      if (actions & _UA_FORCE_UNWIND)
        {
        {
          throw_type = &typeid(abi::__forced_unwind);
          throw_type = &typeid(abi::__forced_unwind);
        }
        }
      // With a foreign exception class, there's no exception type.
      // With a foreign exception class, there's no exception type.
      // ??? What to do about GNU Java and GNU Ada exceptions?
      // ??? What to do about GNU Java and GNU Ada exceptions?
      else if (foreign_exception)
      else if (foreign_exception)
        {
        {
          throw_type = &typeid(abi::__foreign_exception);
          throw_type = &typeid(abi::__foreign_exception);
        }
        }
      else
      else
#endif
#endif
        {
        {
          thrown_ptr = __get_object_from_ue (ue_header);
          thrown_ptr = __get_object_from_ue (ue_header);
          throw_type = __get_exception_header_from_obj
          throw_type = __get_exception_header_from_obj
            (thrown_ptr)->exceptionType;
            (thrown_ptr)->exceptionType;
        }
        }
#endif
#endif
 
 
      while (1)
      while (1)
        {
        {
          p = action_record;
          p = action_record;
          p = read_sleb128 (p, &ar_filter);
          p = read_sleb128 (p, &ar_filter);
          read_sleb128 (p, &ar_disp);
          read_sleb128 (p, &ar_disp);
 
 
          if (ar_filter == 0)
          if (ar_filter == 0)
            {
            {
              // Zero filter values are cleanups.
              // Zero filter values are cleanups.
              saw_cleanup = true;
              saw_cleanup = true;
            }
            }
          else if (ar_filter > 0)
          else if (ar_filter > 0)
            {
            {
              // Positive filter values are handlers.
              // Positive filter values are handlers.
              catch_type = get_ttype_entry (&info, ar_filter);
              catch_type = get_ttype_entry (&info, ar_filter);
 
 
              // Null catch type is a catch-all handler; we can catch foreign
              // Null catch type is a catch-all handler; we can catch foreign
              // exceptions with this.  Otherwise we must match types.
              // exceptions with this.  Otherwise we must match types.
              if (! catch_type
              if (! catch_type
                  || (throw_type
                  || (throw_type
                      && get_adjusted_ptr (catch_type, throw_type,
                      && get_adjusted_ptr (catch_type, throw_type,
                                           &thrown_ptr)))
                                           &thrown_ptr)))
                {
                {
                  saw_handler = true;
                  saw_handler = true;
                  break;
                  break;
                }
                }
            }
            }
          else
          else
            {
            {
              // Negative filter values are exception specifications.
              // Negative filter values are exception specifications.
              // ??? How do foreign exceptions fit in?  As far as I can
              // ??? How do foreign exceptions fit in?  As far as I can
              // see we can't match because there's no __cxa_exception
              // see we can't match because there's no __cxa_exception
              // object to stuff bits in for __cxa_call_unexpected to use.
              // object to stuff bits in for __cxa_call_unexpected to use.
              // Allow them iff the exception spec is non-empty.  I.e.
              // Allow them iff the exception spec is non-empty.  I.e.
              // a throw() specification results in __unexpected.
              // a throw() specification results in __unexpected.
              if ((throw_type
              if ((throw_type
                   && !(actions & _UA_FORCE_UNWIND)
                   && !(actions & _UA_FORCE_UNWIND)
                   && !foreign_exception)
                   && !foreign_exception)
                  ? ! check_exception_spec (&info, throw_type, thrown_ptr,
                  ? ! check_exception_spec (&info, throw_type, thrown_ptr,
                                            ar_filter)
                                            ar_filter)
                  : empty_exception_spec (&info, ar_filter))
                  : empty_exception_spec (&info, ar_filter))
                {
                {
                  saw_handler = true;
                  saw_handler = true;
                  break;
                  break;
                }
                }
            }
            }
 
 
          if (ar_disp == 0)
          if (ar_disp == 0)
            break;
            break;
          action_record = p + ar_disp;
          action_record = p + ar_disp;
        }
        }
 
 
      if (saw_handler)
      if (saw_handler)
        {
        {
          handler_switch_value = ar_filter;
          handler_switch_value = ar_filter;
          found_type = found_handler;
          found_type = found_handler;
        }
        }
      else
      else
        found_type = (saw_cleanup ? found_cleanup : found_nothing);
        found_type = (saw_cleanup ? found_cleanup : found_nothing);
    }
    }
 
 
 do_something:
 do_something:
   if (found_type == found_nothing)
   if (found_type == found_nothing)
     CONTINUE_UNWINDING;
     CONTINUE_UNWINDING;
 
 
  if (actions & _UA_SEARCH_PHASE)
  if (actions & _UA_SEARCH_PHASE)
    {
    {
      if (found_type == found_cleanup)
      if (found_type == found_cleanup)
        CONTINUE_UNWINDING;
        CONTINUE_UNWINDING;
 
 
      // For domestic exceptions, we cache data from phase 1 for phase 2.
      // For domestic exceptions, we cache data from phase 1 for phase 2.
      if (!foreign_exception)
      if (!foreign_exception)
        {
        {
          save_caught_exception(ue_header, context, thrown_ptr,
          save_caught_exception(ue_header, context, thrown_ptr,
                                handler_switch_value, language_specific_data,
                                handler_switch_value, language_specific_data,
                                landing_pad, action_record);
                                landing_pad, action_record);
        }
        }
      return _URC_HANDLER_FOUND;
      return _URC_HANDLER_FOUND;
    }
    }
 
 
 install_context:
 install_context:
 
 
  // We can't use any of the cxa routines with foreign exceptions,
  // We can't use any of the cxa routines with foreign exceptions,
  // because they all expect ue_header to be a struct __cxa_exception.
  // because they all expect ue_header to be a struct __cxa_exception.
  // So in that case, call terminate or unexpected directly.
  // So in that case, call terminate or unexpected directly.
  if ((actions & _UA_FORCE_UNWIND)
  if ((actions & _UA_FORCE_UNWIND)
      || foreign_exception)
      || foreign_exception)
    {
    {
      if (found_type == found_terminate)
      if (found_type == found_terminate)
        std::terminate ();
        std::terminate ();
      else if (handler_switch_value < 0)
      else if (handler_switch_value < 0)
        {
        {
          __try
          __try
            { std::unexpected (); }
            { std::unexpected (); }
          __catch(...)
          __catch(...)
            { std::terminate (); }
            { std::terminate (); }
        }
        }
    }
    }
  else
  else
    {
    {
      if (found_type == found_terminate)
      if (found_type == found_terminate)
        __cxa_call_terminate(ue_header);
        __cxa_call_terminate(ue_header);
 
 
      // Cache the TType base value for __cxa_call_unexpected, as we won't
      // Cache the TType base value for __cxa_call_unexpected, as we won't
      // have an _Unwind_Context then.
      // have an _Unwind_Context then.
      if (handler_switch_value < 0)
      if (handler_switch_value < 0)
        {
        {
          parse_lsda_header (context, language_specific_data, &info);
          parse_lsda_header (context, language_specific_data, &info);
 
 
#ifdef __ARM_EABI_UNWINDER__
#ifdef __ARM_EABI_UNWINDER__
          const _Unwind_Word* e;
          const _Unwind_Word* e;
          _Unwind_Word n;
          _Unwind_Word n;
 
 
          e = ((const _Unwind_Word*) info.TType) - handler_switch_value - 1;
          e = ((const _Unwind_Word*) info.TType) - handler_switch_value - 1;
          // Count the number of rtti objects.
          // Count the number of rtti objects.
          n = 0;
          n = 0;
          while (e[n] != 0)
          while (e[n] != 0)
            n++;
            n++;
 
 
          // Count.
          // Count.
          ue_header->barrier_cache.bitpattern[1] = n;
          ue_header->barrier_cache.bitpattern[1] = n;
          // Base (obsolete)
          // Base (obsolete)
          ue_header->barrier_cache.bitpattern[2] = 0;
          ue_header->barrier_cache.bitpattern[2] = 0;
          // Stride.
          // Stride.
          ue_header->barrier_cache.bitpattern[3] = 4;
          ue_header->barrier_cache.bitpattern[3] = 4;
          // List head.
          // List head.
          ue_header->barrier_cache.bitpattern[4] = (_Unwind_Word) e;
          ue_header->barrier_cache.bitpattern[4] = (_Unwind_Word) e;
#else
#else
          xh->catchTemp = base_of_encoded_value (info.ttype_encoding, context);
          xh->catchTemp = base_of_encoded_value (info.ttype_encoding, context);
#endif
#endif
        }
        }
    }
    }
 
 
  /* For targets with pointers smaller than the word size, we must extend the
  /* For targets with pointers smaller than the word size, we must extend the
     pointer, and this extension is target dependent.  */
     pointer, and this extension is target dependent.  */
  _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
  _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
                 __builtin_extend_pointer (ue_header));
                 __builtin_extend_pointer (ue_header));
  _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
  _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
                 handler_switch_value);
                 handler_switch_value);
  _Unwind_SetIP (context, landing_pad);
  _Unwind_SetIP (context, landing_pad);
#ifdef __ARM_EABI_UNWINDER__
#ifdef __ARM_EABI_UNWINDER__
  if (found_type == found_cleanup)
  if (found_type == found_cleanup)
    __cxa_begin_cleanup(ue_header);
    __cxa_begin_cleanup(ue_header);
#endif
#endif
  return _URC_INSTALL_CONTEXT;
  return _URC_INSTALL_CONTEXT;
}
}
 
 
/* The ARM EABI implementation of __cxa_call_unexpected is in a
/* The ARM EABI implementation of __cxa_call_unexpected is in a
   different file so that the personality routine (PR) can be used
   different file so that the personality routine (PR) can be used
   standalone.  The generic routine shared datastructures with the PR
   standalone.  The generic routine shared datastructures with the PR
   so it is most convenient to implement it here.  */
   so it is most convenient to implement it here.  */
#ifndef __ARM_EABI_UNWINDER__
#ifndef __ARM_EABI_UNWINDER__
extern "C" void
extern "C" void
__cxa_call_unexpected (void *exc_obj_in)
__cxa_call_unexpected (void *exc_obj_in)
{
{
  _Unwind_Exception *exc_obj
  _Unwind_Exception *exc_obj
    = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
    = reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
 
 
  __cxa_begin_catch (exc_obj);
  __cxa_begin_catch (exc_obj);
 
 
  // This function is a handler for our exception argument.  If we exit
  // This function is a handler for our exception argument.  If we exit
  // by throwing a different exception, we'll need the original cleaned up.
  // by throwing a different exception, we'll need the original cleaned up.
  struct end_catch_protect
  struct end_catch_protect
  {
  {
    end_catch_protect() { }
    end_catch_protect() { }
    ~end_catch_protect() { __cxa_end_catch(); }
    ~end_catch_protect() { __cxa_end_catch(); }
  } end_catch_protect_obj;
  } end_catch_protect_obj;
 
 
  lsda_header_info info;
  lsda_header_info info;
  __cxa_exception *xh = __get_exception_header_from_ue (exc_obj);
  __cxa_exception *xh = __get_exception_header_from_ue (exc_obj);
  const unsigned char *xh_lsda;
  const unsigned char *xh_lsda;
  _Unwind_Sword xh_switch_value;
  _Unwind_Sword xh_switch_value;
  std::terminate_handler xh_terminate_handler;
  std::terminate_handler xh_terminate_handler;
 
 
  // If the unexpectedHandler rethrows the exception (e.g. to categorize it),
  // If the unexpectedHandler rethrows the exception (e.g. to categorize it),
  // it will clobber data about the current handler.  So copy the data out now.
  // it will clobber data about the current handler.  So copy the data out now.
  xh_lsda = xh->languageSpecificData;
  xh_lsda = xh->languageSpecificData;
  xh_switch_value = xh->handlerSwitchValue;
  xh_switch_value = xh->handlerSwitchValue;
  xh_terminate_handler = xh->terminateHandler;
  xh_terminate_handler = xh->terminateHandler;
  info.ttype_base = (_Unwind_Ptr) xh->catchTemp;
  info.ttype_base = (_Unwind_Ptr) xh->catchTemp;
 
 
  __try
  __try
    { __unexpected (xh->unexpectedHandler); }
    { __unexpected (xh->unexpectedHandler); }
  __catch(...)
  __catch(...)
    {
    {
      // Get the exception thrown from unexpected.
      // Get the exception thrown from unexpected.
 
 
      __cxa_eh_globals *globals = __cxa_get_globals_fast ();
      __cxa_eh_globals *globals = __cxa_get_globals_fast ();
      __cxa_exception *new_xh = globals->caughtExceptions;
      __cxa_exception *new_xh = globals->caughtExceptions;
      void *new_ptr = __get_object_from_ambiguous_exception (new_xh);
      void *new_ptr = __get_object_from_ambiguous_exception (new_xh);
 
 
      // We don't quite have enough stuff cached; re-parse the LSDA.
      // We don't quite have enough stuff cached; re-parse the LSDA.
      parse_lsda_header (0, xh_lsda, &info);
      parse_lsda_header (0, xh_lsda, &info);
 
 
      // If this new exception meets the exception spec, allow it.
      // If this new exception meets the exception spec, allow it.
      if (check_exception_spec (&info, __get_exception_header_from_obj
      if (check_exception_spec (&info, __get_exception_header_from_obj
                                  (new_ptr)->exceptionType,
                                  (new_ptr)->exceptionType,
                                new_ptr, xh_switch_value))
                                new_ptr, xh_switch_value))
        __throw_exception_again;
        __throw_exception_again;
 
 
      // If the exception spec allows std::bad_exception, throw that.
      // If the exception spec allows std::bad_exception, throw that.
      // We don't have a thrown object to compare against, but since
      // We don't have a thrown object to compare against, but since
      // bad_exception doesn't have virtual bases, that's OK; just pass 0.
      // bad_exception doesn't have virtual bases, that's OK; just pass 0.
#if defined(__EXCEPTIONS) && defined(__GXX_RTTI)
#if defined(__EXCEPTIONS) && defined(__GXX_RTTI)
      const std::type_info &bad_exc = typeid (std::bad_exception);
      const std::type_info &bad_exc = typeid (std::bad_exception);
      if (check_exception_spec (&info, &bad_exc, 0, xh_switch_value))
      if (check_exception_spec (&info, &bad_exc, 0, xh_switch_value))
        throw std::bad_exception();
        throw std::bad_exception();
#endif   
#endif   
 
 
      // Otherwise, die.
      // Otherwise, die.
      __terminate (xh_terminate_handler);
      __terminate (xh_terminate_handler);
    }
    }
}
}
#endif
#endif
 
 
} // namespace __cxxabiv1
} // namespace __cxxabiv1
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.