From e2307c2ded0b86a7fd69818cddcc8fba762a6034 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 18 May 2021 19:19:20 -0700 Subject: [PATCH] moved some files around so its cleaner --- {Zycore => include/Zycore}/API/Memory.h | 0 {Zycore => include/Zycore}/API/Process.h | 0 .../Zycore}/API/Synchronization.h | 0 {Zycore => include/Zycore}/API/Terminal.h | 0 {Zycore => include/Zycore}/API/Thread.h | 0 {Zycore => include/Zycore}/Allocator.h | 0 {Zycore => include/Zycore}/ArgParse.h | 0 {Zycore => include/Zycore}/Bitset.h | 0 {Zycore => include/Zycore}/Comparison.h | 0 {Zycore => include/Zycore}/Defines.h | 0 {Zycore => include/Zycore}/Format.h | 0 {Zycore => include/Zycore}/LibC.h | 0 {Zycore => include/Zycore}/List.h | 0 {Zycore => include/Zycore}/Object.h | 0 {Zycore => include/Zycore}/Status.h | 0 {Zycore => include/Zycore}/String.h | 0 {Zycore => include/Zycore}/Types.h | 0 {Zycore => include/Zycore}/Vector.h | 0 {Zycore => include/Zycore}/Zycore.h | 0 .../ZycoreExportConfig.h | 0 {Zydis => include/Zydis}/Decoder.h | 0 {Zydis => include/Zydis}/DecoderTypes.h | 0 {Zydis => include/Zydis}/Formatter.h | 0 {Zydis => include/Zydis}/FormatterBuffer.h | 0 .../Zydis}/Generated/EnumISAExt.h | 0 .../Zydis}/Generated/EnumISASet.h | 0 .../Generated/EnumInstructionCategory.h | 0 .../Zydis}/Generated/EnumMnemonic.h | 0 .../Zydis}/Generated/EnumRegister.h | 0 .../Zydis}/Internal/DecoderData.h | 0 .../Zydis}/Internal/FormatterATT.h | 0 .../Zydis}/Internal/FormatterBase.h | 0 .../Zydis}/Internal/FormatterIntel.h | 0 .../Zydis}/Internal/SharedData.h | 0 {Zydis => include/Zydis}/Internal/String.h | 0 {Zydis => include/Zydis}/MetaInfo.h | 0 {Zydis => include/Zydis}/Mnemonic.h | 0 {Zydis => include/Zydis}/Register.h | 0 {Zydis => include/Zydis}/SharedTypes.h | 0 {Zydis => include/Zydis}/ShortString.h | 0 {Zydis => include/Zydis}/Status.h | 0 {Zydis => include/Zydis}/Utils.h | 0 {Zydis => include/Zydis}/Zydis.h | 0 .../ZydisExportConfig.h | 0 transform.hpp => include/transform.hpp | 0 vm.h => include/vm.h | 0 vmctx.h => include/vmctx.h | 0 vmp2.hpp => include/vmp2.hpp | 0 vmprofiler.hpp => include/vmprofiler.hpp | 0 vmutils.h => include/vmutils.h | 0 src/Zycore/API/Memory.h | 134 ++ src/Zycore/API/Process.h | 67 + src/Zycore/API/Synchronization.h | 133 ++ src/Zycore/API/Terminal.h | 163 ++ src/Zycore/API/Thread.h | 244 +++ src/Zycore/Allocator.h | 143 ++ src/Zycore/ArgParse.h | 173 ++ src/Zycore/Bitset.h | 484 +++++ src/Zycore/Comparison.h | 316 ++++ src/Zycore/Defines.h | 451 +++++ src/Zycore/Format.h | 286 +++ src/Zycore/LibC.h | 511 +++++ src/Zycore/List.h | 574 ++++++ src/Zycore/Object.h | 84 + src/Zycore/Status.h | 287 +++ src/Zycore/String.h | 1012 ++++++++++ src/Zycore/Types.h | 195 ++ src/Zycore/Vector.h | 723 ++++++++ src/Zycore/Zycore.h | 111 ++ src/ZycoreExportConfig.h | 42 + src/Zydis/Decoder.h | 237 +++ src/Zydis/DecoderTypes.h | 1528 +++++++++++++++ src/Zydis/Formatter.h | 1179 ++++++++++++ src/Zydis/FormatterBuffer.h | 306 +++ src/Zydis/Generated/EnumISAExt.h | 98 + src/Zydis/Generated/EnumISASet.h | 184 ++ src/Zydis/Generated/EnumInstructionCategory.h | 117 ++ src/Zydis/Generated/EnumMnemonic.h | 1643 +++++++++++++++++ src/Zydis/Generated/EnumRegister.h | 301 +++ src/Zydis/Internal/DecoderData.h | 331 ++++ src/Zydis/Internal/FormatterATT.h | 178 ++ src/Zydis/Internal/FormatterBase.h | 318 ++++ src/Zydis/Internal/FormatterIntel.h | 267 +++ src/Zydis/Internal/SharedData.h | 974 ++++++++++ src/Zydis/Internal/String.h | 464 +++++ src/Zydis/MetaInfo.h | 88 + src/Zydis/Mnemonic.h | 88 + src/Zydis/Register.h | 293 +++ src/Zydis/SharedTypes.h | 480 +++++ src/Zydis/ShortString.h | 90 + src/Zydis/Status.h | 159 ++ src/Zydis/Utils.h | 275 +++ src/Zydis/Zydis.h | 169 ++ src/ZydisExportConfig.h | 42 + src/transform.hpp | 201 ++ vm.cpp => src/vm.cpp | 0 src/vm.h | 51 + vmctx.cpp => src/vmctx.cpp | 0 src/vmctx.h | 29 + src/vmp2.hpp | 72 + src/vmprofiler.hpp | 367 ++++ vmprofiler.vcxproj => src/vmprofiler.vcxproj | 2 +- .../vmprofiler.vcxproj.filters | 0 vmutils.cpp => src/vmutils.cpp | 0 src/vmutils.h | 40 + vmprofiler.sln | 90 +- vmprofiler.vcxproj.user | 7 - 107 files changed, 16748 insertions(+), 53 deletions(-) rename {Zycore => include/Zycore}/API/Memory.h (100%) rename {Zycore => include/Zycore}/API/Process.h (100%) rename {Zycore => include/Zycore}/API/Synchronization.h (100%) rename {Zycore => include/Zycore}/API/Terminal.h (100%) rename {Zycore => include/Zycore}/API/Thread.h (100%) rename {Zycore => include/Zycore}/Allocator.h (100%) rename {Zycore => include/Zycore}/ArgParse.h (100%) rename {Zycore => include/Zycore}/Bitset.h (100%) rename {Zycore => include/Zycore}/Comparison.h (100%) rename {Zycore => include/Zycore}/Defines.h (100%) rename {Zycore => include/Zycore}/Format.h (100%) rename {Zycore => include/Zycore}/LibC.h (100%) rename {Zycore => include/Zycore}/List.h (100%) rename {Zycore => include/Zycore}/Object.h (100%) rename {Zycore => include/Zycore}/Status.h (100%) rename {Zycore => include/Zycore}/String.h (100%) rename {Zycore => include/Zycore}/Types.h (100%) rename {Zycore => include/Zycore}/Vector.h (100%) rename {Zycore => include/Zycore}/Zycore.h (100%) rename ZycoreExportConfig.h => include/ZycoreExportConfig.h (100%) rename {Zydis => include/Zydis}/Decoder.h (100%) rename {Zydis => include/Zydis}/DecoderTypes.h (100%) rename {Zydis => include/Zydis}/Formatter.h (100%) rename {Zydis => include/Zydis}/FormatterBuffer.h (100%) rename {Zydis => include/Zydis}/Generated/EnumISAExt.h (100%) rename {Zydis => include/Zydis}/Generated/EnumISASet.h (100%) rename {Zydis => include/Zydis}/Generated/EnumInstructionCategory.h (100%) rename {Zydis => include/Zydis}/Generated/EnumMnemonic.h (100%) rename {Zydis => include/Zydis}/Generated/EnumRegister.h (100%) rename {Zydis => include/Zydis}/Internal/DecoderData.h (100%) rename {Zydis => include/Zydis}/Internal/FormatterATT.h (100%) rename {Zydis => include/Zydis}/Internal/FormatterBase.h (100%) rename {Zydis => include/Zydis}/Internal/FormatterIntel.h (100%) rename {Zydis => include/Zydis}/Internal/SharedData.h (100%) rename {Zydis => include/Zydis}/Internal/String.h (100%) rename {Zydis => include/Zydis}/MetaInfo.h (100%) rename {Zydis => include/Zydis}/Mnemonic.h (100%) rename {Zydis => include/Zydis}/Register.h (100%) rename {Zydis => include/Zydis}/SharedTypes.h (100%) rename {Zydis => include/Zydis}/ShortString.h (100%) rename {Zydis => include/Zydis}/Status.h (100%) rename {Zydis => include/Zydis}/Utils.h (100%) rename {Zydis => include/Zydis}/Zydis.h (100%) rename ZydisExportConfig.h => include/ZydisExportConfig.h (100%) rename transform.hpp => include/transform.hpp (100%) rename vm.h => include/vm.h (100%) rename vmctx.h => include/vmctx.h (100%) rename vmp2.hpp => include/vmp2.hpp (100%) rename vmprofiler.hpp => include/vmprofiler.hpp (100%) rename vmutils.h => include/vmutils.h (100%) create mode 100644 src/Zycore/API/Memory.h create mode 100644 src/Zycore/API/Process.h create mode 100644 src/Zycore/API/Synchronization.h create mode 100644 src/Zycore/API/Terminal.h create mode 100644 src/Zycore/API/Thread.h create mode 100644 src/Zycore/Allocator.h create mode 100644 src/Zycore/ArgParse.h create mode 100644 src/Zycore/Bitset.h create mode 100644 src/Zycore/Comparison.h create mode 100644 src/Zycore/Defines.h create mode 100644 src/Zycore/Format.h create mode 100644 src/Zycore/LibC.h create mode 100644 src/Zycore/List.h create mode 100644 src/Zycore/Object.h create mode 100644 src/Zycore/Status.h create mode 100644 src/Zycore/String.h create mode 100644 src/Zycore/Types.h create mode 100644 src/Zycore/Vector.h create mode 100644 src/Zycore/Zycore.h create mode 100644 src/ZycoreExportConfig.h create mode 100644 src/Zydis/Decoder.h create mode 100644 src/Zydis/DecoderTypes.h create mode 100644 src/Zydis/Formatter.h create mode 100644 src/Zydis/FormatterBuffer.h create mode 100644 src/Zydis/Generated/EnumISAExt.h create mode 100644 src/Zydis/Generated/EnumISASet.h create mode 100644 src/Zydis/Generated/EnumInstructionCategory.h create mode 100644 src/Zydis/Generated/EnumMnemonic.h create mode 100644 src/Zydis/Generated/EnumRegister.h create mode 100644 src/Zydis/Internal/DecoderData.h create mode 100644 src/Zydis/Internal/FormatterATT.h create mode 100644 src/Zydis/Internal/FormatterBase.h create mode 100644 src/Zydis/Internal/FormatterIntel.h create mode 100644 src/Zydis/Internal/SharedData.h create mode 100644 src/Zydis/Internal/String.h create mode 100644 src/Zydis/MetaInfo.h create mode 100644 src/Zydis/Mnemonic.h create mode 100644 src/Zydis/Register.h create mode 100644 src/Zydis/SharedTypes.h create mode 100644 src/Zydis/ShortString.h create mode 100644 src/Zydis/Status.h create mode 100644 src/Zydis/Utils.h create mode 100644 src/Zydis/Zydis.h create mode 100644 src/ZydisExportConfig.h create mode 100644 src/transform.hpp rename vm.cpp => src/vm.cpp (100%) create mode 100644 src/vm.h rename vmctx.cpp => src/vmctx.cpp (100%) create mode 100644 src/vmctx.h create mode 100644 src/vmp2.hpp create mode 100644 src/vmprofiler.hpp rename vmprofiler.vcxproj => src/vmprofiler.vcxproj (98%) rename vmprofiler.vcxproj.filters => src/vmprofiler.vcxproj.filters (100%) rename vmutils.cpp => src/vmutils.cpp (100%) create mode 100644 src/vmutils.h delete mode 100644 vmprofiler.vcxproj.user diff --git a/Zycore/API/Memory.h b/include/Zycore/API/Memory.h similarity index 100% rename from Zycore/API/Memory.h rename to include/Zycore/API/Memory.h diff --git a/Zycore/API/Process.h b/include/Zycore/API/Process.h similarity index 100% rename from Zycore/API/Process.h rename to include/Zycore/API/Process.h diff --git a/Zycore/API/Synchronization.h b/include/Zycore/API/Synchronization.h similarity index 100% rename from Zycore/API/Synchronization.h rename to include/Zycore/API/Synchronization.h diff --git a/Zycore/API/Terminal.h b/include/Zycore/API/Terminal.h similarity index 100% rename from Zycore/API/Terminal.h rename to include/Zycore/API/Terminal.h diff --git a/Zycore/API/Thread.h b/include/Zycore/API/Thread.h similarity index 100% rename from Zycore/API/Thread.h rename to include/Zycore/API/Thread.h diff --git a/Zycore/Allocator.h b/include/Zycore/Allocator.h similarity index 100% rename from Zycore/Allocator.h rename to include/Zycore/Allocator.h diff --git a/Zycore/ArgParse.h b/include/Zycore/ArgParse.h similarity index 100% rename from Zycore/ArgParse.h rename to include/Zycore/ArgParse.h diff --git a/Zycore/Bitset.h b/include/Zycore/Bitset.h similarity index 100% rename from Zycore/Bitset.h rename to include/Zycore/Bitset.h diff --git a/Zycore/Comparison.h b/include/Zycore/Comparison.h similarity index 100% rename from Zycore/Comparison.h rename to include/Zycore/Comparison.h diff --git a/Zycore/Defines.h b/include/Zycore/Defines.h similarity index 100% rename from Zycore/Defines.h rename to include/Zycore/Defines.h diff --git a/Zycore/Format.h b/include/Zycore/Format.h similarity index 100% rename from Zycore/Format.h rename to include/Zycore/Format.h diff --git a/Zycore/LibC.h b/include/Zycore/LibC.h similarity index 100% rename from Zycore/LibC.h rename to include/Zycore/LibC.h diff --git a/Zycore/List.h b/include/Zycore/List.h similarity index 100% rename from Zycore/List.h rename to include/Zycore/List.h diff --git a/Zycore/Object.h b/include/Zycore/Object.h similarity index 100% rename from Zycore/Object.h rename to include/Zycore/Object.h diff --git a/Zycore/Status.h b/include/Zycore/Status.h similarity index 100% rename from Zycore/Status.h rename to include/Zycore/Status.h diff --git a/Zycore/String.h b/include/Zycore/String.h similarity index 100% rename from Zycore/String.h rename to include/Zycore/String.h diff --git a/Zycore/Types.h b/include/Zycore/Types.h similarity index 100% rename from Zycore/Types.h rename to include/Zycore/Types.h diff --git a/Zycore/Vector.h b/include/Zycore/Vector.h similarity index 100% rename from Zycore/Vector.h rename to include/Zycore/Vector.h diff --git a/Zycore/Zycore.h b/include/Zycore/Zycore.h similarity index 100% rename from Zycore/Zycore.h rename to include/Zycore/Zycore.h diff --git a/ZycoreExportConfig.h b/include/ZycoreExportConfig.h similarity index 100% rename from ZycoreExportConfig.h rename to include/ZycoreExportConfig.h diff --git a/Zydis/Decoder.h b/include/Zydis/Decoder.h similarity index 100% rename from Zydis/Decoder.h rename to include/Zydis/Decoder.h diff --git a/Zydis/DecoderTypes.h b/include/Zydis/DecoderTypes.h similarity index 100% rename from Zydis/DecoderTypes.h rename to include/Zydis/DecoderTypes.h diff --git a/Zydis/Formatter.h b/include/Zydis/Formatter.h similarity index 100% rename from Zydis/Formatter.h rename to include/Zydis/Formatter.h diff --git a/Zydis/FormatterBuffer.h b/include/Zydis/FormatterBuffer.h similarity index 100% rename from Zydis/FormatterBuffer.h rename to include/Zydis/FormatterBuffer.h diff --git a/Zydis/Generated/EnumISAExt.h b/include/Zydis/Generated/EnumISAExt.h similarity index 100% rename from Zydis/Generated/EnumISAExt.h rename to include/Zydis/Generated/EnumISAExt.h diff --git a/Zydis/Generated/EnumISASet.h b/include/Zydis/Generated/EnumISASet.h similarity index 100% rename from Zydis/Generated/EnumISASet.h rename to include/Zydis/Generated/EnumISASet.h diff --git a/Zydis/Generated/EnumInstructionCategory.h b/include/Zydis/Generated/EnumInstructionCategory.h similarity index 100% rename from Zydis/Generated/EnumInstructionCategory.h rename to include/Zydis/Generated/EnumInstructionCategory.h diff --git a/Zydis/Generated/EnumMnemonic.h b/include/Zydis/Generated/EnumMnemonic.h similarity index 100% rename from Zydis/Generated/EnumMnemonic.h rename to include/Zydis/Generated/EnumMnemonic.h diff --git a/Zydis/Generated/EnumRegister.h b/include/Zydis/Generated/EnumRegister.h similarity index 100% rename from Zydis/Generated/EnumRegister.h rename to include/Zydis/Generated/EnumRegister.h diff --git a/Zydis/Internal/DecoderData.h b/include/Zydis/Internal/DecoderData.h similarity index 100% rename from Zydis/Internal/DecoderData.h rename to include/Zydis/Internal/DecoderData.h diff --git a/Zydis/Internal/FormatterATT.h b/include/Zydis/Internal/FormatterATT.h similarity index 100% rename from Zydis/Internal/FormatterATT.h rename to include/Zydis/Internal/FormatterATT.h diff --git a/Zydis/Internal/FormatterBase.h b/include/Zydis/Internal/FormatterBase.h similarity index 100% rename from Zydis/Internal/FormatterBase.h rename to include/Zydis/Internal/FormatterBase.h diff --git a/Zydis/Internal/FormatterIntel.h b/include/Zydis/Internal/FormatterIntel.h similarity index 100% rename from Zydis/Internal/FormatterIntel.h rename to include/Zydis/Internal/FormatterIntel.h diff --git a/Zydis/Internal/SharedData.h b/include/Zydis/Internal/SharedData.h similarity index 100% rename from Zydis/Internal/SharedData.h rename to include/Zydis/Internal/SharedData.h diff --git a/Zydis/Internal/String.h b/include/Zydis/Internal/String.h similarity index 100% rename from Zydis/Internal/String.h rename to include/Zydis/Internal/String.h diff --git a/Zydis/MetaInfo.h b/include/Zydis/MetaInfo.h similarity index 100% rename from Zydis/MetaInfo.h rename to include/Zydis/MetaInfo.h diff --git a/Zydis/Mnemonic.h b/include/Zydis/Mnemonic.h similarity index 100% rename from Zydis/Mnemonic.h rename to include/Zydis/Mnemonic.h diff --git a/Zydis/Register.h b/include/Zydis/Register.h similarity index 100% rename from Zydis/Register.h rename to include/Zydis/Register.h diff --git a/Zydis/SharedTypes.h b/include/Zydis/SharedTypes.h similarity index 100% rename from Zydis/SharedTypes.h rename to include/Zydis/SharedTypes.h diff --git a/Zydis/ShortString.h b/include/Zydis/ShortString.h similarity index 100% rename from Zydis/ShortString.h rename to include/Zydis/ShortString.h diff --git a/Zydis/Status.h b/include/Zydis/Status.h similarity index 100% rename from Zydis/Status.h rename to include/Zydis/Status.h diff --git a/Zydis/Utils.h b/include/Zydis/Utils.h similarity index 100% rename from Zydis/Utils.h rename to include/Zydis/Utils.h diff --git a/Zydis/Zydis.h b/include/Zydis/Zydis.h similarity index 100% rename from Zydis/Zydis.h rename to include/Zydis/Zydis.h diff --git a/ZydisExportConfig.h b/include/ZydisExportConfig.h similarity index 100% rename from ZydisExportConfig.h rename to include/ZydisExportConfig.h diff --git a/transform.hpp b/include/transform.hpp similarity index 100% rename from transform.hpp rename to include/transform.hpp diff --git a/vm.h b/include/vm.h similarity index 100% rename from vm.h rename to include/vm.h diff --git a/vmctx.h b/include/vmctx.h similarity index 100% rename from vmctx.h rename to include/vmctx.h diff --git a/vmp2.hpp b/include/vmp2.hpp similarity index 100% rename from vmp2.hpp rename to include/vmp2.hpp diff --git a/vmprofiler.hpp b/include/vmprofiler.hpp similarity index 100% rename from vmprofiler.hpp rename to include/vmprofiler.hpp diff --git a/vmutils.h b/include/vmutils.h similarity index 100% rename from vmutils.h rename to include/vmutils.h diff --git a/src/Zycore/API/Memory.h b/src/Zycore/API/Memory.h new file mode 100644 index 0000000..c5fa8a9 --- /dev/null +++ b/src/Zycore/API/Memory.h @@ -0,0 +1,134 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * @brief + */ + +#ifndef ZYCORE_API_MEMORY_H +#define ZYCORE_API_MEMORY_H + +#include +#include +#include +#include + +#if defined(ZYAN_WINDOWS) +# include +#elif defined(ZYAN_POSIX) +# include +#else +# error "Unsupported platform detected" +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZyanMemoryPageProtection` enum. + */ +typedef enum ZyanMemoryPageProtection_ +{ +#if defined(ZYAN_WINDOWS) + + ZYAN_PAGE_READONLY = PAGE_READONLY, + ZYAN_PAGE_READWRITE = PAGE_READWRITE, + ZYAN_PAGE_EXECUTE = PAGE_EXECUTE, + ZYAN_PAGE_EXECUTE_READ = PAGE_EXECUTE_READ, + ZYAN_PAGE_EXECUTE_READWRITE = PAGE_EXECUTE_READWRITE + +#elif defined(ZYAN_POSIX) + + ZYAN_PAGE_READONLY = PROT_READ, + ZYAN_PAGE_READWRITE = PROT_READ | PROT_WRITE, + ZYAN_PAGE_EXECUTE = PROT_EXEC, + ZYAN_PAGE_EXECUTE_READ = PROT_EXEC | PROT_READ, + ZYAN_PAGE_EXECUTE_READWRITE = PROT_EXEC | PROT_READ | PROT_WRITE + +#endif +} ZyanMemoryPageProtection; + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the system page size. + * + * @return The system page size. + */ +ZYCORE_EXPORT ZyanU32 ZyanMemoryGetSystemPageSize(); + +/** + * Returns the system allocation granularity. + * + * The system allocation granularity specifies the minimum amount of bytes which can be allocated + * at a specific address by a single call of `ZyanMemoryVirtualAlloc`. + * + * This value is typically 64KiB on Windows systems and equal to the page size on most POSIX + * platforms. + * + * @return The system allocation granularity. + */ +ZYCORE_EXPORT ZyanU32 ZyanMemoryGetSystemAllocationGranularity(); + +/* ---------------------------------------------------------------------------------------------- */ +/* Memory management */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Changes the memory protection value of one or more pages. + * + * @param address The start address aligned to a page boundary. + * @param size The size. + * @param protection The new page protection value. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanMemoryVirtualProtect(void* address, ZyanUSize size, + ZyanMemoryPageProtection protection); + +/** + * Releases one or more memory pages starting at the given address. + * + * @param address The start address aligned to a page boundary. + * @param size The size. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanMemoryVirtualFree(void* address, ZyanUSize size); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#endif /* ZYCORE_API_MEMORY_H */ diff --git a/src/Zycore/API/Process.h b/src/Zycore/API/Process.h new file mode 100644 index 0000000..0b6a5c6 --- /dev/null +++ b/src/Zycore/API/Process.h @@ -0,0 +1,67 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * @brief + */ + +#ifndef ZYCORE_API_PROCESS_H +#define ZYCORE_API_PROCESS_H + +#include +#include +#include + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + + + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @brief Flushes the process instruction cache. + * + * @param address The address. + * @param size The size. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanProcessFlushInstructionCache(void* address, ZyanUSize size); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#endif /* ZYCORE_API_PROCESS_H */ diff --git a/src/Zycore/API/Synchronization.h b/src/Zycore/API/Synchronization.h new file mode 100644 index 0000000..8414a44 --- /dev/null +++ b/src/Zycore/API/Synchronization.h @@ -0,0 +1,133 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * @brief + */ + +#ifndef ZYCORE_API_SYNCHRONIZATION_H +#define ZYCORE_API_SYNCHRONIZATION_H + +#ifndef ZYAN_NO_LIBC + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +#if defined(ZYAN_POSIX) + +#include + +/* ---------------------------------------------------------------------------------------------- */ +/* Critical Section */ +/* ---------------------------------------------------------------------------------------------- */ + +typedef pthread_mutex_t ZyanCriticalSection; + +/* ---------------------------------------------------------------------------------------------- */ + +#elif defined(ZYAN_WINDOWS) + +#include + +/* ---------------------------------------------------------------------------------------------- */ +/* Critical Section */ +/* ---------------------------------------------------------------------------------------------- */ + +typedef CRITICAL_SECTION ZyanCriticalSection; + +/* ---------------------------------------------------------------------------------------------- */ + +#else +# error "Unsupported platform detected" +#endif + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Critical Section */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Initializes a critical section. + * + * @param critical_section A pointer to the `ZyanCriticalSection` struct. + */ +ZYCORE_EXPORT ZyanStatus ZyanCriticalSectionInitialize(ZyanCriticalSection* critical_section); + +/** + * Enters a critical section. + * + * @param critical_section A pointer to the `ZyanCriticalSection` struct. + */ +ZYCORE_EXPORT ZyanStatus ZyanCriticalSectionEnter(ZyanCriticalSection* critical_section); + +/** + * Tries to enter a critical section. + * + * @param critical_section A pointer to the `ZyanCriticalSection` struct. + * + * @return Returns `ZYAN_TRUE` if the critical section was successfully entered or `ZYAN_FALSE`, + * if not. + */ +ZYCORE_EXPORT ZyanBool ZyanCriticalSectionTryEnter(ZyanCriticalSection* critical_section); + +/** + * Leaves a critical section. + * + * @param critical_section A pointer to the `ZyanCriticalSection` struct. + */ +ZYCORE_EXPORT ZyanStatus ZyanCriticalSectionLeave(ZyanCriticalSection* critical_section); + +/** + * Deletes a critical section. + * + * @param critical_section A pointer to the `ZyanCriticalSection` struct. + */ +ZYCORE_EXPORT ZyanStatus ZyanCriticalSectionDelete(ZyanCriticalSection* critical_section); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYAN_NO_LIBC */ + +#endif /* ZYCORE_API_SYNCHRONIZATION_H */ diff --git a/src/Zycore/API/Terminal.h b/src/Zycore/API/Terminal.h new file mode 100644 index 0000000..17dc384 --- /dev/null +++ b/src/Zycore/API/Terminal.h @@ -0,0 +1,163 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file Provides cross-platform terminal helper functions. + * @brief + */ + +#ifndef ZYCORE_API_TERMINAL_H +#define ZYCORE_API_TERMINAL_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ZYAN_NO_LIBC + +/* ============================================================================================== */ +/* VT100 CSI SGR sequences */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYAN_VT100SGR_RESET "\033[0m" + +/* ---------------------------------------------------------------------------------------------- */ +/* Foreground colors */ +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYAN_VT100SGR_FG_DEFAULT "\033[39m" + +#define ZYAN_VT100SGR_FG_BLACK "\033[30m" +#define ZYAN_VT100SGR_FG_RED "\033[31m" +#define ZYAN_VT100SGR_FG_GREEN "\033[32m" +#define ZYAN_VT100SGR_FG_YELLOW "\033[33m" +#define ZYAN_VT100SGR_FG_BLUE "\033[34m" +#define ZYAN_VT100SGR_FG_MAGENTA "\033[35m" +#define ZYAN_VT100SGR_FG_CYAN "\033[36m" +#define ZYAN_VT100SGR_FG_WHITE "\033[37m" +#define ZYAN_VT100SGR_FG_BRIGHT_BLACK "\033[90m" +#define ZYAN_VT100SGR_FG_BRIGHT_RED "\033[91m" +#define ZYAN_VT100SGR_FG_BRIGHT_GREEN "\033[92m" +#define ZYAN_VT100SGR_FG_BRIGHT_YELLOW "\033[93m" +#define ZYAN_VT100SGR_FG_BRIGHT_BLUE "\033[94m" +#define ZYAN_VT100SGR_FG_BRIGHT_MAGENTA "\033[95m" +#define ZYAN_VT100SGR_FG_BRIGHT_CYAN "\033[96m" +#define ZYAN_VT100SGR_FG_BRIGHT_WHITE "\033[97m" + +/* ---------------------------------------------------------------------------------------------- */ +/* Background color */ +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYAN_VT100SGR_BG_DEFAULT "\033[49m" + +#define ZYAN_VT100SGR_BG_BLACK "\033[40m" +#define ZYAN_VT100SGR_BG_RED "\033[41m" +#define ZYAN_VT100SGR_BG_GREEN "\033[42m" +#define ZYAN_VT100SGR_BG_YELLOW "\033[43m" +#define ZYAN_VT100SGR_BG_BLUE "\033[44m" +#define ZYAN_VT100SGR_BG_MAGENTA "\033[45m" +#define ZYAN_VT100SGR_BG_CYAN "\033[46m" +#define ZYAN_VT100SGR_BG_WHITE "\033[47m" +#define ZYAN_VT100SGR_BG_BRIGHT_BLACK "\033[100m" +#define ZYAN_VT100SGR_BG_BRIGHT_RED "\033[101m" +#define ZYAN_VT100SGR_BG_BRIGHT_GREEN "\033[102m" +#define ZYAN_VT100SGR_BG_BRIGHT_YELLOW "\033[103m" +#define ZYAN_VT100SGR_BG_BRIGHT_BLUE "\033[104m" +#define ZYAN_VT100SGR_BG_BRIGHT_MAGENTA "\033[105m" +#define ZYAN_VT100SGR_BG_BRIGHT_CYAN "\033[106m" +#define ZYAN_VT100SGR_BG_BRIGHT_WHITE "\033[107m" + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Declares the `ZyanStandardStream` enum. + */ +typedef enum ZyanStandardStream_ +{ + /** + * The default input stream. + */ + ZYAN_STDSTREAM_IN, + /** + * The default output stream. + */ + ZYAN_STDSTREAM_OUT, + /** + * The default error stream. + */ + ZYAN_STDSTREAM_ERR +} ZyanStandardStream; + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * Enables VT100 ansi escape codes for the given stream. + * + * @param stream Either `ZYAN_STDSTREAM_OUT` or `ZYAN_STDSTREAM_ERR`. + * + * @return A zyan status code. + * + * This functions returns `ZYAN_STATUS_SUCCESS` on all non-Windows systems without performing any + * operations, assuming that VT100 is supported by default. + * + * On Windows systems, VT100 functionality is only supported on Windows 10 build 1607 (anniversary + * update) and later. + */ +ZYCORE_EXPORT ZyanStatus ZyanTerminalEnableVT100(ZyanStandardStream stream); + +/** + * Checks, if the given standard stream reads from or writes to a terminal. + * + * @param stream The standard stream to check. + * + * @return `ZYAN_STATUS_TRUE`, if the stream is bound to a terminal, `ZYAN_STATUS_FALSE` if not, + * or another zyan status code if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanTerminalIsTTY(ZyanStandardStream stream); + +/* ============================================================================================== */ + +#endif // ZYAN_NO_LIBC + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_API_TERMINAL_H */ diff --git a/src/Zycore/API/Thread.h b/src/Zycore/API/Thread.h new file mode 100644 index 0000000..b1ec085 --- /dev/null +++ b/src/Zycore/API/Thread.h @@ -0,0 +1,244 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * @brief + */ + +#ifndef ZYCORE_API_THREAD_H +#define ZYCORE_API_THREAD_H + +#ifndef ZYAN_NO_LIBC + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +#if defined(ZYAN_POSIX) + +#include + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanThread` data-type. + */ +typedef pthread_t ZyanThread; + +/** + * Defines the `ZyanThreadId` data-type. + */ +typedef ZyanU64 ZyanThreadId; + +/* ---------------------------------------------------------------------------------------------- */ +/* Thread Local Storage (TLS) */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanThreadTlsIndex` data-type. + */ +typedef pthread_key_t ZyanThreadTlsIndex; + +/** + * Defines the `ZyanThreadTlsCallback` function prototype. + */ +typedef void(*ZyanThreadTlsCallback)(void* data); + +/** + * Declares a Thread Local Storage (TLS) callback function. + * + * @param name The callback function name. + * @param param_type The callback data parameter type. + * @param param_name The callback data parameter name. + */ +#define ZYAN_THREAD_DECLARE_TLS_CALLBACK(name, param_type, param_name) \ + void name(param_type* param_name) + +/* ---------------------------------------------------------------------------------------------- */ + +#elif defined(ZYAN_WINDOWS) + +#include + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanThread` data-type. + */ +typedef HANDLE ZyanThread; + +/** + * Defines the `ZyanThreadId` data-type. + */ +typedef DWORD ZyanThreadId; + +/* ---------------------------------------------------------------------------------------------- */ +/* Thread Local Storage (TLS) */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanThreadTlsIndex` data-type. + */ +typedef DWORD ZyanThreadTlsIndex; + +/** + * Defines the `ZyanThreadTlsCallback` function prototype. + */ +typedef PFLS_CALLBACK_FUNCTION ZyanThreadTlsCallback; + +/** + * Declares a Thread Local Storage (TLS) callback function. + * + * @param name The callback function name. + * @param param_type The callback data parameter type. + * @param param_name The callback data parameter name. + */ +#define ZYAN_THREAD_DECLARE_TLS_CALLBACK(name, param_type, param_name) \ + VOID NTAPI name(param_type* param_name) + +/* ---------------------------------------------------------------------------------------------- */ + +#else +# error "Unsupported platform detected" +#endif + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the handle of the current thread. + * + * @param thread Receives the handle of the current thread. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanThreadGetCurrentThread(ZyanThread* thread); + +/** + * Returns the unique id of the current thread. + * + * @param thread_id Receives the unique id of the current thread. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanThreadGetCurrentThreadId(ZyanThreadId* thread_id); + +/* ---------------------------------------------------------------------------------------------- */ +/* Thread Local Storage (TLS) */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Allocates a new Thread Local Storage (TLS) slot. + * + * @param index Receives the TLS slot index. + * @param destructor A pointer to a destructor callback which is invoked to finalize the data + * in the TLS slot or `ZYAN_NULL`, if not needed. + * + * The maximum available number of TLS slots is implementation specific and different on each + * platform: + * - Windows + * - A total amount of 128 slots per process are guaranteed + * - POSIX + * - A total amount of 128 slots per process are guaranteed + * - Some systems guarantee larger amounts like e.g. 1024 slots per process + * + * Note that the invocation rules for the destructor callback are implementation specific and + * different on each platform: + * - Windows + * - The callback is invoked when a thread exits + * - The callback is invoked when the process exits + * - The callback is invoked when the TLS slot is released + * - POSIX + * - The callback is invoked when a thread exits and the stored value is not null + * - The callback is NOT invoked when the process exits + * - The callback is NOT invoked when the TLS slot is released + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanThreadTlsAlloc(ZyanThreadTlsIndex* index, + ZyanThreadTlsCallback destructor); + +/** + * Releases a Thread Local Storage (TLS) slot. + * + * @param index The TLS slot index. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanThreadTlsFree(ZyanThreadTlsIndex index); + +/** + * Returns the value inside the given Thread Local Storage (TLS) slot for the + * calling thread. + * + * @param index The TLS slot index. + * @param data Receives the value inside the given Thread Local Storage + * (TLS) slot for the calling thread. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanThreadTlsGetValue(ZyanThreadTlsIndex index, void** data); + +/** + * Set the value of the given Thread Local Storage (TLS) slot for the calling thread. + * + * @param index The TLS slot index. + * @param data The value to store inside the given Thread Local Storage (TLS) slot for the + * calling thread + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanThreadTlsSetValue(ZyanThreadTlsIndex index, void* data); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYAN_NO_LIBC */ + +#endif /* ZYCORE_API_THREAD_H */ diff --git a/src/Zycore/Allocator.h b/src/Zycore/Allocator.h new file mode 100644 index 0000000..6435171 --- /dev/null +++ b/src/Zycore/Allocator.h @@ -0,0 +1,143 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * @brief + */ + +#ifndef ZYCORE_ALLOCATOR_H +#define ZYCORE_ALLOCATOR_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +struct ZyanAllocator_; + +/** + * Defines the `ZyanAllocatorAllocate` function prototype. + * + * @param allocator A pointer to the `ZyanAllocator` instance. + * @param p Receives a pointer to the first memory block sufficient to hold an + * array of `n` elements with a size of `element_size`. + * @param element_size The size of a single element. + * @param n The number of elements to allocate storage for. + * + * @return A zyan status code. + * + * This prototype is used for the `allocate()` and `reallocate()` functions. + * + * The result of the `reallocate()` function is undefined, if `p` does not point to a memory block + * previously obtained by `(re-)allocate()`. + */ +typedef ZyanStatus (*ZyanAllocatorAllocate)(struct ZyanAllocator_* allocator, void** p, + ZyanUSize element_size, ZyanUSize n); + +/** + * Defines the `ZyanAllocatorDeallocate` function prototype. + * + * @param allocator A pointer to the `ZyanAllocator` instance. + * @param p The pointer obtained from `(re-)allocate()`. + * @param element_size The size of a single element. + * @param n The number of elements earlier passed to `(re-)allocate()`. + * + * @return A zyan status code. + */ +typedef ZyanStatus (*ZyanAllocatorDeallocate)(struct ZyanAllocator_* allocator, void* p, + ZyanUSize element_size, ZyanUSize n); + +/** + * Defines the `ZyanAllocator` struct. + * + * This is the base class for all custom allocator implementations. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZyanAllocator_ +{ + /** + * The allocate function. + */ + ZyanAllocatorAllocate allocate; + /** + * The reallocate function. + */ + ZyanAllocatorAllocate reallocate; + /** + * The deallocate function. + */ + ZyanAllocatorDeallocate deallocate; +} ZyanAllocator; + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * Initializes the given `ZyanAllocator` instance. + * + * @param allocator A pointer to the `ZyanAllocator` instance. + * @param allocate The allocate function. + * @param reallocate The reallocate function. + * @param deallocate The deallocate function. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanAllocatorInit(ZyanAllocator* allocator, ZyanAllocatorAllocate allocate, + ZyanAllocatorAllocate reallocate, ZyanAllocatorDeallocate deallocate); + +#ifndef ZYAN_NO_LIBC + +/** + * Returns the default `ZyanAllocator` instance. + * + * @return A pointer to the default `ZyanAllocator` instance. + * + * The default allocator uses the default memory manager to allocate memory on the heap. + * + * You should in no case modify the returned allocator instance to avoid unexpected behavior. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanAllocator* ZyanAllocatorDefault(void); + +#endif // ZYAN_NO_LIBC + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_ALLOCATOR_H */ diff --git a/src/Zycore/ArgParse.h b/src/Zycore/ArgParse.h new file mode 100644 index 0000000..5d389cb --- /dev/null +++ b/src/Zycore/ArgParse.h @@ -0,0 +1,173 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + Original Author : 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 command-line argument parsing. + */ + +#ifndef ZYCORE_ARGPARSE_H +#define ZYCORE_ARGPARSE_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Structs and other types */ +/* ============================================================================================== */ + +/** + * Definition of a single argument. + */ +typedef struct ZyanArgParseDefinition_ +{ + /** + * The argument name, e.g. `--help`. + * + * Must start with either one or two dashes. Single dash arguments must consist of a single + * character, (e.g. `-n`), double-dash arguments can be of arbitrary length. + */ + const char* name; + /** + * Whether the argument is boolean or expects a value. + */ + ZyanBool boolean; + /** + * Whether this argument is required (error if missing). + */ + ZyanBool required; +} ZyanArgParseDefinition; + +/** + * Configuration for argument parsing. + */ +typedef struct ZyanArgParseConfig_ +{ + /** + * `argv` argument passed to `main` by LibC. + */ + const char** argv; + /** + * `argc` argument passed to `main` by LibC. + */ + ZyanUSize argc; + /** + * Minimum # of accepted unnamed / anonymous arguments. + */ + ZyanUSize min_unnamed_args; + /** + * Maximum # of accepted unnamed / anonymous arguments. + */ + ZyanUSize max_unnamed_args; + /** + * Argument definition array, or `ZYAN_NULL`. + * + * Expects a pointer to an array of `ZyanArgParseDefinition` instances. The array is + * terminated by setting the `.name` field of the last element to `ZYAN_NULL`. If no named + * arguments should be parsed, you can also set this to `ZYAN_NULL`. + */ + ZyanArgParseDefinition* args; +} ZyanArgParseConfig; + +/** + * Information about a parsed argument. + */ +typedef struct ZyanArgParseArg_ +{ + /** + * Corresponding argument definition, or `ZYAN_NULL` for unnamed args. + * + * This pointer is borrowed from the `cfg` pointer passed to `ZyanArgParse`. + */ + const ZyanArgParseDefinition* def; + /** + * Whether the argument has a value (is non-boolean). + */ + ZyanBool has_value; + /** + * If `has_value == true`, then the argument value. + * + * This is a view into the `argv` string array passed to `ZyanArgParse` via the `cfg` argument. + */ + ZyanStringView value; +} ZyanArgParseArg; + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +#ifndef ZYAN_NO_LIBC + +/** + * Parse arguments according to a `ZyanArgParseConfig` definition. + * + * @param cfg Argument parser config to use. + * @param parsed Receives the parsed output. Vector of `ZyanArgParseArg`. Ownership is + * transferred to the user. Input is expected to be uninitialized. On error, + * the vector remains uninitialized. + * @param error_token On error, if it makes sense, receives the argument fragment causing the + * error. Optional, may be `ZYAN_NULL`. The pointer borrows into the `cfg` + * struct and doesn't have to be freed by the user. + * + * @return A `ZyanStatus` status determining whether the parsing succeeded. + */ +ZYCORE_EXPORT ZyanStatus ZyanArgParse(const ZyanArgParseConfig *cfg, ZyanVector* parsed, + const char** error_token); + +#endif + +/** + * Parse arguments according to a `ZyanArgParseConfig` definition. + * + * This version allows specification of a custom memory allocator and thus supports no-libc. + * + * @param cfg Argument parser config to use. + * @param parsed Receives the parsed output. Vector of `ZyanArgParseArg`. Ownership is + * transferred to the user. Input is expected to be uninitialized. On error, + * the vector remains uninitialized. + * @param error_token On error, if it makes sense, receives the argument fragment causing the + * error. Optional, may be `ZYAN_NULL`. The pointer borrows into the `cfg` + * struct and doesn't have to be freed by the user. + * @param allocator The `ZyanAllocator` to be used for allocating the output vector's data. + * + * @return A `ZyanStatus` status determining whether the parsing succeeded. + */ +ZYCORE_EXPORT ZyanStatus ZyanArgParseEx(const ZyanArgParseConfig *cfg, ZyanVector* parsed, + const char** error_token, ZyanAllocator* allocator); + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_ARGPARSE_H */ diff --git a/src/Zycore/Bitset.h b/src/Zycore/Bitset.h new file mode 100644 index 0000000..8c7eb1f --- /dev/null +++ b/src/Zycore/Bitset.h @@ -0,0 +1,484 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * Implements the bitset class. + */ + +#ifndef ZYCORE_BITSET_H +#define ZYCORE_BITSET_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZyanVector` struct. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZyanBitset_ +{ + /** + * The bitset size. + */ + ZyanUSize size; + /** + * The bitset data. + */ + ZyanVector bits; +} ZyanBitset; + +/** + * Defines the `ZyanBitsetByteOperation` function prototype. + * + * @param v1 A pointer to the first byte. This value receives the result after performing the + * desired operation. + * @param v2 A pointer to the second byte. + * + * @return A zyan status code. + * + * This function is used to perform byte-wise operations on two `ZyanBitset` instances. + */ +typedef ZyanStatus (*ZyanBitsetByteOperation)(ZyanU8* v1, const ZyanU8* v2); + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Constructor and destructor */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Initializes the given `ZyanBitset` instance. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param count The initial amount of bits. + * + * @return A zyan status code. + * + * The space for the bitset is dynamically allocated by the default allocator using the default + * growth factor of `2.0f` and the default shrink threshold of `0.5f`. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanBitsetInit(ZyanBitset* bitset, ZyanUSize count); + +#endif // ZYAN_NO_LIBC + +/** + * Initializes the given `ZyanBitset` instance and sets a custom `allocator` and memory + * allocation/deallocation parameters. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param count The initial amount of bits. + * @param allocator A pointer to a `ZyanAllocator` instance. + * @param growth_factor The growth factor (from `1.0f` to `x.xf`). + * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). + * + * @return A zyan status code. + * + * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables + * dynamic shrinking. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetInitEx(ZyanBitset* bitset, ZyanUSize count, + ZyanAllocator* allocator, float growth_factor, float shrink_threshold); + +/** + * Initializes the given `ZyanBitset` instance and configures it to use a custom user + * defined buffer with a fixed size. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param count The initial amount of bits. + * @param buffer A pointer to the buffer that is used as storage for the bits. + * @param capacity The maximum capacity (number of bytes) of the buffer. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetInitBuffer(ZyanBitset* bitset, ZyanUSize count, void* buffer, + ZyanUSize capacity); + +/** + * Destroys the given `ZyanBitset` instance. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetDestroy(ZyanBitset* bitset); + +/* ---------------------------------------------------------------------------------------------- */ +/* Logical operations */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Performs a byte-wise `operation` for every byte in the given `ZyanBitset` instances. + * + * @param destination A pointer to the `ZyanBitset` instance that is used as the first input and + * as the destination. + * @param source A pointer to the `ZyanBitset` instance that is used as the second input. + * @param operation A pointer to the function that performs the desired operation. + * + * @return A zyan status code. + * + * The `operation` callback is invoked once for every byte in the smallest of the `ZyanBitset` + * instances. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetPerformByteOperation(ZyanBitset* destination, + const ZyanBitset* source, ZyanBitsetByteOperation operation); + +/** + * Performs a logical `AND` operation on the given `ZyanBitset` instances. + * + * @param destination A pointer to the `ZyanBitset` instance that is used as the first input and + * as the destination. + * @param source A pointer to the `ZyanBitset` instance that is used as the second input. + * + * @return A zyan status code. + * + * If the destination bitmask contains more bits than the source one, the state of the remaining + * bits will be undefined. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetAND(ZyanBitset* destination, const ZyanBitset* source); + +/** + * Performs a logical `OR` operation on the given `ZyanBitset` instances. + * + * @param destination A pointer to the `ZyanBitset` instance that is used as the first input and + * as the destination. + * @param source A pointer to the `ZyanBitset` instance that is used as the second input. + * + * @return A zyan status code. + * + * If the destination bitmask contains more bits than the source one, the state of the remaining + * bits will be undefined. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetOR (ZyanBitset* destination, const ZyanBitset* source); + +/** + * Performs a logical `XOR` operation on the given `ZyanBitset` instances. + * + * @param destination A pointer to the `ZyanBitset` instance that is used as the first input and + * as the destination. + * @param source A pointer to the `ZyanBitset` instance that is used as the second input. + * + * @return A zyan status code. + * + * If the destination bitmask contains more bits than the source one, the state of the remaining + * bits will be undefined. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetXOR(ZyanBitset* destination, const ZyanBitset* source); + +/** + * Flips all bits of the given `ZyanBitset` instance. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetFlip(ZyanBitset* bitset); + +/* ---------------------------------------------------------------------------------------------- */ +/* Bit access */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Sets the bit at `index` of the given `ZyanBitset` instance to `1`. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param index The bit index. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetSet(ZyanBitset* bitset, ZyanUSize index); + +/** + * Sets the bit at `index` of the given `ZyanBitset` instance to `0`. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param index The bit index. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetReset(ZyanBitset* bitset, ZyanUSize index); + +/** + * Sets the bit at `index` of the given `ZyanBitset` instance to the specified `value`. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param index The bit index. + * @param value The new value. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetAssign(ZyanBitset* bitset, ZyanUSize index, ZyanBool value); + +/** + * Toggles the bit at `index` of the given `ZyanBitset` instance. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param index The bit index. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetToggle(ZyanBitset* bitset, ZyanUSize index); + +/** + * Returns the value of the bit at `index`. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param index The bit index. + * + * @return `ZYAN_STATUS_TRUE`, if the bit is set or `ZYAN_STATUS_FALSE`, if not, Another zyan + * status code, if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetTest(ZyanBitset* bitset, ZyanUSize index); + +/** + * Returns the value of the most significant bit. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return `ZYAN_STATUS_TRUE`, if the bit is set or `ZYAN_STATUS_FALSE`, if not. Another zyan + * status code, if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetTestMSB(ZyanBitset* bitset); + +/** + * Returns the value of the least significant bit. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return `ZYAN_STATUS_TRUE`, if the bit is set or `ZYAN_STATUS_FALSE`, if not. Another zyan + * status code, if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetTestLSB(ZyanBitset* bitset); + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Sets all bits of the given `ZyanBitset` instance to `1`. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetSetAll(ZyanBitset* bitset); + +/** + * Sets all bits of the given `ZyanBitset` instance to `0`. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetResetAll(ZyanBitset* bitset); + +/* ---------------------------------------------------------------------------------------------- */ +/* Size management */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Adds a new bit at the end of the bitset. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param value The value of the new bit. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetPush(ZyanBitset* bitset, ZyanBool value); + +/** + * Removes the last bit of the bitset. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetPop(ZyanBitset* bitset); + +/** + * Deletes all bits of the given `ZyanBitset` instance. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetClear(ZyanBitset* bitset); + +/* ---------------------------------------------------------------------------------------------- */ +/* Memory management */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Changes the capacity of the given `ZyanBitset` instance. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param count The new capacity (number of bits). + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetReserve(ZyanBitset* bitset, ZyanUSize count); + +/** + * Shrinks the capacity of the given bitset to match it's size. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetShrinkToFit(ZyanBitset* bitset); + +/* ---------------------------------------------------------------------------------------------- */ +/* Information */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the current size of the bitset in bits. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param size Receives the size of the bitset in bits. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetGetSize(const ZyanBitset* bitset, ZyanUSize* size); + +/** + * Returns the current capacity of the bitset in bits. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param capacity Receives the size of the bitset in bits. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetGetCapacity(const ZyanBitset* bitset, ZyanUSize* capacity); + +/** + * Returns the current size of the bitset in bytes. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param size Receives the size of the bitset in bytes. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetGetSizeBytes(const ZyanBitset* bitset, ZyanUSize* size); + +/** + * Returns the current capacity of the bitset in bytes. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param capacity Receives the size of the bitset in bytes. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetGetCapacityBytes(const ZyanBitset* bitset, ZyanUSize* capacity); + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the amount of bits set in the given bitset. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * @param count Receives the amount of bits set in the given bitset. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetCount(const ZyanBitset* bitset, ZyanUSize* count); + +/** + * Checks, if all bits of the given bitset are set. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return `ZYAN_STATUS_TRUE`, if all bits are set, `ZYAN_STATUS_FALSE`, if not. Another zyan + * status code, if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetAll(const ZyanBitset* bitset); + +/** + * Checks, if at least one bit of the given bitset is set. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return `ZYAN_STATUS_TRUE`, if at least one bit is set, `ZYAN_STATUS_FALSE`, if not. Another + * zyan status code, if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetAny(const ZyanBitset* bitset); + +/** + * Checks, if none bits of the given bitset are set. + * + * @param bitset A pointer to the `ZyanBitset` instance. + * + * @return `ZYAN_STATUS_TRUE`, if none bits are set, `ZYAN_STATUS_FALSE`, if not. Another zyan + * status code, if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanBitsetNone(const ZyanBitset* bitset); + +///* ---------------------------------------------------------------------------------------------- */ +// +///** +// * Returns a 32-bit unsigned integer representation of the data. +// * +// * @param bitset A pointer to the `ZyanBitset` instance. +// * @param value Receives the 32-bit unsigned integer representation of the data. +// * +// * @return A zyan status code. +// */ +//ZYCORE_EXPORT ZyanStatus ZyanBitsetToU32(const ZyanBitset* bitset, ZyanU32* value); +// +///** +// * Returns a 64-bit unsigned integer representation of the data. +// * +// * @param bitset A pointer to the `ZyanBitset` instance. +// * @param value Receives the 64-bit unsigned integer representation of the data. +// * +// * @return A zyan status code. +// */ +//ZYCORE_EXPORT ZyanStatus ZyanBitsetToU64(const ZyanBitset* bitset, ZyanU64* value); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_BITSET_H */ diff --git a/src/Zycore/Comparison.h b/src/Zycore/Comparison.h new file mode 100644 index 0000000..6d8b518 --- /dev/null +++ b/src/Zycore/Comparison.h @@ -0,0 +1,316 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * Defines prototypes of general-purpose comparison functions. + */ + +#ifndef ZYCORE_COMPARISON_H +#define ZYCORE_COMPARISON_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZyanEqualityComparison` function prototype. + * + * @param left A pointer to the first element. + * @param right A pointer to the second element. + * + * @return This function should return `ZYAN_TRUE` if the `left` element equals the `right` one + * or `ZYAN_FALSE`, if not. + */ +typedef ZyanBool (*ZyanEqualityComparison)(const void* left, const void* right); + +/** + * Defines the `ZyanComparison` function prototype. + * + * @param left A pointer to the first element. + * @param right A pointer to the second element. + * + * @return This function should return values in the following range: + * `left == right -> result == 0` + * `left < right -> result < 0` + * `left > right -> result > 0` + */ +typedef ZyanI32 (*ZyanComparison)(const void* left, const void* right); + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Equality comparison functions */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Declares a generic equality comparison function for an integral data-type. + * + * @param name The name of the function. + * @param type The name of the integral data-type. + */ +#define ZYAN_DECLARE_EQUALITY_COMPARISON(name, type) \ + ZyanBool name(const type* left, const type* right) \ + { \ + ZYAN_ASSERT(left); \ + ZYAN_ASSERT(right); \ + \ + return (*left == *right) ? ZYAN_TRUE : ZYAN_FALSE; \ + } + +/** + * Declares a generic equality comparison function that compares a single integral + * data-type field of a struct. + * + * @param name The name of the function. + * @param type The name of the integral data-type. + * @param field_name The name of the struct field. + */ +#define ZYAN_DECLARE_EQUALITY_COMPARISON_FOR_FIELD(name, type, field_name) \ + ZyanBool name(const type* left, const type* right) \ + { \ + ZYAN_ASSERT(left); \ + ZYAN_ASSERT(right); \ + \ + return (left->field_name == right->field_name) ? ZYAN_TRUE : ZYAN_FALSE; \ + } + +/* ---------------------------------------------------------------------------------------------- */ +/* Comparison functions */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Declares a generic comparison function for an integral data-type. + * + * @param name The name of the function. + * @param type The name of the integral data-type. + */ +#define ZYAN_DECLARE_COMPARISON(name, type) \ + ZyanI32 name(const type* left, const type* right) \ + { \ + ZYAN_ASSERT(left); \ + ZYAN_ASSERT(right); \ + \ + if (*left < *right) \ + { \ + return -1; \ + } \ + if (*left > *right) \ + { \ + return 1; \ + } \ + return 0; \ + } + +/** + * Declares a generic comparison function that compares a single integral data-type field + * of a struct. + * + * @param name The name of the function. + * @param type The name of the integral data-type. + * @param field_name The name of the struct field. + */ +#define ZYAN_DECLARE_COMPARISON_FOR_FIELD(name, type, field_name) \ + ZyanI32 name(const type* left, const type* right) \ + { \ + ZYAN_ASSERT(left); \ + ZYAN_ASSERT(right); \ + \ + if (left->field_name < right->field_name) \ + { \ + return -1; \ + } \ + if (left->field_name > right->field_name) \ + { \ + return 1; \ + } \ + return 0; \ + } + + /* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Default equality comparison functions */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines a default equality comparison function for pointer values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `ZYAN_TRUE` if the `left` value equals the `right` one or `ZYAN_FALSE`, if + * not. + */ +ZYAN_INLINE ZYAN_DECLARE_EQUALITY_COMPARISON(ZyanEqualsPointer, void* const) + +/** + * Defines a default equality comparison function for `ZyanBool` values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `ZYAN_TRUE` if the `left` value equals the `right` one or `ZYAN_FALSE`, if + * not. + */ +ZYAN_INLINE ZYAN_DECLARE_EQUALITY_COMPARISON(ZyanEqualsBool, ZyanBool) + +/** + * Defines a default equality comparison function for 8-bit numeric values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `ZYAN_TRUE` if the `left` value equals the `right` one or `ZYAN_FALSE`, if + * not. + */ +ZYAN_INLINE ZYAN_DECLARE_EQUALITY_COMPARISON(ZyanEqualsNumeric8, ZyanU8) + +/** + * Defines a default equality comparison function for 16-bit numeric values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `ZYAN_TRUE` if the `left` value equals the `right` one or `ZYAN_FALSE`, if + * not. + */ +ZYAN_INLINE ZYAN_DECLARE_EQUALITY_COMPARISON(ZyanEqualsNumeric16, ZyanU16) + +/** + * Defines a default equality comparison function for 32-bit numeric values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `ZYAN_TRUE` if the `left` value equals the `right` one or `ZYAN_FALSE`, if + * not. + */ +ZYAN_INLINE ZYAN_DECLARE_EQUALITY_COMPARISON(ZyanEqualsNumeric32, ZyanU32) + +/** + * Defines a default equality comparison function for 64-bit numeric values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `ZYAN_TRUE` if the `left` value equals the `right` one or `ZYAN_FALSE`, if + * not. + */ +ZYAN_INLINE ZYAN_DECLARE_EQUALITY_COMPARISON(ZyanEqualsNumeric64, ZyanU64) + +/* ---------------------------------------------------------------------------------------------- */ +/* Default comparison functions */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines a default comparison function for pointer values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `0` if the `left` value equals the `right` one, `-1` if the `left` value is + * less than the `right` one, or `1` if the `left` value is greater than the `right` one. + */ +ZYAN_INLINE ZYAN_DECLARE_COMPARISON(ZyanComparePointer, void* const) + +/** + * Defines a default comparison function for `ZyanBool` values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `0` if the `left` value equals the `right` one, `-1` if the `left` value is + * less than the `right` one, or `1` if the `left` value is greater than the `right` one. + */ +ZYAN_INLINE ZYAN_DECLARE_COMPARISON(ZyanCompareBool, ZyanBool) + +/** + * Defines a default comparison function for 8-bit numeric values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `0` if the `left` value equals the `right` one, `-1` if the `left` value is + * less than the `right` one, or `1` if the `left` value is greater than the `right` one. + */ +ZYAN_INLINE ZYAN_DECLARE_COMPARISON(ZyanCompareNumeric8, ZyanU8) + +/** + * Defines a default comparison function for 16-bit numeric values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `0` if the `left` value equals the `right` one, `-1` if the `left` value is + * less than the `right` one, or `1` if the `left` value is greater than the `right` one. + */ +ZYAN_INLINE ZYAN_DECLARE_COMPARISON(ZyanCompareNumeric16, ZyanU16) + +/** + * Defines a default comparison function for 32-bit numeric values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `0` if the `left` value equals the `right` one, `-1` if the `left` value is + * less than the `right` one, or `1` if the `left` value is greater than the `right` one. + */ +ZYAN_INLINE ZYAN_DECLARE_COMPARISON(ZyanCompareNumeric32, ZyanU32) + +/** + * Defines a default comparison function for 64-bit numeric values. + * + * @param left A pointer to the first value. + * @param right A pointer to the second value. + * + * @return Returns `0` if the `left` value equals the `right` one, `-1` if the `left` value is + * less than the `right` one, or `1` if the `left` value is greater than the `right` one. + */ +ZYAN_INLINE ZYAN_DECLARE_COMPARISON(ZyanCompareNumeric64, ZyanU64) + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_COMPARISON_H */ diff --git a/src/Zycore/Defines.h b/src/Zycore/Defines.h new file mode 100644 index 0000000..de81cb7 --- /dev/null +++ b/src/Zycore/Defines.h @@ -0,0 +1,451 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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 + * General helper and platform detection macros. + */ + +#ifndef ZYCORE_DEFINES_H +#define ZYCORE_DEFINES_H + +/* ============================================================================================== */ +/* Meta macros */ +/* ============================================================================================== */ + +/** + * Concatenates two values using the stringify operator (`##`). + * + * @param x The first value. + * @param y The second value. + * + * @return The combined string of the given values. + */ +#define ZYAN_MACRO_CONCAT(x, y) x ## y + +/** + * Concatenates two values using the stringify operator (`##`) and expands the value to + * be used in another macro. + * + * @param x The first value. + * @param y The second value. + * + * @return The combined string of the given values. + */ +#define ZYAN_MACRO_CONCAT_EXPAND(x, y) ZYAN_MACRO_CONCAT(x, y) + +/* ============================================================================================== */ +/* Compiler detection */ +/* ============================================================================================== */ + +#if defined(__clang__) +# define ZYAN_CLANG +# define ZYAN_GNUC +#elif defined(__ICC) || defined(__INTEL_COMPILER) +# define ZYAN_ICC +#elif defined(__GNUC__) || defined(__GNUG__) +# define ZYAN_GCC +# define ZYAN_GNUC +#elif defined(_MSC_VER) +# define ZYAN_MSVC +#elif defined(__BORLANDC__) +# define ZYAN_BORLAND +#else +# define ZYAN_UNKNOWN_COMPILER +#endif + +/* ============================================================================================== */ +/* Platform detection */ +/* ============================================================================================== */ + +#if defined(_WIN32) +# define ZYAN_WINDOWS +#elif defined(__EMSCRIPTEN__) +# define ZYAN_EMSCRIPTEN +#elif defined(__APPLE__) +# define ZYAN_APPLE +# define ZYAN_POSIX +#elif defined(__linux) +# define ZYAN_LINUX +# define ZYAN_POSIX +#elif defined(__FreeBSD__) +# define ZYAN_FREEBSD +# define ZYAN_POSIX +#elif defined(sun) || defined(__sun) +# define ZYAN_SOLARIS +# define ZYAN_POSIX +#elif defined(__unix) +# define ZYAN_UNIX +# define ZYAN_POSIX +#elif defined(__posix) +# define ZYAN_POSIX +#else +# define ZYAN_UNKNOWN_PLATFORM +#endif + +/* ============================================================================================== */ +/* Kernel mode detection */ +/* ============================================================================================== */ + +#if (defined(ZYAN_WINDOWS) && defined(_KERNEL_MODE)) || \ + (defined(ZYAN_APPLE) && defined(KERNEL)) || \ + (defined(ZYAN_LINUX) && defined(__KERNEL__)) || \ + (defined(__FreeBSD_kernel__)) +# define ZYAN_KERNEL +#else +# define ZYAN_USER +#endif + +/* ============================================================================================== */ +/* Architecture detection */ +/* ============================================================================================== */ + +#if defined(_M_AMD64) || defined(__x86_64__) +# define ZYAN_X64 +#elif defined(_M_IX86) || defined(__i386__) +# define ZYAN_X86 +#elif defined(_M_ARM64) || defined(__aarch64__) +# define ZYAN_AARCH64 +#elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__) +# define ZYAN_ARM +#elif defined(__EMSCRIPTEN__) + // Nothing to do, `ZYAN_EMSCRIPTEN` is both platform and arch macro for this one. +#else +# error "Unsupported architecture detected" +#endif + +/* ============================================================================================== */ +/* Debug/Release detection */ +/* ============================================================================================== */ + +#if defined(ZYAN_MSVC) || defined(ZYAN_BORLAND) +# ifdef _DEBUG +# define ZYAN_DEBUG +# else +# define ZYAN_RELEASE +# endif +#elif defined(ZYAN_GNUC) || defined(ZYAN_ICC) +# ifdef NDEBUG +# define ZYAN_RELEASE +# else +# define ZYAN_DEBUG +# endif +#else +# define ZYAN_RELEASE +#endif + +/* ============================================================================================== */ +/* Misc compatibility macros */ +/* ============================================================================================== */ + +#if defined(ZYAN_CLANG) +# define ZYAN_NO_SANITIZE(what) __attribute__((no_sanitize(what))) +#else +# define ZYAN_NO_SANITIZE(what) +#endif + +#if defined(ZYAN_MSVC) || defined(ZYAN_BORLAND) +# define ZYAN_INLINE __inline +#else +# define ZYAN_INLINE static inline +#endif + +#if defined(ZYAN_MSVC) +# define ZYAN_NOINLINE __declspec(noinline) +#elif defined(ZYAN_GCC) || defined(ZYAN_CLANG) +# define ZYAN_NOINLINE __attribute__((noinline)) +#else +# define ZYAN_NOINLINE +#endif + +/* ============================================================================================== */ +/* Debugging and optimization macros */ +/* ============================================================================================== */ + +/** + * Runtime debug assertion. + */ +#if defined(ZYAN_NO_LIBC) +# define ZYAN_ASSERT(condition) (void)(condition) +#elif defined(ZYAN_WINDOWS) && defined(ZYAN_KERNEL) +# include +# define ZYAN_ASSERT(condition) NT_ASSERT(condition) +#else +# include +# define ZYAN_ASSERT(condition) assert(condition) +#endif + +/** + * Compiler-time assertion. + */ +#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus) +# define ZYAN_STATIC_ASSERT(x) _Static_assert(x, #x) +#elif (defined(__cplusplus) && __cplusplus >= 201103L) || \ + (defined(__cplusplus) && defined (_MSC_VER) && (_MSC_VER >= 1600)) || \ + (defined (_MSC_VER) && (_MSC_VER >= 1800)) +# define ZYAN_STATIC_ASSERT(x) static_assert(x, #x) +#else +# define ZYAN_STATIC_ASSERT(x) \ + typedef int ZYAN_MACRO_CONCAT_EXPAND(ZYAN_SASSERT_, __COUNTER__) [(x) ? 1 : -1] +#endif + +/** + * Marks the current code path as unreachable. + */ +#if defined(ZYAN_RELEASE) +# if defined(ZYAN_CLANG) // GCC eagerly evals && RHS, we have to use nested ifs. +# if __has_builtin(__builtin_unreachable) +# define ZYAN_UNREACHABLE __builtin_unreachable() +# else +# define ZYAN_UNREACHABLE for(;;) +# endif +# elif defined(ZYAN_GCC) && ((__GNUC__ == 4 && __GNUC_MINOR__ > 4) || __GNUC__ > 4) +# define ZYAN_UNREACHABLE __builtin_unreachable() +# elif defined(ZYAN_ICC) +# ifdef ZYAN_WINDOWS +# include // "missing return statement" workaround +# define ZYAN_UNREACHABLE __assume(0); (void)abort() +# else +# define ZYAN_UNREACHABLE __builtin_unreachable() +# endif +# elif defined(ZYAN_MSVC) +# define ZYAN_UNREACHABLE __assume(0) +# else +# define ZYAN_UNREACHABLE for(;;) +# endif +#elif defined(ZYAN_NO_LIBC) +# define ZYAN_UNREACHABLE for(;;) +#elif defined(ZYAN_WINDOWS) && defined(ZYAN_KERNEL) +# define ZYAN_UNREACHABLE { __fastfail(0); for(;;){} } +#else +# include +# define ZYAN_UNREACHABLE { assert(0); abort(); } +#endif + +/* ============================================================================================== */ +/* Utils */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* General purpose */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Marks the specified parameter as unused. + * + * @param x The name of the unused parameter. + */ +#define ZYAN_UNUSED(x) (void)(x) + +/** + * Intentional fallthrough. + */ +#if defined(ZYAN_GCC) && __GNUC__ >= 7 +# define ZYAN_FALLTHROUGH __attribute__((fallthrough)) +#else +# define ZYAN_FALLTHROUGH +#endif + +/** + * Declares a bitfield. + * + * @param x The size (in bits) of the bitfield. + */ +#define ZYAN_BITFIELD(x) : x + +/** + * Marks functions that require libc (cannot be used with `ZYAN_NO_LIBC`). + */ +#define ZYAN_REQUIRES_LIBC + +/** + * Decorator for `printf`-style functions. + * + * @param format_index The 1-based index of the format string parameter. + * @param first_to_check The 1-based index of the format arguments parameter. + */ +#if defined(__RESHARPER__) +# define ZYAN_PRINTF_ATTR(format_index, first_to_check) \ + [[gnu::format(printf, format_index, first_to_check)]] +#elif defined(ZYAN_GCC) +# define ZYAN_PRINTF_ATTR(format_index, first_to_check) \ + __attribute__((format(printf, format_index, first_to_check))) +#else +# define ZYAN_PRINTF_ATTR(format_index, first_to_check) +#endif + +/** + * Decorator for `wprintf`-style functions. + * + * @param format_index The 1-based index of the format string parameter. + * @param first_to_check The 1-based index of the format arguments parameter. + */ +#if defined(__RESHARPER__) +# define ZYAN_WPRINTF_ATTR(format_index, first_to_check) \ + [[rscpp::format(wprintf, format_index, first_to_check)]] +#else +# define ZYAN_WPRINTF_ATTR(format_index, first_to_check) +#endif + +/* ---------------------------------------------------------------------------------------------- */ +/* Arrays */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the length (number of elements) of an array. + * + * @param a The name of the array. + * + * @return The number of elements of the given array. + */ +#define ZYAN_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) + +/* ---------------------------------------------------------------------------------------------- */ +/* Arithmetic */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the smaller value of `a` or `b`. + * + * @param a The first value. + * @param b The second value. + * + * @return The smaller value of `a` or `b`. + */ +#define ZYAN_MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/** + * Returns the bigger value of `a` or `b`. + * + * @param a The first value. + * @param b The second value. + * + * @return The bigger value of `a` or `b`. + */ +#define ZYAN_MAX(a, b) (((a) > (b)) ? (a) : (b)) + +/** + * Returns the absolute value of `a`. + * + * @param a The value. + * + * @return The absolute value of `a`. + */ +#define ZYAN_ABS(a) (((a) < 0) ? -(a) : (a)) + +/** + * Checks, if the given value is a power of 2. + * + * @param x The value. + * + * @return `ZYAN_TRUE`, if the given value is a power of 2 or `ZYAN_FALSE`, if not. + * + * Note that this macro always returns `ZYAN_TRUE` for `x == 0`. + */ +#define ZYAN_IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0) + +/** + * Checks, if the given value is properly aligned. + * + * Note that this macro only works for powers of 2. + */ +#define ZYAN_IS_ALIGNED_TO(x, align) (((x) & ((align) - 1)) == 0) + +/** + * Aligns the value to the nearest given alignment boundary (by rounding it up). + * + * @param x The value. + * @param align The desired alignment. + * + * @return The aligned value. + * + * Note that this macro only works for powers of 2. + */ +#define ZYAN_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1)) + +/** + * Aligns the value to the nearest given alignment boundary (by rounding it down). + * + * @param x The value. + * @param align The desired alignment. + * + * @return The aligned value. + * + * Note that this macro only works for powers of 2. + */ +#define ZYAN_ALIGN_DOWN(x, align) (((x) - 1) & ~((align) - 1)) + +/* ---------------------------------------------------------------------------------------------- */ +/* Bit operations */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * Checks, if the bit at index `b` is required to present the ordinal value `n`. + * + * @param n The ordinal value. + * @param b The bit index. + * + * @return `ZYAN_TRUE`, if the bit at index `b` is required to present the ordinal value `n` or + * `ZYAN_FALSE`, if not. + * + * Note that this macro always returns `ZYAN_FALSE` for `n == 0`. + */ +#define ZYAN_NEEDS_BIT(n, b) (((unsigned long)(n) >> (b)) > 0) + +/* + * Returns the number of bits required to represent the ordinal value `n`. + * + * @param n The ordinal value. + * + * @return The number of bits required to represent the ordinal value `n`. + * + * Note that this macro returns `0` for `n == 0`. + */ +#define ZYAN_BITS_TO_REPRESENT(n) \ + ( \ + ZYAN_NEEDS_BIT(n, 0) + ZYAN_NEEDS_BIT(n, 1) + \ + ZYAN_NEEDS_BIT(n, 2) + ZYAN_NEEDS_BIT(n, 3) + \ + ZYAN_NEEDS_BIT(n, 4) + ZYAN_NEEDS_BIT(n, 5) + \ + ZYAN_NEEDS_BIT(n, 6) + ZYAN_NEEDS_BIT(n, 7) + \ + ZYAN_NEEDS_BIT(n, 8) + ZYAN_NEEDS_BIT(n, 9) + \ + ZYAN_NEEDS_BIT(n, 10) + ZYAN_NEEDS_BIT(n, 11) + \ + ZYAN_NEEDS_BIT(n, 12) + ZYAN_NEEDS_BIT(n, 13) + \ + ZYAN_NEEDS_BIT(n, 14) + ZYAN_NEEDS_BIT(n, 15) + \ + ZYAN_NEEDS_BIT(n, 16) + ZYAN_NEEDS_BIT(n, 17) + \ + ZYAN_NEEDS_BIT(n, 18) + ZYAN_NEEDS_BIT(n, 19) + \ + ZYAN_NEEDS_BIT(n, 20) + ZYAN_NEEDS_BIT(n, 21) + \ + ZYAN_NEEDS_BIT(n, 22) + ZYAN_NEEDS_BIT(n, 23) + \ + ZYAN_NEEDS_BIT(n, 24) + ZYAN_NEEDS_BIT(n, 25) + \ + ZYAN_NEEDS_BIT(n, 26) + ZYAN_NEEDS_BIT(n, 27) + \ + ZYAN_NEEDS_BIT(n, 28) + ZYAN_NEEDS_BIT(n, 29) + \ + ZYAN_NEEDS_BIT(n, 30) + ZYAN_NEEDS_BIT(n, 31) \ + ) + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#endif /* ZYCORE_DEFINES_H */ diff --git a/src/Zycore/Format.h b/src/Zycore/Format.h new file mode 100644 index 0000000..b0401e6 --- /dev/null +++ b/src/Zycore/Format.h @@ -0,0 +1,286 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * Provides helper functions for performant number to string conversion. + */ + +#ifndef ZYCORE_FORMAT_H +#define ZYCORE_FORMAT_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Helpers */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Get the absolute value of a 64 bit int. + * + * @param x The value to process. + * @return The absolute, unsigned value. + * + * This gracefully deals with the special case of `x` being `INT_MAX`. + */ +ZYAN_INLINE ZyanU64 ZyanAbsI64(ZyanI64 x) +{ + // INT_MIN special case. Can't use the value directly because GCC thinks + // it's too big for an INT64 literal, however is perfectly happy to accept + // this expression. This is also hit INT64_MIN is defined in `stdint.h`. + if (x == (-0x7fffffffffffffff - 1)) + { + return 0x8000000000000000u; + } + + return (ZyanU64)(x < 0 ? -x : x); +} + +/* ---------------------------------------------------------------------------------------------- */ +/* Insertion */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Inserts formatted text in the destination string at the given `index`. + * + * @param string The destination string. + * @param index The insert index. + * @param format The format string. + * @param ... The format arguments. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYAN_PRINTF_ATTR(3, 4) +ZYCORE_EXPORT ZyanStatus ZyanStringInsertFormat(ZyanString* string, ZyanUSize index, + const char* format, ...); + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Formats the given unsigned ordinal `value` to its decimal text-representation and + * inserts it to the `string`. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The insert index. + * @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`. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringInsertDecU(ZyanString* string, ZyanUSize index, ZyanU64 value, + ZyanU8 padding_length); + +/** + * Formats the given signed ordinal `value` to its decimal text-representation and + * inserts it to the `string`. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The insert index. + * @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. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringInsertDecS(ZyanString* string, ZyanUSize index, ZyanI64 value, + ZyanU8 padding_length, ZyanBool force_sign, const ZyanString* prefix); + +/** + * Formats the given unsigned ordinal `value` to its hexadecimal text-representation and + * inserts it to the `string`. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The insert index. + * @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'). + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringInsertHexU(ZyanString* string, ZyanUSize index, ZyanU64 value, + ZyanU8 padding_length, ZyanBool uppercase); + +/** + * Formats the given signed ordinal `value` to its hexadecimal text-representation and + * inserts it to the `string`. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The insert index. + * @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 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. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringInsertHexS(ZyanString* string, ZyanUSize index, ZyanI64 value, + ZyanU8 padding_length, ZyanBool uppercase, ZyanBool force_sign, const ZyanString* prefix); + +/* ---------------------------------------------------------------------------------------------- */ +/* Appending */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Appends formatted text to the destination string. + * + * @param string The destination string. + * @param format The format string. + * @param ... The format arguments. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYAN_PRINTF_ATTR(2, 3) +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringAppendFormat( + ZyanString* string, const char* format, ...); + +#endif // ZYAN_NO_LIBC + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * 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`. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringAppendDecU(ZyanString* string, ZyanU64 value, + ZyanU8 padding_length); + +/** + * 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. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringAppendDecS(ZyanString* string, ZyanI64 value, + ZyanU8 padding_length, ZyanBool force_sign, const ZyanStringView* prefix); + +/** + * 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'). + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringAppendHexU(ZyanString* string, ZyanU64 value, + ZyanU8 padding_length, ZyanBool uppercase); + +/** + * 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. + * @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 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. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringAppendHexS(ZyanString* string, ZyanI64 value, + ZyanU8 padding_length, ZyanBool uppercase, ZyanBool force_sign, const ZyanStringView* prefix); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif // ZYCORE_FORMAT_H diff --git a/src/Zycore/LibC.h b/src/Zycore/LibC.h new file mode 100644 index 0000000..cb0b2f3 --- /dev/null +++ b/src/Zycore/LibC.h @@ -0,0 +1,511 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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 a simple LibC abstraction and fallback routines. + */ + +#ifndef ZYCORE_LIBC_H +#define ZYCORE_LIBC_H + +#ifndef ZYAN_CUSTOM_LIBC + +// Include a custom LibC header and define `ZYAN_CUSTOM_LIBC` to provide your own LibC +// replacement functions + +#ifndef ZYAN_NO_LIBC + +/* ============================================================================================== */ +/* LibC is available */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* errno.h */ +/* ---------------------------------------------------------------------------------------------- */ + +#include + +#define ZYAN_ERRNO errno + +/* ---------------------------------------------------------------------------------------------- */ +/* stdarg.h */ +/* ---------------------------------------------------------------------------------------------- */ + +#include + +/** + * Defines the `ZyanVAList` datatype. + */ +typedef va_list ZyanVAList; + +#define ZYAN_VA_START va_start +#define ZYAN_VA_ARG va_arg +#define ZYAN_VA_END va_end +#define ZYAN_VA_COPY(dest, source) va_copy((dest), (source)) + +/* ---------------------------------------------------------------------------------------------- */ +/* stdio.h */ +/* ---------------------------------------------------------------------------------------------- */ + +#include + +#define ZYAN_FPUTS fputs +#define ZYAN_FPUTC fputc +#define ZYAN_FPRINTF fprintf +#define ZYAN_PRINTF printf +#define ZYAN_PUTC putc +#define ZYAN_PUTS puts +#define ZYAN_SCANF scanf +#define ZYAN_SSCANF sscanf +#define ZYAN_VSNPRINTF vsnprintf + +/** + * Defines the `ZyanFile` datatype. + */ +typedef FILE ZyanFile; + +#define ZYAN_STDIN stdin +#define ZYAN_STDOUT stdout +#define ZYAN_STDERR stderr + +/* ---------------------------------------------------------------------------------------------- */ +/* stdlib.h */ +/* ---------------------------------------------------------------------------------------------- */ + +#include +#define ZYAN_CALLOC calloc +#define ZYAN_FREE free +#define ZYAN_MALLOC malloc +#define ZYAN_REALLOC realloc + +/* ---------------------------------------------------------------------------------------------- */ +/* string.h */ +/* ---------------------------------------------------------------------------------------------- */ + +#include +#define ZYAN_MEMCHR memchr +#define ZYAN_MEMCMP memcmp +#define ZYAN_MEMCPY memcpy +#define ZYAN_MEMMOVE memmove +#define ZYAN_MEMSET memset +#define ZYAN_STRCAT strcat +#define ZYAN_STRCHR strchr +#define ZYAN_STRCMP strcmp +#define ZYAN_STRCOLL strcoll +#define ZYAN_STRCPY strcpy +#define ZYAN_STRCSPN strcspn +#define ZYAN_STRLEN strlen +#define ZYAN_STRNCAT strncat +#define ZYAN_STRNCMP strncmp +#define ZYAN_STRNCPY strncpy +#define ZYAN_STRPBRK strpbrk +#define ZYAN_STRRCHR strrchr +#define ZYAN_STRSPN strspn +#define ZYAN_STRSTR strstr +#define ZYAN_STRTOK strtok +#define ZYAN_STRXFRM strxfrm + +/* ---------------------------------------------------------------------------------------------- */ + +#else // if ZYAN_NO_LIBC + +/* ============================================================================================== */ +/* No LibC available, use our own functions */ +/* ============================================================================================== */ + +#include +#include + +/* + * These implementations are by no means optimized and will be outperformed by pretty much any + * libc implementation out there. We do not aim towards providing competetive implementations here, + * but towards providing a last resort fallback for environments without a working libc. + */ + +/* ---------------------------------------------------------------------------------------------- */ +/* stdarg.h */ +/* ---------------------------------------------------------------------------------------------- */ + +#if defined(ZYAN_MSVC) || defined(ZYAN_ICC) + +/** + * Defines the `ZyanVAList` datatype. + */ +typedef char* ZyanVAList; + +# define ZYAN_VA_START __crt_va_start +# define ZYAN_VA_ARG __crt_va_arg +# define ZYAN_VA_END __crt_va_end +# define ZYAN_VA_COPY(destination, source) ((destination) = (source)) + +#elif defined(ZYAN_GNUC) + +/** + * Defines the `ZyanVAList` datatype. + */ +typedef __builtin_va_list ZyanVAList; + +# define ZYAN_VA_START(v, l) __builtin_va_start(v, l) +# define ZYAN_VA_END(v) __builtin_va_end(v) +# define ZYAN_VA_ARG(v, l) __builtin_va_arg(v, l) +# define ZYAN_VA_COPY(d, s) __builtin_va_copy(d, s) + +#else +# error "Unsupported compiler for no-libc mode." +#endif + +/* ---------------------------------------------------------------------------------------------- */ +/* stdio.h */ +/* ---------------------------------------------------------------------------------------------- */ + +// ZYAN_INLINE int ZYAN_VSNPRINTF (char* const buffer, ZyanUSize const count, +// char const* const format, ZyanVAList args) +// { +// // We cant provide a fallback implementation for this function +// ZYAN_UNUSED(buffer); +// ZYAN_UNUSED(count); +// ZYAN_UNUSED(format); +// ZYAN_UNUSED(args); +// return ZYAN_NULL; +// } + +/* ---------------------------------------------------------------------------------------------- */ +/* stdlib.h */ +/* ---------------------------------------------------------------------------------------------- */ + +// ZYAN_INLINE void* ZYAN_CALLOC(ZyanUSize nitems, ZyanUSize size) +// { +// // We cant provide a fallback implementation for this function +// ZYAN_UNUSED(nitems); +// ZYAN_UNUSED(size); +// return ZYAN_NULL; +// } +// +// ZYAN_INLINE void ZYAN_FREE(void *p) +// { +// // We cant provide a fallback implementation for this function +// ZYAN_UNUSED(p); +// } +// +// ZYAN_INLINE void* ZYAN_MALLOC(ZyanUSize n) +// { +// // We cant provide a fallback implementation for this function +// ZYAN_UNUSED(n); +// return ZYAN_NULL; +// } +// +// ZYAN_INLINE void* ZYAN_REALLOC(void* p, ZyanUSize n) +// { +// // We cant provide a fallback implementation for this function +// ZYAN_UNUSED(p); +// ZYAN_UNUSED(n); +// return ZYAN_NULL; +// } + +/* ---------------------------------------------------------------------------------------------- */ +/* string.h */ +/* ---------------------------------------------------------------------------------------------- */ + +ZYAN_INLINE void* ZYAN_MEMCHR(const void* str, int c, ZyanUSize n) +{ + const ZyanU8* p = (ZyanU8*)str; + while (n--) + { + if (*p != (ZyanU8)c) + { + p++; + } else + { + return (void*)p; + } + } + return 0; +} + +ZYAN_INLINE int ZYAN_MEMCMP(const void* s1, const void* s2, ZyanUSize n) +{ + const ZyanU8* p1 = s1, *p2 = s2; + while (n--) + { + if (*p1 != *p2) + { + return *p1 - *p2; + } + p1++, p2++; + } + return 0; +} + +ZYAN_INLINE void* ZYAN_MEMCPY(void* dst, const void* src, ZyanUSize n) +{ + volatile ZyanU8* dp = dst; + const ZyanU8* sp = src; + while (n--) + { + *dp++ = *sp++; + } + return dst; +} + +ZYAN_INLINE void* ZYAN_MEMMOVE(void* dst, const void* src, ZyanUSize n) +{ + volatile ZyanU8* pd = dst; + const ZyanU8* ps = src; + if (ps < pd) + { + for (pd += n, ps += n; n--;) + { + *--pd = *--ps; + } + } else + { + while (n--) + { + *pd++ = *ps++; + } + } + return dst; +} + +ZYAN_INLINE void* ZYAN_MEMSET(void* dst, int val, ZyanUSize n) +{ + volatile ZyanU8* p = dst; + while (n--) + { + *p++ = (unsigned char)val; + } + return dst; +} + +ZYAN_INLINE char* ZYAN_STRCAT(char* dest, const char* src) +{ + char* ret = dest; + while (*dest) + { + dest++; + } + while ((*dest++ = *src++)); + return ret; +} + +ZYAN_INLINE char* ZYAN_STRCHR(const char* s, int c) +{ + while (*s != (char)c) + { + if (!*s++) + { + return 0; + } + } + return (char*)s; +} + +ZYAN_INLINE int ZYAN_STRCMP(const char* s1, const char* s2) +{ + while (*s1 && (*s1 == *s2)) + { + s1++, s2++; + } + return *(const ZyanU8*)s1 - *(const ZyanU8*)s2; +} + +ZYAN_INLINE int ZYAN_STRCOLL(const char *s1, const char *s2) +{ + // TODO: Implement + + ZYAN_UNUSED(s1); + ZYAN_UNUSED(s2); + + return 0; +} + +ZYAN_INLINE char* ZYAN_STRCPY(char* dest, const char* src) +{ + char* ret = dest; + while ((*dest++ = *src++)); + return ret; +} + +ZYAN_INLINE ZyanUSize ZYAN_STRCSPN(const char *s1, const char *s2) +{ + ZyanUSize ret = 0; + while (*s1) + { + if (ZYAN_STRCHR(s2, *s1)) + { + return ret; + } + s1++, ret++; + } + return ret; +} + +ZYAN_INLINE ZyanUSize ZYAN_STRLEN(const char* str) +{ + const char* p = str; + while (*str) + { + ++str; + } + return str - p; +} + +ZYAN_INLINE char* ZYAN_STRNCAT(char* dest, const char* src, ZyanUSize n) +{ + char* ret = dest; + while (*dest) + { + dest++; + } + while (n--) + { + if (!(*dest++ = *src++)) + { + return ret; + } + } + *dest = 0; + return ret; +} + +ZYAN_INLINE int ZYAN_STRNCMP(const char* s1, const char* s2, ZyanUSize n) +{ + while (n--) + { + if (*s1++ != *s2++) + { + return *(unsigned char*)(s1 - 1) - *(unsigned char*)(s2 - 1); + } + } + return 0; +} + +ZYAN_INLINE char* ZYAN_STRNCPY(char* dest, const char* src, ZyanUSize n) +{ + char* ret = dest; + do + { + if (!n--) + { + return ret; + } + } while ((*dest++ = *src++)); + while (n--) + { + *dest++ = 0; + } + return ret; +} + +ZYAN_INLINE char* ZYAN_STRPBRK(const char* s1, const char* s2) +{ + while (*s1) + { + if(ZYAN_STRCHR(s2, *s1++)) + { + return (char*)--s1; + } + } + return 0; +} + +ZYAN_INLINE char* ZYAN_STRRCHR(const char* s, int c) +{ + char* ret = 0; + do + { + if (*s == (char)c) + { + ret = (char*)s; + } + } while (*s++); + return ret; +} + +ZYAN_INLINE ZyanUSize ZYAN_STRSPN(const char* s1, const char* s2) +{ + ZyanUSize ret = 0; + while (*s1 && ZYAN_STRCHR(s2, *s1++)) + { + ret++; + } + return ret; +} + +ZYAN_INLINE char* ZYAN_STRSTR(const char* s1, const char* s2) +{ + const ZyanUSize n = ZYAN_STRLEN(s2); + while (*s1) + { + if (!ZYAN_MEMCMP(s1++, s2, n)) + { + return (char*)(s1 - 1); + } + } + return 0; +} + +ZYAN_INLINE char* ZYAN_STRTOK(char* str, const char* delim) +{ + static char* p = 0; + if (str) + { + p = str; + } else + if (!p) + { + return 0; + } + str = p + ZYAN_STRSPN(p, delim); + p = str + ZYAN_STRCSPN(str, delim); + if (p == str) + { + return p = 0; + } + p = *p ? *p = 0, p + 1 : 0; + return str; +} + +ZYAN_INLINE ZyanUSize ZYAN_STRXFRM(char* dest, const char* src, ZyanUSize n) +{ + const ZyanUSize n2 = ZYAN_STRLEN(src); + if (n > n2) + { + ZYAN_STRCPY(dest, src); + } + return n2; +} + +/* ---------------------------------------------------------------------------------------------- */ + +#endif + +#endif + +/* ============================================================================================== */ + +#endif /* ZYCORE_LIBC_H */ diff --git a/src/Zycore/List.h b/src/Zycore/List.h new file mode 100644 index 0000000..015a324 --- /dev/null +++ b/src/Zycore/List.h @@ -0,0 +1,574 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * Implements a doubly linked list. + */ + +#ifndef ZYCORE_LIST_H +#define ZYCORE_LIST_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZyanListNode` struct. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZyanListNode_ +{ + /** + * A pointer to the previous list node. + */ + struct ZyanListNode_* prev; + /** + * A pointer to the next list node. + */ + struct ZyanListNode_* next; +} ZyanListNode; + +/** + * Defines the `ZyanList` struct. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZyanList_ +{ + /** + * The memory allocator. + */ + ZyanAllocator* allocator; + /** + * The current number of elements in the list. + */ + ZyanUSize size; + /** + * The size of a single element in bytes. + */ + ZyanUSize element_size; + /** + * The element destructor callback. + */ + ZyanMemberProcedure destructor; + /** + * The head node. + */ + ZyanListNode* head; + /** + * The tail node. + */ + ZyanListNode* tail; + /** + * The data buffer. + * + * Only used for instances created by `ZyanListInitCustomBuffer`. + */ + void* buffer; + /** + * The data buffer capacity (number of bytes). + * + * Only used for instances created by `ZyanListInitCustomBuffer`. + */ + ZyanUSize capacity; + /** + * The first unused node. + * + * When removing a node, the first-unused value is updated to point at the removed node and the + * next node of the removed node will be updated to point at the old first-unused node. + * + * When appending the memory of the first unused-node is recycled to store the new node. The + * value of the first-unused node is then updated to point at the reused nodes next node. + * + * If the first-unused value is `ZYAN_NULL`, any new node will be "allocated" behind the tail + * node (if there is enough space left in the fixed size buffer). + * + * Only used for instances created by `ZyanListInitCustomBuffer`. + */ + ZyanListNode* first_unused; +} ZyanList; + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines an uninitialized `ZyanList` instance. + */ +#define ZYAN_LIST_INITIALIZER \ + { \ + /* allocator */ ZYAN_NULL, \ + /* size */ 0, \ + /* element_size */ 0, \ + /* head */ ZYAN_NULL, \ + /* destructor */ ZYAN_NULL, \ + /* tail */ ZYAN_NULL, \ + /* buffer */ ZYAN_NULL, \ + /* capacity */ 0, \ + /* first_unused */ ZYAN_NULL \ + } + +/* ---------------------------------------------------------------------------------------------- */ +/* Helper macros */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the data value of the given `node`. + * + * @param type The desired value type. + * @param node A pointer to the `ZyanListNode` struct. + * + * @result The data value of the given `node`. + * + * Note that this function is unsafe and might dereference a null-pointer. + */ +#ifdef __cplusplus +#define ZYAN_LIST_GET(type, node) \ + (*reinterpret_cast(ZyanListGetNodeData(node))) +#else +#define ZYAN_LIST_GET(type, node) \ + (*(const type*)ZyanListGetNodeData(node)) +#endif + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Constructor and destructor */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Initializes the given `ZyanList` instance. + * + * @param list A pointer to the `ZyanList` instance. + * @param element_size The size of a single element in bytes. + * @param destructor A destructor callback that is invoked every time an item is deleted, or + * `ZYAN_NULL` if not needed. + * + * @return A zyan status code. + * + * The memory for the list elements is dynamically allocated by the default allocator. + * + * Finalization with `ZyanListDestroy` is required for all instances created by this function. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanListInit(ZyanList* list, ZyanUSize element_size, + ZyanMemberProcedure destructor); + +#endif // ZYAN_NO_LIBC + +/** + * Initializes the given `ZyanList` instance and sets a custom `allocator`. + * + * @param list A pointer to the `ZyanList` instance. + * @param element_size The size of a single element in bytes. + * @param destructor A destructor callback that is invoked every time an item is deleted, or + * `ZYAN_NULL` if not needed. + * @param allocator A pointer to a `ZyanAllocator` instance. + * + * @return A zyan status code. + * + * Finalization with `ZyanListDestroy` is required for all instances created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanListInitEx(ZyanList* list, ZyanUSize element_size, + ZyanMemberProcedure destructor, ZyanAllocator* allocator); + +/** + * Initializes the given `ZyanList` instance and configures it to use a custom user + * defined buffer with a fixed size. + * + * @param list A pointer to the `ZyanList` instance. + * @param element_size The size of a single element in bytes. + * @param destructor A destructor callback that is invoked every time an item is deleted, or + * `ZYAN_NULL` if not needed. + * @param buffer A pointer to the buffer that is used as storage for the elements. + * @param capacity The maximum capacity (number of bytes) of the buffer including the + * space required for the list-nodes. + * + * @return A zyan status code. + * + * The buffer capacity required to store `n` elements of type `T` is be calculated by: + * `size = n * sizeof(ZyanListNode) + n * sizeof(T)` + * + * Finalization is not required for instances created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanListInitCustomBuffer(ZyanList* list, ZyanUSize element_size, + ZyanMemberProcedure destructor, void* buffer, ZyanUSize capacity); + +/** + * Destroys the given `ZyanList` instance. + * + * @param list A pointer to the `ZyanList` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListDestroy(ZyanList* list); + +/* ---------------------------------------------------------------------------------------------- */ +/* Duplication */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Initializes a new `ZyanList` instance by duplicating an existing list. + * + * @param destination A pointer to the (uninitialized) destination `ZyanList` instance. + * @param source A pointer to the source list. + * + * @return A zyan status code. + * + * The memory for the list is dynamically allocated by the default allocator. + * + * Finalization with `ZyanListDestroy` is required for all instances created by this function. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanListDuplicate(ZyanList* destination, + const ZyanList* source); + +#endif // ZYAN_NO_LIBC + +/** + * Initializes a new `ZyanList` instance by duplicating an existing list and sets a + * custom `allocator`. + * + * @param destination A pointer to the (uninitialized) destination `ZyanList` instance. + * @param source A pointer to the source list. + * @param allocator A pointer to a `ZyanAllocator` instance. + * + * @return A zyan status code. + + * Finalization with `ZyanListDestroy` is required for all instances created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanListDuplicateEx(ZyanList* destination, const ZyanList* source, + ZyanAllocator* allocator); + +/** + * Initializes a new `ZyanList` instance by duplicating an existing list and + * configures it to use a custom user defined buffer with a fixed size. + * + * @param destination A pointer to the (uninitialized) destination `ZyanList` instance. + * @param source A pointer to the source list. + * @param buffer A pointer to the buffer that is used as storage for the elements. + * @param capacity The maximum capacity (number of bytes) of the buffer including the + * space required for the list-nodes. + + * This function will fail, if the capacity of the buffer is not sufficient + * to store all elements of the source list. + * + * @return A zyan status code. + * + * The buffer capacity required to store `n` elements of type `T` is be calculated by: + * `size = n * sizeof(ZyanListNode) + n * sizeof(T)` + * + * Finalization is not required for instances created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanListDuplicateCustomBuffer(ZyanList* destination, + const ZyanList* source, void* buffer, ZyanUSize capacity); + +/* ---------------------------------------------------------------------------------------------- */ +/* Item access */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns a pointer to the first `ZyanListNode` struct of the given list. + * + * @param list A pointer to the `ZyanList` instance. + * @param node Receives a pointer to the first `ZyanListNode` struct of the list. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListGetHeadNode(const ZyanList* list, const ZyanListNode** node); + +/** + * Returns a pointer to the last `ZyanListNode` struct of the given list. + * + * @param list A pointer to the `ZyanList` instance. + * @param node Receives a pointer to the last `ZyanListNode` struct of the list. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListGetTailNode(const ZyanList* list, const ZyanListNode** node); + +/** + * Receives a pointer to the previous `ZyanListNode` struct linked to the passed one. + * + * @param node Receives a pointer to the previous `ZyanListNode` struct linked to the passed + * one. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListGetPrevNode(const ZyanListNode** node); + +/** + * Receives a pointer to the next `ZyanListNode` struct linked to the passed one. + * + * @param node Receives a pointer to the next `ZyanListNode` struct linked to the passed one. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListGetNextNode(const ZyanListNode** node); + +/** + * Returns a constant pointer to the data of the given `node`. + * + * @param node A pointer to the `ZyanListNode` struct. + * + * @return A constant pointer to the the data of the given `node` or `ZYAN_NULL`, if an error + * occured. + * + * Take a look at `ZyanListGetNodeDataEx`, if you need a function that returns a zyan status code. + */ +ZYCORE_EXPORT const void* ZyanListGetNodeData(const ZyanListNode* node); + +/** + * Returns a constant pointer to the data of the given `node`.. + * + * @param node A pointer to the `ZyanListNode` struct. + * @param value Receives a constant pointer to the data of the given `node`. + * + * Take a look at `ZyanListGetNodeData`, if you need a function that directly returns a pointer. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListGetNodeDataEx(const ZyanListNode* node, const void** value); + +/** + * Returns a mutable pointer to the data of the given `node`. + * + * @param node A pointer to the `ZyanListNode` struct. + * + * @return A mutable pointer to the the data of the given `node` or `ZYAN_NULL`, if an error + * occured. + * + * Take a look at `ZyanListGetPointerMutableEx` instead, if you need a function that returns a + * zyan status code. + */ +ZYCORE_EXPORT void* ZyanListGetNodeDataMutable(const ZyanListNode* node); + +/** + * Returns a mutable pointer to the data of the given `node`.. + * + * @param node A pointer to the `ZyanListNode` struct. + * @param value Receives a mutable pointer to the data of the given `node`. + * + * Take a look at `ZyanListGetNodeDataMutable`, if you need a function that directly returns a + * pointer. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListGetNodeDataMutableEx(const ZyanListNode* node, void** value); + +/** + * Assigns a new data value to the given `node`. + * + * @param list A pointer to the `ZyanList` instance. + * @param node A pointer to the `ZyanListNode` struct. + * @param value The value to assign. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListSetNodeData(const ZyanList* list, const ZyanListNode* node, + const void* value); + +/* ---------------------------------------------------------------------------------------------- */ +/* Insertion */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Adds a new `item` to the end of the list. + * + * @param list A pointer to the `ZyanList` instance. + * @param item A pointer to the item to add. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListPushBack(ZyanList* list, const void* item); + +/** + * Adds a new `item` to the beginning of the list. + * + * @param list A pointer to the `ZyanList` instance. + * @param item A pointer to the item to add. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListPushFront(ZyanList* list, const void* item); + +/** + * Constructs an `item` in-place at the end of the list. + * + * @param list A pointer to the `ZyanList` instance. + * @param item Receives a pointer to the new item. + * @param constructor The constructor callback or `ZYAN_NULL`. The new item will be in + * undefined state, if no constructor was passed. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListEmplaceBack(ZyanList* list, void** item, + ZyanMemberFunction constructor); + +/** + * Constructs an `item` in-place at the beginning of the list. + * + * @param list A pointer to the `ZyanList` instance. + * @param item Receives a pointer to the new item. + * @param constructor The constructor callback or `ZYAN_NULL`. The new item will be in + * undefined state, if no constructor was passed. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListEmplaceFront(ZyanList* list, void** item, + ZyanMemberFunction constructor); + +/* ---------------------------------------------------------------------------------------------- */ +/* Deletion */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Removes the last element of the list. + * + * @param list A pointer to the `ZyanList` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListPopBack(ZyanList* list); + +/** + * Removes the firstelement of the list. + * + * @param list A pointer to the `ZyanList` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListPopFront(ZyanList* list); + +/** + * Removes the given `node` from the list. + * + * @param list A pointer to the `ZyanList` instance. + * @param node A pointer to the `ZyanListNode` struct. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListRemove(ZyanList* list, const ZyanListNode* node); + +/** + * Removes multiple nodes from the list. + * + * @param list A pointer to the `ZyanList` instance. + * @param first A pointer to the first node. + * @param last A pointer to the last node. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListRemoveRange(ZyanList* list, const ZyanListNode* first, + const ZyanListNode* last); + +/** + * Erases all elements of the list. + * + * @param list A pointer to the `ZyanList` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListClear(ZyanList* list); + +/* ---------------------------------------------------------------------------------------------- */ +/* Searching */ +/* ---------------------------------------------------------------------------------------------- */ + +// TODO: + +/* ---------------------------------------------------------------------------------------------- */ +/* Memory management */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Resizes the given `ZyanList` instance. + * + * @param list A pointer to the `ZyanList` instance. + * @param size The new size of the list. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListResize(ZyanList* list, ZyanUSize size); + +/** + * Resizes the given `ZyanList` instance. + * + * @param list A pointer to the `ZyanList` instance. + * @param size The new size of the list. + * @param initializer A pointer to a value to be used as initializer for new items. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListResizeEx(ZyanList* list, ZyanUSize size, const void* initializer); + +/* ---------------------------------------------------------------------------------------------- */ +/* Information */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the current size of the list. + * + * @param list A pointer to the `ZyanList` instance. + * @param size Receives the size of the list. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanListGetSize(const ZyanList* list, ZyanUSize* size); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_VECTOR_H */ diff --git a/src/Zycore/Object.h b/src/Zycore/Object.h new file mode 100644 index 0000000..d015cef --- /dev/null +++ b/src/Zycore/Object.h @@ -0,0 +1,84 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * Defines some generic object-related datatypes. + */ + +#ifndef ZYCORE_OBJECT_H +#define ZYCORE_OBJECT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZyanMemberProcedure` function prototype. + * + * @param object A pointer to the object. + */ +typedef void (*ZyanMemberProcedure)(void* object); + +/** + * Defines the `ZyanConstMemberProcedure` function prototype. + * + * @param object A pointer to the object. + */ +typedef void (*ZyanConstMemberProcedure)(const void* object); + +/** + * Defines the `ZyanMemberFunction` function prototype. + * + * @param object A pointer to the object. + * + * @return A zyan status code. + */ +typedef ZyanStatus (*ZyanMemberFunction)(void* object); + +/** + * Defines the `ZyanConstMemberFunction` function prototype. + * + * @param object A pointer to the object. + * + * @return A zyan status code. + */ +typedef ZyanStatus (*ZyanConstMemberFunction)(const void* object); + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_OBJECT_H */ diff --git a/src/Zycore/Status.h b/src/Zycore/Status.h new file mode 100644 index 0000000..b0d7fdf --- /dev/null +++ b/src/Zycore/Status.h @@ -0,0 +1,287 @@ +/*************************************************************************************************** + + Zyan Core Library (Zyan-C) + + 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 + * Status code definitions and check macros. + */ + +#ifndef ZYCORE_STATUS_H +#define ZYCORE_STATUS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZyanStatus` data type. + */ +typedef ZyanU32 ZyanStatus; + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Definition */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines a zyan status code. + * + * @param error `1`, if the status code signals an error or `0`, if not. + * @param module The module id. + * @param code The actual code. + * + * @return The zyan status code. + */ +#define ZYAN_MAKE_STATUS(error, module, code) \ + (ZyanStatus)((((error) & 0x01u) << 31u) | (((module) & 0x7FFu) << 20u) | ((code) & 0xFFFFFu)) + +/* ---------------------------------------------------------------------------------------------- */ +/* Checks */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Checks if a zyan operation was successful. + * + * @param status The zyan status-code to check. + * + * @return `ZYAN_TRUE`, if the operation succeeded or `ZYAN_FALSE`, if not. + */ +#define ZYAN_SUCCESS(status) \ + (!((status) & 0x80000000u)) + +/** + * Checks if a zyan operation failed. + * + * @param status The zyan status-code to check. + * + * @return `ZYAN_TRUE`, if the operation failed or `ZYAN_FALSE`, if not. + */ +#define ZYAN_FAILED(status) \ + ((status) & 0x80000000u) + +/** + * Checks if a zyan operation was successful and returns with the status-code, if not. + * + * @param status The zyan status-code to check. + */ +#define ZYAN_CHECK(status) \ + do \ + { \ + const ZyanStatus status_047620348 = (status); \ + if (!ZYAN_SUCCESS(status_047620348)) \ + { \ + return status_047620348; \ + } \ + } while (0) + +/* ---------------------------------------------------------------------------------------------- */ +/* Information */ +/* ---------------------------------------------------------------------------------------------- */ + + /** + * Returns the module id of a zyan status-code. + * + * @param status The zyan status-code. + * + * @return The module id of the zyan status-code. + */ +#define ZYAN_STATUS_MODULE(status) \ + (((status) >> 20) & 0x7FFu) + + /** + * Returns the code of a zyan status-code. + * + * @param status The zyan status-code. + * + * @return The code of the zyan status-code. + */ +#define ZYAN_STATUS_CODE(status) \ + ((status) & 0xFFFFFu) + +/* ============================================================================================== */ +/* Status codes */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Module IDs */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * The zycore generic module id. + */ +#define ZYAN_MODULE_ZYCORE 0x001u + +/** + * The zycore arg-parse submodule id. + */ +#define ZYAN_MODULE_ARGPARSE 0x003u + +/** + * The base module id for user-defined status codes. + */ +#define ZYAN_MODULE_USER 0x3FFu + +/* ---------------------------------------------------------------------------------------------- */ +/* Status codes (general purpose) */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * The operation completed successfully. + */ +#define ZYAN_STATUS_SUCCESS \ + ZYAN_MAKE_STATUS(0u, ZYAN_MODULE_ZYCORE, 0x00u) + +/** + * The operation failed with an generic error. + */ +#define ZYAN_STATUS_FAILED \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x01u) + +/** + * The operation completed successfully and returned `ZYAN_TRUE`. + */ +#define ZYAN_STATUS_TRUE \ + ZYAN_MAKE_STATUS(0u, ZYAN_MODULE_ZYCORE, 0x02u) + +/** + * The operation completed successfully and returned `ZYAN_FALSE`. + */ +#define ZYAN_STATUS_FALSE \ + ZYAN_MAKE_STATUS(0u, ZYAN_MODULE_ZYCORE, 0x03u) + +/** + * An invalid argument was passed to a function. + */ +#define ZYAN_STATUS_INVALID_ARGUMENT \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x04u) + +/** + * An attempt was made to perform an invalid operation. + */ +#define ZYAN_STATUS_INVALID_OPERATION \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x05u) + +/** + * Insufficient privileges to perform the requested operation. + */ +#define ZYAN_STATUS_ACCESS_DENIED \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x06u) + +/** + * The requested entity was not found. + */ +#define ZYAN_STATUS_NOT_FOUND \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x07u) + +/** + * An index passed to a function was out of bounds. + */ +#define ZYAN_STATUS_OUT_OF_RANGE \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x08u) + +/** + * A buffer passed to a function was too small to complete the requested operation. + */ +#define ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x09u) + +/** + * Insufficient memory to perform the operation. + */ +#define ZYAN_STATUS_NOT_ENOUGH_MEMORY \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x0Au) + +/** + * An unknown error occurred during a system function call. + */ +#define ZYAN_STATUS_BAD_SYSTEMCALL \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x0Bu) + +/** + * The process ran out of resources while performing an operation. + */ +#define ZYAN_STATUS_OUT_OF_RESOURCES \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x0Cu) + +/** + * A dependency library was not found or does have an unexpected version number or + * feature-set. + */ +#define ZYAN_STATUS_MISSING_DEPENDENCY \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYCORE, 0x0Du) + +/* ---------------------------------------------------------------------------------------------- */ +/* Status codes (arg parse) */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Argument was not expected. + */ +#define ZYAN_STATUS_ARG_NOT_UNDERSTOOD \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ARGPARSE, 0x00u) + +/** + * Too few arguments were provided. + */ +#define ZYAN_STATUS_TOO_FEW_ARGS \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ARGPARSE, 0x01u) + +/** + * Too many arguments were provided. + */ +#define ZYAN_STATUS_TOO_MANY_ARGS \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ARGPARSE, 0x02u) + +/** + * An argument that expected a value misses its value. + */ +#define ZYAN_STATUS_ARG_MISSES_VALUE \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ARGPARSE, 0x03u) + +/** +* A required argument is missing. +*/ +#define ZYAN_STATUS_REQUIRED_ARG_MISSING \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ARGPARSE, 0x04u) + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_STATUS_H */ diff --git a/src/Zycore/String.h b/src/Zycore/String.h new file mode 100644 index 0000000..c3157bc --- /dev/null +++ b/src/Zycore/String.h @@ -0,0 +1,1012 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * Implements a string type. + */ + +#ifndef ZYCORE_STRING_H +#define ZYCORE_STRING_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Constants */ +/* ============================================================================================== */ + +/** + * The initial minimum capacity (number of characters) for all dynamically allocated + * string instances - not including the terminating '\0'-character. + */ +#define ZYAN_STRING_MIN_CAPACITY 32 + +/** + * The default growth factor for all string instances. + */ +#define ZYAN_STRING_DEFAULT_GROWTH_FACTOR 2.00f + +/** + * The default shrink threshold for all string instances. + */ +#define ZYAN_STRING_DEFAULT_SHRINK_THRESHOLD 0.25f + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* String flags */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanStringFlags` datatype. + */ +typedef ZyanU8 ZyanStringFlags; + +/** + * The string uses a custom user-defined buffer with a fixed capacity. + */ +#define ZYAN_STRING_HAS_FIXED_CAPACITY 0x01 // (1 << 0) + +/* ---------------------------------------------------------------------------------------------- */ +/* String */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanString` struct. + * + * The `ZyanString` type is implemented as a size-prefixed string - which allows for a lot of + * performance optimizations. + * Nevertheless null-termination is guaranteed at all times to provide maximum compatibility with + * default C-style strings (use `ZyanStringGetData` to access the C-style string). + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZyanString_ +{ + /** + * String flags. + */ + ZyanStringFlags flags; + /** + * The vector that contains the actual string. + */ + ZyanVector vector; +} ZyanString; + +/* ---------------------------------------------------------------------------------------------- */ +/* View */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanStringView` struct. + * + * The `ZyanStringView` type provides a view inside a string (`ZyanString` instances, null- + * terminated C-style strings, or even not-null-terminated custom strings). A view is immutable + * by design and can't be directly converted to a C-style string. + * + * Views might become invalid (e.g. pointing to invalid memory), if the underlying string gets + * destroyed or resized. + * + * The `ZYAN_STRING_TO_VIEW` macro can be used to cast a `ZyanString` to a `ZyanStringView` pointer + * without any runtime overhead. + * Casting a view to a normal string is not supported and will lead to unexpected behavior (use + * `ZyanStringDuplicate` to create a deep-copy instead). + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZyanStringView_ +{ + /** + * The string data. + * + * The view internally re-uses the normal string struct to allow casts without any runtime + * overhead. + */ + ZyanString string; +} ZyanStringView; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines an uninitialized `ZyanString` instance. + */ +#define ZYAN_STRING_INITIALIZER \ + { \ + /* flags */ 0, \ + /* vector */ ZYAN_VECTOR_INITIALIZER \ + } + +/* ---------------------------------------------------------------------------------------------- */ +/* Helper macros */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Casts a `ZyanString` pointer to a constant `ZyanStringView` pointer. + */ +#define ZYAN_STRING_TO_VIEW(string) (const ZyanStringView*)(string) + +/** + * Defines a `ZyanStringView` struct that provides a view into a static C-style string. + * + * @param string The C-style string. + */ +#define ZYAN_DEFINE_STRING_VIEW(string) \ + { \ + /* string */ \ + { \ + /* flags */ 0, \ + /* vector */ \ + { \ + /* allocator */ ZYAN_NULL, \ + /* growth_factor */ 1.0f, \ + /* shrink_threshold */ 0.0f, \ + /* size */ sizeof(string), \ + /* capacity */ sizeof(string), \ + /* element_size */ sizeof(char), \ + /* destructor */ ZYAN_NULL, \ + /* data */ (char*)(string) \ + } \ + } \ + } + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Constructor and destructor */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Initializes the given `ZyanString` instance. + * + * @param string A pointer to the `ZyanString` instance. + * @param capacity The initial capacity (number of characters). + * + * @return A zyan status code. + * + * The memory for the string is dynamically allocated by the default allocator using the default + * growth factor of `2.0f` and the default shrink threshold of `0.25f`. + * + * The allocated buffer will be at least one character larger than the given `capacity`, to reserve + * space for the terminating '\0'. + * + * Finalization with `ZyanStringDestroy` is required for all strings created by this function. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringInit(ZyanString* string, ZyanUSize capacity); + +#endif // ZYAN_NO_LIBC + +/** + * Initializes the given `ZyanString` instance and sets a custom `allocator` and memory + * allocation/deallocation parameters. + * + * @param string A pointer to the `ZyanString` instance. + * @param capacity The initial capacity (number of characters). + * @param allocator A pointer to a `ZyanAllocator` instance. + * @param growth_factor The growth factor (from `1.0f` to `x.xf`). + * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). + * + * @return A zyan status code. + * + * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables + * dynamic shrinking. + * + * The allocated buffer will be at least one character larger than the given `capacity`, to reserve + * space for the terminating '\0'. + * + * Finalization with `ZyanStringDestroy` is required for all strings created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringInitEx(ZyanString* string, ZyanUSize capacity, + ZyanAllocator* allocator, float growth_factor, float shrink_threshold); + +/** + * Initializes the given `ZyanString` instance and configures it to use a custom user + * defined buffer with a fixed size. + * + * @param string A pointer to the `ZyanString` instance. + * @param buffer A pointer to the buffer that is used as storage for the string. + * @param capacity The maximum capacity (number of characters) of the buffer, including + * the terminating '\0'. + * + * @return A zyan status code. + * + * Finalization is not required for strings created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringInitCustomBuffer(ZyanString* string, char* buffer, + ZyanUSize capacity); + +/** + * Destroys the given `ZyanString` instance. + * + * @param string A pointer to the `ZyanString` instance. + * + * @return A zyan status code. + * + */ +ZYCORE_EXPORT ZyanStatus ZyanStringDestroy(ZyanString* string); + +/* ---------------------------------------------------------------------------------------------- */ +/* Duplication */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Initializes a new `ZyanString` instance by duplicating an existing string. + * + * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. + * @param source A pointer to the source string. + * @param capacity The initial capacity (number of characters). + * + * This value is automatically adjusted to the size of the source string, if + * a smaller value was passed. + * + * @return A zyan status code. + * + * The behavior of this function is undefined, if `source` is a view into the `destination` + * string or `destination` points to an already initialized `ZyanString` instance. + * + * The memory for the string is dynamically allocated by the default allocator using the default + * growth factor of `2.0f` and the default shrink threshold of `0.25f`. + * + * The allocated buffer will be at least one character larger than the given `capacity`, to reserve + * space for the terminating '\0'. + * + * Finalization with `ZyanStringDestroy` is required for all strings created by this function. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringDuplicate(ZyanString* destination, + const ZyanStringView* source, ZyanUSize capacity); + +#endif // ZYAN_NO_LIBC + +/** + * Initializes a new `ZyanString` instance by duplicating an existing string and sets a + * custom `allocator` and memory allocation/deallocation parameters. + * + * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. + * @param source A pointer to the source string. + * @param capacity The initial capacity (number of characters). + + * This value is automatically adjusted to the size of the source + * string, if a smaller value was passed. + * @param allocator A pointer to a `ZyanAllocator` instance. + * @param growth_factor The growth factor (from `1.0f` to `x.xf`). + * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). + * + * @return A zyan status code. + * + * The behavior of this function is undefined, if `source` is a view into the `destination` + * string or `destination` points to an already initialized `ZyanString` instance. + * + * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables + * dynamic shrinking. + * + * The allocated buffer will be at least one character larger than the given `capacity`, to reserve + * space for the terminating '\0'. + * + * Finalization with `ZyanStringDestroy` is required for all strings created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringDuplicateEx(ZyanString* destination, + const ZyanStringView* source, ZyanUSize capacity, ZyanAllocator* allocator, + float growth_factor, float shrink_threshold); + +/** + * Initializes a new `ZyanString` instance by duplicating an existing string and + * configures it to use a custom user defined buffer with a fixed size. + * + * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. + * @param source A pointer to the source string. + * @param buffer A pointer to the buffer that is used as storage for the string. + * @param capacity The maximum capacity (number of characters) of the buffer, including the + * terminating '\0'. + + * This function will fail, if the capacity of the buffer is less or equal to + * the size of the source string. + * + * @return A zyan status code. + * + * The behavior of this function is undefined, if `source` is a view into the `destination` + * string or `destination` points to an already initialized `ZyanString` instance. + * + * Finalization is not required for strings created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringDuplicateCustomBuffer(ZyanString* destination, + const ZyanStringView* source, char* buffer, ZyanUSize capacity); + +/* ---------------------------------------------------------------------------------------------- */ +/* Concatenation */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Initializes a new `ZyanString` instance by concatenating two existing strings. + * + * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. + * + * This function will fail, if the destination `ZyanString` instance equals + * one of the source strings. + * @param s1 A pointer to the first source string. + * @param s2 A pointer to the second source string. + * @param capacity The initial capacity (number of characters). + + * This value is automatically adjusted to the combined size of the source + * strings, if a smaller value was passed. + * + * @return A zyan status code. + * + * The behavior of this function is undefined, if `s1` or `s2` are views into the `destination` + * string or `destination` points to an already initialized `ZyanString` instance. + * + * The memory for the string is dynamically allocated by the default allocator using the default + * growth factor of `2.0f` and the default shrink threshold of `0.25f`. + * + * The allocated buffer will be at least one character larger than the given `capacity`, to reserve + * space for the terminating '\0'. + * + * Finalization with `ZyanStringDestroy` is required for all strings created by this function. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringConcat(ZyanString* destination, + const ZyanStringView* s1, const ZyanStringView* s2, ZyanUSize capacity); + +#endif // ZYAN_NO_LIBC + +/** + * Initializes a new `ZyanString` instance by concatenating two existing strings and sets + * a custom `allocator` and memory allocation/deallocation parameters. + * + * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. + * + * This function will fail, if the destination `ZyanString` instance + * equals one of the source strings. + * @param s1 A pointer to the first source string. + * @param s2 A pointer to the second source string. + * @param capacity The initial capacity (number of characters). + * + * This value is automatically adjusted to the combined size of the + * source strings, if a smaller value was passed. + * @param allocator A pointer to a `ZyanAllocator` instance. + * @param growth_factor The growth factor (from `1.0f` to `x.xf`). + * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). + * + * @return A zyan status code. + * + * The behavior of this function is undefined, if `s1` or `s2` are views into the `destination` + * string or `destination` points to an already initialized `ZyanString` instance. + * + * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables + * dynamic shrinking. + * + * The allocated buffer will be at least one character larger than the given `capacity`, to reserve + * space for the terminating '\0'. + * + * Finalization with `ZyanStringDestroy` is required for all strings created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringConcatEx(ZyanString* destination, const ZyanStringView* s1, + const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor, + float shrink_threshold); + +/** + * Initializes a new `ZyanString` instance by concatenating two existing strings and + * configures it to use a custom user defined buffer with a fixed size. + * + * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. + * + * This function will fail, if the destination `ZyanString` instance equals + * one of the source strings. + * @param s1 A pointer to the first source string. + * @param s2 A pointer to the second source string. + * @param buffer A pointer to the buffer that is used as storage for the string. + * @param capacity The maximum capacity (number of characters) of the buffer. + * + * This function will fail, if the capacity of the buffer is less or equal to + * the combined size of the source strings. + * + * @return A zyan status code. + * + * The behavior of this function is undefined, if `s1` or `s2` are views into the `destination` + * string or `destination` points to an already initialized `ZyanString` instance. + * + * Finalization is not required for strings created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringConcatCustomBuffer(ZyanString* destination, + const ZyanStringView* s1, const ZyanStringView* s2, char* buffer, ZyanUSize capacity); + +/* ---------------------------------------------------------------------------------------------- */ +/* Views */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns a view inside an existing view/string. + * + * @param view A pointer to the `ZyanStringView` instance. + * @param source A pointer to the source string. + * + * @return A zyan status code. + * + * The `ZYAN_STRING_TO_VEW` macro can be used to pass any `ZyanString` instance as value for the + * `source` string. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringViewInsideView(ZyanStringView* view, + const ZyanStringView* source); + +/** + * Returns a view inside an existing view/string starting from the given `index`. + * + * @param view A pointer to the `ZyanStringView` instance. + * @param source A pointer to the source string. + * @param index The start index. + * @param count The number of characters. + * + * @return A zyan status code. + * + * The `ZYAN_STRING_TO_VEW` macro can be used to pass any `ZyanString` instance as value for the + * `source` string. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringViewInsideViewEx(ZyanStringView* view, + const ZyanStringView* source, ZyanUSize index, ZyanUSize count); + +/** + * Returns a view inside a null-terminated C-style string. + * + * @param view A pointer to the `ZyanStringView` instance. + * @param string The C-style string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringViewInsideBuffer(ZyanStringView* view, const char* string); + +/** + * Returns a view inside a character buffer with custom length. + * + * @param view A pointer to the `ZyanStringView` instance. + * @param buffer A pointer to the buffer containing the string characters. + * @param length The length of the string (number of characters). + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringViewInsideBufferEx(ZyanStringView* view, const char* buffer, + ZyanUSize length); + +/** + * Returns the size (number of characters) of the view. + * + * @param view A pointer to the `ZyanStringView` instance. + * @param size Receives the size (number of characters) of the view. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringViewGetSize(const ZyanStringView* view, ZyanUSize* size); + +/** + * Returns the C-style string of the given `ZyanString` instance. + * + * @warning The string is not guaranteed to be null terminated! + * + * @param string A pointer to the `ZyanStringView` instance. + * @param value Receives a pointer to the C-style string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringViewGetData(const ZyanStringView* view, const char** buffer); + +/* ---------------------------------------------------------------------------------------------- */ +/* Character access */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the character at the given `index`. + * + * @param string A pointer to the `ZyanStringView` instance. + * @param index The character index. + * @param value Receives the desired character of the string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringGetChar(const ZyanStringView* string, ZyanUSize index, + char* value); + +/** + * Returns a pointer to the character at the given `index`. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The character index. + * @param value Receives a pointer to the desired character in the string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringGetCharMutable(ZyanString* string, ZyanUSize index, + char** value); + +/** + * Assigns a new value to the character at the given `index`. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The character index. + * @param value The character to assign. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringSetChar(ZyanString* string, ZyanUSize index, char value); + +/* ---------------------------------------------------------------------------------------------- */ +/* Insertion */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Inserts the content of the source string in the destination string at the given `index`. + * + * @param destination The destination string. + * @param index The insert index. + * @param source The source string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringInsert(ZyanString* destination, ZyanUSize index, + const ZyanStringView* source); + +/** + * Inserts `count` characters of the source string in the destination string at the given + * `index`. + * + * @param destination The destination string. + * @param destination_index The insert index. + * @param source The source string. + * @param source_index The index of the first character to be inserted from the source + * string. + * @param count The number of chars to insert from the source string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringInsertEx(ZyanString* destination, ZyanUSize destination_index, + const ZyanStringView* source, ZyanUSize source_index, ZyanUSize count); + +/* ---------------------------------------------------------------------------------------------- */ +/* 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. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringAppend(ZyanString* destination, const ZyanStringView* source); + +/** + * Appends `count` characters of the source string to the end of the destination string. + * + * @param destination The destination string. + * @param source The source string. + * @param source_index The index of the first character to be appended from the source string. + * @param count The number of chars to append from the source string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringAppendEx(ZyanString* destination, const ZyanStringView* source, + ZyanUSize source_index, ZyanUSize count); + +/* ---------------------------------------------------------------------------------------------- */ +/* Deletion */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Deletes characters from the given string, starting at `index`. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The index of the first character to delete. + * @param count The number of characters to delete. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringDelete(ZyanString* string, ZyanUSize index, ZyanUSize count); + +/** + * Deletes all remaining characters from the given string, starting at `index`. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The index of the first character to delete. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringTruncate(ZyanString* string, ZyanUSize index); + +/** + * Erases the given string. + * + * @param string A pointer to the `ZyanString` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringClear(ZyanString* string); + +/* ---------------------------------------------------------------------------------------------- */ +/* Searching */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Searches for the first occurrence of `needle` in the given `haystack` starting from the + * left. + * + * @param haystack The string to search in. + * @param needle The sub-string to search for. + * @param found_index A pointer to a variable that receives the index of the first occurrence of + * `needle`. + * + * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + * + * The `found_index` is set to `-1`, if the needle was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringLPos(const ZyanStringView* haystack, + const ZyanStringView* needle, ZyanISize* found_index); + +/** + * Searches for the first occurrence of `needle` in the given `haystack` starting from the + * left. + * + * @param haystack The string to search in. + * @param needle The sub-string to search for. + * @param found_index A pointer to a variable that receives the index of the first occurrence of + * `needle`. + * @param index The start index. + * @param count The maximum number of characters to iterate, beginning from the start + * `index`. + * + * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + * + * The `found_index` is set to `-1`, if the needle was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringLPosEx(const ZyanStringView* haystack, + const ZyanStringView* needle, ZyanISize* found_index, ZyanUSize index, ZyanUSize count); + +/** + * Performs a case-insensitive search for the first occurrence of `needle` in the given + * `haystack` starting from the left. + * + * @param haystack The string to search in. + * @param needle The sub-string to search for. + * @param found_index A pointer to a variable that receives the index of the first occurrence of + * `needle`. + * + * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + * + * The `found_index` is set to `-1`, if the needle was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringLPosI(const ZyanStringView* haystack, + const ZyanStringView* needle, ZyanISize* found_index); + +/** + * Performs a case-insensitive search for the first occurrence of `needle` in the given + * `haystack` starting from the left. + * + * @param haystack The string to search in. + * @param needle The sub-string to search for. + * @param found_index A pointer to a variable that receives the index of the first occurrence of + * `needle`. + * @param index The start index. + * @param count The maximum number of characters to iterate, beginning from the start + * `index`. + * + * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + * + * The `found_index` is set to `-1`, if the needle was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringLPosIEx(const ZyanStringView* haystack, + const ZyanStringView* needle, ZyanISize* found_index, ZyanUSize index, ZyanUSize count); + +/** + * Searches for the first occurrence of `needle` in the given `haystack` starting from the + * right. + * + * @param haystack The string to search in. + * @param needle The sub-string to search for. + * @param found_index A pointer to a variable that receives the index of the first occurrence of + * `needle`. + * + * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + * + * The `found_index` is set to `-1`, if the needle was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringRPos(const ZyanStringView* haystack, + const ZyanStringView* needle, ZyanISize* found_index); + +/** + * Searches for the first occurrence of `needle` in the given `haystack` starting from the + * right. + * + * @param haystack The string to search in. + * @param needle The sub-string to search for. + * @param found_index A pointer to a variable that receives the index of the first occurrence of + * `needle`. + * @param index The start index. + * @param count The maximum number of characters to iterate, beginning from the start + * `index`. + * + * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + * + * The `found_index` is set to `-1`, if the needle was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringRPosEx(const ZyanStringView* haystack, + const ZyanStringView* needle, ZyanISize* found_index, ZyanUSize index, ZyanUSize count); + +/** + * Performs a case-insensitive search for the first occurrence of `needle` in the given + * `haystack` starting from the right. + * + * @param haystack The string to search in. + * @param needle The sub-string to search for. + * @param found_index A pointer to a variable that receives the index of the first occurrence of + * `needle`. + * + * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + * + * The `found_index` is set to `-1`, if the needle was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringRPosI(const ZyanStringView* haystack, + const ZyanStringView* needle, ZyanISize* found_index); + +/** + * Performs a case-insensitive search for the first occurrence of `needle` in the given + * `haystack` starting from the right. + * + * @param haystack The string to search in. + * @param needle The sub-string to search for. + * @param found_index A pointer to a variable that receives the index of the first occurrence of + * `needle`. + * @param index The start index. + * @param count The maximum number of characters to iterate, beginning from the start + * `index`. + * + * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + * + * The `found_index` is set to `-1`, if the needle was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringRPosIEx(const ZyanStringView* haystack, + const ZyanStringView* needle, ZyanISize* found_index, ZyanUSize index, ZyanUSize count); + +/* ---------------------------------------------------------------------------------------------- */ +/* Comparing */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Compares two strings. + * + * @param s1 The first string + * @param s2 The second string. + * @param result Receives the comparison result. + * + * Values: + * - `result < 0` -> The first character that does not match has a lower value + * in `s1` than in `s2`. + * - `result == 0` -> The contents of both strings are equal. + * - `result > 0` -> The first character that does not match has a greater value + * in `s1` than in `s2`. + * + * @return `ZYAN_STATUS_TRUE`, if the strings are equal, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringCompare(const ZyanStringView* s1, const ZyanStringView* s2, + ZyanI32* result); + +/** + * Performs a case-insensitive comparison of two strings. + * + * @param s1 The first string + * @param s2 The second string. + * @param result Receives the comparison result. + * + * Values: + * - `result < 0` -> The first character that does not match has a lower value + * in `s1` than in `s2`. + * - `result == 0` -> The contents of both strings are equal. + * - `result > 0` -> The first character that does not match has a greater value + * in `s1` than in `s2`. + * + * @return `ZYAN_STATUS_TRUE`, if the strings are equal, `ZYAN_STATUS_FALSE`, if not, or another + * zyan status code, if an error occured. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringCompareI(const ZyanStringView* s1, const ZyanStringView* s2, + ZyanI32* result); + +/* ---------------------------------------------------------------------------------------------- */ +/* Case conversion */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Converts the given string to lowercase letters. + * + * @param string A pointer to the `ZyanString` instance. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringToLowerCase(ZyanString* string); + +/** + * Converts `count` characters of the given string to lowercase letters. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The start index. + * @param count The number of characters to convert, beginning from the start `index`. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringToLowerCaseEx(ZyanString* string, ZyanUSize index, + ZyanUSize count); + +/** + * Converts the given string to uppercase letters. + * + * @param string A pointer to the `ZyanString` instance. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringToUpperCase(ZyanString* string); + +/** + * Converts `count` characters of the given string to uppercase letters. + * + * @param string A pointer to the `ZyanString` instance. + * @param index The start index. + * @param count The number of characters to convert, beginning from the start `index`. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringToUpperCaseEx(ZyanString* string, ZyanUSize index, + ZyanUSize count); + +/* ---------------------------------------------------------------------------------------------- */ +/* Memory management */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Resizes the given `ZyanString` instance. + * + * @param string A pointer to the `ZyanString` instance. + * @param size The new size of the string. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringResize(ZyanString* string, ZyanUSize size); + +/** + * Changes the capacity of the given `ZyanString` instance. + * + * @param string A pointer to the `ZyanString` instance. + * @param capacity The new minimum capacity of the string. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringReserve(ZyanString* string, ZyanUSize capacity); + +/** + * Shrinks the capacity of the given string to match it's size. + * + * @param string A pointer to the `ZyanString` instance. + * + * @return A zyan status code. + * + * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified + * `ZyanString` instance. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringShrinkToFit(ZyanString* string); + +/* ---------------------------------------------------------------------------------------------- */ +/* Information */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the current capacity of the string. + * + * @param string A pointer to the `ZyanString` instance. + * @param capacity Receives the size of the string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringGetCapacity(const ZyanString* string, ZyanUSize* capacity); + +/** + * Returns the current size (number of characters) of the string (excluding the + * terminating zero character). + * + * @param string A pointer to the `ZyanString` instance. + * @param size Receives the size (number of characters) of the string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringGetSize(const ZyanString* string, ZyanUSize* size); + +/** + * Returns the C-style string of the given `ZyanString` instance. + * + * @param string A pointer to the `ZyanString` instance. + * @param value Receives a pointer to the C-style string. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanStringGetData(const ZyanString* string, const char** value); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif // ZYCORE_STRING_H diff --git a/src/Zycore/Types.h b/src/Zycore/Types.h new file mode 100644 index 0000000..74fe905 --- /dev/null +++ b/src/Zycore/Types.h @@ -0,0 +1,195 @@ +/*************************************************************************************************** + + Zyan Core Library (Zyan-C) + + 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 + * Includes and defines some default data types. + */ + +#ifndef ZYCORE_TYPES_H +#define ZYCORE_TYPES_H + +#include + +/* ============================================================================================== */ +/* Integer types */ +/* ============================================================================================== */ + +#if defined(ZYAN_NO_LIBC) || \ + (defined(ZYAN_MSVC) && defined(ZYAN_KERNEL)) // The WDK LibC lacks stdint.h. + // No LibC mode, use compiler built-in types / macros. +# if defined(ZYAN_MSVC) || defined(ZYAN_ICC) + typedef unsigned __int8 ZyanU8; + typedef unsigned __int16 ZyanU16; + typedef unsigned __int32 ZyanU32; + typedef unsigned __int64 ZyanU64; + typedef signed __int8 ZyanI8; + typedef signed __int16 ZyanI16; + typedef signed __int32 ZyanI32; + typedef signed __int64 ZyanI64; +# if _WIN64 + typedef ZyanU64 ZyanUSize; + typedef ZyanI64 ZyanISize; + typedef ZyanU64 ZyanUPointer; + typedef ZyanI64 ZyanIPointer; +# else + typedef ZyanU32 ZyanUSize; + typedef ZyanI32 ZyanISize; + typedef ZyanU32 ZyanUPointer; + typedef ZyanI32 ZyanIPointer; +# endif +# elif defined(ZYAN_GNUC) + typedef __UINT8_TYPE__ ZyanU8; + typedef __UINT16_TYPE__ ZyanU16; + typedef __UINT32_TYPE__ ZyanU32; + typedef __UINT64_TYPE__ ZyanU64; + typedef __INT8_TYPE__ ZyanI8; + typedef __INT16_TYPE__ ZyanI16; + typedef __INT32_TYPE__ ZyanI32; + typedef __INT64_TYPE__ ZyanI64; + typedef __SIZE_TYPE__ ZyanUSize; + typedef __PTRDIFF_TYPE__ ZyanISize; + typedef __UINTPTR_TYPE__ ZyanUPointer; + typedef __INTPTR_TYPE__ ZyanIPointer; +# else +# error "Unsupported compiler for no-libc mode." +# endif +#else + // If is LibC present, we use stdint types. +# include +# include + typedef uint8_t ZyanU8; + typedef uint16_t ZyanU16; + typedef uint32_t ZyanU32; + typedef uint64_t ZyanU64; + typedef int8_t ZyanI8; + typedef int16_t ZyanI16; + typedef int32_t ZyanI32; + typedef int64_t ZyanI64; + typedef size_t ZyanUSize; + typedef ptrdiff_t ZyanISize; + typedef uintptr_t ZyanUPointer; + typedef intptr_t ZyanIPointer; +#endif + +// Verify size assumptions. +ZYAN_STATIC_ASSERT(sizeof(ZyanU8 ) == 1 ); +ZYAN_STATIC_ASSERT(sizeof(ZyanU16 ) == 2 ); +ZYAN_STATIC_ASSERT(sizeof(ZyanU32 ) == 4 ); +ZYAN_STATIC_ASSERT(sizeof(ZyanU64 ) == 8 ); +ZYAN_STATIC_ASSERT(sizeof(ZyanI8 ) == 1 ); +ZYAN_STATIC_ASSERT(sizeof(ZyanI16 ) == 2 ); +ZYAN_STATIC_ASSERT(sizeof(ZyanI32 ) == 4 ); +ZYAN_STATIC_ASSERT(sizeof(ZyanI64 ) == 8 ); +ZYAN_STATIC_ASSERT(sizeof(ZyanUSize ) == sizeof(void*)); // TODO: This one is incorrect! +ZYAN_STATIC_ASSERT(sizeof(ZyanISize ) == sizeof(void*)); // TODO: This one is incorrect! +ZYAN_STATIC_ASSERT(sizeof(ZyanUPointer) == sizeof(void*)); +ZYAN_STATIC_ASSERT(sizeof(ZyanIPointer) == sizeof(void*)); + +// Verify signedness assumptions (relies on size checks above). +ZYAN_STATIC_ASSERT((ZyanI8 )-1 >> 1 < (ZyanI8 )((ZyanU8 )-1 >> 1)); +ZYAN_STATIC_ASSERT((ZyanI16)-1 >> 1 < (ZyanI16)((ZyanU16)-1 >> 1)); +ZYAN_STATIC_ASSERT((ZyanI32)-1 >> 1 < (ZyanI32)((ZyanU32)-1 >> 1)); +ZYAN_STATIC_ASSERT((ZyanI64)-1 >> 1 < (ZyanI64)((ZyanU64)-1 >> 1)); + +/* ============================================================================================== */ +/* Pointer */ +/* ============================================================================================== */ + +/** + * Defines the `ZyanVoidPointer` data-type. + */ +typedef char* ZyanVoidPointer; + +/** + * Defines the `ZyanConstVoidPointer` data-type. + */ +typedef const void* ZyanConstVoidPointer; + +#define ZYAN_NULL ((void*)0) + +/* ============================================================================================== */ +/* Logic types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Boolean */ +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYAN_FALSE 0 +#define ZYAN_TRUE 1 + +/** + * Defines the `ZyanBool` data-type. + * + * Represents a default boolean data-type where `0` is interpreted as `false` and all other values + * as `true`. + */ +typedef ZyanU8 ZyanBool; + +/* ---------------------------------------------------------------------------------------------- */ +/* Ternary */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanTernary` data-type. + * + * The `ZyanTernary` is a balanced ternary type that uses three truth values indicating `true`, + * `false` and an indeterminate third value. + */ +typedef ZyanI8 ZyanTernary; + +#define ZYAN_TERNARY_FALSE (-1) +#define ZYAN_TERNARY_UNKNOWN 0x00 +#define ZYAN_TERNARY_TRUE 0x01 + +/* ============================================================================================== */ +/* String types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* C-style strings */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZyanCharPointer` data-type. + * + * This type is most often used to represent null-terminated strings aka. C-style strings. + */ +typedef char* ZyanCharPointer; + +/** + * Defines the `ZyanConstCharPointer` data-type. + * + * This type is most often used to represent null-terminated strings aka. C-style strings. + */ +typedef const char* ZyanConstCharPointer; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#endif /* ZYCORE_TYPES_H */ diff --git a/src/Zycore/Vector.h b/src/Zycore/Vector.h new file mode 100644 index 0000000..47e728c --- /dev/null +++ b/src/Zycore/Vector.h @@ -0,0 +1,723 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * Implements the vector container class. + */ + +#ifndef ZYCORE_VECTOR_H +#define ZYCORE_VECTOR_H + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Constants */ +/* ============================================================================================== */ + +/** + * The initial minimum capacity (number of elements) for all dynamically allocated vector + * instances. + */ +#define ZYAN_VECTOR_MIN_CAPACITY 1 + +/** + * The default growth factor for all vector instances. + */ +#define ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR 2.00f + +/** + * The default shrink threshold for all vector instances. + */ +#define ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD 0.25f + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZyanVector` struct. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZyanVector_ +{ + /** + * The memory allocator. + */ + ZyanAllocator* allocator; + /** + * The growth factor. + */ + float growth_factor; + /** + * The shrink threshold. + */ + float shrink_threshold; + /** + * The current number of elements in the vector. + */ + ZyanUSize size; + /** + * The maximum capacity (number of elements). + */ + ZyanUSize capacity; + /** + * The size of a single element in bytes. + */ + ZyanUSize element_size; + /** + * The element destructor callback. + */ + ZyanMemberProcedure destructor; + /** + * The data pointer. + */ + void* data; +} ZyanVector; + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* General */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines an uninitialized `ZyanVector` instance. + */ +#define ZYAN_VECTOR_INITIALIZER \ + { \ + /* allocator */ ZYAN_NULL, \ + /* growth_factor */ 0.0f, \ + /* shrink_threshold */ 0.0f, \ + /* size */ 0, \ + /* capacity */ 0, \ + /* element_size */ 0, \ + /* destructor */ ZYAN_NULL, \ + /* data */ ZYAN_NULL \ + } + +/* ---------------------------------------------------------------------------------------------- */ +/* Helper macros */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the value of the element at the given `index`. + * + * @param type The desired value type. + * @param vector A pointer to the `ZyanVector` instance. + * @param index The element index. + * + * @result The value of the desired element in the vector. + * + * Note that this function is unsafe and might dereference a null-pointer. + */ +#ifdef __cplusplus +#define ZYAN_VECTOR_GET(type, vector, index) \ + (*reinterpret_cast(ZyanVectorGet(vector, index))) +#else +#define ZYAN_VECTOR_GET(type, vector, index) \ + (*(const type*)ZyanVectorGet(vector, index)) +#endif + +/** + * Loops through all elements of the vector. + * + * @param type The desired value type. + * @param vector A pointer to the `ZyanVector` instance. + * @param item_name The name of the iterator item. + * @param body The body to execute for each item in the vector. + */ +#define ZYAN_VECTOR_FOREACH(type, vector, item_name, body) \ + { \ + const ZyanUSize ZYAN_MACRO_CONCAT_EXPAND(size_d50d3303, item_name) = (vector)->size; \ + for (ZyanUSize ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name) = 0; \ + ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name) < \ + ZYAN_MACRO_CONCAT_EXPAND(size_d50d3303, item_name); \ + ++ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name)) \ + { \ + const type item_name = ZYAN_VECTOR_GET(type, vector, \ + ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name)); \ + body \ + } \ + } + +/** + * Loops through all elements of the vector. + * + * @param type The desired value type. + * @param vector A pointer to the `ZyanVector` instance. + * @param item_name The name of the iterator item. + * @param body The body to execute for each item in the vector. + */ +#define ZYAN_VECTOR_FOREACH_MUTABLE(type, vector, item_name, body) \ + { \ + const ZyanUSize ZYAN_MACRO_CONCAT_EXPAND(size_d50d3303, item_name) = (vector)->size; \ + for (ZyanUSize ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name) = 0; \ + ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name) < \ + ZYAN_MACRO_CONCAT_EXPAND(size_d50d3303, item_name); \ + ++ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name)) \ + { \ + type* const item_name = ZyanVectorGetMutable(vector, \ + ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name)); \ + body \ + } \ + } + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Constructor and destructor */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Initializes the given `ZyanVector` instance. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element_size The size of a single element in bytes. + * @param capacity The initial capacity (number of elements). + * @param destructor A destructor callback that is invoked every time an item is deleted, or + * `ZYAN_NULL` if not needed. + * + * @return A zyan status code. + * + * The memory for the vector elements is dynamically allocated by the default allocator using the + * default growth factor of `2.0f` and the default shrink threshold of `0.25f`. + * + * Finalization with `ZyanVectorDestroy` is required for all instances created by this function. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanVectorInit(ZyanVector* vector, + ZyanUSize element_size, ZyanUSize capacity, ZyanMemberProcedure destructor); + +#endif // ZYAN_NO_LIBC + +/** + * Initializes the given `ZyanVector` instance and sets a custom `allocator` and memory + * allocation/deallocation parameters. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element_size The size of a single element in bytes. + * @param capacity The initial capacity (number of elements). + * @param destructor A destructor callback that is invoked every time an item is deleted, + * or `ZYAN_NULL` if not needed. + * @param allocator A pointer to a `ZyanAllocator` instance. + * @param growth_factor The growth factor (from `1.0f` to `x.xf`). + * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). + * + * @return A zyan status code. + * + * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables + * dynamic shrinking. + * + * Finalization with `ZyanVectorDestroy` is required for all instances created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorInitEx(ZyanVector* vector, ZyanUSize element_size, + ZyanUSize capacity, ZyanMemberProcedure destructor, ZyanAllocator* allocator, + float growth_factor, float shrink_threshold); + +/** + * Initializes the given `ZyanVector` instance and configures it to use a custom user + * defined buffer with a fixed size. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element_size The size of a single element in bytes. + * @param buffer A pointer to the buffer that is used as storage for the elements. + * @param capacity The maximum capacity (number of elements) of the buffer. + * @param destructor A destructor callback that is invoked every time an item is deleted, or + * `ZYAN_NULL` if not needed. + * + * @return A zyan status code. + * + * Finalization is not required for instances created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorInitCustomBuffer(ZyanVector* vector, ZyanUSize element_size, + void* buffer, ZyanUSize capacity, ZyanMemberProcedure destructor); + +/** + * Destroys the given `ZyanVector` instance. + * + * @param vector A pointer to the `ZyanVector` instance.. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorDestroy(ZyanVector* vector); + +/* ---------------------------------------------------------------------------------------------- */ +/* Duplication */ +/* ---------------------------------------------------------------------------------------------- */ + +#ifndef ZYAN_NO_LIBC + +/** + * Initializes a new `ZyanVector` instance by duplicating an existing vector. + * + * @param destination A pointer to the (uninitialized) destination `ZyanVector` instance. + * @param source A pointer to the source vector. + * @param capacity The initial capacity (number of elements). + * + * This value is automatically adjusted to the size of the source vector, if + * a smaller value was passed. + * + * @return A zyan status code. + * + * The memory for the vector is dynamically allocated by the default allocator using the default + * growth factor of `2.0f` and the default shrink threshold of `0.25f`. + * + * Finalization with `ZyanVectorDestroy` is required for all instances created by this function. + */ +ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanVectorDuplicate(ZyanVector* destination, + const ZyanVector* source, ZyanUSize capacity); + +#endif // ZYAN_NO_LIBC + +/** + * Initializes a new `ZyanVector` instance by duplicating an existing vector and sets a + * custom `allocator` and memory allocation/deallocation parameters. + * + * @param destination A pointer to the (uninitialized) destination `ZyanVector` instance. + * @param source A pointer to the source vector. + * @param capacity The initial capacity (number of elements). + + * This value is automatically adjusted to the size of the source + * vector, if a smaller value was passed. + * @param allocator A pointer to a `ZyanAllocator` instance. + * @param growth_factor The growth factor (from `1.0f` to `x.xf`). + * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). + * + * @return A zyan status code. + * + * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables + * dynamic shrinking. + * + * Finalization with `ZyanVectorDestroy` is required for all instances created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorDuplicateEx(ZyanVector* destination, const ZyanVector* source, + ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor, float shrink_threshold); + +/** + * Initializes a new `ZyanVector` instance by duplicating an existing vector and + * configures it to use a custom user defined buffer with a fixed size. + * + * @param destination A pointer to the (uninitialized) destination `ZyanVector` instance. + * @param source A pointer to the source vector. + * @param buffer A pointer to the buffer that is used as storage for the elements. + * @param capacity The maximum capacity (number of elements) of the buffer. + + * This function will fail, if the capacity of the buffer is less than the + * size of the source vector. + * + * @return A zyan status code. + * + * Finalization is not required for instances created by this function. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorDuplicateCustomBuffer(ZyanVector* destination, + const ZyanVector* source, void* buffer, ZyanUSize capacity); + +/* ---------------------------------------------------------------------------------------------- */ +/* Element access */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns a constant pointer to the element at the given `index`. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The element index. + * + * @return A constant pointer to the desired element in the vector or `ZYAN_NULL`, if an error + * occured. + * + * Note that the returned pointer might get invalid when the vector is resized by either a manual + * call to the memory-management functions or implicitly by inserting or removing elements. + * + * Take a look at `ZyanVectorGetPointer` instead, if you need a function that returns a zyan status + * code. + */ +ZYCORE_EXPORT const void* ZyanVectorGet(const ZyanVector* vector, ZyanUSize index); + +/** + * Returns a mutable pointer to the element at the given `index`. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The element index. + * + * @return A mutable pointer to the desired element in the vector or `ZYAN_NULL`, if an error + * occured. + * + * Note that the returned pointer might get invalid when the vector is resized by either a manual + * call to the memory-management functions or implicitly by inserting or removing elements. + * + * Take a look at `ZyanVectorGetPointerMutable` instead, if you need a function that returns a + * zyan status code. + */ +ZYCORE_EXPORT void* ZyanVectorGetMutable(const ZyanVector* vector, ZyanUSize index); + +/** + * Returns a constant pointer to the element at the given `index`. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The element index. + * @param value Receives a constant pointer to the desired element in the vector. + * + * Note that the returned pointer might get invalid when the vector is resized by either a manual + * call to the memory-management functions or implicitly by inserting or removing elements. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorGetPointer(const ZyanVector* vector, ZyanUSize index, + const void** value); + +/** + * Returns a mutable pointer to the element at the given `index`. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The element index. + * @param value Receives a mutable pointer to the desired element in the vector. + * + * Note that the returned pointer might get invalid when the vector is resized by either a manual + * call to the memory-management functions or implicitly by inserting or removing elements. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorGetPointerMutable(const ZyanVector* vector, ZyanUSize index, + void** value); + +/** + * Assigns a new value to the element at the given `index`. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The value index. + * @param value The value to assign. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorSet(ZyanVector* vector, ZyanUSize index, + const void* value); + +/* ---------------------------------------------------------------------------------------------- */ +/* Insertion */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Adds a new `element` to the end of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element A pointer to the element to add. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorPushBack(ZyanVector* vector, const void* element); + +/** + * Inserts an `element` at the given `index` of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The insert index. + * @param element A pointer to the element to insert. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorInsert(ZyanVector* vector, ZyanUSize index, + const void* element); + +/** + * Inserts multiple `elements` at the given `index` of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The insert index. + * @param elements A pointer to the first element. + * @param count The number of elements to insert. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorInsertRange(ZyanVector* vector, ZyanUSize index, + const void* elements, ZyanUSize count); + +/** + * Constructs an `element` in-place at the end of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element Receives a pointer to the new element. + * @param constructor The constructor callback or `ZYAN_NULL`. The new element will be in + * undefined state, if no constructor was passed. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorEmplace(ZyanVector* vector, void** element, + ZyanMemberFunction constructor); + +/** + * Constructs an `element` in-place and inserts it at the given `index` of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The insert index. + * @param element Receives a pointer to the new element. + * @param constructor The constructor callback or `ZYAN_NULL`. The new element will be in + * undefined state, if no constructor was passed. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorEmplaceEx(ZyanVector* vector, ZyanUSize index, + void** element, ZyanMemberFunction constructor); + +/* ---------------------------------------------------------------------------------------------- */ +/* Utils */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Swaps the element at `index_first` with the element at `index_second`. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index_first The index of the first element. + * @param index_second The index of the second element. + * + * @return A zyan status code. + * + * This function requires the vector to have spare capacity for one temporary element. Call + * `ZyanVectorReserve` before this function to increase capacity, if needed. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorSwapElements(ZyanVector* vector, ZyanUSize index_first, + ZyanUSize index_second); + +/* ---------------------------------------------------------------------------------------------- */ +/* Deletion */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Deletes the element at the given `index` of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The element index. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorDelete(ZyanVector* vector, ZyanUSize index); + +/** + * Deletes multiple elements from the given vector, starting at `index`. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param index The index of the first element to delete. + * @param count The number of elements to delete. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorDeleteRange(ZyanVector* vector, ZyanUSize index, + ZyanUSize count); + +/** + * Removes the last element of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorPopBack(ZyanVector* vector); + +/** + * Erases all elements of the given vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorClear(ZyanVector* vector); + +/* ---------------------------------------------------------------------------------------------- */ +/* Searching */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Sequentially searches for the first occurrence of `element` in the given vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element A pointer to the element to search for. + * @param found_index A pointer to a variable that receives the index of the found element. + * @param comparison The comparison function to use. + * + * @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic + * zyan status code if an error occured. + * + * The `found_index` is set to `-1`, if the element was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorFind(const ZyanVector* vector, const void* element, + ZyanISize* found_index, ZyanEqualityComparison comparison); + +/** + * Sequentially searches for the first occurrence of `element` in the given vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element A pointer to the element to search for. + * @param found_index A pointer to a variable that receives the index of the found element. + * @param comparison The comparison function to use. + * @param index The start index. + * @param count The maximum number of elements to iterate, beginning from the start `index`. + * + * @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic + * zyan status code if an error occured. + * + * The `found_index` is set to `-1`, if the element was not found. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorFindEx(const ZyanVector* vector, const void* element, + ZyanISize* found_index, ZyanEqualityComparison comparison, ZyanUSize index, ZyanUSize count); + +/** + * Searches for the first occurrence of `element` in the given vector using a binary- + * search algorithm. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element A pointer to the element to search for. + * @param found_index A pointer to a variable that receives the index of the found element. + * @param comparison The comparison function to use. + * + * @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic + * zyan status code if an error occured. + * + * If found, `found_index` contains the zero-based index of `element`. If not found, `found_index` + * contains the index of the first entry larger than `element`. + * + * This function requires all elements in the vector to be strictly ordered (sorted). + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorBinarySearch(const ZyanVector* vector, const void* element, + ZyanUSize* found_index, ZyanComparison comparison); + +/** + * Searches for the first occurrence of `element` in the given vector using a binary- + * search algorithm. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param element A pointer to the element to search for. + * @param found_index A pointer to a variable that receives the index of the found element. + * @param comparison The comparison function to use. + * @param index The start index. + * @param count The maximum number of elements to iterate, beginning from the start `index`. + * + * @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic + * zyan status code if an error occured. + * + * If found, `found_index` contains the zero-based index of `element`. If not found, `found_index` + * contains the index of the first entry larger than `element`. + * + * This function requires all elements in the vector to be strictly ordered (sorted). + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorBinarySearchEx(const ZyanVector* vector, const void* element, + ZyanUSize* found_index, ZyanComparison comparison, ZyanUSize index, ZyanUSize count); + +/* ---------------------------------------------------------------------------------------------- */ +/* Memory management */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Resizes the given `ZyanVector` instance. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param size The new size of the vector. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorResize(ZyanVector* vector, ZyanUSize size); + +/** + * Resizes the given `ZyanVector` instance. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param size The new size of the vector. + * @param initializer A pointer to a value to be used as initializer for new items. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorResizeEx(ZyanVector* vector, ZyanUSize size, + const void* initializer); + +/** + * Changes the capacity of the given `ZyanVector` instance. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param capacity The new minimum capacity of the vector. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorReserve(ZyanVector* vector, ZyanUSize capacity); + +/** + * Shrinks the capacity of the given vector to match it's size. + * + * @param vector A pointer to the `ZyanVector` instance. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorShrinkToFit(ZyanVector* vector); + +/* ---------------------------------------------------------------------------------------------- */ +/* Information */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the current capacity of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param capacity Receives the size of the vector. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorGetCapacity(const ZyanVector* vector, ZyanUSize* capacity); + +/** + * Returns the current size of the vector. + * + * @param vector A pointer to the `ZyanVector` instance. + * @param size Receives the size of the vector. + * + * @return A zyan status code. + */ +ZYCORE_EXPORT ZyanStatus ZyanVectorGetSize(const ZyanVector* vector, ZyanUSize* size); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_VECTOR_H */ diff --git a/src/Zycore/Zycore.h b/src/Zycore/Zycore.h new file mode 100644 index 0000000..fba30f7 --- /dev/null +++ b/src/Zycore/Zycore.h @@ -0,0 +1,111 @@ +/*************************************************************************************************** + + Zyan Core Library (Zycore-C) + + 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. + +***************************************************************************************************/ + +/** + * @file + * Master include file, including everything else. + */ + +#ifndef ZYCORE_H +#define ZYCORE_H + +#include +#include + +// TODO: + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Constants */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * A macro that defines the zycore version. + */ +#define ZYCORE_VERSION (ZyanU64)0x0001000000000000 + +/* ---------------------------------------------------------------------------------------------- */ +/* Helper macros */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Extracts the major-part of the zycore version. + * + * @param version The zycore version value + */ +#define ZYCORE_VERSION_MAJOR(version_t) (ZyanU16)((version_t & 0xFFFF000000000000) >> 48) + +/** + * Extracts the minor-part of the zycore version. + * + * @param version The zycore version value + */ +#define ZYCORE_VERSION_MINOR(version_t) (ZyanU16)((version_t & 0x0000FFFF00000000) >> 32) + +/** + * Extracts the patch-part of the zycore version. + * + * @param version The zycore version value + */ +#define ZYCORE_VERSION_PATCH(version_t) (ZyanU16)((version_t & 0x00000000FFFF0000) >> 16) + +/** + * Extracts the build-part of the zycore version. + * + * @param version The zycore version value + */ +#define ZYCORE_VERSION_BUILD(version_t) (ZyanU16)(version_t & 0x000000000000FFFF) + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * Returns the zycore version. + * + * @return The zycore version. + * + * Use the macros provided in this file to extract the major, minor, patch and build part from the + * returned version value. + */ +ZYCORE_EXPORT ZyanU64 ZycoreGetVersion(void); + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYCORE_H */ diff --git a/src/ZycoreExportConfig.h b/src/ZycoreExportConfig.h new file mode 100644 index 0000000..f050d37 --- /dev/null +++ b/src/ZycoreExportConfig.h @@ -0,0 +1,42 @@ + +#ifndef ZYCORE_EXPORT_H +#define ZYCORE_EXPORT_H + +#ifdef ZYCORE_STATIC_DEFINE +# define ZYCORE_EXPORT +# define ZYCORE_NO_EXPORT +#else +# ifndef ZYCORE_EXPORT +# ifdef Zycore_EXPORTS + /* We are building this library */ +# define ZYCORE_EXPORT __declspec(dllexport) +# else + /* We are using this library */ +# define ZYCORE_EXPORT __declspec(dllimport) +# endif +# endif + +# ifndef ZYCORE_NO_EXPORT +# define ZYCORE_NO_EXPORT +# endif +#endif + +#ifndef ZYCORE_DEPRECATED +# define ZYCORE_DEPRECATED __declspec(deprecated) +#endif + +#ifndef ZYCORE_DEPRECATED_EXPORT +# define ZYCORE_DEPRECATED_EXPORT ZYCORE_EXPORT ZYCORE_DEPRECATED +#endif + +#ifndef ZYCORE_DEPRECATED_NO_EXPORT +# define ZYCORE_DEPRECATED_NO_EXPORT ZYCORE_NO_EXPORT ZYCORE_DEPRECATED +#endif + +#if 0 /* DEFINE_NO_DEPRECATED */ +# ifndef ZYCORE_NO_DEPRECATED +# define ZYCORE_NO_DEPRECATED +# endif +#endif + +#endif /* ZYCORE_EXPORT_H */ diff --git a/src/Zydis/Decoder.h b/src/Zydis/Decoder.h new file mode 100644 index 0000000..8cfbb0c --- /dev/null +++ b/src/Zydis/Decoder.h @@ -0,0 +1,237 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Functions for decoding instructions. + */ + +#ifndef ZYDIS_DECODER_H +#define ZYDIS_DECODER_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Decoder mode */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisDecoderMode` enum. + */ +typedef enum ZydisDecoderMode_ +{ + /** + * Enables minimal instruction decoding without semantic analysis. + * + * This mode provides access to the mnemonic, the instruction-length, the effective + * operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`) + * and all of the information in the `raw` field of the `ZydisDecodedInstruction` struct. + * + * Operands, most attributes and other specific information (like `AVX` info) are not + * accessible in this mode. + * + * This mode is NOT enabled by default. + */ + ZYDIS_DECODER_MODE_MINIMAL, + /** + * Enables the `AMD`-branch mode. + * + * Intel ignores the operand-size override-prefix (`0x66`) for all branches with 32-bit + * immediates and forces the operand-size of the instruction to 64-bit in 64-bit mode. + * In `AMD`-branch mode `0x66` is not ignored and changes the operand-size and the size of the + * immediate to 16-bit. + * + * This mode is NOT enabled by default. + */ + ZYDIS_DECODER_MODE_AMD_BRANCHES, + /** + * Enables `KNC` compatibility-mode. + * + * `KNC` and `KNL+` chips are sharing opcodes and encodings for some mask-related instructions. + * Enable this mode to use the old `KNC` specifications (different mnemonics, operands, ..). + * + * This mode is NOT enabled by default. + */ + ZYDIS_DECODER_MODE_KNC, + /** + * Enables the `MPX` mode. + * + * The `MPX` isa-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ + ZYDIS_DECODER_MODE_MPX, + /** + * Enables the `CET` mode. + * + * The `CET` isa-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ + ZYDIS_DECODER_MODE_CET, + /** + * Enables the `LZCNT` mode. + * + * The `LZCNT` isa-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ + ZYDIS_DECODER_MODE_LZCNT, + /** + * Enables the `TZCNT` mode. + * + * The `TZCNT` isa-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ + ZYDIS_DECODER_MODE_TZCNT, + /** + * Enables the `WBNOINVD` mode. + * + * The `WBINVD` instruction is interpreted as `WBNOINVD` on ICL chips, if a `F3` prefix is + * used. + * + * This mode is disabled by default. + */ + ZYDIS_DECODER_MODE_WBNOINVD, + /** + * Enables the `CLDEMOTE` mode. + * + * The `CLDEMOTE` isa-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ + ZYDIS_DECODER_MODE_CLDEMOTE, + + /** + * Maximum value of this enum. + */ + ZYDIS_DECODER_MODE_MAX_VALUE = ZYDIS_DECODER_MODE_CLDEMOTE, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_DECODER_MODE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_DECODER_MODE_MAX_VALUE) +} ZydisDecoderMode; + +/* ---------------------------------------------------------------------------------------------- */ +/* Decoder struct */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisDecoder` struct. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZydisDecoder_ +{ + /** + * The machine mode. + */ + ZydisMachineMode machine_mode; + /** + * The address width. + */ + ZydisAddressWidth address_width; + /** + * The decoder mode array. + */ + ZyanBool decoder_mode[ZYDIS_DECODER_MODE_MAX_VALUE + 1]; +} ZydisDecoder; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * @addtogroup decoder Decoder + * Functions allowing decoding of instruction bytes to a machine interpretable struct. + * @{ + */ + +/** + * Initializes the given `ZydisDecoder` instance. + * + * @param decoder A pointer to the `ZydisDecoder` instance. + * @param machine_mode The machine mode. + * @param address_width The address width. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machine_mode, + ZydisAddressWidth address_width); + +/** + * Enables or disables the specified decoder-mode. + * + * @param decoder A pointer to the `ZydisDecoder` instance. + * @param mode The decoder mode. + * @param enabled `ZYAN_TRUE` to enable, or `ZYAN_FALSE` to disable the specified decoder-mode. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisDecoderEnableMode(ZydisDecoder* decoder, ZydisDecoderMode mode, + ZyanBool enabled); + +/** + * Decodes the instruction in the given input `buffer`. + * + * @param decoder A pointer to the `ZydisDecoder` instance. + * @param buffer A pointer to the input buffer. + * @param length The length of the input buffer. Note that this can be bigger than the + * actual size of the instruction -- you don't have to know the size up + * front. This length is merely used to prevent Zydis from doing + * out-of-bounds reads on your buffer. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct, that receives the + * details about the decoded instruction. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, + const void* buffer, ZyanUSize length, ZydisDecodedInstruction* instruction); + +/** @} */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_DECODER_H */ diff --git a/src/Zydis/DecoderTypes.h b/src/Zydis/DecoderTypes.h new file mode 100644 index 0000000..45f5300 --- /dev/null +++ b/src/Zydis/DecoderTypes.h @@ -0,0 +1,1528 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Defines the basic `ZydisDecodedInstruction` and `ZydisDecodedOperand` structs. + */ + +#ifndef ZYDIS_INSTRUCTIONINFO_H +#define ZYDIS_INSTRUCTIONINFO_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Decoded operand */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Memory type */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisMemoryOperandType` enum. + */ +typedef enum ZydisMemoryOperandType_ +{ + ZYDIS_MEMOP_TYPE_INVALID, + /** + * Normal memory operand. + */ + ZYDIS_MEMOP_TYPE_MEM, + /** + * The memory operand is only used for address-generation. No real memory-access is + * caused. + */ + ZYDIS_MEMOP_TYPE_AGEN, + /** + * A memory operand using `SIB` addressing form, where the index register is not used + * in address calculation and scale is ignored. No real memory-access is caused. + */ + ZYDIS_MEMOP_TYPE_MIB, + + /** + * Maximum value of this enum. + */ + ZYDIS_MEMOP_TYPE_MAX_VALUE = ZYDIS_MEMOP_TYPE_MIB, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MEMOP_TYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MEMOP_TYPE_MAX_VALUE) +} ZydisMemoryOperandType; + +/* ---------------------------------------------------------------------------------------------- */ +/* Decoded operand */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisDecodedOperand` struct. + */ +typedef struct ZydisDecodedOperand_ +{ + /** + * The operand-id. + */ + ZyanU8 id; + /** + * The type of the operand. + */ + ZydisOperandType type; + /** + * The visibility of the operand. + */ + ZydisOperandVisibility visibility; + /** + * The operand-actions. + */ + ZydisOperandActions actions; + /** + * The operand-encoding. + */ + ZydisOperandEncoding encoding; + /** + * The logical size of the operand (in bits). + */ + ZyanU16 size; + /** + * The element-type. + */ + ZydisElementType element_type; + /** + * The size of a single element. + */ + ZydisElementSize element_size; + /** + * The number of elements. + */ + ZyanU16 element_count; + /** + * Extended info for register-operands. + */ + struct ZydisDecodedOperandReg_ + { + /** + * The register value. + */ + ZydisRegister value; + // TODO: AVX512_4VNNIW MULTISOURCE registers + } reg; + /** + * Extended info for memory-operands. + */ + struct ZydisDecodedOperandMem_ + { + /** + * The type of the memory operand. + */ + ZydisMemoryOperandType type; + /** + * The segment register. + */ + ZydisRegister segment; + /** + * The base register. + */ + ZydisRegister base; + /** + * The index register. + */ + ZydisRegister index; + /** + * The scale factor. + */ + ZyanU8 scale; + /** + * Extended info for memory-operands with displacement. + */ + struct ZydisDecodedOperandMemDisp_ + { + /** + * Signals, if the displacement value is used. + */ + ZyanBool has_displacement; + /** + * The displacement value + */ + ZyanI64 value; + } disp; + } mem; + /** + * Extended info for pointer-operands. + */ + struct ZydisDecodedOperandPtr_ + { + ZyanU16 segment; + ZyanU32 offset; + } ptr; + /** + * Extended info for immediate-operands. + */ + struct ZydisDecodedOperandImm_ + { + /** + * Signals, if the immediate value is signed. + */ + ZyanBool is_signed; + /** + * Signals, if the immediate value contains a relative offset. You can use + * `ZydisCalcAbsoluteAddress` to determine the absolute address value. + */ + ZyanBool is_relative; + /** + * The immediate value. + */ + union ZydisDecodedOperandImmValue_ + { + ZyanU64 u; + ZyanI64 s; + } value; + } imm; +} ZydisDecodedOperand; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Decoded instruction */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Instruction attributes */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisInstructionAttributes` data-type. + */ +typedef ZyanU64 ZydisInstructionAttributes; + +/** + * The instruction has the `ModRM` byte. + */ +#define ZYDIS_ATTRIB_HAS_MODRM 0x0000000000000001 // (1 << 0) +/** + * The instruction has the `SIB` byte. + */ +#define ZYDIS_ATTRIB_HAS_SIB 0x0000000000000002 // (1 << 1) +/** + * The instruction has the `REX` prefix. + */ +#define ZYDIS_ATTRIB_HAS_REX 0x0000000000000004 // (1 << 2) +/** + * The instruction has the `XOP` prefix. + */ +#define ZYDIS_ATTRIB_HAS_XOP 0x0000000000000008 // (1 << 3) +/** + * The instruction has the `VEX` prefix. + */ +#define ZYDIS_ATTRIB_HAS_VEX 0x0000000000000010 // (1 << 4) +/** + * The instruction has the `EVEX` prefix. + */ +#define ZYDIS_ATTRIB_HAS_EVEX 0x0000000000000020 // (1 << 5) +/** + * The instruction has the `MVEX` prefix. + */ +#define ZYDIS_ATTRIB_HAS_MVEX 0x0000000000000040 // (1 << 6) +/** + * The instruction has one or more operands with position-relative offsets. + */ +#define ZYDIS_ATTRIB_IS_RELATIVE 0x0000000000000080 // (1 << 7) +/** + * The instruction is privileged. + * + * Privileged instructions are any instructions that require a current ring level below 3. + */ +#define ZYDIS_ATTRIB_IS_PRIVILEGED 0x0000000000000100 // (1 << 8) + +/** + * The instruction accesses one or more CPU-flags. + */ +#define ZYDIS_ATTRIB_CPUFLAG_ACCESS 0x0000001000000000 // (1 << 36) // TODO: rebase + +/** + * The instruction may conditionally read the general CPU state. + */ +#define ZYDIS_ATTRIB_CPU_STATE_CR 0x0000002000000000 // (1 << 37) // TODO: rebase +/** + * The instruction may conditionally write the general CPU state. + */ +#define ZYDIS_ATTRIB_CPU_STATE_CW 0x0000004000000000 // (1 << 38) // TODO: rebase +/** + * The instruction may conditionally read the FPU state (X87, MMX). + */ +#define ZYDIS_ATTRIB_FPU_STATE_CR 0x0000008000000000 // (1 << 39) // TODO: rebase +/** + * The instruction may conditionally write the FPU state (X87, MMX). + */ +#define ZYDIS_ATTRIB_FPU_STATE_CW 0x0000010000000000 // (1 << 40) // TODO: rebase +/** + * The instruction may conditionally read the XMM state (AVX, AVX2, AVX-512). + */ +#define ZYDIS_ATTRIB_XMM_STATE_CR 0x0000020000000000 // (1 << 41) // TODO: rebase +/** + * The instruction may conditionally write the XMM state (AVX, AVX2, AVX-512). + */ +#define ZYDIS_ATTRIB_XMM_STATE_CW 0x0000040000000000 // (1 << 42) // TODO: rebase + +/** + * The instruction accepts the `LOCK` prefix (`0xF0`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_LOCK 0x0000000000000200 // (1 << 9) +/** + * The instruction accepts the `REP` prefix (`0xF3`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_REP 0x0000000000000400 // (1 << 10) +/** + * The instruction accepts the `REPE`/`REPZ` prefix (`0xF3`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_REPE 0x0000000000000800 // (1 << 11) +/** + * The instruction accepts the `REPE`/`REPZ` prefix (`0xF3`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_REPZ 0x0000000000000800 // (1 << 11) +/** + * The instruction accepts the `REPNE`/`REPNZ` prefix (`0xF2`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_REPNE 0x0000000000001000 // (1 << 12) +/** + * The instruction accepts the `REPNE`/`REPNZ` prefix (`0xF2`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_REPNZ 0x0000000000001000 // (1 << 12) +/** + * The instruction accepts the `BND` prefix (`0xF2`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_BND 0x0000000000002000 // (1 << 13) +/** + * The instruction accepts the `XACQUIRE` prefix (`0xF2`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_XACQUIRE 0x0000000000004000 // (1 << 14) +/** + * The instruction accepts the `XRELEASE` prefix (`0xF3`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_XRELEASE 0x0000000000008000 // (1 << 15) +/** + * The instruction accepts the `XACQUIRE`/`XRELEASE` prefixes (`0xF2`, `0xF3`) + * without the `LOCK` prefix (`0x0F`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_HLE_WITHOUT_LOCK 0x0000000000010000 // (1 << 16) +/** + * The instruction accepts branch hints (0x2E, 0x3E). + */ +#define ZYDIS_ATTRIB_ACCEPTS_BRANCH_HINTS 0x0000000000020000 // (1 << 17) +/** + * The instruction accepts segment prefixes (`0x2E`, `0x36`, `0x3E`, `0x26`, + * `0x64`, `0x65`). + */ +#define ZYDIS_ATTRIB_ACCEPTS_SEGMENT 0x0000000000040000 // (1 << 18) +/** + * The instruction has the `LOCK` prefix (`0xF0`). + */ +#define ZYDIS_ATTRIB_HAS_LOCK 0x0000000000080000 // (1 << 19) +/** + * The instruction has the `REP` prefix (`0xF3`). + */ +#define ZYDIS_ATTRIB_HAS_REP 0x0000000000100000 // (1 << 20) +/** + * The instruction has the `REPE`/`REPZ` prefix (`0xF3`). + */ +#define ZYDIS_ATTRIB_HAS_REPE 0x0000000000200000 // (1 << 21) +/** + * The instruction has the `REPE`/`REPZ` prefix (`0xF3`). + */ +#define ZYDIS_ATTRIB_HAS_REPZ 0x0000000000200000 // (1 << 21) +/** + * The instruction has the `REPNE`/`REPNZ` prefix (`0xF2`). + */ +#define ZYDIS_ATTRIB_HAS_REPNE 0x0000000000400000 // (1 << 22) +/** + * The instruction has the `REPNE`/`REPNZ` prefix (`0xF2`). + */ +#define ZYDIS_ATTRIB_HAS_REPNZ 0x0000000000400000 // (1 << 22) +/** + * The instruction has the `BND` prefix (`0xF2`). + */ +#define ZYDIS_ATTRIB_HAS_BND 0x0000000000800000 // (1 << 23) +/** + * The instruction has the `XACQUIRE` prefix (`0xF2`). + */ +#define ZYDIS_ATTRIB_HAS_XACQUIRE 0x0000000001000000 // (1 << 24) +/** + * The instruction has the `XRELEASE` prefix (`0xF3`). + */ +#define ZYDIS_ATTRIB_HAS_XRELEASE 0x0000000002000000 // (1 << 25) +/** + * The instruction has the branch-not-taken hint (`0x2E`). + */ +#define ZYDIS_ATTRIB_HAS_BRANCH_NOT_TAKEN 0x0000000004000000 // (1 << 26) +/** + * The instruction has the branch-taken hint (`0x3E`). + */ +#define ZYDIS_ATTRIB_HAS_BRANCH_TAKEN 0x0000000008000000 // (1 << 27) +/** + * The instruction has a segment modifier. + */ +#define ZYDIS_ATTRIB_HAS_SEGMENT 0x00000003F0000000 +/** + * The instruction has the `CS` segment modifier (`0x2E`). + */ +#define ZYDIS_ATTRIB_HAS_SEGMENT_CS 0x0000000010000000 // (1 << 28) +/** + * The instruction has the `SS` segment modifier (`0x36`). + */ +#define ZYDIS_ATTRIB_HAS_SEGMENT_SS 0x0000000020000000 // (1 << 29) +/** + * The instruction has the `DS` segment modifier (`0x3E`). + */ +#define ZYDIS_ATTRIB_HAS_SEGMENT_DS 0x0000000040000000 // (1 << 30) +/** + * The instruction has the `ES` segment modifier (`0x26`). + */ +#define ZYDIS_ATTRIB_HAS_SEGMENT_ES 0x0000000080000000 // (1 << 31) +/** + * The instruction has the `FS` segment modifier (`0x64`). + */ +#define ZYDIS_ATTRIB_HAS_SEGMENT_FS 0x0000000100000000 // (1 << 32) +/** + * The instruction has the `GS` segment modifier (`0x65`). + */ +#define ZYDIS_ATTRIB_HAS_SEGMENT_GS 0x0000000200000000 // (1 << 33) +/** + * The instruction has the operand-size override prefix (`0x66`). + */ +#define ZYDIS_ATTRIB_HAS_OPERANDSIZE 0x0000000400000000 // (1 << 34) // TODO: rename +/** + * The instruction has the address-size override prefix (`0x67`). + */ +#define ZYDIS_ATTRIB_HAS_ADDRESSSIZE 0x0000000800000000 // (1 << 35) // TODO: rename + +/* ---------------------------------------------------------------------------------------------- */ +/* R/E/FLAGS info */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisCPUFlags` data-type. + */ +typedef ZyanU32 ZydisCPUFlags; + +/** + * Defines the `ZydisCPUFlag` data-type. + */ +typedef ZyanU8 ZydisCPUFlag; + +/** + * Carry flag. + */ +#define ZYDIS_CPUFLAG_CF 0 +/** + * Parity flag. + */ +#define ZYDIS_CPUFLAG_PF 2 +/** + * Adjust flag. + */ +#define ZYDIS_CPUFLAG_AF 4 +/** + * Zero flag. + */ +#define ZYDIS_CPUFLAG_ZF 6 +/** + * Sign flag. + */ +#define ZYDIS_CPUFLAG_SF 7 +/** + * Trap flag. + */ +#define ZYDIS_CPUFLAG_TF 8 +/** + * Interrupt enable flag. + */ +#define ZYDIS_CPUFLAG_IF 9 +/** + * Direction flag. + */ +#define ZYDIS_CPUFLAG_DF 10 +/** + * Overflow flag. + */ +#define ZYDIS_CPUFLAG_OF 11 +/** + * I/O privilege level flag. + */ +#define ZYDIS_CPUFLAG_IOPL 12 +/** + * Nested task flag. + */ +#define ZYDIS_CPUFLAG_NT 14 +/** + * Resume flag. + */ +#define ZYDIS_CPUFLAG_RF 16 +/** + * Virtual 8086 mode flag. + */ +#define ZYDIS_CPUFLAG_VM 17 +/** + * Alignment check. + */ +#define ZYDIS_CPUFLAG_AC 18 +/** + * Virtual interrupt flag. + */ +#define ZYDIS_CPUFLAG_VIF 19 +/** + * Virtual interrupt pending. + */ +#define ZYDIS_CPUFLAG_VIP 20 +/** + * Able to use CPUID instruction. + */ +#define ZYDIS_CPUFLAG_ID 21 + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * FPU condition-code flag 0. + * + * DEPRECATED. This flag is not actually part of `FLAGS/EFLAGS/RFLAGS` and will be removed in the + * next major release. Please refer to the `fpu_flags_read`/`fpu_flags_written` field instead and + * use one of the `ZYDIS_FPUFLAG_XXX` masks to check for specific a flag. + */ +#define ZYDIS_CPUFLAG_C0 22 +/** + * FPU condition-code flag 1. + * + * DEPRECATED. This flag is not actually part of `FLAGS/EFLAGS/RFLAGS` and will be removed in the + * next major release. Please refer to the `fpu_flags_read`/`fpu_flags_written` field instead and + * use one of the `ZYDIS_FPUFLAG_XXX` masks to check for specific a flag. + */ +#define ZYDIS_CPUFLAG_C1 23 +/** + * FPU condition-code flag 2. + * + * DEPRECATED. This flag is not actually part of `FLAGS/EFLAGS/RFLAGS` and will be removed in the + * next major release. Please refer to the `fpu_flags_read`/`fpu_flags_written` field instead and + * use one of the `ZYDIS_FPUFLAG_XXX` masks to check for specific a flag. + */ +#define ZYDIS_CPUFLAG_C2 24 +/** + * FPU condition-code flag 3. + * + * DEPRECATED. This flag is not actually part of `FLAGS/EFLAGS/RFLAGS` and will be removed in the + * next major release. Please refer to the `fpu_flags_read`/`fpu_flags_written` field instead and + * use one of the `ZYDIS_FPUFLAG_XXX` masks to check for specific a flag. + */ +#define ZYDIS_CPUFLAG_C3 25 + +/** + * DEPRECATED. This define will be removed in the next major release. + */ +#define ZYDIS_CPUFLAG_MAX_VALUE ZYDIS_CPUFLAG_C3 + + /////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Defines the `ZydisFPUFlags` data-type. + */ +typedef ZyanU8 ZydisFPUFlags; + +/** + * FPU condition-code flag 0. + */ +#define ZYDIS_FPUFLAG_C0 0x00 // (1 << 0) +/** + * FPU condition-code flag 1. + */ +#define ZYDIS_FPUFLAG_C1 0x01 // (1 << 1) + /** + * FPU condition-code flag 2. + */ +#define ZYDIS_FPUFLAG_C2 0x02 // (1 << 2) +/** + * FPU condition-code flag 3. + */ +#define ZYDIS_FPUFLAG_C3 0x04 // (1 << 3) + +/** + * Defines the `ZydisCPUFlagAction` enum. + * + * DEPRECATED. This enum will be removed in the next major release. + */ +typedef enum ZydisCPUFlagAction_ +{ + /** + * The CPU flag is not touched by the instruction. + */ + ZYDIS_CPUFLAG_ACTION_NONE, + /** + * The CPU flag is tested (read). + */ + ZYDIS_CPUFLAG_ACTION_TESTED, + /** + * The CPU flag is tested and modified afterwards (read-write). + */ + ZYDIS_CPUFLAG_ACTION_TESTED_MODIFIED, + /** + * The CPU flag is modified (write). + */ + ZYDIS_CPUFLAG_ACTION_MODIFIED, + /** + * The CPU flag is set to 0 (write). + */ + ZYDIS_CPUFLAG_ACTION_SET_0, + /** + * The CPU flag is set to 1 (write). + */ + ZYDIS_CPUFLAG_ACTION_SET_1, + /** + * The CPU flag is undefined (write). + */ + ZYDIS_CPUFLAG_ACTION_UNDEFINED, + + /** + * Maximum value of this enum. + */ + ZYDIS_CPUFLAG_ACTION_MAX_VALUE = ZYDIS_CPUFLAG_ACTION_UNDEFINED, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_CPUFLAG_ACTION_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_CPUFLAG_ACTION_MAX_VALUE) +} ZydisCPUFlagAction; + +/* ---------------------------------------------------------------------------------------------- */ +/* Branch types */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisBranchType` enum. + */ +typedef enum ZydisBranchType_ +{ + /** + * The instruction is not a branch instruction. + */ + ZYDIS_BRANCH_TYPE_NONE, + /** + * The instruction is a short (8-bit) branch instruction. + */ + ZYDIS_BRANCH_TYPE_SHORT, + /** + * The instruction is a near (16-bit or 32-bit) branch instruction. + */ + ZYDIS_BRANCH_TYPE_NEAR, + /** + * The instruction is a far (inter-segment) branch instruction. + */ + ZYDIS_BRANCH_TYPE_FAR, + + /** + * Maximum value of this enum. + */ + ZYDIS_BRANCH_TYPE_MAX_VALUE = ZYDIS_BRANCH_TYPE_FAR, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_BRANCH_TYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_BRANCH_TYPE_MAX_VALUE) +} ZydisBranchType; + +/* ---------------------------------------------------------------------------------------------- */ +/* SSE/AVX exception-class */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisExceptionClass` enum. + */ +typedef enum ZydisExceptionClass_ +{ + ZYDIS_EXCEPTION_CLASS_NONE, + // TODO: FP Exceptions + ZYDIS_EXCEPTION_CLASS_SSE1, + ZYDIS_EXCEPTION_CLASS_SSE2, + ZYDIS_EXCEPTION_CLASS_SSE3, + ZYDIS_EXCEPTION_CLASS_SSE4, + ZYDIS_EXCEPTION_CLASS_SSE5, + ZYDIS_EXCEPTION_CLASS_SSE7, + ZYDIS_EXCEPTION_CLASS_AVX1, + ZYDIS_EXCEPTION_CLASS_AVX2, + ZYDIS_EXCEPTION_CLASS_AVX3, + ZYDIS_EXCEPTION_CLASS_AVX4, + ZYDIS_EXCEPTION_CLASS_AVX5, + ZYDIS_EXCEPTION_CLASS_AVX6, + ZYDIS_EXCEPTION_CLASS_AVX7, + ZYDIS_EXCEPTION_CLASS_AVX8, + ZYDIS_EXCEPTION_CLASS_AVX11, + ZYDIS_EXCEPTION_CLASS_AVX12, + ZYDIS_EXCEPTION_CLASS_E1, + ZYDIS_EXCEPTION_CLASS_E1NF, + ZYDIS_EXCEPTION_CLASS_E2, + ZYDIS_EXCEPTION_CLASS_E2NF, + ZYDIS_EXCEPTION_CLASS_E3, + ZYDIS_EXCEPTION_CLASS_E3NF, + ZYDIS_EXCEPTION_CLASS_E4, + ZYDIS_EXCEPTION_CLASS_E4NF, + ZYDIS_EXCEPTION_CLASS_E5, + ZYDIS_EXCEPTION_CLASS_E5NF, + ZYDIS_EXCEPTION_CLASS_E6, + ZYDIS_EXCEPTION_CLASS_E6NF, + ZYDIS_EXCEPTION_CLASS_E7NM, + ZYDIS_EXCEPTION_CLASS_E7NM128, + ZYDIS_EXCEPTION_CLASS_E9NF, + ZYDIS_EXCEPTION_CLASS_E10, + ZYDIS_EXCEPTION_CLASS_E10NF, + ZYDIS_EXCEPTION_CLASS_E11, + ZYDIS_EXCEPTION_CLASS_E11NF, + ZYDIS_EXCEPTION_CLASS_E12, + ZYDIS_EXCEPTION_CLASS_E12NP, + ZYDIS_EXCEPTION_CLASS_K20, + ZYDIS_EXCEPTION_CLASS_K21, + ZYDIS_EXCEPTION_CLASS_AMXE1, + ZYDIS_EXCEPTION_CLASS_AMXE2, + ZYDIS_EXCEPTION_CLASS_AMXE3, + ZYDIS_EXCEPTION_CLASS_AMXE4, + ZYDIS_EXCEPTION_CLASS_AMXE5, + ZYDIS_EXCEPTION_CLASS_AMXE6, + + /** + * Maximum value of this enum. + */ + ZYDIS_EXCEPTION_CLASS_MAX_VALUE = ZYDIS_EXCEPTION_CLASS_AMXE6, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_EXCEPTION_CLASS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_EXCEPTION_CLASS_MAX_VALUE) +} ZydisExceptionClass; + +/* ---------------------------------------------------------------------------------------------- */ +/* AVX mask mode */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisMaskMode` enum. + */ +typedef enum ZydisMaskMode_ +{ + ZYDIS_MASK_MODE_INVALID, + /** + * Masking is disabled for the current instruction (`K0` register is used). + */ + ZYDIS_MASK_MODE_DISABLED, + /** + * The embedded mask register is used as a merge-mask. + */ + ZYDIS_MASK_MODE_MERGING, + /** + * The embedded mask register is used as a zero-mask. + */ + ZYDIS_MASK_MODE_ZEROING, + /** + * The embedded mask register is used as a control-mask (element selector). + */ + ZYDIS_MASK_MODE_CONTROL, + /** + * The embedded mask register is used as a zeroing control-mask (element selector). + */ + ZYDIS_MASK_MODE_CONTROL_ZEROING, + + /** + * Maximum value of this enum. + */ + ZYDIS_MASK_MODE_MAX_VALUE = ZYDIS_MASK_MODE_CONTROL_ZEROING, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MASK_MODE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MASK_MODE_MAX_VALUE) +} ZydisMaskMode; + +/* ---------------------------------------------------------------------------------------------- */ +/* AVX broadcast-mode */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisBroadcastMode` enum. + */ +typedef enum ZydisBroadcastMode_ +{ + ZYDIS_BROADCAST_MODE_INVALID, + ZYDIS_BROADCAST_MODE_1_TO_2, + ZYDIS_BROADCAST_MODE_1_TO_4, + ZYDIS_BROADCAST_MODE_1_TO_8, + ZYDIS_BROADCAST_MODE_1_TO_16, + ZYDIS_BROADCAST_MODE_1_TO_32, + ZYDIS_BROADCAST_MODE_1_TO_64, + ZYDIS_BROADCAST_MODE_2_TO_4, + ZYDIS_BROADCAST_MODE_2_TO_8, + ZYDIS_BROADCAST_MODE_2_TO_16, + ZYDIS_BROADCAST_MODE_4_TO_8, + ZYDIS_BROADCAST_MODE_4_TO_16, + ZYDIS_BROADCAST_MODE_8_TO_16, + + /** + * Maximum value of this enum. + */ + ZYDIS_BROADCAST_MODE_MAX_VALUE = ZYDIS_BROADCAST_MODE_8_TO_16, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_BROADCAST_MODE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_BROADCAST_MODE_MAX_VALUE) +} ZydisBroadcastMode; + +/* ---------------------------------------------------------------------------------------------- */ +/* AVX rounding-mode */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisRoundingMode` enum. + */ +typedef enum ZydisRoundingMode_ +{ + ZYDIS_ROUNDING_MODE_INVALID, + /** + * Round to nearest. + */ + ZYDIS_ROUNDING_MODE_RN, + /** + * Round down. + */ + ZYDIS_ROUNDING_MODE_RD, + /** + * Round up. + */ + ZYDIS_ROUNDING_MODE_RU, + /** + * Round towards zero. + */ + ZYDIS_ROUNDING_MODE_RZ, + + /** + * Maximum value of this enum. + */ + ZYDIS_ROUNDING_MODE_MAX_VALUE = ZYDIS_ROUNDING_MODE_RZ, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_ROUNDING_MODE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_ROUNDING_MODE_MAX_VALUE) +} ZydisRoundingMode; + +/* ---------------------------------------------------------------------------------------------- */ +/* KNC swizzle-mode */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisSwizzleMode` enum. + */ +typedef enum ZydisSwizzleMode_ +{ + ZYDIS_SWIZZLE_MODE_INVALID, + ZYDIS_SWIZZLE_MODE_DCBA, + ZYDIS_SWIZZLE_MODE_CDAB, + ZYDIS_SWIZZLE_MODE_BADC, + ZYDIS_SWIZZLE_MODE_DACB, + ZYDIS_SWIZZLE_MODE_AAAA, + ZYDIS_SWIZZLE_MODE_BBBB, + ZYDIS_SWIZZLE_MODE_CCCC, + ZYDIS_SWIZZLE_MODE_DDDD, + + /** + * Maximum value of this enum. + */ + ZYDIS_SWIZZLE_MODE_MAX_VALUE = ZYDIS_SWIZZLE_MODE_DDDD, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_SWIZZLE_MODE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SWIZZLE_MODE_MAX_VALUE) +} ZydisSwizzleMode; + +/* ---------------------------------------------------------------------------------------------- */ +/* KNC conversion-mode */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisConversionMode` enum. + */ +typedef enum ZydisConversionMode_ +{ + ZYDIS_CONVERSION_MODE_INVALID, + ZYDIS_CONVERSION_MODE_FLOAT16, + ZYDIS_CONVERSION_MODE_SINT8, + ZYDIS_CONVERSION_MODE_UINT8, + ZYDIS_CONVERSION_MODE_SINT16, + ZYDIS_CONVERSION_MODE_UINT16, + + /** + * Maximum value of this enum. + */ + ZYDIS_CONVERSION_MODE_MAX_VALUE = ZYDIS_CONVERSION_MODE_UINT16, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_CONVERSION_MODE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_CONVERSION_MODE_MAX_VALUE) +} ZydisConversionMode; + +/* ---------------------------------------------------------------------------------------------- */ +/* Legacy prefix type */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisPrefixType` enum. + */ +typedef enum ZydisPrefixType_ +{ + /** + * The prefix is ignored by the instruction. + * + * This applies to all prefixes that are not accepted by the instruction in general or the + * ones that are overwritten by a prefix of the same group closer to the instruction opcode. + */ + ZYDIS_PREFIX_TYPE_IGNORED, + /** + * The prefix is effectively used by the instruction. + */ + ZYDIS_PREFIX_TYPE_EFFECTIVE, + /** + * The prefix is used as a mandatory prefix. + * + * A mandatory prefix is interpreted as an opcode extension and has no further effect on the + * instruction. + */ + ZYDIS_PREFIX_TYPE_MANDATORY, + + /** + * Maximum value of this enum. + */ + ZYDIS_PREFIX_TYPE_MAX_VALUE = ZYDIS_PREFIX_TYPE_MANDATORY, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_PREFIX_TYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_PREFIX_TYPE_MAX_VALUE) +} ZydisPrefixType; + +// TODO: Check effective for 66/67 prefixes (currently defaults to EFFECTIVE) + +/* ---------------------------------------------------------------------------------------------- */ +/* Decoded instruction */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Information about a decoded instruction. + */ +typedef struct ZydisDecodedInstruction_ +{ + /** + * The machine mode used to decode this instruction. + */ + ZydisMachineMode machine_mode; + /** + * The instruction-mnemonic. + */ + ZydisMnemonic mnemonic; + /** + * The length of the decoded instruction. + */ + ZyanU8 length; + /** + * The instruction-encoding (`LEGACY`, `3DNOW`, `VEX`, `EVEX`, `XOP`). + */ + ZydisInstructionEncoding encoding; + /** + * The opcode-map. + */ + ZydisOpcodeMap opcode_map; + /** + * The instruction-opcode. + */ + ZyanU8 opcode; + /** + * The stack width. + */ + ZyanU8 stack_width; + /** + * The effective operand width. + */ + ZyanU8 operand_width; + /** + * The effective address width. + */ + ZyanU8 address_width; + /** + * The number of instruction-operands. + */ + ZyanU8 operand_count; + /** + * Detailed info for all instruction operands. + * + * Explicit operands are guaranteed to be in the front and ordered as they are printed + * by the formatter in Intel mode. No assumptions can be made about the order of hidden + * operands, except that they always located behind the explicit operands. + */ + ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]; + /** + * Instruction attributes. + */ + ZydisInstructionAttributes attributes; + /** + * Information about accessed CPU flags. + * + * DEPRECATED. This field will be removed in the next major release. Please use the + * `cpu_flags_read`/`cpu_flags_written` or `fpu_flags_read`/`fpu_flags_written` fields + * instead. + */ + struct ZydisDecodedInstructionAccessedFlags_ + { + /** + * The CPU-flag action. + * + * Use `ZydisGetAccessedFlagsByAction` to get a mask with all flags matching a specific + * action. + */ + ZydisCPUFlagAction action; + } accessed_flags[ZYDIS_CPUFLAG_MAX_VALUE + 1]; + /** + * A mask containing the CPU flags read by the instruction. + * + * The bits in this mask correspond to the actual bits in the `FLAGS/EFLAGS/RFLAGS` + * register. + * + * This mask includes the actions `TESTED` and `TESTED_MODIFIED`. + */ + ZydisCPUFlags cpu_flags_read; + /** + * A mask containing the CPU flags written by the instruction. + * + * The bits in this mask correspond to the actual bits in the `FLAGS/EFLAGS/RFLAGS` + * register. + * + * This mask includes the actions `TESTED_MODIFIED`, `SET_0`, `SET_1` and `UNDEFINED`. + */ + ZydisCPUFlags cpu_flags_written; + /** + * A mask containing the FPU flags read by the instruction. + */ + ZydisFPUFlags fpu_flags_read; + /** + * A mask containing the FPU flags written by the instruction. + */ + ZydisFPUFlags fpu_flags_written; + /** + * Extended info for `AVX` instructions. + */ + struct ZydisDecodedInstructionAvx_ + { + /** + * The `AVX` vector-length. + */ + ZyanU16 vector_length; + /** + * Info about the embedded writemask-register (`AVX-512` and `KNC` only). + */ + struct ZydisDecodedInstructionAvxMask_ + { + /** + * The masking mode. + */ + ZydisMaskMode mode; + /** + * The mask register. + */ + ZydisRegister reg; + } mask; + /** + * Contains info about the `AVX` broadcast. + */ + struct ZydisDecodedInstructionAvxBroadcast_ + { + /** + * Signals, if the broadcast is a static broadcast. + * + * This is the case for instructions with inbuilt broadcast functionality, which is + * always active and not controlled by the `EVEX/MVEX.RC` bits. + */ + ZyanBool is_static; + /** + * The `AVX` broadcast-mode. + */ + ZydisBroadcastMode mode; + } broadcast; + /** + * Contains info about the `AVX` rounding. + */ + struct ZydisDecodedInstructionAvxRounding_ + { + /** + * The `AVX` rounding-mode. + */ + ZydisRoundingMode mode; + } rounding; + /** + * Contains info about the `AVX` register-swizzle (`KNC` only). + */ + struct ZydisDecodedInstructionAvxSwizzle_ + { + /** + * The `AVX` register-swizzle mode. + */ + ZydisSwizzleMode mode; + } swizzle; + /** + * Contains info about the `AVX` data-conversion (`KNC` only). + */ + struct ZydisDecodedInstructionAvxConversion_ + { + /** + * The `AVX` data-conversion mode. + */ + ZydisConversionMode mode; + } conversion; + /** + * Signals, if the `SAE` (suppress-all-exceptions) functionality is + * enabled for the instruction. + */ + ZyanBool has_sae; + /** + * Signals, if the instruction has a memory-eviction-hint (`KNC` only). + */ + ZyanBool has_eviction_hint; + // TODO: publish EVEX tuple-type and MVEX functionality + } avx; + /** + * Meta info. + */ + struct ZydisDecodedInstructionMeta_ + { + /** + * The instruction category. + */ + ZydisInstructionCategory category; + /** + * The ISA-set. + */ + ZydisISASet isa_set; + /** + * The ISA-set extension. + */ + ZydisISAExt isa_ext; + /** + * The branch type. + */ + ZydisBranchType branch_type; + /** + * The exception class. + */ + ZydisExceptionClass exception_class; + } meta; + /** + * Detailed info about different instruction-parts like `ModRM`, `SIB` or + * encoding-prefixes. + */ + struct ZydisDecodedInstructionRaw_ + { + /** + * The number of legacy prefixes. + */ + ZyanU8 prefix_count; + /** + * Detailed info about the legacy prefixes (including `REX`). + */ + struct ZydisDecodedInstructionRawPrefixes_ + { + /** + * The prefix type. + */ + ZydisPrefixType type; + /** + * The prefix byte. + */ + ZyanU8 value; + } prefixes[ZYDIS_MAX_INSTRUCTION_LENGTH]; + /** + * Detailed info about the `REX` prefix. + */ + struct ZydisDecodedInstructionRawRex_ + { + /** + * 64-bit operand-size promotion. + */ + ZyanU8 W; + /** + * Extension of the `ModRM.reg` field. + */ + ZyanU8 R; + /** + * Extension of the `SIB.index` field. + */ + ZyanU8 X; + /** + * Extension of the `ModRM.rm`, `SIB.base`, or `opcode.reg` field. + */ + ZyanU8 B; + /** + * The offset of the effective `REX` byte, relative to the beginning of the + * instruction, in bytes. + * + * This offset always points to the "effective" `REX` prefix (the one closest to the + * instruction opcode), if multiple `REX` prefixes are present. + * + * Note that the `REX` byte can be the first byte of the instruction, which would lead + * to an offset of `0`. Please refer to the instruction attributes to check for the + * presence of the `REX` prefix. + */ + ZyanU8 offset; + } rex; + /** + * Detailed info about the `XOP` prefix. + */ + struct ZydisDecodedInstructionRawXop_ + { + /** + * Extension of the `ModRM.reg` field (inverted). + */ + ZyanU8 R; + /** + * Extension of the `SIB.index` field (inverted). + */ + ZyanU8 X; + /** + * Extension of the `ModRM.rm`, `SIB.base`, or `opcode.reg` field (inverted). + */ + ZyanU8 B; + /** + * Opcode-map specifier. + */ + ZyanU8 m_mmmm; + /** + * 64-bit operand-size promotion or opcode-extension. + */ + ZyanU8 W; + /** + * `NDS`/`NDD` (non-destructive-source/destination) register + * specifier (inverted). + */ + ZyanU8 vvvv; + /** + * Vector-length specifier. + */ + ZyanU8 L; + /** + * Compressed legacy prefix. + */ + ZyanU8 pp; + /** + * The offset of the first xop byte, relative to the beginning of + * the instruction, in bytes. + */ + ZyanU8 offset; + } xop; + /** + * Detailed info about the `VEX` prefix. + */ + struct ZydisDecodedInstructionRawVex_ + { + /** + * Extension of the `ModRM.reg` field (inverted). + */ + ZyanU8 R; + /** + * Extension of the `SIB.index` field (inverted). + */ + ZyanU8 X; + /** + * Extension of the `ModRM.rm`, `SIB.base`, or `opcode.reg` field (inverted). + */ + ZyanU8 B; + /** + * Opcode-map specifier. + */ + ZyanU8 m_mmmm; + /** + * 64-bit operand-size promotion or opcode-extension. + */ + ZyanU8 W; + /** + * `NDS`/`NDD` (non-destructive-source/destination) register specifier + * (inverted). + */ + ZyanU8 vvvv; + /** + * Vector-length specifier. + */ + ZyanU8 L; + /** + * Compressed legacy prefix. + */ + ZyanU8 pp; + /** + * The offset of the first `VEX` byte, relative to the beginning of the instruction, in + * bytes. + */ + ZyanU8 offset; + /** + * The size of the `VEX` prefix, in bytes. + */ + ZyanU8 size; + } vex; + /** + * Detailed info about the `EVEX` prefix. + */ + struct ZydisDecodedInstructionRawEvex_ + { + /** + * Extension of the `ModRM.reg` field (inverted). + */ + ZyanU8 R; + /** + * Extension of the `SIB.index/vidx` field (inverted). + */ + ZyanU8 X; + /** + * Extension of the `ModRM.rm` or `SIB.base` field (inverted). + */ + ZyanU8 B; + /** + * High-16 register specifier modifier (inverted). + */ + ZyanU8 R2; + /** + * Opcode-map specifier. + */ + ZyanU8 mm; + /** + * 64-bit operand-size promotion or opcode-extension. + */ + ZyanU8 W; + /** + * `NDS`/`NDD` (non-destructive-source/destination) register specifier + * (inverted). + */ + ZyanU8 vvvv; + /** + * Compressed legacy prefix. + */ + ZyanU8 pp; + /** + * Zeroing/Merging. + */ + ZyanU8 z; + /** + * Vector-length specifier or rounding-control (most significant bit). + */ + ZyanU8 L2; + /** + * Vector-length specifier or rounding-control (least significant bit). + */ + ZyanU8 L; + /** + * Broadcast/RC/SAE context. + */ + ZyanU8 b; + /** + * High-16 `NDS`/`VIDX` register specifier. + */ + ZyanU8 V2; + /** + * Embedded opmask register specifier. + */ + ZyanU8 aaa; + /** + * The offset of the first evex byte, relative to the beginning of the + * instruction, in bytes. + */ + ZyanU8 offset; + } evex; + /** + * Detailed info about the `MVEX` prefix. + */ + struct ZydisDecodedInstructionRawMvex_ + { + /** + * Extension of the `ModRM.reg` field (inverted). + */ + ZyanU8 R; + /** + * Extension of the `SIB.index/vidx` field (inverted). + */ + ZyanU8 X; + /** + * Extension of the `ModRM.rm` or `SIB.base` field (inverted). + */ + ZyanU8 B; + /** + * High-16 register specifier modifier (inverted). + */ + ZyanU8 R2; + /** + * Opcode-map specifier. + */ + ZyanU8 mmmm; + /** + * 64-bit operand-size promotion or opcode-extension. + */ + ZyanU8 W; + /** + * `NDS`/`NDD` (non-destructive-source/destination) register specifier + * (inverted). + */ + ZyanU8 vvvv; + /** + * Compressed legacy prefix. + */ + ZyanU8 pp; + /** + * Non-temporal/eviction hint. + */ + ZyanU8 E; + /** + * Swizzle/broadcast/up-convert/down-convert/static-rounding controls. + */ + ZyanU8 SSS; + /** + * High-16 `NDS`/`VIDX` register specifier. + */ + ZyanU8 V2; + /** + * Embedded opmask register specifier. + */ + ZyanU8 kkk; + /** + * The offset of the first mvex byte, relative to the beginning of the + * instruction, in bytes. + */ + ZyanU8 offset; + } mvex; + /** + * Detailed info about the `ModRM` byte. + */ + struct ZydisDecodedInstructionModRm_ + { + /** + * The addressing mode. + */ + ZyanU8 mod; + /** + * Register specifier or opcode-extension. + */ + ZyanU8 reg; + /** + * Register specifier or opcode-extension. + */ + ZyanU8 rm; + /** + * The offset of the `ModRM` byte, relative to the beginning of the + * instruction, in bytes. + */ + ZyanU8 offset; + } modrm; + /** + * Detailed info about the `SIB` byte. + */ + struct ZydisDecodedInstructionRawSib_ + { + /** + * The scale factor. + */ + ZyanU8 scale; + /** + * The index-register specifier. + */ + ZyanU8 index; + /** + * The base-register specifier. + */ + ZyanU8 base; + /** + * The offset of the `SIB` byte, relative to the beginning of the + * instruction, in bytes. + */ + ZyanU8 offset; + } sib; + /** + * Detailed info about displacement-bytes. + */ + struct ZydisDecodedInstructionRawDisp_ + { + /** + * The displacement value + */ + ZyanI64 value; + /** + * The physical displacement size, in bits. + */ + ZyanU8 size; + // TODO: publish cd8 scale + /** + * The offset of the displacement data, relative to the beginning of the + * instruction, in bytes. + */ + ZyanU8 offset; + } disp; + /** + * Detailed info about immediate-bytes. + */ + struct ZydisDecodedInstructionRawImm_ + { + /** + * Signals, if the immediate value is signed. + */ + ZyanBool is_signed; + /** + * Signals, if the immediate value contains a relative offset. You can use + * `ZydisCalcAbsoluteAddress` to determine the absolute address value. + */ + ZyanBool is_relative; + /** + * The immediate value. + */ + union ZydisDecodedInstructionRawImmValue_ + { + ZyanU64 u; + ZyanI64 s; + } value; + /** + * The physical immediate size, in bits. + */ + ZyanU8 size; + /** + * The offset of the immediate data, relative to the beginning of the + * instruction, in bytes. + */ + ZyanU8 offset; + } imm[2]; + } raw; +} ZydisDecodedInstruction; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_INSTRUCTIONINFO_H */ diff --git a/src/Zydis/Formatter.h b/src/Zydis/Formatter.h new file mode 100644 index 0000000..c68bcde --- /dev/null +++ b/src/Zydis/Formatter.h @@ -0,0 +1,1179 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Functions for formatting instructions to human-readable text. + */ + +#ifndef ZYDIS_FORMATTER_H +#define ZYDIS_FORMATTER_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Constants */ +/* ============================================================================================== */ + +/** + * Use this constant as value for `runtime_address` in `ZydisFormatterFormatInstruction(Ex)` + * or `ZydisFormatterFormatOperand(Ex)` to print relative values for all addresses. + */ +#define ZYDIS_RUNTIME_ADDRESS_NONE (ZyanU64)(-1) + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatter style */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisFormatterStyle` enum. + */ +typedef enum ZydisFormatterStyle_ +{ + /** + * Generates `AT&T`-style disassembly. + */ + ZYDIS_FORMATTER_STYLE_ATT, + /** + * Generates `Intel`-style disassembly. + */ + ZYDIS_FORMATTER_STYLE_INTEL, + /** + * Generates `MASM`-style disassembly that is directly accepted as input for + * the `MASM` assembler. + * + * The runtime-address is ignored in this mode. + */ + ZYDIS_FORMATTER_STYLE_INTEL_MASM, + + /** + * Maximum value of this enum. + */ + ZYDIS_FORMATTER_STYLE_MAX_VALUE = ZYDIS_FORMATTER_STYLE_INTEL_MASM, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_FORMATTER_STYLE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_STYLE_MAX_VALUE) +} ZydisFormatterStyle; + +/* ---------------------------------------------------------------------------------------------- */ +/* Properties */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisFormatterProperty` enum. + */ +typedef enum ZydisFormatterProperty_ +{ + /* ---------------------------------------------------------------------------------------- */ + /* General */ + /* ---------------------------------------------------------------------------------------- */ + + /** + * Controls the printing of effective operand-size suffixes (`AT&T`) or operand-sizes + * of memory operands (`INTEL`). + * + * Pass `ZYAN_TRUE` as value to force the formatter to always print the size, or `ZYAN_FALSE` + * to only print it if needed. + */ + ZYDIS_FORMATTER_PROP_FORCE_SIZE, + /** + * Controls the printing of segment prefixes. + * + * Pass `ZYAN_TRUE` as value to force the formatter to always print the segment register of + * memory-operands or `ZYAN_FALSE` to omit implicit `DS`/`SS` segments. + */ + ZYDIS_FORMATTER_PROP_FORCE_SEGMENT, + /** + * Controls the printing of branch addresses. + * + * Pass `ZYAN_TRUE` as value to force the formatter to always print relative branch addresses + * or `ZYAN_FALSE` to use absolute addresses, if a runtime-address different to + * `ZYDIS_RUNTIME_ADDRESS_NONE` was passed. + */ + ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_BRANCHES, + /** + * Controls the printing of `EIP`/`RIP`-relative addresses. + * + * Pass `ZYAN_TRUE` as value to force the formatter to always print relative addresses for + * `EIP`/`RIP`-relative operands or `ZYAN_FALSE` to use absolute addresses, if a runtime- + * address different to `ZYDIS_RUNTIME_ADDRESS_NONE` was passed. + */ + ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_RIPREL, + /** + * Controls the printing of branch-instructions sizes. + * + * Pass `ZYAN_TRUE` as value to print the size (`short`, `near`) of branch + * instructions or `ZYAN_FALSE` to hide it. + * + * Note that the `far`/`l` modifier is always printed. + */ + ZYDIS_FORMATTER_PROP_PRINT_BRANCH_SIZE, + + /** + * Controls the printing of instruction prefixes. + * + * Pass `ZYAN_TRUE` as value to print all instruction-prefixes (even ignored or duplicate + * ones) or `ZYAN_FALSE` to only print prefixes that are effectively used by the instruction. + */ + ZYDIS_FORMATTER_PROP_DETAILED_PREFIXES, + + /* ---------------------------------------------------------------------------------------- */ + /* Numeric values */ + /* ---------------------------------------------------------------------------------------- */ + + /** + * Controls the base of address values. + */ + ZYDIS_FORMATTER_PROP_ADDR_BASE, + /** + * Controls the signedness of relative addresses. Absolute addresses are + * always unsigned. + */ + ZYDIS_FORMATTER_PROP_ADDR_SIGNEDNESS, + /** + * Controls the padding of absolute address values. + * + * Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all + * addresses to the current stack width (hexadecimal only), or any other integer value for + * custom padding. + */ + ZYDIS_FORMATTER_PROP_ADDR_PADDING_ABSOLUTE, + /** + * Controls the padding of relative address values. + * + * Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all + * addresses to the current stack width (hexadecimal only), or any other integer value for + * custom padding. + */ + ZYDIS_FORMATTER_PROP_ADDR_PADDING_RELATIVE, + + /* ---------------------------------------------------------------------------------------- */ + + /** + * Controls the base of displacement values. + */ + ZYDIS_FORMATTER_PROP_DISP_BASE, + /** + * Controls the signedness of displacement values. + */ + ZYDIS_FORMATTER_PROP_DISP_SIGNEDNESS, + /** + * Controls the padding of displacement values. + * + * Pass `ZYDIS_PADDING_DISABLED` to disable padding, or any other integer value for custom + * padding. + */ + ZYDIS_FORMATTER_PROP_DISP_PADDING, + + /* ---------------------------------------------------------------------------------------- */ + + /** + * Controls the base of immediate values. + */ + ZYDIS_FORMATTER_PROP_IMM_BASE, + /** + * Controls the signedness of immediate values. + * + * Pass `ZYDIS_SIGNEDNESS_AUTO` to automatically choose the most suitable mode based on the + * operands `ZydisDecodedOperand.imm.is_signed` attribute. + */ + ZYDIS_FORMATTER_PROP_IMM_SIGNEDNESS, + /** + * Controls the padding of immediate values. + * + * Pass `ZYDIS_PADDING_DISABLED` to disable padding, `ZYDIS_PADDING_AUTO` to padd all + * immediates to the operand-width (hexadecimal only), or any other integer value for custom + * padding. + */ + ZYDIS_FORMATTER_PROP_IMM_PADDING, + + /* ---------------------------------------------------------------------------------------- */ + /* Text formatting */ + /* ---------------------------------------------------------------------------------------- */ + + /** + * Controls the letter-case for prefixes. + * + * Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase. + */ + ZYDIS_FORMATTER_PROP_UPPERCASE_PREFIXES, + /** + * Controls the letter-case for the mnemonic. + * + * Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase. + */ + ZYDIS_FORMATTER_PROP_UPPERCASE_MNEMONIC, + /** + * Controls the letter-case for registers. + * + * Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase. + */ + ZYDIS_FORMATTER_PROP_UPPERCASE_REGISTERS, + /** + * Controls the letter-case for typecasts. + * + * Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase. + */ + ZYDIS_FORMATTER_PROP_UPPERCASE_TYPECASTS, + /** + * Controls the letter-case for decorators. + * + * Pass `ZYAN_TRUE` as value to format in uppercase or `ZYAN_FALSE` to format in lowercase. + */ + ZYDIS_FORMATTER_PROP_UPPERCASE_DECORATORS, + + /* ---------------------------------------------------------------------------------------- */ + /* Number formatting */ + /* ---------------------------------------------------------------------------------------- */ + + /** + * Controls the prefix for decimal values. + * + * Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters + * to set a custom prefix, or `ZYAN_NULL` to disable it. + * + * The string is deep-copied into an internal buffer. + */ + ZYDIS_FORMATTER_PROP_DEC_PREFIX, + /** + * Controls the suffix for decimal values. + * + * Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters + * to set a custom suffix, or `ZYAN_NULL` to disable it. + * + * The string is deep-copied into an internal buffer. + */ + ZYDIS_FORMATTER_PROP_DEC_SUFFIX, + + /* ---------------------------------------------------------------------------------------- */ + + /** + * Controls the letter-case of hexadecimal values. + * + * Pass `ZYAN_TRUE` as value to format in uppercase and `ZYAN_FALSE` to format in lowercase. + * + * The default value is `ZYAN_TRUE`. + */ + ZYDIS_FORMATTER_PROP_HEX_UPPERCASE, + /** + * Controls the prefix for hexadecimal values. + * + * Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters + * to set a custom prefix, or `ZYAN_NULL` to disable it. + * + * The string is deep-copied into an internal buffer. + */ + ZYDIS_FORMATTER_PROP_HEX_PREFIX, + /** + * Controls the suffix for hexadecimal values. + * + * Pass a pointer to a null-terminated C-style string with a maximum length of 10 characters + * to set a custom suffix, or `ZYAN_NULL` to disable it. + * + * The string is deep-copied into an internal buffer. + */ + ZYDIS_FORMATTER_PROP_HEX_SUFFIX, + + /* ---------------------------------------------------------------------------------------- */ + + /** + * Maximum value of this enum. + */ + ZYDIS_FORMATTER_PROP_MAX_VALUE = ZYDIS_FORMATTER_PROP_HEX_SUFFIX, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_FORMATTER_PROP_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_PROP_MAX_VALUE) +} ZydisFormatterProperty; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisNumericBase` enum. + */ +typedef enum ZydisNumericBase_ +{ + /** + * Decimal system. + */ + ZYDIS_NUMERIC_BASE_DEC, + /** + * Hexadecimal system. + */ + ZYDIS_NUMERIC_BASE_HEX, + + /** + * Maximum value of this enum. + */ + ZYDIS_NUMERIC_BASE_MAX_VALUE = ZYDIS_NUMERIC_BASE_HEX, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_NUMERIC_BASE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_NUMERIC_BASE_MAX_VALUE) +} ZydisNumericBase; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisSignedness` enum. + */ +typedef enum ZydisSignedness_ +{ + /** + * Automatically choose the most suitable mode based on the operands + * ZydisDecodedOperand.imm.is_signed` attribute. + */ + ZYDIS_SIGNEDNESS_AUTO, + /** + * Force signed values. + */ + ZYDIS_SIGNEDNESS_SIGNED, + /** + * Force unsigned values. + */ + ZYDIS_SIGNEDNESS_UNSIGNED, + + /** + * Maximum value of this enum. + */ + ZYDIS_SIGNEDNESS_MAX_VALUE = ZYDIS_SIGNEDNESS_UNSIGNED, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_SIGNEDNESS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIGNEDNESS_MAX_VALUE) +} ZydisSignedness; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisPadding` enum. + */ +typedef enum ZydisPadding_ +{ + /** + * Disables padding. + */ + ZYDIS_PADDING_DISABLED = 0, + /** + * Padds the value to the current stack-width for addresses, or to the + * operand-width for immediate values (hexadecimal only). + */ + ZYDIS_PADDING_AUTO = (-1), + + /** + * Maximum value of this enum. + */ + ZYDIS_PADDING_MAX_VALUE = ZYDIS_PADDING_AUTO, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_PADDING_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_PADDING_MAX_VALUE) +} ZydisPadding; + +/* ---------------------------------------------------------------------------------------------- */ +/* Function types */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisFormatterFunction` enum. + * + * Do NOT change the order of the values this enum or the function fields inside the + * `ZydisFormatter` struct. + */ +typedef enum ZydisFormatterFunction_ +{ + /* ---------------------------------------------------------------------------------------- */ + /* Instruction */ + /* ---------------------------------------------------------------------------------------- */ + + /** + * This function is invoked before the formatter formats an instruction. + */ + ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION, + /** + * This function is invoked after the formatter formatted an instruction. + */ + ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION, + + /* ---------------------------------------------------------------------------------------- */ + + /** + * This function refers to the main formatting function. + * + * Replacing this function allows for complete custom formatting, but indirectly disables all + * other hooks except for `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` and + * `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION`. + */ + ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION, + + /* ---------------------------------------------------------------------------------------- */ + /* Operands */ + /* ---------------------------------------------------------------------------------------- */ + + /** + * This function is invoked before the formatter formats an operand. + */ + ZYDIS_FORMATTER_FUNC_PRE_OPERAND, + /** + * This function is invoked after the formatter formatted an operand. + */ + ZYDIS_FORMATTER_FUNC_POST_OPERAND, + + /* ---------------------------------------------------------------------------------------- */ + + /** + * This function is invoked to format a register operand. + */ + ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG, + /** + * This function is invoked to format a memory operand. + * + * Replacing this function might indirectly disable some specific calls to the + * `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST`, `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT`, + * `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` and `ZYDIS_FORMATTER_FUNC_PRINT_DISP` functions. + */ + ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM, + /** + * This function is invoked to format a pointer operand. + */ + ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR, + /** + * This function is invoked to format an immediate operand. + * + * Replacing this function might indirectly disable some specific calls to the + * `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS`, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` and + * `ZYDIS_FORMATTER_FUNC_PRINT_IMM` functions. + */ + ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM, + + /* ---------------------------------------------------------------------------------------- */ + /* Elemental tokens */ + /* ---------------------------------------------------------------------------------------- */ + + /** + * This function is invoked to print the instruction mnemonic. + */ + ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC, + + /* ---------------------------------------------------------------------------------------- */ + + /** + * This function is invoked to print a register. + */ + ZYDIS_FORMATTER_FUNC_PRINT_REGISTER, + /** + * This function is invoked to print absolute addresses. + * + * Conditionally invoked, if a runtime-address different to `ZYDIS_RUNTIME_ADDRESS_NONE` was + * passed: + * - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...) + * - `MEM` operands with `EIP`/`RIP`-relative address (e.g. `MOV RAX, [RIP+0x12345678]`) + * + * Always invoked for: + * - `MEM` operands with absolute address (e.g. `MOV RAX, [0x12345678]`) + */ + ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS, + /** + * This function is invoked to print relative addresses. + * + * Conditionally invoked, if `ZYDIS_RUNTIME_ADDRESS_NONE` was passed as runtime-address: + * - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...) + */ + ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL, + /** + * This function is invoked to print a memory displacement value. + * + * If the memory displacement contains an address and a runtime-address different to + * `ZYDIS_RUNTIME_ADDRESS_NONE` was passed, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` is called + * instead. + */ + ZYDIS_FORMATTER_FUNC_PRINT_DISP, + /** + * This function is invoked to print an immediate value. + * + * If the immediate contains an address and a runtime-address different to + * `ZYDIS_RUNTIME_ADDRESS_NONE` was passed, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` is called + * instead. + * + * If the immediate contains an address and `ZYDIS_RUNTIME_ADDRESS_NONE` was passed as + * runtime-address, `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` is called instead. + */ + ZYDIS_FORMATTER_FUNC_PRINT_IMM, + + /* ---------------------------------------------------------------------------------------- */ + /* Optional tokens */ + /* ---------------------------------------------------------------------------------------- */ + + /** + * This function is invoked to print the size of a memory operand (`INTEL` only). + */ + ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST, + /** + * This function is invoked to print the segment-register of a memory operand. + */ + ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT, + /** + * This function is invoked to print the instruction prefixes. + */ + ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES, + /** + * This function is invoked after formatting an operand to print a `EVEX`/`MVEX` + * decorator. + */ + ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR, + + /* ---------------------------------------------------------------------------------------- */ + + /** + * Maximum value of this enum. + */ + ZYDIS_FORMATTER_FUNC_MAX_VALUE = ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_FORMATTER_FUNC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FORMATTER_FUNC_MAX_VALUE) +} ZydisFormatterFunction; + +/* ---------------------------------------------------------------------------------------------- */ +/* Decorator types */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisDecorator` enum. + */ +typedef enum ZydisDecorator_ +{ + ZYDIS_DECORATOR_INVALID, + /** + * The embedded-mask decorator. + */ + ZYDIS_DECORATOR_MASK, + /** + * The broadcast decorator. + */ + ZYDIS_DECORATOR_BC, + /** + * The rounding-control decorator. + */ + ZYDIS_DECORATOR_RC, + /** + * The suppress-all-exceptions decorator. + */ + ZYDIS_DECORATOR_SAE, + /** + * The register-swizzle decorator. + */ + ZYDIS_DECORATOR_SWIZZLE, + /** + * The conversion decorator. + */ + ZYDIS_DECORATOR_CONVERSION, + /** + * The eviction-hint decorator. + */ + ZYDIS_DECORATOR_EH, + + /** + * Maximum value of this enum. + */ + ZYDIS_DECORATOR_MAX_VALUE = ZYDIS_DECORATOR_EH, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_DECORATOR_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_DECORATOR_MAX_VALUE) +} ZydisDecorator; + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatter context */ +/* ---------------------------------------------------------------------------------------------- */ + +typedef struct ZydisFormatter_ ZydisFormatter; + +/** + * Defines the `ZydisFormatterContext` struct. + */ +typedef struct ZydisFormatterContext_ +{ + /** + * A pointer to the `ZydisDecodedInstruction` struct. + */ + const ZydisDecodedInstruction* instruction; + /** + * A pointer to the `ZydisDecodedOperand` struct. + */ + const ZydisDecodedOperand* operand; + /** + * The runtime address of the instruction. + */ + ZyanU64 runtime_address; + /** + * A pointer to user-defined data. + */ + void* user_data; +} ZydisFormatterContext; + +/* ---------------------------------------------------------------------------------------------- */ +/* Function prototypes */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisFormatterFunc` function prototype. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param context A pointer to the `ZydisFormatterContext` struct. + * + * @return A zyan status code. + * + * Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the formatting + * process to fail (see exceptions below). + * + * Returning `ZYDIS_STATUS_SKIP_TOKEN` is valid for functions of the following types and will + * instruct the formatter to omit the whole operand: + * - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND` + * - `ZYDIS_FORMATTER_FUNC_POST_OPERAND` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM` + * + * This function prototype is used by functions of the following types: + * - `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` + * - `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION` + * - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND` + * - `ZYDIS_FORMATTER_FUNC_POST_OPERAND` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION` + * - `ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC` + * - `ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM` + * - `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` + * - `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` + * - `ZYDIS_FORMATTER_FUNC_PRINT_DISP` + * - `ZYDIS_FORMATTER_FUNC_PRINT_IMM` + * - `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST` + * - `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT` + */ +typedef ZyanStatus (*ZydisFormatterFunc)(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context); + + /** + * Defines the `ZydisFormatterRegisterFunc` function prototype. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param context A pointer to the `ZydisFormatterContext` struct. + * @param reg The register. + * + * @return Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the + * formatting process to fail. + * + * This function prototype is used by functions of the following types: + * - `ZYDIS_FORMATTER_FUNC_PRINT_REGISTER`. + */ +typedef ZyanStatus (*ZydisFormatterRegisterFunc)(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisRegister reg); + +/** + * Defines the `ZydisFormatterDecoratorFunc` function prototype. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param context A pointer to the `ZydisFormatterContext` struct. + * @param decorator The decorator type. + * + * @return Returning a status code other than `ZYAN_STATUS_SUCCESS` will immediately cause the + * formatting process to fail. + * + * This function type is used for: + * - `ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR` + */ +typedef ZyanStatus (*ZydisFormatterDecoratorFunc)(const ZydisFormatter* formatter, + ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator); + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatter struct */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisFormatter` struct. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + * + * Do NOT change the order of the function fields or the values of the `ZydisFormatterFunction` + * enum. + */ +struct ZydisFormatter_ +{ + /** + * The formatter style. + */ + ZydisFormatterStyle style; + /** + * The `ZYDIS_FORMATTER_PROP_FORCE_SIZE` property. + */ + ZyanBool force_memory_size; + /** + * The `ZYDIS_FORMATTER_PROP_FORCE_SEGMENT` property. + */ + ZyanBool force_memory_segment; + /** + * The `ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_BRANCHES` property. + */ + ZyanBool force_relative_branches; + /** + * The `ZYDIS_FORMATTER_PROP_FORCE_RELATIVE_RIPREL` property. + */ + ZyanBool force_relative_riprel; + /** + * The `ZYDIS_FORMATTER_PROP_PRINT_BRANCH_SIZE` property. + */ + ZyanBool print_branch_size; + /** + * The `ZYDIS_FORMATTER_DETAILED_PREFIXES` property. + */ + ZyanBool detailed_prefixes; + /** + * The `ZYDIS_FORMATTER_ADDR_BASE` property. + */ + ZydisNumericBase addr_base; + /** + * The `ZYDIS_FORMATTER_ADDR_SIGNEDNESS` property. + */ + ZydisSignedness addr_signedness; + /** + * The `ZYDIS_FORMATTER_ADDR_PADDING_ABSOLUTE` property. + */ + ZydisPadding addr_padding_absolute; + /** + * The `ZYDIS_FORMATTER_ADDR_PADDING_RELATIVE` property. + */ + ZydisPadding addr_padding_relative; + /** + * The `ZYDIS_FORMATTER_DISP_BASE` property. + */ + ZydisNumericBase disp_base; + /** + * The `ZYDIS_FORMATTER_DISP_SIGNEDNESS` property. + */ + ZydisSignedness disp_signedness; + /** + * The `ZYDIS_FORMATTER_DISP_PADDING` property. + */ + ZydisPadding disp_padding; + /** + * The `ZYDIS_FORMATTER_IMM_BASE` property. + */ + ZydisNumericBase imm_base; + /** + * The `ZYDIS_FORMATTER_IMM_SIGNEDNESS` property. + */ + ZydisSignedness imm_signedness; + /** + * The `ZYDIS_FORMATTER_IMM_PADDING` property. + */ + ZydisPadding imm_padding; + /** + * The `ZYDIS_FORMATTER_UPPERCASE_PREFIXES` property. + */ + ZyanI32 case_prefixes; + /** + * The `ZYDIS_FORMATTER_UPPERCASE_MNEMONIC` property. + */ + ZyanI32 case_mnemonic; + /** + * The `ZYDIS_FORMATTER_UPPERCASE_REGISTERS` property. + */ + ZyanI32 case_registers; + /** + * The `ZYDIS_FORMATTER_UPPERCASE_TYPECASTS` property. + */ + ZyanI32 case_typecasts; + /** + * The `ZYDIS_FORMATTER_UPPERCASE_DECORATORS` property. + */ + ZyanI32 case_decorators; + /** + * The `ZYDIS_FORMATTER_HEX_UPPERCASE` property. + */ + ZyanBool hex_uppercase; + /** + * The number formats for all numeric bases. + * + * Index 0 = prefix + * Index 1 = suffix + */ + struct + { + /** + * A pointer to the `ZyanStringView` to use as prefix/suffix. + */ + const ZyanStringView* string; + /** + * The `ZyanStringView` to use as prefix/suffix + */ + ZyanStringView string_data; + /** + * The actual string data. + */ + char buffer[11]; + } number_format[ZYDIS_NUMERIC_BASE_MAX_VALUE + 1][2]; + /** + * The `ZYDIS_FORMATTER_FUNC_PRE_INSTRUCTION` function. + */ + ZydisFormatterFunc func_pre_instruction; + /** + * The `ZYDIS_FORMATTER_FUNC_POST_INSTRUCTION` function. + */ + ZydisFormatterFunc func_post_instruction; + /** + * The `ZYDIS_FORMATTER_FUNC_FORMAT_INSTRUCTION` function. + */ + ZydisFormatterFunc func_format_instruction; + /** + * The `ZYDIS_FORMATTER_FUNC_PRE_OPERAND` function. + */ + ZydisFormatterFunc func_pre_operand; + /** + * The `ZYDIS_FORMATTER_FUNC_POST_OPERAND` function. + */ + ZydisFormatterFunc func_post_operand; + /** + * The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG` function. + */ + ZydisFormatterFunc func_format_operand_reg; + /** + * The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM` function. + */ + ZydisFormatterFunc func_format_operand_mem; + /** + * The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR` function. + */ + ZydisFormatterFunc func_format_operand_ptr; + /** + * The `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM` function. + */ + ZydisFormatterFunc func_format_operand_imm; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_MNEMONIC function. + */ + ZydisFormatterFunc func_print_mnemonic; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_REGISTER` function. + */ + ZydisFormatterRegisterFunc func_print_register; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS` function. + */ + ZydisFormatterFunc func_print_address_abs; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_REL` function. + */ + ZydisFormatterFunc func_print_address_rel; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_DISP` function. + */ + ZydisFormatterFunc func_print_disp; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_IMM` function. + */ + ZydisFormatterFunc func_print_imm; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_TYPECAST` function. + */ + ZydisFormatterFunc func_print_typecast; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_SEGMENT` function. + */ + ZydisFormatterFunc func_print_segment; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_PREFIXES` function. + */ + ZydisFormatterFunc func_print_prefixes; + /** + * The `ZYDIS_FORMATTER_FUNC_PRINT_DECORATOR` function. + */ + ZydisFormatterDecoratorFunc func_print_decorator; +}; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * @addtogroup formatter Formatter + * Functions allowing formatting of previously decoded instructions to human readable text. + * @{ + */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Initialization */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Initializes the given `ZydisFormatter` instance. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param style The base formatter style (either `AT&T` or `Intel` style). + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle style); + +/* ---------------------------------------------------------------------------------------------- */ +/* Setter */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Changes the value of the specified formatter `property`. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param property The id of the formatter-property. + * @param value The new value. + * + * @return A zyan status code. + * + * This function returns `ZYAN_STATUS_INVALID_OPERATION` if a property can't be changed for the + * current formatter-style. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterSetProperty(ZydisFormatter* formatter, + ZydisFormatterProperty property, ZyanUPointer value); + +/** + * Replaces a formatter function with a custom callback and/or retrieves the currently + * used function. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param type The formatter function-type. + * @param callback A pointer to a variable that contains the pointer of the callback function + * and receives the pointer of the currently used function. + * + * @return A zyan status code. + * + * Call this function with `callback` pointing to a `ZYAN_NULL` value to retrieve the currently + * used function without replacing it. + * + * This function returns `ZYAN_STATUS_INVALID_OPERATION` if a function can't be replaced for the + * current formatter-style. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterSetHook(ZydisFormatter* formatter, + ZydisFormatterFunction type, const void** callback); + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatting */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Formats the given instruction and writes it into the output buffer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param buffer A pointer to the output buffer. + * @param length The length of the output buffer (in characters). + * @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE` + * to print relative addresses. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, char* buffer, ZyanUSize length, + ZyanU64 runtime_address); + +/** + * Formats the given instruction and writes it into the output buffer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param buffer A pointer to the output buffer. + * @param length The length of the output buffer (in characters). + * @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE` + * to print relative addresses. + * @param user_data A pointer to user-defined data which can be used in custom formatter + * callbacks. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, char* buffer, ZyanUSize length, + ZyanU64 runtime_address, void* user_data); + +/** + * Formats the given operand and writes it into the output buffer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param index The index of the operand to format. + * @param buffer A pointer to the output buffer. + * @param length The length of the output buffer (in characters). + * @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE` + * to print relative addresses. + * + * @return A zyan status code. + * + * Use `ZydisFormatterFormatInstruction` or `ZydisFormatterFormatInstructionEx` to format a + * complete instruction. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatOperand(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, ZyanU8 index, char* buffer, ZyanUSize length, + ZyanU64 runtime_address); + +/** + * Formats the given operand and writes it into the output buffer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param index The index of the operand to format. + * @param buffer A pointer to the output buffer. + * @param length The length of the output buffer (in characters). + * @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE` + * to print relative addresses. + * @param user_data A pointer to user-defined data which can be used in custom formatter + * callbacks. + * + * @return A zyan status code. + * + * Use `ZydisFormatterFormatInstruction` or `ZydisFormatterFormatInstructionEx` to format a + * complete instruction. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterFormatOperandEx(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, ZyanU8 index, char* buffer, ZyanUSize length, + ZyanU64 runtime_address, void* user_data); + +/* ---------------------------------------------------------------------------------------------- */ +/* Tokenizing */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Tokenizes the given instruction and writes it into the output buffer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param buffer A pointer to the output buffer. + * @param length The length of the output buffer (in bytes). + * @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE` + * to print relative addresses. + * @param token Receives a pointer to the first token in the output buffer. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeInstruction(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, void* buffer, ZyanUSize length, + ZyanU64 runtime_address, ZydisFormatterTokenConst** token); + +/** + * Tokenizes the given instruction and writes it into the output buffer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param buffer A pointer to the output buffer. + * @param length The length of the output buffer (in bytes). + * @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE` + * to print relative addresses. + * @param token Receives a pointer to the first token in the output buffer. + * @param user_data A pointer to user-defined data which can be used in custom formatter + * callbacks. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeInstructionEx(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, void* buffer, ZyanUSize length, + ZyanU64 runtime_address, ZydisFormatterTokenConst** token, void* user_data); + +/** + * Tokenizes the given operand and writes it into the output buffer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param index The index of the operand to format. + * @param buffer A pointer to the output buffer. + * @param length The length of the output buffer (in bytes). + * @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE` + * to print relative addresses. + * @param token Receives a pointer to the first token in the output buffer. + * + * @return A zyan status code. + * + * Use `ZydisFormatterTokenizeInstruction` or `ZydisFormatterTokenizeInstructionEx` to tokenize a + * complete instruction. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeOperand(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, ZyanU8 index, void* buffer, ZyanUSize length, + ZyanU64 runtime_address, ZydisFormatterTokenConst** token); + +/** + * Tokenizes the given operand and writes it into the output buffer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param index The index of the operand to format. + * @param buffer A pointer to the output buffer. + * @param length The length of the output buffer (in bytes). + * @param runtime_address The runtime address of the instruction or `ZYDIS_RUNTIME_ADDRESS_NONE` + * to print relative addresses. + * @param token Receives a pointer to the first token in the output buffer. + * @param user_data A pointer to user-defined data which can be used in custom formatter + * callbacks. + * + * @return A zyan status code. + * + * Use `ZydisFormatterTokenizeInstruction` or `ZydisFormatterTokenizeInstructionEx` to tokenize a + * complete instruction. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenizeOperandEx(const ZydisFormatter* formatter, + const ZydisDecodedInstruction* instruction, ZyanU8 index, void* buffer, ZyanUSize length, + ZyanU64 runtime_address, ZydisFormatterTokenConst** token, void* user_data); + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @} + */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_FORMATTER_H */ diff --git a/src/Zydis/FormatterBuffer.h b/src/Zydis/FormatterBuffer.h new file mode 100644 index 0000000..2ae2efe --- /dev/null +++ b/src/Zydis/FormatterBuffer.h @@ -0,0 +1,306 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Implements the `ZydisFormatterToken` type and provides functions to use it. + */ + +#ifndef ZYDIS_FORMATTER_TOKEN_H +#define ZYDIS_FORMATTER_TOKEN_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Constants */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Token types */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @biref Defines the `ZydisTokenType` data-type. + */ +typedef ZyanU8 ZydisTokenType; + +#define ZYDIS_TOKEN_INVALID 0x00 +/** + * A whitespace character. + */ +#define ZYDIS_TOKEN_WHITESPACE 0x01 +/** + * A delimiter character (like `','`, `':'`, `'+'`, `'-'`, `'*'`). + */ +#define ZYDIS_TOKEN_DELIMITER 0x02 +/** + * An opening parenthesis character (like `'('`, `'['`, `'{'`). + */ +#define ZYDIS_TOKEN_PARENTHESIS_OPEN 0x03 +/** + * A closing parenthesis character (like `')'`, `']'`, `'}'`). + */ +#define ZYDIS_TOKEN_PARENTHESIS_CLOSE 0x04 +/** + * A prefix literal (like `"LOCK"`, `"REP"`). + */ +#define ZYDIS_TOKEN_PREFIX 0x05 +/** + * A mnemonic literal (like `"MOV"`, `"VCMPPSD"`, `"LCALL"`). + */ +#define ZYDIS_TOKEN_MNEMONIC 0x06 +/** + * A register literal (like `"RAX"`, `"DS"`, `"%ECX"`). + */ +#define ZYDIS_TOKEN_REGISTER 0x07 +/** + * An absolute address literal (like `0x00400000`). + */ +#define ZYDIS_TOKEN_ADDRESS_ABS 0x08 +/** + * A relative address literal (like `-0x100`). + */ +#define ZYDIS_TOKEN_ADDRESS_REL 0x09 +/** + * A displacement literal (like `0xFFFFFFFF`, `-0x100`, `+0x1234`). + */ +#define ZYDIS_TOKEN_DISPLACEMENT 0x0A +/** + * An immediate literal (like `0xC0`, `-0x1234`, `$0x0000`). + */ +#define ZYDIS_TOKEN_IMMEDIATE 0x0B +/** + * A typecast literal (like `DWORD PTR`). + */ +#define ZYDIS_TOKEN_TYPECAST 0x0C +/** + * A decorator literal (like `"Z"`, `"1TO4"`). + */ +#define ZYDIS_TOKEN_DECORATOR 0x0D +/** + * A symbol literal. + */ +#define ZYDIS_TOKEN_SYMBOL 0x0E + +/** + * The base for user-defined token types. + */ +#define ZYDIS_TOKEN_USER 0x80 + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Token */ +/* ---------------------------------------------------------------------------------------------- */ + +#pragma pack(push, 1) + +/** + * Defines the `ZydisFormatterToken` struct. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZydisFormatterToken_ +{ + /** + * The token type. + */ + ZydisTokenType type; + /** + * An offset to the next token, or `0`. + */ + ZyanU8 next; +} ZydisFormatterToken; + +#pragma pack(pop) + +/** + * Defines the `ZydisFormatterTokenConst` data-type. + */ +typedef const ZydisFormatterToken ZydisFormatterTokenConst; + +/* ---------------------------------------------------------------------------------------------- */ +/* Buffer */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisFormatterBuffer` struct. + * + * All fields in this struct should be considered as "private". Any changes may + * lead to unexpected behavior. + */ +typedef struct ZydisFormatterBuffer_ +{ + /** + * `ZYAN_TRUE`, if the buffer contains a token stream or `ZYAN_FALSE, if it + * contains a simple string. + */ + ZyanBool is_token_list; + /** + * The remaining capacity of the buffer. + */ + ZyanUSize capacity; + /** + * The `ZyanString` instance that refers to the literal value of the most + * recently added token. + */ + ZyanString string; +} ZydisFormatterBuffer; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Token */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the `type` and the string `value` of the given `token`. + * + * @param token A pointer to the `ZydisFormatterToken` struct. + * @param type Receives the token type. + * @param value Receives a pointer to the string value of the token. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenGetValue(const ZydisFormatterToken* token, + ZydisTokenType* type, ZyanConstCharPointer* value); + +/** + * Obtains the next `token` linked to the passed one. + * + * @param token Receives a pointer to the next `ZydisFormatterToken` struct + * linked to the passed one. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenNext(ZydisFormatterTokenConst** token); + +/* ---------------------------------------------------------------------------------------------- */ +/* Buffer */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the current (most recently added) token. + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param token Receives a pointer to the current token. + * + * @return A zyan status code. + * + * This function returns `ZYAN_STATUS_INVALID_OPERATION`, if the buffer does not contain at least + * one token. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferGetToken(const ZydisFormatterBuffer* buffer, + ZydisFormatterTokenConst** token); + +/** + * Returns the `ZyanString` instance associated with the given buffer. + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param string Receives a pointer to the `ZyanString` instance associated with the given + * buffer. + * + * @return A zyan status code. + * + * This function returns `ZYAN_STATUS_INVALID_OPERATION`, if the buffer does not contain at least + * one token. + * + * The returned string always refers to the literal value of the current (most recently added) + * token and will remain valid until the buffer is destroyed. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferGetString(ZydisFormatterBuffer* buffer, + ZyanString** string); + +/** + * Appends a new token to the `buffer`. + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param type The type of the new token. + * + * @return A zyan status code. + * + * Note that the `ZyanString` instance returned by `ZydisFormatterBufferGetString` will + * automatically be updated by calling this function. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferAppend(ZydisFormatterBuffer* buffer, + ZydisTokenType 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. + * + * @return A zyan status code. + * + * Note that the buffer-state is saved inside the buffer itself and thus becomes invalid as soon + * as the buffer gets overwritten or destroyed. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferRemember(const ZydisFormatterBuffer* buffer, + ZyanUPointer* state); + +/** + * Restores a previously saved buffer-state. + * + * @param buffer A pointer to the `ZydisFormatterBuffer` struct. + * @param state The buffer-state to restore. + * + * @return A zyan status code. + * + * All tokens added after obtaining the given `state` snapshot will be removed. This function + * does NOT restore any string content. + * + * Note that the `ZyanString` instance returned by `ZydisFormatterBufferGetString` will + * automatically be updated by calling this function. + */ +ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferRestore(ZydisFormatterBuffer* buffer, + ZyanUPointer state); + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_FORMATTER_TOKEN_H */ diff --git a/src/Zydis/Generated/EnumISAExt.h b/src/Zydis/Generated/EnumISAExt.h new file mode 100644 index 0000000..6de33b7 --- /dev/null +++ b/src/Zydis/Generated/EnumISAExt.h @@ -0,0 +1,98 @@ +/** + * Defines the `ZydisISAExt` enum. + */ +typedef enum ZydisISAExt_ +{ + ZYDIS_ISA_EXT_INVALID, + ZYDIS_ISA_EXT_ADOX_ADCX, + ZYDIS_ISA_EXT_AES, + ZYDIS_ISA_EXT_AMD3DNOW, + ZYDIS_ISA_EXT_AMD3DNOW_PREFETCH, + ZYDIS_ISA_EXT_AMD_INVLPGB, + ZYDIS_ISA_EXT_AMX_BF16, + ZYDIS_ISA_EXT_AMX_INT8, + ZYDIS_ISA_EXT_AMX_TILE, + ZYDIS_ISA_EXT_AVX, + ZYDIS_ISA_EXT_AVX2, + ZYDIS_ISA_EXT_AVX2GATHER, + ZYDIS_ISA_EXT_AVX512EVEX, + ZYDIS_ISA_EXT_AVX512VEX, + ZYDIS_ISA_EXT_AVXAES, + ZYDIS_ISA_EXT_BASE, + ZYDIS_ISA_EXT_BMI1, + ZYDIS_ISA_EXT_BMI2, + ZYDIS_ISA_EXT_CET, + ZYDIS_ISA_EXT_CLDEMOTE, + ZYDIS_ISA_EXT_CLFLUSHOPT, + ZYDIS_ISA_EXT_CLFSH, + ZYDIS_ISA_EXT_CLWB, + ZYDIS_ISA_EXT_CLZERO, + ZYDIS_ISA_EXT_ENQCMD, + ZYDIS_ISA_EXT_F16C, + ZYDIS_ISA_EXT_FMA, + ZYDIS_ISA_EXT_FMA4, + ZYDIS_ISA_EXT_GFNI, + ZYDIS_ISA_EXT_INVPCID, + ZYDIS_ISA_EXT_KNC, + ZYDIS_ISA_EXT_KNCE, + ZYDIS_ISA_EXT_KNCV, + ZYDIS_ISA_EXT_LONGMODE, + ZYDIS_ISA_EXT_LZCNT, + ZYDIS_ISA_EXT_MCOMMIT, + ZYDIS_ISA_EXT_MMX, + ZYDIS_ISA_EXT_MONITOR, + ZYDIS_ISA_EXT_MONITORX, + ZYDIS_ISA_EXT_MOVBE, + ZYDIS_ISA_EXT_MOVDIR, + ZYDIS_ISA_EXT_MPX, + ZYDIS_ISA_EXT_PADLOCK, + ZYDIS_ISA_EXT_PAUSE, + ZYDIS_ISA_EXT_PCLMULQDQ, + ZYDIS_ISA_EXT_PCONFIG, + ZYDIS_ISA_EXT_PKU, + ZYDIS_ISA_EXT_PREFETCHWT1, + ZYDIS_ISA_EXT_PT, + ZYDIS_ISA_EXT_RDPID, + ZYDIS_ISA_EXT_RDPRU, + ZYDIS_ISA_EXT_RDRAND, + ZYDIS_ISA_EXT_RDSEED, + ZYDIS_ISA_EXT_RDTSCP, + ZYDIS_ISA_EXT_RDWRFSGS, + ZYDIS_ISA_EXT_RTM, + ZYDIS_ISA_EXT_SERIALIZE, + ZYDIS_ISA_EXT_SGX, + ZYDIS_ISA_EXT_SGX_ENCLV, + ZYDIS_ISA_EXT_SHA, + ZYDIS_ISA_EXT_SMAP, + ZYDIS_ISA_EXT_SMX, + ZYDIS_ISA_EXT_SNP, + ZYDIS_ISA_EXT_SSE, + ZYDIS_ISA_EXT_SSE2, + ZYDIS_ISA_EXT_SSE3, + ZYDIS_ISA_EXT_SSE4, + ZYDIS_ISA_EXT_SSE4A, + ZYDIS_ISA_EXT_SSSE3, + ZYDIS_ISA_EXT_SVM, + ZYDIS_ISA_EXT_TBM, + ZYDIS_ISA_EXT_TSX_LDTRK, + ZYDIS_ISA_EXT_VAES, + ZYDIS_ISA_EXT_VMFUNC, + ZYDIS_ISA_EXT_VPCLMULQDQ, + ZYDIS_ISA_EXT_VTX, + ZYDIS_ISA_EXT_WAITPKG, + ZYDIS_ISA_EXT_X87, + ZYDIS_ISA_EXT_XOP, + ZYDIS_ISA_EXT_XSAVE, + ZYDIS_ISA_EXT_XSAVEC, + ZYDIS_ISA_EXT_XSAVEOPT, + ZYDIS_ISA_EXT_XSAVES, + + /** + * Maximum value of this enum. + */ + ZYDIS_ISA_EXT_MAX_VALUE = ZYDIS_ISA_EXT_XSAVES, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_ISA_EXT_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_ISA_EXT_MAX_VALUE) +} ZydisISAExt; diff --git a/src/Zydis/Generated/EnumISASet.h b/src/Zydis/Generated/EnumISASet.h new file mode 100644 index 0000000..c04242c --- /dev/null +++ b/src/Zydis/Generated/EnumISASet.h @@ -0,0 +1,184 @@ +/** + * Defines the `ZydisISASet` enum. + */ +typedef enum ZydisISASet_ +{ + ZYDIS_ISA_SET_INVALID, + ZYDIS_ISA_SET_ADOX_ADCX, + ZYDIS_ISA_SET_AES, + ZYDIS_ISA_SET_AMD, + ZYDIS_ISA_SET_AMD3DNOW, + ZYDIS_ISA_SET_AMX_BF16, + ZYDIS_ISA_SET_AMX_INT8, + ZYDIS_ISA_SET_AMX_TILE, + ZYDIS_ISA_SET_AVX, + ZYDIS_ISA_SET_AVX2, + ZYDIS_ISA_SET_AVX2GATHER, + ZYDIS_ISA_SET_AVX512BW_128, + ZYDIS_ISA_SET_AVX512BW_128N, + ZYDIS_ISA_SET_AVX512BW_256, + ZYDIS_ISA_SET_AVX512BW_512, + ZYDIS_ISA_SET_AVX512BW_KOP, + ZYDIS_ISA_SET_AVX512CD_128, + ZYDIS_ISA_SET_AVX512CD_256, + ZYDIS_ISA_SET_AVX512CD_512, + ZYDIS_ISA_SET_AVX512DQ_128, + ZYDIS_ISA_SET_AVX512DQ_128N, + ZYDIS_ISA_SET_AVX512DQ_256, + ZYDIS_ISA_SET_AVX512DQ_512, + ZYDIS_ISA_SET_AVX512DQ_KOP, + ZYDIS_ISA_SET_AVX512DQ_SCALAR, + ZYDIS_ISA_SET_AVX512ER_512, + ZYDIS_ISA_SET_AVX512ER_SCALAR, + ZYDIS_ISA_SET_AVX512F_128, + ZYDIS_ISA_SET_AVX512F_128N, + ZYDIS_ISA_SET_AVX512F_256, + ZYDIS_ISA_SET_AVX512F_512, + ZYDIS_ISA_SET_AVX512F_KOP, + ZYDIS_ISA_SET_AVX512F_SCALAR, + ZYDIS_ISA_SET_AVX512PF_512, + ZYDIS_ISA_SET_AVX512_4FMAPS_512, + ZYDIS_ISA_SET_AVX512_4FMAPS_SCALAR, + ZYDIS_ISA_SET_AVX512_4VNNIW_512, + ZYDIS_ISA_SET_AVX512_BF16_128, + ZYDIS_ISA_SET_AVX512_BF16_256, + ZYDIS_ISA_SET_AVX512_BF16_512, + ZYDIS_ISA_SET_AVX512_BITALG_128, + ZYDIS_ISA_SET_AVX512_BITALG_256, + ZYDIS_ISA_SET_AVX512_BITALG_512, + ZYDIS_ISA_SET_AVX512_GFNI_128, + ZYDIS_ISA_SET_AVX512_GFNI_256, + ZYDIS_ISA_SET_AVX512_GFNI_512, + ZYDIS_ISA_SET_AVX512_IFMA_128, + ZYDIS_ISA_SET_AVX512_IFMA_256, + ZYDIS_ISA_SET_AVX512_IFMA_512, + ZYDIS_ISA_SET_AVX512_VAES_128, + ZYDIS_ISA_SET_AVX512_VAES_256, + ZYDIS_ISA_SET_AVX512_VAES_512, + ZYDIS_ISA_SET_AVX512_VBMI2_128, + ZYDIS_ISA_SET_AVX512_VBMI2_256, + ZYDIS_ISA_SET_AVX512_VBMI2_512, + ZYDIS_ISA_SET_AVX512_VBMI_128, + ZYDIS_ISA_SET_AVX512_VBMI_256, + ZYDIS_ISA_SET_AVX512_VBMI_512, + ZYDIS_ISA_SET_AVX512_VNNI_128, + ZYDIS_ISA_SET_AVX512_VNNI_256, + ZYDIS_ISA_SET_AVX512_VNNI_512, + ZYDIS_ISA_SET_AVX512_VP2INTERSECT_128, + ZYDIS_ISA_SET_AVX512_VP2INTERSECT_256, + ZYDIS_ISA_SET_AVX512_VP2INTERSECT_512, + ZYDIS_ISA_SET_AVX512_VPCLMULQDQ_128, + ZYDIS_ISA_SET_AVX512_VPCLMULQDQ_256, + ZYDIS_ISA_SET_AVX512_VPCLMULQDQ_512, + ZYDIS_ISA_SET_AVX512_VPOPCNTDQ_128, + ZYDIS_ISA_SET_AVX512_VPOPCNTDQ_256, + ZYDIS_ISA_SET_AVX512_VPOPCNTDQ_512, + ZYDIS_ISA_SET_AVXAES, + ZYDIS_ISA_SET_AVX_GFNI, + ZYDIS_ISA_SET_BMI1, + ZYDIS_ISA_SET_BMI2, + ZYDIS_ISA_SET_CET, + ZYDIS_ISA_SET_CLDEMOTE, + ZYDIS_ISA_SET_CLFLUSHOPT, + ZYDIS_ISA_SET_CLFSH, + ZYDIS_ISA_SET_CLWB, + ZYDIS_ISA_SET_CLZERO, + ZYDIS_ISA_SET_CMOV, + ZYDIS_ISA_SET_CMPXCHG16B, + ZYDIS_ISA_SET_ENQCMD, + ZYDIS_ISA_SET_F16C, + ZYDIS_ISA_SET_FAT_NOP, + ZYDIS_ISA_SET_FCMOV, + ZYDIS_ISA_SET_FMA, + ZYDIS_ISA_SET_FMA4, + ZYDIS_ISA_SET_FXSAVE, + ZYDIS_ISA_SET_FXSAVE64, + ZYDIS_ISA_SET_GFNI, + ZYDIS_ISA_SET_I186, + ZYDIS_ISA_SET_I286PROTECTED, + ZYDIS_ISA_SET_I286REAL, + ZYDIS_ISA_SET_I386, + ZYDIS_ISA_SET_I486, + ZYDIS_ISA_SET_I486REAL, + ZYDIS_ISA_SET_I86, + ZYDIS_ISA_SET_INVPCID, + ZYDIS_ISA_SET_KNCE, + ZYDIS_ISA_SET_KNCJKBR, + ZYDIS_ISA_SET_KNCSTREAM, + ZYDIS_ISA_SET_KNCV, + ZYDIS_ISA_SET_KNC_MISC, + ZYDIS_ISA_SET_KNC_PF_HINT, + ZYDIS_ISA_SET_LAHF, + ZYDIS_ISA_SET_LONGMODE, + ZYDIS_ISA_SET_LZCNT, + ZYDIS_ISA_SET_MCOMMIT, + ZYDIS_ISA_SET_MONITOR, + ZYDIS_ISA_SET_MONITORX, + ZYDIS_ISA_SET_MOVBE, + ZYDIS_ISA_SET_MOVDIR, + ZYDIS_ISA_SET_MPX, + ZYDIS_ISA_SET_PADLOCK_ACE, + ZYDIS_ISA_SET_PADLOCK_PHE, + ZYDIS_ISA_SET_PADLOCK_PMM, + ZYDIS_ISA_SET_PADLOCK_RNG, + ZYDIS_ISA_SET_PAUSE, + ZYDIS_ISA_SET_PCLMULQDQ, + ZYDIS_ISA_SET_PCONFIG, + ZYDIS_ISA_SET_PENTIUMMMX, + ZYDIS_ISA_SET_PENTIUMREAL, + ZYDIS_ISA_SET_PKU, + ZYDIS_ISA_SET_POPCNT, + ZYDIS_ISA_SET_PPRO, + ZYDIS_ISA_SET_PREFETCHWT1, + ZYDIS_ISA_SET_PREFETCH_NOP, + ZYDIS_ISA_SET_PT, + ZYDIS_ISA_SET_RDPID, + ZYDIS_ISA_SET_RDPMC, + ZYDIS_ISA_SET_RDPRU, + ZYDIS_ISA_SET_RDRAND, + ZYDIS_ISA_SET_RDSEED, + ZYDIS_ISA_SET_RDTSCP, + ZYDIS_ISA_SET_RDWRFSGS, + ZYDIS_ISA_SET_RTM, + ZYDIS_ISA_SET_SERIALIZE, + ZYDIS_ISA_SET_SGX, + ZYDIS_ISA_SET_SGX_ENCLV, + ZYDIS_ISA_SET_SHA, + ZYDIS_ISA_SET_SMAP, + ZYDIS_ISA_SET_SMX, + ZYDIS_ISA_SET_SSE, + ZYDIS_ISA_SET_SSE2, + ZYDIS_ISA_SET_SSE2MMX, + ZYDIS_ISA_SET_SSE3, + ZYDIS_ISA_SET_SSE3X87, + ZYDIS_ISA_SET_SSE4, + ZYDIS_ISA_SET_SSE42, + ZYDIS_ISA_SET_SSE4A, + ZYDIS_ISA_SET_SSEMXCSR, + ZYDIS_ISA_SET_SSE_PREFETCH, + ZYDIS_ISA_SET_SSSE3, + ZYDIS_ISA_SET_SSSE3MMX, + ZYDIS_ISA_SET_SVM, + ZYDIS_ISA_SET_TBM, + ZYDIS_ISA_SET_TSX_LDTRK, + ZYDIS_ISA_SET_VAES, + ZYDIS_ISA_SET_VMFUNC, + ZYDIS_ISA_SET_VPCLMULQDQ, + ZYDIS_ISA_SET_VTX, + ZYDIS_ISA_SET_WAITPKG, + ZYDIS_ISA_SET_X87, + ZYDIS_ISA_SET_XOP, + ZYDIS_ISA_SET_XSAVE, + ZYDIS_ISA_SET_XSAVEC, + ZYDIS_ISA_SET_XSAVEOPT, + ZYDIS_ISA_SET_XSAVES, + + /** + * Maximum value of this enum. + */ + ZYDIS_ISA_SET_MAX_VALUE = ZYDIS_ISA_SET_XSAVES, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_ISA_SET_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_ISA_SET_MAX_VALUE) +} ZydisISASet; diff --git a/src/Zydis/Generated/EnumInstructionCategory.h b/src/Zydis/Generated/EnumInstructionCategory.h new file mode 100644 index 0000000..755afbc --- /dev/null +++ b/src/Zydis/Generated/EnumInstructionCategory.h @@ -0,0 +1,117 @@ +/** + * Defines the `ZydisInstructionCategory` enum. + */ +typedef enum ZydisInstructionCategory_ +{ + ZYDIS_CATEGORY_INVALID, + ZYDIS_CATEGORY_ADOX_ADCX, + ZYDIS_CATEGORY_AES, + ZYDIS_CATEGORY_AMD3DNOW, + ZYDIS_CATEGORY_AMX_TILE, + ZYDIS_CATEGORY_AVX, + ZYDIS_CATEGORY_AVX2, + ZYDIS_CATEGORY_AVX2GATHER, + ZYDIS_CATEGORY_AVX512, + ZYDIS_CATEGORY_AVX512_4FMAPS, + ZYDIS_CATEGORY_AVX512_4VNNIW, + ZYDIS_CATEGORY_AVX512_BITALG, + ZYDIS_CATEGORY_AVX512_VBMI, + ZYDIS_CATEGORY_AVX512_VP2INTERSECT, + ZYDIS_CATEGORY_BINARY, + ZYDIS_CATEGORY_BITBYTE, + ZYDIS_CATEGORY_BLEND, + ZYDIS_CATEGORY_BMI1, + ZYDIS_CATEGORY_BMI2, + ZYDIS_CATEGORY_BROADCAST, + ZYDIS_CATEGORY_CALL, + ZYDIS_CATEGORY_CET, + ZYDIS_CATEGORY_CLDEMOTE, + ZYDIS_CATEGORY_CLFLUSHOPT, + ZYDIS_CATEGORY_CLWB, + ZYDIS_CATEGORY_CLZERO, + ZYDIS_CATEGORY_CMOV, + ZYDIS_CATEGORY_COMPRESS, + ZYDIS_CATEGORY_COND_BR, + ZYDIS_CATEGORY_CONFLICT, + ZYDIS_CATEGORY_CONVERT, + ZYDIS_CATEGORY_DATAXFER, + ZYDIS_CATEGORY_DECIMAL, + ZYDIS_CATEGORY_ENQCMD, + ZYDIS_CATEGORY_EXPAND, + ZYDIS_CATEGORY_FCMOV, + ZYDIS_CATEGORY_FLAGOP, + ZYDIS_CATEGORY_FMA4, + ZYDIS_CATEGORY_GATHER, + ZYDIS_CATEGORY_GFNI, + ZYDIS_CATEGORY_IFMA, + ZYDIS_CATEGORY_INTERRUPT, + ZYDIS_CATEGORY_IO, + ZYDIS_CATEGORY_IOSTRINGOP, + ZYDIS_CATEGORY_KMASK, + ZYDIS_CATEGORY_KNC, + ZYDIS_CATEGORY_KNCMASK, + ZYDIS_CATEGORY_KNCSCALAR, + ZYDIS_CATEGORY_LOGICAL, + ZYDIS_CATEGORY_LOGICAL_FP, + ZYDIS_CATEGORY_LZCNT, + ZYDIS_CATEGORY_MISC, + ZYDIS_CATEGORY_MMX, + ZYDIS_CATEGORY_MOVDIR, + ZYDIS_CATEGORY_MPX, + ZYDIS_CATEGORY_NOP, + ZYDIS_CATEGORY_PADLOCK, + ZYDIS_CATEGORY_PCLMULQDQ, + ZYDIS_CATEGORY_PCONFIG, + ZYDIS_CATEGORY_PKU, + ZYDIS_CATEGORY_POP, + ZYDIS_CATEGORY_PREFETCH, + ZYDIS_CATEGORY_PREFETCHWT1, + ZYDIS_CATEGORY_PT, + ZYDIS_CATEGORY_PUSH, + ZYDIS_CATEGORY_RDPID, + ZYDIS_CATEGORY_RDPRU, + ZYDIS_CATEGORY_RDRAND, + ZYDIS_CATEGORY_RDSEED, + ZYDIS_CATEGORY_RDWRFSGS, + ZYDIS_CATEGORY_RET, + ZYDIS_CATEGORY_ROTATE, + ZYDIS_CATEGORY_SCATTER, + ZYDIS_CATEGORY_SEGOP, + ZYDIS_CATEGORY_SEMAPHORE, + ZYDIS_CATEGORY_SERIALIZE, + ZYDIS_CATEGORY_SETCC, + ZYDIS_CATEGORY_SGX, + ZYDIS_CATEGORY_SHA, + ZYDIS_CATEGORY_SHIFT, + ZYDIS_CATEGORY_SMAP, + ZYDIS_CATEGORY_SSE, + ZYDIS_CATEGORY_STRINGOP, + ZYDIS_CATEGORY_STTNI, + ZYDIS_CATEGORY_SYSCALL, + ZYDIS_CATEGORY_SYSRET, + ZYDIS_CATEGORY_SYSTEM, + ZYDIS_CATEGORY_TBM, + ZYDIS_CATEGORY_TSX_LDTRK, + ZYDIS_CATEGORY_UFMA, + ZYDIS_CATEGORY_UNCOND_BR, + ZYDIS_CATEGORY_VAES, + ZYDIS_CATEGORY_VBMI2, + ZYDIS_CATEGORY_VFMA, + ZYDIS_CATEGORY_VPCLMULQDQ, + ZYDIS_CATEGORY_VTX, + ZYDIS_CATEGORY_WAITPKG, + ZYDIS_CATEGORY_WIDENOP, + ZYDIS_CATEGORY_X87_ALU, + ZYDIS_CATEGORY_XOP, + ZYDIS_CATEGORY_XSAVE, + ZYDIS_CATEGORY_XSAVEOPT, + + /** + * Maximum value of this enum. + */ + ZYDIS_CATEGORY_MAX_VALUE = ZYDIS_CATEGORY_XSAVEOPT, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_CATEGORY_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_CATEGORY_MAX_VALUE) +} ZydisInstructionCategory; diff --git a/src/Zydis/Generated/EnumMnemonic.h b/src/Zydis/Generated/EnumMnemonic.h new file mode 100644 index 0000000..bcb6265 --- /dev/null +++ b/src/Zydis/Generated/EnumMnemonic.h @@ -0,0 +1,1643 @@ +/** + * Defines the `ZydisMnemonic` enum. + */ +typedef enum ZydisMnemonic_ +{ + ZYDIS_MNEMONIC_INVALID, + ZYDIS_MNEMONIC_AAA, + ZYDIS_MNEMONIC_AAD, + ZYDIS_MNEMONIC_AAM, + ZYDIS_MNEMONIC_AAS, + ZYDIS_MNEMONIC_ADC, + ZYDIS_MNEMONIC_ADCX, + ZYDIS_MNEMONIC_ADD, + ZYDIS_MNEMONIC_ADDPD, + ZYDIS_MNEMONIC_ADDPS, + ZYDIS_MNEMONIC_ADDSD, + ZYDIS_MNEMONIC_ADDSS, + ZYDIS_MNEMONIC_ADDSUBPD, + ZYDIS_MNEMONIC_ADDSUBPS, + ZYDIS_MNEMONIC_ADOX, + ZYDIS_MNEMONIC_AESDEC, + ZYDIS_MNEMONIC_AESDECLAST, + ZYDIS_MNEMONIC_AESENC, + ZYDIS_MNEMONIC_AESENCLAST, + ZYDIS_MNEMONIC_AESIMC, + ZYDIS_MNEMONIC_AESKEYGENASSIST, + ZYDIS_MNEMONIC_AND, + ZYDIS_MNEMONIC_ANDN, + ZYDIS_MNEMONIC_ANDNPD, + ZYDIS_MNEMONIC_ANDNPS, + ZYDIS_MNEMONIC_ANDPD, + ZYDIS_MNEMONIC_ANDPS, + ZYDIS_MNEMONIC_ARPL, + ZYDIS_MNEMONIC_BEXTR, + ZYDIS_MNEMONIC_BLCFILL, + ZYDIS_MNEMONIC_BLCI, + ZYDIS_MNEMONIC_BLCIC, + ZYDIS_MNEMONIC_BLCMSK, + ZYDIS_MNEMONIC_BLCS, + ZYDIS_MNEMONIC_BLENDPD, + ZYDIS_MNEMONIC_BLENDPS, + ZYDIS_MNEMONIC_BLENDVPD, + ZYDIS_MNEMONIC_BLENDVPS, + ZYDIS_MNEMONIC_BLSFILL, + ZYDIS_MNEMONIC_BLSI, + ZYDIS_MNEMONIC_BLSIC, + ZYDIS_MNEMONIC_BLSMSK, + ZYDIS_MNEMONIC_BLSR, + ZYDIS_MNEMONIC_BNDCL, + ZYDIS_MNEMONIC_BNDCN, + ZYDIS_MNEMONIC_BNDCU, + ZYDIS_MNEMONIC_BNDLDX, + ZYDIS_MNEMONIC_BNDMK, + ZYDIS_MNEMONIC_BNDMOV, + ZYDIS_MNEMONIC_BNDSTX, + ZYDIS_MNEMONIC_BOUND, + ZYDIS_MNEMONIC_BSF, + ZYDIS_MNEMONIC_BSR, + ZYDIS_MNEMONIC_BSWAP, + ZYDIS_MNEMONIC_BT, + ZYDIS_MNEMONIC_BTC, + ZYDIS_MNEMONIC_BTR, + ZYDIS_MNEMONIC_BTS, + ZYDIS_MNEMONIC_BZHI, + ZYDIS_MNEMONIC_CALL, + ZYDIS_MNEMONIC_CBW, + ZYDIS_MNEMONIC_CDQ, + ZYDIS_MNEMONIC_CDQE, + ZYDIS_MNEMONIC_CLAC, + ZYDIS_MNEMONIC_CLC, + ZYDIS_MNEMONIC_CLD, + ZYDIS_MNEMONIC_CLDEMOTE, + ZYDIS_MNEMONIC_CLEVICT0, + ZYDIS_MNEMONIC_CLEVICT1, + ZYDIS_MNEMONIC_CLFLUSH, + ZYDIS_MNEMONIC_CLFLUSHOPT, + ZYDIS_MNEMONIC_CLGI, + ZYDIS_MNEMONIC_CLI, + ZYDIS_MNEMONIC_CLRSSBSY, + ZYDIS_MNEMONIC_CLTS, + ZYDIS_MNEMONIC_CLWB, + ZYDIS_MNEMONIC_CLZERO, + ZYDIS_MNEMONIC_CMC, + ZYDIS_MNEMONIC_CMOVB, + ZYDIS_MNEMONIC_CMOVBE, + ZYDIS_MNEMONIC_CMOVL, + ZYDIS_MNEMONIC_CMOVLE, + ZYDIS_MNEMONIC_CMOVNB, + ZYDIS_MNEMONIC_CMOVNBE, + ZYDIS_MNEMONIC_CMOVNL, + ZYDIS_MNEMONIC_CMOVNLE, + ZYDIS_MNEMONIC_CMOVNO, + ZYDIS_MNEMONIC_CMOVNP, + ZYDIS_MNEMONIC_CMOVNS, + ZYDIS_MNEMONIC_CMOVNZ, + ZYDIS_MNEMONIC_CMOVO, + ZYDIS_MNEMONIC_CMOVP, + ZYDIS_MNEMONIC_CMOVS, + ZYDIS_MNEMONIC_CMOVZ, + ZYDIS_MNEMONIC_CMP, + ZYDIS_MNEMONIC_CMPPD, + ZYDIS_MNEMONIC_CMPPS, + ZYDIS_MNEMONIC_CMPSB, + ZYDIS_MNEMONIC_CMPSD, + ZYDIS_MNEMONIC_CMPSQ, + ZYDIS_MNEMONIC_CMPSS, + ZYDIS_MNEMONIC_CMPSW, + ZYDIS_MNEMONIC_CMPXCHG, + ZYDIS_MNEMONIC_CMPXCHG16B, + ZYDIS_MNEMONIC_CMPXCHG8B, + ZYDIS_MNEMONIC_COMISD, + ZYDIS_MNEMONIC_COMISS, + ZYDIS_MNEMONIC_CPUID, + ZYDIS_MNEMONIC_CQO, + ZYDIS_MNEMONIC_CRC32, + ZYDIS_MNEMONIC_CVTDQ2PD, + ZYDIS_MNEMONIC_CVTDQ2PS, + ZYDIS_MNEMONIC_CVTPD2DQ, + ZYDIS_MNEMONIC_CVTPD2PI, + ZYDIS_MNEMONIC_CVTPD2PS, + ZYDIS_MNEMONIC_CVTPI2PD, + ZYDIS_MNEMONIC_CVTPI2PS, + ZYDIS_MNEMONIC_CVTPS2DQ, + ZYDIS_MNEMONIC_CVTPS2PD, + ZYDIS_MNEMONIC_CVTPS2PI, + ZYDIS_MNEMONIC_CVTSD2SI, + ZYDIS_MNEMONIC_CVTSD2SS, + ZYDIS_MNEMONIC_CVTSI2SD, + ZYDIS_MNEMONIC_CVTSI2SS, + ZYDIS_MNEMONIC_CVTSS2SD, + ZYDIS_MNEMONIC_CVTSS2SI, + ZYDIS_MNEMONIC_CVTTPD2DQ, + ZYDIS_MNEMONIC_CVTTPD2PI, + ZYDIS_MNEMONIC_CVTTPS2DQ, + ZYDIS_MNEMONIC_CVTTPS2PI, + ZYDIS_MNEMONIC_CVTTSD2SI, + ZYDIS_MNEMONIC_CVTTSS2SI, + ZYDIS_MNEMONIC_CWD, + ZYDIS_MNEMONIC_CWDE, + ZYDIS_MNEMONIC_DAA, + ZYDIS_MNEMONIC_DAS, + ZYDIS_MNEMONIC_DEC, + ZYDIS_MNEMONIC_DELAY, + ZYDIS_MNEMONIC_DIV, + ZYDIS_MNEMONIC_DIVPD, + ZYDIS_MNEMONIC_DIVPS, + ZYDIS_MNEMONIC_DIVSD, + ZYDIS_MNEMONIC_DIVSS, + ZYDIS_MNEMONIC_DPPD, + ZYDIS_MNEMONIC_DPPS, + ZYDIS_MNEMONIC_EMMS, + ZYDIS_MNEMONIC_ENCLS, + ZYDIS_MNEMONIC_ENCLU, + ZYDIS_MNEMONIC_ENCLV, + ZYDIS_MNEMONIC_ENDBR32, + ZYDIS_MNEMONIC_ENDBR64, + ZYDIS_MNEMONIC_ENQCMD, + ZYDIS_MNEMONIC_ENQCMDS, + ZYDIS_MNEMONIC_ENTER, + ZYDIS_MNEMONIC_EXTRACTPS, + ZYDIS_MNEMONIC_EXTRQ, + ZYDIS_MNEMONIC_F2XM1, + ZYDIS_MNEMONIC_FABS, + ZYDIS_MNEMONIC_FADD, + ZYDIS_MNEMONIC_FADDP, + ZYDIS_MNEMONIC_FBLD, + ZYDIS_MNEMONIC_FBSTP, + ZYDIS_MNEMONIC_FCHS, + ZYDIS_MNEMONIC_FCMOVB, + ZYDIS_MNEMONIC_FCMOVBE, + ZYDIS_MNEMONIC_FCMOVE, + ZYDIS_MNEMONIC_FCMOVNB, + ZYDIS_MNEMONIC_FCMOVNBE, + ZYDIS_MNEMONIC_FCMOVNE, + ZYDIS_MNEMONIC_FCMOVNU, + ZYDIS_MNEMONIC_FCMOVU, + ZYDIS_MNEMONIC_FCOM, + ZYDIS_MNEMONIC_FCOMI, + ZYDIS_MNEMONIC_FCOMIP, + ZYDIS_MNEMONIC_FCOMP, + ZYDIS_MNEMONIC_FCOMPP, + ZYDIS_MNEMONIC_FCOS, + ZYDIS_MNEMONIC_FDECSTP, + ZYDIS_MNEMONIC_FDISI8087_NOP, + ZYDIS_MNEMONIC_FDIV, + ZYDIS_MNEMONIC_FDIVP, + ZYDIS_MNEMONIC_FDIVR, + ZYDIS_MNEMONIC_FDIVRP, + ZYDIS_MNEMONIC_FEMMS, + ZYDIS_MNEMONIC_FENI8087_NOP, + ZYDIS_MNEMONIC_FFREE, + ZYDIS_MNEMONIC_FFREEP, + ZYDIS_MNEMONIC_FIADD, + ZYDIS_MNEMONIC_FICOM, + ZYDIS_MNEMONIC_FICOMP, + ZYDIS_MNEMONIC_FIDIV, + ZYDIS_MNEMONIC_FIDIVR, + ZYDIS_MNEMONIC_FILD, + ZYDIS_MNEMONIC_FIMUL, + ZYDIS_MNEMONIC_FINCSTP, + ZYDIS_MNEMONIC_FIST, + ZYDIS_MNEMONIC_FISTP, + ZYDIS_MNEMONIC_FISTTP, + ZYDIS_MNEMONIC_FISUB, + ZYDIS_MNEMONIC_FISUBR, + ZYDIS_MNEMONIC_FLD, + ZYDIS_MNEMONIC_FLD1, + ZYDIS_MNEMONIC_FLDCW, + ZYDIS_MNEMONIC_FLDENV, + ZYDIS_MNEMONIC_FLDL2E, + ZYDIS_MNEMONIC_FLDL2T, + ZYDIS_MNEMONIC_FLDLG2, + ZYDIS_MNEMONIC_FLDLN2, + ZYDIS_MNEMONIC_FLDPI, + ZYDIS_MNEMONIC_FLDZ, + ZYDIS_MNEMONIC_FMUL, + ZYDIS_MNEMONIC_FMULP, + ZYDIS_MNEMONIC_FNCLEX, + ZYDIS_MNEMONIC_FNINIT, + ZYDIS_MNEMONIC_FNOP, + ZYDIS_MNEMONIC_FNSAVE, + ZYDIS_MNEMONIC_FNSTCW, + ZYDIS_MNEMONIC_FNSTENV, + ZYDIS_MNEMONIC_FNSTSW, + ZYDIS_MNEMONIC_FPATAN, + ZYDIS_MNEMONIC_FPREM, + ZYDIS_MNEMONIC_FPREM1, + ZYDIS_MNEMONIC_FPTAN, + ZYDIS_MNEMONIC_FRNDINT, + ZYDIS_MNEMONIC_FRSTOR, + ZYDIS_MNEMONIC_FSCALE, + ZYDIS_MNEMONIC_FSETPM287_NOP, + ZYDIS_MNEMONIC_FSIN, + ZYDIS_MNEMONIC_FSINCOS, + ZYDIS_MNEMONIC_FSQRT, + ZYDIS_MNEMONIC_FST, + ZYDIS_MNEMONIC_FSTP, + ZYDIS_MNEMONIC_FSTPNCE, + ZYDIS_MNEMONIC_FSUB, + ZYDIS_MNEMONIC_FSUBP, + ZYDIS_MNEMONIC_FSUBR, + ZYDIS_MNEMONIC_FSUBRP, + ZYDIS_MNEMONIC_FTST, + ZYDIS_MNEMONIC_FUCOM, + ZYDIS_MNEMONIC_FUCOMI, + ZYDIS_MNEMONIC_FUCOMIP, + ZYDIS_MNEMONIC_FUCOMP, + ZYDIS_MNEMONIC_FUCOMPP, + ZYDIS_MNEMONIC_FWAIT, + ZYDIS_MNEMONIC_FXAM, + ZYDIS_MNEMONIC_FXCH, + ZYDIS_MNEMONIC_FXRSTOR, + ZYDIS_MNEMONIC_FXRSTOR64, + ZYDIS_MNEMONIC_FXSAVE, + ZYDIS_MNEMONIC_FXSAVE64, + ZYDIS_MNEMONIC_FXTRACT, + ZYDIS_MNEMONIC_FYL2X, + ZYDIS_MNEMONIC_FYL2XP1, + ZYDIS_MNEMONIC_GETSEC, + ZYDIS_MNEMONIC_GF2P8AFFINEINVQB, + ZYDIS_MNEMONIC_GF2P8AFFINEQB, + ZYDIS_MNEMONIC_GF2P8MULB, + ZYDIS_MNEMONIC_HADDPD, + ZYDIS_MNEMONIC_HADDPS, + ZYDIS_MNEMONIC_HLT, + ZYDIS_MNEMONIC_HSUBPD, + ZYDIS_MNEMONIC_HSUBPS, + ZYDIS_MNEMONIC_IDIV, + ZYDIS_MNEMONIC_IMUL, + ZYDIS_MNEMONIC_IN, + ZYDIS_MNEMONIC_INC, + ZYDIS_MNEMONIC_INCSSPD, + ZYDIS_MNEMONIC_INCSSPQ, + ZYDIS_MNEMONIC_INSB, + ZYDIS_MNEMONIC_INSD, + ZYDIS_MNEMONIC_INSERTPS, + ZYDIS_MNEMONIC_INSERTQ, + ZYDIS_MNEMONIC_INSW, + ZYDIS_MNEMONIC_INT, + ZYDIS_MNEMONIC_INT1, + ZYDIS_MNEMONIC_INT3, + ZYDIS_MNEMONIC_INTO, + ZYDIS_MNEMONIC_INVD, + ZYDIS_MNEMONIC_INVEPT, + ZYDIS_MNEMONIC_INVLPG, + ZYDIS_MNEMONIC_INVLPGA, + ZYDIS_MNEMONIC_INVLPGB, + ZYDIS_MNEMONIC_INVPCID, + ZYDIS_MNEMONIC_INVVPID, + ZYDIS_MNEMONIC_IRET, + ZYDIS_MNEMONIC_IRETD, + ZYDIS_MNEMONIC_IRETQ, + ZYDIS_MNEMONIC_JB, + ZYDIS_MNEMONIC_JBE, + ZYDIS_MNEMONIC_JCXZ, + ZYDIS_MNEMONIC_JECXZ, + ZYDIS_MNEMONIC_JKNZD, + ZYDIS_MNEMONIC_JKZD, + ZYDIS_MNEMONIC_JL, + ZYDIS_MNEMONIC_JLE, + ZYDIS_MNEMONIC_JMP, + ZYDIS_MNEMONIC_JNB, + ZYDIS_MNEMONIC_JNBE, + ZYDIS_MNEMONIC_JNL, + ZYDIS_MNEMONIC_JNLE, + ZYDIS_MNEMONIC_JNO, + ZYDIS_MNEMONIC_JNP, + ZYDIS_MNEMONIC_JNS, + ZYDIS_MNEMONIC_JNZ, + ZYDIS_MNEMONIC_JO, + ZYDIS_MNEMONIC_JP, + ZYDIS_MNEMONIC_JRCXZ, + ZYDIS_MNEMONIC_JS, + ZYDIS_MNEMONIC_JZ, + ZYDIS_MNEMONIC_KADDB, + ZYDIS_MNEMONIC_KADDD, + ZYDIS_MNEMONIC_KADDQ, + ZYDIS_MNEMONIC_KADDW, + ZYDIS_MNEMONIC_KAND, + ZYDIS_MNEMONIC_KANDB, + ZYDIS_MNEMONIC_KANDD, + ZYDIS_MNEMONIC_KANDN, + ZYDIS_MNEMONIC_KANDNB, + ZYDIS_MNEMONIC_KANDND, + ZYDIS_MNEMONIC_KANDNQ, + ZYDIS_MNEMONIC_KANDNR, + ZYDIS_MNEMONIC_KANDNW, + ZYDIS_MNEMONIC_KANDQ, + ZYDIS_MNEMONIC_KANDW, + ZYDIS_MNEMONIC_KCONCATH, + ZYDIS_MNEMONIC_KCONCATL, + ZYDIS_MNEMONIC_KEXTRACT, + ZYDIS_MNEMONIC_KMERGE2L1H, + ZYDIS_MNEMONIC_KMERGE2L1L, + ZYDIS_MNEMONIC_KMOV, + ZYDIS_MNEMONIC_KMOVB, + ZYDIS_MNEMONIC_KMOVD, + ZYDIS_MNEMONIC_KMOVQ, + ZYDIS_MNEMONIC_KMOVW, + ZYDIS_MNEMONIC_KNOT, + ZYDIS_MNEMONIC_KNOTB, + ZYDIS_MNEMONIC_KNOTD, + ZYDIS_MNEMONIC_KNOTQ, + ZYDIS_MNEMONIC_KNOTW, + ZYDIS_MNEMONIC_KOR, + ZYDIS_MNEMONIC_KORB, + ZYDIS_MNEMONIC_KORD, + ZYDIS_MNEMONIC_KORQ, + ZYDIS_MNEMONIC_KORTEST, + ZYDIS_MNEMONIC_KORTESTB, + ZYDIS_MNEMONIC_KORTESTD, + ZYDIS_MNEMONIC_KORTESTQ, + ZYDIS_MNEMONIC_KORTESTW, + ZYDIS_MNEMONIC_KORW, + ZYDIS_MNEMONIC_KSHIFTLB, + ZYDIS_MNEMONIC_KSHIFTLD, + ZYDIS_MNEMONIC_KSHIFTLQ, + ZYDIS_MNEMONIC_KSHIFTLW, + ZYDIS_MNEMONIC_KSHIFTRB, + ZYDIS_MNEMONIC_KSHIFTRD, + ZYDIS_MNEMONIC_KSHIFTRQ, + ZYDIS_MNEMONIC_KSHIFTRW, + ZYDIS_MNEMONIC_KTESTB, + ZYDIS_MNEMONIC_KTESTD, + ZYDIS_MNEMONIC_KTESTQ, + ZYDIS_MNEMONIC_KTESTW, + ZYDIS_MNEMONIC_KUNPCKBW, + ZYDIS_MNEMONIC_KUNPCKDQ, + ZYDIS_MNEMONIC_KUNPCKWD, + ZYDIS_MNEMONIC_KXNOR, + ZYDIS_MNEMONIC_KXNORB, + ZYDIS_MNEMONIC_KXNORD, + ZYDIS_MNEMONIC_KXNORQ, + ZYDIS_MNEMONIC_KXNORW, + ZYDIS_MNEMONIC_KXOR, + ZYDIS_MNEMONIC_KXORB, + ZYDIS_MNEMONIC_KXORD, + ZYDIS_MNEMONIC_KXORQ, + ZYDIS_MNEMONIC_KXORW, + ZYDIS_MNEMONIC_LAHF, + ZYDIS_MNEMONIC_LAR, + ZYDIS_MNEMONIC_LDDQU, + ZYDIS_MNEMONIC_LDMXCSR, + ZYDIS_MNEMONIC_LDS, + ZYDIS_MNEMONIC_LDTILECFG, + ZYDIS_MNEMONIC_LEA, + ZYDIS_MNEMONIC_LEAVE, + ZYDIS_MNEMONIC_LES, + ZYDIS_MNEMONIC_LFENCE, + ZYDIS_MNEMONIC_LFS, + ZYDIS_MNEMONIC_LGDT, + ZYDIS_MNEMONIC_LGS, + ZYDIS_MNEMONIC_LIDT, + ZYDIS_MNEMONIC_LLDT, + ZYDIS_MNEMONIC_LLWPCB, + ZYDIS_MNEMONIC_LMSW, + ZYDIS_MNEMONIC_LODSB, + ZYDIS_MNEMONIC_LODSD, + ZYDIS_MNEMONIC_LODSQ, + ZYDIS_MNEMONIC_LODSW, + ZYDIS_MNEMONIC_LOOP, + ZYDIS_MNEMONIC_LOOPE, + ZYDIS_MNEMONIC_LOOPNE, + ZYDIS_MNEMONIC_LSL, + ZYDIS_MNEMONIC_LSS, + ZYDIS_MNEMONIC_LTR, + ZYDIS_MNEMONIC_LWPINS, + ZYDIS_MNEMONIC_LWPVAL, + ZYDIS_MNEMONIC_LZCNT, + ZYDIS_MNEMONIC_MASKMOVDQU, + ZYDIS_MNEMONIC_MASKMOVQ, + ZYDIS_MNEMONIC_MAXPD, + ZYDIS_MNEMONIC_MAXPS, + ZYDIS_MNEMONIC_MAXSD, + ZYDIS_MNEMONIC_MAXSS, + ZYDIS_MNEMONIC_MCOMMIT, + ZYDIS_MNEMONIC_MFENCE, + ZYDIS_MNEMONIC_MINPD, + ZYDIS_MNEMONIC_MINPS, + ZYDIS_MNEMONIC_MINSD, + ZYDIS_MNEMONIC_MINSS, + ZYDIS_MNEMONIC_MONITOR, + ZYDIS_MNEMONIC_MONITORX, + ZYDIS_MNEMONIC_MONTMUL, + ZYDIS_MNEMONIC_MOV, + ZYDIS_MNEMONIC_MOVAPD, + ZYDIS_MNEMONIC_MOVAPS, + ZYDIS_MNEMONIC_MOVBE, + ZYDIS_MNEMONIC_MOVD, + ZYDIS_MNEMONIC_MOVDDUP, + ZYDIS_MNEMONIC_MOVDIR64B, + ZYDIS_MNEMONIC_MOVDIRI, + ZYDIS_MNEMONIC_MOVDQ2Q, + ZYDIS_MNEMONIC_MOVDQA, + ZYDIS_MNEMONIC_MOVDQU, + ZYDIS_MNEMONIC_MOVHLPS, + ZYDIS_MNEMONIC_MOVHPD, + ZYDIS_MNEMONIC_MOVHPS, + ZYDIS_MNEMONIC_MOVLHPS, + ZYDIS_MNEMONIC_MOVLPD, + ZYDIS_MNEMONIC_MOVLPS, + ZYDIS_MNEMONIC_MOVMSKPD, + ZYDIS_MNEMONIC_MOVMSKPS, + ZYDIS_MNEMONIC_MOVNTDQ, + ZYDIS_MNEMONIC_MOVNTDQA, + ZYDIS_MNEMONIC_MOVNTI, + ZYDIS_MNEMONIC_MOVNTPD, + ZYDIS_MNEMONIC_MOVNTPS, + ZYDIS_MNEMONIC_MOVNTQ, + ZYDIS_MNEMONIC_MOVNTSD, + ZYDIS_MNEMONIC_MOVNTSS, + ZYDIS_MNEMONIC_MOVQ, + ZYDIS_MNEMONIC_MOVQ2DQ, + ZYDIS_MNEMONIC_MOVSB, + ZYDIS_MNEMONIC_MOVSD, + ZYDIS_MNEMONIC_MOVSHDUP, + ZYDIS_MNEMONIC_MOVSLDUP, + ZYDIS_MNEMONIC_MOVSQ, + ZYDIS_MNEMONIC_MOVSS, + ZYDIS_MNEMONIC_MOVSW, + ZYDIS_MNEMONIC_MOVSX, + ZYDIS_MNEMONIC_MOVSXD, + ZYDIS_MNEMONIC_MOVUPD, + ZYDIS_MNEMONIC_MOVUPS, + ZYDIS_MNEMONIC_MOVZX, + ZYDIS_MNEMONIC_MPSADBW, + ZYDIS_MNEMONIC_MUL, + ZYDIS_MNEMONIC_MULPD, + ZYDIS_MNEMONIC_MULPS, + ZYDIS_MNEMONIC_MULSD, + ZYDIS_MNEMONIC_MULSS, + ZYDIS_MNEMONIC_MULX, + ZYDIS_MNEMONIC_MWAIT, + ZYDIS_MNEMONIC_MWAITX, + ZYDIS_MNEMONIC_NEG, + ZYDIS_MNEMONIC_NOP, + ZYDIS_MNEMONIC_NOT, + ZYDIS_MNEMONIC_OR, + ZYDIS_MNEMONIC_ORPD, + ZYDIS_MNEMONIC_ORPS, + ZYDIS_MNEMONIC_OUT, + ZYDIS_MNEMONIC_OUTSB, + ZYDIS_MNEMONIC_OUTSD, + ZYDIS_MNEMONIC_OUTSW, + ZYDIS_MNEMONIC_PABSB, + ZYDIS_MNEMONIC_PABSD, + ZYDIS_MNEMONIC_PABSW, + ZYDIS_MNEMONIC_PACKSSDW, + ZYDIS_MNEMONIC_PACKSSWB, + ZYDIS_MNEMONIC_PACKUSDW, + ZYDIS_MNEMONIC_PACKUSWB, + ZYDIS_MNEMONIC_PADDB, + ZYDIS_MNEMONIC_PADDD, + ZYDIS_MNEMONIC_PADDQ, + ZYDIS_MNEMONIC_PADDSB, + ZYDIS_MNEMONIC_PADDSW, + ZYDIS_MNEMONIC_PADDUSB, + ZYDIS_MNEMONIC_PADDUSW, + ZYDIS_MNEMONIC_PADDW, + ZYDIS_MNEMONIC_PALIGNR, + ZYDIS_MNEMONIC_PAND, + ZYDIS_MNEMONIC_PANDN, + ZYDIS_MNEMONIC_PAUSE, + ZYDIS_MNEMONIC_PAVGB, + ZYDIS_MNEMONIC_PAVGUSB, + ZYDIS_MNEMONIC_PAVGW, + ZYDIS_MNEMONIC_PBLENDVB, + ZYDIS_MNEMONIC_PBLENDW, + ZYDIS_MNEMONIC_PCLMULQDQ, + ZYDIS_MNEMONIC_PCMPEQB, + ZYDIS_MNEMONIC_PCMPEQD, + ZYDIS_MNEMONIC_PCMPEQQ, + ZYDIS_MNEMONIC_PCMPEQW, + ZYDIS_MNEMONIC_PCMPESTRI, + ZYDIS_MNEMONIC_PCMPESTRM, + ZYDIS_MNEMONIC_PCMPGTB, + ZYDIS_MNEMONIC_PCMPGTD, + ZYDIS_MNEMONIC_PCMPGTQ, + ZYDIS_MNEMONIC_PCMPGTW, + ZYDIS_MNEMONIC_PCMPISTRI, + ZYDIS_MNEMONIC_PCMPISTRM, + ZYDIS_MNEMONIC_PCONFIG, + ZYDIS_MNEMONIC_PDEP, + ZYDIS_MNEMONIC_PEXT, + ZYDIS_MNEMONIC_PEXTRB, + ZYDIS_MNEMONIC_PEXTRD, + ZYDIS_MNEMONIC_PEXTRQ, + ZYDIS_MNEMONIC_PEXTRW, + ZYDIS_MNEMONIC_PF2ID, + ZYDIS_MNEMONIC_PF2IW, + ZYDIS_MNEMONIC_PFACC, + ZYDIS_MNEMONIC_PFADD, + ZYDIS_MNEMONIC_PFCMPEQ, + ZYDIS_MNEMONIC_PFCMPGE, + ZYDIS_MNEMONIC_PFCMPGT, + ZYDIS_MNEMONIC_PFCPIT1, + ZYDIS_MNEMONIC_PFMAX, + ZYDIS_MNEMONIC_PFMIN, + ZYDIS_MNEMONIC_PFMUL, + ZYDIS_MNEMONIC_PFNACC, + ZYDIS_MNEMONIC_PFPNACC, + ZYDIS_MNEMONIC_PFRCP, + ZYDIS_MNEMONIC_PFRCPIT2, + ZYDIS_MNEMONIC_PFRSQIT1, + ZYDIS_MNEMONIC_PFSQRT, + ZYDIS_MNEMONIC_PFSUB, + ZYDIS_MNEMONIC_PFSUBR, + ZYDIS_MNEMONIC_PHADDD, + ZYDIS_MNEMONIC_PHADDSW, + ZYDIS_MNEMONIC_PHADDW, + ZYDIS_MNEMONIC_PHMINPOSUW, + ZYDIS_MNEMONIC_PHSUBD, + ZYDIS_MNEMONIC_PHSUBSW, + ZYDIS_MNEMONIC_PHSUBW, + ZYDIS_MNEMONIC_PI2FD, + ZYDIS_MNEMONIC_PI2FW, + ZYDIS_MNEMONIC_PINSRB, + ZYDIS_MNEMONIC_PINSRD, + ZYDIS_MNEMONIC_PINSRQ, + ZYDIS_MNEMONIC_PINSRW, + ZYDIS_MNEMONIC_PMADDUBSW, + ZYDIS_MNEMONIC_PMADDWD, + ZYDIS_MNEMONIC_PMAXSB, + ZYDIS_MNEMONIC_PMAXSD, + ZYDIS_MNEMONIC_PMAXSW, + ZYDIS_MNEMONIC_PMAXUB, + ZYDIS_MNEMONIC_PMAXUD, + ZYDIS_MNEMONIC_PMAXUW, + ZYDIS_MNEMONIC_PMINSB, + ZYDIS_MNEMONIC_PMINSD, + ZYDIS_MNEMONIC_PMINSW, + ZYDIS_MNEMONIC_PMINUB, + ZYDIS_MNEMONIC_PMINUD, + ZYDIS_MNEMONIC_PMINUW, + ZYDIS_MNEMONIC_PMOVMSKB, + ZYDIS_MNEMONIC_PMOVSXBD, + ZYDIS_MNEMONIC_PMOVSXBQ, + ZYDIS_MNEMONIC_PMOVSXBW, + ZYDIS_MNEMONIC_PMOVSXDQ, + ZYDIS_MNEMONIC_PMOVSXWD, + ZYDIS_MNEMONIC_PMOVSXWQ, + ZYDIS_MNEMONIC_PMOVZXBD, + ZYDIS_MNEMONIC_PMOVZXBQ, + ZYDIS_MNEMONIC_PMOVZXBW, + ZYDIS_MNEMONIC_PMOVZXDQ, + ZYDIS_MNEMONIC_PMOVZXWD, + ZYDIS_MNEMONIC_PMOVZXWQ, + ZYDIS_MNEMONIC_PMULDQ, + ZYDIS_MNEMONIC_PMULHRSW, + ZYDIS_MNEMONIC_PMULHRW, + ZYDIS_MNEMONIC_PMULHUW, + ZYDIS_MNEMONIC_PMULHW, + ZYDIS_MNEMONIC_PMULLD, + ZYDIS_MNEMONIC_PMULLW, + ZYDIS_MNEMONIC_PMULUDQ, + ZYDIS_MNEMONIC_POP, + ZYDIS_MNEMONIC_POPA, + ZYDIS_MNEMONIC_POPAD, + ZYDIS_MNEMONIC_POPCNT, + ZYDIS_MNEMONIC_POPF, + ZYDIS_MNEMONIC_POPFD, + ZYDIS_MNEMONIC_POPFQ, + ZYDIS_MNEMONIC_POR, + ZYDIS_MNEMONIC_PREFETCH, + ZYDIS_MNEMONIC_PREFETCHNTA, + ZYDIS_MNEMONIC_PREFETCHT0, + ZYDIS_MNEMONIC_PREFETCHT1, + ZYDIS_MNEMONIC_PREFETCHT2, + ZYDIS_MNEMONIC_PREFETCHW, + ZYDIS_MNEMONIC_PREFETCHWT1, + ZYDIS_MNEMONIC_PSADBW, + ZYDIS_MNEMONIC_PSHUFB, + ZYDIS_MNEMONIC_PSHUFD, + ZYDIS_MNEMONIC_PSHUFHW, + ZYDIS_MNEMONIC_PSHUFLW, + ZYDIS_MNEMONIC_PSHUFW, + ZYDIS_MNEMONIC_PSIGNB, + ZYDIS_MNEMONIC_PSIGND, + ZYDIS_MNEMONIC_PSIGNW, + ZYDIS_MNEMONIC_PSLLD, + ZYDIS_MNEMONIC_PSLLDQ, + ZYDIS_MNEMONIC_PSLLQ, + ZYDIS_MNEMONIC_PSLLW, + ZYDIS_MNEMONIC_PSMASH, + ZYDIS_MNEMONIC_PSRAD, + ZYDIS_MNEMONIC_PSRAW, + ZYDIS_MNEMONIC_PSRLD, + ZYDIS_MNEMONIC_PSRLDQ, + ZYDIS_MNEMONIC_PSRLQ, + ZYDIS_MNEMONIC_PSRLW, + ZYDIS_MNEMONIC_PSUBB, + ZYDIS_MNEMONIC_PSUBD, + ZYDIS_MNEMONIC_PSUBQ, + ZYDIS_MNEMONIC_PSUBSB, + ZYDIS_MNEMONIC_PSUBSW, + ZYDIS_MNEMONIC_PSUBUSB, + ZYDIS_MNEMONIC_PSUBUSW, + ZYDIS_MNEMONIC_PSUBW, + ZYDIS_MNEMONIC_PSWAPD, + ZYDIS_MNEMONIC_PTEST, + ZYDIS_MNEMONIC_PTWRITE, + ZYDIS_MNEMONIC_PUNPCKHBW, + ZYDIS_MNEMONIC_PUNPCKHDQ, + ZYDIS_MNEMONIC_PUNPCKHQDQ, + ZYDIS_MNEMONIC_PUNPCKHWD, + ZYDIS_MNEMONIC_PUNPCKLBW, + ZYDIS_MNEMONIC_PUNPCKLDQ, + ZYDIS_MNEMONIC_PUNPCKLQDQ, + ZYDIS_MNEMONIC_PUNPCKLWD, + ZYDIS_MNEMONIC_PUSH, + ZYDIS_MNEMONIC_PUSHA, + ZYDIS_MNEMONIC_PUSHAD, + ZYDIS_MNEMONIC_PUSHF, + ZYDIS_MNEMONIC_PUSHFD, + ZYDIS_MNEMONIC_PUSHFQ, + ZYDIS_MNEMONIC_PVALIDATE, + ZYDIS_MNEMONIC_PXOR, + ZYDIS_MNEMONIC_RCL, + ZYDIS_MNEMONIC_RCPPS, + ZYDIS_MNEMONIC_RCPSS, + ZYDIS_MNEMONIC_RCR, + ZYDIS_MNEMONIC_RDFSBASE, + ZYDIS_MNEMONIC_RDGSBASE, + ZYDIS_MNEMONIC_RDMSR, + ZYDIS_MNEMONIC_RDPID, + ZYDIS_MNEMONIC_RDPKRU, + ZYDIS_MNEMONIC_RDPMC, + ZYDIS_MNEMONIC_RDPRU, + ZYDIS_MNEMONIC_RDRAND, + ZYDIS_MNEMONIC_RDSEED, + ZYDIS_MNEMONIC_RDSSPD, + ZYDIS_MNEMONIC_RDSSPQ, + ZYDIS_MNEMONIC_RDTSC, + ZYDIS_MNEMONIC_RDTSCP, + ZYDIS_MNEMONIC_RET, + ZYDIS_MNEMONIC_RMPADJUST, + ZYDIS_MNEMONIC_RMPUPDATE, + ZYDIS_MNEMONIC_ROL, + ZYDIS_MNEMONIC_ROR, + ZYDIS_MNEMONIC_RORX, + ZYDIS_MNEMONIC_ROUNDPD, + ZYDIS_MNEMONIC_ROUNDPS, + ZYDIS_MNEMONIC_ROUNDSD, + ZYDIS_MNEMONIC_ROUNDSS, + ZYDIS_MNEMONIC_RSM, + ZYDIS_MNEMONIC_RSQRTPS, + ZYDIS_MNEMONIC_RSQRTSS, + ZYDIS_MNEMONIC_RSTORSSP, + ZYDIS_MNEMONIC_SAHF, + ZYDIS_MNEMONIC_SALC, + ZYDIS_MNEMONIC_SAR, + ZYDIS_MNEMONIC_SARX, + ZYDIS_MNEMONIC_SAVEPREVSSP, + ZYDIS_MNEMONIC_SBB, + ZYDIS_MNEMONIC_SCASB, + ZYDIS_MNEMONIC_SCASD, + ZYDIS_MNEMONIC_SCASQ, + ZYDIS_MNEMONIC_SCASW, + ZYDIS_MNEMONIC_SERIALIZE, + ZYDIS_MNEMONIC_SETB, + ZYDIS_MNEMONIC_SETBE, + ZYDIS_MNEMONIC_SETL, + ZYDIS_MNEMONIC_SETLE, + ZYDIS_MNEMONIC_SETNB, + ZYDIS_MNEMONIC_SETNBE, + ZYDIS_MNEMONIC_SETNL, + ZYDIS_MNEMONIC_SETNLE, + ZYDIS_MNEMONIC_SETNO, + ZYDIS_MNEMONIC_SETNP, + ZYDIS_MNEMONIC_SETNS, + ZYDIS_MNEMONIC_SETNZ, + ZYDIS_MNEMONIC_SETO, + ZYDIS_MNEMONIC_SETP, + ZYDIS_MNEMONIC_SETS, + ZYDIS_MNEMONIC_SETSSBSY, + ZYDIS_MNEMONIC_SETZ, + ZYDIS_MNEMONIC_SFENCE, + ZYDIS_MNEMONIC_SGDT, + ZYDIS_MNEMONIC_SHA1MSG1, + ZYDIS_MNEMONIC_SHA1MSG2, + ZYDIS_MNEMONIC_SHA1NEXTE, + ZYDIS_MNEMONIC_SHA1RNDS4, + ZYDIS_MNEMONIC_SHA256MSG1, + ZYDIS_MNEMONIC_SHA256MSG2, + ZYDIS_MNEMONIC_SHA256RNDS2, + ZYDIS_MNEMONIC_SHL, + ZYDIS_MNEMONIC_SHLD, + ZYDIS_MNEMONIC_SHLX, + ZYDIS_MNEMONIC_SHR, + ZYDIS_MNEMONIC_SHRD, + ZYDIS_MNEMONIC_SHRX, + ZYDIS_MNEMONIC_SHUFPD, + ZYDIS_MNEMONIC_SHUFPS, + ZYDIS_MNEMONIC_SIDT, + ZYDIS_MNEMONIC_SKINIT, + ZYDIS_MNEMONIC_SLDT, + ZYDIS_MNEMONIC_SLWPCB, + ZYDIS_MNEMONIC_SMSW, + ZYDIS_MNEMONIC_SPFLT, + ZYDIS_MNEMONIC_SQRTPD, + ZYDIS_MNEMONIC_SQRTPS, + ZYDIS_MNEMONIC_SQRTSD, + ZYDIS_MNEMONIC_SQRTSS, + ZYDIS_MNEMONIC_STAC, + ZYDIS_MNEMONIC_STC, + ZYDIS_MNEMONIC_STD, + ZYDIS_MNEMONIC_STGI, + ZYDIS_MNEMONIC_STI, + ZYDIS_MNEMONIC_STMXCSR, + ZYDIS_MNEMONIC_STOSB, + ZYDIS_MNEMONIC_STOSD, + ZYDIS_MNEMONIC_STOSQ, + ZYDIS_MNEMONIC_STOSW, + ZYDIS_MNEMONIC_STR, + ZYDIS_MNEMONIC_STTILECFG, + ZYDIS_MNEMONIC_SUB, + ZYDIS_MNEMONIC_SUBPD, + ZYDIS_MNEMONIC_SUBPS, + ZYDIS_MNEMONIC_SUBSD, + ZYDIS_MNEMONIC_SUBSS, + ZYDIS_MNEMONIC_SWAPGS, + ZYDIS_MNEMONIC_SYSCALL, + ZYDIS_MNEMONIC_SYSENTER, + ZYDIS_MNEMONIC_SYSEXIT, + ZYDIS_MNEMONIC_SYSRET, + ZYDIS_MNEMONIC_T1MSKC, + ZYDIS_MNEMONIC_TDPBF16PS, + ZYDIS_MNEMONIC_TDPBSSD, + ZYDIS_MNEMONIC_TDPBSUD, + ZYDIS_MNEMONIC_TDPBUSD, + ZYDIS_MNEMONIC_TDPBUUD, + ZYDIS_MNEMONIC_TEST, + ZYDIS_MNEMONIC_TILELOADD, + ZYDIS_MNEMONIC_TILELOADDT1, + ZYDIS_MNEMONIC_TILERELEASE, + ZYDIS_MNEMONIC_TILESTORED, + ZYDIS_MNEMONIC_TILEZERO, + ZYDIS_MNEMONIC_TLBSYNC, + ZYDIS_MNEMONIC_TPAUSE, + ZYDIS_MNEMONIC_TZCNT, + ZYDIS_MNEMONIC_TZCNTI, + ZYDIS_MNEMONIC_TZMSK, + ZYDIS_MNEMONIC_UCOMISD, + ZYDIS_MNEMONIC_UCOMISS, + ZYDIS_MNEMONIC_UD0, + ZYDIS_MNEMONIC_UD1, + ZYDIS_MNEMONIC_UD2, + ZYDIS_MNEMONIC_UMONITOR, + ZYDIS_MNEMONIC_UMWAIT, + ZYDIS_MNEMONIC_UNPCKHPD, + ZYDIS_MNEMONIC_UNPCKHPS, + ZYDIS_MNEMONIC_UNPCKLPD, + ZYDIS_MNEMONIC_UNPCKLPS, + ZYDIS_MNEMONIC_V4FMADDPS, + ZYDIS_MNEMONIC_V4FMADDSS, + ZYDIS_MNEMONIC_V4FNMADDPS, + ZYDIS_MNEMONIC_V4FNMADDSS, + ZYDIS_MNEMONIC_VADDNPD, + ZYDIS_MNEMONIC_VADDNPS, + ZYDIS_MNEMONIC_VADDPD, + ZYDIS_MNEMONIC_VADDPS, + ZYDIS_MNEMONIC_VADDSD, + ZYDIS_MNEMONIC_VADDSETSPS, + ZYDIS_MNEMONIC_VADDSS, + ZYDIS_MNEMONIC_VADDSUBPD, + ZYDIS_MNEMONIC_VADDSUBPS, + ZYDIS_MNEMONIC_VAESDEC, + ZYDIS_MNEMONIC_VAESDECLAST, + ZYDIS_MNEMONIC_VAESENC, + ZYDIS_MNEMONIC_VAESENCLAST, + ZYDIS_MNEMONIC_VAESIMC, + ZYDIS_MNEMONIC_VAESKEYGENASSIST, + ZYDIS_MNEMONIC_VALIGND, + ZYDIS_MNEMONIC_VALIGNQ, + ZYDIS_MNEMONIC_VANDNPD, + ZYDIS_MNEMONIC_VANDNPS, + ZYDIS_MNEMONIC_VANDPD, + ZYDIS_MNEMONIC_VANDPS, + ZYDIS_MNEMONIC_VBLENDMPD, + ZYDIS_MNEMONIC_VBLENDMPS, + ZYDIS_MNEMONIC_VBLENDPD, + ZYDIS_MNEMONIC_VBLENDPS, + ZYDIS_MNEMONIC_VBLENDVPD, + ZYDIS_MNEMONIC_VBLENDVPS, + ZYDIS_MNEMONIC_VBROADCASTF128, + ZYDIS_MNEMONIC_VBROADCASTF32X2, + ZYDIS_MNEMONIC_VBROADCASTF32X4, + ZYDIS_MNEMONIC_VBROADCASTF32X8, + ZYDIS_MNEMONIC_VBROADCASTF64X2, + ZYDIS_MNEMONIC_VBROADCASTF64X4, + ZYDIS_MNEMONIC_VBROADCASTI128, + ZYDIS_MNEMONIC_VBROADCASTI32X2, + ZYDIS_MNEMONIC_VBROADCASTI32X4, + ZYDIS_MNEMONIC_VBROADCASTI32X8, + ZYDIS_MNEMONIC_VBROADCASTI64X2, + ZYDIS_MNEMONIC_VBROADCASTI64X4, + ZYDIS_MNEMONIC_VBROADCASTSD, + ZYDIS_MNEMONIC_VBROADCASTSS, + ZYDIS_MNEMONIC_VCMPPD, + ZYDIS_MNEMONIC_VCMPPS, + ZYDIS_MNEMONIC_VCMPSD, + ZYDIS_MNEMONIC_VCMPSS, + ZYDIS_MNEMONIC_VCOMISD, + ZYDIS_MNEMONIC_VCOMISS, + ZYDIS_MNEMONIC_VCOMPRESSPD, + ZYDIS_MNEMONIC_VCOMPRESSPS, + ZYDIS_MNEMONIC_VCVTDQ2PD, + ZYDIS_MNEMONIC_VCVTDQ2PS, + ZYDIS_MNEMONIC_VCVTFXPNTDQ2PS, + ZYDIS_MNEMONIC_VCVTFXPNTPD2DQ, + ZYDIS_MNEMONIC_VCVTFXPNTPD2UDQ, + ZYDIS_MNEMONIC_VCVTFXPNTPS2DQ, + ZYDIS_MNEMONIC_VCVTFXPNTPS2UDQ, + ZYDIS_MNEMONIC_VCVTFXPNTUDQ2PS, + ZYDIS_MNEMONIC_VCVTNE2PS2BF16, + ZYDIS_MNEMONIC_VCVTNEPS2BF16, + ZYDIS_MNEMONIC_VCVTPD2DQ, + ZYDIS_MNEMONIC_VCVTPD2PS, + ZYDIS_MNEMONIC_VCVTPD2QQ, + ZYDIS_MNEMONIC_VCVTPD2UDQ, + ZYDIS_MNEMONIC_VCVTPD2UQQ, + ZYDIS_MNEMONIC_VCVTPH2PS, + ZYDIS_MNEMONIC_VCVTPS2DQ, + ZYDIS_MNEMONIC_VCVTPS2PD, + ZYDIS_MNEMONIC_VCVTPS2PH, + ZYDIS_MNEMONIC_VCVTPS2QQ, + ZYDIS_MNEMONIC_VCVTPS2UDQ, + ZYDIS_MNEMONIC_VCVTPS2UQQ, + ZYDIS_MNEMONIC_VCVTQQ2PD, + ZYDIS_MNEMONIC_VCVTQQ2PS, + ZYDIS_MNEMONIC_VCVTSD2SI, + ZYDIS_MNEMONIC_VCVTSD2SS, + ZYDIS_MNEMONIC_VCVTSD2USI, + ZYDIS_MNEMONIC_VCVTSI2SD, + ZYDIS_MNEMONIC_VCVTSI2SS, + ZYDIS_MNEMONIC_VCVTSS2SD, + ZYDIS_MNEMONIC_VCVTSS2SI, + ZYDIS_MNEMONIC_VCVTSS2USI, + ZYDIS_MNEMONIC_VCVTTPD2DQ, + ZYDIS_MNEMONIC_VCVTTPD2QQ, + ZYDIS_MNEMONIC_VCVTTPD2UDQ, + ZYDIS_MNEMONIC_VCVTTPD2UQQ, + ZYDIS_MNEMONIC_VCVTTPS2DQ, + ZYDIS_MNEMONIC_VCVTTPS2QQ, + ZYDIS_MNEMONIC_VCVTTPS2UDQ, + ZYDIS_MNEMONIC_VCVTTPS2UQQ, + ZYDIS_MNEMONIC_VCVTTSD2SI, + ZYDIS_MNEMONIC_VCVTTSD2USI, + ZYDIS_MNEMONIC_VCVTTSS2SI, + ZYDIS_MNEMONIC_VCVTTSS2USI, + ZYDIS_MNEMONIC_VCVTUDQ2PD, + ZYDIS_MNEMONIC_VCVTUDQ2PS, + ZYDIS_MNEMONIC_VCVTUQQ2PD, + ZYDIS_MNEMONIC_VCVTUQQ2PS, + ZYDIS_MNEMONIC_VCVTUSI2SD, + ZYDIS_MNEMONIC_VCVTUSI2SS, + ZYDIS_MNEMONIC_VDBPSADBW, + ZYDIS_MNEMONIC_VDIVPD, + ZYDIS_MNEMONIC_VDIVPS, + ZYDIS_MNEMONIC_VDIVSD, + ZYDIS_MNEMONIC_VDIVSS, + ZYDIS_MNEMONIC_VDPBF16PS, + ZYDIS_MNEMONIC_VDPPD, + ZYDIS_MNEMONIC_VDPPS, + ZYDIS_MNEMONIC_VERR, + ZYDIS_MNEMONIC_VERW, + ZYDIS_MNEMONIC_VEXP223PS, + ZYDIS_MNEMONIC_VEXP2PD, + ZYDIS_MNEMONIC_VEXP2PS, + ZYDIS_MNEMONIC_VEXPANDPD, + ZYDIS_MNEMONIC_VEXPANDPS, + ZYDIS_MNEMONIC_VEXTRACTF128, + ZYDIS_MNEMONIC_VEXTRACTF32X4, + ZYDIS_MNEMONIC_VEXTRACTF32X8, + ZYDIS_MNEMONIC_VEXTRACTF64X2, + ZYDIS_MNEMONIC_VEXTRACTF64X4, + ZYDIS_MNEMONIC_VEXTRACTI128, + ZYDIS_MNEMONIC_VEXTRACTI32X4, + ZYDIS_MNEMONIC_VEXTRACTI32X8, + ZYDIS_MNEMONIC_VEXTRACTI64X2, + ZYDIS_MNEMONIC_VEXTRACTI64X4, + ZYDIS_MNEMONIC_VEXTRACTPS, + ZYDIS_MNEMONIC_VFIXUPIMMPD, + ZYDIS_MNEMONIC_VFIXUPIMMPS, + ZYDIS_MNEMONIC_VFIXUPIMMSD, + ZYDIS_MNEMONIC_VFIXUPIMMSS, + ZYDIS_MNEMONIC_VFIXUPNANPD, + ZYDIS_MNEMONIC_VFIXUPNANPS, + ZYDIS_MNEMONIC_VFMADD132PD, + ZYDIS_MNEMONIC_VFMADD132PS, + ZYDIS_MNEMONIC_VFMADD132SD, + ZYDIS_MNEMONIC_VFMADD132SS, + ZYDIS_MNEMONIC_VFMADD213PD, + ZYDIS_MNEMONIC_VFMADD213PS, + ZYDIS_MNEMONIC_VFMADD213SD, + ZYDIS_MNEMONIC_VFMADD213SS, + ZYDIS_MNEMONIC_VFMADD231PD, + ZYDIS_MNEMONIC_VFMADD231PS, + ZYDIS_MNEMONIC_VFMADD231SD, + ZYDIS_MNEMONIC_VFMADD231SS, + ZYDIS_MNEMONIC_VFMADD233PS, + ZYDIS_MNEMONIC_VFMADDPD, + ZYDIS_MNEMONIC_VFMADDPS, + ZYDIS_MNEMONIC_VFMADDSD, + ZYDIS_MNEMONIC_VFMADDSS, + ZYDIS_MNEMONIC_VFMADDSUB132PD, + ZYDIS_MNEMONIC_VFMADDSUB132PS, + ZYDIS_MNEMONIC_VFMADDSUB213PD, + ZYDIS_MNEMONIC_VFMADDSUB213PS, + ZYDIS_MNEMONIC_VFMADDSUB231PD, + ZYDIS_MNEMONIC_VFMADDSUB231PS, + ZYDIS_MNEMONIC_VFMADDSUBPD, + ZYDIS_MNEMONIC_VFMADDSUBPS, + ZYDIS_MNEMONIC_VFMSUB132PD, + ZYDIS_MNEMONIC_VFMSUB132PS, + ZYDIS_MNEMONIC_VFMSUB132SD, + ZYDIS_MNEMONIC_VFMSUB132SS, + ZYDIS_MNEMONIC_VFMSUB213PD, + ZYDIS_MNEMONIC_VFMSUB213PS, + ZYDIS_MNEMONIC_VFMSUB213SD, + ZYDIS_MNEMONIC_VFMSUB213SS, + ZYDIS_MNEMONIC_VFMSUB231PD, + ZYDIS_MNEMONIC_VFMSUB231PS, + ZYDIS_MNEMONIC_VFMSUB231SD, + ZYDIS_MNEMONIC_VFMSUB231SS, + ZYDIS_MNEMONIC_VFMSUBADD132PD, + ZYDIS_MNEMONIC_VFMSUBADD132PS, + ZYDIS_MNEMONIC_VFMSUBADD213PD, + ZYDIS_MNEMONIC_VFMSUBADD213PS, + ZYDIS_MNEMONIC_VFMSUBADD231PD, + ZYDIS_MNEMONIC_VFMSUBADD231PS, + ZYDIS_MNEMONIC_VFMSUBADDPD, + ZYDIS_MNEMONIC_VFMSUBADDPS, + ZYDIS_MNEMONIC_VFMSUBPD, + ZYDIS_MNEMONIC_VFMSUBPS, + ZYDIS_MNEMONIC_VFMSUBSD, + ZYDIS_MNEMONIC_VFMSUBSS, + ZYDIS_MNEMONIC_VFNMADD132PD, + ZYDIS_MNEMONIC_VFNMADD132PS, + ZYDIS_MNEMONIC_VFNMADD132SD, + ZYDIS_MNEMONIC_VFNMADD132SS, + ZYDIS_MNEMONIC_VFNMADD213PD, + ZYDIS_MNEMONIC_VFNMADD213PS, + ZYDIS_MNEMONIC_VFNMADD213SD, + ZYDIS_MNEMONIC_VFNMADD213SS, + ZYDIS_MNEMONIC_VFNMADD231PD, + ZYDIS_MNEMONIC_VFNMADD231PS, + ZYDIS_MNEMONIC_VFNMADD231SD, + ZYDIS_MNEMONIC_VFNMADD231SS, + ZYDIS_MNEMONIC_VFNMADDPD, + ZYDIS_MNEMONIC_VFNMADDPS, + ZYDIS_MNEMONIC_VFNMADDSD, + ZYDIS_MNEMONIC_VFNMADDSS, + ZYDIS_MNEMONIC_VFNMSUB132PD, + ZYDIS_MNEMONIC_VFNMSUB132PS, + ZYDIS_MNEMONIC_VFNMSUB132SD, + ZYDIS_MNEMONIC_VFNMSUB132SS, + ZYDIS_MNEMONIC_VFNMSUB213PD, + ZYDIS_MNEMONIC_VFNMSUB213PS, + ZYDIS_MNEMONIC_VFNMSUB213SD, + ZYDIS_MNEMONIC_VFNMSUB213SS, + ZYDIS_MNEMONIC_VFNMSUB231PD, + ZYDIS_MNEMONIC_VFNMSUB231PS, + ZYDIS_MNEMONIC_VFNMSUB231SD, + ZYDIS_MNEMONIC_VFNMSUB231SS, + ZYDIS_MNEMONIC_VFNMSUBPD, + ZYDIS_MNEMONIC_VFNMSUBPS, + ZYDIS_MNEMONIC_VFNMSUBSD, + ZYDIS_MNEMONIC_VFNMSUBSS, + ZYDIS_MNEMONIC_VFPCLASSPD, + ZYDIS_MNEMONIC_VFPCLASSPS, + ZYDIS_MNEMONIC_VFPCLASSSD, + ZYDIS_MNEMONIC_VFPCLASSSS, + ZYDIS_MNEMONIC_VFRCZPD, + ZYDIS_MNEMONIC_VFRCZPS, + ZYDIS_MNEMONIC_VFRCZSD, + ZYDIS_MNEMONIC_VFRCZSS, + ZYDIS_MNEMONIC_VGATHERDPD, + ZYDIS_MNEMONIC_VGATHERDPS, + ZYDIS_MNEMONIC_VGATHERPF0DPD, + ZYDIS_MNEMONIC_VGATHERPF0DPS, + ZYDIS_MNEMONIC_VGATHERPF0HINTDPD, + ZYDIS_MNEMONIC_VGATHERPF0HINTDPS, + ZYDIS_MNEMONIC_VGATHERPF0QPD, + ZYDIS_MNEMONIC_VGATHERPF0QPS, + ZYDIS_MNEMONIC_VGATHERPF1DPD, + ZYDIS_MNEMONIC_VGATHERPF1DPS, + ZYDIS_MNEMONIC_VGATHERPF1QPD, + ZYDIS_MNEMONIC_VGATHERPF1QPS, + ZYDIS_MNEMONIC_VGATHERQPD, + ZYDIS_MNEMONIC_VGATHERQPS, + ZYDIS_MNEMONIC_VGETEXPPD, + ZYDIS_MNEMONIC_VGETEXPPS, + ZYDIS_MNEMONIC_VGETEXPSD, + ZYDIS_MNEMONIC_VGETEXPSS, + ZYDIS_MNEMONIC_VGETMANTPD, + ZYDIS_MNEMONIC_VGETMANTPS, + ZYDIS_MNEMONIC_VGETMANTSD, + ZYDIS_MNEMONIC_VGETMANTSS, + ZYDIS_MNEMONIC_VGF2P8AFFINEINVQB, + ZYDIS_MNEMONIC_VGF2P8AFFINEQB, + ZYDIS_MNEMONIC_VGF2P8MULB, + ZYDIS_MNEMONIC_VGMAXABSPS, + ZYDIS_MNEMONIC_VGMAXPD, + ZYDIS_MNEMONIC_VGMAXPS, + ZYDIS_MNEMONIC_VGMINPD, + ZYDIS_MNEMONIC_VGMINPS, + ZYDIS_MNEMONIC_VHADDPD, + ZYDIS_MNEMONIC_VHADDPS, + ZYDIS_MNEMONIC_VHSUBPD, + ZYDIS_MNEMONIC_VHSUBPS, + ZYDIS_MNEMONIC_VINSERTF128, + ZYDIS_MNEMONIC_VINSERTF32X4, + ZYDIS_MNEMONIC_VINSERTF32X8, + ZYDIS_MNEMONIC_VINSERTF64X2, + ZYDIS_MNEMONIC_VINSERTF64X4, + ZYDIS_MNEMONIC_VINSERTI128, + ZYDIS_MNEMONIC_VINSERTI32X4, + ZYDIS_MNEMONIC_VINSERTI32X8, + ZYDIS_MNEMONIC_VINSERTI64X2, + ZYDIS_MNEMONIC_VINSERTI64X4, + ZYDIS_MNEMONIC_VINSERTPS, + ZYDIS_MNEMONIC_VLDDQU, + ZYDIS_MNEMONIC_VLDMXCSR, + ZYDIS_MNEMONIC_VLOADUNPACKHD, + ZYDIS_MNEMONIC_VLOADUNPACKHPD, + ZYDIS_MNEMONIC_VLOADUNPACKHPS, + ZYDIS_MNEMONIC_VLOADUNPACKHQ, + ZYDIS_MNEMONIC_VLOADUNPACKLD, + ZYDIS_MNEMONIC_VLOADUNPACKLPD, + ZYDIS_MNEMONIC_VLOADUNPACKLPS, + ZYDIS_MNEMONIC_VLOADUNPACKLQ, + ZYDIS_MNEMONIC_VLOG2PS, + ZYDIS_MNEMONIC_VMASKMOVDQU, + ZYDIS_MNEMONIC_VMASKMOVPD, + ZYDIS_MNEMONIC_VMASKMOVPS, + ZYDIS_MNEMONIC_VMAXPD, + ZYDIS_MNEMONIC_VMAXPS, + ZYDIS_MNEMONIC_VMAXSD, + ZYDIS_MNEMONIC_VMAXSS, + ZYDIS_MNEMONIC_VMCALL, + ZYDIS_MNEMONIC_VMCLEAR, + ZYDIS_MNEMONIC_VMFUNC, + ZYDIS_MNEMONIC_VMINPD, + ZYDIS_MNEMONIC_VMINPS, + ZYDIS_MNEMONIC_VMINSD, + ZYDIS_MNEMONIC_VMINSS, + ZYDIS_MNEMONIC_VMLAUNCH, + ZYDIS_MNEMONIC_VMLOAD, + ZYDIS_MNEMONIC_VMMCALL, + ZYDIS_MNEMONIC_VMOVAPD, + ZYDIS_MNEMONIC_VMOVAPS, + ZYDIS_MNEMONIC_VMOVD, + ZYDIS_MNEMONIC_VMOVDDUP, + ZYDIS_MNEMONIC_VMOVDQA, + ZYDIS_MNEMONIC_VMOVDQA32, + ZYDIS_MNEMONIC_VMOVDQA64, + ZYDIS_MNEMONIC_VMOVDQU, + ZYDIS_MNEMONIC_VMOVDQU16, + ZYDIS_MNEMONIC_VMOVDQU32, + ZYDIS_MNEMONIC_VMOVDQU64, + ZYDIS_MNEMONIC_VMOVDQU8, + ZYDIS_MNEMONIC_VMOVHLPS, + ZYDIS_MNEMONIC_VMOVHPD, + ZYDIS_MNEMONIC_VMOVHPS, + ZYDIS_MNEMONIC_VMOVLHPS, + ZYDIS_MNEMONIC_VMOVLPD, + ZYDIS_MNEMONIC_VMOVLPS, + ZYDIS_MNEMONIC_VMOVMSKPD, + ZYDIS_MNEMONIC_VMOVMSKPS, + ZYDIS_MNEMONIC_VMOVNRAPD, + ZYDIS_MNEMONIC_VMOVNRAPS, + ZYDIS_MNEMONIC_VMOVNRNGOAPD, + ZYDIS_MNEMONIC_VMOVNRNGOAPS, + ZYDIS_MNEMONIC_VMOVNTDQ, + ZYDIS_MNEMONIC_VMOVNTDQA, + ZYDIS_MNEMONIC_VMOVNTPD, + ZYDIS_MNEMONIC_VMOVNTPS, + ZYDIS_MNEMONIC_VMOVQ, + ZYDIS_MNEMONIC_VMOVSD, + ZYDIS_MNEMONIC_VMOVSHDUP, + ZYDIS_MNEMONIC_VMOVSLDUP, + ZYDIS_MNEMONIC_VMOVSS, + ZYDIS_MNEMONIC_VMOVUPD, + ZYDIS_MNEMONIC_VMOVUPS, + ZYDIS_MNEMONIC_VMPSADBW, + ZYDIS_MNEMONIC_VMPTRLD, + ZYDIS_MNEMONIC_VMPTRST, + ZYDIS_MNEMONIC_VMREAD, + ZYDIS_MNEMONIC_VMRESUME, + ZYDIS_MNEMONIC_VMRUN, + ZYDIS_MNEMONIC_VMSAVE, + ZYDIS_MNEMONIC_VMULPD, + ZYDIS_MNEMONIC_VMULPS, + ZYDIS_MNEMONIC_VMULSD, + ZYDIS_MNEMONIC_VMULSS, + ZYDIS_MNEMONIC_VMWRITE, + ZYDIS_MNEMONIC_VMXOFF, + ZYDIS_MNEMONIC_VMXON, + ZYDIS_MNEMONIC_VORPD, + ZYDIS_MNEMONIC_VORPS, + ZYDIS_MNEMONIC_VP2INTERSECTD, + ZYDIS_MNEMONIC_VP2INTERSECTQ, + ZYDIS_MNEMONIC_VP4DPWSSD, + ZYDIS_MNEMONIC_VP4DPWSSDS, + ZYDIS_MNEMONIC_VPABSB, + ZYDIS_MNEMONIC_VPABSD, + ZYDIS_MNEMONIC_VPABSQ, + ZYDIS_MNEMONIC_VPABSW, + ZYDIS_MNEMONIC_VPACKSSDW, + ZYDIS_MNEMONIC_VPACKSSWB, + ZYDIS_MNEMONIC_VPACKSTOREHD, + ZYDIS_MNEMONIC_VPACKSTOREHPD, + ZYDIS_MNEMONIC_VPACKSTOREHPS, + ZYDIS_MNEMONIC_VPACKSTOREHQ, + ZYDIS_MNEMONIC_VPACKSTORELD, + ZYDIS_MNEMONIC_VPACKSTORELPD, + ZYDIS_MNEMONIC_VPACKSTORELPS, + ZYDIS_MNEMONIC_VPACKSTORELQ, + ZYDIS_MNEMONIC_VPACKUSDW, + ZYDIS_MNEMONIC_VPACKUSWB, + ZYDIS_MNEMONIC_VPADCD, + ZYDIS_MNEMONIC_VPADDB, + ZYDIS_MNEMONIC_VPADDD, + ZYDIS_MNEMONIC_VPADDQ, + ZYDIS_MNEMONIC_VPADDSB, + ZYDIS_MNEMONIC_VPADDSETCD, + ZYDIS_MNEMONIC_VPADDSETSD, + ZYDIS_MNEMONIC_VPADDSW, + ZYDIS_MNEMONIC_VPADDUSB, + ZYDIS_MNEMONIC_VPADDUSW, + ZYDIS_MNEMONIC_VPADDW, + ZYDIS_MNEMONIC_VPALIGNR, + ZYDIS_MNEMONIC_VPAND, + ZYDIS_MNEMONIC_VPANDD, + ZYDIS_MNEMONIC_VPANDN, + ZYDIS_MNEMONIC_VPANDND, + ZYDIS_MNEMONIC_VPANDNQ, + ZYDIS_MNEMONIC_VPANDQ, + ZYDIS_MNEMONIC_VPAVGB, + ZYDIS_MNEMONIC_VPAVGW, + ZYDIS_MNEMONIC_VPBLENDD, + ZYDIS_MNEMONIC_VPBLENDMB, + ZYDIS_MNEMONIC_VPBLENDMD, + ZYDIS_MNEMONIC_VPBLENDMQ, + ZYDIS_MNEMONIC_VPBLENDMW, + ZYDIS_MNEMONIC_VPBLENDVB, + ZYDIS_MNEMONIC_VPBLENDW, + ZYDIS_MNEMONIC_VPBROADCASTB, + ZYDIS_MNEMONIC_VPBROADCASTD, + ZYDIS_MNEMONIC_VPBROADCASTMB2Q, + ZYDIS_MNEMONIC_VPBROADCASTMW2D, + ZYDIS_MNEMONIC_VPBROADCASTQ, + ZYDIS_MNEMONIC_VPBROADCASTW, + ZYDIS_MNEMONIC_VPCLMULQDQ, + ZYDIS_MNEMONIC_VPCMOV, + ZYDIS_MNEMONIC_VPCMPB, + ZYDIS_MNEMONIC_VPCMPD, + ZYDIS_MNEMONIC_VPCMPEQB, + ZYDIS_MNEMONIC_VPCMPEQD, + ZYDIS_MNEMONIC_VPCMPEQQ, + ZYDIS_MNEMONIC_VPCMPEQW, + ZYDIS_MNEMONIC_VPCMPESTRI, + ZYDIS_MNEMONIC_VPCMPESTRM, + ZYDIS_MNEMONIC_VPCMPGTB, + ZYDIS_MNEMONIC_VPCMPGTD, + ZYDIS_MNEMONIC_VPCMPGTQ, + ZYDIS_MNEMONIC_VPCMPGTW, + ZYDIS_MNEMONIC_VPCMPISTRI, + ZYDIS_MNEMONIC_VPCMPISTRM, + ZYDIS_MNEMONIC_VPCMPLTD, + ZYDIS_MNEMONIC_VPCMPQ, + ZYDIS_MNEMONIC_VPCMPUB, + ZYDIS_MNEMONIC_VPCMPUD, + ZYDIS_MNEMONIC_VPCMPUQ, + ZYDIS_MNEMONIC_VPCMPUW, + ZYDIS_MNEMONIC_VPCMPW, + ZYDIS_MNEMONIC_VPCOMB, + ZYDIS_MNEMONIC_VPCOMD, + ZYDIS_MNEMONIC_VPCOMPRESSB, + ZYDIS_MNEMONIC_VPCOMPRESSD, + ZYDIS_MNEMONIC_VPCOMPRESSQ, + ZYDIS_MNEMONIC_VPCOMPRESSW, + ZYDIS_MNEMONIC_VPCOMQ, + ZYDIS_MNEMONIC_VPCOMUB, + ZYDIS_MNEMONIC_VPCOMUD, + ZYDIS_MNEMONIC_VPCOMUQ, + ZYDIS_MNEMONIC_VPCOMUW, + ZYDIS_MNEMONIC_VPCOMW, + ZYDIS_MNEMONIC_VPCONFLICTD, + ZYDIS_MNEMONIC_VPCONFLICTQ, + ZYDIS_MNEMONIC_VPDPBUSD, + ZYDIS_MNEMONIC_VPDPBUSDS, + ZYDIS_MNEMONIC_VPDPWSSD, + ZYDIS_MNEMONIC_VPDPWSSDS, + ZYDIS_MNEMONIC_VPERM2F128, + ZYDIS_MNEMONIC_VPERM2I128, + ZYDIS_MNEMONIC_VPERMB, + ZYDIS_MNEMONIC_VPERMD, + ZYDIS_MNEMONIC_VPERMF32X4, + ZYDIS_MNEMONIC_VPERMI2B, + ZYDIS_MNEMONIC_VPERMI2D, + ZYDIS_MNEMONIC_VPERMI2PD, + ZYDIS_MNEMONIC_VPERMI2PS, + ZYDIS_MNEMONIC_VPERMI2Q, + ZYDIS_MNEMONIC_VPERMI2W, + ZYDIS_MNEMONIC_VPERMIL2PD, + ZYDIS_MNEMONIC_VPERMIL2PS, + ZYDIS_MNEMONIC_VPERMILPD, + ZYDIS_MNEMONIC_VPERMILPS, + ZYDIS_MNEMONIC_VPERMPD, + ZYDIS_MNEMONIC_VPERMPS, + ZYDIS_MNEMONIC_VPERMQ, + ZYDIS_MNEMONIC_VPERMT2B, + ZYDIS_MNEMONIC_VPERMT2D, + ZYDIS_MNEMONIC_VPERMT2PD, + ZYDIS_MNEMONIC_VPERMT2PS, + ZYDIS_MNEMONIC_VPERMT2Q, + ZYDIS_MNEMONIC_VPERMT2W, + ZYDIS_MNEMONIC_VPERMW, + ZYDIS_MNEMONIC_VPEXPANDB, + ZYDIS_MNEMONIC_VPEXPANDD, + ZYDIS_MNEMONIC_VPEXPANDQ, + ZYDIS_MNEMONIC_VPEXPANDW, + ZYDIS_MNEMONIC_VPEXTRB, + ZYDIS_MNEMONIC_VPEXTRD, + ZYDIS_MNEMONIC_VPEXTRQ, + ZYDIS_MNEMONIC_VPEXTRW, + ZYDIS_MNEMONIC_VPGATHERDD, + ZYDIS_MNEMONIC_VPGATHERDQ, + ZYDIS_MNEMONIC_VPGATHERQD, + ZYDIS_MNEMONIC_VPGATHERQQ, + ZYDIS_MNEMONIC_VPHADDBD, + ZYDIS_MNEMONIC_VPHADDBQ, + ZYDIS_MNEMONIC_VPHADDBW, + ZYDIS_MNEMONIC_VPHADDD, + ZYDIS_MNEMONIC_VPHADDDQ, + ZYDIS_MNEMONIC_VPHADDSW, + ZYDIS_MNEMONIC_VPHADDUBD, + ZYDIS_MNEMONIC_VPHADDUBQ, + ZYDIS_MNEMONIC_VPHADDUBW, + ZYDIS_MNEMONIC_VPHADDUDQ, + ZYDIS_MNEMONIC_VPHADDUWD, + ZYDIS_MNEMONIC_VPHADDUWQ, + ZYDIS_MNEMONIC_VPHADDW, + ZYDIS_MNEMONIC_VPHADDWD, + ZYDIS_MNEMONIC_VPHADDWQ, + ZYDIS_MNEMONIC_VPHMINPOSUW, + ZYDIS_MNEMONIC_VPHSUBBW, + ZYDIS_MNEMONIC_VPHSUBD, + ZYDIS_MNEMONIC_VPHSUBDQ, + ZYDIS_MNEMONIC_VPHSUBSW, + ZYDIS_MNEMONIC_VPHSUBW, + ZYDIS_MNEMONIC_VPHSUBWD, + ZYDIS_MNEMONIC_VPINSRB, + ZYDIS_MNEMONIC_VPINSRD, + ZYDIS_MNEMONIC_VPINSRQ, + ZYDIS_MNEMONIC_VPINSRW, + ZYDIS_MNEMONIC_VPLZCNTD, + ZYDIS_MNEMONIC_VPLZCNTQ, + ZYDIS_MNEMONIC_VPMACSDD, + ZYDIS_MNEMONIC_VPMACSDQH, + ZYDIS_MNEMONIC_VPMACSDQL, + ZYDIS_MNEMONIC_VPMACSSDD, + ZYDIS_MNEMONIC_VPMACSSDQH, + ZYDIS_MNEMONIC_VPMACSSDQL, + ZYDIS_MNEMONIC_VPMACSSWD, + ZYDIS_MNEMONIC_VPMACSSWW, + ZYDIS_MNEMONIC_VPMACSWD, + ZYDIS_MNEMONIC_VPMACSWW, + ZYDIS_MNEMONIC_VPMADCSSWD, + ZYDIS_MNEMONIC_VPMADCSWD, + ZYDIS_MNEMONIC_VPMADD231D, + ZYDIS_MNEMONIC_VPMADD233D, + ZYDIS_MNEMONIC_VPMADD52HUQ, + ZYDIS_MNEMONIC_VPMADD52LUQ, + ZYDIS_MNEMONIC_VPMADDUBSW, + ZYDIS_MNEMONIC_VPMADDWD, + ZYDIS_MNEMONIC_VPMASKMOVD, + ZYDIS_MNEMONIC_VPMASKMOVQ, + ZYDIS_MNEMONIC_VPMAXSB, + ZYDIS_MNEMONIC_VPMAXSD, + ZYDIS_MNEMONIC_VPMAXSQ, + ZYDIS_MNEMONIC_VPMAXSW, + ZYDIS_MNEMONIC_VPMAXUB, + ZYDIS_MNEMONIC_VPMAXUD, + ZYDIS_MNEMONIC_VPMAXUQ, + ZYDIS_MNEMONIC_VPMAXUW, + ZYDIS_MNEMONIC_VPMINSB, + ZYDIS_MNEMONIC_VPMINSD, + ZYDIS_MNEMONIC_VPMINSQ, + ZYDIS_MNEMONIC_VPMINSW, + ZYDIS_MNEMONIC_VPMINUB, + ZYDIS_MNEMONIC_VPMINUD, + ZYDIS_MNEMONIC_VPMINUQ, + ZYDIS_MNEMONIC_VPMINUW, + ZYDIS_MNEMONIC_VPMOVB2M, + ZYDIS_MNEMONIC_VPMOVD2M, + ZYDIS_MNEMONIC_VPMOVDB, + ZYDIS_MNEMONIC_VPMOVDW, + ZYDIS_MNEMONIC_VPMOVM2B, + ZYDIS_MNEMONIC_VPMOVM2D, + ZYDIS_MNEMONIC_VPMOVM2Q, + ZYDIS_MNEMONIC_VPMOVM2W, + ZYDIS_MNEMONIC_VPMOVMSKB, + ZYDIS_MNEMONIC_VPMOVQ2M, + ZYDIS_MNEMONIC_VPMOVQB, + ZYDIS_MNEMONIC_VPMOVQD, + ZYDIS_MNEMONIC_VPMOVQW, + ZYDIS_MNEMONIC_VPMOVSDB, + ZYDIS_MNEMONIC_VPMOVSDW, + ZYDIS_MNEMONIC_VPMOVSQB, + ZYDIS_MNEMONIC_VPMOVSQD, + ZYDIS_MNEMONIC_VPMOVSQW, + ZYDIS_MNEMONIC_VPMOVSWB, + ZYDIS_MNEMONIC_VPMOVSXBD, + ZYDIS_MNEMONIC_VPMOVSXBQ, + ZYDIS_MNEMONIC_VPMOVSXBW, + ZYDIS_MNEMONIC_VPMOVSXDQ, + ZYDIS_MNEMONIC_VPMOVSXWD, + ZYDIS_MNEMONIC_VPMOVSXWQ, + ZYDIS_MNEMONIC_VPMOVUSDB, + ZYDIS_MNEMONIC_VPMOVUSDW, + ZYDIS_MNEMONIC_VPMOVUSQB, + ZYDIS_MNEMONIC_VPMOVUSQD, + ZYDIS_MNEMONIC_VPMOVUSQW, + ZYDIS_MNEMONIC_VPMOVUSWB, + ZYDIS_MNEMONIC_VPMOVW2M, + ZYDIS_MNEMONIC_VPMOVWB, + ZYDIS_MNEMONIC_VPMOVZXBD, + ZYDIS_MNEMONIC_VPMOVZXBQ, + ZYDIS_MNEMONIC_VPMOVZXBW, + ZYDIS_MNEMONIC_VPMOVZXDQ, + ZYDIS_MNEMONIC_VPMOVZXWD, + ZYDIS_MNEMONIC_VPMOVZXWQ, + ZYDIS_MNEMONIC_VPMULDQ, + ZYDIS_MNEMONIC_VPMULHD, + ZYDIS_MNEMONIC_VPMULHRSW, + ZYDIS_MNEMONIC_VPMULHUD, + ZYDIS_MNEMONIC_VPMULHUW, + ZYDIS_MNEMONIC_VPMULHW, + ZYDIS_MNEMONIC_VPMULLD, + ZYDIS_MNEMONIC_VPMULLQ, + ZYDIS_MNEMONIC_VPMULLW, + ZYDIS_MNEMONIC_VPMULTISHIFTQB, + ZYDIS_MNEMONIC_VPMULUDQ, + ZYDIS_MNEMONIC_VPOPCNTB, + ZYDIS_MNEMONIC_VPOPCNTD, + ZYDIS_MNEMONIC_VPOPCNTQ, + ZYDIS_MNEMONIC_VPOPCNTW, + ZYDIS_MNEMONIC_VPOR, + ZYDIS_MNEMONIC_VPORD, + ZYDIS_MNEMONIC_VPORQ, + ZYDIS_MNEMONIC_VPPERM, + ZYDIS_MNEMONIC_VPREFETCH0, + ZYDIS_MNEMONIC_VPREFETCH1, + ZYDIS_MNEMONIC_VPREFETCH2, + ZYDIS_MNEMONIC_VPREFETCHE0, + ZYDIS_MNEMONIC_VPREFETCHE1, + ZYDIS_MNEMONIC_VPREFETCHE2, + ZYDIS_MNEMONIC_VPREFETCHENTA, + ZYDIS_MNEMONIC_VPREFETCHNTA, + ZYDIS_MNEMONIC_VPROLD, + ZYDIS_MNEMONIC_VPROLQ, + ZYDIS_MNEMONIC_VPROLVD, + ZYDIS_MNEMONIC_VPROLVQ, + ZYDIS_MNEMONIC_VPRORD, + ZYDIS_MNEMONIC_VPRORQ, + ZYDIS_MNEMONIC_VPRORVD, + ZYDIS_MNEMONIC_VPRORVQ, + ZYDIS_MNEMONIC_VPROTB, + ZYDIS_MNEMONIC_VPROTD, + ZYDIS_MNEMONIC_VPROTQ, + ZYDIS_MNEMONIC_VPROTW, + ZYDIS_MNEMONIC_VPSADBW, + ZYDIS_MNEMONIC_VPSBBD, + ZYDIS_MNEMONIC_VPSBBRD, + ZYDIS_MNEMONIC_VPSCATTERDD, + ZYDIS_MNEMONIC_VPSCATTERDQ, + ZYDIS_MNEMONIC_VPSCATTERQD, + ZYDIS_MNEMONIC_VPSCATTERQQ, + ZYDIS_MNEMONIC_VPSHAB, + ZYDIS_MNEMONIC_VPSHAD, + ZYDIS_MNEMONIC_VPSHAQ, + ZYDIS_MNEMONIC_VPSHAW, + ZYDIS_MNEMONIC_VPSHLB, + ZYDIS_MNEMONIC_VPSHLD, + ZYDIS_MNEMONIC_VPSHLDD, + ZYDIS_MNEMONIC_VPSHLDQ, + ZYDIS_MNEMONIC_VPSHLDVD, + ZYDIS_MNEMONIC_VPSHLDVQ, + ZYDIS_MNEMONIC_VPSHLDVW, + ZYDIS_MNEMONIC_VPSHLDW, + ZYDIS_MNEMONIC_VPSHLQ, + ZYDIS_MNEMONIC_VPSHLW, + ZYDIS_MNEMONIC_VPSHRDD, + ZYDIS_MNEMONIC_VPSHRDQ, + ZYDIS_MNEMONIC_VPSHRDVD, + ZYDIS_MNEMONIC_VPSHRDVQ, + ZYDIS_MNEMONIC_VPSHRDVW, + ZYDIS_MNEMONIC_VPSHRDW, + ZYDIS_MNEMONIC_VPSHUFB, + ZYDIS_MNEMONIC_VPSHUFBITQMB, + ZYDIS_MNEMONIC_VPSHUFD, + ZYDIS_MNEMONIC_VPSHUFHW, + ZYDIS_MNEMONIC_VPSHUFLW, + ZYDIS_MNEMONIC_VPSIGNB, + ZYDIS_MNEMONIC_VPSIGND, + ZYDIS_MNEMONIC_VPSIGNW, + ZYDIS_MNEMONIC_VPSLLD, + ZYDIS_MNEMONIC_VPSLLDQ, + ZYDIS_MNEMONIC_VPSLLQ, + ZYDIS_MNEMONIC_VPSLLVD, + ZYDIS_MNEMONIC_VPSLLVQ, + ZYDIS_MNEMONIC_VPSLLVW, + ZYDIS_MNEMONIC_VPSLLW, + ZYDIS_MNEMONIC_VPSRAD, + ZYDIS_MNEMONIC_VPSRAQ, + ZYDIS_MNEMONIC_VPSRAVD, + ZYDIS_MNEMONIC_VPSRAVQ, + ZYDIS_MNEMONIC_VPSRAVW, + ZYDIS_MNEMONIC_VPSRAW, + ZYDIS_MNEMONIC_VPSRLD, + ZYDIS_MNEMONIC_VPSRLDQ, + ZYDIS_MNEMONIC_VPSRLQ, + ZYDIS_MNEMONIC_VPSRLVD, + ZYDIS_MNEMONIC_VPSRLVQ, + ZYDIS_MNEMONIC_VPSRLVW, + ZYDIS_MNEMONIC_VPSRLW, + ZYDIS_MNEMONIC_VPSUBB, + ZYDIS_MNEMONIC_VPSUBD, + ZYDIS_MNEMONIC_VPSUBQ, + ZYDIS_MNEMONIC_VPSUBRD, + ZYDIS_MNEMONIC_VPSUBRSETBD, + ZYDIS_MNEMONIC_VPSUBSB, + ZYDIS_MNEMONIC_VPSUBSETBD, + ZYDIS_MNEMONIC_VPSUBSW, + ZYDIS_MNEMONIC_VPSUBUSB, + ZYDIS_MNEMONIC_VPSUBUSW, + ZYDIS_MNEMONIC_VPSUBW, + ZYDIS_MNEMONIC_VPTERNLOGD, + ZYDIS_MNEMONIC_VPTERNLOGQ, + ZYDIS_MNEMONIC_VPTEST, + ZYDIS_MNEMONIC_VPTESTMB, + ZYDIS_MNEMONIC_VPTESTMD, + ZYDIS_MNEMONIC_VPTESTMQ, + ZYDIS_MNEMONIC_VPTESTMW, + ZYDIS_MNEMONIC_VPTESTNMB, + ZYDIS_MNEMONIC_VPTESTNMD, + ZYDIS_MNEMONIC_VPTESTNMQ, + ZYDIS_MNEMONIC_VPTESTNMW, + ZYDIS_MNEMONIC_VPUNPCKHBW, + ZYDIS_MNEMONIC_VPUNPCKHDQ, + ZYDIS_MNEMONIC_VPUNPCKHQDQ, + ZYDIS_MNEMONIC_VPUNPCKHWD, + ZYDIS_MNEMONIC_VPUNPCKLBW, + ZYDIS_MNEMONIC_VPUNPCKLDQ, + ZYDIS_MNEMONIC_VPUNPCKLQDQ, + ZYDIS_MNEMONIC_VPUNPCKLWD, + ZYDIS_MNEMONIC_VPXOR, + ZYDIS_MNEMONIC_VPXORD, + ZYDIS_MNEMONIC_VPXORQ, + ZYDIS_MNEMONIC_VRANGEPD, + ZYDIS_MNEMONIC_VRANGEPS, + ZYDIS_MNEMONIC_VRANGESD, + ZYDIS_MNEMONIC_VRANGESS, + ZYDIS_MNEMONIC_VRCP14PD, + ZYDIS_MNEMONIC_VRCP14PS, + ZYDIS_MNEMONIC_VRCP14SD, + ZYDIS_MNEMONIC_VRCP14SS, + ZYDIS_MNEMONIC_VRCP23PS, + ZYDIS_MNEMONIC_VRCP28PD, + ZYDIS_MNEMONIC_VRCP28PS, + ZYDIS_MNEMONIC_VRCP28SD, + ZYDIS_MNEMONIC_VRCP28SS, + ZYDIS_MNEMONIC_VRCPPS, + ZYDIS_MNEMONIC_VRCPSS, + ZYDIS_MNEMONIC_VREDUCEPD, + ZYDIS_MNEMONIC_VREDUCEPS, + ZYDIS_MNEMONIC_VREDUCESD, + ZYDIS_MNEMONIC_VREDUCESS, + ZYDIS_MNEMONIC_VRNDFXPNTPD, + ZYDIS_MNEMONIC_VRNDFXPNTPS, + ZYDIS_MNEMONIC_VRNDSCALEPD, + ZYDIS_MNEMONIC_VRNDSCALEPS, + ZYDIS_MNEMONIC_VRNDSCALESD, + ZYDIS_MNEMONIC_VRNDSCALESS, + ZYDIS_MNEMONIC_VROUNDPD, + ZYDIS_MNEMONIC_VROUNDPS, + ZYDIS_MNEMONIC_VROUNDSD, + ZYDIS_MNEMONIC_VROUNDSS, + ZYDIS_MNEMONIC_VRSQRT14PD, + ZYDIS_MNEMONIC_VRSQRT14PS, + ZYDIS_MNEMONIC_VRSQRT14SD, + ZYDIS_MNEMONIC_VRSQRT14SS, + ZYDIS_MNEMONIC_VRSQRT23PS, + ZYDIS_MNEMONIC_VRSQRT28PD, + ZYDIS_MNEMONIC_VRSQRT28PS, + ZYDIS_MNEMONIC_VRSQRT28SD, + ZYDIS_MNEMONIC_VRSQRT28SS, + ZYDIS_MNEMONIC_VRSQRTPS, + ZYDIS_MNEMONIC_VRSQRTSS, + ZYDIS_MNEMONIC_VSCALEFPD, + ZYDIS_MNEMONIC_VSCALEFPS, + ZYDIS_MNEMONIC_VSCALEFSD, + ZYDIS_MNEMONIC_VSCALEFSS, + ZYDIS_MNEMONIC_VSCALEPS, + ZYDIS_MNEMONIC_VSCATTERDPD, + ZYDIS_MNEMONIC_VSCATTERDPS, + ZYDIS_MNEMONIC_VSCATTERPF0DPD, + ZYDIS_MNEMONIC_VSCATTERPF0DPS, + ZYDIS_MNEMONIC_VSCATTERPF0HINTDPD, + ZYDIS_MNEMONIC_VSCATTERPF0HINTDPS, + ZYDIS_MNEMONIC_VSCATTERPF0QPD, + ZYDIS_MNEMONIC_VSCATTERPF0QPS, + ZYDIS_MNEMONIC_VSCATTERPF1DPD, + ZYDIS_MNEMONIC_VSCATTERPF1DPS, + ZYDIS_MNEMONIC_VSCATTERPF1QPD, + ZYDIS_MNEMONIC_VSCATTERPF1QPS, + ZYDIS_MNEMONIC_VSCATTERQPD, + ZYDIS_MNEMONIC_VSCATTERQPS, + ZYDIS_MNEMONIC_VSHUFF32X4, + ZYDIS_MNEMONIC_VSHUFF64X2, + ZYDIS_MNEMONIC_VSHUFI32X4, + ZYDIS_MNEMONIC_VSHUFI64X2, + ZYDIS_MNEMONIC_VSHUFPD, + ZYDIS_MNEMONIC_VSHUFPS, + ZYDIS_MNEMONIC_VSQRTPD, + ZYDIS_MNEMONIC_VSQRTPS, + ZYDIS_MNEMONIC_VSQRTSD, + ZYDIS_MNEMONIC_VSQRTSS, + ZYDIS_MNEMONIC_VSTMXCSR, + ZYDIS_MNEMONIC_VSUBPD, + ZYDIS_MNEMONIC_VSUBPS, + ZYDIS_MNEMONIC_VSUBRPD, + ZYDIS_MNEMONIC_VSUBRPS, + ZYDIS_MNEMONIC_VSUBSD, + ZYDIS_MNEMONIC_VSUBSS, + ZYDIS_MNEMONIC_VTESTPD, + ZYDIS_MNEMONIC_VTESTPS, + ZYDIS_MNEMONIC_VUCOMISD, + ZYDIS_MNEMONIC_VUCOMISS, + ZYDIS_MNEMONIC_VUNPCKHPD, + ZYDIS_MNEMONIC_VUNPCKHPS, + ZYDIS_MNEMONIC_VUNPCKLPD, + ZYDIS_MNEMONIC_VUNPCKLPS, + ZYDIS_MNEMONIC_VXORPD, + ZYDIS_MNEMONIC_VXORPS, + ZYDIS_MNEMONIC_VZEROALL, + ZYDIS_MNEMONIC_VZEROUPPER, + ZYDIS_MNEMONIC_WBINVD, + ZYDIS_MNEMONIC_WRFSBASE, + ZYDIS_MNEMONIC_WRGSBASE, + ZYDIS_MNEMONIC_WRMSR, + ZYDIS_MNEMONIC_WRPKRU, + ZYDIS_MNEMONIC_WRSSD, + ZYDIS_MNEMONIC_WRSSQ, + ZYDIS_MNEMONIC_WRUSSD, + ZYDIS_MNEMONIC_WRUSSQ, + ZYDIS_MNEMONIC_XABORT, + ZYDIS_MNEMONIC_XADD, + ZYDIS_MNEMONIC_XBEGIN, + ZYDIS_MNEMONIC_XCHG, + ZYDIS_MNEMONIC_XCRYPT_CBC, + ZYDIS_MNEMONIC_XCRYPT_CFB, + ZYDIS_MNEMONIC_XCRYPT_CTR, + ZYDIS_MNEMONIC_XCRYPT_ECB, + ZYDIS_MNEMONIC_XCRYPT_OFB, + ZYDIS_MNEMONIC_XEND, + ZYDIS_MNEMONIC_XGETBV, + ZYDIS_MNEMONIC_XLAT, + ZYDIS_MNEMONIC_XOR, + ZYDIS_MNEMONIC_XORPD, + ZYDIS_MNEMONIC_XORPS, + ZYDIS_MNEMONIC_XRESLDTRK, + ZYDIS_MNEMONIC_XRSTOR, + ZYDIS_MNEMONIC_XRSTOR64, + ZYDIS_MNEMONIC_XRSTORS, + ZYDIS_MNEMONIC_XRSTORS64, + ZYDIS_MNEMONIC_XSAVE, + ZYDIS_MNEMONIC_XSAVE64, + ZYDIS_MNEMONIC_XSAVEC, + ZYDIS_MNEMONIC_XSAVEC64, + ZYDIS_MNEMONIC_XSAVEOPT, + ZYDIS_MNEMONIC_XSAVEOPT64, + ZYDIS_MNEMONIC_XSAVES, + ZYDIS_MNEMONIC_XSAVES64, + ZYDIS_MNEMONIC_XSETBV, + ZYDIS_MNEMONIC_XSHA1, + ZYDIS_MNEMONIC_XSHA256, + ZYDIS_MNEMONIC_XSTORE, + ZYDIS_MNEMONIC_XSUSLDTRK, + ZYDIS_MNEMONIC_XTEST, + + /** + * Maximum value of this enum. + */ + ZYDIS_MNEMONIC_MAX_VALUE = ZYDIS_MNEMONIC_XTEST, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MNEMONIC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MNEMONIC_MAX_VALUE) +} ZydisMnemonic; diff --git a/src/Zydis/Generated/EnumRegister.h b/src/Zydis/Generated/EnumRegister.h new file mode 100644 index 0000000..3135fe0 --- /dev/null +++ b/src/Zydis/Generated/EnumRegister.h @@ -0,0 +1,301 @@ +/** + * Defines the `ZydisRegister` enum. + */ +typedef enum ZydisRegister_ +{ + ZYDIS_REGISTER_NONE, + + // General purpose registers 8-bit + ZYDIS_REGISTER_AL, + ZYDIS_REGISTER_CL, + ZYDIS_REGISTER_DL, + ZYDIS_REGISTER_BL, + ZYDIS_REGISTER_AH, + ZYDIS_REGISTER_CH, + ZYDIS_REGISTER_DH, + ZYDIS_REGISTER_BH, + ZYDIS_REGISTER_SPL, + ZYDIS_REGISTER_BPL, + ZYDIS_REGISTER_SIL, + ZYDIS_REGISTER_DIL, + ZYDIS_REGISTER_R8B, + ZYDIS_REGISTER_R9B, + ZYDIS_REGISTER_R10B, + ZYDIS_REGISTER_R11B, + ZYDIS_REGISTER_R12B, + ZYDIS_REGISTER_R13B, + ZYDIS_REGISTER_R14B, + ZYDIS_REGISTER_R15B, + // General purpose registers 16-bit + ZYDIS_REGISTER_AX, + ZYDIS_REGISTER_CX, + ZYDIS_REGISTER_DX, + ZYDIS_REGISTER_BX, + ZYDIS_REGISTER_SP, + ZYDIS_REGISTER_BP, + ZYDIS_REGISTER_SI, + ZYDIS_REGISTER_DI, + ZYDIS_REGISTER_R8W, + ZYDIS_REGISTER_R9W, + ZYDIS_REGISTER_R10W, + ZYDIS_REGISTER_R11W, + ZYDIS_REGISTER_R12W, + ZYDIS_REGISTER_R13W, + ZYDIS_REGISTER_R14W, + ZYDIS_REGISTER_R15W, + // General purpose registers 32-bit + ZYDIS_REGISTER_EAX, + ZYDIS_REGISTER_ECX, + ZYDIS_REGISTER_EDX, + ZYDIS_REGISTER_EBX, + ZYDIS_REGISTER_ESP, + ZYDIS_REGISTER_EBP, + ZYDIS_REGISTER_ESI, + ZYDIS_REGISTER_EDI, + ZYDIS_REGISTER_R8D, + ZYDIS_REGISTER_R9D, + ZYDIS_REGISTER_R10D, + ZYDIS_REGISTER_R11D, + ZYDIS_REGISTER_R12D, + ZYDIS_REGISTER_R13D, + ZYDIS_REGISTER_R14D, + ZYDIS_REGISTER_R15D, + // General purpose registers 64-bit + ZYDIS_REGISTER_RAX, + ZYDIS_REGISTER_RCX, + ZYDIS_REGISTER_RDX, + ZYDIS_REGISTER_RBX, + ZYDIS_REGISTER_RSP, + ZYDIS_REGISTER_RBP, + ZYDIS_REGISTER_RSI, + ZYDIS_REGISTER_RDI, + ZYDIS_REGISTER_R8, + ZYDIS_REGISTER_R9, + ZYDIS_REGISTER_R10, + ZYDIS_REGISTER_R11, + ZYDIS_REGISTER_R12, + ZYDIS_REGISTER_R13, + ZYDIS_REGISTER_R14, + ZYDIS_REGISTER_R15, + // Floating point legacy registers + ZYDIS_REGISTER_ST0, + ZYDIS_REGISTER_ST1, + ZYDIS_REGISTER_ST2, + ZYDIS_REGISTER_ST3, + ZYDIS_REGISTER_ST4, + ZYDIS_REGISTER_ST5, + ZYDIS_REGISTER_ST6, + ZYDIS_REGISTER_ST7, + ZYDIS_REGISTER_X87CONTROL, + ZYDIS_REGISTER_X87STATUS, + ZYDIS_REGISTER_X87TAG, + // Floating point multimedia registers + ZYDIS_REGISTER_MM0, + ZYDIS_REGISTER_MM1, + ZYDIS_REGISTER_MM2, + ZYDIS_REGISTER_MM3, + ZYDIS_REGISTER_MM4, + ZYDIS_REGISTER_MM5, + ZYDIS_REGISTER_MM6, + ZYDIS_REGISTER_MM7, + // Floating point vector registers 128-bit + ZYDIS_REGISTER_XMM0, + ZYDIS_REGISTER_XMM1, + ZYDIS_REGISTER_XMM2, + ZYDIS_REGISTER_XMM3, + ZYDIS_REGISTER_XMM4, + ZYDIS_REGISTER_XMM5, + ZYDIS_REGISTER_XMM6, + ZYDIS_REGISTER_XMM7, + ZYDIS_REGISTER_XMM8, + ZYDIS_REGISTER_XMM9, + ZYDIS_REGISTER_XMM10, + ZYDIS_REGISTER_XMM11, + ZYDIS_REGISTER_XMM12, + ZYDIS_REGISTER_XMM13, + ZYDIS_REGISTER_XMM14, + ZYDIS_REGISTER_XMM15, + ZYDIS_REGISTER_XMM16, + ZYDIS_REGISTER_XMM17, + ZYDIS_REGISTER_XMM18, + ZYDIS_REGISTER_XMM19, + ZYDIS_REGISTER_XMM20, + ZYDIS_REGISTER_XMM21, + ZYDIS_REGISTER_XMM22, + ZYDIS_REGISTER_XMM23, + ZYDIS_REGISTER_XMM24, + ZYDIS_REGISTER_XMM25, + ZYDIS_REGISTER_XMM26, + ZYDIS_REGISTER_XMM27, + ZYDIS_REGISTER_XMM28, + ZYDIS_REGISTER_XMM29, + ZYDIS_REGISTER_XMM30, + ZYDIS_REGISTER_XMM31, + // Floating point vector registers 256-bit + ZYDIS_REGISTER_YMM0, + ZYDIS_REGISTER_YMM1, + ZYDIS_REGISTER_YMM2, + ZYDIS_REGISTER_YMM3, + ZYDIS_REGISTER_YMM4, + ZYDIS_REGISTER_YMM5, + ZYDIS_REGISTER_YMM6, + ZYDIS_REGISTER_YMM7, + ZYDIS_REGISTER_YMM8, + ZYDIS_REGISTER_YMM9, + ZYDIS_REGISTER_YMM10, + ZYDIS_REGISTER_YMM11, + ZYDIS_REGISTER_YMM12, + ZYDIS_REGISTER_YMM13, + ZYDIS_REGISTER_YMM14, + ZYDIS_REGISTER_YMM15, + ZYDIS_REGISTER_YMM16, + ZYDIS_REGISTER_YMM17, + ZYDIS_REGISTER_YMM18, + ZYDIS_REGISTER_YMM19, + ZYDIS_REGISTER_YMM20, + ZYDIS_REGISTER_YMM21, + ZYDIS_REGISTER_YMM22, + ZYDIS_REGISTER_YMM23, + ZYDIS_REGISTER_YMM24, + ZYDIS_REGISTER_YMM25, + ZYDIS_REGISTER_YMM26, + ZYDIS_REGISTER_YMM27, + ZYDIS_REGISTER_YMM28, + ZYDIS_REGISTER_YMM29, + ZYDIS_REGISTER_YMM30, + ZYDIS_REGISTER_YMM31, + // Floating point vector registers 512-bit + ZYDIS_REGISTER_ZMM0, + ZYDIS_REGISTER_ZMM1, + ZYDIS_REGISTER_ZMM2, + ZYDIS_REGISTER_ZMM3, + ZYDIS_REGISTER_ZMM4, + ZYDIS_REGISTER_ZMM5, + ZYDIS_REGISTER_ZMM6, + ZYDIS_REGISTER_ZMM7, + ZYDIS_REGISTER_ZMM8, + ZYDIS_REGISTER_ZMM9, + ZYDIS_REGISTER_ZMM10, + ZYDIS_REGISTER_ZMM11, + ZYDIS_REGISTER_ZMM12, + ZYDIS_REGISTER_ZMM13, + ZYDIS_REGISTER_ZMM14, + ZYDIS_REGISTER_ZMM15, + ZYDIS_REGISTER_ZMM16, + ZYDIS_REGISTER_ZMM17, + ZYDIS_REGISTER_ZMM18, + ZYDIS_REGISTER_ZMM19, + ZYDIS_REGISTER_ZMM20, + ZYDIS_REGISTER_ZMM21, + ZYDIS_REGISTER_ZMM22, + ZYDIS_REGISTER_ZMM23, + ZYDIS_REGISTER_ZMM24, + ZYDIS_REGISTER_ZMM25, + ZYDIS_REGISTER_ZMM26, + ZYDIS_REGISTER_ZMM27, + ZYDIS_REGISTER_ZMM28, + ZYDIS_REGISTER_ZMM29, + ZYDIS_REGISTER_ZMM30, + ZYDIS_REGISTER_ZMM31, + // Matrix registers + ZYDIS_REGISTER_TMM0, + ZYDIS_REGISTER_TMM1, + ZYDIS_REGISTER_TMM2, + ZYDIS_REGISTER_TMM3, + ZYDIS_REGISTER_TMM4, + ZYDIS_REGISTER_TMM5, + ZYDIS_REGISTER_TMM6, + ZYDIS_REGISTER_TMM7, + // Flags registers + ZYDIS_REGISTER_FLAGS, + ZYDIS_REGISTER_EFLAGS, + ZYDIS_REGISTER_RFLAGS, + // Instruction-pointer registers + ZYDIS_REGISTER_IP, + ZYDIS_REGISTER_EIP, + ZYDIS_REGISTER_RIP, + // Segment registers + ZYDIS_REGISTER_ES, + ZYDIS_REGISTER_CS, + ZYDIS_REGISTER_SS, + ZYDIS_REGISTER_DS, + ZYDIS_REGISTER_FS, + ZYDIS_REGISTER_GS, + // Table registers + ZYDIS_REGISTER_GDTR, + ZYDIS_REGISTER_LDTR, + ZYDIS_REGISTER_IDTR, + ZYDIS_REGISTER_TR, + // Test registers + ZYDIS_REGISTER_TR0, + ZYDIS_REGISTER_TR1, + ZYDIS_REGISTER_TR2, + ZYDIS_REGISTER_TR3, + ZYDIS_REGISTER_TR4, + ZYDIS_REGISTER_TR5, + ZYDIS_REGISTER_TR6, + ZYDIS_REGISTER_TR7, + // Control registers + ZYDIS_REGISTER_CR0, + ZYDIS_REGISTER_CR1, + ZYDIS_REGISTER_CR2, + ZYDIS_REGISTER_CR3, + ZYDIS_REGISTER_CR4, + ZYDIS_REGISTER_CR5, + ZYDIS_REGISTER_CR6, + ZYDIS_REGISTER_CR7, + ZYDIS_REGISTER_CR8, + ZYDIS_REGISTER_CR9, + ZYDIS_REGISTER_CR10, + ZYDIS_REGISTER_CR11, + ZYDIS_REGISTER_CR12, + ZYDIS_REGISTER_CR13, + ZYDIS_REGISTER_CR14, + ZYDIS_REGISTER_CR15, + // Debug registers + ZYDIS_REGISTER_DR0, + ZYDIS_REGISTER_DR1, + ZYDIS_REGISTER_DR2, + ZYDIS_REGISTER_DR3, + ZYDIS_REGISTER_DR4, + ZYDIS_REGISTER_DR5, + ZYDIS_REGISTER_DR6, + ZYDIS_REGISTER_DR7, + ZYDIS_REGISTER_DR8, + ZYDIS_REGISTER_DR9, + ZYDIS_REGISTER_DR10, + ZYDIS_REGISTER_DR11, + ZYDIS_REGISTER_DR12, + ZYDIS_REGISTER_DR13, + ZYDIS_REGISTER_DR14, + ZYDIS_REGISTER_DR15, + // Mask registers + ZYDIS_REGISTER_K0, + ZYDIS_REGISTER_K1, + ZYDIS_REGISTER_K2, + ZYDIS_REGISTER_K3, + ZYDIS_REGISTER_K4, + ZYDIS_REGISTER_K5, + ZYDIS_REGISTER_K6, + ZYDIS_REGISTER_K7, + // Bound registers + ZYDIS_REGISTER_BND0, + ZYDIS_REGISTER_BND1, + ZYDIS_REGISTER_BND2, + ZYDIS_REGISTER_BND3, + ZYDIS_REGISTER_BNDCFG, + ZYDIS_REGISTER_BNDSTATUS, + // Uncategorized + ZYDIS_REGISTER_MXCSR, + ZYDIS_REGISTER_PKRU, + ZYDIS_REGISTER_XCR0, + + /** + * Maximum value of this enum. + */ + ZYDIS_REGISTER_MAX_VALUE = ZYDIS_REGISTER_XCR0, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_REGISTER_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_REGISTER_MAX_VALUE) +} ZydisRegister; diff --git a/src/Zydis/Internal/DecoderData.h b/src/Zydis/Internal/DecoderData.h new file mode 100644 index 0000000..db6cf53 --- /dev/null +++ b/src/Zydis/Internal/DecoderData.h @@ -0,0 +1,331 @@ +/*************************************************************************************************** + + 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 +#include + +#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/src/Zydis/Internal/FormatterATT.h b/src/Zydis/Internal/FormatterATT.h new file mode 100644 index 0000000..08b7134 --- /dev/null +++ b/src/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 + * Implements the `AT&T` style instruction-formatter. + */ + +#ifndef ZYDIS_FORMATTER_ATT_H +#define ZYDIS_FORMATTER_ATT_H + +#include +#include +#include + +#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 */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * 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/src/Zydis/Internal/FormatterBase.h b/src/Zydis/Internal/FormatterBase.h new file mode 100644 index 0000000..0a61747 --- /dev/null +++ b/src/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 + * Provides formatter functions that are shared between the different formatters. + */ + +#ifndef ZYDIS_FORMATTER_BASE_H +#define ZYDIS_FORMATTER_BASE_H + +#include +#include + +#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. + * @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; \ + } + +/** + * 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 */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * 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 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/src/Zydis/Internal/FormatterIntel.h b/src/Zydis/Internal/FormatterIntel.h new file mode 100644 index 0000000..cd12d38 --- /dev/null +++ b/src/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 + * Implements the `INTEL` style instruction-formatter. + */ + +#ifndef ZYDIS_FORMATTER_INTEL_H +#define ZYDIS_FORMATTER_INTEL_H + +#include +#include +#include + +#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_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 */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * 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/src/Zydis/Internal/SharedData.h b/src/Zydis/Internal/SharedData.h new file mode 100644 index 0000000..d8db4fb --- /dev/null +++ b/src/Zydis/Internal/SharedData.h @@ -0,0 +1,974 @@ +/*************************************************************************************************** + + 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 +#include +#include +#include +#include + +#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_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_ +{ + 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, + + /** + * 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_ +{ + 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, + + /** + * Maximum value of this enum. + */ + ZYDIS_IMPLMEM_BASE_MAX_VALUE = ZYDIS_IMPLMEM_BASE_ADI, + /** + * 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; +} 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 `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, + ZYDIS_REG_CONSTRAINTS_NO_REL, + + /** + * Maximum value of this enum. + */ + ZYDIS_REG_CONSTRAINTS_MAX_VALUE = ZYDIS_REG_CONSTRAINTS_NO_REL, + /** + * 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; + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * 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, + + /** + * Maximum value of this enum. + */ + ZYDIS_TUPLETYPE_MAX_VALUE = ZYDIS_TUPLETYPE_DUP, + /** + * 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; + +/* ---------------------------------------------------------------------------------------------- */ + +// 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) + +/** + * 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_hle_without_lock ZYAN_BITFIELD( 1); + ZyanBool accepts_branch_hints ZYAN_BITFIELD( 1); + ZyanBool accepts_segment 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 + +/* ---------------------------------------------------------------------------------------------- */ +/* Accessed CPU flags */ +/* ---------------------------------------------------------------------------------------------- */ + +typedef struct ZydisAccessedFlags_ +{ + ZydisCPUFlagAction action[ZYDIS_CPUFLAG_MAX_VALUE + 1]; + ZyanU32 cpu_flags_read ZYAN_BITFIELD(22); + ZyanU32 cpu_flags_written ZYAN_BITFIELD(22); + ZyanU8 fpu_flags_read ZYAN_BITFIELD( 4); + ZyanU8 fpu_flags_written ZYAN_BITFIELD( 4); +} ZydisAccessedFlags; + +/* ---------------------------------------------------------------------------------------------- */ + +#pragma pack(pop) + +#ifdef ZYAN_MSVC +# pragma warning(pop) +#endif + +/* ============================================================================================== */ +/* 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. + * @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 +/** + * 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 `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/src/Zydis/Internal/String.h b/src/Zydis/Internal/String.h new file mode 100644 index 0000000..18ed812 --- /dev/null +++ b/src/Zydis/Internal/String.h @@ -0,0 +1,464 @@ +/*************************************************************************************************** + + 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 +#include +#include +#include +#include +#include + +#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. + * @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. + * @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, 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. + * @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); + +/** + * 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, ZyanAbsI64(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 diff --git a/src/Zydis/MetaInfo.h b/src/Zydis/MetaInfo.h new file mode 100644 index 0000000..6867d32 --- /dev/null +++ b/src/Zydis/MetaInfo.h @@ -0,0 +1,88 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * @brief + */ + +#ifndef ZYDIS_METAINFO_H +#define ZYDIS_METAINFO_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +#include +#include +#include + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + + /** + * Returns the specified instruction category string. + * + * @param category The instruction category. + * + * @return The instruction category string or `ZYAN_NULL`, if an invalid category was passed. + */ +ZYDIS_EXPORT const char* ZydisCategoryGetString(ZydisInstructionCategory category); + +/** + * Returns the specified isa-set string. + * + * @param isa_set The isa-set. + * + * @return The isa-set string or `ZYAN_NULL`, if an invalid isa-set was passed. + */ +ZYDIS_EXPORT const char* ZydisISASetGetString(ZydisISASet isa_set); + +/** + * Returns the specified isa-extension string. + * + * @param isa_ext The isa-extension. + * + * @return The isa-extension string or `ZYAN_NULL`, if an invalid isa-extension was passed. + */ +ZYDIS_EXPORT const char* ZydisISAExtGetString(ZydisISAExt isa_ext); + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_METAINFO_H */ diff --git a/src/Zydis/Mnemonic.h b/src/Zydis/Mnemonic.h new file mode 100644 index 0000000..dd8fec8 --- /dev/null +++ b/src/Zydis/Mnemonic.h @@ -0,0 +1,88 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Mnemonic constant definitions and helper functions. + */ + +#ifndef ZYDIS_MNEMONIC_H +#define ZYDIS_MNEMONIC_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +#include + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * @addtogroup mnemonic Mnemonic + * Functions for retrieving mnemonic names. + * @{ + */ + +/** + * Returns the specified instruction mnemonic string. + * + * @param mnemonic The mnemonic. + * + * @return The instruction mnemonic string or `ZYAN_NULL`, if an invalid mnemonic was passed. + */ +ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic); + +/** + * Returns the specified instruction mnemonic as `ZydisShortString`. + * + * @param mnemonic The mnemonic. + * + * @return The instruction mnemonic string or `ZYAN_NULL`, if an invalid mnemonic was passed. + * + * The `buffer` of the returned struct is guaranteed to be zero-terminated in this special case. + */ +ZYDIS_EXPORT const ZydisShortString* ZydisMnemonicGetStringWrapped(ZydisMnemonic mnemonic); + +/** + * @} + */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_MNEMONIC_H */ diff --git a/src/Zydis/Register.h b/src/Zydis/Register.h new file mode 100644 index 0000000..0ff955f --- /dev/null +++ b/src/Zydis/Register.h @@ -0,0 +1,293 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Utility functions and constants for registers. + */ + +#ifndef ZYDIS_REGISTER_H +#define ZYDIS_REGISTER_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Registers */ +/* ---------------------------------------------------------------------------------------------- */ + +#include + +/* ---------------------------------------------------------------------------------------------- */ +/* Register classes */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisRegisterClass` enum. + * + * Please note that this enum does not contain a matching entry for all values of the + * `ZydisRegister` enum, but only for those registers where it makes sense to logically group them + * for decoding/encoding purposes. + * + * These are mainly the registers that can be identified by an id within their corresponding + * register-class. The `IP` and `FLAGS` values are exceptions to this rule. + */ +typedef enum ZydisRegisterClass_ +{ + ZYDIS_REGCLASS_INVALID, + /** + * 8-bit general-purpose registers. + */ + ZYDIS_REGCLASS_GPR8, + /** + * 16-bit general-purpose registers. + */ + ZYDIS_REGCLASS_GPR16, + /** + * 32-bit general-purpose registers. + */ + ZYDIS_REGCLASS_GPR32, + /** + * 64-bit general-purpose registers. + */ + ZYDIS_REGCLASS_GPR64, + /** + * Floating point legacy registers. + */ + ZYDIS_REGCLASS_X87, + /** + * Floating point multimedia registers. + */ + ZYDIS_REGCLASS_MMX, + /** + * 128-bit vector registers. + */ + ZYDIS_REGCLASS_XMM, + /** + * 256-bit vector registers. + */ + ZYDIS_REGCLASS_YMM, + /** + * 512-bit vector registers. + */ + ZYDIS_REGCLASS_ZMM, + /** + * Matrix registers. + */ + ZYDIS_REGCLASS_TMM, + /* + * Flags registers. + */ + ZYDIS_REGCLASS_FLAGS, + /** + * Instruction-pointer registers. + */ + ZYDIS_REGCLASS_IP, + /** + * Segment registers. + */ + ZYDIS_REGCLASS_SEGMENT, + /** + * Test registers. + */ + ZYDIS_REGCLASS_TEST, + /** + * Control registers. + */ + ZYDIS_REGCLASS_CONTROL, + /** + * Debug registers. + */ + ZYDIS_REGCLASS_DEBUG, + /** + * Mask registers. + */ + ZYDIS_REGCLASS_MASK, + /** + * Bound registers. + */ + ZYDIS_REGCLASS_BOUND, + + /** + * Maximum value of this enum. + */ + ZYDIS_REGCLASS_MAX_VALUE = ZYDIS_REGCLASS_BOUND, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_REGCLASS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_REGCLASS_MAX_VALUE) +} ZydisRegisterClass; + +/* ---------------------------------------------------------------------------------------------- */ +/* Register width */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisRegisterWidth` data-type. + */ +typedef ZyanU16 ZydisRegisterWidth; + +/* ---------------------------------------------------------------------------------------------- */ +/* Register context */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisRegisterContext` struct. + */ +typedef struct ZydisRegisterContext_ +{ + /** + * The values stored in the register context. + */ + ZyanU64 values[ZYDIS_REGISTER_MAX_VALUE + 1]; +} ZydisRegisterContext; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * @addtogroup register Register + * Functions allowing retrieval of information about registers. + * @{ + */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Register */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the register specified by the `register_class` and `id` tuple. + * + * @param register_class The register class. + * @param id The register id. + * + * @return The register specified by the `register_class` and `id` tuple or `ZYDIS_REGISTER_NONE`, + * if an invalid parameter was passed. + */ +ZYDIS_EXPORT ZydisRegister ZydisRegisterEncode(ZydisRegisterClass register_class, ZyanU8 id); + +/** + * Returns the id of the specified register. + * + * @param reg The register. + * + * @return The id of the specified register, or -1 if an invalid parameter was passed. + */ +ZYDIS_EXPORT ZyanI8 ZydisRegisterGetId(ZydisRegister reg); + +/** + * Returns the register-class of the specified register. + * + * @param reg The register. + * + * @return The register-class of the specified register. + */ +ZYDIS_EXPORT ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg); + +/** + * Returns the width of the specified register. + * + * @param mode The active machine mode. + * @param reg The register. + * + * @return The width of the specified register, or `ZYDIS_REGISTER_NONE` if the register is + * invalid for the active machine-mode. + */ +ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterGetWidth(ZydisMachineMode mode, ZydisRegister reg); + +/** + * Returns the largest enclosing register of the given register. + * + * @param mode The active machine mode. + * @param reg The register. + * + * @return The largest enclosing register of the given register, or `ZYDIS_REGISTER_NONE` if the + * register is invalid for the active machine-mode or does not have an enclosing-register. + */ +ZYDIS_EXPORT ZydisRegister ZydisRegisterGetLargestEnclosing(ZydisMachineMode mode, + ZydisRegister reg); + +/** + * Returns the specified register string. + * + * @param reg The register. + * + * @return The register string or `ZYAN_NULL`, if an invalid register was passed. + */ +ZYDIS_EXPORT const char* ZydisRegisterGetString(ZydisRegister reg); + +/** + * Returns the specified register string as `ZydisShortString`. + * + * @param reg The register. + * + * @return The register string or `ZYAN_NULL`, if an invalid register was passed. + * + * The `buffer` of the returned struct is guaranteed to be zero-terminated in this special case. + */ +ZYDIS_EXPORT const ZydisShortString* ZydisRegisterGetStringWrapped(ZydisRegister reg); + +/* ---------------------------------------------------------------------------------------------- */ +/* Register class */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns the width of the specified register-class. + * + * @param mode The active machine mode. + * @param register_class The register class. + * + * @return The width of the specified register. + */ +ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterClassGetWidth(ZydisMachineMode mode, + ZydisRegisterClass register_class); + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @} + */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_REGISTER_H */ diff --git a/src/Zydis/SharedTypes.h b/src/Zydis/SharedTypes.h new file mode 100644 index 0000000..82a4121 --- /dev/null +++ b/src/Zydis/SharedTypes.h @@ -0,0 +1,480 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Defines decoder/encoder-shared macros and types. + */ + +#ifndef ZYDIS_SHAREDTYPES_H +#define ZYDIS_SHAREDTYPES_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Constants */ +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYDIS_MAX_INSTRUCTION_LENGTH 15 +#define ZYDIS_MAX_OPERAND_COUNT 10 + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Machine mode */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisMachineMode` enum. + */ +typedef enum ZydisMachineMode_ +{ + /** + * 64 bit mode. + */ + ZYDIS_MACHINE_MODE_LONG_64, + /** + * 32 bit protected mode. + */ + ZYDIS_MACHINE_MODE_LONG_COMPAT_32, + /** + * 16 bit protected mode. + */ + ZYDIS_MACHINE_MODE_LONG_COMPAT_16, + /** + * 32 bit protected mode. + */ + ZYDIS_MACHINE_MODE_LEGACY_32, + /** + * 16 bit protected mode. + */ + ZYDIS_MACHINE_MODE_LEGACY_16, + /** + * 16 bit real mode. + */ + ZYDIS_MACHINE_MODE_REAL_16, + + /** + * Maximum value of this enum. + */ + ZYDIS_MACHINE_MODE_MAX_VALUE = ZYDIS_MACHINE_MODE_REAL_16, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_MACHINE_MODE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MACHINE_MODE_MAX_VALUE) +} ZydisMachineMode; + +/* ---------------------------------------------------------------------------------------------- */ +/* Address width */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisAddressWidth` enum. + */ +typedef enum ZydisAddressWidth_ +{ + ZYDIS_ADDRESS_WIDTH_16, + ZYDIS_ADDRESS_WIDTH_32, + ZYDIS_ADDRESS_WIDTH_64, + + /** + * Maximum value of this enum. + */ + ZYDIS_ADDRESS_WIDTH_MAX_VALUE = ZYDIS_ADDRESS_WIDTH_64, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_ADDRESS_WIDTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_ADDRESS_WIDTH_MAX_VALUE) +} ZydisAddressWidth; + +/* ---------------------------------------------------------------------------------------------- */ +/* Element type */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisElementType` enum. + */ +typedef enum ZydisElementType_ +{ + ZYDIS_ELEMENT_TYPE_INVALID, + /** + * A struct type. + */ + ZYDIS_ELEMENT_TYPE_STRUCT, + /** + * Unsigned integer value. + */ + ZYDIS_ELEMENT_TYPE_UINT, + /** + * Signed integer value. + */ + ZYDIS_ELEMENT_TYPE_INT, + /** + * 16-bit floating point value (`half`). + */ + ZYDIS_ELEMENT_TYPE_FLOAT16, + /** + * 32-bit floating point value (`single`). + */ + ZYDIS_ELEMENT_TYPE_FLOAT32, + /** + * 64-bit floating point value (`double`). + */ + ZYDIS_ELEMENT_TYPE_FLOAT64, + /** + * 80-bit floating point value (`extended`). + */ + ZYDIS_ELEMENT_TYPE_FLOAT80, + /** + * Binary coded decimal value. + */ + ZYDIS_ELEMENT_TYPE_LONGBCD, + /** + * A condition code (e.g. used by `CMPPD`, `VCMPPD`, ...). + */ + ZYDIS_ELEMENT_TYPE_CC, + + /** + * Maximum value of this enum. + */ + ZYDIS_ELEMENT_TYPE_MAX_VALUE = ZYDIS_ELEMENT_TYPE_CC, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_ELEMENT_TYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_ELEMENT_TYPE_MAX_VALUE) +} ZydisElementType; + +/* ---------------------------------------------------------------------------------------------- */ +/* Element size */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisElementSize` datatype. + */ +typedef ZyanU16 ZydisElementSize; + +/* ---------------------------------------------------------------------------------------------- */ +/* Operand type */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisOperandType` enum. + */ +typedef enum ZydisOperandType_ +{ + /** + * The operand is not used. + */ + ZYDIS_OPERAND_TYPE_UNUSED, + /** + * The operand is a register operand. + */ + ZYDIS_OPERAND_TYPE_REGISTER, + /** + * The operand is a memory operand. + */ + ZYDIS_OPERAND_TYPE_MEMORY, + /** + * The operand is a pointer operand with a segment:offset lvalue. + */ + ZYDIS_OPERAND_TYPE_POINTER, + /** + * The operand is an immediate operand. + */ + ZYDIS_OPERAND_TYPE_IMMEDIATE, + + /** + * Maximum value of this enum. + */ + ZYDIS_OPERAND_TYPE_MAX_VALUE = ZYDIS_OPERAND_TYPE_IMMEDIATE, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_OPERAND_TYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_OPERAND_TYPE_MAX_VALUE) +} ZydisOperandType; + +/* ---------------------------------------------------------------------------------------------- */ +/* Operand encoding */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisOperandEncoding` enum. + */ +typedef enum ZydisOperandEncoding_ +{ + ZYDIS_OPERAND_ENCODING_NONE, + ZYDIS_OPERAND_ENCODING_MODRM_REG, + ZYDIS_OPERAND_ENCODING_MODRM_RM, + ZYDIS_OPERAND_ENCODING_OPCODE, + ZYDIS_OPERAND_ENCODING_NDSNDD, + ZYDIS_OPERAND_ENCODING_IS4, + ZYDIS_OPERAND_ENCODING_MASK, + ZYDIS_OPERAND_ENCODING_DISP8, + ZYDIS_OPERAND_ENCODING_DISP16, + ZYDIS_OPERAND_ENCODING_DISP32, + ZYDIS_OPERAND_ENCODING_DISP64, + ZYDIS_OPERAND_ENCODING_DISP16_32_64, + ZYDIS_OPERAND_ENCODING_DISP32_32_64, + ZYDIS_OPERAND_ENCODING_DISP16_32_32, + ZYDIS_OPERAND_ENCODING_UIMM8, + ZYDIS_OPERAND_ENCODING_UIMM16, + ZYDIS_OPERAND_ENCODING_UIMM32, + ZYDIS_OPERAND_ENCODING_UIMM64, + ZYDIS_OPERAND_ENCODING_UIMM16_32_64, + ZYDIS_OPERAND_ENCODING_UIMM32_32_64, + ZYDIS_OPERAND_ENCODING_UIMM16_32_32, + ZYDIS_OPERAND_ENCODING_SIMM8, + ZYDIS_OPERAND_ENCODING_SIMM16, + ZYDIS_OPERAND_ENCODING_SIMM32, + ZYDIS_OPERAND_ENCODING_SIMM64, + ZYDIS_OPERAND_ENCODING_SIMM16_32_64, + ZYDIS_OPERAND_ENCODING_SIMM32_32_64, + ZYDIS_OPERAND_ENCODING_SIMM16_32_32, + ZYDIS_OPERAND_ENCODING_JIMM8, + ZYDIS_OPERAND_ENCODING_JIMM16, + ZYDIS_OPERAND_ENCODING_JIMM32, + ZYDIS_OPERAND_ENCODING_JIMM64, + ZYDIS_OPERAND_ENCODING_JIMM16_32_64, + ZYDIS_OPERAND_ENCODING_JIMM32_32_64, + ZYDIS_OPERAND_ENCODING_JIMM16_32_32, + + /** + * Maximum value of this enum. + */ + ZYDIS_OPERAND_ENCODING_MAX_VALUE = ZYDIS_OPERAND_ENCODING_JIMM16_32_32, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_OPERAND_ENCODING_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_OPERAND_ENCODING_MAX_VALUE) +} ZydisOperandEncoding; + +/* ---------------------------------------------------------------------------------------------- */ +/* Operand visibility */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisOperandVisibility` enum. + */ +typedef enum ZydisOperandVisibility_ +{ + ZYDIS_OPERAND_VISIBILITY_INVALID, + /** + * The operand is explicitly encoded in the instruction. + */ + ZYDIS_OPERAND_VISIBILITY_EXPLICIT, + /** + * The operand is part of the opcode, but listed as an operand. + */ + ZYDIS_OPERAND_VISIBILITY_IMPLICIT, + /** + * The operand is part of the opcode, and not typically listed as an operand. + */ + ZYDIS_OPERAND_VISIBILITY_HIDDEN, + + /** + * Maximum value of this enum. + */ + ZYDIS_OPERAND_VISIBILITY_MAX_VALUE = ZYDIS_OPERAND_VISIBILITY_HIDDEN, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_OPERAND_VISIBILITY_REQUIRED_BITS = + ZYAN_BITS_TO_REPRESENT(ZYDIS_OPERAND_VISIBILITY_MAX_VALUE) +} ZydisOperandVisibility; + +/* ---------------------------------------------------------------------------------------------- */ +/* Operand action */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisOperandAction` enum. + */ +typedef enum ZydisOperandAction_ +{ + /* ------------------------------------------------------------------------------------------ */ + /* Elemental actions */ + /* ------------------------------------------------------------------------------------------ */ + + /** + * The operand is read by the instruction. + */ + ZYDIS_OPERAND_ACTION_READ = 0x01, + /** + * The operand is written by the instruction (must write). + */ + ZYDIS_OPERAND_ACTION_WRITE = 0x02, + /** + * The operand is conditionally read by the instruction. + */ + ZYDIS_OPERAND_ACTION_CONDREAD = 0x04, + /** + * The operand is conditionally written by the instruction (may write). + */ + ZYDIS_OPERAND_ACTION_CONDWRITE = 0x08, + + /* ------------------------------------------------------------------------------------------ */ + /* Combined actions */ + /* ------------------------------------------------------------------------------------------ */ + + /** + * The operand is read (must read) and written by the instruction (must write). + */ + ZYDIS_OPERAND_ACTION_READWRITE = ZYDIS_OPERAND_ACTION_READ | ZYDIS_OPERAND_ACTION_WRITE, + /** + * The operand is conditionally read (may read) and conditionally written by + * the instruction (may write). + */ + ZYDIS_OPERAND_ACTION_CONDREAD_CONDWRITE = + ZYDIS_OPERAND_ACTION_CONDREAD | ZYDIS_OPERAND_ACTION_CONDWRITE, + /** + * The operand is read (must read) and conditionally written by the + * instruction (may write). + */ + ZYDIS_OPERAND_ACTION_READ_CONDWRITE = + ZYDIS_OPERAND_ACTION_READ | ZYDIS_OPERAND_ACTION_CONDWRITE, + /** + * The operand is written (must write) and conditionally read by the + * instruction (may read). + */ + ZYDIS_OPERAND_ACTION_CONDREAD_WRITE = + ZYDIS_OPERAND_ACTION_CONDREAD | ZYDIS_OPERAND_ACTION_WRITE, + + /** + * Mask combining all reading access flags. + */ + ZYDIS_OPERAND_ACTION_MASK_READ = ZYDIS_OPERAND_ACTION_READ | ZYDIS_OPERAND_ACTION_CONDREAD, + /** + * Mask combining all writing access flags. + */ + ZYDIS_OPERAND_ACTION_MASK_WRITE = ZYDIS_OPERAND_ACTION_WRITE | ZYDIS_OPERAND_ACTION_CONDWRITE, + + /* ------------------------------------------------------------------------------------------ */ + + /** + * The minimum number of bits required to represent all values of this bitset. + */ + ZYDIS_OPERAND_ACTION_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_OPERAND_ACTION_CONDWRITE) +} ZydisOperandAction; + +/** + * Defines the `ZydisOperandActions` data-type. + */ +typedef ZyanU8 ZydisOperandActions; + +/* ---------------------------------------------------------------------------------------------- */ +/* Instruction encoding */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisInstructionEncoding` enum. + */ +typedef enum ZydisInstructionEncoding_ +{ + /** + * The instruction uses the legacy encoding. + */ + ZYDIS_INSTRUCTION_ENCODING_LEGACY, + /** + * The instruction uses the AMD 3DNow-encoding. + */ + ZYDIS_INSTRUCTION_ENCODING_3DNOW, + /** + * The instruction uses the AMD XOP-encoding. + */ + ZYDIS_INSTRUCTION_ENCODING_XOP, + /** + * The instruction uses the VEX-encoding. + */ + ZYDIS_INSTRUCTION_ENCODING_VEX, + /** + * The instruction uses the EVEX-encoding. + */ + ZYDIS_INSTRUCTION_ENCODING_EVEX, + /** + * The instruction uses the MVEX-encoding. + */ + ZYDIS_INSTRUCTION_ENCODING_MVEX, + + /** + * Maximum value of this enum. + */ + ZYDIS_INSTRUCTION_ENCODING_MAX_VALUE = ZYDIS_INSTRUCTION_ENCODING_MVEX, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_INSTRUCTION_ENCODING_REQUIRED_BITS = + ZYAN_BITS_TO_REPRESENT(ZYDIS_INSTRUCTION_ENCODING_MAX_VALUE) +} ZydisInstructionEncoding; + +/* ---------------------------------------------------------------------------------------------- */ +/* Opcode map */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Defines the `ZydisOpcodeMap` enum. + */ +typedef enum ZydisOpcodeMap_ +{ + ZYDIS_OPCODE_MAP_DEFAULT, + ZYDIS_OPCODE_MAP_0F, + ZYDIS_OPCODE_MAP_0F38, + ZYDIS_OPCODE_MAP_0F3A, + ZYDIS_OPCODE_MAP_0F0F, + ZYDIS_OPCODE_MAP_XOP8, + ZYDIS_OPCODE_MAP_XOP9, + ZYDIS_OPCODE_MAP_XOPA, + + /** + * Maximum value of this enum. + */ + ZYDIS_OPCODE_MAP_MAX_VALUE = ZYDIS_OPCODE_MAP_XOPA, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_OPCODE_MAP_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_OPCODE_MAP_MAX_VALUE) +} ZydisOpcodeMap; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_SHAREDTYPES_H */ diff --git a/src/Zydis/ShortString.h b/src/Zydis/ShortString.h new file mode 100644 index 0000000..bed45af --- /dev/null +++ b/src/Zydis/ShortString.h @@ -0,0 +1,90 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Defines the immutable and storage-efficient `ZydisShortString` struct, which + * is used to store strings in the generated tables. + */ + +#ifndef ZYDIS_SHORTSTRING_H +#define ZYDIS_SHORTSTRING_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +#pragma pack(push, 1) + +/** + * Defines the `ZydisShortString` struct. + * + * This compact struct is mainly used for internal string-tables to save up some bytes. + * + * All fields in this struct should be considered as "private". Any changes may lead to unexpected + * behavior. + */ +typedef struct ZydisShortString_ +{ + /** + * The buffer that contains the actual (null-terminated) string. + */ + const char* data; + /** + * The length (number of characters) of the string (without 0-termination). + */ + ZyanU8 size; +} ZydisShortString; + +#pragma pack(pop) + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/** + * Declares a `ZydisShortString` from a static C-style string. + * + * @param string The C-string constant. + */ +#define ZYDIS_MAKE_SHORTSTRING(string) \ + { string, sizeof(string) - 1 } + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_SHORTSTRING_H */ diff --git a/src/Zydis/Status.h b/src/Zydis/Status.h new file mode 100644 index 0000000..d2a75f3 --- /dev/null +++ b/src/Zydis/Status.h @@ -0,0 +1,159 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Status code definitions and check macros. + */ + +#ifndef ZYDIS_STATUS_H +#define ZYDIS_STATUS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Status codes */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Module IDs */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * The zydis module id. + */ +#define ZYAN_MODULE_ZYDIS 0x002u + +/* ---------------------------------------------------------------------------------------------- */ +/* Status codes */ +/* ---------------------------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Decoder */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * An attempt was made to read data from an input data-source that has no more + * data available. + */ +#define ZYDIS_STATUS_NO_MORE_DATA \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x00u) + +/** + * An general error occured while decoding the current instruction. The + * instruction might be undefined. + */ +#define ZYDIS_STATUS_DECODING_ERROR \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x01u) + +/** + * The instruction exceeded the maximum length of 15 bytes. + */ +#define ZYDIS_STATUS_INSTRUCTION_TOO_LONG \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x02u) + +/** + * The instruction encoded an invalid register. + */ +#define ZYDIS_STATUS_BAD_REGISTER \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x03u) + +/** + * A lock-prefix (F0) was found while decoding an instruction that does not + * support locking. + */ +#define ZYDIS_STATUS_ILLEGAL_LOCK \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x04u) + +/** + * A legacy-prefix (F2, F3, 66) was found while decoding a XOP/VEX/EVEX/MVEX + * instruction. + */ +#define ZYDIS_STATUS_ILLEGAL_LEGACY_PFX \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x05u) + +/** + * A rex-prefix was found while decoding a XOP/VEX/EVEX/MVEX instruction. + */ +#define ZYDIS_STATUS_ILLEGAL_REX \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x06u) + +/** + * An invalid opcode-map value was found while decoding a XOP/VEX/EVEX/MVEX-prefix. + */ +#define ZYDIS_STATUS_INVALID_MAP \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x07u) + +/** + * An error occured while decoding the EVEX-prefix. + */ +#define ZYDIS_STATUS_MALFORMED_EVEX \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x08u) + +/** + * An error occured while decoding the MVEX-prefix. + */ +#define ZYDIS_STATUS_MALFORMED_MVEX \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x09u) + +/** + * An invalid write-mask was specified for an EVEX/MVEX instruction. + */ +#define ZYDIS_STATUS_INVALID_MASK \ + ZYAN_MAKE_STATUS(1u, ZYAN_MODULE_ZYDIS, 0x0Au) + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatter */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returning this status code in some specified formatter callbacks will cause + * the formatter to omit the corresponding token. + * + * Valid callbacks: + * - `ZYDIS_FORMATTER_FUNC_PRE_OPERAND` + * - `ZYDIS_FORMATTER_FUNC_POST_OPERAND` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_REG` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_MEM` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_PTR` + * - `ZYDIS_FORMATTER_FUNC_FORMAT_OPERAND_IMM` + */ +#define ZYDIS_STATUS_SKIP_TOKEN \ + ZYAN_MAKE_STATUS(0u, ZYAN_MODULE_ZYDIS, 0x0Bu) + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_STATUS_H */ diff --git a/src/Zydis/Utils.h b/src/Zydis/Utils.h new file mode 100644 index 0000000..aef9e96 --- /dev/null +++ b/src/Zydis/Utils.h @@ -0,0 +1,275 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Other utility functions. + */ + +#ifndef ZYDIS_UTILS_H +#define ZYDIS_UTILS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Constants */ +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYDIS_MAX_INSTRUCTION_SEGMENT_COUNT 9 + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZydisInstructionSegment` struct. + */ +typedef enum ZydisInstructionSegment_ +{ + ZYDIS_INSTR_SEGMENT_NONE, + /** + * The legacy prefixes (including ignored `REX` prefixes). + */ + ZYDIS_INSTR_SEGMENT_PREFIXES, + /** + * The effective `REX` prefix byte. + */ + ZYDIS_INSTR_SEGMENT_REX, + /** + * The `XOP` prefix bytes. + */ + ZYDIS_INSTR_SEGMENT_XOP, + /** + * The `VEX` prefix bytes. + */ + ZYDIS_INSTR_SEGMENT_VEX, + /** + * The `EVEX` prefix bytes. + */ + ZYDIS_INSTR_SEGMENT_EVEX, + /** + * The `MVEX` prefix bytes. + */ + ZYDIS_INSTR_SEGMENT_MVEX, + /** + * The opcode bytes. + */ + ZYDIS_INSTR_SEGMENT_OPCODE, + /** + * The `ModRM` byte. + */ + ZYDIS_INSTR_SEGMENT_MODRM, + /** + * The `SIB` byte. + */ + ZYDIS_INSTR_SEGMENT_SIB, + /** + * The displacement bytes. + */ + ZYDIS_INSTR_SEGMENT_DISPLACEMENT, + /** + * The immediate bytes. + */ + ZYDIS_INSTR_SEGMENT_IMMEDIATE, + + /** + * Maximum value of this enum. + */ + ZYDIS_INSTR_SEGMENT_MAX_VALUE = ZYDIS_INSTR_SEGMENT_IMMEDIATE, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_INSTR_SEGMENT_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_INSTR_SEGMENT_MAX_VALUE) +} ZydisInstructionSegment; + +/** + * Defines the `ZydisInstructionSegments` struct. + */ +typedef struct ZydisInstructionSegments_ +{ + /** + * The number of logical instruction segments. + */ + ZyanU8 count; + struct + { + /** + * The type of the segment. + */ + ZydisInstructionSegment type; + /** + * The offset of the segment relative to the start of the instruction (in bytes). + */ + ZyanU8 offset; + /** + * The size of the segment, in bytes. + */ + ZyanU8 size; + } segments[ZYDIS_MAX_INSTRUCTION_SEGMENT_COUNT]; +} ZydisInstructionSegments; + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * @addtogroup utils Utils + * Miscellaneous utility functions. Address translation and other helpers. + * @{ + */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Address calculation */ +/* ---------------------------------------------------------------------------------------------- */ + +// TODO: Provide a function that works in minimal-mode and does not require a operand parameter + +/** + * Calculates the absolute address value for the given instruction operand. + * + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param operand A pointer to the `ZydisDecodedOperand` struct. + * @param runtime_address The runtime address of the instruction. + * @param result_address A pointer to the memory that receives the absolute address. + * + * @return A zyan status code. + * + * You should use this function in the following cases: + * - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...) + * - `MEM` operands with `RIP`/`EIP`-relative address (e.g. `MOV RAX, [RIP+0x12345678]`) + * - `MEM` operands with absolute address (e.g. `MOV RAX, [0x12345678]`) + * - The displacement needs to get truncated and zero extended + */ +ZYDIS_EXPORT ZyanStatus ZydisCalcAbsoluteAddress(const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, ZyanU64 runtime_address, ZyanU64* result_address); + +/** + * Calculates the absolute address value for the given instruction operand. + * + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param operand A pointer to the `ZydisDecodedOperand` struct. + * @param runtime_address The runtime address of the instruction. + * @param register_context A pointer to the `ZydisRegisterContext` struct. + * @param result_address A pointer to the memory that receives the absolute target-address. + * + * @return A zyan status code. + * + * This function behaves like `ZydisCalcAbsoluteAddress` but takes an additional register-context + * argument to allow calculation of addresses depending on runtime register values. + * + * Note that `IP/EIP/RIP` from the register-context will be ignored in favor of the passed + * runtime-address. + */ +ZYDIS_EXPORT ZyanStatus ZydisCalcAbsoluteAddressEx(const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, ZyanU64 runtime_address, + const ZydisRegisterContext* register_context, ZyanU64* result_address); + +/* ---------------------------------------------------------------------------------------------- */ +/* Accessed CPU flags */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns a mask of accessed CPU-flags matching the given `action`. + * + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param action The CPU-flag action. + * @param flags Receives the flag mask. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisGetAccessedFlagsByAction(const ZydisDecodedInstruction* instruction, + ZydisCPUFlagAction action, ZydisCPUFlags* flags); + +/** + * Returns a mask of accessed CPU-flags that are read (tested) by the current instruction. + * + * DEPRECATED. This function will be removed in the next major release. Please refer to the + * `cpu_flags_read` or `fpu_flags_read` fields of the `ZydisDecodedInstruction` instead. + * + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param flags Receives the flag mask. + * + * @return A zyan status code. + */ +ZYDIS_DEPRECATED_EXPORT ZyanStatus ZydisGetAccessedFlagsRead( + const ZydisDecodedInstruction* instruction, ZydisCPUFlags* flags); + +/** + * Returns a mask of accessed CPU-flags that are written (modified, undefined) by the current + * instruction. + * + * DEPRECATED. This function will be removed in the next major release. Please refer to the + * `cpu_flags_written` or `fpu_flags_written` fields of the `ZydisDecodedInstruction` instead. + * + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param flags Receives the flag mask. + * + * @return A zyan status code. + */ +ZYDIS_DEPRECATED_EXPORT ZyanStatus ZydisGetAccessedFlagsWritten( + const ZydisDecodedInstruction* instruction, ZydisCPUFlags* flags); + +/* ---------------------------------------------------------------------------------------------- */ +/* Instruction segments */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Returns offsets and sizes of all logical instruction segments (e.g. `OPCODE`, + * `MODRM`, ...). + * + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param segments Receives the instruction segments information. + * + * @return A zyan status code. + */ +ZYDIS_EXPORT ZyanStatus ZydisGetInstructionSegments(const ZydisDecodedInstruction* instruction, + ZydisInstructionSegments* segments); + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @} + */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_UTILS_H */ diff --git a/src/Zydis/Zydis.h b/src/Zydis/Zydis.h new file mode 100644 index 0000000..79f2670 --- /dev/null +++ b/src/Zydis/Zydis.h @@ -0,0 +1,169 @@ +/*************************************************************************************************** + + 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. + +***************************************************************************************************/ + +/** + * @file + * Master include file, including everything else. + */ + +#ifndef ZYDIS_H +#define ZYDIS_H + +#include +#include + +#ifndef ZYDIS_DISABLE_DECODER +# include +# include +#endif + +#ifndef ZYDIS_DISABLE_FORMATTER +# include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Constants */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * A macro that defines the zydis version. + */ +#define ZYDIS_VERSION (ZyanU64)0x0003000100000000 + +/* ---------------------------------------------------------------------------------------------- */ +/* Helper macros */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Extracts the major-part of the zydis version. + * + * @param version The zydis version value + */ +#define ZYDIS_VERSION_MAJOR(version_t) (ZyanU16)(((version_t) & 0xFFFF000000000000) >> 48) + +/** + * Extracts the minor-part of the zydis version. + * + * @param version The zydis version value + */ +#define ZYDIS_VERSION_MINOR(version_t) (ZyanU16)(((version_t) & 0x0000FFFF00000000) >> 32) + +/** + * Extracts the patch-part of the zydis version. + * + * @param version The zydis version value + */ +#define ZYDIS_VERSION_PATCH(version_t) (ZyanU16)(((version_t) & 0x00000000FFFF0000) >> 16) + +/** + * Extracts the build-part of the zydis version. + * + * @param version The zydis version value + */ +#define ZYDIS_VERSION_BUILD(version_t) (ZyanU16)((version_t) & 0x000000000000FFFF) + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Enums and types */ +/* ============================================================================================== */ + +/** + * Defines the `ZydisFeature` enum. + */ +typedef enum ZydisFeature_ +{ + ZYDIS_FEATURE_DECODER, + ZYDIS_FEATURE_FORMATTER, + ZYDIS_FEATURE_AVX512, + ZYDIS_FEATURE_KNC, + + /** + * Maximum value of this enum. + */ + ZYDIS_FEATURE_MAX_VALUE = ZYDIS_FEATURE_KNC, + /** + * The minimum number of bits required to represent all values of this enum. + */ + ZYDIS_FEATURE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_FEATURE_MAX_VALUE) +} ZydisFeature; + +/* ============================================================================================== */ +/* Exported functions */ +/* ============================================================================================== */ + +/** + * @addtogroup version Version + * Functions for checking the library version and build options. + * @{ + */ + +/** + * Returns the zydis version. + * + * @return The zydis version. + * + * Use the macros provided in this file to extract the major, minor, patch and build part from the + * returned version value. + */ +ZYDIS_EXPORT ZyanU64 ZydisGetVersion(void); + +/** + * Checks, if the specified feature is enabled in the current zydis library instance. + * + * @param feature The feature. + * + * @return `ZYAN_STATUS_TRUE` if the feature is enabled, `ZYAN_STATUS_FALSE` if not. Another + * zyan status code, if an error occured. + */ +ZYDIS_EXPORT ZyanStatus ZydisIsFeatureEnabled(ZydisFeature feature); + +/** + * @} + */ + +/* ============================================================================================== */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZYDIS_H */ diff --git a/src/ZydisExportConfig.h b/src/ZydisExportConfig.h new file mode 100644 index 0000000..2e0b4a2 --- /dev/null +++ b/src/ZydisExportConfig.h @@ -0,0 +1,42 @@ + +#ifndef ZYDIS_EXPORT_H +#define ZYDIS_EXPORT_H + +#ifdef ZYDIS_STATIC_DEFINE +# define ZYDIS_EXPORT +# define ZYDIS_NO_EXPORT +#else +# ifndef ZYDIS_EXPORT +# ifdef Zydis_EXPORTS + /* We are building this library */ +# define ZYDIS_EXPORT __declspec(dllexport) +# else + /* We are using this library */ +# define ZYDIS_EXPORT __declspec(dllimport) +# endif +# endif + +# ifndef ZYDIS_NO_EXPORT +# define ZYDIS_NO_EXPORT +# endif +#endif + +#ifndef ZYDIS_DEPRECATED +# define ZYDIS_DEPRECATED __declspec(deprecated) +#endif + +#ifndef ZYDIS_DEPRECATED_EXPORT +# define ZYDIS_DEPRECATED_EXPORT ZYDIS_EXPORT ZYDIS_DEPRECATED +#endif + +#ifndef ZYDIS_DEPRECATED_NO_EXPORT +# define ZYDIS_DEPRECATED_NO_EXPORT ZYDIS_NO_EXPORT ZYDIS_DEPRECATED +#endif + +#if 0 /* DEFINE_NO_DEPRECATED */ +# ifndef ZYDIS_NO_DEPRECATED +# define ZYDIS_NO_DEPRECATED +# endif +#endif + +#endif /* ZYDIS_EXPORT_H */ diff --git a/src/transform.hpp b/src/transform.hpp new file mode 100644 index 0000000..3dc6f11 --- /dev/null +++ b/src/transform.hpp @@ -0,0 +1,201 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace vm +{ + namespace transform + { + // taken from ida... + template inline T __ROL__(T value, int count) + { + const unsigned int nbits = sizeof(T) * 8; + + if (count > 0) + { + count %= nbits; + T high = value >> (nbits - count); + if (T(-1) < 0) // signed value + high &= ~((T(-1) << count)); + value <<= count; + value |= high; + } + else + { + count = -count % nbits; + T low = value << (nbits - count); + value >>= count; + value |= low; + } + return value; + } + + // taken from ida... + inline u8 __ROL1__(u8 value, int count) { return __ROL__((u8)value, count); } + inline u16 __ROL2__(u16 value, int count) { return __ROL__((u16)value, count); } + inline u32 __ROL4__(u32 value, int count) { return __ROL__((u32)value, count); } + inline u64 __ROL8__(u64 value, int count) { return __ROL__((u64)value, count); } + inline u8 __ROR1__(u8 value, int count) { return __ROL__((u8)value, -count); } + inline u16 __ROR2__(u16 value, int count) { return __ROL__((u16)value, -count); } + inline u32 __ROR4__(u32 value, int count) { return __ROL__((u32)value, -count); } + inline u64 __ROR8__(u64 value, int count) { return __ROL__((u64)value, -count); } + + template + using transform_t = std::function; + + enum class type + { + rolling_key, + generic1, + generic2, + generic3, + update_key + }; + + using map_t = std::map; + + template + inline const auto _bswap = [](T a, T b) -> T + { + if constexpr (std::is_same_v) + return _byteswap_uint64(a); + if constexpr (std::is_same_v) + return _byteswap_ulong(a); + if constexpr (std::is_same_v) + return _byteswap_ushort(a); + + throw std::invalid_argument("invalid type size..."); + }; + + template + inline const auto _add = [](T a, T b) -> T + { + return a + b; + }; + + template + inline const auto _xor = [](T a, T b) -> T + { + return a ^ b; + }; + + template + inline const auto _sub = [](T a, T b) -> T + { + return a - b; + }; + + template + inline const auto _neg = [](T a, T b) -> T + { + return a * -1; + }; + + template + inline const auto _not = [](T a, T b) -> T + { + return ~a; + }; + + template + inline const auto _ror = [](T a, T b) -> T + { + if constexpr (std::is_same_v) + return __ROR8__(a, b); + if constexpr (std::is_same_v) + return __ROR4__(a, b); + if constexpr (std::is_same_v) + return __ROR2__(a, b); + if constexpr (std::is_same_v ) + return __ROR1__(a, b); + + throw std::invalid_argument("invalid type size..."); + }; + + template + inline const auto _rol = [](T a, T b) -> T + { + if constexpr (std::is_same_v) + return __ROL8__(a, b); + if constexpr (std::is_same_v) + return __ROL4__(a, b); + if constexpr (std::is_same_v) + return __ROL2__(a, b); + if constexpr (std::is_same_v ) + return __ROL1__(a, b); + + throw std::invalid_argument("invalid type size..."); + }; + + template + inline const auto _inc = [](T a, T b) -> T + { + return a + 1; + }; + + template + inline const auto _dec = [](T a, T b) -> T + { + return a - 1; + }; + + template + inline std::map> transforms = + { + { ZYDIS_MNEMONIC_ADD, _add }, + { ZYDIS_MNEMONIC_XOR, _xor }, + { ZYDIS_MNEMONIC_BSWAP, _bswap }, + { ZYDIS_MNEMONIC_SUB, _sub}, + { ZYDIS_MNEMONIC_NEG, _neg}, + { ZYDIS_MNEMONIC_NOT, _not}, + { ZYDIS_MNEMONIC_ROR, _ror}, + { ZYDIS_MNEMONIC_ROL, _rol}, + { ZYDIS_MNEMONIC_INC, _inc}, + { ZYDIS_MNEMONIC_DEC, _dec} + }; + + inline std::map inverse = + { + {ZYDIS_MNEMONIC_ADD, ZYDIS_MNEMONIC_SUB}, + {ZYDIS_MNEMONIC_XOR, ZYDIS_MNEMONIC_XOR}, + {ZYDIS_MNEMONIC_BSWAP, ZYDIS_MNEMONIC_BSWAP}, + {ZYDIS_MNEMONIC_SUB, ZYDIS_MNEMONIC_ADD}, + {ZYDIS_MNEMONIC_NEG, ZYDIS_MNEMONIC_NEG}, + {ZYDIS_MNEMONIC_NOT, ZYDIS_MNEMONIC_NOT}, + {ZYDIS_MNEMONIC_ROR, ZYDIS_MNEMONIC_ROL}, + {ZYDIS_MNEMONIC_ROL, ZYDIS_MNEMONIC_ROR}, + {ZYDIS_MNEMONIC_INC, ZYDIS_MNEMONIC_DEC}, + {ZYDIS_MNEMONIC_DEC, ZYDIS_MNEMONIC_INC} + }; + + // max size of a and b is 64 bits, a and b is then converted to + // the number of bits in bitsize, the transformation is applied, + // finally the result is converted back to 64bits... zero extended... + inline auto apply(std::uint8_t bitsize, ZydisMnemonic op, + std::uint64_t a, std::uint64_t b) -> std::uint64_t + { + switch (bitsize) + { + case 8: + return transforms[op](a, b); + case 16: + return transforms[op](a, b); + case 32: + return transforms[op](a, b); + case 64: + return transforms[op](a, b); + default: + throw std::invalid_argument("invalid bit size..."); + } + } + + inline bool has_imm(ZydisDecodedInstruction* instr) + { + return instr->operand_count > 1 && + (instr->operands[1].type & ZYDIS_OPERAND_TYPE_IMMEDIATE); + } + } +} \ No newline at end of file diff --git a/vm.cpp b/src/vm.cpp similarity index 100% rename from vm.cpp rename to src/vm.cpp diff --git a/src/vm.h b/src/vm.h new file mode 100644 index 0000000..ad8a28b --- /dev/null +++ b/src/vm.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include +#include + +namespace vm +{ + std::pair decrypt_operand(transform::map_t& transforms, + std::uint64_t operand, std::uint64_t rolling_key); + + std::pair encrypt_operand(transform::map_t& transforms, + std::uint64_t operand, std::uint64_t rolling_key); + + void inverse_transforms(transform::map_t& transforms, transform::map_t& inverse); + bool get_calc_jmp(const zydis_routine_t& vm_entry, zydis_routine_t& calc_jmp); + bool get_vinstr_rva_transform( + const zydis_routine_t& vm_entry, ZydisDecodedInstruction* transform_instr); + + struct handler_t + { + u8 imm_size; // size in bits... + vm::transform::map_t transforms; + vm::handler::profile_t* profile; + zydis_routine_t instrs; + std::uintptr_t address; + }; + + namespace handler + { + bool has_imm(const zydis_routine_t& vm_handler); + std::uint8_t imm_size(const zydis_routine_t& vm_handler); + bool get(zydis_routine_t& vm_entry, zydis_routine_t& vm_handler, std::uintptr_t handler_addr); + + // may throw an exception... + bool get_all(std::uintptr_t module_base, std::uintptr_t image_base, + zydis_routine_t& vm_entry, std::uintptr_t* vm_handler_table, std::vector& vm_handlers); + + // can be used on calc_jmp... + bool get_operand_transforms(const zydis_routine_t& vm_handler, transform::map_t& transforms); + vm::handler::profile_t* get_profile(vm::handler_t& vm_handler); + + namespace table + { + std::uintptr_t* get(const zydis_routine_t& vm_entry); + bool get_transform(const zydis_routine_t& vm_entry, ZydisDecodedInstruction* transform_instr); + + std::uint64_t encrypt(ZydisDecodedInstruction& transform_instr, std::uint64_t val); + std::uint64_t decrypt(ZydisDecodedInstruction& transform_instr, std::uint64_t val); + } + } +} \ No newline at end of file diff --git a/vmctx.cpp b/src/vmctx.cpp similarity index 100% rename from vmctx.cpp rename to src/vmctx.cpp diff --git a/src/vmctx.h b/src/vmctx.h new file mode 100644 index 0000000..3bede1e --- /dev/null +++ b/src/vmctx.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include + +namespace vm +{ + class vmctx_t + { + public: + explicit vmctx_t( + vmp2::file_header* file_header, + vmp2::entry_t* entry_list, + std::vector& vm_handlers, + std::uintptr_t module_base, + std::uintptr_t image_base + ); + + std::pair step() const; + private: + std::uintptr_t get_imm(vmp2::exec_type_t exec_type_t, + std::uint32_t vip_offset, std::uint8_t imm_size) const; + + mutable std::uint32_t idx; + const std::uintptr_t image_base, module_base; + const vmp2::entry_t* entry_list; + const vmp2::file_header* file_header; + std::vector vm_handlers; + }; +} \ No newline at end of file diff --git a/src/vmp2.hpp b/src/vmp2.hpp new file mode 100644 index 0000000..3f616a4 --- /dev/null +++ b/src/vmp2.hpp @@ -0,0 +1,72 @@ +#pragma once +#include "vm.h" + +namespace vmp2 +{ + enum class exec_type_t + { + forward, + backward + }; + + enum class version_t + { + invalid, + v1 = 0x101 + }; + + struct file_header + { + u32 magic; // VMP2 + u64 epoch_time; + u64 module_base; + exec_type_t advancement; + version_t version; + + u32 entry_count; + u32 entry_offset; + }; + + struct entry_t + { + u8 handler_idx; + u64 decrypt_key; + u64 vip; + + union + { + struct + { + u64 r15; + u64 r14; + u64 r13; + u64 r12; + u64 r11; + u64 r10; + u64 r9; + u64 r8; + u64 rbp; + u64 rdi; + u64 rsi; + u64 rdx; + u64 rcx; + u64 rbx; + u64 rax; + u64 rflags; + }; + u64 raw[16]; + } regs; + + union + { + u64 qword[0x28]; + u8 raw[0x140]; + } vregs; + + union + { + u64 qword[0x20]; + u8 raw[0x100]; + } vsp; + }; +} \ No newline at end of file diff --git a/src/vmprofiler.hpp b/src/vmprofiler.hpp new file mode 100644 index 0000000..c8fba9b --- /dev/null +++ b/src/vmprofiler.hpp @@ -0,0 +1,367 @@ +#pragma once +#include + +namespace vm +{ + namespace handler + { + enum extention_t + { + none, + sign_extend, + zero_extend + }; + + struct profile_t + { + const char* name; + u8 imm_size; + std::vector> signature; + extention_t extention; + }; + + namespace profile + { + // store a value from the stack into scratch register X (RDI+X)... + // where X is an 8bit immediate value... + inline vm::handler::profile_t sregq = + { + "SREGQ", 8, + { + { 0x48, 0x8B, 0x55, 0x0 }, // mov rdx, [rbp+0] + { 0x48, 0x83, 0xC5, 0x8 }, // add rbp, 8 + { 0x48, 0x89, 0x14, 0x38 }, // mov [rax+rdi], rdx + } + }; + + inline vm::handler::profile_t sregdw = + { + "SREGDW", 8, + { + { 0x8B, 0x55, 0x00 }, + { 0x48, 0x83, 0xC5, 0x04 }, + { 0x89, 0x14, 0x38 } + } + }; + + inline vm::handler::profile_t sregw = + { + "SREGW", 8, + { + { 0x66, 0x8B, 0x55, 0x00 }, // mov dx, [rbp] + { 0x48, 0x83, 0xC5, 0x02 }, // add rbp, 0x02 + { 0x66, 0x89, 0x14, 0x38 } // mov [rax+rdi], dx + } + }; + + // load scratch register value onto virtual stack... + inline vm::handler::profile_t lregq = + { + "LREGQ", 8, + { + {0x48, 0x8B, 0x14, 0x38}, // mov rdx, [rax+rdi] + {0x48, 0x83, 0xED, 0x08}, // sub rbp, 8 + {0x48, 0x89, 0x55, 0x0} // mov [rbp+0], rdx + } + }; + + /* + > 0x00007FF64724445C mov edx, [rax+rdi*1] + > 0x00007FF647244463 sub rbp, 0x04 + > 0x00007FF647246333 mov [rbp], edx + */ + inline vm::handler::profile_t lregdw = + { + "LREGDW", 8, + { + { 0x8B, 0x14, 0x38 }, + { 0x48, 0x83, 0xED, 0x04 }, + { 0x89, 0x55, 0x00 } + } + }; + + // load constant value into stack.... + inline vm::handler::profile_t lconstq = + { + "LCONSTQ", 64, + { + {0x48, 0x83, 0xED, 0x08}, // sub rbp, 8 + {0x48, 0x89, 0x45, 0x00} // mov [rbp+0], rax + } + }; + + // load 1 byte constant zero extended into 2bytes on the stack... + inline vm::handler::profile_t lconstbzx = + { + "LCONSTBZX", 8, + { + {0x48, 0x83, 0xED, 0x02}, // sub rbp, 2 + {0x66, 0x89, 0x45, 0x00} // mov [rbp+0], ax + } + }; + + inline vm::handler::profile_t lconstbsx = + { + "LCONSTBSX", 8, + { + { 0x98 }, + { 0x48, 0x83, 0xED, 0x04 }, + { 0x89, 0x45, 0x00 } + }, + vm::handler::extention_t::sign_extend + }; + + // load 4 byte constant value sign extended qword into vsp... + inline vm::handler::profile_t lconstbsx1 = + { + "LCONSTBSX", 8, + { + {0x48, 0x98}, // cdqe + {0x48, 0x83, 0xED, 0x8}, // sub rbp, 8 + {0x48, 0x89, 0x45, 0x0}, // mov [rbp+0], rax + }, + vm::handler::extention_t::sign_extend + }; + + // load 4 byte constant value sign extended qword into vsp... + inline vm::handler::profile_t lconstdsx = + { + "LCONSTDSX", 32, + { + {0x48, 0x98}, // cdqe + {0x48, 0x83, 0xED, 0x8}, // sub rbp, 8 + {0x48, 0x89, 0x45, 0x0}, // mov [rbp+0], rax + }, + vm::handler::extention_t::sign_extend + }; + + // load 2 byte constant value sign extended qword into vsp... + inline vm::handler::profile_t lconstwsx = + { + "LCONSTWSX", 16, + { + {0x48, 0x98}, // cdqe + {0x48, 0x83, 0xED, 0x8}, // sub rbp, 8 + {0x48, 0x89, 0x45, 0x0}, // mov [rbp+0], rax + }, + vm::handler::extention_t::sign_extend + }; + + inline vm::handler::profile_t lconstw = + { + "LCONSTW", 8, + { + { 0x48, 0x83, 0xED, 0x02 }, // sub rbp, 0x02 + { 0x66, 0x89, 0x45, 0x00 } // mov [rbp], ax + } + }; + + inline vm::handler::profile_t lconstdw = + { + "LCONSTDW", 32, + { + { 0x48, 0x83, 0xED, 0x04 }, + { 0x89, 0x45, 0x00 } + } + }; + + inline vm::handler::profile_t pushvsp = + { + "PUSHVSP", 0, + { + {0x48, 0x89, 0xE8}, // mov rax, rbp + {0x48, 0x83, 0xED, 0x08}, // sub rbp, 8 + {0x48, 0x89, 0x45, 0x0} // mov [rbp+0], rax + } + }; + + // add two stack values together... + inline vm::handler::profile_t addq = + { + "ADDQ", 0, + { + {0x48, 0x1, 0x45, 0x8}, // add [rbp+8], rax + {0x9C}, // pushfq + {0x8F, 0x45, 0x0} // pop qword ptr [rbp+0] + } + }; + + inline vm::handler::profile_t adddw = + { + "ADDDW", 0, + { + { 0x01, 0x45, 0x08 }, // add [rbp+0x08], eax + { 0x9C }, // pushfq + { 0x8F, 0x45, 0x00 } // pop [rbp] + } + }; + + // two qwords on the top of the stack together then not the result... + // ~(VSP[0] | VSP[1])... + inline vm::handler::profile_t nandq = + { + "NANDQ", 0, + { + {0x48, 0x8B, 0x45, 0x0}, // mov rax, [rbp+0] + {0x48, 0x8B, 0x55, 0x8}, // mov rdx, [rbp+8] + {0x48, 0xF7, 0xD0}, // not rax + {0x48, 0xF7, 0xD2}, // not rdx + {0x48, 0x21, 0xD0}, // and rax, rdx + {0x48, 0x89, 0x45, 0x8}, // mov [rbp+8], rax + {0x9C}, // pushfq + {0x8F, 0x45, 0x0} // pop qword ptr [rbp+0] + } + }; + + // leaves the virtual machine... + inline vm::handler::profile_t vmexit = + { + "VMEXIT", 0, + { + {0x48, 0x89, 0xec}, // mov rsp, rbp + {0x9d}, // popfq + {0xc3} // ret + } + }; + + inline vm::handler::profile_t jmp = + { + "JMP", 0, + { + { 0x8B, 0x75, 0x00 }, // mov esi, [rbp] + { 0x48, 0x01, 0xC6 }, // add rsi, rax + { 0x48, 0x89, 0xF3 }, // mov rbx, rsi + { 0x48, 0x03, 0x75, 0x00 } // add rsi, [rbp] + } + }; + + inline vm::handler::profile_t readw = + { + "READW", 0, + { + { 0x48, 0x8B, 0x45, 0x00 }, // mov rax, [rbp] + { 0x48, 0x83, 0xC5, 0x06 }, // add rbp, 0x06 + { 0x36, 0x66, 0x8B, 0x00 }, // mov ax, ss:[rax] + { 0x66, 0x89, 0x45, 0x00 } // mov [rbp], ax + } + }; + + inline vm::handler::profile_t writeq = + { + "WRITEQ", 0, + { + { 0x48, 0x8B, 0x45, 0x00 }, // mov rax, [rbp] + { 0x48, 0x8B, 0x55, 0x08 }, // mov rdx, [rbp+0x08] + { 0x48, 0x83, 0xC5, 0x10 }, // add rbp, 0x10 + { 0x36, 0x48, 0x89, 0x10 }, // mov ss:[rax], rdx + } + }; + + inline vm::handler::profile_t writeq1 = + { + "WRITEQ", 0, + { + { 0x48, 0x8B, 0x45, 0x00 }, // mov rax, [rbp] + { 0x48, 0x8B, 0x55, 0x08 }, // mov rdx, [rbp+0x08] + { 0x48, 0x83, 0xC5, 0x10 }, // add rbp, 0x10 + { 0x48, 0x89, 0x10 } // mov [rax], rdx + } + }; + + inline vm::handler::profile_t shrw = + { + "SHRW", 0, + { + { 0x66, 0x8B, 0x45, 0x00 }, + { 0x8A, 0x4D, 0x02 }, + { 0x48, 0x83, 0xED, 0x06 }, + { 0x66, 0xD3, 0xE8 }, + { 0x66, 0x89, 0x45, 0x08 }, + { 0x9C }, + { 0x8F, 0x45, 0x00 } + } + }; + + inline vm::handler::profile_t shrdw = + { + "SHRDW", 0, + { + { 0x8B, 0x45, 0x00 }, + { 0x8A, 0x4D, 0x04 }, + { 0x48, 0x83, 0xED, 0x06 }, + { 0xD3, 0xE8 }, + { 0x89, 0x45, 0x08 }, + { 0x9C }, + { 0x8F, 0x45, 0x00 } + } + }; + + inline vm::handler::profile_t shrq = + { + "SHRQ", 0, + { + { 0x48, 0x8B, 0x45, 0x00 }, + { 0x8A, 0x4D, 0x08 }, + { 0x48, 0x83, 0xED, 0x06 }, + { 0x48, 0xD3, 0xE8 }, + { 0x48, 0x89, 0x45, 0x08 }, + { 0x9C }, + { 0x8F, 0x45, 0x00 }, + } + }; + + inline vm::handler::profile_t nanddw = + { + "NANDDW", 0, + { + { 0x48, 0xF7, 0x55, 0x00 }, // not qword ptr [rbp+0] + { 0x8B, 0x45, 0x00 }, // mov eax, [rbp+0] + { 0x48, 0x83, 0xED, 0x04 }, // sub rbp, 4 + { 0x21, 0x45, 0x08 }, // and [rbp+8], eax + { 0x9C }, // pushfq + { 0x8F, 0x45, 0x00 } // pop qword ptr [rbp+0] + } + }; + + inline vm::handler::profile_t lvsp = + { + "LVSP", 0, + { + { 0x48, 0x8B, 0x6D, 0x00 } // mov rbp, [rbp] + } + }; + + inline std::vector all = + { + &sregq, + &lregq, + &lconstq, + &lconstdsx, + &lconstwsx, + &lconstbzx, + &addq, + &nandq, + &pushvsp, + &vmexit, + &jmp, + &adddw, + &writeq, + &sregw, + &lconstw, + &shrw, + &shrq, + &writeq1, + &readw, + &lregdw, + &shrdw, + &sregdw, + &lconstbsx, + &lconstbsx1, + &shrq, + &lvsp, + &lconstdw, + &nanddw + }; + } + } +} \ No newline at end of file diff --git a/vmprofiler.vcxproj b/src/vmprofiler.vcxproj similarity index 98% rename from vmprofiler.vcxproj rename to src/vmprofiler.vcxproj index 1028939..a9a93e3 100644 --- a/vmprofiler.vcxproj +++ b/src/vmprofiler.vcxproj @@ -115,7 +115,7 @@ - + {88a23124-5640-35a0-b890-311d7a67a7d2} diff --git a/vmprofiler.vcxproj.filters b/src/vmprofiler.vcxproj.filters similarity index 100% rename from vmprofiler.vcxproj.filters rename to src/vmprofiler.vcxproj.filters diff --git a/vmutils.cpp b/src/vmutils.cpp similarity index 100% rename from vmutils.cpp rename to src/vmutils.cpp diff --git a/src/vmutils.h b/src/vmutils.h new file mode 100644 index 0000000..b0fb25b --- /dev/null +++ b/src/vmutils.h @@ -0,0 +1,40 @@ +#pragma once +#include +#include +#include +#include + +using u8 = unsigned char; +using u16 = unsigned short; +using u32 = unsigned int; +using u64 = unsigned long long; +using u128 = __m128; + +struct zydis_instr_t +{ + ZydisDecodedInstruction instr; + std::vector raw; + std::uintptr_t addr; +}; + +using zydis_routine_t = std::vector; + +namespace vm +{ + namespace util + { + namespace reg + { + // converts say... AL to RAX... + ZydisRegister to64(ZydisRegister reg); + bool compare(ZydisRegister a, ZydisRegister b); + } + + void print(zydis_routine_t& routine); + void print(const ZydisDecodedInstruction& instr); + bool is_jmp(const ZydisDecodedInstruction& instr); + + bool flatten(zydis_routine_t& routine, std::uintptr_t routine_addr, bool keep_jmps = false); + void deobfuscate(zydis_routine_t& routine); + } +} \ No newline at end of file diff --git a/vmprofiler.sln b/vmprofiler.sln index c6597c2..d118abb 100644 --- a/vmprofiler.sln +++ b/vmprofiler.sln @@ -3,10 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30907.101 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmprofiler", "vmprofiler.vcxproj", "{D0B6092A-9944-4F24-9486-4B7DAE372619}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Zydis", "dependancies\zydis\msvc\zydis\Zydis.vcxproj", "{88A23124-5640-35A0-B890-311D7A67A7D2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmprofiler", "src\vmprofiler.vcxproj", "{D0B6092A-9944-4F24-9486-4B7DAE372619}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug Kernel|x64 = Debug Kernel|x64 @@ -33,49 +33,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x86.ActiveCfg = Release|x64 {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x64.ActiveCfg = Debug Kernel|x64 {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x64.Build.0 = Debug Kernel|x64 {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x64.Deploy.0 = Debug Kernel|x64 @@ -124,6 +81,49 @@ Global {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.Build.0 = Release MD DLL|x64 {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.ActiveCfg = Release MT DLL|Win32 {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.Build.0 = Release MT DLL|Win32 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.ActiveCfg = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.Build.0 = Release|x64 + {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x86.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/vmprofiler.vcxproj.user b/vmprofiler.vcxproj.user deleted file mode 100644 index c6ce1a1..0000000 --- a/vmprofiler.vcxproj.user +++ /dev/null @@ -1,7 +0,0 @@ - - - - $(ProjectDir)..\refbuilds\vmptest.vmp.exe output.vmp2 0x1000 0x140000000 - WindowsLocalDebugger - - \ No newline at end of file