From 587745cce8d01b14f82b83425e249b00b684a7ae Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Sun, 7 Aug 2005 14:48:03 +0000 Subject: [PATCH] A minimal implementation of the x86 sysenter instruction (experimental). Limitations as commented in the code. git-svn-id: svn://svn.valgrind.org/vex/trunk@1320 --- VEX/priv/guest-x86/toIR.c | 29 +++++++++++++++++++++++++++++ VEX/priv/host-x86/hdefs.c | 3 +++ VEX/priv/ir/irdefs.c | 23 ++++++++++++----------- VEX/pub/libvex_ir.h | 4 +++- VEX/pub/libvex_trc_values.h | 3 +++ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index d8e8ba90f4..79321fcf72 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -88,6 +88,15 @@ happen. Programs that set it to 1 and then rely on the resulting SIGBUSs to inform them of misaligned accesses will not work. + Implementation sysenter is necessarily partial. sysenter is a kind + of system call entry. When doing a sysenter, the return address is + not known -- that is something that is beyond Vex's knowledge. So + the generated IR forces a return to the scheduler, which can do + what it likes to simulate the systemter, but it MUST set this + thread's guest_EIP field with the continuation address before + resuming execution. If that doesn't happen, the thread will jump + to address zero, which is probably fatal. + This module uses global variables and so is not MT-safe (if that should ever become relevant). @@ -11974,6 +11983,26 @@ DisResult disInstr_X86_WRK ( "%cl", False ); break; + /* =-=-=-=-=-=-=-=-=- SYSENTER -=-=-=-=-=-=-=-=-=-= */ + + case 0x34: + /* Simple implementation needing a long explaination. + + sysenter is a kind of syscall entry. The key thing here + is that the return address is not known -- that is + something that is beyond Vex's knowledge. So this IR + forces a return to the scheduler, which can do what it + likes to simulate the systemter, but it MUST set this + thread's guest_EIP field with the continuation address + before resuming execution. If that doesn't happen, the + thread will jump to address zero, which is probably + fatal. + */ + jmp_lit(Ijk_SysenterX86, 0/*bogus next EIP value*/); + dres.whatNext = Dis_StopHere; + DIP("sysenter"); + break; + /* =-=-=-=-=-=-=-=-=- XADD -=-=-=-=-=-=-=-=-=-= */ //-- case 0xC0: /* XADD Gb,Eb */ diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index 014adf66a9..d0fccf1774 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -2165,6 +2165,9 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) case Ijk_TInval: *p++ = 0xBD; p = emit32(p, VEX_TRC_JMP_TINVAL); break; + case Ijk_SysenterX86: + *p++ = 0xBD; + p = emit32(p, VEX_TRC_JMP_SYSENTER_X86); break; case Ijk_Ret: case Ijk_Call: case Ijk_Boring: diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index cd72beed0e..dba60612c8 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -599,17 +599,18 @@ void ppIRDirty ( IRDirty* d ) void ppIRJumpKind ( IRJumpKind kind ) { switch (kind) { - case Ijk_Boring: vex_printf("Boring"); break; - case Ijk_Call: vex_printf("Call"); break; - case Ijk_Ret: vex_printf("Return"); break; - case Ijk_ClientReq: vex_printf("ClientReq"); break; - case Ijk_Syscall: vex_printf("Syscall"); break; - case Ijk_Yield: vex_printf("Yield"); break; - case Ijk_EmWarn: vex_printf("EmWarn"); break; - case Ijk_NoDecode: vex_printf("NoDecode"); break; - case Ijk_MapFail: vex_printf("MapFail"); break; - case Ijk_TInval: vex_printf("Invalidate"); break; - default: vpanic("ppIRJumpKind"); + case Ijk_Boring: vex_printf("Boring"); break; + case Ijk_Call: vex_printf("Call"); break; + case Ijk_Ret: vex_printf("Return"); break; + case Ijk_ClientReq: vex_printf("ClientReq"); break; + case Ijk_Syscall: vex_printf("Syscall"); break; + case Ijk_Yield: vex_printf("Yield"); break; + case Ijk_EmWarn: vex_printf("EmWarn"); break; + case Ijk_NoDecode: vex_printf("NoDecode"); break; + case Ijk_MapFail: vex_printf("MapFail"); break; + case Ijk_TInval: vex_printf("Invalidate"); break; + case Ijk_SysenterX86: vex_printf("SysenterX86"); break; + default: vpanic("ppIRJumpKind"); } } diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 924e21e25d..fabe3a5837 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -816,7 +816,9 @@ typedef Ijk_EmWarn, /* report emulation warning before continuing */ Ijk_NoDecode, /* next instruction cannot be decoded */ Ijk_MapFail, /* Vex-provided address translation failed */ - Ijk_TInval /* Invalidate translations before continuing. */ + Ijk_TInval, /* Invalidate translations before continuing. */ + Ijk_SysenterX86 /* X86 sysenter. guest_EIP becomes invalid + at the point this happens. */ } IRJumpKind; diff --git a/VEX/pub/libvex_trc_values.h b/VEX/pub/libvex_trc_values.h index c2d096643a..8de587dd03 100644 --- a/VEX/pub/libvex_trc_values.h +++ b/VEX/pub/libvex_trc_values.h @@ -67,6 +67,9 @@ #define VEX_TRC_JMP_NODECODE 29 /* next instruction in not decodable */ #define VEX_TRC_JMP_MAPFAIL 31 /* address translation failed */ +#define VEX_TRC_JMP_SYSENTER_X86 9 /* simulate X86 sysenter before + continuing */ + #endif /* ndef __LIBVEX_TRC_VALUES_H */ -- 2.47.3