diff options
-rw-r--r-- | mono/mini/aot-compiler.c | 4 | ||||
-rw-r--r-- | mono/mini/aot-runtime.c | 8 | ||||
-rw-r--r-- | mono/mini/exceptions-amd64.c | 37 | ||||
-rw-r--r-- | mono/mini/exceptions-arm.c | 49 | ||||
-rw-r--r-- | mono/mini/exceptions-arm64.c | 29 | ||||
-rw-r--r-- | mono/mini/exceptions-mips.c | 36 | ||||
-rw-r--r-- | mono/mini/exceptions-ppc.c | 32 | ||||
-rw-r--r-- | mono/mini/exceptions-s390x.c | 44 | ||||
-rw-r--r-- | mono/mini/exceptions-sparc.c | 31 | ||||
-rw-r--r-- | mono/mini/exceptions-wasm.c | 14 | ||||
-rw-r--r-- | mono/mini/exceptions-x86.c | 36 | ||||
-rw-r--r-- | mono/mini/mini-amd64.h | 2 | ||||
-rw-r--r-- | mono/mini/mini-arm.h | 2 | ||||
-rw-r--r-- | mono/mini/mini-arm64.h | 2 | ||||
-rw-r--r-- | mono/mini/mini-exceptions.c | 16 | ||||
-rw-r--r-- | mono/mini/mini-ppc.h | 2 | ||||
-rw-r--r-- | mono/mini/mini-x86.h | 2 | ||||
-rw-r--r-- | mono/mini/mini.h | 4 | ||||
-rw-r--r-- | mono/mini/tramp-amd64.c | 4 | ||||
-rw-r--r-- | mono/mini/tramp-arm.c | 4 | ||||
-rw-r--r-- | mono/mini/tramp-arm64.c | 4 | ||||
-rw-r--r-- | mono/mini/tramp-ppc.c | 2 | ||||
-rw-r--r-- | mono/mini/tramp-s390x.c | 2 | ||||
-rw-r--r-- | mono/mini/tramp-x86.c | 4 |
24 files changed, 282 insertions, 88 deletions
diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index 37f75ee223e..19d9e66129a 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -7056,6 +7056,10 @@ emit_trampolines (MonoAotCompile *acfg) emit_trampoline (acfg, acfg->got_offset, info); mono_tramp_info_free (info); + mono_arch_get_rethrow_preserve_exception (&info, TRUE); + emit_trampoline (acfg, acfg->got_offset, info); + mono_tramp_info_free (info); + mono_arch_get_throw_corlib_exception (&info, TRUE); emit_trampoline (acfg, acfg->got_offset, info); mono_tramp_info_free (info); diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 03f83638ffd..ad469fb69bb 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -5315,8 +5315,8 @@ load_function_full (MonoAotModule *amodule, const char *name, MonoTrampInfo **ou target = (gpointer)mono_exception_from_token; } else if (!strcmp (ji->data.name, "mono_throw_exception")) { target = (gpointer)mono_get_throw_exception (); - } else if (!strcmp (ji->data.name, "mono_rethrow_exception")) { - target = (gpointer)mono_get_rethrow_exception (); + } else if (!strcmp (ji->data.name, "mono_rethrow_preserve_exception")) { + target = (gpointer)mono_get_rethrow_preserve_exception (); } else if (strstr (ji->data.name, "trampoline_func_") == ji->data.name) { MonoTrampolineType tramp_type2 = (MonoTrampolineType)atoi (ji->data.name + strlen ("trampoline_func_")); target = (gpointer)mono_get_trampoline_func (tramp_type2); @@ -5335,8 +5335,8 @@ load_function_full (MonoAotModule *amodule, const char *name, MonoTrampInfo **ou target = (gpointer)mini_get_dbg_callbacks ()->breakpoint_from_context; } else if (!strcmp (ji->data.name, "throw_exception_addr")) { target = mono_get_throw_exception_addr (); - } else if (!strcmp (ji->data.name, "rethrow_exception_addr")) { - target = mono_get_rethrow_exception_addr (); + } else if (!strcmp (ji->data.name, "rethrow_preserve_exception_addr")) { + target = mono_get_rethrow_preserve_exception_addr (); } else if (strstr (ji->data.name, "generic_trampoline_")) { target = mono_aot_get_trampoline (ji->data.name); } else if (aot_jit_icall_hash && g_hash_table_lookup (aot_jit_icall_hash, ji->data.name)) { diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index 006dab03e21..1cefe97f180 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -378,7 +378,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) void mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4, guint64 dummy5, guint64 dummy6, - MonoContext *mctx, MonoObject *exc, gboolean rethrow) + MonoContext *mctx, MonoObject *exc, gboolean rethrow, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; @@ -391,6 +391,8 @@ mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guin if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; + } else if (preserve_ips) { + mono_ex->caught_in_unmanaged = TRUE; } } mono_error_assert_ok (error); @@ -418,7 +420,7 @@ mono_amd64_throw_corlib_exception (guint64 dummy1, guint64 dummy2, guint64 dummy /* Negate the ip adjustment done in mono_amd64_throw_exception () */ mctx->gregs [AMD64_RIP] += 1; - mono_amd64_throw_exception (dummy1, dummy2, dummy3, dummy4, dummy5, dummy6, mctx, (MonoObject*)ex, FALSE); + mono_amd64_throw_exception (dummy1, dummy2, dummy3, dummy4, dummy5, dummy6, mctx, (MonoObject*)ex, FALSE, FALSE); } void @@ -443,7 +445,7 @@ mono_amd64_resume_unwind (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint6 * mono_amd64_throw_corlib_exception. */ static gpointer -get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, gboolean llvm_abs, gboolean resume_unwind, const char *tramp_name, gboolean aot) +get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, gboolean llvm_abs, gboolean resume_unwind, const char *tramp_name, gboolean aot, gboolean preserve_ips) { guint8* start; guint8 *code; @@ -486,6 +488,7 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g arg_offsets [0] = dummy_stack_space + 0; arg_offsets [1] = dummy_stack_space + sizeof(mgreg_t); arg_offsets [2] = dummy_stack_space + sizeof(mgreg_t) * 2; + arg_offsets [3] = dummy_stack_space + sizeof(mgreg_t) * 3; ctx_offset = dummy_stack_space + sizeof(mgreg_t) * 4; regs_offset = ctx_offset + MONO_STRUCT_OFFSET (MonoContext, gregs); @@ -521,6 +524,9 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g amd64_mov_membase_reg (code, AMD64_RSP, arg_offsets [2], AMD64_ARG_REG2, sizeof(mgreg_t)); } else { amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], rethrow, sizeof(mgreg_t)); + + /* Set arg4 == preserve_ips */ + amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [3], preserve_ips, sizeof(mgreg_t)); } if (aot) { @@ -562,13 +568,19 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g gpointer mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (info, FALSE, FALSE, FALSE, FALSE, "throw_exception", aot); + return get_throw_trampoline (info, FALSE, FALSE, FALSE, FALSE, "throw_exception", aot, FALSE); } gpointer mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (info, TRUE, FALSE, FALSE, FALSE, "rethrow_exception", aot); + return get_throw_trampoline (info, TRUE, FALSE, FALSE, FALSE, "rethrow_exception", aot, FALSE); +} + +gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + return get_throw_trampoline (info, TRUE, FALSE, FALSE, FALSE, "rethrow_preserve_exception", aot, TRUE); } /** @@ -584,7 +596,7 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) gpointer mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (info, FALSE, TRUE, FALSE, FALSE, "throw_corlib_exception", aot); + return get_throw_trampoline (info, FALSE, TRUE, FALSE, FALSE, "throw_corlib_exception", aot, FALSE); } #endif /* !DISABLE_JIT */ @@ -911,13 +923,13 @@ mono_amd64_get_exception_trampolines (gboolean aot) GSList *tramps = NULL; /* LLVM needs different throw trampolines */ - get_throw_trampoline (&info, FALSE, TRUE, FALSE, FALSE, "llvm_throw_corlib_exception_trampoline", aot); + get_throw_trampoline (&info, FALSE, TRUE, FALSE, FALSE, "llvm_throw_corlib_exception_trampoline", aot, FALSE); tramps = g_slist_prepend (tramps, info); - get_throw_trampoline (&info, FALSE, TRUE, TRUE, FALSE, "llvm_throw_corlib_exception_abs_trampoline", aot); + get_throw_trampoline (&info, FALSE, TRUE, TRUE, FALSE, "llvm_throw_corlib_exception_abs_trampoline", aot, FALSE); tramps = g_slist_prepend (tramps, info); - get_throw_trampoline (&info, FALSE, TRUE, TRUE, TRUE, "llvm_resume_unwind_trampoline", aot); + get_throw_trampoline (&info, FALSE, TRUE, TRUE, TRUE, "llvm_resume_unwind_trampoline", aot, FALSE); tramps = g_slist_prepend (tramps, info); return tramps; @@ -1953,6 +1965,13 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) } gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { g_assert_not_reached (); diff --git a/mono/mini/exceptions-arm.c b/mono/mini/exceptions-arm.c index 94c6dfe3512..ed822d20608 100644 --- a/mono/mini/exceptions-arm.c +++ b/mono/mini/exceptions-arm.c @@ -144,7 +144,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) } void -mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs) +mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; @@ -167,6 +167,8 @@ mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_ if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; + } else if (preserve_ips) { + mono_ex->caught_in_unmanaged = TRUE; } } mono_error_assert_ok (error); @@ -182,7 +184,7 @@ mono_arm_throw_exception_by_token (guint32 ex_token_index, mgreg_t pc, mgreg_t s /* Clear thumb bit */ pc &= ~1; - mono_arm_throw_exception ((MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token), pc, sp, int_regs, fp_regs); + mono_arm_throw_exception ((MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token), pc, sp, int_regs, fp_regs, FALSE); } void @@ -212,7 +214,7 @@ mono_arm_resume_unwind (guint32 dummy1, mgreg_t pc, mgreg_t sp, mgreg_t *int_reg * */ static gpointer -get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm, gboolean resume_unwind, const char *tramp_name, MonoTrampInfo **info, gboolean aot) +get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm, gboolean resume_unwind, const char *tramp_name, MonoTrampInfo **info, gboolean aot, gboolean preserve_ips) { guint8 *start; guint8 *code; @@ -241,8 +243,11 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm } /* Param area */ - ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 8); - cfa_offset += 8; + int param_size = 8; + if (!resume_unwind && !corlib) + param_size += 4; // Extra arg + ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, param_size); + cfa_offset += param_size; mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, cfa_offset); /* call throw_exception (exc, ip, sp, int_regs, fp_regs) */ @@ -271,9 +276,19 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm } /* int regs */ ARM_ADD_REG_IMM8 (code, ARMREG_R3, ARMREG_SP, (cfa_offset - (MONO_ARM_NUM_SAVED_REGS * sizeof (mgreg_t)))); - /* fp regs */ - ARM_ADD_REG_IMM8 (code, ARMREG_LR, ARMREG_SP, 8); - ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, 0); + if (resume_unwind || corlib) { + /* fp regs */ + ARM_ADD_REG_IMM8 (code, ARMREG_LR, ARMREG_SP, 8); + ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, 0); + } else { + /* preserve_ips */ + ARM_MOV_REG_IMM8 (code, ARMREG_R5, preserve_ips); + ARM_STR_IMM (code, ARMREG_R5, ARMREG_SP, 4); + + /* fp regs */ + ARM_ADD_REG_IMM8 (code, ARMREG_LR, ARMREG_SP, 8); + ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, 0); + } if (aot) { const char *icall_name; @@ -323,7 +338,7 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm gpointer mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (132, FALSE, FALSE, FALSE, FALSE, "throw_exception", info, aot); + return get_throw_trampoline (132, FALSE, FALSE, FALSE, FALSE, "throw_exception", info, aot, FALSE); } /** @@ -337,7 +352,13 @@ mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) gpointer mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (132, FALSE, TRUE, FALSE, FALSE, "rethrow_exception", info, aot); + return get_throw_trampoline (132, FALSE, TRUE, FALSE, FALSE, "rethrow_exception", info, aot, FALSE); +} + +gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + return get_throw_trampoline (132, FALSE, TRUE, FALSE, FALSE, "rethrow_preserve_exception", info, aot, TRUE); } /** @@ -353,7 +374,7 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) gpointer mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (168, TRUE, FALSE, FALSE, FALSE, "throw_corlib_exception", info, aot); + return get_throw_trampoline (168, TRUE, FALSE, FALSE, FALSE, "throw_corlib_exception", info, aot, FALSE); } GSList* @@ -363,13 +384,13 @@ mono_arm_get_exception_trampolines (gboolean aot) GSList *tramps = NULL; /* LLVM uses the normal trampolines, but with a different name */ - get_throw_trampoline (168, TRUE, FALSE, FALSE, FALSE, "llvm_throw_corlib_exception_trampoline", &info, aot); + get_throw_trampoline (168, TRUE, FALSE, FALSE, FALSE, "llvm_throw_corlib_exception_trampoline", &info, aot, FALSE); tramps = g_slist_prepend (tramps, info); - get_throw_trampoline (168, TRUE, FALSE, TRUE, FALSE, "llvm_throw_corlib_exception_abs_trampoline", &info, aot); + get_throw_trampoline (168, TRUE, FALSE, TRUE, FALSE, "llvm_throw_corlib_exception_abs_trampoline", &info, aot, FALSE); tramps = g_slist_prepend (tramps, info); - get_throw_trampoline (168, FALSE, FALSE, FALSE, TRUE, "llvm_resume_unwind_trampoline", &info, aot); + get_throw_trampoline (168, FALSE, FALSE, FALSE, TRUE, "llvm_resume_unwind_trampoline", &info, aot, FALSE); tramps = g_slist_prepend (tramps, info); return tramps; diff --git a/mono/mini/exceptions-arm64.c b/mono/mini/exceptions-arm64.c index 04e301b030d..15ebd08283d 100644 --- a/mono/mini/exceptions-arm64.c +++ b/mono/mini/exceptions-arm64.c @@ -161,7 +161,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) } static gpointer -get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm, gboolean resume_unwind, const char *tramp_name, MonoTrampInfo **info, gboolean aot) +get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm, gboolean resume_unwind, const char *tramp_name, MonoTrampInfo **info, gboolean aot, gboolean preserve_ips) { guint8 *start, *code; MonoJumpInfo *ji = NULL; @@ -223,6 +223,11 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm arm_movzx (code, ARMREG_R4, corlib ? 1 : 0, 0); /* Arg 6 = rethrow */ arm_movzx (code, ARMREG_R5, rethrow ? 1 : 0, 0); + if (!resume_unwind) { + /* Arg 7 = preserve_ips */ + arm_movzx (code, ARMREG_R6, preserve_ips ? 1 : 0, 0); + } + /* Call the function */ if (aot) { const char *icall_name; @@ -260,19 +265,25 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm gpointer mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (256, FALSE, FALSE, FALSE, FALSE, "throw_exception", info, aot); + return get_throw_trampoline (256, FALSE, FALSE, FALSE, FALSE, "throw_exception", info, aot, FALSE); } gpointer mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (256, FALSE, TRUE, FALSE, FALSE, "rethrow_exception", info, aot); + return get_throw_trampoline (256, FALSE, TRUE, FALSE, FALSE, "rethrow_exception", info, aot, FALSE); +} + +gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + return get_throw_trampoline (256, FALSE, TRUE, FALSE, FALSE, "rethrow_preserve_exception", info, aot, TRUE); } gpointer mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline (256, TRUE, FALSE, FALSE, FALSE, "throw_corlib_exception", info, aot); + return get_throw_trampoline (256, TRUE, FALSE, FALSE, FALSE, "throw_corlib_exception", info, aot, FALSE); } GSList* @@ -282,13 +293,13 @@ mono_arm_get_exception_trampolines (gboolean aot) GSList *tramps = NULL; /* LLVM uses the normal trampolines, but with a different name */ - get_throw_trampoline (256, TRUE, FALSE, FALSE, FALSE, "llvm_throw_corlib_exception_trampoline", &info, aot); + get_throw_trampoline (256, TRUE, FALSE, FALSE, FALSE, "llvm_throw_corlib_exception_trampoline", &info, aot, FALSE); tramps = g_slist_prepend (tramps, info); - get_throw_trampoline (256, TRUE, FALSE, TRUE, FALSE, "llvm_throw_corlib_exception_abs_trampoline", &info, aot); + get_throw_trampoline (256, TRUE, FALSE, TRUE, FALSE, "llvm_throw_corlib_exception_abs_trampoline", &info, aot, FALSE); tramps = g_slist_prepend (tramps, info); - get_throw_trampoline (256, FALSE, FALSE, FALSE, TRUE, "llvm_resume_unwind_trampoline", &info, aot); + get_throw_trampoline (256, FALSE, FALSE, FALSE, TRUE, "llvm_resume_unwind_trampoline", &info, aot, FALSE); tramps = g_slist_prepend (tramps, info); return tramps; @@ -372,7 +383,7 @@ mono_arch_exceptions_init (void) * FP_REGS points to the 8 callee saved fp regs. */ void -mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow) +mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; @@ -403,6 +414,8 @@ mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble * if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; + } else if (preserve_ips) { + mono_ex->caught_in_unmanaged = TRUE; } } mono_error_assert_ok (error); diff --git a/mono/mini/exceptions-mips.c b/mono/mini/exceptions-mips.c index 9efa0894fb1..195d9b3e20d 100644 --- a/mono/mini/exceptions-mips.c +++ b/mono/mini/exceptions-mips.c @@ -177,7 +177,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) } static void -throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean rethrow) +throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean rethrow, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; @@ -203,6 +203,8 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; + } if (preserve_ips) { + mono_ex->catch_in_unmanaged = TRUE; } } mono_error_assert_ok (error); @@ -227,7 +229,7 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean * */ static gpointer -mono_arch_get_throw_exception_generic (guint8 *start, int size, int corlib, gboolean rethrow) +mono_arch_get_throw_exception_generic (guint8 *start, int size, int corlib, gboolean rethrow, gboolean preserve_ips) { guint8 *code; int alloc_size, pos, i; @@ -312,7 +314,31 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) if (inited) return start; - mono_arch_get_throw_exception_generic (start, sizeof (start), FALSE, TRUE); + mono_arch_get_throw_exception_generic (start, sizeof (start), FALSE, TRUE, FALSE); + inited = 1; + return start; +} + +/** + * mono_arch_get_rethrow_preserve_exception: + * \returns a function pointer which can be used to rethrow + * exceptions while avoiding modification of saved trace_ips. + * The returned function has the following + * signature: void (*func) (MonoException *exc); + */ +gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + static guint8 start [GENERIC_EXCEPTION_SIZE]; + static int inited = 0; + + g_assert (!aot); + if (info) + *info = NULL; + + if (inited) + return start; + mono_arch_get_throw_exception_generic (start, sizeof (start), FALSE, TRUE, TRUE); inited = 1; return start; } @@ -341,7 +367,7 @@ mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) if (inited) return start; - mono_arch_get_throw_exception_generic (start, sizeof (start), FALSE, FALSE); + mono_arch_get_throw_exception_generic (start, sizeof (start), FALSE, FALSE, FALSE); inited = 1; return start; } @@ -379,7 +405,7 @@ mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) if (inited) return start; - mono_arch_get_throw_exception_generic (start, sizeof (start), TRUE, FALSE); + mono_arch_get_throw_exception_generic (start, sizeof (start), TRUE, FALSE, FALSE); inited = 1; return start; } diff --git a/mono/mini/exceptions-ppc.c b/mono/mini/exceptions-ppc.c index 3483ba835d8..89125df5d05 100644 --- a/mono/mini/exceptions-ppc.c +++ b/mono/mini/exceptions-ppc.c @@ -322,7 +322,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) } void -mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, mgreg_t *int_regs, gdouble *fp_regs, gboolean rethrow) +mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, mgreg_t *int_regs, gdouble *fp_regs, gboolean rethrow, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; @@ -343,6 +343,8 @@ mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; + } else if (preserve_ips) { + mono_ex->catch_in_unmanaged = TRUE } } mono_error_assert_ok (error); @@ -362,7 +364,7 @@ mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, * */ static gpointer -mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corlib, gboolean rethrow, gboolean aot) +mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corlib, gboolean rethrow, gboolean aot, gboolean preserve_ips) { guint8 *start, *code; int alloc_size, pos; @@ -424,6 +426,7 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corli pos -= sizeof (gpointer) * MONO_MAX_IREGS; ppc_addi (code, ppc_r6, ppc_sp, pos); ppc_li (code, ppc_r8, rethrow); + ppc_li (code, ppc_r9, preserve_ips); if (aot) { // This can be called from runtime code, which can't guarantee that @@ -449,12 +452,29 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corli MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL)); if (info) - *info = mono_tramp_info_create (corlib ? "throw_corlib_exception" : (rethrow ? "rethrow_exception" : "throw_exception"), start, code - start, ji, unwind_ops); + *info = mono_tramp_info_create (corlib ? "throw_corlib_exception" : (rethrow ? "rethrow_preserve_exception" : (rethrow ? "rethrow_exception" : "throw_exception"), start, code - start, ji, unwind_ops); return start; } /** + * mono_arch_get_rethrow_preserve_exception: + * \returns a function pointer which can be used to rethrow + * exceptions and completely preserve trace_ips. + * The returned function has the following + * signature: void (*func) (MonoException *exc); + */ +gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + int size = MONO_PPC_32_64_CASE (132, 224) + PPC_FTNPTR_SIZE; + + if (aot) + size += 64; + return mono_arch_get_throw_exception_generic (size, info, FALSE, TRUE, aot, TRUE); +} + +/** * mono_arch_get_rethrow_exception: * \returns a function pointer which can be used to rethrow * exceptions. The returned function has the following @@ -467,7 +487,7 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) if (aot) size += 64; - return mono_arch_get_throw_exception_generic (size, info, FALSE, TRUE, aot); + return mono_arch_get_throw_exception_generic (size, info, FALSE, TRUE, aot, FALSE); } /** @@ -489,7 +509,7 @@ mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) if (aot) size += 64; - return mono_arch_get_throw_exception_generic (size, info, FALSE, FALSE, aot); + return mono_arch_get_throw_exception_generic (size, info, FALSE, FALSE, aot, FALSE); } /** @@ -506,7 +526,7 @@ mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) if (aot) size += 64; - return mono_arch_get_throw_exception_generic (size, info, TRUE, FALSE, aot); + return mono_arch_get_throw_exception_generic (size, info, TRUE, FALSE, aot, FALSE); } /* diff --git a/mono/mini/exceptions-s390x.c b/mono/mini/exceptions-s390x.c index 23fecb60d2e..38b30c792ec 100644 --- a/mono/mini/exceptions-s390x.c +++ b/mono/mini/exceptions-s390x.c @@ -27,7 +27,8 @@ #define S390_THROWSTACK_ACCPRM S390_MINIMAL_STACK_SIZE #define S390_THROWSTACK_FPCPRM (S390_THROWSTACK_ACCPRM+sizeof(gpointer)) -#define S390_THROWSTACK_RETHROW (S390_THROWSTACK_FPCPRM+sizeof(gulong)) +#define S390_THROWSTACK_PRESERVE_IPS (S390_THROWSTACK_FPCPRM+sizeof(gulong)) +#define S390_THROWSTACK_RETHROW (S390_THROWSTACK_PRESERVE_IPS+sizeof(gboolean)) #define S390_THROWSTACK_INTREGS (S390_THROWSTACK_RETHROW+sizeof(gboolean)) #define S390_THROWSTACK_FLTREGS (S390_THROWSTACK_INTREGS+(16*sizeof(gulong))) #define S390_THROWSTACK_ACCREGS (S390_THROWSTACK_FLTREGS+(16*sizeof(gdouble))) @@ -72,7 +73,7 @@ static void throw_exception (MonoObject *, unsigned long, unsigned long, gulong *, gdouble *, gint32 *, guint, gboolean); static gpointer mono_arch_get_throw_exception_generic (int, MonoTrampInfo **, - int, gboolean, gboolean); + int, gboolean, gboolean, gboolean); static void handle_signal_exception (gpointer); /*========================= End of Prototypes ======================*/ @@ -240,7 +241,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) static void throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp, gulong *int_regs, gdouble *fp_regs, gint32 *acc_regs, - guint fpc, gboolean rethrow) + guint fpc, gboolean rethrow, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; @@ -269,6 +270,8 @@ throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp, if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; + } else if (preserve_ips) { + mono_ex->catch_in_unmanaged = TRUE } } mono_error_assert_ok (error); @@ -295,7 +298,7 @@ throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp, static gpointer mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, - int corlib, gboolean rethrow, gboolean aot) + int corlib, gboolean rethrow, gboolean aot, gboolean preserve_ips) { guint8 *code, *start; int alloc_size, pos, i; @@ -358,6 +361,8 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, S390_SET (code, s390_r1, (guint8 *)throw_exception); s390_lghi (code, s390_r7, rethrow); s390_stg (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_RETHROW); + s390_lghi (code, s390_r7, preserve_ips); + s390_stg (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_PRESERVE_IPS); s390_basr (code, s390_r14, s390_r1); /* we should never reach this breakpoint */ s390_break (code); @@ -369,6 +374,7 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, if (info) *info = mono_tramp_info_create (corlib ? "throw_corlib_exception" : (rethrow ? "rethrow_exception" + : (preserve_ips ? "rethrow_preserve_exception" : "throw_exception"), start, code - start, ji, unwind_ops); @@ -396,7 +402,31 @@ mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) if (info) *info = NULL; - return (mono_arch_get_throw_exception_generic (SZ_THROW, info, FALSE, FALSE, aot)); + return (mono_arch_get_throw_exception_generic (SZ_THROW, info, FALSE, FALSE, aot, FALSE)); +} + +/*========================= End of Function ========================*/ + +/*------------------------------------------------------------------*/ +/* */ +/* Name - arch_get_rethrow_preserve_exception */ +/* */ +/* Function - Return a function pointer which can be used to */ +/* raise exceptions. This preserves the stored ips. */ +/* The returned function has the */ +/* following signature: */ +/* void (*func) (MonoException *exc); */ +/* */ +/*------------------------------------------------------------------*/ + +gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + g_assert (!aot); + if (info) + *info = NULL; + + return (mono_arch_get_throw_exception_generic (SZ_THROW, info, FALSE, TRUE, aot, TRUE)); } /*========================= End of Function ========================*/ @@ -419,7 +449,7 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) if (info) *info = NULL; - return (mono_arch_get_throw_exception_generic (SZ_THROW, info, FALSE, TRUE, aot)); + return (mono_arch_get_throw_exception_generic (SZ_THROW, info, FALSE, TRUE, aot, FALSE)); } /*========================= End of Function ========================*/ @@ -442,7 +472,7 @@ mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) if (info) *info = NULL; - return (mono_arch_get_throw_exception_generic (SZ_THROW, info, TRUE, FALSE, aot)); + return (mono_arch_get_throw_exception_generic (SZ_THROW, info, TRUE, FALSE, aot, FALSE)); } /*========================= End of Function ========================*/ diff --git a/mono/mini/exceptions-sparc.c b/mono/mini/exceptions-sparc.c index fbf7f73392f..4ce3906a648 100644 --- a/mono/mini/exceptions-sparc.c +++ b/mono/mini/exceptions-sparc.c @@ -167,7 +167,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) } static void -throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow) +throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; @@ -187,6 +187,8 @@ throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow) if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; + } else (preserve_ips) { + mono_ex->catch_in_unmanaged = NULL; } } mono_error_assert_ok (error); @@ -197,7 +199,7 @@ throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow) } static gpointer -get_throw_exception (gboolean rethrow) +get_throw_exception (gboolean rethrow, gboolean preserve_ips) { guint32 *start, *code; @@ -210,6 +212,7 @@ get_throw_exception (gboolean rethrow) sparc_mov_reg_reg (code, sparc_fp, sparc_o1); sparc_mov_reg_reg (code, sparc_i7, sparc_o2); sparc_set (code, rethrow, sparc_o3); + sparc_set (code, preserve_ips, sparc_o3); sparc_set (code, throw_exception, sparc_o7); sparc_jmpl (code, sparc_o7, sparc_g0, sparc_callsite); sparc_nop (code); @@ -243,7 +246,7 @@ mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) inited = 1; - start = get_throw_exception (FALSE); + start = get_throw_exception (FALSE, FALSE); return start; } @@ -263,7 +266,27 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) inited = 1; - start = get_throw_exception (TRUE); + start = get_throw_exception (TRUE, FALSE); + + return start; +} + +gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + static guint32* start; + static int inited = 0; + + g_assert (!aot); + if (info) + *info = NULL; + + if (inited) + return start; + + inited = 1; + + start = get_throw_exception (TRUE, TRUE); return start; } diff --git a/mono/mini/exceptions-wasm.c b/mono/mini/exceptions-wasm.c index 07abc7a10ee..c6d70a04e33 100644 --- a/mono/mini/exceptions-wasm.c +++ b/mono/mini/exceptions-wasm.c @@ -25,6 +25,12 @@ wasm_rethrow_exception (void) } static void +wasm_rethrow_preserve_exception (void) +{ + g_error ("wasm_rethrow_preserve_exception"); +} + +static void wasm_throw_corlib_exception (void) { g_error ("wasm_throw_corlib_exception"); @@ -81,6 +87,14 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) } gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + if (info) + *info = mono_tramp_info_create ("rethrow_preserve_exception", (guint8*)wasm_rethrow_preserve_exception, 1, NULL, NULL); + return (gpointer)wasm_rethrow_exception; +} + +gpointer mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { if (info) diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c index b2ffd3ff78d..4e2c88f2b12 100644 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -453,7 +453,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) */ void mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, - mgreg_t eip, gboolean rethrow) + mgreg_t eip, gboolean rethrow, gboolean preserve_ips) { ERROR_DECL (error); MonoContext ctx; @@ -478,6 +478,8 @@ mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, if (!rethrow) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; + } else if (preserve_ips) { + mono_ex->caught_in_unmanaged = TRUE; } } mono_error_assert_ok (error); @@ -506,7 +508,7 @@ mono_x86_throw_corlib_exception (mgreg_t *regs, guint32 ex_token_index, /* Negate the ip adjustment done in mono_x86_throw_exception () */ eip += 1; - mono_x86_throw_exception (regs, (MonoObject*)ex, eip, FALSE); + mono_x86_throw_exception (regs, (MonoObject*)ex, eip, FALSE, FALSE); } static void @@ -537,7 +539,7 @@ mono_x86_resume_unwind (mgreg_t *regs, MonoObject *exc, * which doesn't push the arguments. */ static guint8* -get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolean corlib, gboolean llvm_abs, gboolean resume_unwind, MonoTrampInfo **info, gboolean aot) +get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolean corlib, gboolean llvm_abs, gboolean resume_unwind, MonoTrampInfo **info, gboolean aot, gboolean preserve_ips) { guint8 *start, *code, *labels [16]; int i, stack_size, stack_offset, arg_offsets [5], regs_offset; @@ -575,7 +577,8 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea arg_offsets [1] = 4; arg_offsets [2] = 8; arg_offsets [3] = 12; - regs_offset = 16; + arg_offsets [4] = 16; + regs_offset = 20; /* Save registers */ for (i = 0; i < X86_NREG; ++i) @@ -651,6 +654,9 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea x86_mov_membase_reg (code, X86_ESP, arg_offsets [3], X86_EAX, 4); } else { x86_mov_membase_imm (code, X86_ESP, arg_offsets [3], rethrow, 4); + + /* Set arg4 == preserve_ips */ + x86_mov_membase_imm (code, X86_ESP, arg_offsets [4], preserve_ips, 4); } /* Make the call */ if (aot) { @@ -697,13 +703,19 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea gpointer mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline ("throw_exception", FALSE, FALSE, FALSE, FALSE, FALSE, info, aot); + return get_throw_trampoline ("throw_exception", FALSE, FALSE, FALSE, FALSE, FALSE, info, aot, FALSE); } gpointer mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline ("rethrow_exception", TRUE, FALSE, FALSE, FALSE, FALSE, info, aot); + return get_throw_trampoline ("rethrow_exception", TRUE, FALSE, FALSE, FALSE, FALSE, info, aot, FALSE); +} + +gpointer +mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) +{ + return get_throw_trampoline ("rethrow_preserve_exception", TRUE, FALSE, FALSE, FALSE, FALSE, info, aot, TRUE); } /** @@ -718,7 +730,7 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) gpointer mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { - return get_throw_trampoline ("throw_corlib_exception", FALSE, FALSE, TRUE, FALSE, FALSE, info, aot); + return get_throw_trampoline ("throw_corlib_exception", FALSE, FALSE, TRUE, FALSE, FALSE, info, aot, FALSE); } void @@ -755,23 +767,23 @@ mono_arch_exceptions_init (void) } /* LLVM needs different throw trampolines */ - tramp = get_throw_trampoline ("llvm_throw_exception_trampoline", FALSE, TRUE, FALSE, FALSE, FALSE, &tinfo, FALSE); + tramp = get_throw_trampoline ("llvm_throw_exception_trampoline", FALSE, TRUE, FALSE, FALSE, FALSE, &tinfo, FALSE, FALSE); mono_register_jit_icall (tramp, "llvm_throw_exception_trampoline", NULL, TRUE); mono_tramp_info_register (tinfo, NULL); - tramp = get_throw_trampoline ("llvm_rethrow_exception_trampoline", TRUE, TRUE, FALSE, FALSE, FALSE, &tinfo, FALSE); + tramp = get_throw_trampoline ("llvm_rethrow_exception_trampoline", TRUE, TRUE, FALSE, FALSE, FALSE, &tinfo, FALSE, FALSE); mono_register_jit_icall (tramp, "llvm_rethrow_exception_trampoline", NULL, TRUE); mono_tramp_info_register (tinfo, NULL); - tramp = get_throw_trampoline ("llvm_throw_corlib_exception_trampoline", FALSE, TRUE, TRUE, FALSE, FALSE, &tinfo, FALSE); + tramp = get_throw_trampoline ("llvm_throw_corlib_exception_trampoline", FALSE, TRUE, TRUE, FALSE, FALSE, &tinfo, FALSE, FALSE); mono_register_jit_icall (tramp, "llvm_throw_corlib_exception_trampoline", NULL, TRUE); mono_tramp_info_register (tinfo, NULL); - tramp = get_throw_trampoline ("llvm_throw_corlib_exception_abs_trampoline", FALSE, TRUE, TRUE, TRUE, FALSE, &tinfo, FALSE); + tramp = get_throw_trampoline ("llvm_throw_corlib_exception_abs_trampoline", FALSE, TRUE, TRUE, TRUE, FALSE, &tinfo, FALSE, FALSE); mono_register_jit_icall (tramp, "llvm_throw_corlib_exception_abs_trampoline", NULL, TRUE); mono_tramp_info_register (tinfo, NULL); - tramp = get_throw_trampoline ("llvm_resume_unwind_trampoline", FALSE, FALSE, FALSE, FALSE, TRUE, &tinfo, FALSE); + tramp = get_throw_trampoline ("llvm_resume_unwind_trampoline", FALSE, FALSE, FALSE, FALSE, TRUE, &tinfo, FALSE, FALSE); mono_register_jit_icall (tramp, "llvm_resume_unwind_trampoline", NULL, TRUE); mono_tramp_info_register (tinfo, NULL); diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h index 42c9360a54e..71e276f6216 100644 --- a/mono/mini/mini-amd64.h +++ b/mono/mini/mini-amd64.h @@ -501,7 +501,7 @@ mono_amd64_patch (unsigned char* code, gpointer target); void mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4, guint64 dummy5, guint64 dummy6, - MonoContext *mctx, MonoObject *exc, gboolean rethrow); + MonoContext *mctx, MonoObject *exc, gboolean rethrow, gboolean preserve_ips); void mono_amd64_throw_corlib_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guint64 dummy4, diff --git a/mono/mini/mini-arm.h b/mono/mini/mini-arm.h index 344659c43a2..e851d6d11b5 100644 --- a/mono/mini/mini-arm.h +++ b/mono/mini/mini-arm.h @@ -397,7 +397,7 @@ typedef struct MonoCompileArch { #define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) void -mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs); +mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs, gboolean preserve_ips); void mono_arm_throw_exception_by_token (guint32 type_token, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs); diff --git a/mono/mini/mini-arm64.h b/mono/mini/mini-arm64.h index 36fba6467eb..f1c7c2e52a4 100644 --- a/mono/mini/mini-arm64.h +++ b/mono/mini/mini-arm64.h @@ -258,7 +258,7 @@ guint8* mono_arm_emit_aotconst (gpointer ji, guint8 *code, guint8 *code_start, i void mono_arm_patch (guint8 *code, guint8 *target, int relocation); -void mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow); +void mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow, gboolean preserve_ips); void mono_arm_gsharedvt_init (void); diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index da8044c62d5..40df4b3e09a 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -114,7 +114,7 @@ typedef struct #define TRACE_IP_ENTRY_SIZE (sizeof (ExceptionTraceIp) / sizeof (gpointer)) static gpointer restore_context_func, call_filter_func; -static gpointer throw_exception_func, rethrow_exception_func; +static gpointer throw_exception_func, rethrow_exception_func, rethrow_preserve_exception_func; static gpointer throw_corlib_exception_func; static MonoFtnPtrEHCallback ftnptr_eh_callback; @@ -216,6 +216,7 @@ mono_exceptions_init (void) call_filter_func = mono_aot_get_trampoline ("call_filter"); throw_exception_func = mono_aot_get_trampoline ("throw_exception"); rethrow_exception_func = mono_aot_get_trampoline ("rethrow_exception"); + rethrow_preserve_exception_func = mono_aot_get_trampoline ("rethrow_preserve_exception"); } else { MonoTrampInfo *info; @@ -227,6 +228,8 @@ mono_exceptions_init (void) mono_tramp_info_register (info, NULL); rethrow_exception_func = mono_arch_get_rethrow_exception (&info, FALSE); mono_tramp_info_register (info, NULL); + rethrow_preserve_exception_func = mono_arch_get_rethrow_preserve_exception (&info, FALSE); + mono_tramp_info_register (info, NULL); } mono_arch_exceptions_init (); @@ -269,6 +272,13 @@ mono_get_rethrow_exception (void) } gpointer +mono_get_rethrow_preserve_exception (void) +{ + g_assert (rethrow_preserve_exception_func); + return rethrow_preserve_exception_func; +} + +gpointer mono_get_call_filter (void) { g_assert (call_filter_func); @@ -319,9 +329,9 @@ mono_get_throw_exception_addr (void) } gpointer -mono_get_rethrow_exception_addr (void) +mono_get_rethrow_preserve_exception_addr (void) { - return &rethrow_exception_func; + return &rethrow_preserve_exception_func; } static gboolean diff --git a/mono/mini/mini-ppc.h b/mono/mini/mini-ppc.h index 8308387e8c9..47de3b525c8 100644 --- a/mono/mini/mini-ppc.h +++ b/mono/mini/mini-ppc.h @@ -384,7 +384,7 @@ void mono_ppc_patch (guchar *code, const guchar *target); void -mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, mgreg_t *int_regs, gdouble *fp_regs, gboolean rethrow); +mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, mgreg_t *int_regs, gdouble *fp_regs, gboolean rethrow, gboolean preserve_ips); #ifdef __mono_ppc64__ #define MONO_PPC_32_64_CASE(c32,c64) c64 diff --git a/mono/mini/mini-x86.h b/mono/mini/mini-x86.h index 33e2528553f..23d20b0f1a5 100644 --- a/mono/mini/mini-x86.h +++ b/mono/mini/mini-x86.h @@ -330,7 +330,7 @@ mono_x86_get_this_arg_offset (MonoMethodSignature *sig); void mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc, - mgreg_t eip, gboolean rethrow); + mgreg_t eip, gboolean rethrow, gboolean preserve_ips); void mono_x86_throw_corlib_exception (mgreg_t *regs, guint32 ex_token_index, diff --git a/mono/mini/mini.h b/mono/mini/mini.h index a994909d06a..1b8f52f49fb 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -2350,6 +2350,7 @@ gpointer mono_arch_get_call_filter (MonoTrampInfo **info, gboolean gpointer mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot); gpointer mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot); gpointer mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot); +gpointer mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot); gpointer mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot); gpointer mono_arch_get_throw_pending_exception (MonoTrampInfo **info, gboolean aot); gboolean mono_arch_handle_exception (void *sigctx, gpointer obj); @@ -2461,12 +2462,13 @@ mono_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls, gpointer mono_get_throw_exception (void); gpointer mono_get_rethrow_exception (void); +gpointer mono_get_rethrow_preserve_exception (void); gpointer mono_get_call_filter (void); gpointer mono_get_restore_context (void); gpointer mono_get_throw_exception_by_name (void); gpointer mono_get_throw_corlib_exception (void); gpointer mono_get_throw_exception_addr (void); -gpointer mono_get_rethrow_exception_addr (void); +gpointer mono_get_rethrow_preserve_exception_addr (void); ICALL_EXPORT MonoArray *ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info); diff --git a/mono/mini/tramp-amd64.c b/mono/mini/tramp-amd64.c index c90c4e73f4e..002a4f7ed81 100644 --- a/mono/mini/tramp-amd64.c +++ b/mono/mini/tramp-amd64.c @@ -520,9 +520,9 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf */ if (aot) { /* Not really a jit icall */ - code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "rethrow_exception_addr"); + code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "rethrow_preserve_exception_addr"); } else { - amd64_mov_reg_imm (code, AMD64_R11, (guint8*)mono_get_rethrow_exception_addr ()); + amd64_mov_reg_imm (code, AMD64_R11, (guint8*)mono_get_rethrow_preserve_exception_addr ()); } amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0, sizeof(gpointer)); amd64_mov_reg_reg (code, AMD64_ARG_REG1, AMD64_RAX, sizeof(mgreg_t)); diff --git a/mono/mini/tramp-arm.c b/mono/mini/tramp-arm.c index d6b72d378fe..fa53a53a924 100644 --- a/mono/mini/tramp-arm.c +++ b/mono/mini/tramp-arm.c @@ -416,11 +416,11 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf */ if (aot) { /* Not really a jit icall */ - code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP, MONO_PATCH_INFO_JIT_ICALL_ADDR, "rethrow_exception_addr"); + code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP, MONO_PATCH_INFO_JIT_ICALL_ADDR, "rethrow_preserve_exception_addr"); } else { ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0); ARM_B (code, 0); - *(gpointer*)code = mono_get_rethrow_exception_addr (); + *(gpointer*)code = mono_get_rethrow_preserve_exception_addr (); code += 4; } ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, 0); diff --git a/mono/mini/tramp-arm64.c b/mono/mini/tramp-arm64.c index 1bf6e7cd79a..d4c9606e9ad 100644 --- a/mono/mini/tramp-arm64.c +++ b/mono/mini/tramp-arm64.c @@ -303,9 +303,9 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf */ if (aot) { /* Not really a jit icall */ - code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, "rethrow_exception_addr"); + code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, "rethrow_preserve_exception_addr"); } else { - code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)mono_get_rethrow_exception_addr ()); + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)mono_get_rethrow_preserve_exception_addr ()); } arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0); /* lr contains the return address, the trampoline will use it as the throw site */ diff --git a/mono/mini/tramp-ppc.c b/mono/mini/tramp-ppc.c index abbf65a82e3..a12e04fc636 100644 --- a/mono/mini/tramp-ppc.c +++ b/mono/mini/tramp-ppc.c @@ -424,7 +424,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf if (aot) { g_error ("Not implemented"); } else { - ppc_load_func (code, PPC_CALL_REG, mono_get_rethrow_exception_addr ()); + ppc_load_func (code, PPC_CALL_REG, mono_get_rethrow_preserve_exception_addr ()); ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtctr (code, PPC_CALL_REG); } diff --git a/mono/mini/tramp-s390x.c b/mono/mini/tramp-s390x.c index b70cae7d099..166b63c1b65 100644 --- a/mono/mini/tramp-s390x.c +++ b/mono/mini/tramp-s390x.c @@ -330,7 +330,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf * We have an exception we want to throw in the caller's frame, so pop * the trampoline frame and throw from the caller. */ - S390_SET (buf, s390_r1, (guint *)mono_get_rethrow_exception_addr ()); + S390_SET (buf, s390_r1, (guint *)mono_get_rethrow_preserve_exception_addr ()); s390_aghi (buf, STK_BASE, sizeof(trampStack_t)); s390_lg (buf, s390_r1, 0, s390_r1, 0); s390_lmg (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET); diff --git a/mono/mini/tramp-x86.c b/mono/mini/tramp-x86.c index 95e2d12c1f5..7a87ba67e31 100644 --- a/mono/mini/tramp-x86.c +++ b/mono/mini/tramp-x86.c @@ -343,9 +343,9 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf */ if (aot) { /* Not really a jit icall */ - code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "rethrow_exception_addr"); + code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "rethrow_preserve_exception_addr"); } else { - x86_mov_reg_imm (code, X86_ECX, (guint8*)mono_get_rethrow_exception_addr ()); + x86_mov_reg_imm (code, X86_ECX, (guint8*)mono_get_rethrow_preserve_exception_addr ()); } x86_mov_reg_membase (code, X86_ECX, X86_ECX, 0, sizeof(target_mgreg_t)); x86_jump_reg (code, X86_ECX); |