]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 345248 - add support for Solaris OS in valgrind
authorJulian Seward <jseward@acm.org>
Tue, 21 Jul 2015 14:43:23 +0000 (14:43 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 21 Jul 2015 14:43:23 +0000 (14:43 +0000)
VEX aspects -- pretty minimal.

Authors of this port:
    Petr Pavlu         setup@dagobah.cz
    Ivo Raisr          ivosh@ivosh.net
    Theo Schlossnagle  theo@omniti.com

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

16 files changed:
VEX/priv/guest_amd64_defs.h
VEX/priv/guest_amd64_helpers.c
VEX/priv/guest_amd64_toIR.c
VEX/priv/guest_x86_defs.h
VEX/priv/guest_x86_helpers.c
VEX/priv/guest_x86_toIR.c
VEX/priv/host_amd64_defs.c
VEX/priv/host_amd64_isel.c
VEX/priv/host_x86_defs.c
VEX/priv/host_x86_isel.c
VEX/priv/ir_defs.c
VEX/pub/libvex.h
VEX/pub/libvex_guest_amd64.h
VEX/pub/libvex_guest_x86.h
VEX/pub/libvex_ir.h
VEX/pub/libvex_trc_values.h

index 003ebde9a492746f64d6b2f58673ed088212cc3c..3b9e7ffeac47852f08bb3525a64eb18143cb9351 100644 (file)
@@ -316,6 +316,15 @@ extern void amd64g_dirtyhelper_AESKEYGENASSIST (
 #define AMD64G_CC_MASK_C    (1ULL << AMD64G_CC_SHIFT_C)
 #define AMD64G_CC_MASK_P    (1ULL << AMD64G_CC_SHIFT_P)
 
+/* additional rflags masks */
+#define AMD64G_CC_SHIFT_ID  21
+#define AMD64G_CC_SHIFT_AC  18
+#define AMD64G_CC_SHIFT_D   10
+
+#define AMD64G_CC_MASK_ID   (1ULL << AMD64G_CC_SHIFT_ID)
+#define AMD64G_CC_MASK_AC   (1ULL << AMD64G_CC_SHIFT_AC)
+#define AMD64G_CC_MASK_D    (1ULL << AMD64G_CC_SHIFT_D)
+
 /* FPU flag masks */
 #define AMD64G_FC_SHIFT_C3   14
 #define AMD64G_FC_SHIFT_C2   10
index c2b216ae53513d935a6d8a125f67bddae2d50117..e3c3b73a4d09935e727bcadea1abacd3f01b98f3 100644 (file)
@@ -911,6 +911,43 @@ ULong LibVEX_GuestAMD64_get_rflags ( /*IN*/const VexGuestAMD64State* vex_state )
    return rflags;
 }
 
+/* VISIBLE TO LIBVEX CLIENT */
+void
+LibVEX_GuestAMD64_put_rflags ( ULong rflags,
+                               /*MOD*/VexGuestAMD64State* vex_state )
+{
+   /* D flag */
+   if (rflags & AMD64G_CC_MASK_D) {
+      vex_state->guest_DFLAG = -1;
+      rflags &= ~AMD64G_CC_MASK_D;
+   }
+   else
+      vex_state->guest_DFLAG = 1;
+
+   /* ID flag */
+   if (rflags & AMD64G_CC_MASK_ID) {
+      vex_state->guest_IDFLAG = 1;
+      rflags &= ~AMD64G_CC_MASK_ID;
+   }
+   else
+      vex_state->guest_IDFLAG = 0;
+
+   /* AC flag */
+   if (rflags & AMD64G_CC_MASK_AC) {
+      vex_state->guest_ACFLAG = 1;
+      rflags &= ~AMD64G_CC_MASK_AC;
+   }
+   else
+      vex_state->guest_ACFLAG = 0;
+
+   UInt cc_mask = AMD64G_CC_MASK_O | AMD64G_CC_MASK_S | AMD64G_CC_MASK_Z |
+                  AMD64G_CC_MASK_A | AMD64G_CC_MASK_C | AMD64G_CC_MASK_P;
+   vex_state->guest_CC_OP   = AMD64G_CC_OP_COPY;
+   vex_state->guest_CC_DEP1 = rflags & cc_mask;
+   vex_state->guest_CC_DEP2 = 0;
+   vex_state->guest_CC_NDEP = 0;
+}
+
 /* VISIBLE TO LIBVEX CLIENT */
 void
 LibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag,
@@ -1906,11 +1943,8 @@ void do_get_x87 ( /*IN*/VexGuestAMD64State* vex_state,
 }
 
 
-/* CALLED FROM GENERATED CODE */
-/* DIRTY HELPER (reads guest state, writes guest mem) */
-/* NOTE: only handles 32-bit format (no REX.W on the insn) */
-void amd64g_dirtyhelper_FXSAVE_ALL_EXCEPT_XMM ( VexGuestAMD64State* gst,
-                                                HWord addr )
+static
+void do_fxsave ( VexGuestAMD64State* gst, HWord addr, Bool save_xmm_regs )
 {
    /* Derived from values obtained from
       vendor_id       : AuthenticAMD
@@ -1988,19 +2022,48 @@ void amd64g_dirtyhelper_FXSAVE_ALL_EXCEPT_XMM ( VexGuestAMD64State* gst,
       dstS[7] = 0;
    }
 
-   /* That's the first 160 bytes of the image done.  Now only %xmm0
-      .. %xmm15 remain to be copied, and we let the generated IR do
-      that, so as to make Memcheck's definedness flow for the non-XMM
-      parts independant from that of the all the other control and
-      status words in the structure.  This avoids the false positives
-      shown in #291310. */
+   /* That's the first 160 bytes of the image done. */
+   if (save_xmm_regs == True) {
+      /* Now only %xmm0 .. %xmm15 remain to be copied.  If the host is
+         big-endian, these need to be byte-swapped. */
+      U128 *xmm = (U128 *)(addr + 160);
+
+      vassert(host_is_little_endian());
+
+#     define COPY_U128(_dst,_src)                       \
+         do { _dst[0] = _src[0]; _dst[1] = _src[1];     \
+              _dst[2] = _src[2]; _dst[3] = _src[3]; }   \
+         while (0)
+
+      COPY_U128( xmm[0],  gst->guest_YMM0 );
+      COPY_U128( xmm[1],  gst->guest_YMM1 );
+      COPY_U128( xmm[2],  gst->guest_YMM2 );
+      COPY_U128( xmm[3],  gst->guest_YMM3 );
+      COPY_U128( xmm[4],  gst->guest_YMM4 );
+      COPY_U128( xmm[5],  gst->guest_YMM5 );
+      COPY_U128( xmm[6],  gst->guest_YMM6 );
+      COPY_U128( xmm[7],  gst->guest_YMM7 );
+      COPY_U128( xmm[8],  gst->guest_YMM8 );
+      COPY_U128( xmm[9],  gst->guest_YMM9 );
+      COPY_U128( xmm[10], gst->guest_YMM10 );
+      COPY_U128( xmm[11], gst->guest_YMM11 );
+      COPY_U128( xmm[12], gst->guest_YMM12 );
+      COPY_U128( xmm[13], gst->guest_YMM13 );
+      COPY_U128( xmm[14], gst->guest_YMM14 );
+      COPY_U128( xmm[15], gst->guest_YMM15 );
+#  undef COPY_U128
+   } else {
+      /* We let the generated IR to copy remaining %xmm0 .. %xmm15, so as to
+       make Memcheck's definedness flow for the non-XMM parts independent from
+       that of the all the other control and status words in the structure.
+       This avoids the false positives shown in #291310. */
+   }
 }
 
 
-/* CALLED FROM GENERATED CODE */
-/* DIRTY HELPER (writes guest state, reads guest mem) */
-VexEmNote amd64g_dirtyhelper_FXRSTOR_ALL_EXCEPT_XMM ( VexGuestAMD64State* gst,
-                                                      HWord addr )
+static
+VexEmNote do_fxrstor ( VexGuestAMD64State* gst, HWord addr,
+                       Bool rstor_xmm_regs )
 {
    Fpu_State tmp;
    VexEmNote warnX87 = EmNote_NONE;
@@ -2010,9 +2073,41 @@ VexEmNote amd64g_dirtyhelper_FXRSTOR_ALL_EXCEPT_XMM ( VexGuestAMD64State* gst,
    UShort    fp_tags;
    Int       r, stno, i;
 
-   /* Don't restore %xmm0 .. %xmm15, for the same reasons that
-      amd64g_dirtyhelper_FXSAVE_ALL_EXCEPT_XMM doesn't save them.  See
-      comment in that function for details. */
+   if (rstor_xmm_regs == True) {
+      /* Restore %xmm0 .. %xmm15.  If the host is big-endian, these need
+         to be byte-swapped. */
+      U128 *xmm = (U128 *)(addr + 160);
+
+      vassert(host_is_little_endian());
+
+#     define COPY_U128(_dst,_src)                       \
+         do { _dst[0] = _src[0]; _dst[1] = _src[1];     \
+              _dst[2] = _src[2]; _dst[3] = _src[3]; }   \
+         while (0)
+
+      COPY_U128( gst->guest_YMM0, xmm[0] );
+      COPY_U128( gst->guest_YMM1, xmm[1] );
+      COPY_U128( gst->guest_YMM2, xmm[2] );
+      COPY_U128( gst->guest_YMM3, xmm[3] );
+      COPY_U128( gst->guest_YMM4, xmm[4] );
+      COPY_U128( gst->guest_YMM5, xmm[5] );
+      COPY_U128( gst->guest_YMM6, xmm[6] );
+      COPY_U128( gst->guest_YMM7, xmm[7] );
+      COPY_U128( gst->guest_YMM8, xmm[8] );
+      COPY_U128( gst->guest_YMM9, xmm[9] );
+      COPY_U128( gst->guest_YMM10, xmm[10] );
+      COPY_U128( gst->guest_YMM11, xmm[11] );
+      COPY_U128( gst->guest_YMM12, xmm[12] );
+      COPY_U128( gst->guest_YMM13, xmm[13] );
+      COPY_U128( gst->guest_YMM14, xmm[14] );
+      COPY_U128( gst->guest_YMM15, xmm[15] );
+
+#  undef COPY_U128
+   } else {
+      /* Don't restore %xmm0 .. %xmm15, for the same reasons that
+         do_fxsave(save_xmm_regs = False) doesn't save them.  See
+         comment in that function for details. */
+   }
 
    /* Copy the x87 registers out of the image, into a temporary
       Fpu_State struct. */
@@ -2061,6 +2156,25 @@ VexEmNote amd64g_dirtyhelper_FXRSTOR_ALL_EXCEPT_XMM ( VexGuestAMD64State* gst,
 }
 
 
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (reads guest state, writes guest mem) */
+/* NOTE: only handles 32-bit format (no REX.W on the insn) */
+/* NOTE: does not save XMM registers - see do_fxsave() for details */
+void amd64g_dirtyhelper_FXSAVE_ALL_EXCEPT_XMM ( VexGuestAMD64State* gst,
+                                                HWord addr )
+{
+   do_fxsave( gst, addr, False );
+}
+
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (writes guest state, reads guest mem) */
+VexEmNote amd64g_dirtyhelper_FXRSTOR_ALL_EXCEPT_XMM ( VexGuestAMD64State* gst,
+                                                      HWord addr )
+{
+   return do_fxrstor( gst, addr, False );
+}
+
+
 /* DIRTY HELPER (writes guest state) */
 /* Initialise the x87 FPU state as per 'finit'. */
 void amd64g_dirtyhelper_FINIT ( VexGuestAMD64State* gst )
@@ -2351,6 +2465,25 @@ VexEmNote amd64g_dirtyhelper_FRSTORS ( /*OUT*/VexGuestAMD64State* vex_state,
    return ew;
 }
 
+/* VISIBLE TO LIBVEX CLIENT */
+/* Do FXSAVE from the supplied VexGuestAMD64tate structure and store the
+   result at the given address which represents a buffer of at least 416
+   bytes. Saves also XMM registers. */
+void LibVEX_GuestAMD64_fxsave ( /*IN*/VexGuestAMD64State* gst,
+                                /*OUT*/HWord fp_state )
+{
+   do_fxsave( gst, fp_state, True );
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+/* Do FXRSTOR from the supplied address and store read values to the given
+   VexGuestAMD64State structure. Restores also XMM registers. */
+VexEmNote LibVEX_GuestAMD64_fxrstor ( /*IN*/HWord fp_state,
+                                      /*MOD*/VexGuestAMD64State* gst )
+{
+   return do_fxrstor( gst, fp_state, True );
+}
+
 
 /*---------------------------------------------------------------*/
 /*--- Misc integer helpers, including rotates and CPUID.      ---*/
index add943d76acc1695e5eb285ca5ce5ae98f95ea55..4cec1ad867265e3e1af63aa3ef5406615e623843 100644 (file)
@@ -2146,18 +2146,18 @@ static const HChar* nameGrp8 ( Int opc_aux )
    return grp8_names[opc_aux];
 }
 
-//.. static const HChar* nameSReg ( UInt sreg )
-//.. {
-//..    switch (sreg) {
-//..       case R_ES: return "%es";
-//..       case R_CS: return "%cs";
-//..       case R_SS: return "%ss";
-//..       case R_DS: return "%ds";
-//..       case R_FS: return "%fs";
-//..       case R_GS: return "%gs";
-//..       default: vpanic("nameSReg(x86)");
-//..    }
-//.. }
+static const HChar* nameSReg ( UInt sreg )
+{
+   switch (sreg) {
+      case R_ES: return "%es";
+      case R_CS: return "%cs";
+      case R_SS: return "%ss";
+      case R_DS: return "%ds";
+      case R_FS: return "%fs";
+      case R_GS: return "%gs";
+      default: vpanic("nameSReg(amd64)");
+   }
+}
 
 static const HChar* nameMMXReg ( Int mmxreg )
 {
@@ -8615,8 +8615,57 @@ ULong dis_xadd_G_E ( /*OUT*/Bool* decode_ok,
 //..       return len+delta0;
 //..    }
 //.. }
-//.. 
-//.. 
+
+/* Handle move instructions of the form
+      mov S, E  meaning
+      mov sreg, reg-or-mem
+   Is passed the a ptr to the modRM byte, and the data size.  Returns
+   the address advanced completely over this instruction.
+
+   VEX does not currently simulate segment registers on AMD64 which means that
+   instead of moving a value of a segment register, zero is moved to the
+   destination.  The zero value represents a null (unused) selector.  This is
+   not correct (especially for the %cs, %fs and %gs registers) but it seems to
+   provide a sufficient simulation for currently seen programs that use this
+   instruction.  If some program actually decides to use the obtained segment
+   selector for something meaningful then the zero value should be a clear
+   indicator that there is some problem.
+
+   S(src) is sreg.
+   E(dst) is reg-or-mem
+
+   If E is reg, -->    PUT $0, %E
+
+   If E is mem, -->    (getAddr E) -> tmpa
+                       ST $0, (tmpa)
+*/
+static
+ULong dis_mov_S_E ( const VexAbiInfo* vbi,
+                    Prefix      pfx,
+                    Int         size,
+                    Long        delta0 )
+{
+   Int   len;
+   UChar rm = getUChar(delta0);
+   HChar dis_buf[50];
+
+   if (epartIsReg(rm)) {
+      putIRegE(size, pfx, rm, mkU(szToITy(size), 0));
+      DIP("mov %s,%s\n", nameSReg(gregOfRexRM(pfx, rm)),
+                         nameIRegE(size, pfx, rm));
+      return 1+delta0;
+   }
+
+   /* E refers to memory */
+   {
+      IRTemp addr = disAMode(&len, vbi, pfx, delta0, dis_buf, 0);
+      storeLE(mkexpr(addr), mkU16(0));
+      DIP("mov %s,%s\n", nameSReg(gregOfRexRM(pfx, rm)),
+                         dis_buf);
+      return len+delta0;
+   }
+}
+
 //.. static 
 //.. void dis_push_segreg ( UInt sreg, Int sz )
 //.. {
@@ -19925,6 +19974,11 @@ Long dis_ESC_NONE (
       delta = dis_mov_E_G(vbi, pfx, sz, delta);
       return delta;
 
+   case 0x8C: /* MOV S,E -- MOV from a SEGMENT REGISTER */
+      if (haveF2orF3(pfx)) goto decode_failure;
+      delta = dis_mov_S_E(vbi, pfx, sz, delta);
+      return delta;
+
    case 0x8D: /* LEA M,Gv */
       if (haveF2orF3(pfx)) goto decode_failure;
       if (sz != 4 && sz != 8)
@@ -20534,6 +20588,18 @@ Long dis_ESC_NONE (
       DIP("int $0x3\n");
       return delta;
 
+   case 0xCD: /* INT imm8 */
+      d64 = getUChar(delta); delta++;
+
+      /* Handle int $0xD2 (Solaris fasttrap syscalls). */
+      if (d64 == 0xD2) {
+         jmp_lit(dres, Ijk_Sys_int210, guest_RIP_bbstart + delta);
+         vassert(dres->whatNext == Dis_StopHere);
+         DIP("int $0xD2\n");
+         return delta;
+      }
+      goto decode_failure;
+
    case 0xD0: { /* Grp2 1,Eb */
       Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
index 7b43c0ada98856a999105151a809fa2b0635e434..712aa66600d6f563ceab67afb3a66860d4be065e 100644 (file)
@@ -194,6 +194,15 @@ extern VexEmNote
 #define X86G_CC_MASK_C    (1 << X86G_CC_SHIFT_C)
 #define X86G_CC_MASK_P    (1 << X86G_CC_SHIFT_P)
 
+/* additional eflags masks */
+#define X86G_CC_SHIFT_ID  21
+#define X86G_CC_SHIFT_AC  18
+#define X86G_CC_SHIFT_D   10
+
+#define X86G_CC_MASK_ID   (1 << X86G_CC_SHIFT_ID)
+#define X86G_CC_MASK_AC   (1 << X86G_CC_SHIFT_AC)
+#define X86G_CC_MASK_D    (1 << X86G_CC_SHIFT_D)
+
 /* FPU flag masks */
 #define X86G_FC_SHIFT_C3   14
 #define X86G_FC_SHIFT_C2   10
index a3d6a84fe772a9f772b5d9c8795e5983155ae8dd..1d5cfaef8af7601da8d174863c4b51b0257dd926 100644 (file)
@@ -724,15 +724,52 @@ UInt LibVEX_GuestX86_get_eflags ( /*IN*/const VexGuestX86State* vex_state )
    UInt dflag = vex_state->guest_DFLAG;
    vassert(dflag == 1 || dflag == 0xFFFFFFFF);
    if (dflag == 0xFFFFFFFF)
-      eflags |= (1<<10);
+      eflags |= X86G_CC_MASK_D;
    if (vex_state->guest_IDFLAG == 1)
-      eflags |= (1<<21);
+      eflags |= X86G_CC_MASK_ID;
    if (vex_state->guest_ACFLAG == 1)
-      eflags |= (1<<18);
+      eflags |= X86G_CC_MASK_AC;
                                             
    return eflags;
 }
 
+/* VISIBLE TO LIBVEX CLIENT */
+void
+LibVEX_GuestX86_put_eflags ( UInt eflags,
+                             /*MOD*/VexGuestX86State* vex_state )
+{
+   /* D flag */
+   if (eflags & X86G_CC_MASK_D) {
+      vex_state->guest_DFLAG = 0xFFFFFFFF;
+      eflags &= ~X86G_CC_MASK_D;
+   }
+   else
+      vex_state->guest_DFLAG = 1;
+
+   /* ID flag */
+   if (eflags & X86G_CC_MASK_ID) {
+      vex_state->guest_IDFLAG = 1;
+      eflags &= ~X86G_CC_MASK_ID;
+   }
+   else
+      vex_state->guest_IDFLAG = 0;
+
+   /* AC flag */
+   if (eflags & X86G_CC_MASK_AC) {
+      vex_state->guest_ACFLAG = 1;
+      eflags &= ~X86G_CC_MASK_AC;
+   }
+   else
+      vex_state->guest_ACFLAG = 0;
+
+   UInt cc_mask = X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z |
+                  X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P;
+   vex_state->guest_CC_OP   = X86G_CC_OP_COPY;
+   vex_state->guest_CC_DEP1 = eflags & cc_mask;
+   vex_state->guest_CC_DEP2 = 0;
+   vex_state->guest_CC_NDEP = 0;
+}
+
 /* VISIBLE TO LIBVEX CLIENT */
 void
 LibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag,
@@ -1835,7 +1872,7 @@ VexEmNote x86g_dirtyhelper_FXRSTOR ( VexGuestX86State* gst, HWord addr )
 
      warnXMM = (VexEmNote)(w64 >> 32);
 
-     gst->guest_SSEROUND = (UInt)w64;
+     gst->guest_SSEROUND = w64 & 0xFFFFFFFF;
    }
 
    /* Prefer an X87 emwarn over an XMM one, if both exist. */
@@ -1880,6 +1917,42 @@ VexEmNote x86g_dirtyhelper_FLDENV ( VexGuestX86State* gst, HWord addr )
    return do_put_x87( False/*don't move regs*/, (UChar*)addr, gst);
 }
 
+/* VISIBLE TO LIBVEX CLIENT */
+/* Do x87 save from the supplied VexGuestX86State structure and store the
+   result at the given address which represents a buffer of at least 108
+   bytes. */
+void LibVEX_GuestX86_get_x87 ( /*IN*/VexGuestX86State* vex_state,
+                               /*OUT*/UChar* x87_state )
+{
+   do_get_x87 ( vex_state, x87_state );
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+/* Do x87 restore from the supplied address and store read values to the given
+   VexGuestX86State structure. */
+VexEmNote LibVEX_GuestX86_put_x87 ( /*IN*/UChar* x87_state,
+                                    /*MOD*/VexGuestX86State* vex_state )
+{
+   return do_put_x87 ( True/*moveRegs*/, x87_state, vex_state );
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+/* Return mxcsr from the supplied VexGuestX86State structure. */
+UInt LibVEX_GuestX86_get_mxcsr ( /*IN*/VexGuestX86State* vex_state )
+{
+   return x86g_create_mxcsr ( vex_state->guest_SSEROUND );
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+/* Modify the given VexGuestX86State structure according to the passed mxcsr
+   value. */
+VexEmNote LibVEX_GuestX86_put_mxcsr ( /*IN*/UInt mxcsr,
+                                      /*MOD*/VexGuestX86State* vex_state)
+{
+   ULong w64 = x86g_check_ldmxcsr( mxcsr );
+   vex_state->guest_SSEROUND = w64 & 0xFFFFFFFF;
+   return (VexEmNote)(w64 >> 32);
+}
 
 /*---------------------------------------------------------------*/
 /*--- Misc integer helpers, including rotates and CPUID.      ---*/
index 24bbd7f8fd90053b132f91ae7c154577c5a86065..9d8f15e21dd9f10447d6d538e847ab3973f63b27 100644 (file)
@@ -13366,36 +13366,38 @@ DisResult disInstr_X86_WRK (
       }
 
       /* Handle int $0x80 (linux syscalls), int $0x81 and $0x82
-         (darwin syscalls).  As part of this, note where we are, so we
+         (darwin syscalls), int $0x91 (Solaris syscalls) and int $0xD2
+         (Solaris fasttrap syscalls).  As part of this, note where we are, so we
          can back up the guest to this point if the syscall needs to
          be restarted. */
-      if (d32 == 0x80) {
-         stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL,
-                           mkU32(guest_EIP_curr_instr) ) );
-         jmp_lit(&dres, Ijk_Sys_int128, ((Addr32)guest_EIP_bbstart)+delta);
-         vassert(dres.whatNext == Dis_StopHere);
-         DIP("int $0x80\n");
+      IRJumpKind jump_kind;
+      switch (d32) {
+      case 0x80:
+         jump_kind = Ijk_Sys_int128;
          break;
-      }
-      if (d32 == 0x81) {
-         stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL,
-                           mkU32(guest_EIP_curr_instr) ) );
-         jmp_lit(&dres, Ijk_Sys_int129, ((Addr32)guest_EIP_bbstart)+delta);
-         vassert(dres.whatNext == Dis_StopHere);
-         DIP("int $0x81\n");
+      case 0x81:
+         jump_kind = Ijk_Sys_int129;
          break;
-      }
-      if (d32 == 0x82) {
-         stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL,
-                           mkU32(guest_EIP_curr_instr) ) );
-         jmp_lit(&dres, Ijk_Sys_int130, ((Addr32)guest_EIP_bbstart)+delta);
-         vassert(dres.whatNext == Dis_StopHere);
-         DIP("int $0x82\n");
+      case 0x82:
+         jump_kind = Ijk_Sys_int130;
+         break;
+      case 0x91:
+         jump_kind = Ijk_Sys_int145;
+         break;
+      case 0xD2:
+         jump_kind = Ijk_Sys_int210;
          break;
+      default:
+         /* none of the above */
+         goto decode_failure;
       }
 
-      /* none of the above */
-      goto decode_failure;
+      stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL,
+                        mkU32(guest_EIP_curr_instr) ) );
+      jmp_lit(&dres, jump_kind, ((Addr32)guest_EIP_bbstart)+delta);
+      vassert(dres.whatNext == Dis_StopHere);
+      DIP("int $0x%x\n", (Int)d32);
+      break;
 
    /* ------------------------ Jcond, byte offset --------- */
 
@@ -15342,7 +15344,7 @@ DisResult disInstr_X86_WRK (
 
       case 0x05: /* AMD's syscall */
          stmt( IRStmt_Put( OFFB_IP_AT_SYSCALL,
-              mkU32(guest_EIP_curr_instr) ) );
+                           mkU32(guest_EIP_curr_instr) ) );
          jmp_lit(&dres, Ijk_Sys_syscall, ((Addr32)guest_EIP_bbstart)+delta);
          vassert(dres.whatNext == Dis_StopHere);
          DIP("syscall\n");
