Author: zoltan
Date: 2007-12-07 10:29:51 -0500 (Fri, 07 Dec 2007)
New Revision: 90941

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/aot-compiler.c
   trunk/mono/mono/mini/aot-runtime.c
   trunk/mono/mono/mini/cpu-arm.md
   trunk/mono/mono/mini/inssel-arm.brg
   trunk/mono/mono/mini/mini-arm.c
   trunk/mono/mono/mini/mini-arm.h
   trunk/mono/mono/mini/tramp-arm.c
Log:
2007-12-07  Zoltan Varga  <[EMAIL PROTECTED]>

        * mini-arm.h mini-arm.c tramp-arm.c inssel-arm.brg cpu-arm.md 
        aot-runtime.c aot-compiler.c: Implement AOT support.    


Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2007-12-07 15:28:17 UTC (rev 90940)
+++ trunk/mono/mono/mini/ChangeLog      2007-12-07 15:29:51 UTC (rev 90941)
@@ -1,3 +1,8 @@
+2007-12-07  Zoltan Varga  <[EMAIL PROTECTED]>
+
+       * mini-arm.h mini-arm.c tramp-arm.c inssel-arm.brg cpu-arm.md 
+       aot-runtime.c aot-compiler.c: Implement AOT support.    
+
 2007-12-07  Mark Probst  <[EMAIL PROTECTED]>
 
        * mini-trampolines.c (mono_generic_class_init_trampoline): Fixed

Modified: trunk/mono/mono/mini/aot-compiler.c
===================================================================
--- trunk/mono/mono/mini/aot-compiler.c 2007-12-07 15:28:17 UTC (rev 90940)
+++ trunk/mono/mono/mini/aot-compiler.c 2007-12-07 15:29:51 UTC (rev 90941)
@@ -184,17 +184,10 @@
 static gboolean 
 is_got_patch (MonoJumpInfoType patch_type)
 {
-#ifdef __x86_64__
        return TRUE;
-#elif defined(__i386__)
-       return TRUE;
-#else
-       return FALSE;
-#endif
 }
 
-#if defined(__ppc__) && defined(__MACH__)
-static int
+static G_GNUC_UNUSED int
 ilog2(register int value)
 {
        int count = -1;
@@ -202,7 +195,6 @@
        while (value) count++, value >>= 1;
        return count;
 }
-#endif
 
 #ifdef USE_BIN_WRITER
 
@@ -1261,7 +1253,7 @@
        emit_unset_mode (acfg);
 #if defined(PLATFORM_WIN32)
        fprintf (acfg->fp, ".section %s\n", section_name);
-#elif defined(sparc)
+#elif defined(sparc) || defined(__arm__)
        /* For solaris as, GNU as should accept the same */
        fprintf (acfg->fp, ".section \"%s\"\n", section_name);
 #elif defined(__ppc__) && defined(__MACH__)
@@ -1283,7 +1275,7 @@
                stype = "object";
 
        emit_unset_mode (acfg);
-#if defined(sparc)
+#if defined(sparc) || defined(__arm__)
        fprintf (acfg->fp, "\t.type %s,#%s\n", name, stype);
 #elif defined(PLATFORM_WIN32)
 
@@ -1353,7 +1345,9 @@
 emit_alignment (MonoAotCompile *acfg, int size)
 {
        emit_unset_mode (acfg);
-#if defined(__ppc__) && defined(__MACH__)
+#if defined(__arm__)
+       fprintf (acfg->fp, "\t.align %d\n", ilog2 (size));
+#elif defined(__ppc__) && defined(__MACH__)
        // the mach-o assembler specifies alignments as powers of 2.
        fprintf (acfg->fp, "\t.align %d\t; ilog2\n", ilog2(size));
 #elif defined(__powerpc__)
@@ -1402,7 +1396,12 @@
                acfg->col_count = 0;
        }
        if ((acfg->col_count++ % 8) == 0)
+#if defined(__arm__)
+               /* FIXME: Use .hword on other archs as well */
+               fprintf (acfg->fp, "\n\t.hword ");
+#else
                fprintf (acfg->fp, "\n\t.word ");
+#endif
        else
                fprintf (acfg->fp, ", ");
        fprintf (acfg->fp, "%d", value);
