1// Copyright (C) 2012 The Android Open Source Project
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1. Redistributions of source code must retain the above copyright
8//    notice, this list of conditions and the following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright
10//    notice, this list of conditions and the following disclaimer in the
11//    documentation and/or other materials provided with the distribution.
12// 3. Neither the name of the project nor the names of its contributors
13//    may be used to endorse or promote products derived from this software
14//    without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19// ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26// SUCH DAMAGE.
27
28#ifndef __GXXABI_HELPER_FUNC_INTERNAL_H
29#define __GXXABI_HELPER_FUNC_INTERNAL_H
30
31#include <cxxabi.h>
32#include <exception>
33#include <unwind.h>
34#include "dwarf_helper.h"
35
36// Target-independent helper functions
37namespace __cxxabiv1 {
38
39  _GABIXX_NORETURN void call_terminate(_Unwind_Exception* unwind_exception) _GABIXX_HIDDEN;
40
41#if __arm__
42  uint32_t decodeRelocTarget2 (uint32_t ptr) _GABIXX_HIDDEN;
43#endif
44
45  // An exception spec acts like a catch handler, but in reverse.
46  // If any catchType in the list can catch an excpType,
47  // then this exception spec does not catch the excpType.
48  bool canExceptionSpecCatch(int64_t specIndex,
49                             const uint8_t* classInfo,
50                             uint8_t ttypeEncoding,
51                             const std::type_info* excpType,
52                             void* adjustedPtr,
53                             _Unwind_Exception* unwind_exception)
54      _GABIXX_HIDDEN;
55
56  void setRegisters(_Unwind_Exception* unwind_exception,
57                    _Unwind_Context* context,
58                    const ScanResultInternal& results) _GABIXX_HIDDEN;
59
60  _Unwind_Reason_Code continueUnwinding(_Unwind_Exception *ex,
61                                        _Unwind_Context *context)
62      _GABIXX_HIDDEN;
63
64  void saveDataToBarrierCache(_Unwind_Exception* exc,
65                              _Unwind_Context* ctx,
66                              const ScanResultInternal& results)
67      _GABIXX_HIDDEN;
68
69  void loadDataFromBarrierCache(_Unwind_Exception* exc,
70                                ScanResultInternal& results)
71      _GABIXX_HIDDEN;
72
73  void prepareBeginCleanup(_Unwind_Exception* exc) _GABIXX_HIDDEN;
74
75  void saveUnexpectedDataToBarrierCache(_Unwind_Exception* exc,
76                                        _Unwind_Context* ctx,
77                                        const ScanResultInternal& results)
78      _GABIXX_HIDDEN;
79
80  void scanEHTable(ScanResultInternal& results,
81                   _Unwind_Action actions,
82                   bool native_exception,
83                   _Unwind_Exception* unwind_exception,
84                   _Unwind_Context* context) _GABIXX_HIDDEN;
85
86  // Make it easier to adapt to Itanium PR
87#ifdef __arm__
88
89  extern "C"
90  _Unwind_Reason_Code __gxx_personality_v0(_Unwind_State,
91                                           _Unwind_Exception*,
92                                           _Unwind_Context*) _GABIXX_DEFAULT;
93
94#  define BEGIN_DEFINE_PERSONALITY_FUNC \
95    __gxx_personality_v0(_Unwind_State state, \
96                         _Unwind_Exception* unwind_exception, \
97                         _Unwind_Context* context) { \
98      int version = 1; \
99      uint64_t exceptionClass = unwind_exception->exception_class; \
100      _Unwind_Action actions = 0; \
101      switch (state) { \
102      default: { \
103        return _URC_FAILURE; \
104      } \
105      case _US_VIRTUAL_UNWIND_FRAME: { \
106        actions = _UA_SEARCH_PHASE; \
107        break; \
108      } \
109      case _US_UNWIND_FRAME_STARTING: { \
110        actions = _UA_CLEANUP_PHASE; \
111        if (unwind_exception->barrier_cache.sp == _Unwind_GetGR(context, UNWIND_STACK_REG)) { \
112          actions |= _UA_HANDLER_FRAME; \
113        } \
114        break; \
115      } \
116      case _US_UNWIND_FRAME_RESUME: { \
117        return continueUnwinding(unwind_exception, context); \
118        break; \
119      } \
120      } \
121      _Unwind_SetGR (context, UNWIND_POINTER_REG, reinterpret_cast<uint32_t>(unwind_exception));
122#else // ! __arm__
123
124  extern "C"
125  _Unwind_Reason_Code __gxx_personality_v0(int, _Unwind_Action, uint64_t,
126                                           _Unwind_Exception*,
127                                           _Unwind_Context*) _GABIXX_DEFAULT;
128
129#  define BEGIN_DEFINE_PERSONALITY_FUNC \
130      __gxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass, \
131                           _Unwind_Exception* unwind_exception, _Unwind_Context* context) {
132#endif
133
134} // namespace __cxxabiv1
135
136#endif // __GXXABI_HELPER_FUNC_INTERNAL_H
137