Fixed a bug where diassembling an instruction that had a prefix would cause LLVM to identify a 1-byte instruction, but then upon querying it for that 1-byte instruction would cause an undefined opcode.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189698 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Mitton 2013-08-30 21:19:48 +00:00
parent 86d49563a6
commit d4b3168609
2 changed files with 68 additions and 7 deletions

View File

@ -314,20 +314,22 @@ static int readPrefixes(struct InternalInstruction* insn) {
while (isPrefix) { while (isPrefix) {
prefixLocation = insn->readerCursor; prefixLocation = insn->readerCursor;
/* If we fail reading prefixes, just stop here and let the opcode reader deal with it */
if (consumeByte(insn, &byte)) if (consumeByte(insn, &byte))
return -1; break;
/* /*
* If the byte is a LOCK/REP/REPNE prefix and not a part of the opcode, then * If the byte is a LOCK/REP/REPNE prefix and not a part of the opcode, then
* break and let it be disassembled as a normal "instruction". * break and let it be disassembled as a normal "instruction".
*/ */
if (insn->readerCursor - 1 == insn->startLocation && byte == 0xf0)
break;
uint8_t nextByte;
if (insn->readerCursor - 1 == insn->startLocation if (insn->readerCursor - 1 == insn->startLocation
&& (byte == 0xf0 || byte == 0xf2 || byte == 0xf3)) { && (byte == 0xf2 || byte == 0xf3)
uint8_t nextByte; && !lookAtByte(insn, &nextByte))
if (byte == 0xf0) {
break;
if (lookAtByte(insn, &nextByte))
return -1;
/* /*
* If the byte is 0xf2 or 0xf3, and any of the following conditions are * If the byte is 0xf2 or 0xf3, and any of the following conditions are
* met: * met:

View File

@ -0,0 +1,59 @@
# RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s
# CHECK: lock
# CHECK-NEXT: orl $16, %fs:776
0xf0 0x64 0x83 0x0c 0x25 0x08 0x03 0x00 0x00 0x10
# CHECK: movq %fs:768, %rdi
0x64 0x48 0x8b 0x3c 0x25 0x00 0x03 0x00 0x00
# CHECK: rep
# CHECK-NEXT: stosq
0xf3 0x48 0xab
# CHECK: rep
# CHECK-NEXT: stosl
0xf3 0x67 0x48 0xab
# CHECK: movl 32(%rbp), %eax
0x8b 0x45 0x20
# CHECK: movl %es:32(%rbp), %eax
0x26 0x8b 0x45 0x20
# CHECK: movl %es:32(%rbp), %eax
0x2e 0x26 0x8b 0x45 0x20
# Test that multiple prefixes stack.
# (todo- the correct disassembly is actually more like "es movl %cs:32(%rbp), %eax"
# but we don't support that)
# CHECK: movl %cs:32(%rbp), %eax
0x26 0x2e 0x8b 0x45 0x20
# Test that 0xf3 as part of the opcode works.
# CHECK: cvtdq2pd (%rax), %xmm0
0xf3 0x0f 0xe6 0x00
# CHECK: pause
0xf3 0x90
# CHECK: nop
0x90
# CHECK: lock
# CHECK-NEXT: nop
0xf0 0x90
# Test that multiple redundant prefixes work (redundant, but valid x86).
# CHECK: rep
# CHECK-NEXT: rep
# CHECK-NEXT: stosq
0xf3 0xf3 0x48 0xab
# Test that a prefix on it's own works. It's debatable as to if this is
# something that is considered valid, but however as LLVM's own disassembler
# has decided to disassemble prefixes as being separate opcodes, it therefore
# should be capable of re-consuming it's own output.
# CHECK: rep
0xf3
# ***IMPORTANT ^-- this must be at the end of the file to be a valid test ***