[X86] Fix PR23271 - RIP-relative decoding bug in disassembler.

Differential Revision: http://reviews.llvm.org/D9110

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237310 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Katzman 2015-05-13 22:44:52 +00:00
parent 393c054cd2
commit a8a342bb41
2 changed files with 46 additions and 9 deletions

View File

@ -1366,16 +1366,17 @@ static int readModRM(struct InternalInstruction* insn) {
switch (mod) {
case 0x0:
insn->eaDisplacement = EA_DISP_NONE; /* readSIB may override this */
switch (rm) {
case 0x14:
case 0x4:
case 0xc: /* in case REXW.b is set */
// In determining whether RIP-relative mode is used (rm=5),
// or whether a SIB byte is present (rm=4),
// the extension bits (REX.b and EVEX.x) are ignored.
switch (rm & 7) {
case 0x4: // SIB byte is present
insn->eaBase = (insn->addressSize == 4 ?
EA_BASE_sib : EA_BASE_sib64);
if (readSIB(insn) || readDisplacement(insn))
return -1;
break;
case 0x5:
case 0x5: // RIP-relative
insn->eaBase = EA_BASE_NONE;
insn->eaDisplacement = EA_DISP_32;
if (readDisplacement(insn))
@ -1391,10 +1392,8 @@ static int readModRM(struct InternalInstruction* insn) {
/* FALLTHROUGH */
case 0x2:
insn->eaDisplacement = (mod == 0x1 ? EA_DISP_8 : EA_DISP_32);
switch (rm) {
case 0x14:
case 0x4:
case 0xc: /* in case REXW.b is set */
switch (rm & 7) {
case 0x4: // SIB byte is present
insn->eaBase = EA_BASE_sib;
if (readSIB(insn) || readDisplacement(insn))
return -1;

View File

@ -301,3 +301,41 @@
# CHECK: movq %rax, 1515870810
0x67, 0x48 0xa3 0x5a 0x5a 0x5a 0x5a
# CHECK: addq 255(%rip), %rbx
0x49, 0x03, 0x1d, 0xff, 0x00, 0x00, 0x00
# The following 4 encodings are equivalent, as confirmed by the 'xed64'
# decoder tool provided by Intel, which we assume to be canonical even
# if the real silicon does something different. If that should happen,
# then we'll all have disassembler bugs to repair.
# Try all combinations of EVEX.x and REX.b:
# CHECK: vaddps 287453952(%rip), %zmm20, %zmm15
0x62 0x11 0x5c 0x40 0x58 0x3d 0x00 0x33 0x22 0x11
# CHECK: vaddps 287453952(%rip), %zmm20, %zmm15
0x62 0x31 0x5c 0x40 0x58 0x3d 0x00 0x33 0x22 0x11
# CHECK: vaddps 287453952(%rip), %zmm20, %zmm15
0x62 0x51 0x5c 0x40 0x58 0x3d 0x00 0x33 0x22 0x11
# CHECK: vaddps 287453952(%rip), %zmm20, %zmm15
0x62 0x71 0x5c 0x40 0x58 0x3d 0x00 0x33 0x22 0x11
# Known bugs: these use a SIB byte. The index register is incorrectly
# printed as an xmm register. Indeed there are "gather" load instructions
# taking a vector of indices, but ONLY those instructions can do that.
# The CHECK lines test the current incorrect output; FIXME is desired.
# CHECK: vaddps (%r10,%xmm9), %zmm20, %zmm15
# FIXME: vaddps (%r10,%r9), %zmm20, %zmm15
0x62 0x11 0x5c 0x40 0x58 0x3c 0x0a
# CHECK: vaddps (%rdx,%xmm9), %zmm20, %zmm15
# FIXME: vaddps (%rdx,%r9), %zmm20, %zmm15
0x62 0x31 0x5c 0x40 0x58 0x3c 0x0a
# CHECK: vaddps (%r10,%xmm1), %zmm20, %zmm15
# FIXME: vaddps (%r10,%rcx), %zmm20, %zmm15
0x62 0x51 0x5c 0x40 0x58 0x3c 0x0a
# CHECK: vaddps (%rdx,%xmm1), %zmm20, %zmm15
# FIXME: vaddps (%rdx,%rcx), %zmm20, %zmm15
0x62 0x71 0x5c 0x40 0x58 0x3c 0x0a