Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kyte <alkyte@microsoft.com>2018-10-02 20:19:00 +0300
committerAlexander Kyte <alkyte@microsoft.com>2018-10-04 00:11:04 +0300
commite46fa20466010a18b9b9a8130f6d8c62899780b3 (patch)
tree4df531b790829c84ae31bd266560a98d788d0590
parent52a9b776eae9908e2a1f797b335122157914bca4 (diff)
[crash] Fix trampoline rethrows to set caught_in_unmanaged
-rw-r--r--mono/mini/aot-compiler.c4
-rw-r--r--mono/mini/aot-runtime.c8
-rw-r--r--mono/mini/exceptions-amd64.c37
-rw-r--r--mono/mini/exceptions-arm.c49
-rw-r--r--mono/mini/exceptions-arm64.c29
-rw-r--r--mono/mini/exceptions-mips.c36
-rw-r--r--mono/mini/exceptions-ppc.c32
-rw-r--r--mono/mini/exceptions-s390x.c44
-rw-r--r--mono/mini/exceptions-sparc.c31
-rw-r--r--mono/mini/exceptions-wasm.c14
-rw-r--r--mono/mini/exceptions-x86.c36
-rw-r--r--mono/mini/mini-amd64.h2
-rw-r--r--mono/mini/mini-arm.h2
-rw-r--r--mono/mini/mini-arm64.h2
-rw-r--r--mono/mini/mini-exceptions.c16
-rw-r--r--mono/mini/mini-ppc.h2
-rw-r--r--mono/mini/mini-x86.h2
-rw-r--r--mono/mini/mini.h4
-rw-r--r--mono/mini/tramp-amd64.c4
-rw-r--r--mono/mini/tramp-arm.c4
-rw-r--r--mono/mini/tramp-arm64.c4
-rw-r--r--mono/mini/tramp-ppc.c2
-rw-r--r--mono/mini/tramp-s390x.c2
-rw-r--r--mono/mini/tramp-x86.c4
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);