Skip to content

Commit 7530e70

Browse files
[X86] Ignore REX prefixes not immediately before opcode (#117299)
The Intel X86 Architecture Manual says the following: > A REX prefix is ignored, as are its individual bits, when it is not needed > for an instruction or when it does not immediately precede the opcode byte or > the escape opcode byte (0FH) of an instruction for which it is needed. This > has the implication that only one REX prefix, properly located, can affect an > instruction. We currently do not handle these cases in the disassembler, leading to incorrect disassembly. This patch rectifies the situation by treating REX prefixes as standard prefixes rather than only expecting them before the Opcode. The motivating test case added as a test was fuzzer generated.
1 parent 71f14ff commit 7530e70

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,14 @@ static int readPrefixes(struct InternalInstruction *insn) {
329329
break;
330330
}
331331

332+
if (isREX(insn, byte)) {
333+
insn->rexPrefix = byte;
334+
isPrefix = true;
335+
LLVM_DEBUG(dbgs() << format("Found REX prefix 0x%hhx", byte));
336+
} else if (isPrefix) {
337+
insn->rexPrefix = 0;
338+
}
339+
332340
if (isPrefix)
333341
LLVM_DEBUG(dbgs() << format("Found prefix 0x%hhx", byte));
334342
}
@@ -506,11 +514,6 @@ static int readPrefixes(struct InternalInstruction *insn) {
506514
LLVM_DEBUG(dbgs() << format("Found REX2 prefix 0x%hhx 0x%hhx",
507515
insn->rex2ExtensionPrefix[0],
508516
insn->rex2ExtensionPrefix[1]));
509-
} else if (isREX(insn, byte)) {
510-
if (peek(insn, nextByte))
511-
return -1;
512-
insn->rexPrefix = byte;
513-
LLVM_DEBUG(dbgs() << format("Found REX prefix 0x%hhx", byte));
514517
} else
515518
--insn->readerCursor;
516519

llvm/test/MC/Disassembler/X86/x86-64.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,3 +770,9 @@
770770

771771
# CHECK: prefetchit1 (%rip)
772772
0x0f,0x18,0x35,0x00,0x00,0x00,0x00
773+
774+
# Check that we correctly ignore a REX prefix that is not immediately before
775+
# the opcode. REX prefixes not immediately preceding the Opcode are ignored
776+
# according to Section 2.2.1 of the Intel 64 Architecture Manual.
777+
# CHECK: orw $25659, %ax
778+
0x66 0x4c 0x64 0x0d 0x3b 0x64

0 commit comments

Comments
 (0)