2005-06-05 Peter Bartok <pbartok@novell.com>
[mono.git] / mono / mini / exceptions-ia64.c
1 /*
2  * exceptions-ia64.c: exception support for IA64
3  *
4  * Authors:
5  *   Zoltan Varga (vargaz@gmail.com)
6  *
7  * (C) 2001 Ximian, Inc.
8  */
9
10 #include <config.h>
11 #include <glib.h>
12 #include <signal.h>
13 #include <string.h>
14 #include <sys/ucontext.h>
15
16 #include <mono/arch/ia64/ia64-codegen.h>
17 #include <mono/metadata/appdomain.h>
18 #include <mono/metadata/tabledefs.h>
19 #include <mono/metadata/threads.h>
20 #include <mono/metadata/debug-helpers.h>
21 #include <mono/metadata/exception.h>
22 #include <mono/metadata/gc-internal.h>
23 #include <mono/metadata/mono-debug.h>
24
25 #include "mini.h"
26 #include "mini-ia64.h"
27
28 #define ALIGN_TO(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
29
30 #define NOT_IMPLEMENTED g_assert_not_reached ()
31
32 /*
33  * mono_arch_get_restore_context:
34  *
35  * Returns a pointer to a method which restores a previously saved sigcontext.
36  */
37 gpointer
38 mono_arch_get_restore_context (void)
39 {
40         static guint8 *start = NULL;
41         static gboolean inited = FALSE;
42         Ia64CodegenState code;
43
44         if (inited)
45                 return start;
46
47         /* restore_contect (MonoContext *ctx) */
48
49         start = mono_global_codeman_reserve (256);
50
51         /* FIXME: */
52         ia64_codegen_init (code, start);
53         ia64_break_i (code, 0);
54         ia64_codegen_close (code);
55
56         g_assert ((code.buf - start) <= 256);
57
58         mono_arch_flush_icache (start, code.buf - start);
59
60         return start;
61 }
62
63 /*
64  * mono_arch_get_call_filter:
65  *
66  * Returns a pointer to a method which calls an exception filter. We
67  * also use this function to call finally handlers (we pass NULL as 
68  * @exc object in this case).
69  */
70 gpointer
71 mono_arch_get_call_filter (void)
72 {
73         static guint8 *start;
74         static gboolean inited = FALSE;
75         int i;
76         guint32 pos;
77         Ia64CodegenState code;
78
79         if (inited)
80                 return start;
81
82         if (inited)
83                 return start;
84
85         start = mono_global_codeman_reserve (256);
86
87         /* call_filter (MonoContext *ctx, unsigned long eip) */
88
89         /* FIXME: */
90         ia64_codegen_init (code, start);
91         ia64_break_i (code, 0);
92         ia64_codegen_close (code);
93
94         g_assert ((code.buf - start) <= 256);
95
96         mono_arch_flush_icache (start, code.buf - start);
97
98         return start;
99 }
100
101 static void
102 throw_exception (MonoObject *exc, guint64 rip, guint64 rsp,
103                                  guint64 rbx, guint64 rbp, guint64 r12, guint64 r13, 
104                                  guint64 r14, guint64 r15, guint64 rethrow)
105 {
106         static void (*restore_context) (MonoContext *);
107         MonoContext ctx;
108
109         if (!restore_context)
110                 restore_context = mono_arch_get_restore_context ();
111
112         NOT_IMPLEMENTED;
113 }
114
115 static gpointer
116 get_throw_trampoline (gboolean rethrow)
117 {
118         guint8* start;
119         Ia64CodegenState code;
120
121         start = mono_global_codeman_reserve (64);
122
123         /* FIXME: */
124         ia64_codegen_init (code, start);
125         ia64_break_i (code, 0);
126         ia64_codegen_close (code);
127
128         g_assert ((code.buf - start) <= 256);
129
130         mono_arch_flush_icache (start, code.buf - start);
131
132         return start;
133 }
134
135 /**
136  * mono_arch_get_throw_exception:
137  *
138  * Returns a function pointer which can be used to raise 
139  * exceptions. The returned function has the following 
140  * signature: void (*func) (MonoException *exc); 
141  *
142  */
143 gpointer 
144 mono_arch_get_throw_exception (void)
145 {
146         static guint8* start;
147         static gboolean inited = FALSE;
148
149         if (inited)
150                 return start;
151
152         start = get_throw_trampoline (FALSE);
153
154         inited = TRUE;
155
156         return start;
157 }
158
159 gpointer 
160 mono_arch_get_rethrow_exception (void)
161 {
162         static guint8* start;
163         static gboolean inited = FALSE;
164
165         if (inited)
166                 return start;
167
168         start = get_throw_trampoline (TRUE);
169
170         inited = TRUE;
171
172         return start;
173 }
174
175 gpointer 
176 mono_arch_get_throw_exception_by_name (void)
177 {       
178         static gboolean inited = FALSE; 
179         guint8* start;
180         Ia64CodegenState code;
181
182         start = mono_global_codeman_reserve (64);
183
184         /* Not used on ia64 */
185         ia64_codegen_init (code, start);
186         ia64_break_i (code, 0);
187         ia64_codegen_close (code);
188
189         g_assert ((code.buf - start) <= 256);
190
191         mono_arch_flush_icache (start, code.buf - start);
192
193         return start;
194 }
195
196 /**
197  * mono_arch_get_throw_corlib_exception:
198  *
199  * Returns a function pointer which can be used to raise 
200  * corlib exceptions. The returned function has the following 
201  * signature: void (*func) (guint32 ex_token, guint32 offset); 
202  * Here, offset is the offset which needs to be substracted from the caller IP 
203  * to get the IP of the throw. Passing the offset has the advantage that it 
204  * needs no relocations in the caller.
205  */
206 gpointer 
207 mono_arch_get_throw_corlib_exception (void)
208 {
209         static guint8* start;
210         static gboolean inited = FALSE;
211         guint64 throw_ex;
212         Ia64CodegenState code;
213
214         if (inited)
215                 return start;
216
217         start = mono_global_codeman_reserve (64);
218
219         /* FIXME: */
220         ia64_codegen_init (code, start);
221         ia64_break_i (code, 0);
222         ia64_codegen_close (code);
223
224         g_assert ((code.buf - start) <= 256);
225
226         mono_arch_flush_icache (start, code.buf - start);
227
228         return start;
229 }
230
231 /* mono_arch_find_jit_info:
232  *
233  * This function is used to gather information from @ctx. It return the 
234  * MonoJitInfo of the corresponding function, unwinds one stack frame and
235  * stores the resulting context into @new_ctx. It also stores a string 
236  * describing the stack location into @trace (if not NULL), and modifies
237  * the @lmf if necessary. @native_offset return the IP offset from the 
238  * start of the function or -1 if that info is not available.
239  */
240 MonoJitInfo *
241 mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx, 
242                          MonoContext *new_ctx, char **trace, MonoLMF **lmf, int *native_offset,
243                          gboolean *managed)
244 {
245         MonoJitInfo *ji;
246         int i;
247         gpointer ip = MONO_CONTEXT_GET_IP (ctx);
248
249         NOT_IMPLEMENTED;
250         return NULL;
251 }
252
253 /**
254  * mono_arch_handle_exception:
255  *
256  * @ctx: saved processor state
257  * @obj: the exception object
258  */
259 gboolean
260 mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
261 {
262         ucontext_t *ctx = (ucontext_t*)sigctx;
263         MonoContext mctx;
264
265         NOT_IMPLEMENTED;
266         return FALSE;
267 }
268
269 gpointer
270 mono_arch_ip_from_context (void *sigctx)
271 {
272         NOT_IMPLEMENTED;
273         return NULL;
274 }