void mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr) { guint8 *code; guint8 buf [8]; gboolean can_write = mono_breakpoint_clean_code (method_start, orig_code, 8, buf, sizeof (buf)); code = buf + 8; /* go to the start of the call instruction * * address_byte = (m << 6) | (o << 3) | reg * call opcode: 0xff address_byte displacement * 0xff m=1,o=2 imm8 * 0xff m=2,o=2 imm32 */ code -= 6; orig_code -= 6; if (code [1] == 0xe8) { if (can_write) { mono_atomic_xchg_i32 ((gint32*)(orig_code + 2), (guint)addr - ((guint)orig_code + 1) - 5); /* Tell valgrind to recompile the patched code */ VALGRIND_DISCARD_TRANSLATIONS (orig_code + 2, 4); } } else if (code [1] == 0xe9) { /* A PLT entry: jmp <DISP> */ if (can_write) mono_atomic_xchg_i32 ((gint32*)(orig_code + 2), (guint)addr - ((guint)orig_code + 1) - 5); } else { printf ("Invalid trampoline sequence: %x %x %x %x %x %x %x\n", code [0], code [1], code [2], code [3], code [4], code [5], code [6]); g_assert_not_reached (); } }
static inline void leave_alertable_wait (MonoThreadInfo *info) { // Clear any previous flags. Thread is exiting alertable wait state, and info around pending interrupt/abort APC's // can now be discarded as well, thread is out of wait operation and can proceed it's execution. mono_atomic_xchg_i32 (&info->thread_wait_info, THREAD_WAIT_INFO_CLEARED); }
static inline void enter_alertable_wait (MonoThreadInfo *info) { // Clear any previous flags. Set alertable wait flag. mono_atomic_xchg_i32 (&info->thread_wait_info, THREAD_WAIT_INFO_ALERTABLE_WAIT_SLOT); }