]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
A minimal implementation of the x86 sysenter instruction
authorJulian Seward <jseward@acm.org>
Sun, 7 Aug 2005 14:48:03 +0000 (14:48 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 7 Aug 2005 14:48:03 +0000 (14:48 +0000)
(experimental).  Limitations as commented in the code.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1320

VEX/priv/guest-x86/toIR.c
VEX/priv/host-x86/hdefs.c
VEX/priv/ir/irdefs.c
VEX/pub/libvex_ir.h
VEX/pub/libvex_trc_values.h

index d8e8ba90f41cab334ea195b41cef3ae393bbc985..79321fcf721fd4004f90ba1c1d264e7458a03a6f 100644 (file)
    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 */
index 014adf66a9ab07086c7647d0e4e17ae81f35c3ad..d0fccf177405a85732fd9f743850cf4cfc55d0c8 100644 (file)
@@ -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:
index cd72beed0eb361a9978b11dbf21c3cff4259306d..dba60612c8d5634b750a1e016dff625768668bb1 100644 (file)
@@ -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");
    }
 }
 
index 924e21e25d04b3c150db2837ad4ae207a3c58021..fabe3a583771ecc1ae9440618ff3f3605232e02c 100644 (file)
@@ -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;
 
index c2d096643a8d74a3282728746492e49eeca25d02..8de587dd03b2ea818d0d9cce83d8a945e80f45bb 100644 (file)
@@ -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 */