Author: lupus
Date: 2007-10-31 13:35:56 -0500 (Wed, 31 Oct 2007)
New Revision: 88598

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/mini-amd64.c
   trunk/mono/mono/mini/mini-amd64.h
   trunk/mono/mono/mini/tramp-amd64.c
Log:


Wed Oct 31 19:53:33 CET 2007 Paolo Molaro <[EMAIL PROTECTED]>

        * mini-amd64.c, mini-amd64.h, tramp-amd64.c: breakpoint table support
        for amd64.



Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2007-10-31 18:22:03 UTC (rev 88597)
+++ trunk/mono/mono/mini/ChangeLog      2007-10-31 18:35:56 UTC (rev 88598)
@@ -1,4 +1,9 @@
 
+Wed Oct 31 19:53:33 CET 2007 Paolo Molaro <[EMAIL PROTECTED]>
+
+       * mini-amd64.c, mini-amd64.h, tramp-amd64.c: breakpoint table support
+       for amd64.
+
 Wed Oct 31 19:29:30 CET 2007 Paolo Molaro <[EMAIL PROTECTED]>
 
        * mini.c, mini.h, mini-x86, tramp-x86.c, mini-x86.h: added API to

Modified: trunk/mono/mono/mini/mini-amd64.c
===================================================================
--- trunk/mono/mono/mini/mini-amd64.c   2007-10-31 18:22:03 UTC (rev 88597)
+++ trunk/mono/mono/mini/mini-amd64.c   2007-10-31 18:35:56 UTC (rev 88598)
@@ -60,6 +60,9 @@
 #define mono_mini_arch_unlock() LeaveCriticalSection (&mini_arch_mutex)
 static CRITICAL_SECTION mini_arch_mutex;
 
+MonoBreakpointInfo
+mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+
 #define ARGS_OFFSET 16
 #define GP_SCRATCH_REG AMD64_R11
 
@@ -5238,13 +5241,39 @@
        return 3;
 }
 
+gboolean
+mono_breakpoint_clean_code (guint8 *code, guint8 *buf, int size)
+{
+       int i;
+       gboolean can_write = TRUE;
+       memcpy (buf, code, size);
+       for (i = 0; i < MONO_BREAKPOINT_ARRAY_SIZE; ++i) {
+               int idx = mono_breakpoint_info_index [i];
+               guint8 *ptr;
+               if (idx < 1)
+                       continue;
+               ptr = mono_breakpoint_info [idx].address;
+               if (ptr >= code && ptr < code + size) {
+                       guint8 saved_byte = mono_breakpoint_info 
[idx].saved_byte;
+                       can_write = FALSE;
+                       /*g_print ("patching %p with 0x%02x (was: 0x%02x)\n", 
ptr, saved_byte, buf [ptr - code]);*/
+                       buf [ptr - code] = saved_byte;
+               }
+       }
+       return can_write;
+}
+
 gpointer
 mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
 {
+       guint8 buf [10];
        guint32 reg;
        gint32 disp;
        guint8 rex = 0;
 
+       mono_breakpoint_clean_code (code - 10, buf, sizeof (buf));
+       code = buf + 10;
+
        *displacement = 0;
 
        /* go to the start of the call instruction

Modified: trunk/mono/mono/mini/mini-amd64.h
===================================================================
--- trunk/mono/mono/mini/mini-amd64.h   2007-10-31 18:22:03 UTC (rev 88597)
+++ trunk/mono/mono/mini/mini-amd64.h   2007-10-31 18:35:56 UTC (rev 88598)
@@ -278,5 +278,12 @@
 void 
 mono_amd64_patch (unsigned char* code, gpointer target) MONO_INTERNAL;
 
+typedef struct {
+       guint8 *address;
+       guint8 saved_byte;
+} MonoBreakpointInfo;
+
+extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+
 #endif /* __MONO_MINI_AMD64_H__ */  
 

Modified: trunk/mono/mono/mini/tramp-amd64.c
===================================================================
--- trunk/mono/mono/mini/tramp-amd64.c  2007-10-31 18:22:03 UTC (rev 88597)
+++ trunk/mono/mono/mini/tramp-amd64.c  2007-10-31 18:35:56 UTC (rev 88598)
@@ -63,21 +63,30 @@
 }
 
 void
-mono_arch_patch_callsite (guint8 *code, guint8 *addr)
+mono_arch_patch_callsite (guint8 *orig_code, guint8 *addr)
 {
+       guint8 *code;
+       guint8 buf [16];
+       gboolean can_write = mono_breakpoint_clean_code (orig_code - 14, buf, 
sizeof (buf));
+
+       code = buf + 14;
+
        if (((code [-13] == 0x49) && (code [-12] == 0xbb)) || (code [-5] == 
0xe8)) {
-               if (code [-5] != 0xe8)
-                       InterlockedExchangePointer ((gpointer*)(code - 11), 
addr);
-               else {
+               if (code [-5] != 0xe8) {
+                       if (can_write)
+                               InterlockedExchangePointer 
((gpointer*)(orig_code - 11), addr);
+               } else {
                        g_assert ((((guint64)(addr)) >> 32) == 0);
-                       g_assert ((((guint64)(code)) >> 32) == 0);
-                       InterlockedExchange ((gint32*)(code - 4), ((gint64)addr 
- (gint64)code));
+                       g_assert ((((guint64)(orig_code)) >> 32) == 0);
+                       if (can_write)
+                               InterlockedExchange ((gint32*)(orig_code - 4), 
((gint64)addr - (gint64)orig_code));
                }
        }
        else if ((code [-7] == 0x41) && (code [-6] == 0xff) && (code [-5] == 
0x15)) {
                /* call *<OFFSET>(%rip) */
-               gpointer *got_entry = (gpointer*)((guint8*)code + 
(*(guint32*)(code - 4)));
-               InterlockedExchangePointer (got_entry, addr);
+               gpointer *got_entry = (gpointer*)((guint8*)orig_code + 
(*(guint32*)(orig_code - 4)));
+               if (can_write)
+                       InterlockedExchangePointer (got_entry, addr);
        }
 }
 

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

Reply via email to