Merge pull request #2767 from lambdageek/dev/monoerror-mono_lookup_dynamic_token
authormonojenkins <jo.shields+jenkins@xamarin.com>
Tue, 29 Mar 2016 15:15:20 +0000 (16:15 +0100)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Tue, 29 Mar 2016 15:15:20 +0000 (16:15 +0100)
[runtime] MonoError-ize mono_loookup_dynamic_token{,_class}

Push `MonoError` through `mono_lookup_dynamic_token_class` and `mono_lookup_dynamic_token`

Also simplify the implementations of those functions so that they call `mono_reflection_lookup_dynamic_token` directly, rather than via a function pointer.  The old implementation was a holdover from when the runtime was implemented as separate libraries.

17 files changed:
external/referencesource
mcs/build/gensources.sh
mcs/class/System.Web/System.Web.Handlers/AssemblyResourceLoader.cs
mcs/class/System/System.Diagnostics/DefaultTraceListener.cs
mono/metadata/marshal.c
mono/metadata/sgen-client-mono.h
mono/metadata/sgen-new-bridge.c
mono/metadata/sgen-old-bridge.c
mono/mini/exceptions-amd64.c
mono/mini/exceptions-arm.c
mono/mini/exceptions-ia64.c
mono/mini/exceptions-ppc.c
mono/mini/mini-arm.c
mono/mini/mini-llvm.c
mono/mini/unwind.c
mono/sgen/sgen-gc.c
mono/utils/mono-signal-handler.h

index df1c00441047e7cc439608aa1aa083f585f5ace0..6c6e36218c4a0b6dfb85bd27fa6746467761e8a0 160000 (submodule)
@@ -1 +1 @@
-Subproject commit df1c00441047e7cc439608aa1aa083f585f5ace0
+Subproject commit 6c6e36218c4a0b6dfb85bd27fa6746467761e8a0
index 2eb4995bdd80c6569867178350c70fdaad71a2b6..14a0a01db59d07b4503b9a5d1ae8882e25442524 100644 (file)
@@ -43,7 +43,7 @@ sort -u $outfile.inc > $outfile.inc_s
 rm -f $outfile.inc
 
 
-if test -n "$excfile"; then
+if test -n "$excfile" -a -f "$excfile"; then
     process_includes $excfile $outfile.exc
 fi
 
index a8cd2f842cb2d887242b5e8292085c3e6410e5e2..7f59b52e22b47f90653406803db3f8ef8acc6c08 100644 (file)
@@ -79,7 +79,9 @@ namespace System.Web.Handlers
                                        if (!hashAlg.CanReuseTransform) {
                                                canReuseHashAlg = false;
                                                hashAlg = null;
+                                               return null;
                                        }
+                                       hashAlg.Key = MachineKeySectionUtils.GetValidationKey (mks);
                                }
 
                                if (hashAlg != null)
index 2bf4cab23c6e5641bcf5c351a09c2c7444058b10..fb31ace627b679a46f3b9eece4154858108a0c14 100644 (file)
@@ -255,10 +255,10 @@ namespace System.Diagnostics {
                                WritePrefix ();
                        }
 
-                       WriteDebugString (message);
-
                        if (Debugger.IsLogging())
                                Debugger.Log (0, null, message);
+                       else
+                               WriteDebugString (message);
 
                        WriteLogFile (message, LogFileName);
                }
index 675bd2c7129bb462c89b689ef9843085a318e8c7..9b7eca1ffce41cca0086710387a74c9d10f9157c 100644 (file)
@@ -211,11 +211,11 @@ init_safe_handle ()
 }
 
 static void
-register_icall (gpointer func, const char *name, const char *sigstr, gboolean save)
+register_icall (gpointer func, const char *name, const char *sigstr, gboolean no_wrapper)
 {
        MonoMethodSignature *sig = mono_create_icall_signature (sigstr);
 
-       mono_register_jit_icall (func, name, sig, save);
+       mono_register_jit_icall (func, name, sig, no_wrapper);
 }
 
 MonoMethodSignature*
