]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Initial VEX-end support for Darwin (x86 and amd64).
authorJulian Seward <jseward@acm.org>
Wed, 3 Dec 2008 21:29:59 +0000 (21:29 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 3 Dec 2008 21:29:59 +0000 (21:29 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@1874

VEX/Makefile
VEX/priv/guest-amd64/ghelpers.c
VEX/priv/guest-amd64/toIR.c
VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c
VEX/priv/host-x86/hdefs.c
VEX/priv/ir/irdefs.c
VEX/pub/libvex_guest_amd64.h
VEX/pub/libvex_guest_x86.h
VEX/pub/libvex_ir.h
VEX/pub/libvex_trc_values.h

index e0f3085b011d71daf235b75ff1c735792bc1963a..ff238dea8a2f159d2914dc7bce30d9ba97f56325 100644 (file)
@@ -125,6 +125,18 @@ TAG_amd64_linux:
        if [ ! -f TAG_amd64_linux ] ; then rm -f $(LIB_OBJS) TAG_* libvex.a ; fi
        touch TAG_amd64_linux
 
+libvex_x86_darwin.a: TAG_x86_darwin libvex.a
+       mv -f libvex.a libvex_x86_darwin.a
+TAG_x86_darwin:
+       if [ ! -f TAG_x86_darwin ] ; then rm -f $(LIB_OBJS) TAG_* libvex.a ; fi
+       touch TAG_x86_darwin
+
+libvex_amd64_darwin.a: TAG_amd64_darwin libvex.a
+       mv -f libvex.a libvex_amd64_darwin.a
+TAG_amd64_darwin:
+       if [ ! -f TAG_amd64_darwin ] ; then rm -f $(LIB_OBJS) TAG_* libvex.a ; fi
+       touch TAG_amd64_darwin
+
 libvex_ppc32_linux.a: TAG_ppc32_linux libvex.a
        mv -f libvex.a libvex_ppc32_linux.a
 TAG_ppc32_linux:
index 89dddef1377a78c24a44af292920ca1714efeb5a..9d01403073e05ab6fdc163afdc9fd6ff5f8625ff 100644 (file)
@@ -838,6 +838,28 @@ ULong LibVEX_GuestAMD64_get_rflags ( /*IN*/VexGuestAMD64State* vex_state )
    return rflags;
 }
 
+/* VISIBLE TO LIBVEX CLIENT */
+void
+LibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag,
+                               /*MOD*/VexGuestAMD64State* vex_state )
+{
+   ULong oszacp = amd64g_calculate_rflags_all_WRK(
+                     vex_state->guest_CC_OP,
+                     vex_state->guest_CC_DEP1,
+                     vex_state->guest_CC_DEP2,
+                     vex_state->guest_CC_NDEP
+                  );
+   if (new_carry_flag & 1) {
+      oszacp |= AMD64G_CC_MASK_C;
+   } else {
+      oszacp &= ~AMD64G_CC_MASK_C;
+   }
+   vex_state->guest_CC_OP   = AMD64G_CC_OP_COPY;
+   vex_state->guest_CC_DEP1 = oszacp;
+   vex_state->guest_CC_DEP2 = 0;
+   vex_state->guest_CC_NDEP = 0;
+}
+
 
 /*---------------------------------------------------------------*/
 /*--- %rflags translation-time function specialisers.         ---*/
@@ -2225,8 +2247,6 @@ ULong amd64g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo )
 /* VISIBLE TO LIBVEX CLIENT */
 void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state )
 {
-   //Int i;
-
    vex_state->guest_RAX = 0;
    vex_state->guest_RCX = 0;
    vex_state->guest_RDX = 0;
@@ -2291,7 +2311,11 @@ void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state )
    vex_state->guest_TISTART = 0;
    vex_state->guest_TILEN   = 0;
 
-   vex_state->guest_NRADDR = 0;
+   vex_state->guest_NRADDR   = 0;
+   vex_state->guest_SC_CLASS = 0;
+   vex_state->guest_GS_0x60  = 0;
+
+   vex_state->padding = 0;
 }
 
 
