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
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]
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 #include <sys/types.h>
40 #if defined(__amd64) /* none of this is valid except for AMD64 */
44 _URC_FOREIGN_EXCEPTION_CAUGHT
= 1,
45 _URC_FATAL_PHASE2_ERROR
= 2,
46 _URC_FATAL_PHASE1_ERROR
= 3,
48 _URC_END_OF_STACK
= 5,
49 _URC_HANDLER_FOUND
= 6,
50 _URC_INSTALL_CONTEXT
= 7,
51 _URC_CONTINUE_UNWIND
= 8
52 } _Unwind_Reason_Code
;
54 typedef int _Unwind_Action
;
55 extern const _Unwind_Action _UA_SEARCH_PHASE
;
56 extern const _Unwind_Action _UA_CLEANUP_PHASE
;
57 extern const _Unwind_Action _UA_HANDLER_FRAME
;
58 extern const _Unwind_Action _UA_FORCE_UNWIND
;
60 struct _Unwind_Exception
;
61 struct _Unwind_Context
;
65 * Signature of language specific call back for deleting exception object
67 typedef void (*_Unwind_Exception_Cleanup_Fn
)(
68 _Unwind_Reason_Code reason
,
69 struct _Unwind_Exception
*exc
);
72 * Header preceding language specific exception object
73 * For Sun C++ these fields are the beginning of the
74 * language specific structure.
76 struct _Unwind_Exception
{
77 uint64_t exception_class
;
78 _Unwind_Exception_Cleanup_Fn exception_cleanup
;
84 * Signature for language specific routine - address is in eh_frame CIE.
85 * During phase one it predicts whether exception would be caught at this
86 * frame and during phase two selects a handler as predicted. An action
87 * of _UA_FORCE_UNWIND will prevent any catch block from being selected.
89 * The personality function is the only call back used when
90 * _Unwind_RaiseException() is called.
92 typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn
)(
94 _Unwind_Action actions
,
95 uint64_t exceptionClass
,
96 struct _Unwind_Exception
*exceptionObject
,
97 struct _Unwind_Context
*context
);
100 * Signature of callback function that is used when _Unwind_ForcedUnwind()
101 * is called. It is called at every step of walkback and that can control
102 * the execution of the personality routine at each frame.
104 typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn
)(
106 _Unwind_Action actions
,
107 uint64_t exceptionClass
,
108 struct _Unwind_Exception
*exceptionObject
,
109 struct _Unwind_Context
*context
,
110 void *stop_parameter
);
113 * Here begins the external functional interface
117 * Used to implement C++ throw - starts walkback with caller's caller.
118 * The routine in the middle must use %rbp as a frame pointer
120 _Unwind_Reason_Code
_Unwind_RaiseException(
121 struct _Unwind_Exception
*exception_object
);
124 * Used (with different stop functions) for POSIX thread cancellation
125 * and stack walking - starts walkback with caller's caller.
127 * Note: must be called by a routine which has a real FP and doesn't use
128 * callee saves registers.
130 _Unwind_Reason_Code
_Unwind_ForcedUnwind(
131 struct _Unwind_Exception
*exception_object
,
132 _Unwind_Stop_Fn stop
,
133 void *stop_parameter
);
136 * Used to resume unwinding at end of cleanup (not catch) code
137 * Assumes that caller is language specific cleanup code and
138 * pops the stack one level before resuming walk.
140 void _Unwind_Resume(struct _Unwind_Exception
*exception_object
);
143 * Calls destructor function for exception object
145 void _Unwind_DeleteException(struct _Unwind_Exception
*exception_object
);
148 * (*(exception_object->exception_cleanup))(_URC_NO_REASON,
156 extern "C" _Unwind_Reason_Code
157 __example_stop_fn(int version
, int actions
, uint64_t exclass
,
158 struct _Unwind_Exception
*exception_object
,
159 struct _Unwind_Context
*ctx
, void *_Sa
)
161 _Unwind_Reason_Code res
;
163 uint64_t fp
= _Unwind_GetCFA(ctx
);
165 if (fp
== 0 || _Unwind_GetGR(ctx
, RET_ADD
) == 0) {
168 res
= _URC_END_OF_STACK
;
178 * framework will call personality routine for current context
179 * then then move one frame back the stack and call here with
180 * updated context. POSIX thread cancellation uses this pattern.
182 * If this path is taken the exception object passed must have
183 * been constructed by the same language system supplying the
184 * personality routines. i.e. foreign exceptions are not
187 * The Sun Microsystems C++ runtime contains the routine
189 * _ex_unwind(_Unwind_Stop_fn sfunc, void *sfunc_arg)
191 * which is a wrapper around _Unwind_ForcedUnwind that
192 * sets up a C++ exception object.
194 * Once this path is taken, the stack frame from which
195 * _Unwind_ForcedUnwind was called is not guaranteed to
196 * still exist. Thus the return codes listed below which
197 * result in that call returning are rendered bogus.
199 * A thread reaching the end of the stack during cancellation
200 * must die instead of returning _URC_END_OF_STACK.
203 case _URC_CONTINUE_UNWIND
:
205 * framework will move one frame back the stack and
206 * call here with updated context
208 * The exception record supplied to _Unwind_ForcedUnwind
209 * need only contain the header and may be stack allocated
210 * if this function will never allow the personality
211 * function to run (as in a trace generator).
214 case _URC_INSTALL_CONTEXT
:
216 * framework will resume execution of user code at location
217 * specified by (altered) context
219 _Unwind_Delete_Exception(res
, exception_object
);
221 case _URC_NORMAL_STOP
:
223 * call to _Unwind_ForcedUnwind will return _URC_NORMAL_STOP
225 _Unwind_Delete_Exception(res
, exception_object
);
227 case _URC_END_OF_STACK
:
229 * call to _Unwind_ForcedUnwind will return _URC_END_OF_STACK
231 _Unwind_Delete_Exception(res
, exception_object
);
233 case _URC_FOREIGN_EXCEPTION_CAUGHT
:
234 case _URC_FATAL_PHASE2_ERROR
:
235 case _URC_FATAL_PHASE1_ERROR
:
236 case _URC_HANDLER_FOUND
:
238 * call to _Unwind_ForcedUnwind will return
239 * _URC_FATAL_PHASE2_ERROR
241 _Unwind_Delete_Exception(res
, exception_object
);
250 * Stack frame context accessors defined in ABI
251 * (despite all the dire text in the ABI these are reliable Get/Set routines)
252 * Note: RA is handled as a GR value
256 * Valid Index values for _Unwind_GetGR
258 #define GPR_RBX 3 /* callee saves */
259 #define FP_RBP 6 /* callee saves (optional frame pointer) */
260 #define SP_RSP 7 /* callee saves */
261 #define EIR_R12 12 /* callee saves */
262 #define EIR_R13 13 /* callee saves */
263 #define EIR_R14 14 /* callee saves */
264 #define EIR_R15 15 /* callee saves */
265 #define RET_ADD 16 /* virtual register - really caller's PC */
268 * Valid Index values for _Unwind_SetGR
270 #define GPR_RDX 1 /* landing pad parameter */
271 #define GPR_RCX 2 /* landing pad parameter */
272 #define GPR_RSI 4 /* landing pad parameter */
273 #define GPR_RDI 5 /* landing pad parameter */
275 uint64_t _Unwind_GetGR(struct _Unwind_Context
*context
, int index
);
277 void _Unwind_SetGR(struct _Unwind_Context
*context
, int index
,
280 uint64_t _Unwind_GetCFA(struct _Unwind_Context
*context
);
282 uint64_t _Unwind_GetIP(struct _Unwind_Context
*context
);
284 void _Unwind_SetIP(struct _Unwind_Context
*context
, uint64_t new_value
);
286 void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context
*context
);
288 uint64_t _Unwind_GetRegionStart(struct _Unwind_Context
*context
);
296 #endif /* _STACK_UNWIND_H */