Skip to content

Commit

Permalink
[X86][MC] Reject out-of-range control and debug registers encoded wit…
Browse files Browse the repository at this point in the history
…h APX (llvm#82584)

Fixes llvm#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.
  • Loading branch information
anematode authored Feb 23, 2024
1 parent 1c2456d commit ae91a42
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 0 deletions.
4 changes: 4 additions & 0 deletions llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; \
Expand Down
4 changes: 4 additions & 0 deletions llvm/test/MC/Disassembler/X86/x86-64-err.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ae91a42

Please sign in to comment.