fix(relinker): do not add the F6/F7 TEST immediate to EVEX instructions
The decoder adds the TEST immediate of opcodes F6 and F7 when ModRM.reg is 0 or 1. The check excluded VEX and two-byte opcodes but not EVEX, so an EVEX.0F F6 (VPSADBW) whose ModRM.reg is 0 or 1 was given an extra imm8 and decoded one byte too long. VPSADBW has no immediate (Intel SDM Vol. 2B, VPSADBW).
This commit is contained in:
parent
df16c4c256
commit
f4ef1cd6ec
|
|
@ -274,7 +274,7 @@ std::size_t X64InstructionDecoder::Decode(const std::uint8_t* data, std::size_t
|
|||
const auto reg = static_cast<std::uint8_t>((modrm >> ModRmRegShift) & ModRmRegMask);
|
||||
const auto rm = static_cast<std::uint8_t>(modrm & ModRmRmMask);
|
||||
|
||||
if (!vexPresent && !twoByteOpcode &&
|
||||
if (!vexPresent && !evexPresent && !twoByteOpcode &&
|
||||
(opcode == OneByteTestGrp3Rm8 || opcode == OneByteTestGrp3Rm) &&
|
||||
reg <= Grp3RegTestMax) {
|
||||
immediateSize = (opcode == OneByteTestGrp3Rm8)
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ void decoderLengths() {
|
|||
{0xF2, 0x44, 0x0F, 0x2B, 0x4C, 0x24, 0x10}, {0x0F, 0x01, 0xFA}, {0x0F, 0xB9, 0x00},
|
||||
{0x41, 0x0F, 0xBB, 0xF7}, {0x0F, 0xBB, 0x47, 0x08},
|
||||
{0x0F, 0x38, 0xCB, 0xCA}, {0x45, 0x0F, 0x38, 0xCC, 0xE1}, {0x0F, 0x38, 0xCD, 0x08}, {0x0F, 0x38, 0xCB, 0x0D, 0x10, 0x00, 0x00, 0x00},
|
||||
{0x62, 0xF1, 0x75, 0x48, 0xF6, 0xC2}, {0x62, 0xF1, 0x7D, 0x48, 0xF6, 0x05, 0x10, 0x00, 0x00, 0x00}, {0x62, 0xF1, 0x6D, 0x48, 0xF6, 0x4C, 0x24, 0x01},
|
||||
{0x0F, 0x3A, 0xCC, 0xD5, 0x03}, {0x45, 0x0F, 0x3A, 0xCC, 0xE1, 0x00}, {0x0F, 0x3A, 0xCC, 0x08, 0x01}, {0x0F, 0x38, 0xC8, 0xCA}, {0x0F, 0x38, 0xC9, 0xCA}, {0x0F, 0x38, 0xCA, 0x08},
|
||||
{0x48, 0x66, 0xB8, 0x34, 0x12}, {0x66, 0x48, 0xB8, 1, 2, 3, 4, 5, 6, 7, 8}, {0x41, 0x48, 0xB8, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||
{0x48, 0x64, 0x8B, 0x00}, {0x48, 0xF3, 0x0F, 0x2B, 0x00}, {0x48, 0x67, 0x0F, 0x01, 0xFC}, {0x48, 0x48, 0x0F, 0x01, 0xFC}};
|
||||
|
|
|
|||
Loading…
Reference in New Issue