From nobody Mon Sep 17 00:00:00 2001 From: Ilya Berezhniuk Date: Wed, 27 Feb 2008 17:52:47 +0300 Subject: [PATCH] Improved processof flags setup in transfer control stubs --- vm/port/src/thread/linux/thread_asm_em64t.s | 9 +++-- vm/port/src/thread/linux/thread_asm_ia32.s | 9 +++-- vm/port/src/thread/win/thread_asm_em64t.asm | 9 +++-- vm/port/src/thread/win/thread_asm_ia32.asm | 9 +++-- vm/vmcore/src/lil/em64t/stack_iterator_em64t.cpp | 22 +++++++++--- vm/vmcore/src/lil/ia32/stack_iterator_ia32.cpp | 41 +++++++++++++++------- 6 files changed, 69 insertions(+), 30 deletions(-) 76e2b0f5e9d9ab900468b8cb42b1ca651841d384 diff --git a/vm/port/src/thread/linux/thread_asm_em64t.s b/vm/port/src/thread/linux/thread_asm_em64t.s index 72d82c6..2360958 100755 --- a/vm/port/src/thread/linux/thread_asm_em64t.s +++ b/vm/port/src/thread/linux/thread_asm_em64t.s @@ -67,11 +67,14 @@ port_transfer_to_regs: movq %rcx, -0x88(%rax)// (new RIP) -> [(new RSP) - 128 - 8] movq 0x40(%rdx), %rax // RAX field - movzbq 0x88(%rdx), %rcx // (EFLAGS & 0xff) -> RCX + movzwq 0x88(%rdx), %rcx // (word)EFLAGS -> RCX test %rcx, %rcx je __skipefl__ - push %rcx - popfq + pushfq + andl $0x003F7202, (%rsp) // Clear OF, DF, TF, SF, ZF, AF, PF, CF + andl $0x00000CD5, %ecx // Clear all except OF, DF, SF, ZF, AF, PF, CF + orl %ecx, (%rsp) + popfq // restore RFLAGS __skipefl__: movq 0x48(%rdx), %rcx // RCX field diff --git a/vm/port/src/thread/linux/thread_asm_ia32.s b/vm/port/src/thread/linux/thread_asm_ia32.s index ceae264..fd15aaf 100755 --- a/vm/port/src/thread/linux/thread_asm_ia32.s +++ b/vm/port/src/thread/linux/thread_asm_ia32.s @@ -46,11 +46,14 @@ port_transfer_to_regs: movl %ebx, (%ecx) // new EIP -> (new ESP - 4) (as return address) movl 0x00(%edx), %eax // EAX field movl 0x04(%edx), %ebx // EBX field - movzbl 0x24(%edx), %ecx // (EFLAGS & 0xff) -> ECX + movzwl 0x24(%edx), %ecx // (word)EFLAGS -> ECX test %ecx, %ecx je _label_ - push %ecx // restore EFLAGS - popfl + pushfl + andl $0x003F7202, (%esp) + andl $0x00000CD5, %ecx + orl %ecx, (%esp) + popfl // restore EFLAGS _label_: movl 0x08(%edx), %ecx // ECX field movl 0x0C(%edx), %edx // EDX field diff --git a/vm/port/src/thread/win/thread_asm_em64t.asm b/vm/port/src/thread/win/thread_asm_em64t.asm index 1424eec..3f5a453 100755 --- a/vm/port/src/thread/win/thread_asm_em64t.asm +++ b/vm/port/src/thread/win/thread_asm_em64t.asm @@ -68,11 +68,14 @@ port_transfer_to_regs PROC mov qword ptr [rax-88h],rcx ; (new RIP) -> [(new RSP) - 128 - 8] mov rax, qword ptr [rdx+40h] ; RAX field - movzx rcx, byte ptr [rdx+88h] ; (EFLAGS & 0xff) -> RCX + movzx rcx, word ptr [rdx+88h] ; (word)EFLAGS -> RCX test rcx, rcx je __skipefl__ - push rcx - popfq + pushfq + and dword ptr [rsp], 003F7202h ; Clear OF, DF, TF, SF, ZF, AF, PF, CF + and ecx, 00000CD5h ; Clear all except OF, DF, SF, ZF, AF, PF, CF + or dword ptr [rsp], ecx + popfq ; restore RFLAGS __skipefl__: mov rcx, qword ptr [rdx+48h] ; RCX field diff --git a/vm/port/src/thread/win/thread_asm_ia32.asm b/vm/port/src/thread/win/thread_asm_ia32.asm index 01e4b13..b3b4adb 100755 --- a/vm/port/src/thread/win/thread_asm_ia32.asm +++ b/vm/port/src/thread/win/thread_asm_ia32.asm @@ -48,11 +48,14 @@ port_transfer_to_regs PROC mov dword ptr [ecx], ebx ; new EIP -> (new ESP - 4) (as return address) mov eax, dword ptr [edx+00h] ; EAX field mov ebx, dword ptr [edx+04h] ; EBX field - movzx ecx, byte ptr [edx+24h] ; (EFLAGS & 0xff) -> ECX + movzx ecx, word ptr [edx+24h] ; (word)EFLAGS -> ECX test ecx, ecx je _label_ - push ecx ; restore EFLAGS - popfd + pushfd + and dword ptr [esp], 003F7202h ; Clear OF, DF, TF, SF, ZF, AF, PF, CF + and ecx, 00000CD5h ; Clear all except OF, DF, SF, ZF, AF, PF, CF + or dword ptr [esp], ecx + popfd ; restore EFLAGS _label_: mov ecx, dword ptr [edx+08h] ; ECX field mov edx, dword ptr [edx+0Ch] ; EDX field diff --git a/vm/vmcore/src/lil/em64t/stack_iterator_em64t.cpp b/vm/vmcore/src/lil/em64t/stack_iterator_em64t.cpp index bd80833..a4ad99b 100644 --- a/vm/vmcore/src/lil/em64t/stack_iterator_em64t.cpp +++ b/vm/vmcore/src/lil/em64t/stack_iterator_em64t.cpp @@ -169,6 +169,11 @@ typedef void (* transfer_control_stub_ty #define CONTEXT_OFFSET(_field_) \ ((int64)&((StackIterator*)0)->jit_frame_context._field_) +// Clear OF, DF, TF, SF, ZF, AF, PF, CF, do not touch reserved bits +#define FLG_CLEAR_MASK ((unsigned)0x003F7202) +// Set OF, DF, SF, ZF, AF, PF, CF +#define FLG_SET_MASK ((unsigned)0x00000CD5) + static transfer_control_stub_type gen_transfer_control_stub() { static transfer_control_stub_type addr = NULL; @@ -177,7 +182,7 @@ static transfer_control_stub_type gen_tr return addr; } - const int STUB_SIZE = 239; + const int STUB_SIZE = 255; char * stub = (char *)malloc_fixed_code_for_jit(STUB_SIZE, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_COLD, CAA_Allocate); char * ss = stub; @@ -225,11 +230,15 @@ #endif ss = get_reg(ss, rax_opnd, rdx_reg, CONTEXT_OFFSET(p_rax), true); // Restore processor flags - ss = movzx(ss, rcx_opnd, M_Base_Opnd(rdx_reg, CONTEXT_OFFSET(eflags)), size_8); + ss = movzx(ss, rcx_opnd, M_Base_Opnd(rdx_reg, CONTEXT_OFFSET(eflags)), size_16); ss = test(ss, rcx_opnd, rcx_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, rcx_opnd); + *ss++ = (char)0x9C; // PUSHFQ + M_Base_Opnd sflags(rsp_reg, 0); + ss = alu(ss, and_opc, sflags, Imm_Opnd(size_32,FLG_CLEAR_MASK), size_32); + ss = alu(ss, and_opc, rcx_opnd, Imm_Opnd(size_32,FLG_SET_MASK), size_32); + ss = alu(ss, or_opc, sflags, rcx_opnd, size_32); *ss++ = (char)0x9D; // POPFQ // Patch conditional jump POINTER_SIZE_SINT offset = @@ -275,10 +284,13 @@ __label11__ je __label12__ mov rax,qword ptr [rax] __label12__ - movzx rcx,byte ptr [rdx+90h] + movzx rcx,word ptr [rdx+90h] test rcx,rcx je __label13__ - push rcx + pushfq + and dword ptr [rsp], 0x003F7202 + and ecx, 0x00000CD5 + or dword ptr [esp], ecx popfq __label13__ mov rcx,qword ptr [rdx+50h] diff --git a/vm/vmcore/src/lil/ia32/stack_iterator_ia32.cpp b/vm/vmcore/src/lil/ia32/stack_iterator_ia32.cpp index 768530e..af5de5e 100644 --- a/vm/vmcore/src/lil/ia32/stack_iterator_ia32.cpp +++ b/vm/vmcore/src/lil/ia32/stack_iterator_ia32.cpp @@ -127,6 +127,14 @@ static char* get_reg(char* ss, R_Opnd* d typedef void (__cdecl *transfer_control_stub_type)(StackIterator*); +#define CONTEXT_OFFSET(_field_) \ + ((unsigned)&((StackIterator*)0)->c._field_) + +// Clear OF, DF, TF, SF, ZF, AF, PF, CF, do not touch reserved bits +#define FLG_CLEAR_MASK ((unsigned)0x003F7202) +// Set OF, DF, SF, ZF, AF, PF, CF +#define FLG_SET_MASK ((unsigned)0x00000CD5) + static transfer_control_stub_type gen_transfer_control_stub() { static transfer_control_stub_type addr = NULL; @@ -134,7 +142,7 @@ static transfer_control_stub_type gen_tr return addr; } - const int stub_size = 0x48; + const int stub_size = 0x57; 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); @@ -150,36 +158,40 @@ #endif M_Base_Opnd m1(esp_reg, 4); ss = mov(ss, edx_opnd, m1); - ss = get_reg(ss, &ebx_opnd, ebx_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_eip); + ss = get_reg(ss, &ebx_opnd, ebx_reg, edx_reg, CONTEXT_OFFSET(p_eip)); - M_Base_Opnd m2(edx_reg, (int)&((StackIterator*)0)->c.esp); + M_Base_Opnd m2(edx_reg, CONTEXT_OFFSET(esp)); ss = mov(ss, ecx_opnd, m2); ss = alu(ss, sub_opc, ecx_opnd, Imm_Opnd(4)); ss = mov(ss, m1, ecx_opnd); - ss = get_reg(ss, &esi_opnd, esi_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_esi); - ss = get_reg(ss, &edi_opnd, edi_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_edi); - ss = get_reg(ss, &ebp_opnd, ebp_reg, edx_reg, (unsigned)&((StackIterator*)0)->c.p_ebp); + ss = get_reg(ss, &esi_opnd, esi_reg, edx_reg, CONTEXT_OFFSET(p_esi)); + ss = get_reg(ss, &edi_opnd, edi_reg, edx_reg, CONTEXT_OFFSET(p_edi)); + ss = get_reg(ss, &ebp_opnd, ebp_reg, edx_reg, CONTEXT_OFFSET(p_ebp)); M_Base_Opnd m3(ecx_reg, 0); ss = mov(ss, m3, ebx_opnd); - 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 = get_reg(ss, &eax_opnd, eax_reg, edx_reg, CONTEXT_OFFSET(p_eax)); + ss = get_reg(ss, &ebx_opnd, ebx_reg, edx_reg, CONTEXT_OFFSET(p_ebx)); - ss = movzx(ss, ecx_opnd, M_Base_Opnd(edx_reg, (unsigned)&((StackIterator*)0)->c.eflags), size_8); + ss = mov(ss, ecx_opnd, M_Base_Opnd(edx_reg, CONTEXT_OFFSET(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)0x9C; // PUSHFD + M_Base_Opnd m4(esp_reg, 0); + ss = alu(ss, and_opc, m4, Imm_Opnd(FLG_CLEAR_MASK)); + ss = alu(ss, and_opc, ecx_opnd, Imm_Opnd(FLG_SET_MASK)); + ss = alu(ss, or_opc, m4, 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); + ss = get_reg(ss, &ecx_opnd, ecx_reg, edx_reg, CONTEXT_OFFSET(p_ecx)); + ss = get_reg(ss, &edx_opnd, edx_reg, edx_reg, CONTEXT_OFFSET(p_edx)); ss = mov(ss, esp_opnd, m1); ss = ret(ss); @@ -210,7 +222,10 @@ #endif movzx ecx,byte ptr [edx+28h] test ecx,ecx je _label_ - push ecx + pushfd + and dword ptr [esp], 0x003F7202 + and ecx, 0x00000CD5 + or dword ptr [esp], ecx popfd _label_: mov ecx,dword ptr [edx+20h] -- 1.3.3