Improved formatting of decorators

This commit is contained in:
flobernd 2017-07-04 19:02:11 +02:00
parent 9f735b0f51
commit 8a626388ae
5 changed files with 299 additions and 186 deletions

View File

@ -50,20 +50,23 @@ typedef uint32_t ZydisDecodeGranularity;
*/
enum ZydisDecodeGranularities
{
/**
* @brief Defaults to `ZYDIS_DECODE_GRANULARITY_FULL`.
*/
ZYDIS_DECODE_GRANULARITY_DEFAULT,
/**
* @brief Minimal instruction decoding without semantic analysis.
*
* This mode should be sufficient, if you plan to analyse code for pure relocation purposes,
* as it gives you access to the mnemonic, the instruction-length, displacements, immediates
* and the `ZYDIS_ATTRIB_IS_RELATIVE` attribute.
* This mode provides access to the mnemonic, the instruction-length, the effective
* operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`)
* and all of the information in the `raw` field of the `ZydisDecodedInstruction` struct.
*
* Operands, most attributes and other specific information (like AVX info) are not
* accessible in this mode.
*/
ZYDIS_DECODE_GRANULARITY_MINIMAL,
/**
* @brief Full physical and semantical instruction-decoding.
* @brief Full physical and semantic instruction-decoding.
*/
ZYDIS_DECODE_GRANULARITY_FULL
};

View File

@ -277,6 +277,26 @@ enum ZydisFormatterHookTypes
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisDecoratorType datatype.
*/
typedef uint8_t ZydisDecoratorType;
/**
* @brief Values that represent decorator-types.
*/
enum ZydisDecoratorTypes
{
ZYDIS_DECORATOR_TYPE_INVALID,
ZYDIS_DECORATOR_TYPE_MASK,
ZYDIS_DECORATOR_TYPE_BROADCAST,
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL,
ZYDIS_DECORATOR_TYPE_SAE,
ZYDIS_DECORATOR_TYPE_SWIZZLE,
ZYDIS_DECORATOR_TYPE_CONVERSION,
ZYDIS_DECORATOR_TYPE_EVICTION_HINT
};
typedef struct ZydisFormatter_ ZydisFormatter;
/**
@ -373,6 +393,32 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, uint64_t address);
/**
* @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param type The decorator type.
* @param mask The embedded-mask register (`ZYDIS_DECORATOR_TYPE_MASK` only).
*
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail.
*
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
* number of chars written.
*
* Returning @c ZYDIS_STATUS_SUCCESS without increasing the buffer-pointer is valid and will cause
* the formatter to omit the current decorator.
*
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type.
*/
typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, ZydisDecoratorType type, ZydisRegister mask);
/**
* @brief Defines the @c ZydisFormatter struct.
*/
@ -393,15 +439,10 @@ struct ZydisFormatter_
ZydisFormatterFormatOperandFunc funcFormatOperandImm;
ZydisFormatterFormatOperandFunc funcPrintOperandSize;
ZydisFormatterFormatOperandFunc funcPrintSegment;
ZydisFormatterFormatOperandFunc funcPrintDecorator;
ZydisFormatterFormatDecoratorFunc funcPrintDecorator;
ZydisFormatterFormatAddressFunc funcPrintAddress;
ZydisFormatterFormatOperandFunc funcPrintDisplacement;
ZydisFormatterFormatOperandFunc funcPrintImmediate;
const char* prefixHEX;
const char* prefixOCT;
const char* delimMnemonic;
const char* delimOperands;
const char* fmtDecorator; // TODO:
ZydisFormatterFormatOperandFunc funcPrintImmediate;
};
/* ============================================================================================== */
@ -435,13 +476,18 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, ZydisFo
ZydisFormatterImmediateFormat immmediateFormat);
/**
* @brief TODO:
* @brief Replaces a formatter function with a custom callback and/or retrieves the currently
* used function.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param hook The formatter hook-type.
* @param callback TODO: In Out
* @param callback A pointer to a variable that contains the pointer of the callback function
* and receives the pointer of the currently used function.
*
* @return A zydis status code.
*
* Call this function with `callback` pointing to a `NULL` value to retrieve the currently used
* function without replacing it.
*/
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter,
ZydisFormatterHookType hook, const void** callback);

