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:
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. ---*/
/* 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;
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;
}
#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)
}
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. */
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;
}
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
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 --------- */
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;
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");
}
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;
}
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
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;
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. */
}
#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 */