index fd36c3941eeee0e0f2bc1ba44f3b1acc3b8d97b2..d0eaa26e14e014df49aa86ef63fa043d644d896e 100644 (file)
@@ -731,7 +731,7 @@ extern MonoNativeTlsKey thread_info_key;
 
 #define SGEN_TV_DECLARE(name) gint64 name
 #define SGEN_TV_GETTIME(tv) tv = mono_100ns_ticks ()
-#define SGEN_TV_ELAPSED(start,end) ((long)(end-start))
+#define SGEN_TV_ELAPSED(start,end) ((gint64)(end-start))
 
 typedef MonoSemType SgenSemaphore;
 
index 20fdb460adde86c416d941f2625f335516b3e1bb..a4f05e63ac954da9942505ad65d012ef0ec6d861 100644 (file)
@@ -968,7 +968,7 @@ compare_hash_entries (const HashEntry *e1, const HashEntry *e2)
 
 DEF_QSORT_INLINE(hash_entries, HashEntry*, compare_hash_entries)
 
-static unsigned long step_1, step_2, step_3, step_4, step_5, step_6;
+static gint64 step_1, step_2, step_3, step_4, step_5, step_6;
 static int fist_pass_links, second_pass_links, sccs_links;
 static int max_sccs_links = 0;
 
index 83f991d5b867ce64bd230021fe7a96381fc09158..f8437fe4810ccb775aa0858ddc85bce4e30207ce 100644 (file)
@@ -616,7 +616,7 @@ compare_hash_entries (const HashEntry *e1, const HashEntry *e2)
 
 DEF_QSORT_INLINE(hash_entries, HashEntry*, compare_hash_entries)
 
-static unsigned long step_1, step_2, step_3, step_4, step_5, step_6;
+static gint64 step_1, step_2, step_3, step_4, step_5, step_6;
 static int fist_pass_links, second_pass_links, sccs_links;
 static int max_sccs_links = 0;
 
index 9ec2caa843208d23fdba7cd08592078886829602..cab03fc0f2eae39d21165e0a02250a666d7cbd79 100644 (file)
@@ -417,10 +417,7 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g
        amd64_lea_membase (code, AMD64_RAX, AMD64_RSP, stack_size + sizeof(mgreg_t));
        amd64_mov_membase_reg (code, AMD64_RSP, regs_offset + (AMD64_RSP * sizeof(mgreg_t)), X86_EAX, sizeof(mgreg_t));
        /* Save IP */
-       if (llvm_abs)
-               amd64_alu_reg_reg (code, X86_XOR, AMD64_RAX, AMD64_RAX);
-       else
-               amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, stack_size, sizeof(mgreg_t));
+       amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, stack_size, sizeof(mgreg_t));
        amd64_mov_membase_reg (code, AMD64_RSP, regs_offset + (AMD64_RIP * sizeof(mgreg_t)), AMD64_RAX, sizeof(mgreg_t));
        /* Set arg1 == ctx */
        amd64_lea_membase (code, AMD64_RAX, AMD64_RSP, ctx_offset);
@@ -434,14 +431,14 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g
        if (resume_unwind) {
                amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], 0, sizeof(mgreg_t));
        } else if (corlib) {
-               amd64_mov_membase_reg (code, AMD64_RSP, arg_offsets [2], AMD64_ARG_REG2, sizeof(mgreg_t));
                if (llvm_abs)
-                       /* 
-                        * The caller is LLVM code which passes the absolute address not a pc offset,
-                        * so compensate by passing 0 as 'rip' and passing the negated abs address as
-                        * the pc offset.
+                       /*
+                        * The caller doesn't pass in a pc/pc offset, instead we simply use the
+                        * caller ip. Negate the pc adjustment done in mono_amd64_throw_corlib_exception ().
                         */
-                       amd64_neg_membase (code, AMD64_RSP, arg_offsets [2]);
+                       amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], 1, sizeof(mgreg_t));
+               else
+                       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));
        }
