From: Julian Seward Date: Sun, 10 Feb 2008 13:29:19 +0000 (+0000) Subject: Fix CPUID: X-Git-Tag: svn/VALGRIND_3_4_1^2~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd5303df462147cbd4f5acdd3449a6a301cc883b;p=thirdparty%2Fvalgrind.git Fix CPUID: - when EAX=4, output also depends on ECX - handle out-of-range EAX correctly git-svn-id: svn://svn.valgrind.org/vex/trunk@1810 --- diff --git a/VEX/priv/guest-amd64/ghelpers.c b/VEX/priv/guest-amd64/ghelpers.c index 3526f54552..e76ed0defb 100644 --- a/VEX/priv/guest-amd64/ghelpers.c +++ b/VEX/priv/guest-amd64/ghelpers.c @@ -1807,9 +1807,19 @@ void amd64g_dirtyhelper_CPUID ( VexGuestAMD64State* st ) case 0x00000003: SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); break; - case 0x00000004: - SET_ABCD(0x04000121, 0x01c0003f, 0x0000003f, 0x00000001); + case 0x00000004: { + switch (0xFFFFFFFF & st->guest_RCX) { + case 0x00000000: SET_ABCD(0x04000121, 0x01c0003f, + 0x0000003f, 0x00000001); break; + case 0x00000001: SET_ABCD(0x04000122, 0x01c0003f, + 0x0000003f, 0x00000001); break; + case 0x00000002: SET_ABCD(0x04004143, 0x03c0003f, + 0x00000fff, 0x00000001); break; + default: SET_ABCD(0x00000000, 0x00000000, + 0x00000000, 0x00000000); break; + } break; + } case 0x00000005: SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00000020); break; @@ -1826,6 +1836,7 @@ void amd64g_dirtyhelper_CPUID ( VexGuestAMD64State* st ) SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); break; case 0x0000000a: + unhandled_eax_value: SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); break; case 0x80000000: @@ -1855,15 +1866,8 @@ void amd64g_dirtyhelper_CPUID ( VexGuestAMD64State* st ) case 0x80000008: SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); break; - case 0x80860000: - SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); - break; - case 0xc0000000: - SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); - break; default: - SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); - break; + goto unhandled_eax_value; } # undef SET_ABCD } diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index 630fccc6ea..28083742ae 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -15337,7 +15337,7 @@ DisResult disInstr_AMD64_WRK ( d->fxState[1].fx = Ifx_Write; d->fxState[1].offset = OFFB_RBX; d->fxState[1].size = 8; - d->fxState[2].fx = Ifx_Write; + d->fxState[2].fx = Ifx_Modify; d->fxState[2].offset = OFFB_RCX; d->fxState[2].size = 8; d->fxState[3].fx = Ifx_Write; diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 8351120e51..2c900087ac 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -2124,9 +2124,19 @@ void x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st ) case 0x00000003: SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); break; - case 0x00000004: - SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); + case 0x00000004: { + switch (st->guest_ECX) { + case 0x00000000: SET_ABCD(0x04000121, 0x01c0003f, + 0x0000003f, 0x00000001); break; + case 0x00000001: SET_ABCD(0x04000122, 0x01c0003f, + 0x0000003f, 0x00000001); break; + case 0x00000002: SET_ABCD(0x04004143, 0x03c0003f, + 0x00000fff, 0x00000001); break; + default: SET_ABCD(0x00000000, 0x00000000, + 0x00000000, 0x00000000); break; + } break; + } case 0x00000005: SET_ABCD(0x00000040, 0x00000040, 0x00000003, 0x00000020); break; @@ -2143,6 +2153,7 @@ void x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st ) SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); break; case 0x0000000a: + unhandled_eax_value: SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); break; case 0x80000000: @@ -2172,15 +2183,8 @@ void x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st ) case 0x80000008: SET_ABCD(0x00003024, 0x00000000, 0x00000000, 0x00000000); break; - case 0x80860000: - SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); - break; - case 0xc0000000: - SET_ABCD(0x07280202, 0x00000000, 0x00000000, 0x00000000); - break; - default: - SET_ABCD(0x00000000, 0x00000000, 0x00000000, 0x00000000); - break; + default: + goto unhandled_eax_value; } # undef SET_ABCD } diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 86a9ac573b..343a4f6c03 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -13907,7 +13907,7 @@ DisResult disInstr_X86_WRK ( d->fxState[1].fx = Ifx_Write; d->fxState[1].offset = OFFB_EBX; d->fxState[1].size = 4; - d->fxState[2].fx = Ifx_Write; + d->fxState[2].fx = Ifx_Modify; d->fxState[2].offset = OFFB_ECX; d->fxState[2].size = 4; d->fxState[3].fx = Ifx_Write;