Revert "[mono][debugger] First PR to implement iCorDebug on mono (#20757)"
[mono-project.git] / mono / mini / exceptions-riscv.c
blob989b9a899f0777cd9e33f288894c3646ee967e5e
1 /*
2 * Licensed to the .NET Foundation under one or more agreements.
3 * The .NET Foundation licenses this file to you under the MIT license.
4 */
6 #include "mini-runtime.h"
8 #include <mono/metadata/abi-details.h>
9 #include <mono/utils/mono-sigcontext.h>
10 #include "mono/utils/mono-tls-inline.h"
12 #ifndef DISABLE_JIT
14 static gpointer
15 nop_stub (unsigned int pattern)
17 guint8 *code, *start;
19 start = code = mono_global_codeman_reserve (0x50);
21 /* hang in debugger */
22 riscv_addi (code, RISCV_X0, RISCV_X0, pattern);
23 riscv_ebreak (code);
25 mono_arch_flush_icache (start, code - start);
27 return start;
30 gpointer
31 mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
33 guint8 *start, *code;
34 MonoJumpInfo *ji = NULL;
35 GSList *unwind_ops = NULL;
36 int i, ctx_reg, size;
38 size = 512;
39 code = start = mono_global_codeman_reserve (size);
41 riscv_addi (code, RISCV_T0, RISCV_A0, 0);
42 ctx_reg = RISCV_T0;
44 /* Restore fregs */
45 for (i = 0; i < RISCV_N_FREGS; ++i)
46 riscv_flw (code, i, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, fregs) + (i * sizeof (double)));
48 /* Restore gregs */
49 for (i = 0; i < RISCV_N_FREGS; ++i) {
50 if (i == ctx_reg)
51 continue;
52 riscv_ld (code, i, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, gregs) + (i * sizeof (double)));
55 riscv_ld (code, ctx_reg, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, gregs) + (RISCV_ZERO * sizeof (double)));
56 riscv_jalr (code, RISCV_ZERO, ctx_reg, 0);
57 /* Not reached */
58 riscv_ebreak (code);
60 g_assert ((code - start) < size);
61 mono_arch_flush_icache (start, code - start);
62 MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL));
64 if (info)
65 *info = mono_tramp_info_create ("restore_context", start, code - start, ji, unwind_ops);
67 return start;
70 gpointer
71 mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
73 *info = NULL;
74 return nop_stub (0x37);
77 gpointer
78 mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
80 *info = NULL;
81 return nop_stub (0x77);
84 gpointer
85 mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
87 *info = NULL;
88 return nop_stub (0x88);
91 gpointer
92 mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot)
94 *info = NULL;
95 return nop_stub (0x99);
98 gpointer
99 mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
101 *info = NULL;
102 return nop_stub (0xaa);
105 #else
107 gpointer
108 mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
110 g_assert_not_reached ();
111 return NULL;
114 gpointer
115 mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
117 g_assert_not_reached ();
118 return NULL;
121 gpointer
122 mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
124 g_assert_not_reached ();
125 return NULL;
128 gpointer
129 mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
131 g_assert_not_reached ();
132 return NULL;
135 gpointer
136 mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
138 g_assert_not_reached ();
139 return NULL;
142 #endif
144 void
145 mono_arch_exceptions_init (void)
147 // NOT_IMPLEMENTED;
150 gboolean
151 mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *ji,
152 MonoContext *ctx, MonoContext *new_ctx, MonoLMF **lmf,
153 host_mgreg_t **save_locations, StackFrameInfo *frame)
155 gpointer ip = MONO_CONTEXT_GET_IP (ctx);
157 memset (frame, 0, sizeof (StackFrameInfo));
158 frame->ji = ji;
160 *new_ctx = *ctx;
162 if (ji != NULL) {
163 NOT_IMPLEMENTED;
164 host_mgreg_t regs [MONO_MAX_IREGS + 12 + 1];
165 guint8 *cfa;
166 guint32 unwind_info_len;
167 guint8 *unwind_info;
170 if (ji->is_trampoline)
171 frame->type = FRAME_TYPE_TRAMPOLINE;
172 else
173 frame->type = FRAME_TYPE_MANAGED;
175 unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
177 memcpy (regs, &new_ctx->gregs, sizeof (host_mgreg_t) * 32);
179 /* f8..f9 & f18..f27 are callee saved */
180 for (int i = 0; i < 2; i++)
181 (regs + MONO_MAX_IREGS) [i] = *((host_mgreg_t*)&new_ctx->fregs [RISCV_F8 + i]);
182 for (int i = 0; i < 10; i++)
183 (regs + MONO_MAX_IREGS) [i] = *((host_mgreg_t*)&new_ctx->fregs [RISCV_F18 + i]);
185 gboolean success = mono_unwind_frame (unwind_info, unwind_info_len, (guint8*)ji->code_start,
186 (guint8*)ji->code_start + ji->code_size,
187 (guint8*)ip, NULL, regs, MONO_MAX_IREGS + 8,
188 save_locations, MONO_MAX_IREGS, (guint8**)&cfa);
190 if (!success)
191 return FALSE;
193 memcpy (&new_ctx->gregs, regs, sizeof (host_mgreg_t) * 32);
194 for (int i = 0; i < 2; i++)
195 *((host_mgreg_t*)&new_ctx->fregs [RISCV_F8 + i]) = (regs + MONO_MAX_IREGS) [i];
196 for (int i = 0; i < 10; i++)
197 *((host_mgreg_t*)&new_ctx->fregs [RISCV_F18 + i]) = (regs + MONO_MAX_IREGS) [i];
199 new_ctx->gregs [RISCV_SP] = (host_mgreg_t)(gsize)cfa;
201 if (*lmf)
202 NOT_IMPLEMENTED;
204 /* we substract 1, so that the IP points into the call instruction */
205 new_ctx->gregs [RISCV_ZERO]--;
207 return TRUE;
208 } else if (*lmf) {
209 NOT_IMPLEMENTED;
212 return FALSE;
215 static void
216 handle_signal_exception (gpointer obj)
218 MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
219 MonoContext ctx = jit_tls->ex_ctx;
221 mono_handle_exception (&ctx, obj);
222 mono_restore_context (&ctx);
225 gboolean
226 mono_arch_handle_exception (void *ctx, gpointer obj)
228 MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
230 mono_sigctx_to_monoctx (ctx, &jit_tls->ex_ctx);
232 // Call handle_signal_exception () on the normal stack.
233 UCONTEXT_GREGS (ctx) [RISCV_A0] = (long) obj;
234 UCONTEXT_REG_PC (ctx) = (long) handle_signal_exception;
236 return TRUE;
239 gpointer
240 mono_arch_ip_from_context (void *sigctx)
242 return (gpointer) UCONTEXT_REG_PC (sigctx);
245 void
246 mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data)
248 // Allocate a stack frame and redirect PC.
249 MONO_CONTEXT_SET_SP (ctx, (host_mgreg_t) MONO_CONTEXT_GET_SP (ctx) - 32);
251 mono_arch_setup_resume_sighandler_ctx (ctx, async_cb);
254 void
255 mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func)
257 MONO_CONTEXT_SET_IP (ctx, func);
260 void
261 mono_arch_undo_ip_adjustment (MonoContext *context)
263 context->gregs[RISCV_ZERO]++;
266 void
267 mono_arch_do_ip_adjustment (MonoContext *context)
269 context->gregs[RISCV_ZERO]--;