From d743c659c506199c2e4e9414b4121e0a8841ee81 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Mon, 30 May 2016 03:40:56 -0400 Subject: [PATCH] [jit] Emit code to throw method access exceptions instead of throwing them from the JIT, so the stack trace is correct. Fixes #41280. (#3072) --- mono/mini/jit-icalls.c | 14 ++++++++++++++ mono/mini/jit-icalls.h | 2 ++ mono/mini/method-to-ir.c | 31 ++++++++++++++----------------- mono/mini/mini-runtime.c | 1 + 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index eea343db4a7..39abeb28549 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -1869,3 +1869,17 @@ mono_interruption_checkpoint_from_trampoline (void) if (ex) mono_raise_exception (ex); } + +void +mono_throw_method_access (MonoMethod *callee, MonoMethod *caller) +{ + char *callee_name = mono_method_full_name (callee, 1); + char *caller_name = mono_method_full_name (caller, 1); + MonoError error; + + mono_error_init (&error); + mono_error_set_generic_error (&error, "System", "MethodAccessException", "Method `%s' is inaccessible from method `%s'\n", callee_name, caller_name); + mono_error_set_pending_exception (&error); + g_free (callee_name); + g_free (caller_name); +} diff --git a/mono/mini/jit-icalls.h b/mono/mini/jit-icalls.h index 8e2b37d3676..319ec902a01 100644 --- a/mono/mini/jit-icalls.h +++ b/mono/mini/jit-icalls.h @@ -224,4 +224,6 @@ MonoObject* mono_get_method_object (MonoMethod *method); double mono_ckfinite (double d); +void mono_throw_method_access (MonoMethod *callee, MonoMethod *caller); + #endif /* __MONO_JIT_ICALLS_H__ */ diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 8758d4e89af..ec4e6f429e4 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -90,10 +90,6 @@ if (cfg->exception_type != MONO_EXCEPTION_NONE) \ goto exception_exit; \ } while (0) -#define METHOD_ACCESS_FAILURE(method, cmethod) do { \ - method_access_failure ((cfg), (method), (cmethod)); \ - goto exception_exit; \ - } while (0) #define FIELD_ACCESS_FAILURE(method, field) do { \ field_access_failure ((cfg), (method), (field)); \ goto exception_exit; \ @@ -377,17 +373,6 @@ break_on_unverified (void) G_BREAKPOINT (); } -static MONO_NEVER_INLINE void -method_access_failure (MonoCompile *cfg, MonoMethod *method, MonoMethod *cil_method) -{ - char *method_fname = mono_method_full_name (method, TRUE); - char *cil_method_fname = mono_method_full_name (cil_method, TRUE); - mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR); - mono_error_set_generic_error (&cfg->error, "System", "MethodAccessException", "Method `%s' is inaccessible from method `%s'\n", cil_method_fname, method_fname); - g_free (method_fname); - g_free (cil_method_fname); -} - static MONO_NEVER_INLINE void field_access_failure (MonoCompile *cfg, MonoMethod *method, MonoClassField *field) { @@ -3156,6 +3141,18 @@ mono_emit_widen_call_res (MonoCompile *cfg, MonoInst *ins, MonoMethodSignature * return ins; } + +static void +emit_method_access_failure (MonoCompile *cfg, MonoMethod *method, MonoMethod *cil_method) +{ + MonoInst *args [16]; + + args [0] = emit_get_rgctx_method (cfg, mono_method_check_context_used (method), method, MONO_RGCTX_INFO_METHOD); + args [1] = emit_get_rgctx_method (cfg, mono_method_check_context_used (cil_method), cil_method, MONO_RGCTX_INFO_METHOD); + + mono_emit_jit_icall (cfg, mono_throw_method_access, args); +} + static MonoMethod* get_memcpy_method (void) { @@ -9269,7 +9266,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } if (!mono_method_can_access_method (method_definition, target_method) && !mono_method_can_access_method (method, cil_method)) - METHOD_ACCESS_FAILURE (method, cil_method); + emit_method_access_failure (cfg, method, cil_method); } if (mono_security_core_clr_enabled ()) @@ -13080,7 +13077,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b cil_method = cmethod; if (!dont_verify && !cfg->skip_visibility && !mono_method_can_access_method (method, cmethod)) - METHOD_ACCESS_FAILURE (method, cil_method); + emit_method_access_failure (cfg, method, cil_method); if (mono_security_core_clr_enabled ()) ensure_method_is_allowed_to_call_method (cfg, method, cmethod); diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index b1cb79734d5..9bb896ee4ee 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -3951,6 +3951,7 @@ register_icalls (void) register_icall (mono_llvmonly_init_delegate_virtual, "mono_llvmonly_init_delegate_virtual", "void object object ptr", TRUE); register_icall (mono_get_assembly_object, "mono_get_assembly_object", "object ptr", TRUE); register_icall (mono_get_method_object, "mono_get_method_object", "object ptr", TRUE); + register_icall (mono_throw_method_access, "mono_throw_method_access", "void ptr ptr", FALSE); register_icall_with_wrapper (mono_monitor_enter, "mono_monitor_enter", "void obj"); register_icall_with_wrapper (mono_monitor_enter_v4, "mono_monitor_enter_v4", "void obj ptr"); -- 2.25.1