index cef973bb57ec0ae70197b467130377a3c34eeaa3..5607dc24da8279a36f2bd28cb1995f9f408fd92c 100644 (file)
@@ -381,6 +381,7 @@ static void unimplemented ( HChar* str )
 #define OFFB_RIP       offsetof(VexGuestAMD64State,guest_RIP)
 
 #define OFFB_FS_ZERO   offsetof(VexGuestAMD64State,guest_FS_ZERO)
+#define OFFB_GS_0x60   offsetof(VexGuestAMD64State,guest_GS_0x60)
 
 #define OFFB_CC_OP     offsetof(VexGuestAMD64State,guest_CC_OP)
 #define OFFB_CC_DEP1   offsetof(VexGuestAMD64State,guest_CC_DEP1)
@@ -2008,7 +2009,10 @@ IRExpr* handleAddrOverrides ( Prefix pfx, IRExpr* virtual )
    }
 
    if (pfx & PFX_GS) {
-      unimplemented("amd64 %gs segment override");
+      /* Note that this is a darwin-kernel specific hack that relies
+         on the assumption that %gs is always 0x60. */
+      /* return virtual + guest_GS_0x60. */
+      virtual = binop(Iop_Add64, virtual, IRExpr_Get(OFFB_GS_0x60, Ity_I64));
    }
 
    /* cs, ds, es and ss are simply ignored in 64-bit mode. */
index a44e5e6b159e8e91fee108b6a3d196be35cbe40d..d7b95cb9fbc18ffe7ad2f7aa96dfdee76322a020 100644 (file)
@@ -2633,7 +2633,8 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
    vex_state->guest_TISTART = 0;
    vex_state->guest_TILEN   = 0;
 
-   vex_state->guest_NRADDR = 0;
+   vex_state->guest_NRADDR   = 0;
+   vex_state->guest_SC_CLASS = 0;
 }
 
 
index 7551d2957dce8324aa7a4cc494567634eb0f9304..4f7eec44d2e462f82c3fb623f8893d7ddd12539b 100644 (file)
@@ -12573,6 +12573,12 @@ DisResult disInstr_X86_WRK (
    case 0xCD: /* INT imm8 */
       d32 = getIByte(delta); delta++;
 
+      /* For any of the cases where we emit a jump (that is, for all
+         currently handled cases), it's important that all ArchRegs
+         carry their up-to-date value at this point.  So we declare an
+         end-of-block here, which forces any TempRegs caching ArchRegs
+         to be flushed. */
+
       /* Handle int $0x40 .. $0x43 by synthesising a segfault and a
          restart of this instruction (hence the "-2" two lines below,
          to get the restart EIP to be this instruction.  This is
@@ -12585,14 +12591,29 @@ DisResult disInstr_X86_WRK (
          break;
       }
 
-      if (d32 != 0x80) goto decode_failure;
-      /* It's important that all ArchRegs carry their up-to-date value
-         at this point.  So we declare an end-of-block here, which
-         forces any TempRegs caching ArchRegs to be flushed. */
-      jmp_lit(Ijk_Sys_int128,((Addr32)guest_EIP_bbstart)+delta);
-      dres.whatNext = Dis_StopHere;
-      DIP("int $0x80\n");
-      break;
+      /* Handle int $0x80 (linux syscalls), int $0x81 and $0x82
+         (darwin syscalls). */
+      if (d32 == 0x80) {
+         jmp_lit(Ijk_Sys_int128,((Addr32)guest_EIP_bbstart)+delta);
+         dres.whatNext = Dis_StopHere;
+         DIP("int $0x80\n");
+         break;
+      }
+      if (d32 == 0x81) {
+         jmp_lit(Ijk_Sys_int129,((Addr32)guest_EIP_bbstart)+delta);
+         dres.whatNext = Dis_StopHere;
+         DIP("int $0x81\n");
+         break;
+      }
+      if (d32 == 0x82) {
+         jmp_lit(Ijk_Sys_int130,((Addr32)guest_EIP_bbstart)+delta);
+         dres.whatNext = Dis_StopHere;
+         DIP("int $0x82\n");
+         break;
+      }
+
+      /* none of the above */
+      goto decode_failure;
 
    /* ------------------------ Jcond, byte offset --------- */
 
index aeb08352d9b7e25a8910e4def42b5188e475fa55..ae8c4ad6758539455ade141bf6fde573888fc2b1 100644 (file)
@@ -2276,6 +2276,12 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i,
          case Ijk_Sys_int128:
             *p++ = 0xBD;
             p = emit32(p, VEX_TRC_JMP_SYS_INT128); break;
+         case Ijk_Sys_int129:
+            *p++ = 0xBD;
+            p = emit32(p, VEX_TRC_JMP_SYS_INT129); break;
+         case Ijk_Sys_int130:
+            *p++ = 0xBD;
+            p = emit32(p, VEX_TRC_JMP_SYS_INT130); break;
          case Ijk_Yield: 
             *p++ = 0xBD;
             p = emit32(p, VEX_TRC_JMP_YIELD); break;
index a09e08c84badc84f78132e4a83bf24465d9a1a4f..15084a0dd10f15cc1a45e14d45cf11de68d5e267 100644 (file)
@@ -742,6 +742,8 @@ void ppIRJumpKind ( IRJumpKind kind )
       case Ijk_Sys_syscall:  vex_printf("Sys_syscall"); break;
       case Ijk_Sys_int32:    vex_printf("Sys_int32"); break;
       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_sysenter: vex_printf("Sys_sysenter"); break;
       default:               vpanic("ppIRJumpKind");
    }
