summaryrefslogtreecommitdiffstats
path: root/js/src/zydis/Zydis/Internal
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /js/src/zydis/Zydis/Internal
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/zydis/Zydis/Internal')
-rw-r--r--js/src/zydis/Zydis/Internal/DecoderData.h326
-rw-r--r--js/src/zydis/Zydis/Internal/FormatterATT.h178
-rw-r--r--js/src/zydis/Zydis/Internal/FormatterBase.h318
-rw-r--r--js/src/zydis/Zydis/Internal/FormatterIntel.h267
-rw-r--r--js/src/zydis/Zydis/Internal/SharedData.h968
-rw-r--r--js/src/zydis/Zydis/Internal/String.h463
6 files changed, 2520 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..6592e19fba
--- /dev/null
+++ b/js/src/zydis/Zydis/Internal/DecoderData.h
@@ -0,0 +1,326 @@
+/***************************************************************************************************
+
+ 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/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)
+
+/* ---------------------------------------------------------------------------------------------- */
+/* Decoder tree */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisDecoderTreeNodeType` data-type.
+ */
+typedef ZyanU8 ZydisDecoderTreeNodeType;
+
+/**
+ * @brief Values that represent zydis decoder tree node types.
+ */
+enum ZydisDecoderTreeNodeTypes
+{
+ ZYDIS_NODETYPE_INVALID = 0x00,
+ /**
+ * @brief Reference to an instruction-definition.
+ */
+ ZYDIS_NODETYPE_DEFINITION_MASK = 0x80,
+ /**
+ * @brief Reference to an XOP-map filter.
+ */
+ ZYDIS_NODETYPE_FILTER_XOP = 0x01,
+ /**
+ * @brief Reference to an VEX-map filter.
+ */
+ ZYDIS_NODETYPE_FILTER_VEX = 0x02,
+ /**
+ * @brief Reference to an EVEX/MVEX-map filter.
+ */
+ ZYDIS_NODETYPE_FILTER_EMVEX = 0x03,
+ /**
+ * @brief Reference to an opcode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_OPCODE = 0x04,
+ /**
+ * @brief Reference to an instruction-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE = 0x05,
+ /**
+ * @brief Reference to an compacted instruction-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_COMPACT = 0x06,
+ /**
+ * @brief Reference to a ModRM.mod filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODRM_MOD = 0x07,
+ /**
+ * @brief Reference to a compacted ModRM.mod filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT = 0x08,
+ /**
+ * @brief Reference to a ModRM.reg filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODRM_REG = 0x09,
+ /**
+ * @brief Reference to a ModRM.rm filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODRM_RM = 0x0A,
+ /**
+ * @brief Reference to a PrefixGroup1 filter.
+ */
+ ZYDIS_NODETYPE_FILTER_PREFIX_GROUP1 = 0x0B,
+ /**
+ * @brief Reference to a mandatory-prefix filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MANDATORY_PREFIX = 0x0C,
+ /**
+ * @brief Reference to an operand-size filter.
+ */
+ ZYDIS_NODETYPE_FILTER_OPERAND_SIZE = 0x0D,
+ /**
+ * @brief Reference to an address-size filter.
+ */
+ ZYDIS_NODETYPE_FILTER_ADDRESS_SIZE = 0x0E,
+ /**
+ * @brief Reference to a vector-length filter.
+ */
+ ZYDIS_NODETYPE_FILTER_VECTOR_LENGTH = 0x0F,
+ /**
+ * @brief Reference to an REX/VEX/EVEX.W filter.
+ */
+ ZYDIS_NODETYPE_FILTER_REX_W = 0x10,
+ /**
+ * @brief Reference to an REX/VEX/EVEX.B filter.
+ */
+ ZYDIS_NODETYPE_FILTER_REX_B = 0x11,
+ /**
+ * @brief Reference to an EVEX.b filter.
+ */
+ ZYDIS_NODETYPE_FILTER_EVEX_B = 0x12,
+ /**
+ * @brief Reference to an MVEX.E filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MVEX_E = 0x13,
+ /**
+ * @brief Reference to a AMD-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_AMD = 0x14,
+ /**
+ * @brief Reference to a KNC-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_KNC = 0x15,
+ /**
+ * @brief Reference to a MPX-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_MPX = 0x16,
+ /**
+ * @brief Reference to a CET-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_CET = 0x17,
+ /**
+ * @brief Reference to a LZCNT-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_LZCNT = 0x18,
+ /**
+ * @brief Reference to a TZCNT-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_TZCNT = 0x19,
+ /**
+ * @brief Reference to a WBNOINVD-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_WBNOINVD = 0x1A,
+ /**
+ * @brief Reference to a CLDEMOTE-mode filter.
+ */
+ ZYDIS_NODETYPE_FILTER_MODE_CLDEMOTE = 0x1B
+};
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisDecoderTreeNodeValue` data-type.
+ */
+typedef ZyanU16 ZydisDecoderTreeNodeValue;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisInstructionEncodingFlags` data-type.
+ */
+typedef ZyanU8 ZydisInstructionEncodingFlags;
+
+/**
+ * @brief The instruction has an optional modrm byte.
+ */
+#define ZYDIS_INSTR_ENC_FLAG_HAS_MODRM 0x01
+
+/**
+ * @brief The instruction has an optional displacement value.
+ */
+#define ZYDIS_INSTR_ENC_FLAG_HAS_DISP 0x02
+
+/**
+ * @brief The instruction has an optional immediate value.
+ */
+#define ZYDIS_INSTR_ENC_FLAG_HAS_IMM0 0x04
+
+/**
+ * @brief The instruction has a second optional immediate value.
+ */
+#define ZYDIS_INSTR_ENC_FLAG_HAS_IMM1 0x08
+
+/**
+ * @brief 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
+
+/**
+ * @brief Defines the `ZydisInstructionEncodingInfo` struct.
+ */
+typedef struct ZydisInstructionEncodingInfo_
+{
+ /**
+ * @brief Contains flags with information about the physical instruction-encoding.
+ */
+ ZydisInstructionEncodingFlags flags;
+ /**
+ * @brief Displacement info.
+ */
+ struct
+ {
+ /**
+ * @brief The size of the displacement value.
+ */
+ ZyanU8 size[3];
+ } disp;
+ /**
+ * @brief Immediate info.
+ */
+ struct
+ {
+ /**
+ * @brief The size of the immediate value.
+ */
+ ZyanU8 size[3];
+ /**
+ * @brief Signals, if the value is signed.
+ */
+ ZyanBool is_signed;
+ /**
+ * @brief Signals, if the value is a relative offset.
+ */
+ ZyanBool is_relative;
+ } imm[2];
+} ZydisInstructionEncodingInfo;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/* ============================================================================================== */
+/* Functions */
+/* ============================================================================================== */
+
+/* ---------------------------------------------------------------------------------------------- */
+/* Decoder tree */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Returns the root node of the instruction tree.
+ *
+ * @return The root node of the instruction tree.
+ */
+ZYDIS_NO_EXPORT const ZydisDecoderTreeNode* ZydisDecoderTreeGetRootNode(void);
+
+/**
+ * @brief 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);
+
+/**
+ * @brief 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/FormatterATT.h b/js/src/zydis/Zydis/Internal/FormatterATT.h
new file mode 100644
index 0000000000..9d019972ec
--- /dev/null
+++ b/js/src/zydis/Zydis/Internal/FormatterATT.h
@@ -0,0 +1,178 @@
+/***************************************************************************************************
+
+ 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
+ * @brief 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 ZydisFormatterATTPrintDISP(const ZydisFormatter* formatter,
+ ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
+
+ZyanStatus ZydisFormatterATTPrintIMM(const ZydisFormatter* formatter,
+ ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/* ============================================================================================== */
+/* Fomatter presets */
+/* ============================================================================================== */
+
+/* ---------------------------------------------------------------------------------------------- */
+/* AT&T */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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_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,
+ /* 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 */ &ZydisFormatterBasePrintAddressABS,
+ /* 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..51009a929b
--- /dev/null
+++ b/js/src/zydis/Zydis/Internal/FormatterBase.h
@@ -0,0 +1,318 @@
+/***************************************************************************************************
+
+ 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
+ * @brief 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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.
+ * @param padding_length The padding length.
+ */
+#define ZYDIS_STRING_APPEND_NUM_U(formatter, base, str, value, padding_length) \
+ 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, \
+ (formatter)->hex_uppercase, \
+ (formatter)->number_format[base][0].string, \
+ (formatter)->number_format[base][1].string)); \
+ break; \
+ default: \
+ return ZYAN_STATUS_INVALID_ARGUMENT; \
+ }
+
+/**
+ * @brief 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.
+ * @param padding_length The padding length.
+ * @param force_sign Forces printing of the '+' sign for positive numbers.
+ */
+#define ZYDIS_STRING_APPEND_NUM_S(formatter, base, str, value, padding_length, 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, \
+ (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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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)); \
+ }
+
+/**
+ * @brief 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; \
+ }
+
+/**
+ * @brief Appends a string (`STR_`-prefix) or a predefined token-list (`TOK_`-prefix).
+ *
+ * @brief buffer A pointer to the `ZydisFormatterBuffer` struct.
+ * @brief 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
+
+/**
+ * @brief Appends a string (`STR_`-prefix) or a predefined token-list (`TOK_`-prefix).
+ *
+ * @brief buffer A pointer to the `ZydisFormatterBuffer` struct.
+ * @brief name The base name (without prefix) of the string- or token.
+ * @brief 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
+
+/**
+ * @brief 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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 memop_id The operand-id of 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, ZyanU8 memop_id);
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/* ============================================================================================== */
+/* 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..d8017e90db
--- /dev/null
+++ b/js/src/zydis/Zydis/Internal/FormatterIntel.h
@@ -0,0 +1,267 @@
+/***************************************************************************************************
+
+ 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
+ * @brief 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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_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,
+ /* 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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_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,
+ /* 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..e6a777d644
--- /dev/null
+++ b/js/src/zydis/Zydis/Internal/SharedData.h
@@ -0,0 +1,968 @@
+/***************************************************************************************************
+
+ 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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_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,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_SEMANTIC_OPTYPE_MAX_VALUE = ZYDIS_SEMANTIC_OPTYPE_MIB,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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_FLOAT32,
+ ZYDIS_IELEMENT_TYPE_FLOAT64,
+ ZYDIS_IELEMENT_TYPE_FLOAT80,
+ ZYDIS_IELEMENT_TYPE_BCD80,
+ ZYDIS_IELEMENT_TYPE_CC3,
+ ZYDIS_IELEMENT_TYPE_CC5,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_IELEMENT_TYPE_MAX_VALUE = ZYDIS_IELEMENT_TYPE_CC5,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisImplicitRegisterType` enum.
+ */
+typedef enum ZydisImplicitRegisterType_
+{
+ ZYDIS_IMPLREG_TYPE_STATIC,
+ ZYDIS_IMPLREG_TYPE_GPR_OSZ,
+ ZYDIS_IMPLREG_TYPE_GPR_ASZ,
+ ZYDIS_IMPLREG_TYPE_GPR_SSZ,
+ ZYDIS_IMPLREG_TYPE_IP_ASZ,
+ ZYDIS_IMPLREG_TYPE_IP_SSZ,
+ ZYDIS_IMPLREG_TYPE_FLAGS_SSZ,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_IMPLREG_TYPE_MAX_VALUE = ZYDIS_IMPLREG_TYPE_FLAGS_SSZ,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisImplicitMemBase` enum.
+ */
+typedef enum ZydisImplicitMemBase_
+{
+ 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_ASP,
+ ZYDIS_IMPLMEM_BASE_ABP,
+ ZYDIS_IMPLMEM_BASE_ASI,
+ ZYDIS_IMPLMEM_BASE_ADI,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_IMPLMEM_BASE_MAX_VALUE = ZYDIS_IMPLMEM_BASE_ADI,
+ /**
+ * @brief 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);
+
+/**
+ * @brief 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;
+} ZydisOperandDefinition;
+
+/* ---------------------------------------------------------------------------------------------- */
+/* Instruction definition */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisReadWriteAction` enum.
+ */
+typedef enum ZydisReadWriteAction_
+{
+ ZYDIS_RW_ACTION_NONE,
+ ZYDIS_RW_ACTION_READ,
+ ZYDIS_RW_ACTION_WRITE,
+ ZYDIS_RW_ACTION_READWRITE,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_RW_ACTION_MAX_VALUE = ZYDIS_RW_ACTION_READWRITE,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisRegisterConstraint` enum.
+ */
+typedef enum ZydisRegisterConstraint_
+{
+ ZYDIS_REG_CONSTRAINTS_UNUSED,
+ ZYDIS_REG_CONSTRAINTS_NONE,
+ ZYDIS_REG_CONSTRAINTS_GPR,
+ ZYDIS_REG_CONSTRAINTS_SR_DEST,
+ ZYDIS_REG_CONSTRAINTS_SR,
+ ZYDIS_REG_CONSTRAINTS_CR,
+ ZYDIS_REG_CONSTRAINTS_DR,
+ ZYDIS_REG_CONSTRAINTS_MASK,
+ ZYDIS_REG_CONSTRAINTS_BND,
+ ZYDIS_REG_CONSTRAINTS_VSIB,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_REG_CONSTRAINTS_MAX_VALUE = ZYDIS_REG_CONSTRAINTS_VSIB,
+ /**
+ * @brief The minimum number of bits required to represent all values of this enum.
+ */
+ ZYDIS_REG_CONSTRAINTS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_REG_CONSTRAINTS_MAX_VALUE)
+} ZydisRegisterConstraint;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_IVECTOR_LENGTH_MAX_VALUE = ZYDIS_IVECTOR_LENGTH_FIXED_512,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_IELEMENT_SIZE_MAX_VALUE = ZYDIS_IELEMENT_SIZE_128,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisEVEXFunctionality` enum.
+ */
+typedef enum ZydisEVEXFunctionality_
+{
+ ZYDIS_EVEX_FUNC_INVALID,
+ /**
+ * @brief `EVEX.b` enables broadcast functionality.
+ */
+ ZYDIS_EVEX_FUNC_BC,
+ /**
+ * @brief `EVEX.b` enables embedded-rounding functionality.
+ */
+ ZYDIS_EVEX_FUNC_RC,
+ /**
+ * @brief `EVEX.b` enables sae functionality.
+ */
+ ZYDIS_EVEX_FUNC_SAE,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_EVEX_FUNC_MAX_VALUE = ZYDIS_EVEX_FUNC_SAE,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisEVEXTupleType` enum.
+ */
+typedef enum ZydisEVEXTupleType_
+{
+ ZYDIS_TUPLETYPE_INVALID,
+ /**
+ * @brief Full Vector
+ */
+ ZYDIS_TUPLETYPE_FV,
+ /**
+ * @brief Half Vector
+ */
+ ZYDIS_TUPLETYPE_HV,
+ /**
+ * @brief Full Vector Mem
+ */
+ ZYDIS_TUPLETYPE_FVM,
+ /**
+ * @brief Tuple1 Scalar
+ */
+ ZYDIS_TUPLETYPE_T1S,
+ /**
+ * @brief Tuple1 Fixed
+ */
+ ZYDIS_TUPLETYPE_T1F,
+ /**
+ * @brief Tuple1 4x32
+ */
+ ZYDIS_TUPLETYPE_T1_4X,
+ /**
+ * @brief Gather / Scatter
+ */
+ ZYDIS_TUPLETYPE_GSCAT,
+ /**
+ * @brief Tuple2
+ */
+ ZYDIS_TUPLETYPE_T2,
+ /**
+ * @brief Tuple4
+ */
+ ZYDIS_TUPLETYPE_T4,
+ /**
+ * @brief Tuple8
+ */
+ ZYDIS_TUPLETYPE_T8,
+ /**
+ * @brief Half Mem
+ */
+ ZYDIS_TUPLETYPE_HVM,
+ /**
+ * @brief QuarterMem
+ */
+ ZYDIS_TUPLETYPE_QVM,
+ /**
+ * @brief OctMem
+ */
+ ZYDIS_TUPLETYPE_OVM,
+ /**
+ * @brief Mem128
+ */
+ ZYDIS_TUPLETYPE_M128,
+ /**
+ * @brief MOVDDUP
+ */
+ ZYDIS_TUPLETYPE_DUP,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_TUPLETYPE_MAX_VALUE = ZYDIS_TUPLETYPE_DUP,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisMVEXFunctionality` enum.
+ */
+typedef enum ZydisMVEXFunctionality_
+{
+ /**
+ * @brief The `MVEX.SSS` value is ignored.
+ */
+ ZYDIS_MVEX_FUNC_IGNORED,
+ /**
+ * @brief `MVEX.SSS` must be `000b`.
+ */
+ ZYDIS_MVEX_FUNC_INVALID,
+ /**
+ * @brief `MVEX.SSS` controls embedded-rounding functionality.
+ */
+ ZYDIS_MVEX_FUNC_RC,
+ /**
+ * @brief `MVEX.SSS` controls sae functionality.
+ */
+ ZYDIS_MVEX_FUNC_SAE,
+ /**
+ * @brief No special operation (32bit float elements).
+ */
+ ZYDIS_MVEX_FUNC_F_32,
+ /**
+ * @brief No special operation (32bit uint elements).
+ */
+ ZYDIS_MVEX_FUNC_I_32,
+ /**
+ * @brief No special operation (64bit float elements).
+ */
+ ZYDIS_MVEX_FUNC_F_64,
+ /**
+ * @brief No special operation (64bit uint elements).
+ */
+ ZYDIS_MVEX_FUNC_I_64,
+ /**
+ * @brief Sf32(reg) or Si32(reg).
+ */
+ ZYDIS_MVEX_FUNC_SWIZZLE_32,
+ /**
+ * @brief Sf64(reg) or Si64(reg).
+ */
+ ZYDIS_MVEX_FUNC_SWIZZLE_64,
+ /**
+ * @brief Sf32(mem).
+ */
+ ZYDIS_MVEX_FUNC_SF_32,
+ /**
+ * @brief Sf32(mem) broadcast only.
+ */
+ ZYDIS_MVEX_FUNC_SF_32_BCST,
+ /**
+ * @brief Sf32(mem) broadcast 4to16 only.
+ */
+ ZYDIS_MVEX_FUNC_SF_32_BCST_4TO16,
+ /**
+ * @brief Sf64(mem).
+ */
+ ZYDIS_MVEX_FUNC_SF_64,
+ /**
+ * @brief Si32(mem).
+ */
+ ZYDIS_MVEX_FUNC_SI_32,
+ /**
+ * @brief Si32(mem) broadcast only.
+ */
+ ZYDIS_MVEX_FUNC_SI_32_BCST,
+ /**
+ * @brief Si32(mem) broadcast 4to16 only.
+ */
+ ZYDIS_MVEX_FUNC_SI_32_BCST_4TO16,
+ /**
+ * @brief Si64(mem).
+ */
+ ZYDIS_MVEX_FUNC_SI_64,
+ /**
+ * @brief Uf32.
+ */
+ ZYDIS_MVEX_FUNC_UF_32,
+ /**
+ * @brief Uf64.
+ */
+ ZYDIS_MVEX_FUNC_UF_64,
+ /**
+ * @brief Ui32.
+ */
+ ZYDIS_MVEX_FUNC_UI_32,
+ /**
+ * @brief Ui64.
+ */
+ ZYDIS_MVEX_FUNC_UI_64,
+ /**
+ * @brief Df32.
+ */
+ ZYDIS_MVEX_FUNC_DF_32,
+ /**
+ * @brief Df64.
+ */
+ ZYDIS_MVEX_FUNC_DF_64,
+ /**
+ * @brief Di32.
+ */
+ ZYDIS_MVEX_FUNC_DI_32,
+ /**
+ * @brief Di64.
+ */
+ ZYDIS_MVEX_FUNC_DI_64,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_MVEX_FUNC_MAX_VALUE = ZYDIS_MVEX_FUNC_DI_64,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_VEX_STATIC_BROADCAST_MAX_VALUE = ZYDIS_VEX_STATIC_BROADCAST_2_TO_4,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_EVEX_STATIC_BROADCAST_MAX_VALUE = ZYDIS_EVEX_STATIC_BROADCAST_8_TO_16,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_MVEX_STATIC_BROADCAST_MAX_VALUE = ZYDIS_MVEX_STATIC_BROADCAST_4_TO_16,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisMaskPolicy` enum.
+ */
+typedef enum ZydisMaskPolicy_
+{
+ ZYDIS_MASK_POLICY_INVALID,
+ /**
+ * @brief The instruction accepts mask-registers other than the default-mask (K0), but
+ * does not require them.
+ */
+ ZYDIS_MASK_POLICY_ALLOWED,
+ /**
+ * @brief The instruction requires a mask-register other than the default-mask (K0).
+ */
+ ZYDIS_MASK_POLICY_REQUIRED,
+ /**
+ * @brief The instruction does not allow a mask-register other than the default-mask (K0).
+ */
+ ZYDIS_MASK_POLICY_FORBIDDEN,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_MASK_POLICY_MAX_VALUE = ZYDIS_MASK_POLICY_FORBIDDEN,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisMaskOverride` enum.
+ */
+typedef enum ZydisMaskOverride_
+{
+ ZYDIS_MASK_OVERRIDE_DEFAULT,
+ ZYDIS_MASK_OVERRIDE_ZEROING,
+ ZYDIS_MASK_OVERRIDE_CONTROL,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_MASK_OVERRIDE_MAX_VALUE = ZYDIS_MASK_OVERRIDE_CONTROL,
+ /**
+ * @brief 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;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+// 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_REG_CONSTRAINTS_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); \
+ 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); \
+ 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 constr_REG ZYAN_BITFIELD(ZYDIS_REG_CONSTRAINTS_REQUIRED_BITS); \
+ ZyanU8 constr_RM ZYAN_BITFIELD(ZYDIS_REG_CONSTRAINTS_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)
+#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); \
+ ZyanU8 constr_REG ZYAN_BITFIELD(ZYDIS_REG_CONSTRAINTS_REQUIRED_BITS); \
+ ZyanU8 constr_RM ZYAN_BITFIELD(ZYDIS_REG_CONSTRAINTS_REQUIRED_BITS)
+#endif
+
+#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR \
+ ZYDIS_INSTRUCTION_DEFINITION_BASE; \
+ ZyanU8 constr_NDSNDD ZYAN_BITFIELD(ZYDIS_REG_CONSTRAINTS_REQUIRED_BITS)
+
+#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_INTEL \
+ ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; \
+ ZyanBool is_gather ZYAN_BITFIELD( 1)
+
+/**
+ * @brief Defines the `ZydisInstructionDefinition` struct.
+ */
+typedef struct ZydisInstructionDefinition_
+{
+ ZYDIS_INSTRUCTION_DEFINITION_BASE;
+} ZydisInstructionDefinition;
+
+/**
+ * @brief 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_hle_without_lock ZYAN_BITFIELD( 1);
+ ZyanBool accepts_branch_hints ZYAN_BITFIELD( 1);
+ ZyanBool accepts_segment ZYAN_BITFIELD( 1);
+#endif
+} ZydisInstructionDefinitionLEGACY;
+
+/**
+ * @brief Defines the `ZydisInstructionDefinition3DNOW` struct.
+ */
+typedef struct ZydisInstructionDefinition3DNOW_
+{
+ ZYDIS_INSTRUCTION_DEFINITION_BASE;
+} ZydisInstructionDefinition3DNOW;
+
+/**
+ * @brief 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);
+
+/**
+ * @brief 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);
+
+/**
+ * @brief 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);
+
+/**
+ * @brief 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
+
+/* ---------------------------------------------------------------------------------------------- */
+/* Accessed CPU flags */
+/* ---------------------------------------------------------------------------------------------- */
+
+typedef struct ZydisAccessedFlags_
+{
+ ZydisCPUFlagAction action[ZYDIS_CPUFLAG_MAX_VALUE + 1];
+} ZydisAccessedFlags;
+
+/* ---------------------------------------------------------------------------------------------- */
+
+#pragma pack(pop)
+
+#ifdef ZYAN_MSVC
+# pragma warning(pop)
+#endif
+
+/* ============================================================================================== */
+/* Functions */
+/* ============================================================================================== */
+
+/* ---------------------------------------------------------------------------------------------- */
+/* Instruction definition */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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
+/**
+ * @brief Returns the the operand-definitions for the given instruction-`definition`.
+ *
+ * @param definition A pointer to the instruction-definition.
+ * @param operand A pointer to the variable that receives a pointer to the first operand-
+ * definition of the instruction.
+ *
+ * @return The number of operands for the given instruction-definition.
+ */
+ZYDIS_NO_EXPORT ZyanU8 ZydisGetOperandDefinitions(const ZydisInstructionDefinition* definition,
+ const ZydisOperandDefinition** operand);
+#endif
+
+/* ---------------------------------------------------------------------------------------------- */
+/* Element info */
+/* ---------------------------------------------------------------------------------------------- */
+
+#ifndef ZYDIS_MINIMAL_MODE
+/**
+ * @brief 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
+/**
+ * @brief 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 `ZydisAccessedFlags` struct.
+ *
+ * @return `ZYAN_TRUE`, if the instruction accesses any flags, or `ZYAN_FALSE`, if not.
+ */
+ZYDIS_NO_EXPORT ZyanBool ZydisGetAccessedFlags(const ZydisInstructionDefinition* definition,
+ const ZydisAccessedFlags** 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..df6ad4381f
--- /dev/null
+++ b/js/src/zydis/Zydis/Internal/String.h
@@ -0,0 +1,463 @@
+/***************************************************************************************************
+
+ 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
+ * @brief 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/Zydis/ShortString.h"
+#include "zydis/Zydis/Status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ============================================================================================== */
+/* Enums and types */
+/* ============================================================================================== */
+
+/* ---------------------------------------------------------------------------------------------- */
+/* Letter Case */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief Defines the `ZydisLetterCase` enum.
+ */
+typedef enum ZydisLetterCase_
+{
+ /**
+ * @brief Uses the given text "as is".
+ */
+ ZYDIS_LETTER_CASE_DEFAULT,
+ /**
+ * @brief Converts the given text to lowercase letters.
+ */
+ ZYDIS_LETTER_CASE_LOWER,
+ /**
+ * @brief Converts the given text to uppercase letters.
+ */
+ ZYDIS_LETTER_CASE_UPPER,
+
+ /**
+ * @brief Maximum value of this enum.
+ */
+ ZYDIS_LETTER_CASE_MAX_VALUE = ZYDIS_LETTER_CASE_UPPER,
+ /**
+ * @brief 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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');
+
+/**
+ * @brief 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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;
+}
+
+/**
+ * @brief 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;
+}
+
+/**
+ * @brief 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;
+}
+
+/**
+ * @brief 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 */
+/* ---------------------------------------------------------------------------------------------- */
+
+/**
+ * @brief 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.
+ * @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);
+
+/**
+ * @brief 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.
+ * @param padding_length Padds the converted value with leading zeros, if the number of chars is
+ * less than the `padding_length`.
+ * @param force_sign Set `ZYAN_TRUE`, to force printing of 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, -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);
+}
+
+/**
+ * @brief 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.
+ * @param padding_length Padds the converted value with leading zeros, if the number of chars is
+ * less than the `padding_length`.
+ * @param uppercase Set `ZYAN_TRUE` 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 uppercase, const ZyanStringView* prefix, const ZyanStringView* suffix);
+
+/**
+ * @brief Formats the given signed ordinal `value` to its hexadecimal text-representation and
+ * appends it to the `string`.
+ *
+ * @param string A pointer to the string.
+ * @param value The value.
+ * @param padding_length Padds the converted value with leading zeros, if the number of chars is
+ * less than the `padding_length` (the sign char is ignored).
+ * @param uppercase Set `ZYAN_TRUE` to print the hexadecimal value in uppercase letters
+ * instead of lowercase ones.
+ * @param force_sign Set to `ZYAN_TRUE`, to force printing of the `+` sign for positive
+ * numbers.
+ * @param prefix The string to use as prefix or `NULL`, if not needed.
+ * @param suffix The string to use as suffix or `NULL`, if not needed.
+ *
+ * @return `ZYAN_STATUS_SUCCESS`, if the function succeeded, or
+ * `ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE`, if the size of the buffer was not
+ * sufficient to append the given `value`.
+ *
+ * The string-buffer pointer is increased by the number of chars written, if the call was
+ * successful.
+ */
+ZYAN_INLINE ZyanStatus ZydisStringAppendHexS(ZyanString* string, ZyanI64 value,
+ ZyanU8 padding_length, 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, -value, padding_length, 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, uppercase, prefix, suffix);
+}
+
+/* ---------------------------------------------------------------------------------------------- */
+
+/* ============================================================================================== */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ZYDIS_INTERNAL_STRING_H