diff options
Diffstat (limited to 'js/src/zydis/Zydis/Internal')
-rw-r--r-- | js/src/zydis/Zydis/Internal/DecoderData.h | 332 | ||||
-rw-r--r-- | js/src/zydis/Zydis/Internal/EncoderData.h | 249 | ||||
-rw-r--r-- | js/src/zydis/Zydis/Internal/FormatterATT.h | 183 | ||||
-rw-r--r-- | js/src/zydis/Zydis/Internal/FormatterBase.h | 324 | ||||
-rw-r--r-- | js/src/zydis/Zydis/Internal/FormatterIntel.h | 271 | ||||
-rw-r--r-- | js/src/zydis/Zydis/Internal/SharedData.h | 979 | ||||
-rw-r--r-- | js/src/zydis/Zydis/Internal/String.h | 470 |
7 files changed, 2808 insertions, 0 deletions
diff --git a/js/src/zydis/Zydis/Internal/DecoderData.h b/js/src/zydis/Zydis/Internal/DecoderData.h new file mode 100644 index 0000000000..b121e8d57a --- /dev/null +++ b/js/src/zydis/Zydis/Internal/DecoderData.h @@ -0,0 +1,332 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Florian Bernd + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +#ifndef ZYDIS_INTERNAL_DECODERDATA_H +#define ZYDIS_INTERNAL_DECODERDATA_H + +#include "zydis/Zycore/Defines.h" +#include "zydis/Zycore/Types.h" +#include "zydis/Zydis/Defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +// MSVC does not like types other than (un-)signed int for bit-fields +#ifdef ZYAN_MSVC +# pragma warning(push) +# pragma warning(disable:4214) +#endif + +#pragma pack(push, 1) + +/* ---------------------------------------------------------------------------------------------- */ +/* Decoder tree */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisDecoderTreeNodeType` data-type. + */ +typedef ZyanU8 ZydisDecoderTreeNodeType; + +/** + * Values that represent zydis decoder tree node types. + */ +enum ZydisDecoderTreeNodeTypes +{ + ZYDIS_NODETYPE_INVALID = 0x00, + /** + * Reference to an instruction-definition. + */ + ZYDIS_NODETYPE_DEFINITION_MASK = 0x80, + /** + * Reference to an XOP-map filter. + */ + ZYDIS_NODETYPE_FILTER_XOP = 0x01, + /** + * Reference to an VEX-map filter. + */ + ZYDIS_NODETYPE_FILTER_VEX = 0x02, + /** + * Reference to an EVEX/MVEX-map filter. + */ + ZYDIS_NODETYPE_FILTER_EMVEX = 0x03, + /** + * Reference to an opcode filter. + */ + ZYDIS_NODETYPE_FILTER_OPCODE = 0x04, + /** + * Reference to an instruction-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE = 0x05, + /** + * Reference to an compacted instruction-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_COMPACT = 0x06, + /** + * Reference to a ModRM.mod filter. + */ + ZYDIS_NODETYPE_FILTER_MODRM_MOD = 0x07, + /** + * Reference to a compacted ModRM.mod filter. + */ + ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT = 0x08, + /** + * Reference to a ModRM.reg filter. + */ + ZYDIS_NODETYPE_FILTER_MODRM_REG = 0x09, + /** + * Reference to a ModRM.rm filter. + */ + ZYDIS_NODETYPE_FILTER_MODRM_RM = 0x0A, + /** + * Reference to a PrefixGroup1 filter. + */ + ZYDIS_NODETYPE_FILTER_PREFIX_GROUP1 = 0x0B, + /** + * Reference to a mandatory-prefix filter. + */ + ZYDIS_NODETYPE_FILTER_MANDATORY_PREFIX = 0x0C, + /** + * Reference to an operand-size filter. + */ + ZYDIS_NODETYPE_FILTER_OPERAND_SIZE = 0x0D, + /** + * Reference to an address-size filter. + */ + ZYDIS_NODETYPE_FILTER_ADDRESS_SIZE = 0x0E, + /** + * Reference to a vector-length filter. + */ + ZYDIS_NODETYPE_FILTER_VECTOR_LENGTH = 0x0F, + /** + * Reference to an REX/VEX/EVEX.W filter. + */ + ZYDIS_NODETYPE_FILTER_REX_W = 0x10, + /** + * Reference to an REX/VEX/EVEX.B filter. + */ + ZYDIS_NODETYPE_FILTER_REX_B = 0x11, + /** + * Reference to an EVEX.b filter. + */ + ZYDIS_NODETYPE_FILTER_EVEX_B = 0x12, + /** + * Reference to an MVEX.E filter. + */ + ZYDIS_NODETYPE_FILTER_MVEX_E = 0x13, + /** + * Reference to a AMD-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_AMD = 0x14, + /** + * Reference to a KNC-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_KNC = 0x15, + /** + * Reference to a MPX-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_MPX = 0x16, + /** + * Reference to a CET-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_CET = 0x17, + /** + * Reference to a LZCNT-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_LZCNT = 0x18, + /** + * Reference to a TZCNT-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_TZCNT = 0x19, + /** + * Reference to a WBNOINVD-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_WBNOINVD = 0x1A, + /** + * Reference to a CLDEMOTE-mode filter. + */ + ZYDIS_NODETYPE_FILTER_MODE_CLDEMOTE = 0x1B +}; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisDecoderTreeNodeValue` data-type. + */ +typedef ZyanU16 ZydisDecoderTreeNodeValue; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisDecoderTreeNode` struct. + */ +typedef struct ZydisDecoderTreeNode_ +{ + ZydisDecoderTreeNodeType type; + ZydisDecoderTreeNodeValue value; +} ZydisDecoderTreeNode; + +/* ---------------------------------------------------------------------------------------------- */ + +#pragma pack(pop) + +#ifdef ZYAN_MSVC +# pragma warning(pop) +#endif + +/* ---------------------------------------------------------------------------------------------- */ +/* Physical instruction encoding info */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisInstructionEncodingFlags` data-type. + */ +typedef ZyanU8 ZydisInstructionEncodingFlags; + +/** + * The instruction has an optional modrm byte. + */ +#define ZYDIS_INSTR_ENC_FLAG_HAS_MODRM 0x01 + +/** + * The instruction has an optional displacement value. + */ +#define ZYDIS_INSTR_ENC_FLAG_HAS_DISP 0x02 + +/** + * The instruction has an optional immediate value. + */ +#define ZYDIS_INSTR_ENC_FLAG_HAS_IMM0 0x04 + +/** + * The instruction has a second optional immediate value. + */ +#define ZYDIS_INSTR_ENC_FLAG_HAS_IMM1 0x08 + +/** + * The instruction ignores the value of `modrm.mod` and always assumes `modrm.mod == 3` + * ("reg, reg" - form). + * + * Instructions with this flag can't have a SIB byte or a displacement value. + */ +#define ZYDIS_INSTR_ENC_FLAG_FORCE_REG_FORM 0x10 + +/** + * Defines the `ZydisInstructionEncodingInfo` struct. + */ +typedef struct ZydisInstructionEncodingInfo_ +{ + /** + * Contains flags with information about the physical instruction-encoding. + */ + ZydisInstructionEncodingFlags flags; + /** + * Displacement info. + */ + struct + { + /** + * The size of the displacement value. + */ + ZyanU8 size[3]; + } disp; + /** + * Immediate info. + */ + struct + { + /** + * The size of the immediate value. + */ + ZyanU8 size[3]; + /** + * Signals, if the value is signed. + */ + ZyanBool is_signed; + /** + * Signals, if the value is a relative offset. + */ + ZyanBool is_relative; + } imm[2]; +} ZydisInstructionEncodingInfo; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Decoder tree */ +/* ---------------------------------------------------------------------------------------------- */ + +extern const ZydisDecoderTreeNode zydis_decoder_tree_root; + +/** + * Returns the root node of the instruction tree. + * + * @return The root node of the instruction tree. + */ +ZYAN_INLINE const ZydisDecoderTreeNode* ZydisDecoderTreeGetRootNode(void) +{ + return &zydis_decoder_tree_root; +} + +/** + * Returns the child node of `parent` specified by `index`. + * + * @param parent The parent node. + * @param index The index of the child node to retrieve. + * + * @return The specified child node. + */ +ZYDIS_NO_EXPORT const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode( + const ZydisDecoderTreeNode* parent, ZyanU16 index); + +/** + * Returns information about optional instruction parts (like modrm, displacement or + * immediates) for the instruction that is linked to the given `node`. + * + * @param node The instruction definition node. + * @param info A pointer to the `ZydisInstructionParts` struct. + */ +ZYDIS_NO_EXPORT void ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode* node, + const ZydisInstructionEncodingInfo** info); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_INTERNAL_DECODERDATA_H */ diff --git a/js/src/zydis/Zydis/Internal/EncoderData.h b/js/src/zydis/Zydis/Internal/EncoderData.h new file mode 100644 index 0000000000..bb9b4d5c4e --- /dev/null +++ b/js/src/zydis/Zydis/Internal/EncoderData.h @@ -0,0 +1,249 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Mappa + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +#ifndef ZYDIS_INTERNAL_ENCODERDATA_H +#define ZYDIS_INTERNAL_ENCODERDATA_H + +#include "zydis/Zycore/Defines.h" +#include "zydis/Zydis/Mnemonic.h" +#include "zydis/Zydis/SharedTypes.h" + +/** + * Used in encoder's table to represent standard ISA sizes in form of bit flags. + */ +typedef enum ZydisWidthFlag_ +{ + ZYDIS_WIDTH_INVALID = 0x00, + ZYDIS_WIDTH_16 = 0x01, + ZYDIS_WIDTH_32 = 0x02, + ZYDIS_WIDTH_64 = 0x04, + + /** + * Maximum value of this enum. + */ + ZYDIS_WIDTH_MAX_VALUE = (ZYDIS_WIDTH_64 | (ZYDIS_WIDTH_64 - 1)), + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_WIDTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_WIDTH_MAX_VALUE) +} ZydisWidthFlag; + +/** + * Used in encoder's table to represent mandatory instruction prefix. Using this enum instead of + * actual prefix value saves space. + */ +typedef enum ZydisMandatoryPrefix_ +{ + ZYDIS_MANDATORY_PREFIX_NONE, + ZYDIS_MANDATORY_PREFIX_66, + ZYDIS_MANDATORY_PREFIX_F2, + ZYDIS_MANDATORY_PREFIX_F3, + + /** + * Maximum value of this enum. + */ + ZYDIS_MANDATORY_PREFIX_MAX_VALUE = ZYDIS_MANDATORY_PREFIX_F3, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MANDATORY_PREFIX_MAX_VALUE) +} ZydisMandatoryPrefix; + +/** + * Used in encoder's table to represent vector size supported by instruction definition. + */ +typedef enum ZydisVectorLength_ +{ + ZYDIS_VECTOR_LENGTH_INVALID, + ZYDIS_VECTOR_LENGTH_128, + ZYDIS_VECTOR_LENGTH_256, + ZYDIS_VECTOR_LENGTH_512, + + /** + * Maximum value of this enum. + */ + ZYDIS_VECTOR_LENGTH_MAX_VALUE = ZYDIS_VECTOR_LENGTH_512, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_VECTOR_LENGTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_VECTOR_LENGTH_MAX_VALUE) +} ZydisVectorLength; + +/** + * Used in encoder's table to represent hint type supported by instruction definition. + */ +typedef enum ZydisSizeHint_ +{ + ZYDIS_SIZE_HINT_NONE, + ZYDIS_SIZE_HINT_ASZ, + ZYDIS_SIZE_HINT_OSZ, + + /** + * Maximum value of this enum. + */ + ZYDIS_SIZE_HINT_MAX_VALUE = ZYDIS_SIZE_HINT_OSZ, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_SIZE_HINT_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIZE_HINT_MAX_VALUE) +} ZydisSizeHint; + +/** + * Used in encoder's primary lookup table which allows to access a set of instruction definitions + * for specified mnemonic in constant time. + */ +typedef struct ZydisEncoderLookupEntry_ +{ + /** + * Index to main array of `ZydisEncodableInstruction`. + */ + ZyanU16 encoder_reference; + /** + * The number of entries. + */ + ZyanU8 instruction_count; +} ZydisEncoderLookupEntry; + +#pragma pack(push, 1) + +/** + * This structure is encoder's internal representation of encodable instruction definition. + */ +typedef struct ZydisEncodableInstruction_ +{ + /** + * Index to one of decoder's instruction definition arrays. + */ + ZyanU16 instruction_reference; + /** + * Compressed information about operand count and types. Operand count is stored in lowest bits. + * Types of subsequent operands are stored in higher bits. + */ + ZyanU16 operand_mask; + /** + * The instruction-opcode. + */ + ZyanU8 opcode; + /** + * The mandatory ModR/M value. + */ + ZyanU8 modrm; + /** + * The instruction-encoding. + */ + ZyanU8 encoding ZYAN_BITFIELD(ZYDIS_INSTRUCTION_ENCODING_REQUIRED_BITS); + /** + * The opcode map. + */ + ZyanU8 opcode_map ZYAN_BITFIELD(ZYDIS_OPCODE_MAP_REQUIRED_BITS); + /** + * The combination of allowed processor modes. + */ + ZyanU8 modes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS); + /** + * The combination of allowed address sizes. + */ + ZyanU8 address_sizes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS); + /** + * The combination of allowed operand sizes. + */ + ZyanU8 operand_sizes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS); + /** + * The mandatory prefix. + */ + ZyanU8 mandatory_prefix ZYAN_BITFIELD(ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS); + /** + * True if `REX.W` is required for this definition. + */ + ZyanU8 rex_w ZYAN_BITFIELD(1); + /** + * The vector length. + */ + ZyanU8 vector_length ZYAN_BITFIELD(ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS); + /** + * The accepted sizing hint. + */ + ZyanU8 accepts_hint ZYAN_BITFIELD(ZYDIS_SIZE_HINT_REQUIRED_BITS); + /** + * Indicates that next instruction definition can be safely used instead of current one. This + * is used with some `VEX` instructions to take advantage of 2-byte `VEX` prefix when possible. + * 2-byte `VEX` allows to use high registers only when operand is encoded in `modrm_reg` + * (high bit in `REX.R`). Encoder uses swappable definitions to take advantage of this + * optimization opportunity. + * + * Second use of this field is to handle special case for `mov` instruction. This particular + * conflict is described in detail inside `ZydisHandleSwappableDefinition`. + */ + ZyanU8 swappable ZYAN_BITFIELD(1); +} ZydisEncodableInstruction; + +#pragma pack(pop) + +/** + * Contains information used by instruction size prediction algorithm inside + * `ZydisEncoderEncodeInstructionAbsolute`. + */ +typedef struct ZydisEncoderRelInfo_ +{ + /** + * Sizes of instruction variants. First index is effective address size. Second index is + * desired immediate size (8, 16 and 32 bits respectively). + */ + ZyanU8 size[3][3]; + /** + * See `ZydisSizeHint`. + */ + ZyanU8 accepts_scaling_hints; + /** + * True if instruction accepts branch hint prefixes. + */ + ZyanBool accepts_branch_hints; +} ZydisEncoderRelInfo; + +/** + * Fetches array of `ZydisEncodableInstruction` structures and its size for given instruction + * mnemonic. + * + * @param mnemonic Instruction mnemonic. + * @param instruction This variable will receive a pointer to the array of + * `ZydisEncodableInstruction` structures. + * + * @return Entry count (0 if function failed). + */ +ZyanU8 ZydisGetEncodableInstructions(ZydisMnemonic mnemonic, + const ZydisEncodableInstruction **instruction); + +/** + * Fetches `ZydisEncoderRelInfo` record for given instruction mnemonic. + * + * @param mnemonic Instruction mnemonic. + * + * @return Pointer to `ZydisEncoderRelInfo` structure or `ZYAN_NULL` if instruction doesn't have + * relative operands. + */ +const ZydisEncoderRelInfo *ZydisGetRelInfo(ZydisMnemonic mnemonic); + +#endif /* ZYDIS_INTERNAL_ENCODERDATA_H */ diff --git a/js/src/zydis/Zydis/Internal/FormatterATT.h b/js/src/zydis/Zydis/Internal/FormatterATT.h new file mode 100644 index 0000000000..92fb36a7cd --- /dev/null +++ b/js/src/zydis/Zydis/Internal/FormatterATT.h @@ -0,0 +1,183 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Florian Bernd, Joel Hoener + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +/** + * @file + * Implements the `AT&T` style instruction-formatter. + */ + +#ifndef ZYDIS_FORMATTER_ATT_H +#define ZYDIS_FORMATTER_ATT_H + +#include "zydis/Zydis/Formatter.h" +#include "zydis/Zydis/Internal/FormatterBase.h" +#include "zydis/Zydis/Internal/String.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Formatter functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Instruction */ +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZydisFormatterATTFormatInstruction(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +/* ---------------------------------------------------------------------------------------------- */ +/* Operands */ +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZydisFormatterATTFormatOperandMEM(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +/* ---------------------------------------------------------------------------------------------- */ +/* Elemental tokens */ +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZydisFormatterATTPrintMnemonic(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterATTPrintRegister(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisRegister reg); + +ZyanStatus ZydisFormatterATTPrintAddressABS(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterATTPrintDISP(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterATTPrintIMM(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Fomatter presets */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* AT&T */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * The default formatter configuration for `AT&T` style disassembly. + */ +static const ZydisFormatter FORMATTER_ATT = +{ + /* style */ ZYDIS_FORMATTER_STYLE_ATT, + /* force_memory_size */ ZYAN_FALSE, + /* force_memory_seg */ ZYAN_FALSE, + /* force_memory_scale */ ZYAN_TRUE, + /* force_relative_branches */ ZYAN_FALSE, + /* force_relative_riprel */ ZYAN_FALSE, + /* print_branch_size */ ZYAN_FALSE, + /* detailed_prefixes */ ZYAN_FALSE, + /* addr_base */ ZYDIS_NUMERIC_BASE_HEX, + /* addr_signedness */ ZYDIS_SIGNEDNESS_SIGNED, + /* addr_padding_absolute */ ZYDIS_PADDING_AUTO, + /* addr_padding_relative */ 2, + /* disp_base */ ZYDIS_NUMERIC_BASE_HEX, + /* disp_signedness */ ZYDIS_SIGNEDNESS_SIGNED, + /* disp_padding */ 2, + /* imm_base */ ZYDIS_NUMERIC_BASE_HEX, + /* imm_signedness */ ZYDIS_SIGNEDNESS_AUTO, + /* imm_padding */ 2, + /* case_prefixes */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_mnemonic */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_registers */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_typecasts */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_decorators */ ZYDIS_LETTER_CASE_DEFAULT, + /* hex_uppercase */ ZYAN_TRUE, + /* hex_force_leading_number */ ZYAN_FALSE, + /* number_format */ + { + // ZYDIS_NUMERIC_BASE_DEC + { + // Prefix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + // Suffix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + } + }, + // ZYDIS_NUMERIC_BASE_HEX + { + // Prefix + { + /* string */ &FORMATTER_ATT.number_format[ + ZYDIS_NUMERIC_BASE_HEX][0].string_data, + /* string_data */ ZYAN_DEFINE_STRING_VIEW("0x"), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + // Suffix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + } + } + }, + /* func_pre_instruction */ ZYAN_NULL, + /* func_post_instruction */ ZYAN_NULL, + /* func_format_instruction */ &ZydisFormatterATTFormatInstruction, + /* func_pre_operand */ ZYAN_NULL, + /* func_post_operand */ ZYAN_NULL, + /* func_format_operand_reg */ &ZydisFormatterBaseFormatOperandREG, + /* func_format_operand_mem */ &ZydisFormatterATTFormatOperandMEM, + /* func_format_operand_ptr */ &ZydisFormatterBaseFormatOperandPTR, + /* func_format_operand_imm */ &ZydisFormatterBaseFormatOperandIMM, + /* func_print_mnemonic */ &ZydisFormatterATTPrintMnemonic, + /* func_print_register */ &ZydisFormatterATTPrintRegister, + /* func_print_address_abs */ &ZydisFormatterATTPrintAddressABS, + /* func_print_address_rel */ &ZydisFormatterBasePrintAddressREL, + /* func_print_disp */ &ZydisFormatterATTPrintDISP, + /* func_print_imm */ &ZydisFormatterATTPrintIMM, + /* func_print_typecast */ ZYAN_NULL, + /* func_print_segment */ &ZydisFormatterBasePrintSegment, + /* func_print_prefixes */ &ZydisFormatterBasePrintPrefixes, + /* func_print_decorator */ &ZydisFormatterBasePrintDecorator +}; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif // ZYDIS_FORMATTER_ATT_H diff --git a/js/src/zydis/Zydis/Internal/FormatterBase.h b/js/src/zydis/Zydis/Internal/FormatterBase.h new file mode 100644 index 0000000000..f5989b5348 --- /dev/null +++ b/js/src/zydis/Zydis/Internal/FormatterBase.h @@ -0,0 +1,324 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Florian Bernd, Joel Hoener + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +/** + * @file + * Provides formatter functions that are shared between the different formatters. + */ + +#ifndef ZYDIS_FORMATTER_BASE_H +#define ZYDIS_FORMATTER_BASE_H + +#include "zydis/Zydis/Formatter.h" +#include "zydis/Zydis/Internal/String.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* String */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Appends an unsigned numeric value to the given string. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param base The numeric base. + * @param str The destination string. + * @param value The value to append. + * @param padding_length The padding length. + * @param force_leading_number Enable this option to prepend a leading `0` if the first + * character is non-numeric. + */ +#define ZYDIS_STRING_APPEND_NUM_U(formatter, base, str, value, padding_length, \ + force_leading_number) \ + switch (base) \ + { \ + case ZYDIS_NUMERIC_BASE_DEC: \ + ZYAN_CHECK(ZydisStringAppendDecU(str, value, padding_length, \ + (formatter)->number_format[base][0].string, \ + (formatter)->number_format[base][1].string)); \ + break; \ + case ZYDIS_NUMERIC_BASE_HEX: \ + ZYAN_CHECK(ZydisStringAppendHexU(str, value, padding_length, force_leading_number, \ + (formatter)->hex_uppercase, \ + (formatter)->number_format[base][0].string, \ + (formatter)->number_format[base][1].string)); \ + break; \ + default: \ + return ZYAN_STATUS_INVALID_ARGUMENT; \ + } + +/** + * Appends a signed numeric value to the given string. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param base The numeric base. + * @param str The destination string. + * @param value The value to append. + * @param padding_length The padding length. + * @param force_leading_number Enable this option to prepend a leading `0`, if the first + * character is non-numeric. + * @param force_sign Enable to print the '+' sign for positive numbers. + */ +#define ZYDIS_STRING_APPEND_NUM_S(formatter, base, str, value, padding_length, \ + force_leading_number, force_sign) \ + switch (base) \ + { \ + case ZYDIS_NUMERIC_BASE_DEC: \ + ZYAN_CHECK(ZydisStringAppendDecS(str, value, padding_length, force_sign, \ + (formatter)->number_format[base][0].string, \ + (formatter)->number_format[base][1].string)); \ + break; \ + case ZYDIS_NUMERIC_BASE_HEX: \ + ZYAN_CHECK(ZydisStringAppendHexS(str, value, padding_length, force_leading_number, \ + (formatter)->hex_uppercase, force_sign, \ + (formatter)->number_format[base][0].string, \ + (formatter)->number_format[base][1].string)); \ + break; \ + default: \ + return ZYAN_STATUS_INVALID_ARGUMENT; \ + } + +/* ---------------------------------------------------------------------------------------------- */ +/* Buffer */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Invokes the `ZydisFormatterBufferAppend` routine, if tokenization is enabled for the + * current pass. + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param type The token type. + * + * Using this macro instead of direct calls to `ZydisFormatterBufferAppend` greatly improves the + * performance for non-tokenizing passes. + */ +#define ZYDIS_BUFFER_APPEND_TOKEN(buffer, type) \ + if ((buffer)->is_token_list) \ + { \ + ZYAN_CHECK(ZydisFormatterBufferAppend(buffer, type)); \ + } + +/** + * Returns a snapshot of the buffer-state. + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param state Receives a snapshot of the buffer-state. + * + * Using this macro instead of direct calls to `ZydisFormatterBufferRemember` improves the + * performance for non-tokenizing passes. + */ +#define ZYDIS_BUFFER_REMEMBER(buffer, state) \ + if ((buffer)->is_token_list) \ + { \ + (state) = (ZyanUPointer)(buffer)->string.vector.data; \ + } else \ + { \ + (state) = (ZyanUPointer)(buffer)->string.vector.size; \ + } + +/** + * Appends a string (`STR_`-prefix) or a predefined token-list (`TOK_`-prefix). + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param name The base name (without prefix) of the string- or token. + */ +#define ZYDIS_BUFFER_APPEND(buffer, name) \ + if ((buffer)->is_token_list) \ + { \ + ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer, TOK_ ## name)); \ + } else \ + { \ + ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_ ## name)); \ + } + +// TODO: Implement `letter_case` for predefined tokens + +/** + * Appends a string (`STR_`-prefix) or a predefined token-list (`TOK_`-prefix). + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param name The base name (without prefix) of the string- or token. + * @param letter_case The desired letter-case. + */ +#define ZYDIS_BUFFER_APPEND_CASE(buffer, name, letter_case) \ + if ((buffer)->is_token_list) \ + { \ + ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer, TOK_ ## name)); \ + } else \ + { \ + ZYAN_CHECK(ZydisStringAppendShortCase(&buffer->string, &STR_ ## name, letter_case)); \ + } + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Helper functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Buffer */ +/* ---------------------------------------------------------------------------------------------- */ + +// MSVC does not like the C99 flexible-array extension +#ifdef ZYAN_MSVC +# pragma warning(push) +# pragma warning(disable:4200) +#endif + +#pragma pack(push, 1) + +typedef struct ZydisPredefinedToken_ +{ + ZyanU8 size; + ZyanU8 next; + ZyanU8 data[]; +} ZydisPredefinedToken; + +#pragma pack(pop) + +#ifdef ZYAN_MSVC +# pragma warning(pop) +#endif + +/** + * Appends a predefined token-list to the `buffer`. + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param data A pointer to the `ZydisPredefinedToken` struct. + * + * @return A zycore status code. + * + * This function is internally used to improve performance while adding static strings or multiple + * tokens at once. + */ +ZYAN_INLINE ZyanStatus ZydisFormatterBufferAppendPredefined(ZydisFormatterBuffer* buffer, + const ZydisPredefinedToken* data) +{ + ZYAN_ASSERT(buffer); + ZYAN_ASSERT(data); + + const ZyanUSize len = buffer->string.vector.size; + ZYAN_ASSERT((len > 0) && (len < 256)); + if (buffer->capacity <= len + data->size) + { + return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZydisFormatterToken* const last = (ZydisFormatterToken*)buffer->string.vector.data - 1; + last->next = (ZyanU8)len; + + ZYAN_MEMCPY((ZyanU8*)buffer->string.vector.data + len, &data->data[0], data->size); + + const ZyanUSize delta = len + data->next; + buffer->capacity -= delta; + buffer->string.vector.data = (ZyanU8*)buffer->string.vector.data + delta; + buffer->string.vector.size = data->size - data->next; + buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255); + + return ZYAN_STATUS_SUCCESS; +} + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the size to be used as explicit size suffix (`AT&T`) or explicit typecast + * (`INTEL`), if required. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param context A pointer to the `ZydisFormatterContext` struct. + * @param operand The instructions first memory operand. + * + * @return Returns the explicit size, if required, or `0`, if not needed. + * + * This function always returns a size different to `0`, if the `ZYDIS_FORMATTER_PROP_FORCE_SIZE` + * is set to `ZYAN_TRUE`. + */ +ZyanU32 ZydisFormatterHelperGetExplicitSize(const ZydisFormatter* formatter, + ZydisFormatterContext* context, const ZydisDecodedOperand* operand); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Formatter functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Operands */ +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZydisFormatterBaseFormatOperandREG(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterBaseFormatOperandPTR(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterBaseFormatOperandIMM(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +/* ---------------------------------------------------------------------------------------------- */ +/* Elemental tokens */ +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZydisFormatterBasePrintAddressABS(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterBasePrintAddressREL(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterBasePrintIMM(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +/* ---------------------------------------------------------------------------------------------- */ +/* Optional tokens */ +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZydisFormatterBasePrintSegment(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterBasePrintPrefixes(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterBasePrintDecorator(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif // ZYDIS_FORMATTER_BASE_H diff --git a/js/src/zydis/Zydis/Internal/FormatterIntel.h b/js/src/zydis/Zydis/Internal/FormatterIntel.h new file mode 100644 index 0000000000..0c62fa5bc7 --- /dev/null +++ b/js/src/zydis/Zydis/Internal/FormatterIntel.h @@ -0,0 +1,271 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Florian Bernd, Joel Hoener + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +/** + * @file + * Implements the `INTEL` style instruction-formatter. + */ + +#ifndef ZYDIS_FORMATTER_INTEL_H +#define ZYDIS_FORMATTER_INTEL_H + +#include "zydis/Zydis/Formatter.h" +#include "zydis/Zydis/Internal/FormatterBase.h" +#include "zydis/Zydis/Internal/String.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Formatter functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Intel */ +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZydisFormatterIntelFormatInstruction(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterIntelFormatOperandMEM(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterIntelPrintMnemonic(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterIntelPrintRegister(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisRegister reg); + +ZyanStatus ZydisFormatterIntelPrintDISP(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterIntelPrintTypecast(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +/* ---------------------------------------------------------------------------------------------- */ +/* MASM */ +/* ---------------------------------------------------------------------------------------------- */ + +ZyanStatus ZydisFormatterIntelFormatInstructionMASM(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +ZyanStatus ZydisFormatterIntelPrintAddressMASM(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Fomatter presets */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* INTEL */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * The default formatter configuration for `INTEL` style disassembly. + */ +static const ZydisFormatter FORMATTER_INTEL = +{ + /* style */ ZYDIS_FORMATTER_STYLE_INTEL, + /* force_memory_size */ ZYAN_FALSE, + /* force_memory_seg */ ZYAN_FALSE, + /* force_memory_scale */ ZYAN_TRUE, + /* force_relative_branches */ ZYAN_FALSE, + /* force_relative_riprel */ ZYAN_FALSE, + /* print_branch_size */ ZYAN_FALSE, + /* detailed_prefixes */ ZYAN_FALSE, + /* addr_base */ ZYDIS_NUMERIC_BASE_HEX, + /* addr_signedness */ ZYDIS_SIGNEDNESS_SIGNED, + /* addr_padding_absolute */ ZYDIS_PADDING_AUTO, + /* addr_padding_relative */ 2, + /* disp_base */ ZYDIS_NUMERIC_BASE_HEX, + /* disp_signedness */ ZYDIS_SIGNEDNESS_SIGNED, + /* disp_padding */ 2, + /* imm_base */ ZYDIS_NUMERIC_BASE_HEX, + /* imm_signedness */ ZYDIS_SIGNEDNESS_UNSIGNED, + /* imm_padding */ 2, + /* case_prefixes */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_mnemonic */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_registers */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_typecasts */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_decorators */ ZYDIS_LETTER_CASE_DEFAULT, + /* hex_uppercase */ ZYAN_TRUE, + /* hex_force_leading_number */ ZYAN_FALSE, + /* number_format */ + { + // ZYDIS_NUMERIC_BASE_DEC + { + // Prefix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + // Suffix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + } + }, + // ZYDIS_NUMERIC_BASE_HEX + { + // Prefix + { + /* string */ &FORMATTER_INTEL.number_format[ + ZYDIS_NUMERIC_BASE_HEX][0].string_data, + /* string_data */ ZYAN_DEFINE_STRING_VIEW("0x"), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + // Suffix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + } + } + }, + /* func_pre_instruction */ ZYAN_NULL, + /* func_post_instruction */ ZYAN_NULL, + /* func_format_instruction */ &ZydisFormatterIntelFormatInstruction, + /* func_pre_operand */ ZYAN_NULL, + /* func_post_operand */ ZYAN_NULL, + /* func_format_operand_reg */ &ZydisFormatterBaseFormatOperandREG, + /* func_format_operand_mem */ &ZydisFormatterIntelFormatOperandMEM, + /* func_format_operand_ptr */ &ZydisFormatterBaseFormatOperandPTR, + /* func_format_operand_imm */ &ZydisFormatterBaseFormatOperandIMM, + /* func_print_mnemonic */ &ZydisFormatterIntelPrintMnemonic, + /* func_print_register */ &ZydisFormatterIntelPrintRegister, + /* func_print_address_abs */ &ZydisFormatterBasePrintAddressABS, + /* func_print_address_rel */ &ZydisFormatterBasePrintAddressREL, + /* func_print_disp */ &ZydisFormatterIntelPrintDISP, + /* func_print_imm */ &ZydisFormatterBasePrintIMM, + /* func_print_typecast */ &ZydisFormatterIntelPrintTypecast, + /* func_print_segment */ &ZydisFormatterBasePrintSegment, + /* func_print_prefixes */ &ZydisFormatterBasePrintPrefixes, + /* func_print_decorator */ &ZydisFormatterBasePrintDecorator +}; + +/* ---------------------------------------------------------------------------------------------- */ +/* MASM */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * The default formatter configuration for `MASM` style disassembly. + */ +static const ZydisFormatter FORMATTER_INTEL_MASM = +{ + /* style */ ZYDIS_FORMATTER_STYLE_INTEL_MASM, + /* force_memory_size */ ZYAN_TRUE, + /* force_memory_seg */ ZYAN_FALSE, + /* force_memory_scale */ ZYAN_TRUE, + /* force_relative_branches */ ZYAN_FALSE, + /* force_relative_riprel */ ZYAN_FALSE, + /* print_branch_size */ ZYAN_FALSE, + /* detailed_prefixes */ ZYAN_FALSE, + /* addr_base */ ZYDIS_NUMERIC_BASE_HEX, + /* addr_signedness */ ZYDIS_SIGNEDNESS_SIGNED, + /* addr_padding_absolute */ ZYDIS_PADDING_DISABLED, + /* addr_padding_relative */ ZYDIS_PADDING_DISABLED, + /* disp_base */ ZYDIS_NUMERIC_BASE_HEX, + /* disp_signedness */ ZYDIS_SIGNEDNESS_SIGNED, + /* disp_padding */ ZYDIS_PADDING_DISABLED, + /* imm_base */ ZYDIS_NUMERIC_BASE_HEX, + /* imm_signedness */ ZYDIS_SIGNEDNESS_AUTO, + /* imm_padding */ ZYDIS_PADDING_DISABLED, + /* case_prefixes */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_mnemonic */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_registers */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_typecasts */ ZYDIS_LETTER_CASE_DEFAULT, + /* case_decorators */ ZYDIS_LETTER_CASE_DEFAULT, + /* hex_uppercase */ ZYAN_TRUE, + /* hex_force_leading_number */ ZYAN_TRUE, + /* number_format */ + { + // ZYDIS_NUMERIC_BASE_DEC + { + // Prefix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + // Suffix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + } + }, + // ZYDIS_NUMERIC_BASE_HEX + { + // Prefix + { + /* string */ ZYAN_NULL, + /* string_data */ ZYAN_DEFINE_STRING_VIEW(""), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + // Suffix + { + /* string */ &FORMATTER_INTEL_MASM.number_format[ + ZYDIS_NUMERIC_BASE_HEX][1].string_data, + /* string_data */ ZYAN_DEFINE_STRING_VIEW("h"), + /* buffer */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + } + } + }, + /* func_pre_instruction */ ZYAN_NULL, + /* func_post_instruction */ ZYAN_NULL, + /* func_format_instruction */ &ZydisFormatterIntelFormatInstructionMASM, + /* func_pre_operand */ ZYAN_NULL, + /* func_post_operand */ ZYAN_NULL, + /* func_format_operand_reg */ &ZydisFormatterBaseFormatOperandREG, + /* func_format_operand_mem */ &ZydisFormatterIntelFormatOperandMEM, + /* func_format_operand_ptr */ &ZydisFormatterBaseFormatOperandPTR, + /* func_format_operand_imm */ &ZydisFormatterBaseFormatOperandIMM, + /* func_print_mnemonic */ &ZydisFormatterIntelPrintMnemonic, + /* func_print_register */ &ZydisFormatterIntelPrintRegister, + /* func_print_address_abs */ &ZydisFormatterIntelPrintAddressMASM, + /* func_print_address_rel */ &ZydisFormatterIntelPrintAddressMASM, + /* func_print_disp */ &ZydisFormatterIntelPrintDISP, + /* func_print_imm */ &ZydisFormatterBasePrintIMM, + /* func_print_typecast */ &ZydisFormatterIntelPrintTypecast, + /* func_print_segment */ &ZydisFormatterBasePrintSegment, + /* func_print_prefixes */ &ZydisFormatterBasePrintPrefixes, + /* func_print_decorator */ &ZydisFormatterBasePrintDecorator +}; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif // ZYDIS_FORMATTER_INTEL_H diff --git a/js/src/zydis/Zydis/Internal/SharedData.h b/js/src/zydis/Zydis/Internal/SharedData.h new file mode 100644 index 0000000000..ddd4b83c17 --- /dev/null +++ b/js/src/zydis/Zydis/Internal/SharedData.h @@ -0,0 +1,979 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Florian Bernd + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +#ifndef ZYDIS_INTERNAL_SHAREDDATA_H +#define ZYDIS_INTERNAL_SHAREDDATA_H + +#include "zydis/Zycore/Defines.h" +#include "zydis/Zydis/Mnemonic.h" +#include "zydis/Zydis/Register.h" +#include "zydis/Zydis/SharedTypes.h" +#include "zydis/Zydis/DecoderTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +// MSVC does not like types other than (un-)signed int for bit-fields +#ifdef ZYAN_MSVC +# pragma warning(push) +# pragma warning(disable:4214) +#endif + +#pragma pack(push, 1) + +/* ---------------------------------------------------------------------------------------------- */ +/* Operand definition */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisSemanticOperandType` enum. + */ +typedef enum ZydisSemanticOperandType_ +{ + ZYDIS_SEMANTIC_OPTYPE_UNUSED, + ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_REG, + ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_MEM, + ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_IMM1, + ZYDIS_SEMANTIC_OPTYPE_GPR8, + ZYDIS_SEMANTIC_OPTYPE_GPR16, + ZYDIS_SEMANTIC_OPTYPE_GPR32, + ZYDIS_SEMANTIC_OPTYPE_GPR64, + ZYDIS_SEMANTIC_OPTYPE_GPR16_32_64, + ZYDIS_SEMANTIC_OPTYPE_GPR32_32_64, + ZYDIS_SEMANTIC_OPTYPE_GPR16_32_32, + ZYDIS_SEMANTIC_OPTYPE_GPR_ASZ, + ZYDIS_SEMANTIC_OPTYPE_FPR, + ZYDIS_SEMANTIC_OPTYPE_MMX, + ZYDIS_SEMANTIC_OPTYPE_XMM, + ZYDIS_SEMANTIC_OPTYPE_YMM, + ZYDIS_SEMANTIC_OPTYPE_ZMM, + ZYDIS_SEMANTIC_OPTYPE_TMM, + ZYDIS_SEMANTIC_OPTYPE_BND, + ZYDIS_SEMANTIC_OPTYPE_SREG, + ZYDIS_SEMANTIC_OPTYPE_CR, + ZYDIS_SEMANTIC_OPTYPE_DR, + ZYDIS_SEMANTIC_OPTYPE_MASK, + ZYDIS_SEMANTIC_OPTYPE_MEM, + ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBX, + ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBY, + ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBZ, + ZYDIS_SEMANTIC_OPTYPE_IMM, + ZYDIS_SEMANTIC_OPTYPE_REL, + ZYDIS_SEMANTIC_OPTYPE_PTR, + ZYDIS_SEMANTIC_OPTYPE_AGEN, + ZYDIS_SEMANTIC_OPTYPE_MOFFS, + ZYDIS_SEMANTIC_OPTYPE_MIB, + + /** + * Maximum value of this enum. + */ + ZYDIS_SEMANTIC_OPTYPE_MAX_VALUE = ZYDIS_SEMANTIC_OPTYPE_MIB, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_SEMANTIC_OPTYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SEMANTIC_OPTYPE_MAX_VALUE) +} ZydisSemanticOperandType; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisInternalElementType` enum. + */ +typedef enum ZydisInternalElementType_ +{ + ZYDIS_IELEMENT_TYPE_INVALID, + ZYDIS_IELEMENT_TYPE_VARIABLE, + ZYDIS_IELEMENT_TYPE_STRUCT, + ZYDIS_IELEMENT_TYPE_INT, + ZYDIS_IELEMENT_TYPE_UINT, + ZYDIS_IELEMENT_TYPE_INT1, + ZYDIS_IELEMENT_TYPE_INT8, + ZYDIS_IELEMENT_TYPE_INT16, + ZYDIS_IELEMENT_TYPE_INT32, + ZYDIS_IELEMENT_TYPE_INT64, + ZYDIS_IELEMENT_TYPE_UINT8, + ZYDIS_IELEMENT_TYPE_UINT16, + ZYDIS_IELEMENT_TYPE_UINT32, + ZYDIS_IELEMENT_TYPE_UINT64, + ZYDIS_IELEMENT_TYPE_UINT128, + ZYDIS_IELEMENT_TYPE_UINT256, + ZYDIS_IELEMENT_TYPE_FLOAT16, + ZYDIS_IELEMENT_TYPE_FLOAT16X2, + ZYDIS_IELEMENT_TYPE_FLOAT32, + ZYDIS_IELEMENT_TYPE_FLOAT64, + ZYDIS_IELEMENT_TYPE_FLOAT80, + ZYDIS_IELEMENT_TYPE_BCD80, + ZYDIS_IELEMENT_TYPE_CC3, + ZYDIS_IELEMENT_TYPE_CC5, + + /** + * Maximum value of this enum. + */ + ZYDIS_IELEMENT_TYPE_MAX_VALUE = ZYDIS_IELEMENT_TYPE_CC5, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_IELEMENT_TYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_IELEMENT_TYPE_MAX_VALUE) +} ZydisInternalElementType; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisImplicitRegisterType` enum. + */ +typedef enum ZydisImplicitRegisterType_ +{ + // TODO: Rename OSZ|ASZ|SSZ_ + ZYDIS_IMPLREG_TYPE_STATIC, + ZYDIS_IMPLREG_TYPE_GPR_OSZ, + ZYDIS_IMPLREG_TYPE_GPR_ASZ, + ZYDIS_IMPLREG_TYPE_IP_ASZ, + ZYDIS_IMPLREG_TYPE_IP_SSZ, + ZYDIS_IMPLREG_TYPE_GPR_SSZ, + ZYDIS_IMPLREG_TYPE_FLAGS_SSZ, + + /** + * Maximum value of this enum. + */ + ZYDIS_IMPLREG_TYPE_MAX_VALUE = ZYDIS_IMPLREG_TYPE_FLAGS_SSZ, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_IMPLREG_TYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_IMPLREG_TYPE_MAX_VALUE) +} ZydisImplicitRegisterType; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisImplicitMemBase` enum. + */ +typedef enum ZydisImplicitMemBase_ +{ + // TODO: Rename OSZ|ASZ|SSZ_ + ZYDIS_IMPLMEM_BASE_AGPR_REG, + ZYDIS_IMPLMEM_BASE_AGPR_RM, + ZYDIS_IMPLMEM_BASE_AAX, + ZYDIS_IMPLMEM_BASE_ADX, + ZYDIS_IMPLMEM_BASE_ABX, + ZYDIS_IMPLMEM_BASE_ASI, + ZYDIS_IMPLMEM_BASE_ADI, + ZYDIS_IMPLMEM_BASE_SSP, + ZYDIS_IMPLMEM_BASE_SBP, + + /** + * Maximum value of this enum. + */ + ZYDIS_IMPLMEM_BASE_MAX_VALUE = ZYDIS_IMPLMEM_BASE_SBP, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_IMPLMEM_BASE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_IMPLMEM_BASE_MAX_VALUE) +} ZydisImplicitMemBase; + +/* ---------------------------------------------------------------------------------------------- */ + +// MSVC does not correctly execute the `pragma pack(1)` compiler-directive, if we use the correct +// enum types +ZYAN_STATIC_ASSERT(ZYDIS_SEMANTIC_OPTYPE_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_OPERAND_VISIBILITY_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_OPERAND_ACTION_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_IELEMENT_TYPE_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_OPERAND_ENCODING_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_IMPLREG_TYPE_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_REGISTER_REQUIRED_BITS <= 16); +ZYAN_STATIC_ASSERT(ZYDIS_IMPLMEM_BASE_REQUIRED_BITS <= 8); + +/** + * Defines the `ZydisOperandDefinition` struct. + */ +typedef struct ZydisOperandDefinition_ +{ + ZyanU8 type ZYAN_BITFIELD(ZYDIS_SEMANTIC_OPTYPE_REQUIRED_BITS); + ZyanU8 visibility ZYAN_BITFIELD(ZYDIS_OPERAND_VISIBILITY_REQUIRED_BITS); + ZyanU8 actions ZYAN_BITFIELD(ZYDIS_OPERAND_ACTION_REQUIRED_BITS); + ZyanU16 size[3]; + ZyanU8 element_type ZYAN_BITFIELD(ZYDIS_IELEMENT_TYPE_REQUIRED_BITS); + union + { + ZyanU8 encoding ZYAN_BITFIELD(ZYDIS_OPERAND_ENCODING_REQUIRED_BITS); + struct + { + ZyanU8 type ZYAN_BITFIELD(ZYDIS_IMPLREG_TYPE_REQUIRED_BITS); + union + { + ZyanU16 reg ZYAN_BITFIELD(ZYDIS_REGISTER_REQUIRED_BITS); + ZyanU8 id ZYAN_BITFIELD(6); + } reg; + } reg; + struct + { + ZyanU8 seg ZYAN_BITFIELD(3); + ZyanU8 base ZYAN_BITFIELD(ZYDIS_IMPLMEM_BASE_REQUIRED_BITS); + } mem; + } op; + ZyanBool is_multisource4 ZYAN_BITFIELD(1); + ZyanBool ignore_seg_override ZYAN_BITFIELD(1); +} ZydisOperandDefinition; + +/* ---------------------------------------------------------------------------------------------- */ +/* Instruction definition */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisReadWriteAction` enum. + */ +typedef enum ZydisReadWriteAction_ +{ + ZYDIS_RW_ACTION_NONE, + ZYDIS_RW_ACTION_READ, + ZYDIS_RW_ACTION_WRITE, + ZYDIS_RW_ACTION_READWRITE, + + /** + * Maximum value of this enum. + */ + ZYDIS_RW_ACTION_MAX_VALUE = ZYDIS_RW_ACTION_READWRITE, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_RW_ACTION_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_RW_ACTION_MAX_VALUE) +} ZydisReadWriteAction; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisInternalVectorLength` enum. + */ +typedef enum ZydisInternalVectorLength_ +{ + ZYDIS_IVECTOR_LENGTH_DEFAULT, + ZYDIS_IVECTOR_LENGTH_FIXED_128, + ZYDIS_IVECTOR_LENGTH_FIXED_256, + ZYDIS_IVECTOR_LENGTH_FIXED_512, + + /** + * Maximum value of this enum. + */ + ZYDIS_IVECTOR_LENGTH_MAX_VALUE = ZYDIS_IVECTOR_LENGTH_FIXED_512, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_IVECTOR_LENGTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_IVECTOR_LENGTH_MAX_VALUE) +} ZydisInternalVectorLength; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisInternalElementSize` enum. + */ +typedef enum ZydisInternalElementSize_ +{ + ZYDIS_IELEMENT_SIZE_INVALID, + ZYDIS_IELEMENT_SIZE_8, + ZYDIS_IELEMENT_SIZE_16, + ZYDIS_IELEMENT_SIZE_32, + ZYDIS_IELEMENT_SIZE_64, + ZYDIS_IELEMENT_SIZE_128, + + /** + * Maximum value of this enum. + */ + ZYDIS_IELEMENT_SIZE_MAX_VALUE = ZYDIS_IELEMENT_SIZE_128, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_IELEMENT_SIZE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_IELEMENT_SIZE_MAX_VALUE) +} ZydisInternalElementSize; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisEVEXFunctionality` enum. + */ +typedef enum ZydisEVEXFunctionality_ +{ + ZYDIS_EVEX_FUNC_INVALID, + /** + * `EVEX.b` enables broadcast functionality. + */ + ZYDIS_EVEX_FUNC_BC, + /** + * `EVEX.b` enables embedded-rounding functionality. + */ + ZYDIS_EVEX_FUNC_RC, + /** + * `EVEX.b` enables sae functionality. + */ + ZYDIS_EVEX_FUNC_SAE, + + /** + * Maximum value of this enum. + */ + ZYDIS_EVEX_FUNC_MAX_VALUE = ZYDIS_EVEX_FUNC_SAE, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_EVEX_FUNC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_EVEX_FUNC_MAX_VALUE) +} ZydisEVEXFunctionality; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisEVEXTupleType` enum. + */ +typedef enum ZydisEVEXTupleType_ +{ + ZYDIS_TUPLETYPE_INVALID, + /** + * Full Vector + */ + ZYDIS_TUPLETYPE_FV, + /** + * Half Vector + */ + ZYDIS_TUPLETYPE_HV, + /** + * Full Vector Mem + */ + ZYDIS_TUPLETYPE_FVM, + /** + * Tuple1 Scalar + */ + ZYDIS_TUPLETYPE_T1S, + /** + * Tuple1 Fixed + */ + ZYDIS_TUPLETYPE_T1F, + /** + * Tuple1 4x32 + */ + ZYDIS_TUPLETYPE_T1_4X, + /** + * Gather / Scatter + */ + ZYDIS_TUPLETYPE_GSCAT, + /** + * Tuple2 + */ + ZYDIS_TUPLETYPE_T2, + /** + * Tuple4 + */ + ZYDIS_TUPLETYPE_T4, + /** + * Tuple8 + */ + ZYDIS_TUPLETYPE_T8, + /** + * Half Mem + */ + ZYDIS_TUPLETYPE_HVM, + /** + * QuarterMem + */ + ZYDIS_TUPLETYPE_QVM, + /** + * OctMem + */ + ZYDIS_TUPLETYPE_OVM, + /** + * Mem128 + */ + ZYDIS_TUPLETYPE_M128, + /** + * MOVDDUP + */ + ZYDIS_TUPLETYPE_DUP, + /** + * Quarter of the vector-length. + */ + ZYDIS_TUPLETYPE_QUARTER, + + /** + * Maximum value of this enum. + */ + ZYDIS_TUPLETYPE_MAX_VALUE = ZYDIS_TUPLETYPE_QUARTER, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_TUPLETYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_TUPLETYPE_MAX_VALUE) +} ZydisEVEXTupleType; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisMVEXFunctionality` enum. + */ +typedef enum ZydisMVEXFunctionality_ +{ + /** + * The `MVEX.SSS` value is ignored. + */ + ZYDIS_MVEX_FUNC_IGNORED, + /** + * `MVEX.SSS` must be `000b`. + */ + ZYDIS_MVEX_FUNC_INVALID, + /** + * `MVEX.SSS` controls embedded-rounding functionality. + */ + ZYDIS_MVEX_FUNC_RC, + /** + * `MVEX.SSS` controls sae functionality. + */ + ZYDIS_MVEX_FUNC_SAE, + /** + * No special operation (32bit float elements). + */ + ZYDIS_MVEX_FUNC_F_32, + /** + * No special operation (32bit uint elements). + */ + ZYDIS_MVEX_FUNC_I_32, + /** + * No special operation (64bit float elements). + */ + ZYDIS_MVEX_FUNC_F_64, + /** + * No special operation (64bit uint elements). + */ + ZYDIS_MVEX_FUNC_I_64, + /** + * Sf32(reg) or Si32(reg). + */ + ZYDIS_MVEX_FUNC_SWIZZLE_32, + /** + * Sf64(reg) or Si64(reg). + */ + ZYDIS_MVEX_FUNC_SWIZZLE_64, + /** + * Sf32(mem). + */ + ZYDIS_MVEX_FUNC_SF_32, + /** + * Sf32(mem) broadcast only. + */ + ZYDIS_MVEX_FUNC_SF_32_BCST, + /** + * Sf32(mem) broadcast 4to16 only. + */ + ZYDIS_MVEX_FUNC_SF_32_BCST_4TO16, + /** + * Sf64(mem). + */ + ZYDIS_MVEX_FUNC_SF_64, + /** + * Si32(mem). + */ + ZYDIS_MVEX_FUNC_SI_32, + /** + * Si32(mem) broadcast only. + */ + ZYDIS_MVEX_FUNC_SI_32_BCST, + /** + * Si32(mem) broadcast 4to16 only. + */ + ZYDIS_MVEX_FUNC_SI_32_BCST_4TO16, + /** + * Si64(mem). + */ + ZYDIS_MVEX_FUNC_SI_64, + /** + * Uf32. + */ + ZYDIS_MVEX_FUNC_UF_32, + /** + * Uf64. + */ + ZYDIS_MVEX_FUNC_UF_64, + /** + * Ui32. + */ + ZYDIS_MVEX_FUNC_UI_32, + /** + * Ui64. + */ + ZYDIS_MVEX_FUNC_UI_64, + /** + * Df32. + */ + ZYDIS_MVEX_FUNC_DF_32, + /** + * Df64. + */ + ZYDIS_MVEX_FUNC_DF_64, + /** + * Di32. + */ + ZYDIS_MVEX_FUNC_DI_32, + /** + * Di64. + */ + ZYDIS_MVEX_FUNC_DI_64, + + /** + * Maximum value of this enum. + */ + ZYDIS_MVEX_FUNC_MAX_VALUE = ZYDIS_MVEX_FUNC_DI_64, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MVEX_FUNC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MVEX_FUNC_MAX_VALUE) +} ZydisMVEXFunctionality; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisVEXStaticBroadcast` enum. + */ +typedef enum ZydisVEXStaticBroadcast +{ + ZYDIS_VEX_STATIC_BROADCAST_NONE, + ZYDIS_VEX_STATIC_BROADCAST_1_TO_2, + ZYDIS_VEX_STATIC_BROADCAST_1_TO_4, + ZYDIS_VEX_STATIC_BROADCAST_1_TO_8, + ZYDIS_VEX_STATIC_BROADCAST_1_TO_16, + ZYDIS_VEX_STATIC_BROADCAST_1_TO_32, + ZYDIS_VEX_STATIC_BROADCAST_2_TO_4, + + /** + * Maximum value of this enum. + */ + ZYDIS_VEX_STATIC_BROADCAST_MAX_VALUE = ZYDIS_VEX_STATIC_BROADCAST_2_TO_4, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_VEX_STATIC_BROADCAST_REQUIRED_BITS = + ZYAN_BITS_TO_REPRESENT(ZYDIS_VEX_STATIC_BROADCAST_MAX_VALUE) +} ZydisVEXStaticBroadcast; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisEVEXStaticBroadcast` enum. + */ +typedef enum ZydisEVEXStaticBroadcast_ +{ + ZYDIS_EVEX_STATIC_BROADCAST_NONE, + ZYDIS_EVEX_STATIC_BROADCAST_1_TO_2, + ZYDIS_EVEX_STATIC_BROADCAST_1_TO_4, + ZYDIS_EVEX_STATIC_BROADCAST_1_TO_8, + ZYDIS_EVEX_STATIC_BROADCAST_1_TO_16, + ZYDIS_EVEX_STATIC_BROADCAST_1_TO_32, + ZYDIS_EVEX_STATIC_BROADCAST_1_TO_64, + ZYDIS_EVEX_STATIC_BROADCAST_2_TO_4, + ZYDIS_EVEX_STATIC_BROADCAST_2_TO_8, + ZYDIS_EVEX_STATIC_BROADCAST_2_TO_16, + ZYDIS_EVEX_STATIC_BROADCAST_4_TO_8, + ZYDIS_EVEX_STATIC_BROADCAST_4_TO_16, + ZYDIS_EVEX_STATIC_BROADCAST_8_TO_16, + + /** + * Maximum value of this enum. + */ + ZYDIS_EVEX_STATIC_BROADCAST_MAX_VALUE = ZYDIS_EVEX_STATIC_BROADCAST_8_TO_16, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_EVEX_STATIC_BROADCAST_REQUIRED_BITS = + ZYAN_BITS_TO_REPRESENT(ZYDIS_EVEX_STATIC_BROADCAST_MAX_VALUE) +} ZydisEVEXStaticBroadcast; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisMVEXStaticBroadcast` enum. + */ +typedef enum ZydisMVEXStaticBroadcast_ +{ + ZYDIS_MVEX_STATIC_BROADCAST_NONE, + ZYDIS_MVEX_STATIC_BROADCAST_1_TO_8, + ZYDIS_MVEX_STATIC_BROADCAST_1_TO_16, + ZYDIS_MVEX_STATIC_BROADCAST_4_TO_8, + ZYDIS_MVEX_STATIC_BROADCAST_4_TO_16, + + /** + * Maximum value of this enum. + */ + ZYDIS_MVEX_STATIC_BROADCAST_MAX_VALUE = ZYDIS_MVEX_STATIC_BROADCAST_4_TO_16, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MVEX_STATIC_BROADCAST_REQUIRED_BITS = + ZYAN_BITS_TO_REPRESENT(ZYDIS_MVEX_STATIC_BROADCAST_MAX_VALUE) +} ZydisMVEXStaticBroadcast; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisMaskPolicy` enum. + */ +typedef enum ZydisMaskPolicy_ +{ + ZYDIS_MASK_POLICY_INVALID, + /** + * The instruction accepts mask-registers other than the default-mask (K0), but + * does not require them. + */ + ZYDIS_MASK_POLICY_ALLOWED, + /** + * The instruction requires a mask-register other than the default-mask (K0). + */ + ZYDIS_MASK_POLICY_REQUIRED, + /** + * The instruction does not allow a mask-register other than the default-mask (K0). + */ + ZYDIS_MASK_POLICY_FORBIDDEN, + + /** + * Maximum value of this enum. + */ + ZYDIS_MASK_POLICY_MAX_VALUE = ZYDIS_MASK_POLICY_FORBIDDEN, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MASK_POLICY_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MASK_POLICY_MAX_VALUE) +} ZydisMaskPolicy; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisMaskOverride` enum. + */ +typedef enum ZydisMaskOverride_ +{ + ZYDIS_MASK_OVERRIDE_DEFAULT, + ZYDIS_MASK_OVERRIDE_ZEROING, + ZYDIS_MASK_OVERRIDE_CONTROL, + + /** + * Maximum value of this enum. + */ + ZYDIS_MASK_OVERRIDE_MAX_VALUE = ZYDIS_MASK_OVERRIDE_CONTROL, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MASK_OVERRIDE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MASK_OVERRIDE_MAX_VALUE) +} ZydisMaskOverride; + +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYDIS_OPDEF_REQUIRED_BITS \ + ZYAN_MAX(ZYDIS_REGKIND_REQUIRED_BITS, ZYDIS_MEMOP_TYPE_REQUIRED_BITS + 1) + 1 + +#define ZYDIS_OPDEF_GET_REG(operand_definition) \ + ((operand_definition) & ((1 << ZYDIS_REGKIND_REQUIRED_BITS ) - 1)) + +#define ZYDIS_OPDEF_GET_MEM(operand_definition) \ + ((operand_definition) & ((1 << ZYDIS_MEMOP_TYPE_REQUIRED_BITS) - 1)) + +#define ZYDIS_OPDEF_GET_REG_HIGH_BIT(operand_definition) \ + (((operand_definition) >> ZYDIS_REGKIND_REQUIRED_BITS ) & 0x01) + +#define ZYDIS_OPDEF_GET_MEM_HIGH_BIT(operand_definition) \ + (((operand_definition) >> ZYDIS_MEMOP_TYPE_REQUIRED_BITS) & 0x01) + +// MSVC does not correctly execute the `pragma pack(1)` compiler-directive, if we use the correct +// enum types +ZYAN_STATIC_ASSERT(ZYDIS_MNEMONIC_REQUIRED_BITS <= 16); +ZYAN_STATIC_ASSERT(ZYDIS_CATEGORY_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_ISA_SET_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_ISA_EXT_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_BRANCH_TYPE_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_EXCEPTION_CLASS_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_OPDEF_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_RW_ACTION_REQUIRED_BITS <= 8); + +#ifndef ZYDIS_MINIMAL_MODE +# define ZYDIS_INSTRUCTION_DEFINITION_BASE \ + ZyanU16 mnemonic ZYAN_BITFIELD(ZYDIS_MNEMONIC_REQUIRED_BITS); \ + ZyanU8 operand_count ZYAN_BITFIELD( 4); \ + ZyanU8 operand_count_visible ZYAN_BITFIELD( 3); \ + ZyanU16 operand_reference ZYAN_BITFIELD(15); \ + ZyanU8 operand_size_map ZYAN_BITFIELD( 3); \ + ZyanU8 address_size_map ZYAN_BITFIELD( 2); \ + ZyanU8 flags_reference ZYAN_BITFIELD( 7); \ + ZyanBool requires_protected_mode ZYAN_BITFIELD( 1); \ + ZyanBool no_compat_mode ZYAN_BITFIELD( 1); \ + ZyanU8 category ZYAN_BITFIELD(ZYDIS_CATEGORY_REQUIRED_BITS); \ + ZyanU8 isa_set ZYAN_BITFIELD(ZYDIS_ISA_SET_REQUIRED_BITS); \ + ZyanU8 isa_ext ZYAN_BITFIELD(ZYDIS_ISA_EXT_REQUIRED_BITS); \ + ZyanU8 branch_type ZYAN_BITFIELD(ZYDIS_BRANCH_TYPE_REQUIRED_BITS); \ + ZyanU8 exception_class ZYAN_BITFIELD(ZYDIS_EXCEPTION_CLASS_REQUIRED_BITS); \ + ZyanU8 op_reg ZYAN_BITFIELD(ZYDIS_OPDEF_REQUIRED_BITS); \ + ZyanU8 op_rm ZYAN_BITFIELD(ZYDIS_OPDEF_REQUIRED_BITS); \ + ZyanU8 cpu_state ZYAN_BITFIELD(ZYDIS_RW_ACTION_REQUIRED_BITS); \ + ZyanU8 fpu_state ZYAN_BITFIELD(ZYDIS_RW_ACTION_REQUIRED_BITS); \ + ZyanU8 xmm_state ZYAN_BITFIELD(ZYDIS_RW_ACTION_REQUIRED_BITS); \ + ZyanBool accepts_segment ZYAN_BITFIELD( 1) +#else +# define ZYDIS_INSTRUCTION_DEFINITION_BASE \ + ZyanU16 mnemonic ZYAN_BITFIELD(ZYDIS_MNEMONIC_REQUIRED_BITS); \ + ZyanU8 operand_size_map ZYAN_BITFIELD( 3); \ + ZyanU8 address_size_map ZYAN_BITFIELD( 2); \ + ZyanBool requires_protected_mode ZYAN_BITFIELD( 1); \ + ZyanBool no_compat_mode ZYAN_BITFIELD( 1); \ + ZyanU8 op_reg ZYAN_BITFIELD(ZYDIS_OPDEF_REQUIRED_BITS); \ + ZyanU8 op_rm ZYAN_BITFIELD(ZYDIS_OPDEF_REQUIRED_BITS) +#endif + +#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR \ + ZYDIS_INSTRUCTION_DEFINITION_BASE; \ + ZyanU8 op_ndsndd ZYAN_BITFIELD(ZYDIS_OPDEF_REQUIRED_BITS) + +#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_INTEL \ + ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; \ + ZyanBool is_gather ZYAN_BITFIELD( 1); \ + ZyanBool no_source_dest_match ZYAN_BITFIELD( 1); \ + ZyanBool no_source_source_match ZYAN_BITFIELD( 1) // TODO: Could be moved to VEX + +/** + * Defines the `ZydisInstructionDefinition` struct. + */ +typedef struct ZydisInstructionDefinition_ +{ + ZYDIS_INSTRUCTION_DEFINITION_BASE; +} ZydisInstructionDefinition; + +/** + * Defines the `ZydisInstructionDefinitionLEGACY` struct. + */ +typedef struct ZydisInstructionDefinitionLEGACY_ +{ + ZYDIS_INSTRUCTION_DEFINITION_BASE; +#ifndef ZYDIS_MINIMAL_MODE + ZyanBool is_privileged ZYAN_BITFIELD( 1); +#endif + ZyanBool accepts_LOCK ZYAN_BITFIELD( 1); +#ifndef ZYDIS_MINIMAL_MODE + ZyanBool accepts_REP ZYAN_BITFIELD( 1); + ZyanBool accepts_REPEREPZ ZYAN_BITFIELD( 1); + ZyanBool accepts_REPNEREPNZ ZYAN_BITFIELD( 1); + ZyanBool accepts_BOUND ZYAN_BITFIELD( 1); + ZyanBool accepts_XACQUIRE ZYAN_BITFIELD( 1); + ZyanBool accepts_XRELEASE ZYAN_BITFIELD( 1); + ZyanBool accepts_NOTRACK ZYAN_BITFIELD( 1); + ZyanBool accepts_hle_without_lock ZYAN_BITFIELD( 1); + ZyanBool accepts_branch_hints ZYAN_BITFIELD( 1); +#endif +} ZydisInstructionDefinitionLEGACY; + +/** + * Defines the `ZydisInstructionDefinition3DNOW` struct. + */ +typedef struct ZydisInstructionDefinition3DNOW_ +{ + ZYDIS_INSTRUCTION_DEFINITION_BASE; +} ZydisInstructionDefinition3DNOW; + +/** + * Defines the `ZydisInstructionDefinitionXOP` struct. + */ +typedef struct ZydisInstructionDefinitionXOP_ +{ + ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; +} ZydisInstructionDefinitionXOP; + +// MSVC does not correctly execute the `pragma pack(1)` compiler-directive, if we use the correct +// enum types +ZYAN_STATIC_ASSERT(ZYDIS_VEX_STATIC_BROADCAST_REQUIRED_BITS <= 8); + +/** + * Defines the `ZydisInstructionDefinitionVEX` struct. + */ +typedef struct ZydisInstructionDefinitionVEX_ +{ + ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_INTEL; +#ifndef ZYDIS_MINIMAL_MODE + ZyanU8 broadcast ZYAN_BITFIELD(ZYDIS_VEX_STATIC_BROADCAST_REQUIRED_BITS); +#endif +} ZydisInstructionDefinitionVEX; + +#ifndef ZYDIS_DISABLE_AVX512 + +// MSVC does not correctly execute the `pragma pack(1)` compiler-directive, if we use the correct +// enum types +ZYAN_STATIC_ASSERT(ZYDIS_IVECTOR_LENGTH_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_TUPLETYPE_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_IELEMENT_SIZE_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_EVEX_FUNC_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_MASK_POLICY_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_MASK_OVERRIDE_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_EVEX_STATIC_BROADCAST_REQUIRED_BITS <= 8); + +/** + * Defines the `ZydisInstructionDefinitionEVEX` struct. + */ +typedef struct ZydisInstructionDefinitionEVEX_ +{ + ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_INTEL; +#ifndef ZYDIS_MINIMAL_MODE + ZyanU8 vector_length ZYAN_BITFIELD(ZYDIS_IVECTOR_LENGTH_REQUIRED_BITS); + ZyanU8 tuple_type ZYAN_BITFIELD(ZYDIS_TUPLETYPE_REQUIRED_BITS); + ZyanU8 element_size ZYAN_BITFIELD(ZYDIS_IELEMENT_SIZE_REQUIRED_BITS); + ZyanU8 functionality ZYAN_BITFIELD(ZYDIS_EVEX_FUNC_REQUIRED_BITS); +#endif + ZyanU8 mask_policy ZYAN_BITFIELD(ZYDIS_MASK_POLICY_REQUIRED_BITS); + ZyanBool accepts_zero_mask ZYAN_BITFIELD( 1); +#ifndef ZYDIS_MINIMAL_MODE + ZyanU8 mask_override ZYAN_BITFIELD(ZYDIS_MASK_OVERRIDE_REQUIRED_BITS); + ZyanU8 broadcast ZYAN_BITFIELD(ZYDIS_EVEX_STATIC_BROADCAST_REQUIRED_BITS); +#endif +} ZydisInstructionDefinitionEVEX; +#endif + +#ifndef ZYDIS_DISABLE_KNC + +// MSVC does not correctly execute the `pragma pack(1)` compiler-directive, if we use the correct +// enum types +ZYAN_STATIC_ASSERT(ZYDIS_MVEX_FUNC_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_MASK_POLICY_REQUIRED_BITS <= 8); +ZYAN_STATIC_ASSERT(ZYDIS_MVEX_STATIC_BROADCAST_REQUIRED_BITS <= 8); + +/** + * Defines the `ZydisInstructionDefinitionMVEX` struct. + */ +typedef struct ZydisInstructionDefinitionMVEX_ +{ + ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_INTEL; + ZyanU8 functionality ZYAN_BITFIELD(ZYDIS_MVEX_FUNC_REQUIRED_BITS); + ZyanU8 mask_policy ZYAN_BITFIELD(ZYDIS_MASK_POLICY_REQUIRED_BITS); +#ifndef ZYDIS_MINIMAL_MODE + ZyanBool has_element_granularity ZYAN_BITFIELD( 1); + ZyanU8 broadcast ZYAN_BITFIELD(ZYDIS_MVEX_STATIC_BROADCAST_REQUIRED_BITS); +#endif +} ZydisInstructionDefinitionMVEX; +#endif + +/* ---------------------------------------------------------------------------------------------- */ + +#pragma pack(pop) + +#ifdef ZYAN_MSVC +# pragma warning(pop) +#endif + +/* ---------------------------------------------------------------------------------------------- */ +/* Accessed CPU/FPU flags */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * Contains information about the CPU/FPU flags accessed by an instruction. + * + * We don't want this struct to be packed! A pointer to the individual members will be used by the + * `ZydisDecodedInstruction` struct. + */ +typedef struct ZydisDefinitionAccessedFlags_ +{ + ZydisAccessedFlags cpu_flags; + ZydisAccessedFlags fpu_flags; +} ZydisDefinitionAccessedFlags; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Instruction definition */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the instruction-definition with the given `encoding` and `id`. + * + * @param encoding The instruction-encoding. + * @param id The definition-id. + * @param definition A pointer to the variable that receives a pointer to the instruction- + * definition. + */ +ZYDIS_NO_EXPORT void ZydisGetInstructionDefinition(ZydisInstructionEncoding encoding, + ZyanU16 id, const ZydisInstructionDefinition** definition); + +/* ---------------------------------------------------------------------------------------------- */ +/* Operand definition */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYDIS_MINIMAL_MODE +/** + * Returns the the operand-definitions for the given instruction-`definition`. + * + * @param definition A pointer to the instruction-definition. + * + * @return A pointer to the first operand definition of the instruction, or `ZYAN_NULL`. + */ +ZYDIS_NO_EXPORT const ZydisOperandDefinition* ZydisGetOperandDefinitions( + const ZydisInstructionDefinition* definition); +#endif + +/* ---------------------------------------------------------------------------------------------- */ +/* Element info */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYDIS_MINIMAL_MODE +/** + * Returns the actual type and size of an internal element-type. + * + * @param element The internal element type. + * @param type The actual element type. + * @param size The element size. + */ +ZYDIS_NO_EXPORT void ZydisGetElementInfo(ZydisInternalElementType element, ZydisElementType* type, + ZydisElementSize* size); +#endif + +/* ---------------------------------------------------------------------------------------------- */ +/* Accessed CPU flags */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYDIS_MINIMAL_MODE +/** + * Returns the the operand-definitions for the given instruction-`definition`. + * + * @param definition A pointer to the instruction-definition. + * @param flags A pointer to the variable that receives the `ZydisDefinitionAccessedFlags` + * struct. + * + * @return `ZYAN_TRUE`, if the instruction accesses any flags, or `ZYAN_FALSE`, if not. + */ +ZYDIS_NO_EXPORT ZyanBool ZydisGetAccessedFlags(const ZydisInstructionDefinition* definition, + const ZydisDefinitionAccessedFlags** flags); +#endif + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_INTERNAL_SHAREDDATA_H */ diff --git a/js/src/zydis/Zydis/Internal/String.h b/js/src/zydis/Zydis/Internal/String.h new file mode 100644 index 0000000000..0d3ead900f --- /dev/null +++ b/js/src/zydis/Zydis/Internal/String.h @@ -0,0 +1,470 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Florian Bernd, Joel Hoener + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +/** + * @file + * Provides some internal, more performant, but unsafe helper functions for the `ZyanString` + * data-type. + * + * Most of these functions are very similar to the ones in `Zycore/String.h`, but inlined and + * without optional overhead like parameter-validation checks, etc ... + * + * The `ZyanString` data-type is able to dynamically allocate memory on the heap, but as `Zydis` is + * designed to be a non-'malloc'ing library, all functions in this file assume that the instances + * they are operating on are created with a user-defined static-buffer. + */ + +#ifndef ZYDIS_INTERNAL_STRING_H +#define ZYDIS_INTERNAL_STRING_H + +#include "zydis/Zycore/LibC.h" +#include "zydis/Zycore/String.h" +#include "zydis/Zycore/Types.h" +#include "zydis/Zycore/Format.h" +#include "zydis/Zydis/ShortString.h" +#include "zydis/Zycore/Defines.h" +#include "zydis/Zycore/Status.h" +#include "zydis/Zycore/Vector.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Letter Case */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisLetterCase` enum. + */ +typedef enum ZydisLetterCase_ +{ + /** + * Uses the given text "as is". + */ + ZYDIS_LETTER_CASE_DEFAULT, + /** + * Converts the given text to lowercase letters. + */ + ZYDIS_LETTER_CASE_LOWER, + /** + * Converts the given text to uppercase letters. + */ + ZYDIS_LETTER_CASE_UPPER, + + /** + * Maximum value of this enum. + */ + ZYDIS_LETTER_CASE_MAX_VALUE = ZYDIS_LETTER_CASE_UPPER, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_LETTER_CASE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_LETTER_CASE_MAX_VALUE) +} ZydisLetterCase; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Internal macros */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Checks for a terminating '\0' character at the end of the string data. + */ +#define ZYDIS_STRING_ASSERT_NULLTERMINATION(string) \ + ZYAN_ASSERT(*(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) == '\0'); + +/** + * Writes a terminating '\0' character at the end of the string data. + */ +#define ZYDIS_STRING_NULLTERMINATE(string) \ + *(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) = '\0'; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Internal Functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Appending */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Appends the content of the source string to the end of the destination string. + * + * @param destination The destination string. + * @param source The source string. + * + * @return A zyan status code. + */ +ZYAN_INLINE ZyanStatus ZydisStringAppend(ZyanString* destination, const ZyanStringView* source) +{ + ZYAN_ASSERT(destination && source); + ZYAN_ASSERT(!destination->vector.allocator); + ZYAN_ASSERT(destination->vector.size && source->string.vector.size); + + if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity) + { + return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, + source->string.vector.data, source->string.vector.size - 1); + + destination->vector.size += source->string.vector.size - 1; + ZYDIS_STRING_NULLTERMINATE(destination); + + return ZYAN_STATUS_SUCCESS; +} + +/** + * Appends the content of the source string to the end of the destination + * string, converting the characters to the specified letter-case. + * + * @param destination The destination string. + * @param source The source string. + * @param letter_case The desired letter-case. + * + * @return A zyan status code. + */ +ZYAN_INLINE ZyanStatus ZydisStringAppendCase(ZyanString* destination, const ZyanStringView* source, + ZydisLetterCase letter_case) +{ + ZYAN_ASSERT(destination && source); + ZYAN_ASSERT(!destination->vector.allocator); + ZYAN_ASSERT(destination->vector.size && source->string.vector.size); + + if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity) + { + return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, + source->string.vector.data, source->string.vector.size - 1); + + switch (letter_case) + { + case ZYDIS_LETTER_CASE_DEFAULT: + break; + case ZYDIS_LETTER_CASE_LOWER: + { + const ZyanUSize index = destination->vector.size - 1; + const ZyanUSize count = source->string.vector.size - 1; + char* s = (char*)destination->vector.data + index; + for (ZyanUSize i = index; i < index + count; ++i) + { + const char c = *s; + if ((c >= 'A') && (c <= 'Z')) + { + *s = c | 32; + } + ++s; + } + break; + } + case ZYDIS_LETTER_CASE_UPPER: + { + const ZyanUSize index = destination->vector.size - 1; + const ZyanUSize count = source->string.vector.size - 1; + char* s = (char*)destination->vector.data + index; + for (ZyanUSize i = index; i < index + count; ++i) + { + const char c = *s; + if ((c >= 'a') && (c <= 'z')) + { + *s = c & ~32; + } + ++s; + } + break; + } + default: + ZYAN_UNREACHABLE; + } + + destination->vector.size += source->string.vector.size - 1; + ZYDIS_STRING_NULLTERMINATE(destination); + + return ZYAN_STATUS_SUCCESS; +} + +/** + * Appends the content of the source short-string to the end of the destination string. + * + * @param destination The destination string. + * @param source The source string. + * + * @return A zyan status code. + */ +ZYAN_INLINE ZyanStatus ZydisStringAppendShort(ZyanString* destination, + const ZydisShortString* source) +{ + ZYAN_ASSERT(destination && source); + ZYAN_ASSERT(!destination->vector.allocator); + ZYAN_ASSERT(destination->vector.size && source->size); + + if (destination->vector.size + source->size > destination->vector.capacity) + { + return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, + (ZyanUSize)source->size + 1); + + destination->vector.size += source->size; + ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); + + return ZYAN_STATUS_SUCCESS; +} + +/** + * Appends the content of the source short-string to the end of the destination string, + * converting the characters to the specified letter-case. + * + * @param destination The destination string. + * @param source The source string. + * @param letter_case The desired letter-case. + * + * @return A zyan status code. + */ +ZYAN_INLINE ZyanStatus ZydisStringAppendShortCase(ZyanString* destination, + const ZydisShortString* source, ZydisLetterCase letter_case) +{ + ZYAN_ASSERT(destination && source); + ZYAN_ASSERT(!destination->vector.allocator); + ZYAN_ASSERT(destination->vector.size && source->size); + + if (destination->vector.size + source->size > destination->vector.capacity) + { + return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, + (ZyanUSize)source->size + 1); + + switch (letter_case) + { + case ZYDIS_LETTER_CASE_DEFAULT: + break; + case ZYDIS_LETTER_CASE_LOWER: + { + const ZyanUSize index = destination->vector.size - 1; + const ZyanUSize count = source->size; + char* s = (char*)destination->vector.data + index; + for (ZyanUSize i = index; i < index + count; ++i) + { + const char c = *s; + if ((c >= 'A') && (c <= 'Z')) + { + *s = c | 32; + } + ++s; + } + break; + } + case ZYDIS_LETTER_CASE_UPPER: + { + const ZyanUSize index = destination->vector.size - 1; + const ZyanUSize count = source->size; + char* s = (char*)destination->vector.data + index; + for (ZyanUSize i = index; i < index + count; ++i) + { + const char c = *s; + if ((c >= 'a') && (c <= 'z')) + { + *s = c & ~32; + } + ++s; + } + break; + } + default: + ZYAN_UNREACHABLE; + } + + destination->vector.size += source->size; + ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); + + return ZYAN_STATUS_SUCCESS; +} + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatting */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Formats the given unsigned ordinal `value` to its decimal text-representation and + * appends it to the `string`. + * + * @param string A pointer to the `ZyanString` instance. + * @param value The value to append. + * @param padding_length Padds the converted value with leading zeros, if the number of chars is + * less than the `padding_length`. + * @param prefix The string to use as prefix or `ZYAN_NULL`, if not needed. + * @param suffix The string to use as suffix or `ZYAN_NULL`, if not needed. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZyanStatus ZydisStringAppendDecU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length, + const ZyanStringView* prefix, const ZyanStringView* suffix); + +/** + * Formats the given signed ordinal `value` to its decimal text-representation and + * appends it to the `string`. + * + * @param string A pointer to the `ZyanString` instance. + * @param value The value to append. + * @param padding_length Padds the converted value with leading zeros, if the number of chars is + * less than the `padding_length`. + * @param force_sign Enable this option to print the `+` sign for positive numbers. + * @param prefix The string to use as prefix or `ZYAN_NULL`, if not needed. + * @param suffix The string to use as suffix or `ZYAN_NULL`, if not needed. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYAN_INLINE ZyanStatus ZydisStringAppendDecS(ZyanString* string, ZyanI64 value, + ZyanU8 padding_length, ZyanBool force_sign, const ZyanStringView* prefix, + const ZyanStringView* suffix) +{ + static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); + static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); + + if (value < 0) + { + ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); + if (prefix) + { + ZYAN_CHECK(ZydisStringAppend(string, prefix)); + } + return ZydisStringAppendDecU(string, ZyanAbsI64(value), padding_length, + (const ZyanStringView*)ZYAN_NULL, suffix); + } + + if (force_sign) + { + ZYAN_ASSERT(value >= 0); + ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); + } + return ZydisStringAppendDecU(string, value, padding_length, prefix, suffix); +} + +/** + * Formats the given unsigned ordinal `value` to its hexadecimal text-representation and + * appends it to the `string`. + * + * @param string A pointer to the `ZyanString` instance. + * @param value The value to append. + * @param padding_length Pads the converted value with leading zeros if the number of + * chars is less than the `padding_length`. + * @param force_leading_number Enable this option to prepend a leading `0` if the first + * character is non-numeric. + * @param uppercase Enable this option to use uppercase letters ('A'-'F') instead + * of lowercase ones ('a'-'f'). + * @param prefix The string to use as prefix or `ZYAN_NULL`, if not needed. + * @param suffix The string to use as suffix or `ZYAN_NULL`, if not needed. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZyanStatus ZydisStringAppendHexU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length, + ZyanBool force_leading_number, ZyanBool uppercase, const ZyanStringView* prefix, + const ZyanStringView* suffix); + +/** + * Formats the given signed ordinal `value` to its hexadecimal text-representation and + * appends it to the `string`. + * + * @param string A pointer to the `ZyanString` instance. + * @param value The value to append. + * @param padding_length Padds the converted value with leading zeros, if the number of + * chars is less than the `padding_length` (the sign char does not + * count). + * @param force_leading_number Enable this option to prepend a leading `0`, if the first + * character is non-numeric. + * @param uppercase Enable this option to use uppercase letters ('A'-'F') instead + * of lowercase ones ('a'-'f'). + * @param force_sign Enable this option to print the `+` sign for positive numbers. + * @param prefix The string to use as prefix or `ZYAN_NULL`, if not needed. + * @param suffix The string to use as suffix or `ZYAN_NULL`, if not needed. + * + * @return A zyan status code. + * + * This function will fail if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYAN_INLINE ZyanStatus ZydisStringAppendHexS(ZyanString* string, ZyanI64 value, + ZyanU8 padding_length, ZyanBool force_leading_number, ZyanBool uppercase, ZyanBool force_sign, + const ZyanStringView* prefix, const ZyanStringView* suffix) +{ + static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); + static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); + + if (value < 0) + { + ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); + if (prefix) + { + ZYAN_CHECK(ZydisStringAppend(string, prefix)); + } + return ZydisStringAppendHexU(string, ZyanAbsI64(value), padding_length, + force_leading_number, uppercase, (const ZyanStringView*)ZYAN_NULL, suffix); + } + + if (force_sign) + { + ZYAN_ASSERT(value >= 0); + ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); + } + return ZydisStringAppendHexU(string, value, padding_length, force_leading_number, uppercase, + prefix, suffix); +} + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif // ZYDIS_INTERNAL_STRING_H |