]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libcxxrt/unwind-arm.h
Import libc++ / libcxxrt into base. Not build by default yet (use
[FreeBSD/FreeBSD.git] / contrib / libcxxrt / unwind-arm.h
1 /**
2  * ARM-specific unwind definitions.  These are taken from the ARM EHABI
3  * specification.
4  */
5  typedef enum
6 {
7         _URC_OK = 0,                /* operation completed successfully */
8         _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
9     _URC_END_OF_STACK = 5,
10         _URC_HANDLER_FOUND = 6,
11         _URC_INSTALL_CONTEXT = 7,
12         _URC_CONTINUE_UNWIND = 8,
13         _URC_FAILURE = 9,            /* unspecified failure of some kind */
14         _URC_FATAL_PHASE1_ERROR = _URC_FAILURE
15 } _Unwind_Reason_Code;
16
17 typedef uint32_t _Unwind_State;
18 #ifdef __clang__
19 static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME  = 0;
20 static const _Unwind_State _US_UNWIND_FRAME_STARTING = 1;
21 static const _Unwind_State _US_UNWIND_FRAME_RESUME   = 2;
22 #else // GCC fails at knowing what a constant expression is
23 #       define _US_VIRTUAL_UNWIND_FRAME  0
24 #       define _US_UNWIND_FRAME_STARTING 1
25 #       define _US_UNWIND_FRAME_RESUME 2
26 #endif
27
28 typedef struct _Unwind_Context _Unwind_Context;
29
30 typedef uint32_t _Unwind_EHT_Header;
31
32 struct _Unwind_Exception
33 {
34         uint64_t exception_class;
35         void (*exception_cleanup)(_Unwind_Reason_Code, struct _Unwind_Exception *);
36         /* Unwinder cache, private fields for the unwinder's use */
37         struct
38         {
39                 uint32_t reserved1;
40                 uint32_t reserved2;
41                 uint32_t reserved3;
42                 uint32_t reserved4;
43                 uint32_t reserved5;
44         /* init reserved1 to 0, then don't touch */
45         } unwinder_cache;
46         /* Propagation barrier cache (valid after phase 1): */
47         struct
48         {
49                 uint32_t sp;
50                 uint32_t bitpattern[5];
51         } barrier_cache;
52         /* Cleanup cache (preserved over cleanup): */
53         struct
54         {
55                 uint32_t bitpattern[4];
56         } cleanup_cache;
57         /* Pr cache (for pr's benefit): */
58         struct
59         {
60                 /** function start address */
61                 uint32_t fnstart;
62                 /** pointer to EHT entry header word */
63                 _Unwind_EHT_Header *ehtp;
64                 /** additional data */
65                 uint32_t additional;
66                 uint32_t reserved1;
67         } pr_cache;
68         /** Force alignment of next item to 8-byte boundary */
69         long long int :0;
70 };
71
72 /* Unwinding functions */
73 _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *ucbp);
74 void _Unwind_Resume(struct _Unwind_Exception *ucbp);
75 void _Unwind_Complete(struct _Unwind_Exception *ucbp);
76 void _Unwind_DeleteException(struct _Unwind_Exception *ucbp);
77 void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context*);
78
79 typedef enum
80 {
81         _UVRSR_OK = 0,
82         _UVRSR_NOT_IMPLEMENTED = 1,
83         _UVRSR_FAILED = 2
84 } _Unwind_VRS_Result;
85 typedef enum
86 {
87         _UVRSC_CORE = 0,
88         _UVRSC_VFP = 1,
89         _UVRSC_WMMXD = 3,
90         _UVRSC_WMMXC = 4
91 } _Unwind_VRS_RegClass;
92 typedef enum
93 {
94         _UVRSD_UINT32 = 0,
95         _UVRSD_VFPX = 1,
96         _UVRSD_UINT64 = 3,
97         _UVRSD_FLOAT = 4,
98         _UVRSD_DOUBLE = 5
99 } _Unwind_VRS_DataRepresentation;
100
101 _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *context,
102                                    _Unwind_VRS_RegClass regclass,
103                                    uint32_t regno,
104                                    _Unwind_VRS_DataRepresentation representation,
105                                    void *valuep);
106 _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context,
107                                    _Unwind_VRS_RegClass regclass,
108                                    uint32_t regno,
109                                    _Unwind_VRS_DataRepresentation representation,
110                                    void *valuep);
111
112 /* Return the base-address for data references.  */
113 extern unsigned long _Unwind_GetDataRelBase(struct _Unwind_Context *);
114
115 /* Return the base-address for text references.  */
116 extern unsigned long _Unwind_GetTextRelBase(struct _Unwind_Context *);
117 extern unsigned long _Unwind_GetRegionStart(struct _Unwind_Context *);
118
119 typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *,
120                                                  void *);
121 extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
122 extern _Unwind_Reason_Code
123           _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
124
125 /**
126  * The next set of functions are compatibility extensions, implementing Itanium
127  * ABI functions on top of ARM ones.
128  */
129
130 #define _UA_SEARCH_PHASE        1
131 #define _UA_CLEANUP_PHASE       2
132 #define _UA_HANDLER_FRAME       4
133 #define _UA_FORCE_UNWIND        8
134
135 static inline unsigned long _Unwind_GetGR(struct _Unwind_Context *context, int reg)
136 {
137         unsigned long val;
138         _Unwind_VRS_Get(context, _UVRSC_CORE, reg, _UVRSD_UINT32, &val);
139         return val;
140 }
141 static inline  void _Unwind_SetGR(struct _Unwind_Context *context, int reg, unsigned long val)
142 {
143         _Unwind_VRS_Set(context, _UVRSC_CORE, reg, _UVRSD_UINT32, &val);
144 }
145 static inline unsigned long _Unwind_GetIP(_Unwind_Context *context)
146 {
147         // Low bit store the thumb state - discard it
148         return _Unwind_GetGR(context, 15) & ~1;
149 }
150 static inline void _Unwind_SetIP(_Unwind_Context *context, unsigned long val)
151 {
152         // The lowest bit of the instruction pointer indicates whether we're in
153         // thumb or ARM mode.  This is assumed to be fixed throughout a function,
154         // so must be propagated when setting the program counter.
155         unsigned long thumbState = _Unwind_GetGR(context, 15) & 1;
156    _Unwind_SetGR(context, 15, (val | thumbState));
157 }
158
159 /** GNU API function that unwinds the frame */
160 _Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception*, struct _Unwind_Context*);
161
162
163 #define DECLARE_PERSONALITY_FUNCTION(name) \
164 _Unwind_Reason_Code name(_Unwind_State state,\
165                          struct _Unwind_Exception *exceptionObject,\
166                          struct _Unwind_Context *context);
167
168 #define BEGIN_PERSONALITY_FUNCTION(name) \
169 _Unwind_Reason_Code name(_Unwind_State state,\
170                          struct _Unwind_Exception *exceptionObject,\
171                          struct _Unwind_Context *context)\
172 {\
173         int version = 1;\
174         uint64_t exceptionClass = exceptionObject->exception_class;\
175         int actions;\
176         switch (state)\
177         {\
178                 default: return _URC_FAILURE;\
179                 case _US_VIRTUAL_UNWIND_FRAME:\
180                 {\
181                         actions = _UA_SEARCH_PHASE;\
182                         break;\
183                 }\
184                 case _US_UNWIND_FRAME_STARTING:\
185                 {\
186                         actions = _UA_CLEANUP_PHASE;\
187                         if (exceptionObject->barrier_cache.sp == _Unwind_GetGR(context, 13))\
188                         {\
189                                 actions |= _UA_HANDLER_FRAME;\
190                         }\
191                         break;\
192                 }\
193                 case _US_UNWIND_FRAME_RESUME:\
194                 {\
195                         return continueUnwinding(exceptionObject, context);\
196                         break;\
197                 }\
198         }\
199         _Unwind_SetGR (context, 12, (unsigned long)exceptionObject);\
200
201 #define CALL_PERSONALITY_FUNCTION(name) name(state,exceptionObject,context)