View File

@ -2026,14 +2026,14 @@ FinalizeOperand:
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Sets prefix-related attributes for the given instruction.
* @brief Sets attributes for the given instruction.
*
* @param context A pointer to the @c ZydisDecoderContext struct.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param definition A pointer to the @c ZydisInstructionDefinition struct.
*/
static void ZydisSetPrefixRelatedAttributes(ZydisDecoderContext* context,
ZydisDecodedInstruction* instruction, const ZydisInstructionDefinition* definition)
static void ZydisSetAttributes(ZydisDecoderContext* context, ZydisDecodedInstruction* instruction,
const ZydisInstructionDefinition* definition)
{
ZYDIS_ASSERT(context);
ZYDIS_ASSERT(instruction);
@ -4294,7 +4294,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
if (context->decoder->decodeGranularity == ZYDIS_DECODE_GRANULARITY_FULL)
{
ZydisSetPrefixRelatedAttributes(context, instruction, definition);
ZydisSetAttributes(context, instruction, definition);
switch (instruction->encoding)
{
case ZYDIS_INSTRUCTION_ENCODING_XOP:

View File

@ -251,6 +251,11 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if ((operand->id == 1) && (operand->encoding == ZYDIS_OPERAND_ENCODING_MASK))
{
return ZYDIS_STATUS_SUCCESS;
}
const char* reg = ZydisRegisterGetString(operand->reg);
if (!reg)
{
@ -514,9 +519,11 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
switch (operand->id)
{
case 0:
typecast = ((instruction->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
(instruction->operands[0].size != instruction->operands[1].size)) ? instruction->operands[0].size : 0;
typecast =
((instruction->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
(instruction->operands[0].size != instruction->operands[1].size)) ?
instruction->operands[0].size : 0;
if (!typecast &&
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(instruction->operands[1].reg == ZYDIS_REGISTER_CL))
@ -539,8 +546,9 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
case 1:
case 2:
typecast =
(instruction->operands[operand->id - 1].size != instruction->operands[operand->id].size) ?
instruction->operands[operand->id].size : 0;
(instruction->operands[operand->id - 1].size !=
instruction->operands[operand->id].size) ?
instruction->operands[operand->id].size : 0;
break;
default:
break;
@ -627,7 +635,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand)
ZydisDecodedOperand* operand, ZydisDecoratorType type, ZydisRegister mask)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{
@ -635,194 +643,197 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
}
const char* bufEnd = *buffer + bufferLen;
if (operand->id == 1)
switch (type)
{
if ((operand->type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(operand->encoding == ZYDIS_OPERAND_ENCODING_MASK) &&
(operand->reg != ZYDIS_REGISTER_K0))
case ZYDIS_DECORATOR_TYPE_MASK:
{
if (mask != ZYDIS_REGISTER_K0)
{
const char* reg = ZydisRegisterGetString(operand->reg);
const char* reg = ZydisRegisterGetString(mask);
if (!reg)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
" {%s}", reg));
ZYDIS_CHECK(ZydisStringBufferAppendFormat(
buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, " {%s}", reg));
if (instruction->avx.maskMode == ZYDIS_MASK_MODE_ZERO)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
}
}
} else
{
if (instruction->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
if (!instruction->avx.broadcast.isStatic)
{
switch (instruction->avx.broadcast.mode)
{
case ZYDIS_BROADCAST_MODE_INVALID:
break;
case ZYDIS_BROADCAST_MODE_1_TO_2:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
break;
case ZYDIS_BROADCAST_MODE_1_TO_4:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
break;
case ZYDIS_BROADCAST_MODE_1_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
break;
case ZYDIS_BROADCAST_MODE_1_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
break;
case ZYDIS_BROADCAST_MODE_4_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to8}"));
break;
case ZYDIS_BROADCAST_MODE_4_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to16}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
switch (instruction->avx.conversionMode)
{
case ZYDIS_CONVERSION_MODE_INVALID:
break;
case ZYDIS_CONVERSION_MODE_FLOAT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {float16}"));
break;
case ZYDIS_CONVERSION_MODE_SINT8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint8}"));
break;
case ZYDIS_CONVERSION_MODE_UINT8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint8}"));
break;
case ZYDIS_CONVERSION_MODE_SINT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint16}"));
break;
case ZYDIS_CONVERSION_MODE_UINT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint16}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if (instruction->avx.hasEvictionHint)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {eh}"));
}
}
}
if ((operand->id == (instruction->operandCount - 1)) ||
((operand->id != (instruction->operandCount - 1)) &&
(instruction->operands[operand->id + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)))
break;
}
case ZYDIS_DECORATOR_TYPE_BROADCAST:
if (!instruction->avx.broadcast.isStatic)
{
if (instruction->avx.hasSAE)
switch (instruction->avx.broadcast.mode)
{
switch (instruction->avx.roundingMode)
{
case ZYDIS_ROUNDING_MODE_INVALID:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz-sae}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
} else
{
switch (instruction->avx.roundingMode)
{
case ZYDIS_ROUNDING_MODE_INVALID:
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn}"));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd}"));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru}"));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
switch (instruction->avx.swizzleMode)
{
case ZYDIS_SWIZZLE_MODE_INVALID:
case ZYDIS_SWIZZLE_MODE_DCBA:
// Nothing to do here
break;
case ZYDIS_SWIZZLE_MODE_CDAB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cdab}"));
case ZYDIS_BROADCAST_MODE_INVALID:
break;
case ZYDIS_SWIZZLE_MODE_BADC:
case ZYDIS_BROADCAST_MODE_1_TO_2:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {badc}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
break;
case ZYDIS_SWIZZLE_MODE_DACB:
case ZYDIS_BROADCAST_MODE_1_TO_4:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dacb}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
break;
case ZYDIS_SWIZZLE_MODE_AAAA:
case ZYDIS_BROADCAST_MODE_1_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {aaaa}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
break;
case ZYDIS_SWIZZLE_MODE_BBBB:
case ZYDIS_BROADCAST_MODE_1_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {bbbb}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
break;
case ZYDIS_SWIZZLE_MODE_CCCC:
case ZYDIS_BROADCAST_MODE_4_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cccc}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to8}"));
break;
case ZYDIS_SWIZZLE_MODE_DDDD:
case ZYDIS_BROADCAST_MODE_4_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dddd}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to16}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
break;
case ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL:
if (instruction->avx.hasSAE)
{
switch (instruction->avx.roundingMode)
{
case ZYDIS_ROUNDING_MODE_INVALID:
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz-sae}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
} else
{
switch (instruction->avx.roundingMode)
{
case ZYDIS_ROUNDING_MODE_INVALID:
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn}"));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd}"));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru}"));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
break;
case ZYDIS_DECORATOR_TYPE_SAE:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
break;
case ZYDIS_DECORATOR_TYPE_SWIZZLE:
switch (instruction->avx.swizzleMode)
{
case ZYDIS_SWIZZLE_MODE_INVALID:
case ZYDIS_SWIZZLE_MODE_DCBA:
// Nothing to do here
break;
case ZYDIS_SWIZZLE_MODE_CDAB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cdab}"));
break;
case ZYDIS_SWIZZLE_MODE_BADC:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {badc}"));
break;
case ZYDIS_SWIZZLE_MODE_DACB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dacb}"));
break;
case ZYDIS_SWIZZLE_MODE_AAAA:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {aaaa}"));
break;
case ZYDIS_SWIZZLE_MODE_BBBB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {bbbb}"));
break;
case ZYDIS_SWIZZLE_MODE_CCCC:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cccc}"));
break;
case ZYDIS_SWIZZLE_MODE_DDDD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dddd}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
break;
case ZYDIS_DECORATOR_TYPE_CONVERSION:
switch (instruction->avx.conversionMode)
{
case ZYDIS_CONVERSION_MODE_INVALID:
break;
case ZYDIS_CONVERSION_MODE_FLOAT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {float16}"));
break;
case ZYDIS_CONVERSION_MODE_SINT8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint8}"));
break;
case ZYDIS_CONVERSION_MODE_UINT8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint8}"));
break;
case ZYDIS_CONVERSION_MODE_SINT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint16}"));
break;
case ZYDIS_CONVERSION_MODE_UINT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint16}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
break;
case ZYDIS_DECORATOR_TYPE_EVICTION_HINT:
if (instruction->avx.hasEvictionHint)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {eh}"));
}
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
return ZYDIS_STATUS_SUCCESS;
@ -903,8 +914,55 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer,
instruction, &instruction->operands[i]));
if (i == 0)
{
if (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_MASK, instruction->operands[i + 1].reg));
}
} else
{
if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_BROADCAST, ZYDIS_REGISTER_NONE));
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_CONVERSION, ZYDIS_REGISTER_NONE));
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_EVICTION_HINT, ZYDIS_REGISTER_NONE));
}
} else
{
if ((i == (instruction->operandCount - 1)) ||
(instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
{
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SWIZZLE, ZYDIS_REGISTER_NONE));
}
if (instruction->avx.roundingMode)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, ZYDIS_REGISTER_NONE));
} else
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SAE, ZYDIS_REGISTER_NONE));
}
}
}
}
}
}
}
@ -1079,7 +1137,7 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT
formatter->funcPrintSegment = *(ZydisFormatterFormatOperandFunc*)&temp;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR:
formatter->funcPrintDecorator = *(ZydisFormatterFormatOperandFunc*)&temp;
formatter->funcPrintDecorator = *(ZydisFormatterFormatDecoratorFunc*)&temp;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS:
formatter->funcPrintAddress = *(ZydisFormatterFormatAddressFunc*)&temp;

