diff --git a/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp b/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp index ebb2b24..172fe9d 100755 --- a/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp +++ b/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp @@ -88,6 +88,7 @@ #endif si->c.p_esi = &m2nfl->regs->esi; si->c.p_edi = &m2nfl->regs->edi; si->c.p_ebp = &m2nfl->regs->ebp; + si->c.eflags = m2nfl->regs->eflags; } else if (over_popped && (FRAME_MODIFIED_STACK == (FRAME_MODIFIED_STACK & m2n_get_frame_type(m2nfl)))) { si->c.esp = m2nfl->pop_regs->esp; @@ -100,6 +101,7 @@ #endif si->c.p_esi = &m2nfl->pop_regs->esi; si->c.p_edi = &m2nfl->pop_regs->edi; si->c.p_ebp = &m2nfl->pop_regs->ebp; + si->c.eflags = m2nfl->pop_regs->eflags; } else { // Normal M2nFrame, eip is past instruction, esp is implicitly address just beyond the frame, callee saves registers in M2nFrame si->c.esp = (uint32)m2nfl + m2n_sizeof_m2n_frame; @@ -129,7 +131,7 @@ static transfer_control_stub_type gen_tr return addr; } - const int stub_size = 64; + const int stub_size = 0x47; char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_COLD, CAA_Allocate); #ifdef _DEBUG memset(stub, 0xcc /*int 3*/, stub_size); @@ -162,6 +164,17 @@ #endif ss = get_reg(ss, &eax_opnd, eax_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_eax); ss = get_reg(ss, &ebx_opnd, ebx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_ebx); + + ss = mov(ss, ecx_opnd, M_Base_Opnd(edx_reg, (unsigned)&((StackIterator*)0)->c.eflags)); + ss = test(ss, ecx_opnd, ecx_opnd); + ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); + char* patch_offset = ((char *)ss) - 1; // Store location for jump patch + ss = push(ss, ecx_opnd); + *ss++ = (char)0x9D; // POPFD + // Patch conditional jump + signed offset = (signed)ss - (signed)patch_offset - 1; + *patch_offset = (char)offset; + ss = get_reg(ss, &ecx_opnd, ecx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_ecx); ss = get_reg(ss, &edx_opnd, edx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_edx); @@ -191,6 +204,12 @@ #endif mov eax,dword ptr [eax] mov ebx,dword ptr [edx+18h] mov ebx,dword ptr [ebx] + mov ecx,dword ptr [edx+28h] + test ecx,ecx + je _label_ + push ecx + popfd +_label_: mov ecx,dword ptr [edx+20h] mov ecx,dword ptr [ecx] mov edx,dword ptr [edx+24h] @@ -249,8 +268,9 @@ StackIterator* si_create_from_registers( memset(res, 0, sizeof(StackIterator)); // Setup current frame + // It's possible that registers represent native code and res->cci==NULL res->cci = vm_methods->find((NativeCodePtr)regs->eip, is_ip_past); - assert(res->cci); + res->c.esp = regs->esp; res->c.p_eip = ®s->eip; res->c.p_ebp = ®s->ebp; @@ -261,6 +281,7 @@ StackIterator* si_create_from_registers( res->c.p_ecx = ®s->ecx; res->c.p_edx = ®s->edx; res->c.is_ip_past = is_ip_past; + res->c.eflags = regs->eflags; res->m2nfl = lm2nf; return res; @@ -504,6 +525,7 @@ void si_copy_to_registers(StackIterator* ASSERT_NO_INTERPRETER regs->esp = si->c.esp; + regs->eflags = si->c.eflags; regs->eip = unref_reg(si->c.p_eip); regs->ebp = unref_reg(si->c.p_ebp); regs->edi = unref_reg(si->c.p_edi); diff --git a/vm/vmcore/include/jit_export_rt.h b/vm/vmcore/include/jit_export_rt.h index 88c134d..5ad2ac6 100644 --- a/vm/vmcore/include/jit_export_rt.h +++ b/vm/vmcore/include/jit_export_rt.h @@ -109,6 +109,9 @@ struct JitFrameContext { uint32 *p_ecx; uint32 *p_edx; + // To restore processor flags during transfer + uint32 eflags; + Boolean is_ip_past; } JitFrameContext; diff --git a/vm/vmcore/include/vm_core_types.h b/vm/vmcore/include/vm_core_types.h index 35ba2f9..c4d5c9b 100644 --- a/vm/vmcore/include/vm_core_types.h +++ b/vm/vmcore/include/vm_core_types.h @@ -114,6 +114,7 @@ struct Registers { uint32 ebp; uint32 esp; uint32 eip; + uint32 eflags; void reset_ip() { eip = 0; } void* get_ip() { return (void*)eip; } diff --git a/vm/vmcore/src/jvmti/jvmti_break_intf.cpp b/vm/vmcore/src/jvmti/jvmti_break_intf.cpp index 8770425..4a9ec9e 100644 --- a/vm/vmcore/src/jvmti/jvmti_break_intf.cpp +++ b/vm/vmcore/src/jvmti/jvmti_break_intf.cpp @@ -610,14 +610,7 @@ #endif //_IA32_ && PLATFORM_POSIX && INS << (bp->method ? method_get_descriptor((Method*)bp->method) : "") << " :" << bp->location << " :" << bp->addr); - bool push_frame = (vm_identify_eip(addr) == VM_TYPE_JAVA); - M2nFrame* m2nf; - - if (push_frame) { - m2nf = m2n_push_suspended_frame(®s); - } else { - m2nf = m2n_get_last_frame(); - } + M2nFrame* m2nf = m2n_push_suspended_frame(®s); jbyte *instruction_buffer; BEGIN_RAISE_AREA; @@ -812,12 +805,6 @@ #endif //_IA32_ && PLATFORM_POSIX && INS StackIterator *si = si_create_from_registers(®s, false, m2n_get_previous_frame(m2nf)); - if (push_frame) - { - m2n_set_last_frame(m2n_get_previous_frame(m2nf)); - STD_FREE(m2nf); - } - si_set_ip(si, instruction_buffer, false); si_transfer_control(si); } diff --git a/vm/vmcore/src/util/linux/signals_ia32.cpp b/vm/vmcore/src/util/linux/signals_ia32.cpp index 3774726..c45266c 100644 --- a/vm/vmcore/src/util/linux/signals_ia32.cpp +++ b/vm/vmcore/src/util/linux/signals_ia32.cpp @@ -89,6 +89,7 @@ void linux_ucontext_to_regs(Registers* r regs->ebp = uc->uc_mcontext.gregs[REG_EBP]; regs->eip = uc->uc_mcontext.gregs[REG_EIP]; regs->esp = uc->uc_mcontext.gregs[REG_ESP]; + regs->eflags = uc->uc_mcontext.gregs[REG_EFL]; } void linux_regs_to_ucontext(ucontext_t *uc, Registers* regs) @@ -102,6 +103,7 @@ void linux_regs_to_ucontext(ucontext_t * uc->uc_mcontext.gregs[REG_EBP] = regs->ebp; uc->uc_mcontext.gregs[REG_EIP] = regs->eip; uc->uc_mcontext.gregs[REG_ESP] = regs->esp; + uc->uc_mcontext.gregs[REG_EFL] = regs->eflags; } // exception catch support for JVMTI diff --git a/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp b/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp index ff69dfc..8f63460 100644 --- a/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp +++ b/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp @@ -51,6 +51,7 @@ void nt_to_vm_context(PCONTEXT context, regs->ebp = context->Ebp; regs->eip = context->Eip; regs->esp = context->Esp; + regs->eflags = context->EFlags; } void vm_to_nt_context(Registers* regs, PCONTEXT context) @@ -64,6 +65,7 @@ void vm_to_nt_context(Registers* regs, P context->Eax = regs->eax; context->Ecx = regs->ecx; context->Edx = regs->edx; + context->EFlags = regs->eflags; } static void print_state(LPEXCEPTION_POINTERS nt_exception, const char *msg)