From 63c6fc6cacf82e6b39f7373d44c1e1e1a0a757fa Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 4 Jun 2019 12:45:20 -0700 Subject: [PATCH] i386: Check for reserved VEX.vvvv and EVEX.vvvv If VEX.vvvv and EVEX.vvvv are reserved, they must be all 1s, which are all 0s in inverted form. Add check for unused VEX.vvvv and EVEX.vvvv when disassembling VEX and EVEX instructions. gas/ PR binutils/24626 * testsuite/gas/i386/disassem.s: Add tests for reserved VEX.vvvv and EVEX.vvvv. * testsuite/gas/i386/x86-64-disassem.s: Likewise. * testsuite/gas/i386/disassem.d: Updated. * testsuite/gas/i386/x86-64-disassem.d: Likewise. opcodes/ PR binutils/24626 * i386-dis.c (print_insn): Check for unused VEX.vvvv and EVEX.vvvv when disassembling VEX and EVEX instructions. (OP_VEX): Set vex.register_specifier to 0 after readding vex.register_specifier. (OP_Vex_2src_1): Likewise. (OP_Vex_2src_2): Likewise. (OP_LWP_E): Likewise. (OP_EX_Vex): Don't check vex.register_specifier. (OP_XMM_Vex): Likewise. --- gas/ChangeLog | 9 +++++++++ gas/testsuite/gas/i386/disassem.d | 5 +++++ gas/testsuite/gas/i386/disassem.s | 2 ++ gas/testsuite/gas/i386/x86-64-disassem.d | 4 ++++ gas/testsuite/gas/i386/x86-64-disassem.s | 2 ++ opcodes/ChangeLog | 13 +++++++++++++ opcodes/i386-dis.c | 24 ++++++++++++++---------- 7 files changed, 49 insertions(+), 10 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 1a1b3ded24c..036d734dd98 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2019-06-04 H.J. Lu + + PR binutils/24626 + * testsuite/gas/i386/disassem.s: Add tests for reserved VEX.vvvv + and EVEX.vvvv. + * testsuite/gas/i386/x86-64-disassem.s: Likewise. + * testsuite/gas/i386/disassem.d: Updated. + * testsuite/gas/i386/x86-64-disassem.d: Likewise. + 2019-06-04 Igor Tsimbalist Lili Cui diff --git a/gas/testsuite/gas/i386/disassem.d b/gas/testsuite/gas/i386/disassem.d index 2f39662bfb1..ff9ee497e32 100644 --- a/gas/testsuite/gas/i386/disassem.d +++ b/gas/testsuite/gas/i386/disassem.d @@ -341,4 +341,9 @@ Disassembly of section \.text: [ ]*[a-f0-9]+:[ ]*6f[ ]*outsl %ds:\(%esi\),\(%dx\) [ ]*[a-f0-9]+:[ ]*c4 e1 f9 93[ ]*\(bad\)[ ]* [ ]*[a-f0-9]+:[ ]*3f[ ]*aas[ ]* +[ ]*[a-f0-9]+:[ ]*c4 e2 01 1c[ ]*\(bad\)[ ]* +[ ]*[a-f0-9]+:[ ]*41[ ]*inc[ ]*%ecx +[ ]*[a-f0-9]+:[ ]*37[ ]*aaa[ ]* +[ ]*[a-f0-9]+:[ ]*62 f2 ad 08 1c[ ]*\(bad\)[ ]* +[ ]*[a-f0-9]+:[ ]*01[ ]*.byte[ ]*0x1 #pass diff --git a/gas/testsuite/gas/i386/disassem.s b/gas/testsuite/gas/i386/disassem.s index 2e6c157c2c2..700208aa356 100644 --- a/gas/testsuite/gas/i386/disassem.s +++ b/gas/testsuite/gas/i386/disassem.s @@ -167,3 +167,5 @@ .byte 0xC4, 0xE1, 0xF9, 0x93, 0x9B .byte 0xC4, 0xE1, 0xF9, 0x93, 0x6F .byte 0xC4, 0xE1, 0xF9, 0x93, 0x3F +.byte 0xc4, 0xe2, 0x1, 0x1c, 0x41, 0x37 +.byte 0x62, 0xf2, 0xad, 0x08, 0x1c, 0x01 diff --git a/gas/testsuite/gas/i386/x86-64-disassem.d b/gas/testsuite/gas/i386/x86-64-disassem.d index f21bab004ab..c8277bf0eba 100644 --- a/gas/testsuite/gas/i386/x86-64-disassem.d +++ b/gas/testsuite/gas/i386/x86-64-disassem.d @@ -341,4 +341,8 @@ Disassembly of section \.text: [ ]*[a-f0-9]+:[ ]*6f[ ]*outsl %ds:\(%rsi\),\(%dx\) [ ]*[a-f0-9]+:[ ]*c4 e1 f9 93[ ]*\(bad\)[ ]* [ ]*[a-f0-9]+:[ ]*3f[ ]*\(bad\)[ ]* +[ ]*[a-f0-9]+:[ ]*c4 62 01 1c[ ]*\(bad\)[ ]* +[ ]*[a-f0-9]+:[ ]*41 37[ ]*rex.B \(bad\)[ ]* +[ ]*[a-f0-9]+:[ ]*62 72 ad 08 1c[ ]*\(bad\)[ ]* +[ ]*[a-f0-9]+:[ ]*01[ ]*.byte[ ]*0x1 #pass diff --git a/gas/testsuite/gas/i386/x86-64-disassem.s b/gas/testsuite/gas/i386/x86-64-disassem.s index 2e6c157c2c2..ade5e15c1db 100644 --- a/gas/testsuite/gas/i386/x86-64-disassem.s +++ b/gas/testsuite/gas/i386/x86-64-disassem.s @@ -167,3 +167,5 @@ .byte 0xC4, 0xE1, 0xF9, 0x93, 0x9B .byte 0xC4, 0xE1, 0xF9, 0x93, 0x6F .byte 0xC4, 0xE1, 0xF9, 0x93, 0x3F +.byte 0xc4, 0x62, 0x1, 0x1c, 0x41, 0x37 +.byte 0x62, 0x72, 0xad, 0x08, 0x1c, 0x01 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 0fa27c5b2b5..9f5b347c68f 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,16 @@ +2019-06-04 H.J. Lu + + PR binutils/24626 + * i386-dis.c (print_insn): Check for unused VEX.vvvv and + EVEX.vvvv when disassembling VEX and EVEX instructions. + (OP_VEX): Set vex.register_specifier to 0 after readding + vex.register_specifier. + (OP_Vex_2src_1): Likewise. + (OP_Vex_2src_2): Likewise. + (OP_LWP_E): Likewise. + (OP_EX_Vex): Don't check vex.register_specifier. + (OP_XMM_Vex): Likewise. + 2019-06-04 Igor Tsimbalist Lili Cui diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 18e6729ffb7..f5975398328 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -12155,6 +12155,14 @@ print_insn (bfd_vma pc, disassemble_info *info) } } + /* If VEX.vvvv and EVEX.vvvv are unused, they must be all 1s, which + are all 0s in inverted form. */ + if (need_vex && vex.register_specifier != 0) + { + (*info->fprintf_func) (info->stream, "(bad)"); + return end_codep - priv.the_buffer; + } + /* Check if the REX prefix is used. */ if (rex_ignored == 0 && (rex ^ rex_used) == 0 && last_rex_prefix >= 0) all_prefixes[last_rex_prefix] = 0; @@ -15921,6 +15929,7 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED) return; reg = vex.register_specifier; + vex.register_specifier = 0; if (address_mode != mode_64bit) reg &= 7; else if (vex.evex && !vex.v) @@ -16204,6 +16213,7 @@ OP_Vex_2src_1 (int bytemode, int sizeflag) if (vex.w) { unsigned int reg = vex.register_specifier; + vex.register_specifier = 0; if (address_mode != mode_64bit) reg &= 7; @@ -16221,6 +16231,7 @@ OP_Vex_2src_2 (int bytemode, int sizeflag) else { unsigned int reg = vex.register_specifier; + vex.register_specifier = 0; if (address_mode != mode_64bit) reg &= 7; @@ -16298,11 +16309,7 @@ static void OP_EX_Vex (int bytemode, int sizeflag) { if (modrm.mod != 3) - { - if (vex.register_specifier != 0) - BadOp (); - need_vex_reg = 0; - } + need_vex_reg = 0; OP_EX (bytemode, sizeflag); } @@ -16310,11 +16317,7 @@ static void OP_XMM_Vex (int bytemode, int sizeflag) { if (modrm.mod != 3) - { - if (vex.register_specifier != 0) - BadOp (); - need_vex_reg = 0; - } + need_vex_reg = 0; OP_XMM (bytemode, sizeflag); } @@ -16594,6 +16597,7 @@ OP_LWP_E (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { const char **names; unsigned int reg = vex.register_specifier; + vex.register_specifier = 0; if (rex & REX_W) names = names64; -- 2.30.2