View File

@ -217,7 +217,7 @@ typedef uint8_t ZydisInternalElementType;
enum ZydisInternalElementTypes
{
ZYDIS_IELEMENT_TYPE_INVALID,
ZYDIS_IELEMENT_TYPE_VARIABLE, // TODO: Remove
ZYDIS_IELEMENT_TYPE_VARIABLE,
ZYDIS_IELEMENT_TYPE_STRUCT,
ZYDIS_IELEMENT_TYPE_INT,
ZYDIS_IELEMENT_TYPE_UINT,
@ -270,6 +270,9 @@ typedef struct ZydisOperandDefinition_
} op;
} ZydisOperandDefinition;
/**
* @brief Values that represent implicit-register types.
*/
enum ZydisImplicitRegisterType
{
ZYDIS_IMPLREG_TYPE_STATIC,
@ -281,6 +284,9 @@ enum ZydisImplicitRegisterType
ZYDIS_IMPLREG_TYPE_FLAGS_SSZ
};
/**
* @brief Values that represent implicit-memory base-registers.
*/
enum ZydisImplicitMemBase
{
ZYDIS_IMPLMEM_BASE_ABX,
@ -657,7 +663,7 @@ enum ZydisMaskPolicies
#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX \
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; \
ZydisBool hasVSIB ZYDIS_BITFIELD( 1)
ZydisBool hasVSIB ZYDIS_BITFIELD( 1)
/**
* @brief Defines the @c ZydisInstructionDefinition struct.