@@ -1949,9 +1948,16 @@
                                        emit_byte (acfg, '\xe8');
                                        emit_symbol_diff (acfg, 
direct_call_target, ".", -4);
                                        i += 4;
+#elif defined(__arm__)
+#ifdef USE_BIN_WRITER
+                                       /* FIXME: Can't encode this using the 
current symbol writer functions */
+                                       g_assert_not_reached ();
 #else
-                                       g_assert_not_reached ();
+                                       emit_unset_mode (acfg);
+                                       fprintf (acfg->fp, "bl %s\n", 
direct_call_target);
+                                       i += 4 - 1;
 #endif
+#endif
                                } else {
                                        got_slot = get_got_offset (acfg, 
patch_info);
 
@@ -1960,6 +1966,10 @@
                                        emit_symbol_diff (acfg, "got", ".", 
(unsigned int) ((got_slot * sizeof (gpointer)) - 4));
 #elif defined(__i386__)
                                        emit_int32 (acfg, (unsigned int) 
((got_slot * sizeof (gpointer))));
+#elif defined(__arm__)
+                                       emit_symbol_diff (acfg, "got", ".", 
(unsigned int) ((got_slot * sizeof (gpointer))) - 12);
+#else
+                                       g_assert_not_reached ();
 #endif
                                        
                                        i += mono_arch_get_patch_offset (code + 
i) + 4 - 1;
@@ -2413,7 +2423,7 @@
  * - the ELF PLT entries make an indirect jump though the GOT so they expect 
the
  *   GOT pointer to be in EBX. We want to avoid this, so our table contains 
direct
  *   jumps. This means the jumps need to be patched when the address of the 
callee is
- *   known. Initially the PLT entries jump to code which transfer control to 
the
+ *   known. Initially the PLT entries jump to code which transfers control to 
the
  *   AOT runtime through the first PLT entry.
  */
 static void
@@ -2449,6 +2459,11 @@
        emit_alignment (acfg, PAGESIZE);
        emit_label (acfg, symbol);
 
+#if defined(USE_BIN_WRITER) && defined(__arm__)
+       /* FIXME: */
+       g_assert_not_reached ();
+#endif
+
        /* 
         * The first plt entry is used to transfer code to the AOT loader. 
         */
@@ -2463,6 +2478,12 @@
        emit_byte (acfg, '\x25');
        emit_symbol_diff (acfg, "plt_jump_table", ".", -4);
        emit_zero_bytes (acfg, 10);
+#elif defined(__arm__)
+       /* This is 8 bytes long, init_plt () depends on this */
+       emit_unset_mode (acfg);
+       fprintf (acfg->fp, "\tldr pc, [pc, #-4]\n");
+       /* This is filled up during loading by the AOT loader */
+       fprintf (acfg->fp, "\t.word 0\n");
 #else
        g_assert_not_reached ();
 #endif
@@ -2498,6 +2519,22 @@
                /* jmp .Lp_0 */
                emit_byte (acfg, '\xe9');
                emit_symbol_diff (acfg, ".Lp_0", ".", -4);
+#elif defined(__arm__)
+               /* 
+                * Emit an indirect call since branch displacements are limited 
to 24 bits on 
+                * ARM. Put the jump table entries inline since offsets are 
even smaller on
+                * ARM.
+                * FIXME:
+                * - optimize OP_AOTCONST implementation
+                * - optimize the PLT entries
+                * - optimize SWITCH AOT implementation
+                * - implement IMT support
+                */
+               /* This is 8 bytes long, init_plt () depends on this */
+               emit_unset_mode (acfg);
+               fprintf (acfg->fp, "\tldr pc, [pc, #-4]\n");
+               /* This is filled up during loading by the AOT loader */
+               fprintf (acfg->fp, "\t.word 0\n");
 #else
                g_assert_not_reached ();
 #endif
@@ -2528,6 +2565,12 @@
                emit_symbol_diff (acfg, ".Lp_0", ".", -4);
 #elif defined(__x86_64__)
                /* Emitted along with the PLT entries since they will not be 
patched */
+#elif defined(__arm__)
+               /* This is 12 bytes long, init_plt () depends on this */
+               emit_unset_mode (acfg);
+               fprintf (acfg->fp, "\tldr ip, [pc, #0]\n");
+               fprintf (acfg->fp, "\tb .Lp_0\n");
+               fprintf (acfg->fp, "\t.word %d\n", plt_info_offsets [i]);
 #else
                g_assert_not_reached ();
 #endif
@@ -3114,7 +3157,7 @@
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
-       /* To reduce size of generate assembly */
+       /* To reduce size of generated assembly */
        symbol = g_strdup_printf ("ex");
        emit_label (acfg, symbol);
 

Modified: trunk/mono/mono/mini/aot-runtime.c
===================================================================
--- trunk/mono/mono/mini/aot-runtime.c  2007-12-07 15:28:17 UTC (rev 90940)
+++ trunk/mono/mono/mini/aot-runtime.c  2007-12-07 15:29:51 UTC (rev 90941)
@@ -150,13 +150,7 @@
 static inline gboolean 
 is_got_patch (MonoJumpInfoType patch_type)
 {
-#ifdef __x86_64__
        return TRUE;
-#elif defined(__i386__)
-       return TRUE;
-#else
-       return FALSE;
-#endif
 }
 
 /*****************************************************/
@@ -2013,9 +2007,10 @@
 #ifdef MONO_ARCH_AOT_SUPPORTED
 #ifdef __i386__
        guint8 *buf = info->plt;
-#endif
-#if defined(__x86_64__)
+#elif defined(__x86_64__)
        int i, n_entries;
+#elif defined(__arm__)
+       int i, n_entries;
 #endif
        gpointer tramp;
 
@@ -2039,6 +2034,21 @@
         for (i = 1; i < n_entries; ++i)
                 /* Each PLT entry is 16 bytes long, the default entry begins 
at offset 6 */
                 ((gpointer*)info->plt_jump_table)[i] = info->plt + (i * 16) + 
6;
+#elif defined(__arm__)
+        /* Initialize the first PLT entry */
+        make_writable (info->plt, info->plt_end - info->plt);
+        ((guint32*)info->plt)[1] = (guint32)tramp;
+
+        n_entries = ((guint8*)info->plt_end - (guint8*)info->plt) / 8;
+
+        /* 
+         * Initialize the jump targets embedded inside the PLT entries to the 
default
+         * targets.
+         */
+        for (i = 1; i < n_entries; ++i)
+                /* Each PLT entry is 8 bytes long, the jump target is at 
offset 4 */
+                /* Each default PLT target is 12 bytes long */
+                ((guint32*)info->plt)[(i * 2) + 1] = (guint8*)info->plt_end + 
((i - 1) * 12);
 #else
        g_assert_not_reached ();
 #endif
@@ -2068,6 +2078,19 @@
                if ((target >= (guint8*)(aot_module->plt)) && (target < 
(guint8*)(aot_module->plt_end)))
                        return target;
        }
