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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libstdc++-v3/] [libsupc++/] [eh_arm.cc] - Blame information for rev 847

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
// -*- C++ -*- ARM specific Exception handling support routines.
2
// Copyright (C) 2004, 2005, 2008, 2009 Free Software Foundation, Inc.
3
//
4
// This file is part of GCC.
5
//
6
// GCC is free software; you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation; either version 3, or (at your option)
9
// any later version.
10
//
11
// GCC is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
//
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
//
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// <http://www.gnu.org/licenses/>.
24
 
25
#include <cxxabi.h>
26
#include "unwind-cxx.h"
27
 
28
#ifdef __ARM_EABI_UNWINDER__
29
 
30
using namespace __cxxabiv1;
31
 
32
 
33
// Given the thrown type THROW_TYPE, pointer to a variable containing a
34
// pointer to the exception object THROWN_PTR_P and a type CATCH_TYPE to
35
// compare against, return whether or not there is a match and if so,
36
// update *THROWN_PTR_P.
37
 
38
extern "C" __cxa_type_match_result
39
__cxa_type_match(_Unwind_Exception* ue_header,
40
                 const std::type_info* catch_type,
41
                 bool is_reference __attribute__((__unused__)),
42
                 void** thrown_ptr_p)
43
{
44
  bool forced_unwind = __is_gxx_forced_unwind_class(ue_header->exception_class);
45
  bool foreign_exception = !forced_unwind && !__is_gxx_exception_class(ue_header->exception_class);
46
  bool dependent_exception =
47
    __is_dependent_exception(ue_header->exception_class);
48
  __cxa_exception* xh = __get_exception_header_from_ue(ue_header);
49
  __cxa_dependent_exception *dx = __get_dependent_exception_from_ue(ue_header);
50
  const std::type_info* throw_type;
51
 
52
  if (forced_unwind)
53
    throw_type = &typeid(abi::__forced_unwind);
54
  else if (foreign_exception)
55
    throw_type = &typeid(abi::__foreign_exception);
56
  else if (dependent_exception)
57
    throw_type = __get_exception_header_from_obj
58
      (dx->primaryException)->exceptionType;
59
  else
60
    throw_type = xh->exceptionType;
61
 
62
  void* thrown_ptr = *thrown_ptr_p;
63
 
64
  // Pointer types need to adjust the actual pointer, not
65
  // the pointer to pointer that is the exception object.
66
  // This also has the effect of passing pointer types
67
  // "by value" through the __cxa_begin_catch return value.
68
  if (throw_type->__is_pointer_p())
69
    thrown_ptr = *(void**) thrown_ptr;
70
 
71
  if (catch_type->__do_catch(throw_type, &thrown_ptr, 1))
72
    {
73
      *thrown_ptr_p = thrown_ptr;
74
 
75
      if (typeid(*catch_type) == typeid (typeid(void*)))
76
        {
77
          const __pointer_type_info *catch_pointer_type =
78
            static_cast<const __pointer_type_info *> (catch_type);
79
          const __pointer_type_info *throw_pointer_type =
80
            static_cast<const __pointer_type_info *> (throw_type);
81
 
82
          if (typeid (*catch_pointer_type->__pointee) != typeid (void)
83
              && (*catch_pointer_type->__pointee !=
84
                  *throw_pointer_type->__pointee))
85
            return ctm_succeeded_with_ptr_to_base;
86
        }
87
 
88
      return ctm_succeeded;
89
    }
90
 
91
  return ctm_failed;
92
}
93
 
94
// ABI defined routine called at the start of a cleanup handler.
95
extern "C" bool
96
__cxa_begin_cleanup(_Unwind_Exception* ue_header)
97
{
98
  __cxa_eh_globals *globals = __cxa_get_globals();
99
  __cxa_exception *header = __get_exception_header_from_ue(ue_header);
100
  bool native = __is_gxx_exception_class(header->unwindHeader.exception_class);
101
 
102
 
103
  if (native)
104
    {
105
      header->propagationCount++;
106
      // Add it to the chain if this is the first time we've seen this
107
      // exception.
108
      if (header->propagationCount == 1)
109
        {
110
          header->nextPropagatingException = globals->propagatingExceptions;
111
          globals->propagatingExceptions = header;
112
        }
113
    }
114
  else
115
    {
116
      // Remember the exception object, so end_cleanup can return it.
117
      // These cannot be stacked, so we must abort if we already have
118
      // a propagating exception.
119
      if (globals->propagatingExceptions)
120
        std::terminate ();
121
      globals->propagatingExceptions = header;
122
    }
123
 
124
  return true;
125
}
126
 
127
// Do the work for __cxa_end_cleanup.  Returns the currently propagating
128
// exception object.
129
extern "C" _Unwind_Exception *
130
__gnu_end_cleanup(void)
131
{
132
  __cxa_exception *header;
133
  __cxa_eh_globals *globals = __cxa_get_globals();
134
 
135
  header = globals->propagatingExceptions;
136
 
137
  // Check something hasn't gone horribly wrong.
138
  if (!header)
139
    std::terminate();
140
 
141
  if (__is_gxx_exception_class(header->unwindHeader.exception_class))
142
    {
143
      header->propagationCount--;
144
      if (header->propagationCount == 0)
145
        {
146
          // Remove exception from chain.
147
          globals->propagatingExceptions = header->nextPropagatingException;
148
          header->nextPropagatingException = NULL;
149
        }
150
    }
151
  else
152
    globals->propagatingExceptions = NULL;
153
 
154
  return &header->unwindHeader;
155
}
156
 
157
// Assembly wrapper to call __gnu_end_cleanup without clobbering r1-r3.
158
// Also push r4 to preserve stack alignment.
159
#ifdef __thumb__
160
asm (".global __cxa_end_cleanup\n"
161
"       .type __cxa_end_cleanup, \"function\"\n"
162
"       .thumb_func\n"
163
"__cxa_end_cleanup:\n"
164
"       push\t{r1, r2, r3, r4}\n"
165
"       bl\t__gnu_end_cleanup\n"
166
"       pop\t{r1, r2, r3, r4}\n"
167
"       bl\t_Unwind_Resume @ Never returns\n");
168
#else
169
asm (".global __cxa_end_cleanup\n"
170
"       .type __cxa_end_cleanup, \"function\"\n"
171
"__cxa_end_cleanup:\n"
172
"       stmfd\tsp!, {r1, r2, r3, r4}\n"
173
"       bl\t__gnu_end_cleanup\n"
174
"       ldmfd\tsp!, {r1, r2, r3, r4}\n"
175
"       bl\t_Unwind_Resume @ Never returns\n");
176
#endif
177
 
178
#endif

powered by: WebSVN 2.1.0

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