From: Julian Seward Date: Wed, 3 Dec 2008 21:29:59 +0000 (+0000) Subject: Initial VEX-end support for Darwin (x86 and amd64). X-Git-Tag: svn/VALGRIND_3_4_1^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4c82569cedce75fdce8e462c81fe3a863af911e7;p=thirdparty%2Fvalgrind.git Initial VEX-end support for Darwin (x86 and amd64). git-svn-id: svn://svn.valgrind.org/vex/trunk@1874 --- diff --git a/VEX/Makefile b/VEX/Makefile index e0f3085b01..ff238dea8a 100644 --- a/VEX/Makefile +++ b/VEX/Makefile @@ -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: diff --git a/VEX/priv/guest-amd64/ghelpers.c b/VEX/priv/guest-amd64/ghelpers.c index 89dddef137..9d01403073 100644 --- a/VEX/priv/guest-amd64/ghelpers.c +++ b/VEX/priv/guest-amd64/ghelpers.c @@ -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; } diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index cef973bb57..5607dc24da 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -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. */ diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index a44e5e6b15..d7b95cb9fb 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -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; } diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 7551d2957d..4f7eec44d2 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -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 --------- */ diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index aeb08352d9..ae8c4ad675 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -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; diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index a09e08c84b..15084a0dd1 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -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"); } diff --git a/VEX/pub/libvex_guest_amd64.h b/VEX/pub/libvex_guest_amd64.h index 41c4ad6baa..2a49151b78 100644 --- a/VEX/pub/libvex_guest_amd64.h +++ b/VEX/pub/libvex_guest_amd64.h @@ -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 diff --git a/VEX/pub/libvex_guest_x86.h b/VEX/pub/libvex_guest_x86.h index 062482e3f5..620d39d6a9 100644 --- a/VEX/pub/libvex_guest_x86.h +++ b/VEX/pub/libvex_guest_x86.h @@ -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; diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 4fa195df73..168b7d68f4 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -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. */ } diff --git a/VEX/pub/libvex_trc_values.h b/VEX/pub/libvex_trc_values.h index a227848887..aa1ef70cb2 100644 --- a/VEX/pub/libvex_trc_values.h +++ b/VEX/pub/libvex_trc_values.h @@ -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 */