+#elif defined(__arm__)
+       guint32 ins = ((guint32*)code) [-1];
+
+       /* Should be a 'bl' */
+       if ((((ins >> 25) & 0x7) == 0x5) && (((ins >> 24) & 0x1) == 0x1)) {
+               gint32 disp = ((gint32)ins) & 0xffffff;
+               guint8 *target = code - 4 + 8 + (disp * 4);
+
+               if ((target >= (guint8*)(aot_module->plt)) && (target < 
(guint8*)(aot_module->plt_end)))
+                       return target;
+       }               
+#else
+       g_assert_not_reached ();
 #endif
 
        return NULL;

Modified: trunk/mono/mono/mini/cpu-arm.md
===================================================================
--- trunk/mono/mono/mini/cpu-arm.md     2007-12-07 15:28:17 UTC (rev 90940)
+++ trunk/mono/mono/mini/cpu-arm.md     2007-12-07 15:29:51 UTC (rev 90941)
@@ -530,7 +530,7 @@
 float_conv_to_u: dest:i src1:f len:36
 call_handler: len:12
 op_endfilter: src1:i len:16
-aot_const: dest:i len:8
+aot_const: dest:i len:16
 sqrt: dest:f src1:f len:4
 adc: dest:i src1:i src2:i len:4
 addcc: dest:i src1:i src2:i len:4