index 41c4ad6baaf2de320ba24d45d9170f0dfd6c86fc..2a49151b78db357eaa490b81059be829f82b4ecc 100644 (file)
@@ -152,6 +152,15 @@ typedef
          replace-style ones. */
       ULong guest_NRADDR;
 
+      /* Used for Darwin syscall dispatching. */
+      ULong guest_SC_CLASS;
+
+      /* HACK to make tls on darwin work.  %gs only ever seems to
+         hold 0x60, and so guest_GS_0x60 holds the 64-bit offset
+         associated with a %gs value of 0x60.  (A direct analogue
+         of the %fs-zero hack for amd64-linux). */
+      ULong guest_GS_0x60;
+
       /* Padding to make it have an 16-aligned size */
       ULong padding;
    }
@@ -176,6 +185,13 @@ void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state );
 extern 
 ULong LibVEX_GuestAMD64_get_rflags ( /*IN*/VexGuestAMD64State* vex_state );
 
+/* Set the carry flag in the given state to 'new_carry_flag', which
+   should be zero or one. */
+extern
+void
+LibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag,
+                                /*MOD*/VexGuestAMD64State* vex_state );
+
 
 #if 0
 /* Convert a saved x87 FPU image (as created by fsave) and write it
index 062482e3f5983fda5f973d35e965c6064cd5d42f..620d39d6a9d10b8bc33ed77334171bc3026d7a6f 100644 (file)
@@ -220,8 +220,11 @@ typedef
          replace-style ones. */
       UInt guest_NRADDR;
 
+      /* Used for Darwin syscall dispatching. */
+      UInt guest_SC_CLASS;
+
       /* Padding to make it have an 16-aligned size */
-      UInt padding;
+      /* UInt padding; */
    }
    VexGuestX86State;
 
index 4fa195df73313313b86aeedbe91debcc58d4fed1..168b7d68f48b8e05adb1210ed11bf96f254028a4 100644 (file)
@@ -1217,6 +1217,8 @@ typedef
       Ijk_Sys_syscall,    /* amd64 'syscall', ppc 'sc' */
       Ijk_Sys_int32,      /* amd64/x86 'int $0x20' */
       Ijk_Sys_int128,     /* amd64/x86 'int $0x80' */
+      Ijk_Sys_int129,     /* amd64/x86 'int $0x81' */
+      Ijk_Sys_int130,     /* amd64/x86 'int $0x82' */
       Ijk_Sys_sysenter    /* x86 'sysenter'.  guest_EIP becomes 
                              invalid at the point this happens. */
    }
index a22784888727d9d76e41fb913548f2f12d8563c0..aa1ef70cb2abac3edbd8af181c17948c1b255375 100644 (file)
@@ -79,6 +79,9 @@
 #define VEX_TRC_JMP_SYS_SYSCALL  73 /* do syscall before continuing */
 #define VEX_TRC_JMP_SYS_INT32    75 /* do syscall before continuing */
 #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_SYSENTER 79 /* do syscall before continuing */
 
 #endif /* ndef __LIBVEX_TRC_VALUES_H */