Skip to content

Commit 64a93af

Browse files
committed
[X86][Disassembler] Fix a bug when disassembling an empty string
readPrefixes() assumes insn->bytes is non-empty. The code path is not exercised in llvm-mc because llvm-mc does not feed empty input to MCDisassembler::getInstruction(). This bug is uncovered by a5994c7. An empty string did not crash before because the deleted regionReader() allowed UINT64_C(-1) as insn->readerCursor. Bytes.size() <= Address -> R->Base 0 <= UINT64_C(-1) - UINT32_C(-1)
1 parent 484a747 commit 64a93af

File tree

2 files changed

+7
-1
lines changed

2 files changed

+7
-1
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ static bool isREX(struct InternalInstruction *insn, uint8_t prefix) {
203203
// Consumes all of an instruction's prefix bytes, and marks the
204204
// instruction as having them. Also sets the instruction's default operand,
205205
// address, and other relevant data sizes to report operands correctly.
206+
//
207+
// insn must not be empty.
206208
static int readPrefixes(struct InternalInstruction *insn) {
207209
bool isPrefix = true;
208210
uint8_t byte = 0;
@@ -1707,7 +1709,7 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction(
17071709
Insn.readerCursor = Address;
17081710
Insn.mode = fMode;
17091711

1710-
if (readPrefixes(&Insn) || readOpcode(&Insn) ||
1712+
if (Bytes.empty() || readPrefixes(&Insn) || readOpcode(&Insn) ||
17111713
getInstructionID(&Insn, MII.get()) || Insn.instructionID == 0 ||
17121714
readOperands(&Insn)) {
17131715
Size = Insn.readerCursor - Address;

llvm/unittests/MC/Disassembler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ TEST(Disassembler, X86Test) {
3838
unsigned NumBytes = sizeof(Bytes);
3939
unsigned PC = 0;
4040

41+
InstSize =
42+
LLVMDisasmInstruction(DCR, BytesP, 0, PC, OutString, OutStringSize);
43+
EXPECT_EQ(InstSize, 0U);
44+
4145
InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
4246
OutStringSize);
4347
EXPECT_EQ(InstSize, 1U);

0 commit comments

Comments
 (0)