提交 1502a804 编写于 作者: Z Zoltan Varga

2004-04-28 Zoltan Varga <vargaz@freemail.hu>

	* Makefile.am mini.h mini-exceptions.c mini-x86.h mini-sparc.h exceptions-sparc.c: Move parts of the sparc exception handling code to XP code.

svn path=/trunk/mono/; revision=26140
上级 9a9983c0
2004-04-28 Zoltan Varga <vargaz@freemail.hu>
* Makefile.am mini.h mini-exceptions.c mini-x86.h mini-sparc.h exceptions-sparc.c: Move parts of the sparc exception handling code to XP code.
* exceptions-sparc.c exceptions-ppc.c exceptions-s390.c mini-ppc.h mini-s390.h mini-sparc.h: Fix up ports after changes.
* mini-exceptions.c: New file.
......
......@@ -81,6 +81,7 @@ ppc_sources = \
sparc_sources = \
mini-sparc.c \
mini-sparc.h \
mini-exceptions.c \
exceptions-sparc.c \
tramp-sparc.c
......
......@@ -26,23 +26,13 @@
#include "mini.h"
#include "mini-sparc.h"
gboolean mono_sparc_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only);
#define MONO_CONTEXT_SET_IP(ctx,eip) do { (ctx)->ip = (long)(eip); } while (0);
#define MONO_CONTEXT_SET_BP(ctx,ebp) do { (ctx)->fp = (long)(ebp); } while (0);
#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->ip))
#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->fp))
#define IS_ON_SIGALTSTACK(jit_tls) FALSE
/*
* arch_get_restore_context:
* mono_arch_get_restore_context:
*
* Returns a pointer to a method which restores a previously saved sigcontext.
*/
static gpointer
arch_get_restore_context (void)
gpointer
mono_arch_get_restore_context (void)
{
static guint32 start [32];
static int inited = 0;
......@@ -68,7 +58,7 @@ arch_get_restore_context (void)
}
/*
* arch_get_call_filter:
* mono_arch_get_call_filter:
*
* Returns a pointer to a method which calls an exception filter. We
* also use this function to call finally handlers (we pass NULL as
......@@ -76,8 +66,8 @@ arch_get_restore_context (void)
*
* call_filter (MonoContext *ctx, gpointer ip)
*/
static gpointer
arch_get_call_filter (void)
gpointer
mono_arch_get_call_filter (void)
{
static guint32 start [64];
static int inited = 0;
......@@ -161,20 +151,20 @@ throw_exception (MonoObject *ex, guint32 sp, guint32 ip)
static void (*restore_context) (MonoContext *);
if (!restore_context)
restore_context = arch_get_restore_context ();
restore_context = mono_arch_get_restore_context ();
ctx.sp = (guint32*)sp;
ctx.ip = ip;
ctx.fp = (guint32*)ctx.sp [sparc_i6 - 16];
mono_sparc_handle_exception (&ctx, ex, FALSE);
mono_handle_exception (&ctx, ex, FALSE);
restore_context (&ctx);
g_assert_not_reached ();
}
/**
* arch_get_throw_exception_by_name:
* mono_arch_get_throw_exception_by_name:
*
* Returns a function pointer which can be used to raise exceptions.
* The returned function has the following
......@@ -209,7 +199,7 @@ mono_arch_get_throw_exception (void)
}
/**
* arch_get_throw_exception_by_name:
* 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
......@@ -367,306 +357,6 @@ mono_arch_has_unwind_info (gconstpointer addr)
return FALSE;
}
static MonoArray *
glist_to_array (GList *list)
{
MonoDomain *domain = mono_domain_get ();
MonoArray *res;
int len, i;
if (!list)
return NULL;
len = g_list_length (list);
res = mono_array_new (domain, mono_defaults.int_class, len);
for (i = 0; list; list = list->next, i++)
mono_array_set (res, gpointer, i, list->data);
return res;
}
MonoArray *
ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info)
{
return NULL;
}
void
mono_jit_walk_stack (MonoStackWalk func, gpointer user_data)
{
MonoDomain *domain = mono_domain_get ();
MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
MonoLMF *lmf = jit_tls->lmf;
MonoJitInfo *ji, rji;
gint native_offset, il_offset;
gboolean managed;
MonoContext ctx, new_ctx;
mono_sparc_flushw ();
MONO_CONTEXT_SET_IP (&ctx, __builtin_return_address (0));
MONO_CONTEXT_SET_BP (&ctx, __builtin_frame_address (0));
while (MONO_CONTEXT_GET_BP (&ctx) < jit_tls->end_of_stack) {
ji = mono_arch_find_jit_info (domain, jit_tls, &rji, NULL, &ctx, &new_ctx, NULL, &lmf, &native_offset, &managed);
g_assert (ji);
if (ji == (gpointer)-1)
return;
il_offset = mono_debug_il_offset_from_address (ji->method, native_offset, domain);
if (func (ji->method, native_offset, il_offset, managed, user_data))
return;
ctx = new_ctx;
}
}
MonoBoolean
ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
MonoReflectionMethod **method,
gint32 *iloffset, gint32 *native_offset,
MonoString **file, gint32 *line, gint32 *column)
{
return FALSE;
}
/**
* mono_sparc_handle_exception:
* @ctx: saved processor state
* @obj: the exception object
* @test_only: only test if the exception is caught, but dont call handlers
*
*
*/
gboolean
mono_sparc_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
{
MonoDomain *domain = mono_domain_get ();
MonoJitInfo *ji, rji;
static int (*call_filter) (MonoContext *, gpointer) = NULL;
static void (*restore_context) (MonoContext *);
MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
MonoLMF *lmf = jit_tls->lmf;
GList *trace_ips = NULL;
MonoException *mono_ex;
gboolean stack_overflow = FALSE;
MonoContext initial_ctx;
int frame_count = 0;
gboolean gc_disabled = FALSE;
MonoString *initial_stack_trace;
/*
* This function might execute on an alternate signal stack, and Boehm GC
* can't handle that.
* Also, since the altstack is small, stack space intensive operations like
* JIT compilation should be avoided.
*/
if (IS_ON_SIGALTSTACK (jit_tls)) {
/*
* FIXME: disabling/enabling GC while already on a signal stack might
* not be safe either.
*/
/* Have to reenable it later */
gc_disabled = TRUE;
mono_gc_disable ();
}
g_assert (ctx != NULL);
if (!obj) {
MonoException *ex = mono_get_exception_null_reference ();
ex->message = mono_string_new (domain, "Object reference not set to an instance of an object");
obj = (MonoObject *)ex;
}
if (mono_object_isinst (obj, mono_defaults.exception_class)) {
mono_ex = (MonoException*)obj;
mono_ex->stack_trace = NULL;
initial_stack_trace = mono_ex->stack_trace;
} else {
mono_ex = NULL;
}
//printf ("HANDLING EXCEPTION: %s\n", ((MonoObject*)obj)->vtable->klass->name);
if (obj == domain->stack_overflow_ex)
stack_overflow = TRUE;
if (!call_filter)
call_filter = arch_get_call_filter ();
if (!restore_context)
restore_context = arch_get_restore_context ();
g_assert (jit_tls->end_of_stack);
g_assert (jit_tls->abort_func);
if (!test_only) {
MonoContext ctx_cp = *ctx;
if (mono_jit_trace_calls != NULL)
g_print ("EXCEPTION handling: %s\n", mono_object_class (obj)->name);
if (!mono_sparc_handle_exception (&ctx_cp, obj, TRUE)) {
if (mono_break_on_exc)
G_BREAKPOINT ();
mono_unhandled_exception (obj);
}
}
initial_ctx = *ctx;
memset (&rji, 0, sizeof (rji));
while (1) {
MonoContext new_ctx;
char *trace = NULL;
gboolean need_trace = FALSE;
guint32 free_stack;
if (test_only && (frame_count < 1000))
need_trace = TRUE;
ji = mono_arch_find_jit_info (domain, jit_tls, &rji, &rji, ctx, &new_ctx,
need_trace ? &trace : NULL, &lmf, NULL, NULL);
if (!ji) {
g_warning ("Exception inside function without unwind info");
g_assert_not_reached ();
}
//printf ("JI: %p IP: %p SP: %p.\n", ji, (gpointer)new_ctx.ip, new_ctx.sp);
if (ji != (gpointer)-1) {
frame_count ++;
//printf ("M: %s %p %p %d.\n", mono_method_full_name (ji->method, TRUE), jit_tls->end_of_stack, ctx->ebp, count);
if (test_only && ji->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && mono_ex) {
char *tmp, *strace;
/*
* Avoid overwriting the stack trace if the exception is
* rethrown. Also avoid giant stack traces during a stack
* overflow.
*/
if (!initial_stack_trace && (frame_count < 1000)) {
trace_ips = g_list_append (trace_ips, MONO_CONTEXT_GET_IP (ctx));
if (!mono_ex->stack_trace)
strace = g_strdup ("");
else
strace = mono_string_to_utf8 (mono_ex->stack_trace);
tmp = g_strdup_printf ("%s%s\n", strace, trace);
g_free (strace);
mono_ex->stack_trace = mono_string_new (domain, tmp);
g_free (tmp);
}
}
/*
if (stack_overflow)
free_stack = (guint8*)(MONO_CONTEXT_GET_BP (ctx)) - (guint8*)(MONO_CONTEXT_GET_BP (&initial_ctx));
else
free_stack = 0xffffff;
*/
free_stack = 0xffffff;
/*
* During stack overflow, wait till the unwinding frees some stack
* space before running handlers/finalizers.
*/
if ((free_stack > (64 * 1024)) && ji->num_clauses) {
int i;
g_assert (ji->clauses);
for (i = 0; i < ji->num_clauses; i++) {
MonoJitExceptionInfo *ei = &ji->clauses [i];
if (ei->try_start <= MONO_CONTEXT_GET_IP (ctx) &&
MONO_CONTEXT_GET_IP (ctx) <= ei->try_end) {
/* catch block */
if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE) || (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)) {
/* store the exception object int cfg->excvar */
g_assert (ji->exvar_offset);
*((gpointer *)((char *)MONO_CONTEXT_GET_BP (ctx) + ji->exvar_offset)) = obj;
}
if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE &&
mono_object_isinst (obj, mono_class_get (ji->method->klass->image, ei->data.token))) ||
((ei->flags == MONO_EXCEPTION_CLAUSE_FILTER &&
call_filter (ctx, ei->data.filter)))) {
if (test_only) {
if (mono_ex)
mono_ex->trace_ips = glist_to_array (trace_ips);
g_list_free (trace_ips);
g_free (trace);
if (gc_disabled)
mono_gc_enable ();
return TRUE;
}
if (mono_jit_trace_calls != NULL && mono_trace_eval (ji->method))
g_print ("EXCEPTION: catch found at clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
jit_tls->lmf = lmf;
g_free (trace);
if (gc_disabled)
mono_gc_enable ();
return 0;
}
if (!test_only && ei->try_start <= MONO_CONTEXT_GET_IP (ctx) &&
MONO_CONTEXT_GET_IP (ctx) < ei->try_end &&
(ei->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
if (mono_jit_trace_calls != NULL && mono_trace_eval (ji->method))
g_print ("EXCEPTION: finally clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
call_filter (ctx, ei->handler_start);
}
}
}
}
}
g_free (trace);
*ctx = new_ctx;
if ((ji == (gpointer)-1) || MONO_CONTEXT_GET_BP (ctx) >= jit_tls->end_of_stack) {
if (gc_disabled)
mono_gc_enable ();
if (!test_only) {
jit_tls->lmf = lmf;
if (IS_ON_SIGALTSTACK (jit_tls)) {
/* Switch back to normal stack */
if (stack_overflow)
/* Free up some stack space */
initial_ctx.sp += (64 * 1024);
initial_ctx.ip = (unsigned int)jit_tls->abort_func;
restore_context (&initial_ctx);
}
else
jit_tls->abort_func (obj);
g_assert_not_reached ();
} else {
if (mono_ex)
mono_ex->trace_ips = glist_to_array (trace_ips);
g_list_free (trace_ips);
return FALSE;
}
}
}
g_assert_not_reached ();
}
gboolean
mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
{
......@@ -684,7 +374,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
mctx.sp = ctx->uc_mcontext.gregs [REG_SP];
mctx.fp = mctx.sp [sparc_fp - 16];
mono_sparc_handle_exception (&mctx, obj, test_only);
mono_handle_exception (&mctx, obj, test_only);
/* We can't use restore_context to return from a signal handler */
ctx->uc_mcontext.gregs [REG_PC] = mctx.ip;
......
......@@ -88,6 +88,8 @@ mono_jit_walk_stack (MonoStackWalk func, gpointer user_data) {
MonoContext ctx, new_ctx;
mono_arch_flush_register_windows ();
MONO_CONTEXT_SET_IP (&ctx, __builtin_return_address (0));
MONO_CONTEXT_SET_BP (&ctx, __builtin_frame_address (1));
......@@ -395,8 +397,8 @@ mono_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
/* Switch back to normal stack */
if (stack_overflow)
/* Free up some stack space */
initial_ctx.SC_ESP += (64 * 1024);
initial_ctx.SC_EIP = (unsigned int)jit_tls->abort_func;
MONO_CONTEXT_SET_SP (&initial_ctx, (guint32)(MONO_CONTEXT_GET_SP (&initial_ctx)) + (64 * 1024));
MONO_CONTEXT_SET_IP (&initial_ctx, (unsigned int)jit_tls->abort_func);
restore_context (&initial_ctx);
}
else
......
......@@ -212,6 +212,12 @@ mono_sparc_flushw (void)
flushw ();
}
void
mono_arch_flush_register_windows (void)
{
mono_sparc_flushw ();
}
gboolean
mono_sparc_is_v9 (void) {
return sparcv9;
......
......@@ -35,6 +35,14 @@ typedef struct MonoCompileArch {
guint32 localloc_offset;
} MonoCompileArch;
#define MONO_CONTEXT_SET_IP(ctx,eip) do { (ctx)->ip = (long)(eip); } while (0);
#define MONO_CONTEXT_SET_BP(ctx,ebp) do { (ctx)->fp = (long)(ebp); } while (0);
#define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->sp = (long)(esp); } while (0);
#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->ip))
#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->fp))
#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sp))
#define MONO_ARCH_USE_SIGACTION 1
#define MONO_ARCH_EMULATE_FCONV_TO_I8 1
......
......@@ -3362,6 +3362,11 @@ mono_arch_flush_icache (guint8 *code, gint size)
/* not needed */
}
void
mono_arch_flush_register_windows (void)
{
}
/*
* Support for fast access to the thread-local lmf structure using the GS
* segment register on NPTL + kernel 2.6.x.
......
......@@ -63,11 +63,13 @@ typedef struct MonoCompileArch {
typedef struct sigcontext MonoContext;
#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->SC_EIP = (long)ip; } while (0);
#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->SC_EBP = (long)bp; } while (0);
#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->SC_EIP = (long)(ip); } while (0);
#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->SC_EBP = (long)(bp); } while (0);
#define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->SC_ESP = (long)(esp); } while (0);
#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->SC_EIP))
#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->SC_EBP))
#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->SC_ESP))
#ifndef PLATFORM_WIN32
......
......@@ -758,6 +758,7 @@ MonoJitInfo *mono_arch_find_jit_info (MonoDomain *domain,
gpointer mono_arch_get_call_filter (void);
gpointer mono_arch_get_restore_context (void);
gboolean mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only);
void mono_arch_flush_register_windows (void);
/* Exception handling */
gboolean mono_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册