2 * Licensed to the .NET Foundation under one or more agreements.
3 * The .NET Foundation licenses this file to you under the MIT license.
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"
15 nop_stub (unsigned int pattern
)
19 start
= code
= mono_global_codeman_reserve (0x50);
21 /* hang in debugger */
22 riscv_addi (code
, RISCV_X0
, RISCV_X0
, pattern
);
25 mono_arch_flush_icache (start
, code
- start
);
31 mono_arch_get_restore_context (MonoTrampInfo
**info
, gboolean aot
)
34 MonoJumpInfo
*ji
= NULL
;
35 GSList
*unwind_ops
= NULL
;
39 code
= start
= mono_global_codeman_reserve (size
);
41 riscv_addi (code
, RISCV_T0
, RISCV_A0
, 0);
45 for (i
= 0; i
< RISCV_N_FREGS
; ++i
)
46 riscv_flw (code
, i
, ctx_reg
, MONO_STRUCT_OFFSET (MonoContext
, fregs
) + (i
* sizeof (double)));
49 for (i
= 0; i
< RISCV_N_FREGS
; ++i
) {
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);
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
));
65 *info
= mono_tramp_info_create ("restore_context", start
, code
- start
, ji
, unwind_ops
);
71 mono_arch_get_call_filter (MonoTrampInfo
**info
, gboolean aot
)
74 return nop_stub (0x37);
78 mono_arch_get_throw_exception (MonoTrampInfo
**info
, gboolean aot
)
81 return nop_stub (0x77);
85 mono_arch_get_rethrow_exception (MonoTrampInfo
**info
, gboolean aot
)
88 return nop_stub (0x88);
92 mono_arch_get_rethrow_preserve_exception (MonoTrampInfo
**info
, gboolean aot
)
95 return nop_stub (0x99);
99 mono_arch_get_throw_corlib_exception (MonoTrampInfo
**info
, gboolean aot
)
102 return nop_stub (0xaa);
108 mono_arch_get_restore_context (MonoTrampInfo
**info
, gboolean aot
)
110 g_assert_not_reached ();
115 mono_arch_get_call_filter (MonoTrampInfo
**info
, gboolean aot
)
117 g_assert_not_reached ();
122 mono_arch_get_throw_exception (MonoTrampInfo
**info
, gboolean aot
)
124 g_assert_not_reached ();
129 mono_arch_get_rethrow_exception (MonoTrampInfo
**info
, gboolean aot
)
131 g_assert_not_reached ();
136 mono_arch_get_throw_corlib_exception (MonoTrampInfo
**info
, gboolean aot
)
138 g_assert_not_reached ();
145 mono_arch_exceptions_init (void)
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
));
164 host_mgreg_t regs
[MONO_MAX_IREGS
+ 12 + 1];
166 guint32 unwind_info_len
;
170 if (ji
->is_trampoline
)
171 frame
->type
= FRAME_TYPE_TRAMPOLINE
;
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
);
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
;
204 /* we substract 1, so that the IP points into the call instruction */
205 new_ctx
->gregs
[RISCV_ZERO
]--;
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
);
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
;
240 mono_arch_ip_from_context (void *sigctx
)
242 return (gpointer
) UCONTEXT_REG_PC (sigctx
);
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
);
255 mono_arch_setup_resume_sighandler_ctx (MonoContext
*ctx
, gpointer func
)
257 MONO_CONTEXT_SET_IP (ctx
, func
);
261 mono_arch_undo_ip_adjustment (MonoContext
*context
)
263 context
->gregs
[RISCV_ZERO
]++;
267 mono_arch_do_ip_adjustment (MonoContext
*context
)
269 context
->gregs
[RISCV_ZERO
]--;