]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 415757 - vex x86->IR: unhandled instruction bytes: 0x66 0xF 0xCE (bswapw).
authorJulian Seward <jseward@acm.org>
Wed, 22 Jan 2020 08:26:43 +0000 (09:26 +0100)
committerJulian Seward <jseward@acm.org>
Wed, 22 Jan 2020 08:31:57 +0000 (09:31 +0100)
Implement bswapw, even though the instruction does not officially exist.  Patch
from Alex Henrie (alexhenrie24@gmail.com).

VEX/priv/guest_x86_toIR.c
none/tests/x86/Makefile.am
none/tests/x86/bswapw.c [new file with mode: 0644]
none/tests/x86/bswapw.stderr.exp [new file with mode: 0644]
none/tests/x86/bswapw.stdout.exp [new file with mode: 0644]
none/tests/x86/bswapw.vgtest [new file with mode: 0644]

index 01bcc8a95241641a12ecb1afcd974c2a9dba74f4..5d6e6dc64fddbe379c3322b9d099be259522bb5e 100644 (file)
@@ -14676,15 +14676,21 @@ DisResult disInstr_X86_WRK (
       case 0xCD:
       case 0xCE:
       case 0xCF: /* BSWAP %edi */
-         /* AFAICS from the Intel docs, this only exists at size 4. */
-         if (sz != 4) goto decode_failure;
-         
-         t1 = newTemp(Ity_I32);
-         assign( t1, getIReg(4, opc-0xC8) );
-         t2 = math_BSWAP(t1, Ity_I32);
-
-         putIReg(4, opc-0xC8, mkexpr(t2));
-         DIP("bswapl %s\n", nameIReg(4, opc-0xC8));
+         /* According to the Intel and AMD docs, 16-bit BSWAP is undefined.
+          * However, the result of a 16-bit BSWAP is always zero in every Intel
+          * and AMD CPU, and some software depends on this behavior. */
+         if (sz == 2) {
+            putIReg(2, opc-0xC8, mkU16(0));
+            DIP("bswapw %s\n", nameIReg(2, opc-0xC8));
+         } else if (sz == 4) {
+            t1 = newTemp(Ity_I32);
+            assign( t1, getIReg(4, opc-0xC8) );
+            t2 = math_BSWAP(t1, Ity_I32);
+            putIReg(4, opc-0xC8, mkexpr(t2));
+            DIP("bswapl %s\n", nameIReg(4, opc-0xC8));
+         } else {
+            goto decode_failure;
+         }
          break;
 
       /* =-=-=-=-=-=-=-=-=- BT/BTS/BTR/BTC =-=-=-=-=-=-= */
index bc9615ec147648d00f958e9862d5dc4997d970c3..4086cd8348d5fbd8ed1d5ee10dc4b4d87ba41ec7 100644 (file)
@@ -35,6 +35,7 @@ EXTRA_DIST = \
        aad_aam.stdout.exp aad_aam.stderr.exp aad_aam.vgtest \
        badseg.stderr.exp badseg.stdout.exp badseg.stdout.exp-solaris \
        badseg.vgtest \
+       bswapw.stderr.exp bswapw.stdout.exp bswapw.vgtest \
        bt_everything.stderr.exp bt_everything.stdout.exp bt_everything.vgtest \
        bt_literal.stderr.exp bt_literal.stdout.exp bt_literal.vgtest \
        bug125959-x86.stderr.exp bug125959-x86.stdout.exp bug125959-x86.vgtest \
@@ -85,6 +86,7 @@ check_PROGRAMS = \
        aad_aam \
        allexec \
        badseg \
+       bswapw \
        bt_everything \
        bt_literal \
        bug125959-x86 \
diff --git a/none/tests/x86/bswapw.c b/none/tests/x86/bswapw.c
new file mode 100644 (file)
index 0000000..adb0bf6
--- /dev/null
@@ -0,0 +1,31 @@
+
+#include <stdio.h>
+
+typedef  unsigned int  UInt;
+
+int main ( void )
+{
+
+#define GO16(REG,VALUE) \
+      value = VALUE; \
+      __asm__ __volatile__( \
+         "pushl %%" REG " \n\t" \
+         "movl 0(" "%0" "), %%" REG " \n\t" \
+         ".byte 0x66 \n\t" "bswapl %%" REG "\n\t" \
+         "movl %%" REG ", 0(" "%0" ") \n\t" \
+         "popl %%" REG "\n" \
+             : : "r" (&value) : REG, "memory", "cc" \
+      ); \
+      printf("0x%08x\n", value)
+
+   UInt value;
+   GO16("eax", 0x12345678);
+   GO16("ebx", 0x23456789);
+   GO16("ecx", 0x3456789a);
+   GO16("edx", 0x456789ab);
+   GO16("esi", 0x56789abc);
+   GO16("edi", 0x6789abcd);
+   //GO16("ebp", 0x789abcde); // The compiler complains
+
+   return 0;
+}
diff --git a/none/tests/x86/bswapw.stderr.exp b/none/tests/x86/bswapw.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/x86/bswapw.stdout.exp b/none/tests/x86/bswapw.stdout.exp
new file mode 100644 (file)
index 0000000..a59b9a0
--- /dev/null
@@ -0,0 +1,6 @@
+0x12340000
+0x23450000
+0x34560000
+0x45670000
+0x56780000
+0x67890000
diff --git a/none/tests/x86/bswapw.vgtest b/none/tests/x86/bswapw.vgtest
new file mode 100644 (file)
index 0000000..0d2d920
--- /dev/null
@@ -0,0 +1,2 @@
+prog: bswapw
+vgopts: -q