index 366e086c8b3fe5e225d67979e8ec53eccb55e0bd..4c2b5ce821db200b5cbb1765ac463eb54cde8463 100644 (file)
@@ -167,12 +167,13 @@ mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_
 }
 
 void
-mono_arm_throw_exception_by_token (guint32 type_token, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs)
+mono_arm_throw_exception_by_token (guint32 ex_token_index, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs)
 {
+       guint32 ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index;
        /* Clear thumb bit */
        pc &= ~1;
 
-       mono_arm_throw_exception ((MonoObject*)mono_exception_from_token (mono_defaults.corlib, type_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);
 }
 
 void
@@ -247,9 +248,15 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm
        /* exc is already in place in r0 */
        if (corlib) {
                /* The caller ip is already in R1 */
-               if (llvm)
-                       /* Negate the ip adjustment done in mono_arm_throw_exception */
-                       ARM_ADD_REG_IMM8 (code, ARMREG_R1, ARMREG_R1, 4);
+               if (llvm) {
+                       /*
+                        * The address passed by llvm might point to before the call,
+                        * thus outside the eh range recorded by llvm. Use the return
+                        * address instead.
+                        * FIXME: Do this on more platforms.
+                        */
+                       ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_LR); /* caller ip */
+               }
        } else {
                ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_LR); /* caller ip */
        }
index 2f5324c69e7b75453b360a70c0e4a2d2305552f8..adae20f2b5f2fb83a57d67b3b08b30a77f007483 100644 (file)
@@ -242,7 +242,7 @@ throw_exception (MonoObject *exc, guint64 rethrow)
        unw_word_t ip, sp;
        int res;
 
-       if (mono_object_isinst (exc, mono_defaults.exception_class, &error)) {
+       if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
                MonoException *mono_ex = (MonoException*)exc;
                if (!rethrow) {
                        mono_ex->stack_trace = NULL;
index df828692ac3289c5ec99ffc57fe4c9255c67cede..80a579b05eb87e539e3b1c344edf636991b4c667 100644 (file)
@@ -332,7 +332,7 @@ mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp,
        memcpy (&ctx.regs, int_regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
        memcpy (&ctx.fregs, fp_regs, sizeof (double) * MONO_SAVED_FREGS);
 
-       if (mono_object_isinst (exc, mono_defaults.exception_class, &error)) {
+       if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
                MonoException *mono_ex = (MonoException*)exc;
                if (!rethrow) {
                        mono_ex->stack_trace = NULL;
index c584d6c8b4249fc36ef7ddd76f8762dab64367e5..a7df6fc1c1b282990ba87401cf50423291a546f0 100644 (file)
@@ -6827,7 +6827,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
                        patch_info->ip.i = code - cfg->native_code;
                        ARM_BL (code, 0);
                        cfg->thunk_area += THUNK_SIZE;
-                       *(guint32*)(gpointer)code = exc_class->type_token;
+                       *(guint32*)(gpointer)code = exc_class->type_token - MONO_TOKEN_TYPE_DEF;
                        code += 4;
 #endif
                        break;
index 558db05357e9a8a6085d952badbdbb1b470e6339..f8aa239061589f9c9092ff6b246e76eecfa98591 100644 (file)
@@ -2068,6 +2068,11 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
        MonoClass *exc_class;
        LLVMValueRef args [2];
        LLVMValueRef callee;
+       gboolean no_pc = FALSE;
+
+       if (IS_TARGET_AMD64)
+               /* Some platforms don't require the pc argument */
+               no_pc = TRUE;
        
        ex_bb = gen_bb (ctx, "EX_BB");
        if (ctx->llvm_only)
@@ -2112,7 +2117,10 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
                LLVMTypeRef sig;
                const char *icall_name;
 
-               sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
+               if (no_pc)
+                       sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
+               else
+                       sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
                icall_name = "llvm_throw_corlib_exception_abs_trampoline";
 
                if (ctx->cfg->compile_aot) {
@@ -2144,17 +2152,18 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
                }
        }
 
-       if (IS_TARGET_X86 || IS_TARGET_AMD64)
-               args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
-       else
-               args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
+       args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
 
        /*
         * The LLVM mono branch contains changes so a block address can be passed as an
         * argument to a call.
         */
-       args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
-       emit_call (ctx, bb, &builder, callee, args, 2);
+       if (no_pc) {
+               emit_call (ctx, bb, &builder, callee, args, 1);
+       } else {
+               args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
+               emit_call (ctx, bb, &builder, callee, args, 2);
+       }
 
        LLVMBuildUnreachable (builder);
 
index 82f14d7882255940ad311339fbe8c50073075a1b..ef3c65a7f225790813dfa5ab71f9a5e11b8c8ed4 100644 (file)
@@ -652,8 +652,12 @@ mono_unwind_cleanup (void)
 
                g_free (cached);
        }
-
        g_free (cached_info);
+
+       for (GSList *cursor = cached_info_list; cursor != NULL; cursor = cursor->next)
+               g_free (cursor->data);
+
+       g_slist_free (cached_info_list);
 }
 
 /*
@@ -708,10 +712,10 @@ mono_cache_unwind_info (guint8 *unwind_info, guint32 unwind_info_len)
 
                mono_memory_barrier ();
 
-               cached_info = new_table;
-
                cached_info_list = g_slist_prepend (cached_info_list, cached_info);
 
+               cached_info = new_table;
+
                cached_info_size *= 2;
        }
 
index e4d787a8bc85eb4c2f5867db98e062a0acd2f075..b91a9f4394884ed873958efc931b1d57aee7c1a8 100644 (file)
@@ -1169,7 +1169,7 @@ finish_gray_stack (int generation, ScanCopyContext ctx)
        sgen_client_clear_togglerefs (start_addr, end_addr, ctx);
 
        TV_GETTIME (btv);
-       SGEN_LOG (2, "Finalize queue handling scan for %s generation: %ld usecs %d ephemeron rounds", generation_name (generation), TV_ELAPSED (atv, btv), ephemeron_rounds);
+       SGEN_LOG (2, "Finalize queue handling scan for %s generation: %lld usecs %d ephemeron rounds", generation_name (generation), TV_ELAPSED (atv, btv), ephemeron_rounds);
 
        /*
         * handle disappearing links
@@ -1561,7 +1561,7 @@ collect_nursery (SgenGrayQueue *unpin_queue, gboolean finish_up_concurrent_mark)
 
        TV_GETTIME (atv);
        time_minor_pinning += TV_ELAPSED (btv, atv);
-       SGEN_LOG (2, "Finding pinned pointers: %zd in %ld usecs", sgen_get_pinned_count (), TV_ELAPSED (btv, atv));
+       SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), TV_ELAPSED (btv, atv));
        SGEN_LOG (4, "Start scan with %zd pinned objects", sgen_get_pinned_count ());
 
        sj = (ScanJob*)sgen_thread_pool_job_alloc ("scan remset", job_remembered_set_scan, sizeof (ScanJob));
@@ -1571,7 +1571,7 @@ collect_nursery (SgenGrayQueue *unpin_queue, gboolean finish_up_concurrent_mark)
        /* we don't have complete write barrier yet, so we scan all the old generation sections */
        TV_GETTIME (btv);
        time_minor_scan_remsets += TV_ELAPSED (atv, btv);
-       SGEN_LOG (2, "Old generation scan: %ld usecs", TV_ELAPSED (atv, btv));
+       SGEN_LOG (2, "Old generation scan: %lld usecs", TV_ELAPSED (atv, btv));
 
        sgen_pin_stats_print_class_stats ();
 
@@ -1612,7 +1612,7 @@ collect_nursery (SgenGrayQueue *unpin_queue, gboolean finish_up_concurrent_mark)
        sgen_client_binary_protocol_reclaim_end (GENERATION_NURSERY);
        TV_GETTIME (btv);
        time_minor_fragment_creation += TV_ELAPSED (atv, btv);
-       SGEN_LOG (2, "Fragment creation: %ld usecs, %lu bytes available", TV_ELAPSED (atv, btv), (unsigned long)fragment_total);
+       SGEN_LOG (2, "Fragment creation: %lld usecs, %lu bytes available", TV_ELAPSED (atv, btv), (unsigned long)fragment_total);
 
        if (consistency_check_at_minor_collection)
                sgen_check_major_refs ();
@@ -1777,7 +1777,7 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
 
        TV_GETTIME (btv);
        time_major_pinning += TV_ELAPSED (atv, btv);
-       SGEN_LOG (2, "Finding pinned pointers: %zd in %ld usecs", sgen_get_pinned_count (), TV_ELAPSED (atv, btv));
+       SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), TV_ELAPSED (atv, btv));
        SGEN_LOG (4, "Start scan with %zd pinned objects", sgen_get_pinned_count ());
 
        major_collector.init_to_space ();
