Skip to content

Commit fd5ff6b

Browse files
committed
Revert evex.u handling and fix egpr detection
1 parent 16fdb3f commit fd5ff6b

File tree

2 files changed

+14484
-12913
lines changed

2 files changed

+14484
-12913
lines changed

src/Decoder.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ static ZyanStatus ZydisDecodeEVEX(const ZydisDecoder* decoder, ZydisDecoderConte
603603
instruction->raw.evex.mmm = (data[1] >> 0) & 0x07;
604604

605605
const ZyanBool is_apx = ZYDIS_DECODER_MODE_ACTIVE(decoder, ZYDIS_DECODER_MODE_APX);
606-
if (!is_apx && (data[1] & 0x08)) // TODO: This condition might have to as well consider AVX 10.2 besides APX
606+
if (!is_apx && (instruction->raw.evex.B4 != 0)) // TODO: This condition might have to as well consider AVX 10.2 besides APX
607607
{
608608
// Invalid according to the intel documentation
609609
return ZYDIS_STATUS_MALFORMED_EVEX;
@@ -4315,14 +4315,23 @@ static ZyanStatus ZydisNodeHandlerEvexU(const ZydisDecoderState* state,
43154315
ZYAN_ASSERT(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX);
43164316
ZYAN_ASSERT(instruction->attributes & ZYDIS_ATTRIB_HAS_EVEX);
43174317

4318-
// TODO: Reevaluate this condition when adding AVX10.2 support.
4319-
ZYAN_ASSERT(ZYDIS_DECODER_MODE_ACTIVE(state->decoder, ZYDIS_DECODER_MODE_APX));
4318+
*index = instruction->raw.evex.U;
43204319

4321-
// The `evex.u` filter requires a preceding `modrm.mod == 3` filter.
4322-
ZYAN_ASSERT(instruction->attributes & ZYDIS_ATTRIB_HAS_MODRM);
4323-
ZYAN_ASSERT(instruction->raw.modrm.mod == 3);
4320+
if (!ZYDIS_DECODER_MODE_ACTIVE(state->decoder, ZYDIS_DECODER_MODE_APX)) // TODO: AVX10.2
4321+
{
4322+
return ZYAN_STATUS_SUCCESS;
4323+
}
43244324

4325-
*index = instruction->raw.evex.U;
4325+
if ((instruction->attributes & ZYDIS_ATTRIB_HAS_MODRM) && (instruction->raw.modrm.mod != 3))
4326+
{
4327+
// APX reinterprets `EVEX.U` as `EVEX.X4` for instructions with memory operands
4328+
// (`modrm.mod != 3`).
4329+
4330+
// We don't care about the actual value of `EVEX.U` in this case and force it to `1` to
4331+
// emulate legacy `EVEX` instruction behavior.
4332+
4333+
*index = 1;
4334+
}
43264335

43274336
return ZYAN_STATUS_SUCCESS;
43284337
}
@@ -4668,11 +4677,14 @@ static ZyanStatus ZydisPopulateRegisterIds(ZydisDecoderContext* context,
46684677

46694678
// Assign to context
46704679

4680+
const ZyanBool has_base = !is_mod_reg && !(instruction->raw.modrm.mod == 0 && id_base == 5);
4681+
const ZyanBool has_index = has_sib && (instruction->raw.sib.index != 4);
4682+
46714683
context->reg_info.id_reg = def_reg ? id_reg : -1;
46724684
context->reg_info.id_rm = def_rm && is_mod_reg ? id_rm : -1;
46734685
context->reg_info.id_ndsndd = def_vvvv ? id_vvvv : -1;
4674-
context->reg_info.id_base = !is_mod_reg ? id_base : -1;
4675-
context->reg_info.id_index = !is_mod_reg ? id_index : -1;
4686+
context->reg_info.id_base = has_base ? id_base : -1;
4687+
context->reg_info.id_index = has_index ? id_index : -1;
46764688

46774689
// Update APX info
46784690

@@ -4684,9 +4696,8 @@ static ZyanStatus ZydisPopulateRegisterIds(ZydisDecoderContext* context,
46844696
const ZyanBool has_egpr_reg = (def_reg == ZYDIS_REGKIND_GPR) && (id_reg >= 16);
46854697
const ZyanBool has_egpr_rm = is_mod_reg && (def_rm == ZYDIS_REGKIND_GPR) && (id_rm >= 16);
46864698
const ZyanBool has_egpr_vvvv = (def_vvvv == ZYDIS_REGKIND_GPR) && (id_vvvv >= 16);
4687-
const ZyanBool has_egpr_base = !is_mod_reg && (id_base >= 16) &&
4688-
((instruction->raw.modrm.mod != 0) || (instruction->raw.modrm.rm != 5));
4689-
const ZyanBool has_egpr_index = !is_mod_reg && !has_vsib && (id_index >= 16);
4699+
const ZyanBool has_egpr_base = has_base && (id_base >= 16);
4700+
const ZyanBool has_egpr_index = has_index && !has_vsib && (id_index >= 16);
46904701

46914702
if (has_egpr_reg || has_egpr_rm || has_egpr_vvvv || has_egpr_base || has_egpr_index)
46924703
{

0 commit comments

Comments
 (0)