1b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===------------------------------- unwind.h -----------------------------===//
2b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
3b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//                     The LLVM Compiler Infrastructure
4b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
5b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// This file is dual licensed under the MIT and the University of Illinois Open
6b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// Source Licenses. See LICENSE.TXT for details.
7b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
8b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
9b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// C++ ABI Level 1 ABI documented at:
10b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//   http://mentorembedded.github.io/cxx-abi/abi-eh.html
11b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
12b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===----------------------------------------------------------------------===//
13b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
14b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifndef __UNWIND_H__
15b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#define __UNWIND_H__
16b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
17b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdint.h>
18b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stddef.h>
19b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
20839f7f23c0a652e2b799345fc3112ae0c5a03098Saleem Abdulrasool#if defined(__APPLE__)
2129180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik#define LIBUNWIND_UNAVAIL __attribute__ (( unavailable ))
22839f7f23c0a652e2b799345fc3112ae0c5a03098Saleem Abdulrasool#else
2329180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik#define LIBUNWIND_UNAVAIL
24839f7f23c0a652e2b799345fc3112ae0c5a03098Saleem Abdulrasool#endif
25839f7f23c0a652e2b799345fc3112ae0c5a03098Saleem Abdulrasool
26e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// FIXME: This is also in cxxabi.h and libunwind.h, can we consolidate?
27e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
28e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
29e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#define LIBCXXABI_ARM_EHABI 1
30e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else
31e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#define LIBCXXABI_ARM_EHABI 0
32e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
33e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
34b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef enum {
35b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _URC_NO_REASON = 0,
36e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _URC_OK = 0,
37b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
38b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _URC_FATAL_PHASE2_ERROR = 2,
39b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _URC_FATAL_PHASE1_ERROR = 3,
40b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _URC_NORMAL_STOP = 4,
41b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _URC_END_OF_STACK = 5,
42b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _URC_HANDLER_FOUND = 6,
43b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _URC_INSTALL_CONTEXT = 7,
44e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _URC_CONTINUE_UNWIND = 8,
45e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI
46e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _URC_FAILURE = 9
47e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
48b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} _Unwind_Reason_Code;
49b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
50b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef enum {
51b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _UA_SEARCH_PHASE = 1,
52b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _UA_CLEANUP_PHASE = 2,
53b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _UA_HANDLER_FRAME = 4,
54b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _UA_FORCE_UNWIND = 8,
55b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _UA_END_OF_STACK = 16 // gcc extension to C++ ABI
56b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} _Unwind_Action;
57b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
58e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef struct _Unwind_Context _Unwind_Context;   // opaque
59e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
60e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI
61e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef uint32_t _Unwind_State;
62e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
63e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic const _Unwind_State _US_VIRTUAL_UNWIND_FRAME   = 0;
64e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic const _Unwind_State _US_UNWIND_FRAME_STARTING  = 1;
65e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic const _Unwind_State _US_UNWIND_FRAME_RESUME    = 2;
66e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
67e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef uint32_t _Unwind_EHT_Header;
68e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
69e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstruct _Unwind_Control_Block;
70e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef struct _Unwind_Control_Block _Unwind_Control_Block;
71e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
72e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
73e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstruct _Unwind_Control_Block {
74e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uint64_t exception_class;
75e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block*);
76e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
77e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  /* Unwinder cache, private fields for the unwinder's use */
78e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  struct {
79e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t reserved1; /* init reserved1 to 0, then don't touch */
80e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t reserved2;
81e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t reserved3;
82e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t reserved4;
83e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t reserved5;
84e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  } unwinder_cache;
85e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
86e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  /* Propagation barrier cache (valid after phase 1): */
87e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  struct {
88e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t sp;
89e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t bitpattern[5];
90e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  } barrier_cache;
91e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
92e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  /* Cleanup cache (preserved over cleanup): */
93e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  struct {
94e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t bitpattern[4];
95e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  } cleanup_cache;
96e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
97e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  /* Pr cache (for pr's benefit): */
98e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  struct {
99e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t fnstart; /* function start address */
100e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    _Unwind_EHT_Header* ehtp; /* pointer to EHT entry header word */
101e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t additional;
102e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t reserved1;
103e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  } pr_cache;
104e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
105e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  long long int :0; /* Enforce the 8-byte alignment */
106e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert};
107e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
108e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
109e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert      (_Unwind_State state,
110e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert       _Unwind_Exception* exceptionObject,
111e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert       struct _Unwind_Context* context);
112e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
113e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef _Unwind_Reason_Code (*__personality_routine)
114e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert      (_Unwind_State state,
115e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert       _Unwind_Exception* exceptionObject,
116e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert       struct _Unwind_Context* context);
117e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else
118b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct _Unwind_Context;   // opaque
119b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct _Unwind_Exception; // forward declaration
120e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef struct _Unwind_Exception _Unwind_Exception;
121b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
122b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct _Unwind_Exception {
123b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint64_t exception_class;
124b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  void (*exception_cleanup)(_Unwind_Reason_Code reason,
125e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                            _Unwind_Exception *exc);
126b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t private_1; // non-zero means forced unwind
127b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t private_2; // holds sp that phase1 found for phase2 to use
128b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if !__LP64__
129b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // The gcc implementation of _Unwind_Exception used attribute mode on the
130b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // above fields which had the side effect of causing this whole struct to
131b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // round up to 32 bytes in size. To be more explicit, we add pad fields
132b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // added for binary compatibility.
133b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t reserved[3];
134b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
135b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
136b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
137b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
138b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    (int version,
139b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik     _Unwind_Action actions,
140b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik     uint64_t exceptionClass,
141e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert     _Unwind_Exception* exceptionObject,
142b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik     struct _Unwind_Context* context,
143b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik     void* stop_parameter );
144b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
145b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef _Unwind_Reason_Code (*__personality_routine)
146b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      (int version,
147b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik       _Unwind_Action actions,
148b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik       uint64_t exceptionClass,
149e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert       _Unwind_Exception* exceptionObject,
150b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik       struct _Unwind_Context* context);
151e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
152b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
153b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifdef __cplusplus
154b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern "C" {
155b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
156b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
157b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
158b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// The following are the base functions documented by the C++ ABI
159b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
160c2e9313c38fdd56ecd50d7cd21e8a14d8f16a1b7Dan Albert#if __USING_SJLJ_EXCEPTIONS__
161b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code
162e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    _Unwind_SjLj_RaiseException(_Unwind_Exception *exception_object);
163e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern void _Unwind_SjLj_Resume(_Unwind_Exception *exception_object);
164b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else
165b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code
166e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    _Unwind_RaiseException(_Unwind_Exception *exception_object);
167e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern void _Unwind_Resume(_Unwind_Exception *exception_object);
168b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
169e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern void _Unwind_DeleteException(_Unwind_Exception *exception_object);
170e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
171e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI
172e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef enum {
173e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSC_CORE = 0, /* integer register */
174e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSC_VFP = 1, /* vfp */
175e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSC_WMMXD = 3, /* Intel WMMX data register */
176e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSC_WMMXC = 4 /* Intel WMMX control register */
177e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} _Unwind_VRS_RegClass;
178e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
179e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef enum {
180e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSD_UINT32 = 0,
181e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSD_VFPX = 1,
182e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSD_UINT64 = 3,
183e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSD_FLOAT = 4,
184e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSD_DOUBLE = 5
185e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} _Unwind_VRS_DataRepresentation;
186e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
187e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef enum {
188e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSR_OK = 0,
189e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSR_NOT_IMPLEMENTED = 1,
190e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _UVRSR_FAILED = 2
191e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} _Unwind_VRS_Result;
192e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
193e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern void _Unwind_Complete(_Unwind_Exception* exception_object);
194e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
195e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern _Unwind_VRS_Result
196e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert_Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
197e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                uint32_t regno, _Unwind_VRS_DataRepresentation representation,
198e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                void *valuep);
199e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
200e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern _Unwind_VRS_Result
201e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert_Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
202e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                uint32_t regno, _Unwind_VRS_DataRepresentation representation,
203e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                void *valuep);
204e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
205e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern _Unwind_VRS_Result
206e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert_Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
207e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                uint32_t discriminator,
208e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                _Unwind_VRS_DataRepresentation representation);
209e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
210e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline uintptr_t _Unwind_GetGR(struct _Unwind_Context* context,
211e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                                      int index) {
212e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uintptr_t value = 0;
213e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
214e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  return value;
215e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}
216e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
217e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline void _Unwind_SetGR(struct _Unwind_Context* context, int index,
218e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                                 uintptr_t new_value) {
219e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index,
220e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                  _UVRSD_UINT32, &new_value);
221e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}
222e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
223e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline uintptr_t _Unwind_GetIP(struct _Unwind_Context* context) {
224e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  // remove the thumb-bit before returning
225e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  return (_Unwind_GetGR(context, 15) & (~(uintptr_t)0x1));
226e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}
227e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
228e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline void _Unwind_SetIP(struct _Unwind_Context* context,
229e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                                 uintptr_t new_value) {
230e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
231e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _Unwind_SetGR(context, 15, new_value | thumb_bit);
232e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}
233e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else
234b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index);
235b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void _Unwind_SetGR(struct _Unwind_Context *context, int index,
236b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                          uintptr_t new_value);
237b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context);
238b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value);
239e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
240e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
241b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context);
242b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t
243b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context);
244e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __USING_SJLJ_EXCEPTIONS__
245b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code
246e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *exception_object,
247b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              _Unwind_Stop_Fn stop, void *stop_parameter);
248b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else
249b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code
250e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    _Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
251b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                         _Unwind_Stop_Fn stop, void *stop_parameter);
252b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
253b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
254e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __USING_SJLJ_EXCEPTIONS__
255b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t;
256b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc);
257b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc);
258b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
259b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
260b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
261b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// The following are semi-suppoted extensions to the C++ ABI
262b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
263b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
264b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
265b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//  called by __cxa_rethrow().
266b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
267e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __USING_SJLJ_EXCEPTIONS__
268b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code
269e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *exception_object);
270b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else
271b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code
272e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object);
273b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
274b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
275b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_Backtrace() is a gcc extension that walks the stack and calls the
276b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack
277b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON.
278b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
279b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                void *);
280b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *);
281b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
282b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_GetCFA is a gcc extension that can be called from within a
283b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// personality handler to get the CFA (stack pointer before call) of
284b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// current frame.
285b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *);
286b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
287b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
288b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_GetIPInfo is a gcc extension that can be called from within a
289e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// personality handler.  Similar to _Unwind_GetIP() but also returns in
290e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// *ipBefore a non-zero value if the instruction pointer is at or before the
291e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// instruction causing the unwind. Normally, in a function call, the IP returned
292b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// is the return address which is after the call instruction and may be past the
293b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// end of the function containing the call instruction.
294b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
295b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                   int *ipBefore);
296b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
297b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
298b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// __register_frame() is used with dynamically generated code to register the
299b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// FDE for a generated (JIT) code.  The FDE must use pc-rel addressing to point
300b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// to its function and optional LSDA.
301b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// __register_frame() has existed in all versions of Mac OS X, but in 10.4 and
302b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 10.5 it was buggy and did not actually register the FDE with the unwinder.
303b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// In 10.6 and later it does register properly.
304b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame(const void *fde);
305b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __deregister_frame(const void *fde);
306b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
307b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has
308b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind
309b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// info" which the runtime uses in preference to dwarf unwind info.  This
310b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// function will only work if the target function has an FDE but no compact
311b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// unwind info.
312b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct dwarf_eh_bases {
313b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t tbase;
314b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t dbase;
315b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t func;
316b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
317b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *);
318b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
319b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
320b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// This function attempts to find the start (address of first instruction) of
321b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// a function given an address inside the function.  It only works if the
322b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// function has an FDE (dwarf unwind info).
323b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// This function is unimplemented on Mac OS X 10.6 and later.  Instead, use
324b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result.
325b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void *_Unwind_FindEnclosingFunction(void *pc);
326b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
327b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// Mac OS X does not support text-rel and data-rel addressing so these functions
328b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// are unimplemented
329b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context)
33029180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik    LIBUNWIND_UNAVAIL;
331b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context)
33229180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik    LIBUNWIND_UNAVAIL;
333b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
334b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// Mac OS X 10.4 and 10.5 had implementations of these functions in
335b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// libgcc_s.dylib, but they never worked.
336b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// These functions are no longer available on Mac OS X.
337b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_info_bases(const void *fde, void *ob, void *tb,
33829180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik                                        void *db) LIBUNWIND_UNAVAIL;
339b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_info(const void *fde, void *ob)
34029180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik    LIBUNWIND_UNAVAIL;
341b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_info_table_bases(const void *fde, void *ob,
342b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                              void *tb, void *db)
34329180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik    LIBUNWIND_UNAVAIL;
344b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_info_table(const void *fde, void *ob)
34529180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik    LIBUNWIND_UNAVAIL;
346b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_table(const void *fde)
34729180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik    LIBUNWIND_UNAVAIL;
348b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void *__deregister_frame_info(const void *fde)
34929180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik    LIBUNWIND_UNAVAIL;
350b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void *__deregister_frame_info_bases(const void *fde)
35129180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik    LIBUNWIND_UNAVAIL;
352b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
353b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifdef __cplusplus
354b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
355b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
356b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
357b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // __UNWIND_H__
358