Skip to content

Commit

Permalink
Add UD0_COMPAT decoder mode (#477)
Browse files Browse the repository at this point in the history
  • Loading branch information
flobernd committed Jan 26, 2024
1 parent a605f54 commit 15e38ac
Show file tree
Hide file tree
Showing 8 changed files with 1,112 additions and 1,074 deletions.
11 changes: 10 additions & 1 deletion include/Zydis/Decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,20 @@ typedef enum ZydisDecoderMode_
* This mode is enabled by default.
*/
ZYDIS_DECODER_MODE_IPREFETCH,
/**
* Enables the `UD0` compatibility mode.
*
* Some processors decode the `UD0` instruction without a ModR/M byte. Enable this decoder mode
* to mimic this behavior.
*
* This mode is disabled by default.
*/
ZYDIS_DECODER_MODE_UD0_COMPAT,

/**
* Maximum value of this enum.
*/
ZYDIS_DECODER_MODE_MAX_VALUE = ZYDIS_DECODER_MODE_IPREFETCH,
ZYDIS_DECODER_MODE_MAX_VALUE = ZYDIS_DECODER_MODE_UD0_COMPAT,
/**
* The minimum number of bits required to represent all values of this enum.
*/
Expand Down
6 changes: 5 additions & 1 deletion include/Zydis/Internal/DecoderData.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,11 @@ enum ZydisDecoderTreeNodeTypes
/**
* Reference to a IPREFETCH-mode filter.
*/
ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH = 0x1C
ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH = 0x1C,
/**
* Reference to a UD0_COMPAT-mode filter.
*/
ZYDIS_NODETYPE_FILTER_MODE_UD0_COMPAT = 0x1D
};

/* ---------------------------------------------------------------------------------------------- */
Expand Down
5 changes: 5 additions & 0 deletions src/Decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -4803,6 +4803,9 @@ static ZyanStatus ZydisDecodeInstruction(ZydisDecoderState* state,
case ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH:
index = !!(state->decoder->decoder_mode & (1 << ZYDIS_DECODER_MODE_IPREFETCH));
break;
case ZYDIS_NODETYPE_FILTER_MODE_UD0_COMPAT:
index = !!(state->decoder->decoder_mode & (1 << ZYDIS_DECODER_MODE_UD0_COMPAT));
break;
default:
if (node_type & ZYDIS_NODETYPE_DEFINITION_MASK)
{
Expand Down Expand Up @@ -4899,6 +4902,8 @@ static ZyanStatus ZydisDecodeInstruction(ZydisDecoderState* state,
ZyanStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machine_mode,
ZydisStackWidth stack_width)
{
ZYAN_STATIC_ASSERT(ZYDIS_DECODER_MODE_MAX_VALUE <= 32);

static const ZyanU32 decoder_modes =
#ifdef ZYDIS_MINIMAL_MODE
(1 << ZYDIS_DECODER_MODE_MINIMAL) |
Expand Down
3 changes: 3 additions & 0 deletions src/DecoderData.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode(const ZydisDecoderTreeN
case ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH:
ZYAN_ASSERT(index < 2);
return &FILTERS_MODE_IPREFETCH[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODE_UD0_COMPAT:
ZYAN_ASSERT(index < 2);
return &FILTERS_MODE_UD0_COMPAT[parent->value][index];
default:
ZYAN_UNREACHABLE;
}
Expand Down
115 changes: 60 additions & 55 deletions src/Generated/DecoderTables.inc

Large diffs are not rendered by default.

0 comments on commit 15e38ac

Please sign in to comment.