[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