mk: use executable LIBMODE
[unleashed.git] / include / stack_unwind.h
blob5f6fd71eb14958a7496b4e9aeb2d6081ed996c51
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Public interfaces for AMD64 Unwind routines
31 #ifndef _STACK_UNWIND_H
32 #define _STACK_UNWIND_H
34 #pragma ident "%Z%%M% %I% %E% SMI"
36 #include <sys/types.h>
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
42 #if defined(__amd64) /* none of this is valid except for AMD64 */
44 typedef enum {
45 _URC_NO_REASON = 0,
46 _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
47 _URC_FATAL_PHASE2_ERROR = 2,
48 _URC_FATAL_PHASE1_ERROR = 3,
49 _URC_NORMAL_STOP = 4,
50 _URC_END_OF_STACK = 5,
51 _URC_HANDLER_FOUND = 6,
52 _URC_INSTALL_CONTEXT = 7,
53 _URC_CONTINUE_UNWIND = 8
54 } _Unwind_Reason_Code;
56 typedef int _Unwind_Action;
57 extern const _Unwind_Action _UA_SEARCH_PHASE;
58 extern const _Unwind_Action _UA_CLEANUP_PHASE;
59 extern const _Unwind_Action _UA_HANDLER_FRAME;
60 extern const _Unwind_Action _UA_FORCE_UNWIND;
62 struct _Unwind_Exception;
63 struct _Unwind_Context;
67 * Signature of language specific call back for deleting exception object
69 typedef void (*_Unwind_Exception_Cleanup_Fn)(
70 _Unwind_Reason_Code reason,
71 struct _Unwind_Exception *exc);
74 * Header preceding language specific exception object
75 * For Sun C++ these fields are the beginning of the
76 * language specific structure.
78 struct _Unwind_Exception {
79 uint64_t exception_class;
80 _Unwind_Exception_Cleanup_Fn exception_cleanup;
81 uint64_t private_1;
82 uint64_t private_2;
86 * Signature for language specific routine - address is in eh_frame CIE.
87 * During phase one it predicts whether exception would be caught at this
88 * frame and during phase two selects a handler as predicted. An action
89 * of _UA_FORCE_UNWIND will prevent any catch block from being selected.
91 * The personality function is the only call back used when
92 * _Unwind_RaiseException() is called.
94 typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(
95 int version,
96 _Unwind_Action actions,
97 uint64_t exceptionClass,
98 struct _Unwind_Exception *exceptionObject,
99 struct _Unwind_Context *context);
102 * Signature of callback function that is used when _Unwind_ForcedUnwind()
103 * is called. It is called at every step of walkback and that can control
104 * the execution of the personality routine at each frame.
106 typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(
107 int version,
108 _Unwind_Action actions,
109 uint64_t exceptionClass,
110 struct _Unwind_Exception *exceptionObject,
111 struct _Unwind_Context *context,
112 void *stop_parameter);
115 * Here begins the external functional interface
119 * Used to implement C++ throw - starts walkback with caller's caller.
120 * The routine in the middle must use %rbp as a frame pointer
122 _Unwind_Reason_Code _Unwind_RaiseException(
123 struct _Unwind_Exception *exception_object);
126 * Used (with different stop functions) for POSIX thread cancellation
127 * and stack walking - starts walkback with caller's caller.
129 * Note: must be called by a routine which has a real FP and doesn't use
130 * callee saves registers.
132 _Unwind_Reason_Code _Unwind_ForcedUnwind(
133 struct _Unwind_Exception *exception_object,
134 _Unwind_Stop_Fn stop,
135 void *stop_parameter);
138 * Used to resume unwinding at end of cleanup (not catch) code
139 * Assumes that caller is language specific cleanup code and
140 * pops the stack one level before resuming walk.
142 void _Unwind_Resume(struct _Unwind_Exception *exception_object);
145 * Calls destructor function for exception object
147 void _Unwind_DeleteException(struct _Unwind_Exception *exception_object);
150 * (*(exception_object->exception_cleanup))(_URC_NO_REASON,
151 * exception_object);
156 #if 0
158 extern "C" _Unwind_Reason_Code
159 __example_stop_fn(int version, int actions, uint64_t exclass,
160 struct _Unwind_Exception *exception_object,
161 struct _Unwind_Context *ctx, void *_Sa)
163 _Unwind_Reason_Code res;
165 uint64_t fp = _Unwind_GetCFA(ctx);
167 if (fp == 0 || _Unwind_GetGR(ctx, RET_ADD) == 0) {
168 if (no_return)
169 die;
170 res = _URC_END_OF_STACK;
171 } else {
173 * Your logic here:
174 * res = ........
177 switch (res) {
178 case _URC_NO_REASON:
180 * framework will call personality routine for current context
181 * then then move one frame back the stack and call here with
182 * updated context. POSIX thread cancellation uses this pattern.
184 * If this path is taken the exception object passed must have
185 * been constructed by the same language system supplying the
186 * personality routines. i.e. foreign exceptions are not
187 * implemented.
189 * The Sun Microsystems C++ runtime contains the routine
191 * _ex_unwind(_Unwind_Stop_fn sfunc, void *sfunc_arg)
193 * which is a wrapper around _Unwind_ForcedUnwind that
194 * sets up a C++ exception object.
196 * Once this path is taken, the stack frame from which
197 * _Unwind_ForcedUnwind was called is not guaranteed to
198 * still exist. Thus the return codes listed below which
199 * result in that call returning are rendered bogus.
201 * A thread reaching the end of the stack during cancellation
202 * must die instead of returning _URC_END_OF_STACK.
204 break;
205 case _URC_CONTINUE_UNWIND:
207 * framework will move one frame back the stack and
208 * call here with updated context
210 * The exception record supplied to _Unwind_ForcedUnwind
211 * need only contain the header and may be stack allocated
212 * if this function will never allow the personality
213 * function to run (as in a trace generator).
215 break;
216 case _URC_INSTALL_CONTEXT:
218 * framework will resume execution of user code at location
219 * specified by (altered) context
221 _Unwind_Delete_Exception(res, exception_object);
222 break;
223 case _URC_NORMAL_STOP:
225 * call to _Unwind_ForcedUnwind will return _URC_NORMAL_STOP
227 _Unwind_Delete_Exception(res, exception_object);
228 break;
229 case _URC_END_OF_STACK:
231 * call to _Unwind_ForcedUnwind will return _URC_END_OF_STACK
233 _Unwind_Delete_Exception(res, exception_object);
234 break;
235 case _URC_FOREIGN_EXCEPTION_CAUGHT:
236 case _URC_FATAL_PHASE2_ERROR:
237 case _URC_FATAL_PHASE1_ERROR:
238 case _URC_HANDLER_FOUND:
240 * call to _Unwind_ForcedUnwind will return
241 * _URC_FATAL_PHASE2_ERROR
243 _Unwind_Delete_Exception(res, exception_object);
244 break;
246 return (res);
249 #endif
252 * Stack frame context accessors defined in ABI
253 * (despite all the dire text in the ABI these are reliable Get/Set routines)
254 * Note: RA is handled as a GR value
258 * Valid Index values for _Unwind_GetGR
260 #define GPR_RBX 3 /* callee saves */
261 #define FP_RBP 6 /* callee saves (optional frame pointer) */
262 #define SP_RSP 7 /* callee saves */
263 #define EIR_R12 12 /* callee saves */
264 #define EIR_R13 13 /* callee saves */
265 #define EIR_R14 14 /* callee saves */
266 #define EIR_R15 15 /* callee saves */
267 #define RET_ADD 16 /* virtual register - really caller's PC */
270 * Valid Index values for _Unwind_SetGR
272 #define GPR_RDX 1 /* landing pad parameter */
273 #define GPR_RCX 2 /* landing pad parameter */
274 #define GPR_RSI 4 /* landing pad parameter */
275 #define GPR_RDI 5 /* landing pad parameter */
277 uint64_t _Unwind_GetGR(struct _Unwind_Context *context, int index);
279 void _Unwind_SetGR(struct _Unwind_Context *context, int index,
280 uint64_t new_value);
282 uint64_t _Unwind_GetCFA(struct _Unwind_Context *context);
284 uint64_t _Unwind_GetIP(struct _Unwind_Context *context);
286 void _Unwind_SetIP(struct _Unwind_Context *context, uint64_t new_value);
288 void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context);
290 uint64_t _Unwind_GetRegionStart(struct _Unwind_Context *context);
292 #endif /* __amd64 */
294 #ifdef __cplusplus
296 #endif
298 #endif /* _STACK_UNWIND_H */