Modified: trunk/mono/mono/mini/inssel-arm.brg
===================================================================
--- trunk/mono/mono/mini/inssel-arm.brg 2007-12-07 15:28:17 UTC (rev 90940)
+++ trunk/mono/mono/mini/inssel-arm.brg 2007-12-07 15:29:51 UTC (rev 90941)
@@ -496,11 +496,33 @@
 
        MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, n);
        MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_many_bb [n]);
-       mono_bblock_add_inst (s->cbb, label);
-       mono_create_jump_table (s, label, tree->inst_many_bb, n);
-       /* the backend code will deal with aot vs normal case */
-       tree->sreg1 = state->left->reg1;
-       mono_bblock_add_inst (s->cbb, tree);
+
+       if (s->compile_aot) {
+               /* FIXME: Optimize this */
+               int offset_reg = mono_regstate_next_int (s->rs);
+               int target_reg = mono_regstate_next_int (s->rs);
+               int table_reg = mono_regstate_next_int (s->rs);
+               int sum_reg = mono_regstate_next_int (s->rs);
+               MonoJumpInfoBBTable *table;
+
+               MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, offset_reg, 
state->left->reg1, 2);
+
+               table = mono_mempool_alloc (s->mempool, sizeof 
(MonoJumpInfoBBTable));
+               table->table = tree->inst_many_bb;
+               table->table_size = n;
+
+               MONO_EMIT_NEW_AOTCONST (s, table_reg, table, 
MONO_PATCH_INFO_SWITCH);
+
+               MONO_EMIT_NEW_BIALU (s, CEE_ADD, sum_reg, table_reg, 
offset_reg);
+               MONO_EMIT_NEW_LOAD_MEMBASE (s, target_reg, sum_reg, 0);
+               MONO_EMIT_UNALU (s, tree, OP_BR_REG, -1, target_reg);
+       } else {
+               mono_bblock_add_inst (s->cbb, label);
+               mono_create_jump_table (s, label, tree->inst_many_bb, n);
+               /* the backend code will deal with aot vs normal case */
+               tree->sreg1 = state->left->reg1;
+               mono_bblock_add_inst (s->cbb, tree);
+       }
 }
 
 %%

Modified: trunk/mono/mono/mini/mini-arm.c
===================================================================
--- trunk/mono/mono/mini/mini-arm.c     2007-12-07 15:28:17 UTC (rev 90940)
+++ trunk/mono/mono/mini/mini-arm.c     2007-12-07 15:29:51 UTC (rev 90941)
@@ -2410,8 +2410,14 @@
                        code = mono_arm_emit_load_imm (code, ins->dreg, 
ins->inst_c0);
                        break;
                case OP_AOTCONST:
-                       g_assert_not_reached ();
+                       /* Load the GOT offset */
                        mono_add_patch_info (cfg, offset, 
(MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
+                       ARM_LDR_IMM (code, ins->dreg, ARMREG_PC, 0);
+                       ARM_B (code, 0);
+                       *(gpointer*)code = NULL;
+                       code += 4;
+                       /* Load the value from the GOT */
+                       ARM_LDR_REG_REG (code, ins->dreg, ARMREG_PC, ins->dreg);
                        break;
                case CEE_CONV_I4:
                case CEE_CONV_U4:
@@ -2502,6 +2508,9 @@
                        g_assert (ins->sreg1 != ARMREG_LR);
                        call = (MonoCallInst*)ins;
                        if (call->method->klass->flags & 
TYPE_ATTRIBUTE_INTERFACE) {
+                               if (cfg->compile_aot)
+                                       /* FIXME: */
+                                       cfg->disable_aot = 1;
                                ARM_ADD_REG_IMM8 (code, ARMREG_LR, ARMREG_PC, 
4);
                                ARM_LDR_IMM (code, ARMREG_PC, ins->sreg1, 
ins->inst_offset);
                                *((gpointer*)code) = (gpointer)call->method;
@@ -2696,15 +2705,31 @@
                /* floating point opcodes */
 #ifdef ARM_FPU_FPA
                case OP_R8CONST:
-                       /* FIXME: we can optimize the imm load by dealing with 
part of 
-                        * the displacement in LDFD (aligning to 512).
-                        */
-                       code = mono_arm_emit_load_imm (code, ARMREG_LR, 
(guint32)ins->inst_p0);
-                       ARM_LDFD (code, ins->dreg, ARMREG_LR, 0);
+                       if (cfg->compile_aot) {
+                               ARM_LDFD (code, ins->dreg, ARMREG_PC, 0);
+                               ARM_B (code, 1);
+                               *(guint32*)code = ((guint32*)(ins->inst_p0))[0];
+                               code += 4;
+                               *(guint32*)code = ((guint32*)(ins->inst_p0))[1];
+                               code += 4;
+                       } else {
+                               /* FIXME: we can optimize the imm load by 
dealing with part of 
+                                * the displacement in LDFD (aligning to 512).
+                                */
+                               code = mono_arm_emit_load_imm (code, ARMREG_LR, 
(guint32)ins->inst_p0);
+                               ARM_LDFD (code, ins->dreg, ARMREG_LR, 0);
+                       }
                        break;
                case OP_R4CONST:
-                       code = mono_arm_emit_load_imm (code, ARMREG_LR, 
(guint32)ins->inst_p0);
-                       ARM_LDFS (code, ins->dreg, ARMREG_LR, 0);
+                       if (cfg->compile_aot) {
+                               ARM_LDFS (code, ins->dreg, ARMREG_PC, 0);
+                               ARM_B (code, 0);
+                               *(guint32*)code = ((guint32*)(ins->inst_p0))[0];
+                               code += 4;
+                       } else {
+                               code = mono_arm_emit_load_imm (code, ARMREG_LR, 
(guint32)ins->inst_p0);
+                               ARM_LDFS (code, ins->dreg, ARMREG_LR, 0);
+                       }
                        break;
                case OP_STORER8_MEMBASE_REG:
                        g_assert (arm_is_fpimm8 (ins->inst_offset));
@@ -2756,16 +2781,33 @@
                        break;
 #elif defined(ARM_FPU_VFP)
                case OP_R8CONST:
-                       /* FIXME: we can optimize the imm load by dealing with 
part of 
-                        * the displacement in LDFD (aligning to 512).
-                        */
-                       code = mono_arm_emit_load_imm (code, ARMREG_LR, 
(guint32)ins->inst_p0);
-                       ARM_FLDD (code, ins->dreg, ARMREG_LR, 0);
+                       if (cfg->compile_aot) {
+                               ARM_LDFD (code, ins->dreg, ARMREG_PC, 0);
+                               ARM_B (code, 1);
+                               *(guint32*)code = ((guint32*)(ins->inst_p0))[0];
+                               code += 4;
+                               *(guint32*)code = ((guint32*)(ins->inst_p0))[1];
+                               code += 4;
+                       } else {
+                               /* FIXME: we can optimize the imm load by 
dealing with part of 
+                                * the displacement in LDFD (aligning to 512).
+                                */
+                               code = mono_arm_emit_load_imm (code, ARMREG_LR, 
(guint32)ins->inst_p0);
+                               ARM_FLDD (code, ins->dreg, ARMREG_LR, 0);
+                       }
                        break;
                case OP_R4CONST:
-                       code = mono_arm_emit_load_imm (code, ARMREG_LR, 
(guint32)ins->inst_p0);
-                       ARM_FLDS (code, ins->dreg, ARMREG_LR, 0);
-                       ARM_CVTS (code, ins->dreg, ins->dreg);
+                       if (cfg->compile_aot) {
+                               ARM_FLDS (code, ins->dreg, ARMREG_PC, 0);
+                               ARM_B (code, 0);
+                               *(guint32*)code = ((guint32*)(ins->inst_p0))[0];
+                               code += 4;
+                               ARM_CVTS (code, ins->dreg, ins->dreg);
+                       } else {
+                               code = mono_arm_emit_load_imm (code, ARMREG_LR, 
(guint32)ins->inst_p0);
+                               ARM_FLDS (code, ins->dreg, ARMREG_LR, 0);
+                               ARM_CVTS (code, ins->dreg, ins->dreg);
+                       }
                        break;
                case OP_STORER8_MEMBASE_REG:
                        g_assert (arm_is_fpimm8 (ins->inst_offset));
@@ -3082,25 +3124,36 @@
 mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, 
MonoJumpInfo *ji, gboolean run_cctors)
 {
        MonoJumpInfo *patch_info;
+       gboolean compile_aot = !run_cctors;
 
        for (patch_info = ji; patch_info; patch_info = patch_info->next) {
                unsigned char *ip = patch_info->ip.i + code;
                const unsigned char *target;
 
-               if (patch_info->type == MONO_PATCH_INFO_SWITCH) {
+               if (patch_info->type == MONO_PATCH_INFO_SWITCH && !compile_aot) 
{
                        gpointer *jt = (gpointer*)(ip + 8);
                        int i;
                        /* jt is the inlined jump table, 2 instructions after ip
                         * In the normal case we store the absolute addresses,
                         * otherwise the displacements.
                         */
-                       for (i = 0; i < patch_info->data.table->table_size; 
i++) { 
+                       for (i = 0; i < patch_info->data.table->table_size; i++)
                                jt [i] = code + 
(int)patch_info->data.table->table [i];
-                       }
                        continue;
                }
                target = mono_resolve_patch_target (method, domain, code, 
patch_info, run_cctors);
 
+               if (compile_aot) {
+                       switch (patch_info->type) {
+                       case MONO_PATCH_INFO_BB:
+                       case MONO_PATCH_INFO_LABEL:
+                               break;
+                       default:
+                               /* No need to patch these */
+                               continue;
+                       }
+               }
+
                switch (patch_info->type) {
                case MONO_PATCH_INFO_IP:
                        g_assert_not_reached ();
@@ -3652,6 +3705,13 @@
        return NULL;
 }
 
+guint32
+mono_arch_get_patch_offset (guint8 *code)
+{
+       /* OP_AOTCONST */
+       return 8;
+}
+
 void
 mono_arch_flush_register_windows (void)
 {

Modified: trunk/mono/mono/mini/mini-arm.h
===================================================================
--- trunk/mono/mono/mini/mini-arm.h     2007-12-07 15:28:17 UTC (rev 90940)
+++ trunk/mono/mono/mini/mini-arm.h     2007-12-07 15:29:51 UTC (rev 90941)
@@ -57,6 +57,8 @@
  * reproduceable results for benchmarks */
 #define MONO_ARCH_CODE_ALIGNMENT 32
 
+#define MONO_ARCH_AOT_PLT_OFFSET_REG ARMREG_IP
+
 void arm_patch (guchar *code, const guchar *target);
 guint8* mono_arm_emit_load_imm (guint8 *code, int dreg, guint32 val);
 
@@ -118,6 +120,8 @@
 
 #define MONO_ARCH_HAVE_IMT 1
 
+#define MONO_ARCH_AOT_SUPPORTED 1
+
 /* we have the stack pointer, not the base pointer in sigcontext */
 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->eip = (int)ip; } while (0); 
 #define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->ebp = (int)bp; } while (0); 

Modified: trunk/mono/mono/mini/tramp-arm.c
===================================================================
--- trunk/mono/mono/mini/tramp-arm.c    2007-12-07 15:28:17 UTC (rev 90940)
+++ trunk/mono/mono/mini/tramp-arm.c    2007-12-07 15:29:51 UTC (rev 90941)
@@ -105,7 +105,15 @@
 void
 mono_arch_patch_plt_entry (guint8 *code, guint8 *addr)
 {
-       g_assert_not_reached ();
+       guint32 ins = branch_for_target_reachable (code, addr);
+
+       if (ins)
+               /* Patch the branch */
+               ((guint32*)code) [0] = ins;
+       else
+               /* Patch the jump address */
+               ((guint32*)code) [1] = addr;
+       mono_arch_flush_icache ((char*)code, 4);
 }
 
 void
@@ -117,7 +125,14 @@
 void
 mono_arch_nullify_plt_entry (guint8 *code)
 {
-       g_assert_not_reached ();
+       guint8 buf [4];
+       guint8 *p;
+
+       p = buf;
+       ARM_MOV_REG_REG (p, ARMREG_PC, ARMREG_LR);
+
+       ((guint32*)code) [0] = ((guint32*)buf) [0];
+       mono_arch_flush_icache ((char*)code, 4);
 }
 
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to