index 3928d30ff59b0aac59207fb6b7289d71b183c221..3f1bb40cbe973852e48d8c2acc0d442798283a37 100644 (file)
@@ -3004,6 +3004,7 @@ Int emit_AMD64Instr ( /*MB_MOD*/Bool* is_profInc,
          case Ijk_ClientReq:   trcval = VEX_TRC_JMP_CLIENTREQ;   break;
          case Ijk_Sys_syscall: trcval = VEX_TRC_JMP_SYS_SYSCALL; break;
          case Ijk_Sys_int32:   trcval = VEX_TRC_JMP_SYS_INT32;   break;
+         case Ijk_Sys_int210:  trcval = VEX_TRC_JMP_SYS_INT210;  break;
          case Ijk_Yield:       trcval = VEX_TRC_JMP_YIELD;       break;
          case Ijk_EmWarn:      trcval = VEX_TRC_JMP_EMWARN;      break;
          case Ijk_MapFail:     trcval = VEX_TRC_JMP_MAPFAIL;     break;
index 3403d54563af7fc2f67f0efa99c5ef05830ba67b..9d9d78e35149969fe1ca65ad6c8420c58d5b02fd 100644 (file)
@@ -4774,6 +4774,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
          case Ijk_SigSEGV:
          case Ijk_SigTRAP:
          case Ijk_Sys_syscall:
+         case Ijk_Sys_int210:
          case Ijk_InvalICache:
          case Ijk_Yield:
          {
@@ -4869,6 +4870,7 @@ static void iselNext ( ISelEnv* env,
       case Ijk_SigSEGV:
       case Ijk_SigTRAP:
       case Ijk_Sys_syscall:
+      case Ijk_Sys_int210:
       case Ijk_InvalICache:
       case Ijk_Yield: {
          HReg        r     = iselIntExpr_R(env, next);
index 29c60236a92111ca761aab899d471a9bd92d1f69..ac73a3187c9efbb1f80e17159ee7d9b4c0093d56 100644 (file)
@@ -2560,6 +2560,8 @@ Int emit_X86Instr ( /*MB_MOD*/Bool* is_profInc,
          case Ijk_Sys_int128:   trcval = VEX_TRC_JMP_SYS_INT128;   break;
          case Ijk_Sys_int129:   trcval = VEX_TRC_JMP_SYS_INT129;   break;
          case Ijk_Sys_int130:   trcval = VEX_TRC_JMP_SYS_INT130;   break;
+         case Ijk_Sys_int145:   trcval = VEX_TRC_JMP_SYS_INT145;   break;
+         case Ijk_Sys_int210:   trcval = VEX_TRC_JMP_SYS_INT210;   break;
          case Ijk_Sys_sysenter: trcval = VEX_TRC_JMP_SYS_SYSENTER; break;
          case Ijk_Yield:        trcval = VEX_TRC_JMP_YIELD;        break;
          case Ijk_EmWarn:       trcval = VEX_TRC_JMP_EMWARN;       break;
index 011cba568f554c76b2be4e00c5fd9c728a2486fc..c153065c43b3f6fcfc7c2eb489172ad7118378bc 100644 (file)
@@ -4285,6 +4285,8 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
          case Ijk_Sys_int128:
          case Ijk_Sys_int129:
          case Ijk_Sys_int130:
+         case Ijk_Sys_int145:
+         case Ijk_Sys_int210:
          case Ijk_Sys_syscall:
          case Ijk_Sys_sysenter:
          case Ijk_InvalICache:
@@ -4384,6 +4386,8 @@ static void iselNext ( ISelEnv* env,
       case Ijk_Sys_int128:
       case Ijk_Sys_int129:
       case Ijk_Sys_int130:
+      case Ijk_Sys_int145:
+      case Ijk_Sys_int210:
       case Ijk_Sys_syscall:
       case Ijk_Sys_sysenter:
       case Ijk_InvalICache:
index da851f518d1f8dbc82acc76fc25a1c4444b8986a..7f6b29f9bb34075575a91c8543cab567869b9148 100644 (file)
@@ -1520,6 +1520,8 @@ void ppIRJumpKind ( IRJumpKind kind )
       case Ijk_Sys_int128:    vex_printf("Sys_int128"); break;
       case Ijk_Sys_int129:    vex_printf("Sys_int129"); break;
       case Ijk_Sys_int130:    vex_printf("Sys_int130"); break;
+      case Ijk_Sys_int145:    vex_printf("Sys_int145"); break;
+      case Ijk_Sys_int210:    vex_printf("Sys_int210"); break;
       case Ijk_Sys_sysenter:  vex_printf("Sys_sysenter"); break;
       default:                vpanic("ppIRJumpKind");
    }
index 3543de9d62b8dde9ec067f6b2bfea8b3f3c5b0cd..d5c8bcdf0bd387cb6e903314422ed720f7935cd0 100644 (file)
@@ -324,11 +324,13 @@ void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai );
    guest_amd64_assume_fs_is_const
       guest is amd64-linux                ==> True
       guest is amd64-darwin               ==> False
+      guest is amd64-solaris              ==> True
       guest is other                      ==> inapplicable
 
    guest_amd64_assume_gs_is_const
       guest is amd64-darwin               ==> True
       guest is amd64-linux                ==> True
+      guest is amd64-solaris              ==> False
       guest is other                      ==> inapplicable
 
    guest_ppc_zap_RZ_at_blr
@@ -355,7 +357,7 @@ typedef
 
       /* AMD64 GUESTS only: should we translate %fs-prefixed
          instructions using the assumption that %fs always contains
-         the same value? (typically zero on linux) */
+         the same value? (typically zero on linux and solaris) */
       Bool guest_amd64_assume_fs_is_const;
 
       /* AMD64 GUESTS only: should we translate %gs-prefixed
index 1043b20c0d81c296fcd5896526d0399c6ea86f1f..630dfc8e456bb4e8a8ac854ae287fa04245480ab 100644 (file)
@@ -37,6 +37,7 @@
 #define __LIBVEX_PUB_GUEST_AMD64_H
 
 #include "libvex_basictypes.h"
+#include "libvex_emnote.h"
 
 
 /*---------------------------------------------------------------*/
@@ -90,8 +91,8 @@ typedef
          all the old x87 FPU gunk
          segment registers */
 
-      /* HACK to e.g. make tls on amd64-linux work.  %fs only ever seems to
-         hold a constant value (zero on linux main thread, 0x63 in other
+      /* HACK to e.g. make tls on amd64-linux/solaris work.  %fs only ever seems
+         to hold a constant value (zero on linux main thread, 0x63 in other
          threads), and so guest_FS_CONST holds
          the 64-bit offset associated with this constant %fs value. */
       /* 200 */ ULong guest_FS_CONST;
@@ -159,7 +160,7 @@ typedef
          %gs only ever seems to hold a constant value (e.g. 0x60 on darwin,
          0x6b on linux), and so guest_GS_CONST holds the 64-bit offset
          associated with this constant %gs value.  (A direct analogue
-         of the %fs-const hack for amd64-linux). */
+         of the %fs-const hack for amd64-linux/solaris). */
       ULong guest_GS_CONST;
 
       /* Needed for Darwin (but mandated for all guest architectures):
@@ -192,6 +193,11 @@ void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state );
 extern 
 ULong LibVEX_GuestAMD64_get_rflags ( /*IN*/const VexGuestAMD64State* vex_state );
 
+/* Put rflags into the given state. */
+extern
+void LibVEX_GuestAMD64_put_rflags ( ULong rflags,
+                                    /*MOD*/VexGuestAMD64State* vex_state );
+
 /* Set the carry flag in the given state to 'new_carry_flag', which
    should be zero or one. */
 extern
@@ -199,6 +205,18 @@ void
 LibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag,
                                 /*MOD*/VexGuestAMD64State* vex_state );
 
+/* Do FXSAVE from the supplied VexGuestAMD64tate structure and store the
+   result at the given address which represents a buffer of at least 416
+   bytes. */
+extern
+void LibVEX_GuestAMD64_fxsave ( /*IN*/VexGuestAMD64State* gst,
+                                /*OUT*/HWord fp_state );
+
+/* Do FXRSTOR from the supplied address and store read values to the given
+   VexGuestAMD64State structure. */
+extern
+VexEmNote LibVEX_GuestAMD64_fxrstor ( /*IN*/HWord fp_state,
+                                      /*MOD*/VexGuestAMD64State* gst );
 
 #endif /* ndef __LIBVEX_PUB_GUEST_AMD64_H */
 
index ac780ac652120a79b0946315201a63ca3cde3091..8f71ecd0befd20e1f9ff06daefbea9a5fe58fdd6 100644 (file)
@@ -37,6 +37,7 @@
 #define __LIBVEX_PUB_GUEST_X86_H
 
 #include "libvex_basictypes.h"
+#include "libvex_emnote.h"
 
 
 /*---------------------------------------------------------------*/
@@ -279,6 +280,11 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state );
 extern 
 UInt LibVEX_GuestX86_get_eflags ( /*IN*/const VexGuestX86State* vex_state );
 
