|
1 /* unwind_env.h |
|
2 * |
|
3 * Copyright 2003-2005 ARM Limited. All rights reserved. |
|
4 */ |
|
5 /* |
|
6 Licence |
|
7 |
|
8 1. Subject to the provisions of clause 2, ARM hereby grants to LICENSEE a |
|
9 perpetual, non-exclusive, nontransferable, royalty free, worldwide licence |
|
10 to use this Example Implementation of Exception Handling solely for the |
|
11 purpose of developing, having developed, manufacturing, having |
|
12 manufactured, offering to sell, selling, supplying or otherwise |
|
13 distributing products which comply with the Exception Handling ABI for the |
|
14 ARM Architecture specification. All other rights are reserved to ARM or its |
|
15 licensors. |
|
16 |
|
17 2. THIS EXAMPLE IMPLEMENTATION OF EXCEPTION HANDLING IS PROVIDED "AS IS" |
|
18 WITH NO WARRANTIES EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED |
|
19 TO ANY WARRANTY OF SATISFACTORY QUALITY, MERCHANTABILITY, NONINFRINGEMENT |
|
20 OR FITNESS FOR A PARTICULAR PURPOSE. |
|
21 */ |
|
22 |
|
23 /* Portions copyright Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). */ |
|
24 |
|
25 /* |
|
26 * RCS $Revision: 92949 $ |
|
27 * Checkin $Date: 2005-10-12 11:07:03 +0100 (Wed, 12 Oct 2005) $ |
|
28 * Revising $Author: achapman $ |
|
29 */ |
|
30 |
|
31 /* Environment definition - abstractions and requirements - to aid |
|
32 * portability of the ARM exceptions code. |
|
33 */ |
|
34 |
|
35 #ifndef UNWINDENV_H |
|
36 #define UNWINDENV_H |
|
37 |
|
38 /* ---------------------------------------------------------------------- */ |
|
39 |
|
40 /* Source language |
|
41 * |
|
42 * The compiler is expected to define preprocessor symbols as follows: |
|
43 * __cplusplus when compiling in C++ mode. |
|
44 * __thumb when compiling to Thumb code. |
|
45 * |
|
46 * Some use is made of embedded assembly language, introduced by __asm. |
|
47 * This is described in ARM's toolchain documentation. Some edits may be |
|
48 * required for other compilers. The compiler should define one or more of: |
|
49 * __TARGET_ARCH_4T __TARGET_ARCH_4TXM __TARGET_ARCH_5T __TARGET_ARCH_5TXM |
|
50 * __TARGET_ARCH_5TE __TARGET_ARCH_6 |
|
51 * so the correct assembly wrappers are generated for certain functions. |
|
52 * |
|
53 * __APCS_INTERWORK should be defined if ARM/Thumb interworking is required. |
|
54 * |
|
55 * For all the above symbols, if your compiler does not provide appropriate |
|
56 * definitions, add them here. |
|
57 * |
|
58 * Some source language extensions are also used. |
|
59 */ |
|
60 |
|
61 /* ---------------------------------------------------------------------- */ |
|
62 |
|
63 /* Library structure |
|
64 * |
|
65 * ARM's private make system contains an automated facility for compiling |
|
66 * source files multiple times to create multiple object files. The source |
|
67 * regions intended to constitute object file xxx.o are delimited by |
|
68 * #ifdef xxx_c / #endif directives. The exact preprocessor symbols used |
|
69 * for this conditionalisation are described in a comment at the start of |
|
70 * each file. When porting to a different system, compilations must be |
|
71 * performed with these preprocessor symbols appropriately defined |
|
72 * (or remove the conditionalisation). |
|
73 * |
|
74 */ |
|
75 #ifdef __EPOC32__ |
|
76 |
|
77 #define ARM_EXCEPTIONS_ENABLED |
|
78 |
|
79 // turn on the source regions in unwinder.c |
|
80 #define unwinder_c |
|
81 #define unwind_activity_c |
|
82 |
|
83 // turn on the source regions in unwind_pr.c |
|
84 #define pr0_c |
|
85 #define pr1_c |
|
86 #define pr2_c |
|
87 #define prcommon_c |
|
88 |
|
89 // turn on the source regions in cppsemantics.cpp |
|
90 #define arm_exceptions_globs_c |
|
91 #define arm_exceptions_mem_c |
|
92 #define arm_exceptions_uncaught_c |
|
93 #define arm_exceptions_terminate_c |
|
94 #define arm_exceptions_setterminate_c |
|
95 #define arm_exceptions_unexpected_c |
|
96 #define arm_exceptions_setunexpected_c |
|
97 #define arm_exceptions_support_c |
|
98 #define arm_exceptions_callterm_c |
|
99 #define arm_exceptions_callunex_c |
|
100 #define arm_exceptions_currenttype_c |
|
101 #define arm_exceptions_alloc_c |
|
102 #define arm_exceptions_free_c |
|
103 #define arm_exceptions_throw_c |
|
104 #define arm_exceptions_rethrow_c |
|
105 #define arm_exceptions_foreign_c |
|
106 #define arm_exceptions_cleanup_c |
|
107 #define arm_exceptions_getexceptionptr_c |
|
108 #define arm_exceptions_catchsemantics_c |
|
109 #define arm_exceptions_begincatch_c |
|
110 #define arm_exceptions_endcatch_c |
|
111 #define arm_exceptions_bad_typeid_c |
|
112 #define arm_exceptions_bad_cast_c |
|
113 #endif |
|
114 |
|
115 /* ARM declares (or redeclares) some routines as weak in order that |
|
116 * references to them are weak, so that the static linker will not load |
|
117 * unwanted code. This is achieved by decorating routine declarations |
|
118 * with appropriate language extensions. Note that compilers supporting |
|
119 * similar features but via a different syntax may require edits to |
|
120 * the library source. |
|
121 * |
|
122 * Define those decorations here (define as empty if not required): |
|
123 */ |
|
124 |
|
125 #ifndef __EPOC32__ |
|
126 #define WEAKDECL __weak /* token in C and C++ */ |
|
127 #define WEAKASMDECL [WEAK] /* token in assembler */ |
|
128 #else |
|
129 // The symbian version needs all of these in the DLL, so don't make them weak |
|
130 #define WEAKDECL |
|
131 #define WEAKASMDECL |
|
132 #endif |
|
133 |
|
134 /* ---------------------------------------------------------------------- */ |
|
135 |
|
136 /* Source language support and language extensions */ |
|
137 |
|
138 /* It is possible to compile the C++ semantics code using a compiler |
|
139 * which does not support C++ exceptions; this was useful to ARM whilst |
|
140 * ARM's compiler was being developed, and the facility has not been |
|
141 * removed. C++ exceptions syntax is conditionalised by |
|
142 * #ifdef ARM_EXCEPTIONS_ENABLED / #endif. Define ARM_EXCEPTIONS_ENABLED |
|
143 * by some means here if you want a usable library: |
|
144 */ |
|
145 |
|
146 #ifdef __cplusplus |
|
147 extern "C" { |
|
148 /* For conditionalisation, specifically on ARM_EXCEPTIONS_ENABLED */ |
|
149 #include "basics.h" |
|
150 } |
|
151 #endif |
|
152 |
|
153 /* The following definitions of syntax decoration may be empty if the |
|
154 * facility is not required. Note that compilers supporting similar |
|
155 * features but via a different syntax may require edits to the library |
|
156 * source. |
|
157 * |
|
158 * Define the decorations here (define as empty if not required): |
|
159 */ |
|
160 |
|
161 /* If the compiler understands noreturn functions: */ |
|
162 #define NORETURNDECL __declspec(noreturn) |
|
163 /* Inlining when compiling C */ |
|
164 #define INLINE __inline |
|
165 /* Stronger encouragement to inline */ |
|
166 #define FORCEINLINE __forceinline |
|
167 |
|
168 /* ---------------------------------------------------------------------- */ |
|
169 |
|
170 /* Types */ |
|
171 |
|
172 /* The implementation requires types uint8_t, uint16_t, uint32_t and |
|
173 * uint64_t to be defined as unsigned integers of the appropriate number |
|
174 * of bits. |
|
175 * |
|
176 * Do that here: |
|
177 */ |
|
178 |
|
179 #ifndef __EPOC32__ |
|
180 #include <stdint.h> |
|
181 #else |
|
182 #include <e32def.h> |
|
183 typedef TUint8 uint8_t; |
|
184 typedef TUint16 uint16_t; |
|
185 typedef TInt32 int32_t; |
|
186 typedef TUint32 uint32_t; |
|
187 typedef Uint64 uint64_t; |
|
188 #endif |
|
189 |
|
190 /* The C++ semantics support requires definition of the RTTI object |
|
191 * layout. We use the same structures and names as the generic C++ |
|
192 * ABI for Itanium. |
|
193 * |
|
194 * Define those structures here: |
|
195 */ |
|
196 |
|
197 #ifdef __cplusplus |
|
198 extern "C" { |
|
199 #include "cxxabi.h" |
|
200 } |
|
201 #endif |
|
202 |
|
203 /* ---------------------------------------------------------------------- */ |
|
204 |
|
205 /* External requirements */ |
|
206 |
|
207 /* The C++ exception-handling 'globals' should be allocated per-thread. |
|
208 * The Exceptions ABI does not specify how this happens, but it is |
|
209 * intended that the details are localised to __cxa_get_globals. |
|
210 * |
|
211 * In the ARM implementation of __cxa_get_globals, it is assumed that a |
|
212 * zero-initialised location in a known per-thread place is somehow |
|
213 * obtainable, and can be assigned (by __cxa_get_globals) a pointer to |
|
214 * the allocated globals data structure. The macro EH_GLOBALS should be |
|
215 * defined here to yield a suitable address of type void*. This is used |
|
216 * only in __cxa_get_globals. |
|
217 * |
|
218 * Define it here: |
|
219 */ |
|
220 |
|
221 #ifdef __cplusplus |
|
222 #ifndef __EPOC32__ |
|
223 extern "C" { |
|
224 /* for __user_libspace() machinery */ |
|
225 #include <interns.h> |
|
226 #define EH_GLOBALS libspace.eh_globals |
|
227 } |
|
228 #else |
|
229 #include <e32std.h> |
|
230 #define EH_GLOBALS (Dll::Tls()) |
|
231 #endif |
|
232 #endif |
|
233 |
|
234 /* A routine is required for C++ derived class to base class conversion. |
|
235 * This is used once, in __cxa_type_match. It is likely that suitable |
|
236 * code exists as part of the RTTI support code. Therefore access it |
|
237 * via a macro: |
|
238 * DERIVED_TO_BASE_CONVERSION(PTR, P_NEW_PTR, CLASS_INFO, BASE_INFO) |
|
239 * Convert PTR from a pointer to a derived class (described by |
|
240 * CLASS_INFO) to a pointer to a base class (described by BASE_INFO) |
|
241 * and store the resulting pointer in P_NEW_PTR. Return true (or |
|
242 * non-zero) if the base class was found and the conversion was done, |
|
243 * otherwise return false (or zero). |
|
244 * |
|
245 * Define the macro here: |
|
246 */ |
|
247 |
|
248 #ifdef __cplusplus |
|
249 /* In the ARM implementation, a suitable routine exists elsewhere in the |
|
250 * C++ runtime library, where it is part of the dynamic_cast mechanism. |
|
251 */ |
|
252 #if !defined(__EPOC32__) || (__ARMCC_VERSION > 310000) |
|
253 extern "C" int __derived_to_base_conversion(void** p_ptr, void** p_new_ptr, |
|
254 const std::type_info * class_info, |
|
255 const std::type_info * base_info, |
|
256 char** access_flags, int use_access_flags); |
|
257 |
|
258 #define DERIVED_TO_BASE_CONVERSION(PTR, P_NEW_PTR, CLASS_INFO, BASE_INFO) \ |
|
259 __derived_to_base_conversion(&(PTR), (P_NEW_PTR), (CLASS_INFO), (BASE_INFO), NULL, 0) |
|
260 #else |
|
261 extern "C" TBool _DoDerivedToBaseConversion(const std::type_info* aDerivedType, |
|
262 const std::type_info* aBaseType, |
|
263 TAny** aDerivedObj, |
|
264 TAny** aBaseObj); |
|
265 |
|
266 #define DERIVED_TO_BASE_CONVERSION(PTR, P_NEW_PTR, CLASS_INFO, BASE_INFO) \ |
|
267 _DoDerivedToBaseConversion(CLASS_INFO, BASE_INFO, &(PTR), P_NEW_PTR) |
|
268 #endif |
|
269 |
|
270 #endif |
|
271 |
|
272 /* The effect of R_ARM_TARGET2 relocations is platform-specific. A |
|
273 * routine is required for handling references created via such |
|
274 * relocations. The routine takes the address of a location that was |
|
275 * relocated by R_ARM_TARGET2, and returns a pointer to the absolute |
|
276 * address of the referenced entity. |
|
277 */ |
|
278 |
|
279 static FORCEINLINE void *__ARM_resolve_target2(void *p) |
|
280 { |
|
281 #ifdef __APCS_FPIC |
|
282 /* SVr4: R_ARM_TARGET2 is equivalent to R_ARM_GOT_PREL (placerel32 indirect) */ |
|
283 return *(void **)(*(uint32_t *)p + (uint32_t)p); |
|
284 #else |
|
285 /* Bare metal: R_ARM_TARGET2 is equivalent to R_ARM_ABS32 */ |
|
286 return *(void **)p; |
|
287 #endif |
|
288 } |
|
289 |
|
290 /* ---------------------------------------------------------------------- */ |
|
291 |
|
292 /* Runtime debug support |
|
293 * |
|
294 * Here we define the interface to a "bottleneck function" to be called |
|
295 * by exception handling code at 'interesting' points during execution, |
|
296 * and breakpointable by a debugger. |
|
297 * |
|
298 * This is not part of the Exceptions ABI but is expected to be |
|
299 * standardised elsewhere, probably in a Debug ABI. |
|
300 * |
|
301 * If you don't want this, define DEBUGGER_BOTTLENECK as a dummy, e.g. |
|
302 * #define DEBUGGER_BOTTLENECK(UCBP,LANG,ACTIVITY,ARG) (void)0 |
|
303 */ |
|
304 |
|
305 #ifdef __cplusplus |
|
306 extern "C" { |
|
307 #endif |
|
308 |
|
309 struct _Unwind_Control_Block; |
|
310 |
|
311 typedef enum { |
|
312 _UASUBSYS_CPP = 0x00, |
|
313 _UASUBSYS_UNWINDER = 0xff |
|
314 } _Unwind_Activity_subsystem; |
|
315 |
|
316 typedef enum { |
|
317 _UAACT_STARTING = 0x0, |
|
318 _UAACT_ENDING = 0x1, |
|
319 _UAACT_BARRIERFOUND = 0x2, |
|
320 _UAACT_PADENTRY = 0x3, |
|
321 _UAACT_CPP_TYPEINFO = 0x80 |
|
322 } _Unwind_Activity_activity; |
|
323 |
|
324 typedef enum { |
|
325 _UAARG_ENDING_UNSPECIFIED = 0x0, |
|
326 _UAARG_ENDING_TABLECORRUPT = 0x1, |
|
327 _UAARG_ENDING_NOUNWIND = 0x2, |
|
328 _UAARG_ENDING_VRSFAILED = 0x3, |
|
329 /* C++ only: */ |
|
330 _UAARG_ENDING_CPP_BADOPCODE = 0x4, |
|
331 /* Unwinder only: */ |
|
332 _UAARG_ENDING_UNWINDER_LOOKUPFAILED = 0x4, |
|
333 _UAARG_ENDING_UNWINDER_BUFFERFAILED = 0x5 |
|
334 } _Unwind_Activity_arg; |
|
335 |
|
336 void _Unwind_Activity(struct _Unwind_Control_Block *ucbp, uint32_t reason, uint32_t arg); |
|
337 #define DEBUGGER_BOTTLENECK(UCBP,LANG,ACTIVITY,ARG) \ |
|
338 _Unwind_Activity((UCBP),((((uint32_t)(LANG))<<24)|ACTIVITY),(uint32_t)(ARG)) |
|
339 |
|
340 #ifdef __cplusplus |
|
341 } |
|
342 #endif |
|
343 |
|
344 |
|
345 /* ---------------------------------------------------------------------- */ |
|
346 |
|
347 /* Printed diagnostics |
|
348 * |
|
349 * These may be useful for debugging purposes during development, provided |
|
350 * the execution environment supports diagnostics via printf. |
|
351 * |
|
352 * #define PR_DIAGNOSTICS for printed diagnostics from the personality routine. |
|
353 * #define VRS_DIAGNOSTICS for printed diagnostics about VRS operations. |
|
354 * #define UNWIND_ACTIVITY_DIAGNOSTICS for printed information from _Unwind_Activity. |
|
355 * #define CPP_DIAGNOSTICS for printed diagnostics from the C++ semantics routines. |
|
356 */ |
|
357 |
|
358 /* ---------------------------------------------------------------------- |
|
359 * Abstractions added for SymbianOS. A process is contructed from multiple |
|
360 * executables each with their own RO segment and exception data structures. |
|
361 * SymbianOS caches pointers to two data structures in the UCB which it then |
|
362 * uses to speed up the retrieval of certain information including values returned |
|
363 * by the functions below. |
|
364 * ---------------------------------------------------------------------- */ |
|
365 #ifndef __EPOC32__ |
|
366 #define ADDR_TO_ER_RO_OFFSET(addr, ucbp) addr_to_ER_RO_offset(addr) |
|
367 #define ER_RO_OFFSET_TO_ADDR(addr, ucbp) ER_RO_offset_to_addr(addr) |
|
368 #else |
|
369 #define ADDR_TO_ER_RO_OFFSET(addr, ucbp) addr_to_ER_RO_offset(addr, ucbp) |
|
370 #define ER_RO_OFFSET_TO_ADDR(addr, ucbp) ER_RO_offset_to_addr(addr, ucbp) |
|
371 #endif |
|
372 |
|
373 |
|
374 #endif /* defined UNWINDENV_H */ |
|
375 |
|
376 |
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 |