Skip to content

Commit 6a9c06c

Browse files
authored
x86: simplify REX prefix parsing (#2885)
The previous implementation for handling REX prefixes was quite complex. It required looking ahead to determine if a REX prefix should be ignored. This patch simplifies the implementation by instead resetting insn->rexPrefix when a non-REX prefix is encountered.
1 parent 95fe762 commit 6a9c06c

1 file changed

Lines changed: 12 additions & 50 deletions

File tree

arch/X86/X86DisassemblerDecoder.c

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -429,48 +429,6 @@ static int readPrefixes(struct InternalInstruction *insn)
429429
uint8_t nextByte;
430430

431431
while (isPrefix) {
432-
if (insn->mode == MODE_64BIT) {
433-
// eliminate consecutive redundant REX bytes in front
434-
if (consumeByte(insn, &byte))
435-
return -1;
436-
437-
if ((byte & 0xf0) == 0x40) {
438-
while (true) {
439-
if (lookAtByte(
440-
insn,
441-
&byte)) // out of input code
442-
return -1;
443-
if ((byte & 0xf0) == 0x40) {
444-
// another REX prefix, but we only remember the last one
445-
if (consumeByte(insn, &byte))
446-
return -1;
447-
} else
448-
break;
449-
}
450-
451-
// recover the last REX byte if next byte is not a legacy prefix
452-
switch (byte) {
453-
case 0xf2: /* REPNE/REPNZ */
454-
case 0xf3: /* REP or REPE/REPZ */
455-
case 0xf0: /* LOCK */
456-
case 0x2e: /* CS segment override -OR- Branch not taken */
457-
case 0x36: /* SS segment override -OR- Branch taken */
458-
case 0x3e: /* DS segment override */
459-
case 0x26: /* ES segment override */
460-
case 0x64: /* FS segment override */
461-
case 0x65: /* GS segment override */
462-
case 0x66: /* Operand-size override */
463-
case 0x67: /* Address-size override */
464-
break;
465-
default: /* Not a prefix byte */
466-
unconsumeByte(insn);
467-
break;
468-
}
469-
} else {
470-
unconsumeByte(insn);
471-
}
472-
}
473-
474432
/* If we fail reading prefixes, just stop here and let the opcode reader deal with it */
475433
if (consumeByte(insn, &byte))
476434
return -1;
@@ -503,6 +461,7 @@ static int readPrefixes(struct InternalInstruction *insn)
503461
// only accept the last prefix
504462
setGroup0Prefix(insn, byte);
505463
insn->prefix0 = byte;
464+
insn->rexPrefix = 0;
506465
break;
507466

508467
case 0x2e: /* CS segment override -OR- Branch not taken */
@@ -534,19 +493,28 @@ static int readPrefixes(struct InternalInstruction *insn)
534493
// debug("Unhandled override");
535494
return -1;
536495
}
496+
insn->rexPrefix = 0;
537497
break;
538498

539499
case 0x66: /* Operand-size override */
540500
insn->hasOpSize = true;
541501
insn->prefix2 = byte;
502+
insn->rexPrefix = 0;
542503
break;
543504

544505
case 0x67: /* Address-size override */
545506
insn->hasAdSize = true;
546507
insn->prefix3 = byte;
508+
insn->rexPrefix = 0;
547509
break;
548-
default: /* Not a prefix byte */
549-
isPrefix = false;
510+
default:
511+
if (isREX(insn, byte)) {
512+
/* REX prefix byte */
513+
insn->rexPrefix = byte;
514+
} else {
515+
/* Not a prefix byte */
516+
isPrefix = false;
517+
}
550518
break;
551519
}
552520
}
@@ -736,12 +704,6 @@ static int readPrefixes(struct InternalInstruction *insn)
736704
// insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
737705
// insn->vectorExtensionPrefix[2]);
738706
}
739-
} else if (isREX(insn, byte)) {
740-
if (lookAtByte(insn, &nextByte))
741-
return -1;
742-
743-
insn->rexPrefix = byte;
744-
// dbgprintf(insn, "Found REX prefix 0x%hhx", byte);
745707
} else
746708
unconsumeByte(insn);
747709

0 commit comments

Comments
 (0)