+/* Put eflags into the given state. */
+extern
+void LibVEX_GuestX86_put_eflags ( UInt eflags,
+                                  /*MOD*/VexGuestX86State* vex_state );
+
 /* Set the carry flag in the given state to 'new_carry_flag', which
    should be zero or one. */
 extern
@@ -286,6 +292,29 @@ void
 LibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag,
                               /*MOD*/VexGuestX86State* vex_state );
 
+/* Do x87 save from the supplied VexGuestX86State structure and store the
+   result at the given address which represents a buffer of at least 108
+   bytes. */
+extern
+void LibVEX_GuestX86_get_x87 ( /*IN*/VexGuestX86State* vex_state,
+                               /*OUT*/UChar* x87_state );
+
+/* Do x87 restore from the supplied address and store read values to the given
+   VexGuestX86State structure. */
+extern
+VexEmNote LibVEX_GuestX86_put_x87 ( /*IN*/UChar* x87_state,
+                                    /*MOD*/VexGuestX86State* vex_state);
+
+/* Return mxcsr from the supplied VexGuestX86State structure. */
+extern
+UInt LibVEX_GuestX86_get_mxcsr ( /*IN*/VexGuestX86State* vex_state );
+
+/* Modify the given VexGuestX86State structure according to the passed mxcsr
+   value. */
+extern
+VexEmNote LibVEX_GuestX86_put_mxcsr ( /*IN*/UInt mxcsr,
+                                      /*MOD*/VexGuestX86State* vex_state);
+
 #endif /* ndef __LIBVEX_PUB_GUEST_X86_H */
 
 /*---------------------------------------------------------------*/
