[llvm] ae91a42 - [X86][MC] Reject out-of-range control and debug registers encoded with APX (#82584)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 23 12:49:08 PST 2024


Author: Timothy Herchen
Date: 2024-02-23T12:49:05-08:00
New Revision: ae91a427ac8f9fc7368ec052995cec6a6aeb8ea8

URL: https://github.com/llvm/llvm-project/commit/ae91a427ac8f9fc7368ec052995cec6a6aeb8ea8
DIFF: https://github.com/llvm/llvm-project/commit/ae91a427ac8f9fc7368ec052995cec6a6aeb8ea8.diff

LOG: [X86][MC] Reject out-of-range control and debug registers encoded with APX (#82584)

Fixes #82557. APX specification states that the high bits found in REX2
used to encode GPRs can also be used to encode control and debug
registers, although all of them will #UD. Therefore, when disassembling
we reject attempts to create control or debug registers with a value of
16 or more.

See page 22 of the
[specification](https://www.intel.com/content/www/us/en/developer/articles/technical/advanced-performance-extensions-apx.html):

> Note that the R, X and B register identifiers can also address non-GPR
register types, such as vector registers, control registers and debug
registers. When any of them does, the highest-order bits REX2.R4,
REX2.X4 or REX2.B4 are generally ignored, except when the register being
addressed is a control or debug register. [...] The exception is that
REX2.R4 and REX2.R3 [*sic*] are not ignored when the R register
identifier addresses a control or debug register. Furthermore, if any
attempt is made to access a non-existent control register (CR*) or debug
register (DR*) using the REX2 prefix and one of the following
instructions:
“MOV CR*, r64”, “MOV r64, CR*”, “MOV DR*, r64”, “MOV r64, DR*”. #UD is
raised.

The invalid encodings are 64-bit only because `0xd5` is a valid
instruction in 32-bit mode.

Added: 
    

Modified: 
    llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
    llvm/test/MC/Disassembler/X86/x86-64-err.txt

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
index 5f852613610664..dbc2cef39d8682 100644
--- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -819,8 +819,12 @@ static int readModRM(struct InternalInstruction *insn) {
         *valid = 0;                                                            \
       return prefix##_ES + (index & 7);                                        \
     case TYPE_DEBUGREG:                                                        \
+      if (index > 15)                                                          \
+        *valid = 0;                                                            \
       return prefix##_DR0 + index;                                             \
     case TYPE_CONTROLREG:                                                      \
+      if (index > 15)                                                          \
+        *valid = 0;                                                            \
       return prefix##_CR0 + index;                                             \
     case TYPE_MVSIBX:                                                          \
       return prefix##_XMM0 + index;                                            \

diff  --git a/llvm/test/MC/Disassembler/X86/x86-64-err.txt b/llvm/test/MC/Disassembler/X86/x86-64-err.txt
index 3eca239e60f5c7..2d6c3e86ceaba1 100644
--- a/llvm/test/MC/Disassembler/X86/x86-64-err.txt
+++ b/llvm/test/MC/Disassembler/X86/x86-64-err.txt
@@ -5,6 +5,10 @@
 # 32: into
 0xce
 
+# 64: invalid instruction encoding
+0xd5,0xc5,0x20,0xef
+# 64: invalid instruction encoding
+0xd5,0xc5,0x21,0xef
 # 64: invalid instruction encoding
 0xc4,0x62,0xf9,0x18,0x20
 # 64: invalid instruction encoding


        


More information about the llvm-commits mailing list