index fbe798eeb0e6321667023429bfc88b4cb65bb1ce..94335964cd08a58b4c50f791f171ef2b1ffe50fd 100644 (file)
@@ -9,10 +9,53 @@
 
 #include "config.h"
 
-#ifdef ENABLE_EXTENSION_MODULE
-#include "../../../mono-extensions/mono/utils/mono-signal-handler.h"
+/*
+ * When a signal is delivered to a thread on a Krait Android device
+ * that's in the middle of skipping over an "IT" block, such as this
+ * one:
+ *
+ * 0x40184ef0 <dlfree+1308>:   ldr     r1, [r3, #0]
+ * 0x40184ef2 <dlfree+1310>:   add.w   r5, r12, r2, lsl #3
+ * 0x40184ef6 <dlfree+1314>:   lsls.w  r2, r0, r2
+ * 0x40184efa <dlfree+1318>:   tst     r2, r1
+ * ### this is the IT instruction
+ * 0x40184efc <dlfree+1320>:   itt     eq
+ * 0x40184efe <dlfree+1322>:   orreq   r2, r1
+ * ### signal arrives here
+ * 0x40184f00 <dlfree+1324>:   streq   r2, [r3, #0]
+ * 0x40184f02 <dlfree+1326>:   beq.n   0x40184f1a <dlfree+1350>
+ * 0x40184f04 <dlfree+1328>:   ldr     r2, [r5, #8]
+ * 0x40184f06 <dlfree+1330>:   ldr     r3, [r3, #16]
+ *
+ * then the first few (at most four, one would assume) instructions of
+ * the signal handler (!) might be skipped.  They happen to be the
+ * push of the frame pointer and return address, so once the signal
+ * handler has done its work, it returns into a SIGSEGV.
+ */
+
+#if defined (TARGET_ARM) && defined (HAVE_ARMV7) && defined (TARGET_ANDROID)
+#define KRAIT_IT_BUG_WORKAROUND        1
+#endif
+
+#ifdef KRAIT_IT_BUG_WORKAROUND
+#define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist)                \
+       static void __krait_ ## name arglist;   \
+       __attribute__ ((naked)) access void                             \
+       name arglist                                                    \
+       {                                                               \
+               asm volatile (                                          \
+                             "mov r0, r0\n\t"                          \
+                             "mov r0, r0\n\t"                          \
+                             "mov r0, r0\n\t"                          \
+                             "mov r0, r0\n\t");                        \
+               asm volatile (                                          \
+                             "bx %0"                                   \
+                             : : "r" (__krait_ ## name));              \
+       }       \
+       static void __krait_ ## name arglist
 #endif
 
+
 /* Don't use this */
 #ifndef MONO_SIGNAL_HANDLER_FUNC
 #define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist) access void name arglist