index 145caa481cf8e1cd7591406fdfa74b6683cdd0d3..67edc8a7dd743a3d263b4d86ff26d8f0d89f2e25 100644 (file)
@@ -2282,6 +2282,8 @@ typedef
       Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
       Ijk_Sys_int129,     /* amd64/x86 'int $0x81' */
       Ijk_Sys_int130,     /* amd64/x86 'int $0x82' */
+      Ijk_Sys_int145,     /* amd64/x86 'int $0x91' */
+      Ijk_Sys_int210,     /* amd64/x86 'int $0xD2' */
       Ijk_Sys_sysenter    /* x86 'sysenter'.  guest_EIP becomes 
                              invalid at the point this happens. */
    }
index 82090424facb8cd32e35d6ad66331b02276f039c..1a1be945ae38761f748aec3eae1c92371635d0eb 100644 (file)
@@ -83,6 +83,8 @@
 #define VEX_TRC_JMP_SYS_INT128   77 /* do syscall before continuing */
 #define VEX_TRC_JMP_SYS_INT129   89 /* do syscall before continuing */
 #define VEX_TRC_JMP_SYS_INT130   91 /* do syscall before continuing */
+#define VEX_TRC_JMP_SYS_INT145  111 /* do syscall before continuing */
+#define VEX_TRC_JMP_SYS_INT210  113 /* do syscall before continuing */
 
 #define VEX_TRC_JMP_SYS_SYSENTER 79 /* do syscall before continuing */