#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/mono-debug.h>
-#include <mono/metadata/gc-internal.h>
+#include <mono/metadata/gc-internals.h>
#include <mono/metadata/tokentype.h>
#include "mini.h"
* Returns a pointer to a method which restores a previously saved sigcontext.
*/
gpointer
-mono_arch_get_restore_context (void)
+mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
{
static guint32 *start;
static int inited = 0;
guint32 *code;
+ g_assert (!aot);
+ if (info)
+ *info = NULL;
+
if (inited)
return start;
* call_filter (MonoContext *ctx, gpointer ip)
*/
gpointer
-mono_arch_get_call_filter (void)
+mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
{
static guint32 *start;
static int inited = 0;
guint32 *code;
int i;
+ g_assert (!aot);
+ if (info)
+ *info = NULL;
+
if (inited)
return start;
gpointer *window;
if (!restore_context)
- restore_context = mono_arch_get_restore_context ();
+ restore_context = mono_get_restore_context ();
window = MONO_SPARC_WINDOW_ADDR (sp);
ctx.sp = (gpointer*)sp;
if (mono_object_isinst (exc, mono_defaults.exception_class)) {
MonoException *mono_ex = (MonoException*)exc;
- if (!rethrow)
+ if (!rethrow) {
mono_ex->stack_trace = NULL;
+ mono_ex->trace_ips = NULL;
+ }
}
- mono_handle_exception (&ctx, exc, ip, FALSE);
+ mono_handle_exception (&ctx, exc);
restore_context (&ctx);
g_assert_not_reached ();
* The returned function has the following
* signature: void (*func) (MonoException *exc);
*/
-gpointer
-mono_arch_get_throw_exception (void)
+gpointer
+mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
{
static guint32* start;
static int inited = 0;
+ g_assert (!aot);
+ if (info)
+ *info = NULL;
+
if (inited)
return start;
return start;
}
-gpointer
-mono_arch_get_rethrow_exception (void)
+gpointer
+mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
{
static guint32* start;
static int inited = 0;
- if (inited)
- return start;
-
- inited = 1;
-
- start = get_throw_exception (TRUE);
-
- return start;
-}
-
-/**
- * mono_arch_get_throw_exception_by_name:
- *
- * Returns a function pointer which can be used to raise
- * corlib exceptions. The returned function has the following
- * signature: void (*func) (char *exc_name, gpointer ip);
- */
-gpointer
-mono_arch_get_throw_exception_by_name (void)
-{
- static guint32 *start;
- static int inited = 0;
- guint32 *code;
- int reg;
+ g_assert (!aot);
+ if (info)
+ *info = NULL;
if (inited)
return start;
inited = 1;
- code = start = mono_global_codeman_reserve (64 * sizeof (guint32));
-
-#ifdef SPARCV9
- reg = sparc_g4;
-#else
- reg = sparc_g1;
-#endif
-
- sparc_save_imm (code, sparc_sp, -160, sparc_sp);
-
- sparc_mov_reg_reg (code, sparc_i0, sparc_o2);
- sparc_set (code, mono_defaults.corlib, sparc_o0);
- sparc_set (code, "System", sparc_o1);
- sparc_set (code, mono_exception_from_name, sparc_o7);
- sparc_jmpl (code, sparc_o7, sparc_g0, sparc_callsite);
- sparc_nop (code);
-
- /* Return to the caller, so exception handling does not see this frame */
- sparc_restore (code, sparc_o0, sparc_g0, sparc_o0);
-
- /* Put original return address into %o7 */
- sparc_mov_reg_reg (code, sparc_o1, sparc_o7);
- sparc_set (code, mono_arch_get_throw_exception (), reg);
- /* Use a jmp instead of a call so o7 is preserved */
- sparc_jmpl_imm (code, reg, 0, sparc_g0);
- sparc_nop (code);
-
- g_assert ((code - start) < 32);
- mono_arch_flush_icache ((guint8*)start, (guint8*)code - (guint8*)start);
+ start = get_throw_exception (TRUE);
return start;
}
* to get the IP of the throw. Passing the offset has the advantage that it
* needs no relocations in the caller.
*/
-gpointer
-mono_arch_get_throw_corlib_exception (void)
+gpointer
+mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
{
static guint32 *start;
static int inited = 0;
guint32 *code;
int reg;
+ g_assert (!aot);
+ if (info)
+ *info = NULL;
+
if (inited)
return start;
sparc_sll_imm (code, sparc_o1, 2, sparc_o1);
sparc_sub (code, 0, sparc_o2, sparc_o1, sparc_o7);
- sparc_set (code, mono_arch_get_throw_exception (), reg);
+ sparc_set (code, mono_arch_get_throw_exception (NULL, FALSE), reg);
/* Use a jmp instead of a call so o7 is preserved */
sparc_jmpl_imm (code, reg, 0, sparc_g0);
sparc_nop (code);
return start;
}
-/* mono_arch_find_jit_info:
+/* mono_arch_unwind_frame:
*
* This function is used to gather information from @ctx. It return the
* MonoJitInfo of the corresponding function, unwinds one stack frame and
* the @lmf if necessary. @native_offset return the IP offset from the
* start of the function or -1 if that info is not available.
*/
-MonoJitInfo *
-mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx,
- MonoContext *new_ctx, char **trace, MonoLMF **lmf, int *native_offset,
- gboolean *managed)
+gboolean
+mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls,
+ MonoJitInfo *ji, MonoContext *ctx,
+ MonoContext *new_ctx, MonoLMF **lmf,
+ mgreg_t **save_locations,
+ StackFrameInfo *frame)
{
- MonoJitInfo *ji;
- gpointer ip = MONO_CONTEXT_GET_IP (ctx);
gpointer *window;
- /* Avoid costly table lookup during stack overflow */
- if (prev_ji && (ip > prev_ji->code_start && ((guint8*)ip < ((guint8*)prev_ji->code_start) + prev_ji->code_size)))
- ji = prev_ji;
- else
- ji = mono_jit_info_table_find (domain, ip);
+ memset (frame, 0, sizeof (StackFrameInfo));
+ frame->ji = ji;
- if (managed)
- *managed = FALSE;
+ *new_ctx = *ctx;
if (ji != NULL) {
- *new_ctx = *ctx;
-
- if (managed)
- if (!ji->method->wrapper_type)
- *managed = TRUE;
-
- if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) {
- /* remove any unused lmf */
- *lmf = (*lmf)->previous_lmf;
- }
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
/* Restore ip and sp from the saved register window */
window = MONO_SPARC_WINDOW_ADDR (ctx->sp);
new_ctx->sp = (gpointer*)(window [sparc_i6 - 16]);
new_ctx->fp = (gpointer*)(MONO_SPARC_WINDOW_ADDR (new_ctx->sp) [sparc_i6 - 16]);
- return ji;
+ return TRUE;
}
else {
if (!(*lmf))
- return NULL;
-
- *new_ctx = *ctx;
+ return FALSE;
if (!(*lmf)->method)
- return (gpointer)-1;
+ return FALSE;
- if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->ip))) {
- } else {
- memset (res, 0, sizeof (MonoJitInfo));
- res->method = (*lmf)->method;
- }
+ ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->ip, NULL);
+ if (!ji)
+ return FALSE;
+
+ frame->ji = ji;
+ frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;
new_ctx->ip = (*lmf)->ip;
new_ctx->sp = (*lmf)->sp;
*lmf = (*lmf)->previous_lmf;
- return ji ? ji : res;
+ return TRUE;
}
}
-gboolean
-mono_arch_has_unwind_info (gconstpointer addr)
-{
- return FALSE;
-}
-
#ifdef __linux__
gboolean
-mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
+mono_arch_handle_exception (void *sigctx, gpointer obj)
{
MonoContext mctx;
struct sigcontext *sc = sigctx;
window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS);
mctx.fp = window [sparc_fp - 16];
- mono_handle_exception (&mctx, obj, mctx.ip, test_only);
+ mono_handle_exception (&mctx, obj);
#ifdef SPARCV9
sc->sigc_regs.tpc = (unsigned long) mctx.ip;
#else /* !__linux__ */
gboolean
-mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
+mono_arch_handle_exception (void *sigctx, gpointer obj)
{
MonoContext mctx;
ucontext_t *ctx = (ucontext_t*)sigctx;
window = (gpointer*)(((guint8*)mctx.sp) + MONO_SPARC_STACK_BIAS);
mctx.fp = window [sparc_fp - 16];
- mono_handle_exception (&mctx, obj, mctx.ip, test_only);
+ mono_handle_exception (&mctx, obj);
/* We can't use restore_context to return from a signal handler */
ctx->uc_mcontext.gregs [REG_PC] = mctx.ip;