1 /**
2  * \file
3  * Copyright 2008-2010 Novell, Inc.
4  * Copyright 2011 Xamarin Inc.
5  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
6  */
7 #ifndef __MONO_MONO_STACK_UNWINDING_H__
8 #define __MONO_MONO_STACK_UNWINDING_H__
9 
10 #include <mono/metadata/appdomain.h>
11 #include <mono/metadata/metadata.h>
12 #include <mono/utils/mono-context.h>
13 
14 /*
15  * Possible frame types returned by the stack walker.
16  */
17 typedef enum {
18 	/* Normal managed frames */
19 	FRAME_TYPE_MANAGED = 0,
20 	/* Pseudo frame marking the start of a method invocation done by the soft debugger */
21 	FRAME_TYPE_DEBUGGER_INVOKE = 1,
22 	/* Frame for transitioning to native code */
23 	FRAME_TYPE_MANAGED_TO_NATIVE = 2,
24 	FRAME_TYPE_TRAMPOLINE = 3,
25 	/* Interpreter frame */
26 	FRAME_TYPE_INTERP = 4,
27 	/* Frame for transitioning from interpreter to managed code */
28 	FRAME_TYPE_INTERP_TO_MANAGED = 5,
29 	FRAME_TYPE_NUM = 6
30 } MonoStackFrameType;
31 
32 typedef enum {
33 	MONO_UNWIND_NONE = 0x0,
34 	MONO_UNWIND_LOOKUP_IL_OFFSET = 0x1,
35 	/* NOT signal safe */
36 	MONO_UNWIND_LOOKUP_ACTUAL_METHOD = 0x2,
37 	/*
38 	 * Store the locations where caller-saved registers are saved on the stack in
39 	 * frame->reg_locations. The pointer is only valid during the call to the unwind
40 	 * callback.
41 	 */
42 	MONO_UNWIND_REG_LOCATIONS = 0x4,
43 	MONO_UNWIND_DEFAULT = MONO_UNWIND_LOOKUP_ACTUAL_METHOD,
44 	MONO_UNWIND_SIGNAL_SAFE = MONO_UNWIND_NONE,
45 	MONO_UNWIND_LOOKUP_ALL = MONO_UNWIND_LOOKUP_IL_OFFSET | MONO_UNWIND_LOOKUP_ACTUAL_METHOD,
46 } MonoUnwindOptions;
47 
48 typedef struct {
49 	MonoStackFrameType type;
50 	/*
51 	 * For FRAME_TYPE_MANAGED, otherwise NULL.
52 	 */
53 	MonoJitInfo *ji;
54 	/*
55 	 * Same as ji->method.
56 	 * Not valid if ASYNC_CONTEXT is true.
57 	 */
58 	MonoMethod *method;
59 	/*
60 	 * If ji->method is a gshared method, this is the actual method instance.
61 	 * This is only filled if lookup for actual method was requested (MONO_UNWIND_LOOKUP_ACTUAL_METHOD)
62 	 * Not valid if ASYNC_CONTEXT is true.
63 	 */
64 	MonoMethod *actual_method;
65 	/* The domain containing the code executed by this frame */
66 	MonoDomain *domain;
67 	/* Whenever method is a user level method */
68 	gboolean managed;
69 	/*
70 	 * Whenever this frame was loaded in async context.
71 	 */
72 	gboolean async_context;
73 	int native_offset;
74 	/*
75 	 * IL offset of this frame.
76 	 * Only available if the runtime have debugging enabled (--debug switch) and
77 	 *  il offset resultion was requested (MONO_UNWIND_LOOKUP_IL_OFFSET)
78 	 */
79 	int il_offset;
80 
81 	/* For FRAME_TYPE_INTERP_EXIT */
82 	gpointer interp_exit_data;
83 
84 	/* For FRAME_TYPE_INTERP */
85 	gpointer interp_frame;
86 
87 	/* The next fields are only useful for the jit */
88 	gpointer lmf;
89 	guint32 unwind_info_len;
90 	guint8 *unwind_info;
91 
92 	mgreg_t **reg_locations;
93 } MonoStackFrameInfo;
94 
95 /*Index into MonoThreadState::unwind_data. */
96 enum {
97 	MONO_UNWIND_DATA_DOMAIN,
98 	MONO_UNWIND_DATA_LMF,
99 	MONO_UNWIND_DATA_JIT_TLS,
100 };
101 
102 /*
103  * This structs holds all information needed to unwind the stack
104  * of a thread.
105  */
106 typedef struct {
107 	MonoContext ctx;
108 	gpointer unwind_data [3]; /*right now: domain, lmf and jit_tls*/
109 	gboolean valid;
110 	void *gc_stackdata;
111 	int gc_stackdata_size;
112 } MonoThreadUnwindState;
113 
114 
115 #endif
116