Index: priv/guest_x86_defs.h =================================================================== --- priv/guest_x86_defs.h (revision 1965) +++ priv/guest_x86_defs.h (working copy) @@ -164,6 +164,8 @@ extern void x86g_dirtyhelper_OUT ( UInt portno, UInt data, UInt sz/*1,2 or 4*/ ); +void x86g_dirtyhelper_SxDT ( void* address, ULong op /* 0 or 1 */ ); + extern VexEmWarn x86g_dirtyhelper_FXRSTOR ( VexGuestX86State*, HWord ); Index: priv/guest_amd64_helpers.c =================================================================== --- priv/guest_amd64_helpers.c (revision 1965) +++ priv/guest_amd64_helpers.c (working copy) @@ -2229,6 +2229,28 @@ # endif } +/* CALLED FROM GENERATED CODE */ +/* DIRTY HELPER (non-referentially-transparent) */ +/* Horrible hack. On non-amd64 platforms, do nothing. */ +/* op = 0: call the native SGDT instruction. + op = 1: call the native SIDT instruction. +*/ +void amd64g_dirtyhelper_SxDT ( void *address, ULong op ) { +# if defined(__x86_64__) + switch (op) { + case 0: + __asm__ __volatile__("sgdt %0" : "=m" (*address)); + break; + case 1: + __asm__ __volatile__("sidt %0" : "=m" (*address)); + break; + default: + break; + } +# else + /* do nothing */ +# endif +} /*---------------------------------------------------------------*/ /*--- Helpers for MMX/SSE/SSE2. ---*/ Index: priv/guest_amd64_toIR.c =================================================================== --- priv/guest_amd64_toIR.c (revision 1965) +++ priv/guest_amd64_toIR.c (working copy) @@ -16752,6 +16752,36 @@ DIP("{f}emms\n"); break; + /* =-=-=-=-=-=-=-=-=- SGDT and SIDT =-=-=-=-=-=-=-=-=-=-= */ + case 0x01: /* 0F 01 /0 -- SGDT */ + /* 0F 01 /1 -- SIDT */ + + modrm = getUChar(delta); + addr = disAMode ( &alen, vbi, pfx, delta, dis_buf, 0 ); + delta += alen; + if (epartIsReg(modrm)) goto decode_failure; + if (gregLO3ofRM(modrm) != 0 && gregLO3ofRM(modrm) != 1) + goto decode_failure; + switch (gregLO3ofRM(modrm)) { + case 0: DIP("sgdt %p\n", addr); break; + case 1: DIP("sidt %p\n", addr); break; + default: vassert(0); /*NOTREACHED*/ + } + + IRDirty* d = unsafeIRDirty_0_N ( + 0/*regparms*/, + "amd64g_dirtyhelper_SxDT", + &amd64g_dirtyhelper_SxDT, + mkIRExprVec_2( mkexpr(addr), + mkU64(gregLO3ofRM(modrm)) ) + ); + /* declare we're writing memory */ + d->mFx = Ifx_Write; + d->mAddr = mkexpr(addr); + d->mSize = 6; + stmt( IRStmt_Dirty(d) ); + break; + /* =-=-=-=-=-=-=-=-=- unimp2 =-=-=-=-=-=-=-=-=-=-= */ default: Index: priv/guest_amd64_defs.h =================================================================== --- priv/guest_amd64_defs.h (revision 1965) +++ priv/guest_amd64_defs.h (working copy) @@ -164,6 +164,7 @@ extern void amd64g_dirtyhelper_OUT ( ULong portno, ULong data, ULong sz/*1,2 or 4*/ ); +void amd64g_dirtyhelper_SxDT ( void* address, ULong op /* 0 or 1 */ ); //extern void amd64g_dirtyhelper_CPUID_sse0 ( VexGuestAMD64State* ); //extern void amd64g_dirtyhelper_CPUID_sse1 ( VexGuestAMD64State* ); //extern void amd64g_dirtyhelper_CPUID_sse2 ( VexGuestAMD64State* ); Index: priv/guest_x86_helpers.c =================================================================== --- priv/guest_x86_helpers.c (revision 1965) +++ priv/guest_x86_helpers.c (working copy) @@ -2364,6 +2364,28 @@ # endif } +/* CALLED FROM GENERATED CODE */ +/* DIRTY HELPER (non-referentially-transparent) */ +/* Horrible hack. On non-x86 platforms, do nothing. */ +/* op = 0: call the native SGDT instruction. + op = 1: call the native SIDT instruction. +*/ +void x86g_dirtyhelper_SxDT ( void *address, ULong op ) { +# if defined(__i386__) + switch (op) { + case 0: + __asm__ __volatile__("sgdt %0" : "=m" (*address)); + break; + case 1: + __asm__ __volatile__("sidt %0" : "=m" (*address)); + break; + default: + break; + } +# else + /* do nothing */ +# endif +} /*---------------------------------------------------------------*/ /*--- Helpers for MMX/SSE/SSE2. ---*/ Index: priv/guest_x86_toIR.c =================================================================== --- priv/guest_x86_toIR.c (revision 1965) +++ priv/guest_x86_toIR.c (working copy) @@ -14777,6 +14777,36 @@ DIP("emms\n"); break; + /* =-=-=-=-=-=-=-=-=- SGDT and SIDT =-=-=-=-=-=-=-=-=-=-= */ + case 0x01: /* 0F 01 /0 -- SGDT */ + /* 0F 01 /1 -- SIDT */ + + modrm = getUChar(delta); + addr = disAMode ( &alen, sorb, delta, dis_buf ); + delta += alen; + if (epartIsReg(modrm)) goto decode_failure; + if (gregOfRM(modrm) != 0 && gregOfRM(modrm) != 1) + goto decode_failure; + switch (gregOfRM(modrm)) { + case 0: DIP("sgdt %p\n", addr); break; + case 1: DIP("sidt %p\n", addr); break; + default: vassert(0); /*NOTREACHED*/ + } + + IRDirty* d = unsafeIRDirty_0_N ( + 0/*regparms*/, + "x86g_dirtyhelper_SxDT", + &x86g_dirtyhelper_SxDT, + mkIRExprVec_2( mkexpr(addr), + mkU64(gregOfRM(modrm)) ) + ); + /* declare we're writing memory */ + d->mFx = Ifx_Write; + d->mAddr = mkexpr(addr); + d->mSize = 6; + stmt( IRStmt_Dirty(d) ); + break; + /* =-=-=-=-=-=-=-=-=- unimp2 =-=-=-=-=-=-=-=-=-=-= */ default: