diff --git a/Examples/DemoDrv/DriverEntry.cpp b/Examples/DemoDrv/DriverEntry.cpp index 5e54af4..99605f7 100644 --- a/Examples/DemoDrv/DriverEntry.cpp +++ b/Examples/DemoDrv/DriverEntry.cpp @@ -1,7 +1,6 @@ #include "Theodosius.h" #include "Types.h" - // this routine is not obfuscated... void PrintCR3() { @@ -13,14 +12,15 @@ void PrintCR3() } ObfuscateRoutine -void LoopDemo() +void LoopDemo(bool* result) { // JCC's work! :) for (auto idx = 0u; idx < 10; ++idx) DbgPrint("> Loop Demo: %d\n", idx); + + *result = true; } -// entry point must be named "DrvEntry" for this example... MutateRoutine extern "C" void DrvEntry() { DbgPrint("> Hello World!\n"); @@ -34,5 +34,8 @@ MutateRoutine extern "C" void DrvEntry() // example of calling other obfuscated/non obfuscated routines... PrintCR3(); - LoopDemo(); + + bool result = false; + LoopDemo(&result); + DbgPrint("> result = %d\n", result); } \ No newline at end of file diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius-MSREXEC.vcxproj b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius-MSREXEC.vcxproj index 48f8190..b9915c1 100644 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius-MSREXEC.vcxproj +++ b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius-MSREXEC.vcxproj @@ -63,7 +63,7 @@ Console true - Zydis.lib;Zycore.lib;%(AdditionalDependencies) + Zydis.lib;Zycore.lib;%(AdditionalDependencies);Theodosius.lib @@ -81,190 +81,24 @@ true true true - Zydis.lib;Zycore.lib;%(AdditionalDependencies) + %(AdditionalDependencies);Theodosius.lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius-MSREXEC.vcxproj.filters b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius-MSREXEC.vcxproj.filters index d9502c7..32c0008 100644 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius-MSREXEC.vcxproj.filters +++ b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius-MSREXEC.vcxproj.filters @@ -9,39 +9,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - {8d07ce7e-3b56-4b27-bb05-d12987f22384} - - - {77c3f715-9d9f-488e-a1d5-542124a490b0} - - - {c89c1fbb-39b5-4954-9774-0c2600773705} - - - {db8b5110-ec16-4fc2-80cc-7241ccbfec1c} - - - {c51e3b93-1496-49d7-838f-825d75b29ee6} - - - {d28d9202-4139-42a0-9f49-71beb5e01670} - - - {a847dc8c-08a3-4ea7-a20d-157963dd41a8} - - - {706001e9-56f5-41d2-b209-9f5543d0bd11} - - - {a8e52093-e1b2-4ef3-b427-ebea8772bbbf} - - - {da6ded33-7d62-4f83-b8e7-4d343fe49cd7} - - - {244a52bf-80cb-43ac-ac0d-a6aad89b9eb0} - @@ -50,521 +17,23 @@ Source Files - - Source Files - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\core - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - - - Source Files\asmjit\x86 - Source Files - - Source Files - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - Header Files Header Files - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore\API - - - Header Files\Zycore\API - - - Header Files\Zycore\API - - - Header Files\Zycore\API - - - Header Files\Zycore\API - - - Header Files\Zydis - - - Header Files\Zycore - Header Files Header Files - - Header Files - - - Header Files\asmjit - - - Header Files\asmjit - - - Header Files\asmjit - - - Header Files\asmjit - - - Header Files\asmjit - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\core - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - - - Header Files\asmjit\x86 - Header Files diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius.lib b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius.lib new file mode 100644 index 0000000..ad57f54 Binary files /dev/null and b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Theodosius.lib differ diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Memory.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Memory.h deleted file mode 100644 index c5fa8a9..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Memory.h +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Process.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Process.h deleted file mode 100644 index 0b6a5c6..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Process.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Synchronization.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Synchronization.h deleted file mode 100644 index 8414a44..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Synchronization.h +++ /dev/null @@ -1,133 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Terminal.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Terminal.h deleted file mode 100644 index 17dc384..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Terminal.h +++ /dev/null @@ -1,163 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Thread.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Thread.h deleted file mode 100644 index b1ec085..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/API/Thread.h +++ /dev/null @@ -1,244 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Allocator.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Allocator.h deleted file mode 100644 index 6435171..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Allocator.h +++ /dev/null @@ -1,143 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/ArgParse.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/ArgParse.h deleted file mode 100644 index 5d389cb..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/ArgParse.h +++ /dev/null @@ -1,173 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Bitset.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Bitset.h deleted file mode 100644 index 8c7eb1f..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Bitset.h +++ /dev/null @@ -1,484 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Comparison.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Comparison.h deleted file mode 100644 index 6d8b518..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Comparison.h +++ /dev/null @@ -1,316 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Defines.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Defines.h deleted file mode 100644 index 65afbaa..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Defines.h +++ /dev/null @@ -1,443 +0,0 @@ -/*************************************************************************************************** - - 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 - -/* ============================================================================================== */ -/* 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Format.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Format.h deleted file mode 100644 index b0401e6..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Format.h +++ /dev/null @@ -1,286 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/LibC.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/LibC.h deleted file mode 100644 index cb0b2f3..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/LibC.h +++ /dev/null @@ -1,511 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/List.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/List.h deleted file mode 100644 index 015a324..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/List.h +++ /dev/null @@ -1,574 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Object.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Object.h deleted file mode 100644 index d015cef..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Object.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Status.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Status.h deleted file mode 100644 index b0d7fdf..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Status.h +++ /dev/null @@ -1,287 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/String.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/String.h deleted file mode 100644 index c3157bc..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/String.h +++ /dev/null @@ -1,1012 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Types.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Types.h deleted file mode 100644 index 74fe905..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Types.h +++ /dev/null @@ -1,195 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Vector.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Vector.h deleted file mode 100644 index 47e728c..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Vector.h +++ /dev/null @@ -1,723 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Zycore.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Zycore.h deleted file mode 100644 index e136acf..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zycore/Zycore.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************************************** - - 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) (ZyanU16)((version & 0xFFFF000000000000) >> 48) - -/** - * Extracts the minor-part of the zycore version. - * - * @param version The zycore version value - */ -#define ZYCORE_VERSION_MINOR(version) (ZyanU16)((version & 0x0000FFFF00000000) >> 32) - -/** - * Extracts the patch-part of the zycore version. - * - * @param version The zycore version value - */ -#define ZYCORE_VERSION_PATCH(version) (ZyanU16)((version & 0x00000000FFFF0000) >> 16) - -/** - * Extracts the build-part of the zycore version. - * - * @param version The zycore version value - */ -#define ZYCORE_VERSION_BUILD(version) (ZyanU16)(version & 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/ZycoreExportConfig.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/ZycoreExportConfig.h deleted file mode 100644 index f050d37..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/ZycoreExportConfig.h +++ /dev/null @@ -1,42 +0,0 @@ - -#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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Decoder.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Decoder.h deleted file mode 100644 index 8cfbb0c..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Decoder.h +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/DecoderTypes.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/DecoderTypes.h deleted file mode 100644 index 45f5300..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/DecoderTypes.h +++ /dev/null @@ -1,1528 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Formatter.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Formatter.h deleted file mode 100644 index c68bcde..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Formatter.h +++ /dev/null @@ -1,1179 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/FormatterBuffer.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/FormatterBuffer.h deleted file mode 100644 index 2ae2efe..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/FormatterBuffer.h +++ /dev/null @@ -1,306 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumISAExt.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumISAExt.h deleted file mode 100644 index 6de33b7..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumISAExt.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumISASet.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumISASet.h deleted file mode 100644 index c04242c..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumISASet.h +++ /dev/null @@ -1,184 +0,0 @@ -/** - * 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumInstructionCategory.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumInstructionCategory.h deleted file mode 100644 index 755afbc..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumInstructionCategory.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumMnemonic.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumMnemonic.h deleted file mode 100644 index 899efb8..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumMnemonic.h +++ /dev/null @@ -1,1643 +0,0 @@ -/** - * 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; \ No newline at end of file diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumRegister.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumRegister.h deleted file mode 100644 index 3135fe0..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Generated/EnumRegister.h +++ /dev/null @@ -1,301 +0,0 @@ -/** - * 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/DecoderData.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/DecoderData.h deleted file mode 100644 index db6cf53..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/DecoderData.h +++ /dev/null @@ -1,331 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterATT.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterATT.h deleted file mode 100644 index 08b7134..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterATT.h +++ /dev/null @@ -1,178 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterBase.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterBase.h deleted file mode 100644 index 0a61747..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterBase.h +++ /dev/null @@ -1,318 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterIntel.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterIntel.h deleted file mode 100644 index cd12d38..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/FormatterIntel.h +++ /dev/null @@ -1,267 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/SharedData.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/SharedData.h deleted file mode 100644 index d8db4fb..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/SharedData.h +++ /dev/null @@ -1,974 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/String.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/String.h deleted file mode 100644 index 18ed812..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Internal/String.h +++ /dev/null @@ -1,464 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/MetaInfo.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/MetaInfo.h deleted file mode 100644 index 6867d32..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/MetaInfo.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Mnemonic.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Mnemonic.h deleted file mode 100644 index dd8fec8..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Mnemonic.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Register.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Register.h deleted file mode 100644 index 0ff955f..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Register.h +++ /dev/null @@ -1,293 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/SharedTypes.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/SharedTypes.h deleted file mode 100644 index 82a4121..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/SharedTypes.h +++ /dev/null @@ -1,480 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/ShortString.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/ShortString.h deleted file mode 100644 index bed45af..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/ShortString.h +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Status.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Status.h deleted file mode 100644 index d2a75f3..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Status.h +++ /dev/null @@ -1,159 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Utils.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Utils.h deleted file mode 100644 index aef9e96..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Utils.h +++ /dev/null @@ -1,275 +0,0 @@ -/*************************************************************************************************** - - 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Zydis.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Zydis.h deleted file mode 100644 index a0d2d87..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/Zydis/Zydis.h +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************************************** - - 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) (ZyanU16)(((version) & 0xFFFF000000000000) >> 48) - -/** - * Extracts the minor-part of the zydis version. - * - * @param version The zydis version value - */ -#define ZYDIS_VERSION_MINOR(version) (ZyanU16)(((version) & 0x0000FFFF00000000) >> 32) - -/** - * Extracts the patch-part of the zydis version. - * - * @param version The zydis version value - */ -#define ZYDIS_VERSION_PATCH(version) (ZyanU16)(((version) & 0x00000000FFFF0000) >> 16) - -/** - * Extracts the build-part of the zydis version. - * - * @param version The zydis version value - */ -#define ZYDIS_VERSION_BUILD(version) (ZyanU16)((version) & 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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/ZydisExportConfig.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/ZydisExportConfig.h deleted file mode 100644 index 2e0b4a2..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/ZydisExportConfig.h +++ /dev/null @@ -1,42 +0,0 @@ - -#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/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit.natvis b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit.natvis deleted file mode 100644 index b73d848..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit.natvis +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - {_small.data, s8} - {_large.data, s8} - - - Small - Large - External - - (int)_small.type, d - _large.size, d - asmjit::String::kSSOCapacity, d - _large.capacity, d - _small.data, s8 - _large.data, s8 - - - - - {{ [size={_size, d} capacity={_capacity, d}] }} - - _size, d - _capacity, d - - _size - (($T1*)_data) - - - - - - - - - - - - - - - - - - - - - - - - - - [None] - [Reg] {{ id={_baseId, d} group={regGroup(), d} type={regType(), d} size={opSize(), d} }} - [Mem] {{ baseId={memBaseId(), d} indexId={memIndexId(), d} offset={(__int64)memOffset(), d} }} - [Imm] {{ val={immValue(), d} hex={immValue(), X} }} - [Label] {{ id={_baseId} }} - [Unknown] - - _signature, X - (asmjit::Operand_::OpType)opType() - opSize(), d - (asmjit::BaseReg::RegType)regType() - (asmjit::BaseReg::RegGroup)regGroup() - (asmjit::BaseReg::RegType)memBaseType() - (asmjit::BaseReg::RegType)memIndexType() - (asmjit::BaseMem::AddrType)memAddrType() - (bool)memRegHome() - _baseId - _data[0] - _data[1] - _data[0] - _data[1] - _data[0] - _data[1] - - - - - - - - - - - - - - - [RegValue {{ regType={regType()} indirect={isIndirect()} done={isDone()} }}] - [StackValue {{ indirect={isIndirect()} done={isDone()} }}] - [Unknown] - - - _data - (asmjit::Type::Id)(typeId()) - (asmjit::BaseReg::RegType)regType() - regId() - stackOffset() - - - - - - - - - - - - - - - - - - - - - - - - - [InstNode] - [SectionNode] - [LabelNode] - [AlignNode] - [EmbedDataNode] - [EmbedLabelNode] - [EmbedLabelDeltaNode] - [ConstPoolNode] - [CommentNode] - [SentinelNode] - [JumpNode] - [FuncNode] - [FuncRetNode] - [InvokeNode] - [UnknownNode {nodeType(), d}] - - - _prev - _next - - (asmjit::BaseNode::NodeType)_any._nodeType - (asmjit::BaseNode::Flags)_any._nodeFlags - - _position - _userDataU64 - _userDataPtr - _passData - _inlineComment, s8 - - ((asmjit::InstNode*)this)->_baseInst - _inst._opCount - _inst._opCapacity - ((asmjit::InstNode*)this)->_opArray, [_inst._opCount] - - ((asmjit::SectionNode*)this)->_id - ((asmjit::SectionNode*)this)->_nextSection - - ((asmjit::LabelNode*)this)->_id - - ((asmjit::AlignNode*)this)->_alignMode - ((asmjit::AlignNode*)this)->_alignment - - _embed._typeId, d - _embed._typeSize, d - ((asmjit::EmbedDataNode*)this)->_itemCount - ((asmjit::EmbedDataNode*)this)->_repeatCount - ((asmjit::EmbedDataNode*)this)->_inlineData - ((asmjit::EmbedDataNode*)this)->_externalData - - ((asmjit::EmbedLabelNode*)this)->_id - - ((asmjit::EmbedLabelDeltaNode*)this)->_id - ((asmjit::EmbedLabelDeltaNode*)this)->_baseId - ((asmjit::EmbedLabelDeltaNode*)this)->_dataSize - - ((asmjit::ConstPoolNode*)this)->_constPool - - (asmjit::SentinelNode::SentinelType)_sentinel._sentinelType - - ((asmjit::JumpNode*)this)->_annotation - - ((asmjit::FuncNode*)this)->_funcDetail - ((asmjit::FuncNode*)this)->_frame - ((asmjit::FuncNode*)this)->_exitNode - ((asmjit::FuncNode*)this)->_end - ((asmjit::FuncNode*)this)->_args, [((asmjit::FuncNode*)this)->_funcDetail._argCount] - - ((asmjit::InvokeNode*)this)->_funcDetail - ((asmjit::InvokeNode*)this)->_rets, [((asmjit::InvokeNode*)this)->_funcDetail._retCount] - ((asmjit::InvokeNode*)this)->_args, [((asmjit::InvokeNode*)this)->_funcDetail._argCount] - - - diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit-scope-begin.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit-scope-begin.h deleted file mode 100644 index 6ee5050..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit-scope-begin.h +++ /dev/null @@ -1,35 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifdef _WIN32 - #pragma push_macro("min") - #pragma push_macro("max") - - #ifdef min - #undef min - #endif - - #ifdef max - #undef max - #endif -#endif diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit-scope-end.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit-scope-end.h deleted file mode 100644 index 447105a..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit-scope-end.h +++ /dev/null @@ -1,27 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifdef _WIN32 - #pragma pop_macro("min") - #pragma pop_macro("max") -#endif diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit.h deleted file mode 100644 index 400426c..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/asmjit.h +++ /dev/null @@ -1,37 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_ASMJIT_H_INCLUDED -#define ASMJIT_ASMJIT_H_INCLUDED - -#include "./core.h" - -#ifdef ASMJIT_BUILD_X86 - #include "./x86.h" -#endif - -#ifdef ASMJIT_BUILD_ARM - #include "./arm.h" -#endif - -#endif // ASMJIT_ASMJIT_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core.h deleted file mode 100644 index 52540ab..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core.h +++ /dev/null @@ -1,2063 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_H_INCLUDED -#define ASMJIT_CORE_H_INCLUDED - -//! Root namespace used by AsmJit. -namespace asmjit { - -// ============================================================================ -// [Documentation - mainpage] -// ============================================================================ - -//! \mainpage API Reference -//! -//! AsmJit C++ API reference documentation generated by Doxygen. -//! -//! AsmJit library uses one global namespace called \ref asmjit, which provides -//! the whole functionality. Core functionality is within \ref asmjit namespace -//! and architecture specific functionality is always in its own namespace. For -//! example \ref asmjit::x86 provides both 32-bit and 64-bit X86 code generation. -//! -//! \section main_groups Documentation Groups -//! -//! AsmJit documentation is structured into groups. Groups can be followed in -//! order to learn AsmJit, but knowledge from multiple groups is required to -//! use AsmJit properly: -//! -//! $$DOCS_GROUP_OVERVIEW$$ -//! -//! \note It's important to understand that in order to learn AsmJit all groups -//! are important. Some groups can be omitted if a particular tool is out of -//! interest - for example \ref asmjit_assembler users don't need to know about -//! \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users -//! must know about \ref asmjit_assembler as it also uses operands, labels, and -//! other concepts. Similarly \ref asmjit_compiler users must know how both \ref -//! asmjit_assembler and \ref asmjit_builder tools work. -//! -//! \section where_to_start Where To Start -//! -//! AsmJit \ref asmjit_core provides the following two classes that are essential -//! from the code generation perspective: -//! -//! - \ref CodeHolder provides functionality -//! to temporarily hold the generated code. It stores all the necessary -//! information about the code - code buffers, sections, labels, symbols, -//! and information about relocations. -//! -//! - \ref BaseEmitter provides interface used -//! by emitter implementations. The interface provides basic building blocks -//! that are then implemented by \ref BaseAssembler, \ref BaseBuilder, and -//! \ref BaseCompiler. -//! -//! Code emitters: -//! -//! - \ref asmjit_assembler - provides direct machine code generation. -//! -//! - \ref asmjit_builder - provides intermediate code generation that can -//! be processed before it's serialized to \ref BaseAssembler. -//! -//! - \ref asmjit_compiler - provides high-level code generation with built-in -//! register allocation. -//! -//! - \ref FuncNode - provides insight into how function looks from the Compiler -//! perspective and how it's stored in a node-list. -//! -//! \section main_recommendations Recommendations -//! -//! The following steps are recommended for all AsmJit users: -//! -//! - Make sure that you use \ref Logger, see \ref asmjit_logging. -//! -//! - Make sure that you use \ref ErrorHandler, see \ref asmjit_error_handling. -//! -//! - Instruction validation in your debug builds can reveal problems too. -//! AsmJit provides validation at instruction level, that can be enabled -//! by \ref BaseEmitter::addValidationOptions(). -//! -//! See \ref BaseEmitter::ValidationOptions for more details. -//! -//! - Make sure you put a breakpoint into \ref DebugUtils::errored() function -//! if you have a problem with AsmJit returning errors during instruction -//! encoding or register allocation. Having an active breakpoint there can -//! help to reveal the origin of the error, to inspect variables and other -//! conditions that caused to it. -//! -//! The reason for using \ref Logger and \ref ErrorHandler is that they provide -//! a very useful information about what's happening inside emitters. In many -//! cases the information provided by these two is crucial to quickly fix issues -//! that happen during development (for example wrong instruction, address, or -//! register used). In addition, output from \ref Logger is always necessary -//! when filling bug reports. In other words, using logging and proper error -//! handling can save a lot of time during the development. -//! -//! \section main_other Other Pages -//! -//! - Class List - List of classes sorted alphabetically -//! - AsmJit Namespace - List of symbols provided by `asmjit` namespace - -// ============================================================================ -// [Documentation - asmjit_build] -// ============================================================================ - -//! \defgroup asmjit_build Build Instructions -//! \brief Build instructions, supported environments, and feature selection. -//! -//! ### Overview -//! -//! AsmJit is designed to be easy embeddable in any project. However, it depends -//! on some compile-time definitions that can be used to enable or disable -//! features to decrease the resulting binary size. A typical way of building -//! AsmJit is to use [cmake](https://www.cmake.org), but it's also possible to -//! just include AsmJit source code in your project and to just build it. The -//! easiest way to include AsmJit in your project is to just include **src** -//! directory in your project and to define \ref ASMJIT_STATIC. AsmJit can be -//! just updated from time to time without any changes to this integration -//! process. Do not embed AsmJit's `test` files in such case as these are used -//! exclusively for testing. -//! -//! ### Supported C++ Compilers -//! -//! - Requirements: -//! -//! - AsmJit won't build without C++11 enabled. If you use older GCC or Clang -//! you would have to enable at least C++11 standard through compiler flags. -//! -//! - Tested: -//! -//! - **Clang** - Tested by Travis-CI - Clang 3.9+ (with C++11 enabled) is -//! officially supported (older Clang versions having C++11 support are -//! probably fine, but are not regularly tested). -//! -//! - **GNU** - Tested by Travis-CI - GCC 4.8+ (with C++11 enabled) is -//! officially supported. -//! -//! - **MINGW** - Tested by Travis-CI - Use the latest version, if possible. -//! -//! - **MSVC** - Tested by Travis-CI - VS2017+ is officially supported, VS2015 -//! is reported to work. -//! -//! - Untested: -//! -//! - **Intel** - No maintainers and no CI environment to regularly test -//! this compiler. -//! -//! - **Other** C++ compilers would require basic support in -//! [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h). -//! -//! ### Supported Operating Systems and Platforms -//! -//! - Tested: -//! -//! - **Linux** - Tested by Travis-CI (any distribution is generally supported). -//! -//! - **OSX** - Tested by Travis-CI (any version is supported). -//! -//! - **Windows** - Tested by Travis-CI - (Windows 7+ is officially supported). -//! -//! - **Emscripten** - Works if compiled with \ref ASMJIT_NO_JIT. AsmJit -//! cannot generate WASM code, but can be used to generate X86/X64 code -//! within a browser, for example. -//! -//! - Untested: -//! -//! - **BSDs** - No maintainers, no CI environment to regularly test BSDs, -//! but they should work out of box. -//! -//! - **Haiku** - Not regularly tested, but reported to work. -//! -//! - **Other** operating systems would require some testing and support in -//! the following files: -//! - [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h) -//! - [core/osutils.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/osutils.cpp) -//! - [core/virtmem.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/virtmem.cpp) -//! -//! ### Supported Backends / Architectures -//! -//! - **X86** - Both 32-bit and 64-bit backends tested by Travis-CI. -//! - **ARM** - Work-in-progress (not public at the moment). -//! -//! ### Static Builds and Embedding -//! -//! These definitions can be used to enable static library build. Embed is used -//! when AsmJit's source code is embedded directly in another project, implies -//! static build as well. -//! -//! - \ref ASMJIT_EMBED - Asmjit is embedded, implies \ref ASMJIT_STATIC. -//! - \ref ASMJIT_STATIC - Enable static-library build. -//! -//! \note Projects that use AsmJit statically must define \ref ASMJIT_STATIC in -//! all compilation units that use AsmJit, otherwise AsmJit would use dynamic -//! library imports in \ref ASMJIT_API decorator. The recommendation is to -//! define this macro across the whole project that uses AsmJit this way. -//! -//! ### Build Configuration -//! -//! These definitions control whether asserts are active or not. By default -//! AsmJit would autodetect build configuration from existing pre-processor -//! definitions, but this behavior can be overridden, for example to enable -//! debug asserts in release configuration. -//! -//! - \ref ASMJIT_BUILD_DEBUG - Overrides build configuration to debug, -//! asserts will be enabled in this case. -//! - \ref ASMJIT_BUILD_RELEASE - Overrides build configuration to release, -//! asserts will be disabled in this case. -//! -//! \note There is usually no need to override the build configuration. AsmJit -//! detects the build configuration by checking whether `NDEBUG` is defined and -//! automatically defines \ref ASMJIT_BUILD_RELEASE if configuration overrides -//! were not used. We only recommend using build configuration overrides in -//! special situations, like using AsmJit in release configuration with asserts -//! enabled for whatever reason. -//! -//! ### AsmJit Backends -//! -//! AsmJit currently supports only X86/X64 backend, but the plan is to add more -//! backends in the future. By default AsmJit builds only the host backend, which -//! is autodetected at compile-time, but this can be overridden. -//! -//! - \ref ASMJIT_BUILD_X86 - Always build X86 backend (X86 and X86_64). -//! - \ref ASMJIT_BUILD_ARM - Always build ARM backend (ARM and AArch64). -//! - \ref ASMJIT_BUILD_HOST - Always build the host backend. -//! -//! ### Features Selection -//! -//! AsmJit builds by defaults all supported features, which includes all emitters, -//! logging, instruction validation and introspection, and JIT memory allocation. -//! Features can be disabled at compile time by using `ASMJIT_NO_...` definitions. -//! -//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time -//! so it won't be available and the compilation will fail if there is -//! attempt to use such API. This includes deprecated classes, namespaces, -//! enumerations, and functions. -//! -//! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architectures. -//! If defined, it would internally set \ref ASMJIT_BUILD_HOST to true. -//! -//! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality -//! completely. This implies \ref ASMJIT_NO_COMPILER as \ref asmjit_compiler -//! cannot be used without \ref asmjit_builder. -//! -//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality -//! completely. -//! -//! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime. -//! -//! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter. -//! -//! - \ref ASMJIT_NO_TEXT - Disables everything that contains string -//! representation of AsmJit constants, should be used together with -//! \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the -//! ability to quiry instruction names, register names, etc... -//! -//! - \ref ASMJIT_NO_VALIDATION - Disables validation API. -//! -//! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API, -//! must be used together with \ref ASMJIT_NO_COMPILER as \ref asmjit_compiler -//! requires introspection for its liveness analysis and register allocation. -//! -//! \note It's not recommended to disable features if you plan to build AsmJit -//! as a shared library that will be used by multiple projects that you don't -//! control how AsmJit was built (for example AsmJit in a Linux distribution). -//! The possibility to disable certain features exists mainly for customized -//! AsmJit builds. - -// ============================================================================ -// [Documentation - asmjit_breaking_changes] -// ============================================================================ - -//! \defgroup asmjit_breaking_changes Breaking Changes -//! \brief Documentation of breaking changes -//! -//! ### Overview -//! -//! AsmJit is a live project that is being actively developed. Deprecating the -//! existing API in favor of a new one is preferred, but it's not always -//! possible if the changes are significant. AsmJit authors prefer to do -//! accumulated breaking changes at once instead of breaking the API often. -//! This page documents deprecated and removed APIs and should serve as a how-to -//! guide for people that want to port existing code to work with the newest AsmJit. -//! -//! ### Tips -//! -//! Useful tips before you start: -//! -//! - Visit our [Public Gitter Channel](https://gitter.im/asmjit/asmjit) if -//! you need a quick help. -//! -//! - Build AsmJit with `ASMJIT_NO_DEPRECATED` macro defined to make sure that -//! you are not using deprecated functionality at all. Deprecated functions -//! are decorated with `ASMJIT_DEPRECATED()` macro, but sometimes it's not -//! possible to decorate everything like classes, which are used by deprecated -//! functions as well, because some compilers would warn about that. If your -//! project compiles fine with `ASMJIT_NO_DEPRECATED` it's not using anything, -//! which was deprecated. -//! -//! ### Changes committed at 2020-05-30 -//! -//! AsmJit has been cleaned up significantly, many todo items have been fixed -//! and many functions and classes have been redesigned, some in an incompatible -//! way. -//! -//! Core changes: -//! -//! - \ref Imm operand has now only \ref Imm::value() and \ref Imm::valueAs() -//! functions that return its value content, and \ref Imm::setValue() function -//! that sets the content. Functions like `setI8()`, `setU8()` were deprecated. -//! -//! Old functions were deprecated, but code using them should still compile. -//! -//! - `ArchInfo` has been replaced with \ref Environment. Environment provides -//! more details about the architecture, but drops some properties that -//! were used by arch info - `gpSize(`) and `gpCount()`. `gpSize()` can -//! be replaced with `registerSize()` getter, which returns a native register -//! size of the architecture the environment uses. However, `gpCount()` was -//! removed - at the moment \ref ArchRegs can be used to access such properties. -//! -//! Some other functions were renamed, like `ArchInfo::isX86Family()` is -//! now \ref Environment::isFamilyX86(), etc. The reason for changing the -//! order was support for more propertries and all the accessors now -//! start with the type of the property, like \ref Environment::isPlatformWindows(). -//! -//! This function causes many other classes to provide `environment()` getter -//! instead of `archInfo()` getter. In addition, AsmJit now uses `arch()` to -//! get an architecture instead of `archId()`. `ArchInfo::kIdXXX` was renamed -//! to `Environment::kArchXXX`. -//! -//! Some functions were deprecated, some removed... -//! -//! - `CodeInfo` has been removed in favor of \ref Environment. If you used -//! `CodeInfo` to set architecture and base address, this is now possible -//! with \ref Environment and setting base address explicitly by \ref -//! CodeHolder::init() - the first argument is \ref Environment, and the -//! second argument is base address, which defaults to \ref -//! Globals::kNoBaseAddress. -//! -//! CodeInfo class was deprecated, but the code using it should still -//! compile with warnings. -//! -//! - \ref CallConv has been updated to offer a more unified way of representing -//! calling conventions - many calling conventions were abstracted to follow -//! standard naming like \ref CallConv::kIdCDecl or \ref CallConv::kIdStdCall. -//! -//! This change means that other APIs like \ref FuncDetail::init() now -//! require both, calling convention and target \ref Environment. -//! -//! - `Logging` namespace has been renamed to \ref Formatter, which now -//! provides general functionality for formatting in AsmJit. -//! -//! Logging namespace should still work, but its use is deprecated. -//! Unfortunately this will be without deprecation warnings, so please -//! make sure you don't use it. -//! -//! - `Data64`, `Data128`, and `Data256` structs were deprecated and should -//! no longer be used. There is no replacement, AsmJit users should simply -//! create their own structures if they need them or use the new repeated -//! embed API in emitters, see \ref BaseEmitter::embedDataArray(). -//! -//! Emitter changes: -//! -//! - \ref BaseEmitter::emit() function signature has been changed to accept -//! 3 operands by reference and the rest 3 operands as a continuous array. -//! This change is purely cosmetic and shouldn't affect users as emit() -//! has many overloads that dispatch to the right function. -//! -//! - \ref x86::Emitter (Assembler, Builder, Compiler) deprecates embed -//! utilities like `dint8()`, `duint8()`, `duint16()`, `dxmm()`, etc... -//! in favor of a new and more powerful \ref BaseEmitter::embedDataArray(). -//! This function also allows emitting repeated values and/or patterns, -//! which is used by helpers \ref BaseEmitter::embedUInt8(), and others... -//! -//! - Validation is now available through \ref BaseEmitter::ValidationOptions, -//! which can be enabled/disabled through \ref BaseEmitter::addValidationOptions() -//! and \ref BaseEmitter::clearValidationOptions(), respectively. Validation -//! options now separate between encoding and Builder/Compiler so it's possible -//! to choose the granularity required. -//! -//! Builder changes: -//! -//! - Internal functions for creating nodes were redesigned. They now accept -//! a pointer to the node created as a first parameter. These changes should -//! not affect AsmJit users as these functions were used internally. -//! -//! Compiler changes: -//! -//! - `FuncCallNode` has been renamed to \ref InvokeNode. Additionally, function -//! calls should now use \ref x86::Compiler::invoke() instead of `call()`. -//! The reason behind this is to remove the confusion between a `call` -//! instruction and AsmJit's `call()` intrinsic, which is now `invoke()`. -//! -//! - Creating new nodes also changed. Now the preferred way of invoking a -//! function is to call \ref x86::Compiler::invoke() where the first -//! argument is `InvokeNode**`. The function now returns an error and would -//! call \ref ErrorHandler in case of a failure. Error handling was -//! unspecified in the past - the function was marked noexcept, but called -//! error handler, which could throw. -//! -//! The reason behind this change is to make the API consistent with other -//! changes and to also make it possible to inspect the possible error. In -//! the previous API it returned a new node or `nullptr` in case of error, -//! which the user couldn't inspect unless there was an attached \ref -//! ErrorHandler. -//! -//! Samples: -//! -//! ``` -//! #include -//! using namespace asmjit; -//! -//! // The basic setup of JitRuntime and CodeHolder changed, use environment() -//! // instead of codeInfo(). -//! void basicSetup() { -//! JitRuntime rt; -//! CodeHolder code(rt.environment()); -//! } -//! -//! // Calling a function (Compiler) changed - use invoke() instead of call(). -//! void functionInvocation(x86::Compiler& cc) { -//! InvokeNode* invokeNode; -//! cc.invoke(&invokeNode, targetOperand, FuncSignatureT<...>(...)); -//! } -//! ``` - -// ============================================================================ -// [Documentation - asmjit_core] -// ============================================================================ - -//! \defgroup asmjit_core Core -//! \brief Globals, code storage, and emitter interface. -//! -//! ### Overview -//! -//! AsmJit library uses \ref CodeHolder to hold code during code generation and -//! emitters inheriting from \ref BaseEmitter to emit code. CodeHolder uses -//! containers to manage its data: -//! -//! - \ref Section - stores information about a code or data section. -//! - \ref CodeBuffer - stores actual code or data, part of \ref Section. -//! - \ref LabelEntry - stores information about a label - its name, offset, -//! section where it belongs to, and other bits. -//! - \ref LabelLink - stores information about yet unbound label, which was -//! already used by the assembler. -//! - \ref RelocEntry - stores information about a relocation. -//! - \ref AddressTableEntry - stores information about an address, which was -//! used in a jump or call. Such address may need relocation. -//! -//! To generate code you would need to instantiate at least the following classes: -//! -//! - \ref CodeHolder - to hold code during code generation. -//! - \ref BaseEmitter - to emit code into \ref CodeHolder. -//! - \ref Target (optional) - most likely \ref JitRuntime to keep the generated -//! code in executable memory. \ref Target can be customized by inheriting from -//! it. -//! -//! There are also other core classes that are important: -//! -//! - \ref Environment - describes where the code will run. Environment brings -//! the concept of target triples or tuples into AsmJit, which means that users -//! can specify target architecture, platform, and ABI. -//! - \ref Type - encapsulates lightweight type functionality that can be used -//! to describe primitive and vector types. Types are used by higher level -//! utilities, for example by \ref asmjit_function and \ref asmjit_compiler. -//! - \ref CpuInfo - encapsulates CPU information - stores both CPU information -//! and features described by \ref BaseFeatures. -//! -//! AsmJit also provides global constants: -//! -//! - \ref Globals - namespace that provides global constants. -//! - \ref ByteOrder - byte-order constants and functionality. -//! -//! \note CodeHolder examples use \ref x86::Assembler as abstract interfaces cannot -//! be used to generate code. -//! -//! ### CodeHolder & Emitters -//! -//! The example below shows how the mentioned classes interact to generate X86 code: -//! -//! ``` -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! // Signature of the generated function. -//! typedef int (*Func)(void); -//! -//! int main() { -//! JitRuntime rt; // Runtime specialized for JIT code execution. -//! -//! CodeHolder code; // Holds code and relocation information. -//! code.init(rt.environment()); // Initialize code to match the JIT environment. -//! -//! x86::Assembler a(&code); // Create and attach x86::Assembler to code. -//! a.mov(x86::eax, 1); // Move one to eax register. -//! a.ret(); // Return from function. -//! // ===== x86::Assembler is no longer needed from here and can be destroyed ===== -//! -//! Func fn; // Holds address to the generated function. -//! Error err = rt.add(&fn, &code); // Add the generated code to the runtime. -//! if (err) return 1; // Handle a possible error returned by AsmJit. -//! // ===== CodeHolder is no longer needed from here and can be destroyed ===== -//! -//! int result = fn(); // Execute the generated code. -//! printf("%d\n", result); // Print the resulting "1". -//! -//! // All classes use RAII, all resources will be released before `main()` returns, -//! // the generated function can be, however, released explicitly if you intend to -//! // reuse or keep the runtime alive, which you should in a production-ready code. -//! rt.release(fn); -//! -//! return 0; -//! } -//! ``` -//! -//! The example above used \ref x86::Assembler as an emitter. AsmJit provides the -//! following emitters that offer various levels of abstraction: -//! -//! - \ref asmjit_assembler - Low-level emitter that emits directly to \ref CodeBuffer. -//! - \ref asmjit_builder - Low-level emitter that emits to a \ref BaseNode list. -//! - \ref asmjit_compiler - High-level emitter that provides register allocation. -//! -//! ### Targets and JitRuntime -//! -//! AsmJit's \ref Target is an interface that provides basic target abstraction. -//! At the moment AsmJit provides only one implementation called \ref JitRuntime, -//! which as the name suggests provides JIT code target and execution runtime. -//! \ref JitRuntime provides all the necessary stuff to implement a simple JIT -//! compiler with basic memory management. It only provides \ref JitRuntime::add() -//! and \ref JitRuntime::release() functions that are used to either add code -//! to the runtime or release it. \ref JitRuntime doesn't do any decisions on -//! when the code should be released, the decision is up to the developer. -//! -//! See more at \ref asmjit_virtual_memory group. -//! -//! ### More About Environment -//! -//! In the previous example the \ref Environment is retrieved from \ref JitRuntime. -//! It's logical as \ref JitRuntime always returns an \ref Environment that is -//! compatible with the host. For example if your application runs in 64-bit mode -//! the \ref Environment returned will use \ref Environment::kArchX64 architecture -//! in contrast to \ref Environment::kArchX86, which will be used in 32-bit mode on -//! any X86 platform. -//! -//! AsmJit allows to setup the \ref Environment manually and to select a different -//! architecture and ABI when necessary. So let's do something else this time, let's -//! always generate a 32-bit code and print its binary representation. To do that, we -//! can create our own \ref Environment and initialize it to \ref Environment::kArchX86. -//! -//! ``` -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! int main(int argc, char* argv[]) { -//! using namespace asmjit::x86; -//! -//! // Create a custom environment initialized to 32-bit X86 architecture. -//! Environment env; -//! env.setArch(Environment::kArchX86); -//! -//! CodeHolder code; // Create a CodeHolder. -//! code.init(env); // Initialize CodeHolder with custom environment. -//! -//! // Generate a 32-bit function that sums 4 floats and looks like: -//! // void func(float* dst, const float* a, const float* b) -//! x86::Assembler a(&code); // Create and attach x86::Assembler to `code`. -//! -//! a.mov(eax, dword_ptr(esp, 4)); // Load the destination pointer. -//! a.mov(ecx, dword_ptr(esp, 8)); // Load the first source pointer. -//! a.mov(edx, dword_ptr(esp, 12)); // Load the second source pointer. -//! -//! a.movups(xmm0, ptr(ecx)); // Load 4 floats from [ecx] to XMM0. -//! a.movups(xmm1, ptr(edx)); // Load 4 floats from [edx] to XMM1. -//! a.addps(xmm0, xmm1); // Add 4 floats in XMM1 to XMM0. -//! a.movups(ptr(eax), xmm0); // Store the result to [eax]. -//! a.ret(); // Return from function. -//! -//! // We have no Runtime this time, it's on us what we do with the code. -//! // CodeHolder stores code in Section, which provides some basic properties -//! // and CodeBuffer structure. We are interested in section's CodeBuffer. -//! // -//! // NOTE: The first section is always '.text', it can be retrieved by -//! // code.sectionById(0) or simply by code.textSection(). -//! CodeBuffer& buffer = code.textSection()->buffer(); -//! -//! // Print the machine-code generated or do something else with it... -//! // 8B4424048B4C24048B5424040F28010F58010F2900C3 -//! for (size_t i = 0; i < buffer.length; i++) -//! printf("%02X", buffer.data[i]); -//! -//! return 0; -//! } -//! ``` -//! -//! ### Explicit Code Relocation -//! -//! In addition to \ref Environment, \ref CodeHolder can be configured to -//! specify a base-address (or a virtual base-address in a linker terminology), -//! which could be static (useful when you know the location where the target's -//! machine code will be) or dynamic. AsmJit assumes dynamic base-address by -//! default and relocates the code held by \ref CodeHolder to a user provided -//! address on-demand. To be able to relocate to a user provided address it needs -//! to store some information about relocations, which is represented by \ref -//! RelocEntry. Relocation entries are only required if you call external functions -//! from the generated code that cannot be encoded by using a 32-bit displacement -//! (64-bit displacements are not provided by aby supported architecture). -//! -//! There is also a concept called \ref LabelLink - label link is a lightweight -//! data structure that doesn't have any identifier and is stored in \ref LabelEntry -//! as a single-linked list. Label link represents either unbound yet used label -//! and cross-sections links (only relevant to code that uses multiple sections). -//! Since crossing sections is something that cannot be resolved immediately these -//! links persist until offsets of these sections are assigned and until -//! \ref CodeHolder::resolveUnresolvedLinks() is called. It's an error if you end -//! up with code that has unresolved label links after flattening. You can verify -//! it by calling \ref CodeHolder::hasUnresolvedLinks(), which inspects the value -//! returned by \ref CodeHolder::unresolvedLinkCount(). -//! -//! AsmJit can flatten code that uses multiple sections by assigning each section -//! an incrementing offset that respects its alignment. Use \ref CodeHolder::flatten() -//! to do that. After the sections are flattened their offsets and virtual-sizes -//! are adjusted to respect each section's buffer size and alignment. The \ref -//! CodeHolder::resolveUnresolvedLinks() function must be called before relocating -//! the code held by \ref CodeHolder. You can also flatten your code manually by -//! iterating over all sections and calculating their offsets (relative to base) -//! by your own algorithm. In that case \ref CodeHolder::flatten() should not be -//! called, however, \ref CodeHolder::resolveUnresolvedLinks() should be. -//! -//! The example below shows how to use a built-in virtual memory allocator -//! \ref JitAllocator instead of using \ref JitRuntime (just in case you want -//! to use your own memory management) and how to relocate the generated code -//! into your own memory block - you can use your own virtual memory allocator -//! if you prefer that, but that's OS specific and not covered by the documentation. -//! -//! The following code is similar to the previous one, but implements a function -//! working in both 32-bit and 64-bit environments: -//! -//! ``` -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! typedef void (*SumIntsFunc)(int* dst, const int* a, const int* b); -//! -//! int main() { -//! // Create a custom environment that matches the current host environment. -//! Environment env = hostEnvironment(); -//! -//! CodeHolder code; // Create a CodeHolder. -//! code.init(env); // Initialize CodeHolder with environment. -//! -//! x86::Assembler a(&code); // Create and attach x86::Assembler to `code`. -//! -//! // Signature: 'void func(int* dst, const int* a, const int* b)'. -//! x86::Gp dst; -//! x86::Gp src_a; -//! x86::Gp src_b; -//! -//! // Handle the difference between 32-bit and 64-bit calling conventions -//! // (arguments passed through stack vs. arguments passed by registers). -//! if (env.is32Bit()) { -//! dst = x86::eax; -//! src_a = x86::ecx; -//! src_b = x86::edx; -//! a.mov(dst , x86::dword_ptr(x86::esp, 4)); -//! a.mov(src_a, x86::dword_ptr(x86::esp, 8)); -//! a.mov(src_b, x86::dword_ptr(x86::esp, 12)); -//! } -//! else { -//! if (env.isPlatformWindows()) { -//! dst = x86::rcx; // First argument (destination pointer). -//! src_a = x86::rdx; // Second argument (source 'a' pointer). -//! src_b = x86::r8; // Third argument (source 'b' pointer). -//! } -//! else { -//! dst = x86::rdi; // First argument (destination pointer). -//! src_a = x86::rsi; // Second argument (source 'a' pointer). -//! src_b = x86::rdx; // Third argument (source 'b' pointer). -//! } -//! } -//! -//! a.movdqu(x86::xmm0, x86::ptr(src_a)); // Load 4 ints from [src_a] to XMM0. -//! a.movdqu(x86::xmm1, x86::ptr(src_b)); // Load 4 ints from [src_b] to XMM1. -//! a.paddd(x86::xmm0, x86::xmm1); // Add 4 ints in XMM1 to XMM0. -//! a.movdqu(x86::ptr(dst), x86::xmm0); // Store the result to [dst]. -//! a.ret(); // Return from function. -//! -//! // Even when we didn't use multiple sections AsmJit could insert one section -//! // called '.addrtab' (address table section), which would be filled by data -//! // required by relocations (absolute jumps and calls). You can omit this code -//! // if you are 100% sure your code doesn't contain multiple sections and -//! // such relocations. You can use `CodeHolder::hasAddressTable()` to verify -//! // whether the address table section does exist. -//! code.flatten(); -//! code.resolveUnresolvedLinks(); -//! -//! // After the code was generated it can be relocated manually to any memory -//! // location, however, we need to know it's size before we perform memory -//! // allocation. `CodeHolder::codeSize()` returns the worst estimated code -//! // size in case that relocations are not possible without trampolines (in -//! // that case some extra code at the end of the current code buffer is -//! // generated during relocation). -//! size_t estimatedSize = code.codeSize(); -//! -//! // Instead of rolling up our own memory allocator we can use the one AsmJit -//! // provides. It's decoupled so you don't need to use `JitRuntime` for that. -//! JitAllocator allocator; -//! -//! // Allocate an executable virtual memory and handle a possible failure. -//! void* p = allocator.alloc(estimatedSize); -//! if (!p) -//! return 0; -//! -//! // Now relocate the code to the address provided by the memory allocator. -//! // Please note that this DOESN'T COPY anything to `p`. This function will -//! // store the address in CodeHolder and use relocation entries to patch the -//! // existing code in all sections to respect the base address provided. -//! code.relocateToBase((uint64_t)p); -//! -//! // This is purely optional. There are cases in which the relocation can omit -//! // unneeded data, which would shrink the size of address table. If that -//! // happened the codeSize returned after relocateToBase() would be smaller -//! // than the originally `estimatedSize`. -//! size_t codeSize = code.codeSize(); -//! -//! // This will copy code from all sections to `p`. Iterating over all sections -//! // and calling `memcpy()` would work as well, however, this function supports -//! // additional options that can be used to also zero pad sections' virtual -//! // size, etc. -//! // -//! // With some additional features, copyFlattenData() does roughly this: -//! // for (Section* section : code.sections()) -//! // memcpy((uint8_t*)p + section->offset(), -//! // section->data(), -//! // section->bufferSize()); -//! code.copyFlattenedData(p, codeSize, CodeHolder::kCopyPadSectionBuffer); -//! -//! // Execute the generated function. -//! int inA[4] = { 4, 3, 2, 1 }; -//! int inB[4] = { 1, 5, 2, 8 }; -//! int out[4]; -//! -//! // This code uses AsmJit's ptr_as_func<> to cast between void* and SumIntsFunc. -//! ptr_as_func(p)(out, inA, inB); -//! -//! // Prints {5 8 4 9} -//! printf("{%d %d %d %d}\n", out[0], out[1], out[2], out[3]); -//! -//! // Release 'p' is it's no longer needed. It will be destroyed with 'vm' -//! // instance anyway, but it's a good practice to release it explicitly -//! // when you know that the function will not be needed anymore. -//! allocator.release(p); -//! -//! return 0; -//! } -//! ``` -//! -//! If you know the base-address in advance (before the code generation) it can -//! be passed as a second argument to \ref CodeHolder::init(). In that case the -//! Assembler will know the absolute position of each instruction and would be -//! able to use it during instruction encoding to prevent relocations where -//! possible. The following example shows how to configure the base address: -//! -//! ``` -//! #include -//! #include -//! -//! void initializeCodeHolder(CodeHolder& code) { -//! Environment env = hostEnvironment(); -//! uint64_t baseAddress = uint64_t(0x1234); -//! -//! // initialize CodeHolder with environment and custom base address. -//! code.init(env, baseAddress); -//! } -//! ``` -//! -//! ### Label Offsets and Links -//! -//! When a label that is not yet bound is used by the Assembler, it creates a -//! \ref LabelLink, which is then added to a \ref LabelEntry. These links are -//! also created if a label is used in a different section than in which it -//! was bound. Let's examine some functions that can be used to check whether -//! there are any unresolved links. -//! -//! ``` -//! #include -//! #include -//! -//! void labelLinksExample(CodeHolder& code, const Label& label) { -//! // Tests whether the `label` is bound. -//! bool isBound = code.isLabelBound(label); -//! printf("Label %u is %s\n", label.id(), isBound ? "bound" : "not bound"); -//! -//! // Returns true if the code contains either referenced, but unbound -//! // labels, or cross-section label links that are not resolved yet. -//! bool hasUnresolved = code.hasUnresolvedLinks(); // Boolean answer. -//! size_t nUnresolved = code.unresolvedLinkCount(); // Count of unresolved links. -//! -//! printf("Number of unresolved links: %zu\n", nUnresolved); -//! } -//! ``` -//! -//! There is no function that would return the number of unbound labels as this -//! is completely unimportant from CodeHolder's perspective. If a label is not -//! used then it doesn't matter whether it's bound or not, only actually used -//! labels matter. After a Label is bound it's possible to query its offset -//! offset relative to the start of the section where it was bound: -//! -//! ``` -//! #include -//! #include -//! -//! void labelOffsetExample(CodeHolder& code, const Label& label) { -//! // Label offset is known after it's bound. The offset provided is relative -//! // to the start of the section, see below for alternative. If the given -//! // label is not bound the offset returned will be zero. It's recommended -//! // to always check whether the label is bound before using its offset. -//! uint64_t sectionOffset = code.labelOffset(label); -//! printf("Label offset relative to section: %llu\n", (unsigned long long)sectionOffset); -//! -//! // If you use multiple sections and want the offset relative to the base. -//! // NOTE: This function expects that the section has already an offset and -//! // the label-link was resolved (if this is not true you will still get an -//! // offset relative to the start of the section). -//! uint64_t baseOffset = code.labelOffsetFromBase(label); -//! printf("Label offset relative to base: %llu\n", (unsigned long long)baseOffset); -//! } -//! ``` -//! -//! ### Sections -//! -//! AsmJit allows to create multiple sections within the same \ref CodeHolder. -//! A test-case [asmjit_test_x86_sections.cpp](https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_sections.cpp) -//! can be used as a reference point although the following example should -//! also provide a useful insight: -//! -//! ``` -//! #include -//! #include -//! -//! void sectionsExample(CodeHolder& code) { -//! // Text section is always provided as the first section. -//! Section* text = code.textSection(); // or code.sectionById(0); -//! -//! // To create another section use CodeHolder::newSection(). -//! Section* data; -//! Error err = code.newSection(&data, -//! ".data", // Section name -//! SIZE_MAX, // Name length if the name is not null terminated (or SIZE_MAX). -//! 0, // Section flags, see Section::Flags. -//! 8, // Section alignment, must be power of 2. -//! 0); // Section order value (optional, default 0). -//! -//! // When you switch sections in Assembler, Builder, or Compiler the cursor -//! // will always move to the end of that section. When you create an Assembler -//! // the cursor would be placed at the end of the first (.text) section, which -//! // is initially empty. -//! x86::Assembler a(&code); -//! Label L_Data = a.newLabel(); -//! -//! a.mov(x86::eax, x86::ebx); // Emits in .text section. -//! -//! a.section(data); // Switches to the end of .data section. -//! a.bind(L_Data); // Binds label in this .data section -//! a.db(0x01); // Emits byte in .data section. -//! -//! a.section(text); // Switches to the end of .text section. -//! a.add(x86::ebx, x86::eax); // Emits in .text section. -//! -//! // References a label in .text section, which was bound in .data section. -//! // This would create a LabelLink even when the L_Data is already bound, -//! // because the reference crosses sections. See below... -//! a.lea(x86::rsi, x86::ptr(L_Data)); -//! } -//! ``` -//! -//! The last line in the example above shows that a LabelLink would be created -//! even for bound labels that cross sections. In this case a referenced label -//! was bound in another section, which means that the link couldn't be resolved -//! at that moment. If your code uses sections, but you wish AsmJit to flatten -//! these sections (you don't plan to flatten them manually) then there is an -//! API for that. -//! -//! ``` -//! #include -//! #include -//! -//! // ... (continuing the previous example) ... -//! void sectionsExampleContinued(CodeHolder& code) { -//! // Suppose we have some code that contains multiple sections and -//! // we would like to flatten it by using AsmJit's built-in API: -//! Error err = code.flatten(); -//! if (err) { -//! // There are many reasons it can fail, so always handle a possible error. -//! printf("Failed to flatten the code: %s\n", DebugUtils::errorAsString(err)); -//! exit(1); -//! } -//! -//! // After flattening all sections would contain assigned offsets -//! // relative to base. Offsets are 64-bit unsigned integers so we -//! // cast them to `size_t` for simplicity. On 32-bit targets it's -//! // guaranteed that the offset cannot be greater than `2^32 - 1`. -//! printf("Data section offset %zu", size_t(data->offset())); -//! -//! // The flattening doesn't resolve unresolved label links, this -//! // has to be done manually as flattening can be done separately. -//! err = code.resolveUnresolvedLinks(); -//! if (err) { -//! // This is the kind of error that should always be handled... -//! printf("Failed to resolve label links: %s\n", DebugUtils::errorAsString(err)); -//! exit(1); -//! } -//! -//! if (code.hasUnresolvedLinks()) { -//! // This would mean either unbound label or some other issue. -//! printf("The code has %zu unbound labels\n", code.unresovedLinkCount()); -//! exit(1); -//! } -//! } -//! ``` - -// ============================================================================ -// [Documentation - asmjit_assembler] -// ============================================================================ - -//! \defgroup asmjit_assembler Assembler -//! \brief Assembler interface and operands. -//! -//! ### Overview -//! -//! AsmJit's Assembler is used to emit machine code directly into a \ref -//! CodeBuffer. In general, code generation with assembler requires the knowledge -//! of the following: -//! -//! - \ref BaseAssembler and architecture-specific assemblers: -//! - \ref x86::Assembler - Assembler specific to X86 architecture -//! - \ref Operand and its variations: -//! - \ref BaseReg - Base class for a register operand, inherited by: -//! - \ref x86::Reg - Register operand specific to X86 architecture. -//! - \ref BaseMem - Base class for a memory operand, inherited by: -//! - \ref x86::Mem - Memory operand specific to X86 architecture. -//! - \ref Imm - Immediate (value) operand. -//! - \ref Label - Label operand. -//! -//! \note Assembler examples use \ref x86::Assembler as abstract interfaces cannot -//! be used to generate code. -//! -//! ### Operand Basics -//! -//! Let's start with operands. \ref Operand is a data structure that defines a -//! data layout of any operand. It can be inherited, but any class inheriting -//! it cannot add any members to it, only the existing layout can be reused. -//! AsmJit allows to construct operands dynamically, to store them, and to query -//! a complete information about them at run-time. Operands are small (always 16 -//! bytes per \ref Operand) and can be copied and passed by value. Please never -//! allocate individual operands dynamically by using a `new` keyword - it would -//! work, but then you would have to be responsible for deleting such operands. -//! In AsmJit operands are always part of some other data structures like \ref -//! InstNode, which is part of \ref asmjit_builder tool. -//! -//! Operands contain only identifiers, but not pointers to any code-generation data. -//! For example \ref Label operand only provides label identifier, but not a pointer -//! to \ref LabelEntry structure. In AsmJit such IDs are used to link stuff together -//! without having to deal with pointers. -//! -//! AsmJit's operands all inherit from a base class called \ref Operand. Operands -//! have the following properties that are commonly accessible by getters and setters: -//! -//! - \ref Operand - Base operand, which only provides accessors that are common -//! to all operand types. -//! - \ref BaseReg - Describes either physical or virtual register. Physical -//! registers have id that matches the target's machine id directly whereas -//! virtual registers must be allocated into physical registers by a register -//! allocator pass. Register operand provides: -//! - Register Type - Unique id that describes each possible register provided -//! by the target architecture - for example X86 backend provides \ref -//! x86::Reg::RegType, which defines all variations of general purpose registers -//! (GPB-LO, GPB-HI, GPW, GPD, and GPQ) and all types of other registers like K, -//! MM, BND, XMM, YMM, and ZMM. -//! - Register Group - Groups multiple register types under a single group - for -//! example all general-purpose registers (of all sizes) on X86 are part of -//! \ref x86::Reg::kGroupGp and all SIMD registers (XMM, YMM, ZMM) are part -//! of \ref x86::Reg::kGroupVec. -//! - Register Size - Contains the size of the register in bytes. If the size -//! depends on the mode (32-bit vs 64-bit) then generally the higher size is -//! used (for example RIP register has size 8 by default). -//! - Register Id - Contains physical or virtual id of the register. -//! - \ref BaseMem - Used to reference a memory location. Memory operand provides: -//! - Base Register - A base register type and id (physical or virtual). -//! - Index Register - An index register type and id (physical or virtual). -//! - Offset - Displacement or absolute address to be referenced (32-bit if base -//! register is used and 64-bit if base register is not used). -//! - Flags that can describe various architecture dependent information (like -//! scale and segment-override on X86). -//! - \ref Imm - Immediate values are usually part of instructions (encoded within -//! the instruction itself) or data. -//! - \ref Label - used to reference a location in code or data. Labels must be -//! created by the \ref BaseEmitter or by \ref CodeHolder. Each label has its -//! unique id per \ref CodeHolder instance. -//! -//! ### Operand Manipulation -//! -//! AsmJit allows to construct operands dynamically, to store them, and to query -//! a complete information about them at run-time. Operands are small (always 16 -//! bytes per `Operand`) and should be always copied (by value) if you intend to -//! store them (don't create operands by using `new` keyword, it's not recommended). -//! Operands are safe to be passed to `memcpy()` and `memset()`, which becomes -//! handy when working with arrays of operands. If you set all members of an \ref -//! Operand to zero the operand would become NONE operand, which is the same as a -//! default constructed Operand. -//! -//! The example below illustrates how operands can be used and modified even -//! without using any other code generation classes. The example uses X86 -//! architecture-specific operands. -//! -//! ``` -//! #include -//! -//! using namespace asmjit; -//! -//! // Registers can be copied, it's a common practice. -//! x86::Gp dstRegByValue() { return x86::ecx; } -//! -//! void usingOperandsExample(x86::Assembler& a) { -//! // Gets `ecx` register returned by a function. -//! x86::Gp dst = dstRegByValue(); -//! // Gets `rax` register directly from the provided `x86` namespace. -//! x86::Gp src = x86::rax; -//! // Constructs `r10` dynamically. -//! x86::Gp idx = x86::gpq(10); -//! // Constructs [src + idx] memory address - referencing [rax + r10]. -//! x86::Mem m = x86::ptr(src, idx); -//! -//! // Examine `m`: Returns `x86::Reg::kTypeGpq`. -//! m.indexType(); -//! // Examine `m`: Returns 10 (`r10`). -//! m.indexId(); -//! -//! // Reconstruct `idx` stored in mem: -//! x86::Gp idx_2 = x86::Gp::fromTypeAndId(m.indexType(), m.indexId()); -//! -//! // True, `idx` and idx_2` are identical. -//! idx == idx_2; -//! -//! // Possible - op will still be the same as `m`. -//! Operand op = m; -//! // True (can be casted to BaseMem or architecture-specific Mem). -//! op.isMem(); -//! -//! // True, `op` is just a copy of `m`. -//! m == op; -//! -//! // Static cast is fine and valid here. -//! static_cast(op).addOffset(1); -//! // However, using `as()` to cast to a derived type is preferred. -//! op.as().addOffset(1); -//! // False, `op` now points to [rax + r10 + 2], which is not [rax + r10]. -//! m == op; -//! -//! // Emitting 'mov' - type safe way. -//! a.mov(dst, m); -//! // Not possible, `mov` doesn't provide mov(x86::Gp, Operand) overload. -//! a.mov(dst, op); -//! -//! // Type-unsafe, but possible. -//! a.emit(x86::Inst::kIdMov, dst, m); -//! // Also possible, `emit()` is typeless and can be used with raw Operand. -//! a.emit(x86::Inst::kIdMov, dst, op); -//! } -//! ``` -//! -//! Some operands have to be created explicitly by emitters. For example labels -//! must be created by \ref BaseEmitter::newLabel(), which creates a label entry -//! and returns a \ref Label operand with the id that refers to it. Such label -//! then can be used by emitters. -//! -//! ### Memory Operands -//! -//! Some architectures like X86 provide a complex memory addressing model that -//! allows to encode addresses having a BASE register, INDEX register with a -//! possible scale (left shift), and displacement (called offset in AsmJit). -//! Memory address on X86 can also specify memory segment (segment-override in -//! X86 terminology) and some instructions (gather / scatter) require INDEX to -//! be a \ref x86::Vec register instead of a general-purpose register. -//! -//! AsmJit allows to encode and work with all forms of addresses mentioned and -//! implemented by X86. In addition, it also allows to construct absolute 64-bit -//! memory address operands, which is only allowed in one form of 'mov' instruction. -//! -//! ``` -//! #include -//! -//! using namespace asmjit; -//! -//! void testX86Mem() { -//! // Makes it easier to access x86 stuff... -//! using namespace asmjit::x86; -//! -//! // BASE + OFFSET. -//! Mem a = ptr(rax); // a = [rax] -//! Mem b = ptr(rax, 15); // b = [rax + 15] -//! -//! // BASE + INDEX << SHIFT - Shift is in BITS as used by X86! -//! Mem c = ptr(rax, rbx); // c = [rax + rbx] -//! Mem d = ptr(rax, rbx, 2); // d = [rax + rbx << 2] -//! Mem e = ptr(rax, rbx, 2, 15); // e = [rax + rbx << 2 + 15] -//! -//! // BASE + VM (Vector Index) (encoded as MOD+VSIB). -//! Mem f = ptr(rax, xmm1); // f = [rax + xmm1] -//! Mem g = ptr(rax, xmm1, 2); // g = [rax + xmm1 << 2] -//! Mem h = ptr(rax, xmm1, 2, 15); // h = [rax + xmm1 << 2 + 15] -//! -//! // Absolute adddress: -//! uint64_t addr = (uint64_t)0x1234; -//! Mem i = ptr(addr); // i = [0x1234] -//! Mem j = ptr(addr, rbx); // j = [0x1234 + rbx] -//! Mem k = ptr(addr, rbx, 2); // k = [0x1234 + rbx << 2] -//! -//! // LABEL - Will be encoded as RIP (64-bit) or absolute address (32-bit). -//! Label L = ...; -//! Mem m = ptr(L); // m = [L] -//! Mem n = ptr(L, rbx); // n = [L + rbx] -//! Mem o = ptr(L, rbx, 2); // o = [L + rbx << 2] -//! Mem p = ptr(L, rbx, 2, 15); // p = [L + rbx << 2 + 15] -//! -//! // RIP - 64-bit only (RIP can't use INDEX). -//! Mem q = ptr(rip, 24); // q = [rip + 24] -//! } -//! ``` -//! -//! Memory operands can optionally contain memory size. This is required by -//! instructions where the memory size cannot be deduced from other operands, -//! like `inc` and `dec` on X86: -//! -//! ``` -//! #include -//! -//! using namespace asmjit; -//! -//! void testX86Mem() { -//! // The same as: dword ptr [rax + rbx]. -//! x86::Mem a = x86::dword_ptr(rax, rbx); -//! -//! // The same as: qword ptr [rdx + rsi << 0 + 1]. -//! x86::Mem b = x86::qword_ptr(rdx, rsi, 0, 1); -//! } -//! ``` -//! -//! Memory operands provide API that can be used to access its properties: -//! -//! ``` -//! #include -//! -//! using namespace asmjit; -//! -//! void testX86Mem() { -//! // The same as: dword ptr [rax + 12]. -//! x86::Mem mem = x86::dword_ptr(rax, 12); -//! -//! mem.hasBase(); // true. -//! mem.hasIndex(); // false. -//! mem.size(); // 4. -//! mem.offset(); // 12. -//! -//! mem.setSize(0); // Sets the size to 0 (makes it sizeless). -//! mem.addOffset(-1); // Adds -1 to the offset and makes it 11. -//! mem.setOffset(0); // Sets the offset to 0. -//! mem.setBase(rcx); // Changes BASE to RCX. -//! mem.setIndex(rax); // Changes INDEX to RAX. -//! mem.hasIndex(); // true. -//! } -//! // ... -//! ``` -//! -//! Making changes to memory operand is very comfortable when emitting loads -//! and stores: -//! -//! ``` -//! #include -//! -//! using namespace asmjit; -//! -//! void testX86Mem(CodeHolder& code) { -//! x86::Assembler a(code); // Your initialized x86::Assembler. -//! x86::Mem mSrc = x86::ptr(eax); // Construct [eax] memory operand. -//! -//! // One way of emitting bunch of loads is to use `mem.adjusted()`, which -//! // returns a new memory operand and keeps the source operand unchanged. -//! a.movaps(x86::xmm0, mSrc); // No adjustment needed to load [eax]. -//! a.movaps(x86::xmm1, mSrc.adjusted(16)); // Loads from [eax + 16]. -//! a.movaps(x86::xmm2, mSrc.adjusted(32)); // Loads from [eax + 32]. -//! a.movaps(x86::xmm3, mSrc.adjusted(48)); // Loads from [eax + 48]. -//! -//! // ... do something with xmm0-3 ... -//! -//! // Another way of adjusting memory is to change the operand in-place. -//! // If you want to keep the original operand you can simply clone it. -//! x86::Mem mDst = mSrc.clone(); // Clone mSrc. -//! -//! a.movaps(mDst, x86::xmm0); // Stores xmm0 to [eax]. -//! mDst.addOffset(16); // Adds 16 to `mDst`. -//! -//! a.movaps(mDst, x86::xmm1); // Stores to [eax + 16] . -//! mDst.addOffset(16); // Adds 16 to `mDst`. -//! -//! a.movaps(mDst, x86::xmm2); // Stores to [eax + 32]. -//! mDst.addOffset(16); // Adds 16 to `mDst`. -//! -//! a.movaps(mDst, x86::xmm3); // Stores to [eax + 48]. -//! } -//! ``` -//! -//! ### Assembler Examples -//! -//! - \ref x86::Assembler provides many X86/X64 examples. - -// ============================================================================ -// [Documentation - asmjit_builder] -// ============================================================================ - -//! \defgroup asmjit_builder Builder -//! \brief Builder interface, nodes, and passes. -//! -//! ### Overview -//! -//! Both \ref BaseBuilder and \ref BaseCompiler interfaces describe emitters -//! that emit into a representation that allows further processing. The code -//! stored in such representation is completely safe to be patched, simplified, -//! reordered, obfuscated, removed, injected, analyzed, or processed some other -//! way. Each instruction, label, directive, or other building block is stored -//! as \ref BaseNode (or derived class like \ref InstNode or \ref LabelNode) -//! and contains all the information necessary to pass that node later to the -//! assembler. -//! -//! \ref BaseBuilder is an emitter that inherits from \ref BaseEmitter interface. -//! It was designed to provide a maximum compatibility with the existing \ref -//! BaseAssembler emitter so users can move from assembler to builder when needed, -//! for example to implement post-processing, which is not possible with Assembler. -//! -//! ### Builder Nodes -//! -//! \ref BaseBuilder doesn't generate machine code directly, it uses an intermediate -//! representation based on nodes, however, it allows to serialize to \ref BaseAssembler -//! when the code is ready to be encoded. -//! -//! There are multiple node types used by both \ref BaseBuilder and \ref BaseCompiler : -//! -//! - Basic nodes: -//! - \ref BaseNode - Base class for all nodes. -//! - \ref InstNode - Represents an instruction node. -//! - \ref AlignNode - Represents an alignment directive (.align). -//! - \ref LabelNode - Represents a location where to bound a \ref Label. -//! -//! - Data nodes: -//! - \ref EmbedDataNode - Represents data. -//! - \ref EmbedLabelNode - Represents \ref Label address embedded as data. -//! - \ref EmbedLabelDeltaNode - Represents a difference of two labels -//! embedded in data. -//! - \ref ConstPoolNode - Represents a constant pool data embedded as data. -//! -//! - Informative nodes: -//! - \ref CommentNode - Represents a comment string, doesn't affect code -//! generation. -//! - \ref SentinelNode - A marker that can be used to remember certain -//! position in code or data, doesn't affect code generation. Used by -//! \ref FuncNode to mark the end of a function. -//! -//! - Other nodes are provided by \ref asmjit_compiler infrastructure. -//! -//! ### Builder Examples -//! -//! - \ref x86::Builder provides many X86/X64 examples. - -// ============================================================================ -// [Documentation - asmjit_compiler] -// ============================================================================ - -//! \defgroup asmjit_compiler Compiler -//! \brief Compiler interface. -//! -//! ### Overview -//! -//! \ref BaseCompiler is a high-level interface built on top of \ref BaseBuilder -//! interface, which provides register allocation and support for defining and -//! invoking functions. At the moment it's the easiest way of generating code -//! in AsmJit as most architecture and OS specifics is properly abstracted and -//! handled by AsmJit automatically. However, abstractions also mean restrictions, -//! which means that \ref BaseCompiler has more limitations than \ref BaseAssembler -//! or \ref BaseBuilder. -//! -//! Since \ref BaseCompiler provides register allocation it also establishes the -//! concept of functions - a function in Compiler sense is a unit in which virtual -//! registers are allocated into physical registers by the register allocator. -//! In addition, it enables to use such virtual registers in function invocations. -//! -//! \ref BaseCompiler automatically handles function calling conventions. It's -//! still architecture dependent, but makes the code generation much easies. -//! Functions are essential; the first-step to generate some code is to define a -//! signature of the function to be generated (before generating the function body -//! itself). Function arguments and return value(s) are handled by assigning -//! virtual registers to them. Similarly, function calls are handled the same way. -//! -//! ### Compiler Nodes -//! -//! \ref BaseCompiler adds some nodes that are required for function generation -//! and invocation: -//! -//! - \ref FuncNode - Represents a function definition. -//! - \ref FuncRetNode - Represents a function return. -//! - \ref InvokeNode - Represents a function invocation. -//! -//! \ref BaseCompiler also makes the use of passes (\ref Pass) and automatically -//! adds an architecture-dependent register allocator pass to the list of passes -//! when attached to \ref CodeHolder. -//! -//! ### Compiler Examples -//! -//! - \ref x86::Compiler provides many X86/X64 examples. -//! -//! ### Compiler Tips -//! -//! Users of AsmJit have done mistakes in the past, this section should provide -//! some useful tips for beginners: -//! -//! - Virtual registers in compiler are bound to a single function. At the -//! moment the implementation doesn't care whether a single virtual register -//! is used in multiple functions, but it sees it as two independent virtual -//! registers in that case. This means that virtual registers cannot be used -//! to implement global variables. Global variables are basically memory -//! addresses which functions can read from and write to, and they have to -//! be implemented in the same way. -//! -//! - Compiler provides a useful debugging functionality, which can be turned -//! on through \ref FormatOptions::Flags. Use \ref Logger::addFlags() to -//! turn on additional logging features when using Compiler. - -// ============================================================================ -// [Documentation - asmjit_function] -// ============================================================================ - -//! \defgroup asmjit_function Function -//! \brief Function definitions. -//! -//! ### Overview -//! -//! AsmJit provides functionality that can be used to define function signatures -//! and to calculate automatically optimal function frame that can be used directly -//! by a prolog and epilog insertion. This feature was exclusive to AsmJit's Compiler -//! for a very long time, but was abstracted out and is now available for all users -//! regardless of the emitter they use. The following use cases are possible: -//! -//! - Calculate function frame before the function is generated - this is the -//! only way available to \ref BaseAssembler users and it will be described -//! in this section. -//! -//! - Calculate function frame after the function is generated - this way is -//! generally used by \ref BaseBuilder and \ref BaseCompiler emitters and -//! this way is generally described in \ref asmjit_compiler section. -//! -//! The following concepts are used to describe and create functions in AsmJit: -//! -//! - \ref Type::Id - Type-id is an 8-bit value that describes a platform -//! independent type as we know from C/C++. It provides abstractions for -//! most common types like `int8_t`, `uint32_t`, `uintptr_t`, `float`, -//! `double`, and all possible vector types to match ISAs up to AVX512. -//! \ref Type::Id was introduced originally for \ref asmjit_compiler, but -//! it's now used by \ref FuncSignature as well. -//! -//! - \ref CallConv - Describes a calling convention - this class contains -//! instructions to assign registers and stack addresses to function -//! arguments and return value(s), but doesn't specify any function -//! signature itself. Calling conventions are architecture and OS dependent. -//! -//! - \ref FuncSignature - Describes a function signature, for example -//! `int func(int, int)`. FuncSignature contains a function calling convention -//! id, return value type, and function arguments. The signature itself is -//! platform independent and uses \ref Type::Id to describe types of function -//! arguments and function return value(s). -//! -//! - \ref FuncDetail - Architecture and ABI dependent information that describes -//! \ref CallConv and expanded \ref FuncSignature. Each function argument and -//! return value is represented as \ref FuncValue that contains the original -//! \ref Type::Id enriched with additional information that specifies whether -//! the value is passed or returned by register (and which register) or by -//! stack. Each value also contains some other metadata that provide additional -//! information required to handle it properly (for example whether a vector is -//! passed indirectly by a pointer as required by WIN64 calling convention). -//! -//! - \ref FuncFrame - Contains information about the function frame that can -//! be used by prolog/epilog inserter (PEI). Holds call stack size size and -//! alignment, local stack size and alignment, and various attributes that -//! describe how prolog and epilog should be constructed. `FuncFrame` doesn't -//! know anything about function's arguments or return values, it hold only -//! information necessary to create a valid and ABI conforming function prologs -//! and epilogs. -//! -//! - \ref FuncArgsAssignment - A helper class that can be used to reassign -//! function arguments into user specified registers. It's architecture and -//! ABI dependent mapping from function arguments described by \ref CallConv -//! and \ref FuncDetail into registers specified by the user. -//! -//! It's a lot of concepts where each represents one step in a function frame -//! calculation. It can be used to create function prologs, epilogs, and also -//! to calculate information necessary to perform function calls. - -// ============================================================================ -// [Documentation - asmjit_logging] -// ============================================================================ - -//! \defgroup asmjit_logging Logging -//! \brief Logging and formatting. -//! -//! ### Overview -//! -//! The initial phase of a project that generates machine code is not always smooth. -//! Failure cases are common not just at the beginning phase, but also during the -//! development or refactoring. AsmJit provides logging functionality to address -//! this issue. AsmJit does already a good job with function overloading to prevent -//! from emitting unencodable instructions, but it can't prevent from emitting machine -//! code that is correct at instruction level, but doesn't work when it's executed as -//! a whole. Logging has always been an important part of AsmJit's infrastructure and -//! looking at logs can sometimes reveal code generation issues quickly. -//! -//! AsmJit provides API for logging and formatting: -//! - \ref Logger - A logger that you can pass to \ref CodeHolder and all emitters -//! that inherit from \ref BaseEmitter. -//! - \ref FormatOptions - Formatting options that can change how instructions and -//! operands are formatted. -//! - \ref Formatter - A namespace that provides functions that can format input -//! data like \ref Operand, \ref BaseReg, \ref Label, and \ref BaseNode into -//! \ref String. -//! -//! AsmJit's \ref Logger serves the following purposes: -//! - Provides a basic foundation for logging. -//! - Abstract class leaving the implementation on users. The following built-in -//! inplementations are provided for simplicty: -//! - \ref FileLogger implements logging into a standard `FILE` stream. -//! - \ref StringLogger serializes all logs into a \ref String instance. -//! -//! AsmJit's \ref FormatOptions provides the following to customize the formatting of -//! instructions and operands through: -//! - \ref FormatOptions::Flags -//! - \ref FormatOptions::IndentationType -//! -//! ### Logging -//! -//! A \ref Logger is typically attached to a \ref CodeHolder, which propagates it -//! to all attached emitters automatically. The example below illustrates how to -//! use \ref FileLogger that outputs to standard output: -//! -//! ``` -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! int main() { -//! JitRuntime rt; // Runtime specialized for JIT code execution. -//! FileLogger logger(stdout); // Logger should always survive CodeHolder. -//! -//! CodeHolder code; // Holds code and relocation information. -//! code.init(rt.environment()); // Initialize to the same arch as JIT runtime. -//! code.setLogger(&logger); // Attach the `logger` to `code` holder. -//! -//! // ... code as usual, everything emitted will be logged to `stdout` ... -//! return 0; -//! } -//! ``` -//! -//! If output to FILE stream is not desired it's possible to use \ref StringLogger, -//! which concatenates everything into a multi-line string: -//! -//! ``` -//! #include -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! int main() { -//! JitRuntime rt; // Runtime specialized for JIT code execution. -//! StringLogger logger; // Logger should always survive CodeHolder. -//! -//! CodeHolder code; // Holds code and relocation information. -//! code.init(rt.environment()); // Initialize to the same arch as JIT runtime. -//! code.setLogger(&logger); // Attach the `logger` to `code` holder. -//! -//! // ... code as usual, logging will be concatenated to logger string ... -//! -//! // You can either use the string from StringLogger directly or you can -//! // move it. Logger::data() returns its content as null terminated char[]. -//! printf("Logger content: %s\n", logger.data()); -//! -//! // It can be moved into your own string like this: -//! String content = std::move(logger.content()); -//! printf("The same content: %s\n", content.data()); -//! -//! return 0; -//! } -//! ``` -//! -//! ### Formatting -//! -//! AsmJit uses \ref Formatter to format inputs that are then passed to \ref -//! Logger. Formatting is public and can be used by AsmJit users as well. The -//! most important thing to know regarding formatting is that \ref Formatter -//! always appends to the output string, so it can be used to build complex -//! strings without having to concatenate intermediate strings. -//! -//! The first example illustrates how to format operands: -//! -//! ``` -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! void logOperand(uint32_t arch, const Operand_& op) { -//! // The emitter is optional (named labels and virtual registers need it). -//! BaseEmitter* emitter = nullptr; -//! -//! // No flags by default. -//! uint32_t formatFlags = FormatOptions::kNoFlags; -//! -//! StringTmp<128> sb; -//! Formatter::formatOperand(sb, formatFlags, emitter, arch, op); -//! printf("%s\n", sb.data()); -//! } -//! -//! void formattingExample() { -//! using namespace x86; -//! -//! // Architecture is not part of operand, it must be passed explicitly. -//! // Format flags. We pass it explicitly also to 'logOperand' to make -//! // compatible with what AsmJit normally does. -//! uint32_t arch = Environment::kArchX64; -//! -//! log(arch, rax); // Prints 'rax'. -//! log(arch, ptr(rax, rbx, 2)); // Prints '[rax + rbx * 4]`. -//! log(arch, dword_ptr(rax, rbx, 2)); // Prints 'dword [rax + rbx * 4]`. -//! log(arch, imm(42)); // Prints '42'. -//! } -//! ``` -//! -//! Next example illustrates how to format whole instructions: -//! -//! ``` -//! #include -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! template -//! void logInstruction(uint32_t arch, const BaseInst& inst, Args&&... args) { -//! // The emitter is optional (named labels and virtual registers need it). -//! BaseEmitter* emitter = nullptr; -//! -//! // No flags by default. -//! uint32_t formatFlags = FormatOptions::kNoFlags; -//! -//! // The formatter expects operands in an array. -//! Operand_ operands { std::forward(args)... }; -//! -//! StringTmp<128> sb; -//! Formatter::formatInstruction( -//! sb, formatFlags, emitter, arch, inst, operands, sizeof...(args)); -//! printf("%s\n", sb.data()); -//! } -//! -//! void formattingExample() { -//! using namespace x86; -//! -//! // Architecture is not part of operand, it must be passed explicitly. -//! // Format flags. We pass it explicitly also to 'logOperand' to make -//! // compatible with what AsmJit normally does. -//! uint32_t arch = Environment::kArchX64; -//! -//! // Prints 'mov rax, rcx'. -//! logInstruction(arch, BaseInst(Inst::kIdMov), rax, rcx); -//! -//! // Prints 'vaddpd zmm0, zmm1, [rax] {1to8}'. -//! logInstruction(arch, -//! BaseInst(Inst::kIdVaddpd), -//! zmm0, zmm1, ptr(rax)._1toN()); -//! -//! // BaseInst abstracts instruction id, instruction options, and extraReg. -//! // Prints 'lock add [rax], rcx'. -//! logInstruction(arch, -//! BaseInst(Inst::kIdAdd, Inst::kOptionLock), -//! x86::ptr(rax), rcx); -//! -//! // Similarly an extra register (like AVX-512 selector) can be used. -//! // Prints 'vaddpd zmm0 {k2} {z}, zmm1, [rax]'. -//! logInstruction(arch, -//! BaseInst(Inst::kIdAdd, Inst::kOptionZMask, k2), -//! zmm0, zmm1, ptr(rax)); -//! } -//! ``` -//! -//! And finally, the example below illustrates how to use a built-in function -//! to format the content of \ref BaseBuilder, which consists of nodes: -//! -//! ``` -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! void formattingExample(BaseBuilder* builder) { -//! uint32_t formatFlags = FormatOptions::kNoFlags; -//! -//! // This also shows how temporary strings can be used. -//! StringTmp<512> sb; -//! -//! // FormatNodeList requires the String for output, formatting flags, which -//! // were zero (no extra flags), and the builder instance, which we have -//! // provided. An overloaded version also exists, which accepts begin and -//! // and end nodes, which can be used to only format a range of nodes. -//! Formatter::formatNodeList(sb, formatFlags, builder); -//! -//! // You can do whatever else with the string, it's always null terminated, -//! // so it can be passed to C functions like printf(). -//! printf("%s\n", sb.data()); -//! } -//! ``` - -// ============================================================================ -// [Documentation - asmjit_error_handling] -// ============================================================================ - -//! \defgroup asmjit_error_handling Error Handling -//! \brief Error handling. -//! -//! ### Overview -//! -//! AsmJit uses error codes to represent and return errors. Every function that -//! can fail returns an \ref Error code. Exceptions are never thrown by AsmJit -//! itself even in extreme conditions like out-of-memory, but it's possible to -//! override \ref ErrorHandler::handleError() to throw, in that case no error -//! will be returned and exception will be thrown instead. All functions where -//! this can happen are not marked `noexcept`. -//! -//! Errors should never be ignored, however, checking errors after each AsmJit -//! API call would simply overcomplicate the whole code generation experience. -//! \ref ErrorHandler exists to make the use of AsmJit API simpler as it allows -//! to customize how errors can be handled: -//! -//! - Record the error and continue (the way how the error is user-implemented). -//! - Throw an exception. AsmJit doesn't use exceptions and is completely -//! exception-safe, but it's perfectly legal to throw an exception from -//! the error handler. -//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler, -//! Builder and Compiler to a consistent state before calling \ref -//! ErrorHandler::handleError(), so `longjmp()` can be used without issues to -//! cancel the code-generation if an error occurred. This method can be used if -//! exception handling in your project is turned off and you still want some -//! comfort. In most cases it should be safe as AsmJit uses \ref Zone memory -//! and the ownership of memory it allocates always ends with the instance that -//! allocated it. If using this approach please never jump outside the life-time -//! of \ref CodeHolder and \ref BaseEmitter. -//! -//! ### Using ErrorHandler -//! -//! An example of attaching \ref ErrorHandler to \ref CodeHolder. -//! -//! ``` -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! // A simple error handler implementation, extend according to your needs. -//! class MyErrorHandler : public ErrorHandler { -//! public: -//! void handleError(Error err, const char* message, BaseEmitter* origin) override { -//! printf("AsmJit error: %s\n", message); -//! } -//! }; -//! -//! int main() { -//! JitRuntime rt; -//! -//! MyErrorHandler myErrorHandler; -//! CodeHolder code; -//! -//! code.init(rt.environment()); -//! code.setErrorHandler(&myErrorHandler); -//! -//! x86::Assembler a(&code); -//! // ... code generation ... -//! -//! return 0; -//! } -//! ``` -//! -//! Useful classes in error handling group: -//! -//! - See \ref DebugUtils that provides utilities useful for debugging. -//! - See \ref Error that lists error codes that AsmJit uses. -//! - See \ref ErrorHandler for more details about error handling. - -// ============================================================================ -// [Documentation - asmjit_instruction_db] -// ============================================================================ - -//! \defgroup asmjit_instruction_db Instruction DB -//! \brief Instruction database (introspection, read/write, validation, ...). -//! -//! ### Overview -//! -//! AsmJit provides a public instruction database that can be used to query -//! information about a complete instruction. The instruction database requires -//! the knowledge of the following: -//! -//! - \ref BaseInst - Base instruction that contains instruction id, options, -//! and a possible extra-register that represents either REP prefix counter -//! or AVX-512 selector (mask). -//! - \ref Operand - Represents operands of an instruction. -//! -//! Each instruction can be then queried for the following information: -//! -//! - \ref InstRWInfo - Read/write information of instruction and its oprands. -//! - \ref OpRWInfo - Read/write information of a single operand, part of -//! \ref InstRWInfo data structure. -//! - \ref BaseFeatures - CPU features required to execute the instruction. -//! -//! In addition to query functionality AsmJit is also able to validate whether -//! an instruction and its operands are valid. This is useful for making sure -//! that what user tries to emit is correct and it can be also used by other -//! projects that parse user input, like AsmTK project. -//! -//! ### Query API -//! -//! The instruction query API is provided by \ref InstAPI namespace. The -//! following queries are possible: -//! -//! - \ref InstAPI::queryRWInfo() - queries read/write information of the -//! given instruction and its operands. Includes also CPU flags read/written. -//! -//! - \ref InstAPI::queryFeatures() - queries CPU features that are required -//! to execute the given instruction. A full instruction with operands must -//! be given as some architectures like X86 may require different features -//! for the same instruction based on its operands. -//! -//! - asmjit_test_x86_instinfo.cpp -//! can be also used as a reference about accessing instruction information. -//! -//! ### Validation API -//! -//! The instruction validation API is provided by \ref InstAPI namespace in the -//! similar fashion like the Query API, however, validation can also be turned -//! on at \ref BaseEmitter level. The following is possible: -//! -//! - \ref InstAPI::validate() - low-level instruction validation function -//! that is used internally by emitters if strict validation is enabled. -//! -//! - \ref BaseEmitter::addValidationOptions() - can be used to enable -//! validation at emitter level, see \ref BaseEmitter::ValidationOptions. - - -// ============================================================================ -// [Documentation - asmjit_virtual_memory] -// ============================================================================ - -//! \defgroup asmjit_virtual_memory Virtual Memory -//! \brief Virtual memory management. -//! -//! ### Overview -//! -//! AsmJit's virtual memory management is divided into two main categories: -//! -//! - Low level API that provides cross-platform abstractions for virtual -//! memory allocation. Implemented in \ref VirtMem namespace. -//! - High level API that makes it very easy to store generated code for -//! execution. See \ref JitRuntime, which is used by many examples for its -//! simplicity and easy integration with \ref CodeHolder. There is also -//! \ref JitAllocator, which lays somewhere between RAW memory allocation -//! and \ref JitRuntime. - -// ============================================================================ -// [Documentation - asmjit_zone_memory] -// ============================================================================ - -//! \defgroup asmjit_zone Zone Memory -//! \brief Zone memory allocator and containers. -//! -//! ### Overview -//! -//! AsmJit uses zone memory allocation (also known as Arena allocation) to allocate -//! most of the data it uses. It's a fast allocator that allows AsmJit to allocate -//! a lot of small data structures fast and without `malloc()` overhead. Since -//! code generators and all related classes are usually short-lived this approach -//! decreases memory usage and fragmentation as arena-based allocators always -//! allocate larger blocks of memory, which are then split into smaller chunks. -//! -//! Another advantage of zone memory allocation is that since the whole library -//! uses this strategy it's very easy to deallocate everything that a particular -//! instance is holding by simply releasing the memory the allocator holds. This -//! improves destruction time of such objects as there is no destruction at all. -//! Long-lived objects just reset its data in destructor or in their reset() -//! member function for a future reuse. For this purpose all containers in AsmJit -//! are also zone allocated. -//! -//! ### Zone Allocation -//! -//! - \ref Zone - Incremental zone memory allocator with minimum features. It -//! can only allocate memory without the possibility to return it back to -//! the allocator. -//! -//! - \ref ZoneTmp - A temporary \ref Zone with some initial static storage. -//! If the allocation requests fit the static storage allocated then there -//! will be no dynamic memory allocation during the lifetime of \ref ZoneTmp, -//! otherwise it would act as \ref Zone with one preallocated block on the -//! stack. -//! -//! - \ref ZoneAllocator - A wrapper of \ref Zone that provides the capability -//! of returning memory to the allocator. Such memory is stored in a pool for -//! later reuse. -//! -//! ### Zone Allocated Containers -//! -//! - \ref ZoneString - Zone allocated string. -//! - \ref ZoneHash - Zone allocated hash table. -//! - \ref ZoneTree - Zone allocated red-black tree. -//! - \ref ZoneList - Zone allocated double-linked list. -//! - \ref ZoneStack - Zone allocated stack. -//! - \ref ZoneVector - Zone allocated vector. -//! - \ref ZoneBitVector - Zone allocated vector of bits. -//! -//! ### Using Zone Allocated Containers -//! -//! The most common data structure exposed by AsmJit is \ref ZoneVector. It's very -//! similar to `std::vector`, but the implementation doesn't use exceptions and -//! uses the mentioned \ref ZoneAllocator for performance reasons. You don't have -//! to worry about allocations as you should not need to add items to AsmJit's -//! data structures directly as there should be API for all required operations. -//! -//! The following APIs in \ref CodeHolder returns \ref ZoneVector reference: -//! -//! ``` -//! using namespace asmjit; -//! -//! void example(CodeHolder& code) { -//! // Contains all emitters attached to CodeHolder. -//! const ZoneVector& emitters = code.emitters(); -//! -//! // Contains all section entries managed by CodeHolder. -//! const ZoneVector& sections = code.sections(); -//! -//! // Contains all label entries managed by CodeHolder. -//! const ZoneVector& labelEntries = code.labelEntries(); -//! -//! // Contains all relocation entries managed by CodeHolder. -//! const ZoneVector& relocEntries = code.relocEntries(); -//! } -//! ``` -//! -//! \ref ZoneVector has overloaded array access operator to make it possible -//! to access its elements through operator[]. Some standard functions like -//! \ref ZoneVector::empty(), \ref ZoneVector::size(), and \ref ZoneVector::data() -//! are provided as well. Vectors are also iterable through a range-based for loop: -//! -//! ``` -//! using namespace asmjit; -//! -//! void example(CodeHolder& code) { -//! for (LabelEntry* le : code.labelEntries()) { -//! printf("Label #%u {Bound=%s Offset=%llu}", -//! le->id(), -//! le->isBound() ? "true" : "false", -//! (unsigned long long)le->offset()); -//! } -//! } -//! ``` -//! -//! ### Design Considerations -//! -//! Zone-allocated containers do not store the allocator within the container. -//! This decision was made to reduce the footprint of such containers as AsmJit -//! tooling, especially Compiler's register allocation, may use many instances -//! of such containers to perform code analysis and register allocation. -//! -//! For example to append an item into a \ref ZoneVector it's required to pass -//! the allocator as the first argument, so it can be used in case that the -//! vector needs a reallocation. Such function also returns an error, which -//! must be propagated to the caller. -//! -//! ``` -//! using namespace asmjit -//! -//! Error example(ZoneAllocator* allocator) { -//! ZoneVector vector; -//! -//! // Unfortunately, allocator must be provided to all functions that mutate -//! // the vector. However, AsmJit users should never need to do this as all -//! // manipulation should be done through public API, which takes care of -//! // that. -//! for (int i = 0; i < 100; i++) { -//! ASMJIT_PROPAGATE(vector.append(allocator, i)); -//! } -//! -//! // By default vector's destructor doesn't release anything as it knows -//! // that its content is zone allocated. However, \ref ZoneVector::release -//! // can be used to explicitly release the vector data to the allocator if -//! // necessary -//! vector.release(allocator); -//! } -//! ``` -//! -//! Containers like \ref ZoneVector also provide a functionality to reserve a -//! certain number of items before any items are added to it. This approach is -//! used internally in most places as it allows to prepare space for data that -//! will be added to some container before the data itself was created. -//! -//! ``` -//! using namespace asmjit -//! -//! Error example(ZoneAllocator* allocator) { -//! ZoneVector vector; -//! -//! ASMJIT_PROPAGATE(vector.willGrow(100)); -//! for (int i = 0; i < 100; i++) { -//! // Cannot fail. -//! vector.appendUnsafe(allocator, i); -//! } -//! -//! vector.release(allocator); -//! } -//! ``` - -// ============================================================================ -// [Documentation - asmjit_utilities] -// ============================================================================ - -//! \defgroup asmjit_utilities Utilities -//! \brief Utility classes and functions. -//! -//! ### Overview -//! -//! AsmJit uses and provides utility classes and functions, that can be used -//! with AsmJit. The functionality can be divided into the following topics: -//! -//! ### String Functionality -//! -//! - \ref String - AsmJit's string container, which is used internally -//! and which doesn't use exceptions and has a stable layout, which is -//! not dependent on C++ standard library. -//! - \ref StringTmp - String that can have base storage allocated on -//! stack. The amount of storage on stack can be specified as a template -//! parameter. -//! - \ref FixedString - Fixed string container limited up to N characters. -//! -//! ### Code Generation Utilities -//! -//! - \ref ConstPool - Constant pool used by \ref BaseCompiler, but also -//! available to users that may find use of it. -//! -//! ### Support Functionality Used by AsmJit -//! -//! - \ref Support namespace provides many other utility functions and -//! classes that are used by AsmJit, and made public. - -// ============================================================================ -// [Documentation - asmjit_ backends] -// ============================================================================ - -//! \defgroup asmjit_x86 X86 Backend -//! \brief X86/X64 backend. - -// ============================================================================ -// [Documentation - asmjit_ra] -// ============================================================================ - -//! \cond INTERNAL -//! \defgroup asmjit_ra RA -//! \brief Register allocator internals. -//! \endcond - -} // {asmjit} - -// ============================================================================ -// [Core Headers] -// ============================================================================ - -#include "asmjit-scope-begin.h" -#include "core/archtraits.h" -#include "core/assembler.h" -#include "core/builder.h" -#include "core/codeholder.h" -#include "core/compiler.h" -#include "core/constpool.h" -#include "core/cpuinfo.h" -#include "core/datatypes.h" -#include "core/emitter.h" -#include "core/environment.h" -#include "core/errorhandler.h" -#include "core/features.h" -#include "core/formatter.h" -#include "core/func.h" -#include "core/globals.h" -#include "core/inst.h" -#include "core/jitallocator.h" -#include "core/jitruntime.h" -#include "core/logger.h" -#include "core/operand.h" -#include "core/osutils.h" -#include "core/string.h" -#include "core/support.h" -#include "core/target.h" -#include "core/type.h" -#include "core/virtmem.h" -#include "core/zone.h" -#include "core/zonehash.h" -#include "core/zonelist.h" -#include "core/zonetree.h" -#include "core/zonestack.h" -#include "core/zonestring.h" -#include "core/zonevector.h" -#include "asmjit-scope-end.h" - -// ============================================================================ -// [Deprecated] -// ============================================================================ - -#ifndef ASMJIT_NO_DEPRECATED -namespace asmjit { - -#ifndef ASMJIT_NO_COMPILER -ASMJIT_DEPRECATED("Use InvokeNode instead of FuncCallNode") -typedef InvokeNode FuncCallNode; -#endif // !ASMJIT_NO_COMPILER - -#ifndef ASMJIT_NO_LOGGING -namespace Logging { using namespace Formatter; } -#endif //! ASMJIT_NO_LOGGING - -} // {asmjit} -#endif // !ASMJIT_NO_DEPRECATED - -#endif // ASMJIT_CORE_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/api-build_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/api-build_p.h deleted file mode 100644 index db37ca7..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/api-build_p.h +++ /dev/null @@ -1,77 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_API_BUILD_P_H_INCLUDED -#define ASMJIT_CORE_API_BUILD_P_H_INCLUDED - -#define ASMJIT_EXPORTS - -// Only turn-off these warnings when building asmjit itself. -#ifdef _MSC_VER - #ifndef _CRT_SECURE_NO_DEPRECATE - #define _CRT_SECURE_NO_DEPRECATE - #endif - #ifndef _CRT_SECURE_NO_WARNINGS - #define _CRT_SECURE_NO_WARNINGS - #endif -#endif - -// Dependencies only required for asmjit build, but never exposed through public headers. -#ifdef _WIN32 - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - #ifndef NOMINMAX - #define NOMINMAX - #endif - #include -#endif - -// ============================================================================ -// [asmjit::Build - Globals - Build-Only] -// ============================================================================ - -#include "./api-config.h" - -#if !defined(ASMJIT_BUILD_DEBUG) && defined(__GNUC__) && !defined(__clang__) - #define ASMJIT_FAVOR_SIZE __attribute__((__optimize__("Os"))) - #define ASMJIT_FAVOR_SPEED __attribute__((__optimize__("O3"))) -#elif ASMJIT_CXX_HAS_ATTRIBUTE(__minsize__, 0) - #define ASMJIT_FAVOR_SIZE __attribute__((__minsize__)) - #define ASMJIT_FAVOR_SPEED -#else - #define ASMJIT_FAVOR_SIZE - #define ASMJIT_FAVOR_SPEED -#endif - -// Make sure '#ifdef'ed unit tests are properly highlighted in IDE. -#if !defined(ASMJIT_TEST) && defined(__INTELLISENSE__) - #define ASMJIT_TEST -#endif - -// Include a unit testing package if this is a `asmjit_test_unit` build. -#if defined(ASMJIT_TEST) - #include "../../../test/broken.h" -#endif - -#endif // ASMJIT_CORE_API_BUILD_P_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/api-config.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/api-config.h deleted file mode 100644 index aab3473..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/api-config.h +++ /dev/null @@ -1,552 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_API_CONFIG_H_INCLUDED -#define ASMJIT_CORE_API_CONFIG_H_INCLUDED - -// ============================================================================ -// [asmjit::Version] -// ============================================================================ - -//! \addtogroup asmjit_core -//! \{ - -//! AsmJit library version in `(Major << 16) | (Minor << 8) | (Patch)` format. -#define ASMJIT_LIBRARY_VERSION 0x010400 /* 1.4.0 */ - -//! \} - -// ============================================================================ -// [asmjit::Build - Documentation] -// ============================================================================ - -// NOTE: Doxygen cannot document macros that are not defined, that's why we have -// to define them and then undefine them, so it won't use the macros with its -// own preprocessor. -#ifdef _DOXYGEN -namespace asmjit { - -//! \addtogroup asmjit_build -//! \{ - -//! Asmjit is embedded, implies \ref ASMJIT_STATIC. -#define ASMJIT_EMBED - -//! Enables static-library build. -#define ASMJIT_STATIC - -//! Defined when AsmJit's build configuration is 'Debug'. -//! -//! \note Can be defined explicitly to bypass autodetection. -#define ASMJIT_BUILD_DEBUG - -//! Defined when AsmJit's build configuration is 'Release'. -//! -//! \note Can be defined explicitly to bypass autodetection. -#define ASMJIT_BUILD_RELEASE - -//! Defined to build X86/X64 backend. -#define ASMJIT_BUILD_X86 - -//! Defined to build host backend autodetected at compile-time. -#define ASMJIT_BUILD_HOST - -//! Disables deprecated API at compile time. -#define ASMJIT_NO_DEPRECATED - -//! Disable non-host architectures entirely. -#define ASMJIT_NO_FOREIGN - -//! Disables \ref asmjit_builder functionality completely. -#define ASMJIT_NO_BUILDER - -//! Disables \ref asmjit_compiler functionality completely. -#define ASMJIT_NO_COMPILER - -//! Disables JIT memory management and \ref JitRuntime. -#define ASMJIT_NO_JIT - -//! Disables \ref Logger and \ref Formatter. -#define ASMJIT_NO_LOGGING - -//! Disables everything that contains text. -#define ASMJIT_NO_TEXT - -//! Disables instruction validation API. -#define ASMJIT_NO_VALIDATION - -//! Disables instruction introspection API. -#define ASMJIT_NO_INTROSPECTION - -// Avoid doxygen preprocessor using feature-selection definitions. -#undef ASMJIT_NO_BUILDER -#undef ASMJIT_NO_COMPILER -#undef ASMJIT_NO_JIT -#undef ASMJIT_NO_LOGGING -#undef ASMJIT_NO_TEXT -#undef ASMJIT_NO_VALIDATION -#undef ASMJIT_NO_INTROSPECTION - -//! \} - -} // {asmjit} -#endif // _DOXYGEN - -// Enable all features at IDE level, so it's properly highlighted and indexed. -#ifdef __INTELLISENSE__ - #ifndef ASMJIT_BUILD_X86 - #define ASMJIT_BUILD_X86 - #endif -#endif - -// ============================================================================ -// [asmjit::Dependencies] -// ============================================================================ - -// We really want std-types as globals. -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) - #include -#endif - - -// ============================================================================ -// [asmjit::Options] -// ============================================================================ - -// ASMJIT_NO_BUILDER implies ASMJIT_NO_COMPILER. -#if defined(ASMJIT_NO_BUILDER) && !defined(ASMJIT_NO_COMPILER) - #define ASMJIT_NO_COMPILER -#endif - -// Prevent compile-time errors caused by misconfiguration. -#if defined(ASMJIT_NO_TEXT) && !defined(ASMJIT_NO_LOGGING) - #pragma "ASMJIT_NO_TEXT can only be defined when ASMJIT_NO_LOGGING is defined." - #undef ASMJIT_NO_TEXT -#endif - -#if defined(ASMJIT_NO_INTROSPECTION) && !defined(ASMJIT_NO_COMPILER) - #pragma message("ASMJIT_NO_INTROSPECTION can only be defined when ASMJIT_NO_COMPILER is defined") - #undef ASMJIT_NO_INTROSPECTION -#endif - -// ============================================================================ -// [asmjit::Build - Globals - Deprecated] -// ============================================================================ - -#ifndef ASMJIT_NO_DEPRECATED - #if defined(ASMJIT_BUILD_EMBED) || defined(ASMJIT_BUILD_STATIC) - #if defined(ASMJIT_BUILD_EMBED) - #pragma message("'ASMJIT_BUILD_EMBED' is deprecated, use 'ASMJIT_STATIC'") - #endif - #if defined(ASMJIT_BUILD_STATIC) - #pragma message("'ASMJIT_BUILD_STATIC' is deprecated, use 'ASMJIT_STATIC'") - #endif - - #if !defined(ASMJIT_STATIC) - #define ASMJIT_STATIC - #endif - #endif -#endif // !ASMJIT_NO_DEPRECATED - -// ============================================================================ -// [asmjit::Build - Globals - Build Mode] -// ============================================================================ - -// Detect ASMJIT_BUILD_DEBUG and ASMJIT_BUILD_RELEASE if not defined. -#if !defined(ASMJIT_BUILD_DEBUG) && !defined(ASMJIT_BUILD_RELEASE) - #if !defined(NDEBUG) - #define ASMJIT_BUILD_DEBUG - #else - #define ASMJIT_BUILD_RELEASE - #endif -#endif - -// ============================================================================ -// [asmjit::Build - Globals - Target Architecture Information] -// ============================================================================ - -#if defined(_M_X64) || defined(__x86_64__) - #define ASMJIT_ARCH_X86 64 -#elif defined(_M_IX86) || defined(__X86__) || defined(__i386__) - #define ASMJIT_ARCH_X86 32 -#else - #define ASMJIT_ARCH_X86 0 -#endif - -#if defined(__arm64__) || defined(__aarch64__) -# define ASMJIT_ARCH_ARM 64 -#elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__) || defined(__thumb2__) - #define ASMJIT_ARCH_ARM 32 -#else - #define ASMJIT_ARCH_ARM 0 -#endif - -#if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) - #define ASMJIT_ARCH_MIPS 64 -#elif defined(_MIPS_ARCH_MIPS32) || defined(_M_MRX000) || defined(__mips__) - #define ASMJIT_ARCH_MIPS 32 -#else - #define ASMJIT_ARCH_MIPS 0 -#endif - -#define ASMJIT_ARCH_BITS (ASMJIT_ARCH_X86 | ASMJIT_ARCH_ARM | ASMJIT_ARCH_MIPS) -#if ASMJIT_ARCH_BITS == 0 - #undef ASMJIT_ARCH_BITS - #if defined (__LP64__) || defined(_LP64) - #define ASMJIT_ARCH_BITS 64 - #else - #define ASMJIT_ARCH_BITS 32 - #endif -#endif - -#if (defined(__ARMEB__)) || \ - (defined(__MIPSEB__)) || \ - (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) - #define ASMJIT_ARCH_LE 0 - #define ASMJIT_ARCH_BE 1 -#else - #define ASMJIT_ARCH_LE 1 - #define ASMJIT_ARCH_BE 0 -#endif - -// ============================================================================ -// [asmjit::Build - Globals - Build Architectures Definitions] -// ============================================================================ - -#if !defined(ASMJIT_NO_FOREIGN) - // If 'ASMJIT_NO_FOREIGN' is not defined then all architectures will be built. - #if !defined(ASMJIT_BUILD_X86) - #define ASMJIT_BUILD_X86 - #endif -#else - // Detect architectures to build if building only for the host architecture. - #if ASMJIT_ARCH_X86 && !defined(ASMJIT_BUILD_X86) - #define ASMJIT_BUILD_X86 - #endif -#endif - -// Define 'ASMJIT_BUILD_HOST' if we know that host architecture will be built. -#if !defined(ASMJIT_BUILD_HOST) && ASMJIT_ARCH_X86 && defined(ASMJIT_BUILD_X86) - #define ASMJIT_BUILD_HOST -#endif - -// ============================================================================ -// [asmjit::Build - Globals - C++ Compiler and Features Detection] -// ============================================================================ - -#define ASMJIT_CXX_GNU 0 -#define ASMJIT_CXX_MAKE_VER(MAJOR, MINOR) ((MAJOR) * 1000 + (MINOR)) - -// Intel Compiler [pretends to be GNU or MSC, so it must be checked first]: -// - https://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler -// - https://software.intel.com/en-us/articles/c14-features-supported-by-intel-c-compiler -// - https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler -#if defined(__INTEL_COMPILER) - -// MSC Compiler: -// - https://msdn.microsoft.com/en-us/library/hh567368.aspx -// -// Version List: -// - 16.00.0 == VS2010 -// - 17.00.0 == VS2012 -// - 18.00.0 == VS2013 -// - 19.00.0 == VS2015 -// - 19.10.0 == VS2017 -#elif defined(_MSC_VER) && defined(_MSC_FULL_VER) - -// Clang Compiler [Pretends to be GNU, so it must be checked before]: -// - https://clang.llvm.org/cxx_status.html -#elif defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) - -// GNU Compiler: -// - https://gcc.gnu.org/projects/cxx-status.html -#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) - - #undef ASMJIT_CXX_GNU - #define ASMJIT_CXX_GNU ASMJIT_CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__) - -#endif - -// Compiler features detection macros. -#if defined(__clang__) && defined(__has_attribute) - #define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (__has_attribute(NAME)) -#else - #define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (!(!(CHECK))) -#endif - -// ============================================================================ -// [asmjit::Build - Globals - API Decorators & Language Extensions] -// ============================================================================ - -// API (Export / Import). -#if !defined(ASMJIT_STATIC) - #if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__)) - #ifdef ASMJIT_EXPORTS - #define ASMJIT_API __declspec(dllexport) - #else - #define ASMJIT_API __declspec(dllimport) - #endif - #elif defined(_WIN32) && defined(__GNUC__) - #ifdef ASMJIT_EXPORTS - #define ASMJIT_API __attribute__((__dllexport__)) - #else - #define ASMJIT_API __attribute__((__dllimport__)) - #endif - #elif defined(__GNUC__) - #define ASMJIT_API __attribute__((__visibility__("default"))) - #endif -#endif - -#if !defined(ASMJIT_API) - #define ASMJIT_API -#endif - -#if !defined(ASMJIT_VARAPI) - #define ASMJIT_VARAPI extern ASMJIT_API -#endif - -// This is basically a workaround. When using MSVC and marking class as DLL -// export everything gets exported, which is unwanted in most projects. MSVC -// automatically exports typeinfo and vtable if at least one symbol of the -// class is exported. However, GCC has some strange behavior that even if -// one or more symbol is exported it doesn't export typeinfo unless the -// class itself is decorated with "visibility(default)" (i.e. ASMJIT_API). -#if !defined(_WIN32) && defined(__GNUC__) - #define ASMJIT_VIRTAPI ASMJIT_API -#else - #define ASMJIT_VIRTAPI -#endif - -// Function attributes. -#if !defined(ASMJIT_BUILD_DEBUG) && defined(__GNUC__) - #define ASMJIT_INLINE inline __attribute__((__always_inline__)) -#elif !defined(ASMJIT_BUILD_DEBUG) && defined(_MSC_VER) - #define ASMJIT_INLINE __forceinline -#else - #define ASMJIT_INLINE inline -#endif - -#if defined(__GNUC__) - #define ASMJIT_NOINLINE __attribute__((__noinline__)) - #define ASMJIT_NORETURN __attribute__((__noreturn__)) -#elif defined(_MSC_VER) - #define ASMJIT_NOINLINE __declspec(noinline) - #define ASMJIT_NORETURN __declspec(noreturn) -#else - #define ASMJIT_NOINLINE - #define ASMJIT_NORETURN -#endif - -// Calling conventions. -#if ASMJIT_ARCH_X86 == 32 && defined(__GNUC__) - #define ASMJIT_CDECL __attribute__((__cdecl__)) - #define ASMJIT_STDCALL __attribute__((__stdcall__)) - #define ASMJIT_FASTCALL __attribute__((__fastcall__)) - #define ASMJIT_REGPARM(N) __attribute__((__regparm__(N))) -#elif ASMJIT_ARCH_X86 == 32 && defined(_MSC_VER) - #define ASMJIT_CDECL __cdecl - #define ASMJIT_STDCALL __stdcall - #define ASMJIT_FASTCALL __fastcall - #define ASMJIT_REGPARM(N) -#else - #define ASMJIT_CDECL - #define ASMJIT_STDCALL - #define ASMJIT_FASTCALL - #define ASMJIT_REGPARM(N) -#endif - -#if ASMJIT_ARCH_X86 && defined(_WIN32) && defined(_MSC_VER) - #define ASMJIT_VECTORCALL __vectorcall -#elif ASMJIT_ARCH_X86 && defined(_WIN32) - #define ASMJIT_VECTORCALL __attribute__((__vectorcall__)) -#else - #define ASMJIT_VECTORCALL -#endif - - -// Type alignment (not allowed by C++11 'alignas' keyword). -#if defined(__GNUC__) - #define ASMJIT_ALIGN_TYPE(TYPE, N) __attribute__((__aligned__(N))) TYPE -#elif defined(_MSC_VER) - #define ASMJIT_ALIGN_TYPE(TYPE, N) __declspec(align(N)) TYPE -#else - #define ASMJIT_ALIGN_TYPE(TYPE, N) TYPE -#endif - -//! \def ASMJIT_MAY_ALIAS -//! -//! Expands to `__attribute__((__may_alias__))` if supported. -#if defined(__GNUC__) - #define ASMJIT_MAY_ALIAS __attribute__((__may_alias__)) -#else - #define ASMJIT_MAY_ALIAS -#endif - -//! \def ASMJIT_LIKELY(...) -//! -//! Condition is likely to be taken (mostly error handling and edge cases). - -//! \def ASMJIT_UNLIKELY(...) -//! -//! Condition is unlikely to be taken (mostly error handling and edge cases). -#if defined(__GNUC__) - #define ASMJIT_LIKELY(...) __builtin_expect(!!(__VA_ARGS__), 1) - #define ASMJIT_UNLIKELY(...) __builtin_expect(!!(__VA_ARGS__), 0) -#else - #define ASMJIT_LIKELY(...) (__VA_ARGS__) - #define ASMJIT_UNLIKELY(...) (__VA_ARGS__) -#endif - -//! \def ASMJIT_FALLTHROUGH -//! -//! Portable [[fallthrough]] attribute. -#if defined(__clang__) && __cplusplus >= 201103L - #define ASMJIT_FALLTHROUGH [[clang::fallthrough]] -#elif defined(__GNUC__) && __GNUC__ >= 7 - #define ASMJIT_FALLTHROUGH __attribute__((__fallthrough__)) -#else - #define ASMJIT_FALLTHROUGH ((void)0) /* fallthrough */ -#endif - -//! \def ASMJIT_DEPRECATED -//! -//! Marks function, class, struct, enum, or anything else as deprecated. -#if defined(__GNUC__) - #define ASMJIT_DEPRECATED(MESSAGE) __attribute__((__deprecated__(MESSAGE))) - #if defined(__clang__) - #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) __attribute__((__deprecated__(MESSAGE))) - #else - #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) /* not usable if a deprecated function uses it */ - #endif -#elif defined(_MSC_VER) - #define ASMJIT_DEPRECATED(MESSAGE) __declspec(deprecated(MESSAGE)) - #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) /* not usable if a deprecated function uses it */ -#else - #define ASMJIT_DEPRECATED(MESSAGE) - #define ASMJIT_DEPRECATED_STRUCT(MESSAGE) -#endif - -// Utilities. -#define ASMJIT_OFFSET_OF(STRUCT, MEMBER) ((int)(intptr_t)((const char*)&((const STRUCT*)0x100)->MEMBER) - 0x100) -#define ASMJIT_ARRAY_SIZE(X) uint32_t(sizeof(X) / sizeof(X[0])) - -#if ASMJIT_CXX_HAS_ATTRIBUTE(no_sanitize, 0) - #define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize__("undefined"))) -#elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 9) - #define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize_undefined__)) -#else - #define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF -#endif - -// ============================================================================ -// [asmjit::Build - Globals - Begin-Namespace / End-Namespace] -// ============================================================================ - -#if defined(__clang__) - #define ASMJIT_BEGIN_NAMESPACE \ - namespace asmjit { \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wconstant-logical-operand\"") \ - _Pragma("clang diagnostic ignored \"-Wunnamed-type-template-args\"") - #define ASMJIT_END_NAMESPACE \ - _Pragma("clang diagnostic pop") \ - } -#elif defined(__GNUC__) && __GNUC__ == 4 - #define ASMJIT_BEGIN_NAMESPACE \ - namespace asmjit { \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") - #define ASMJIT_END_NAMESPACE \ - _Pragma("GCC diagnostic pop") \ - } -#elif defined(__GNUC__) && __GNUC__ >= 8 - #define ASMJIT_BEGIN_NAMESPACE \ - namespace asmjit { \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wclass-memaccess\"") - #define ASMJIT_END_NAMESPACE \ - _Pragma("GCC diagnostic pop") \ - } -#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) - #define ASMJIT_BEGIN_NAMESPACE \ - namespace asmjit { \ - __pragma(warning(push)) \ - __pragma(warning(disable: 4127)) /* conditional expression is const */ \ - __pragma(warning(disable: 4201)) /* nameless struct/union */ - #define ASMJIT_END_NAMESPACE \ - __pragma(warning(pop)) \ - } -#endif - -#if !defined(ASMJIT_BEGIN_NAMESPACE) && !defined(ASMJIT_END_NAMESPACE) - #define ASMJIT_BEGIN_NAMESPACE namespace asmjit { - #define ASMJIT_END_NAMESPACE } -#endif - -#define ASMJIT_BEGIN_SUB_NAMESPACE(NAMESPACE) \ - ASMJIT_BEGIN_NAMESPACE \ - namespace NAMESPACE { - -#define ASMJIT_END_SUB_NAMESPACE \ - } \ - ASMJIT_END_NAMESPACE - -// ============================================================================ -// [asmjit::Build - Globals - Utilities] -// ============================================================================ - -#define ASMJIT_NONCOPYABLE(...) \ - private: \ - __VA_ARGS__(const __VA_ARGS__& other) = delete; \ - __VA_ARGS__& operator=(const __VA_ARGS__& other) = delete; \ - public: - -#define ASMJIT_NONCONSTRUCTIBLE(...) \ - private: \ - __VA_ARGS__() = delete; \ - __VA_ARGS__(const __VA_ARGS__& other) = delete; \ - __VA_ARGS__& operator=(const __VA_ARGS__& other) = delete; \ - public: - -// ============================================================================ -// [asmjit::Build - Globals - Cleanup] -// ============================================================================ - -// Cleanup definitions that are only used within this header file. -#undef ASMJIT_CXX_GNU -#undef ASMJIT_CXX_MAKE_VER - -#endif // ASMJIT_CORE_API_CONFIG_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archcommons.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archcommons.h deleted file mode 100644 index fda2451..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archcommons.h +++ /dev/null @@ -1,164 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED -#define ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED - -// This file provides architecture-specific classes that are required in the -// core library. For example Imm operand allows to be created from arm::Shift -// in a const-expr way, so the arm::Shift must be provided. So this header -// file provides everything architecture-specific that is used by the Core API. - -#include "../core/globals.h" - -// ============================================================================ -// [asmjit::arm] -// ============================================================================ - -ASMJIT_BEGIN_SUB_NAMESPACE(arm) - -//! \addtogroup asmjit_arm -//! \{ - -//! Represents ARM immediate shift operation type and value. -class Shift { -public: - //! Operation predicate (ARM) describes either SHIFT or EXTEND operation. - //! - //! \note The constants are AsmJit specific. The first 5 values describe real - //! constants on ARM32 and AArch64 hardware, however, the addition constants - //! that describe extend modes are specific to AsmJit and would be translated - //! to the AArch64 specific constants by the assembler. - enum Op : uint32_t { - //! Shift left logical operation (default). - //! - //! Available to all ARM architectures. - kOpLSL = 0x00u, - - //! Shift right logical operation. - //! - //! Available to all ARM architectures. - kOpLSR = 0x01u, - - //! Shift right arithmetic operation. - //! - //! Available to all ARM architectures. - kOpASR = 0x02u, - - //! Rotate right operation. - //! - //! \note Not available in AArch64 mode. - kOpROR = 0x03u, - - //! Rotate right with carry operation (encoded as `kShiftROR` with zero). - //! - //! \note Not available in AArch64 mode. - kOpRRX = 0x04u, - - //! Shift left by filling low order bits with ones. - kOpMSL = 0x05u, - - //! UXTN extend register operation (AArch64 only). - kOpUXTB = 0x06u, - //! UXTH extend register operation (AArch64 only). - kOpUXTH = 0x07u, - //! UXTW extend register operation (AArch64 only). - kOpUXTW = 0x08u, - //! UXTX extend register operation (AArch64 only). - kOpUXTX = 0x09u, - - //! SXTB extend register operation (AArch64 only). - kOpSXTB = 0x0Au, - //! SXTH extend register operation (AArch64 only). - kOpSXTH = 0x0Bu, - //! SXTW extend register operation (AArch64 only). - kOpSXTW = 0x0Cu, - //! SXTX extend register operation (AArch64 only). - kOpSXTX = 0x0Du - - // NOTE: 0xE and 0xF are used by memory operand to specify POST|PRE offset mode. - }; - - //! Shift operation. - uint32_t _op; - //! Shift Value. - uint32_t _value; - - //! Default constructed Shift is not initialized. - inline Shift() noexcept = default; - - //! Copy constructor (default) - constexpr Shift(const Shift& other) noexcept = default; - - //! Constructs Shift from operation `op` and shift `value`. - constexpr Shift(uint32_t op, uint32_t value) noexcept - : _op(op), - _value(value) {} - - //! Returns the shift operation. - constexpr uint32_t op() const noexcept { return _op; } - //! Returns the shift smount. - constexpr uint32_t value() const noexcept { return _value; } - - //! Sets shift operation to `op`. - inline void setOp(uint32_t op) noexcept { _op = op; } - //! Sets shift amount to `value`. - inline void setValue(uint32_t value) noexcept { _value = value; } -}; - -//! Constructs a `LSL #value` shift (logical shift left). -static constexpr Shift lsl(uint32_t value) noexcept { return Shift(Shift::kOpLSL, value); } -//! Constructs a `LSR #value` shift (logical shift right). -static constexpr Shift lsr(uint32_t value) noexcept { return Shift(Shift::kOpLSR, value); } -//! Constructs a `ASR #value` shift (arithmetic shift right). -static constexpr Shift asr(uint32_t value) noexcept { return Shift(Shift::kOpASR, value); } -//! Constructs a `ROR #value` shift (rotate right). -static constexpr Shift ror(uint32_t value) noexcept { return Shift(Shift::kOpROR, value); } -//! Constructs a `RRX` shift (rotate with carry by 1). -static constexpr Shift rrx() noexcept { return Shift(Shift::kOpRRX, 0); } -//! Constructs a `MSL #value` shift (logical shift left filling ones). -static constexpr Shift msl(uint32_t value) noexcept { return Shift(Shift::kOpMSL, value); } - -//! Constructs a `UXTB #value` extend and shift (unsigned byte extend). -static constexpr Shift uxtb(uint32_t value) noexcept { return Shift(Shift::kOpUXTB, value); } -//! Constructs a `UXTH #value` extend and shift (unsigned hword extend). -static constexpr Shift uxth(uint32_t value) noexcept { return Shift(Shift::kOpUXTH, value); } -//! Constructs a `UXTW #value` extend and shift (unsigned word extend). -static constexpr Shift uxtw(uint32_t value) noexcept { return Shift(Shift::kOpUXTW, value); } -//! Constructs a `UXTX #value` extend and shift (unsigned dword extend). -static constexpr Shift uxtx(uint32_t value) noexcept { return Shift(Shift::kOpUXTX, value); } - -//! Constructs a `SXTB #value` extend and shift (signed byte extend). -static constexpr Shift sxtb(uint32_t value) noexcept { return Shift(Shift::kOpSXTB, value); } -//! Constructs a `SXTH #value` extend and shift (signed hword extend). -static constexpr Shift sxth(uint32_t value) noexcept { return Shift(Shift::kOpSXTH, value); } -//! Constructs a `SXTW #value` extend and shift (signed word extend). -static constexpr Shift sxtw(uint32_t value) noexcept { return Shift(Shift::kOpSXTW, value); } -//! Constructs a `SXTX #value` extend and shift (signed dword extend). -static constexpr Shift sxtx(uint32_t value) noexcept { return Shift(Shift::kOpSXTX, value); } - -//! \} - -ASMJIT_END_SUB_NAMESPACE - -#endif // ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archtraits.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archtraits.cpp deleted file mode 100644 index f069354..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archtraits.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/archtraits.h" -#include "../core/misc_p.h" - -#ifdef ASMJIT_BUILD_X86 - #include "../x86/x86archtraits_p.h" -#endif - -#ifdef ASMJIT_BUILD_ARM - #include "../arm/armarchtraits_p.h" -#endif - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::ArchTraits] -// ============================================================================ - -static const constexpr ArchTraits noArchTraits = { - 0xFF, // SP. - 0xFF, // FP. - 0xFF, // LR. - 0xFF, // PC. - { 0, 0, 0 }, // Reserved. - 0, // HW stack alignment. - 0, // Min stack offset. - 0, // Max stack offset. - { 0, 0, 0, 0}, // ISA features [Gp, Vec, Other0, Other1]. - { { 0 } }, // RegTypeToSignature. - { 0 }, // RegTypeToTypeId. - { 0 } // TypeIdToRegType. -}; - -ASMJIT_VARAPI const ArchTraits _archTraits[Environment::kArchCount] = { - // No architecture. - noArchTraits, - - // X86/X86 architectures. -#ifdef ASMJIT_BUILD_X86 - x86::x86ArchTraits, - x86::x64ArchTraits, -#else - noArchTraits, - noArchTraits, -#endif - - // RISCV32/RISCV64 architectures. - noArchTraits, - noArchTraits, - - // ARM architecture - noArchTraits, - - // AArch64 architecture. -#ifdef ASMJIT_BUILD_ARM - arm::a64ArchTraits, -#else - noArchTraits, -#endif - - // ARM/Thumb architecture. - noArchTraits, - - // Reserved. - noArchTraits, - - // MIPS32/MIPS64 - noArchTraits, - noArchTraits -}; - -// ============================================================================ -// [asmjit::ArchUtils] -// ============================================================================ - -ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfoOut) noexcept { - const ArchTraits& archTraits = ArchTraits::byArch(arch); - - // Passed RegType instead of TypeId? - if (typeId <= BaseReg::kTypeMax) - typeId = archTraits.regTypeToTypeId(typeId); - - if (ASMJIT_UNLIKELY(!Type::isValid(typeId))) - return DebugUtils::errored(kErrorInvalidTypeId); - - // First normalize architecture dependent types. - if (Type::isAbstract(typeId)) { - bool is32Bit = Environment::is32Bit(arch); - if (typeId == Type::kIdIntPtr) - typeId = is32Bit ? Type::kIdI32 : Type::kIdI64; - else - typeId = is32Bit ? Type::kIdU32 : Type::kIdU64; - } - - // Type size helps to construct all groups of registers. - // TypeId is invalid if the size is zero. - uint32_t size = Type::sizeOf(typeId); - if (ASMJIT_UNLIKELY(!size)) - return DebugUtils::errored(kErrorInvalidTypeId); - - if (ASMJIT_UNLIKELY(typeId == Type::kIdF80)) - return DebugUtils::errored(kErrorInvalidUseOfF80); - - uint32_t regType = 0; - if (typeId >= Type::_kIdBaseStart && typeId < Type::_kIdVec32Start) { - regType = archTraits._typeIdToRegType[typeId - Type::_kIdBaseStart]; - if (!regType) { - if (typeId == Type::kIdI64 || typeId == Type::kIdU64) - return DebugUtils::errored(kErrorInvalidUseOfGpq); - else - return DebugUtils::errored(kErrorInvalidTypeId); - } - } - else { - if (size <= 8 && archTraits._regInfo[BaseReg::kTypeVec64].isValid()) - regType = BaseReg::kTypeVec64; - else if (size <= 16 && archTraits._regInfo[BaseReg::kTypeVec128].isValid()) - regType = BaseReg::kTypeVec128; - else if (size == 32 && archTraits._regInfo[BaseReg::kTypeVec256].isValid()) - regType = BaseReg::kTypeVec256; - else if (archTraits._regInfo[BaseReg::kTypeVec512].isValid()) - regType = BaseReg::kTypeVec512; - else - return DebugUtils::errored(kErrorInvalidTypeId); - } - - *typeIdOut = typeId; - regInfoOut->reset(archTraits.regTypeToSignature(regType)); - return kErrorOk; -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archtraits.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archtraits.h deleted file mode 100644 index 5af6c7e..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/archtraits.h +++ /dev/null @@ -1,174 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_ARCHTRAITS_H_INCLUDED -#define ASMJIT_CORE_ARCHTRAITS_H_INCLUDED - -#include "../core/environment.h" -#include "../core/operand.h" -#include "../core/type.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [asmjit::ArchTraits] -// ============================================================================ - -//! Architecture traits used by Function API and Compiler's register allocator. -struct ArchTraits { - //! ISA features for each register group. - enum IsaFeatures : uint32_t { - //! ISA features a register swap by using a single instruction. - kIsaFeatureSwap = 0x01u, - //! ISA features a push/pop like instruction for this register group. - kIsaFeaturePushPop = 0x02u, - }; - - //! Stack pointer register id. - uint8_t _spRegId; - //! Frame pointer register id. - uint8_t _fpRegId; - //! Link register id. - uint8_t _linkRegId; - //! Instruction pointer (or program counter) register id, if accessible. - uint8_t _ipRegId; - - // Reserved. - uint8_t _reserved[3]; - //! Hardware stack alignment requirement. - uint8_t _hwStackAlignment; - //! Minimum addressable offset on stack guaranteed for all instructions. - uint32_t _minStackOffset; - //! Maximum addressable offset on stack depending on specific instruction. - uint32_t _maxStackOffset; - - //! Flags for each virtual register group (always covers GP and Vec groups). - uint8_t _isaFlags[BaseReg::kGroupVirt]; - - //! Maps register type into a signature, that provides group, size and can - //! be used to construct register operands. - RegInfo _regInfo[BaseReg::kTypeMax + 1]; - //! Maps a register to type-id, see \ref Type::Id. - uint8_t _regTypeToTypeId[BaseReg::kTypeMax + 1]; - //! Maps base TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref Type::Id. - uint8_t _typeIdToRegType[32]; - - //! Resets all members to zeros. - inline void reset() noexcept { memset(this, 0, sizeof(*this)); } - - //! \name Accessors - //! \{ - - //! Returns stack pointer register id. - inline constexpr uint32_t spRegId() const noexcept { return _spRegId; } - //! Returns stack frame register id. - inline constexpr uint32_t fpRegId() const noexcept { return _fpRegId; } - //! Returns link register id, if the architecture provides it. - inline constexpr uint32_t linkRegId() const noexcept { return _linkRegId; } - //! Returns instruction pointer register id, if the architecture provides it. - inline constexpr uint32_t ipRegId() const noexcept { return _ipRegId; } - - //! Returns a hardware stack alignment requirement. - //! - //! \note This is a hardware constraint. Architectures that don't constrain - //! it would return the lowest alignment (1), however, some architectures may - //! constrain the alignment, for example AArch64 requires 16-byte alignment. - inline constexpr uint32_t hwStackAlignment() const noexcept { return _hwStackAlignment; } - - //! Tests whether the architecture provides link register, which is used across - //! function calls. If the link register is not provided then a function call - //! pushes the return address on stack (X86/X64). - inline constexpr bool hasLinkReg() const noexcept { return _linkRegId != BaseReg::kIdBad; } - - //! Returns minimum addressable offset on stack guaranteed for all instructions. - inline constexpr uint32_t minStackOffset() const noexcept { return _minStackOffset; } - //! Returns maximum addressable offset on stack depending on specific instruction. - inline constexpr uint32_t maxStackOffset() const noexcept { return _maxStackOffset; } - - //! Returns ISA flags of the given register `group`. - inline constexpr uint32_t isaFlags(uint32_t group) const noexcept { return _isaFlags[group]; } - //! Tests whether the given register `group` has the given `flag` set. - inline constexpr bool hasIsaFlag(uint32_t group, uint32_t flag) const noexcept { return (_isaFlags[group] & flag) != 0; } - //! Tests whether the ISA provides register swap instruction for the given register `group`. - inline constexpr bool hasSwap(uint32_t group) const noexcept { return hasIsaFlag(group, kIsaFeatureSwap); } - //! Tests whether the ISA provides push/pop instructions for the given register `group`. - inline constexpr bool hasPushPop(uint32_t group) const noexcept { return hasIsaFlag(group, kIsaFeaturePushPop); } - - inline uint32_t hasRegType(uint32_t rType) const noexcept { - return rType <= BaseReg::kTypeMax && _regInfo[rType].signature() != 0; - } - - inline uint32_t regTypeToSignature(uint32_t rType) const noexcept { - ASMJIT_ASSERT(rType <= BaseReg::kTypeMax); - return _regInfo[rType].signature(); - } - - inline uint32_t regTypeToGroup(uint32_t rType) const noexcept { - ASMJIT_ASSERT(rType <= BaseReg::kTypeMax); - return _regInfo[rType].group(); - } - - inline uint32_t regTypeToSize(uint32_t rType) const noexcept { - ASMJIT_ASSERT(rType <= BaseReg::kTypeMax); - return _regInfo[rType].size(); - } - - inline uint32_t regTypeToTypeId(uint32_t rType) const noexcept { - ASMJIT_ASSERT(rType <= BaseReg::kTypeMax); - return _regTypeToTypeId[rType]; - } - - //! \} - - //! \name Statics - //! \{ - - //! Returns a const reference to `ArchTraits` for the given architecture `arch`. - static inline const ArchTraits& byArch(uint32_t arch) noexcept; - - //! \} -}; - -ASMJIT_VARAPI const ArchTraits _archTraits[Environment::kArchCount]; - -inline const ArchTraits& ArchTraits::byArch(uint32_t arch) noexcept { return _archTraits[arch & ~Environment::kArchBigEndianMask]; } - -// ============================================================================ -// [asmjit::ArchUtils] -// ============================================================================ - -//! Architecture utilities. -namespace ArchUtils { - -ASMJIT_API Error typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfo) noexcept; - -} // {ArchUtils} - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_ARCHTRAITS_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/assembler.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/assembler.cpp deleted file mode 100644 index c0cbf0f..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/assembler.cpp +++ /dev/null @@ -1,409 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/assembler.h" -#include "../core/codewriter_p.h" -#include "../core/constpool.h" -#include "../core/emitterutils_p.h" -#include "../core/formatter.h" -#include "../core/logger.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::BaseAssembler - Construction / Destruction] -// ============================================================================ - -BaseAssembler::BaseAssembler() noexcept - : BaseEmitter(kTypeAssembler) {} - -BaseAssembler::~BaseAssembler() noexcept {} - -// ============================================================================ -// [asmjit::BaseAssembler - Buffer Management] -// ============================================================================ - -Error BaseAssembler::setOffset(size_t offset) { - if (ASMJIT_UNLIKELY(!_code)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - - size_t size = Support::max(_section->bufferSize(), this->offset()); - if (ASMJIT_UNLIKELY(offset > size)) - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - _bufferPtr = _bufferData + offset; - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseAssembler - Section Management] -// ============================================================================ - -static void BaseAssembler_initSection(BaseAssembler* self, Section* section) noexcept { - uint8_t* p = section->_buffer._data; - - self->_section = section; - self->_bufferData = p; - self->_bufferPtr = p + section->_buffer._size; - self->_bufferEnd = p + section->_buffer._capacity; -} - -Error BaseAssembler::section(Section* section) { - if (ASMJIT_UNLIKELY(!_code)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - - if (!_code->isSectionValid(section->id()) || _code->_sections[section->id()] != section) - return reportError(DebugUtils::errored(kErrorInvalidSection)); - -#ifndef ASMJIT_NO_LOGGING - if (_logger) - _logger->logf(".section %s {#%u}\n", section->name(), section->id()); -#endif - - BaseAssembler_initSection(this, section); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseAssembler - Label Management] -// ============================================================================ - -Label BaseAssembler::newLabel() { - uint32_t labelId = Globals::kInvalidId; - if (ASMJIT_LIKELY(_code)) { - LabelEntry* le; - Error err = _code->newLabelEntry(&le); - if (ASMJIT_UNLIKELY(err)) - reportError(err); - else - labelId = le->id(); - } - return Label(labelId); -} - -Label BaseAssembler::newNamedLabel(const char* name, size_t nameSize, uint32_t type, uint32_t parentId) { - uint32_t labelId = Globals::kInvalidId; - if (ASMJIT_LIKELY(_code)) { - LabelEntry* le; - Error err = _code->newNamedLabelEntry(&le, name, nameSize, type, parentId); - if (ASMJIT_UNLIKELY(err)) - reportError(err); - else - labelId = le->id(); - } - return Label(labelId); -} - -Error BaseAssembler::bind(const Label& label) { - if (ASMJIT_UNLIKELY(!_code)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - - Error err = _code->bindLabel(label, _section->id(), offset()); - -#ifndef ASMJIT_NO_LOGGING - if (_logger) - EmitterUtils::logLabelBound(this, label); -#endif - - resetInlineComment(); - if (err) - return reportError(err); - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseAssembler - Embed] -// ============================================================================ - -#ifndef ASMJIT_NO_LOGGING -struct DataSizeByPower { - char str[4]; -}; - -static const DataSizeByPower dataSizeByPowerTable[] = { - { "db" }, - { "dw" }, - { "dd" }, - { "dq" } -}; -#endif - -Error BaseAssembler::embed(const void* data, size_t dataSize) { - if (ASMJIT_UNLIKELY(!_code)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - - if (dataSize == 0) - return kErrorOk; - - CodeWriter writer(this); - ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize)); - - writer.emitData(data, dataSize); - -#ifndef ASMJIT_NO_LOGGING - if (_logger) - _logger->logBinary(data, dataSize); -#endif - - writer.done(this); - return kErrorOk; -} - -Error BaseAssembler::embedDataArray(uint32_t typeId, const void* data, size_t itemCcount, size_t repeatCount) { - uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize()); - uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta); - - if (ASMJIT_UNLIKELY(!Type::isValid(finalTypeId))) - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - if (itemCcount == 0 || repeatCount == 0) - return kErrorOk; - - uint32_t typeSize = Type::sizeOf(finalTypeId); - Support::FastUInt8 of = 0; - - size_t dataSize = Support::mulOverflow(itemCcount, size_t(typeSize), &of); - size_t totalSize = Support::mulOverflow(dataSize, repeatCount, &of); - - if (ASMJIT_UNLIKELY(of)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - - CodeWriter writer(this); - ASMJIT_PROPAGATE(writer.ensureSpace(this, totalSize)); - -#ifndef ASMJIT_NO_LOGGING - const uint8_t* start = writer.cursor(); -#endif - - for (size_t i = 0; i < repeatCount; i++) { - writer.emitData(data, dataSize); - } - -#ifndef ASMJIT_NO_LOGGING - if (_logger) - _logger->logBinary(start, totalSize); -#endif - - writer.done(this); - return kErrorOk; -} - -Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) { - if (ASMJIT_UNLIKELY(!_code)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - - if (ASMJIT_UNLIKELY(!isLabelValid(label))) - return reportError(DebugUtils::errored(kErrorInvalidLabel)); - - ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment()))); - ASMJIT_PROPAGATE(bind(label)); - - size_t size = pool.size(); - CodeWriter writer(this); - ASMJIT_PROPAGATE(writer.ensureSpace(this, size)); - - pool.fill(writer.cursor()); - -#ifndef ASMJIT_NO_LOGGING - if (_logger) - _logger->logBinary(writer.cursor(), size); -#endif - - writer.advance(size); - writer.done(this); - - return kErrorOk; -} - -Error BaseAssembler::embedLabel(const Label& label, size_t dataSize) { - if (ASMJIT_UNLIKELY(!_code)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - - ASMJIT_ASSERT(_code != nullptr); - RelocEntry* re; - LabelEntry* le = _code->labelEntry(label); - - if (ASMJIT_UNLIKELY(!le)) - return reportError(DebugUtils::errored(kErrorInvalidLabel)); - - if (dataSize == 0) - dataSize = registerSize(); - - if (ASMJIT_UNLIKELY(!Support::isPowerOf2(dataSize) || dataSize > 8)) - return reportError(DebugUtils::errored(kErrorInvalidOperandSize)); - - CodeWriter writer(this); - ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize)); - -#ifndef ASMJIT_NO_LOGGING - if (_logger) { - StringTmp<256> sb; - sb.appendFormat("%s ", dataSizeByPowerTable[Support::ctz(dataSize)].str); - Formatter::formatLabel(sb, 0, this, label.id()); - sb.append('\n'); - _logger->log(sb); - } -#endif - - Error err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs); - if (ASMJIT_UNLIKELY(err)) - return reportError(err); - - re->_sourceSectionId = _section->id(); - re->_sourceOffset = offset(); - re->_format.resetToDataValue(uint32_t(dataSize)); - - if (le->isBound()) { - re->_targetSectionId = le->section()->id(); - re->_payload = le->offset(); - } - else { - OffsetFormat of; - of.resetToDataValue(uint32_t(dataSize)); - - LabelLink* link = _code->newLabelLink(le, _section->id(), offset(), 0, of); - if (ASMJIT_UNLIKELY(!link)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - - link->relocId = re->id(); - } - - // Emit dummy DWORD/QWORD depending on the data size. - writer.emitZeros(dataSize); - writer.done(this); - - return kErrorOk; -} - -Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) { - if (ASMJIT_UNLIKELY(!_code)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - - LabelEntry* labelEntry = _code->labelEntry(label); - LabelEntry* baseEntry = _code->labelEntry(base); - - if (ASMJIT_UNLIKELY(!labelEntry || !baseEntry)) - return reportError(DebugUtils::errored(kErrorInvalidLabel)); - - if (dataSize == 0) - dataSize = registerSize(); - - if (ASMJIT_UNLIKELY(!Support::isPowerOf2(dataSize) || dataSize > 8)) - return reportError(DebugUtils::errored(kErrorInvalidOperandSize)); - - CodeWriter writer(this); - ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize)); - -#ifndef ASMJIT_NO_LOGGING - if (_logger) { - StringTmp<256> sb; - sb.appendFormat(".%s (", dataSizeByPowerTable[Support::ctz(dataSize)].str); - Formatter::formatLabel(sb, 0, this, label.id()); - sb.append(" - "); - Formatter::formatLabel(sb, 0, this, base.id()); - sb.append(")\n"); - _logger->log(sb); - } -#endif - - // If both labels are bound within the same section it means the delta can be calculated now. - if (labelEntry->isBound() && baseEntry->isBound() && labelEntry->section() == baseEntry->section()) { - uint64_t delta = labelEntry->offset() - baseEntry->offset(); - writer.emitValueLE(delta, dataSize); - } - else { - RelocEntry* re; - Error err = _code->newRelocEntry(&re, RelocEntry::kTypeExpression); - if (ASMJIT_UNLIKELY(err)) - return reportError(err); - - Expression* exp = _code->_zone.newT(); - if (ASMJIT_UNLIKELY(!exp)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - - exp->reset(); - exp->opType = Expression::kOpSub; - exp->setValueAsLabel(0, labelEntry); - exp->setValueAsLabel(1, baseEntry); - - re->_format.resetToDataValue(dataSize); - re->_sourceSectionId = _section->id(); - re->_sourceOffset = offset(); - re->_payload = (uint64_t)(uintptr_t)exp; - - writer.emitZeros(dataSize); - } - - writer.done(this); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseAssembler - Comment] -// ============================================================================ - -Error BaseAssembler::comment(const char* data, size_t size) { - if (!hasEmitterFlag(kFlagLogComments)) { - if (!hasEmitterFlag(kFlagAttached)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - return kErrorOk; - } - -#ifndef ASMJIT_NO_LOGGING - // Logger cannot be NULL if `kFlagLogComments` is set. - ASMJIT_ASSERT(_logger != nullptr); - - _logger->log(data, size); - _logger->log("\n", 1); - return kErrorOk; -#else - DebugUtils::unused(data, size); - return kErrorOk; -#endif -} - -// ============================================================================ -// [asmjit::BaseAssembler - Events] -// ============================================================================ - -Error BaseAssembler::onAttach(CodeHolder* code) noexcept { - ASMJIT_PROPAGATE(Base::onAttach(code)); - - // Attach to the end of the .text section. - BaseAssembler_initSection(this, code->_sections[0]); - - return kErrorOk; -} - -Error BaseAssembler::onDetach(CodeHolder* code) noexcept { - _section = nullptr; - _bufferData = nullptr; - _bufferEnd = nullptr; - _bufferPtr = nullptr; - return Base::onDetach(code); -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/assembler.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/assembler.h deleted file mode 100644 index 6e38bc5..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/assembler.h +++ /dev/null @@ -1,152 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_ASSEMBLER_H_INCLUDED -#define ASMJIT_CORE_ASSEMBLER_H_INCLUDED - -#include "../core/codeholder.h" -#include "../core/datatypes.h" -#include "../core/emitter.h" -#include "../core/operand.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_assembler -//! \{ - -// ============================================================================ -// [asmjit::BaseAssembler] -// ============================================================================ - -//! Base assembler. -//! -//! This is a base class that provides interface used by architecture specific -//! assembler implementations. Assembler doesn't hold any data, instead it's -//! attached to \ref CodeHolder, which provides all the data that Assembler -//! needs and which can be altered by it. -//! -//! Check out architecture specific assemblers for more details and examples: -//! -//! - \ref x86::Assembler - X86/X64 assembler implementation. -class ASMJIT_VIRTAPI BaseAssembler : public BaseEmitter { -public: - ASMJIT_NONCOPYABLE(BaseAssembler) - typedef BaseEmitter Base; - - //! Current section where the assembling happens. - Section* _section = nullptr; - //! Start of the CodeBuffer of the current section. - uint8_t* _bufferData = nullptr; - //! End (first invalid byte) of the current section. - uint8_t* _bufferEnd = nullptr; - //! Pointer in the CodeBuffer of the current section. - uint8_t* _bufferPtr = nullptr; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `BaseAssembler` instance. - ASMJIT_API BaseAssembler() noexcept; - //! Destroys the `BaseAssembler` instance. - ASMJIT_API virtual ~BaseAssembler() noexcept; - - //! \} - - //! \name Code-Buffer Management - //! \{ - - //! Returns the capacity of the current CodeBuffer. - inline size_t bufferCapacity() const noexcept { return (size_t)(_bufferEnd - _bufferData); } - //! Returns the number of remaining bytes in the current CodeBuffer. - inline size_t remainingSpace() const noexcept { return (size_t)(_bufferEnd - _bufferPtr); } - - //! Returns the current position in the CodeBuffer. - inline size_t offset() const noexcept { return (size_t)(_bufferPtr - _bufferData); } - - //! Sets the current position in the CodeBuffer to `offset`. - //! - //! \note The `offset` cannot be greater than buffer size even if it's - //! within the buffer's capacity. - ASMJIT_API Error setOffset(size_t offset); - - //! Returns the start of the CodeBuffer in the current section. - inline uint8_t* bufferData() const noexcept { return _bufferData; } - //! Returns the end (first invalid byte) in the current section. - inline uint8_t* bufferEnd() const noexcept { return _bufferEnd; } - //! Returns the current pointer in the CodeBuffer in the current section. - inline uint8_t* bufferPtr() const noexcept { return _bufferPtr; } - - //! \} - - //! \name Section Management - //! \{ - - //! Returns the current section. - inline Section* currentSection() const noexcept { return _section; } - - ASMJIT_API Error section(Section* section) override; - - //! \} - - //! \name Label Management - //! \{ - - ASMJIT_API Label newLabel() override; - ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) override; - ASMJIT_API Error bind(const Label& label) override; - - //! \} - - //! \name Embed - //! \{ - - ASMJIT_API Error embed(const void* data, size_t dataSize) override; - ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t itemCcount, size_t repeatCount = 1) override; - ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override; - - ASMJIT_API Error embedLabel(const Label& label, size_t dataSize = 0) override; - ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) override; - - //! \} - - //! \name Comment - //! \{ - - ASMJIT_API Error comment(const char* data, size_t size = SIZE_MAX) override; - - //! \} - - //! \name Events - //! \{ - - ASMJIT_API Error onAttach(CodeHolder* code) noexcept override; - ASMJIT_API Error onDetach(CodeHolder* code) noexcept override; - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_ASSEMBLER_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/builder.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/builder.cpp deleted file mode 100644 index ad89f1d..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/builder.cpp +++ /dev/null @@ -1,920 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#ifndef ASMJIT_NO_BUILDER - -#include "../core/builder.h" -#include "../core/emitterutils_p.h" -#include "../core/errorhandler.h" -#include "../core/formatter.h" -#include "../core/logger.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::PostponedErrorHandler (Internal)] -// ============================================================================ - -//! Postponed error handler that never throws. Used as a temporal error handler -//! to run passes. If error occurs, the caller is notified and will call the -//! real error handler, that can throw. -class PostponedErrorHandler : public ErrorHandler { -public: - void handleError(Error err, const char* message, BaseEmitter* origin) override { - DebugUtils::unused(err, origin); - _message.assign(message); - } - - StringTmp<128> _message; -}; - -// ============================================================================ -// [asmjit::BaseBuilder - Utilities] -// ============================================================================ - -static void BaseBuilder_deletePasses(BaseBuilder* self) noexcept { - for (Pass* pass : self->_passes) - pass->~Pass(); - self->_passes.reset(); -} - -// ============================================================================ -// [asmjit::BaseBuilder - Construction / Destruction] -// ============================================================================ - -BaseBuilder::BaseBuilder() noexcept - : BaseEmitter(kTypeBuilder), - _codeZone(32768 - Zone::kBlockOverhead), - _dataZone(16384 - Zone::kBlockOverhead), - _passZone(65536 - Zone::kBlockOverhead), - _allocator(&_codeZone) {} - -BaseBuilder::~BaseBuilder() noexcept { - BaseBuilder_deletePasses(this); -} - -// ============================================================================ -// [asmjit::BaseBuilder - Node Management] -// ============================================================================ - -Error BaseBuilder::_newInstNode(InstNode** out, uint32_t instId, uint32_t instOptions, uint32_t opCount) { - uint32_t opCapacity = InstNode::capacityOfOpCount(opCount); - ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity); - - InstNode* node = _allocator.allocT(InstNode::nodeSizeOfOpCapacity(opCapacity)); - if (ASMJIT_UNLIKELY(!node)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - - *out = new(node) InstNode(this, instId, instOptions, opCount, opCapacity); - return kErrorOk; -} - - -Error BaseBuilder::_newLabelNode(LabelNode** out) { - *out = nullptr; - - ASMJIT_PROPAGATE(_newNodeT(out)); - return registerLabelNode(*out); -} - -Error BaseBuilder::_newAlignNode(AlignNode** out, uint32_t alignMode, uint32_t alignment) { - *out = nullptr; - return _newNodeT(out, alignMode, alignment); -} - -Error BaseBuilder::_newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount) { - *out = nullptr; - - uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize()); - uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta); - - if (ASMJIT_UNLIKELY(!Type::isValid(finalTypeId))) - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - uint32_t typeSize = Type::sizeOf(finalTypeId); - Support::FastUInt8 of = 0; - - size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of); - if (ASMJIT_UNLIKELY(of)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - - EmbedDataNode* node; - ASMJIT_PROPAGATE(_newNodeT(&node)); - - node->_embed._typeId = uint8_t(typeId); - node->_embed._typeSize = uint8_t(typeSize); - node->_itemCount = itemCount; - node->_repeatCount = repeatCount; - - uint8_t* dstData = node->_inlineData; - if (dataSize > EmbedDataNode::kInlineBufferSize) { - dstData = static_cast(_dataZone.alloc(dataSize, 8)); - if (ASMJIT_UNLIKELY(!dstData)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - node->_externalData = dstData; - } - - if (data) - memcpy(dstData, data, dataSize); - - *out = node; - return kErrorOk; -} - -Error BaseBuilder::_newConstPoolNode(ConstPoolNode** out) { - *out = nullptr; - - ASMJIT_PROPAGATE(_newNodeT(out)); - return registerLabelNode(*out); -} - -Error BaseBuilder::_newCommentNode(CommentNode** out, const char* data, size_t size) { - *out = nullptr; - - if (data) { - if (size == SIZE_MAX) - size = strlen(data); - - if (size > 0) { - data = static_cast(_dataZone.dup(data, size, true)); - if (ASMJIT_UNLIKELY(!data)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - } - } - - return _newNodeT(out, data); -} - -BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept { - ASMJIT_ASSERT(node); - ASMJIT_ASSERT(!node->_prev); - ASMJIT_ASSERT(!node->_next); - ASMJIT_ASSERT(!node->isActive()); - - if (!_cursor) { - if (!_firstNode) { - _firstNode = node; - _lastNode = node; - } - else { - node->_next = _firstNode; - _firstNode->_prev = node; - _firstNode = node; - } - } - else { - BaseNode* prev = _cursor; - BaseNode* next = _cursor->next(); - - node->_prev = prev; - node->_next = next; - - prev->_next = node; - if (next) - next->_prev = node; - else - _lastNode = node; - } - - node->addFlags(BaseNode::kFlagIsActive); - if (node->isSection()) - _dirtySectionLinks = true; - - _cursor = node; - return node; -} - -BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref) noexcept { - ASMJIT_ASSERT(node); - ASMJIT_ASSERT(ref); - - ASMJIT_ASSERT(!node->_prev); - ASMJIT_ASSERT(!node->_next); - - BaseNode* prev = ref; - BaseNode* next = ref->next(); - - node->_prev = prev; - node->_next = next; - - node->addFlags(BaseNode::kFlagIsActive); - if (node->isSection()) - _dirtySectionLinks = true; - - prev->_next = node; - if (next) - next->_prev = node; - else - _lastNode = node; - - return node; -} - -BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref) noexcept { - ASMJIT_ASSERT(node != nullptr); - ASMJIT_ASSERT(!node->_prev); - ASMJIT_ASSERT(!node->_next); - ASMJIT_ASSERT(!node->isActive()); - ASMJIT_ASSERT(ref != nullptr); - ASMJIT_ASSERT(ref->isActive()); - - BaseNode* prev = ref->prev(); - BaseNode* next = ref; - - node->_prev = prev; - node->_next = next; - - node->addFlags(BaseNode::kFlagIsActive); - if (node->isSection()) - _dirtySectionLinks = true; - - next->_prev = node; - if (prev) - prev->_next = node; - else - _firstNode = node; - - return node; -} - -BaseNode* BaseBuilder::removeNode(BaseNode* node) noexcept { - if (!node->isActive()) - return node; - - BaseNode* prev = node->prev(); - BaseNode* next = node->next(); - - if (_firstNode == node) - _firstNode = next; - else - prev->_next = next; - - if (_lastNode == node) - _lastNode = prev; - else - next->_prev = prev; - - node->_prev = nullptr; - node->_next = nullptr; - node->clearFlags(BaseNode::kFlagIsActive); - if (node->isSection()) - _dirtySectionLinks = true; - - if (_cursor == node) - _cursor = prev; - - return node; -} - -void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last) noexcept { - if (first == last) { - removeNode(first); - return; - } - - if (!first->isActive()) - return; - - BaseNode* prev = first->prev(); - BaseNode* next = last->next(); - - if (_firstNode == first) - _firstNode = next; - else - prev->_next = next; - - if (_lastNode == last) - _lastNode = prev; - else - next->_prev = prev; - - BaseNode* node = first; - uint32_t didRemoveSection = false; - - for (;;) { - next = node->next(); - ASMJIT_ASSERT(next != nullptr); - - node->_prev = nullptr; - node->_next = nullptr; - node->clearFlags(BaseNode::kFlagIsActive); - didRemoveSection |= uint32_t(node->isSection()); - - if (_cursor == node) - _cursor = prev; - - if (node == last) - break; - node = next; - } - - if (didRemoveSection) - _dirtySectionLinks = true; -} - -BaseNode* BaseBuilder::setCursor(BaseNode* node) noexcept { - BaseNode* old = _cursor; - _cursor = node; - return old; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Section] -// ============================================================================ - -Error BaseBuilder::sectionNodeOf(SectionNode** out, uint32_t sectionId) { - *out = nullptr; - - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - if (ASMJIT_UNLIKELY(!_code->isSectionValid(sectionId))) - return reportError(DebugUtils::errored(kErrorInvalidSection)); - - if (sectionId >= _sectionNodes.size()) { - Error err = _sectionNodes.reserve(&_allocator, sectionId + 1); - if (ASMJIT_UNLIKELY(err != kErrorOk)) - return reportError(err); - } - - SectionNode* node = nullptr; - if (sectionId < _sectionNodes.size()) - node = _sectionNodes[sectionId]; - - if (!node) { - ASMJIT_PROPAGATE(_newNodeT(&node, sectionId)); - - // We have already reserved enough space, this cannot fail now. - if (sectionId >= _sectionNodes.size()) - _sectionNodes.resize(&_allocator, sectionId + 1); - - _sectionNodes[sectionId] = node; - } - - *out = node; - return kErrorOk; -} - -Error BaseBuilder::section(Section* section) { - SectionNode* node; - ASMJIT_PROPAGATE(sectionNodeOf(&node, section->id())); - - if (!node->isActive()) { - // Insert the section at the end if it was not part of the code. - addAfter(node, lastNode()); - _cursor = node; - } - else { - // This is a bit tricky. We cache section links to make sure that - // switching sections doesn't involve traversal in linked-list unless - // the position of the section has changed. - if (hasDirtySectionLinks()) - updateSectionLinks(); - - if (node->_nextSection) - _cursor = node->_nextSection->_prev; - else - _cursor = _lastNode; - } - - return kErrorOk; -} - -void BaseBuilder::updateSectionLinks() noexcept { - if (!_dirtySectionLinks) - return; - - BaseNode* node_ = _firstNode; - SectionNode* currentSection = nullptr; - - while (node_) { - if (node_->isSection()) { - if (currentSection) - currentSection->_nextSection = node_->as(); - currentSection = node_->as(); - } - node_ = node_->next(); - } - - if (currentSection) - currentSection->_nextSection = nullptr; - - _dirtySectionLinks = false; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Labels] -// ============================================================================ - -Error BaseBuilder::labelNodeOf(LabelNode** out, uint32_t labelId) { - *out = nullptr; - - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - uint32_t index = labelId; - if (ASMJIT_UNLIKELY(index >= _code->labelCount())) - return DebugUtils::errored(kErrorInvalidLabel); - - if (index >= _labelNodes.size()) - ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, index + 1)); - - LabelNode* node = _labelNodes[index]; - if (!node) { - ASMJIT_PROPAGATE(_newNodeT(&node, labelId)); - _labelNodes[index] = node; - } - - *out = node; - return kErrorOk; -} - -Error BaseBuilder::registerLabelNode(LabelNode* node) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - LabelEntry* le; - ASMJIT_PROPAGATE(_code->newLabelEntry(&le)); - uint32_t labelId = le->id(); - - // We just added one label so it must be true. - ASMJIT_ASSERT(_labelNodes.size() < labelId + 1); - ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, labelId + 1)); - - _labelNodes[labelId] = node; - node->_labelId = labelId; - - return kErrorOk; -} - -static Error BaseBuilder_newLabelInternal(BaseBuilder* self, uint32_t labelId) { - ASMJIT_ASSERT(self->_labelNodes.size() < labelId + 1); - - uint32_t growBy = labelId - self->_labelNodes.size(); - Error err = self->_labelNodes.willGrow(&self->_allocator, growBy); - - if (ASMJIT_UNLIKELY(err)) - return self->reportError(err); - - LabelNode* node; - ASMJIT_PROPAGATE(self->_newNodeT(&node, labelId)); - - self->_labelNodes.resize(&self->_allocator, labelId + 1); - self->_labelNodes[labelId] = node; - node->_labelId = labelId; - return kErrorOk; -} - -Label BaseBuilder::newLabel() { - uint32_t labelId = Globals::kInvalidId; - LabelEntry* le; - - if (_code && - _code->newLabelEntry(&le) == kErrorOk && - BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) { - labelId = le->id(); - } - - return Label(labelId); -} - -Label BaseBuilder::newNamedLabel(const char* name, size_t nameSize, uint32_t type, uint32_t parentId) { - uint32_t labelId = Globals::kInvalidId; - LabelEntry* le; - - if (_code && - _code->newNamedLabelEntry(&le, name, nameSize, type, parentId) == kErrorOk && - BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) { - labelId = le->id(); - } - - return Label(labelId); -} - -Error BaseBuilder::bind(const Label& label) { - LabelNode* node; - ASMJIT_PROPAGATE(labelNodeOf(&node, label)); - - addNode(node); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Passes] -// ============================================================================ - -ASMJIT_FAVOR_SIZE Pass* BaseBuilder::passByName(const char* name) const noexcept { - for (Pass* pass : _passes) - if (strcmp(pass->name(), name) == 0) - return pass; - return nullptr; -} - -ASMJIT_FAVOR_SIZE Error BaseBuilder::addPass(Pass* pass) noexcept { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - if (ASMJIT_UNLIKELY(pass == nullptr)) { - // Since this is directly called by `addPassT()` we treat `null` argument - // as out-of-memory condition. Otherwise it would be API misuse. - return DebugUtils::errored(kErrorOutOfMemory); - } - else if (ASMJIT_UNLIKELY(pass->_cb)) { - // Kinda weird, but okay... - if (pass->_cb == this) - return kErrorOk; - return DebugUtils::errored(kErrorInvalidState); - } - - ASMJIT_PROPAGATE(_passes.append(&_allocator, pass)); - pass->_cb = this; - return kErrorOk; -} - -ASMJIT_FAVOR_SIZE Error BaseBuilder::deletePass(Pass* pass) noexcept { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - if (ASMJIT_UNLIKELY(pass == nullptr)) - return DebugUtils::errored(kErrorInvalidArgument); - - if (pass->_cb != nullptr) { - if (pass->_cb != this) - return DebugUtils::errored(kErrorInvalidState); - - uint32_t index = _passes.indexOf(pass); - ASMJIT_ASSERT(index != Globals::kNotFound); - - pass->_cb = nullptr; - _passes.removeAt(index); - } - - pass->~Pass(); - return kErrorOk; -} - -Error BaseBuilder::runPasses() { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - if (_passes.empty()) - return kErrorOk; - - ErrorHandler* prev = errorHandler(); - PostponedErrorHandler postponed; - - Error err = kErrorOk; - setErrorHandler(&postponed); - - for (Pass* pass : _passes) { - _passZone.reset(); - err = pass->run(&_passZone, _logger); - if (err) - break; - } - _passZone.reset(); - setErrorHandler(prev); - - if (ASMJIT_UNLIKELY(err)) - return reportError(err, !postponed._message.empty() ? postponed._message.data() : nullptr); - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Emit] -// ============================================================================ - -Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) { - uint32_t opCount = EmitterUtils::opCountFromEmitArgs(o0, o1, o2, opExt); - uint32_t options = instOptions() | forcedInstOptions(); - - if (options & BaseInst::kOptionReserved) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - -#ifndef ASMJIT_NO_VALIDATION - // Strict validation. - if (hasValidationOption(kValidationOptionIntermediate)) { - Operand_ opArray[Globals::kMaxOpCount]; - EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt); - - Error err = InstAPI::validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount); - if (ASMJIT_UNLIKELY(err)) { - resetInstOptions(); - resetExtraReg(); - resetInlineComment(); - return reportError(err); - } - } -#endif - - // Clear options that should never be part of `InstNode`. - options &= ~BaseInst::kOptionReserved; - } - - uint32_t opCapacity = InstNode::capacityOfOpCount(opCount); - ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity); - - InstNode* node = _allocator.allocT(InstNode::nodeSizeOfOpCapacity(opCapacity)); - const char* comment = inlineComment(); - - resetInstOptions(); - resetInlineComment(); - - if (ASMJIT_UNLIKELY(!node)) { - resetExtraReg(); - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - } - - node = new(node) InstNode(this, instId, options, opCount, opCapacity); - node->setExtraReg(extraReg()); - node->setOp(0, o0); - node->setOp(1, o1); - node->setOp(2, o2); - for (uint32_t i = 3; i < opCount; i++) - node->setOp(i, opExt[i - 3]); - node->resetOpRange(opCount, opCapacity); - - if (comment) - node->setInlineComment(static_cast(_dataZone.dup(comment, strlen(comment), true))); - - addNode(node); - resetExtraReg(); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Align] -// ============================================================================ - -Error BaseBuilder::align(uint32_t alignMode, uint32_t alignment) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - AlignNode* node; - ASMJIT_PROPAGATE(_newAlignNode(&node, alignMode, alignment)); - - addNode(node); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Embed] -// ============================================================================ - -Error BaseBuilder::embed(const void* data, size_t dataSize) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - EmbedDataNode* node; - ASMJIT_PROPAGATE(_newEmbedDataNode(&node, Type::kIdU8, data, dataSize)); - - addNode(node); - return kErrorOk; -} - -Error BaseBuilder::embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t itemRepeat) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - EmbedDataNode* node; - ASMJIT_PROPAGATE(_newEmbedDataNode(&node, typeId, data, itemCount, itemRepeat)); - - addNode(node); - return kErrorOk; -} - -Error BaseBuilder::embedConstPool(const Label& label, const ConstPool& pool) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - if (!isLabelValid(label)) - return reportError(DebugUtils::errored(kErrorInvalidLabel)); - - ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment()))); - ASMJIT_PROPAGATE(bind(label)); - - EmbedDataNode* node; - ASMJIT_PROPAGATE(_newEmbedDataNode(&node, Type::kIdU8, nullptr, pool.size())); - - pool.fill(node->data()); - addNode(node); - return kErrorOk; -} - -// EmbedLabel / EmbedLabelDelta -// ---------------------------- -// -// If dataSize is zero it means that the size is the same as target register -// width, however, if it's provided we really want to validate whether it's -// within the possible range. - -static inline bool BaseBuilder_checkDataSize(size_t dataSize) noexcept { - return !dataSize || (Support::isPowerOf2(dataSize) && dataSize <= 8); -} - -Error BaseBuilder::embedLabel(const Label& label, size_t dataSize) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - if (!BaseBuilder_checkDataSize(dataSize)) - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - EmbedLabelNode* node; - ASMJIT_PROPAGATE(_newNodeT(&node, label.id(), uint32_t(dataSize))); - - addNode(node); - return kErrorOk; -} - -Error BaseBuilder::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - if (!BaseBuilder_checkDataSize(dataSize)) - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - EmbedLabelDeltaNode* node; - ASMJIT_PROPAGATE(_newNodeT(&node, label.id(), base.id(), uint32_t(dataSize))); - - addNode(node); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Comment] -// ============================================================================ - -Error BaseBuilder::comment(const char* data, size_t size) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - - CommentNode* node; - ASMJIT_PROPAGATE(_newCommentNode(&node, data, size)); - - addNode(node); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Serialize] -// ============================================================================ - -Error BaseBuilder::serializeTo(BaseEmitter* dst) { - Error err = kErrorOk; - BaseNode* node_ = _firstNode; - - Operand_ opArray[Globals::kMaxOpCount]; - - do { - dst->setInlineComment(node_->inlineComment()); - - if (node_->isInst()) { - InstNode* node = node_->as(); - - // NOTE: Inlined to remove one additional call per instruction. - dst->setInstOptions(node->instOptions()); - dst->setExtraReg(node->extraReg()); - - const Operand_* op = node->operands(); - const Operand_* opExt = EmitterUtils::noExt; - - uint32_t opCount = node->opCount(); - if (opCount > 3) { - uint32_t i = 4; - opArray[3] = op[3]; - - while (i < opCount) { - opArray[i].copyFrom(op[i]); - i++; - } - while (i < Globals::kMaxOpCount) { - opArray[i].reset(); - i++; - } - opExt = opArray + 3; - } - - err = dst->_emit(node->id(), op[0], op[1], op[2], opExt); - } - else if (node_->isLabel()) { - if (node_->isConstPool()) { - ConstPoolNode* node = node_->as(); - err = dst->embedConstPool(node->label(), node->constPool()); - } - else { - LabelNode* node = node_->as(); - err = dst->bind(node->label()); - } - } - else if (node_->isAlign()) { - AlignNode* node = node_->as(); - err = dst->align(node->alignMode(), node->alignment()); - } - else if (node_->isEmbedData()) { - EmbedDataNode* node = node_->as(); - err = dst->embedDataArray(node->typeId(), node->data(), node->itemCount(), node->repeatCount()); - } - else if (node_->isEmbedLabel()) { - EmbedLabelNode* node = node_->as(); - err = dst->embedLabel(node->label(), node->dataSize()); - } - else if (node_->isEmbedLabelDelta()) { - EmbedLabelDeltaNode* node = node_->as(); - err = dst->embedLabelDelta(node->label(), node->baseLabel(), node->dataSize()); - } - else if (node_->isSection()) { - SectionNode* node = node_->as(); - err = dst->section(_code->sectionById(node->id())); - } - else if (node_->isComment()) { - CommentNode* node = node_->as(); - err = dst->comment(node->inlineComment()); - } - - if (err) break; - node_ = node_->next(); - } while (node_); - - return err; -} - -// ============================================================================ -// [asmjit::BaseBuilder - Events] -// ============================================================================ - -Error BaseBuilder::onAttach(CodeHolder* code) noexcept { - ASMJIT_PROPAGATE(Base::onAttach(code)); - - SectionNode* initialSection; - Error err = sectionNodeOf(&initialSection, 0); - - if (!err) - err = _passes.willGrow(&_allocator, 8); - - if (ASMJIT_UNLIKELY(err)) { - onDetach(code); - return err; - } - - _cursor = initialSection; - _firstNode = initialSection; - _lastNode = initialSection; - initialSection->setFlags(BaseNode::kFlagIsActive); - - return kErrorOk; -} - -Error BaseBuilder::onDetach(CodeHolder* code) noexcept { - BaseBuilder_deletePasses(this); - _sectionNodes.reset(); - _labelNodes.reset(); - - _allocator.reset(&_codeZone); - _codeZone.reset(); - _dataZone.reset(); - _passZone.reset(); - - _nodeFlags = 0; - - _cursor = nullptr; - _firstNode = nullptr; - _lastNode = nullptr; - - return Base::onDetach(code); -} - -// ============================================================================ -// [asmjit::Pass - Construction / Destruction] -// ============================================================================ - -Pass::Pass(const char* name) noexcept - : _name(name) {} -Pass::~Pass() noexcept {} - -ASMJIT_END_NAMESPACE - -#endif // !ASMJIT_NO_BUILDER diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/builder.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/builder.h deleted file mode 100644 index 317bda1..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/builder.h +++ /dev/null @@ -1,1435 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_BUILDER_H_INCLUDED -#define ASMJIT_CORE_BUILDER_H_INCLUDED - -#include "../core/api-config.h" -#ifndef ASMJIT_NO_BUILDER - -#include "../core/assembler.h" -#include "../core/codeholder.h" -#include "../core/constpool.h" -#include "../core/formatter.h" -#include "../core/inst.h" -#include "../core/operand.h" -#include "../core/string.h" -#include "../core/support.h" -#include "../core/type.h" -#include "../core/zone.h" -#include "../core/zonevector.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_builder -//! \{ - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -class BaseBuilder; -class Pass; - -class BaseNode; -class InstNode; -class SectionNode; -class LabelNode; -class AlignNode; -class EmbedDataNode; -class EmbedLabelNode; -class ConstPoolNode; -class CommentNode; -class SentinelNode; -class LabelDeltaNode; - -// Only used by Compiler infrastructure. -class JumpAnnotation; - -// ============================================================================ -// [asmjit::BaseBuilder] -// ============================================================================ - -//! Builder interface. -//! -//! `BaseBuilder` interface was designed to be used as a \ref BaseAssembler -//! replacement in case pre-processing or post-processing of the generated code -//! is required. The code can be modified during or after code generation. Pre -//! or post processing can be done manually or through a \ref Pass object. \ref -//! BaseBuilder stores the emitted code as a double-linked list of nodes, which -//! allows O(1) insertion and removal during processing. -//! -//! Check out architecture specific builders for more details and examples: -//! -//! - \ref x86::Builder - X86/X64 builder implementation. -class ASMJIT_VIRTAPI BaseBuilder : public BaseEmitter { -public: - ASMJIT_NONCOPYABLE(BaseBuilder) - typedef BaseEmitter Base; - - //! Base zone used to allocate nodes and passes. - Zone _codeZone; - //! Data zone used to allocate data and names. - Zone _dataZone; - //! Pass zone, passed to `Pass::run()`. - Zone _passZone; - //! Allocator that uses `_codeZone`. - ZoneAllocator _allocator; - - //! Array of `Pass` objects. - ZoneVector _passes {}; - //! Maps section indexes to `LabelNode` nodes. - ZoneVector _sectionNodes {}; - //! Maps label indexes to `LabelNode` nodes. - ZoneVector _labelNodes {}; - - //! Current node (cursor). - BaseNode* _cursor = nullptr; - //! First node of the current section. - BaseNode* _firstNode = nullptr; - //! Last node of the current section. - BaseNode* _lastNode = nullptr; - - //! Flags assigned to each new node. - uint32_t _nodeFlags = 0; - //! The sections links are dirty (used internally). - bool _dirtySectionLinks = false; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `BaseBuilder` instance. - ASMJIT_API BaseBuilder() noexcept; - //! Destroys the `BaseBuilder` instance. - ASMJIT_API virtual ~BaseBuilder() noexcept; - - //! \} - - //! \name Node Management - //! \{ - - //! Returns the first node. - inline BaseNode* firstNode() const noexcept { return _firstNode; } - //! Returns the last node. - inline BaseNode* lastNode() const noexcept { return _lastNode; } - - //! Allocates and instantiates a new node of type `T` and returns its instance. - //! If the allocation fails `nullptr` is returned. - //! - //! The template argument `T` must be a type that is extends \ref BaseNode. - //! - //! \remarks The pointer returned (if non-null) is owned by the Builder or - //! Compiler. When the Builder/Compiler is destroyed it destroys all nodes - //! it created so no manual memory management is required. - template - inline Error _newNodeT(T** out, Args&&... args) { - *out = _allocator.newT(this, std::forward(args)...); - if (ASMJIT_UNLIKELY(!*out)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - return kErrorOk; - } - - //! Creates a new \ref InstNode. - ASMJIT_API Error _newInstNode(InstNode** out, uint32_t instId, uint32_t instOptions, uint32_t opCount); - //! Creates a new \ref LabelNode. - ASMJIT_API Error _newLabelNode(LabelNode** out); - //! Creates a new \ref AlignNode. - ASMJIT_API Error _newAlignNode(AlignNode** out, uint32_t alignMode, uint32_t alignment); - //! Creates a new \ref EmbedDataNode. - ASMJIT_API Error _newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1); - //! Creates a new \ref ConstPoolNode. - ASMJIT_API Error _newConstPoolNode(ConstPoolNode** out); - //! Creates a new \ref CommentNode. - ASMJIT_API Error _newCommentNode(CommentNode** out, const char* data, size_t size); - - //! Adds `node` after the current and sets the current node to the given `node`. - ASMJIT_API BaseNode* addNode(BaseNode* node) noexcept; - //! Inserts the given `node` after `ref`. - ASMJIT_API BaseNode* addAfter(BaseNode* node, BaseNode* ref) noexcept; - //! Inserts the given `node` before `ref`. - ASMJIT_API BaseNode* addBefore(BaseNode* node, BaseNode* ref) noexcept; - //! Removes the given `node`. - ASMJIT_API BaseNode* removeNode(BaseNode* node) noexcept; - //! Removes multiple nodes. - ASMJIT_API void removeNodes(BaseNode* first, BaseNode* last) noexcept; - - //! Returns the cursor. - //! - //! When the Builder/Compiler is created it automatically creates a '.text' - //! \ref SectionNode, which will be the initial one. When instructions are - //! added they are always added after the cursor and the cursor is changed - //! to be that newly added node. Use `setCursor()` to change where new nodes - //! are inserted. - inline BaseNode* cursor() const noexcept { - return _cursor; - } - - //! Sets the current node to `node` and return the previous one. - ASMJIT_API BaseNode* setCursor(BaseNode* node) noexcept; - - //! Sets the current node without returning the previous node. - //! - //! Only use this function if you are concerned about performance and want - //! this inlined (for example if you set the cursor in a loop, etc...). - inline void _setCursor(BaseNode* node) noexcept { - _cursor = node; - } - - //! \} - - //! \name Section Management - //! \{ - - //! Returns a vector of SectionNode objects. - //! - //! \note If a section of some id is not associated with the Builder/Compiler - //! it would be null, so always check for nulls if you iterate over the vector. - inline const ZoneVector& sectionNodes() const noexcept { - return _sectionNodes; - } - - //! Tests whether the `SectionNode` of the given `sectionId` was registered. - inline bool hasRegisteredSectionNode(uint32_t sectionId) const noexcept { - return sectionId < _sectionNodes.size() && _sectionNodes[sectionId] != nullptr; - } - - //! Returns or creates a `SectionNode` that matches the given `sectionId`. - //! - //! \remarks This function will either get the existing `SectionNode` or create - //! it in case it wasn't created before. You can check whether a section has a - //! registered `SectionNode` by using `BaseBuilder::hasRegisteredSectionNode()`. - ASMJIT_API Error sectionNodeOf(SectionNode** out, uint32_t sectionId); - - ASMJIT_API Error section(Section* section) override; - - //! Returns whether the section links of active section nodes are dirty. You can - //! update these links by calling `updateSectionLinks()` in such case. - inline bool hasDirtySectionLinks() const noexcept { return _dirtySectionLinks; } - - //! Updates links of all active section nodes. - ASMJIT_API void updateSectionLinks() noexcept; - - //! \} - - //! \name Label Management - //! \{ - - //! Returns a vector of \ref LabelNode nodes. - //! - //! \note If a label of some id is not associated with the Builder/Compiler - //! it would be null, so always check for nulls if you iterate over the vector. - inline const ZoneVector& labelNodes() const noexcept { return _labelNodes; } - - //! Tests whether the `LabelNode` of the given `labelId` was registered. - inline bool hasRegisteredLabelNode(uint32_t labelId) const noexcept { - return labelId < _labelNodes.size() && _labelNodes[labelId] != nullptr; - } - - //! \overload - inline bool hasRegisteredLabelNode(const Label& label) const noexcept { - return hasRegisteredLabelNode(label.id()); - } - - //! Gets or creates a \ref LabelNode that matches the given `labelId`. - //! - //! \remarks This function will either get the existing `LabelNode` or create - //! it in case it wasn't created before. You can check whether a label has a - //! registered `LabelNode` by calling \ref BaseBuilder::hasRegisteredLabelNode(). - ASMJIT_API Error labelNodeOf(LabelNode** out, uint32_t labelId); - - //! \overload - inline Error labelNodeOf(LabelNode** out, const Label& label) { - return labelNodeOf(out, label.id()); - } - - //! Registers this \ref LabelNode (internal). - //! - //! This function is used internally to register a newly created `LabelNode` - //! with this instance of Builder/Compiler. Use \ref labelNodeOf() functions - //! to get back \ref LabelNode from a label or its identifier. - ASMJIT_API Error registerLabelNode(LabelNode* node); - - ASMJIT_API Label newLabel() override; - ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) override; - ASMJIT_API Error bind(const Label& label) override; - - //! \} - - //! \name Passes - //! \{ - - //! Returns a vector of `Pass` instances that will be executed by `runPasses()`. - inline const ZoneVector& passes() const noexcept { return _passes; } - - //! Allocates and instantiates a new pass of type `T` and returns its instance. - //! If the allocation fails `nullptr` is returned. - //! - //! The template argument `T` must be a type that is extends \ref Pass. - //! - //! \remarks The pointer returned (if non-null) is owned by the Builder or - //! Compiler. When the Builder/Compiler is destroyed it destroys all passes - //! it created so no manual memory management is required. - template - inline T* newPassT() noexcept { return _codeZone.newT(); } - - //! \overload - template - inline T* newPassT(Args&&... args) noexcept { return _codeZone.newT(std::forward(args)...); } - - template - inline Error addPassT() { return addPass(newPassT()); } - - template - inline Error addPassT(Args&&... args) { return addPass(newPassT(std::forward(args)...)); } - - //! Returns `Pass` by name. - //! - //! If the pass having the given `name` doesn't exist `nullptr` is returned. - ASMJIT_API Pass* passByName(const char* name) const noexcept; - //! Adds `pass` to the list of passes. - ASMJIT_API Error addPass(Pass* pass) noexcept; - //! Removes `pass` from the list of passes and delete it. - ASMJIT_API Error deletePass(Pass* pass) noexcept; - - //! Runs all passes in order. - ASMJIT_API Error runPasses(); - - //! \} - - //! \name Emit - //! \{ - - ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override; - - //! \} - - //! \name Align - //! \{ - - ASMJIT_API Error align(uint32_t alignMode, uint32_t alignment) override; - - //! \} - - //! \name Embed - //! \{ - - ASMJIT_API Error embed(const void* data, size_t dataSize) override; - ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t count, size_t repeat = 1) override; - ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override; - - ASMJIT_API Error embedLabel(const Label& label, size_t dataSize = 0) override; - ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) override; - - //! \} - - //! \name Comment - //! \{ - - ASMJIT_API Error comment(const char* data, size_t size = SIZE_MAX) override; - - //! \} - - //! \name Serialization - //! \{ - - //! Serializes everything the given emitter `dst`. - //! - //! Although not explicitly required the emitter will most probably be of - //! Assembler type. The reason is that there is no known use of serializing - //! nodes held by Builder/Compiler into another Builder-like emitter. - ASMJIT_API Error serializeTo(BaseEmitter* dst); - - //! \} - - //! \name Events - //! \{ - - ASMJIT_API Error onAttach(CodeHolder* code) noexcept override; - ASMJIT_API Error onDetach(CodeHolder* code) noexcept override; - - //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use serializeTo() instead, serialize() is now also an instruction.") - inline Error serialize(BaseEmitter* dst) { - return serializeTo(dst); - } - -#ifndef ASMJIT_NO_LOGGING - ASMJIT_DEPRECATED("Use Formatter::formatNodeList(sb, formatFlags, builder)") - inline Error dump(String& sb, uint32_t formatFlags = 0) const noexcept { - return Formatter::formatNodeList(sb, formatFlags, this); - } -#endif // !ASMJIT_NO_LOGGING -#endif // !ASMJIT_NO_DEPRECATED -}; - -// ============================================================================ -// [asmjit::BaseNode] -// ============================================================================ - -//! Base node. -//! -//! Every node represents a building-block used by \ref BaseBuilder. It can -//! be instruction, data, label, comment, directive, or any other high-level -//! representation that can be transformed to the building blocks mentioned. -//! Every class that inherits \ref BaseBuilder can define its own high-level -//! nodes that can be later lowered to basic nodes like instructions. -class BaseNode { -public: - ASMJIT_NONCOPYABLE(BaseNode) - - union { - struct { - //! Previous node. - BaseNode* _prev; - //! Next node. - BaseNode* _next; - }; - //! Links (an alternative view to previous and next nodes). - BaseNode* _links[2]; - }; - - //! Data shared between all types of nodes. - struct AnyData { - //! Node type, see \ref NodeType. - uint8_t _nodeType; - //! Node flags, see \ref Flags. - uint8_t _nodeFlags; - //! Not used by BaseNode. - uint8_t _reserved0; - //! Not used by BaseNode. - uint8_t _reserved1; - }; - - //! Data used by \ref InstNode. - struct InstData { - //! Node type, see \ref NodeType. - uint8_t _nodeType; - //! Node flags, see \ref Flags. - uint8_t _nodeFlags; - //! Instruction operands count (used). - uint8_t _opCount; - //! Instruction operands capacity (allocated). - uint8_t _opCapacity; - }; - - //! Data used by \ref EmbedDataNode. - struct EmbedData { - //! Node type, see \ref NodeType. - uint8_t _nodeType; - //! Node flags, see \ref Flags. - uint8_t _nodeFlags; - //! Type id, see \ref Type::Id. - uint8_t _typeId; - //! Size of `_typeId`. - uint8_t _typeSize; - }; - - //! Data used by \ref SentinelNode. - struct SentinelData { - //! Node type, see \ref NodeType. - uint8_t _nodeType; - //! Node flags, see \ref Flags. - uint8_t _nodeFlags; - //! Sentinel type. - uint8_t _sentinelType; - //! Not used by BaseNode. - uint8_t _reserved1; - }; - - //! Data that can have different meaning dependning on \ref NodeType. - union { - //! Data useful by any node type. - AnyData _any; - //! Data specific to \ref InstNode. - InstData _inst; - //! Data specific to \ref EmbedDataNode. - EmbedData _embed; - //! Data specific to \ref SentinelNode. - SentinelData _sentinel; - }; - - //! Node position in code (should be unique). - uint32_t _position; - - //! Value reserved for AsmJit users never touched by AsmJit itself. - union { - //! User data as 64-bit integer. - uint64_t _userDataU64; - //! User data as pointer. - void* _userDataPtr; - }; - - //! Data used exclusively by the current `Pass`. - void* _passData; - - //! Inline comment/annotation or nullptr if not used. - const char* _inlineComment; - - //! Type of `BaseNode`. - enum NodeType : uint32_t { - //! Invalid node (internal, don't use). - kNodeNone = 0, - - // [BaseBuilder] - - //! Node is \ref InstNode or \ref InstExNode. - kNodeInst = 1, - //! Node is \ref SectionNode. - kNodeSection = 2, - //! Node is \ref LabelNode. - kNodeLabel = 3, - //! Node is \ref AlignNode. - kNodeAlign = 4, - //! Node is \ref EmbedDataNode. - kNodeEmbedData = 5, - //! Node is \ref EmbedLabelNode. - kNodeEmbedLabel = 6, - //! Node is \ref EmbedLabelDeltaNode. - kNodeEmbedLabelDelta = 7, - //! Node is \ref ConstPoolNode. - kNodeConstPool = 8, - //! Node is \ref CommentNode. - kNodeComment = 9, - //! Node is \ref SentinelNode. - kNodeSentinel = 10, - - // [BaseCompiler] - - //! Node is \ref JumpNode (acts as InstNode). - kNodeJump = 15, - //! Node is \ref FuncNode (acts as LabelNode). - kNodeFunc = 16, - //! Node is \ref FuncRetNode (acts as InstNode). - kNodeFuncRet = 17, - //! Node is \ref InvokeNode (acts as InstNode). - kNodeInvoke = 18, - - // [UserDefined] - - //! First id of a user-defined node. - kNodeUser = 32, - -#ifndef ASMJIT_NO_DEPRECATED - kNodeFuncCall = kNodeInvoke -#endif // !ASMJIT_NO_DEPRECATED - }; - - //! Node flags, specify what the node is and/or does. - enum Flags : uint32_t { - //! Node is code that can be executed (instruction, label, align, etc...). - kFlagIsCode = 0x01u, - //! Node is data that cannot be executed (data, const-pool, etc...). - kFlagIsData = 0x02u, - //! Node is informative, can be removed and ignored. - kFlagIsInformative = 0x04u, - //! Node can be safely removed if unreachable. - kFlagIsRemovable = 0x08u, - //! Node does nothing when executed (label, align, explicit nop). - kFlagHasNoEffect = 0x10u, - //! Node is an instruction or acts as it. - kFlagActsAsInst = 0x20u, - //! Node is a label or acts as it. - kFlagActsAsLabel = 0x40u, - //! Node is active (part of the code). - kFlagIsActive = 0x80u - }; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `BaseNode` - always use `BaseBuilder` to allocate nodes. - ASMJIT_INLINE BaseNode(BaseBuilder* cb, uint32_t type, uint32_t flags = 0) noexcept { - _prev = nullptr; - _next = nullptr; - _any._nodeType = uint8_t(type); - _any._nodeFlags = uint8_t(flags | cb->_nodeFlags); - _any._reserved0 = 0; - _any._reserved1 = 0; - _position = 0; - _userDataU64 = 0; - _passData = nullptr; - _inlineComment = nullptr; - } - - //! \} - - //! \name Accessors - //! \{ - - //! Casts this node to `T*`. - template - inline T* as() noexcept { return static_cast(this); } - //! Casts this node to `const T*`. - template - inline const T* as() const noexcept { return static_cast(this); } - - //! Returns previous node or `nullptr` if this node is either first or not - //! part of Builder/Compiler node-list. - inline BaseNode* prev() const noexcept { return _prev; } - //! Returns next node or `nullptr` if this node is either last or not part - //! of Builder/Compiler node-list. - inline BaseNode* next() const noexcept { return _next; } - - //! Returns the type of the node, see `NodeType`. - inline uint32_t type() const noexcept { return _any._nodeType; } - - //! Sets the type of the node, see `NodeType` (internal). - //! - //! \remarks You should never set a type of a node to anything else than the - //! initial value. This function is only provided for users that use custom - //! nodes and need to change the type either during construction or later. - inline void setType(uint32_t type) noexcept { _any._nodeType = uint8_t(type); } - - //! Tests whether this node is either `InstNode` or extends it. - inline bool isInst() const noexcept { return hasFlag(kFlagActsAsInst); } - //! Tests whether this node is `SectionNode`. - inline bool isSection() const noexcept { return type() == kNodeSection; } - //! Tests whether this node is either `LabelNode` or extends it. - inline bool isLabel() const noexcept { return hasFlag(kFlagActsAsLabel); } - //! Tests whether this node is `AlignNode`. - inline bool isAlign() const noexcept { return type() == kNodeAlign; } - //! Tests whether this node is `EmbedDataNode`. - inline bool isEmbedData() const noexcept { return type() == kNodeEmbedData; } - //! Tests whether this node is `EmbedLabelNode`. - inline bool isEmbedLabel() const noexcept { return type() == kNodeEmbedLabel; } - //! Tests whether this node is `EmbedLabelDeltaNode`. - inline bool isEmbedLabelDelta() const noexcept { return type() == kNodeEmbedLabelDelta; } - //! Tests whether this node is `ConstPoolNode`. - inline bool isConstPool() const noexcept { return type() == kNodeConstPool; } - //! Tests whether this node is `CommentNode`. - inline bool isComment() const noexcept { return type() == kNodeComment; } - //! Tests whether this node is `SentinelNode`. - inline bool isSentinel() const noexcept { return type() == kNodeSentinel; } - - //! Tests whether this node is `FuncNode`. - inline bool isFunc() const noexcept { return type() == kNodeFunc; } - //! Tests whether this node is `FuncRetNode`. - inline bool isFuncRet() const noexcept { return type() == kNodeFuncRet; } - //! Tests whether this node is `InvokeNode`. - inline bool isInvoke() const noexcept { return type() == kNodeInvoke; } - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use isInvoke") - inline bool isFuncCall() const noexcept { return isInvoke(); } -#endif // !ASMJIT_NO_DEPRECATED - - //! Returns the node flags, see \ref Flags. - inline uint32_t flags() const noexcept { return _any._nodeFlags; } - //! Tests whether the node has the given `flag` set. - inline bool hasFlag(uint32_t flag) const noexcept { return (uint32_t(_any._nodeFlags) & flag) != 0; } - //! Replaces node flags with `flags`. - inline void setFlags(uint32_t flags) noexcept { _any._nodeFlags = uint8_t(flags); } - //! Adds the given `flags` to node flags. - inline void addFlags(uint32_t flags) noexcept { _any._nodeFlags = uint8_t(_any._nodeFlags | flags); } - //! Clears the given `flags` from node flags. - inline void clearFlags(uint32_t flags) noexcept { _any._nodeFlags = uint8_t(_any._nodeFlags & (flags ^ 0xFF)); } - - //! Tests whether the node is code that can be executed. - inline bool isCode() const noexcept { return hasFlag(kFlagIsCode); } - //! Tests whether the node is data that cannot be executed. - inline bool isData() const noexcept { return hasFlag(kFlagIsData); } - //! Tests whether the node is informative only (is never encoded like comment, etc...). - inline bool isInformative() const noexcept { return hasFlag(kFlagIsInformative); } - //! Tests whether the node is removable if it's in an unreachable code block. - inline bool isRemovable() const noexcept { return hasFlag(kFlagIsRemovable); } - //! Tests whether the node has no effect when executed (label, .align, nop, ...). - inline bool hasNoEffect() const noexcept { return hasFlag(kFlagHasNoEffect); } - //! Tests whether the node is part of the code. - inline bool isActive() const noexcept { return hasFlag(kFlagIsActive); } - - //! Tests whether the node has a position assigned. - //! - //! \remarks Returns `true` if node position is non-zero. - inline bool hasPosition() const noexcept { return _position != 0; } - //! Returns node position. - inline uint32_t position() const noexcept { return _position; } - //! Sets node position. - //! - //! Node position is a 32-bit unsigned integer that is used by Compiler to - //! track where the node is relatively to the start of the function. It doesn't - //! describe a byte position in a binary, instead it's just a pseudo position - //! used by liveness analysis and other tools around Compiler. - //! - //! If you don't use Compiler then you may use `position()` and `setPosition()` - //! freely for your own purposes if the 32-bit value limit is okay for you. - inline void setPosition(uint32_t position) noexcept { _position = position; } - - //! Returns user data casted to `T*`. - //! - //! User data is decicated to be used only by AsmJit users and not touched - //! by the library. The data has a pointer size so you can either store a - //! pointer or `intptr_t` value through `setUserDataAsIntPtr()`. - template - inline T* userDataAsPtr() const noexcept { return static_cast(_userDataPtr); } - //! Returns user data casted to `int64_t`. - inline int64_t userDataAsInt64() const noexcept { return int64_t(_userDataU64); } - //! Returns user data casted to `uint64_t`. - inline uint64_t userDataAsUInt64() const noexcept { return _userDataU64; } - - //! Sets user data to `data`. - template - inline void setUserDataAsPtr(T* data) noexcept { _userDataPtr = static_cast(data); } - //! Sets used data to the given 64-bit signed `value`. - inline void setUserDataAsInt64(int64_t value) noexcept { _userDataU64 = uint64_t(value); } - //! Sets used data to the given 64-bit unsigned `value`. - inline void setUserDataAsUInt64(uint64_t value) noexcept { _userDataU64 = value; } - - //! Resets user data to zero / nullptr. - inline void resetUserData() noexcept { _userDataU64 = 0; } - - //! Tests whether the node has an associated pass data. - inline bool hasPassData() const noexcept { return _passData != nullptr; } - //! Returns the node pass data - data used during processing & transformations. - template - inline T* passData() const noexcept { return (T*)_passData; } - //! Sets the node pass data to `data`. - template - inline void setPassData(T* data) noexcept { _passData = (void*)data; } - //! Resets the node pass data to nullptr. - inline void resetPassData() noexcept { _passData = nullptr; } - - //! Tests whether the node has an inline comment/annotation. - inline bool hasInlineComment() const noexcept { return _inlineComment != nullptr; } - //! Returns an inline comment/annotation string. - inline const char* inlineComment() const noexcept { return _inlineComment; } - //! Sets an inline comment/annotation string to `s`. - inline void setInlineComment(const char* s) noexcept { _inlineComment = s; } - //! Resets an inline comment/annotation string to nullptr. - inline void resetInlineComment() noexcept { _inlineComment = nullptr; } - - //! \} -}; - -// ============================================================================ -// [asmjit::InstNode] -// ============================================================================ - -//! Instruction node. -//! -//! Wraps an instruction with its options and operands. -class InstNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(InstNode) - - enum : uint32_t { - //! Count of embedded operands per `InstNode` that are always allocated as - //! a part of the instruction. Minimum embedded operands is 4, but in 32-bit - //! more pointers are smaller and we can embed 5. The rest (up to 6 operands) - //! is always stored in `InstExNode`. - kBaseOpCapacity = uint32_t((128 - sizeof(BaseNode) - sizeof(BaseInst)) / sizeof(Operand_)) - }; - - //! Base instruction data. - BaseInst _baseInst; - //! First 4 or 5 operands (indexed from 0). - Operand_ _opArray[kBaseOpCapacity]; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `InstNode` instance. - ASMJIT_INLINE InstNode(BaseBuilder* cb, uint32_t instId, uint32_t options, uint32_t opCount, uint32_t opCapacity = kBaseOpCapacity) noexcept - : BaseNode(cb, kNodeInst, kFlagIsCode | kFlagIsRemovable | kFlagActsAsInst), - _baseInst(instId, options) { - _inst._opCapacity = uint8_t(opCapacity); - _inst._opCount = uint8_t(opCount); - } - - //! \cond INTERNAL - //! Reset all built-in operands, including `extraReg`. - inline void _resetOps() noexcept { - _baseInst.resetExtraReg(); - resetOpRange(0, opCapacity()); - } - //! \endcond - - //! \} - - //! \name Accessors - //! \{ - - inline BaseInst& baseInst() noexcept { return _baseInst; } - inline const BaseInst& baseInst() const noexcept { return _baseInst; } - - //! Returns the instruction id, see `BaseInst::Id`. - inline uint32_t id() const noexcept { return _baseInst.id(); } - //! Sets the instruction id to `id`, see `BaseInst::Id`. - inline void setId(uint32_t id) noexcept { _baseInst.setId(id); } - - //! Returns instruction options. - inline uint32_t instOptions() const noexcept { return _baseInst.options(); } - //! Sets instruction options. - inline void setInstOptions(uint32_t options) noexcept { _baseInst.setOptions(options); } - //! Adds instruction options. - inline void addInstOptions(uint32_t options) noexcept { _baseInst.addOptions(options); } - //! Clears instruction options. - inline void clearInstOptions(uint32_t options) noexcept { _baseInst.clearOptions(options); } - - //! Tests whether the node has an extra register operand. - inline bool hasExtraReg() const noexcept { return _baseInst.hasExtraReg(); } - //! Returns extra register operand. - inline RegOnly& extraReg() noexcept { return _baseInst.extraReg(); } - //! \overload - inline const RegOnly& extraReg() const noexcept { return _baseInst.extraReg(); } - //! Sets extra register operand to `reg`. - inline void setExtraReg(const BaseReg& reg) noexcept { _baseInst.setExtraReg(reg); } - //! Sets extra register operand to `reg`. - inline void setExtraReg(const RegOnly& reg) noexcept { _baseInst.setExtraReg(reg); } - //! Resets extra register operand. - inline void resetExtraReg() noexcept { _baseInst.resetExtraReg(); } - - //! Returns operand count. - inline uint32_t opCount() const noexcept { return _inst._opCount; } - //! Returns operand capacity. - inline uint32_t opCapacity() const noexcept { return _inst._opCapacity; } - - //! Sets operand count. - inline void setOpCount(uint32_t opCount) noexcept { _inst._opCount = uint8_t(opCount); } - - //! Returns operands array. - inline Operand* operands() noexcept { return (Operand*)_opArray; } - //! Returns operands array (const). - inline const Operand* operands() const noexcept { return (const Operand*)_opArray; } - - //! Returns operand at the given `index`. - inline Operand& op(uint32_t index) noexcept { - ASMJIT_ASSERT(index < opCapacity()); - return _opArray[index].as(); - } - - //! Returns operand at the given `index` (const). - inline const Operand& op(uint32_t index) const noexcept { - ASMJIT_ASSERT(index < opCapacity()); - return _opArray[index].as(); - } - - //! Sets operand at the given `index` to `op`. - inline void setOp(uint32_t index, const Operand_& op) noexcept { - ASMJIT_ASSERT(index < opCapacity()); - _opArray[index].copyFrom(op); - } - - //! Resets operand at the given `index` to none. - inline void resetOp(uint32_t index) noexcept { - ASMJIT_ASSERT(index < opCapacity()); - _opArray[index].reset(); - } - - //! Resets operands at `[start, end)` range. - inline void resetOpRange(uint32_t start, uint32_t end) noexcept { - for (uint32_t i = start; i < end; i++) - _opArray[i].reset(); - } - - //! \} - - //! \name Utilities - //! \{ - - inline bool hasOpType(uint32_t opType) const noexcept { - for (uint32_t i = 0, count = opCount(); i < count; i++) - if (_opArray[i].opType() == opType) - return true; - return false; - } - - inline bool hasRegOp() const noexcept { return hasOpType(Operand::kOpReg); } - inline bool hasMemOp() const noexcept { return hasOpType(Operand::kOpMem); } - inline bool hasImmOp() const noexcept { return hasOpType(Operand::kOpImm); } - inline bool hasLabelOp() const noexcept { return hasOpType(Operand::kOpLabel); } - - inline uint32_t indexOfOpType(uint32_t opType) const noexcept { - uint32_t i = 0; - uint32_t count = opCount(); - - while (i < count) { - if (_opArray[i].opType() == opType) - break; - i++; - } - - return i; - } - - inline uint32_t indexOfMemOp() const noexcept { return indexOfOpType(Operand::kOpMem); } - inline uint32_t indexOfImmOp() const noexcept { return indexOfOpType(Operand::kOpImm); } - inline uint32_t indexOfLabelOp() const noexcept { return indexOfOpType(Operand::kOpLabel); } - - //! \} - - //! \name Rewriting - //! \{ - - //! \cond INTERNAL - inline uint32_t* _getRewriteArray() noexcept { return &_baseInst._extraReg._id; } - inline const uint32_t* _getRewriteArray() const noexcept { return &_baseInst._extraReg._id; } - - ASMJIT_INLINE uint32_t getRewriteIndex(const uint32_t* id) const noexcept { - const uint32_t* array = _getRewriteArray(); - ASMJIT_ASSERT(array <= id); - - size_t index = (size_t)(id - array); - ASMJIT_ASSERT(index < 32); - - return uint32_t(index); - } - - ASMJIT_INLINE void rewriteIdAtIndex(uint32_t index, uint32_t id) noexcept { - uint32_t* array = _getRewriteArray(); - array[index] = id; - } - //! \endcond - - //! \} - - //! \name Static Functions - //! \{ - - //! \cond INTERNAL - static inline uint32_t capacityOfOpCount(uint32_t opCount) noexcept { - return opCount <= kBaseOpCapacity ? kBaseOpCapacity : Globals::kMaxOpCount; - } - - static inline size_t nodeSizeOfOpCapacity(uint32_t opCapacity) noexcept { - size_t base = sizeof(InstNode) - kBaseOpCapacity * sizeof(Operand); - return base + opCapacity * sizeof(Operand); - } - //! \endcond - - //! \} -}; - -// ============================================================================ -// [asmjit::InstExNode] -// ============================================================================ - -//! Instruction node with maximum number of operands. -//! -//! This node is created automatically by Builder/Compiler in case that the -//! required number of operands exceeds the default capacity of `InstNode`. -class InstExNode : public InstNode { -public: - ASMJIT_NONCOPYABLE(InstExNode) - - //! Continued `_opArray[]` to hold up to `kMaxOpCount` operands. - Operand_ _opArrayEx[Globals::kMaxOpCount - kBaseOpCapacity]; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `InstExNode` instance. - inline InstExNode(BaseBuilder* cb, uint32_t instId, uint32_t options, uint32_t opCapacity = Globals::kMaxOpCount) noexcept - : InstNode(cb, instId, options, opCapacity) {} - - //! \} -}; - -// ============================================================================ -// [asmjit::SectionNode] -// ============================================================================ - -//! Section node. -class SectionNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(SectionNode) - - //! Section id. - uint32_t _id; - - //! Next section node that follows this section. - //! - //! This link is only valid when the section is active (is part of the code) - //! and when `Builder::hasDirtySectionLinks()` returns `false`. If you intend - //! to use this field you should always call `Builder::updateSectionLinks()` - //! before you do so. - SectionNode* _nextSection; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `SectionNode` instance. - inline SectionNode(BaseBuilder* cb, uint32_t id = 0) noexcept - : BaseNode(cb, kNodeSection, kFlagHasNoEffect), - _id(id), - _nextSection(nullptr) {} - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the section id. - inline uint32_t id() const noexcept { return _id; } - - //! \} -}; - -// ============================================================================ -// [asmjit::LabelNode] -// ============================================================================ - -//! Label node. -class LabelNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(LabelNode) - - //! Label identifier. - uint32_t _labelId; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `LabelNode` instance. - inline LabelNode(BaseBuilder* cb, uint32_t labelId = 0) noexcept - : BaseNode(cb, kNodeLabel, kFlagHasNoEffect | kFlagActsAsLabel), - _labelId(labelId) {} - - //! \} - - //! \name Accessors - //! \{ - - //! Returns \ref Label representation of the \ref LabelNode. - inline Label label() const noexcept { return Label(_labelId); } - //! Returns the id of the label. - inline uint32_t labelId() const noexcept { return _labelId; } - - //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use labelId() instead") - inline uint32_t id() const noexcept { return labelId(); } -#endif // !ASMJIT_NO_DEPRECATED -}; - -// ============================================================================ -// [asmjit::AlignNode] -// ============================================================================ - -//! Align directive (BaseBuilder). -//! -//! Wraps `.align` directive. -class AlignNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(AlignNode) - - //! Align mode, see `AlignMode`. - uint32_t _alignMode; - //! Alignment (in bytes). - uint32_t _alignment; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `AlignNode` instance. - inline AlignNode(BaseBuilder* cb, uint32_t alignMode, uint32_t alignment) noexcept - : BaseNode(cb, kNodeAlign, kFlagIsCode | kFlagHasNoEffect), - _alignMode(alignMode), - _alignment(alignment) {} - - //! \} - - //! \name Accessors - //! \{ - - //! Returns align mode. - inline uint32_t alignMode() const noexcept { return _alignMode; } - //! Sets align mode to `alignMode`. - inline void setAlignMode(uint32_t alignMode) noexcept { _alignMode = alignMode; } - - //! Returns align offset in bytes. - inline uint32_t alignment() const noexcept { return _alignment; } - //! Sets align offset in bytes to `offset`. - inline void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; } - - //! \} -}; - -// ============================================================================ -// [asmjit::EmbedDataNode] -// ============================================================================ - -//! Embed data node. -//! -//! Wraps `.data` directive. The node contains data that will be placed at the -//! node's position in the assembler stream. The data is considered to be RAW; -//! no analysis nor byte-order conversion is performed on RAW data. -class EmbedDataNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(EmbedDataNode) - - enum : uint32_t { - kInlineBufferSize = 128 - (sizeof(BaseNode) + sizeof(size_t) * 2) - }; - - size_t _itemCount; - size_t _repeatCount; - - union { - uint8_t* _externalData; - uint8_t _inlineData[kInlineBufferSize]; - }; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `EmbedDataNode` instance. - inline EmbedDataNode(BaseBuilder* cb) noexcept - : BaseNode(cb, kNodeEmbedData, kFlagIsData), - _itemCount(0), - _repeatCount(0) { - _embed._typeId = uint8_t(Type::kIdU8), - _embed._typeSize = uint8_t(1); - memset(_inlineData, 0, kInlineBufferSize); - } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns \ref Type::Id of the data. - inline uint32_t typeId() const noexcept { return _embed._typeId; } - //! Returns the size of a single data element. - inline uint32_t typeSize() const noexcept { return _embed._typeSize; } - - //! Returns a pointer to the data casted to `uint8_t`. - inline uint8_t* data() const noexcept { - return dataSize() <= kInlineBufferSize ? const_cast(_inlineData) : _externalData; - } - - //! Returns a pointer to the data casted to `T`. - template - inline T* dataAs() const noexcept { return reinterpret_cast(data()); } - - //! Returns the number of (typed) items in the array. - inline size_t itemCount() const noexcept { return _itemCount; } - - //! Returns how many times the data is repeated (default 1). - //! - //! Repeated data is useful when defining constants for SIMD, for example. - inline size_t repeatCount() const noexcept { return _repeatCount; } - - //! Returns the size of the data, not considering the number of times it repeats. - //! - //! \note The returned value is the same as `typeSize() * itemCount()`. - inline size_t dataSize() const noexcept { return typeSize() * _itemCount; } - - //! \} -}; - -// ============================================================================ -// [asmjit::EmbedLabelNode] -// ============================================================================ - -//! Label data node. -class EmbedLabelNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(EmbedLabelNode) - - uint32_t _labelId; - uint32_t _dataSize; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `EmbedLabelNode` instance. - inline EmbedLabelNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t dataSize = 0) noexcept - : BaseNode(cb, kNodeEmbedLabel, kFlagIsData), - _labelId(labelId), - _dataSize(dataSize) {} - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the label to embed as \ref Label operand. - inline Label label() const noexcept { return Label(_labelId); } - //! Returns the id of the label. - inline uint32_t labelId() const noexcept { return _labelId; } - - //! Sets the label id from `label` operand. - inline void setLabel(const Label& label) noexcept { setLabelId(label.id()); } - //! Sets the label id (use with caution, improper use can break a lot of things). - inline void setLabelId(uint32_t labelId) noexcept { _labelId = labelId; } - - //! Returns the data size. - inline uint32_t dataSize() const noexcept { return _dataSize; } - //! Sets the data size. - inline void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; } - - //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use labelId() instead") - inline uint32_t id() const noexcept { return labelId(); } -#endif // !ASMJIT_NO_DEPRECATED -}; - -// ============================================================================ -// [asmjit::EmbedLabelDeltaNode] -// ============================================================================ - -//! Label data node. -class EmbedLabelDeltaNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(EmbedLabelDeltaNode) - - uint32_t _labelId; - uint32_t _baseLabelId; - uint32_t _dataSize; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `EmbedLabelDeltaNode` instance. - inline EmbedLabelDeltaNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t baseLabelId = 0, uint32_t dataSize = 0) noexcept - : BaseNode(cb, kNodeEmbedLabelDelta, kFlagIsData), - _labelId(labelId), - _baseLabelId(baseLabelId), - _dataSize(dataSize) {} - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the label as `Label` operand. - inline Label label() const noexcept { return Label(_labelId); } - //! Returns the id of the label. - inline uint32_t labelId() const noexcept { return _labelId; } - - //! Sets the label id from `label` operand. - inline void setLabel(const Label& label) noexcept { setLabelId(label.id()); } - //! Sets the label id. - inline void setLabelId(uint32_t labelId) noexcept { _labelId = labelId; } - - //! Returns the base label as `Label` operand. - inline Label baseLabel() const noexcept { return Label(_baseLabelId); } - //! Returns the id of the base label. - inline uint32_t baseLabelId() const noexcept { return _baseLabelId; } - - //! Sets the base label id from `label` operand. - inline void setBaseLabel(const Label& baseLabel) noexcept { setBaseLabelId(baseLabel.id()); } - //! Sets the base label id. - inline void setBaseLabelId(uint32_t baseLabelId) noexcept { _baseLabelId = baseLabelId; } - - //! Returns the size of the embedded label address. - inline uint32_t dataSize() const noexcept { return _dataSize; } - //! Sets the size of the embedded label address. - inline void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; } - - //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use labelId() instead") - inline uint32_t id() const noexcept { return labelId(); } - - ASMJIT_DEPRECATED("Use setLabelId() instead") - inline void setId(uint32_t id) noexcept { setLabelId(id); } - - ASMJIT_DEPRECATED("Use baseLabelId() instead") - inline uint32_t baseId() const noexcept { return baseLabelId(); } - - ASMJIT_DEPRECATED("Use setBaseLabelId() instead") - inline void setBaseId(uint32_t id) noexcept { setBaseLabelId(id); } -#endif // !ASMJIT_NO_DEPRECATED -}; - -// ============================================================================ -// [asmjit::ConstPoolNode] -// ============================================================================ - -//! A node that wraps `ConstPool`. -class ConstPoolNode : public LabelNode { -public: - ASMJIT_NONCOPYABLE(ConstPoolNode) - - ConstPool _constPool; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `ConstPoolNode` instance. - inline ConstPoolNode(BaseBuilder* cb, uint32_t id = 0) noexcept - : LabelNode(cb, id), - _constPool(&cb->_codeZone) { - - setType(kNodeConstPool); - addFlags(kFlagIsData); - clearFlags(kFlagIsCode | kFlagHasNoEffect); - } - - //! \} - - //! \name Accessors - //! \{ - - //! Tests whether the constant-pool is empty. - inline bool empty() const noexcept { return _constPool.empty(); } - //! Returns the size of the constant-pool in bytes. - inline size_t size() const noexcept { return _constPool.size(); } - //! Returns minimum alignment. - inline size_t alignment() const noexcept { return _constPool.alignment(); } - - //! Returns the wrapped `ConstPool` instance. - inline ConstPool& constPool() noexcept { return _constPool; } - //! Returns the wrapped `ConstPool` instance (const). - inline const ConstPool& constPool() const noexcept { return _constPool; } - - //! \} - - //! \name Utilities - //! \{ - - //! See `ConstPool::add()`. - inline Error add(const void* data, size_t size, size_t& dstOffset) noexcept { - return _constPool.add(data, size, dstOffset); - } - - //! \} -}; - -// ============================================================================ -// [asmjit::CommentNode] -// ============================================================================ - -//! Comment node. -class CommentNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(CommentNode) - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `CommentNode` instance. - inline CommentNode(BaseBuilder* cb, const char* comment) noexcept - : BaseNode(cb, kNodeComment, kFlagIsInformative | kFlagHasNoEffect | kFlagIsRemovable) { - _inlineComment = comment; - } - - //! \} -}; - -// ============================================================================ -// [asmjit::SentinelNode] -// ============================================================================ - -//! Sentinel node. -//! -//! Sentinel is a marker that is completely ignored by the code builder. It's -//! used to remember a position in a code as it never gets removed by any pass. -class SentinelNode : public BaseNode { -public: - ASMJIT_NONCOPYABLE(SentinelNode) - - //! Type of the sentinel (purery informative purpose). - enum SentinelType : uint32_t { - //! Type of the sentinel is not known. - kSentinelUnknown = 0u, - //! This is a sentinel used at the end of \ref FuncNode. - kSentinelFuncEnd = 1u - }; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `SentinelNode` instance. - inline SentinelNode(BaseBuilder* cb, uint32_t sentinelType = kSentinelUnknown) noexcept - : BaseNode(cb, kNodeSentinel, kFlagIsInformative | kFlagHasNoEffect) { - - _sentinel._sentinelType = uint8_t(sentinelType); - } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the type of the sentinel. - inline uint32_t sentinelType() const noexcept { - return _sentinel._sentinelType; - } - - //! Sets the type of the sentinel. - inline void setSentinelType(uint32_t type) noexcept { - _sentinel._sentinelType = uint8_t(type); - } - - //! \} -}; - -// ============================================================================ -// [asmjit::Pass] -// ============================================================================ - -//! Pass can be used to implement code transformations, analysis, and lowering. -class ASMJIT_VIRTAPI Pass { -public: - ASMJIT_BASE_CLASS(Pass) - ASMJIT_NONCOPYABLE(Pass) - - //! BaseBuilder this pass is assigned to. - BaseBuilder* _cb = nullptr; - //! Name of the pass. - const char* _name = nullptr; - - //! \name Construction & Destruction - //! \{ - - ASMJIT_API Pass(const char* name) noexcept; - ASMJIT_API virtual ~Pass() noexcept; - - //! \} - - //! \name Accessors - //! \{ - - //! Returns \ref BaseBuilder associated with the pass. - inline const BaseBuilder* cb() const noexcept { return _cb; } - //! Returns the name of the pass. - inline const char* name() const noexcept { return _name; } - - //! \} - - //! \name Pass Interface - //! \{ - - //! Processes the code stored in Builder or Compiler. - //! - //! This is the only function that is called by the `BaseBuilder` to process - //! the code. It passes `zone`, which will be reset after the `run()` finishes. - virtual Error run(Zone* zone, Logger* logger) = 0; - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // !ASMJIT_NO_BUILDER -#endif // ASMJIT_CORE_BUILDER_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codebuffer.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codebuffer.h deleted file mode 100644 index 76c86b1..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codebuffer.h +++ /dev/null @@ -1,126 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_CODEBUFFER_H_INCLUDED -#define ASMJIT_CORE_CODEBUFFER_H_INCLUDED - -#include "../core/globals.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [asmjit::CodeBuffer] -// ============================================================================ - -//! Code or data buffer. -struct CodeBuffer { - //! The content of the buffer (data). - uint8_t* _data; - //! Number of bytes of `data` used. - size_t _size; - //! Buffer capacity (in bytes). - size_t _capacity; - //! Buffer flags. - uint32_t _flags; - - //! Code buffer flags. - enum Flags : uint32_t { - //! Buffer is external (not allocated by asmjit). - kFlagIsExternal = 0x00000001u, - //! Buffer is fixed (cannot be reallocated). - kFlagIsFixed = 0x00000002u - }; - - //! \name Overloaded Operators - //! \{ - - //! Returns a referebce to the byte at the given `index`. - inline uint8_t& operator[](size_t index) noexcept { - ASMJIT_ASSERT(index < _size); - return _data[index]; - } - //! \overload - inline const uint8_t& operator[](size_t index) const noexcept { - ASMJIT_ASSERT(index < _size); - return _data[index]; - } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns code buffer flags, see \ref Flags. - inline uint32_t flags() const noexcept { return _flags; } - //! Tests whether the code buffer has the given `flag` set. - inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; } - - //! Tests whether this code buffer has a fixed size. - //! - //! Fixed size means that the code buffer is fixed and cannot grow. - inline bool isFixed() const noexcept { return hasFlag(kFlagIsFixed); } - - //! Tests whether the data in this code buffer is external. - //! - //! External data can only be provided by users, it's never used by AsmJit. - inline bool isExternal() const noexcept { return hasFlag(kFlagIsExternal); } - - //! Tests whether the data in this code buffer is allocated (non-null). - inline bool isAllocated() const noexcept { return _data != nullptr; } - - //! Tests whether the code buffer is empty. - inline bool empty() const noexcept { return !_size; } - - //! Returns the size of the data. - inline size_t size() const noexcept { return _size; } - //! Returns the capacity of the data. - inline size_t capacity() const noexcept { return _capacity; } - - //! Returns the pointer to the data the buffer references. - inline uint8_t* data() noexcept { return _data; } - //! \overload - inline const uint8_t* data() const noexcept { return _data; } - - //! \} - - //! \name Iterators - //! \{ - - inline uint8_t* begin() noexcept { return _data; } - inline const uint8_t* begin() const noexcept { return _data; } - - inline uint8_t* end() noexcept { return _data + _size; } - inline const uint8_t* end() const noexcept { return _data + _size; } - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_CODEBUFFER_H_INCLUDED - diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codeholder.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codeholder.cpp deleted file mode 100644 index 3c4154e..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codeholder.cpp +++ /dev/null @@ -1,1150 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/assembler.h" -#include "../core/codewriter_p.h" -#include "../core/logger.h" -#include "../core/support.h" - -#include -#include - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [Globals] -// ============================================================================ - -static const char CodeHolder_addrTabName[] = ".addrtab"; - -//! Encode MOD byte. -static inline uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) noexcept { - return (m << 6) | (o << 3) | rm; -} - -// ============================================================================ -// [asmjit::LabelLinkIterator] -// ============================================================================ - -class LabelLinkIterator { -public: - ASMJIT_INLINE LabelLinkIterator(LabelEntry* le) noexcept { reset(le); } - - ASMJIT_INLINE explicit operator bool() const noexcept { return isValid(); } - ASMJIT_INLINE bool isValid() const noexcept { return _link != nullptr; } - - ASMJIT_INLINE LabelLink* link() const noexcept { return _link; } - ASMJIT_INLINE LabelLink* operator->() const noexcept { return _link; } - - ASMJIT_INLINE void reset(LabelEntry* le) noexcept { - _pPrev = &le->_links; - _link = *_pPrev; - } - - ASMJIT_INLINE void next() noexcept { - _pPrev = &_link->next; - _link = *_pPrev; - } - - ASMJIT_INLINE void resolveAndNext(CodeHolder* code) noexcept { - LabelLink* linkToDelete = _link; - - _link = _link->next; - *_pPrev = _link; - - code->_unresolvedLinkCount--; - code->_allocator.release(linkToDelete, sizeof(LabelLink)); - } - - LabelLink** _pPrev; - LabelLink* _link; -}; - -// ============================================================================ -// [asmjit::CodeHolder - Utilities] -// ============================================================================ - -static void CodeHolder_resetInternal(CodeHolder* self, uint32_t resetPolicy) noexcept { - uint32_t i; - const ZoneVector& emitters = self->emitters(); - - i = emitters.size(); - while (i) - self->detach(emitters[--i]); - - // Reset everything into its construction state. - self->_environment.reset(); - self->_baseAddress = Globals::kNoBaseAddress; - self->_logger = nullptr; - self->_errorHandler = nullptr; - - // Reset all sections. - uint32_t numSections = self->_sections.size(); - for (i = 0; i < numSections; i++) { - Section* section = self->_sections[i]; - if (section->_buffer.data() && !section->_buffer.isExternal()) - ::free(section->_buffer._data); - section->_buffer._data = nullptr; - section->_buffer._capacity = 0; - } - - // Reset zone allocator and all containers using it. - ZoneAllocator* allocator = self->allocator(); - - self->_emitters.reset(); - self->_namedLabels.reset(); - self->_relocations.reset(); - self->_labelEntries.reset(); - self->_sections.reset(); - self->_sectionsByOrder.reset(); - - self->_unresolvedLinkCount = 0; - self->_addressTableSection = nullptr; - self->_addressTableEntries.reset(); - - allocator->reset(&self->_zone); - self->_zone.reset(resetPolicy); -} - -static void CodeHolder_onSettingsUpdated(CodeHolder* self) noexcept { - // Notify all attached emitters about a settings update. - for (BaseEmitter* emitter : self->emitters()) { - emitter->onSettingsUpdated(); - } -} - -// ============================================================================ -// [asmjit::CodeHolder - Construction / Destruction] -// ============================================================================ - -CodeHolder::CodeHolder() noexcept - : _environment(), - _baseAddress(Globals::kNoBaseAddress), - _logger(nullptr), - _errorHandler(nullptr), - _zone(16384 - Zone::kBlockOverhead), - _allocator(&_zone), - _unresolvedLinkCount(0), - _addressTableSection(nullptr) {} - -CodeHolder::~CodeHolder() noexcept { - CodeHolder_resetInternal(this, Globals::kResetHard); -} - -// ============================================================================ -// [asmjit::CodeHolder - Init / Reset] -// ============================================================================ - -inline void CodeHolder_setSectionDefaultName( - Section* section, - char c0 = 0, char c1 = 0, char c2 = 0, char c3 = 0, - char c4 = 0, char c5 = 0, char c6 = 0, char c7 = 0) noexcept { - - section->_name.u32[0] = Support::bytepack32_4x8(uint8_t(c0), uint8_t(c1), uint8_t(c2), uint8_t(c3)); - section->_name.u32[1] = Support::bytepack32_4x8(uint8_t(c4), uint8_t(c5), uint8_t(c6), uint8_t(c7)); -} - -Error CodeHolder::init(const Environment& environment, uint64_t baseAddress) noexcept { - // Cannot reinitialize if it's locked or there is one or more emitter attached. - if (isInitialized()) - return DebugUtils::errored(kErrorAlreadyInitialized); - - // If we are just initializing there should be no emitters attached. - ASMJIT_ASSERT(_emitters.empty()); - - // Create a default section and insert it to the `_sections` array. - Error err = _sections.willGrow(&_allocator) | - _sectionsByOrder.willGrow(&_allocator); - if (err == kErrorOk) { - Section* section = _allocator.allocZeroedT
(); - if (ASMJIT_LIKELY(section)) { - section->_flags = Section::kFlagExec | Section::kFlagConst; - CodeHolder_setSectionDefaultName(section, '.', 't', 'e', 'x', 't'); - _sections.appendUnsafe(section); - _sectionsByOrder.appendUnsafe(section); - } - else { - err = DebugUtils::errored(kErrorOutOfMemory); - } - } - - if (ASMJIT_UNLIKELY(err)) { - _zone.reset(); - return err; - } - else { - _environment = environment; - _baseAddress = baseAddress; - return kErrorOk; - } -} - -void CodeHolder::reset(uint32_t resetPolicy) noexcept { - CodeHolder_resetInternal(this, resetPolicy); -} - -// ============================================================================ -// [asmjit::CodeHolder - Attach / Detach] -// ============================================================================ - -Error CodeHolder::attach(BaseEmitter* emitter) noexcept { - // Catch a possible misuse of the API. - if (ASMJIT_UNLIKELY(!emitter)) - return DebugUtils::errored(kErrorInvalidArgument); - - // Invalid emitter, this should not be possible. - uint32_t type = emitter->emitterType(); - if (ASMJIT_UNLIKELY(type == BaseEmitter::kTypeNone || type >= BaseEmitter::kTypeCount)) - return DebugUtils::errored(kErrorInvalidState); - - // This is suspicious, but don't fail if `emitter` is already attached - // to this code holder. This is not error, but it's not recommended. - if (emitter->_code != nullptr) { - if (emitter->_code == this) - return kErrorOk; - return DebugUtils::errored(kErrorInvalidState); - } - - // Reserve the space now as we cannot fail after `onAttach()` succeeded. - ASMJIT_PROPAGATE(_emitters.willGrow(&_allocator, 1)); - ASMJIT_PROPAGATE(emitter->onAttach(this)); - - // Connect CodeHolder <-> BaseEmitter. - ASMJIT_ASSERT(emitter->_code == this); - _emitters.appendUnsafe(emitter); - - return kErrorOk; -} - -Error CodeHolder::detach(BaseEmitter* emitter) noexcept { - if (ASMJIT_UNLIKELY(!emitter)) - return DebugUtils::errored(kErrorInvalidArgument); - - if (ASMJIT_UNLIKELY(emitter->_code != this)) - return DebugUtils::errored(kErrorInvalidState); - - // NOTE: We always detach if we were asked to, if error happens during - // `emitter->onDetach()` we just propagate it, but the BaseEmitter will - // be detached. - Error err = kErrorOk; - if (!emitter->isDestroyed()) - err = emitter->onDetach(this); - - // Disconnect CodeHolder <-> BaseEmitter. - uint32_t index = _emitters.indexOf(emitter); - ASMJIT_ASSERT(index != Globals::kNotFound); - - _emitters.removeAt(index); - emitter->_code = nullptr; - - return err; -} - -// ============================================================================ -// [asmjit::CodeHolder - Logging] -// ============================================================================ - -void CodeHolder::setLogger(Logger* logger) noexcept { -#ifndef ASMJIT_NO_LOGGING - _logger = logger; - CodeHolder_onSettingsUpdated(this); -#else - DebugUtils::unused(logger); -#endif -} - -// ============================================================================ -// [asmjit::CodeHolder - Error Handling] -// ============================================================================ - -void CodeHolder::setErrorHandler(ErrorHandler* errorHandler) noexcept { - _errorHandler = errorHandler; - CodeHolder_onSettingsUpdated(this); -} - -// ============================================================================ -// [asmjit::CodeHolder - Code Buffer] -// ============================================================================ - -static Error CodeHolder_reserveInternal(CodeHolder* self, CodeBuffer* cb, size_t n) noexcept { - uint8_t* oldData = cb->_data; - uint8_t* newData; - - if (oldData && !cb->isExternal()) - newData = static_cast(::realloc(oldData, n)); - else - newData = static_cast(::malloc(n)); - - if (ASMJIT_UNLIKELY(!newData)) - return DebugUtils::errored(kErrorOutOfMemory); - - cb->_data = newData; - cb->_capacity = n; - - // Update pointers used by assemblers, if attached. - for (BaseEmitter* emitter : self->emitters()) { - if (emitter->isAssembler()) { - BaseAssembler* a = static_cast(emitter); - if (&a->_section->_buffer == cb) { - size_t offset = a->offset(); - - a->_bufferData = newData; - a->_bufferEnd = newData + n; - a->_bufferPtr = newData + offset; - } - } - } - - return kErrorOk; -} - -Error CodeHolder::growBuffer(CodeBuffer* cb, size_t n) noexcept { - // The size of the section must be valid. - size_t size = cb->size(); - if (ASMJIT_UNLIKELY(n > std::numeric_limits::max() - size)) - return DebugUtils::errored(kErrorOutOfMemory); - - // We can now check if growing the buffer is really necessary. It's unlikely - // that this function is called while there is still room for `n` bytes. - size_t capacity = cb->capacity(); - size_t required = cb->size() + n; - if (ASMJIT_UNLIKELY(required <= capacity)) - return kErrorOk; - - if (cb->isFixed()) - return DebugUtils::errored(kErrorTooLarge); - - size_t kInitialCapacity = 8096; - if (capacity < kInitialCapacity) - capacity = kInitialCapacity; - else - capacity += Globals::kAllocOverhead; - - do { - size_t old = capacity; - if (capacity < Globals::kGrowThreshold) - capacity *= 2; - else - capacity += Globals::kGrowThreshold; - - // Overflow. - if (ASMJIT_UNLIKELY(old > capacity)) - return DebugUtils::errored(kErrorOutOfMemory); - } while (capacity - Globals::kAllocOverhead < required); - - return CodeHolder_reserveInternal(this, cb, capacity - Globals::kAllocOverhead); -} - -Error CodeHolder::reserveBuffer(CodeBuffer* cb, size_t n) noexcept { - size_t capacity = cb->capacity(); - - if (n <= capacity) - return kErrorOk; - - if (cb->isFixed()) - return DebugUtils::errored(kErrorTooLarge); - - return CodeHolder_reserveInternal(this, cb, n); -} - -// ============================================================================ -// [asmjit::CodeHolder - Sections] -// ============================================================================ - -Error CodeHolder::newSection(Section** sectionOut, const char* name, size_t nameSize, uint32_t flags, uint32_t alignment, int32_t order) noexcept { - *sectionOut = nullptr; - - if (nameSize == SIZE_MAX) - nameSize = strlen(name); - - if (alignment == 0) - alignment = 1; - - if (ASMJIT_UNLIKELY(!Support::isPowerOf2(alignment))) - return DebugUtils::errored(kErrorInvalidArgument); - - if (ASMJIT_UNLIKELY(nameSize > Globals::kMaxSectionNameSize)) - return DebugUtils::errored(kErrorInvalidSectionName); - - uint32_t sectionId = _sections.size(); - if (ASMJIT_UNLIKELY(sectionId == Globals::kInvalidId)) - return DebugUtils::errored(kErrorTooManySections); - - ASMJIT_PROPAGATE(_sections.willGrow(&_allocator)); - ASMJIT_PROPAGATE(_sectionsByOrder.willGrow(&_allocator)); - - Section* section = _allocator.allocZeroedT
(); - if (ASMJIT_UNLIKELY(!section)) - return DebugUtils::errored(kErrorOutOfMemory); - - section->_id = sectionId; - section->_flags = flags; - section->_alignment = alignment; - section->_order = order; - memcpy(section->_name.str, name, nameSize); - - Section** insertPosition = std::lower_bound(_sectionsByOrder.begin(), _sectionsByOrder.end(), section, [](const Section* a, const Section* b) { - return std::make_tuple(a->order(), a->id()) < std::make_tuple(b->order(), b->id()); - }); - - _sections.appendUnsafe(section); - _sectionsByOrder.insertUnsafe((size_t)(insertPosition - _sectionsByOrder.data()), section); - - *sectionOut = section; - return kErrorOk; -} - -Section* CodeHolder::sectionByName(const char* name, size_t nameSize) const noexcept { - if (nameSize == SIZE_MAX) - nameSize = strlen(name); - - // This could be also put in a hash-table similarly like we do with labels, - // however it's questionable as the number of sections should be pretty low - // in general. Create an issue if this becomes a problem. - if (nameSize <= Globals::kMaxSectionNameSize) { - for (Section* section : _sections) - if (memcmp(section->_name.str, name, nameSize) == 0 && section->_name.str[nameSize] == '\0') - return section; - } - - return nullptr; -} - -Section* CodeHolder::ensureAddressTableSection() noexcept { - if (_addressTableSection) - return _addressTableSection; - - newSection(&_addressTableSection, CodeHolder_addrTabName, sizeof(CodeHolder_addrTabName) - 1, 0, _environment.registerSize(), std::numeric_limits::max()); - return _addressTableSection; -} - -Error CodeHolder::addAddressToAddressTable(uint64_t address) noexcept { - AddressTableEntry* entry = _addressTableEntries.get(address); - if (entry) - return kErrorOk; - - Section* section = ensureAddressTableSection(); - if (ASMJIT_UNLIKELY(!section)) - return DebugUtils::errored(kErrorOutOfMemory); - - entry = _zone.newT(address); - if (ASMJIT_UNLIKELY(!entry)) - return DebugUtils::errored(kErrorOutOfMemory); - - _addressTableEntries.insert(entry); - section->_virtualSize += _environment.registerSize(); - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::CodeHolder - Labels / Symbols] -// ============================================================================ - -//! Only used to lookup a label from `_namedLabels`. -class LabelByName { -public: - inline LabelByName(const char* key, size_t keySize, uint32_t hashCode, uint32_t parentId) noexcept - : _key(key), - _keySize(uint32_t(keySize)), - _hashCode(hashCode), - _parentId(parentId) {} - - inline uint32_t hashCode() const noexcept { return _hashCode; } - - inline bool matches(const LabelEntry* entry) const noexcept { - return entry->nameSize() == _keySize && - entry->parentId() == _parentId && - ::memcmp(entry->name(), _key, _keySize) == 0; - } - - const char* _key; - uint32_t _keySize; - uint32_t _hashCode; - uint32_t _parentId; -}; - -// Returns a hash of `name` and fixes `nameSize` if it's `SIZE_MAX`. -static uint32_t CodeHolder_hashNameAndGetSize(const char* name, size_t& nameSize) noexcept { - uint32_t hashCode = 0; - if (nameSize == SIZE_MAX) { - size_t i = 0; - for (;;) { - uint8_t c = uint8_t(name[i]); - if (!c) break; - hashCode = Support::hashRound(hashCode, c); - i++; - } - nameSize = i; - } - else { - for (size_t i = 0; i < nameSize; i++) { - uint8_t c = uint8_t(name[i]); - if (ASMJIT_UNLIKELY(!c)) return DebugUtils::errored(kErrorInvalidLabelName); - hashCode = Support::hashRound(hashCode, c); - } - } - return hashCode; -} - -LabelLink* CodeHolder::newLabelLink(LabelEntry* le, uint32_t sectionId, size_t offset, intptr_t rel, const OffsetFormat& format) noexcept { - LabelLink* link = _allocator.allocT(); - if (ASMJIT_UNLIKELY(!link)) return nullptr; - - link->next = le->_links; - le->_links = link; - - link->sectionId = sectionId; - link->relocId = Globals::kInvalidId; - link->offset = offset; - link->rel = rel; - link->format = format; - - _unresolvedLinkCount++; - return link; -} - -Error CodeHolder::newLabelEntry(LabelEntry** entryOut) noexcept { - *entryOut = nullptr; - - uint32_t labelId = _labelEntries.size(); - if (ASMJIT_UNLIKELY(labelId == Globals::kInvalidId)) - return DebugUtils::errored(kErrorTooManyLabels); - - ASMJIT_PROPAGATE(_labelEntries.willGrow(&_allocator)); - LabelEntry* le = _allocator.allocZeroedT(); - - if (ASMJIT_UNLIKELY(!le)) - return DebugUtils::errored(kErrorOutOfMemory); - - le->_setId(labelId); - le->_parentId = Globals::kInvalidId; - le->_offset = 0; - _labelEntries.appendUnsafe(le); - - *entryOut = le; - return kErrorOk; -} - -Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, uint32_t type, uint32_t parentId) noexcept { - *entryOut = nullptr; - uint32_t hashCode = CodeHolder_hashNameAndGetSize(name, nameSize); - - if (ASMJIT_UNLIKELY(nameSize == 0)) - return DebugUtils::errored(kErrorInvalidLabelName); - - if (ASMJIT_UNLIKELY(nameSize > Globals::kMaxLabelNameSize)) - return DebugUtils::errored(kErrorLabelNameTooLong); - - switch (type) { - case Label::kTypeLocal: - if (ASMJIT_UNLIKELY(parentId >= _labelEntries.size())) - return DebugUtils::errored(kErrorInvalidParentLabel); - - hashCode ^= parentId; - break; - - case Label::kTypeGlobal: - case Label::kTypeExternal: - if (ASMJIT_UNLIKELY(parentId != Globals::kInvalidId)) - return DebugUtils::errored(kErrorNonLocalLabelCannotHaveParent); - break; - - default: - return DebugUtils::errored(kErrorInvalidArgument); - } - - // Don't allow to insert duplicates. Local labels allow duplicates that have - // different id, this is already accomplished by having a different hashes - // between the same label names having different parent labels. - LabelEntry* le = _namedLabels.get(LabelByName(name, nameSize, hashCode, parentId)); - if (ASMJIT_UNLIKELY(le)) - return DebugUtils::errored(kErrorLabelAlreadyDefined); - - Error err = kErrorOk; - uint32_t labelId = _labelEntries.size(); - - if (ASMJIT_UNLIKELY(labelId == Globals::kInvalidId)) - return DebugUtils::errored(kErrorTooManyLabels); - - ASMJIT_PROPAGATE(_labelEntries.willGrow(&_allocator)); - le = _allocator.allocZeroedT(); - - if (ASMJIT_UNLIKELY(!le)) - return DebugUtils::errored(kErrorOutOfMemory); - - le->_hashCode = hashCode; - le->_setId(labelId); - le->_type = uint8_t(type); - le->_parentId = parentId; - le->_offset = 0; - ASMJIT_PROPAGATE(le->_name.setData(&_zone, name, nameSize)); - - _labelEntries.appendUnsafe(le); - _namedLabels.insert(allocator(), le); - - *entryOut = le; - return err; -} - -uint32_t CodeHolder::labelIdByName(const char* name, size_t nameSize, uint32_t parentId) noexcept { - uint32_t hashCode = CodeHolder_hashNameAndGetSize(name, nameSize); - if (ASMJIT_UNLIKELY(!nameSize)) - return 0; - - if (parentId != Globals::kInvalidId) - hashCode ^= parentId; - - LabelEntry* le = _namedLabels.get(LabelByName(name, nameSize, hashCode, parentId)); - return le ? le->id() : uint32_t(Globals::kInvalidId); -} - -ASMJIT_API Error CodeHolder::resolveUnresolvedLinks() noexcept { - if (!hasUnresolvedLinks()) - return kErrorOk; - - Error err = kErrorOk; - for (LabelEntry* le : labelEntries()) { - if (!le->isBound()) - continue; - - LabelLinkIterator link(le); - if (link) { - Support::FastUInt8 of = 0; - Section* toSection = le->section(); - uint64_t toOffset = Support::addOverflow(toSection->offset(), le->offset(), &of); - - do { - uint32_t linkSectionId = link->sectionId; - if (link->relocId == Globals::kInvalidId) { - Section* fromSection = sectionById(linkSectionId); - size_t linkOffset = link->offset; - - CodeBuffer& buf = _sections[linkSectionId]->buffer(); - ASMJIT_ASSERT(linkOffset < buf.size()); - - // Calculate the offset relative to the start of the virtual base. - Support::FastUInt8 localOF = of; - uint64_t fromOffset = Support::addOverflow(fromSection->offset(), linkOffset, &localOF); - int64_t displacement = int64_t(toOffset - fromOffset + uint64_t(int64_t(link->rel))); - - if (!localOF) { - ASMJIT_ASSERT(size_t(linkOffset) < buf.size()); - ASMJIT_ASSERT(buf.size() - size_t(linkOffset) >= link->format.valueSize()); - - // Overwrite a real displacement in the CodeBuffer. - if (CodeWriterUtils::writeOffset(buf._data + linkOffset, displacement, link->format)) { - link.resolveAndNext(this); - continue; - } - } - - err = DebugUtils::errored(kErrorInvalidDisplacement); - // Falls through to `link.next()`. - } - - link.next(); - } while (link); - } - } - - return err; -} - -ASMJIT_API Error CodeHolder::bindLabel(const Label& label, uint32_t toSectionId, uint64_t toOffset) noexcept { - LabelEntry* le = labelEntry(label); - if (ASMJIT_UNLIKELY(!le)) - return DebugUtils::errored(kErrorInvalidLabel); - - if (ASMJIT_UNLIKELY(toSectionId > _sections.size())) - return DebugUtils::errored(kErrorInvalidSection); - - // Label can be bound only once. - if (ASMJIT_UNLIKELY(le->isBound())) - return DebugUtils::errored(kErrorLabelAlreadyBound); - - // Bind the label. - Section* section = _sections[toSectionId]; - le->_section = section; - le->_offset = toOffset; - - Error err = kErrorOk; - CodeBuffer& buf = section->buffer(); - - // Fix all links to this label we have collected so far if they are within - // the same section. We ignore any inter-section links as these have to be - // fixed later. - LabelLinkIterator link(le); - while (link) { - uint32_t linkSectionId = link->sectionId; - size_t linkOffset = link->offset; - - uint32_t relocId = link->relocId; - if (relocId != Globals::kInvalidId) { - // Adjust relocation data only. - RelocEntry* re = _relocations[relocId]; - re->_payload += toOffset; - re->_targetSectionId = toSectionId; - } - else { - if (linkSectionId != toSectionId) { - link.next(); - continue; - } - - ASMJIT_ASSERT(linkOffset < buf.size()); - int64_t displacement = int64_t(toOffset - uint64_t(linkOffset) + uint64_t(int64_t(link->rel))); - - // Size of the value we are going to patch. Only BYTE/DWORD is allowed. - ASMJIT_ASSERT(buf.size() - size_t(linkOffset) >= link->format.regionSize()); - - // Overwrite a real displacement in the CodeBuffer. - if (!CodeWriterUtils::writeOffset(buf._data + linkOffset, displacement, link->format)) { - err = DebugUtils::errored(kErrorInvalidDisplacement); - link.next(); - continue; - } - } - - link.resolveAndNext(this); - } - - return err; -} - -// ============================================================================ -// [asmjit::BaseEmitter - Relocations] -// ============================================================================ - -Error CodeHolder::newRelocEntry(RelocEntry** dst, uint32_t relocType) noexcept { - ASMJIT_PROPAGATE(_relocations.willGrow(&_allocator)); - - uint32_t relocId = _relocations.size(); - if (ASMJIT_UNLIKELY(relocId == Globals::kInvalidId)) - return DebugUtils::errored(kErrorTooManyRelocations); - - RelocEntry* re = _allocator.allocZeroedT(); - if (ASMJIT_UNLIKELY(!re)) - return DebugUtils::errored(kErrorOutOfMemory); - - re->_id = relocId; - re->_relocType = uint8_t(relocType); - re->_sourceSectionId = Globals::kInvalidId; - re->_targetSectionId = Globals::kInvalidId; - _relocations.appendUnsafe(re); - - *dst = re; - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseEmitter - Expression Evaluation] -// ============================================================================ - -static Error CodeHolder_evaluateExpression(CodeHolder* self, Expression* exp, uint64_t* out) noexcept { - uint64_t value[2]; - for (size_t i = 0; i < 2; i++) { - uint64_t v; - switch (exp->valueType[i]) { - case Expression::kValueNone: { - v = 0; - break; - } - - case Expression::kValueConstant: { - v = exp->value[i].constant; - break; - } - - case Expression::kValueLabel: { - LabelEntry* le = exp->value[i].label; - if (!le->isBound()) - return DebugUtils::errored(kErrorExpressionLabelNotBound); - v = le->section()->offset() + le->offset(); - break; - } - - case Expression::kValueExpression: { - Expression* nested = exp->value[i].expression; - ASMJIT_PROPAGATE(CodeHolder_evaluateExpression(self, nested, &v)); - break; - } - - default: - return DebugUtils::errored(kErrorInvalidState); - } - - value[i] = v; - } - - uint64_t result; - uint64_t& a = value[0]; - uint64_t& b = value[1]; - - switch (exp->opType) { - case Expression::kOpAdd: - result = a + b; - break; - - case Expression::kOpSub: - result = a - b; - break; - - case Expression::kOpMul: - result = a * b; - break; - - case Expression::kOpSll: - result = (b > 63) ? uint64_t(0) : uint64_t(a << b); - break; - - case Expression::kOpSrl: - result = (b > 63) ? uint64_t(0) : uint64_t(a >> b); - break; - - case Expression::kOpSra: - result = Support::sar(a, Support::min(b, 63)); - break; - - default: - return DebugUtils::errored(kErrorInvalidState); - } - - *out = result; - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseEmitter - Utilities] -// ============================================================================ - -Error CodeHolder::flatten() noexcept { - uint64_t offset = 0; - for (Section* section : _sectionsByOrder) { - uint64_t realSize = section->realSize(); - if (realSize) { - uint64_t alignedOffset = Support::alignUp(offset, section->alignment()); - if (ASMJIT_UNLIKELY(alignedOffset < offset)) - return DebugUtils::errored(kErrorTooLarge); - - Support::FastUInt8 of = 0; - offset = Support::addOverflow(alignedOffset, realSize, &of); - - if (ASMJIT_UNLIKELY(of)) - return DebugUtils::errored(kErrorTooLarge); - } - } - - // Now we know that we can assign offsets of all sections properly. - Section* prev = nullptr; - offset = 0; - for (Section* section : _sectionsByOrder) { - uint64_t realSize = section->realSize(); - if (realSize) - offset = Support::alignUp(offset, section->alignment()); - section->_offset = offset; - - // Make sure the previous section extends a bit to cover the alignment. - if (prev) - prev->_virtualSize = offset - prev->_offset; - - prev = section; - offset += realSize; - } - - return kErrorOk; -} - -size_t CodeHolder::codeSize() const noexcept { - Support::FastUInt8 of = 0; - uint64_t offset = 0; - - for (Section* section : _sectionsByOrder) { - uint64_t realSize = section->realSize(); - - if (realSize) { - uint64_t alignedOffset = Support::alignUp(offset, section->alignment()); - ASMJIT_ASSERT(alignedOffset >= offset); - offset = Support::addOverflow(alignedOffset, realSize, &of); - } - } - - if ((sizeof(uint64_t) > sizeof(size_t) && offset > SIZE_MAX) || of) - return SIZE_MAX; - - return size_t(offset); -} - -Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept { - // Base address must be provided. - if (ASMJIT_UNLIKELY(baseAddress == Globals::kNoBaseAddress)) - return DebugUtils::errored(kErrorInvalidArgument); - - _baseAddress = baseAddress; - uint32_t addressSize = _environment.registerSize(); - - Section* addressTableSection = _addressTableSection; - uint32_t addressTableEntryCount = 0; - uint8_t* addressTableEntryData = nullptr; - - if (addressTableSection) { - ASMJIT_PROPAGATE( - reserveBuffer(&addressTableSection->_buffer, size_t(addressTableSection->virtualSize()))); - addressTableEntryData = addressTableSection->_buffer.data(); - } - - // Relocate all recorded locations. - for (const RelocEntry* re : _relocations) { - // Possibly deleted or optimized-out entry. - if (re->relocType() == RelocEntry::kTypeNone) - continue; - - Section* sourceSection = sectionById(re->sourceSectionId()); - Section* targetSection = nullptr; - - if (re->targetSectionId() != Globals::kInvalidId) - targetSection = sectionById(re->targetSectionId()); - - uint64_t value = re->payload(); - uint64_t sectionOffset = sourceSection->offset(); - uint64_t sourceOffset = re->sourceOffset(); - - // Make sure that the `RelocEntry` doesn't go out of bounds. - size_t regionSize = re->format().regionSize(); - if (ASMJIT_UNLIKELY(re->sourceOffset() >= sourceSection->bufferSize() || - sourceSection->bufferSize() - size_t(re->sourceOffset()) < regionSize)) - return DebugUtils::errored(kErrorInvalidRelocEntry); - - uint8_t* buffer = sourceSection->data(); - size_t valueOffset = size_t(re->sourceOffset()) + re->format().valueOffset(); - - switch (re->relocType()) { - case RelocEntry::kTypeExpression: { - Expression* expression = (Expression*)(uintptr_t(value)); - ASMJIT_PROPAGATE(CodeHolder_evaluateExpression(this, expression, &value)); - break; - } - - case RelocEntry::kTypeAbsToAbs: { - break; - } - - case RelocEntry::kTypeRelToAbs: { - // Value is currently a relative offset from the start of its section. - // We have to convert it to an absolute offset (including base address). - if (ASMJIT_UNLIKELY(!targetSection)) - return DebugUtils::errored(kErrorInvalidRelocEntry); - - //value += baseAddress + sectionOffset + sourceOffset + regionSize; - value += baseAddress + targetSection->offset(); - break; - } - - case RelocEntry::kTypeAbsToRel: { - value -= baseAddress + sectionOffset + sourceOffset + regionSize; - if (addressSize > 4 && !Support::isInt32(int64_t(value))) - return DebugUtils::errored(kErrorRelocOffsetOutOfRange); - break; - } - - case RelocEntry::kTypeX64AddressEntry: { - if (re->format().valueSize() != 4 || valueOffset < 2) - return DebugUtils::errored(kErrorInvalidRelocEntry); - - // First try whether a relative 32-bit displacement would work. - value -= baseAddress + sectionOffset + sourceOffset + regionSize; - if (!Support::isInt32(int64_t(value))) { - // Relative 32-bit displacement is not possible, use '.addrtab' section. - AddressTableEntry* atEntry = _addressTableEntries.get(re->payload()); - if (ASMJIT_UNLIKELY(!atEntry)) - return DebugUtils::errored(kErrorInvalidRelocEntry); - - // Cannot be null as we have just matched the `AddressTableEntry`. - ASMJIT_ASSERT(addressTableSection != nullptr); - - if (!atEntry->hasAssignedSlot()) - atEntry->_slot = addressTableEntryCount++; - - size_t atEntryIndex = size_t(atEntry->slot()) * addressSize; - uint64_t addrSrc = sectionOffset + sourceOffset + regionSize; - uint64_t addrDst = addressTableSection->offset() + uint64_t(atEntryIndex); - - value = addrDst - addrSrc; - if (!Support::isInt32(int64_t(value))) - return DebugUtils::errored(kErrorRelocOffsetOutOfRange); - - // Bytes that replace [REX, OPCODE] bytes. - uint32_t byte0 = 0xFF; - uint32_t byte1 = buffer[valueOffset - 1]; - - if (byte1 == 0xE8) { - // Patch CALL/MOD byte to FF /2 (-> 0x15). - byte1 = x86EncodeMod(0, 2, 5); - } - else if (byte1 == 0xE9) { - // Patch JMP/MOD byte to FF /4 (-> 0x25). - byte1 = x86EncodeMod(0, 4, 5); - } - else { - return DebugUtils::errored(kErrorInvalidRelocEntry); - } - - // Patch `jmp/call` instruction. - buffer[valueOffset - 2] = uint8_t(byte0); - buffer[valueOffset - 1] = uint8_t(byte1); - - Support::writeU64uLE(addressTableEntryData + atEntryIndex, re->payload()); - } - break; - } - - default: - return DebugUtils::errored(kErrorInvalidRelocEntry); - } - - switch (re->format().valueSize()) { - case 1: - Support::writeU8(buffer + valueOffset, uint32_t(value & 0xFFu)); - break; - - case 2: - Support::writeU16uLE(buffer + valueOffset, uint32_t(value & 0xFFFFu)); - break; - - case 4: - Support::writeU32uLE(buffer + valueOffset, uint32_t(value & 0xFFFFFFFFu)); - break; - - case 8: - Support::writeU64uLE(buffer + valueOffset, value); - break; - - default: - return DebugUtils::errored(kErrorInvalidRelocEntry); - } - } - - // Fixup the virtual size of the address table if it's the last section. - if (_sectionsByOrder.last() == addressTableSection) { - size_t addressTableSize = addressTableEntryCount * addressSize; - addressTableSection->_buffer._size = addressTableSize; - addressTableSection->_virtualSize = addressTableSize; - } - - return kErrorOk; -} - -Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t copyOptions) noexcept { - if (ASMJIT_UNLIKELY(!isSectionValid(sectionId))) - return DebugUtils::errored(kErrorInvalidSection); - - Section* section = sectionById(sectionId); - size_t bufferSize = section->bufferSize(); - - if (ASMJIT_UNLIKELY(dstSize < bufferSize)) - return DebugUtils::errored(kErrorInvalidArgument); - - memcpy(dst, section->data(), bufferSize); - - if (bufferSize < dstSize && (copyOptions & kCopyPadSectionBuffer)) { - size_t paddingSize = dstSize - bufferSize; - memset(static_cast(dst) + bufferSize, 0, paddingSize); - } - - return kErrorOk; -} - -Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOptions) noexcept { - size_t end = 0; - for (Section* section : _sectionsByOrder) { - if (section->offset() > dstSize) - return DebugUtils::errored(kErrorInvalidArgument); - - size_t bufferSize = section->bufferSize(); - size_t offset = size_t(section->offset()); - - if (ASMJIT_UNLIKELY(dstSize - offset < bufferSize)) - return DebugUtils::errored(kErrorInvalidArgument); - - uint8_t* dstTarget = static_cast(dst) + offset; - size_t paddingSize = 0; - memcpy(dstTarget, section->data(), bufferSize); - - if ((copyOptions & kCopyPadSectionBuffer) && bufferSize < section->virtualSize()) { - paddingSize = Support::min(dstSize - offset, size_t(section->virtualSize())) - bufferSize; - memset(dstTarget + bufferSize, 0, paddingSize); - } - - end = Support::max(end, offset + bufferSize + paddingSize); - } - - if (end < dstSize && (copyOptions & kCopyPadTargetBuffer)) { - memset(static_cast(dst) + end, 0, dstSize - end); - } - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::CodeHolder - Unit] -// ============================================================================ - -#if defined(ASMJIT_TEST) -UNIT(code_holder) { - CodeHolder code; - - INFO("Verifying CodeHolder::init()"); - Environment env; - env.init(Environment::kArchX86); - - code.init(env); - EXPECT(code.arch() == Environment::kArchX86); - - INFO("Verifying named labels"); - LabelEntry* le; - EXPECT(code.newNamedLabelEntry(&le, "NamedLabel", SIZE_MAX, Label::kTypeGlobal) == kErrorOk); - EXPECT(strcmp(le->name(), "NamedLabel") == 0); - EXPECT(code.labelIdByName("NamedLabel") == le->id()); - - INFO("Verifying section ordering"); - Section* section1; - EXPECT(code.newSection(§ion1, "high-priority", SIZE_MAX, 0, 1, -1) == kErrorOk); - EXPECT(code.sections()[1] == section1); - EXPECT(code.sectionsByOrder()[0] == section1); - - Section* section0; - EXPECT(code.newSection(§ion0, "higher-priority", SIZE_MAX, 0, 1, -2) == kErrorOk); - EXPECT(code.sections()[2] == section0); - EXPECT(code.sectionsByOrder()[0] == section0); - EXPECT(code.sectionsByOrder()[1] == section1); - - Section* section3; - EXPECT(code.newSection(§ion3, "low-priority", SIZE_MAX, 0, 1, 2) == kErrorOk); - EXPECT(code.sections()[3] == section3); - EXPECT(code.sectionsByOrder()[3] == section3); - -} -#endif - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codeholder.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codeholder.h deleted file mode 100644 index 06bf3f9..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codeholder.h +++ /dev/null @@ -1,1061 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_CODEHOLDER_H_INCLUDED -#define ASMJIT_CORE_CODEHOLDER_H_INCLUDED - -#include "../core/archtraits.h" -#include "../core/codebuffer.h" -#include "../core/datatypes.h" -#include "../core/errorhandler.h" -#include "../core/operand.h" -#include "../core/string.h" -#include "../core/support.h" -#include "../core/target.h" -#include "../core/zone.h" -#include "../core/zonehash.h" -#include "../core/zonestring.h" -#include "../core/zonetree.h" -#include "../core/zonevector.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -class BaseEmitter; -class CodeHolder; -class LabelEntry; -class Logger; - -// ============================================================================ -// [asmjit::AlignMode] -// ============================================================================ - -//! Align mode. -enum AlignMode : uint32_t { - //! Align executable code. - kAlignCode = 0, - //! Align non-executable code. - kAlignData = 1, - //! Align by a sequence of zeros. - kAlignZero = 2, - //! Count of alignment modes. - kAlignCount = 3 -}; - -// ============================================================================ -// [asmjit::Expression] -// ============================================================================ - -//! Expression node that can reference constants, labels, and another expressions. -struct Expression { - //! Operation type. - enum OpType : uint8_t { - //! Addition. - kOpAdd = 0, - //! Subtraction. - kOpSub = 1, - //! Multiplication - kOpMul = 2, - //! Logical left shift. - kOpSll = 3, - //! Logical right shift. - kOpSrl = 4, - //! Arithmetic right shift. - kOpSra = 5 - }; - - //! Type of \ref Value. - enum ValueType : uint8_t { - //! No value or invalid. - kValueNone = 0, - //! Value is 64-bit unsigned integer (constant). - kValueConstant = 1, - //! Value is \ref LabelEntry, which references a \ref Label. - kValueLabel = 2, - //! Value is \ref Expression - kValueExpression = 3 - }; - - //! Expression value. - union Value { - //! Constant. - uint64_t constant; - //! Pointer to another expression. - Expression* expression; - //! Poitner to \ref LabelEntry. - LabelEntry* label; - }; - - //! Operation type. - uint8_t opType; - //! Value types of \ref value. - uint8_t valueType[2]; - //! Reserved for future use, should be initialized to zero. - uint8_t reserved[5]; - //! Expression left and right values. - Value value[2]; - - //! Resets the whole expression. - //! - //! Changes both values to \ref kValueNone. - inline void reset() noexcept { memset(this, 0, sizeof(*this)); } - - //! Sets the value type at `index` to \ref kValueConstant and its content to `constant`. - inline void setValueAsConstant(size_t index, uint64_t constant) noexcept { - valueType[index] = kValueConstant; - value[index].constant = constant; - } - - //! Sets the value type at `index` to \ref kValueLabel and its content to `labelEntry`. - inline void setValueAsLabel(size_t index, LabelEntry* labelEntry) noexcept { - valueType[index] = kValueLabel; - value[index].label = labelEntry; - } - - //! Sets the value type at `index` to \ref kValueExpression and its content to `expression`. - inline void setValueAsExpression(size_t index, Expression* expression) noexcept { - valueType[index] = kValueLabel; - value[index].expression = expression; - } -}; - -// ============================================================================ -// [asmjit::Section] -// ============================================================================ - -//! Section entry. -class Section { -public: - //! Section id. - uint32_t _id; - //! Section flags. - uint32_t _flags; - //! Section alignment requirements (0 if no requirements). - uint32_t _alignment; - //! Order (lower value means higher priority). - int32_t _order; - //! Offset of this section from base-address. - uint64_t _offset; - //! Virtual size of the section (zero initialized sections). - uint64_t _virtualSize; - //! Section name (max 35 characters, PE allows max 8). - FixedString _name; - //! Code or data buffer. - CodeBuffer _buffer; - - //! Section flags. - enum Flags : uint32_t { - //! Executable (.text sections). - kFlagExec = 0x00000001u, - //! Read-only (.text and .data sections). - kFlagConst = 0x00000002u, - //! Zero initialized by the loader (BSS). - kFlagZero = 0x00000004u, - //! Info / comment flag. - kFlagInfo = 0x00000008u, - //! Section created implicitly and can be deleted by \ref Target. - kFlagImplicit = 0x80000000u - }; - - //! \name Accessors - //! \{ - - //! Returns the section id. - inline uint32_t id() const noexcept { return _id; } - //! Returns the section name, as a null terminated string. - inline const char* name() const noexcept { return _name.str; } - - //! Returns the section data. - inline uint8_t* data() noexcept { return _buffer.data(); } - //! \overload - inline const uint8_t* data() const noexcept { return _buffer.data(); } - - //! Returns the section flags, see \ref Flags. - inline uint32_t flags() const noexcept { return _flags; } - //! Tests whether the section has the given `flag`. - inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; } - //! Adds `flags` to the section flags. - inline void addFlags(uint32_t flags) noexcept { _flags |= flags; } - //! Removes `flags` from the section flags. - inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; } - - //! Returns the minimum section alignment - inline uint32_t alignment() const noexcept { return _alignment; } - //! Sets the minimum section alignment - inline void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; } - - //! Returns the section order, which has a higher priority than section id. - inline int32_t order() const noexcept { return _order; } - - //! Returns the section offset, relative to base. - inline uint64_t offset() const noexcept { return _offset; } - //! Set the section offset. - inline void setOffset(uint64_t offset) noexcept { _offset = offset; } - - //! Returns the virtual size of the section. - //! - //! Virtual size is initially zero and is never changed by AsmJit. It's normal - //! if virtual size is smaller than size returned by `bufferSize()` as the buffer - //! stores real data emitted by assemblers or appended by users. - //! - //! Use `realSize()` to get the real and final size of this section. - inline uint64_t virtualSize() const noexcept { return _virtualSize; } - //! Sets the virtual size of the section. - inline void setVirtualSize(uint64_t virtualSize) noexcept { _virtualSize = virtualSize; } - - //! Returns the buffer size of the section. - inline size_t bufferSize() const noexcept { return _buffer.size(); } - //! Returns the real size of the section calculated from virtual and buffer sizes. - inline uint64_t realSize() const noexcept { return Support::max(virtualSize(), bufferSize()); } - - //! Returns the `CodeBuffer` used by this section. - inline CodeBuffer& buffer() noexcept { return _buffer; } - //! Returns the `CodeBuffer` used by this section (const). - inline const CodeBuffer& buffer() const noexcept { return _buffer; } - - //! \} -}; - -// ============================================================================ -// [asmjit::OffsetFormat] -// ============================================================================ - -//! Provides information about formatting offsets, absolute addresses, or their -//! parts. Offset format is used by both \ref RelocEntry and \ref LabelLink. -//! -//! The illustration above describes the relation of region size and offset size. -//! Region size is the size of the whole unit whereas offset size is the size of -//! the unit that will be patched. -//! -//! ``` -//! +-> Code buffer | The subject of the relocation (region) | -//! | | (Word-Offset) (Word-Size) | -//! |xxxxxxxxxxxxxxx|................|*PATCHED*|................|xxxxxxxxxxxx-> -//! | | -//! [Word Offset points here]----+ +--- [WordOffset + WordSize] -//! ``` -//! -//! Once the offset word has been located it can be patched like this: -//! -//! ``` -//! |ImmDiscardLSB (discard LSB bits). -//! |.. -//! [0000000000000iiiiiiiiiiiiiiiiiDD] - Offset value (32-bit) -//! [000000000000000iiiiiiiiiiiiiiiii] - Offset value after discard LSB. -//! [00000000000iiiiiiiiiiiiiiiii0000] - Offset value shifted by ImmBitShift. -//! [xxxxxxxxxxxiiiiiiiiiiiiiiiiixxxx] - Patched word (32-bit) -//! |...............| -//! (ImmBitCount) +- ImmBitShift -//! ``` -struct OffsetFormat { - //! Type of the displacement. - uint8_t _type; - //! Encoding flags. - uint8_t _flags; - //! Size of the region (in bytes) containing the offset value, if the offset - //! value is part of an instruction, otherwise it would be the same as - //! `_valueSize`. - uint8_t _regionSize; - //! Size of the offset value, in bytes (1, 2, 4, or 8). - uint8_t _valueSize; - //! Offset of the offset value, in bytes, relative to the start of the region - //! or data. Value offset would be zero if both region size and value size are - //! equal. - uint8_t _valueOffset; - //! Size of the displacement immediate value in bits. - uint8_t _immBitCount; - //! Shift of the displacement immediate value in bits in the target word. - uint8_t _immBitShift; - //! Number of least significant bits to discard before writing the immediate - //! to the destination. All discarded bits must be zero otherwise the value - //! is invalid. - uint8_t _immDiscardLsb; - - //! Type of the displacement. - enum Type : uint8_t { - //! A value having `_immBitCount` bits and shifted by `_immBitShift`. - //! - //! This displacement type is sufficient for both X86/X64 and many other - //! architectures that store displacement as continuous bits within a machine - //! word. - kTypeCommon = 0, - //! AARCH64 ADR format of `[.|immlo:2|.....|immhi:19|.....]`. - kTypeAArch64_ADR, - //! AARCH64 ADRP format of `[.|immlo:2|.....|immhi:19|.....]` (4kB pages). - kTypeAArch64_ADRP, - - //! Count of displacement types. - kTypeCount - }; - - //! Returns the type of the displacement. - inline uint32_t type() const noexcept { return _type; } - - //! Returns flags. - inline uint32_t flags() const noexcept { return _flags; } - - //! Returns the size of the region/instruction where the displacement is encoded. - inline uint32_t regionSize() const noexcept { return _regionSize; } - - //! Returns the the offset of the word relative to the start of the region - //! where the displacement is. - inline uint32_t valueOffset() const noexcept { return _valueOffset; } - - //! Returns the size of the data-type (word) that contains the displacement, in bytes. - inline uint32_t valueSize() const noexcept { return _valueSize; } - //! Returns the count of bits of the displacement value in the data it's stored in. - inline uint32_t immBitCount() const noexcept { return _immBitCount; } - //! Returns the bit-shift of the displacement value in the data it's stored in. - inline uint32_t immBitShift() const noexcept { return _immBitShift; } - //! Returns the number of least significant bits of the displacement value, - //! that must be zero and that are not part of the encoded data. - inline uint32_t immDiscardLsb() const noexcept { return _immDiscardLsb; } - - //! Resets this offset format to a simple data value of `dataSize` bytes. - //! - //! The region will be the same size as data and immediate bits would correspond - //! to `dataSize * 8`. There will be no immediate bit shift or discarded bits. - inline void resetToDataValue(size_t dataSize) noexcept { - ASMJIT_ASSERT(dataSize <= 8u); - - _type = uint8_t(kTypeCommon); - _flags = uint8_t(0); - _regionSize = uint8_t(dataSize); - _valueSize = uint8_t(dataSize); - _valueOffset = uint8_t(0); - _immBitCount = uint8_t(dataSize * 8u); - _immBitShift = uint8_t(0); - _immDiscardLsb = uint8_t(0); - } - - inline void resetToImmValue(uint32_t type, size_t valueSize, uint32_t immBitShift, uint32_t immBitCount, uint32_t immDiscardLsb) noexcept { - ASMJIT_ASSERT(valueSize <= 8u); - ASMJIT_ASSERT(immBitShift < valueSize * 8u); - ASMJIT_ASSERT(immBitCount <= 64u); - ASMJIT_ASSERT(immDiscardLsb <= 64u); - - _type = uint8_t(type); - _flags = uint8_t(0); - _regionSize = uint8_t(valueSize); - _valueSize = uint8_t(valueSize); - _valueOffset = uint8_t(0); - _immBitCount = uint8_t(immBitCount); - _immBitShift = uint8_t(immBitShift); - _immDiscardLsb = uint8_t(immDiscardLsb); - } - - inline void setRegion(size_t regionSize, size_t valueOffset) noexcept { - _regionSize = uint8_t(regionSize); - _valueOffset = uint8_t(valueOffset); - } - - inline void setLeadingAndTrailingSize(size_t leadingSize, size_t trailingSize) noexcept { - _regionSize = uint8_t(leadingSize + trailingSize + _valueSize); - _valueOffset = uint8_t(leadingSize); - } -}; - -// ============================================================================ -// [asmjit::RelocEntry] -// ============================================================================ - -//! Relocation entry. -struct RelocEntry { - //! Relocation id. - uint32_t _id; - //! Type of the relocation. - uint32_t _relocType; - //! Format of the relocated value. - OffsetFormat _format; - //! Source section id. - uint32_t _sourceSectionId; - //! Target section id. - uint32_t _targetSectionId; - //! Source offset (relative to start of the section). - uint64_t _sourceOffset; - //! Payload (target offset, target address, expression, etc). - uint64_t _payload; - - //! Relocation type. - enum RelocType : uint32_t { - //! None/deleted (no relocation). - kTypeNone = 0, - //! Expression evaluation, `_payload` is pointer to `Expression`. - kTypeExpression = 1, - //! Relocate absolute to absolute. - kTypeAbsToAbs = 2, - //! Relocate relative to absolute. - kTypeRelToAbs = 3, - //! Relocate absolute to relative. - kTypeAbsToRel = 4, - //! Relocate absolute to relative or use trampoline. - kTypeX64AddressEntry = 5 - }; - - //! \name Accessors - //! \{ - - inline uint32_t id() const noexcept { return _id; } - - inline uint32_t relocType() const noexcept { return _relocType; } - inline const OffsetFormat& format() const noexcept { return _format; } - - inline uint32_t sourceSectionId() const noexcept { return _sourceSectionId; } - inline uint32_t targetSectionId() const noexcept { return _targetSectionId; } - - inline uint64_t sourceOffset() const noexcept { return _sourceOffset; } - inline uint64_t payload() const noexcept { return _payload; } - - Expression* payloadAsExpression() const noexcept { - return reinterpret_cast(uintptr_t(_payload)); - } - - //! \} -}; - -// ============================================================================ -// [asmjit::LabelLink] -// ============================================================================ - -//! Data structure used to link either unbound labels or cross-section links. -struct LabelLink { - //! Next link (single-linked list). - LabelLink* next; - //! Section id where the label is bound. - uint32_t sectionId; - //! Relocation id or Globals::kInvalidId. - uint32_t relocId; - //! Label offset relative to the start of the section. - size_t offset; - //! Inlined rel8/rel32. - intptr_t rel; - //! Offset format information. - OffsetFormat format; -}; - -// ============================================================================ -// [asmjit::LabelEntry] -// ============================================================================ - -//! Label entry. -//! -//! Contains the following properties: -//! * Label id - This is the only thing that is set to the `Label` operand. -//! * Label name - Optional, used mostly to create executables and libraries. -//! * Label type - Type of the label, default `Label::kTypeAnonymous`. -//! * Label parent id - Derived from many assemblers that allow to define a -//! local label that falls under a global label. This allows to define -//! many labels of the same name that have different parent (global) label. -//! * Offset - offset of the label bound by `Assembler`. -//! * Links - single-linked list that contains locations of code that has -//! to be patched when the label gets bound. Every use of unbound label -//! adds one link to `_links` list. -//! * HVal - Hash value of label's name and optionally parentId. -//! * HashNext - Hash-table implementation detail. -class LabelEntry : public ZoneHashNode { -public: - // Let's round the size of `LabelEntry` to 64 bytes (as `ZoneAllocator` has - // granularity of 32 bytes anyway). This gives `_name` the remaining space, - // which is should be 16 bytes on 64-bit and 28 bytes on 32-bit architectures. - enum : uint32_t { - kStaticNameSize = - 64 - (sizeof(ZoneHashNode) + 8 + sizeof(Section*) + sizeof(size_t) + sizeof(LabelLink*)) - }; - - //! Label type, see `Label::LabelType`. - uint8_t _type; - //! Must be zero. - uint8_t _flags; - //! Reserved. - uint16_t _reserved16; - //! Label parent id or zero. - uint32_t _parentId; - //! Label offset relative to the start of the `_section`. - uint64_t _offset; - //! Section where the label was bound. - Section* _section; - //! Label links. - LabelLink* _links; - //! Label name. - ZoneString _name; - - //! \name Accessors - //! \{ - - // NOTE: Label id is stored in `_customData`, which is provided by ZoneHashNode - // to fill a padding that a C++ compiler targeting 64-bit CPU will add to align - // the structure to 64-bits. - - //! Returns label id. - inline uint32_t id() const noexcept { return _customData; } - //! Sets label id (internal, used only by `CodeHolder`). - inline void _setId(uint32_t id) noexcept { _customData = id; } - - //! Returns label type, see `Label::LabelType`. - inline uint32_t type() const noexcept { return _type; } - //! Returns label flags, returns 0 at the moment. - inline uint32_t flags() const noexcept { return _flags; } - - //! Tests whether the label has a parent label. - inline bool hasParent() const noexcept { return _parentId != Globals::kInvalidId; } - //! Returns label's parent id. - inline uint32_t parentId() const noexcept { return _parentId; } - - //! Returns the section where the label was bound. - //! - //! If the label was not yet bound the return value is `nullptr`. - inline Section* section() const noexcept { return _section; } - - //! Tests whether the label has name. - inline bool hasName() const noexcept { return !_name.empty(); } - - //! Returns the label's name. - //! - //! \note Local labels will return their local name without their parent - //! part, for example ".L1". - inline const char* name() const noexcept { return _name.data(); } - - //! Returns size of label's name. - //! - //! \note Label name is always null terminated, so you can use `strlen()` to - //! get it, however, it's also cached in `LabelEntry` itself, so if you want - //! to know the size the fastest way is to call `LabelEntry::nameSize()`. - inline uint32_t nameSize() const noexcept { return _name.size(); } - - //! Returns links associated with this label. - inline LabelLink* links() const noexcept { return _links; } - - //! Tests whether the label is bound. - inline bool isBound() const noexcept { return _section != nullptr; } - //! Tests whether the label is bound to a the given `sectionId`. - inline bool isBoundTo(Section* section) const noexcept { return _section == section; } - - //! Returns the label offset (only useful if the label is bound). - inline uint64_t offset() const noexcept { return _offset; } - - //! Returns the hash-value of label's name and its parent label (if any). - //! - //! Label hash is calculated as `HASH(Name) ^ ParentId`. The hash function - //! is implemented in `Support::hashString()` and `Support::hashRound()`. - inline uint32_t hashCode() const noexcept { return _hashCode; } - - //! \} -}; - -// ============================================================================ -// [asmjit::AddressTableEntry] -// ============================================================================ - -//! Entry in an address table. -class AddressTableEntry : public ZoneTreeNodeT { -public: - ASMJIT_NONCOPYABLE(AddressTableEntry) - - //! Address. - uint64_t _address; - //! Slot. - uint32_t _slot; - - //! \name Construction & Destruction - //! \{ - - inline explicit AddressTableEntry(uint64_t address) noexcept - : _address(address), - _slot(0xFFFFFFFFu) {} - - //! \} - - //! \name Accessors - //! \{ - - inline uint64_t address() const noexcept { return _address; } - inline uint32_t slot() const noexcept { return _slot; } - - inline bool hasAssignedSlot() const noexcept { return _slot != 0xFFFFFFFFu; } - - inline bool operator<(const AddressTableEntry& other) const noexcept { return _address < other._address; } - inline bool operator>(const AddressTableEntry& other) const noexcept { return _address > other._address; } - - inline bool operator<(uint64_t queryAddress) const noexcept { return _address < queryAddress; } - inline bool operator>(uint64_t queryAddress) const noexcept { return _address > queryAddress; } - - //! \} -}; - -// ============================================================================ -// [asmjit::CodeHolder] -// ============================================================================ - -//! Contains basic information about the target architecture and its options. -//! -//! In addition, it holds assembled code & data (including sections, labels, and -//! relocation information). `CodeHolder` can store both binary and intermediate -//! representation of assembly, which can be generated by \ref BaseAssembler, -//! \ref BaseBuilder, and \ref BaseCompiler -//! -//! \note `CodeHolder` has an ability to attach an \ref ErrorHandler, however, -//! the error handler is not triggered by `CodeHolder` itself, it's instead -//! propagated to all emitters that attach to it. -class CodeHolder { -public: - ASMJIT_NONCOPYABLE(CodeHolder) - - //! Environment information. - Environment _environment; - //! Base address or \ref Globals::kNoBaseAddress. - uint64_t _baseAddress; - - //! Attached `Logger`, used by all consumers. - Logger* _logger; - //! Attached `ErrorHandler`. - ErrorHandler* _errorHandler; - - //! Code zone (used to allocate core structures). - Zone _zone; - //! Zone allocator, used to manage internal containers. - ZoneAllocator _allocator; - - //! Attached emitters. - ZoneVector _emitters; - //! Section entries. - ZoneVector _sections; - //! Section entries sorted by section order and then section id. - ZoneVector _sectionsByOrder; - //! Label entries. - ZoneVector _labelEntries; - //! Relocation entries. - ZoneVector _relocations; - //! Label name -> LabelEntry (only named labels). - ZoneHash _namedLabels; - - //! Count of label links, which are not resolved. - size_t _unresolvedLinkCount; - //! Pointer to an address table section (or null if this section doesn't exist). - Section* _addressTableSection; - //! Address table entries. - ZoneTree _addressTableEntries; - - //! Options that can be used with \ref copySectionData() and \ref copyFlattenedData(). - enum CopyOptions : uint32_t { - //! If virtual size of a section is greater than the size of its \ref CodeBuffer - //! then all bytes between the buffer size and virtual size will be zeroed. - //! If this option is not set then those bytes would be left as is, which - //! means that if the user didn't initialize them they would have a previous - //! content, which may be unwanted. - kCopyPadSectionBuffer = 0x00000001u, - -#ifndef ASMJIT_NO_DEPRECATED - kCopyWithPadding = kCopyPadSectionBuffer, -#endif // !ASMJIT_NO_DEPRECATED - - //! Zeroes the target buffer if the flattened data is less than the destination - //! size. This option works only with \ref copyFlattenedData() as it processes - //! multiple sections. It is ignored by \ref copySectionData(). - kCopyPadTargetBuffer = 0x00000002u - }; - - //! \name Construction & Destruction - //! \{ - - //! Creates an uninitialized CodeHolder (you must init() it before it can be used). - ASMJIT_API CodeHolder() noexcept; - //! Destroys the CodeHolder. - ASMJIT_API ~CodeHolder() noexcept; - - //! Tests whether the `CodeHolder` has been initialized. - //! - //! Emitters can be only attached to initialized `CodeHolder` instances. - inline bool isInitialized() const noexcept { return _environment.isInitialized(); } - - //! Initializes CodeHolder to hold code described by code `info`. - ASMJIT_API Error init(const Environment& environment, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept; - //! Detaches all code-generators attached and resets the `CodeHolder`. - ASMJIT_API void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept; - - //! \} - - //! \name Attach & Detach - //! \{ - - //! Attaches an emitter to this `CodeHolder`. - ASMJIT_API Error attach(BaseEmitter* emitter) noexcept; - //! Detaches an emitter from this `CodeHolder`. - ASMJIT_API Error detach(BaseEmitter* emitter) noexcept; - - //! \} - - //! \name Allocators - //! \{ - - //! Returns the allocator that the `CodeHolder` uses. - //! - //! \note This should be only used for AsmJit's purposes. Code holder uses - //! arena allocator to allocate everything, so anything allocated through - //! this allocator will be invalidated by \ref CodeHolder::reset() or by - //! CodeHolder's destructor. - inline ZoneAllocator* allocator() const noexcept { return const_cast(&_allocator); } - - //! \} - - //! \name Code & Architecture - //! \{ - - //! Returns the target environment information, see \ref Environment. - inline const Environment& environment() const noexcept { return _environment; } - - //! Returns the target architecture. - inline uint32_t arch() const noexcept { return environment().arch(); } - //! Returns the target sub-architecture. - inline uint32_t subArch() const noexcept { return environment().subArch(); } - - //! Tests whether a static base-address is set. - inline bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; } - //! Returns a static base-address or \ref Globals::kNoBaseAddress, if not set. - inline uint64_t baseAddress() const noexcept { return _baseAddress; } - - //! \} - - //! \name Emitters - //! \{ - - //! Returns a vector of attached emitters. - inline const ZoneVector& emitters() const noexcept { return _emitters; } - - //! \} - - //! \name Logging - //! \{ - - //! Returns the attached logger, see \ref Logger. - inline Logger* logger() const noexcept { return _logger; } - //! Attaches a `logger` to CodeHolder and propagates it to all attached emitters. - ASMJIT_API void setLogger(Logger* logger) noexcept; - //! Resets the logger to none. - inline void resetLogger() noexcept { setLogger(nullptr); } - - //! \name Error Handling - //! \{ - - //! Tests whether the CodeHolder has an attached error handler, see \ref ErrorHandler. - inline bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; } - //! Returns the attached error handler. - inline ErrorHandler* errorHandler() const noexcept { return _errorHandler; } - //! Attach an error handler to this `CodeHolder`. - ASMJIT_API void setErrorHandler(ErrorHandler* errorHandler) noexcept; - //! Resets the error handler to none. - inline void resetErrorHandler() noexcept { setErrorHandler(nullptr); } - - //! \} - - //! \name Code Buffer - //! \{ - - //! Makes sure that at least `n` bytes can be added to CodeHolder's buffer `cb`. - //! - //! \note The buffer `cb` must be managed by `CodeHolder` - otherwise the - //! behavior of the function is undefined. - ASMJIT_API Error growBuffer(CodeBuffer* cb, size_t n) noexcept; - - //! Reserves the size of `cb` to at least `n` bytes. - //! - //! \note The buffer `cb` must be managed by `CodeHolder` - otherwise the - //! behavior of the function is undefined. - ASMJIT_API Error reserveBuffer(CodeBuffer* cb, size_t n) noexcept; - - //! \} - - //! \name Sections - //! \{ - - //! Returns an array of `Section*` records. - inline const ZoneVector& sections() const noexcept { return _sections; } - //! Returns an array of `Section*` records sorted according to section order first, then section id. - inline const ZoneVector& sectionsByOrder() const noexcept { return _sectionsByOrder; } - //! Returns the number of sections. - inline uint32_t sectionCount() const noexcept { return _sections.size(); } - - //! Tests whether the given `sectionId` is valid. - inline bool isSectionValid(uint32_t sectionId) const noexcept { return sectionId < _sections.size(); } - - //! Creates a new section and return its pointer in `sectionOut`. - //! - //! Returns `Error`, does not report a possible error to `ErrorHandler`. - ASMJIT_API Error newSection(Section** sectionOut, const char* name, size_t nameSize = SIZE_MAX, uint32_t flags = 0, uint32_t alignment = 1, int32_t order = 0) noexcept; - - //! Returns a section entry of the given index. - inline Section* sectionById(uint32_t sectionId) const noexcept { return _sections[sectionId]; } - - //! Returns section-id that matches the given `name`. - //! - //! If there is no such section `Section::kInvalidId` is returned. - ASMJIT_API Section* sectionByName(const char* name, size_t nameSize = SIZE_MAX) const noexcept; - - //! Returns '.text' section (section that commonly represents code). - //! - //! \note Text section is always the first section in \ref CodeHolder::sections() array. - inline Section* textSection() const noexcept { return _sections[0]; } - - //! Tests whether '.addrtab' section exists. - inline bool hasAddressTable() const noexcept { return _addressTableSection != nullptr; } - - //! Returns '.addrtab' section. - //! - //! This section is used exclusively by AsmJit to store absolute 64-bit - //! addresses that cannot be encoded in instructions like 'jmp' or 'call'. - //! - //! \note This section is created on demand, the returned pointer can be null. - inline Section* addressTableSection() const noexcept { return _addressTableSection; } - - //! Ensures that '.addrtab' section exists (creates it if it doesn't) and - //! returns it. Can return `nullptr` on out of memory condition. - ASMJIT_API Section* ensureAddressTableSection() noexcept; - - //! Used to add an address to an address table. - //! - //! This implicitly calls `ensureAddressTableSection()` and then creates - //! `AddressTableEntry` that is inserted to `_addressTableEntries`. If the - //! address already exists this operation does nothing as the same addresses - //! use the same slot. - //! - //! This function should be considered internal as it's used by assemblers to - //! insert an absolute address into the address table. Inserting address into - //! address table without creating a particula relocation entry makes no sense. - ASMJIT_API Error addAddressToAddressTable(uint64_t address) noexcept; - - //! \} - - //! \name Labels & Symbols - //! \{ - - //! Returns array of `LabelEntry*` records. - inline const ZoneVector& labelEntries() const noexcept { return _labelEntries; } - - //! Returns number of labels created. - inline uint32_t labelCount() const noexcept { return _labelEntries.size(); } - - //! Tests whether the label having `id` is valid (i.e. created by `newLabelEntry()`). - inline bool isLabelValid(uint32_t labelId) const noexcept { - return labelId < _labelEntries.size(); - } - - //! Tests whether the `label` is valid (i.e. created by `newLabelEntry()`). - inline bool isLabelValid(const Label& label) const noexcept { - return label.id() < _labelEntries.size(); - } - - //! \overload - inline bool isLabelBound(uint32_t labelId) const noexcept { - return isLabelValid(labelId) && _labelEntries[labelId]->isBound(); - } - - //! Tests whether the `label` is already bound. - //! - //! Returns `false` if the `label` is not valid. - inline bool isLabelBound(const Label& label) const noexcept { - return isLabelBound(label.id()); - } - - //! Returns LabelEntry of the given label `id`. - inline LabelEntry* labelEntry(uint32_t labelId) const noexcept { - return isLabelValid(labelId) ? _labelEntries[labelId] : static_cast(nullptr); - } - - //! Returns LabelEntry of the given `label`. - inline LabelEntry* labelEntry(const Label& label) const noexcept { - return labelEntry(label.id()); - } - - //! Returns offset of a `Label` by its `labelId`. - //! - //! The offset returned is relative to the start of the section. Zero offset - //! is returned for unbound labels, which is their initial offset value. - inline uint64_t labelOffset(uint32_t labelId) const noexcept { - ASMJIT_ASSERT(isLabelValid(labelId)); - return _labelEntries[labelId]->offset(); - } - - //! \overload - inline uint64_t labelOffset(const Label& label) const noexcept { - return labelOffset(label.id()); - } - - //! Returns offset of a label by it's `labelId` relative to the base offset. - //! - //! \remarks The offset of the section where the label is bound must be valid - //! in order to use this function, otherwise the value returned will not be - //! reliable. - inline uint64_t labelOffsetFromBase(uint32_t labelId) const noexcept { - ASMJIT_ASSERT(isLabelValid(labelId)); - const LabelEntry* le = _labelEntries[labelId]; - return (le->isBound() ? le->section()->offset() : uint64_t(0)) + le->offset(); - } - - //! \overload - inline uint64_t labelOffsetFromBase(const Label& label) const noexcept { - return labelOffsetFromBase(label.id()); - } - - //! Creates a new anonymous label and return its id in `idOut`. - //! - //! Returns `Error`, does not report error to `ErrorHandler`. - ASMJIT_API Error newLabelEntry(LabelEntry** entryOut) noexcept; - - //! Creates a new named \ref LabelEntry of the given label `type`. - //! - //! \param entryOut Where to store the created \ref LabelEntry. - //! \param name The name of the label. - //! \param nameSize The length of `name` argument, or `SIZE_MAX` if `name` is - //! a null terminated string, which means that the `CodeHolder` will - //! use `strlen()` to determine the length. - //! \param type The type of the label to create, see \ref Label::LabelType. - //! \param parentId Parent id of a local label, otherwise it must be - //! \ref Globals::kInvalidId. - //! - //! \retval Always returns \ref Error, does not report a possible error to - //! the attached \ref ErrorHandler. - //! - //! AsmJit has a support for local labels (\ref Label::kTypeLocal) which - //! require a parent label id (parentId). The names of local labels can - //! conflict with names of other local labels that have a different parent. - ASMJIT_API Error newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, uint32_t type, uint32_t parentId = Globals::kInvalidId) noexcept; - - //! Returns a label by name. - //! - //! If the named label doesn't a default constructed \ref Label is returned, - //! which has its id set to \ref Globals::kInvalidId. - inline Label labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept { - return Label(labelIdByName(name, nameSize, parentId)); - } - - //! Returns a label id by name. - //! - //! If the named label doesn't exist \ref Globals::kInvalidId is returned. - ASMJIT_API uint32_t labelIdByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept; - - //! Tests whether there are any unresolved label links. - inline bool hasUnresolvedLinks() const noexcept { return _unresolvedLinkCount != 0; } - //! Returns the number of label links, which are unresolved. - inline size_t unresolvedLinkCount() const noexcept { return _unresolvedLinkCount; } - - //! Creates a new label-link used to store information about yet unbound labels. - //! - //! Returns `null` if the allocation failed. - ASMJIT_API LabelLink* newLabelLink(LabelEntry* le, uint32_t sectionId, size_t offset, intptr_t rel, const OffsetFormat& format) noexcept; - - //! Resolves cross-section links (`LabelLink`) associated with each label that - //! was used as a destination in code of a different section. It's only useful - //! to people that use multiple sections as it will do nothing if the code only - //! contains a single section in which cross-section links are not possible. - ASMJIT_API Error resolveUnresolvedLinks() noexcept; - - //! Binds a label to a given `sectionId` and `offset` (relative to start of the section). - //! - //! This function is generally used by `BaseAssembler::bind()` to do the heavy lifting. - ASMJIT_API Error bindLabel(const Label& label, uint32_t sectionId, uint64_t offset) noexcept; - - //! \} - - //! \name Relocations - //! \{ - - //! Tests whether the code contains relocation entries. - inline bool hasRelocEntries() const noexcept { return !_relocations.empty(); } - //! Returns array of `RelocEntry*` records. - inline const ZoneVector& relocEntries() const noexcept { return _relocations; } - - //! Returns a RelocEntry of the given `id`. - inline RelocEntry* relocEntry(uint32_t id) const noexcept { return _relocations[id]; } - - //! Creates a new relocation entry of type `relocType`. - //! - //! Additional fields can be set after the relocation entry was created. - ASMJIT_API Error newRelocEntry(RelocEntry** dst, uint32_t relocType) noexcept; - - //! \} - - //! \name Utilities - //! \{ - - //! Flattens all sections by recalculating their offsets, starting at 0. - //! - //! \note This should never be called more than once. - ASMJIT_API Error flatten() noexcept; - - //! Returns computed the size of code & data of all sections. - //! - //! \note All sections will be iterated over and the code size returned - //! would represent the minimum code size of all combined sections after - //! applying minimum alignment. Code size may decrease after calling - //! `flatten()` and `relocateToBase()`. - ASMJIT_API size_t codeSize() const noexcept; - - //! Relocates the code to the given `baseAddress`. - //! - //! \param baseAddress Absolute base address where the code will be relocated - //! to. Please note that nothing is copied to such base address, it's just an - //! absolute value used by the relocator to resolve all stored relocations. - //! - //! \note This should never be called more than once. - ASMJIT_API Error relocateToBase(uint64_t baseAddress) noexcept; - - //! Copies a single section into `dst`. - ASMJIT_API Error copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t copyOptions = 0) noexcept; - - //! Copies all sections into `dst`. - //! - //! This should only be used if the data was flattened and there are no gaps - //! between the sections. The `dstSize` is always checked and the copy will - //! never write anything outside the provided buffer. - ASMJIT_API Error copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOptions = 0) noexcept; - - //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use 'CodeHolder::init(const Environment& environment, uint64_t baseAddress)' instead") - inline Error init(const CodeInfo& codeInfo) noexcept { return init(codeInfo._environment, codeInfo._baseAddress); } - - ASMJIT_DEPRECATED("Use nevironment() instead") - inline CodeInfo codeInfo() const noexcept { return CodeInfo(_environment, _baseAddress); } - - ASMJIT_DEPRECATED("Use BaseEmitter::encodingOptions() - this function always returns zero") - inline uint32_t emitterOptions() const noexcept { return 0; } - - ASMJIT_DEPRECATED("Use BaseEmitter::addEncodingOptions() - this function does nothing") - inline void addEmitterOptions(uint32_t options) noexcept { DebugUtils::unused(options); } - - ASMJIT_DEPRECATED("Use BaseEmitter::clearEncodingOptions() - this function does nothing") - inline void clearEmitterOptions(uint32_t options) noexcept { DebugUtils::unused(options); } -#endif // !ASMJIT_NO_DEPRECATED -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_CODEHOLDER_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codewriter.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codewriter.cpp deleted file mode 100644 index 6097c0e..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codewriter.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/codeholder.h" -#include "../core/codewriter_p.h" - -ASMJIT_BEGIN_NAMESPACE - -bool CodeWriterUtils::encodeOffset32(uint32_t* dst, int64_t offset64, const OffsetFormat& format) noexcept { - uint32_t bitCount = format.immBitCount(); - uint32_t bitShift = format.immBitShift(); - uint32_t discardLsb = format.immDiscardLsb(); - - if (!bitCount || bitCount > format.valueSize() * 8u) - return false; - - if (discardLsb) { - ASMJIT_ASSERT(discardLsb <= 32); - if ((offset64 & Support::lsbMask(discardLsb)) != 0) - return false; - offset64 >>= discardLsb; - } - - if (!Support::isInt32(offset64)) - return false; - - int32_t offset32 = int32_t(offset64); - if (!Support::isEncodableOffset32(offset32, bitCount)) - return false; - - switch (format.type()) { - case OffsetFormat::kTypeCommon: { - *dst = (uint32_t(offset32) & Support::lsbMask(bitCount)) << bitShift; - return true; - } - - case OffsetFormat::kTypeAArch64_ADR: - case OffsetFormat::kTypeAArch64_ADRP: { - // Sanity checks. - if (format.valueSize() != 4 || bitCount != 21 || bitShift != 5) - return false; - - uint32_t immLo = uint32_t(offset32) & 0x3u; - uint32_t immHi = uint32_t(offset32 >> 2) & Support::lsbMask(19); - - *dst = (immLo << 29) | (immHi << 5); - return true; - } - - default: - return false; - } -} - -bool CodeWriterUtils::encodeOffset64(uint64_t* dst, int64_t offset64, const OffsetFormat& format) noexcept { - uint32_t bitCount = format.immBitCount(); - uint32_t discardLsb = format.immDiscardLsb(); - - if (!bitCount || bitCount > format.valueSize() * 8u) - return false; - - if (discardLsb) { - ASMJIT_ASSERT(discardLsb <= 32); - if ((offset64 & Support::lsbMask(discardLsb)) != 0) - return false; - offset64 >>= discardLsb; - } - - if (!Support::isEncodableOffset64(offset64, bitCount)) - return false; - - switch (format.type()) { - case OffsetFormat::kTypeCommon: { - *dst = (uint64_t(offset64) & Support::lsbMask(bitCount)) << format.immBitShift(); - return true; - } - - default: - return false; - } -} - -bool CodeWriterUtils::writeOffset(void* dst, int64_t offset64, const OffsetFormat& format) noexcept { - // Offset the destination by ValueOffset so the `dst` points to the - // patched word instead of the beginning of the patched region. - dst = static_cast(dst) + format.valueOffset(); - - switch (format.valueSize()) { - case 1: { - uint32_t mask; - if (!encodeOffset32(&mask, offset64, format)) - return false; - - Support::writeU8(dst, Support::readU8(dst) | mask); - return true; - } - - case 2: { - uint32_t mask; - if (!encodeOffset32(&mask, offset64, format)) - return false; - - Support::writeU16uLE(dst, Support::readU16uLE(dst) | mask); - return true; - } - - case 4: { - uint32_t mask; - if (!encodeOffset32(&mask, offset64, format)) - return false; - - Support::writeU32uLE(dst, Support::readU32uLE(dst) | mask); - return true; - } - - case 8: { - uint64_t mask; - if (!encodeOffset64(&mask, offset64, format)) - return false; - - Support::writeU64uLE(dst, Support::readU64uLE(dst) | mask); - return true; - } - - default: - return false; - } -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codewriter_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codewriter_p.h deleted file mode 100644 index 61c9101..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/codewriter_p.h +++ /dev/null @@ -1,208 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_CODEBUFFERWRITER_P_H_INCLUDED -#define ASMJIT_CORE_CODEBUFFERWRITER_P_H_INCLUDED - -#include "../core/assembler.h" -#include "../core/codebuffer.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \cond INTERNAL -//! \addtogroup asmjit_assembler -//! \{ - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -struct OffsetFormat; - -// ============================================================================ -// [asmjit::CodeWriter] -// ============================================================================ - -//! Helper that is used to write into a \ref CodeBuffer held by \ref BaseAssembler. -class CodeWriter { -public: - uint8_t* _cursor; - - ASMJIT_INLINE explicit CodeWriter(BaseAssembler* a) noexcept - : _cursor(a->_bufferPtr) {} - - ASMJIT_INLINE Error ensureSpace(BaseAssembler* a, size_t n) noexcept { - size_t remainingSpace = (size_t)(a->_bufferEnd - _cursor); - if (ASMJIT_UNLIKELY(remainingSpace < n)) { - CodeBuffer& buffer = a->_section->_buffer; - Error err = a->_code->growBuffer(&buffer, n); - if (ASMJIT_UNLIKELY(err)) - return a->reportError(err); - _cursor = a->_bufferPtr; - } - return kErrorOk; - } - - ASMJIT_INLINE uint8_t* cursor() const noexcept { return _cursor; } - ASMJIT_INLINE void setCursor(uint8_t* cursor) noexcept { _cursor = cursor; } - ASMJIT_INLINE void advance(size_t n) noexcept { _cursor += n; } - - ASMJIT_INLINE size_t offsetFrom(uint8_t* from) const noexcept { - ASMJIT_ASSERT(_cursor >= from); - return (size_t)(_cursor - from); - } - - template - ASMJIT_INLINE void emit8(T val) noexcept { - typedef typename std::make_unsigned::type U; - _cursor[0] = uint8_t(U(val) & U(0xFF)); - _cursor++; - } - - template - ASMJIT_INLINE void emit8If(T val, Y cond) noexcept { - typedef typename std::make_unsigned::type U; - ASMJIT_ASSERT(size_t(cond) <= 1u); - - _cursor[0] = uint8_t(U(val) & U(0xFF)); - _cursor += size_t(cond); - } - - template - ASMJIT_INLINE void emit16uLE(T val) noexcept { - typedef typename std::make_unsigned::type U; - Support::writeU16uLE(_cursor, uint32_t(U(val) & 0xFFFFu)); - _cursor += 2; - } - - template - ASMJIT_INLINE void emit16uBE(T val) noexcept { - typedef typename std::make_unsigned::type U; - Support::writeU16uBE(_cursor, uint32_t(U(val) & 0xFFFFu)); - _cursor += 2; - } - - template - ASMJIT_INLINE void emit32uLE(T val) noexcept { - typedef typename std::make_unsigned::type U; - Support::writeU32uLE(_cursor, uint32_t(U(val) & 0xFFFFFFFFu)); - _cursor += 4; - } - - template - ASMJIT_INLINE void emit32uBE(T val) noexcept { - typedef typename std::make_unsigned::type U; - Support::writeU32uBE(_cursor, uint32_t(U(val) & 0xFFFFFFFFu)); - _cursor += 4; - } - - ASMJIT_INLINE void emitData(const void* data, size_t size) noexcept { - ASMJIT_ASSERT(size != 0); - memcpy(_cursor, data, size); - _cursor += size; - } - - template - ASMJIT_INLINE void emitValueLE(const T& value, size_t size) noexcept { - typedef typename std::make_unsigned::type U; - ASMJIT_ASSERT(size <= sizeof(T)); - - U v = U(value); - for (uint32_t i = 0; i < size; i++) { - _cursor[i] = uint8_t(v & 0xFFu); - v >>= 8; - } - _cursor += size; - } - - template - ASMJIT_INLINE void emitValueBE(const T& value, size_t size) noexcept { - typedef typename std::make_unsigned::type U; - ASMJIT_ASSERT(size <= sizeof(T)); - - U v = U(value); - for (uint32_t i = 0; i < size; i++) { - _cursor[i] = uint8_t(v >> (sizeof(T) - 8)); - v <<= 8; - } - _cursor += size; - } - - ASMJIT_INLINE void emitZeros(size_t size) noexcept { - ASMJIT_ASSERT(size != 0); - memset(_cursor, 0, size); - _cursor += size; - } - - ASMJIT_INLINE void remove8(uint8_t* where) noexcept { - ASMJIT_ASSERT(where < _cursor); - - uint8_t* p = where; - while (++p != _cursor) - p[-1] = p[0]; - _cursor--; - } - - template - ASMJIT_INLINE void insert8(uint8_t* where, T val) noexcept { - uint8_t* p = _cursor; - - while (p != where) { - p[0] = p[-1]; - p--; - } - - *p = uint8_t(val & 0xFF); - _cursor++; - } - - ASMJIT_INLINE void done(BaseAssembler* a) noexcept { - CodeBuffer& buffer = a->_section->_buffer; - size_t newSize = (size_t)(_cursor - a->_bufferData); - ASMJIT_ASSERT(newSize <= buffer.capacity()); - - a->_bufferPtr = _cursor; - buffer._size = Support::max(buffer._size, newSize); - } -}; - -// ============================================================================ -// [asmjit::CodeWriterUtils] -// ============================================================================ - -namespace CodeWriterUtils { - -bool encodeOffset32(uint32_t* dst, int64_t offset64, const OffsetFormat& format) noexcept; -bool encodeOffset64(uint64_t* dst, int64_t offset64, const OffsetFormat& format) noexcept; - -bool writeOffset(void* dst, int64_t offset64, const OffsetFormat& format) noexcept; - -} // {CodeWriterUtils} - -//! \} -//! \endcond - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_CODEBUFFERWRITER_P_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compiler.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compiler.cpp deleted file mode 100644 index 4d7baab..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compiler.cpp +++ /dev/null @@ -1,628 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#ifndef ASMJIT_NO_COMPILER - -#include "../core/assembler.h" -#include "../core/compiler.h" -#include "../core/cpuinfo.h" -#include "../core/logger.h" -#include "../core/rapass_p.h" -#include "../core/rastack_p.h" -#include "../core/support.h" -#include "../core/type.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::GlobalConstPoolPass] -// ============================================================================ - -class GlobalConstPoolPass : public Pass { - typedef Pass Base; - ASMJIT_NONCOPYABLE(GlobalConstPoolPass) - - GlobalConstPoolPass() noexcept : Pass("GlobalConstPoolPass") {} - - Error run(Zone* zone, Logger* logger) override { - DebugUtils::unused(zone, logger); - - // Flush the global constant pool. - BaseCompiler* compiler = static_cast(_cb); - if (compiler->_globalConstPool) { - compiler->addAfter(compiler->_globalConstPool, compiler->lastNode()); - compiler->_globalConstPool = nullptr; - } - - return kErrorOk; - } -}; - -// ============================================================================ -// [asmjit::BaseCompiler - Construction / Destruction] -// ============================================================================ - -BaseCompiler::BaseCompiler() noexcept - : BaseBuilder(), - _func(nullptr), - _vRegZone(4096 - Zone::kBlockOverhead), - _vRegArray(), - _localConstPool(nullptr), - _globalConstPool(nullptr) { - - _emitterType = uint8_t(kTypeCompiler); - _validationFlags = uint8_t(InstAPI::kValidationFlagVirtRegs); -} -BaseCompiler::~BaseCompiler() noexcept {} - -// ============================================================================ -// [asmjit::BaseCompiler - Function Management] -// ============================================================================ - -Error BaseCompiler::_newFuncNode(FuncNode** out, const FuncSignature& signature) { - *out = nullptr; - - // Create FuncNode together with all the required surrounding nodes. - FuncNode* funcNode; - ASMJIT_PROPAGATE(_newNodeT(&funcNode)); - ASMJIT_PROPAGATE(_newLabelNode(&funcNode->_exitNode)); - ASMJIT_PROPAGATE(_newNodeT(&funcNode->_end, SentinelNode::kSentinelFuncEnd)); - - // Initialize the function's detail info. - Error err = funcNode->detail().init(signature, environment()); - if (ASMJIT_UNLIKELY(err)) - return reportError(err); - - // If the Target guarantees greater stack alignment than required by the - // calling convention then override it as we can prevent having to perform - // dynamic stack alignment - uint32_t environmentStackAlignment = _environment.stackAlignment(); - - if (funcNode->_funcDetail._callConv.naturalStackAlignment() < environmentStackAlignment) - funcNode->_funcDetail._callConv.setNaturalStackAlignment(environmentStackAlignment); - - // Initialize the function frame. - err = funcNode->_frame.init(funcNode->_funcDetail); - if (ASMJIT_UNLIKELY(err)) - return reportError(err); - - // Allocate space for function arguments. - funcNode->_args = nullptr; - if (funcNode->argCount() != 0) { - funcNode->_args = _allocator.allocT(funcNode->argCount() * sizeof(FuncNode::ArgPack)); - if (ASMJIT_UNLIKELY(!funcNode->_args)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - memset(funcNode->_args, 0, funcNode->argCount() * sizeof(FuncNode::ArgPack)); - } - - ASMJIT_PROPAGATE(registerLabelNode(funcNode)); - - *out = funcNode; - return kErrorOk; -} - -Error BaseCompiler::_addFuncNode(FuncNode** out, const FuncSignature& signature) { - ASMJIT_PROPAGATE(_newFuncNode(out, signature)); - addFunc(*out); - return kErrorOk; -} - -Error BaseCompiler::_newRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) { - uint32_t opCount = !o1.isNone() ? 2u : !o0.isNone() ? 1u : 0u; - FuncRetNode* node; - - ASMJIT_PROPAGATE(_newNodeT(&node)); - node->setOpCount(opCount); - node->setOp(0, o0); - node->setOp(1, o1); - node->resetOpRange(2, node->opCapacity()); - - *out = node; - return kErrorOk; -} - -Error BaseCompiler::_addRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) { - ASMJIT_PROPAGATE(_newRetNode(out, o0, o1)); - addNode(*out); - return kErrorOk; -} - -FuncNode* BaseCompiler::addFunc(FuncNode* func) { - ASMJIT_ASSERT(_func == nullptr); - _func = func; - - addNode(func); // Function node. - BaseNode* prev = cursor(); // {CURSOR}. - addNode(func->exitNode()); // Function exit label. - addNode(func->endNode()); // Function end sentinel. - - _setCursor(prev); - return func; -} - -Error BaseCompiler::endFunc() { - FuncNode* func = _func; - - if (ASMJIT_UNLIKELY(!func)) - return reportError(DebugUtils::errored(kErrorInvalidState)); - - // Add the local constant pool at the end of the function (if exists). - if (_localConstPool) { - setCursor(func->endNode()->prev()); - addNode(_localConstPool); - _localConstPool = nullptr; - } - - // Mark as finished. - _func = nullptr; - - SentinelNode* end = func->endNode(); - setCursor(end); - - return kErrorOk; -} - -Error BaseCompiler::_setArg(size_t argIndex, size_t valueIndex, const BaseReg& r) { - FuncNode* func = _func; - - if (ASMJIT_UNLIKELY(!func)) - return reportError(DebugUtils::errored(kErrorInvalidState)); - - if (ASMJIT_UNLIKELY(!isVirtRegValid(r))) - return reportError(DebugUtils::errored(kErrorInvalidVirtId)); - - VirtReg* vReg = virtRegByReg(r); - func->setArg(argIndex, valueIndex, vReg); - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseCompiler - Function Invocation] -// ============================================================================ - -Error BaseCompiler::_newInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature) { - InvokeNode* node; - ASMJIT_PROPAGATE(_newNodeT(&node, instId, 0u)); - - node->setOpCount(1); - node->setOp(0, o0); - node->resetOpRange(1, node->opCapacity()); - - Error err = node->detail().init(signature, environment()); - if (ASMJIT_UNLIKELY(err)) - return reportError(err); - - // Skip the allocation if there are no arguments. - uint32_t argCount = signature.argCount(); - if (argCount) { - node->_args = static_cast(_allocator.alloc(argCount * sizeof(InvokeNode::OperandPack))); - if (!node->_args) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - memset(node->_args, 0, argCount * sizeof(InvokeNode::OperandPack)); - } - - *out = node; - return kErrorOk; -} - -Error BaseCompiler::_addInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature) { - ASMJIT_PROPAGATE(_newInvokeNode(out, instId, o0, signature)); - addNode(*out); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseCompiler - Virtual Registers] -// ============================================================================ - -static void BaseCompiler_assignGenericName(BaseCompiler* self, VirtReg* vReg) { - uint32_t index = unsigned(Operand::virtIdToIndex(vReg->_id)); - - char buf[64]; - int size = snprintf(buf, ASMJIT_ARRAY_SIZE(buf), "%%%u", unsigned(index)); - - ASMJIT_ASSERT(size > 0 && size < int(ASMJIT_ARRAY_SIZE(buf))); - vReg->_name.setData(&self->_dataZone, buf, unsigned(size)); -} - -Error BaseCompiler::newVirtReg(VirtReg** out, uint32_t typeId, uint32_t signature, const char* name) { - *out = nullptr; - uint32_t index = _vRegArray.size(); - - if (ASMJIT_UNLIKELY(index >= uint32_t(Operand::kVirtIdCount))) - return reportError(DebugUtils::errored(kErrorTooManyVirtRegs)); - - if (ASMJIT_UNLIKELY(_vRegArray.willGrow(&_allocator) != kErrorOk)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - - VirtReg* vReg = _vRegZone.allocZeroedT(); - if (ASMJIT_UNLIKELY(!vReg)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - - uint32_t size = Type::sizeOf(typeId); - uint32_t alignment = Support::min(size, 64); - - vReg = new(vReg) VirtReg(Operand::indexToVirtId(index), signature, size, alignment, typeId); - -#ifndef ASMJIT_NO_LOGGING - if (name && name[0] != '\0') - vReg->_name.setData(&_dataZone, name, SIZE_MAX); - else - BaseCompiler_assignGenericName(this, vReg); -#else - DebugUtils::unused(name); -#endif - - _vRegArray.appendUnsafe(vReg); - *out = vReg; - - return kErrorOk; -} - -Error BaseCompiler::_newReg(BaseReg* out, uint32_t typeId, const char* name) { - RegInfo regInfo; - out->reset(); - - Error err = ArchUtils::typeIdToRegInfo(arch(), typeId, &typeId, ®Info); - if (ASMJIT_UNLIKELY(err)) - return reportError(err); - - VirtReg* vReg; - ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regInfo.signature(), name)); - - out->_initReg(regInfo.signature(), vReg->id()); - return kErrorOk; -} - -Error BaseCompiler::_newRegFmt(BaseReg* out, uint32_t typeId, const char* fmt, ...) { - va_list ap; - StringTmp<256> sb; - - va_start(ap, fmt); - sb.appendVFormat(fmt, ap); - va_end(ap); - - return _newReg(out, typeId, sb.data()); -} - -Error BaseCompiler::_newReg(BaseReg* out, const BaseReg& ref, const char* name) { - out->reset(); - - RegInfo regInfo; - uint32_t typeId; - - if (isVirtRegValid(ref)) { - VirtReg* vRef = virtRegByReg(ref); - typeId = vRef->typeId(); - - // NOTE: It's possible to cast one register type to another if it's the - // same register group. However, VirtReg always contains the TypeId that - // was used to create the register. This means that in some cases we may - // end up having different size of `ref` and `vRef`. In such case we - // adjust the TypeId to match the `ref` register type instead of the - // original register type, which should be the expected behavior. - uint32_t typeSize = Type::sizeOf(typeId); - uint32_t refSize = ref.size(); - - if (typeSize != refSize) { - if (Type::isInt(typeId)) { - // GP register - change TypeId to match `ref`, but keep sign of `vRef`. - switch (refSize) { - case 1: typeId = Type::kIdI8 | (typeId & 1); break; - case 2: typeId = Type::kIdI16 | (typeId & 1); break; - case 4: typeId = Type::kIdI32 | (typeId & 1); break; - case 8: typeId = Type::kIdI64 | (typeId & 1); break; - default: typeId = Type::kIdVoid; break; - } - } - else if (Type::isMmx(typeId)) { - // MMX register - always use 64-bit. - typeId = Type::kIdMmx64; - } - else if (Type::isMask(typeId)) { - // Mask register - change TypeId to match `ref` size. - switch (refSize) { - case 1: typeId = Type::kIdMask8; break; - case 2: typeId = Type::kIdMask16; break; - case 4: typeId = Type::kIdMask32; break; - case 8: typeId = Type::kIdMask64; break; - default: typeId = Type::kIdVoid; break; - } - } - else { - // VEC register - change TypeId to match `ref` size, keep vector metadata. - uint32_t elementTypeId = Type::baseOf(typeId); - - switch (refSize) { - case 16: typeId = Type::_kIdVec128Start + (elementTypeId - Type::kIdI8); break; - case 32: typeId = Type::_kIdVec256Start + (elementTypeId - Type::kIdI8); break; - case 64: typeId = Type::_kIdVec512Start + (elementTypeId - Type::kIdI8); break; - default: typeId = Type::kIdVoid; break; - } - } - - if (typeId == Type::kIdVoid) - return reportError(DebugUtils::errored(kErrorInvalidState)); - } - } - else { - typeId = ref.type(); - } - - Error err = ArchUtils::typeIdToRegInfo(arch(), typeId, &typeId, ®Info); - if (ASMJIT_UNLIKELY(err)) - return reportError(err); - - VirtReg* vReg; - ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regInfo.signature(), name)); - - out->_initReg(regInfo.signature(), vReg->id()); - return kErrorOk; -} - -Error BaseCompiler::_newRegFmt(BaseReg* out, const BaseReg& ref, const char* fmt, ...) { - va_list ap; - StringTmp<256> sb; - - va_start(ap, fmt); - sb.appendVFormat(fmt, ap); - va_end(ap); - - return _newReg(out, ref, sb.data()); -} - -Error BaseCompiler::_newStack(BaseMem* out, uint32_t size, uint32_t alignment, const char* name) { - out->reset(); - - if (size == 0) - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - if (alignment == 0) - alignment = 1; - - if (!Support::isPowerOf2(alignment)) - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - if (alignment > 64) - alignment = 64; - - VirtReg* vReg; - ASMJIT_PROPAGATE(newVirtReg(&vReg, 0, 0, name)); - - vReg->_virtSize = size; - vReg->_isStack = true; - vReg->_alignment = uint8_t(alignment); - - // Set the memory operand to GPD/GPQ and its id to VirtReg. - *out = BaseMem(BaseMem::Decomposed { _gpRegInfo.type(), vReg->id(), BaseReg::kTypeNone, 0, 0, 0, BaseMem::kSignatureMemRegHomeFlag }); - return kErrorOk; -} - -Error BaseCompiler::setStackSize(uint32_t virtId, uint32_t newSize, uint32_t newAlignment) { - if (!isVirtIdValid(virtId)) - return DebugUtils::errored(kErrorInvalidVirtId); - - if (newAlignment && !Support::isPowerOf2(newAlignment)) - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - if (newAlignment > 64) - newAlignment = 64; - - VirtReg* vReg = virtRegById(virtId); - if (newSize) - vReg->_virtSize = newSize; - - if (newAlignment) - vReg->_alignment = uint8_t(newAlignment); - - // This is required if the RAPass is already running. There is a chance that - // a stack-slot has been already allocated and in that case it has to be - // updated as well, otherwise we would allocate wrong amount of memory. - RAWorkReg* workReg = vReg->_workReg; - if (workReg && workReg->_stackSlot) { - workReg->_stackSlot->_size = vReg->_virtSize; - workReg->_stackSlot->_alignment = vReg->_alignment; - } - - return kErrorOk; -} - -Error BaseCompiler::_newConst(BaseMem* out, uint32_t scope, const void* data, size_t size) { - out->reset(); - ConstPoolNode** pPool; - - if (scope == ConstPool::kScopeLocal) - pPool = &_localConstPool; - else if (scope == ConstPool::kScopeGlobal) - pPool = &_globalConstPool; - else - return reportError(DebugUtils::errored(kErrorInvalidArgument)); - - if (!*pPool) - ASMJIT_PROPAGATE(_newConstPoolNode(pPool)); - - ConstPoolNode* pool = *pPool; - size_t off; - Error err = pool->add(data, size, off); - - if (ASMJIT_UNLIKELY(err)) - return reportError(err); - - *out = BaseMem(BaseMem::Decomposed { - Label::kLabelTag, // Base type. - pool->labelId(), // Base id. - 0, // Index type. - 0, // Index id. - int32_t(off), // Offset. - uint32_t(size), // Size. - 0 // Flags. - }); - - return kErrorOk; -} - -void BaseCompiler::rename(const BaseReg& reg, const char* fmt, ...) { - if (!reg.isVirtReg()) return; - - VirtReg* vReg = virtRegById(reg.id()); - if (!vReg) return; - - if (fmt && fmt[0] != '\0') { - char buf[128]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap); - va_end(ap); - - vReg->_name.setData(&_dataZone, buf, SIZE_MAX); - } - else { - BaseCompiler_assignGenericName(this, vReg); - } -} - -// ============================================================================ -// [asmjit::BaseCompiler - Jump Annotations] -// ============================================================================ - -Error BaseCompiler::newJumpNode(JumpNode** out, uint32_t instId, uint32_t instOptions, const Operand_& o0, JumpAnnotation* annotation) { - JumpNode* node = _allocator.allocT(); - uint32_t opCount = 1; - - *out = node; - if (ASMJIT_UNLIKELY(!node)) - return reportError(DebugUtils::errored(kErrorOutOfMemory)); - - node = new(node) JumpNode(this, instId, instOptions, opCount, annotation); - node->setOp(0, o0); - node->resetOpRange(opCount, JumpNode::kBaseOpCapacity); - - return kErrorOk; -} - -Error BaseCompiler::emitAnnotatedJump(uint32_t instId, const Operand_& o0, JumpAnnotation* annotation) { - uint32_t options = instOptions() | forcedInstOptions(); - RegOnly extra = extraReg(); - const char* comment = inlineComment(); - - resetInstOptions(); - resetInlineComment(); - resetExtraReg(); - - JumpNode* node; - ASMJIT_PROPAGATE(newJumpNode(&node, instId, options, o0, annotation)); - - node->setExtraReg(extra); - if (comment) - node->setInlineComment(static_cast(_dataZone.dup(comment, strlen(comment), true))); - - addNode(node); - return kErrorOk; -} - -JumpAnnotation* BaseCompiler::newJumpAnnotation() { - if (_jumpAnnotations.grow(&_allocator, 1) != kErrorOk) { - reportError(DebugUtils::errored(kErrorOutOfMemory)); - return nullptr; - } - - uint32_t id = _jumpAnnotations.size(); - JumpAnnotation* jumpAnnotation = _allocator.newT(this, id); - - if (!jumpAnnotation) { - reportError(DebugUtils::errored(kErrorOutOfMemory)); - return nullptr; - } - - _jumpAnnotations.appendUnsafe(jumpAnnotation); - return jumpAnnotation; -} - -// ============================================================================ -// [asmjit::BaseCompiler - Events] -// ============================================================================ - -Error BaseCompiler::onAttach(CodeHolder* code) noexcept { - ASMJIT_PROPAGATE(Base::onAttach(code)); - - const ArchTraits& archTraits = ArchTraits::byArch(code->arch()); - uint32_t nativeRegType = Environment::is32Bit(code->arch()) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64; - _gpRegInfo.setSignature(archTraits.regTypeToSignature(nativeRegType)); - - Error err = addPassT(); - if (ASMJIT_UNLIKELY(err)) { - onDetach(code); - return err; - } - - return kErrorOk; -} - -Error BaseCompiler::onDetach(CodeHolder* code) noexcept { - _func = nullptr; - _localConstPool = nullptr; - _globalConstPool = nullptr; - - _vRegArray.reset(); - _vRegZone.reset(); - - return Base::onDetach(code); -} - -// ============================================================================ -// [asmjit::FuncPass - Construction / Destruction] -// ============================================================================ - -FuncPass::FuncPass(const char* name) noexcept - : Pass(name) {} - -// ============================================================================ -// [asmjit::FuncPass - Run] -// ============================================================================ - -Error FuncPass::run(Zone* zone, Logger* logger) { - BaseNode* node = cb()->firstNode(); - if (!node) return kErrorOk; - - do { - if (node->type() == BaseNode::kNodeFunc) { - FuncNode* func = node->as(); - node = func->endNode(); - ASMJIT_PROPAGATE(runOnFunction(zone, logger, func)); - } - - // Find a function by skipping all nodes that are not `kNodeFunc`. - do { - node = node->next(); - } while (node && node->type() != BaseNode::kNodeFunc); - } while (node); - - return kErrorOk; -} - -ASMJIT_END_NAMESPACE - -#endif // !ASMJIT_NO_COMPILER diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compiler.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compiler.h deleted file mode 100644 index eb2a5aa..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compiler.h +++ /dev/null @@ -1,763 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_COMPILER_H_INCLUDED -#define ASMJIT_CORE_COMPILER_H_INCLUDED - -#include "../core/api-config.h" -#ifndef ASMJIT_NO_COMPILER - -#include "../core/assembler.h" -#include "../core/builder.h" -#include "../core/constpool.h" -#include "../core/compilerdefs.h" -#include "../core/func.h" -#include "../core/inst.h" -#include "../core/operand.h" -#include "../core/support.h" -#include "../core/zone.h" -#include "../core/zonevector.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -class JumpAnnotation; -class JumpNode; -class FuncNode; -class FuncRetNode; -class InvokeNode; - -//! \addtogroup asmjit_compiler -//! \{ - -// ============================================================================ -// [asmjit::BaseCompiler] -// ============================================================================ - -//! Code emitter that uses virtual registers and performs register allocation. -//! -//! Compiler is a high-level code-generation tool that provides register -//! allocation and automatic handling of function calling conventions. It was -//! primarily designed for merging multiple parts of code into a function -//! without worrying about registers and function calling conventions. -//! -//! BaseCompiler can be used, with a minimum effort, to handle 32-bit and -//! 64-bit code generation within a single code base. -//! -//! BaseCompiler is based on BaseBuilder and contains all the features it -//! provides. It means that the code it stores can be modified (removed, added, -//! injected) and analyzed. When the code is finalized the compiler can emit -//! the code into an Assembler to translate the abstract representation into a -//! machine code. -//! -//! Check out architecture specific compilers for more details and examples: -//! -//! - \ref x86::Compiler - X86/X64 compiler implementation. -class ASMJIT_VIRTAPI BaseCompiler : public BaseBuilder { -public: - ASMJIT_NONCOPYABLE(BaseCompiler) - typedef BaseBuilder Base; - - //! Current function. - FuncNode* _func; - //! Allocates `VirtReg` objects. - Zone _vRegZone; - //! Stores array of `VirtReg` pointers. - ZoneVector _vRegArray; - //! Stores jump annotations. - ZoneVector _jumpAnnotations; - - //! Local constant pool, flushed at the end of each function. - ConstPoolNode* _localConstPool; - //! Global constant pool, flushed by `finalize()`. - ConstPoolNode* _globalConstPool; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `BaseCompiler` instance. - ASMJIT_API BaseCompiler() noexcept; - //! Destroys the `BaseCompiler` instance. - ASMJIT_API virtual ~BaseCompiler() noexcept; - - //! \} - - //! \name Function Management - //! \{ - - //! Returns the current function. - inline FuncNode* func() const noexcept { return _func; } - - //! Creates a new \ref FuncNode. - ASMJIT_API Error _newFuncNode(FuncNode** out, const FuncSignature& signature); - //! Creates a new \ref FuncNode adds it to the compiler. - ASMJIT_API Error _addFuncNode(FuncNode** out, const FuncSignature& signature); - - //! Creates a new \ref FuncRetNode. - ASMJIT_API Error _newRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1); - //! Creates a new \ref FuncRetNode and adds it to the compiler. - ASMJIT_API Error _addRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1); - - //! Creates a new \ref FuncNode with the given `signature` and returns it. - inline FuncNode* newFunc(const FuncSignature& signature) { - FuncNode* node; - _newFuncNode(&node, signature); - return node; - } - - //! Creates a new \ref FuncNode with the given `signature`, adds it to the - //! compiler by using the \ref addFunc(FuncNode*) overload, and returns it. - inline FuncNode* addFunc(const FuncSignature& signature) { - FuncNode* node; - _addFuncNode(&node, signature); - return node; - } - - //! Adds a function `node` to the instruction stream. - ASMJIT_API FuncNode* addFunc(FuncNode* func); - //! Emits a sentinel that marks the end of the current function. - ASMJIT_API Error endFunc(); - - ASMJIT_API Error _setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg); - - //! Sets a function argument at `argIndex` to `reg`. - inline Error setArg(size_t argIndex, const BaseReg& reg) { return _setArg(argIndex, 0, reg); } - //! Sets a function argument at `argIndex` at `valueIndex` to `reg`. - inline Error setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg) { return _setArg(argIndex, valueIndex, reg); } - - inline FuncRetNode* newRet(const Operand_& o0, const Operand_& o1) { - FuncRetNode* node; - _newRetNode(&node, o0, o1); - return node; - } - - inline FuncRetNode* addRet(const Operand_& o0, const Operand_& o1) { - FuncRetNode* node; - _addRetNode(&node, o0, o1); - return node; - } - - //! \} - - //! \name Function Invocation - //! \{ - - //! Creates a new \ref InvokeNode. - ASMJIT_API Error _newInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature); - //! Creates a new \ref InvokeNode and adds it to Compiler. - ASMJIT_API Error _addInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature); - - //! Creates a new `InvokeNode`. - inline InvokeNode* newCall(uint32_t instId, const Operand_& o0, const FuncSignature& signature) { - InvokeNode* node; - _newInvokeNode(&node, instId, o0, signature); - return node; - } - - //! Adds a new `InvokeNode`. - inline InvokeNode* addCall(uint32_t instId, const Operand_& o0, const FuncSignature& signature) { - InvokeNode* node; - _addInvokeNode(&node, instId, o0, signature); - return node; - } - - //! \} - - //! \name Virtual Registers - //! \{ - - //! Creates a new virtual register representing the given `typeId` and `signature`. - //! - //! \note This function is public, but it's not generally recommended to be used - //! by AsmJit users, use architecture-specific `newReg()` functionality instead - //! or functions like \ref _newReg() and \ref _newRegFmt(). - ASMJIT_API Error newVirtReg(VirtReg** out, uint32_t typeId, uint32_t signature, const char* name); - - //! Creates a new virtual register of the given `typeId` and stores it to `out` operand. - ASMJIT_API Error _newReg(BaseReg* out, uint32_t typeId, const char* name = nullptr); - - //! Creates a new virtual register of the given `typeId` and stores it to `out` operand. - //! - //! \note This version accepts a snprintf() format `fmt` followed by a variadic arguments. - ASMJIT_API Error _newRegFmt(BaseReg* out, uint32_t typeId, const char* fmt, ...); - - //! Creates a new virtual register compatible with the provided reference register `ref`. - ASMJIT_API Error _newReg(BaseReg* out, const BaseReg& ref, const char* name = nullptr); - - //! Creates a new virtual register compatible with the provided reference register `ref`. - //! - //! \note This version accepts a snprintf() format `fmt` followed by a variadic arguments. - ASMJIT_API Error _newRegFmt(BaseReg* out, const BaseReg& ref, const char* fmt, ...); - - //! Tests whether the given `id` is a valid virtual register id. - inline bool isVirtIdValid(uint32_t id) const noexcept { - uint32_t index = Operand::virtIdToIndex(id); - return index < _vRegArray.size(); - } - //! Tests whether the given `reg` is a virtual register having a valid id. - inline bool isVirtRegValid(const BaseReg& reg) const noexcept { - return isVirtIdValid(reg.id()); - } - - //! Returns \ref VirtReg associated with the given `id`. - inline VirtReg* virtRegById(uint32_t id) const noexcept { - ASMJIT_ASSERT(isVirtIdValid(id)); - return _vRegArray[Operand::virtIdToIndex(id)]; - } - - //! Returns \ref VirtReg associated with the given `reg`. - inline VirtReg* virtRegByReg(const BaseReg& reg) const noexcept { return virtRegById(reg.id()); } - - //! Returns \ref VirtReg associated with the given virtual register `index`. - //! - //! \note This is not the same as virtual register id. The conversion between - //! id and its index is implemented by \ref Operand_::virtIdToIndex() and \ref - //! Operand_::indexToVirtId() functions. - inline VirtReg* virtRegByIndex(uint32_t index) const noexcept { return _vRegArray[index]; } - - //! Returns an array of all virtual registers managed by the Compiler. - inline const ZoneVector& virtRegs() const noexcept { return _vRegArray; } - - //! \name Stack - //! \{ - - //! Creates a new stack of the given `size` and `alignment` and stores it to `out`. - //! - //! \note `name` can be used to give the stack a name, for debugging purposes. - ASMJIT_API Error _newStack(BaseMem* out, uint32_t size, uint32_t alignment, const char* name = nullptr); - - //! Updates the stack size of a stack created by `_newStack()` by its `virtId`. - ASMJIT_API Error setStackSize(uint32_t virtId, uint32_t newSize, uint32_t newAlignment = 0); - - //! Updates the stack size of a stack created by `_newStack()`. - inline Error setStackSize(const BaseMem& mem, uint32_t newSize, uint32_t newAlignment = 0) { - return setStackSize(mem.id(), newSize, newAlignment); - } - - //! \} - - //! \name Constants - //! \{ - - //! Creates a new constant of the given `scope` (see \ref ConstPool::Scope). - //! - //! This function adds a constant of the given `size` to the built-in \ref - //! ConstPool and stores the reference to that constant to the `out` operand. - ASMJIT_API Error _newConst(BaseMem* out, uint32_t scope, const void* data, size_t size); - - //! \} - - //! \name Miscellaneous - //! \{ - - //! Rename the given virtual register `reg` to a formatted string `fmt`. - ASMJIT_API void rename(const BaseReg& reg, const char* fmt, ...); - - //! \} - - //! \name Jump Annotations - //! \{ - - inline const ZoneVector& jumpAnnotations() const noexcept { - return _jumpAnnotations; - } - - ASMJIT_API Error newJumpNode(JumpNode** out, uint32_t instId, uint32_t instOptions, const Operand_& o0, JumpAnnotation* annotation); - ASMJIT_API Error emitAnnotatedJump(uint32_t instId, const Operand_& o0, JumpAnnotation* annotation); - - //! Returns a new `JumpAnnotation` instance, which can be used to aggregate - //! possible targets of a jump where the target is not a label, for example - //! to implement jump tables. - ASMJIT_API JumpAnnotation* newJumpAnnotation(); - - //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("alloc() has no effect, it will be removed in the future") - inline void alloc(BaseReg&) {} - ASMJIT_DEPRECATED("spill() has no effect, it will be removed in the future") - inline void spill(BaseReg&) {} -#endif // !ASMJIT_NO_DEPRECATED - - //! \name Events - //! \{ - - ASMJIT_API Error onAttach(CodeHolder* code) noexcept override; - ASMJIT_API Error onDetach(CodeHolder* code) noexcept override; - - //! \} -}; - -// ============================================================================ -// [asmjit::JumpAnnotation] -// ============================================================================ - -//! Jump annotation used to annotate jumps. -//! -//! \ref BaseCompiler allows to emit jumps where the target is either register -//! or memory operand. Such jumps cannot be trivially inspected, so instead of -//! doing heuristics AsmJit allows to annotate such jumps with possible targets. -//! Register allocator then use the annotation to construct control-flow, which -//! is then used by liveness analysis and other tools to prepare ground for -//! register allocation. -class JumpAnnotation { -public: - ASMJIT_NONCOPYABLE(JumpAnnotation) - - //! Compiler that owns this JumpAnnotation. - BaseCompiler* _compiler; - //! Annotation identifier. - uint32_t _annotationId; - //! Vector of label identifiers, see \ref labelIds(). - ZoneVector _labelIds; - - inline JumpAnnotation(BaseCompiler* compiler, uint32_t annotationId) noexcept - : _compiler(compiler), - _annotationId(annotationId) {} - - //! Returns the compiler that owns this JumpAnnotation. - inline BaseCompiler* compiler() const noexcept { return _compiler; } - //! Returns the annotation id. - inline uint32_t annotationId() const noexcept { return _annotationId; } - //! Returns a vector of label identifiers that lists all targets of the jump. - const ZoneVector& labelIds() const noexcept { return _labelIds; } - - //! Tests whether the given `label` is a target of this JumpAnnotation. - inline bool hasLabel(const Label& label) const noexcept { return hasLabelId(label.id()); } - //! Tests whether the given `labelId` is a target of this JumpAnnotation. - inline bool hasLabelId(uint32_t labelId) const noexcept { return _labelIds.contains(labelId); } - - //! Adds the `label` to the list of targets of this JumpAnnotation. - inline Error addLabel(const Label& label) noexcept { return addLabelId(label.id()); } - //! Adds the `labelId` to the list of targets of this JumpAnnotation. - inline Error addLabelId(uint32_t labelId) noexcept { return _labelIds.append(&_compiler->_allocator, labelId); } -}; - -// ============================================================================ -// [asmjit::JumpNode] -// ============================================================================ - -//! Jump instruction with \ref JumpAnnotation. -//! -//! \note This node should be only used to represent jump where the jump target -//! cannot be deduced by examining instruction operands. For example if the jump -//! target is register or memory location. This pattern is often used to perform -//! indirect jumps that use jump table, e.g. to implement `switch{}` statement. -class JumpNode : public InstNode { -public: - ASMJIT_NONCOPYABLE(JumpNode) - - JumpAnnotation* _annotation; - - //! \name Construction & Destruction - //! \{ - - ASMJIT_INLINE JumpNode(BaseCompiler* cc, uint32_t instId, uint32_t options, uint32_t opCount, JumpAnnotation* annotation) noexcept - : InstNode(cc, instId, options, opCount, kBaseOpCapacity), - _annotation(annotation) { - setType(kNodeJump); - } - - //! \} - - //! \name Accessors - //! \{ - - //! Tests whether this JumpNode has associated a \ref JumpAnnotation. - inline bool hasAnnotation() const noexcept { return _annotation != nullptr; } - //! Returns the \ref JumpAnnotation associated with this jump, or `nullptr`. - inline JumpAnnotation* annotation() const noexcept { return _annotation; } - //! Sets the \ref JumpAnnotation associated with this jump to `annotation`. - inline void setAnnotation(JumpAnnotation* annotation) noexcept { _annotation = annotation; } - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncNode] -// ============================================================================ - -//! Function node represents a function used by \ref BaseCompiler. -//! -//! A function is composed of the following: -//! -//! - Function entry, \ref FuncNode acts as a label, so the entry is implicit. -//! To get the entry, simply use \ref FuncNode::label(), which is the same -//! as \ref LabelNode::label(). -//! -//! - Function exit, which is represented by \ref FuncNode::exitNode(). A -//! helper function \ref FuncNode::exitLabel() exists and returns an exit -//! label instead of node. -//! -//! - Function \ref FuncNode::endNode() sentinel. This node marks the end of -//! a function - there should be no code that belongs to the function after -//! this node, but the Compiler doesn't enforce that at the moment. -//! -//! - Function detail, see \ref FuncNode::detail(). -//! -//! - Function frame, see \ref FuncNode::frame(). -//! -//! - Function arguments mapped to virtual registers, see \ref FuncNode::args(). -//! -//! In a node list, the function and its body looks like the following: -//! -//! \code{.unparsed} -//! [...] - Anything before the function. -//! -//! [FuncNode] - Entry point of the function, acts as a label as well. -//! - Prolog inserted by the register allocator. -//! {...} - Function body - user code basically. -//! [ExitLabel] - Exit label -//! - Epilog inserted by the register allocator. -//! - Return inserted by the register allocator. -//! {...} - Can contain data or user code (error handling, special cases, ...). -//! [FuncEnd] - End sentinel -//! -//! [...] - Anything after the function. -//! \endcode -//! -//! When a function is added to the compiler by \ref BaseCompiler::addFunc() it -//! actually inserts 3 nodes (FuncNode, ExitLabel, and FuncEnd) and sets the -//! current cursor to be FuncNode. When \ref BaseCompiler::endFunc() is called -//! the cursor is set to FuncEnd. This guarantees that user can use ExitLabel -//! as a marker after additional code or data can be placed, and it's a common -//! practice. -class FuncNode : public LabelNode { -public: - ASMJIT_NONCOPYABLE(FuncNode) - - //! Arguments pack. - struct ArgPack { - VirtReg* _data[Globals::kMaxValuePack]; - - inline void reset() noexcept { - for (size_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) - _data[valueIndex] = nullptr; - } - - inline VirtReg*& operator[](size_t valueIndex) noexcept { return _data[valueIndex]; } - inline VirtReg* const& operator[](size_t valueIndex) const noexcept { return _data[valueIndex]; } - }; - - //! Function detail. - FuncDetail _funcDetail; - //! Function frame. - FuncFrame _frame; - //! Function exit label. - LabelNode* _exitNode; - //! Function end (sentinel). - SentinelNode* _end; - - //! Argument packs. - ArgPack* _args; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `FuncNode` instance. - //! - //! Always use `BaseCompiler::addFunc()` to create `FuncNode`. - ASMJIT_INLINE FuncNode(BaseBuilder* cb) noexcept - : LabelNode(cb), - _funcDetail(), - _frame(), - _exitNode(nullptr), - _end(nullptr), - _args(nullptr) { - setType(kNodeFunc); - } - - //! \} - - //! \{ - //! \name Accessors - - //! Returns function exit `LabelNode`. - inline LabelNode* exitNode() const noexcept { return _exitNode; } - //! Returns function exit label. - inline Label exitLabel() const noexcept { return _exitNode->label(); } - - //! Returns "End of Func" sentinel. - inline SentinelNode* endNode() const noexcept { return _end; } - - //! Returns function declaration. - inline FuncDetail& detail() noexcept { return _funcDetail; } - //! Returns function declaration. - inline const FuncDetail& detail() const noexcept { return _funcDetail; } - - //! Returns function frame. - inline FuncFrame& frame() noexcept { return _frame; } - //! Returns function frame. - inline const FuncFrame& frame() const noexcept { return _frame; } - - //! Tests whether the function has a return value. - inline bool hasRet() const noexcept { return _funcDetail.hasRet(); } - //! Returns arguments count. - inline uint32_t argCount() const noexcept { return _funcDetail.argCount(); } - - //! Returns argument packs. - inline ArgPack* argPacks() const noexcept { return _args; } - - //! Returns argument pack at `argIndex`. - inline ArgPack& argPack(size_t argIndex) const noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - return _args[argIndex]; - } - - //! Sets argument at `argIndex`. - inline void setArg(size_t argIndex, VirtReg* vReg) noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - _args[argIndex][0] = vReg; - } - - //! Sets argument at `argIndex` and `valueIndex`. - inline void setArg(size_t argIndex, size_t valueIndex, VirtReg* vReg) noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - _args[argIndex][valueIndex] = vReg; - } - - //! Resets argument pack at `argIndex`. - inline void resetArg(size_t argIndex) noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - _args[argIndex].reset(); - } - - //! Resets argument pack at `argIndex`. - inline void resetArg(size_t argIndex, size_t valueIndex) noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - _args[argIndex][valueIndex] = nullptr; - } - - //! Returns function attributes. - inline uint32_t attributes() const noexcept { return _frame.attributes(); } - //! Adds `attrs` to the function attributes. - inline void addAttributes(uint32_t attrs) noexcept { _frame.addAttributes(attrs); } - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncRetNode] -// ============================================================================ - -//! Function return, used by \ref BaseCompiler. -class FuncRetNode : public InstNode { -public: - ASMJIT_NONCOPYABLE(FuncRetNode) - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `FuncRetNode` instance. - inline FuncRetNode(BaseBuilder* cb) noexcept : InstNode(cb, BaseInst::kIdAbstract, 0, 0) { - _any._nodeType = kNodeFuncRet; - } - - //! \} -}; - -// ============================================================================ -// [asmjit::InvokeNode] -// ============================================================================ - -//! Function invocation, used by \ref BaseCompiler. -class InvokeNode : public InstNode { -public: - ASMJIT_NONCOPYABLE(InvokeNode) - - //! Operand pack provides multiple operands that can be associated with a - //! single return value of function argument. Sometims this is necessary to - //! express an argument or return value that requires multiple registers, for - //! example 64-bit value in 32-bit mode or passing / returning homogenous data - //! structures. - struct OperandPack { - //! Operands. - Operand_ _data[Globals::kMaxValuePack]; - - //! Reset the pack by resetting all operands in the pack. - inline void reset() noexcept { - for (size_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) - _data[valueIndex].reset(); - } - - //! Returns an operand at the given `valueIndex`. - inline Operand& operator[](size_t valueIndex) noexcept { - ASMJIT_ASSERT(valueIndex < Globals::kMaxValuePack); - return _data[valueIndex].as(); - } - - //! Returns an operand at the given `valueIndex` (const). - const inline Operand& operator[](size_t valueIndex) const noexcept { - ASMJIT_ASSERT(valueIndex < Globals::kMaxValuePack); - return _data[valueIndex].as(); - } - }; - - //! Function detail. - FuncDetail _funcDetail; - //! Function return value(s). - OperandPack _rets; - //! Function arguments. - OperandPack* _args; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `InvokeNode` instance. - inline InvokeNode(BaseBuilder* cb, uint32_t instId, uint32_t options) noexcept - : InstNode(cb, instId, options, kBaseOpCapacity), - _funcDetail(), - _args(nullptr) { - setType(kNodeInvoke); - _resetOps(); - _rets.reset(); - addFlags(kFlagIsRemovable); - } - - //! \} - - //! \name Accessors - //! \{ - - //! Sets the function signature. - inline Error init(const FuncSignature& signature, const Environment& environment) noexcept { - return _funcDetail.init(signature, environment); - } - - //! Returns the function detail. - inline FuncDetail& detail() noexcept { return _funcDetail; } - //! Returns the function detail. - inline const FuncDetail& detail() const noexcept { return _funcDetail; } - - //! Returns the target operand. - inline Operand& target() noexcept { return _opArray[0].as(); } - //! \overload - inline const Operand& target() const noexcept { return _opArray[0].as(); } - - //! Returns the number of function return values. - inline bool hasRet() const noexcept { return _funcDetail.hasRet(); } - //! Returns the number of function arguments. - inline uint32_t argCount() const noexcept { return _funcDetail.argCount(); } - - //! Returns operand pack representing function return value(s). - inline OperandPack& retPack() noexcept { return _rets; } - //! Returns operand pack representing function return value(s). - inline const OperandPack& retPack() const noexcept { return _rets; } - - //! Returns the return value at the given `valueIndex`. - inline Operand& ret(size_t valueIndex = 0) noexcept { return _rets[valueIndex]; } - //! \overload - inline const Operand& ret(size_t valueIndex = 0) const noexcept { return _rets[valueIndex]; } - - //! Returns operand pack representing function return value(s). - inline OperandPack& argPack(size_t argIndex) noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - return _args[argIndex]; - } - //! \overload - inline const OperandPack& argPack(size_t argIndex) const noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - return _args[argIndex]; - } - - //! Returns a function argument at the given `argIndex`. - inline Operand& arg(size_t argIndex, size_t valueIndex) noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - return _args[argIndex][valueIndex]; - } - //! \overload - inline const Operand& arg(size_t argIndex, size_t valueIndex) const noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - return _args[argIndex][valueIndex]; - } - - //! Sets the function return value at `i` to `op`. - inline void _setRet(size_t valueIndex, const Operand_& op) noexcept { _rets[valueIndex] = op; } - //! Sets the function argument at `i` to `op`. - inline void _setArg(size_t argIndex, size_t valueIndex, const Operand_& op) noexcept { - ASMJIT_ASSERT(argIndex < argCount()); - _args[argIndex][valueIndex] = op; - } - - //! Sets the function return value at `valueIndex` to `reg`. - inline void setRet(size_t valueIndex, const BaseReg& reg) noexcept { _setRet(valueIndex, reg); } - - //! Sets the first function argument in a value-pack at `argIndex` to `reg`. - inline void setArg(size_t argIndex, const BaseReg& reg) noexcept { _setArg(argIndex, 0, reg); } - //! Sets the first function argument in a value-pack at `argIndex` to `imm`. - inline void setArg(size_t argIndex, const Imm& imm) noexcept { _setArg(argIndex, 0, imm); } - - //! Sets the function argument at `argIndex` and `valueIndex` to `reg`. - inline void setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg) noexcept { _setArg(argIndex, valueIndex, reg); } - //! Sets the function argument at `argIndex` and `valueIndex` to `imm`. - inline void setArg(size_t argIndex, size_t valueIndex, const Imm& imm) noexcept { _setArg(argIndex, valueIndex, imm); } - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncPass] -// ============================================================================ - -//! Function pass extends \ref Pass with \ref FuncPass::runOnFunction(). -class ASMJIT_VIRTAPI FuncPass : public Pass { -public: - ASMJIT_NONCOPYABLE(FuncPass) - typedef Pass Base; - - //! \name Construction & Destruction - //! \{ - - ASMJIT_API FuncPass(const char* name) noexcept; - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the associated `BaseCompiler`. - inline BaseCompiler* cc() const noexcept { return static_cast(_cb); } - - //! \} - - //! \name Run - //! \{ - - //! Calls `runOnFunction()` on each `FuncNode` node found. - ASMJIT_API Error run(Zone* zone, Logger* logger) override; - - //! Called once per `FuncNode`. - virtual Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func) = 0; - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // !ASMJIT_NO_COMPILER -#endif // ASMJIT_CORE_COMPILER_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compilerdefs.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compilerdefs.h deleted file mode 100644 index 32f0757..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/compilerdefs.h +++ /dev/null @@ -1,170 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_COMPILERDEFS_H_INCLUDED -#define ASMJIT_CORE_COMPILERDEFS_H_INCLUDED - -#include "../core/api-config.h" -#include "../core/operand.h" -#include "../core/zonestring.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -class RAWorkReg; - -//! \addtogroup asmjit_compiler -//! \{ - -// ============================================================================ -// [asmjit::VirtReg] -// ============================================================================ - -//! Virtual register data, managed by \ref BaseCompiler. -class VirtReg { -public: - ASMJIT_NONCOPYABLE(VirtReg) - - //! Virtual register id. - uint32_t _id = 0; - //! Virtual register info (signature). - RegInfo _info = {}; - //! Virtual register size (can be smaller than `regInfo._size`). - uint32_t _virtSize = 0; - //! Virtual register alignment (for spilling). - uint8_t _alignment = 0; - //! Type-id. - uint8_t _typeId = 0; - //! Virtual register weight for alloc/spill decisions. - uint8_t _weight = 1; - //! True if this is a fixed register, never reallocated. - uint8_t _isFixed : 1; - //! True if the virtual register is only used as a stack (never accessed as register). - uint8_t _isStack : 1; - uint8_t _reserved : 6; - - //! Virtual register name (user provided or automatically generated). - ZoneString<16> _name {}; - - // ------------------------------------------------------------------------- - // The following members are used exclusively by RAPass. They are initialized - // when the VirtReg is created to NULL pointers and then changed during RAPass - // execution. RAPass sets them back to NULL before it returns. - // ------------------------------------------------------------------------- - - //! Reference to `RAWorkReg`, used during register allocation. - RAWorkReg* _workReg = nullptr; - - //! \name Construction & Destruction - //! \{ - - inline VirtReg(uint32_t id, uint32_t signature, uint32_t virtSize, uint32_t alignment, uint32_t typeId) noexcept - : _id(id), - _info { signature }, - _virtSize(virtSize), - _alignment(uint8_t(alignment)), - _typeId(uint8_t(typeId)), - _isFixed(false), - _isStack(false), - _reserved(0) {} - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the virtual register id. - inline uint32_t id() const noexcept { return _id; } - - //! Returns the virtual register name. - inline const char* name() const noexcept { return _name.data(); } - //! Returns the size of the virtual register name. - inline uint32_t nameSize() const noexcept { return _name.size(); } - - //! Returns a register information that wraps the register signature. - inline const RegInfo& info() const noexcept { return _info; } - //! Returns a virtual register type (maps to the physical register type as well). - inline uint32_t type() const noexcept { return _info.type(); } - //! Returns a virtual register group (maps to the physical register group as well). - inline uint32_t group() const noexcept { return _info.group(); } - - //! Returns a real size of the register this virtual register maps to. - //! - //! For example if this is a 128-bit SIMD register used for a scalar single - //! precision floating point value then its virtSize would be 4, however, the - //! `regSize` would still say 16 (128-bits), because it's the smallest size - //! of that register type. - inline uint32_t regSize() const noexcept { return _info.size(); } - - //! Returns a register signature of this virtual register. - inline uint32_t signature() const noexcept { return _info.signature(); } - - //! Returns the virtual register size. - //! - //! The virtual register size describes how many bytes the virtual register - //! needs to store its content. It can be smaller than the physical register - //! size, see `regSize()`. - inline uint32_t virtSize() const noexcept { return _virtSize; } - - //! Returns the virtual register alignment. - inline uint32_t alignment() const noexcept { return _alignment; } - - //! Returns the virtual register type id, see `Type::Id`. - inline uint32_t typeId() const noexcept { return _typeId; } - - //! Returns the virtual register weight - the register allocator can use it - //! as explicit hint for alloc/spill decisions. - inline uint32_t weight() const noexcept { return _weight; } - //! Sets the virtual register weight (0 to 255) - the register allocator can - //! use it as explicit hint for alloc/spill decisions and initial bin-packing. - inline void setWeight(uint32_t weight) noexcept { _weight = uint8_t(weight); } - - //! Returns whether the virtual register is always allocated to a fixed - //! physical register (and never reallocated). - //! - //! \note This is only used for special purposes and it's mostly internal. - inline bool isFixed() const noexcept { return bool(_isFixed); } - - //! Returns whether the virtual register is indeed a stack that only uses - //! the virtual register id for making it accessible. - //! - //! \note It's an error if a stack is accessed as a register. - inline bool isStack() const noexcept { return bool(_isStack); } - - inline bool hasWorkReg() const noexcept { return _workReg != nullptr; } - inline RAWorkReg* workReg() const noexcept { return _workReg; } - inline void setWorkReg(RAWorkReg* workReg) noexcept { _workReg = workReg; } - inline void resetWorkReg() noexcept { _workReg = nullptr; } - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_COMPILERDEFS_H_INCLUDED - diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/constpool.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/constpool.cpp deleted file mode 100644 index 65c995b..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/constpool.cpp +++ /dev/null @@ -1,375 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/constpool.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::ConstPool - Construction / Destruction] -// ============================================================================ - -ConstPool::ConstPool(Zone* zone) noexcept { reset(zone); } -ConstPool::~ConstPool() noexcept {} - -// ============================================================================ -// [asmjit::ConstPool - Reset] -// ============================================================================ - -void ConstPool::reset(Zone* zone) noexcept { - _zone = zone; - - size_t dataSize = 1; - for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) { - _tree[i].reset(); - _tree[i].setDataSize(dataSize); - _gaps[i] = nullptr; - dataSize <<= 1; - } - - _gapPool = nullptr; - _size = 0; - _alignment = 0; -} - -// ============================================================================ -// [asmjit::ConstPool - Ops] -// ============================================================================ - -static ASMJIT_INLINE ConstPool::Gap* ConstPool_allocGap(ConstPool* self) noexcept { - ConstPool::Gap* gap = self->_gapPool; - if (!gap) - return self->_zone->allocT(); - - self->_gapPool = gap->_next; - return gap; -} - -static ASMJIT_INLINE void ConstPool_freeGap(ConstPool* self, ConstPool::Gap* gap) noexcept { - gap->_next = self->_gapPool; - self->_gapPool = gap; -} - -static void ConstPool_addGap(ConstPool* self, size_t offset, size_t size) noexcept { - ASMJIT_ASSERT(size > 0); - - while (size > 0) { - size_t gapIndex; - size_t gapSize; - - if (size >= 16 && Support::isAligned(offset, 16)) { - gapIndex = ConstPool::kIndex16; - gapSize = 16; - } - else if (size >= 8 && Support::isAligned(offset, 8)) { - gapIndex = ConstPool::kIndex8; - gapSize = 8; - } - else if (size >= 4 && Support::isAligned(offset, 4)) { - gapIndex = ConstPool::kIndex4; - gapSize = 4; - } - else if (size >= 2 && Support::isAligned(offset, 2)) { - gapIndex = ConstPool::kIndex2; - gapSize = 2; - } - else { - gapIndex = ConstPool::kIndex1; - gapSize = 1; - } - - // We don't have to check for errors here, if this failed nothing really - // happened (just the gap won't be visible) and it will fail again at - // place where the same check would generate `kErrorOutOfMemory` error. - ConstPool::Gap* gap = ConstPool_allocGap(self); - if (!gap) - return; - - gap->_next = self->_gaps[gapIndex]; - self->_gaps[gapIndex] = gap; - - gap->_offset = offset; - gap->_size = gapSize; - - offset += gapSize; - size -= gapSize; - } -} - -Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept { - size_t treeIndex; - - if (size == 32) - treeIndex = kIndex32; - else if (size == 16) - treeIndex = kIndex16; - else if (size == 8) - treeIndex = kIndex8; - else if (size == 4) - treeIndex = kIndex4; - else if (size == 2) - treeIndex = kIndex2; - else if (size == 1) - treeIndex = kIndex1; - else - return DebugUtils::errored(kErrorInvalidArgument); - - ConstPool::Node* node = _tree[treeIndex].get(data); - if (node) { - dstOffset = node->_offset; - return kErrorOk; - } - - // Before incrementing the current offset try if there is a gap that can - // be used for the requested data. - size_t offset = ~size_t(0); - size_t gapIndex = treeIndex; - - while (gapIndex != kIndexCount - 1) { - ConstPool::Gap* gap = _gaps[treeIndex]; - - // Check if there is a gap. - if (gap) { - size_t gapOffset = gap->_offset; - size_t gapSize = gap->_size; - - // Destroy the gap for now. - _gaps[treeIndex] = gap->_next; - ConstPool_freeGap(this, gap); - - offset = gapOffset; - ASMJIT_ASSERT(Support::isAligned(offset, size)); - - gapSize -= size; - if (gapSize > 0) - ConstPool_addGap(this, gapOffset, gapSize); - } - - gapIndex++; - } - - if (offset == ~size_t(0)) { - // Get how many bytes have to be skipped so the address is aligned accordingly - // to the 'size'. - size_t diff = Support::alignUpDiff(_size, size); - - if (diff != 0) { - ConstPool_addGap(this, _size, diff); - _size += diff; - } - - offset = _size; - _size += size; - } - - // Add the initial node to the right index. - node = ConstPool::Tree::_newNode(_zone, data, size, offset, false); - if (!node) return DebugUtils::errored(kErrorOutOfMemory); - - _tree[treeIndex].insert(node); - _alignment = Support::max(_alignment, size); - - dstOffset = offset; - - // Now create a bunch of shared constants that are based on the data pattern. - // We stop at size 4, it probably doesn't make sense to split constants down - // to 1 byte. - size_t pCount = 1; - while (size > 4) { - size >>= 1; - pCount <<= 1; - - ASMJIT_ASSERT(treeIndex != 0); - treeIndex--; - - const uint8_t* pData = static_cast(data); - for (size_t i = 0; i < pCount; i++, pData += size) { - node = _tree[treeIndex].get(pData); - if (node) continue; - - node = ConstPool::Tree::_newNode(_zone, pData, size, offset + (i * size), true); - _tree[treeIndex].insert(node); - } - } - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::ConstPool - Reset] -// ============================================================================ - -struct ConstPoolFill { - inline ConstPoolFill(uint8_t* dst, size_t dataSize) noexcept : - _dst(dst), - _dataSize(dataSize) {} - - inline void operator()(const ConstPool::Node* node) noexcept { - if (!node->_shared) - memcpy(_dst + node->_offset, node->data(), _dataSize); - } - - uint8_t* _dst; - size_t _dataSize; -}; - -void ConstPool::fill(void* dst) const noexcept { - // Clears possible gaps, asmjit should never emit garbage to the output. - memset(dst, 0, _size); - - ConstPoolFill filler(static_cast(dst), 1); - for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) { - _tree[i].forEach(filler); - filler._dataSize <<= 1; - } -} - -// ============================================================================ -// [asmjit::ConstPool - Unit] -// ============================================================================ - -#if defined(ASMJIT_TEST) -UNIT(const_pool) { - Zone zone(32384 - Zone::kBlockOverhead); - ConstPool pool(&zone); - - uint32_t i; - uint32_t kCount = BrokenAPI::hasArg("--quick") ? 1000 : 1000000; - - INFO("Adding %u constants to the pool", kCount); - { - size_t prevOffset; - size_t curOffset; - uint64_t c = 0x0101010101010101u; - - EXPECT(pool.add(&c, 8, prevOffset) == kErrorOk); - EXPECT(prevOffset == 0); - - for (i = 1; i < kCount; i++) { - c++; - EXPECT(pool.add(&c, 8, curOffset) == kErrorOk); - EXPECT(prevOffset + 8 == curOffset); - EXPECT(pool.size() == (i + 1) * 8); - prevOffset = curOffset; - } - - EXPECT(pool.alignment() == 8); - } - - INFO("Retrieving %u constants from the pool", kCount); - { - uint64_t c = 0x0101010101010101u; - - for (i = 0; i < kCount; i++) { - size_t offset; - EXPECT(pool.add(&c, 8, offset) == kErrorOk); - EXPECT(offset == i * 8); - c++; - } - } - - INFO("Checking if the constants were split into 4-byte patterns"); - { - uint32_t c = 0x01010101; - for (i = 0; i < kCount; i++) { - size_t offset; - EXPECT(pool.add(&c, 4, offset) == kErrorOk); - EXPECT(offset == i * 8); - c++; - } - } - - INFO("Adding 2 byte constant to misalign the current offset"); - { - uint16_t c = 0xFFFF; - size_t offset; - - EXPECT(pool.add(&c, 2, offset) == kErrorOk); - EXPECT(offset == kCount * 8); - EXPECT(pool.alignment() == 8); - } - - INFO("Adding 8 byte constant to check if pool gets aligned again"); - { - uint64_t c = 0xFFFFFFFFFFFFFFFFu; - size_t offset; - - EXPECT(pool.add(&c, 8, offset) == kErrorOk); - EXPECT(offset == kCount * 8 + 8); - } - - INFO("Adding 2 byte constant to verify the gap is filled"); - { - uint16_t c = 0xFFFE; - size_t offset; - - EXPECT(pool.add(&c, 2, offset) == kErrorOk); - EXPECT(offset == kCount * 8 + 2); - EXPECT(pool.alignment() == 8); - } - - INFO("Checking reset functionality"); - { - pool.reset(&zone); - zone.reset(); - - EXPECT(pool.size() == 0); - EXPECT(pool.alignment() == 0); - } - - INFO("Checking pool alignment when combined constants are added"); - { - uint8_t bytes[32] = { 0 }; - size_t offset; - - pool.add(bytes, 1, offset); - EXPECT(pool.size() == 1); - EXPECT(pool.alignment() == 1); - EXPECT(offset == 0); - - pool.add(bytes, 2, offset); - EXPECT(pool.size() == 4); - EXPECT(pool.alignment() == 2); - EXPECT(offset == 2); - - pool.add(bytes, 4, offset); - EXPECT(pool.size() == 8); - EXPECT(pool.alignment() == 4); - EXPECT(offset == 4); - - pool.add(bytes, 4, offset); - EXPECT(pool.size() == 8); - EXPECT(pool.alignment() == 4); - EXPECT(offset == 4); - - pool.add(bytes, 32, offset); - EXPECT(pool.size() == 64); - EXPECT(pool.alignment() == 32); - EXPECT(offset == 32); - } -} -#endif - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/constpool.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/constpool.h deleted file mode 100644 index d9ac589..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/constpool.h +++ /dev/null @@ -1,262 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_CONSTPOOL_H_INCLUDED -#define ASMJIT_CORE_CONSTPOOL_H_INCLUDED - -#include "../core/support.h" -#include "../core/zone.h" -#include "../core/zonetree.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_utilities -//! \{ - -// ============================================================================ -// [asmjit::ConstPool] -// ============================================================================ - -//! Constant pool. -class ConstPool { -public: - ASMJIT_NONCOPYABLE(ConstPool) - - //! Constant pool scope. - enum Scope : uint32_t { - //! Local constant, always embedded right after the current function. - kScopeLocal = 0, - //! Global constant, embedded at the end of the currently compiled code. - kScopeGlobal = 1 - }; - - //! \cond INTERNAL - - //! Index of a given size in const-pool table. - enum Index : uint32_t { - kIndex1 = 0, - kIndex2 = 1, - kIndex4 = 2, - kIndex8 = 3, - kIndex16 = 4, - kIndex32 = 5, - kIndexCount = 6 - }; - - //! Zone-allocated const-pool gap created by two differently aligned constants. - struct Gap { - //! Pointer to the next gap - Gap* _next; - //! Offset of the gap. - size_t _offset; - //! Remaining bytes of the gap (basically a gap size). - size_t _size; - }; - - //! Zone-allocated const-pool node. - class Node : public ZoneTreeNodeT { - public: - ASMJIT_NONCOPYABLE(Node) - - //! If this constant is shared with another. - uint32_t _shared : 1; - //! Data offset from the beginning of the pool. - uint32_t _offset; - - inline Node(size_t offset, bool shared) noexcept - : ZoneTreeNodeT(), - _shared(shared), - _offset(uint32_t(offset)) {} - - inline void* data() const noexcept { - return static_cast(const_cast(this) + 1); - } - }; - - //! Data comparer used internally. - class Compare { - public: - size_t _dataSize; - - inline Compare(size_t dataSize) noexcept - : _dataSize(dataSize) {} - - inline int operator()(const Node& a, const Node& b) const noexcept { - return ::memcmp(a.data(), b.data(), _dataSize); - } - - inline int operator()(const Node& a, const void* data) const noexcept { - return ::memcmp(a.data(), data, _dataSize); - } - }; - - //! Zone-allocated const-pool tree. - struct Tree { - //! RB tree. - ZoneTree _tree; - //! Size of the tree (number of nodes). - size_t _size; - //! Size of the data. - size_t _dataSize; - - inline explicit Tree(size_t dataSize = 0) noexcept - : _tree(), - _size(0), - _dataSize(dataSize) {} - - inline void reset() noexcept { - _tree.reset(); - _size = 0; - } - - inline bool empty() const noexcept { return _size == 0; } - inline size_t size() const noexcept { return _size; } - - inline void setDataSize(size_t dataSize) noexcept { - ASMJIT_ASSERT(empty()); - _dataSize = dataSize; - } - - inline Node* get(const void* data) noexcept { - Compare cmp(_dataSize); - return _tree.get(data, cmp); - } - - inline void insert(Node* node) noexcept { - Compare cmp(_dataSize); - _tree.insert(node, cmp); - _size++; - } - - template - inline void forEach(Visitor& visitor) const noexcept { - Node* node = _tree.root(); - if (!node) return; - - Node* stack[Globals::kMaxTreeHeight]; - size_t top = 0; - - for (;;) { - Node* left = node->left(); - if (left != nullptr) { - ASMJIT_ASSERT(top != Globals::kMaxTreeHeight); - stack[top++] = node; - - node = left; - continue; - } - - for (;;) { - visitor(node); - node = node->right(); - - if (node != nullptr) - break; - - if (top == 0) - return; - - node = stack[--top]; - } - } - } - - static inline Node* _newNode(Zone* zone, const void* data, size_t size, size_t offset, bool shared) noexcept { - Node* node = zone->allocT(sizeof(Node) + size); - if (ASMJIT_UNLIKELY(!node)) return nullptr; - - node = new(node) Node(offset, shared); - memcpy(node->data(), data, size); - return node; - } - }; - - //! \endcond - - //! Zone allocator. - Zone* _zone; - //! Tree per size. - Tree _tree[kIndexCount]; - //! Gaps per size. - Gap* _gaps[kIndexCount]; - //! Gaps pool - Gap* _gapPool; - - //! Size of the pool (in bytes). - size_t _size; - //! Required pool alignment. - size_t _alignment; - - //! \name Construction & Destruction - //! \{ - - ASMJIT_API ConstPool(Zone* zone) noexcept; - ASMJIT_API ~ConstPool() noexcept; - - ASMJIT_API void reset(Zone* zone) noexcept; - - //! \} - - //! \name Accessors - //! \{ - - //! Tests whether the constant-pool is empty. - inline bool empty() const noexcept { return _size == 0; } - //! Returns the size of the constant-pool in bytes. - inline size_t size() const noexcept { return _size; } - //! Returns minimum alignment. - inline size_t alignment() const noexcept { return _alignment; } - - //! \} - - //! \name Utilities - //! \{ - - //! Adds a constant to the constant pool. - //! - //! The constant must have known size, which is 1, 2, 4, 8, 16 or 32 bytes. - //! The constant is added to the pool only if it doesn't not exist, otherwise - //! cached value is returned. - //! - //! AsmJit is able to subdivide added constants, so for example if you add - //! 8-byte constant 0x1122334455667788 it will create the following slots: - //! - //! 8-byte: 0x1122334455667788 - //! 4-byte: 0x11223344, 0x55667788 - //! - //! The reason is that when combining MMX/SSE/AVX code some patterns are used - //! frequently. However, AsmJit is not able to reallocate a constant that has - //! been already added. For example if you try to add 4-byte constant and then - //! 8-byte constant having the same 4-byte pattern as the previous one, two - //! independent slots will be generated by the pool. - ASMJIT_API Error add(const void* data, size_t size, size_t& dstOffset) noexcept; - - //! Fills the destination with the content of this constant pool. - ASMJIT_API void fill(void* dst) const noexcept; -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_CONSTPOOL_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/cpuinfo.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/cpuinfo.cpp deleted file mode 100644 index edc7d17..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/cpuinfo.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/cpuinfo.h" - -#if !defined(_WIN32) - #include - #include - #include -#endif - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::CpuInfo - Detect - CPU NumThreads] -// ============================================================================ - -#if defined(_WIN32) -static inline uint32_t detectHWThreadCount() noexcept { - SYSTEM_INFO info; - ::GetSystemInfo(&info); - return info.dwNumberOfProcessors; -} -#elif defined(_SC_NPROCESSORS_ONLN) -static inline uint32_t detectHWThreadCount() noexcept { - long res = ::sysconf(_SC_NPROCESSORS_ONLN); - return res <= 0 ? uint32_t(1) : uint32_t(res); -} -#else -static inline uint32_t detectHWThreadCount() noexcept { - return 1; -} -#endif - -// ============================================================================ -// [asmjit::CpuInfo - Detect - CPU Features] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X86) && ASMJIT_ARCH_X86 -namespace x86 { void detectCpu(CpuInfo& cpu) noexcept; } -#endif - -#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM -namespace arm { void detectCpu(CpuInfo& cpu) noexcept; } -#endif - -// ============================================================================ -// [asmjit::CpuInfo - Detect - Static Initializer] -// ============================================================================ - -static uint32_t cpuInfoInitialized; -static CpuInfo cpuInfoGlobal(Globals::NoInit); - -const CpuInfo& CpuInfo::host() noexcept { - // This should never cause a problem as the resulting information should - // always be the same. - if (!cpuInfoInitialized) { - CpuInfo cpuInfoLocal; - -#if defined(ASMJIT_BUILD_X86) && ASMJIT_ARCH_X86 - x86::detectCpu(cpuInfoLocal); -#endif - -#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM - arm::detectCpu(cpuInfoLocal); -#endif - - cpuInfoLocal._hwThreadCount = detectHWThreadCount(); - cpuInfoGlobal = cpuInfoLocal; - cpuInfoInitialized = 1; - } - - return cpuInfoGlobal; -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/cpuinfo.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/cpuinfo.h deleted file mode 100644 index 83bb8c1..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/cpuinfo.h +++ /dev/null @@ -1,154 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_CPUINFO_H_INCLUDED -#define ASMJIT_CORE_CPUINFO_H_INCLUDED - -#include "../core/archtraits.h" -#include "../core/features.h" -#include "../core/globals.h" -#include "../core/string.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [asmjit::CpuInfo] -// ============================================================================ - -//! CPU information. -class CpuInfo { -public: - //! Architecture. - uint8_t _arch; - //! Sub-architecture. - uint8_t _subArch; - //! Reserved for future use. - uint16_t _reserved; - //! CPU family ID. - uint32_t _familyId; - //! CPU model ID. - uint32_t _modelId; - //! CPU brand ID. - uint32_t _brandId; - //! CPU stepping. - uint32_t _stepping; - //! Processor type. - uint32_t _processorType; - //! Maximum number of addressable IDs for logical processors. - uint32_t _maxLogicalProcessors; - //! Cache line size (in bytes). - uint32_t _cacheLineSize; - //! Number of hardware threads. - uint32_t _hwThreadCount; - - //! CPU vendor string. - FixedString<16> _vendor; - //! CPU brand string. - FixedString<64> _brand; - //! CPU features. - BaseFeatures _features; - - //! \name Construction & Destruction - //! \{ - - inline CpuInfo() noexcept { reset(); } - inline CpuInfo(const CpuInfo& other) noexcept = default; - - inline explicit CpuInfo(Globals::NoInit_) noexcept - : _features(Globals::NoInit) {}; - - //! Returns the host CPU information. - ASMJIT_API static const CpuInfo& host() noexcept; - - //! Initializes CpuInfo to the given architecture, see \ref Environment. - inline void initArch(uint32_t arch, uint32_t subArch = 0u) noexcept { - _arch = uint8_t(arch); - _subArch = uint8_t(subArch); - } - - inline void reset() noexcept { memset(this, 0, sizeof(*this)); } - - //! \} - - //! \name Overloaded Operators - //! \{ - - inline CpuInfo& operator=(const CpuInfo& other) noexcept = default; - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the CPU architecture id, see \ref Environment::Arch. - inline uint32_t arch() const noexcept { return _arch; } - //! Returns the CPU architecture sub-id, see \ref Environment::SubArch. - inline uint32_t subArch() const noexcept { return _subArch; } - - //! Returns the CPU family ID. - inline uint32_t familyId() const noexcept { return _familyId; } - //! Returns the CPU model ID. - inline uint32_t modelId() const noexcept { return _modelId; } - //! Returns the CPU brand id. - inline uint32_t brandId() const noexcept { return _brandId; } - //! Returns the CPU stepping. - inline uint32_t stepping() const noexcept { return _stepping; } - //! Returns the processor type. - inline uint32_t processorType() const noexcept { return _processorType; } - //! Returns the number of maximum logical processors. - inline uint32_t maxLogicalProcessors() const noexcept { return _maxLogicalProcessors; } - - //! Returns the size of a cache line flush. - inline uint32_t cacheLineSize() const noexcept { return _cacheLineSize; } - //! Returns number of hardware threads available. - inline uint32_t hwThreadCount() const noexcept { return _hwThreadCount; } - - //! Returns the CPU vendor. - inline const char* vendor() const noexcept { return _vendor.str; } - //! Tests whether the CPU vendor is equal to `s`. - inline bool isVendor(const char* s) const noexcept { return _vendor.eq(s); } - - //! Returns the CPU brand string. - inline const char* brand() const noexcept { return _brand.str; } - - //! Returns all CPU features as `BaseFeatures`, cast to your arch-specific class - //! if needed. - template - inline const T& features() const noexcept { return _features.as(); } - - //! Tests whether the CPU has the given `feature`. - inline bool hasFeature(uint32_t featureId) const noexcept { return _features.has(featureId); } - //! Adds the given CPU `feature` to the list of this CpuInfo features. - inline CpuInfo& addFeature(uint32_t featureId) noexcept { _features.add(featureId); return *this; } - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_CPUINFO_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/datatypes.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/datatypes.h deleted file mode 100644 index 2f6cc1e..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/datatypes.h +++ /dev/null @@ -1,1071 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_DATATYPES_H_INCLUDED -#define ASMJIT_CORE_DATATYPES_H_INCLUDED - -#include "../core/globals.h" - -#ifndef ASMJIT_NO_DEPRECATED - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::Data64] -// ============================================================================ - -//! 64-bit data useful for creating SIMD constants. -union ASMJIT_DEPRECATED_STRUCT("Data64 is deprecated and will be removed in the future") Data64 { - //! Array of eight 8-bit signed integers. - int8_t sb[8]; - //! Array of eight 8-bit unsigned integers. - uint8_t ub[8]; - //! Array of four 16-bit signed integers. - int16_t sw[4]; - //! Array of four 16-bit unsigned integers. - uint16_t uw[4]; - //! Array of two 32-bit signed integers. - int32_t sd[2]; - //! Array of two 32-bit unsigned integers. - uint32_t ud[2]; - //! Array of one 64-bit signed integer. - int64_t sq[1]; - //! Array of one 64-bit unsigned integer. - uint64_t uq[1]; - - //! Array of two SP-FP values. - float sf[2]; - //! Array of one DP-FP value. - double df[1]; - - //! \name Construction & Destruction - //! \{ - - //! Sets all eight 8-bit signed integers. - static inline Data64 fromI8(int8_t x0) noexcept { - Data64 self; - self.setI8(x0); - return self; - } - - //! Sets all eight 8-bit unsigned integers. - static inline Data64 fromU8(uint8_t x0) noexcept { - Data64 self; - self.setU8(x0); - return self; - } - - //! Sets all eight 8-bit signed integers. - static inline Data64 fromI8( - int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7) noexcept { - - Data64 self; - self.setI8(x0, x1, x2, x3, x4, x5, x6, x7); - return self; - } - - //! Sets all eight 8-bit unsigned integers. - static inline Data64 fromU8( - uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7) noexcept { - - Data64 self; - self.setU8(x0, x1, x2, x3, x4, x5, x6, x7); - return self; - } - - //! Sets all four 16-bit signed integers. - static inline Data64 fromI16(int16_t x0) noexcept { - Data64 self; - self.setI16(x0); - return self; - } - - //! Sets all four 16-bit unsigned integers. - static inline Data64 fromU16(uint16_t x0) noexcept { - Data64 self; - self.setU16(x0); - return self; - } - - //! Sets all four 16-bit signed integers. - static inline Data64 fromI16(int16_t x0, int16_t x1, int16_t x2, int16_t x3) noexcept { - Data64 self; - self.setI16(x0, x1, x2, x3); - return self; - } - - //! Sets all four 16-bit unsigned integers. - static inline Data64 fromU16(uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) noexcept { - Data64 self; - self.setU16(x0, x1, x2, x3); - return self; - } - - //! Sets all two 32-bit signed integers. - static inline Data64 fromI32(int32_t x0) noexcept { - Data64 self; - self.setI32(x0); - return self; - } - - //! Sets all two 32-bit unsigned integers. - static inline Data64 fromU32(uint32_t x0) noexcept { - Data64 self; - self.setU32(x0); - return self; - } - - //! Sets all two 32-bit signed integers. - static inline Data64 fromI32(int32_t x0, int32_t x1) noexcept { - Data64 self; - self.setI32(x0, x1); - return self; - } - - //! Sets all two 32-bit unsigned integers. - static inline Data64 fromU32(uint32_t x0, uint32_t x1) noexcept { - Data64 self; - self.setU32(x0, x1); - return self; - } - - //! Sets 64-bit signed integer. - static inline Data64 fromI64(int64_t x0) noexcept { - Data64 self; - self.setI64(x0); - return self; - } - - //! Sets 64-bit unsigned integer. - static inline Data64 fromU64(uint64_t x0) noexcept { - Data64 self; - self.setU64(x0); - return self; - } - - //! Sets all two SP-FP values. - static inline Data64 fromF32(float x0) noexcept { - Data64 self; - self.setF32(x0); - return self; - } - - //! Sets all two SP-FP values. - static inline Data64 fromF32(float x0, float x1) noexcept { - Data64 self; - self.setF32(x0, x1); - return self; - } - - //! Sets all two SP-FP values. - static inline Data64 fromF64(double x0) noexcept { - Data64 self; - self.setF64(x0); - return self; - } - - //! \} - - //! \name Accessors - //! \{ - - //! Sets all eight 8-bit signed integers. - inline void setI8(int8_t x0) noexcept { - setU8(uint8_t(x0)); - } - - //! Sets all eight 8-bit unsigned integers. - inline void setU8(uint8_t x0) noexcept { - if (ASMJIT_ARCH_BITS >= 64) { - uint64_t xq = uint64_t(x0) * 0x0101010101010101u; - uq[0] = xq; - } - else { - uint32_t xd = uint32_t(x0) * 0x01010101u; - ud[0] = xd; - ud[1] = xd; - } - } - - //! Sets all eight 8-bit signed integers. - inline void setI8( - int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7) noexcept { - - sb[0] = x0; sb[1] = x1; sb[2] = x2; sb[3] = x3; - sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7; - } - - //! Sets all eight 8-bit unsigned integers. - inline void setU8( - uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7) noexcept { - - ub[0] = x0; ub[1] = x1; ub[2] = x2; ub[3] = x3; - ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7; - } - - //! Sets all four 16-bit signed integers. - inline void setI16(int16_t x0) noexcept { - setU16(uint16_t(x0)); - } - - //! Sets all four 16-bit unsigned integers. - inline void setU16(uint16_t x0) noexcept { - if (ASMJIT_ARCH_BITS >= 64) { - uint64_t xq = uint64_t(x0) * 0x0001000100010001u; - uq[0] = xq; - } - else { - uint32_t xd = uint32_t(x0) * 0x00010001u; - ud[0] = xd; - ud[1] = xd; - } - } - - //! Sets all four 16-bit signed integers. - inline void setI16(int16_t x0, int16_t x1, int16_t x2, int16_t x3) noexcept { - sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; - } - - //! Sets all four 16-bit unsigned integers. - inline void setU16(uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) noexcept { - uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; - } - - //! Sets all two 32-bit signed integers. - inline void setI32(int32_t x0) noexcept { - sd[0] = x0; sd[1] = x0; - } - - //! Sets all two 32-bit unsigned integers. - inline void setU32(uint32_t x0) noexcept { - ud[0] = x0; ud[1] = x0; - } - - //! Sets all two 32-bit signed integers. - inline void setI32(int32_t x0, int32_t x1) noexcept { - sd[0] = x0; sd[1] = x1; - } - - //! Sets all two 32-bit unsigned integers. - inline void setU32(uint32_t x0, uint32_t x1) noexcept { - ud[0] = x0; ud[1] = x1; - } - - //! Sets 64-bit signed integer. - inline void setI64(int64_t x0) noexcept { - sq[0] = x0; - } - - //! Sets 64-bit unsigned integer. - inline void setU64(uint64_t x0) noexcept { - uq[0] = x0; - } - - //! Sets all two SP-FP values. - inline void setF32(float x0) noexcept { - sf[0] = x0; sf[1] = x0; - } - - //! Sets all two SP-FP values. - inline void setF32(float x0, float x1) noexcept { - sf[0] = x0; sf[1] = x1; - } - - //! Sets all two SP-FP values. - inline void setF64(double x0) noexcept { - df[0] = x0; - } -}; - -// ============================================================================ -// [asmjit::Data128] -// ============================================================================ - -//! 128-bit data useful for creating SIMD constants. -union ASMJIT_DEPRECATED_STRUCT("Data128 is deprecated and will be removed in the future") Data128 { - //! Array of sixteen 8-bit signed integers. - int8_t sb[16]; - //! Array of sixteen 8-bit unsigned integers. - uint8_t ub[16]; - //! Array of eight 16-bit signed integers. - int16_t sw[8]; - //! Array of eight 16-bit unsigned integers. - uint16_t uw[8]; - //! Array of four 32-bit signed integers. - int32_t sd[4]; - //! Array of four 32-bit unsigned integers. - uint32_t ud[4]; - //! Array of two 64-bit signed integers. - int64_t sq[2]; - //! Array of two 64-bit unsigned integers. - uint64_t uq[2]; - - //! Array of four 32-bit single precision floating points. - float sf[4]; - //! Array of two 64-bit double precision floating points. - double df[2]; - - //! \name Construction & Destruction - //! \{ - - //! Sets all sixteen 8-bit signed integers. - static inline Data128 fromI8(int8_t x0) noexcept { - Data128 self; - self.setI8(x0); - return self; - } - - //! Sets all sixteen 8-bit unsigned integers. - static inline Data128 fromU8(uint8_t x0) noexcept { - Data128 self; - self.setU8(x0); - return self; - } - - //! Sets all sixteen 8-bit signed integers. - static inline Data128 fromI8( - int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , - int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , - int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, - int8_t x12, int8_t x13, int8_t x14, int8_t x15) noexcept { - - Data128 self; - self.setI8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); - return self; - } - - //! Sets all sixteen 8-bit unsigned integers. - static inline Data128 fromU8( - uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , - uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , - uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, - uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15) noexcept { - - Data128 self; - self.setU8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); - return self; - } - - //! Sets all eight 16-bit signed integers. - static inline Data128 fromI16(int16_t x0) noexcept { - Data128 self; - self.setI16(x0); - return self; - } - - //! Sets all eight 16-bit unsigned integers. - static inline Data128 fromU16(uint16_t x0) noexcept { - Data128 self; - self.setU16(x0); - return self; - } - - //! Sets all eight 16-bit signed integers. - static inline Data128 fromI16( - int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) noexcept { - - Data128 self; - self.setI16(x0, x1, x2, x3, x4, x5, x6, x7); - return self; - } - - //! Sets all eight 16-bit unsigned integers. - static inline Data128 fromU16( - uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7) noexcept { - - Data128 self; - self.setU16(x0, x1, x2, x3, x4, x5, x6, x7); - return self; - } - - //! Sets all four 32-bit signed integers. - static inline Data128 fromI32(int32_t x0) noexcept { - Data128 self; - self.setI32(x0); - return self; - } - - //! Sets all four 32-bit unsigned integers. - static inline Data128 fromU32(uint32_t x0) noexcept { - Data128 self; - self.setU32(x0); - return self; - } - - //! Sets all four 32-bit signed integers. - static inline Data128 fromI32(int32_t x0, int32_t x1, int32_t x2, int32_t x3) noexcept { - Data128 self; - self.setI32(x0, x1, x2, x3); - return self; - } - - //! Sets all four 32-bit unsigned integers. - static inline Data128 fromU32(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) noexcept { - Data128 self; - self.setU32(x0, x1, x2, x3); - return self; - } - - //! Sets all two 64-bit signed integers. - static inline Data128 fromI64(int64_t x0) noexcept { - Data128 self; - self.setI64(x0); - return self; - } - - //! Sets all two 64-bit unsigned integers. - static inline Data128 fromU64(uint64_t x0) noexcept { - Data128 self; - self.setU64(x0); - return self; - } - - //! Sets all two 64-bit signed integers. - static inline Data128 fromI64(int64_t x0, int64_t x1) noexcept { - Data128 self; - self.setI64(x0, x1); - return self; - } - - //! Sets all two 64-bit unsigned integers. - static inline Data128 fromU64(uint64_t x0, uint64_t x1) noexcept { - Data128 self; - self.setU64(x0, x1); - return self; - } - - //! Sets all four SP-FP floats. - static inline Data128 fromF32(float x0) noexcept { - Data128 self; - self.setF32(x0); - return self; - } - - //! Sets all four SP-FP floats. - static inline Data128 fromF32(float x0, float x1, float x2, float x3) noexcept { - Data128 self; - self.setF32(x0, x1, x2, x3); - return self; - } - - //! Sets all two DP-FP floats. - static inline Data128 fromF64(double x0) noexcept { - Data128 self; - self.setF64(x0); - return self; - } - - //! Sets all two DP-FP floats. - static inline Data128 fromF64(double x0, double x1) noexcept { - Data128 self; - self.setF64(x0, x1); - return self; - } - - //! \} - - //! \name Accessors - //! \{ - - //! Sets all sixteen 8-bit signed integers. - inline void setI8(int8_t x0) noexcept { - setU8(uint8_t(x0)); - } - - //! Sets all sixteen 8-bit unsigned integers. - inline void setU8(uint8_t x0) noexcept { - if (ASMJIT_ARCH_BITS >= 64) { - uint64_t xq = uint64_t(x0) * 0x0101010101010101u; - uq[0] = xq; - uq[1] = xq; - } - else { - uint32_t xd = uint32_t(x0) * 0x01010101u; - ud[0] = xd; - ud[1] = xd; - ud[2] = xd; - ud[3] = xd; - } - } - - //! Sets all sixteen 8-bit signed integers. - inline void setI8( - int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , - int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , - int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, - int8_t x12, int8_t x13, int8_t x14, int8_t x15) noexcept { - - sb[0 ] = x0 ; sb[1 ] = x1 ; sb[2 ] = x2 ; sb[3 ] = x3 ; - sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ; - sb[8 ] = x8 ; sb[9 ] = x9 ; sb[10] = x10; sb[11] = x11; - sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15; - } - - //! Sets all sixteen 8-bit unsigned integers. - inline void setU8( - uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , - uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , - uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, - uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15) noexcept { - - ub[0 ] = x0 ; ub[1 ] = x1 ; ub[2 ] = x2 ; ub[3 ] = x3 ; - ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ; - ub[8 ] = x8 ; ub[9 ] = x9 ; ub[10] = x10; ub[11] = x11; - ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15; - } - - //! Sets all eight 16-bit signed integers. - inline void setI16(int16_t x0) noexcept { - setU16(uint16_t(x0)); - } - - //! Sets all eight 16-bit unsigned integers. - inline void setU16(uint16_t x0) noexcept { - if (ASMJIT_ARCH_BITS >= 64) { - uint64_t xq = uint64_t(x0) * 0x0001000100010001u; - uq[0] = xq; - uq[1] = xq; - } - else { - uint32_t xd = uint32_t(x0) * 0x00010001u; - ud[0] = xd; - ud[1] = xd; - ud[2] = xd; - ud[3] = xd; - } - } - - //! Sets all eight 16-bit signed integers. - inline void setI16( - int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) noexcept { - - sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; - sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7; - } - - //! Sets all eight 16-bit unsigned integers. - inline void setU16( - uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7) noexcept { - - uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; - uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7; - } - - //! Sets all four 32-bit signed integers. - inline void setI32(int32_t x0) noexcept { - setU32(uint32_t(x0)); - } - - //! Sets all four 32-bit unsigned integers. - inline void setU32(uint32_t x0) noexcept { - if (ASMJIT_ARCH_BITS >= 64) { - uint64_t t = (uint64_t(x0) << 32) + x0; - uq[0] = t; - uq[1] = t; - } - else { - ud[0] = x0; - ud[1] = x0; - ud[2] = x0; - ud[3] = x0; - } - } - - //! Sets all four 32-bit signed integers. - inline void setI32(int32_t x0, int32_t x1, int32_t x2, int32_t x3) noexcept { - sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3; - } - - //! Sets all four 32-bit unsigned integers. - inline void setU32(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) noexcept { - ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3; - } - - //! Sets all two 64-bit signed integers. - inline void setI64(int64_t x0) noexcept { - sq[0] = x0; sq[1] = x0; - } - - //! Sets all two 64-bit unsigned integers. - inline void setU64(uint64_t x0) noexcept { - uq[0] = x0; uq[1] = x0; - } - - //! Sets all two 64-bit signed integers. - inline void setI64(int64_t x0, int64_t x1) noexcept { - sq[0] = x0; sq[1] = x1; - } - - //! Sets all two 64-bit unsigned integers. - inline void setU64(uint64_t x0, uint64_t x1) noexcept { - uq[0] = x0; uq[1] = x1; - } - - //! Sets all four SP-FP floats. - inline void setF32(float x0) noexcept { - sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0; - } - - //! Sets all four SP-FP floats. - inline void setF32(float x0, float x1, float x2, float x3) noexcept { - sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3; - } - - //! Sets all two DP-FP floats. - inline void setF64(double x0) noexcept { - df[0] = x0; df[1] = x0; - } - - //! Sets all two DP-FP floats. - inline void setF64(double x0, double x1) noexcept { - df[0] = x0; df[1] = x1; - } -}; - -// ============================================================================ -// [asmjit::Data256] -// ============================================================================ - -//! 256-bit data useful for creating SIMD constants. -union ASMJIT_DEPRECATED_STRUCT("Data256 is deprecated and will be removed in the future") Data256 { - //! Array of thirty two 8-bit signed integers. - int8_t sb[32]; - //! Array of thirty two 8-bit unsigned integers. - uint8_t ub[32]; - //! Array of sixteen 16-bit signed integers. - int16_t sw[16]; - //! Array of sixteen 16-bit unsigned integers. - uint16_t uw[16]; - //! Array of eight 32-bit signed integers. - int32_t sd[8]; - //! Array of eight 32-bit unsigned integers. - uint32_t ud[8]; - //! Array of four 64-bit signed integers. - int64_t sq[4]; - //! Array of four 64-bit unsigned integers. - uint64_t uq[4]; - - //! Array of eight 32-bit single precision floating points. - float sf[8]; - //! Array of four 64-bit double precision floating points. - double df[4]; - - //! \name Construction & Destruction - //! \{ - - //! Sets all thirty two 8-bit signed integers. - static inline Data256 fromI8(int8_t x0) noexcept { - Data256 self; - self.setI8(x0); - return self; - } - - //! Sets all thirty two 8-bit unsigned integers. - static inline Data256 fromU8(uint8_t x0) noexcept { - Data256 self; - self.setU8(x0); - return self; - } - - //! Sets all thirty two 8-bit signed integers. - static inline Data256 fromI8( - int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , - int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , - int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, - int8_t x12, int8_t x13, int8_t x14, int8_t x15, - int8_t x16, int8_t x17, int8_t x18, int8_t x19, - int8_t x20, int8_t x21, int8_t x22, int8_t x23, - int8_t x24, int8_t x25, int8_t x26, int8_t x27, - int8_t x28, int8_t x29, int8_t x30, int8_t x31) noexcept { - - Data256 self; - self.setI8( - x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15, - x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31); - return self; - } - - //! Sets all thirty two 8-bit unsigned integers. - static inline Data256 fromU8( - uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , - uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , - uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, - uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15, - uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19, - uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23, - uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27, - uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31) noexcept { - - Data256 self; - self.setU8( - x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15, - x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31); - return self; - } - - //! Sets all sixteen 16-bit signed integers. - static inline Data256 fromI16(int16_t x0) noexcept { - Data256 self; - self.setI16(x0); - return self; - } - - //! Sets all sixteen 16-bit unsigned integers. - static inline Data256 fromU16(uint16_t x0) noexcept { - Data256 self; - self.setU16(x0); - return self; - } - - //! Sets all sixteen 16-bit signed integers. - static inline Data256 fromI16( - int16_t x0, int16_t x1, int16_t x2 , int16_t x3 , int16_t x4 , int16_t x5 , int16_t x6 , int16_t x7 , - int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15) noexcept { - - Data256 self; - self.setI16(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); - return self; - } - - //! Sets all sixteen 16-bit unsigned integers. - static inline Data256 fromU16( - uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7 , - uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15) noexcept { - - Data256 self; - self.setU16(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); - return self; - } - - //! Sets all eight 32-bit signed integers. - static inline Data256 fromI32(int32_t x0) noexcept { - Data256 self; - self.setI32(x0); - return self; - } - - //! Sets all eight 32-bit unsigned integers. - static inline Data256 fromU32(uint32_t x0) noexcept { - Data256 self; - self.setU32(x0); - return self; - } - - //! Sets all eight 32-bit signed integers. - static inline Data256 fromI32( - int32_t x0, int32_t x1, int32_t x2, int32_t x3, - int32_t x4, int32_t x5, int32_t x6, int32_t x7) noexcept { - - Data256 self; - self.setI32(x0, x1, x2, x3, x4, x5, x6, x7); - return self; - } - - //! Sets all eight 32-bit unsigned integers. - static inline Data256 fromU32( - uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, - uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) noexcept { - - Data256 self; - self.setU32(x0, x1, x2, x3, x4, x5, x6, x7); - return self; - } - - //! Sets all four 64-bit signed integers. - static inline Data256 fromI64(int64_t x0) noexcept { - Data256 self; - self.setI64(x0); - return self; - } - - //! Sets all four 64-bit unsigned integers. - static inline Data256 fromU64(uint64_t x0) noexcept { - Data256 self; - self.setU64(x0); - return self; - } - - //! Sets all four 64-bit signed integers. - static inline Data256 fromI64(int64_t x0, int64_t x1, int64_t x2, int64_t x3) noexcept { - Data256 self; - self.setI64(x0, x1, x2, x3); - return self; - } - - //! Sets all four 64-bit unsigned integers. - static inline Data256 fromU64(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) noexcept { - Data256 self; - self.setU64(x0, x1, x2, x3); - return self; - } - - //! Sets all eight SP-FP floats. - static inline Data256 fromF32(float x0) noexcept { - Data256 self; - self.setF32(x0); - return self; - } - - //! Sets all eight SP-FP floats. - static inline Data256 fromF32( - float x0, float x1, float x2, float x3, - float x4, float x5, float x6, float x7) noexcept { - - Data256 self; - self.setF32(x0, x1, x2, x3, x4, x5, x6, x7); - return self; - } - - //! Sets all four DP-FP floats. - static inline Data256 fromF64(double x0) noexcept { - Data256 self; - self.setF64(x0); - return self; - } - - //! Sets all four DP-FP floats. - static inline Data256 fromF64(double x0, double x1, double x2, double x3) noexcept { - Data256 self; - self.setF64(x0, x1, x2, x3); - return self; - } - - //! \} - - //! \name Accessors - //! \{ - - //! Sets all thirty two 8-bit signed integers. - inline void setI8(int8_t x0) noexcept { - setU8(uint8_t(x0)); - } - - //! Sets all thirty two 8-bit unsigned integers. - inline void setU8(uint8_t x0) noexcept { - if (ASMJIT_ARCH_BITS >= 64) { - uint64_t xq = uint64_t(x0) * 0x0101010101010101u; - uq[0] = xq; - uq[1] = xq; - uq[2] = xq; - uq[3] = xq; - } - else { - uint32_t xd = uint32_t(x0) * 0x01010101u; - ud[0] = xd; - ud[1] = xd; - ud[2] = xd; - ud[3] = xd; - ud[4] = xd; - ud[5] = xd; - ud[6] = xd; - ud[7] = xd; - } - } - - //! Sets all thirty two 8-bit signed integers. - inline void setI8( - int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , - int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , - int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, - int8_t x12, int8_t x13, int8_t x14, int8_t x15, - int8_t x16, int8_t x17, int8_t x18, int8_t x19, - int8_t x20, int8_t x21, int8_t x22, int8_t x23, - int8_t x24, int8_t x25, int8_t x26, int8_t x27, - int8_t x28, int8_t x29, int8_t x30, int8_t x31) noexcept { - - sb[0 ] = x0 ; sb[1 ] = x1 ; sb[2 ] = x2 ; sb[3 ] = x3 ; - sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ; - sb[8 ] = x8 ; sb[9 ] = x9 ; sb[10] = x10; sb[11] = x11; - sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15; - sb[16] = x16; sb[17] = x17; sb[18] = x18; sb[19] = x19; - sb[20] = x20; sb[21] = x21; sb[22] = x22; sb[23] = x23; - sb[24] = x24; sb[25] = x25; sb[26] = x26; sb[27] = x27; - sb[28] = x28; sb[29] = x29; sb[30] = x30; sb[31] = x31; - } - - //! Sets all thirty two 8-bit unsigned integers. - inline void setU8( - uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , - uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , - uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, - uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15, - uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19, - uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23, - uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27, - uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31) noexcept { - - ub[0 ] = x0 ; ub[1 ] = x1 ; ub[2 ] = x2 ; ub[3 ] = x3 ; - ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ; - ub[8 ] = x8 ; ub[9 ] = x9 ; ub[10] = x10; ub[11] = x11; - ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15; - ub[16] = x16; ub[17] = x17; ub[18] = x18; ub[19] = x19; - ub[20] = x20; ub[21] = x21; ub[22] = x22; ub[23] = x23; - ub[24] = x24; ub[25] = x25; ub[26] = x26; ub[27] = x27; - ub[28] = x28; ub[29] = x29; ub[30] = x30; ub[31] = x31; - } - - //! Sets all sixteen 16-bit signed integers. - inline void setI16(int16_t x0) noexcept { - setU16(uint16_t(x0)); - } - - //! Sets all eight 16-bit unsigned integers. - inline void setU16(uint16_t x0) noexcept { - if (ASMJIT_ARCH_BITS >= 64) { - uint64_t xq = uint64_t(x0) * 0x0001000100010001u; - uq[0] = xq; - uq[1] = xq; - uq[2] = xq; - uq[3] = xq; - } - else { - uint32_t xd = uint32_t(x0) * 0x00010001u; - ud[0] = xd; - ud[1] = xd; - ud[2] = xd; - ud[3] = xd; - ud[4] = xd; - ud[5] = xd; - ud[6] = xd; - ud[7] = xd; - } - } - - //! Sets all sixteen 16-bit signed integers. - inline void setI16( - int16_t x0, int16_t x1, int16_t x2 , int16_t x3 , int16_t x4 , int16_t x5 , int16_t x6 , int16_t x7, - int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15) noexcept { - - sw[0 ] = x0 ; sw[1 ] = x1 ; sw[2 ] = x2 ; sw[3 ] = x3 ; - sw[4 ] = x4 ; sw[5 ] = x5 ; sw[6 ] = x6 ; sw[7 ] = x7 ; - sw[8 ] = x8 ; sw[9 ] = x9 ; sw[10] = x10; sw[11] = x11; - sw[12] = x12; sw[13] = x13; sw[14] = x14; sw[15] = x15; - } - - //! Sets all sixteen 16-bit unsigned integers. - inline void setU16( - uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7, - uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15) noexcept { - - uw[0 ] = x0 ; uw[1 ] = x1 ; uw[2 ] = x2 ; uw[3 ] = x3 ; - uw[4 ] = x4 ; uw[5 ] = x5 ; uw[6 ] = x6 ; uw[7 ] = x7 ; - uw[8 ] = x8 ; uw[9 ] = x9 ; uw[10] = x10; uw[11] = x11; - uw[12] = x12; uw[13] = x13; uw[14] = x14; uw[15] = x15; - } - - //! Sets all eight 32-bit signed integers. - inline void setI32(int32_t x0) noexcept { - setU32(uint32_t(x0)); - } - - //! Sets all eight 32-bit unsigned integers. - inline void setU32(uint32_t x0) noexcept { - if (ASMJIT_ARCH_BITS >= 64) { - uint64_t xq = (uint64_t(x0) << 32) + x0; - uq[0] = xq; - uq[1] = xq; - uq[2] = xq; - uq[3] = xq; - } - else { - ud[0] = x0; - ud[1] = x0; - ud[2] = x0; - ud[3] = x0; - ud[4] = x0; - ud[5] = x0; - ud[6] = x0; - ud[7] = x0; - } - } - - //! Sets all eight 32-bit signed integers. - inline void setI32( - int32_t x0, int32_t x1, int32_t x2, int32_t x3, - int32_t x4, int32_t x5, int32_t x6, int32_t x7) noexcept { - - sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3; - sd[4] = x4; sd[5] = x5; sd[6] = x6; sd[7] = x7; - } - - //! Sets all eight 32-bit unsigned integers. - inline void setU32( - uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, - uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) noexcept { - - ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3; - ud[4] = x4; ud[5] = x5; ud[6] = x6; ud[7] = x7; - } - - //! Sets all four 64-bit signed integers. - inline void setI64(int64_t x0) noexcept { - sq[0] = x0; sq[1] = x0; sq[2] = x0; sq[3] = x0; - } - - //! Sets all four 64-bit unsigned integers. - inline void setU64(uint64_t x0) noexcept { - uq[0] = x0; uq[1] = x0; uq[2] = x0; uq[3] = x0; - } - - //! Sets all four 64-bit signed integers. - inline void setI64(int64_t x0, int64_t x1, int64_t x2, int64_t x3) noexcept { - sq[0] = x0; sq[1] = x1; sq[2] = x2; sq[3] = x3; - } - - //! Sets all four 64-bit unsigned integers. - inline void setU64(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) noexcept { - uq[0] = x0; uq[1] = x1; uq[2] = x2; uq[3] = x3; - } - - //! Sets all eight SP-FP floats. - inline void setF32(float x0) noexcept { - sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0; - sf[4] = x0; sf[5] = x0; sf[6] = x0; sf[7] = x0; - } - - //! Sets all eight SP-FP floats. - inline void setF32( - float x0, float x1, float x2, float x3, - float x4, float x5, float x6, float x7) noexcept { - - sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3; - sf[4] = x4; sf[5] = x5; sf[6] = x6; sf[7] = x7; - } - - //! Sets all four DP-FP floats. - inline void setF64(double x0) noexcept { - df[0] = x0; df[1] = x0; df[2] = x0; df[3] = x0; - } - - //! Sets all four DP-FP floats. - inline void setF64(double x0, double x1, double x2, double x3) noexcept { - df[0] = x0; df[1] = x1; df[2] = x2; df[3] = x3; - } - - //! \} -}; - -ASMJIT_END_NAMESPACE - -#endif // !ASMJIT_NO_DEPRECATED -#endif // ASMJIT_CORE_DATATYPES_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emithelper.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emithelper.cpp deleted file mode 100644 index a77211e..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emithelper.cpp +++ /dev/null @@ -1,351 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/archtraits.h" -#include "../core/emithelper_p.h" -#include "../core/formatter.h" -#include "../core/funcargscontext_p.h" -#include "../core/radefs_p.h" - -// Can be used for debugging... -// #define ASMJIT_DUMP_ARGS_ASSIGNMENT - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::BaseEmitHelper - Formatting] -// ============================================================================ - -#ifdef ASMJIT_DUMP_ARGS_ASSIGNMENT -static void dumpFuncValue(String& sb, uint32_t arch, const FuncValue& value) noexcept { - Formatter::formatTypeId(sb, value.typeId()); - sb.append('@'); - - if (value.isIndirect()) - sb.append('['); - - if (value.isReg()) - Formatter::formatRegister(sb, 0, nullptr, arch, value.regType(), value.regId()); - else if (value.isStack()) - sb.appendFormat("[%d]", value.stackOffset()); - else - sb.append(""); - - if (value.isIndirect()) - sb.append(']'); -} - -static void dumpAssignment(String& sb, const FuncArgsContext& ctx) noexcept { - typedef FuncArgsContext::Var Var; - - uint32_t arch = ctx.arch(); - uint32_t varCount = ctx.varCount(); - - for (uint32_t i = 0; i < varCount; i++) { - const Var& var = ctx.var(i); - const FuncValue& dst = var.out; - const FuncValue& cur = var.cur; - - sb.appendFormat("Var%u: ", i); - dumpFuncValue(sb, arch, dst); - sb.append(" <- "); - dumpFuncValue(sb, arch, cur); - - if (var.isDone()) - sb.append(" {Done}"); - - sb.append('\n'); - } -} -#endif - -// ============================================================================ -// [asmjit::BaseEmitHelper - EmitArgsAssignment] -// ============================================================================ - -ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args) { - typedef FuncArgsContext::Var Var; - typedef FuncArgsContext::WorkData WorkData; - - enum WorkFlags : uint32_t { - kWorkNone = 0x00, - kWorkDidSome = 0x01, - kWorkPending = 0x02, - kWorkPostponed = 0x04 - }; - - uint32_t arch = frame.arch(); - const ArchTraits& archTraits = ArchTraits::byArch(arch); - - RAConstraints constraints; - FuncArgsContext ctx; - - ASMJIT_PROPAGATE(constraints.init(arch)); - ASMJIT_PROPAGATE(ctx.initWorkData(frame, args, &constraints)); - -#ifdef ASMJIT_DUMP_ARGS_ASSIGNMENT - { - String sb; - dumpAssignment(sb, ctx); - printf("%s\n", sb.data()); - } -#endif - - uint32_t varCount = ctx._varCount; - WorkData* workData = ctx._workData; - - uint32_t saVarId = ctx._saVarId; - BaseReg sp = BaseReg::fromSignatureAndId(_emitter->_gpRegInfo.signature(), archTraits.spRegId()); - BaseReg sa = sp; - - if (frame.hasDynamicAlignment()) { - if (frame.hasPreservedFP()) - sa.setId(archTraits.fpRegId()); - else - sa.setId(saVarId < varCount ? ctx._vars[saVarId].cur.regId() : frame.saRegId()); - } - - // -------------------------------------------------------------------------- - // Register to stack and stack to stack moves must be first as now we have - // the biggest chance of having as many as possible unassigned registers. - // -------------------------------------------------------------------------- - - if (ctx._stackDstMask) { - // Base address of all arguments passed by stack. - BaseMem baseArgPtr(sa, int32_t(frame.saOffset(sa.id()))); - BaseMem baseStackPtr(sp, 0); - - for (uint32_t varId = 0; varId < varCount; varId++) { - Var& var = ctx._vars[varId]; - - if (!var.out.isStack()) - continue; - - FuncValue& cur = var.cur; - FuncValue& out = var.out; - - ASMJIT_ASSERT(cur.isReg() || cur.isStack()); - BaseReg reg; - - BaseMem dstStackPtr = baseStackPtr.cloneAdjusted(out.stackOffset()); - BaseMem srcStackPtr = baseArgPtr.cloneAdjusted(cur.stackOffset()); - - if (cur.isIndirect()) { - if (cur.isStack()) { - // TODO: Indirect stack. - return DebugUtils::errored(kErrorInvalidAssignment); - } - else { - srcStackPtr.setBaseId(cur.regId()); - } - } - - if (cur.isReg() && !cur.isIndirect()) { - WorkData& wd = workData[archTraits.regTypeToGroup(cur.regType())]; - uint32_t rId = cur.regId(); - - reg.setSignatureAndId(archTraits.regTypeToSignature(cur.regType()), rId); - wd.unassign(varId, rId); - } - else { - // Stack to reg move - tricky since we move stack to stack we can decide which - // register to use. In general we follow the rule that IntToInt moves will use - // GP regs with possibility to signature or zero extend, and all other moves will - // either use GP or VEC regs depending on the size of the move. - RegInfo rInfo = getSuitableRegForMemToMemMove(arch, out.typeId(), cur.typeId()); - if (ASMJIT_UNLIKELY(!rInfo.isValid())) - return DebugUtils::errored(kErrorInvalidState); - - WorkData& wd = workData[rInfo.group()]; - uint32_t availableRegs = wd.availableRegs(); - if (ASMJIT_UNLIKELY(!availableRegs)) - return DebugUtils::errored(kErrorInvalidState); - - uint32_t rId = Support::ctz(availableRegs); - reg.setSignatureAndId(rInfo.signature(), rId); - - ASMJIT_PROPAGATE(emitArgMove(reg, out.typeId(), srcStackPtr, cur.typeId())); - } - - if (cur.isIndirect() && cur.isReg()) - workData[BaseReg::kGroupGp].unassign(varId, cur.regId()); - - // Register to stack move. - ASMJIT_PROPAGATE(emitRegMove(dstStackPtr, reg, cur.typeId())); - var.markDone(); - } - } - - // -------------------------------------------------------------------------- - // Shuffle all registers that are currently assigned accordingly to target - // assignment. - // -------------------------------------------------------------------------- - - uint32_t workFlags = kWorkNone; - for (;;) { - for (uint32_t varId = 0; varId < varCount; varId++) { - Var& var = ctx._vars[varId]; - if (var.isDone() || !var.cur.isReg()) - continue; - - FuncValue& cur = var.cur; - FuncValue& out = var.out; - - uint32_t curGroup = archTraits.regTypeToGroup(cur.regType()); - uint32_t outGroup = archTraits.regTypeToGroup(out.regType()); - - uint32_t curId = cur.regId(); - uint32_t outId = out.regId(); - - if (curGroup != outGroup) { - // TODO: Conversion is not supported. - return DebugUtils::errored(kErrorInvalidAssignment); - } - else { - WorkData& wd = workData[outGroup]; - if (!wd.isAssigned(outId)) { -EmitMove: - ASMJIT_PROPAGATE( - emitArgMove( - BaseReg::fromSignatureAndId(archTraits.regTypeToSignature(out.regType()), outId), out.typeId(), - BaseReg::fromSignatureAndId(archTraits.regTypeToSignature(cur.regType()), curId), cur.typeId())); - - wd.reassign(varId, outId, curId); - cur.initReg(out.regType(), outId, out.typeId()); - - if (outId == out.regId()) - var.markDone(); - workFlags |= kWorkDidSome | kWorkPending; - } - else { - uint32_t altId = wd._physToVarId[outId]; - Var& altVar = ctx._vars[altId]; - - if (!altVar.out.isInitialized() || (altVar.out.isReg() && altVar.out.regId() == curId)) { - // Only few architectures provide swap operations, and only for few register groups. - if (archTraits.hasSwap(curGroup)) { - uint32_t highestType = Support::max(cur.regType(), altVar.cur.regType()); - if (Support::isBetween(highestType, BaseReg::kTypeGp8Lo, BaseReg::kTypeGp16)) - highestType = BaseReg::kTypeGp32; - - uint32_t signature = archTraits.regTypeToSignature(highestType); - ASMJIT_PROPAGATE( - emitRegSwap(BaseReg::fromSignatureAndId(signature, outId), - BaseReg::fromSignatureAndId(signature, curId))); - wd.swap(varId, curId, altId, outId); - cur.setRegId(outId); - var.markDone(); - altVar.cur.setRegId(curId); - - if (altVar.out.isInitialized()) - altVar.markDone(); - workFlags |= kWorkDidSome; - } - else { - // If there is a scratch register it can be used to perform the swap. - uint32_t availableRegs = wd.availableRegs(); - if (availableRegs) { - uint32_t inOutRegs = wd.dstRegs(); - if (availableRegs & ~inOutRegs) - availableRegs &= ~inOutRegs; - outId = Support::ctz(availableRegs); - goto EmitMove; - } - else { - workFlags |= kWorkPending; - } - } - } - else { - workFlags |= kWorkPending; - } - } - } - } - - if (!(workFlags & kWorkPending)) - break; - - // If we did nothing twice it means that something is really broken. - if ((workFlags & (kWorkDidSome | kWorkPostponed)) == kWorkPostponed) - return DebugUtils::errored(kErrorInvalidState); - - workFlags = (workFlags & kWorkDidSome) ? kWorkNone : kWorkPostponed; - } - - // -------------------------------------------------------------------------- - // Load arguments passed by stack into registers. This is pretty simple and - // it never requires multiple iterations like the previous phase. - // -------------------------------------------------------------------------- - - if (ctx._hasStackSrc) { - uint32_t iterCount = 1; - if (frame.hasDynamicAlignment() && !frame.hasPreservedFP()) - sa.setId(saVarId < varCount ? ctx._vars[saVarId].cur.regId() : frame.saRegId()); - - // Base address of all arguments passed by stack. - BaseMem baseArgPtr(sa, int32_t(frame.saOffset(sa.id()))); - - for (uint32_t iter = 0; iter < iterCount; iter++) { - for (uint32_t varId = 0; varId < varCount; varId++) { - Var& var = ctx._vars[varId]; - if (var.isDone()) - continue; - - if (var.cur.isStack()) { - ASMJIT_ASSERT(var.out.isReg()); - - uint32_t outId = var.out.regId(); - uint32_t outType = var.out.regType(); - - uint32_t group = archTraits.regTypeToGroup(outType); - WorkData& wd = ctx._workData[group]; - - if (outId == sa.id() && group == BaseReg::kGroupGp) { - // This register will be processed last as we still need `saRegId`. - if (iterCount == 1) { - iterCount++; - continue; - } - wd.unassign(wd._physToVarId[outId], outId); - } - - BaseReg dstReg = BaseReg::fromSignatureAndId(archTraits.regTypeToSignature(outType), outId); - BaseMem srcMem = baseArgPtr.cloneAdjusted(var.cur.stackOffset()); - - ASMJIT_PROPAGATE(emitArgMove( - dstReg, var.out.typeId(), - srcMem, var.cur.typeId())); - - wd.assign(varId, outId); - var.cur.initReg(outType, outId, var.cur.typeId(), FuncValue::kFlagIsDone); - } - } - } - } - - return kErrorOk; -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emithelper_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emithelper_p.h deleted file mode 100644 index cb8ddf0..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emithelper_p.h +++ /dev/null @@ -1,83 +0,0 @@ - -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_EMITHELPER_P_H_INCLUDED -#define ASMJIT_CORE_EMITHELPER_P_H_INCLUDED - -#include "../core/emitter.h" -#include "../core/operand.h" -#include "../core/type.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \cond INTERNAL -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [asmjit::BaseEmitHelper] -// ============================================================================ - -//! Helper class that provides utilities for each supported architecture. -class BaseEmitHelper { -public: - BaseEmitter* _emitter; - - inline explicit BaseEmitHelper(BaseEmitter* emitter = nullptr) noexcept - : _emitter(emitter) {} - - inline BaseEmitter* emitter() const noexcept { return _emitter; } - inline void setEmitter(BaseEmitter* emitter) noexcept { _emitter = emitter; } - - //! Emits a pure move operation between two registers or the same type or - //! between a register and its home slot. This function does not handle - //! register conversion. - virtual Error emitRegMove( - const Operand_& dst_, - const Operand_& src_, uint32_t typeId, const char* comment = nullptr) = 0; - - //! Emits swap between two registers. - virtual Error emitRegSwap( - const BaseReg& a, - const BaseReg& b, const char* comment = nullptr) = 0; - - //! Emits move from a function argument (either register or stack) to a register. - //! - //! This function can handle the necessary conversion from one argument to - //! another, and from one register type to another, if it's possible. Any - //! attempt of conversion that requires third register of a different group - //! (for example conversion from K to MMX on X86/X64) will fail. - virtual Error emitArgMove( - const BaseReg& dst_, uint32_t dstTypeId, - const Operand_& src_, uint32_t srcTypeId, const char* comment = nullptr) = 0; - - Error emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args); -}; - -//! \} -//! \endcond - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_EMITHELPER_P_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitter.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitter.cpp deleted file mode 100644 index f684140..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitter.cpp +++ /dev/null @@ -1,416 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/emitterutils_p.h" -#include "../core/errorhandler.h" -#include "../core/logger.h" -#include "../core/support.h" - -#ifdef ASMJIT_BUILD_X86 - #include "../x86/x86emithelper_p.h" - #include "../x86/x86instdb_p.h" -#endif // ASMJIT_BUILD_X86 - -#ifdef ASMJIT_BUILD_ARM - #include "../arm/a64emithelper_p.h" - #include "../arm/a64instdb.h" -#endif // ASMJIT_BUILD_ARM - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::BaseEmitter - Construction / Destruction] -// ============================================================================ - -BaseEmitter::BaseEmitter(uint32_t emitterType) noexcept - : _emitterType(uint8_t(emitterType)) {} - -BaseEmitter::~BaseEmitter() noexcept { - if (_code) { - _addEmitterFlags(kFlagDestroyed); - _code->detach(this); - } -} - -// ============================================================================ -// [asmjit::BaseEmitter - Finalize] -// ============================================================================ - -Error BaseEmitter::finalize() { - // Does nothing by default, overridden by `BaseBuilder` and `BaseCompiler`. - return kErrorOk; -} - -// ============================================================================ -// [asmjit::BaseEmitter - Internals] -// ============================================================================ - -static constexpr uint32_t kEmitterPreservedFlags = BaseEmitter::kFlagOwnLogger | BaseEmitter::kFlagOwnErrorHandler; - -static ASMJIT_NOINLINE void BaseEmitter_updateForcedOptions(BaseEmitter* self) noexcept { - bool emitComments = false; - bool hasValidationOptions = false; - - if (self->emitterType() == BaseEmitter::kTypeAssembler) { - // Assembler: Don't emit comments if logger is not attached. - emitComments = self->_code != nullptr && self->_logger != nullptr; - hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionAssembler); - } - else { - // Builder/Compiler: Always emit comments, we cannot assume they won't be used. - emitComments = self->_code != nullptr; - hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionIntermediate); - } - - if (emitComments) - self->_addEmitterFlags(BaseEmitter::kFlagLogComments); - else - self->_clearEmitterFlags(BaseEmitter::kFlagLogComments); - - // The reserved option tells emitter (Assembler/Builder/Compiler) that there - // may be either a border case (CodeHolder not attached, for example) or that - // logging or validation is required. - if (self->_code == nullptr || self->_logger || hasValidationOptions) - self->_forcedInstOptions |= BaseInst::kOptionReserved; - else - self->_forcedInstOptions &= ~BaseInst::kOptionReserved; -} - -// ============================================================================ -// [asmjit::BaseEmitter - Validation Options] -// ============================================================================ - -void BaseEmitter::addValidationOptions(uint32_t options) noexcept { - _validationOptions = uint8_t(_validationOptions | options); - BaseEmitter_updateForcedOptions(this); -} - -void BaseEmitter::clearValidationOptions(uint32_t options) noexcept { - _validationOptions = uint8_t(_validationOptions | options); - BaseEmitter_updateForcedOptions(this); -} - -// ============================================================================ -// [asmjit::BaseEmitter - Logging] -// ============================================================================ - -void BaseEmitter::setLogger(Logger* logger) noexcept { -#ifndef ASMJIT_NO_LOGGING - if (logger) { - _logger = logger; - _addEmitterFlags(kFlagOwnLogger); - } - else { - _logger = nullptr; - _clearEmitterFlags(kFlagOwnLogger); - if (_code) - _logger = _code->logger(); - } - BaseEmitter_updateForcedOptions(this); -#else - DebugUtils::unused(logger); -#endif -} - -// ============================================================================ -// [asmjit::BaseEmitter - Error Handling] -// ============================================================================ - -void BaseEmitter::setErrorHandler(ErrorHandler* errorHandler) noexcept { - if (errorHandler) { - _errorHandler = errorHandler; - _addEmitterFlags(kFlagOwnErrorHandler); - } - else { - _errorHandler = nullptr; - _clearEmitterFlags(kFlagOwnErrorHandler); - if (_code) - _errorHandler = _code->errorHandler(); - } -} - -Error BaseEmitter::reportError(Error err, const char* message) { - ErrorHandler* eh = _errorHandler; - if (eh) { - if (!message) - message = DebugUtils::errorAsString(err); - eh->handleError(err, message, this); - } - return err; -} - -// ============================================================================ -// [asmjit::BaseEmitter - Labels] -// ============================================================================ - -Label BaseEmitter::labelByName(const char* name, size_t nameSize, uint32_t parentId) noexcept { - return Label(_code ? _code->labelIdByName(name, nameSize, parentId) : uint32_t(Globals::kInvalidId)); -} - -bool BaseEmitter::isLabelValid(uint32_t labelId) const noexcept { - return _code && labelId < _code->labelCount(); -} - -// ============================================================================ -// [asmjit::BaseEmitter - Emit (Low-Level)] -// ============================================================================ - -using EmitterUtils::noExt; - -Error BaseEmitter::_emitI(uint32_t instId) { - return _emit(instId, noExt[0], noExt[1], noExt[2], noExt); -} - -Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0) { - return _emit(instId, o0, noExt[1], noExt[2], noExt); -} - -Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1) { - return _emit(instId, o0, o1, noExt[2], noExt); -} - -Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2) { - return _emit(instId, o0, o1, o2, noExt); -} - -Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) { - Operand_ opExt[3] = { o3 }; - return _emit(instId, o0, o1, o2, opExt); -} - -Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4) { - Operand_ opExt[3] = { o3, o4 }; - return _emit(instId, o0, o1, o2, opExt); -} - -Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) { - Operand_ opExt[3] = { o3, o4, o5 }; - return _emit(instId, o0, o1, o2, opExt); -} - -Error BaseEmitter::_emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount) { - const Operand_* op = operands; - - Operand_ opExt[3]; - - switch (opCount) { - case 0: - return _emit(instId, noExt[0], noExt[1], noExt[2], noExt); - - case 1: - return _emit(instId, op[0], noExt[1], noExt[2], noExt); - - case 2: - return _emit(instId, op[0], op[1], noExt[2], noExt); - - case 3: - return _emit(instId, op[0], op[1], op[2], noExt); - - case 4: - opExt[0] = op[3]; - opExt[1].reset(); - opExt[2].reset(); - return _emit(instId, op[0], op[1], op[2], opExt); - - case 5: - opExt[0] = op[3]; - opExt[1] = op[4]; - opExt[2].reset(); - return _emit(instId, op[0], op[1], op[2], opExt); - - case 6: - return _emit(instId, op[0], op[1], op[2], op + 3); - - default: - return DebugUtils::errored(kErrorInvalidArgument); - } -} - -// ============================================================================ -// [asmjit::BaseEmitter - Emit (High-Level)] -// ============================================================================ - -ASMJIT_FAVOR_SIZE Error BaseEmitter::emitProlog(const FuncFrame& frame) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - -#ifdef ASMJIT_BUILD_X86 - if (environment().isFamilyX86()) { - x86::EmitHelper emitHelper(this, frame.isAvxEnabled()); - return emitHelper.emitProlog(frame); - } -#endif - -#ifdef ASMJIT_BUILD_ARM - if (environment().isArchAArch64()) { - a64::EmitHelper emitHelper(this); - return emitHelper.emitProlog(frame); - } -#endif - - return DebugUtils::errored(kErrorInvalidArch); -} - -ASMJIT_FAVOR_SIZE Error BaseEmitter::emitEpilog(const FuncFrame& frame) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - -#ifdef ASMJIT_BUILD_X86 - if (environment().isFamilyX86()) { - x86::EmitHelper emitHelper(this, frame.isAvxEnabled()); - return emitHelper.emitEpilog(frame); - } -#endif - -#ifdef ASMJIT_BUILD_ARM - if (environment().isArchAArch64()) { - a64::EmitHelper emitHelper(this); - return emitHelper.emitEpilog(frame); - } -#endif - - return DebugUtils::errored(kErrorInvalidArch); -} - -ASMJIT_FAVOR_SIZE Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args) { - if (ASMJIT_UNLIKELY(!_code)) - return DebugUtils::errored(kErrorNotInitialized); - -#ifdef ASMJIT_BUILD_X86 - if (environment().isFamilyX86()) { - x86::EmitHelper emitHelper(this, frame.isAvxEnabled()); - return emitHelper.emitArgsAssignment(frame, args); - } -#endif - -#ifdef ASMJIT_BUILD_ARM - if (environment().isArchAArch64()) { - a64::EmitHelper emitHelper(this); - return emitHelper.emitArgsAssignment(frame, args); - } -#endif - - return DebugUtils::errored(kErrorInvalidArch); -} - -// ============================================================================ -// [asmjit::BaseEmitter - Comment] -// ============================================================================ - -Error BaseEmitter::commentf(const char* fmt, ...) { - if (!hasEmitterFlag(kFlagLogComments)) { - if (!hasEmitterFlag(kFlagAttached)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - return kErrorOk; - } - -#ifndef ASMJIT_NO_LOGGING - StringTmp<1024> sb; - - va_list ap; - va_start(ap, fmt); - Error err = sb.appendVFormat(fmt, ap); - va_end(ap); - - ASMJIT_PROPAGATE(err); - return comment(sb.data(), sb.size()); -#else - DebugUtils::unused(fmt); - return kErrorOk; -#endif -} - -Error BaseEmitter::commentv(const char* fmt, va_list ap) { - if (!hasEmitterFlag(kFlagLogComments)) { - if (!hasEmitterFlag(kFlagAttached)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - return kErrorOk; - } - -#ifndef ASMJIT_NO_LOGGING - StringTmp<1024> sb; - Error err = sb.appendVFormat(fmt, ap); - - ASMJIT_PROPAGATE(err); - return comment(sb.data(), sb.size()); -#else - DebugUtils::unused(fmt, ap); - return kErrorOk; -#endif -} - -// ============================================================================ -// [asmjit::BaseEmitter - Events] -// ============================================================================ - -Error BaseEmitter::onAttach(CodeHolder* code) noexcept { - _code = code; - _environment = code->environment(); - _addEmitterFlags(kFlagAttached); - - const ArchTraits& archTraits = ArchTraits::byArch(code->arch()); - uint32_t nativeRegType = Environment::is32Bit(code->arch()) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64; - _gpRegInfo.setSignature(archTraits._regInfo[nativeRegType].signature()); - - onSettingsUpdated(); - return kErrorOk; -} - -Error BaseEmitter::onDetach(CodeHolder* code) noexcept { - DebugUtils::unused(code); - - if (!hasOwnLogger()) - _logger = nullptr; - - if (!hasOwnErrorHandler()) - _errorHandler = nullptr; - - _clearEmitterFlags(~kEmitterPreservedFlags); - _forcedInstOptions = BaseInst::kOptionReserved; - _privateData = 0; - - _environment.reset(); - _gpRegInfo.reset(); - - _instOptions = 0; - _extraReg.reset(); - _inlineComment = nullptr; - - return kErrorOk; -} - -void BaseEmitter::onSettingsUpdated() noexcept { - // Only called when attached to CodeHolder by CodeHolder. - ASMJIT_ASSERT(_code != nullptr); - - if (!hasOwnLogger()) - _logger = _code->logger(); - - if (!hasOwnErrorHandler()) - _errorHandler = _code->errorHandler(); - - BaseEmitter_updateForcedOptions(this); -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitter.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitter.h deleted file mode 100644 index fcb9bb5..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitter.h +++ /dev/null @@ -1,723 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_EMITTER_H_INCLUDED -#define ASMJIT_CORE_EMITTER_H_INCLUDED - -#include "../core/archtraits.h" -#include "../core/codeholder.h" -#include "../core/inst.h" -#include "../core/operand.h" -#include "../core/type.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -class ConstPool; -class FuncFrame; -class FuncArgsAssignment; - -// ============================================================================ -// [asmjit::BaseEmitter] -// ============================================================================ - -//! Provides a base foundation to emit code - specialized by `Assembler` and -//! `BaseBuilder`. -class ASMJIT_VIRTAPI BaseEmitter { -public: - ASMJIT_BASE_CLASS(BaseEmitter) - - //! See \ref EmitterType. - uint8_t _emitterType = 0; - //! See \ref BaseEmitter::EmitterFlags. - uint8_t _emitterFlags = 0; - //! Validation flags in case validation is used, see \ref InstAPI::ValidationFlags. - //! - //! \note Validation flags are specific to the emitter and they are setup at - //! construction time and then never changed. - uint8_t _validationFlags = 0; - //! Validation options, see \ref ValidationOptions. - uint8_t _validationOptions = 0; - - //! Encoding options, see \ref EncodingOptions. - uint32_t _encodingOptions = 0; - - //! Forced instruction options, combined with \ref _instOptions by \ref emit(). - uint32_t _forcedInstOptions = BaseInst::kOptionReserved; - //! Internal private data used freely by any emitter. - uint32_t _privateData = 0; - - //! CodeHolder the emitter is attached to. - CodeHolder* _code = nullptr; - //! Attached \ref Logger. - Logger* _logger = nullptr; - //! Attached \ref ErrorHandler. - ErrorHandler* _errorHandler = nullptr; - - //! Describes the target environment, matches \ref CodeHolder::environment(). - Environment _environment {}; - //! Native GP register signature and signature related information. - RegInfo _gpRegInfo {}; - - //! Next instruction options (affects the next instruction). - uint32_t _instOptions = 0; - //! Extra register (op-mask {k} on AVX-512) (affects the next instruction). - RegOnly _extraReg {}; - //! Inline comment of the next instruction (affects the next instruction). - const char* _inlineComment = nullptr; - - //! Emitter type. - enum EmitterType : uint32_t { - //! Unknown or uninitialized. - kTypeNone = 0, - //! Emitter inherits from \ref BaseAssembler. - kTypeAssembler = 1, - //! Emitter inherits from \ref BaseBuilder. - kTypeBuilder = 2, - //! Emitter inherits from \ref BaseCompiler. - kTypeCompiler = 3, - - //! Count of emitter types. - kTypeCount = 4 - }; - - //! Emitter flags. - enum EmitterFlags : uint32_t { - //! Emitter is attached to CodeHolder. - kFlagAttached = 0x01u, - //! The emitter must emit comments. - kFlagLogComments = 0x08u, - //! The emitter has its own \ref Logger (not propagated from \ref CodeHolder). - kFlagOwnLogger = 0x10u, - //! The emitter has its own \ref ErrorHandler (not propagated from \ref CodeHolder). - kFlagOwnErrorHandler = 0x20u, - //! The emitter was finalized. - kFlagFinalized = 0x40u, - //! The emitter was destroyed. - kFlagDestroyed = 0x80u - }; - - //! Encoding options. - enum EncodingOptions : uint32_t { - //! Emit instructions that are optimized for size, if possible. - //! - //! Default: false. - //! - //! X86 Specific - //! ------------ - //! - //! When this option is set it the assembler will try to fix instructions - //! if possible into operation equivalent instructions that take less bytes - //! by taking advantage of implicit zero extension. For example instruction - //! like `mov r64, imm` and `and r64, imm` can be translated to `mov r32, imm` - //! and `and r32, imm` when the immediate constant is lesser than `2^31`. - kEncodingOptionOptimizeForSize = 0x00000001u, - - //! Emit optimized code-alignment sequences. - //! - //! Default: false. - //! - //! X86 Specific - //! ------------ - //! - //! Default align sequence used by X86 architecture is one-byte (0x90) - //! opcode that is often shown by disassemblers as NOP. However there are - //! more optimized align sequences for 2-11 bytes that may execute faster - //! on certain CPUs. If this feature is enabled AsmJit will generate - //! specialized sequences for alignment between 2 to 11 bytes. - kEncodingOptionOptimizedAlign = 0x00000002u, - - //! Emit jump-prediction hints. - //! - //! Default: false. - //! - //! X86 Specific - //! ------------ - //! - //! Jump prediction is usually based on the direction of the jump. If the - //! jump is backward it is usually predicted as taken; and if the jump is - //! forward it is usually predicted as not-taken. The reason is that loops - //! generally use backward jumps and conditions usually use forward jumps. - //! However this behavior can be overridden by using instruction prefixes. - //! If this option is enabled these hints will be emitted. - //! - //! This feature is disabled by default, because the only processor that - //! used to take into consideration prediction hints was P4. Newer processors - //! implement heuristics for branch prediction and ignore static hints. This - //! means that this feature can be only used for annotation purposes. - kEncodingOptionPredictedJumps = 0x00000010u - }; - -#ifndef ASMJIT_NO_DEPRECATED - enum EmitterOptions : uint32_t { - kOptionOptimizedForSize = kEncodingOptionOptimizeForSize, - kOptionOptimizedAlign = kEncodingOptionOptimizedAlign, - kOptionPredictedJumps = kEncodingOptionPredictedJumps - }; -#endif - - //! Validation options are used to tell emitters to perform strict validation - //! of instructions passed to \ref emit(). - //! - //! \ref BaseAssembler implementation perform by default only basic checks - //! that are necessary to identify all variations of an instruction so the - //! correct encoding can be selected. This is fine for production-ready code - //! as the assembler doesn't have to perform checks that would slow it down. - //! However, sometimes these checks are beneficial especially when the project - //! that uses AsmJit is in a development phase, in which mistakes happen often. - //! To make the experience of using AsmJit seamless it offers validation - //! features that can be controlled by `ValidationOptions`. - enum ValidationOptions : uint32_t { - //! Perform strict validation in \ref BaseAssembler::emit() implementations. - //! - //! This flag ensures that each instruction is checked before it's encoded - //! into a binary representation. This flag is only relevant for \ref - //! BaseAssembler implementations, but can be set in any other emitter type, - //! in that case if that emitter needs to create an assembler on its own, - //! for the purpose of \ref finalize() it would propagate this flag to such - //! assembler so all instructions passed to it are explicitly validated. - //! - //! Default: false. - kValidationOptionAssembler = 0x00000001u, - - //! Perform strict validation in \ref BaseBuilder::emit() and \ref - //! BaseCompiler::emit() implementations. - //! - //! This flag ensures that each instruction is checked before an \ref - //! InstNode representing the instruction is created by Builder or Compiler. - //! - //! Default: false. - kValidationOptionIntermediate = 0x00000002u - }; - - //! \name Construction & Destruction - //! \{ - - ASMJIT_API explicit BaseEmitter(uint32_t emitterType) noexcept; - ASMJIT_API virtual ~BaseEmitter() noexcept; - - //! \} - - //! \name Cast - //! \{ - - template - inline T* as() noexcept { return reinterpret_cast(this); } - - template - inline const T* as() const noexcept { return reinterpret_cast(this); } - - //! \} - - //! \name Emitter Type & Flags - //! \{ - - //! Returns the type of this emitter, see `EmitterType`. - inline uint32_t emitterType() const noexcept { return _emitterType; } - //! Returns emitter flags , see `Flags`. - inline uint32_t emitterFlags() const noexcept { return _emitterFlags; } - - //! Tests whether the emitter inherits from `BaseAssembler`. - inline bool isAssembler() const noexcept { return _emitterType == kTypeAssembler; } - //! Tests whether the emitter inherits from `BaseBuilder`. - //! - //! \note Both Builder and Compiler emitters would return `true`. - inline bool isBuilder() const noexcept { return _emitterType >= kTypeBuilder; } - //! Tests whether the emitter inherits from `BaseCompiler`. - inline bool isCompiler() const noexcept { return _emitterType == kTypeCompiler; } - - //! Tests whether the emitter has the given `flag` enabled. - inline bool hasEmitterFlag(uint32_t flag) const noexcept { return (_emitterFlags & flag) != 0; } - //! Tests whether the emitter is finalized. - inline bool isFinalized() const noexcept { return hasEmitterFlag(kFlagFinalized); } - //! Tests whether the emitter is destroyed (only used during destruction). - inline bool isDestroyed() const noexcept { return hasEmitterFlag(kFlagDestroyed); } - - inline void _addEmitterFlags(uint32_t flags) noexcept { _emitterFlags = uint8_t(_emitterFlags | flags); } - inline void _clearEmitterFlags(uint32_t flags) noexcept { _emitterFlags = uint8_t(_emitterFlags & ~flags); } - - //! \} - - //! \name Target Information - //! \{ - - //! Returns the CodeHolder this emitter is attached to. - inline CodeHolder* code() const noexcept { return _code; } - - //! Returns the target environment, see \ref Environment. - //! - //! The returned \ref Environment reference matches \ref CodeHolder::environment(). - inline const Environment& environment() const noexcept { return _environment; } - - //! Tests whether the target architecture is 32-bit. - inline bool is32Bit() const noexcept { return environment().is32Bit(); } - //! Tests whether the target architecture is 64-bit. - inline bool is64Bit() const noexcept { return environment().is64Bit(); } - - //! Returns the target architecture type. - inline uint32_t arch() const noexcept { return environment().arch(); } - //! Returns the target architecture sub-type. - inline uint32_t subArch() const noexcept { return environment().subArch(); } - - //! Returns the target architecture's GP register size (4 or 8 bytes). - inline uint32_t registerSize() const noexcept { return environment().registerSize(); } - - //! \} - - //! \name Initialization & Finalization - //! \{ - - //! Tests whether the emitter is initialized (i.e. attached to \ref CodeHolder). - inline bool isInitialized() const noexcept { return _code != nullptr; } - - //! Finalizes this emitter. - //! - //! Materializes the content of the emitter by serializing it to the attached - //! \ref CodeHolder through an architecture specific \ref BaseAssembler. This - //! function won't do anything if the emitter inherits from \ref BaseAssembler - //! as assemblers emit directly to a \ref CodeBuffer held by \ref CodeHolder. - //! However, if this is an emitter that inherits from \ref BaseBuilder or \ref - //! BaseCompiler then these emitters need the materialization phase as they - //! store their content in a representation not visible to \ref CodeHolder. - ASMJIT_API virtual Error finalize(); - - //! \} - - //! \name Logging - //! \{ - - //! Tests whether the emitter has a logger. - inline bool hasLogger() const noexcept { return _logger != nullptr; } - - //! Tests whether the emitter has its own logger. - //! - //! Own logger means that it overrides the possible logger that may be used - //! by \ref CodeHolder this emitter is attached to. - inline bool hasOwnLogger() const noexcept { return hasEmitterFlag(kFlagOwnLogger); } - - //! Returns the logger this emitter uses. - //! - //! The returned logger is either the emitter's own logger or it's logger - //! used by \ref CodeHolder this emitter is attached to. - inline Logger* logger() const noexcept { return _logger; } - - //! Sets or resets the logger of the emitter. - //! - //! If the `logger` argument is non-null then the logger will be considered - //! emitter's own logger, see \ref hasOwnLogger() for more details. If the - //! given `logger` is null then the emitter will automatically use logger - //! that is attached to the \ref CodeHolder this emitter is attached to. - ASMJIT_API void setLogger(Logger* logger) noexcept; - - //! Resets the logger of this emitter. - //! - //! The emitter will bail to using a logger attached to \ref CodeHolder this - //! emitter is attached to, or no logger at all if \ref CodeHolder doesn't - //! have one. - inline void resetLogger() noexcept { return setLogger(nullptr); } - - //! \} - - //! \name Error Handling - //! \{ - - //! Tests whether the emitter has an error handler attached. - inline bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; } - - //! Tests whether the emitter has its own error handler. - //! - //! Own error handler means that it overrides the possible error handler that - //! may be used by \ref CodeHolder this emitter is attached to. - inline bool hasOwnErrorHandler() const noexcept { return hasEmitterFlag(kFlagOwnErrorHandler); } - - //! Returns the error handler this emitter uses. - //! - //! The returned error handler is either the emitter's own error handler or - //! it's error handler used by \ref CodeHolder this emitter is attached to. - inline ErrorHandler* errorHandler() const noexcept { return _errorHandler; } - - //! Sets or resets the error handler of the emitter. - ASMJIT_API void setErrorHandler(ErrorHandler* errorHandler) noexcept; - - //! Resets the error handler. - inline void resetErrorHandler() noexcept { setErrorHandler(nullptr); } - - //! Handles the given error in the following way: - //! 1. If the emitter has \ref ErrorHandler attached, it calls its - //! \ref ErrorHandler::handleError() member function first, and - //! then returns the error. The `handleError()` function may throw. - //! 2. if the emitter doesn't have \ref ErrorHandler, the error is - //! simply returned. - ASMJIT_API Error reportError(Error err, const char* message = nullptr); - - //! \} - - //! \name Encoding Options - //! \{ - - //! Returns encoding options, see \ref EncodingOptions. - inline uint32_t encodingOptions() const noexcept { return _encodingOptions; } - //! Tests whether the encoding `option` is set. - inline bool hasEncodingOption(uint32_t option) const noexcept { return (_encodingOptions & option) != 0; } - - //! Enables the given encoding `options`, see \ref EncodingOptions. - inline void addEncodingOptions(uint32_t options) noexcept { _encodingOptions |= options; } - //! Disables the given encoding `options`, see \ref EncodingOptions. - inline void clearEncodingOptions(uint32_t options) noexcept { _encodingOptions &= ~options; } - - //! \} - - //! \name Validation Options - //! \{ - - //! Returns the emitter's validation options, see \ref ValidationOptions. - inline uint32_t validationOptions() const noexcept { - return _validationOptions; - } - - //! Tests whether the given `option` is present in validation options. - inline bool hasValidationOption(uint32_t option) const noexcept { - return (_validationOptions & option) != 0; - } - - //! Activates the given validation `options`, see \ref ValidationOptions. - //! - //! This function is used to activate explicit validation options that will - //! be then used by all emitter implementations. There are in general two - //! possibilities: - //! - //! - Architecture specific assembler is used. In this case a - //! \ref kValidationOptionAssembler can be used to turn on explicit - //! validation that will be used before an instruction is emitted. - //! This means that internally an extra step will be performed to - //! make sure that the instruction is correct. This is needed, because - //! by default assemblers prefer speed over strictness. - //! - //! This option should be used in debug builds as it's pretty expensive. - //! - //! - Architecture specific builder or compiler is used. In this case - //! the user can turn on \ref kValidationOptionIntermediate option - //! that adds explicit validation step before the Builder or Compiler - //! creates an \ref InstNode to represent an emitted instruction. Error - //! will be returned if the instruction is ill-formed. In addition, - //! also \ref kValidationOptionAssembler can be used, which would not be - //! consumed by Builder / Compiler directly, but it would be propagated - //! to an architecture specific \ref BaseAssembler implementation it - //! creates during \ref BaseEmitter::finalize(). - ASMJIT_API void addValidationOptions(uint32_t options) noexcept; - - //! Deactivates the given validation `options`. - //! - //! See \ref addValidationOptions() and \ref ValidationOptions for more details. - ASMJIT_API void clearValidationOptions(uint32_t options) noexcept; - - //! \} - - //! \name Instruction Options - //! \{ - - //! Returns forced instruction options. - //! - //! Forced instruction options are merged with next instruction options before - //! the instruction is encoded. These options have some bits reserved that are - //! used by error handling, logging, and instruction validation purposes. Other - //! options are globals that affect each instruction. - inline uint32_t forcedInstOptions() const noexcept { return _forcedInstOptions; } - - //! Returns options of the next instruction. - inline uint32_t instOptions() const noexcept { return _instOptions; } - //! Returns options of the next instruction. - inline void setInstOptions(uint32_t options) noexcept { _instOptions = options; } - //! Adds options of the next instruction. - inline void addInstOptions(uint32_t options) noexcept { _instOptions |= options; } - //! Resets options of the next instruction. - inline void resetInstOptions() noexcept { _instOptions = 0; } - - //! Tests whether the extra register operand is valid. - inline bool hasExtraReg() const noexcept { return _extraReg.isReg(); } - //! Returns an extra operand that will be used by the next instruction (architecture specific). - inline const RegOnly& extraReg() const noexcept { return _extraReg; } - //! Sets an extra operand that will be used by the next instruction (architecture specific). - inline void setExtraReg(const BaseReg& reg) noexcept { _extraReg.init(reg); } - //! Sets an extra operand that will be used by the next instruction (architecture specific). - inline void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); } - //! Resets an extra operand that will be used by the next instruction (architecture specific). - inline void resetExtraReg() noexcept { _extraReg.reset(); } - - //! Returns comment/annotation of the next instruction. - inline const char* inlineComment() const noexcept { return _inlineComment; } - //! Sets comment/annotation of the next instruction. - //! - //! \note This string is set back to null by `_emit()`, but until that it has - //! to remain valid as the Emitter is not required to make a copy of it (and - //! it would be slow to do that for each instruction). - inline void setInlineComment(const char* s) noexcept { _inlineComment = s; } - //! Resets the comment/annotation to nullptr. - inline void resetInlineComment() noexcept { _inlineComment = nullptr; } - - //! \} - - //! \name Sections - //! \{ - - virtual Error section(Section* section) = 0; - - //! \} - - //! \name Labels - //! \{ - - //! Creates a new label. - virtual Label newLabel() = 0; - //! Creates a new named label. - virtual Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) = 0; - - //! Creates a new external label. - inline Label newExternalLabel(const char* name, size_t nameSize = SIZE_MAX) { - return newNamedLabel(name, nameSize, Label::kTypeExternal); - } - - //! Returns `Label` by `name`. - //! - //! Returns invalid Label in case that the name is invalid or label was not found. - //! - //! \note This function doesn't trigger ErrorHandler in case the name is invalid - //! or no such label exist. You must always check the validity of the `Label` returned. - ASMJIT_API Label labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept; - - //! Binds the `label` to the current position of the current section. - //! - //! \note Attempt to bind the same label multiple times will return an error. - virtual Error bind(const Label& label) = 0; - - //! Tests whether the label `id` is valid (i.e. registered). - ASMJIT_API bool isLabelValid(uint32_t labelId) const noexcept; - //! Tests whether the `label` is valid (i.e. registered). - inline bool isLabelValid(const Label& label) const noexcept { return isLabelValid(label.id()); } - - //! \} - - //! \name Emit - //! \{ - - // NOTE: These `emit()` helpers are designed to address a code-bloat generated - // by C++ compilers to call a function having many arguments. Each parameter to - // `_emit()` requires some code to pass it, which means that if we default to - // 5 arguments in `_emit()` and instId the C++ compiler would have to generate - // a virtual function call having 5 parameters and additional `this` argument, - // which is quite a lot. Since by default most instructions have 2 to 3 operands - // it's better to introduce helpers that pass from 0 to 6 operands that help to - // reduce the size of emit(...) function call. - - //! Emits an instruction (internal). - ASMJIT_API Error _emitI(uint32_t instId); - //! \overload - ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0); - //! \overload - ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1); - //! \overload - ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2); - //! \overload - ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3); - //! \overload - ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4); - //! \overload - ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5); - - //! Emits an instruction `instId` with the given `operands`. - template - ASMJIT_INLINE Error emit(uint32_t instId, Args&&... operands) { - return _emitI(instId, Support::ForwardOp::forward(operands)...); - } - - inline Error emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount) { - return _emitOpArray(instId, operands, opCount); - } - - inline Error emitInst(const BaseInst& inst, const Operand_* operands, size_t opCount) { - setInstOptions(inst.options()); - setExtraReg(inst.extraReg()); - return _emitOpArray(inst.id(), operands, opCount); - } - - //! \cond INTERNAL - //! Emits an instruction - all 6 operands must be defined. - virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) = 0; - //! Emits instruction having operands stored in array. - ASMJIT_API virtual Error _emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount); - //! \endcond - - //! \} - - //! \name Emit Utilities - //! \{ - - ASMJIT_API Error emitProlog(const FuncFrame& frame); - ASMJIT_API Error emitEpilog(const FuncFrame& frame); - ASMJIT_API Error emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args); - - //! \} - - //! \name Align - //! \{ - - //! Aligns the current CodeBuffer position to the `alignment` specified. - //! - //! The sequence that is used to fill the gap between the aligned location - //! and the current location depends on the align `mode`, see \ref AlignMode. - virtual Error align(uint32_t alignMode, uint32_t alignment) = 0; - - //! \} - - //! \name Embed - //! \{ - - //! Embeds raw data into the \ref CodeBuffer. - virtual Error embed(const void* data, size_t dataSize) = 0; - - //! Embeds a typed data array. - //! - //! This is the most flexible function for embedding data as it allows to: - //! - Assign a `typeId` to the data, so the emitter knows the type of - //! items stored in `data`. Binary data should use \ref Type::kIdU8. - //! - Repeat the given data `repeatCount` times, so the data can be used - //! as a fill pattern for example, or as a pattern used by SIMD instructions. - virtual Error embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) = 0; - - //! Embeds int8_t `value` repeated by `repeatCount`. - inline Error embedInt8(int8_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI8, &value, 1, repeatCount); } - //! Embeds uint8_t `value` repeated by `repeatCount`. - inline Error embedUInt8(uint8_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU8, &value, 1, repeatCount); } - //! Embeds int16_t `value` repeated by `repeatCount`. - inline Error embedInt16(int16_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI16, &value, 1, repeatCount); } - //! Embeds uint16_t `value` repeated by `repeatCount`. - inline Error embedUInt16(uint16_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU16, &value, 1, repeatCount); } - //! Embeds int32_t `value` repeated by `repeatCount`. - inline Error embedInt32(int32_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI32, &value, 1, repeatCount); } - //! Embeds uint32_t `value` repeated by `repeatCount`. - inline Error embedUInt32(uint32_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU32, &value, 1, repeatCount); } - //! Embeds int64_t `value` repeated by `repeatCount`. - inline Error embedInt64(int64_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI64, &value, 1, repeatCount); } - //! Embeds uint64_t `value` repeated by `repeatCount`. - inline Error embedUInt64(uint64_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU64, &value, 1, repeatCount); } - //! Embeds a floating point `value` repeated by `repeatCount`. - inline Error embedFloat(float value, size_t repeatCount = 1) { return embedDataArray(Type::kIdF32, &value, 1, repeatCount); } - //! Embeds a floating point `value` repeated by `repeatCount`. - inline Error embedDouble(double value, size_t repeatCount = 1) { return embedDataArray(Type::IdOfT::kTypeId, &value, 1, repeatCount); } - - //! Embeds a constant pool at the current offset by performing the following: - //! 1. Aligns by using kAlignData to the minimum `pool` alignment. - //! 2. Binds the ConstPool label so it's bound to an aligned location. - //! 3. Emits ConstPool content. - virtual Error embedConstPool(const Label& label, const ConstPool& pool) = 0; - - //! Embeds an absolute `label` address as data. - //! - //! The `dataSize` is an optional argument that can be used to specify the - //! size of the address data. If it's zero (default) the address size is - //! deduced from the target architecture (either 4 or 8 bytes). - virtual Error embedLabel(const Label& label, size_t dataSize = 0) = 0; - - //! Embeds a delta (distance) between the `label` and `base` calculating it - //! as `label - base`. This function was designed to make it easier to embed - //! lookup tables where each index is a relative distance of two labels. - virtual Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) = 0; - - //! \} - - //! \name Comment - //! \{ - - //! Emits a comment stored in `data` with an optional `size` parameter. - virtual Error comment(const char* data, size_t size = SIZE_MAX) = 0; - - //! Emits a formatted comment specified by `fmt` and variable number of arguments. - ASMJIT_API Error commentf(const char* fmt, ...); - //! Emits a formatted comment specified by `fmt` and `ap`. - ASMJIT_API Error commentv(const char* fmt, va_list ap); - - //! \} - - //! \name Events - //! \{ - - //! Called after the emitter was attached to `CodeHolder`. - virtual Error onAttach(CodeHolder* code) noexcept = 0; - //! Called after the emitter was detached from `CodeHolder`. - virtual Error onDetach(CodeHolder* code) noexcept = 0; - - //! Called when \ref CodeHolder has updated an important setting, which - //! involves the following: - //! - //! - \ref Logger has been changed (\ref CodeHolder::setLogger() has been - //! called). - //! - \ref ErrorHandler has been changed (\ref CodeHolder::setErrorHandler() - //! has been called). - //! - //! This function ensures that the settings are properly propagated from - //! \ref CodeHolder to the emitter. - //! - //! \note This function is virtual and can be overridden, however, if you - //! do so, always call \ref BaseEmitter::onSettingsUpdated() within your - //! own implementation to ensure that the emitter is in a consisten state. - ASMJIT_API virtual void onSettingsUpdated() noexcept; - - //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use environment() instead") - inline CodeInfo codeInfo() const noexcept { - return CodeInfo(_environment, _code ? _code->baseAddress() : Globals::kNoBaseAddress); - } - - ASMJIT_DEPRECATED("Use arch() instead") - inline uint32_t archId() const noexcept { return arch(); } - - ASMJIT_DEPRECATED("Use registerSize() instead") - inline uint32_t gpSize() const noexcept { return registerSize(); } - - ASMJIT_DEPRECATED("Use encodingOptions() instead") - inline uint32_t emitterOptions() const noexcept { return encodingOptions(); } - - ASMJIT_DEPRECATED("Use addEncodingOptions() instead") - inline void addEmitterOptions(uint32_t options) noexcept { addEncodingOptions(options); } - - ASMJIT_DEPRECATED("Use clearEncodingOptions() instead") - inline void clearEmitterOptions(uint32_t options) noexcept { clearEncodingOptions(options); } - - ASMJIT_DEPRECATED("Use forcedInstOptions() instead") - inline uint32_t globalInstOptions() const noexcept { return forcedInstOptions(); } -#endif // !ASMJIT_NO_DEPRECATED -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_EMITTER_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitterutils.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitterutils.cpp deleted file mode 100644 index 1115934..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitterutils.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/assembler.h" -#include "../core/emitterutils_p.h" -#include "../core/formatter.h" -#include "../core/logger.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::EmitterUtils] -// ============================================================================ - -namespace EmitterUtils { - -#ifndef ASMJIT_NO_LOGGING - -Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept { - size_t currentSize = sb.size(); - size_t commentSize = comment ? Support::strLen(comment, Globals::kMaxCommentSize) : 0; - - ASMJIT_ASSERT(binSize >= dispSize); - const size_t kNoBinSize = SIZE_MAX; - - if ((binSize != 0 && binSize != kNoBinSize) || commentSize) { - size_t align = kMaxInstLineSize; - char sep = ';'; - - for (size_t i = (binSize == kNoBinSize); i < 2; i++) { - size_t begin = sb.size(); - ASMJIT_PROPAGATE(sb.padEnd(align)); - - if (sep) { - ASMJIT_PROPAGATE(sb.append(sep)); - ASMJIT_PROPAGATE(sb.append(' ')); - } - - // Append binary data or comment. - if (i == 0) { - ASMJIT_PROPAGATE(sb.appendHex(binData, binSize - dispSize - immSize)); - ASMJIT_PROPAGATE(sb.appendChars('.', dispSize * 2)); - ASMJIT_PROPAGATE(sb.appendHex(binData + binSize - immSize, immSize)); - if (commentSize == 0) break; - } - else { - ASMJIT_PROPAGATE(sb.append(comment, commentSize)); - } - - currentSize += sb.size() - begin; - align += kMaxBinarySize; - sep = '|'; - } - } - - return sb.append('\n'); -} - -void logLabelBound(BaseAssembler* self, const Label& label) noexcept { - Logger* logger = self->logger(); - - StringTmp<512> sb; - size_t binSize = logger->hasFlag(FormatOptions::kFlagMachineCode) ? size_t(0) : SIZE_MAX; - - sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationLabel)); - Formatter::formatLabel(sb, logger->flags(), self, label.id()); - sb.append(':'); - EmitterUtils::formatLine(sb, nullptr, binSize, 0, 0, self->_inlineComment); - logger->log(sb.data(), sb.size()); -} - -void logInstructionEmitted( - BaseAssembler* self, - uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt, - uint32_t relSize, uint32_t immSize, uint8_t* afterCursor) { - - Logger* logger = self->logger(); - ASMJIT_ASSERT(logger != nullptr); - - StringTmp<256> sb; - uint32_t flags = logger->flags(); - - uint8_t* beforeCursor = self->bufferPtr(); - intptr_t emittedSize = (intptr_t)(afterCursor - beforeCursor); - - Operand_ opArray[Globals::kMaxOpCount]; - EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt); - - sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationCode)); - Formatter::formatInstruction(sb, flags, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount); - - if ((flags & FormatOptions::kFlagMachineCode) != 0) - EmitterUtils::formatLine(sb, self->bufferPtr(), size_t(emittedSize), relSize, immSize, self->inlineComment()); - else - EmitterUtils::formatLine(sb, nullptr, SIZE_MAX, 0, 0, self->inlineComment()); - logger->log(sb); -} - -Error logInstructionFailed( - BaseAssembler* self, - Error err, - uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) { - - StringTmp<256> sb; - sb.append(DebugUtils::errorAsString(err)); - sb.append(": "); - - Operand_ opArray[Globals::kMaxOpCount]; - EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt); - - Formatter::formatInstruction(sb, 0, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount); - - if (self->inlineComment()) { - sb.append(" ; "); - sb.append(self->inlineComment()); - } - - self->resetInstOptions(); - self->resetExtraReg(); - self->resetInlineComment(); - return self->reportError(err, sb.data()); -} - -#endif - -} // {EmitterUtils} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitterutils_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitterutils_p.h deleted file mode 100644 index 7e222d3..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/emitterutils_p.h +++ /dev/null @@ -1,109 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED -#define ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED - -#include "../core/emitter.h" -#include "../core/operand.h" - -ASMJIT_BEGIN_NAMESPACE - -class BaseAssembler; - -//! \cond INTERNAL -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [asmjit::EmitterUtils] -// ============================================================================ - -namespace EmitterUtils { - -static const Operand_ noExt[3] {}; - -enum kOpIndex { - kOp3 = 0, - kOp4 = 1, - kOp5 = 2 -}; - -static ASMJIT_INLINE uint32_t opCountFromEmitArgs(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept { - uint32_t opCount = 0; - - if (opExt[kOp3].isNone()) { - if (!o0.isNone()) opCount = 1; - if (!o1.isNone()) opCount = 2; - if (!o2.isNone()) opCount = 3; - } - else { - opCount = 4; - if (!opExt[kOp4].isNone()) { - opCount = 5 + uint32_t(!opExt[kOp5].isNone()); - } - } - - return opCount; -} - -static ASMJIT_INLINE void opArrayFromEmitArgs(Operand_ dst[Globals::kMaxOpCount], const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept { - dst[0].copyFrom(o0); - dst[1].copyFrom(o1); - dst[2].copyFrom(o2); - dst[3].copyFrom(opExt[kOp3]); - dst[4].copyFrom(opExt[kOp4]); - dst[5].copyFrom(opExt[kOp5]); -} - -#ifndef ASMJIT_NO_LOGGING -enum : uint32_t { - // Has to be big to be able to hold all metadata compiler can assign to a - // single instruction. - kMaxInstLineSize = 44, - kMaxBinarySize = 26 -}; - -Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept; - -void logLabelBound(BaseAssembler* self, const Label& label) noexcept; - -void logInstructionEmitted( - BaseAssembler* self, - uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt, - uint32_t relSize, uint32_t immSize, uint8_t* afterCursor); - -Error logInstructionFailed( - BaseAssembler* self, - Error err, uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt); -#endif - -} - -//! \} -//! \endcond - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED - diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/environment.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/environment.cpp deleted file mode 100644 index 3be2b15..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/environment.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/environment.h" - -ASMJIT_BEGIN_NAMESPACE - -// X86 Target -// ---------- -// -// - 32-bit - Linux, OSX, BSD, and apparently also Haiku guarantee 16-byte -// stack alignment. Other operating systems are assumed to have -// 4-byte alignment by default for safety reasons. -// - 64-bit - stack must be aligned to 16 bytes. -// -// ARM Target -// ---------- -// -// - 32-bit - Stack must be aligned to 8 bytes. -// - 64-bit - Stack must be aligned to 16 bytes (hardware requirement). -uint32_t Environment::stackAlignment() const noexcept { - if (is64Bit()) { - // Assume 16-byte alignment on any 64-bit target. - return 16; - } - else { - // The following platforms use 16-byte alignment in 32-bit mode. - if (isPlatformLinux() || - isPlatformBSD() || - isPlatformApple() || - isPlatformHaiku()) { - return 16u; - } - - if (isFamilyARM()) - return 8; - - // Bail to 4-byte alignment if we don't know. - return 4; - } -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/environment.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/environment.h deleted file mode 100644 index 79e6f7c..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/environment.h +++ /dev/null @@ -1,612 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_ENVIRONMENT_H_INCLUDED -#define ASMJIT_CORE_ENVIRONMENT_H_INCLUDED - -#include "../core/globals.h" - -#if defined(__APPLE__) - #include -#endif - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [asmjit::Environment] -// ============================================================================ - -//! Represents an environment, which is usually related to a \ref Target. -//! -//! Environment has usually an 'arch-subarch-vendor-os-abi' format, which is -//! sometimes called "Triple" (historically it used to be 3 only parts) or -//! "Tuple", which is a convention used by Debian Linux. -//! -//! AsmJit doesn't support all possible combinations or architectures and ABIs, -//! however, it models the environment similarly to other compilers for future -//! extensibility. -class Environment { -public: - //! Architecture type, see \ref Arch. - uint8_t _arch; - //! Sub-architecture type, see \ref SubArch. - uint8_t _subArch; - //! Vendor type, see \ref Vendor. - uint8_t _vendor; - //! Platform type, see \ref Platform. - uint8_t _platform; - //! ABI type, see \ref Abi. - uint8_t _abi; - //! Object format, see \ref Format. - uint8_t _format; - //! Reserved for future use, must be zero. - uint16_t _reserved; - - //! Architecture. - enum Arch : uint32_t { - //! Unknown or uninitialized architecture. - kArchUnknown = 0, - - //! Mask used by 32-bit architectures (odd are 32-bit, even are 64-bit). - kArch32BitMask = 0x01, - //! Mask used by big-endian architectures. - kArchBigEndianMask = 0x80u, - - //! 32-bit X86 architecture. - kArchX86 = 1, - //! 64-bit X86 architecture also known as X86_64 and AMD64. - kArchX64 = 2, - - //! 32-bit RISC-V architecture. - kArchRISCV32 = 3, - //! 64-bit RISC-V architecture. - kArchRISCV64 = 4, - - //! 32-bit ARM architecture (little endian). - kArchARM = 5, - //! 32-bit ARM architecture (big endian). - kArchARM_BE = kArchARM | kArchBigEndianMask, - //! 64-bit ARM architecture in (little endian). - kArchAArch64 = 6, - //! 64-bit ARM architecture in (big endian). - kArchAArch64_BE = kArchAArch64 | kArchBigEndianMask, - //! 32-bit ARM in Thumb mode (little endian). - kArchThumb = 7, - //! 32-bit ARM in Thumb mode (big endian). - kArchThumb_BE = kArchThumb | kArchBigEndianMask, - - // 8 is not used, even numbers are 64-bit architectures. - - //! 32-bit MIPS architecture in (little endian). - kArchMIPS32_LE = 9, - //! 32-bit MIPS architecture in (big endian). - kArchMIPS32_BE = kArchMIPS32_LE | kArchBigEndianMask, - //! 64-bit MIPS architecture in (little endian). - kArchMIPS64_LE = 10, - //! 64-bit MIPS architecture in (big endian). - kArchMIPS64_BE = kArchMIPS64_LE | kArchBigEndianMask, - - //! Count of architectures. - kArchCount = 11 - }; - - //! Sub-architecture. - enum SubArch : uint32_t { - //! Unknown or uninitialized architecture sub-type. - kSubArchUnknown = 0, - - //! Count of sub-architectures. - kSubArchCount - }; - - //! Vendor. - //! - //! \note AsmJit doesn't use vendor information at the moment. It's provided - //! for future use, if required. - enum Vendor : uint32_t { - //! Unknown or uninitialized vendor. - kVendorUnknown = 0, - - //! Count of vendor identifiers. - kVendorCount - }; - - //! Platform / OS. - enum Platform : uint32_t { - //! Unknown or uninitialized platform. - kPlatformUnknown = 0, - - //! Windows OS. - kPlatformWindows, - - //! Other platform, most likely POSIX based. - kPlatformOther, - - //! Linux OS. - kPlatformLinux, - //! GNU/Hurd OS. - kPlatformHurd, - - //! FreeBSD OS. - kPlatformFreeBSD, - //! OpenBSD OS. - kPlatformOpenBSD, - //! NetBSD OS. - kPlatformNetBSD, - //! DragonFly BSD OS. - kPlatformDragonFlyBSD, - - //! Haiku OS. - kPlatformHaiku, - - //! Apple OSX. - kPlatformOSX, - //! Apple iOS. - kPlatformIOS, - //! Apple TVOS. - kPlatformTVOS, - //! Apple WatchOS. - kPlatformWatchOS, - - //! Emscripten platform. - kPlatformEmscripten, - - //! Count of platform identifiers. - kPlatformCount - }; - - //! ABI. - enum Abi : uint32_t { - //! Unknown or uninitialied environment. - kAbiUnknown = 0, - //! Microsoft ABI. - kAbiMSVC, - //! GNU ABI. - kAbiGNU, - //! Android Environment / ABI. - kAbiAndroid, - //! Cygwin ABI. - kAbiCygwin, - - //! Count of known ABI types. - kAbiCount - }; - - //! Object format. - //! - //! \note AsmJit doesn't really use anything except \ref kFormatUnknown and - //! \ref kFormatJIT at the moment. Object file formats are provided for - //! future extensibility and a possibility to generate object files at some - //! point. - enum Format : uint32_t { - //! Unknown or uninitialized object format. - kFormatUnknown = 0, - - //! JIT code generation object, most likely \ref JitRuntime or a custom - //! \ref Target implementation. - kFormatJIT, - - //! Executable and linkable format (ELF). - kFormatELF, - //! Common object file format. - kFormatCOFF, - //! Extended COFF object format. - kFormatXCOFF, - //! Mach object file format. - kFormatMachO, - - //! Count of object format types. - kFormatCount - }; - - //! \name Environment Detection - //! \{ - -#ifdef _DOXYGEN - //! Architecture detected at compile-time (architecture of the host). - static constexpr Arch kArchHost = DETECTED_AT_COMPILE_TIME; - //! Sub-architecture detected at compile-time (sub-architecture of the host). - static constexpr SubArch kSubArchHost = DETECTED_AT_COMPILE_TIME; - //! Vendor detected at compile-time (vendor of the host). - static constexpr Vendor kVendorHost = DETECTED_AT_COMPILE_TIME; - //! Platform detected at compile-time (platform of the host). - static constexpr Platform kPlatformHost = DETECTED_AT_COMPILE_TIME; - //! ABI detected at compile-time (ABI of the host). - static constexpr Abi kAbiHost = DETECTED_AT_COMPILE_TIME; -#else - static constexpr Arch kArchHost = - ASMJIT_ARCH_X86 == 32 ? kArchX86 : - ASMJIT_ARCH_X86 == 64 ? kArchX64 : - - ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kArchARM : - ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kArchARM_BE : - ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kArchAArch64 : - ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_BE ? kArchAArch64_BE : - - ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_LE ? kArchMIPS32_LE : - ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_BE ? kArchMIPS32_BE : - ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_LE ? kArchMIPS64_LE : - ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_BE ? kArchMIPS64_BE : - - kArchUnknown; - - static constexpr SubArch kSubArchHost = - kSubArchUnknown; - - static constexpr Vendor kVendorHost = - kVendorUnknown; - - static constexpr Platform kPlatformHost = -#if defined(__EMSCRIPTEN__) - kPlatformEmscripten -#elif defined(_WIN32) - kPlatformWindows -#elif defined(__linux__) - kPlatformLinux -#elif defined(__gnu_hurd__) - kPlatformHurd -#elif defined(__FreeBSD__) - kPlatformFreeBSD -#elif defined(__OpenBSD__) - kPlatformOpenBSD -#elif defined(__NetBSD__) - kPlatformNetBSD -#elif defined(__DragonFly__) - kPlatformDragonFlyBSD -#elif defined(__HAIKU__) - kPlatformHaiku -#elif defined(__APPLE__) && TARGET_OS_OSX - kPlatformOSX -#elif defined(__APPLE__) && TARGET_OS_TV - kPlatformTVOS -#elif defined(__APPLE__) && TARGET_OS_WATCH - kPlatformWatchOS -#elif defined(__APPLE__) && TARGET_OS_IPHONE - kPlatformIOS -#else - kPlatformOther -#endif - ; - - static constexpr Abi kAbiHost = -#if defined(_MSC_VER) - kAbiMSVC -#elif defined(__CYGWIN__) - kAbiCygwin -#elif defined(__MINGW32__) || defined(__GLIBC__) - kAbiGNU -#elif defined(__ANDROID__) - kAbiAndroid -#else - kAbiUnknown -#endif - ; - -#endif - - //! \} - - //! \name Construction / Destruction - //! \{ - - inline Environment() noexcept : - _arch(uint8_t(kArchUnknown)), - _subArch(uint8_t(kSubArchUnknown)), - _vendor(uint8_t(kVendorUnknown)), - _platform(uint8_t(kPlatformUnknown)), - _abi(uint8_t(kAbiUnknown)), - _format(uint8_t(kFormatUnknown)), - _reserved(0) {} - - inline Environment(const Environment& other) noexcept = default; - - inline explicit Environment(uint32_t arch, - uint32_t subArch = kSubArchUnknown, - uint32_t vendor = kVendorUnknown, - uint32_t platform = kPlatformUnknown, - uint32_t abi = kAbiUnknown, - uint32_t format = kFormatUnknown) noexcept { - init(arch, subArch, vendor, platform, abi, format); - } - - //! \} - - //! \name Overloaded Operators - //! \{ - - inline Environment& operator=(const Environment& other) noexcept = default; - - inline bool operator==(const Environment& other) const noexcept { return equals(other); } - inline bool operator!=(const Environment& other) const noexcept { return !equals(other); } - - //! \} - - //! \name Accessors - //! \{ - - //! Tests whether the environment is not set up. - //! - //! Returns true if all members are zero, and thus unknown. - inline bool empty() const noexcept { - // Unfortunately compilers won't optimize fields are checked one by one... - return _packed() == 0; - } - - //! Tests whether the environment is intialized, which means it must have - //! a valid architecture. - inline bool isInitialized() const noexcept { - return _arch != kArchUnknown; - } - - inline uint64_t _packed() const noexcept { - uint64_t x; - memcpy(&x, this, 8); - return x; - } - - //! Resets all members of the environment to zero / unknown. - inline void reset() noexcept { - _arch = uint8_t(kArchUnknown); - _subArch = uint8_t(kSubArchUnknown); - _vendor = uint8_t(kVendorUnknown); - _platform = uint8_t(kPlatformUnknown); - _abi = uint8_t(kAbiUnknown); - _format = uint8_t(kFormatUnknown); - _reserved = 0; - } - - inline bool equals(const Environment& other) const noexcept { - return _packed() == other._packed(); - } - - //! Returns the architecture, see \ref Arch. - inline uint32_t arch() const noexcept { return _arch; } - //! Returns the sub-architecture, see \ref SubArch. - inline uint32_t subArch() const noexcept { return _subArch; } - //! Returns vendor, see \ref Vendor. - inline uint32_t vendor() const noexcept { return _vendor; } - //! Returns target's platform or operating system, see \ref Platform. - inline uint32_t platform() const noexcept { return _platform; } - //! Returns target's ABI, see \ref Abi. - inline uint32_t abi() const noexcept { return _abi; } - //! Returns target's object format, see \ref Format. - inline uint32_t format() const noexcept { return _format; } - - inline void init(uint32_t arch, - uint32_t subArch = kSubArchUnknown, - uint32_t vendor = kVendorUnknown, - uint32_t platform = kPlatformUnknown, - uint32_t abi = kAbiUnknown, - uint32_t format = kFormatUnknown) noexcept { - _arch = uint8_t(arch); - _subArch = uint8_t(subArch); - _vendor = uint8_t(vendor); - _platform = uint8_t(platform); - _abi = uint8_t(abi); - _format = uint8_t(format); - _reserved = 0; - } - - inline bool isArchX86() const noexcept { return _arch == kArchX86; } - inline bool isArchX64() const noexcept { return _arch == kArchX64; } - inline bool isArchRISCV32() const noexcept { return _arch == kArchRISCV32; } - inline bool isArchRISCV64() const noexcept { return _arch == kArchRISCV64; } - inline bool isArchARM() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchARM; } - inline bool isArchThumb() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchThumb; } - inline bool isArchAArch64() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchAArch64; } - inline bool isArchMIPS32() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchMIPS32_LE; } - inline bool isArchMIPS64() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchMIPS64_LE; } - - //! Tests whether the architecture is 32-bit. - inline bool is32Bit() const noexcept { return is32Bit(_arch); } - //! Tests whether the architecture is 64-bit. - inline bool is64Bit() const noexcept { return is64Bit(_arch); } - - //! Tests whether the architecture is little endian. - inline bool isLittleEndian() const noexcept { return isLittleEndian(_arch); } - //! Tests whether the architecture is big endian. - inline bool isBigEndian() const noexcept { return isBigEndian(_arch); } - - //! Tests whether this architecture is of X86 family. - inline bool isFamilyX86() const noexcept { return isFamilyX86(_arch); } - //! Tests whether this architecture family is RISC-V (both 32-bit and 64-bit). - inline bool isFamilyRISCV() const noexcept { return isFamilyRISCV(_arch); } - //! Tests whether this architecture family is ARM, Thumb, or AArch64. - inline bool isFamilyARM() const noexcept { return isFamilyARM(_arch); } - //! Tests whether this architecture family is MISP or MIPS64. - inline bool isFamilyMIPS() const noexcept { return isFamilyMIPS(_arch); } - - //! Tests whether the environment platform is Windows. - inline bool isPlatformWindows() const noexcept { return _platform == kPlatformWindows; } - - //! Tests whether the environment platform is Linux. - inline bool isPlatformLinux() const noexcept { return _platform == kPlatformLinux; } - - //! Tests whether the environment platform is Hurd. - inline bool isPlatformHurd() const noexcept { return _platform == kPlatformHurd; } - - //! Tests whether the environment platform is Haiku. - inline bool isPlatformHaiku() const noexcept { return _platform == kPlatformHaiku; } - - //! Tests whether the environment platform is any BSD. - inline bool isPlatformBSD() const noexcept { - return _platform == kPlatformFreeBSD || - _platform == kPlatformOpenBSD || - _platform == kPlatformNetBSD || - _platform == kPlatformDragonFlyBSD; - } - - //! Tests whether the environment platform is any Apple platform (OSX, iOS, TVOS, WatchOS). - inline bool isPlatformApple() const noexcept { - return _platform == kPlatformOSX || - _platform == kPlatformIOS || - _platform == kPlatformTVOS || - _platform == kPlatformWatchOS; - } - - //! Tests whether the ABI is MSVC. - inline bool isAbiMSVC() const noexcept { return _abi == kAbiMSVC; } - //! Tests whether the ABI is GNU. - inline bool isAbiGNU() const noexcept { return _abi == kAbiGNU; } - - //! Returns a calculated stack alignment for this environment. - ASMJIT_API uint32_t stackAlignment() const noexcept; - - //! Returns a native register size of this architecture. - uint32_t registerSize() const noexcept { return registerSizeFromArch(_arch); } - - //! Sets the architecture to `arch`. - inline void setArch(uint32_t arch) noexcept { _arch = uint8_t(arch); } - //! Sets the sub-architecture to `subArch`. - inline void setSubArch(uint32_t subArch) noexcept { _subArch = uint8_t(subArch); } - //! Sets the vendor to `vendor`. - inline void setVendor(uint32_t vendor) noexcept { _vendor = uint8_t(vendor); } - //! Sets the platform to `platform`. - inline void setPlatform(uint32_t platform) noexcept { _platform = uint8_t(platform); } - //! Sets the ABI to `abi`. - inline void setAbi(uint32_t abi) noexcept { _abi = uint8_t(abi); } - //! Sets the object format to `format`. - inline void setFormat(uint32_t format) noexcept { _format = uint8_t(format); } - - //! \} - - //! \name Static Utilities - //! \{ - - static inline bool isValidArch(uint32_t arch) noexcept { - return (arch & ~kArchBigEndianMask) != 0 && - (arch & ~kArchBigEndianMask) < kArchCount; - } - - //! Tests whether the given architecture `arch` is 32-bit. - static inline bool is32Bit(uint32_t arch) noexcept { - return (arch & kArch32BitMask) == kArch32BitMask; - } - - //! Tests whether the given architecture `arch` is 64-bit. - static inline bool is64Bit(uint32_t arch) noexcept { - return (arch & kArch32BitMask) == 0; - } - - //! Tests whether the given architecture `arch` is little endian. - static inline bool isLittleEndian(uint32_t arch) noexcept { - return (arch & kArchBigEndianMask) == 0; - } - - //! Tests whether the given architecture `arch` is big endian. - static inline bool isBigEndian(uint32_t arch) noexcept { - return (arch & kArchBigEndianMask) == kArchBigEndianMask; - } - - //! Tests whether the given architecture is AArch64. - static inline bool isArchAArch64(uint32_t arch) noexcept { - arch &= ~kArchBigEndianMask; - return arch == kArchAArch64; - } - - //! Tests whether the given architecture family is X86 or X64. - static inline bool isFamilyX86(uint32_t arch) noexcept { - return arch == kArchX86 || - arch == kArchX64; - } - - //! Tests whether the given architecture family is RISC-V (both 32-bit and 64-bit). - static inline bool isFamilyRISCV(uint32_t arch) noexcept { - return arch == kArchRISCV32 || - arch == kArchRISCV64; - } - - //! Tests whether the given architecture family is ARM, Thumb, or AArch64. - static inline bool isFamilyARM(uint32_t arch) noexcept { - arch &= ~kArchBigEndianMask; - return arch == kArchARM || - arch == kArchAArch64 || - arch == kArchThumb; - } - - //! Tests whether the given architecture family is MISP or MIPS64. - static inline bool isFamilyMIPS(uint32_t arch) noexcept { - arch &= ~kArchBigEndianMask; - return arch == kArchMIPS32_LE || - arch == kArchMIPS64_LE; - } - - //! Returns a native general purpose register size from the given architecture. - static uint32_t registerSizeFromArch(uint32_t arch) noexcept { - return is32Bit(arch) ? 4u : 8u; - } - - //! \} -}; - -//! Returns the host environment constructed from preprocessor macros defined -//! by the compiler. -//! -//! The returned environment should precisely match the target host architecture, -//! sub-architecture, platform, and ABI. -static ASMJIT_INLINE Environment hostEnvironment() noexcept { - return Environment(Environment::kArchHost, - Environment::kSubArchHost, - Environment::kVendorHost, - Environment::kPlatformHost, - Environment::kAbiHost, - Environment::kFormatUnknown); -} - -static_assert(sizeof(Environment) == 8, - "Environment must occupy exactly 8 bytes."); - -//! \} - -#ifndef ASMJIT_NO_DEPRECATED -class ASMJIT_DEPRECATED_STRUCT("Use Environment instead") ArchInfo : public Environment { -public: - inline ArchInfo() noexcept : Environment() {} - - inline ArchInfo(const Environment& other) noexcept : Environment(other) {} - inline explicit ArchInfo(uint32_t arch, uint32_t subArch = kSubArchUnknown) noexcept - : Environment(arch, subArch) {} - - enum Id : uint32_t { - kIdNone = Environment::kArchUnknown, - kIdX86 = Environment::kArchX86, - kIdX64 = Environment::kArchX64, - kIdA32 = Environment::kArchARM, - kIdA64 = Environment::kArchAArch64, - kIdHost = Environment::kArchHost - }; - - enum SubType : uint32_t { - kSubIdNone = Environment::kSubArchUnknown - }; - - static inline ArchInfo host() noexcept { return ArchInfo(hostEnvironment()); } -}; -#endif // !ASMJIT_NO_DEPRECATED - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_ENVIRONMENT_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/errorhandler.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/errorhandler.cpp deleted file mode 100644 index 8372d75..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/errorhandler.cpp +++ /dev/null @@ -1,37 +0,0 @@ - -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/errorhandler.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::ErrorHandler] -// ============================================================================ - -ErrorHandler::ErrorHandler() noexcept {} -ErrorHandler::~ErrorHandler() noexcept {} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/errorhandler.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/errorhandler.h deleted file mode 100644 index 2337cd8..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/errorhandler.h +++ /dev/null @@ -1,267 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_ERRORHANDLER_H_INCLUDED -#define ASMJIT_CORE_ERRORHANDLER_H_INCLUDED - -#include "../core/globals.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_error_handling -//! \{ - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -class BaseEmitter; - -// ============================================================================ -// [asmjit::ErrorHandler] -// ============================================================================ - -//! Error handler can be used to override the default behavior of error handling. -//! -//! It's available to all classes that inherit `BaseEmitter`. Override -//! \ref ErrorHandler::handleError() to implement your own error handler. -//! -//! The following use-cases are supported: -//! -//! - Record the error and continue code generation. This is the simplest -//! approach that can be used to at least log possible errors. -//! - Throw an exception. AsmJit doesn't use exceptions and is completely -//! exception-safe, but it's perfectly legal to throw an exception from -//! the error handler. -//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler, -//! Builder and Compiler to a consistent state before calling \ref handleError(), -//! so `longjmp()` can be used without issues to cancel the code-generation if -//! an error occurred. This method can be used if exception handling in your -//! project is turned off and you still want some comfort. In most cases it -//! should be safe as AsmJit uses \ref Zone memory and the ownership of memory -//! it allocates always ends with the instance that allocated it. If using this -//! approach please never jump outside the life-time of \ref CodeHolder and -//! \ref BaseEmitter. -//! -//! \ref ErrorHandler can be attached to \ref CodeHolder or \ref BaseEmitter, -//! which has a priority. The example below uses error handler that just prints -//! the error, but lets AsmJit continue: -//! -//! ``` -//! // Error Handling #1 - Logging and returing Error. -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! // Error handler that just prints the error and lets AsmJit ignore it. -//! class SimpleErrorHandler : public ErrorHandler { -//! public: -//! Error err; -//! -//! inline SimpleErrorHandler() : err(kErrorOk) {} -//! -//! void handleError(Error err, const char* message, BaseEmitter* origin) override { -//! this->err = err; -//! fprintf(stderr, "ERROR: %s\n", message); -//! } -//! }; -//! -//! int main() { -//! JitRuntime rt; -//! SimpleErrorHandler eh; -//! -//! CodeHolder code; -//! code.init(rt.environment()); -//! code.setErrorHandler(&eh); -//! -//! // Try to emit instruction that doesn't exist. -//! x86::Assembler a(&code); -//! a.emit(x86::Inst::kIdMov, x86::xmm0, x86::xmm1); -//! -//! if (eh.err) { -//! // Assembler failed! -//! return 1; -//! } -//! -//! return 0; -//! } -//! ``` -//! -//! If error happens during instruction emitting / encoding the assembler behaves -//! transactionally - the output buffer won't advance if encoding failed, thus -//! either a fully encoded instruction or nothing is emitted. The error handling -//! shown above is useful, but it's still not the best way of dealing with errors -//! in AsmJit. The following example shows how to use exception handling to handle -//! errors in a more C++ way: -//! -//! ``` -//! // Error Handling #2 - Throwing an exception. -//! #include -//! #include -//! #include -//! #include -//! -//! using namespace asmjit; -//! -//! // Error handler that throws a user-defined `AsmJitException`. -//! class AsmJitException : public std::exception { -//! public: -//! Error err; -//! std::string message; -//! -//! AsmJitException(Error err, const char* message) noexcept -//! : err(err), -//! message(message) {} -//! -//! const char* what() const noexcept override { return message.c_str(); } -//! }; -//! -//! class ThrowableErrorHandler : public ErrorHandler { -//! public: -//! // Throw is possible, functions that use ErrorHandler are never 'noexcept'. -//! void handleError(Error err, const char* message, BaseEmitter* origin) override { -//! throw AsmJitException(err, message); -//! } -//! }; -//! -//! int main() { -//! JitRuntime rt; -//! ThrowableErrorHandler eh; -//! -//! CodeHolder code; -//! code.init(rt.environment()); -//! code.setErrorHandler(&eh); -//! -//! x86::Assembler a(&code); -//! -//! // Try to emit instruction that doesn't exist. -//! try { -//! a.emit(x86::Inst::kIdMov, x86::xmm0, x86::xmm1); -//! } -//! catch (const AsmJitException& ex) { -//! printf("EXCEPTION THROWN: %s\n", ex.what()); -//! return 1; -//! } -//! -//! return 0; -//! } -//! ``` -//! -//! If C++ exceptions are not what you like or your project turns off them -//! completely there is still a way of reducing the error handling to a minimum -//! by using a standard setjmp/longjmp approach. AsmJit is exception-safe and -//! cleans up everything before calling the ErrorHandler, so any approach is -//! safe. You can simply jump from the error handler without causing any -//! side-effects or memory leaks. The following example demonstrates how it -//! could be done: -//! -//! ``` -//! // Error Handling #3 - Using setjmp/longjmp if exceptions are not allowed. -//! #include -//! #include -//! #include -//! -//! class LongJmpErrorHandler : public asmjit::ErrorHandler { -//! public: -//! inline LongJmpErrorHandler() : err(asmjit::kErrorOk) {} -//! -//! void handleError(asmjit::Error err, const char* message, asmjit::BaseEmitter* origin) override { -//! this->err = err; -//! longjmp(state, 1); -//! } -//! -//! jmp_buf state; -//! asmjit::Error err; -//! }; -//! -//! int main(int argc, char* argv[]) { -//! using namespace asmjit; -//! -//! JitRuntime rt; -//! LongJmpErrorHandler eh; -//! -//! CodeHolder code; -//! code.init(rt.rt.environment()); -//! code.setErrorHandler(&eh); -//! -//! x86::Assembler a(&code); -//! -//! if (!setjmp(eh.state)) { -//! // Try to emit instruction that doesn't exist. -//! a.emit(x86::Inst::kIdMov, x86::xmm0, x86::xmm1); -//! } -//! else { -//! Error err = eh.err; -//! printf("ASMJIT ERROR: 0x%08X [%s]\n", err, DebugUtils::errorAsString(err)); -//! } -//! -//! return 0; -//! } -//! ``` -class ASMJIT_VIRTAPI ErrorHandler { -public: - ASMJIT_BASE_CLASS(ErrorHandler) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Creates a new `ErrorHandler` instance. - ASMJIT_API ErrorHandler() noexcept; - //! Destroys the `ErrorHandler` instance. - ASMJIT_API virtual ~ErrorHandler() noexcept; - - // -------------------------------------------------------------------------- - // [Handle Error] - // -------------------------------------------------------------------------- - - //! Error handler (must be reimplemented). - //! - //! Error handler is called after an error happened and before it's propagated - //! to the caller. There are multiple ways how the error handler can be used: - //! - //! 1. User-based error handling without throwing exception or using C's - //! `longjmp()`. This is for users that don't use exceptions and want - //! customized error handling. - //! - //! 2. Throwing an exception. AsmJit doesn't use exceptions and is completely - //! exception-safe, but you can throw exception from your error handler if - //! this way is the preferred way of handling errors in your project. - //! - //! 3. Using plain old C's `setjmp()` and `longjmp()`. Asmjit always puts - //! `BaseEmitter` to a consistent state before calling `handleError()` - //! so `longjmp()` can be used without any issues to cancel the code - //! generation if an error occurred. There is no difference between - //! exceptions and `longjmp()` from AsmJit's perspective, however, - //! never jump outside of `CodeHolder` and `BaseEmitter` scope as you - //! would leak memory. - virtual void handleError(Error err, const char* message, BaseEmitter* origin) = 0; -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_ERRORHANDLER_H_INCLUDED - diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/features.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/features.h deleted file mode 100644 index 0f2cfe2..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/features.h +++ /dev/null @@ -1,186 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_FEATURES_H_INCLUDED -#define ASMJIT_CORE_FEATURES_H_INCLUDED - -#include "../core/globals.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [asmjit::BaseFeatures] -// ============================================================================ - -//! Base class that provides information about CPU features. -//! -//! Internally each feature is represented by a single bit in an embedded -//! bit-array, however, feature bits are defined by an architecture specific -//! implementations, like \ref x86::Features. -class BaseFeatures { -public: - typedef Support::BitWord BitWord; - typedef Support::BitVectorIterator Iterator; - - enum : uint32_t { - kMaxFeatures = 256, - kNumBitWords = kMaxFeatures / Support::kBitWordSizeInBits - }; - - BitWord _bits[kNumBitWords]; - - //! \name Construction & Destruction - //! \{ - - inline BaseFeatures() noexcept { reset(); } - inline BaseFeatures(const BaseFeatures& other) noexcept = default; - inline explicit BaseFeatures(Globals::NoInit_) noexcept {} - - inline void reset() noexcept { - for (size_t i = 0; i < kNumBitWords; i++) - _bits[i] = 0; - } - - //! \} - - //! \name Overloaded Operators - //! \{ - - inline BaseFeatures& operator=(const BaseFeatures& other) noexcept = default; - - inline bool operator==(const BaseFeatures& other) noexcept { return eq(other); } - inline bool operator!=(const BaseFeatures& other) noexcept { return !eq(other); } - - //! \} - - //! \name Cast - //! \{ - - //! Casts this base class into a derived type `T`. - template - inline T& as() noexcept { return static_cast(*this); } - - //! Casts this base class into a derived type `T` (const). - template - inline const T& as() const noexcept { return static_cast(*this); } - - //! \} - - //! \name Accessors - //! \{ - - inline bool empty() const noexcept { - for (uint32_t i = 0; i < kNumBitWords; i++) - if (_bits[i]) - return false; - return true; - } - - //! Returns all features as array of bitwords (see \ref Support::BitWord). - inline BitWord* bits() noexcept { return _bits; } - //! Returns all features as array of bitwords (const). - inline const BitWord* bits() const noexcept { return _bits; } - - //! Returns the number of BitWords returned by \ref bits(). - inline size_t bitWordCount() const noexcept { return kNumBitWords; } - - //! Returns \ref Support::BitVectorIterator, that can be used to iterate - //! all features efficiently - inline Iterator iterator() const noexcept { - return Iterator(_bits, kNumBitWords); - } - - //! Tests whether the feature `featureId` is present. - inline bool has(uint32_t featureId) const noexcept { - ASMJIT_ASSERT(featureId < kMaxFeatures); - - uint32_t idx = featureId / Support::kBitWordSizeInBits; - uint32_t bit = featureId % Support::kBitWordSizeInBits; - - return bool((_bits[idx] >> bit) & 0x1); - } - - //! Tests whether all features as defined by `other` are present. - inline bool hasAll(const BaseFeatures& other) const noexcept { - for (uint32_t i = 0; i < kNumBitWords; i++) - if ((_bits[i] & other._bits[i]) != other._bits[i]) - return false; - return true; - } - - //! \} - - //! \name Utilities - //! \{ - - //! Adds the given CPU `featureId` to the list of features. - inline void add(uint32_t featureId) noexcept { - ASMJIT_ASSERT(featureId < kMaxFeatures); - - uint32_t idx = featureId / Support::kBitWordSizeInBits; - uint32_t bit = featureId % Support::kBitWordSizeInBits; - - _bits[idx] |= BitWord(1) << bit; - } - - template - inline void add(uint32_t featureId, Args... otherIds) noexcept { - add(featureId); - add(otherIds...); - } - - //! Removes the given CPU `featureId` from the list of features. - inline void remove(uint32_t featureId) noexcept { - ASMJIT_ASSERT(featureId < kMaxFeatures); - - uint32_t idx = featureId / Support::kBitWordSizeInBits; - uint32_t bit = featureId % Support::kBitWordSizeInBits; - - _bits[idx] &= ~(BitWord(1) << bit); - } - - template - inline void remove(uint32_t featureId, Args... otherIds) noexcept { - remove(featureId); - remove(otherIds...); - } - - inline bool eq(const BaseFeatures& other) const noexcept { - for (size_t i = 0; i < kNumBitWords; i++) - if (_bits[i] != other._bits[i]) - return false; - return true; - } - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_FEATURES_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/formatter.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/formatter.cpp deleted file mode 100644 index 89c3228..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/formatter.cpp +++ /dev/null @@ -1,481 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#ifndef ASMJIT_NO_LOGGING - -#include "../core/builder.h" -#include "../core/codeholder.h" -#include "../core/compiler.h" -#include "../core/emitter.h" -#include "../core/formatter.h" -#include "../core/string.h" -#include "../core/support.h" -#include "../core/type.h" - -#ifdef ASMJIT_BUILD_X86 - #include "../x86/x86formatter_p.h" -#endif - -#ifdef ASMJIT_BUILD_ARM - #include "../arm/armformatter_p.h" -#endif - -ASMJIT_BEGIN_NAMESPACE - -#if defined(ASMJIT_NO_COMPILER) -class VirtReg; -#endif - -// ============================================================================ -// [asmjit::Formatter] -// ============================================================================ - -namespace Formatter { - -Error formatTypeId(String& sb, uint32_t typeId) noexcept { - if (typeId == Type::kIdVoid) - return sb.append("void"); - - if (!Type::isValid(typeId)) - return sb.append("unknown"); - - const char* typeName = "unknown"; - uint32_t typeSize = Type::sizeOf(typeId); - - uint32_t baseId = Type::baseOf(typeId); - switch (baseId) { - case Type::kIdIntPtr : typeName = "iptr" ; break; - case Type::kIdUIntPtr: typeName = "uptr" ; break; - case Type::kIdI8 : typeName = "i8" ; break; - case Type::kIdU8 : typeName = "u8" ; break; - case Type::kIdI16 : typeName = "i16" ; break; - case Type::kIdU16 : typeName = "u16" ; break; - case Type::kIdI32 : typeName = "i32" ; break; - case Type::kIdU32 : typeName = "u32" ; break; - case Type::kIdI64 : typeName = "i64" ; break; - case Type::kIdU64 : typeName = "u64" ; break; - case Type::kIdF32 : typeName = "f32" ; break; - case Type::kIdF64 : typeName = "f64" ; break; - case Type::kIdF80 : typeName = "f80" ; break; - case Type::kIdMask8 : typeName = "mask8" ; break; - case Type::kIdMask16 : typeName = "mask16"; break; - case Type::kIdMask32 : typeName = "mask32"; break; - case Type::kIdMask64 : typeName = "mask64"; break; - case Type::kIdMmx32 : typeName = "mmx32" ; break; - case Type::kIdMmx64 : typeName = "mmx64" ; break; - } - - uint32_t baseSize = Type::sizeOf(baseId); - if (typeSize > baseSize) { - uint32_t count = typeSize / baseSize; - return sb.appendFormat("%sx%u", typeName, unsigned(count)); - } - else { - return sb.append(typeName); - } -} - -Error formatFeature( - String& sb, - uint32_t arch, - uint32_t featureId) noexcept { - -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::FormatterInternal::formatFeature(sb, featureId); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isFamilyARM(arch)) - return arm::FormatterInternal::formatFeature(sb, featureId); -#endif - - return kErrorInvalidArch; -} - -Error formatLabel( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - uint32_t labelId) noexcept { - - DebugUtils::unused(formatFlags); - - const LabelEntry* le = emitter->code()->labelEntry(labelId); - if (ASMJIT_UNLIKELY(!le)) - return sb.appendFormat("", labelId); - - if (le->hasName()) { - if (le->hasParent()) { - uint32_t parentId = le->parentId(); - const LabelEntry* pe = emitter->code()->labelEntry(parentId); - - if (ASMJIT_UNLIKELY(!pe)) - ASMJIT_PROPAGATE(sb.appendFormat("", labelId)); - else if (ASMJIT_UNLIKELY(!pe->hasName())) - ASMJIT_PROPAGATE(sb.appendFormat("L%u", parentId)); - else - ASMJIT_PROPAGATE(sb.append(pe->name())); - - ASMJIT_PROPAGATE(sb.append('.')); - } - return sb.append(le->name()); - } - else { - return sb.appendFormat("L%u", labelId); - } -} - -Error formatRegister( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - uint32_t arch, - uint32_t regType, - uint32_t regId) noexcept { - -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isFamilyARM(arch)) - return arm::FormatterInternal::formatRegister(sb, formatFlags, emitter, arch, regType, regId); -#endif - - return kErrorInvalidArch; -} - -Error formatOperand( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - uint32_t arch, - const Operand_& op) noexcept { - -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isFamilyARM(arch)) - return arm::FormatterInternal::formatOperand(sb, formatFlags, emitter, arch, op); -#endif - - return kErrorInvalidArch; -} - -Error formatInstruction( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - uint32_t arch, - const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept { - -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::FormatterInternal::formatInstruction(sb, formatFlags, emitter, arch, inst, operands, opCount); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isFamilyARM(arch)) - return arm::FormatterInternal::formatInstruction(sb, formatFlags, emitter, arch, inst, operands, opCount); -#endif - - return kErrorInvalidArch; -} - -#ifndef ASMJIT_NO_BUILDER - -#ifndef ASMJIT_NO_COMPILER -static Error formatFuncValue(String& sb, uint32_t formatFlags, const BaseEmitter* emitter, FuncValue value) noexcept { - uint32_t typeId = value.typeId(); - ASMJIT_PROPAGATE(formatTypeId(sb, typeId)); - - if (value.isAssigned()) { - ASMJIT_PROPAGATE(sb.append('@')); - - if (value.isIndirect()) - ASMJIT_PROPAGATE(sb.append('[')); - - // NOTE: It should be either reg or stack, but never both. We - // use two IFs on purpose so if the FuncValue is both it would - // show in logs. - if (value.isReg()) { - ASMJIT_PROPAGATE(formatRegister(sb, formatFlags, emitter, emitter->arch(), value.regType(), value.regId())); - } - - if (value.isStack()) { - ASMJIT_PROPAGATE(sb.appendFormat("[%d]", int(value.stackOffset()))); - } - - if (value.isIndirect()) - ASMJIT_PROPAGATE(sb.append(']')); - } - - return kErrorOk; -} - -static Error formatFuncValuePack( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - const FuncValuePack& pack, - VirtReg* const* vRegs) noexcept { - - size_t count = pack.count(); - if (!count) - return sb.append("void"); - - if (count > 1) - sb.append('['); - - for (uint32_t valueIndex = 0; valueIndex < count; valueIndex++) { - const FuncValue& value = pack[valueIndex]; - if (!value) - break; - - if (valueIndex) - ASMJIT_PROPAGATE(sb.append(", ")); - - ASMJIT_PROPAGATE(formatFuncValue(sb, formatFlags, emitter, value)); - - if (vRegs) { - static const char nullRet[] = ""; - ASMJIT_PROPAGATE(sb.appendFormat(" %s", vRegs[valueIndex] ? vRegs[valueIndex]->name() : nullRet)); - } - } - - if (count > 1) - sb.append(']'); - - return kErrorOk; -} - -static Error formatFuncRets( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - const FuncDetail& fd) noexcept { - - return formatFuncValuePack(sb, formatFlags, emitter, fd.retPack(), nullptr); -} - -static Error formatFuncArgs( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - const FuncDetail& fd, - const FuncNode::ArgPack* argPacks) noexcept { - - uint32_t argCount = fd.argCount(); - if (!argCount) - return sb.append("void"); - - for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) { - if (argIndex) - ASMJIT_PROPAGATE(sb.append(", ")); - - ASMJIT_PROPAGATE(formatFuncValuePack(sb, formatFlags, emitter, fd.argPack(argIndex), argPacks[argIndex]._data)); - } - - return kErrorOk; -} -#endif - -Error formatNode( - String& sb, - uint32_t formatFlags, - const BaseBuilder* builder, - const BaseNode* node) noexcept { - - if (node->hasPosition() && (formatFlags & FormatOptions::kFlagPositions) != 0) - ASMJIT_PROPAGATE(sb.appendFormat("<%05u> ", node->position())); - - switch (node->type()) { - case BaseNode::kNodeInst: - case BaseNode::kNodeJump: { - const InstNode* instNode = node->as(); - ASMJIT_PROPAGATE( - formatInstruction(sb, formatFlags, builder, - builder->arch(), - instNode->baseInst(), instNode->operands(), instNode->opCount())); - break; - } - - case BaseNode::kNodeSection: { - const SectionNode* sectionNode = node->as(); - if (builder->_code->isSectionValid(sectionNode->id())) { - const Section* section = builder->_code->sectionById(sectionNode->id()); - ASMJIT_PROPAGATE(sb.appendFormat(".section %s", section->name())); - } - break; - } - - case BaseNode::kNodeLabel: { - const LabelNode* labelNode = node->as(); - ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, labelNode->labelId())); - ASMJIT_PROPAGATE(sb.append(":")); - break; - } - - case BaseNode::kNodeAlign: { - const AlignNode* alignNode = node->as(); - ASMJIT_PROPAGATE( - sb.appendFormat("align %u (%s)", - alignNode->alignment(), - alignNode->alignMode() == kAlignCode ? "code" : "data")); - break; - } - - case BaseNode::kNodeEmbedData: { - const EmbedDataNode* embedNode = node->as(); - ASMJIT_PROPAGATE(sb.append("embed ")); - if (embedNode->repeatCount() != 1) - ASMJIT_PROPAGATE(sb.appendFormat("[repeat=%zu] ", size_t(embedNode->repeatCount()))); - ASMJIT_PROPAGATE(sb.appendFormat("%u bytes", embedNode->dataSize())); - break; - } - - case BaseNode::kNodeEmbedLabel: { - const EmbedLabelNode* embedNode = node->as(); - ASMJIT_PROPAGATE(sb.append(".label ")); - ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->labelId())); - break; - } - - case BaseNode::kNodeEmbedLabelDelta: { - const EmbedLabelDeltaNode* embedNode = node->as(); - ASMJIT_PROPAGATE(sb.append(".label (")); - ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->labelId())); - ASMJIT_PROPAGATE(sb.append(" - ")); - ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->baseLabelId())); - ASMJIT_PROPAGATE(sb.append(")")); - break; - } - - case BaseNode::kNodeComment: { - const CommentNode* commentNode = node->as(); - ASMJIT_PROPAGATE(sb.appendFormat("; %s", commentNode->inlineComment())); - break; - } - - case BaseNode::kNodeSentinel: { - const SentinelNode* sentinelNode = node->as(); - const char* sentinelName = nullptr; - - switch (sentinelNode->sentinelType()) { - case SentinelNode::kSentinelFuncEnd: - sentinelName = "[FuncEnd]"; - break; - - default: - sentinelName = "[Sentinel]"; - break; - } - - ASMJIT_PROPAGATE(sb.append(sentinelName)); - break; - } - -#ifndef ASMJIT_NO_COMPILER - case BaseNode::kNodeFunc: { - const FuncNode* funcNode = node->as(); - - ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, funcNode->labelId())); - ASMJIT_PROPAGATE(sb.append(": ")); - - ASMJIT_PROPAGATE(formatFuncRets(sb, formatFlags, builder, funcNode->detail())); - ASMJIT_PROPAGATE(sb.append(" Func(")); - ASMJIT_PROPAGATE(formatFuncArgs(sb, formatFlags, builder, funcNode->detail(), funcNode->argPacks())); - ASMJIT_PROPAGATE(sb.append(")")); - break; - } - - case BaseNode::kNodeFuncRet: { - const FuncRetNode* retNode = node->as(); - ASMJIT_PROPAGATE(sb.append("[FuncRet]")); - - for (uint32_t i = 0; i < 2; i++) { - const Operand_& op = retNode->_opArray[i]; - if (!op.isNone()) { - ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", ")); - ASMJIT_PROPAGATE(formatOperand(sb, formatFlags, builder, builder->arch(), op)); - } - } - break; - } - - case BaseNode::kNodeInvoke: { - const InvokeNode* invokeNode = node->as(); - ASMJIT_PROPAGATE( - formatInstruction(sb, formatFlags, builder, - builder->arch(), - invokeNode->baseInst(), invokeNode->operands(), invokeNode->opCount())); - break; - } -#endif - - default: { - ASMJIT_PROPAGATE(sb.appendFormat("[UserNode:%u]", node->type())); - break; - } - } - - return kErrorOk; -} - - -Error formatNodeList( - String& sb, - uint32_t formatFlags, - const BaseBuilder* builder) noexcept { - - return formatNodeList(sb, formatFlags, builder, builder->firstNode(), nullptr); -} - -Error formatNodeList( - String& sb, - uint32_t formatFlags, - const BaseBuilder* builder, - const BaseNode* begin, - const BaseNode* end) noexcept { - - const BaseNode* node = begin; - while (node != end) { - ASMJIT_PROPAGATE(formatNode(sb, formatFlags, builder, node)); - ASMJIT_PROPAGATE(sb.append('\n')); - node = node->next(); - } - return kErrorOk; -} -#endif - -} // {Formatter} - -ASMJIT_END_NAMESPACE - -#endif diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/formatter.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/formatter.h deleted file mode 100644 index 14934ba..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/formatter.h +++ /dev/null @@ -1,256 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_FORMATTER_H_INCLUDED -#define ASMJIT_CORE_FORMATTER_H_INCLUDED - -#include "../core/inst.h" -#include "../core/string.h" - -#ifndef ASMJIT_NO_LOGGING - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_logging -//! \{ - -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -class BaseEmitter; -struct Operand_; - -#ifndef ASMJIT_NO_BUILDER -class BaseBuilder; -class BaseNode; -#endif - -#ifndef ASMJIT_NO_COMPILER -class BaseCompiler; -#endif - -// ============================================================================ -// [asmjit::FormatOptions] -// ============================================================================ - -//! Formatting options used by \ref Logger and \ref Formatter. -class FormatOptions { -public: - //! Format flags, see \ref Flags. - uint32_t _flags; - //! Indentation by type, see \ref IndentationType. - uint8_t _indentation[4]; - - //! Flags can enable a logging feature. - enum Flags : uint32_t { - //! No flags. - kNoFlags = 0u, - - //! Show also binary form of each logged instruction (Assembler). - kFlagMachineCode = 0x00000001u, - //! Show a text explanation of some immediate values. - kFlagExplainImms = 0x00000002u, - //! Use hexadecimal notation of immediate values. - kFlagHexImms = 0x00000004u, - //! Use hexadecimal notation of address offsets. - kFlagHexOffsets = 0x00000008u, - //! Show casts between virtual register types (Compiler). - kFlagRegCasts = 0x00000010u, - //! Show positions associated with nodes (Compiler). - kFlagPositions = 0x00000020u, - //! Annotate nodes that are lowered by passes. - kFlagAnnotations = 0x00000040u, - - // TODO: These must go, keep this only for formatting. - //! Show an additional output from passes. - kFlagDebugPasses = 0x00000080u, - //! Show an additional output from RA. - kFlagDebugRA = 0x00000100u - }; - - //! Describes indentation type of code, label, or comment in logger output. - enum IndentationType : uint32_t { - //! Indentation used for instructions and directives. - kIndentationCode = 0u, - //! Indentation used for labels and function nodes. - kIndentationLabel = 1u, - //! Indentation used for comments (not inline comments). - kIndentationComment = 2u, - //! \cond INTERNAL - //! Reserved for future use. - kIndentationReserved = 3u - //! \endcond - }; - - //! \name Construction & Destruction - //! \{ - - //! Creates a default-initialized FormatOptions. - constexpr FormatOptions() noexcept - : _flags(0), - _indentation { 0, 0, 0, 0 } {} - - constexpr FormatOptions(const FormatOptions& other) noexcept = default; - inline FormatOptions& operator=(const FormatOptions& other) noexcept = default; - - //! Resets FormatOptions to its default initialized state. - inline void reset() noexcept { - _flags = 0; - _indentation[0] = 0; - _indentation[1] = 0; - _indentation[2] = 0; - _indentation[3] = 0; - } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns format flags. - constexpr uint32_t flags() const noexcept { return _flags; } - //! Tests whether the given `flag` is set in format flags. - constexpr bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; } - //! Resets all format flags to `flags`. - inline void setFlags(uint32_t flags) noexcept { _flags = flags; } - //! Adds `flags` to format flags. - inline void addFlags(uint32_t flags) noexcept { _flags |= flags; } - //! Removes `flags` from format flags. - inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; } - - //! Returns indentation for the given `type`, see \ref IndentationType. - constexpr uint8_t indentation(uint32_t type) const noexcept { return _indentation[type]; } - //! Sets indentation for the given `type`, see \ref IndentationType. - inline void setIndentation(uint32_t type, uint32_t n) noexcept { _indentation[type] = uint8_t(n); } - //! Resets indentation for the given `type` to zero. - inline void resetIndentation(uint32_t type) noexcept { _indentation[type] = uint8_t(0); } - - //! \} -}; - -// ============================================================================ -// [asmjit::Formatter] -// ============================================================================ - -//! Provides formatting functionality to format operands, instructions, and nodes. -namespace Formatter { - -//! Appends a formatted `typeId` to the output string `sb`. -ASMJIT_API Error formatTypeId( - String& sb, - uint32_t typeId) noexcept; - -//! Appends a formatted `featureId` to the output string `sb`. -//! -//! See \ref BaseFeatures. -ASMJIT_API Error formatFeature( - String& sb, - uint32_t arch, - uint32_t featureId) noexcept; - -//! Appends a formatted register to the output string `sb`. -//! -//! \note Emitter is optional, but it's required to format virtual registers, -//! which won't be formatted properly if the `emitter` is not provided. -ASMJIT_API Error formatRegister( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - uint32_t arch, - uint32_t regType, - uint32_t regId) noexcept; - -//! Appends a formatted label to the output string `sb`. -//! -//! \note Emitter is optional, but it's required to format named labels -//! properly, otherwise the formatted as it is an anonymous label. -ASMJIT_API Error formatLabel( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - uint32_t labelId) noexcept; - -//! Appends a formatted operand to the output string `sb`. -//! -//! \note Emitter is optional, but it's required to format named labels and -//! virtual registers. See \ref formatRegister() and \ref formatLabel() for -//! more details. -ASMJIT_API Error formatOperand( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - uint32_t arch, - const Operand_& op) noexcept; - -//! Appends a formatted instruction to the output string `sb`. -//! -//! \note Emitter is optional, but it's required to format named labels and -//! virtual registers. See \ref formatRegister() and \ref formatLabel() for -//! more details. -ASMJIT_API Error formatInstruction( - String& sb, - uint32_t formatFlags, - const BaseEmitter* emitter, - uint32_t arch, - const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept; - -#ifndef ASMJIT_NO_BUILDER -//! Appends a formatted node to the output string `sb`. -//! -//! The `node` must belong to the provided `builder`. -ASMJIT_API Error formatNode( - String& sb, - uint32_t formatFlags, - const BaseBuilder* builder, - const BaseNode* node) noexcept; - -//! Appends formatted nodes to the output string `sb`. -//! -//! All nodes that are part of the given `builder` will be appended. -ASMJIT_API Error formatNodeList( - String& sb, - uint32_t formatFlags, - const BaseBuilder* builder) noexcept; - -//! Appends formatted nodes to the output string `sb`. -//! -//! This function works the same as \ref formatNode(), but appends more nodes -//! to the output string, separating each node with a newline '\n' character. -ASMJIT_API Error formatNodeList( - String& sb, - uint32_t formatFlags, - const BaseBuilder* builder, - const BaseNode* begin, - const BaseNode* end) noexcept; -#endif - -} // {Formatter} - -//! \} - -ASMJIT_END_NAMESPACE - -#endif - -#endif // ASMJIT_CORE_FORMATTER_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/func.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/func.cpp deleted file mode 100644 index bb131a0..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/func.cpp +++ /dev/null @@ -1,310 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/archtraits.h" -#include "../core/func.h" -#include "../core/operand.h" -#include "../core/type.h" -#include "../core/funcargscontext_p.h" - -#ifdef ASMJIT_BUILD_X86 - #include "../x86/x86func_p.h" -#endif - -#ifdef ASMJIT_BUILD_ARM - #include "../arm/armfunc_p.h" -#endif - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::CallConv - Init / Reset] -// ============================================================================ - -ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId, const Environment& environment) noexcept { - reset(); - -#ifdef ASMJIT_BUILD_X86 - if (environment.isFamilyX86()) - return x86::FuncInternal::initCallConv(*this, ccId, environment); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (environment.isFamilyARM()) - return arm::FuncInternal::initCallConv(*this, ccId, environment); -#endif - - return DebugUtils::errored(kErrorInvalidArgument); -} - -// ============================================================================ -// [asmjit::FuncDetail - Init / Reset] -// ============================================================================ - -ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& signature, const Environment& environment) noexcept { - uint32_t ccId = signature.callConv(); - uint32_t argCount = signature.argCount(); - - if (ASMJIT_UNLIKELY(argCount > Globals::kMaxFuncArgs)) - return DebugUtils::errored(kErrorInvalidArgument); - - CallConv& cc = _callConv; - ASMJIT_PROPAGATE(cc.init(ccId, environment)); - - uint32_t registerSize = Environment::registerSizeFromArch(cc.arch()); - uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize); - - const uint8_t* signatureArgs = signature.args(); - for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) { - FuncValuePack& argPack = _args[argIndex]; - argPack[0].initTypeId(Type::deabstract(signatureArgs[argIndex], deabstractDelta)); - } - _argCount = uint8_t(argCount); - _vaIndex = uint8_t(signature.vaIndex()); - - uint32_t ret = signature.ret(); - if (ret != Type::kIdVoid) - _rets[0].initTypeId(Type::deabstract(ret, deabstractDelta)); - -#ifdef ASMJIT_BUILD_X86 - if (environment.isFamilyX86()) - return x86::FuncInternal::initFuncDetail(*this, signature, registerSize); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (environment.isFamilyARM()) - return arm::FuncInternal::initFuncDetail(*this, signature, registerSize); -#endif - - // We should never bubble here as if `cc.init()` succeeded then there has to - // be an implementation for the current architecture. However, stay safe. - return DebugUtils::errored(kErrorInvalidArgument); -} - -// ============================================================================ -// [asmjit::FuncFrame - Init / Finalize] -// ============================================================================ - -ASMJIT_FAVOR_SIZE Error FuncFrame::init(const FuncDetail& func) noexcept { - uint32_t arch = func.callConv().arch(); - if (!Environment::isValidArch(arch)) - return DebugUtils::errored(kErrorInvalidArch); - - const ArchTraits& archTraits = ArchTraits::byArch(arch); - - // Initializing FuncFrame means making a copy of some properties of `func`. - // Properties like `_localStackSize` will be set by the user before the frame - // is finalized. - reset(); - - _arch = uint8_t(arch); - _spRegId = uint8_t(archTraits.spRegId()); - _saRegId = uint8_t(BaseReg::kIdBad); - - uint32_t naturalStackAlignment = func.callConv().naturalStackAlignment(); - uint32_t minDynamicAlignment = Support::max(naturalStackAlignment, 16); - - if (minDynamicAlignment == naturalStackAlignment) - minDynamicAlignment <<= 1; - - _naturalStackAlignment = uint8_t(naturalStackAlignment); - _minDynamicAlignment = uint8_t(minDynamicAlignment); - _redZoneSize = uint8_t(func.redZoneSize()); - _spillZoneSize = uint8_t(func.spillZoneSize()); - _finalStackAlignment = uint8_t(_naturalStackAlignment); - - if (func.hasFlag(CallConv::kFlagCalleePopsStack)) { - _calleeStackCleanup = uint16_t(func.argStackSize()); - } - - // Initial masks of dirty and preserved registers. - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) { - _dirtyRegs[group] = func.usedRegs(group); - _preservedRegs[group] = func.preservedRegs(group); - } - - // Exclude stack pointer - this register is never included in saved GP regs. - _preservedRegs[BaseReg::kGroupGp] &= ~Support::bitMask(archTraits.spRegId()); - - // The size and alignment of save/restore area of registers for each significant register group. - memcpy(_saveRestoreRegSize, func.callConv()._saveRestoreRegSize, sizeof(_saveRestoreRegSize)); - memcpy(_saveRestoreAlignment, func.callConv()._saveRestoreAlignment, sizeof(_saveRestoreAlignment)); - - return kErrorOk; -} - -ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept { - if (!Environment::isValidArch(arch())) - return DebugUtils::errored(kErrorInvalidArch); - - const ArchTraits& archTraits = ArchTraits::byArch(arch()); - - uint32_t registerSize = _saveRestoreRegSize[BaseReg::kGroupGp]; - uint32_t vectorSize = _saveRestoreRegSize[BaseReg::kGroupVec]; - uint32_t returnAddressSize = archTraits.hasLinkReg() ? 0u : registerSize; - - // The final stack alignment must be updated accordingly to call and local stack alignments. - uint32_t stackAlignment = _finalStackAlignment; - ASMJIT_ASSERT(stackAlignment == Support::max(_naturalStackAlignment, - _callStackAlignment, - _localStackAlignment)); - - bool hasFP = hasPreservedFP(); - bool hasDA = hasDynamicAlignment(); - - uint32_t kSp = archTraits.spRegId(); - uint32_t kFp = archTraits.fpRegId(); - uint32_t kLr = archTraits.linkRegId(); - - // Make frame pointer dirty if the function uses it. - if (hasFP) { - _dirtyRegs[BaseReg::kGroupGp] |= Support::bitMask(kFp); - - // Currently required by ARM, if this works differently across architectures - // we would have to generalize most likely in CallConv. - if (kLr != BaseReg::kIdBad) - _dirtyRegs[BaseReg::kGroupGp] |= Support::bitMask(kLr); - } - - // These two are identical if the function doesn't align its stack dynamically. - uint32_t saRegId = _saRegId; - if (saRegId == BaseReg::kIdBad) - saRegId = kSp; - - // Fix stack arguments base-register from SP to FP in case it was not picked - // before and the function performs dynamic stack alignment. - if (hasDA && saRegId == kSp) - saRegId = kFp; - - // Mark as dirty any register but SP if used as SA pointer. - if (saRegId != kSp) - _dirtyRegs[BaseReg::kGroupGp] |= Support::bitMask(saRegId); - - _spRegId = uint8_t(kSp); - _saRegId = uint8_t(saRegId); - - // Setup stack size used to save preserved registers. - uint32_t saveRestoreSizes[2] {}; - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) - saveRestoreSizes[size_t(!archTraits.hasPushPop(group))] - += Support::alignUp(Support::popcnt(savedRegs(group)) * saveRestoreRegSize(group), saveRestoreAlignment(group)); - - _pushPopSaveSize = uint16_t(saveRestoreSizes[0]); - _extraRegSaveSize = uint16_t(saveRestoreSizes[1]); - - uint32_t v = 0; // The beginning of the stack frame relative to SP after prolog. - v += callStackSize(); // Count 'callStackSize' <- This is used to call functions. - v = Support::alignUp(v, stackAlignment); // Align to function's stack alignment. - - _localStackOffset = v; // Store 'localStackOffset' <- Function's local stack starts here. - v += localStackSize(); // Count 'localStackSize' <- Function's local stack ends here. - - // If the function's stack must be aligned, calculate the alignment necessary - // to store vector registers, and set `FuncFrame::kAttrAlignedVecSR` to inform - // PEI that it can use instructions that perform aligned stores/loads. - if (stackAlignment >= vectorSize && _extraRegSaveSize) { - addAttributes(FuncFrame::kAttrAlignedVecSR); - v = Support::alignUp(v, vectorSize); // Align 'extraRegSaveOffset'. - } - - _extraRegSaveOffset = v; // Store 'extraRegSaveOffset' <- Non-GP save/restore starts here. - v += _extraRegSaveSize; // Count 'extraRegSaveSize' <- Non-GP save/restore ends here. - - // Calculate if dynamic alignment (DA) slot (stored as offset relative to SP) is required and its offset. - if (hasDA && !hasFP) { - _daOffset = v; // Store 'daOffset' <- DA pointer would be stored here. - v += registerSize; // Count 'daOffset'. - } - else { - _daOffset = FuncFrame::kTagInvalidOffset; - } - - // Link Register - // ------------- - // - // The stack is aligned after the function call as the return address is - // stored in a link register. Some architectures may require to always - // have aligned stack after PUSH/POP operation, which is represented by - // ArchTraits::stackAlignmentConstraint(). - // - // No Link Register (X86/X64) - // -------------------------- - // - // The return address should be stored after GP save/restore regs. It has - // the same size as `registerSize` (basically the native register/pointer - // size). We don't adjust it now as `v` now contains the exact size that the - // function requires to adjust (call frame + stack frame, vec stack size). - // The stack (if we consider this size) is misaligned now, as it's always - // aligned before the function call - when `call()` is executed it pushes - // the current EIP|RIP onto the stack, and misaligns it by 12 or 8 bytes - // (depending on the architecture). So count number of bytes needed to align - // it up to the function's CallFrame (the beginning). - if (v || hasFuncCalls() || !returnAddressSize) - v += Support::alignUpDiff(v + pushPopSaveSize() + returnAddressSize, stackAlignment); - - _pushPopSaveOffset = v; // Store 'pushPopSaveOffset' <- Function's push/pop save/restore starts here. - _stackAdjustment = v; // Store 'stackAdjustment' <- SA used by 'add SP, SA' and 'sub SP, SA'. - v += _pushPopSaveSize; // Count 'pushPopSaveSize' <- Function's push/pop save/restore ends here. - _finalStackSize = v; // Store 'finalStackSize' <- Final stack used by the function. - - if (!archTraits.hasLinkReg()) - v += registerSize; // Count 'ReturnAddress' <- As CALL pushes onto stack. - - // If the function performs dynamic stack alignment then the stack-adjustment must be aligned. - if (hasDA) - _stackAdjustment = Support::alignUp(_stackAdjustment, stackAlignment); - - // Calculate where the function arguments start relative to SP. - _saOffsetFromSP = hasDA ? FuncFrame::kTagInvalidOffset : v; - - // Calculate where the function arguments start relative to FP or user-provided register. - _saOffsetFromSA = hasFP ? returnAddressSize + registerSize // Return address + frame pointer. - : returnAddressSize + _pushPopSaveSize; // Return address + all push/pop regs. - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::FuncArgsAssignment] -// ============================================================================ - -ASMJIT_FAVOR_SIZE Error FuncArgsAssignment::updateFuncFrame(FuncFrame& frame) const noexcept { - uint32_t arch = frame.arch(); - const FuncDetail* func = funcDetail(); - - if (!func) - return DebugUtils::errored(kErrorInvalidState); - - RAConstraints constraints; - ASMJIT_PROPAGATE(constraints.init(arch)); - - FuncArgsContext ctx; - ASMJIT_PROPAGATE(ctx.initWorkData(frame, *this, &constraints)); - ASMJIT_PROPAGATE(ctx.markDstRegsDirty(frame)); - ASMJIT_PROPAGATE(ctx.markScratchRegs(frame)); - ASMJIT_PROPAGATE(ctx.markStackArgsReg(frame)); - return kErrorOk; -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/func.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/func.h deleted file mode 100644 index 6cfd044..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/func.h +++ /dev/null @@ -1,1426 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_FUNC_H_INCLUDED -#define ASMJIT_CORE_FUNC_H_INCLUDED - -#include "../core/archtraits.h" -#include "../core/environment.h" -#include "../core/operand.h" -#include "../core/type.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_function -//! \{ - -// ============================================================================ -// [asmjit::CallConv] -// ============================================================================ - -//! Function calling convention. -//! -//! Function calling convention is a scheme that defines how function parameters -//! are passed and how function returns its result. AsmJit defines a variety of -//! architecture and OS specific calling conventions and also provides a compile -//! time detection to make the code-generation easier. -struct CallConv { - //! Calling convention id, see \ref Id. - uint8_t _id; - //! Architecture identifier, see \ref Environment::Arch. - uint8_t _arch; - //! Register assignment strategy, see \ref Strategy. - uint8_t _strategy; - - //! Red zone size (AMD64 == 128 bytes). - uint8_t _redZoneSize; - //! Spill zone size (WIN-X64 == 32 bytes). - uint8_t _spillZoneSize; - //! Natural stack alignment as defined by OS/ABI. - uint8_t _naturalStackAlignment; - - //! Flags. - uint16_t _flags; - - //! Size to save/restore per register group. - uint8_t _saveRestoreRegSize[BaseReg::kGroupVirt]; - //! Alignment of save/restore groups. - uint8_t _saveRestoreAlignment[BaseReg::kGroupVirt]; - - //! Mask of all passed registers, per group. - uint32_t _passedRegs[BaseReg::kGroupVirt]; - //! Mask of all preserved registers, per group. - uint32_t _preservedRegs[BaseReg::kGroupVirt]; - - //! Internal limits of AsmJit's CallConv. - enum Limits : uint32_t { - //! Maximum number of register arguments per register group. - //! - //! \note This is not really AsmJit's limitatation, it's just the number - //! that makes sense considering all common calling conventions. Usually - //! even conventions that use registers to pass function arguments are - //! limited to 8 and less arguments passed via registers per group. - kMaxRegArgsPerGroup = 16 - }; - - //! Passed registers' order. - union RegOrder { - //! Passed registers, ordered. - uint8_t id[kMaxRegArgsPerGroup]; - //! Packed IDs in `uint32_t` array. - uint32_t packed[(kMaxRegArgsPerGroup + 3) / 4]; - }; - - //! Passed registers' order, per register group. - RegOrder _passedOrder[BaseReg::kGroupVirt]; - - //! Calling convention id. - //! - //! Calling conventions can be divided into the following groups: - //! - //! - Universal - calling conventions are applicable to any target. They - //! will be converted to a target dependent calling convention at runtime - //! by \ref init(). The purpose of these conventions is to make using - //! functions less target dependent and closer to how they are declared - //! in C and C++. - //! - //! - Target specific - calling conventions that are used by a particular - //! architecture and ABI. For example Windows 64-bit calling convention - //! and AMD64 SystemV calling convention. - enum Id : uint32_t { - //! None or invalid (can't be used). - kIdNone = 0, - - // ------------------------------------------------------------------------ - // [Universal Calling Conventions] - // ------------------------------------------------------------------------ - - //! Standard function call or explicit `__cdecl` where it can be specified. - //! - //! This is a universal calling convention, which is used to initialize - //! specific calling connventions based on architecture, platform, and its ABI. - kIdCDecl = 1, - - //! `__stdcall` on targets that support this calling convention (X86). - //! - //! \note This calling convention is only supported on 32-bit X86. If used - //! on environment that doesn't support this calling convention it will be - //! replaced by \ref kIdCDecl. - kIdStdCall = 2, - - //! `__fastcall` on targets that support this calling convention (X86). - //! - //! \note This calling convention is only supported on 32-bit X86. If used - //! on environment that doesn't support this calling convention it will be - //! replaced by \ref kIdCDecl. - kIdFastCall = 3, - - //! `__vectorcall` on targets that support this calling convention (X86/X64). - //! - //! \note This calling convention is only supported on 32-bit and 64-bit - //! X86 architecture on Windows platform. If used on environment that doesn't - //! support this calling it will be replaced by \ref kIdCDecl. - kIdVectorCall = 4, - - //! `__thiscall` on targets that support this calling convention (X86). - //! - //! \note This calling convention is only supported on 32-bit X86 Windows - //! platform. If used on environment that doesn't support this calling - //! convention it will be replaced by \ref kIdCDecl. - kIdThisCall = 5, - - //! `__attribute__((regparm(1)))` convention (GCC and Clang). - kIdRegParm1 = 6, - //! `__attribute__((regparm(2)))` convention (GCC and Clang). - kIdRegParm2 = 7, - //! `__attribute__((regparm(3)))` convention (GCC and Clang). - kIdRegParm3 = 8, - - //! Soft-float calling convention (ARM). - //! - //! Floating point arguments are passed via general purpose registers. - kIdSoftFloat = 9, - - //! Hard-float calling convention (ARM). - //! - //! Floating point arguments are passed via SIMD registers. - kIdHardFloat = 10, - - //! AsmJit specific calling convention designed for calling functions - //! inside a multimedia code that don't use many registers internally, - //! but are long enough to be called and not inlined. These functions are - //! usually used to calculate trigonometric functions, logarithms, etc... - kIdLightCall2 = 16, - kIdLightCall3 = 17, - kIdLightCall4 = 18, - - // ------------------------------------------------------------------------ - // [ABI-Specific Calling Conventions] - // ------------------------------------------------------------------------ - - //! X64 System-V calling convention. - kIdX64SystemV = 32, - //! X64 Windows calling convention. - kIdX64Windows = 33, - - // ------------------------------------------------------------------------ - // [Host] - // ------------------------------------------------------------------------ - - //! Host calling convention detected at compile-time. - kIdHost = -#if ASMJIT_ARCH_ARM == 32 && defined(__SOFTFP__) - kIdSoftFloat -#elif ASMJIT_ARCH_ARM == 32 && !defined(__SOFTFP__) - kIdHardFloat -#else - kIdCDecl -#endif - -#ifndef ASMJIT_NO_DEPRECATE - , kIdHostCDecl = kIdCDecl - , kIdHostStdCall = kIdStdCall - , kIdHostFastCall = kIdFastCall - , kIdHostLightCall2 = kIdLightCall2 - , kIdHostLightCall3 = kIdLightCall3 - , kIdHostLightCall4 = kIdLightCall4 -#endif // !ASMJIT_NO_DEPRECATE - }; - - //! Strategy used to assign registers to function arguments. - //! - //! This is AsmJit specific. It basically describes how AsmJit should convert - //! the function arguments defined by `FuncSignature` into register IDs and - //! stack offsets. The default strategy `kStrategyDefault` assigns registers - //! and then stack whereas `kStrategyWin64` strategy does register shadowing - //! as defined by WIN64 calling convention - it applies to 64-bit calling - //! conventions only. - enum Strategy : uint32_t { - //! Default register assignment strategy. - kStrategyDefault = 0, - //! Windows 64-bit ABI register assignment strategy. - kStrategyX64Windows = 1, - //! Windows 64-bit __vectorcall register assignment strategy. - kStrategyX64VectorCall = 2, - - //! Number of assignment strategies. - kStrategyCount = 3 - }; - - //! Calling convention flags. - enum Flags : uint32_t { - //! Callee is responsible for cleaning up the stack. - kFlagCalleePopsStack = 0x0001u, - //! Pass vector arguments indirectly (as a pointer). - kFlagIndirectVecArgs = 0x0002u, - //! Pass F32 and F64 arguments via VEC128 register. - kFlagPassFloatsByVec = 0x0004u, - //! Pass MMX and vector arguments via stack if the function has variable arguments. - kFlagPassVecByStackIfVA = 0x0008u, - //! MMX registers are passed and returned via GP registers. - kFlagPassMmxByGp = 0x0010u, - //! MMX registers are passed and returned via XMM registers. - kFlagPassMmxByXmm = 0x0020u, - //! Calling convention can be used with variable arguments. - kFlagVarArgCompatible = 0x0080u - }; - - //! \name Construction & Destruction - //! \{ - - //! Initializes this calling convention to the given `ccId` based on the - //! `environment`. - //! - //! See \ref Id and \ref Environment for more details. - ASMJIT_API Error init(uint32_t ccId, const Environment& environment) noexcept; - - //! Resets this CallConv struct into a defined state. - //! - //! It's recommended to reset the \ref CallConv struct in case you would - //! like create a custom calling convention as it prevents from using an - //! uninitialized data (CallConv doesn't have a constructor that would - //! initialize it, it's just a struct). - inline void reset() noexcept { - memset(this, 0, sizeof(*this)); - memset(_passedOrder, 0xFF, sizeof(_passedOrder)); - } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the calling convention id, see `Id`. - inline uint32_t id() const noexcept { return _id; } - //! Sets the calling convention id, see `Id`. - inline void setId(uint32_t id) noexcept { _id = uint8_t(id); } - - //! Returns the calling function architecture id. - inline uint32_t arch() const noexcept { return _arch; } - //! Sets the calling function architecture id. - inline void setArch(uint32_t arch) noexcept { _arch = uint8_t(arch); } - - //! Returns the strategy used to assign registers to arguments, see `Strategy`. - inline uint32_t strategy() const noexcept { return _strategy; } - //! Sets the strategy used to assign registers to arguments, see `Strategy`. - inline void setStrategy(uint32_t strategy) noexcept { _strategy = uint8_t(strategy); } - - //! Tests whether the calling convention has the given `flag` set. - inline bool hasFlag(uint32_t flag) const noexcept { return (uint32_t(_flags) & flag) != 0; } - //! Returns the calling convention flags, see `Flags`. - inline uint32_t flags() const noexcept { return _flags; } - //! Adds the calling convention flags, see `Flags`. - inline void setFlags(uint32_t flag) noexcept { _flags = uint16_t(flag); }; - //! Adds the calling convention flags, see `Flags`. - inline void addFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags | flags); }; - - //! Tests whether this calling convention specifies 'RedZone'. - inline bool hasRedZone() const noexcept { return _redZoneSize != 0; } - //! Tests whether this calling convention specifies 'SpillZone'. - inline bool hasSpillZone() const noexcept { return _spillZoneSize != 0; } - - //! Returns size of 'RedZone'. - inline uint32_t redZoneSize() const noexcept { return _redZoneSize; } - //! Returns size of 'SpillZone'. - inline uint32_t spillZoneSize() const noexcept { return _spillZoneSize; } - - //! Sets size of 'RedZone'. - inline void setRedZoneSize(uint32_t size) noexcept { _redZoneSize = uint8_t(size); } - //! Sets size of 'SpillZone'. - inline void setSpillZoneSize(uint32_t size) noexcept { _spillZoneSize = uint8_t(size); } - - //! Returns a natural stack alignment. - inline uint32_t naturalStackAlignment() const noexcept { return _naturalStackAlignment; } - //! Sets a natural stack alignment. - //! - //! This function can be used to override the default stack alignment in case - //! that you know that it's alignment is different. For example it allows to - //! implement custom calling conventions that guarantee higher stack alignment. - inline void setNaturalStackAlignment(uint32_t value) noexcept { _naturalStackAlignment = uint8_t(value); } - - //! Returns the size of a register (or its part) to be saved and restored of the given `group`. - inline uint32_t saveRestoreRegSize(uint32_t group) const noexcept { return _saveRestoreRegSize[group]; } - //! Sets the size of a vector register (or its part) to be saved and restored. - inline void setSaveRestoreRegSize(uint32_t group, uint32_t size) noexcept { _saveRestoreRegSize[group] = uint8_t(size); } - - //! Returns the alignment of a save-restore area of the given `group`. - inline uint32_t saveRestoreAlignment(uint32_t group) const noexcept { return _saveRestoreAlignment[group]; } - //! Sets the alignment of a save-restore area of the given `group`. - inline void setSaveRestoreAlignment(uint32_t group, uint32_t alignment) noexcept { _saveRestoreAlignment[group] = uint8_t(alignment); } - - //! Returns the order of passed registers of the given `group`, see \ref BaseReg::RegGroup. - inline const uint8_t* passedOrder(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _passedOrder[group].id; - } - - //! Returns the mask of passed registers of the given `group`, see \ref BaseReg::RegGroup. - inline uint32_t passedRegs(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _passedRegs[group]; - } - - inline void _setPassedPacked(uint32_t group, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - - _passedOrder[group].packed[0] = p0; - _passedOrder[group].packed[1] = p1; - _passedOrder[group].packed[2] = p2; - _passedOrder[group].packed[3] = p3; - } - - //! Resets the order and mask of passed registers. - inline void setPassedToNone(uint32_t group) noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - - _setPassedPacked(group, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu); - _passedRegs[group] = 0u; - } - - //! Sets the order and mask of passed registers. - inline void setPassedOrder(uint32_t group, uint32_t a0, uint32_t a1 = 0xFF, uint32_t a2 = 0xFF, uint32_t a3 = 0xFF, uint32_t a4 = 0xFF, uint32_t a5 = 0xFF, uint32_t a6 = 0xFF, uint32_t a7 = 0xFF) noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - - // NOTE: This should always be called with all arguments known at compile time, - // so even if it looks scary it should be translated into few instructions. - _setPassedPacked(group, Support::bytepack32_4x8(a0, a1, a2, a3), - Support::bytepack32_4x8(a4, a5, a6, a7), - 0xFFFFFFFFu, - 0xFFFFFFFFu); - - _passedRegs[group] = (a0 != 0xFF ? 1u << a0 : 0u) | - (a1 != 0xFF ? 1u << a1 : 0u) | - (a2 != 0xFF ? 1u << a2 : 0u) | - (a3 != 0xFF ? 1u << a3 : 0u) | - (a4 != 0xFF ? 1u << a4 : 0u) | - (a5 != 0xFF ? 1u << a5 : 0u) | - (a6 != 0xFF ? 1u << a6 : 0u) | - (a7 != 0xFF ? 1u << a7 : 0u) ; - } - - //! Returns preserved register mask of the given `group`, see \ref BaseReg::RegGroup. - inline uint32_t preservedRegs(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _preservedRegs[group]; - } - - //! Sets preserved register mask of the given `group`, see \ref BaseReg::RegGroup. - inline void setPreservedRegs(uint32_t group, uint32_t regs) noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - _preservedRegs[group] = regs; - } - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncSignature] -// ============================================================================ - -//! Function signature. -//! -//! Contains information about function return type, count of arguments and -//! their TypeIds. Function signature is a low level structure which doesn't -//! contain platform specific or calling convention specific information. -struct FuncSignature { - //! Calling convention id. - uint8_t _callConv; - //! Count of arguments. - uint8_t _argCount; - //! Index of a first VA or `kNoVarArgs`. - uint8_t _vaIndex; - //! Return value TypeId. - uint8_t _ret; - //! Function arguments TypeIds. - const uint8_t* _args; - - enum : uint8_t { - //! Doesn't have variable number of arguments (`...`). - kNoVarArgs = 0xFF - }; - - //! \name Initializtion & Reset - //! \{ - - //! Initializes the function signature. - inline void init(uint32_t ccId, uint32_t vaIndex, uint32_t ret, const uint8_t* args, uint32_t argCount) noexcept { - ASMJIT_ASSERT(ccId <= 0xFF); - ASMJIT_ASSERT(argCount <= 0xFF); - - _callConv = uint8_t(ccId); - _argCount = uint8_t(argCount); - _vaIndex = uint8_t(vaIndex); - _ret = uint8_t(ret); - _args = args; - } - - inline void reset() noexcept { memset(this, 0, sizeof(*this)); } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the calling convention. - inline uint32_t callConv() const noexcept { return _callConv; } - //! Sets the calling convention to `ccId`; - inline void setCallConv(uint32_t ccId) noexcept { _callConv = uint8_t(ccId); } - - //! Tests whether the function has variable number of arguments (...). - inline bool hasVarArgs() const noexcept { return _vaIndex != kNoVarArgs; } - //! Returns the variable arguments (...) index, `kNoVarArgs` if none. - inline uint32_t vaIndex() const noexcept { return _vaIndex; } - //! Sets the variable arguments (...) index to `index`. - inline void setVaIndex(uint32_t index) noexcept { _vaIndex = uint8_t(index); } - //! Resets the variable arguments index (making it a non-va function). - inline void resetVaIndex() noexcept { _vaIndex = kNoVarArgs; } - - //! Returns the number of function arguments. - inline uint32_t argCount() const noexcept { return _argCount; } - - inline bool hasRet() const noexcept { return _ret != Type::kIdVoid; } - //! Returns the return value type. - inline uint32_t ret() const noexcept { return _ret; } - - //! Returns the type of the argument at index `i`. - inline uint32_t arg(uint32_t i) const noexcept { - ASMJIT_ASSERT(i < _argCount); - return _args[i]; - } - //! Returns the array of function arguments' types. - inline const uint8_t* args() const noexcept { return _args; } - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncSignatureT] -// ============================================================================ - -template -class FuncSignatureT : public FuncSignature { -public: - inline FuncSignatureT(uint32_t ccId = CallConv::kIdHost, uint32_t vaIndex = kNoVarArgs) noexcept { - static const uint8_t ret_args[] = { (uint8_t(Type::IdOfT::kTypeId))... }; - init(ccId, vaIndex, ret_args[0], ret_args + 1, uint32_t(ASMJIT_ARRAY_SIZE(ret_args) - 1)); - } -}; - -// ============================================================================ -// [asmjit::FuncSignatureBuilder] -// ============================================================================ - -//! Function signature builder. -class FuncSignatureBuilder : public FuncSignature { -public: - uint8_t _builderArgList[Globals::kMaxFuncArgs]; - - //! \name Initializtion & Reset - //! \{ - - inline FuncSignatureBuilder(uint32_t ccId = CallConv::kIdHost, uint32_t vaIndex = kNoVarArgs) noexcept { - init(ccId, vaIndex, Type::kIdVoid, _builderArgList, 0); - } - - //! \} - - //! \name Accessors - //! \{ - - //! Sets the return type to `retType`. - inline void setRet(uint32_t retType) noexcept { _ret = uint8_t(retType); } - //! Sets the return type based on `T`. - template - inline void setRetT() noexcept { setRet(Type::IdOfT::kTypeId); } - - //! Sets the argument at index `index` to `argType`. - inline void setArg(uint32_t index, uint32_t argType) noexcept { - ASMJIT_ASSERT(index < _argCount); - _builderArgList[index] = uint8_t(argType); - } - //! Sets the argument at index `i` to the type based on `T`. - template - inline void setArgT(uint32_t index) noexcept { setArg(index, Type::IdOfT::kTypeId); } - - //! Appends an argument of `type` to the function prototype. - inline void addArg(uint32_t type) noexcept { - ASMJIT_ASSERT(_argCount < Globals::kMaxFuncArgs); - _builderArgList[_argCount++] = uint8_t(type); - } - //! Appends an argument of type based on `T` to the function prototype. - template - inline void addArgT() noexcept { addArg(Type::IdOfT::kTypeId); } - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncValue] -// ============================================================================ - -//! Argument or return value (or its part) as defined by `FuncSignature`, but -//! with register or stack address (and other metadata) assigned. -struct FuncValue { - uint32_t _data; - - enum Parts : uint32_t { - kTypeIdShift = 0, //!< TypeId shift. - kTypeIdMask = 0x000000FFu, //!< TypeId mask. - - kFlagIsReg = 0x00000100u, //!< Passed by register. - kFlagIsStack = 0x00000200u, //!< Passed by stack. - kFlagIsIndirect = 0x00000400u, //!< Passed indirectly by reference (internally a pointer). - kFlagIsDone = 0x00000800u, //!< Used internally by arguments allocator. - - kStackOffsetShift = 12, //!< Stack offset shift. - kStackOffsetMask = 0xFFFFF000u, //!< Stack offset mask (must occupy MSB bits). - - kRegIdShift = 16, //!< RegId shift. - kRegIdMask = 0x00FF0000u, //!< RegId mask. - - kRegTypeShift = 24, //!< RegType shift. - kRegTypeMask = 0xFF000000u //!< RegType mask. - }; - - //! \name Initializtion & Reset - //! \{ - - // These initialize the whole `FuncValue` to either register or stack. Useful - // when you know all of these properties and wanna just set it up. - - //! Initializes the `typeId` of this `FuncValue`. - inline void initTypeId(uint32_t typeId) noexcept { - _data = typeId << kTypeIdShift; - } - - inline void initReg(uint32_t regType, uint32_t regId, uint32_t typeId, uint32_t flags = 0) noexcept { - _data = (regType << kRegTypeShift) | (regId << kRegIdShift) | (typeId << kTypeIdShift) | kFlagIsReg | flags; - } - - inline void initStack(int32_t offset, uint32_t typeId) noexcept { - _data = (uint32_t(offset) << kStackOffsetShift) | (typeId << kTypeIdShift) | kFlagIsStack; - } - - //! Resets the value to its unassigned state. - inline void reset() noexcept { _data = 0; } - - //! \} - - //! \name Assign - //! \{ - - // These initialize only part of `FuncValue`, useful when building `FuncValue` - // incrementally. The caller should first init the type-id by caliing `initTypeId` - // and then continue building either register or stack. - - inline void assignRegData(uint32_t regType, uint32_t regId) noexcept { - ASMJIT_ASSERT((_data & (kRegTypeMask | kRegIdMask)) == 0); - _data |= (regType << kRegTypeShift) | (regId << kRegIdShift) | kFlagIsReg; - } - - inline void assignStackOffset(int32_t offset) noexcept { - ASMJIT_ASSERT((_data & kStackOffsetMask) == 0); - _data |= (uint32_t(offset) << kStackOffsetShift) | kFlagIsStack; - } - - //! \} - - //! \name Accessors - //! \{ - - inline explicit operator bool() const noexcept { return _data != 0; } - - inline void _replaceValue(uint32_t mask, uint32_t value) noexcept { _data = (_data & ~mask) | value; } - - //! Tests whether the `FuncValue` has a flag `flag` set. - inline bool hasFlag(uint32_t flag) const noexcept { return (_data & flag) != 0; } - //! Adds `flags` to `FuncValue`. - inline void addFlags(uint32_t flags) noexcept { _data |= flags; } - //! Clears `flags` of `FuncValue`. - inline void clearFlags(uint32_t flags) noexcept { _data &= ~flags; } - - //! Tests whether the value is initialized (i.e. contains a valid data). - inline bool isInitialized() const noexcept { return _data != 0; } - //! Tests whether the argument is passed by register. - inline bool isReg() const noexcept { return hasFlag(kFlagIsReg); } - //! Tests whether the argument is passed by stack. - inline bool isStack() const noexcept { return hasFlag(kFlagIsStack); } - //! Tests whether the argument is passed by register. - inline bool isAssigned() const noexcept { return hasFlag(kFlagIsReg | kFlagIsStack); } - //! Tests whether the argument is passed through a pointer (used by WIN64 to pass XMM|YMM|ZMM). - inline bool isIndirect() const noexcept { return hasFlag(kFlagIsIndirect); } - - //! Tests whether the argument was already processed (used internally). - inline bool isDone() const noexcept { return hasFlag(kFlagIsDone); } - - //! Returns a register type of the register used to pass function argument or return value. - inline uint32_t regType() const noexcept { return (_data & kRegTypeMask) >> kRegTypeShift; } - //! Sets a register type of the register used to pass function argument or return value. - inline void setRegType(uint32_t regType) noexcept { _replaceValue(kRegTypeMask, regType << kRegTypeShift); } - - //! Returns a physical id of the register used to pass function argument or return value. - inline uint32_t regId() const noexcept { return (_data & kRegIdMask) >> kRegIdShift; } - //! Sets a physical id of the register used to pass function argument or return value. - inline void setRegId(uint32_t regId) noexcept { _replaceValue(kRegIdMask, regId << kRegIdShift); } - - //! Returns a stack offset of this argument. - inline int32_t stackOffset() const noexcept { return int32_t(_data & kStackOffsetMask) >> kStackOffsetShift; } - //! Sets a stack offset of this argument. - inline void setStackOffset(int32_t offset) noexcept { _replaceValue(kStackOffsetMask, uint32_t(offset) << kStackOffsetShift); } - - //! Tests whether the argument or return value has associated `Type::Id`. - inline bool hasTypeId() const noexcept { return (_data & kTypeIdMask) != 0; } - //! Returns a TypeId of this argument or return value. - inline uint32_t typeId() const noexcept { return (_data & kTypeIdMask) >> kTypeIdShift; } - //! Sets a TypeId of this argument or return value. - inline void setTypeId(uint32_t typeId) noexcept { _replaceValue(kTypeIdMask, typeId << kTypeIdShift); } - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncValuePack] -// ============================================================================ - -//! Contains multiple `FuncValue` instances in an array so functions that use -//! multiple registers for arguments or return values can represent all inputs -//! and outputs. -struct FuncValuePack { -public: - //! Values data. - FuncValue _values[Globals::kMaxValuePack]; - - inline void reset() noexcept { - for (size_t i = 0; i < Globals::kMaxValuePack; i++) - _values[i].reset(); - } - - //! Calculates how many values are in the pack, checking for non-values - //! from the end. - inline uint32_t count() const noexcept { - uint32_t n = Globals::kMaxValuePack; - while (n && !_values[n - 1]) - n--; - return n; - } - - inline FuncValue* values() noexcept { return _values; } - inline const FuncValue* values() const noexcept { return _values; } - - inline void resetValue(size_t index) noexcept { - ASMJIT_ASSERT(index < Globals::kMaxValuePack); - _values[index].reset(); - } - - inline bool hasValue(size_t index) noexcept { - ASMJIT_ASSERT(index < Globals::kMaxValuePack); - return _values[index].isInitialized(); - } - - inline void assignReg(size_t index, const BaseReg& reg, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(index < Globals::kMaxValuePack); - ASMJIT_ASSERT(reg.isPhysReg()); - _values[index].initReg(reg.type(), reg.id(), typeId); - } - - inline void assignReg(size_t index, uint32_t regType, uint32_t regId, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(index < Globals::kMaxValuePack); - _values[index].initReg(regType, regId, typeId); - } - - inline void assignStack(size_t index, int32_t offset, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(index < Globals::kMaxValuePack); - _values[index].initStack(offset, typeId); - } - - inline FuncValue& operator[](size_t index) { - ASMJIT_ASSERT(index < Globals::kMaxValuePack); - return _values[index]; - } - - inline const FuncValue& operator[](size_t index) const { - ASMJIT_ASSERT(index < Globals::kMaxValuePack); - return _values[index]; - } -}; - -// ============================================================================ -// [asmjit::FuncDetail] -// ============================================================================ - -//! Function detail - CallConv and expanded FuncSignature. -//! -//! Function detail is architecture and OS dependent representation of a function. -//! It contains calling convention and expanded function signature so all -//! arguments have assigned either register type & id or stack address. -class FuncDetail { -public: - //! Calling convention. - CallConv _callConv; - //! Number of function arguments. - uint8_t _argCount; - //! Variable arguments index of `kNoVarArgs`. - uint8_t _vaIndex; - //! Reserved for future use. - uint16_t _reserved; - //! Registers that contains arguments. - uint32_t _usedRegs[BaseReg::kGroupVirt]; - //! Size of arguments passed by stack. - uint32_t _argStackSize; - //! Function return value(s). - FuncValuePack _rets; - //! Function arguments. - FuncValuePack _args[Globals::kMaxFuncArgs]; - - enum : uint8_t { - //! Doesn't have variable number of arguments (`...`). - kNoVarArgs = 0xFF - }; - - //! \name Construction & Destruction - //! \{ - - inline FuncDetail() noexcept { reset(); } - inline FuncDetail(const FuncDetail& other) noexcept = default; - - //! Initializes this `FuncDetail` to the given signature. - ASMJIT_API Error init(const FuncSignature& signature, const Environment& environment) noexcept; - inline void reset() noexcept { memset(this, 0, sizeof(*this)); } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the function's calling convention, see `CallConv`. - inline const CallConv& callConv() const noexcept { return _callConv; } - - //! Returns the associated calling convention flags, see `CallConv::Flags`. - inline uint32_t flags() const noexcept { return _callConv.flags(); } - //! Checks whether a CallConv `flag` is set, see `CallConv::Flags`. - inline bool hasFlag(uint32_t ccFlag) const noexcept { return _callConv.hasFlag(ccFlag); } - - //! Tests whether the function has a return value. - inline bool hasRet() const noexcept { return bool(_rets[0]); } - //! Returns the number of function arguments. - inline uint32_t argCount() const noexcept { return _argCount; } - - //! Returns function return values. - inline FuncValuePack& retPack() noexcept { return _rets; } - //! Returns function return values. - inline const FuncValuePack& retPack() const noexcept { return _rets; } - - //! Returns a function return value associated with the given `valueIndex`. - inline FuncValue& ret(size_t valueIndex = 0) noexcept { return _rets[valueIndex]; } - //! Returns a function return value associated with the given `valueIndex` (const). - inline const FuncValue& ret(size_t valueIndex = 0) const noexcept { return _rets[valueIndex]; } - - //! Returns function argument packs array. - inline FuncValuePack* argPacks() noexcept { return _args; } - //! Returns function argument packs array (const). - inline const FuncValuePack* argPacks() const noexcept { return _args; } - - //! Returns function argument pack at the given `argIndex`. - inline FuncValuePack& argPack(size_t argIndex) noexcept { - ASMJIT_ASSERT(argIndex < Globals::kMaxFuncArgs); - return _args[argIndex]; - } - - //! Returns function argument pack at the given `argIndex` (const). - inline const FuncValuePack& argPack(size_t argIndex) const noexcept { - ASMJIT_ASSERT(argIndex < Globals::kMaxFuncArgs); - return _args[argIndex]; - } - - //! Returns an argument at `valueIndex` from the argument pack at the given `argIndex`. - inline FuncValue& arg(size_t argIndex, size_t valueIndex = 0) noexcept { - ASMJIT_ASSERT(argIndex < Globals::kMaxFuncArgs); - return _args[argIndex][valueIndex]; - } - - //! Returns an argument at `valueIndex` from the argument pack at the given `argIndex` (const). - inline const FuncValue& arg(size_t argIndex, size_t valueIndex = 0) const noexcept { - ASMJIT_ASSERT(argIndex < Globals::kMaxFuncArgs); - return _args[argIndex][valueIndex]; - } - - //! Resets an argument at the given `argIndex`. - //! - //! If the argument is a parameter pack (has multiple values) all values are reset. - inline void resetArg(size_t argIndex) noexcept { - ASMJIT_ASSERT(argIndex < Globals::kMaxFuncArgs); - _args[argIndex].reset(); - } - - //! Tests whether the function has variable arguments. - inline bool hasVarArgs() const noexcept { return _vaIndex != kNoVarArgs; } - //! Returns an index of a first variable argument. - inline uint32_t vaIndex() const noexcept { return _vaIndex; } - - //! Tests whether the function passes one or more argument by stack. - inline bool hasStackArgs() const noexcept { return _argStackSize != 0; } - //! Returns stack size needed for function arguments passed on the stack. - inline uint32_t argStackSize() const noexcept { return _argStackSize; } - - //! Returns red zone size. - inline uint32_t redZoneSize() const noexcept { return _callConv.redZoneSize(); } - //! Returns spill zone size. - inline uint32_t spillZoneSize() const noexcept { return _callConv.spillZoneSize(); } - //! Returns natural stack alignment. - inline uint32_t naturalStackAlignment() const noexcept { return _callConv.naturalStackAlignment(); } - - //! Returns a mask of all passed registers of the given register `group`. - inline uint32_t passedRegs(uint32_t group) const noexcept { return _callConv.passedRegs(group); } - //! Returns a mask of all preserved registers of the given register `group`. - inline uint32_t preservedRegs(uint32_t group) const noexcept { return _callConv.preservedRegs(group); } - - //! Returns a mask of all used registers of the given register `group`. - inline uint32_t usedRegs(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _usedRegs[group]; - } - - //! Adds `regs` to the mask of used registers of the given register `group`. - inline void addUsedRegs(uint32_t group, uint32_t regs) noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - _usedRegs[group] |= regs; - } - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncFrame] -// ============================================================================ - -//! Function frame. -//! -//! Function frame is used directly by prolog and epilog insertion (PEI) utils. -//! It provides information necessary to insert a proper and ABI comforming -//! prolog and epilog. Function frame calculation is based on `CallConv` and -//! other function attributes. -//! -//! Function Frame Structure -//! ------------------------ -//! -//! Various properties can contribute to the size and structure of the function -//! frame. The function frame in most cases won't use all of the properties -//! illustrated (for example Spill Zone and Red Zone are never used together). -//! -//! ``` -//! +-----------------------------+ -//! | Arguments Passed by Stack | -//! +-----------------------------+ -//! | Spill Zone | -//! +-----------------------------+ <- Stack offset (args) starts from here. -//! | Return Address, if Pushed | -//! +-----------------------------+ <- Stack pointer (SP) upon entry. -//! | Save/Restore Stack. | -//! +-----------------------------+-----------------------------+ -//! | Local Stack | | -//! +-----------------------------+ Final Stack | -//! | Call Stack | | -//! +-----------------------------+-----------------------------+ <- SP after prolog. -//! | Red Zone | -//! +-----------------------------+ -//! ``` -class FuncFrame { -public: - enum Tag : uint32_t { - //! Tag used to inform that some offset is invalid. - kTagInvalidOffset = 0xFFFFFFFFu - }; - - //! Attributes are designed in a way that all are initially false, and user - //! or FuncFrame finalizer adds them when necessary. - enum Attributes : uint32_t { - //! Function has variable number of arguments. - kAttrHasVarArgs = 0x00000001u, - //! Preserve frame pointer (don't omit FP). - kAttrHasPreservedFP = 0x00000010u, - //! Function calls other functions (is not leaf). - kAttrHasFuncCalls = 0x00000020u, - - //! Use AVX instead of SSE for all operations (X86). - kAttrX86AvxEnabled = 0x00010000u, - //! Emit VZEROUPPER instruction in epilog (X86). - kAttrX86AvxCleanup = 0x00020000u, - //! Emit EMMS instruction in epilog (X86). - kAttrX86MmxCleanup = 0x00040000u, - - //! Function has aligned save/restore of vector registers. - kAttrAlignedVecSR = 0x40000000u, - //! FuncFrame is finalized and can be used by PEI. - kAttrIsFinalized = 0x80000000u - }; - - //! Function attributes. - uint32_t _attributes; - - //! Architecture, see \ref Environment::Arch. - uint8_t _arch; - //! SP register ID (to access call stack and local stack). - uint8_t _spRegId; - //! SA register ID (to access stack arguments). - uint8_t _saRegId; - - //! Red zone size (copied from CallConv). - uint8_t _redZoneSize; - //! Spill zone size (copied from CallConv). - uint8_t _spillZoneSize; - //! Natural stack alignment (copied from CallConv). - uint8_t _naturalStackAlignment; - //! Minimum stack alignment to turn on dynamic alignment. - uint8_t _minDynamicAlignment; - - //! Call stack alignment. - uint8_t _callStackAlignment; - //! Local stack alignment. - uint8_t _localStackAlignment; - //! Final stack alignment. - uint8_t _finalStackAlignment; - - //! Adjustment of the stack before returning (X86-STDCALL). - uint16_t _calleeStackCleanup; - - //! Call stack size. - uint32_t _callStackSize; - //! Local stack size. - uint32_t _localStackSize; - //! Final stack size (sum of call stack and local stack). - uint32_t _finalStackSize; - - //! Local stack offset (non-zero only if call stack is used). - uint32_t _localStackOffset; - //! Offset relative to SP that contains previous SP (before alignment). - uint32_t _daOffset; - //! Offset of the first stack argument relative to SP. - uint32_t _saOffsetFromSP; - //! Offset of the first stack argument relative to SA (_saRegId or FP). - uint32_t _saOffsetFromSA; - - //! Local stack adjustment in prolog/epilog. - uint32_t _stackAdjustment; - - //! Registers that are dirty. - uint32_t _dirtyRegs[BaseReg::kGroupVirt]; - //! Registers that must be preserved (copied from CallConv). - uint32_t _preservedRegs[BaseReg::kGroupVirt]; - //! Size to save/restore per register group. - uint8_t _saveRestoreRegSize[BaseReg::kGroupVirt]; - //! Alignment of save/restore area per register group. - uint8_t _saveRestoreAlignment[BaseReg::kGroupVirt]; - - //! Stack size required to save registers with push/pop. - uint16_t _pushPopSaveSize; - //! Stack size required to save extra registers that cannot use push/pop. - uint16_t _extraRegSaveSize; - //! Offset where registers saved/restored via push/pop are stored - uint32_t _pushPopSaveOffset; - //! Offset where extra ragisters that cannot use push/pop are stored. - uint32_t _extraRegSaveOffset; - - //! \name Construction & Destruction - //! \{ - - inline FuncFrame() noexcept { reset(); } - inline FuncFrame(const FuncFrame& other) noexcept = default; - - ASMJIT_API Error init(const FuncDetail& func) noexcept; - - inline void reset() noexcept { - memset(this, 0, sizeof(FuncFrame)); - _spRegId = BaseReg::kIdBad; - _saRegId = BaseReg::kIdBad; - _daOffset = kTagInvalidOffset; - } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the target architecture of the function frame. - inline uint32_t arch() const noexcept { return _arch; } - - //! Returns function frame attributes, see `Attributes`. - inline uint32_t attributes() const noexcept { return _attributes; } - //! Checks whether the FuncFame contains an attribute `attr`. - inline bool hasAttribute(uint32_t attr) const noexcept { return (_attributes & attr) != 0; } - //! Adds attributes `attrs` to the FuncFrame. - inline void addAttributes(uint32_t attrs) noexcept { _attributes |= attrs; } - //! Clears attributes `attrs` from the FrameFrame. - inline void clearAttributes(uint32_t attrs) noexcept { _attributes &= ~attrs; } - - //! Tests whether the function has variable number of arguments. - inline bool hasVarArgs() const noexcept { return hasAttribute(kAttrHasVarArgs); } - //! Sets the variable arguments flag. - inline void setVarArgs() noexcept { addAttributes(kAttrHasVarArgs); } - //! Resets variable arguments flag. - inline void resetVarArgs() noexcept { clearAttributes(kAttrHasVarArgs); } - - //! Tests whether the function preserves frame pointer (EBP|ESP on X86). - inline bool hasPreservedFP() const noexcept { return hasAttribute(kAttrHasPreservedFP); } - //! Enables preserved frame pointer. - inline void setPreservedFP() noexcept { addAttributes(kAttrHasPreservedFP); } - //! Disables preserved frame pointer. - inline void resetPreservedFP() noexcept { clearAttributes(kAttrHasPreservedFP); } - - //! Tests whether the function calls other functions. - inline bool hasFuncCalls() const noexcept { return hasAttribute(kAttrHasFuncCalls); } - //! Sets `kFlagHasCalls` to true. - inline void setFuncCalls() noexcept { addAttributes(kAttrHasFuncCalls); } - //! Sets `kFlagHasCalls` to false. - inline void resetFuncCalls() noexcept { clearAttributes(kAttrHasFuncCalls); } - - //! Tests whether the function contains AVX cleanup - 'vzeroupper' instruction in epilog. - inline bool hasAvxCleanup() const noexcept { return hasAttribute(kAttrX86AvxCleanup); } - //! Enables AVX cleanup. - inline void setAvxCleanup() noexcept { addAttributes(kAttrX86AvxCleanup); } - //! Disables AVX cleanup. - inline void resetAvxCleanup() noexcept { clearAttributes(kAttrX86AvxCleanup); } - - //! Tests whether the function contains AVX cleanup - 'vzeroupper' instruction in epilog. - inline bool isAvxEnabled() const noexcept { return hasAttribute(kAttrX86AvxEnabled); } - //! Enables AVX cleanup. - inline void setAvxEnabled() noexcept { addAttributes(kAttrX86AvxEnabled); } - //! Disables AVX cleanup. - inline void resetAvxEnabled() noexcept { clearAttributes(kAttrX86AvxEnabled); } - - //! Tests whether the function contains MMX cleanup - 'emms' instruction in epilog. - inline bool hasMmxCleanup() const noexcept { return hasAttribute(kAttrX86MmxCleanup); } - //! Enables MMX cleanup. - inline void setMmxCleanup() noexcept { addAttributes(kAttrX86MmxCleanup); } - //! Disables MMX cleanup. - inline void resetMmxCleanup() noexcept { clearAttributes(kAttrX86MmxCleanup); } - - //! Tests whether the function uses call stack. - inline bool hasCallStack() const noexcept { return _callStackSize != 0; } - //! Tests whether the function uses local stack. - inline bool hasLocalStack() const noexcept { return _localStackSize != 0; } - //! Tests whether vector registers can be saved and restored by using aligned reads and writes. - inline bool hasAlignedVecSR() const noexcept { return hasAttribute(kAttrAlignedVecSR); } - //! Tests whether the function has to align stack dynamically. - inline bool hasDynamicAlignment() const noexcept { return _finalStackAlignment >= _minDynamicAlignment; } - - //! Tests whether the calling convention specifies 'RedZone'. - inline bool hasRedZone() const noexcept { return _redZoneSize != 0; } - //! Tests whether the calling convention specifies 'SpillZone'. - inline bool hasSpillZone() const noexcept { return _spillZoneSize != 0; } - - //! Returns the size of 'RedZone'. - inline uint32_t redZoneSize() const noexcept { return _redZoneSize; } - //! Returns the size of 'SpillZone'. - inline uint32_t spillZoneSize() const noexcept { return _spillZoneSize; } - //! Returns natural stack alignment (guaranteed stack alignment upon entry). - inline uint32_t naturalStackAlignment() const noexcept { return _naturalStackAlignment; } - //! Returns natural stack alignment (guaranteed stack alignment upon entry). - inline uint32_t minDynamicAlignment() const noexcept { return _minDynamicAlignment; } - - //! Tests whether the callee must adjust SP before returning (X86-STDCALL only) - inline bool hasCalleeStackCleanup() const noexcept { return _calleeStackCleanup != 0; } - //! Returns home many bytes of the stack the the callee must adjust before returning (X86-STDCALL only) - inline uint32_t calleeStackCleanup() const noexcept { return _calleeStackCleanup; } - - //! Returns call stack alignment. - inline uint32_t callStackAlignment() const noexcept { return _callStackAlignment; } - //! Returns local stack alignment. - inline uint32_t localStackAlignment() const noexcept { return _localStackAlignment; } - //! Returns final stack alignment (the maximum value of call, local, and natural stack alignments). - inline uint32_t finalStackAlignment() const noexcept { return _finalStackAlignment; } - - //! Sets call stack alignment. - //! - //! \note This also updates the final stack alignment. - inline void setCallStackAlignment(uint32_t alignment) noexcept { - _callStackAlignment = uint8_t(alignment); - _finalStackAlignment = Support::max(_naturalStackAlignment, _callStackAlignment, _localStackAlignment); - } - - //! Sets local stack alignment. - //! - //! \note This also updates the final stack alignment. - inline void setLocalStackAlignment(uint32_t value) noexcept { - _localStackAlignment = uint8_t(value); - _finalStackAlignment = Support::max(_naturalStackAlignment, _callStackAlignment, _localStackAlignment); - } - - //! Combines call stack alignment with `alignment`, updating it to the greater value. - //! - //! \note This also updates the final stack alignment. - inline void updateCallStackAlignment(uint32_t alignment) noexcept { - _callStackAlignment = uint8_t(Support::max(_callStackAlignment, alignment)); - _finalStackAlignment = Support::max(_finalStackAlignment, _callStackAlignment); - } - - //! Combines local stack alignment with `alignment`, updating it to the greater value. - //! - //! \note This also updates the final stack alignment. - inline void updateLocalStackAlignment(uint32_t alignment) noexcept { - _localStackAlignment = uint8_t(Support::max(_localStackAlignment, alignment)); - _finalStackAlignment = Support::max(_finalStackAlignment, _localStackAlignment); - } - - //! Returns call stack size. - inline uint32_t callStackSize() const noexcept { return _callStackSize; } - //! Returns local stack size. - inline uint32_t localStackSize() const noexcept { return _localStackSize; } - - //! Sets call stack size. - inline void setCallStackSize(uint32_t size) noexcept { _callStackSize = size; } - //! Sets local stack size. - inline void setLocalStackSize(uint32_t size) noexcept { _localStackSize = size; } - - //! Combines call stack size with `size`, updating it to the greater value. - inline void updateCallStackSize(uint32_t size) noexcept { _callStackSize = Support::max(_callStackSize, size); } - //! Combines local stack size with `size`, updating it to the greater value. - inline void updateLocalStackSize(uint32_t size) noexcept { _localStackSize = Support::max(_localStackSize, size); } - - //! Returns final stack size (only valid after the FuncFrame is finalized). - inline uint32_t finalStackSize() const noexcept { return _finalStackSize; } - - //! Returns an offset to access the local stack (non-zero only if call stack is used). - inline uint32_t localStackOffset() const noexcept { return _localStackOffset; } - - //! Tests whether the function prolog/epilog requires a memory slot for storing unaligned SP. - inline bool hasDAOffset() const noexcept { return _daOffset != kTagInvalidOffset; } - //! Returns a memory offset used to store DA (dynamic alignment) slot (relative to SP). - inline uint32_t daOffset() const noexcept { return _daOffset; } - - inline uint32_t saOffset(uint32_t regId) const noexcept { - return regId == _spRegId ? saOffsetFromSP() - : saOffsetFromSA(); - } - - inline uint32_t saOffsetFromSP() const noexcept { return _saOffsetFromSP; } - inline uint32_t saOffsetFromSA() const noexcept { return _saOffsetFromSA; } - - //! Returns mask of registers of the given register `group` that are modified - //! by the function. The engine would then calculate which registers must be - //! saved & restored by the function by using the data provided by the calling - //! convention. - inline uint32_t dirtyRegs(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _dirtyRegs[group]; - } - - //! Sets which registers (as a mask) are modified by the function. - //! - //! \remarks Please note that this will completely overwrite the existing - //! register mask, use `addDirtyRegs()` to modify the existing register - //! mask. - inline void setDirtyRegs(uint32_t group, uint32_t regs) noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - _dirtyRegs[group] = regs; - } - - //! Adds which registers (as a mask) are modified by the function. - inline void addDirtyRegs(uint32_t group, uint32_t regs) noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - _dirtyRegs[group] |= regs; - } - - //! \overload - inline void addDirtyRegs(const BaseReg& reg) noexcept { - ASMJIT_ASSERT(reg.id() < Globals::kMaxPhysRegs); - addDirtyRegs(reg.group(), Support::bitMask(reg.id())); - } - - //! \overload - template - ASMJIT_INLINE void addDirtyRegs(const BaseReg& reg, Args&&... args) noexcept { - addDirtyRegs(reg); - addDirtyRegs(std::forward(args)...); - } - - inline void setAllDirty() noexcept { - for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_dirtyRegs); i++) - _dirtyRegs[i] = 0xFFFFFFFFu; - } - - inline void setAllDirty(uint32_t group) noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - _dirtyRegs[group] = 0xFFFFFFFFu; - } - - //! Returns a calculated mask of registers of the given `group` that will be - //! saved and restored in the function's prolog and epilog, respectively. The - //! register mask is calculated from both `dirtyRegs` (provided by user) and - //! `preservedMask` (provided by the calling convention). - inline uint32_t savedRegs(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _dirtyRegs[group] & _preservedRegs[group]; - } - - //! Returns the mask of preserved registers of the given register `group`. - //! - //! Preserved registers are those that must survive the function call - //! unmodified. The function can only modify preserved registers it they - //! are saved and restored in funciton's prolog and epilog, respectively. - inline uint32_t preservedRegs(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _preservedRegs[group]; - } - - inline uint32_t saveRestoreRegSize(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _saveRestoreRegSize[group]; - } - - inline uint32_t saveRestoreAlignment(uint32_t group) const noexcept { - ASMJIT_ASSERT(group < BaseReg::kGroupVirt); - return _saveRestoreAlignment[group]; - } - - inline bool hasSARegId() const noexcept { return _saRegId != BaseReg::kIdBad; } - inline uint32_t saRegId() const noexcept { return _saRegId; } - inline void setSARegId(uint32_t regId) { _saRegId = uint8_t(regId); } - inline void resetSARegId() { setSARegId(BaseReg::kIdBad); } - - //! Returns stack size required to save/restore registers via push/pop. - inline uint32_t pushPopSaveSize() const noexcept { return _pushPopSaveSize; } - //! Returns an offset to the stack where registers are saved via push/pop. - inline uint32_t pushPopSaveOffset() const noexcept { return _pushPopSaveOffset; } - - //! Returns stack size required to save/restore extra registers that don't - //! use push/pop/ - //! - //! \note On X86 this covers all registers except GP registers, on other - //! architectures it can be always zero (for example AArch64 saves all - //! registers via push/pop like instructions, so this would be zero). - inline uint32_t extraRegSaveSize() const noexcept { return _extraRegSaveSize; } - //! Returns an offset to the stack where extra registers are saved. - inline uint32_t extraRegSaveOffset() const noexcept { return _extraRegSaveOffset; } - - //! Tests whether the functions contains stack adjustment. - inline bool hasStackAdjustment() const noexcept { return _stackAdjustment != 0; } - //! Returns function's stack adjustment used in function's prolog and epilog. - //! - //! If the returned value is zero it means that the stack is not adjusted. - //! This can mean both that the stack is not used and/or the stack is only - //! adjusted by instructions that pust/pop registers into/from stack. - inline uint32_t stackAdjustment() const noexcept { return _stackAdjustment; } - - //! \} - - //! \name Finaliztion - //! \{ - - ASMJIT_API Error finalize() noexcept; - - //! \} -}; - -// ============================================================================ -// [asmjit::FuncArgsAssignment] -// ============================================================================ - -//! A helper class that can be used to assign a physical register for each -//! function argument. Use with `BaseEmitter::emitArgsAssignment()`. -class FuncArgsAssignment { -public: - //! Function detail. - const FuncDetail* _funcDetail; - //! Register that can be used to access arguments passed by stack. - uint8_t _saRegId; - //! Reserved for future use. - uint8_t _reserved[3]; - //! Mapping of each function argument. - FuncValuePack _argPacks[Globals::kMaxFuncArgs]; - - //! \name Construction & Destruction - //! \{ - - inline explicit FuncArgsAssignment(const FuncDetail* fd = nullptr) noexcept { reset(fd); } - - inline FuncArgsAssignment(const FuncArgsAssignment& other) noexcept { - memcpy(this, &other, sizeof(*this)); - } - - inline void reset(const FuncDetail* fd = nullptr) noexcept { - _funcDetail = fd; - _saRegId = uint8_t(BaseReg::kIdBad); - memset(_reserved, 0, sizeof(_reserved)); - memset(_argPacks, 0, sizeof(_argPacks)); - } - - //! \} - - //! \name Accessors - //! \{ - - inline const FuncDetail* funcDetail() const noexcept { return _funcDetail; } - inline void setFuncDetail(const FuncDetail* fd) noexcept { _funcDetail = fd; } - - inline bool hasSARegId() const noexcept { return _saRegId != BaseReg::kIdBad; } - inline uint32_t saRegId() const noexcept { return _saRegId; } - inline void setSARegId(uint32_t regId) { _saRegId = uint8_t(regId); } - inline void resetSARegId() { _saRegId = uint8_t(BaseReg::kIdBad); } - - inline FuncValue& arg(size_t argIndex, size_t valueIndex) noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - return _argPacks[argIndex][valueIndex]; - } - inline const FuncValue& arg(size_t argIndex, size_t valueIndex) const noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - return _argPacks[argIndex][valueIndex]; - } - - inline bool isAssigned(size_t argIndex, size_t valueIndex) const noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - return _argPacks[argIndex][valueIndex].isAssigned(); - } - - inline void assignReg(size_t argIndex, const BaseReg& reg, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - ASMJIT_ASSERT(reg.isPhysReg()); - _argPacks[argIndex][0].initReg(reg.type(), reg.id(), typeId); - } - - inline void assignReg(size_t argIndex, uint32_t regType, uint32_t regId, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - _argPacks[argIndex][0].initReg(regType, regId, typeId); - } - - inline void assignStack(size_t argIndex, int32_t offset, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - _argPacks[argIndex][0].initStack(offset, typeId); - } - - inline void assignRegInPack(size_t argIndex, size_t valueIndex, const BaseReg& reg, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - ASMJIT_ASSERT(reg.isPhysReg()); - _argPacks[argIndex][valueIndex].initReg(reg.type(), reg.id(), typeId); - } - - inline void assignRegInPack(size_t argIndex, size_t valueIndex, uint32_t regType, uint32_t regId, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - _argPacks[argIndex][valueIndex].initReg(regType, regId, typeId); - } - - inline void assignStackInPack(size_t argIndex, size_t valueIndex, int32_t offset, uint32_t typeId = Type::kIdVoid) noexcept { - ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); - _argPacks[argIndex][valueIndex].initStack(offset, typeId); - } - - // NOTE: All `assignAll()` methods are shortcuts to assign all arguments at - // once, however, since registers are passed all at once these initializers - // don't provide any way to pass TypeId and/or to keep any argument between - // the arguments passed unassigned. - inline void _assignAllInternal(size_t argIndex, const BaseReg& reg) noexcept { - assignReg(argIndex, reg); - } - - template - inline void _assignAllInternal(size_t argIndex, const BaseReg& reg, Args&&... args) noexcept { - assignReg(argIndex, reg); - _assignAllInternal(argIndex + 1, std::forward(args)...); - } - - template - inline void assignAll(Args&&... args) noexcept { - _assignAllInternal(0, std::forward(args)...); - } - - //! \} - - //! \name Utilities - //! \{ - - //! Update `FuncFrame` based on function's arguments assignment. - //! - //! \note You MUST call this in orher to use `BaseEmitter::emitArgsAssignment()`, - //! otherwise the FuncFrame would not contain the information necessary to - //! assign all arguments into the registers and/or stack specified. - ASMJIT_API Error updateFuncFrame(FuncFrame& frame) const noexcept; - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_FUNC_H_INCLUDED - diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/funcargscontext.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/funcargscontext.cpp deleted file mode 100644 index 331e205..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/funcargscontext.cpp +++ /dev/null @@ -1,315 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/funcargscontext_p.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \cond INTERNAL -//! \addtogroup asmjit_core -//! \{ - -FuncArgsContext::FuncArgsContext() noexcept { - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) - _workData[group].reset(); -} - -ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args, const RAConstraints* constraints) noexcept { - // The code has to be updated if this changes. - ASMJIT_ASSERT(BaseReg::kGroupVirt == 4); - - uint32_t i; - - uint32_t arch = frame.arch(); - const FuncDetail& func = *args.funcDetail(); - - _archTraits = &ArchTraits::byArch(arch); - _constraints = constraints; - _arch = uint8_t(arch); - - // Initialize `_archRegs`. - for (i = 0; i < BaseReg::kGroupVirt; i++) - _workData[i]._archRegs = _constraints->availableRegs(i); - - if (frame.hasPreservedFP()) - _workData[BaseReg::kGroupGp]._archRegs &= ~Support::bitMask(archTraits().fpRegId()); - - // Extract information from all function arguments/assignments and build Var[] array. - uint32_t varId = 0; - for (uint32_t argIndex = 0; argIndex < Globals::kMaxFuncArgs; argIndex++) { - for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) { - const FuncValue& dst_ = args.arg(argIndex, valueIndex); - if (!dst_.isAssigned()) - continue; - - const FuncValue& src_ = func.arg(argIndex, valueIndex); - if (ASMJIT_UNLIKELY(!src_.isAssigned())) - return DebugUtils::errored(kErrorInvalidState); - - Var& var = _vars[varId]; - var.init(src_, dst_); - - FuncValue& src = var.cur; - FuncValue& dst = var.out; - - uint32_t dstGroup = 0xFFFFFFFFu; - uint32_t dstId = BaseReg::kIdBad; - WorkData* dstWd = nullptr; - - // Not supported. - if (src.isIndirect()) - return DebugUtils::errored(kErrorInvalidAssignment); - - if (dst.isReg()) { - uint32_t dstType = dst.regType(); - if (ASMJIT_UNLIKELY(!archTraits().hasRegType(dstType))) - return DebugUtils::errored(kErrorInvalidRegType); - - // Copy TypeId from source if the destination doesn't have it. The RA - // used by BaseCompiler would never leave TypeId undefined, but users - // of FuncAPI can just assign phys regs without specifying the type. - if (!dst.hasTypeId()) - dst.setTypeId(archTraits().regTypeToTypeId(dst.regType())); - - dstGroup = archTraits().regTypeToGroup(dstType); - if (ASMJIT_UNLIKELY(dstGroup >= BaseReg::kGroupVirt)) - return DebugUtils::errored(kErrorInvalidRegGroup); - - dstWd = &_workData[dstGroup]; - dstId = dst.regId(); - if (ASMJIT_UNLIKELY(dstId >= 32 || !Support::bitTest(dstWd->archRegs(), dstId))) - return DebugUtils::errored(kErrorInvalidPhysId); - - if (ASMJIT_UNLIKELY(Support::bitTest(dstWd->dstRegs(), dstId))) - return DebugUtils::errored(kErrorOverlappedRegs); - - dstWd->_dstRegs |= Support::bitMask(dstId); - dstWd->_dstShuf |= Support::bitMask(dstId); - dstWd->_usedRegs |= Support::bitMask(dstId); - } - else { - if (!dst.hasTypeId()) - dst.setTypeId(src.typeId()); - - RegInfo regInfo = getSuitableRegForMemToMemMove(arch, dst.typeId(), src.typeId()); - if (ASMJIT_UNLIKELY(!regInfo.isValid())) - return DebugUtils::errored(kErrorInvalidState); - _stackDstMask = uint8_t(_stackDstMask | Support::bitMask(regInfo.group())); - } - - if (src.isReg()) { - uint32_t srcId = src.regId(); - uint32_t srcGroup = archTraits().regTypeToGroup(src.regType()); - - if (dstGroup == srcGroup) { - dstWd->assign(varId, srcId); - - // The best case, register is allocated where it is expected to be. - if (dstId == srcId) - var.markDone(); - } - else { - if (ASMJIT_UNLIKELY(srcGroup >= BaseReg::kGroupVirt)) - return DebugUtils::errored(kErrorInvalidState); - - WorkData& srcData = _workData[srcGroup]; - srcData.assign(varId, srcId); - } - } - else { - if (dstWd) - dstWd->_numStackArgs++; - _hasStackSrc = true; - } - - varId++; - } - } - - // Initialize WorkData::workRegs. - for (i = 0; i < BaseReg::kGroupVirt; i++) { - _workData[i]._workRegs = (_workData[i].archRegs() & (frame.dirtyRegs(i) | ~frame.preservedRegs(i))) | _workData[i].dstRegs() | _workData[i].assignedRegs(); - } - - // Create a variable that represents `SARegId` if necessary. - bool saRegRequired = _hasStackSrc && frame.hasDynamicAlignment() && !frame.hasPreservedFP(); - - WorkData& gpRegs = _workData[BaseReg::kGroupGp]; - uint32_t saCurRegId = frame.saRegId(); - uint32_t saOutRegId = args.saRegId(); - - if (saCurRegId != BaseReg::kIdBad) { - // Check if the provided `SARegId` doesn't collide with input registers. - if (ASMJIT_UNLIKELY(gpRegs.isAssigned(saCurRegId))) - return DebugUtils::errored(kErrorOverlappedRegs); - } - - if (saOutRegId != BaseReg::kIdBad) { - // Check if the provided `SARegId` doesn't collide with argument assignments. - if (ASMJIT_UNLIKELY(Support::bitTest(gpRegs.dstRegs(), saOutRegId))) - return DebugUtils::errored(kErrorOverlappedRegs); - saRegRequired = true; - } - - if (saRegRequired) { - uint32_t ptrTypeId = Environment::is32Bit(arch) ? Type::kIdU32 : Type::kIdU64; - uint32_t ptrRegType = Environment::is32Bit(arch) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64; - - _saVarId = uint8_t(varId); - _hasPreservedFP = frame.hasPreservedFP(); - - Var& var = _vars[varId]; - var.reset(); - - if (saCurRegId == BaseReg::kIdBad) { - if (saOutRegId != BaseReg::kIdBad && !gpRegs.isAssigned(saOutRegId)) { - saCurRegId = saOutRegId; - } - else { - uint32_t availableRegs = gpRegs.availableRegs(); - if (!availableRegs) - availableRegs = gpRegs.archRegs() & ~gpRegs.workRegs(); - - if (ASMJIT_UNLIKELY(!availableRegs)) - return DebugUtils::errored(kErrorNoMorePhysRegs); - - saCurRegId = Support::ctz(availableRegs); - } - } - - var.cur.initReg(ptrRegType, saCurRegId, ptrTypeId); - gpRegs.assign(varId, saCurRegId); - gpRegs._workRegs |= Support::bitMask(saCurRegId); - - if (saOutRegId != BaseReg::kIdBad) { - var.out.initReg(ptrRegType, saOutRegId, ptrTypeId); - gpRegs._dstRegs |= Support::bitMask(saOutRegId); - gpRegs._workRegs |= Support::bitMask(saOutRegId); - } - else { - var.markDone(); - } - - varId++; - } - - _varCount = varId; - - // Detect register swaps. - for (varId = 0; varId < _varCount; varId++) { - Var& var = _vars[varId]; - if (var.cur.isReg() && var.out.isReg()) { - uint32_t srcId = var.cur.regId(); - uint32_t dstId = var.out.regId(); - - uint32_t group = archTraits().regTypeToGroup(var.cur.regType()); - if (group != archTraits().regTypeToGroup(var.out.regType())) - continue; - - WorkData& wd = _workData[group]; - if (wd.isAssigned(dstId)) { - Var& other = _vars[wd._physToVarId[dstId]]; - if (archTraits().regTypeToGroup(other.out.regType()) == group && other.out.regId() == srcId) { - wd._numSwaps++; - _regSwapsMask = uint8_t(_regSwapsMask | Support::bitMask(group)); - } - } - } - } - - return kErrorOk; -} - -ASMJIT_FAVOR_SIZE Error FuncArgsContext::markDstRegsDirty(FuncFrame& frame) noexcept { - for (uint32_t i = 0; i < BaseReg::kGroupVirt; i++) { - WorkData& wd = _workData[i]; - uint32_t regs = wd.usedRegs() | wd._dstShuf; - - wd._workRegs |= regs; - frame.addDirtyRegs(i, regs); - } - - return kErrorOk; -} - -ASMJIT_FAVOR_SIZE Error FuncArgsContext::markScratchRegs(FuncFrame& frame) noexcept { - uint32_t groupMask = 0; - - // Handle stack to stack moves. - groupMask |= _stackDstMask; - - // Handle register swaps. - groupMask |= _regSwapsMask & ~Support::bitMask(BaseReg::kGroupGp); - - if (!groupMask) - return kErrorOk; - - // Selects one dirty register per affected group that can be used as a scratch register. - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) { - if (Support::bitTest(groupMask, group)) { - WorkData& wd = _workData[group]; - - // Initially, pick some clobbered or dirty register. - uint32_t workRegs = wd.workRegs(); - uint32_t regs = workRegs & ~(wd.usedRegs() | wd._dstShuf); - - // If that didn't work out pick some register which is not in 'used'. - if (!regs) - regs = workRegs & ~wd.usedRegs(); - - // If that didn't work out pick any other register that is allocable. - // This last resort case will, however, result in marking one more - // register dirty. - if (!regs) - regs = wd.archRegs() & ~workRegs; - - // If that didn't work out we will have to use XORs instead of MOVs. - if (!regs) - continue; - - uint32_t regMask = Support::blsi(regs); - wd._workRegs |= regMask; - frame.addDirtyRegs(group, regMask); - } - } - - return kErrorOk; -} - -ASMJIT_FAVOR_SIZE Error FuncArgsContext::markStackArgsReg(FuncFrame& frame) noexcept { - if (_saVarId != kVarIdNone) { - const Var& var = _vars[_saVarId]; - frame.setSARegId(var.cur.regId()); - } - else if (frame.hasPreservedFP()) { - frame.setSARegId(archTraits().fpRegId()); - } - - return kErrorOk; -} - -//! \} -//! \endcond - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/funcargscontext_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/funcargscontext_p.h deleted file mode 100644 index 6c4ea6a..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/funcargscontext_p.h +++ /dev/null @@ -1,224 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED -#define ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED - -#include "../core/archtraits.h" -#include "../core/environment.h" -#include "../core/func.h" -#include "../core/operand.h" -#include "../core/radefs_p.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \cond INTERNAL -//! \addtogroup asmjit_core -//! \{ - -// ============================================================================ -// [TODO: Place somewhere else] -// ============================================================================ - -static inline RegInfo getSuitableRegForMemToMemMove(uint32_t arch, uint32_t dstTypeId, uint32_t srcTypeId) noexcept { - const ArchTraits& archTraits = ArchTraits::byArch(arch); - - uint32_t dstSize = Type::sizeOf(dstTypeId); - uint32_t srcSize = Type::sizeOf(srcTypeId); - uint32_t maxSize = Support::max(dstSize, srcSize); - uint32_t regSize = Environment::registerSizeFromArch(arch); - - uint32_t signature = 0; - if (maxSize <= regSize || (Type::isInt(dstTypeId) && Type::isInt(srcTypeId))) - signature = maxSize <= 4 ? archTraits.regTypeToSignature(BaseReg::kTypeGp32) - : archTraits.regTypeToSignature(BaseReg::kTypeGp64); - else if (maxSize <= 8 && archTraits.hasRegType(BaseReg::kTypeVec64)) - signature = archTraits.regTypeToSignature(BaseReg::kTypeVec64); - else if (maxSize <= 16 && archTraits.hasRegType(BaseReg::kTypeVec128)) - signature = archTraits.regTypeToSignature(BaseReg::kTypeVec128); - else if (maxSize <= 32 && archTraits.hasRegType(BaseReg::kTypeVec256)) - signature = archTraits.regTypeToSignature(BaseReg::kTypeVec256); - else if (maxSize <= 64 && archTraits.hasRegType(BaseReg::kTypeVec512)) - signature = archTraits.regTypeToSignature(BaseReg::kTypeVec512); - - return RegInfo { signature }; -} - -// ============================================================================ -// [asmjit::FuncArgsContext] -// ============================================================================ - -class FuncArgsContext { -public: - enum VarId : uint32_t { - kVarIdNone = 0xFF - }; - - //! Contains information about a single argument or SA register that may need shuffling. - struct Var { - FuncValue cur; - FuncValue out; - - inline void init(const FuncValue& cur_, const FuncValue& out_) noexcept { - cur = cur_; - out = out_; - } - - //! Reset the value to its unassigned state. - inline void reset() noexcept { - cur.reset(); - out.reset(); - } - - inline bool isDone() const noexcept { return cur.isDone(); } - inline void markDone() noexcept { cur.addFlags(FuncValue::kFlagIsDone); } - }; - - struct WorkData { - //! All allocable registers provided by the architecture. - uint32_t _archRegs; - //! All registers that can be used by the shuffler. - uint32_t _workRegs; - //! Registers used by the shuffler (all). - uint32_t _usedRegs; - //! Assigned registers. - uint32_t _assignedRegs; - //! Destination registers assigned to arguments or SA. - uint32_t _dstRegs; - //! Destination registers that require shuffling. - uint32_t _dstShuf; - //! Number of register swaps. - uint8_t _numSwaps; - //! Number of stack loads. - uint8_t _numStackArgs; - //! Reserved (only used as padding). - uint8_t _reserved[6]; - //! Physical ID to variable ID mapping. - uint8_t _physToVarId[32]; - - inline void reset() noexcept { - _archRegs = 0; - _workRegs = 0; - _usedRegs = 0; - _assignedRegs = 0; - _dstRegs = 0; - _dstShuf = 0; - _numSwaps = 0; - _numStackArgs = 0; - memset(_reserved, 0, sizeof(_reserved)); - memset(_physToVarId, kVarIdNone, 32); - } - - inline bool isAssigned(uint32_t regId) const noexcept { - ASMJIT_ASSERT(regId < 32); - return Support::bitTest(_assignedRegs, regId); - } - - inline void assign(uint32_t varId, uint32_t regId) noexcept { - ASMJIT_ASSERT(!isAssigned(regId)); - ASMJIT_ASSERT(_physToVarId[regId] == kVarIdNone); - - _physToVarId[regId] = uint8_t(varId); - _assignedRegs ^= Support::bitMask(regId); - } - - inline void reassign(uint32_t varId, uint32_t newId, uint32_t oldId) noexcept { - ASMJIT_ASSERT( isAssigned(oldId)); - ASMJIT_ASSERT(!isAssigned(newId)); - ASMJIT_ASSERT(_physToVarId[oldId] == varId); - ASMJIT_ASSERT(_physToVarId[newId] == kVarIdNone); - - _physToVarId[oldId] = uint8_t(kVarIdNone); - _physToVarId[newId] = uint8_t(varId); - _assignedRegs ^= Support::bitMask(newId) ^ Support::bitMask(oldId); - } - - inline void swap(uint32_t aVarId, uint32_t aRegId, uint32_t bVarId, uint32_t bRegId) noexcept { - ASMJIT_ASSERT(isAssigned(aRegId)); - ASMJIT_ASSERT(isAssigned(bRegId)); - ASMJIT_ASSERT(_physToVarId[aRegId] == aVarId); - ASMJIT_ASSERT(_physToVarId[bRegId] == bVarId); - - _physToVarId[aRegId] = uint8_t(bVarId); - _physToVarId[bRegId] = uint8_t(aVarId); - } - - inline void unassign(uint32_t varId, uint32_t regId) noexcept { - ASMJIT_ASSERT(isAssigned(regId)); - ASMJIT_ASSERT(_physToVarId[regId] == varId); - - DebugUtils::unused(varId); - _physToVarId[regId] = uint8_t(kVarIdNone); - _assignedRegs ^= Support::bitMask(regId); - } - - inline uint32_t archRegs() const noexcept { return _archRegs; } - inline uint32_t workRegs() const noexcept { return _workRegs; } - inline uint32_t usedRegs() const noexcept { return _usedRegs; } - inline uint32_t assignedRegs() const noexcept { return _assignedRegs; } - inline uint32_t dstRegs() const noexcept { return _dstRegs; } - inline uint32_t availableRegs() const noexcept { return _workRegs & ~_assignedRegs; } - }; - - //! Architecture traits. - const ArchTraits* _archTraits = nullptr; - const RAConstraints* _constraints = nullptr; - //! Architecture identifier. - uint8_t _arch = 0; - //! Has arguments passed via stack (SRC). - bool _hasStackSrc = false; - //! Has preserved frame-pointer (FP). - bool _hasPreservedFP = false; - //! Has arguments assigned to stack (DST). - uint8_t _stackDstMask = 0; - //! Register swap groups (bit-mask). - uint8_t _regSwapsMask = 0; - uint8_t _saVarId = kVarIdNone; - uint32_t _varCount = 0; - WorkData _workData[BaseReg::kGroupVirt]; - Var _vars[Globals::kMaxFuncArgs * Globals::kMaxValuePack + 1]; - - FuncArgsContext() noexcept; - - inline const ArchTraits& archTraits() const noexcept { return *_archTraits; } - inline uint32_t arch() const noexcept { return _arch; } - - inline uint32_t varCount() const noexcept { return _varCount; } - inline size_t indexOf(const Var* var) const noexcept { return (size_t)(var - _vars); } - - inline Var& var(size_t varId) noexcept { return _vars[varId]; } - inline const Var& var(size_t varId) const noexcept { return _vars[varId]; } - - Error initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args, const RAConstraints* constraints) noexcept; - Error markScratchRegs(FuncFrame& frame) noexcept; - Error markDstRegsDirty(FuncFrame& frame) noexcept; - Error markStackArgsReg(FuncFrame& frame) noexcept; -}; - -//! \} -//! \endcond - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/globals.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/globals.cpp deleted file mode 100644 index dc5083b..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/globals.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/globals.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::DebugUtils] -// ============================================================================ - -ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept { -#ifndef ASMJIT_NO_TEXT - // @EnumStringBegin{"enum": "ErrorCode", "output": "sError", "strip": "kError"}@ - static const char sErrorString[] = - "Ok\0" - "OutOfMemory\0" - "InvalidArgument\0" - "InvalidState\0" - "InvalidArch\0" - "NotInitialized\0" - "AlreadyInitialized\0" - "FeatureNotEnabled\0" - "TooManyHandles\0" - "TooLarge\0" - "NoCodeGenerated\0" - "InvalidDirective\0" - "InvalidLabel\0" - "TooManyLabels\0" - "LabelAlreadyBound\0" - "LabelAlreadyDefined\0" - "LabelNameTooLong\0" - "InvalidLabelName\0" - "InvalidParentLabel\0" - "NonLocalLabelCannotHaveParent\0" - "InvalidSection\0" - "TooManySections\0" - "InvalidSectionName\0" - "TooManyRelocations\0" - "InvalidRelocEntry\0" - "RelocOffsetOutOfRange\0" - "InvalidAssignment\0" - "InvalidInstruction\0" - "InvalidRegType\0" - "InvalidRegGroup\0" - "InvalidPhysId\0" - "InvalidVirtId\0" - "InvalidElementIndex\0" - "InvalidPrefixCombination\0" - "InvalidLockPrefix\0" - "InvalidXAcquirePrefix\0" - "InvalidXReleasePrefix\0" - "InvalidRepPrefix\0" - "InvalidRexPrefix\0" - "InvalidExtraReg\0" - "InvalidKMaskUse\0" - "InvalidKZeroUse\0" - "InvalidBroadcast\0" - "InvalidEROrSAE\0" - "InvalidAddress\0" - "InvalidAddressIndex\0" - "InvalidAddressScale\0" - "InvalidAddress64Bit\0" - "InvalidAddress64BitZeroExtension\0" - "InvalidDisplacement\0" - "InvalidSegment\0" - "InvalidImmediate\0" - "InvalidOperandSize\0" - "AmbiguousOperandSize\0" - "OperandSizeMismatch\0" - "InvalidOption\0" - "OptionAlreadyDefined\0" - "InvalidTypeId\0" - "InvalidUseOfGpbHi\0" - "InvalidUseOfGpq\0" - "InvalidUseOfF80\0" - "NotConsecutiveRegs\0" - "IllegalVirtReg\0" - "TooManyVirtRegs\0" - "NoMorePhysRegs\0" - "OverlappedRegs\0" - "OverlappingStackRegWithRegArg\0" - "ExpressionLabelNotBound\0" - "ExpressionOverflow\0" - "FailedToOpenAnonymousMemory\0" - "\0"; - - static const uint16_t sErrorIndex[] = { - 0, 3, 15, 31, 44, 56, 71, 90, 108, 123, 132, 148, 165, 178, 192, 210, 230, - 247, 264, 283, 313, 328, 344, 363, 382, 400, 422, 440, 459, 474, 490, 504, - 518, 538, 563, 581, 603, 625, 642, 659, 675, 691, 707, 724, 739, 754, 774, - 794, 814, 847, 867, 882, 899, 918, 939, 959, 973, 994, 1008, 1026, 1042, - 1058, 1077, 1092, 1108, 1123, 1138, 1168, 1192, 1211, 1239 - }; - // @EnumStringEnd@ - - return sErrorString + sErrorIndex[Support::min(err, kErrorCount)]; -#else - DebugUtils::unused(err); - static const char noMessage[] = ""; - return noMessage; -#endif -} - -ASMJIT_FAVOR_SIZE void DebugUtils::debugOutput(const char* str) noexcept { -#if defined(_WIN32) - ::OutputDebugStringA(str); -#else - ::fputs(str, stderr); -#endif -} - -ASMJIT_FAVOR_SIZE void DebugUtils::assertionFailed(const char* file, int line, const char* msg) noexcept { - char str[1024]; - - snprintf(str, 1024, - "[asmjit] Assertion failed at %s (line %d):\n" - "[asmjit] %s\n", file, line, msg); - - debugOutput(str); - ::abort(); -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/globals.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/globals.h deleted file mode 100644 index 3b7bfc9..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/globals.h +++ /dev/null @@ -1,462 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_GLOBALS_H_INCLUDED -#define ASMJIT_CORE_GLOBALS_H_INCLUDED - -#include "../core/api-config.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::Support] -// ============================================================================ - -//! \cond INTERNAL -//! \addtogroup asmjit_utilities -//! \{ -namespace Support { - //! Cast designed to cast between function and void* pointers. - template - static inline Dst ptr_cast_impl(Src p) noexcept { return (Dst)p; } -} // {Support} - -#if defined(ASMJIT_NO_STDCXX) -namespace Support { - ASMJIT_INLINE void* operatorNew(size_t n) noexcept { return malloc(n); } - ASMJIT_INLINE void operatorDelete(void* p) noexcept { if (p) free(p); } -} // {Support} - -#define ASMJIT_BASE_CLASS(TYPE) \ - ASMJIT_INLINE void* operator new(size_t n) noexcept { \ - return Support::operatorNew(n); \ - } \ - \ - ASMJIT_INLINE void operator delete(void* p) noexcept { \ - Support::operatorDelete(p); \ - } \ - \ - ASMJIT_INLINE void* operator new(size_t, void* p) noexcept { return p; } \ - ASMJIT_INLINE void operator delete(void*, void*) noexcept {} -#else -#define ASMJIT_BASE_CLASS(TYPE) -#endif - -//! \} -//! \endcond - -// ============================================================================ -// [asmjit::Globals] -// ============================================================================ - -//! \addtogroup asmjit_core -//! \{ - -//! Contains typedefs, constants, and variables used globally by AsmJit. -namespace Globals { - -// ============================================================================ -// [asmjit::Globals::] -// ============================================================================ - -//! Host memory allocator overhead. -static constexpr uint32_t kAllocOverhead = uint32_t(sizeof(intptr_t) * 4); - -//! Host memory allocator alignment. -static constexpr uint32_t kAllocAlignment = 8; - -//! Aggressive growing strategy threshold. -static constexpr uint32_t kGrowThreshold = 1024 * 1024 * 16; - -//! Maximum depth of RB-Tree is: -//! -//! `2 * log2(n + 1)` -//! -//! Size of RB node is at least two pointers (without data), -//! so a theoretical architecture limit would be: -//! -//! `2 * log2(addressableMemorySize / sizeof(Node) + 1)` -//! -//! Which yields 30 on 32-bit arch and 61 on 64-bit arch. -//! The final value was adjusted by +1 for safety reasons. -static constexpr uint32_t kMaxTreeHeight = (ASMJIT_ARCH_BITS == 32 ? 30 : 61) + 1; - -//! Maximum number of operands per a single instruction. -static constexpr uint32_t kMaxOpCount = 6; - -//! Maximum arguments of a function supported by the Compiler / Function API. -static constexpr uint32_t kMaxFuncArgs = 16; - -//! The number of values that can be assigned to a single function argument or -//! return value. -static constexpr uint32_t kMaxValuePack = 4; - -//! Maximum number of physical registers AsmJit can use per register group. -static constexpr uint32_t kMaxPhysRegs = 32; - -//! Maximum alignment. -static constexpr uint32_t kMaxAlignment = 64; - -//! Maximum label or symbol size in bytes. -static constexpr uint32_t kMaxLabelNameSize = 2048; - -//! Maximum section name size. -static constexpr uint32_t kMaxSectionNameSize = 35; - -//! Maximum size of comment. -static constexpr uint32_t kMaxCommentSize = 1024; - -//! Invalid identifier. -static constexpr uint32_t kInvalidId = 0xFFFFFFFFu; - -//! Returned by `indexOf()` and similar when working with containers that use 32-bit index/size. -static constexpr uint32_t kNotFound = 0xFFFFFFFFu; - -//! Invalid base address. -static constexpr uint64_t kNoBaseAddress = ~uint64_t(0); - -// ============================================================================ -// [asmjit::Globals::ResetPolicy] -// ============================================================================ - -//! Reset policy used by most `reset()` functions. -enum ResetPolicy : uint32_t { - //! Soft reset, doesn't deallocate memory (default). - kResetSoft = 0, - //! Hard reset, releases all memory used, if any. - kResetHard = 1 -}; - -// ============================================================================ -// [asmjit::Globals::Link] -// ============================================================================ - -enum Link : uint32_t { - kLinkLeft = 0, - kLinkRight = 1, - - kLinkPrev = 0, - kLinkNext = 1, - - kLinkFirst = 0, - kLinkLast = 1, - - kLinkCount = 2 -}; - -struct Init_ {}; -struct NoInit_ {}; - -static const constexpr Init_ Init {}; -static const constexpr NoInit_ NoInit {}; - -} // {Globals} - -// ============================================================================ -// [asmjit::ByteOrder] -// ============================================================================ - -//! Byte order. -namespace ByteOrder { - enum : uint32_t { - kLE = 0, - kBE = 1, - kNative = ASMJIT_ARCH_LE ? kLE : kBE, - kSwapped = ASMJIT_ARCH_LE ? kBE : kLE - }; -} - -// ============================================================================ -// [asmjit::ptr_as_func / func_as_ptr] -// ============================================================================ - -template -static inline Func ptr_as_func(void* func) noexcept { return Support::ptr_cast_impl(func); } - -template -static inline void* func_as_ptr(Func func) noexcept { return Support::ptr_cast_impl(func); } - -//! \} - -// ============================================================================ -// [asmjit::Error] -// ============================================================================ - -//! \addtogroup asmjit_error_handling -//! \{ - -//! AsmJit error type (uint32_t). -typedef uint32_t Error; - -//! AsmJit error codes. -enum ErrorCode : uint32_t { - // @EnumValuesBegin{"enum": "ErrorCode"}@ - - //! No error (success). - kErrorOk = 0, - - //! Out of memory. - kErrorOutOfMemory, - - //! Invalid argument. - kErrorInvalidArgument, - - //! Invalid state. - //! - //! If this error is returned it means that either you are doing something - //! wrong or AsmJit caught itself by doing something wrong. This error should - //! never be ignored. - kErrorInvalidState, - - //! Invalid or incompatible architecture. - kErrorInvalidArch, - - //! The object is not initialized. - kErrorNotInitialized, - //! The object is already initialized. - kErrorAlreadyInitialized, - - //! Built-in feature was disabled at compile time and it's not available. - kErrorFeatureNotEnabled, - - //! Too many handles (Windows) or file descriptors (Unix/Posix). - kErrorTooManyHandles, - //! Code generated is larger than allowed. - kErrorTooLarge, - - //! No code generated. - //! - //! Returned by runtime if the \ref CodeHolder contains no code. - kErrorNoCodeGenerated, - - //! Invalid directive. - kErrorInvalidDirective, - //! Attempt to use uninitialized label. - kErrorInvalidLabel, - //! Label index overflow - a single \ref BaseAssembler instance can hold - //! almost 2^32 (4 billion) labels. If there is an attempt to create more - //! labels then this error is returned. - kErrorTooManyLabels, - //! Label is already bound. - kErrorLabelAlreadyBound, - //! Label is already defined (named labels). - kErrorLabelAlreadyDefined, - //! Label name is too long. - kErrorLabelNameTooLong, - //! Label must always be local if it's anonymous (without a name). - kErrorInvalidLabelName, - //! Parent id passed to \ref CodeHolder::newNamedLabelEntry() was invalid. - kErrorInvalidParentLabel, - //! Parent id specified for a non-local (global) label. - kErrorNonLocalLabelCannotHaveParent, - - //! Invalid section. - kErrorInvalidSection, - //! Too many sections (section index overflow). - kErrorTooManySections, - //! Invalid section name (most probably too long). - kErrorInvalidSectionName, - - //! Relocation index overflow (too many relocations). - kErrorTooManyRelocations, - //! Invalid relocation entry. - kErrorInvalidRelocEntry, - //! Reloc entry contains address that is out of range (unencodable). - kErrorRelocOffsetOutOfRange, - - //! Invalid assignment to a register, function argument, or function return value. - kErrorInvalidAssignment, - //! Invalid instruction. - kErrorInvalidInstruction, - //! Invalid register type. - kErrorInvalidRegType, - //! Invalid register group. - kErrorInvalidRegGroup, - //! Invalid physical register id. - kErrorInvalidPhysId, - //! Invalid virtual register id. - kErrorInvalidVirtId, - //! Invalid element index (ARM). - kErrorInvalidElementIndex, - //! Invalid prefix combination (X86|X64). - kErrorInvalidPrefixCombination, - //! Invalid LOCK prefix (X86|X64). - kErrorInvalidLockPrefix, - //! Invalid XACQUIRE prefix (X86|X64). - kErrorInvalidXAcquirePrefix, - //! Invalid XRELEASE prefix (X86|X64). - kErrorInvalidXReleasePrefix, - //! Invalid REP prefix (X86|X64). - kErrorInvalidRepPrefix, - //! Invalid REX prefix (X86|X64). - kErrorInvalidRexPrefix, - //! Invalid {...} register (X86|X64). - kErrorInvalidExtraReg, - //! Invalid {k} use (not supported by the instruction) (X86|X64). - kErrorInvalidKMaskUse, - //! Invalid {k}{z} use (not supported by the instruction) (X86|X64). - kErrorInvalidKZeroUse, - //! Invalid broadcast - Currently only related to invalid use of AVX-512 {1tox} (X86|X64). - kErrorInvalidBroadcast, - //! Invalid 'embedded-rounding' {er} or 'suppress-all-exceptions' {sae} (AVX-512) (X86|X64). - kErrorInvalidEROrSAE, - //! Invalid address used (not encodable). - kErrorInvalidAddress, - //! Invalid index register used in memory address (not encodable). - kErrorInvalidAddressIndex, - //! Invalid address scale (not encodable). - kErrorInvalidAddressScale, - //! Invalid use of 64-bit address. - kErrorInvalidAddress64Bit, - //! Invalid use of 64-bit address that require 32-bit zero-extension (X64). - kErrorInvalidAddress64BitZeroExtension, - //! Invalid displacement (not encodable). - kErrorInvalidDisplacement, - //! Invalid segment (X86). - kErrorInvalidSegment, - - //! Invalid immediate (out of bounds on X86 and invalid pattern on ARM). - kErrorInvalidImmediate, - - //! Invalid operand size. - kErrorInvalidOperandSize, - //! Ambiguous operand size (memory has zero size while it's required to determine the operation type. - kErrorAmbiguousOperandSize, - //! Mismatching operand size (size of multiple operands doesn't match the operation size). - kErrorOperandSizeMismatch, - - //! Invalid option. - kErrorInvalidOption, - //! Option already defined. - kErrorOptionAlreadyDefined, - - //! Invalid TypeId. - kErrorInvalidTypeId, - //! Invalid use of a 8-bit GPB-HIGH register. - kErrorInvalidUseOfGpbHi, - //! Invalid use of a 64-bit GPQ register in 32-bit mode. - kErrorInvalidUseOfGpq, - //! Invalid use of an 80-bit float (\ref Type::kIdF80). - kErrorInvalidUseOfF80, - //! Some registers in the instruction muse be consecutive (some ARM and AVX512 - //! neural-net instructions). - kErrorNotConsecutiveRegs, - - //! Illegal virtual register - reported by instruction validation. - kErrorIllegalVirtReg, - //! AsmJit cannot create more virtual registers. - kErrorTooManyVirtRegs, - - //! AsmJit requires a physical register, but no one is available. - kErrorNoMorePhysRegs, - //! A variable has been assigned more than once to a function argument (BaseCompiler). - kErrorOverlappedRegs, - //! Invalid register to hold stack arguments offset. - kErrorOverlappingStackRegWithRegArg, - - //! Unbound label cannot be evaluated by expression. - kErrorExpressionLabelNotBound, - //! Arithmetic overflow during expression evaluation. - kErrorExpressionOverflow, - - //! Failed to open anonymous memory handle or file descriptor. - kErrorFailedToOpenAnonymousMemory, - - // @EnumValuesEnd@ - - //! Count of AsmJit error codes. - kErrorCount -}; - -// ============================================================================ -// [asmjit::DebugUtils] -// ============================================================================ - -//! Debugging utilities. -namespace DebugUtils { - -//! \cond INTERNAL -//! Used to silence warnings about unused arguments or variables. -template -static ASMJIT_INLINE void unused(Args&&...) noexcept {} -//! \endcond - -//! Returns the error `err` passed. -//! -//! Provided for debugging purposes. Putting a breakpoint inside `errored` can -//! help with tracing the origin of any error reported / returned by AsmJit. -static constexpr Error errored(Error err) noexcept { return err; } - -//! Returns a printable version of `asmjit::Error` code. -ASMJIT_API const char* errorAsString(Error err) noexcept; - -//! Called to output debugging message(s). -ASMJIT_API void debugOutput(const char* str) noexcept; - -//! Called on assertion failure. -//! -//! \param file Source file name where it happened. -//! \param line Line in the source file. -//! \param msg Message to display. -//! -//! If you have problems with assertion failures a breakpoint can be put -//! at \ref assertionFailed() function (asmjit/core/globals.cpp). A call stack -//! will be available when such assertion failure is triggered. AsmJit always -//! returns errors on failures, assertions are a last resort and usually mean -//! unrecoverable state due to out of range array access or totally invalid -//! arguments like nullptr where a valid pointer should be provided, etc... -ASMJIT_API void ASMJIT_NORETURN assertionFailed(const char* file, int line, const char* msg) noexcept; - -} // {DebugUtils} - -//! \def ASMJIT_ASSERT(...) -//! -//! AsmJit's own assert macro used in AsmJit code-base. -#if defined(ASMJIT_BUILD_DEBUG) -#define ASMJIT_ASSERT(...) \ - do { \ - if (ASMJIT_LIKELY(__VA_ARGS__)) \ - break; \ - ::asmjit::DebugUtils::assertionFailed(__FILE__, __LINE__, #__VA_ARGS__); \ - } while (0) -#else -#define ASMJIT_ASSERT(...) ((void)0) -#endif - -//! \def ASMJIT_PROPAGATE(...) -//! -//! Propagates a possible `Error` produced by `...` to the caller by returning -//! the error immediately. Used by AsmJit internally, but kept public for users -//! that want to use the same technique to propagate errors to the caller. -#define ASMJIT_PROPAGATE(...) \ - do { \ - ::asmjit::Error _err = __VA_ARGS__; \ - if (ASMJIT_UNLIKELY(_err)) \ - return _err; \ - } while (0) - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_GLOBALS_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/inst.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/inst.cpp deleted file mode 100644 index a79fe83..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/inst.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#ifdef ASMJIT_BUILD_X86 - -#include "../core/archtraits.h" -#include "../core/inst.h" - -#ifdef ASMJIT_BUILD_X86 - #include "../x86/x86instapi_p.h" -#endif - -#ifdef ASMJIT_BUILD_ARM - #include "../arm/a64instapi_p.h" -#endif - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::InstAPI - Text] -// ============================================================================ - -#ifndef ASMJIT_NO_TEXT -Error InstAPI::instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept { -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::InstInternal::instIdToString(arch, instId, output); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isArchAArch64(arch)) - return a64::InstInternal::instIdToString(arch, instId, output); -#endif - - return DebugUtils::errored(kErrorInvalidArch); -} - -uint32_t InstAPI::stringToInstId(uint32_t arch, const char* s, size_t len) noexcept { -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::InstInternal::stringToInstId(arch, s, len); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isArchAArch64(arch)) - return a64::InstInternal::stringToInstId(arch, s, len); -#endif - - return 0; -} -#endif // !ASMJIT_NO_TEXT - -// ============================================================================ -// [asmjit::InstAPI - Validate] -// ============================================================================ - -#ifndef ASMJIT_NO_VALIDATION -Error InstAPI::validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept { -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::InstInternal::validate(arch, inst, operands, opCount, validationFlags); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isArchAArch64(arch)) - return a64::InstInternal::validate(arch, inst, operands, opCount, validationFlags); -#endif - - return DebugUtils::errored(kErrorInvalidArch); -} -#endif // !ASMJIT_NO_VALIDATION - -// ============================================================================ -// [asmjit::InstAPI - QueryRWInfo] -// ============================================================================ - -#ifndef ASMJIT_NO_INTROSPECTION -Error InstAPI::queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept { - if (ASMJIT_UNLIKELY(opCount > Globals::kMaxOpCount)) - return DebugUtils::errored(kErrorInvalidArgument); - -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::InstInternal::queryRWInfo(arch, inst, operands, opCount, out); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isArchAArch64(arch)) - return a64::InstInternal::queryRWInfo(arch, inst, operands, opCount, out); -#endif - - return DebugUtils::errored(kErrorInvalidArch); -} -#endif // !ASMJIT_NO_INTROSPECTION - -// ============================================================================ -// [asmjit::InstAPI - QueryFeatures] -// ============================================================================ - -#ifndef ASMJIT_NO_INTROSPECTION -Error InstAPI::queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept { -#ifdef ASMJIT_BUILD_X86 - if (Environment::isFamilyX86(arch)) - return x86::InstInternal::queryFeatures(arch, inst, operands, opCount, out); -#endif - -#ifdef ASMJIT_BUILD_ARM - if (Environment::isArchAArch64(arch)) - return a64::InstInternal::queryFeatures(arch, inst, operands, opCount, out); -#endif - - return DebugUtils::errored(kErrorInvalidArch); -} -#endif // !ASMJIT_NO_INTROSPECTION - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_BUILD_X86 diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/inst.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/inst.h deleted file mode 100644 index bc3708d..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/inst.h +++ /dev/null @@ -1,559 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_INST_H_INCLUDED -#define ASMJIT_CORE_INST_H_INCLUDED - -#include "../core/cpuinfo.h" -#include "../core/operand.h" -#include "../core/string.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_instruction_db -//! \{ - -// ============================================================================ -// [asmjit::BaseInst] -// ============================================================================ - -//! Instruction id, options, and extraReg in a single structure. This structure -//! exists mainly to simplify analysis and validation API that requires `BaseInst` -//! and `Operand[]` array. -class BaseInst { -public: - //! Instruction id, see \ref BaseInst::Id or {arch-specific}::Inst::Id. - uint32_t _id; - //! Instruction options, see \ref BaseInst::Options or {arch-specific}::Inst::Options. - uint32_t _options; - //! Extra register used by instruction (either REP register or AVX-512 selector). - RegOnly _extraReg; - - enum Id : uint32_t { - //! Invalid or uninitialized instruction id. - kIdNone = 0x00000000u, - //! Abstract instruction (BaseBuilder and BaseCompiler). - kIdAbstract = 0x80000000u - }; - - enum Options : uint32_t { - //! Used internally by emitters for handling errors and rare cases. - kOptionReserved = 0x00000001u, - - //! Prevents following a jump during compilation (BaseCompiler). - kOptionUnfollow = 0x00000002u, - - //! Overwrite the destination operand(s) (BaseCompiler). - //! - //! Hint that is important for register liveness analysis. It tells the - //! compiler that the destination operand will be overwritten now or by - //! adjacent instructions. BaseCompiler knows when a register is completely - //! overwritten by a single instruction, for example you don't have to - //! mark "movaps" or "pxor x, x", however, if a pair of instructions is - //! used and the first of them doesn't completely overwrite the content - //! of the destination, BaseCompiler fails to mark that register as dead. - //! - //! X86 Specific - //! ------------ - //! - //! - All instructions that always overwrite at least the size of the - //! register the virtual-register uses , for example "mov", "movq", - //! "movaps" don't need the overwrite option to be used - conversion, - //! shuffle, and other miscellaneous instructions included. - //! - //! - All instructions that clear the destination register if all operands - //! are the same, for example "xor x, x", "pcmpeqb x x", etc... - //! - //! - Consecutive instructions that partially overwrite the variable until - //! there is no old content require `BaseCompiler::overwrite()` to be used. - //! Some examples (not always the best use cases thought): - //! - //! - `movlps xmm0, ?` followed by `movhps xmm0, ?` and vice versa - //! - `movlpd xmm0, ?` followed by `movhpd xmm0, ?` and vice versa - //! - `mov al, ?` followed by `and ax, 0xFF` - //! - `mov al, ?` followed by `mov ah, al` - //! - `pinsrq xmm0, ?, 0` followed by `pinsrq xmm0, ?, 1` - //! - //! - If allocated variable is used temporarily for scalar operations. For - //! example if you allocate a full vector like `x86::Compiler::newXmm()` - //! and then use that vector for scalar operations you should use - //! `overwrite()` directive: - //! - //! - `sqrtss x, y` - only LO element of `x` is changed, if you don't - //! use HI elements, use `compiler.overwrite().sqrtss(x, y)`. - kOptionOverwrite = 0x00000004u, - - //! Emit short-form of the instruction. - kOptionShortForm = 0x00000010u, - //! Emit long-form of the instruction. - kOptionLongForm = 0x00000020u, - - //! Conditional jump is likely to be taken. - kOptionTaken = 0x00000040u, - //! Conditional jump is unlikely to be taken. - kOptionNotTaken = 0x00000080u - }; - - //! Control type. - enum ControlType : uint32_t { - //! No control type (doesn't jump). - kControlNone = 0u, - //! Unconditional jump. - kControlJump = 1u, - //! Conditional jump (branch). - kControlBranch = 2u, - //! Function call. - kControlCall = 3u, - //! Function return. - kControlReturn = 4u - }; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new BaseInst instance with `id` and `options` set. - //! - //! Default values of `id` and `options` are zero, which means none instruciton. - //! Such instruction is guaranteed to never exist for any architecture supported - //! by AsmJit. - inline explicit BaseInst(uint32_t id = 0, uint32_t options = 0) noexcept - : _id(id), - _options(options), - _extraReg() {} - - inline BaseInst(uint32_t id, uint32_t options, const RegOnly& extraReg) noexcept - : _id(id), - _options(options), - _extraReg(extraReg) {} - - inline BaseInst(uint32_t id, uint32_t options, const BaseReg& extraReg) noexcept - : _id(id), - _options(options), - _extraReg { extraReg.signature(), extraReg.id() } {} - - //! \} - - //! \name Instruction ID - //! \{ - - //! Returns the instruction id. - inline uint32_t id() const noexcept { return _id; } - //! Sets the instruction id to the given `id`. - inline void setId(uint32_t id) noexcept { _id = id; } - //! Resets the instruction id to zero, see \ref kIdNone. - inline void resetId() noexcept { _id = 0; } - - //! \} - - //! \name Instruction Options - //! \{ - - inline uint32_t options() const noexcept { return _options; } - inline bool hasOption(uint32_t option) const noexcept { return (_options & option) != 0; } - inline void setOptions(uint32_t options) noexcept { _options = options; } - inline void addOptions(uint32_t options) noexcept { _options |= options; } - inline void clearOptions(uint32_t options) noexcept { _options &= ~options; } - inline void resetOptions() noexcept { _options = 0; } - - //! \} - - //! \name Extra Register - //! \{ - - inline bool hasExtraReg() const noexcept { return _extraReg.isReg(); } - inline RegOnly& extraReg() noexcept { return _extraReg; } - inline const RegOnly& extraReg() const noexcept { return _extraReg; } - inline void setExtraReg(const BaseReg& reg) noexcept { _extraReg.init(reg); } - inline void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); } - inline void resetExtraReg() noexcept { _extraReg.reset(); } - - //! \} -}; - -// ============================================================================ -// [asmjit::OpRWInfo] -// ============================================================================ - -//! Read/Write information related to a single operand, used by \ref InstRWInfo. -struct OpRWInfo { - //! Read/Write flags, see \ref OpRWInfo::Flags. - uint32_t _opFlags; - //! Physical register index, if required. - uint8_t _physId; - //! Size of a possible memory operand that can replace a register operand. - uint8_t _rmSize; - //! Reserved for future use. - uint8_t _reserved[2]; - //! Read bit-mask where each bit represents one byte read from Reg/Mem. - uint64_t _readByteMask; - //! Write bit-mask where each bit represents one byte written to Reg/Mem. - uint64_t _writeByteMask; - //! Zero/Sign extend bit-mask where each bit represents one byte written to Reg/Mem. - uint64_t _extendByteMask; - - //! Flags describe how the operand is accessed and some additional information. - enum Flags : uint32_t { - //! Operand is read. - kRead = 0x00000001u, - - //! Operand is written. - kWrite = 0x00000002u, - - //! Operand is both read and written. - kRW = 0x00000003u, - - //! Register operand can be replaced by a memory operand. - kRegMem = 0x00000004u, - - //! The `extendByteMask()` represents a zero extension. - kZExt = 0x00000010u, - - //! Register operand must use \ref physId(). - kRegPhysId = 0x00000100u, - //! Base register of a memory operand must use \ref physId(). - kMemPhysId = 0x00000200u, - - //! This memory operand is only used to encode registers and doesn't access memory. - //! - //! X86 Specific - //! ------------ - //! - //! Instructions that use such feature include BNDLDX, BNDSTX, and LEA. - kMemFake = 0x000000400u, - - //! Base register of the memory operand will be read. - kMemBaseRead = 0x00001000u, - //! Base register of the memory operand will be written. - kMemBaseWrite = 0x00002000u, - //! Base register of the memory operand will be read & written. - kMemBaseRW = 0x00003000u, - - //! Index register of the memory operand will be read. - kMemIndexRead = 0x00004000u, - //! Index register of the memory operand will be written. - kMemIndexWrite = 0x00008000u, - //! Index register of the memory operand will be read & written. - kMemIndexRW = 0x0000C000u, - - //! Base register of the memory operand will be modified before the operation. - kMemBasePreModify = 0x00010000u, - //! Base register of the memory operand will be modified after the operation. - kMemBasePostModify = 0x00020000u - }; - - // Don't remove these asserts. Read/Write flags are used extensively - // by Compiler and they must always be compatible with constants below. - static_assert(kRead == 0x1, "OpRWInfo::kRead flag must be 0x1"); - static_assert(kWrite == 0x2, "OpRWInfo::kWrite flag must be 0x2"); - static_assert(kRegMem == 0x4, "OpRWInfo::kRegMem flag must be 0x4"); - - //! \name Reset - //! \{ - - //! Resets this operand information to all zeros. - inline void reset() noexcept { memset(this, 0, sizeof(*this)); } - - //! Resets this operand info (resets all members) and set common information - //! to the given `opFlags`, `regSize`, and possibly `physId`. - inline void reset(uint32_t opFlags, uint32_t regSize, uint32_t physId = BaseReg::kIdBad) noexcept { - _opFlags = opFlags; - _physId = uint8_t(physId); - _rmSize = uint8_t((opFlags & kRegMem) ? regSize : uint32_t(0)); - _resetReserved(); - - uint64_t mask = Support::lsbMask(regSize); - _readByteMask = opFlags & kRead ? mask : uint64_t(0); - _writeByteMask = opFlags & kWrite ? mask : uint64_t(0); - _extendByteMask = 0; - } - - inline void _resetReserved() noexcept { - memset(_reserved, 0, sizeof(_reserved)); - } - - //! \} - - //! \name Operand Flags - //! \{ - - //! Returns operand flags, see \ref Flags. - inline uint32_t opFlags() const noexcept { return _opFlags; } - //! Tests whether operand flags contain the given `flag`. - inline bool hasOpFlag(uint32_t flag) const noexcept { return (_opFlags & flag) != 0; } - - //! Adds the given `flags` to operand flags. - inline void addOpFlags(uint32_t flags) noexcept { _opFlags |= flags; } - //! Removes the given `flags` from operand flags. - inline void clearOpFlags(uint32_t flags) noexcept { _opFlags &= ~flags; } - - //! Tests whether this operand is read from. - inline bool isRead() const noexcept { return hasOpFlag(kRead); } - //! Tests whether this operand is written to. - inline bool isWrite() const noexcept { return hasOpFlag(kWrite); } - //! Tests whether this operand is both read and write. - inline bool isReadWrite() const noexcept { return (_opFlags & kRW) == kRW; } - //! Tests whether this operand is read only. - inline bool isReadOnly() const noexcept { return (_opFlags & kRW) == kRead; } - //! Tests whether this operand is write only. - inline bool isWriteOnly() const noexcept { return (_opFlags & kRW) == kWrite; } - - //! Tests whether this operand is Reg/Mem - //! - //! Reg/Mem operands can use either register or memory. - inline bool isRm() const noexcept { return hasOpFlag(kRegMem); } - - //! Tests whether the operand will be zero extended. - inline bool isZExt() const noexcept { return hasOpFlag(kZExt); } - - //! \} - - //! \name Memory Flags - //! \{ - - //! Tests whether this is a fake memory operand, which is only used, because - //! of encoding. Fake memory operands do not access any memory, they are only - //! used to encode registers. - inline bool isMemFake() const noexcept { return hasOpFlag(kMemFake); } - - //! Tests whether the instruction's memory BASE register is used. - inline bool isMemBaseUsed() const noexcept { return (_opFlags & kMemBaseRW) != 0; } - //! Tests whether the instruction reads from its BASE registers. - inline bool isMemBaseRead() const noexcept { return hasOpFlag(kMemBaseRead); } - //! Tests whether the instruction writes to its BASE registers. - inline bool isMemBaseWrite() const noexcept { return hasOpFlag(kMemBaseWrite); } - //! Tests whether the instruction reads and writes from/to its BASE registers. - inline bool isMemBaseReadWrite() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseRW; } - //! Tests whether the instruction only reads from its BASE registers. - inline bool isMemBaseReadOnly() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseRead; } - //! Tests whether the instruction only writes to its BASE registers. - inline bool isMemBaseWriteOnly() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseWrite; } - - //! Tests whether the instruction modifies the BASE register before it uses - //! it to calculate the target address. - inline bool isMemBasePreModify() const noexcept { return hasOpFlag(kMemBasePreModify); } - //! Tests whether the instruction modifies the BASE register after it uses - //! it to calculate the target address. - inline bool isMemBasePostModify() const noexcept { return hasOpFlag(kMemBasePostModify); } - - //! Tests whether the instruction's memory INDEX register is used. - inline bool isMemIndexUsed() const noexcept { return (_opFlags & kMemIndexRW) != 0; } - //! Tests whether the instruction reads the INDEX registers. - inline bool isMemIndexRead() const noexcept { return hasOpFlag(kMemIndexRead); } - //! Tests whether the instruction writes to its INDEX registers. - inline bool isMemIndexWrite() const noexcept { return hasOpFlag(kMemIndexWrite); } - //! Tests whether the instruction reads and writes from/to its INDEX registers. - inline bool isMemIndexReadWrite() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexRW; } - //! Tests whether the instruction only reads from its INDEX registers. - inline bool isMemIndexReadOnly() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexRead; } - //! Tests whether the instruction only writes to its INDEX registers. - inline bool isMemIndexWriteOnly() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexWrite; } - - //! \} - - //! \name Physical Register ID - //! \{ - - //! Returns a physical id of the register that is fixed for this operand. - //! - //! Returns \ref BaseReg::kIdBad if any register can be used. - inline uint32_t physId() const noexcept { return _physId; } - //! Tests whether \ref physId() would return a valid physical register id. - inline bool hasPhysId() const noexcept { return _physId != BaseReg::kIdBad; } - //! Sets physical register id, which would be fixed for this operand. - inline void setPhysId(uint32_t physId) noexcept { _physId = uint8_t(physId); } - - //! \} - - //! \name Reg/Mem Information - //! \{ - - //! Returns Reg/Mem size of the operand. - inline uint32_t rmSize() const noexcept { return _rmSize; } - //! Sets Reg/Mem size of the operand. - inline void setRmSize(uint32_t rmSize) noexcept { _rmSize = uint8_t(rmSize); } - - //! \} - - //! \name Read & Write Masks - //! \{ - - //! Returns read mask. - inline uint64_t readByteMask() const noexcept { return _readByteMask; } - //! Returns write mask. - inline uint64_t writeByteMask() const noexcept { return _writeByteMask; } - //! Returns extend mask. - inline uint64_t extendByteMask() const noexcept { return _extendByteMask; } - - //! Sets read mask. - inline void setReadByteMask(uint64_t mask) noexcept { _readByteMask = mask; } - //! Sets write mask. - inline void setWriteByteMask(uint64_t mask) noexcept { _writeByteMask = mask; } - //! Sets externd mask. - inline void setExtendByteMask(uint64_t mask) noexcept { _extendByteMask = mask; } - - //! \} -}; - -// ============================================================================ -// [asmjit::InstRWInfo] -// ============================================================================ - -//! Read/Write information of an instruction. -struct InstRWInfo { - //! Instruction flags (there are no flags at the moment, this field is reserved). - uint32_t _instFlags; - //! Mask of CPU flags read. - uint32_t _readFlags; - //! Mask of CPU flags written. - uint32_t _writeFlags; - //! Count of operands. - uint8_t _opCount; - //! CPU feature required for replacing register operand with memory operand. - uint8_t _rmFeature; - //! Reserved for future use. - uint8_t _reserved[18]; - //! Read/Write onfo of extra register (rep{} or kz{}). - OpRWInfo _extraReg; - //! Read/Write info of instruction operands. - OpRWInfo _operands[Globals::kMaxOpCount]; - - //! \name Commons - //! \{ - - //! Resets this RW information to all zeros. - inline void reset() noexcept { memset(this, 0, sizeof(*this)); } - - //! \} - - //! \name Instruction Flags - //! - //! \{ - - inline uint32_t instFlags() const noexcept { return _instFlags; } - inline bool hasInstFlag(uint32_t flag) const noexcept { return (_instFlags & flag) != 0; } - - //! } - - //! \name CPU Flags Read/Write Information - //! \{ - - //! Returns read flags of the instruction. - inline uint32_t readFlags() const noexcept { return _readFlags; } - //! Returns write flags of the instruction. - inline uint32_t writeFlags() const noexcept { return _writeFlags; } - - //! \} - - //! \name Reg/Mem Information - //! \{ - - //! Returns the CPU feature required to replace a register operand with memory - //! operand. If the returned feature is zero (none) then this instruction - //! either doesn't provide memory operand combination or there is no extra - //! CPU feature required. - //! - //! X86 Specific - //! ------------ - //! - //! Some AVX+ instructions may require extra features for replacing registers - //! with memory operands, for example VPSLLDQ instruction only supports - //! 'reg/reg/imm' combination on AVX/AVX2 capable CPUs and requires AVX-512 for - //! 'reg/mem/imm' combination. - inline uint32_t rmFeature() const noexcept { return _rmFeature; } - - //! \} - - //! \name Operand Read/Write Information - //! \{ - - //! Returns RW information of extra register operand (extraReg). - inline const OpRWInfo& extraReg() const noexcept { return _extraReg; } - - //! Returns RW information of all instruction's operands. - inline const OpRWInfo* operands() const noexcept { return _operands; } - - //! Returns RW information of the operand at the given `index`. - inline const OpRWInfo& operand(size_t index) const noexcept { - ASMJIT_ASSERT(index < Globals::kMaxOpCount); - return _operands[index]; - } - - //! Returns the number of operands this instruction has. - inline uint32_t opCount() const noexcept { return _opCount; } - - //! \} -}; - -// ============================================================================ -// [asmjit::InstAPI] -// ============================================================================ - -//! Instruction API. -namespace InstAPI { - -//! Validation flags that can be used with \ref InstAPI::validate(). -enum ValidationFlags : uint32_t { - //! Allow virtual registers in the instruction. - kValidationFlagVirtRegs = 0x01u -}; - -#ifndef ASMJIT_NO_TEXT -//! Appends the name of the instruction specified by `instId` and `instOptions` -//! into the `output` string. -//! -//! \note Instruction options would only affect instruction prefix & suffix, -//! other options would be ignored. If `instOptions` is zero then only raw -//! instruction name (without any additional text) will be appended. -ASMJIT_API Error instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept; - -//! Parses an instruction name in the given string `s`. Length is specified -//! by `len` argument, which can be `SIZE_MAX` if `s` is known to be null -//! terminated. -//! -//! Returns the parsed instruction id or \ref BaseInst::kIdNone if no such -//! instruction exists. -ASMJIT_API uint32_t stringToInstId(uint32_t arch, const char* s, size_t len) noexcept; -#endif // !ASMJIT_NO_TEXT - -#ifndef ASMJIT_NO_VALIDATION -//! Validates the given instruction considering the validation `flags`, see -//! \ref ValidationFlags. -ASMJIT_API Error validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags = 0) noexcept; -#endif // !ASMJIT_NO_VALIDATION - -#ifndef ASMJIT_NO_INTROSPECTION -//! Gets Read/Write information of the given instruction. -ASMJIT_API Error queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept; - -//! Gets CPU features required by the given instruction. -ASMJIT_API Error queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept; -#endif // !ASMJIT_NO_INTROSPECTION - -} // {InstAPI} - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_INST_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitallocator.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitallocator.cpp deleted file mode 100644 index b576e21..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitallocator.cpp +++ /dev/null @@ -1,1246 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#ifndef ASMJIT_NO_JIT - -#include "../core/archtraits.h" -#include "../core/jitallocator.h" -#include "../core/osutils_p.h" -#include "../core/support.h" -#include "../core/virtmem.h" -#include "../core/zone.h" -#include "../core/zonelist.h" -#include "../core/zonetree.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::JitAllocator - Constants] -// ============================================================================ - -enum JitAllocatorConstants : uint32_t { - //! Number of pools to use when `JitAllocator::kOptionUseMultiplePools` is set. - //! - //! Each pool increases granularity twice to make memory management more - //! efficient. Ideal number of pools appears to be 3 to 4 as it distributes - //! small and large functions properly. - kJitAllocatorMultiPoolCount = 3, - - //! Minimum granularity (and the default granularity for pool #0). - kJitAllocatorBaseGranularity = 64, - - //! Maximum block size (32MB). - kJitAllocatorMaxBlockSize = 1024 * 1024 * 32 -}; - -static inline uint32_t JitAllocator_defaultFillPattern() noexcept { - // X86 and X86_64 - 4x 'int3' instruction. - if (ASMJIT_ARCH_X86) - return 0xCCCCCCCCu; - - // Unknown... - return 0u; -} - -// ============================================================================ -// [asmjit::BitVectorRangeIterator] -// ============================================================================ - -template -class BitVectorRangeIterator { -public: - const T* _ptr; - size_t _idx; - size_t _end; - T _bitWord; - - enum : uint32_t { kBitWordSize = Support::bitSizeOf() }; - enum : T { kXorMask = B == 0 ? Support::allOnes() : T(0) }; - - ASMJIT_INLINE BitVectorRangeIterator(const T* data, size_t numBitWords) noexcept { - init(data, numBitWords); - } - - ASMJIT_INLINE BitVectorRangeIterator(const T* data, size_t numBitWords, size_t start, size_t end) noexcept { - init(data, numBitWords, start, end); - } - - ASMJIT_INLINE void init(const T* data, size_t numBitWords) noexcept { - init(data, numBitWords, 0, numBitWords * kBitWordSize); - } - - ASMJIT_INLINE void init(const T* data, size_t numBitWords, size_t start, size_t end) noexcept { - ASMJIT_ASSERT(numBitWords >= (end + kBitWordSize - 1) / kBitWordSize); - DebugUtils::unused(numBitWords); - - size_t idx = Support::alignDown(start, kBitWordSize); - const T* ptr = data + (idx / kBitWordSize); - - T bitWord = 0; - if (idx < end) - bitWord = (*ptr ^ kXorMask) & (Support::allOnes() << (start % kBitWordSize)); - - _ptr = ptr; - _idx = idx; - _end = end; - _bitWord = bitWord; - } - - ASMJIT_INLINE bool nextRange(size_t* rangeStart, size_t* rangeEnd, size_t rangeHint = std::numeric_limits::max()) noexcept { - // Skip all empty BitWords. - while (_bitWord == 0) { - _idx += kBitWordSize; - if (_idx >= _end) - return false; - _bitWord = (*++_ptr) ^ kXorMask; - } - - size_t i = Support::ctz(_bitWord); - - *rangeStart = _idx + i; - _bitWord = ~(_bitWord ^ ~(Support::allOnes() << i)); - - if (_bitWord == 0) { - *rangeEnd = Support::min(_idx + kBitWordSize, _end); - while (*rangeEnd - *rangeStart < rangeHint) { - _idx += kBitWordSize; - if (_idx >= _end) - break; - - _bitWord = (*++_ptr) ^ kXorMask; - if (_bitWord != Support::allOnes()) { - size_t j = Support::ctz(~_bitWord); - *rangeEnd = Support::min(_idx + j, _end); - _bitWord = _bitWord ^ ~(Support::allOnes() << j); - break; - } - - *rangeEnd = Support::min(_idx + kBitWordSize, _end); - _bitWord = 0; - continue; - } - - return true; - } - else { - size_t j = Support::ctz(_bitWord); - *rangeEnd = Support::min(_idx + j, _end); - - _bitWord = ~(_bitWord ^ ~(Support::allOnes() << j)); - return true; - } - } -}; - -// ============================================================================ -// [asmjit::JitAllocator - Pool] -// ============================================================================ - -class JitAllocatorBlock; - -class JitAllocatorPool { -public: - ASMJIT_NONCOPYABLE(JitAllocatorPool) - - inline JitAllocatorPool(uint32_t granularity) noexcept - : blocks(), - cursor(nullptr), - blockCount(0), - granularity(uint16_t(granularity)), - granularityLog2(uint8_t(Support::ctz(granularity))), - emptyBlockCount(0), - totalAreaSize(0), - totalAreaUsed(0), - totalOverheadBytes(0) {} - - inline void reset() noexcept { - blocks.reset(); - cursor = nullptr; - blockCount = 0; - totalAreaSize = 0; - totalAreaUsed = 0; - totalOverheadBytes = 0; - } - - inline size_t byteSizeFromAreaSize(uint32_t areaSize) const noexcept { return size_t(areaSize) * granularity; } - inline uint32_t areaSizeFromByteSize(size_t size) const noexcept { return uint32_t((size + granularity - 1) >> granularityLog2); } - - inline size_t bitWordCountFromAreaSize(uint32_t areaSize) const noexcept { - using namespace Support; - return alignUp(areaSize, kBitWordSizeInBits) / kBitWordSizeInBits; - } - - //! Double linked list of blocks. - ZoneList blocks; - //! Where to start looking first. - JitAllocatorBlock* cursor; - - //! Count of blocks. - uint32_t blockCount; - //! Allocation granularity. - uint16_t granularity; - //! Log2(granularity). - uint8_t granularityLog2; - //! Count of empty blocks (either 0 or 1 as we won't keep more blocks empty). - uint8_t emptyBlockCount; - - //! Number of bits reserved across all blocks. - size_t totalAreaSize; - //! Number of bits used across all blocks. - size_t totalAreaUsed; - //! Overhead of all blocks (in bytes). - size_t totalOverheadBytes; -}; - -// ============================================================================ -// [asmjit::JitAllocator - Block] -// ============================================================================ - -class JitAllocatorBlock : public ZoneTreeNodeT, - public ZoneListNode { -public: - ASMJIT_NONCOPYABLE(JitAllocatorBlock) - - enum Flags : uint32_t { - //! Block is empty. - kFlagEmpty = 0x00000001u, - //! Block is dirty (largestUnusedArea, searchStart, searchEnd). - kFlagDirty = 0x00000002u, - //! Block is dual-mapped. - kFlagDualMapped = 0x00000004u - }; - - //! Link to the pool that owns this block. - JitAllocatorPool* _pool; - //! Virtual memory mapping - either single mapping (both pointers equal) or - //! dual mapping, where one pointer is Read+Execute and the second Read+Write. - VirtMem::DualMapping _mapping; - //! Virtual memory size (block size) [bytes]. - size_t _blockSize; - - //! Block flags. - uint32_t _flags; - //! Size of the whole block area (bit-vector size). - uint32_t _areaSize; - //! Used area (number of bits in bit-vector used). - uint32_t _areaUsed; - //! The largest unused continuous area in the bit-vector (or `areaSize` to initiate rescan). - uint32_t _largestUnusedArea; - //! Start of a search range (for unused bits). - uint32_t _searchStart; - //! End of a search range (for unused bits). - uint32_t _searchEnd; - - //! Used bit-vector (0 = unused, 1 = used). - Support::BitWord* _usedBitVector; - //! Stop bit-vector (0 = don't care, 1 = stop). - Support::BitWord* _stopBitVector; - - inline JitAllocatorBlock( - JitAllocatorPool* pool, - VirtMem::DualMapping mapping, - size_t blockSize, - uint32_t blockFlags, - Support::BitWord* usedBitVector, - Support::BitWord* stopBitVector, - uint32_t areaSize) noexcept - : ZoneTreeNodeT(), - _pool(pool), - _mapping(mapping), - _blockSize(blockSize), - _flags(blockFlags), - _areaSize(areaSize), - _areaUsed(0), - _largestUnusedArea(areaSize), - _searchStart(0), - _searchEnd(areaSize), - _usedBitVector(usedBitVector), - _stopBitVector(stopBitVector) {} - - inline JitAllocatorPool* pool() const noexcept { return _pool; } - - inline uint8_t* roPtr() const noexcept { return static_cast(_mapping.ro); } - inline uint8_t* rwPtr() const noexcept { return static_cast(_mapping.rw); } - - inline bool hasFlag(uint32_t f) const noexcept { return (_flags & f) != 0; } - inline void addFlags(uint32_t f) noexcept { _flags |= f; } - inline void clearFlags(uint32_t f) noexcept { _flags &= ~f; } - - inline bool isDirty() const noexcept { return hasFlag(kFlagDirty); } - inline void makeDirty() noexcept { addFlags(kFlagDirty); } - - inline size_t blockSize() const noexcept { return _blockSize; } - - inline uint32_t areaSize() const noexcept { return _areaSize; } - inline uint32_t areaUsed() const noexcept { return _areaUsed; } - inline uint32_t areaAvailable() const noexcept { return _areaSize - _areaUsed; } - inline uint32_t largestUnusedArea() const noexcept { return _largestUnusedArea; } - - inline void decreaseUsedArea(uint32_t value) noexcept { - _areaUsed -= value; - _pool->totalAreaUsed -= value; - } - - inline void markAllocatedArea(uint32_t allocatedAreaStart, uint32_t allocatedAreaEnd) noexcept { - uint32_t allocatedAreaSize = allocatedAreaEnd - allocatedAreaStart; - - // Mark the newly allocated space as occupied and also the sentinel. - Support::bitVectorFill(_usedBitVector, allocatedAreaStart, allocatedAreaSize); - Support::bitVectorSetBit(_stopBitVector, allocatedAreaEnd - 1, true); - - // Update search region and statistics. - _pool->totalAreaUsed += allocatedAreaSize; - _areaUsed += allocatedAreaSize; - - if (areaAvailable() == 0) { - _searchStart = _areaSize; - _searchEnd = 0; - _largestUnusedArea = 0; - clearFlags(kFlagDirty); - } - else { - if (_searchStart == allocatedAreaStart) - _searchStart = allocatedAreaEnd; - if (_searchEnd == allocatedAreaEnd) - _searchEnd = allocatedAreaStart; - addFlags(kFlagDirty); - } - } - - inline void markReleasedArea(uint32_t releasedAreaStart, uint32_t releasedAreaEnd) noexcept { - uint32_t releasedAreaSize = releasedAreaEnd - releasedAreaStart; - - // Update the search region and statistics. - _pool->totalAreaUsed -= releasedAreaSize; - _areaUsed -= releasedAreaSize; - _searchStart = Support::min(_searchStart, releasedAreaStart); - _searchEnd = Support::max(_searchEnd, releasedAreaEnd); - - // Unmark occupied bits and also the sentinel. - Support::bitVectorClear(_usedBitVector, releasedAreaStart, releasedAreaSize); - Support::bitVectorSetBit(_stopBitVector, releasedAreaEnd - 1, false); - - if (areaUsed() == 0) { - _searchStart = 0; - _searchEnd = _areaSize; - _largestUnusedArea = _areaSize; - addFlags(kFlagEmpty); - clearFlags(kFlagDirty); - } - else { - addFlags(kFlagDirty); - } - } - - inline void markShrunkArea(uint32_t shrunkAreaStart, uint32_t shrunkAreaEnd) noexcept { - uint32_t shrunkAreaSize = shrunkAreaEnd - shrunkAreaStart; - - // Shrunk area cannot start at zero as it would mean that we have shrunk the first - // block to zero bytes, which is not allowed as such block must be released instead. - ASMJIT_ASSERT(shrunkAreaStart != 0); - ASMJIT_ASSERT(shrunkAreaSize != 0); - - // Update the search region and statistics. - _pool->totalAreaUsed -= shrunkAreaSize; - _areaUsed -= shrunkAreaSize; - _searchStart = Support::min(_searchStart, shrunkAreaStart); - _searchEnd = Support::max(_searchEnd, shrunkAreaEnd); - - // Unmark the released space and move the sentinel. - Support::bitVectorClear(_usedBitVector, shrunkAreaStart, shrunkAreaSize); - Support::bitVectorSetBit(_stopBitVector, shrunkAreaEnd - 1, false); - Support::bitVectorSetBit(_stopBitVector, shrunkAreaStart - 1, true); - - addFlags(kFlagDirty); - } - - // RBTree default CMP uses '<' and '>' operators. - inline bool operator<(const JitAllocatorBlock& other) const noexcept { return roPtr() < other.roPtr(); } - inline bool operator>(const JitAllocatorBlock& other) const noexcept { return roPtr() > other.roPtr(); } - - // Special implementation for querying blocks by `key`, which must be in `[BlockPtr, BlockPtr + BlockSize)` range. - inline bool operator<(const uint8_t* key) const noexcept { return roPtr() + _blockSize <= key; } - inline bool operator>(const uint8_t* key) const noexcept { return roPtr() > key; } -}; - -// ============================================================================ -// [asmjit::JitAllocator - PrivateImpl] -// ============================================================================ - -class JitAllocatorPrivateImpl : public JitAllocator::Impl { -public: - inline JitAllocatorPrivateImpl(JitAllocatorPool* pools, size_t poolCount) noexcept - : JitAllocator::Impl {}, - pools(pools), - poolCount(poolCount) {} - inline ~JitAllocatorPrivateImpl() noexcept {} - - //! Lock for thread safety. - mutable Lock lock; - //! System page size (also a minimum block size). - uint32_t pageSize; - - //! Blocks from all pools in RBTree. - ZoneTree tree; - //! Allocator pools. - JitAllocatorPool* pools; - //! Number of allocator pools. - size_t poolCount; -}; - -static const JitAllocator::Impl JitAllocatorImpl_none {}; -static const JitAllocator::CreateParams JitAllocatorParams_none {}; - -// ============================================================================ -// [asmjit::JitAllocator - Utilities] -// ============================================================================ - -static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator::CreateParams* params) noexcept { - VirtMem::Info vmInfo = VirtMem::info(); - - if (!params) - params = &JitAllocatorParams_none; - - uint32_t options = params->options; - uint32_t blockSize = params->blockSize; - uint32_t granularity = params->granularity; - uint32_t fillPattern = params->fillPattern; - - // Setup pool count to [1..3]. - size_t poolCount = 1; - if (options & JitAllocator::kOptionUseMultiplePools) - poolCount = kJitAllocatorMultiPoolCount;; - - // Setup block size [64kB..256MB]. - if (blockSize < 64 * 1024 || blockSize > 256 * 1024 * 1024 || !Support::isPowerOf2(blockSize)) - blockSize = vmInfo.pageGranularity; - - // Setup granularity [64..256]. - if (granularity < 64 || granularity > 256 || !Support::isPowerOf2(granularity)) - granularity = kJitAllocatorBaseGranularity; - - // Setup fill-pattern. - if (!(options & JitAllocator::kOptionCustomFillPattern)) - fillPattern = JitAllocator_defaultFillPattern(); - - size_t size = sizeof(JitAllocatorPrivateImpl) + sizeof(JitAllocatorPool) * poolCount; - void* p = ::malloc(size); - if (ASMJIT_UNLIKELY(!p)) - return nullptr; - - JitAllocatorPool* pools = reinterpret_cast((uint8_t*)p + sizeof(JitAllocatorPrivateImpl)); - JitAllocatorPrivateImpl* impl = new(p) JitAllocatorPrivateImpl(pools, poolCount); - - impl->options = options; - impl->blockSize = blockSize; - impl->granularity = granularity; - impl->fillPattern = fillPattern; - impl->pageSize = vmInfo.pageSize; - - for (size_t poolId = 0; poolId < poolCount; poolId++) - new(&pools[poolId]) JitAllocatorPool(granularity << poolId); - - return impl; -} - -static inline void JitAllocatorImpl_destroy(JitAllocatorPrivateImpl* impl) noexcept { - impl->~JitAllocatorPrivateImpl(); - ::free(impl); -} - -static inline size_t JitAllocatorImpl_sizeToPoolId(const JitAllocatorPrivateImpl* impl, size_t size) noexcept { - size_t poolId = impl->poolCount - 1; - size_t granularity = size_t(impl->granularity) << poolId; - - while (poolId) { - if (Support::alignUp(size, granularity) == size) - break; - poolId--; - granularity >>= 1; - } - - return poolId; -} - -static inline size_t JitAllocatorImpl_bitVectorSizeToByteSize(uint32_t areaSize) noexcept { - using Support::kBitWordSizeInBits; - return ((areaSize + kBitWordSizeInBits - 1u) / kBitWordSizeInBits) * sizeof(Support::BitWord); -} - -static inline size_t JitAllocatorImpl_calculateIdealBlockSize(JitAllocatorPrivateImpl* impl, JitAllocatorPool* pool, size_t allocationSize) noexcept { - JitAllocatorBlock* last = pool->blocks.last(); - size_t blockSize = last ? last->blockSize() : size_t(impl->blockSize); - - if (blockSize < kJitAllocatorMaxBlockSize) - blockSize *= 2u; - - if (allocationSize > blockSize) { - blockSize = Support::alignUp(allocationSize, impl->blockSize); - if (ASMJIT_UNLIKELY(blockSize < allocationSize)) - return 0; // Overflown. - } - - return blockSize; -} - -ASMJIT_FAVOR_SPEED static void JitAllocatorImpl_fillPattern(void* mem, uint32_t pattern, size_t sizeInBytes) noexcept { - size_t n = sizeInBytes / 4u; - uint32_t* p = static_cast(mem); - - for (size_t i = 0; i < n; i++) - p[i] = pattern; -} - -// Allocate a new `JitAllocatorBlock` for the given `blockSize`. -// -// NOTE: The block doesn't have `kFlagEmpty` flag set, because the new block -// is only allocated when it's actually needed, so it would be cleared anyway. -static JitAllocatorBlock* JitAllocatorImpl_newBlock(JitAllocatorPrivateImpl* impl, JitAllocatorPool* pool, size_t blockSize) noexcept { - using Support::BitWord; - using Support::kBitWordSizeInBits; - - uint32_t areaSize = uint32_t((blockSize + pool->granularity - 1) >> pool->granularityLog2); - uint32_t numBitWords = (areaSize + kBitWordSizeInBits - 1u) / kBitWordSizeInBits; - - JitAllocatorBlock* block = static_cast(::malloc(sizeof(JitAllocatorBlock))); - BitWord* bitWords = nullptr; - VirtMem::DualMapping virtMem {}; - Error err = kErrorOutOfMemory; - - if (block != nullptr) - bitWords = static_cast(::malloc(size_t(numBitWords) * 2 * sizeof(BitWord))); - - uint32_t blockFlags = 0; - if (bitWords != nullptr) { - if (impl->options & JitAllocator::kOptionUseDualMapping) { - err = VirtMem::allocDualMapping(&virtMem, blockSize, VirtMem::kAccessRWX); - blockFlags |= JitAllocatorBlock::kFlagDualMapped; - } - else { - err = VirtMem::alloc(&virtMem.ro, blockSize, VirtMem::kAccessRWX); - virtMem.rw = virtMem.ro; - } - } - - // Out of memory. - if (ASMJIT_UNLIKELY(!block || !bitWords || err != kErrorOk)) { - if (bitWords) ::free(bitWords); - if (block) ::free(block); - return nullptr; - } - - // Fill the memory if the secure mode is enabled. - if (impl->options & JitAllocator::kOptionFillUnusedMemory) - JitAllocatorImpl_fillPattern(virtMem.rw, impl->fillPattern, blockSize); - - memset(bitWords, 0, size_t(numBitWords) * 2 * sizeof(BitWord)); - return new(block) JitAllocatorBlock(pool, virtMem, blockSize, blockFlags, bitWords, bitWords + numBitWords, areaSize); -} - -static void JitAllocatorImpl_deleteBlock(JitAllocatorPrivateImpl* impl, JitAllocatorBlock* block) noexcept { - DebugUtils::unused(impl); - - if (block->hasFlag(JitAllocatorBlock::kFlagDualMapped)) - VirtMem::releaseDualMapping(&block->_mapping, block->blockSize()); - else - VirtMem::release(block->roPtr(), block->blockSize()); - - ::free(block->_usedBitVector); - ::free(block); -} - -static void JitAllocatorImpl_insertBlock(JitAllocatorPrivateImpl* impl, JitAllocatorBlock* block) noexcept { - JitAllocatorPool* pool = block->pool(); - - if (!pool->cursor) - pool->cursor = block; - - // Add to RBTree and List. - impl->tree.insert(block); - pool->blocks.append(block); - - // Update statistics. - pool->blockCount++; - pool->totalAreaSize += block->areaSize(); - pool->totalOverheadBytes += sizeof(JitAllocatorBlock) + JitAllocatorImpl_bitVectorSizeToByteSize(block->areaSize()) * 2u; -} - -static void JitAllocatorImpl_removeBlock(JitAllocatorPrivateImpl* impl, JitAllocatorBlock* block) noexcept { - JitAllocatorPool* pool = block->pool(); - - // Remove from RBTree and List. - if (pool->cursor == block) - pool->cursor = block->hasPrev() ? block->prev() : block->next(); - - impl->tree.remove(block); - pool->blocks.unlink(block); - - // Update statistics. - pool->blockCount--; - pool->totalAreaSize -= block->areaSize(); - pool->totalOverheadBytes -= sizeof(JitAllocatorBlock) + JitAllocatorImpl_bitVectorSizeToByteSize(block->areaSize()) * 2u; -} - -static void JitAllocatorImpl_wipeOutBlock(JitAllocatorPrivateImpl* impl, JitAllocatorBlock* block) noexcept { - JitAllocatorPool* pool = block->pool(); - - if (block->hasFlag(JitAllocatorBlock::kFlagEmpty)) - return; - - uint32_t areaSize = block->areaSize(); - uint32_t granularity = pool->granularity; - size_t numBitWords = pool->bitWordCountFromAreaSize(areaSize); - - if (impl->options & JitAllocator::kOptionFillUnusedMemory) { - uint8_t* rwPtr = block->rwPtr(); - for (size_t i = 0; i < numBitWords; i++) { - Support::BitWordIterator it(block->_usedBitVector[i]); - while (it.hasNext()) { - size_t index = it.next(); - JitAllocatorImpl_fillPattern(rwPtr + index * granularity , impl->fillPattern, granularity); - } - rwPtr += Support::bitSizeOf() * granularity; - } - } - - memset(block->_usedBitVector, 0, size_t(numBitWords) * sizeof(Support::BitWord)); - memset(block->_stopBitVector, 0, size_t(numBitWords) * sizeof(Support::BitWord)); - - block->_areaUsed = 0; - block->_largestUnusedArea = areaSize; - block->_searchStart = 0; - block->_searchEnd = areaSize; - block->addFlags(JitAllocatorBlock::kFlagEmpty); - block->clearFlags(JitAllocatorBlock::kFlagDirty); -} - -// ============================================================================ -// [asmjit::JitAllocator - Construction / Destruction] -// ============================================================================ - -JitAllocator::JitAllocator(const CreateParams* params) noexcept { - _impl = JitAllocatorImpl_new(params); - if (ASMJIT_UNLIKELY(!_impl)) - _impl = const_cast(&JitAllocatorImpl_none); -} - -JitAllocator::~JitAllocator() noexcept { - if (_impl == &JitAllocatorImpl_none) - return; - - reset(Globals::kResetHard); - JitAllocatorImpl_destroy(static_cast(_impl)); -} - -// ============================================================================ -// [asmjit::JitAllocator - Reset] -// ============================================================================ - -void JitAllocator::reset(uint32_t resetPolicy) noexcept { - if (_impl == &JitAllocatorImpl_none) - return; - - JitAllocatorPrivateImpl* impl = static_cast(_impl); - impl->tree.reset(); - size_t poolCount = impl->poolCount; - - for (size_t poolId = 0; poolId < poolCount; poolId++) { - JitAllocatorPool& pool = impl->pools[poolId]; - JitAllocatorBlock* block = pool.blocks.first(); - - JitAllocatorBlock* blockToKeep = nullptr; - if (resetPolicy != Globals::kResetHard && !(impl->options & kOptionImmediateRelease)) { - blockToKeep = block; - block = block->next(); - } - - while (block) { - JitAllocatorBlock* next = block->next(); - JitAllocatorImpl_deleteBlock(impl, block); - block = next; - } - - pool.reset(); - - if (blockToKeep) { - blockToKeep->_listNodes[0] = nullptr; - blockToKeep->_listNodes[1] = nullptr; - JitAllocatorImpl_wipeOutBlock(impl, blockToKeep); - JitAllocatorImpl_insertBlock(impl, blockToKeep); - pool.emptyBlockCount = 1; - } - } -} - -// ============================================================================ -// [asmjit::JitAllocator - Statistics] -// ============================================================================ - -JitAllocator::Statistics JitAllocator::statistics() const noexcept { - Statistics statistics; - statistics.reset(); - - if (ASMJIT_LIKELY(_impl != &JitAllocatorImpl_none)) { - JitAllocatorPrivateImpl* impl = static_cast(_impl); - LockGuard guard(impl->lock); - - size_t poolCount = impl->poolCount; - for (size_t poolId = 0; poolId < poolCount; poolId++) { - const JitAllocatorPool& pool = impl->pools[poolId]; - statistics._blockCount += size_t(pool.blockCount); - statistics._reservedSize += size_t(pool.totalAreaSize) * pool.granularity; - statistics._usedSize += size_t(pool.totalAreaUsed) * pool.granularity; - statistics._overheadSize += size_t(pool.totalOverheadBytes); - } - } - - return statistics; -} - -// ============================================================================ -// [asmjit::JitAllocator - Alloc / Release] -// ============================================================================ - -Error JitAllocator::alloc(void** roPtrOut, void** rwPtrOut, size_t size) noexcept { - if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none)) - return DebugUtils::errored(kErrorNotInitialized); - - JitAllocatorPrivateImpl* impl = static_cast(_impl); - constexpr uint32_t kNoIndex = std::numeric_limits::max(); - - *roPtrOut = nullptr; - *rwPtrOut = nullptr; - - // Align to the minimum granularity by default. - size = Support::alignUp(size, impl->granularity); - if (ASMJIT_UNLIKELY(size == 0)) - return DebugUtils::errored(kErrorInvalidArgument); - - if (ASMJIT_UNLIKELY(size > std::numeric_limits::max() / 2)) - return DebugUtils::errored(kErrorTooLarge); - - LockGuard guard(impl->lock); - JitAllocatorPool* pool = &impl->pools[JitAllocatorImpl_sizeToPoolId(impl, size)]; - - uint32_t areaIndex = kNoIndex; - uint32_t areaSize = uint32_t(pool->areaSizeFromByteSize(size)); - - // Try to find the requested memory area in existing blocks. - JitAllocatorBlock* block = pool->blocks.first(); - if (block) { - JitAllocatorBlock* initial = block; - do { - JitAllocatorBlock* next = block->hasNext() ? block->next() : pool->blocks.first(); - if (block->areaAvailable() >= areaSize) { - if (block->isDirty() || block->largestUnusedArea() >= areaSize) { - BitVectorRangeIterator it(block->_usedBitVector, pool->bitWordCountFromAreaSize(block->areaSize()), block->_searchStart, block->_searchEnd); - - size_t rangeStart = 0; - size_t rangeEnd = block->areaSize(); - - size_t searchStart = SIZE_MAX; - size_t largestArea = 0; - - while (it.nextRange(&rangeStart, &rangeEnd, areaSize)) { - size_t rangeSize = rangeEnd - rangeStart; - if (rangeSize >= areaSize) { - areaIndex = uint32_t(rangeStart); - break; - } - - searchStart = Support::min(searchStart, rangeStart); - largestArea = Support::max(largestArea, rangeSize); - } - - if (areaIndex != kNoIndex) - break; - - if (searchStart != SIZE_MAX) { - // Because we have iterated over the entire block, we can now mark the - // largest unused area that can be used to cache the next traversal. - size_t searchEnd = rangeEnd; - - block->_searchStart = uint32_t(searchStart); - block->_searchEnd = uint32_t(searchEnd); - block->_largestUnusedArea = uint32_t(largestArea); - block->clearFlags(JitAllocatorBlock::kFlagDirty); - } - } - } - - block = next; - } while (block != initial); - } - - // Allocate a new block if there is no region of a required width. - if (areaIndex == kNoIndex) { - size_t blockSize = JitAllocatorImpl_calculateIdealBlockSize(impl, pool, size); - if (ASMJIT_UNLIKELY(!blockSize)) - return DebugUtils::errored(kErrorOutOfMemory); - - block = JitAllocatorImpl_newBlock(impl, pool, blockSize); - areaIndex = 0; - - if (ASMJIT_UNLIKELY(!block)) - return DebugUtils::errored(kErrorOutOfMemory); - - JitAllocatorImpl_insertBlock(impl, block); - block->_searchStart = areaSize; - block->_largestUnusedArea = block->areaSize() - areaSize; - } - else if (block->hasFlag(JitAllocatorBlock::kFlagEmpty)) { - pool->emptyBlockCount--; - block->clearFlags(JitAllocatorBlock::kFlagEmpty); - } - - // Update statistics. - block->markAllocatedArea(areaIndex, areaIndex + areaSize); - - // Return a pointer to the allocated memory. - size_t offset = pool->byteSizeFromAreaSize(areaIndex); - ASMJIT_ASSERT(offset <= block->blockSize() - size); - - *roPtrOut = block->roPtr() + offset; - *rwPtrOut = block->rwPtr() + offset; - return kErrorOk; -} - -Error JitAllocator::release(void* roPtr) noexcept { - if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none)) - return DebugUtils::errored(kErrorNotInitialized); - - if (ASMJIT_UNLIKELY(!roPtr)) - return DebugUtils::errored(kErrorInvalidArgument); - - JitAllocatorPrivateImpl* impl = static_cast(_impl); - LockGuard guard(impl->lock); - - JitAllocatorBlock* block = impl->tree.get(static_cast(roPtr)); - if (ASMJIT_UNLIKELY(!block)) - return DebugUtils::errored(kErrorInvalidState); - - // Offset relative to the start of the block. - JitAllocatorPool* pool = block->pool(); - size_t offset = (size_t)((uint8_t*)roPtr - block->roPtr()); - - // The first bit representing the allocated area and its size. - uint32_t areaIndex = uint32_t(offset >> pool->granularityLog2); - uint32_t areaEnd = uint32_t(Support::bitVectorIndexOf(block->_stopBitVector, areaIndex, true)) + 1; - uint32_t areaSize = areaEnd - areaIndex; - - block->markReleasedArea(areaIndex, areaEnd); - - // Fill the released memory if the secure mode is enabled. - if (impl->options & kOptionFillUnusedMemory) - JitAllocatorImpl_fillPattern(block->rwPtr() + areaIndex * pool->granularity, impl->fillPattern, areaSize * pool->granularity); - - // Release the whole block if it became empty. - if (block->areaUsed() == 0) { - if (pool->emptyBlockCount || (impl->options & kOptionImmediateRelease)) { - JitAllocatorImpl_removeBlock(impl, block); - JitAllocatorImpl_deleteBlock(impl, block); - } - else { - pool->emptyBlockCount++; - } - } - - return kErrorOk; -} - -Error JitAllocator::shrink(void* roPtr, size_t newSize) noexcept { - if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none)) - return DebugUtils::errored(kErrorNotInitialized); - - if (ASMJIT_UNLIKELY(!roPtr)) - return DebugUtils::errored(kErrorInvalidArgument); - - if (ASMJIT_UNLIKELY(newSize == 0)) - return release(roPtr); - - JitAllocatorPrivateImpl* impl = static_cast(_impl); - LockGuard guard(impl->lock); - JitAllocatorBlock* block = impl->tree.get(static_cast(roPtr)); - - if (ASMJIT_UNLIKELY(!block)) - return DebugUtils::errored(kErrorInvalidArgument); - - // Offset relative to the start of the block. - JitAllocatorPool* pool = block->pool(); - size_t offset = (size_t)((uint8_t*)roPtr - block->roPtr()); - - // The first bit representing the allocated area and its size. - uint32_t areaStart = uint32_t(offset >> pool->granularityLog2); - uint32_t areaEnd = uint32_t(Support::bitVectorIndexOf(block->_stopBitVector, areaStart, true)) + 1; - - uint32_t areaPrevSize = areaEnd - areaStart; - uint32_t areaShrunkSize = pool->areaSizeFromByteSize(newSize); - - if (ASMJIT_UNLIKELY(areaShrunkSize > areaPrevSize)) - return DebugUtils::errored(kErrorInvalidState); - - uint32_t areaDiff = areaPrevSize - areaShrunkSize; - if (areaDiff) { - block->markShrunkArea(areaStart + areaShrunkSize, areaEnd); - - // Fill released memory if the secure mode is enabled. - if (impl->options & kOptionFillUnusedMemory) - JitAllocatorImpl_fillPattern(block->rwPtr() + (areaStart + areaShrunkSize) * pool->granularity, fillPattern(), areaDiff * pool->granularity); - } - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::JitAllocator - Unit] -// ============================================================================ - -#if defined(ASMJIT_TEST) -// A pseudo random number generator based on a paper by Sebastiano Vigna: -// http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf -class Random { -public: - // Constants suggested as `23/18/5`. - enum Steps : uint32_t { - kStep1_SHL = 23, - kStep2_SHR = 18, - kStep3_SHR = 5 - }; - - inline explicit Random(uint64_t seed = 0) noexcept { reset(seed); } - inline Random(const Random& other) noexcept = default; - - inline void reset(uint64_t seed = 0) noexcept { - // The number is arbitrary, it means nothing. - constexpr uint64_t kZeroSeed = 0x1F0A2BE71D163FA0u; - - // Generate the state data by using splitmix64. - for (uint32_t i = 0; i < 2; i++) { - seed += 0x9E3779B97F4A7C15u; - uint64_t x = seed; - x = (x ^ (x >> 30)) * 0xBF58476D1CE4E5B9u; - x = (x ^ (x >> 27)) * 0x94D049BB133111EBu; - x = (x ^ (x >> 31)); - _state[i] = x != 0 ? x : kZeroSeed; - } - } - - inline uint32_t nextUInt32() noexcept { - return uint32_t(nextUInt64() >> 32); - } - - inline uint64_t nextUInt64() noexcept { - uint64_t x = _state[0]; - uint64_t y = _state[1]; - - x ^= x << kStep1_SHL; - y ^= y >> kStep3_SHR; - x ^= x >> kStep2_SHR; - x ^= y; - - _state[0] = y; - _state[1] = x; - return x + y; - } - - uint64_t _state[2]; -}; - -// Helper class to verify that JitAllocator doesn't return addresses that overlap. -class JitAllocatorWrapper { -public: - // Address to a memory region of a given size. - class Range { - public: - inline Range(uint8_t* addr, size_t size) noexcept - : addr(addr), - size(size) {} - uint8_t* addr; - size_t size; - }; - - // Based on JitAllocator::Block, serves our purpose well... - class Record : public ZoneTreeNodeT, - public Range { - public: - inline Record(uint8_t* addr, size_t size) - : ZoneTreeNodeT(), - Range(addr, size) {} - - inline bool operator<(const Record& other) const noexcept { return addr < other.addr; } - inline bool operator>(const Record& other) const noexcept { return addr > other.addr; } - - inline bool operator<(const uint8_t* key) const noexcept { return addr + size <= key; } - inline bool operator>(const uint8_t* key) const noexcept { return addr > key; } - }; - - Zone _zone; - ZoneAllocator _heap; - ZoneTree _records; - JitAllocator _allocator; - - explicit JitAllocatorWrapper(const JitAllocator::CreateParams* params) noexcept - : _zone(1024 * 1024), - _heap(&_zone), - _allocator(params) {} - - void _insert(void* p_, size_t size) noexcept { - uint8_t* p = static_cast(p_); - uint8_t* pEnd = p + size - 1; - - Record* record; - - record = _records.get(p); - if (record) - EXPECT(record == nullptr, "Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size); - - record = _records.get(pEnd); - if (record) - EXPECT(record == nullptr, "Address [%p:%p] collides with a newly allocated [%p:%p]\n", record->addr, record->addr + record->size, p, p + size); - - record = _heap.newT(p, size); - EXPECT(record != nullptr, "Out of memory, cannot allocate 'Record'"); - - _records.insert(record); - } - - void _remove(void* p) noexcept { - Record* record = _records.get(static_cast(p)); - EXPECT(record != nullptr, "Address [%p] doesn't exist\n", p); - - _records.remove(record); - _heap.release(record, sizeof(Record)); - } - - void* alloc(size_t size) noexcept { - void* roPtr; - void* rwPtr; - - Error err = _allocator.alloc(&roPtr, &rwPtr, size); - EXPECT(err == kErrorOk, "JitAllocator failed to allocate %zu bytes\n", size); - - _insert(roPtr, size); - return roPtr; - } - - void release(void* p) noexcept { - _remove(p); - EXPECT(_allocator.release(p) == kErrorOk, "JitAllocator failed to release '%p'\n", p); - } - - void shrink(void* p, size_t newSize) noexcept { - Record* record = _records.get(static_cast(p)); - EXPECT(record != nullptr, "Address [%p] doesn't exist\n", p); - - if (!newSize) - return release(p); - - Error err = _allocator.shrink(p, newSize); - EXPECT(err == kErrorOk, "JitAllocator failed to shrink %p to %zu bytes\n", p, newSize); - - record->size = newSize; - } -}; - -static void JitAllocatorTest_shuffle(void** ptrArray, size_t count, Random& prng) noexcept { - for (size_t i = 0; i < count; ++i) - std::swap(ptrArray[i], ptrArray[size_t(prng.nextUInt32() % count)]); -} - -static void JitAllocatorTest_usage(JitAllocator& allocator) noexcept { - JitAllocator::Statistics stats = allocator.statistics(); - INFO(" Block Count : %9llu [Blocks]" , (unsigned long long)(stats.blockCount())); - INFO(" Reserved (VirtMem): %9llu [Bytes]" , (unsigned long long)(stats.reservedSize())); - INFO(" Used (VirtMem): %9llu [Bytes] (%.1f%%)", (unsigned long long)(stats.usedSize()), stats.usedSizeAsPercent()); - INFO(" Overhead (HeapMem): %9llu [Bytes] (%.1f%%)", (unsigned long long)(stats.overheadSize()), stats.overheadSizeAsPercent()); -} - -template -static void BitVectorRangeIterator_testRandom(Random& rnd, size_t count) noexcept { - for (size_t i = 0; i < count; i++) { - T in[kPatternSize]; - T out[kPatternSize]; - - for (size_t j = 0; j < kPatternSize; j++) { - in[j] = T(uint64_t(rnd.nextUInt32() & 0xFFu) * 0x0101010101010101); - out[j] = Bit == 0 ? Support::allOnes() : T(0); - } - - { - BitVectorRangeIterator it(in, kPatternSize); - size_t rangeStart, rangeEnd; - while (it.nextRange(&rangeStart, &rangeEnd)) { - if (Bit) - Support::bitVectorFill(out, rangeStart, rangeEnd - rangeStart); - else - Support::bitVectorClear(out, rangeStart, rangeEnd - rangeStart); - } - } - - for (size_t j = 0; j < kPatternSize; j++) { - EXPECT(in[j] == out[j], "Invalid pattern detected at [%zu] (%llX != %llX", j, (unsigned long long)in[j], (unsigned long long)out[j]); - } - } -} - -UNIT(jit_allocator) { - size_t kCount = BrokenAPI::hasArg("--quick") ? 1000 : 100000; - - struct TestParams { - const char* name; - uint32_t options; - uint32_t blockSize; - uint32_t granularity; - }; - - static TestParams testParams[] = { - { "Default", 0, 0, 0 }, - { "16MB blocks", 0, 16 * 1024 * 1024, 0 }, - { "256B granularity", 0, 0, 256 }, - { "kOptionUseDualMapping", JitAllocator::kOptionUseDualMapping, 0, 0 }, - { "kOptionUseMultiplePools", JitAllocator::kOptionUseMultiplePools, 0, 0 }, - { "kOptionFillUnusedMemory", JitAllocator::kOptionFillUnusedMemory, 0, 0 }, - { "kOptionImmediateRelease", JitAllocator::kOptionImmediateRelease, 0, 0 }, - { "kOptionUseDualMapping | kOptionFillUnusedMemory", JitAllocator::kOptionUseDualMapping | JitAllocator::kOptionFillUnusedMemory, 0, 0 } - }; - - INFO("BitVectorRangeIterator"); - { - Random rnd; - BitVectorRangeIterator_testRandom(rnd, kCount); - } - - INFO("BitVectorRangeIterator"); - { - Random rnd; - BitVectorRangeIterator_testRandom(rnd, kCount); - } - - for (uint32_t testId = 0; testId < ASMJIT_ARRAY_SIZE(testParams); testId++) { - INFO("JitAllocator(%s)", testParams[testId].name); - - JitAllocator::CreateParams params {}; - params.options = testParams[testId].options; - params.blockSize = testParams[testId].blockSize; - params.granularity = testParams[testId].granularity; - - size_t fixedBlockSize = 256; - - JitAllocatorWrapper wrapper(¶ms); - Random prng(100); - - size_t i; - - INFO(" Memory alloc/release test - %d allocations", kCount); - - void** ptrArray = (void**)::malloc(sizeof(void*) * size_t(kCount)); - EXPECT(ptrArray != nullptr, - "Couldn't allocate '%u' bytes for pointer-array", unsigned(sizeof(void*) * size_t(kCount))); - - // Random blocks tests... - INFO(" Allocating random blocks..."); - for (i = 0; i < kCount; i++) - ptrArray[i] = wrapper.alloc((prng.nextUInt32() % 1024) + 8); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Releasing all allocated blocks from the beginning..."); - for (i = 0; i < kCount; i++) - wrapper.release(ptrArray[i]); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Allocating random blocks again...", kCount); - for (i = 0; i < kCount; i++) - ptrArray[i] = wrapper.alloc((prng.nextUInt32() % 1024) + 8); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Shuffling allocated blocks..."); - JitAllocatorTest_shuffle(ptrArray, unsigned(kCount), prng); - - INFO(" Releasing 50%% of allocated blocks..."); - for (i = 0; i < kCount / 2; i++) - wrapper.release(ptrArray[i]); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Allocating 50%% more blocks again..."); - for (i = 0; i < kCount / 2; i++) - ptrArray[i] = wrapper.alloc((prng.nextUInt32() % 1024) + 8); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Releasing all allocated blocks from the end..."); - for (i = 0; i < kCount; i++) - wrapper.release(ptrArray[kCount - i - 1]); - JitAllocatorTest_usage(wrapper._allocator); - - // Fixed blocks tests... - INFO(" Allocating %zuB blocks...", fixedBlockSize); - for (i = 0; i < kCount / 2; i++) - ptrArray[i] = wrapper.alloc(fixedBlockSize); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Shrinking each %zuB block to 1 byte", fixedBlockSize); - for (i = 0; i < kCount / 2; i++) - wrapper.shrink(ptrArray[i], 1); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Allocating more 64B blocks...", 64); - for (i = kCount / 2; i < kCount; i++) - ptrArray[i] = wrapper.alloc(64); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Releasing all blocks from the beginning..."); - for (i = 0; i < kCount; i++) - wrapper.release(ptrArray[i]); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Allocating %zuB blocks...", fixedBlockSize); - for (i = 0; i < kCount; i++) - ptrArray[i] = wrapper.alloc(fixedBlockSize); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Shuffling allocated blocks..."); - JitAllocatorTest_shuffle(ptrArray, unsigned(kCount), prng); - - INFO(" Releasing 50%% of allocated blocks..."); - for (i = 0; i < kCount / 2; i++) - wrapper.release(ptrArray[i]); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Allocating 50%% more %zuB blocks again...", fixedBlockSize); - for (i = 0; i < kCount / 2; i++) - ptrArray[i] = wrapper.alloc(fixedBlockSize); - JitAllocatorTest_usage(wrapper._allocator); - - INFO(" Releasing all allocated blocks from the end..."); - for (i = 0; i < kCount; i++) - wrapper.release(ptrArray[kCount - i - 1]); - JitAllocatorTest_usage(wrapper._allocator); - - ::free(ptrArray); - } -} -#endif - -ASMJIT_END_NAMESPACE - -#endif diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitallocator.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitallocator.h deleted file mode 100644 index c9eea2a..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitallocator.h +++ /dev/null @@ -1,278 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_JITALLOCATOR_H_INCLUDED -#define ASMJIT_CORE_JITALLOCATOR_H_INCLUDED - -#include "../core/api-config.h" -#ifndef ASMJIT_NO_JIT - -#include "../core/globals.h" -#include "../core/virtmem.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_virtual_memory -//! \{ - -// ============================================================================ -// [asmjit::JitAllocator] -// ============================================================================ - -//! A simple implementation of memory manager that uses `asmjit::VirtMem` -//! functions to manage virtual memory for JIT compiled code. -//! -//! Implementation notes: -//! -//! - Granularity of allocated blocks is different than granularity for a typical -//! C malloc. In addition, the allocator can use several memory pools having a -//! different granularity to minimize the maintenance overhead. Multiple pools -//! feature requires `kFlagUseMultiplePools` flag to be set. -//! -//! - The allocator doesn't store any information in executable memory, instead, -//! the implementation uses two bit-vectors to manage allocated memory of each -//! allocator-block. The first bit-vector called 'used' is used to track used -//! memory (where each bit represents memory size defined by granularity) and -//! the second bit vector called 'stop' is used as a sentinel to mark where -//! the allocated area ends. -//! -//! - Internally, the allocator also uses RB tree to keep track of all blocks -//! across all pools. Each inserted block is added to the tree so it can be -//! matched fast during `release()` and `shrink()`. -class JitAllocator { -public: - ASMJIT_NONCOPYABLE(JitAllocator) - - struct Impl { - //! Allocator options, see \ref JitAllocator::Options. - uint32_t options; - //! Base block size (0 if the allocator is not initialized). - uint32_t blockSize; - //! Base granularity (0 if the allocator is not initialized). - uint32_t granularity; - //! A pattern that is used to fill unused memory if secure mode is enabled. - uint32_t fillPattern; - }; - - //! Allocator implementation (private). - Impl* _impl; - - enum Options : uint32_t { - //! Enables the use of an anonymous memory-mapped memory that is mapped into - //! two buffers having a different pointer. The first buffer has read and - //! execute permissions and the second buffer has read+write permissions. - //! - //! See \ref VirtMem::allocDualMapping() for more details about this feature. - kOptionUseDualMapping = 0x00000001u, - - //! Enables the use of multiple pools with increasing granularity instead of - //! a single pool. This flag would enable 3 internal pools in total having - //! 64, 128, and 256 bytes granularity. - //! - //! This feature is only recommended for users that generate a lot of code - //! and would like to minimize the overhead of `JitAllocator` itself by - //! having blocks of different allocation granularities. Using this feature - //! only for few allocations won't pay off as the allocator may need to - //! create more blocks initially before it can take the advantage of - //! variable block granularity. - kOptionUseMultiplePools = 0x00000002u, - - //! Always fill reserved memory by a fill-pattern. - //! - //! Causes a new block to be cleared by the fill pattern and freshly - //! released memory to be cleared before making it ready for another use. - kOptionFillUnusedMemory = 0x00000004u, - - //! When this flag is set the allocator would immediately release unused - //! blocks during `release()` or `reset()`. When this flag is not set the - //! allocator would keep one empty block in each pool to prevent excessive - //! virtual memory allocations and deallocations in border cases, which - //! involve constantly allocating and deallocating a single block caused - //! by repetitive calling `alloc()` and `release()` when the allocator has - //! either no blocks or have all blocks fully occupied. - kOptionImmediateRelease = 0x00000008u, - - //! Use a custom fill pattern, must be combined with `kFlagFillUnusedMemory`. - kOptionCustomFillPattern = 0x10000000u - }; - - //! \name Construction & Destruction - //! \{ - - //! Parameters that can be passed to `JitAllocator` constructor. - //! - //! Use it like this: - //! - //! ``` - //! // Zero initialize (zero means the default value) and change what you need. - //! JitAllocator::CreateParams params {}; - //! params.blockSize = 1024 * 1024; - //! - //! // Create the allocator. - //! JitAllocator allocator(¶ms); - //! ``` - struct CreateParams { - //! Allocator options, see \ref JitAllocator::Options. - //! - //! No options are used by default. - uint32_t options; - - //! Base size of a single block in bytes (default 64kB). - //! - //! \remarks Block size must be equal or greater to page size and must be - //! power of 2. If the input is not valid then the default block size will - //! be used instead. - uint32_t blockSize; - - //! Base granularity (and also natural alignment) of allocations in bytes - //! (default 64). - //! - //! Since the `JitAllocator` uses bit-arrays to mark used memory the - //! granularity also specifies how many bytes correspond to a single bit in - //! such bit-array. Higher granularity means more waste of virtual memory - //! (as it increases the natural alignment), but smaller bit-arrays as less - //! bits would be required per a single block. - uint32_t granularity; - - //! Patter to use to fill unused memory. - //! - //! Only used if \ref kOptionCustomFillPattern is set. - uint32_t fillPattern; - - // Reset the content of `CreateParams`. - inline void reset() noexcept { memset(this, 0, sizeof(*this)); } - }; - - //! Creates a `JitAllocator` instance. - explicit ASMJIT_API JitAllocator(const CreateParams* params = nullptr) noexcept; - //! Destroys the `JitAllocator` instance and release all blocks held. - ASMJIT_API ~JitAllocator() noexcept; - - inline bool isInitialized() const noexcept { return _impl->blockSize == 0; } - - //! Free all allocated memory - makes all pointers returned by `alloc()` invalid. - //! - //! \remarks This function is not thread-safe as it's designed to be used when - //! nobody else is using allocator. The reason is that there is no point of - //1 calling `reset()` when the allocator is still in use. - ASMJIT_API void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept; - - //! \} - - //! \name Accessors - //! \{ - - //! Returns allocator options, see `Flags`. - inline uint32_t options() const noexcept { return _impl->options; } - //! Tests whether the allocator has the given `option` set. - inline bool hasOption(uint32_t option) const noexcept { return (_impl->options & option) != 0; } - - //! Returns a base block size (a minimum size of block that the allocator would allocate). - inline uint32_t blockSize() const noexcept { return _impl->blockSize; } - //! Returns granularity of the allocator. - inline uint32_t granularity() const noexcept { return _impl->granularity; } - //! Returns pattern that is used to fill unused memory if `kFlagUseFillPattern` is set. - inline uint32_t fillPattern() const noexcept { return _impl->fillPattern; } - - //! \} - - //! \name Alloc & Release - //! \{ - - //! Allocate `size` bytes of virtual memory. - //! - //! \remarks This function is thread-safe. - ASMJIT_API Error alloc(void** roPtrOut, void** rwPtrOut, size_t size) noexcept; - - //! Release a memory returned by `alloc()`. - //! - //! \remarks This function is thread-safe. - ASMJIT_API Error release(void* roPtr) noexcept; - - //! Free extra memory allocated with `p` by restricting it to `newSize` size. - //! - //! \remarks This function is thread-safe. - ASMJIT_API Error shrink(void* roPtr, size_t newSize) noexcept; - - //! \} - - //! \name Statistics - //! \{ - - //! Statistics about `JitAllocator`. - struct Statistics { - //! Number of blocks `JitAllocator` maintains. - size_t _blockCount; - //! How many bytes are currently used / allocated. - size_t _usedSize; - //! How many bytes are currently reserved by the allocator. - size_t _reservedSize; - //! Allocation overhead (in bytes) required to maintain all blocks. - size_t _overheadSize; - - inline void reset() noexcept { - _blockCount = 0; - _usedSize = 0; - _reservedSize = 0; - _overheadSize = 0; - } - - //! Returns count of blocks managed by `JitAllocator` at the moment. - inline size_t blockCount() const noexcept { return _blockCount; } - - //! Returns how many bytes are currently used. - inline size_t usedSize() const noexcept { return _usedSize; } - //! Returns the number of bytes unused by the allocator at the moment. - inline size_t unusedSize() const noexcept { return _reservedSize - _usedSize; } - //! Returns the total number of bytes bytes reserved by the allocator (sum of sizes of all blocks). - inline size_t reservedSize() const noexcept { return _reservedSize; } - //! Returns the number of bytes the allocator needs to manage the allocated memory. - inline size_t overheadSize() const noexcept { return _overheadSize; } - - inline double usedSizeAsPercent() const noexcept { - return (double(usedSize()) / (double(reservedSize()) + 1e-16)) * 100.0; - } - - inline double unusedSizeAsPercent() const noexcept { - return (double(unusedSize()) / (double(reservedSize()) + 1e-16)) * 100.0; - } - - inline double overheadSizeAsPercent() const noexcept { - return (double(overheadSize()) / (double(reservedSize()) + 1e-16)) * 100.0; - } - }; - - //! Returns JIT allocator statistics. - //! - //! \remarks This function is thread-safe. - ASMJIT_API Statistics statistics() const noexcept; - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif -#endif diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitruntime.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitruntime.cpp deleted file mode 100644 index a2b46d7..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitruntime.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#ifndef ASMJIT_NO_JIT - -#include "../core/cpuinfo.h" -#include "../core/jitruntime.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::JitRuntime - Utilities] -// ============================================================================ - -// Only useful on non-x86 architectures. -static inline void JitRuntime_flushInstructionCache(const void* p, size_t size) noexcept { -#if ASMJIT_ARCH_X86 - DebugUtils::unused(p, size); -#else -# if defined(_WIN32) - // Windows has a built-in support in `kernel32.dll`. - ::FlushInstructionCache(::GetCurrentProcess(), p, size); -# elif defined(__GNUC__) - char* start = static_cast(const_cast(p)); - char* end = start + size; - __builtin___clear_cache(start, end); -# else - DebugUtils::unused(p, size); -# endif -#endif -} - -// ============================================================================ -// [asmjit::JitRuntime - Construction / Destruction] -// ============================================================================ - -JitRuntime::JitRuntime(const JitAllocator::CreateParams* params) noexcept - : _allocator(params) { - _environment = hostEnvironment(); - _environment.setFormat(Environment::kFormatJIT); -} - -JitRuntime::~JitRuntime() noexcept {} - -// ============================================================================ -// [asmjit::JitRuntime - Interface] -// ============================================================================ - -Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept { - *dst = nullptr; - - ASMJIT_PROPAGATE(code->flatten()); - ASMJIT_PROPAGATE(code->resolveUnresolvedLinks()); - - size_t estimatedCodeSize = code->codeSize(); - if (ASMJIT_UNLIKELY(estimatedCodeSize == 0)) - return DebugUtils::errored(kErrorNoCodeGenerated); - - uint8_t* ro; - uint8_t* rw; - ASMJIT_PROPAGATE(_allocator.alloc((void**)&ro, (void**)&rw, estimatedCodeSize)); - - // Relocate the code. - Error err = code->relocateToBase(uintptr_t((void*)ro)); - if (ASMJIT_UNLIKELY(err)) { - _allocator.release(ro); - return err; - } - - // Recalculate the final code size and shrink the memory we allocated for it - // in case that some relocations didn't require records in an address table. - size_t codeSize = code->codeSize(); - - for (Section* section : code->_sections) { - size_t offset = size_t(section->offset()); - size_t bufferSize = size_t(section->bufferSize()); - size_t virtualSize = size_t(section->virtualSize()); - - ASMJIT_ASSERT(offset + bufferSize <= codeSize); - memcpy(rw + offset, section->data(), bufferSize); - - if (virtualSize > bufferSize) { - ASMJIT_ASSERT(offset + virtualSize <= codeSize); - memset(rw + offset + bufferSize, 0, virtualSize - bufferSize); - } - } - - if (codeSize < estimatedCodeSize) - _allocator.shrink(ro, codeSize); - - flush(ro, codeSize); - *dst = ro; - - return kErrorOk; -} - -Error JitRuntime::_release(void* p) noexcept { - return _allocator.release(p); -} - -void JitRuntime::flush(const void* p, size_t size) noexcept { - JitRuntime_flushInstructionCache(p, size); -} - -ASMJIT_END_NAMESPACE - -#endif diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitruntime.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitruntime.h deleted file mode 100644 index 91880e6..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/jitruntime.h +++ /dev/null @@ -1,126 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_JITRUNTIME_H_INCLUDED -#define ASMJIT_CORE_JITRUNTIME_H_INCLUDED - -#include "../core/api-config.h" -#ifndef ASMJIT_NO_JIT - -#include "../core/codeholder.h" -#include "../core/jitallocator.h" -#include "../core/target.h" - -ASMJIT_BEGIN_NAMESPACE - -class CodeHolder; - -//! \addtogroup asmjit_virtual_memory -//! \{ - -// ============================================================================ -// [asmjit::JitRuntime] -// ============================================================================ - -//! JIT execution runtime is a special `Target` that is designed to store and -//! execute the generated code. -class ASMJIT_VIRTAPI JitRuntime : public Target { -public: - ASMJIT_NONCOPYABLE(JitRuntime) - - //! Virtual memory allocator. - JitAllocator _allocator; - - //! \name Construction & Destruction - //! \{ - - //! Creates a `JitRuntime` instance. - explicit ASMJIT_API JitRuntime(const JitAllocator::CreateParams* params = nullptr) noexcept; - //! Destroys the `JitRuntime` instance. - ASMJIT_API virtual ~JitRuntime() noexcept; - - inline void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept { - _allocator.reset(resetPolicy); - } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the associated `JitAllocator`. - inline JitAllocator* allocator() const noexcept { return const_cast(&_allocator); } - - //! \} - - //! \name Utilities - //! \{ - - // NOTE: To allow passing function pointers to `add()` and `release()` the - // virtual methods are prefixed with `_` and called from templates instead. - - //! Allocates memory needed for a code stored in the `CodeHolder` and relocates - //! the code to the pointer allocated. - //! - //! The beginning of the memory allocated for the function is returned in `dst`. - //! If failed `Error` code is returned and `dst` is explicitly set to `nullptr` - //! (this means that you don't have to set it to null before calling `add()`). - template - inline Error add(Func* dst, CodeHolder* code) noexcept { - return _add(Support::ptr_cast_impl(dst), code); - } - - //! Releases `p` which was obtained by calling `add()`. - template - inline Error release(Func p) noexcept { - return _release(Support::ptr_cast_impl(p)); - } - - //! Type-unsafe version of `add()`. - ASMJIT_API virtual Error _add(void** dst, CodeHolder* code) noexcept; - - //! Type-unsafe version of `release()`. - ASMJIT_API virtual Error _release(void* p) noexcept; - - //! Flushes an instruction cache. - //! - //! This member function is called after the code has been copied to the - //! destination buffer. It is only useful for JIT code generation as it - //! causes a flush of the processor's cache. - //! - //! Flushing is basically a NOP under X86, but is needed by architectures - //! that do not have a transparent instruction cache like ARM. - //! - //! This function can also be overridden to improve compatibility with tools - //! such as Valgrind, however, it's not an official part of AsmJit. - ASMJIT_API virtual void flush(const void* p, size_t size) noexcept; - - //! \} -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif -#endif diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/logger.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/logger.cpp deleted file mode 100644 index 22e0b9a..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/logger.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#ifndef ASMJIT_NO_LOGGING - -#include "../core/logger.h" -#include "../core/string.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::Logger - Construction / Destruction] -// ============================================================================ - -Logger::Logger() noexcept - : _options() {} -Logger::~Logger() noexcept {} - -// ============================================================================ -// [asmjit::Logger - Logging] -// ============================================================================ - -Error Logger::logf(const char* fmt, ...) noexcept { - Error err; - va_list ap; - - va_start(ap, fmt); - err = logv(fmt, ap); - va_end(ap); - - return err; -} - -Error Logger::logv(const char* fmt, va_list ap) noexcept { - StringTmp<2048> sb; - ASMJIT_PROPAGATE(sb.appendVFormat(fmt, ap)); - return log(sb); -} - -Error Logger::logBinary(const void* data, size_t size) noexcept { - static const char prefix[] = "db "; - - StringTmp<256> sb; - sb.append(prefix, ASMJIT_ARRAY_SIZE(prefix) - 1); - - size_t i = size; - const uint8_t* s = static_cast(data); - - while (i) { - uint32_t n = uint32_t(Support::min(i, 16)); - sb.truncate(ASMJIT_ARRAY_SIZE(prefix) - 1); - sb.appendHex(s, n); - sb.append('\n'); - ASMJIT_PROPAGATE(log(sb)); - s += n; - i -= n; - } - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::FileLogger - Construction / Destruction] -// ============================================================================ - -FileLogger::FileLogger(FILE* file) noexcept - : _file(file) {} -FileLogger::~FileLogger() noexcept {} - -// ============================================================================ -// [asmjit::FileLogger - Logging] -// ============================================================================ - -Error FileLogger::_log(const char* data, size_t size) noexcept { - if (!_file) - return kErrorOk; - - if (size == SIZE_MAX) - size = strlen(data); - - fwrite(data, 1, size, _file); - return kErrorOk; -} - -// ============================================================================ -// [asmjit::StringLogger - Construction / Destruction] -// ============================================================================ - -StringLogger::StringLogger() noexcept {} -StringLogger::~StringLogger() noexcept {} - -// ============================================================================ -// [asmjit::StringLogger - Logging] -// ============================================================================ - -Error StringLogger::_log(const char* data, size_t size) noexcept { - return _content.append(data, size); -} - -ASMJIT_END_NAMESPACE - -#endif diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/logger.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/logger.h deleted file mode 100644 index 2840869..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/logger.h +++ /dev/null @@ -1,228 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_LOGGING_H_INCLUDED -#define ASMJIT_CORE_LOGGING_H_INCLUDED - -#include "../core/inst.h" -#include "../core/string.h" -#include "../core/formatter.h" - -#ifndef ASMJIT_NO_LOGGING - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_logging -//! \{ - -// ============================================================================ -// [asmjit::Logger] -// ============================================================================ - -//! Logging interface. -//! -//! This class can be inherited and reimplemented to fit into your own logging -//! needs. When reimplementing a logger use \ref Logger::_log() method to log -//! customize the output. -//! -//! There are two `Logger` implementations offered by AsmJit: -//! - \ref FileLogger - logs into a `FILE*`. -//! - \ref StringLogger - concatenates all logs into a \ref String. -class ASMJIT_VIRTAPI Logger { -public: - ASMJIT_BASE_CLASS(Logger) - ASMJIT_NONCOPYABLE(Logger) - - //! Format options. - FormatOptions _options; - - //! \name Construction & Destruction - //! \{ - - //! Creates a `Logger` instance. - ASMJIT_API Logger() noexcept; - //! Destroys the `Logger` instance. - ASMJIT_API virtual ~Logger() noexcept; - - //! \} - - //! \name Format Options - //! \{ - - //! Returns \ref FormatOptions of this logger. - inline FormatOptions& options() noexcept { return _options; } - //! \overload - inline const FormatOptions& options() const noexcept { return _options; } - - //! Returns formatting flags, see \ref FormatOptions::Flags. - inline uint32_t flags() const noexcept { return _options.flags(); } - //! Tests whether the logger has the given `flag` enabled. - inline bool hasFlag(uint32_t flag) const noexcept { return _options.hasFlag(flag); } - //! Sets formatting flags to `flags`, see \ref FormatOptions::Flags. - inline void setFlags(uint32_t flags) noexcept { _options.setFlags(flags); } - //! Enables the given formatting `flags`, see \ref FormatOptions::Flags. - inline void addFlags(uint32_t flags) noexcept { _options.addFlags(flags); } - //! Disables the given formatting `flags`, see \ref FormatOptions::Flags. - inline void clearFlags(uint32_t flags) noexcept { _options.clearFlags(flags); } - - //! Returns indentation of `type`, see \ref FormatOptions::IndentationType. - inline uint32_t indentation(uint32_t type) const noexcept { return _options.indentation(type); } - //! Sets indentation of the given indentation `type` to `n` spaces, see \ref - //! FormatOptions::IndentationType. - inline void setIndentation(uint32_t type, uint32_t n) noexcept { _options.setIndentation(type, n); } - //! Resets indentation of the given indentation `type` to 0 spaces. - inline void resetIndentation(uint32_t type) noexcept { _options.resetIndentation(type); } - - //! \} - - //! \name Logging Interface - //! \{ - - //! Logs `str` - must be reimplemented. - //! - //! The function can accept either a null terminated string if `size` is - //! `SIZE_MAX` or a non-null terminated string of the given `size`. The - //! function cannot assume that the data is null terminated and must handle - //! non-null terminated inputs. - virtual Error _log(const char* data, size_t size) noexcept = 0; - - //! Logs string `str`, which is either null terminated or having size `size`. - inline Error log(const char* data, size_t size = SIZE_MAX) noexcept { return _log(data, size); } - //! Logs content of a string `str`. - inline Error log(const String& str) noexcept { return _log(str.data(), str.size()); } - - //! Formats the message by using `snprintf()` and then passes the formatted - //! string to \ref _log(). - ASMJIT_API Error logf(const char* fmt, ...) noexcept; - - //! Formats the message by using `vsnprintf()` and then passes the formatted - //! string to \ref _log(). - ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept; - - //! Logs binary `data` of the given `size`. - ASMJIT_API Error logBinary(const void* data, size_t size) noexcept; - - //! \} -}; - -// ============================================================================ -// [asmjit::FileLogger] -// ============================================================================ - -//! Logger that can log to a `FILE*`. -class ASMJIT_VIRTAPI FileLogger : public Logger { -public: - ASMJIT_NONCOPYABLE(FileLogger) - - FILE* _file; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new `FileLogger` that logs to `FILE*`. - ASMJIT_API FileLogger(FILE* file = nullptr) noexcept; - //! Destroys the `FileLogger`. - ASMJIT_API virtual ~FileLogger() noexcept; - - //! \} - - //! \name Accessors - //! \{ - - //! Returns the logging output stream or null if the logger has no output - //! stream. - inline FILE* file() const noexcept { return _file; } - - //! Sets the logging output stream to `stream` or null. - //! - //! \note If the `file` is null the logging will be disabled. When a logger - //! is attached to `CodeHolder` or any emitter the logging API will always - //! be called regardless of the output file. This means that if you really - //! want to disable logging at emitter level you must not attach a logger - //! to it. - inline void setFile(FILE* file) noexcept { _file = file; } - - //! \} - - ASMJIT_API Error _log(const char* data, size_t size = SIZE_MAX) noexcept override; -}; - -// ============================================================================ -// [asmjit::StringLogger] -// ============================================================================ - -//! Logger that stores everything in an internal string buffer. -class ASMJIT_VIRTAPI StringLogger : public Logger { -public: - ASMJIT_NONCOPYABLE(StringLogger) - - //! Logger data as string. - String _content; - - //! \name Construction & Destruction - //! \{ - - //! Create new `StringLogger`. - ASMJIT_API StringLogger() noexcept; - //! Destroys the `StringLogger`. - ASMJIT_API virtual ~StringLogger() noexcept; - - //! \} - - //! \name Logger Data Accessors - //! \{ - - //! Returns the content of the logger as \ref String. - //! - //! It can be moved, if desired. - inline String& content() noexcept { return _content; } - //! \overload - inline const String& content() const noexcept { return _content; } - - //! Returns aggregated logger data as `char*` pointer. - //! - //! The pointer is owned by `StringLogger`, it can't be modified or freed. - inline const char* data() const noexcept { return _content.data(); } - //! Returns size of the data returned by `data()`. - inline size_t dataSize() const noexcept { return _content.size(); } - - //! \} - - //! \name Logger Data Manipulation - //! \{ - - //! Clears the accumulated logger data. - inline void clear() noexcept { _content.clear(); } - - //! \} - - ASMJIT_API Error _log(const char* data, size_t size = SIZE_MAX) noexcept override; -}; - -//! \} - -ASMJIT_END_NAMESPACE - -#endif - -#endif // ASMJIT_CORE_LOGGER_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/misc_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/misc_p.h deleted file mode 100644 index 225ba6a..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/misc_p.h +++ /dev/null @@ -1,51 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_MISC_P_H_INCLUDED -#define ASMJIT_CORE_MISC_P_H_INCLUDED - -#include "../core/api-config.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \cond INTERNAL -//! \addtogroup asmjit_utilities -//! \{ - -#define ASMJIT_LOOKUP_TABLE_4(T, I) T((I)), T((I+1)), T((I+2)), T((I+3)) -#define ASMJIT_LOOKUP_TABLE_8(T, I) ASMJIT_LOOKUP_TABLE_4(T, I), ASMJIT_LOOKUP_TABLE_4(T, I + 4) -#define ASMJIT_LOOKUP_TABLE_16(T, I) ASMJIT_LOOKUP_TABLE_8(T, I), ASMJIT_LOOKUP_TABLE_8(T, I + 8) -#define ASMJIT_LOOKUP_TABLE_32(T, I) ASMJIT_LOOKUP_TABLE_16(T, I), ASMJIT_LOOKUP_TABLE_16(T, I + 16) -#define ASMJIT_LOOKUP_TABLE_40(T, I) ASMJIT_LOOKUP_TABLE_16(T, I), ASMJIT_LOOKUP_TABLE_16(T, I + 16), ASMJIT_LOOKUP_TABLE_8(T, I + 32) -#define ASMJIT_LOOKUP_TABLE_64(T, I) ASMJIT_LOOKUP_TABLE_32(T, I), ASMJIT_LOOKUP_TABLE_32(T, I + 32) -#define ASMJIT_LOOKUP_TABLE_128(T, I) ASMJIT_LOOKUP_TABLE_64(T, I), ASMJIT_LOOKUP_TABLE_64(T, I + 64) -#define ASMJIT_LOOKUP_TABLE_256(T, I) ASMJIT_LOOKUP_TABLE_128(T, I), ASMJIT_LOOKUP_TABLE_128(T, I + 128) -#define ASMJIT_LOOKUP_TABLE_512(T, I) ASMJIT_LOOKUP_TABLE_256(T, I), ASMJIT_LOOKUP_TABLE_256(T, I + 256) -#define ASMJIT_LOOKUP_TABLE_1024(T, I) ASMJIT_LOOKUP_TABLE_512(T, I), ASMJIT_LOOKUP_TABLE_512(T, I + 512) - -//! \} -//! \endcond - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_MISC_P_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/operand.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/operand.cpp deleted file mode 100644 index cd5931f..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/operand.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/operand.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::Operand - Unit] -// ============================================================================ - -#if defined(ASMJIT_TEST) -UNIT(operand) { - INFO("Checking operand sizes"); - EXPECT(sizeof(Operand) == 16); - EXPECT(sizeof(BaseReg) == 16); - EXPECT(sizeof(BaseMem) == 16); - EXPECT(sizeof(Imm) == 16); - EXPECT(sizeof(Label) == 16); - - INFO("Checking basic functionality of Operand"); - Operand a, b; - Operand dummy; - - EXPECT(a.isNone() == true); - EXPECT(a.isReg() == false); - EXPECT(a.isMem() == false); - EXPECT(a.isImm() == false); - EXPECT(a.isLabel() == false); - EXPECT(a == b); - EXPECT(a._data[0] == 0); - EXPECT(a._data[1] == 0); - - INFO("Checking basic functionality of Label"); - Label label; - EXPECT(label.isValid() == false); - EXPECT(label.id() == Globals::kInvalidId); - - INFO("Checking basic functionality of BaseReg"); - EXPECT(BaseReg().isReg() == true); - EXPECT(BaseReg().isValid() == false); - EXPECT(BaseReg()._data[0] == 0); - EXPECT(BaseReg()._data[1] == 0); - EXPECT(dummy.as().isValid() == false); - - // Create some register (not specific to any architecture). - uint32_t rSig = Operand::kOpReg | (1 << Operand::kSignatureRegTypeShift ) | - (2 << Operand::kSignatureRegGroupShift) | - (8 << Operand::kSignatureSizeShift ) ; - BaseReg r1 = BaseReg::fromSignatureAndId(rSig, 5); - - EXPECT(r1.isValid() == true); - EXPECT(r1.isReg() == true); - EXPECT(r1.isReg(1) == true); - EXPECT(r1.isPhysReg() == true); - EXPECT(r1.isVirtReg() == false); - EXPECT(r1.signature() == rSig); - EXPECT(r1.type() == 1); - EXPECT(r1.group() == 2); - EXPECT(r1.size() == 8); - EXPECT(r1.id() == 5); - EXPECT(r1.isReg(1, 5) == true); // RegType and Id. - EXPECT(r1._data[0] == 0); - EXPECT(r1._data[1] == 0); - - // The same type of register having different id. - BaseReg r2(r1, 6); - EXPECT(r2.isValid() == true); - EXPECT(r2.isReg() == true); - EXPECT(r2.isReg(1) == true); - EXPECT(r2.isPhysReg() == true); - EXPECT(r2.isVirtReg() == false); - EXPECT(r2.signature() == rSig); - EXPECT(r2.type() == r1.type()); - EXPECT(r2.group() == r1.group()); - EXPECT(r2.size() == r1.size()); - EXPECT(r2.id() == 6); - EXPECT(r2.isReg(1, 6) == true); - - r1.reset(); - EXPECT(!r1.isReg()); - EXPECT(!r1.isValid()); - - INFO("Checking basic functionality of BaseMem"); - BaseMem m; - EXPECT(m.isMem()); - EXPECT(m == BaseMem()); - EXPECT(m.hasBase() == false); - EXPECT(m.hasIndex() == false); - EXPECT(m.hasOffset() == false); - EXPECT(m.isOffset64Bit() == true); - EXPECT(m.offset() == 0); - - m.setOffset(-1); - EXPECT(m.offsetLo32() == -1); - EXPECT(m.offset() == -1); - - int64_t x = int64_t(0xFF00FF0000000001u); - int32_t xHi = int32_t(0xFF00FF00u); - - m.setOffset(x); - EXPECT(m.offset() == x); - EXPECT(m.offsetLo32() == 1); - EXPECT(m.offsetHi32() == xHi); - - INFO("Checking basic functionality of Imm"); - Imm immValue(-42); - EXPECT(immValue.type() == Imm::kTypeInteger); - EXPECT(Imm(-1).value() == -1); - EXPECT(imm(-1).value() == -1); - EXPECT(immValue.value() == -42); - EXPECT(imm(0xFFFFFFFF).value() == int64_t(0xFFFFFFFF)); - - Imm immDouble(0.4); - EXPECT(immDouble.type() == Imm::kTypeDouble); - EXPECT(immDouble.valueAs() == 0.4); - EXPECT(immDouble == imm(0.4)); - -} -#endif - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/operand.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/operand.h deleted file mode 100644 index 05e4c0f..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/operand.h +++ /dev/null @@ -1,1530 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_OPERAND_H_INCLUDED -#define ASMJIT_CORE_OPERAND_H_INCLUDED - -#include "../core/archcommons.h" -#include "../core/support.h" - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [Macros] -// ============================================================================ - -//! Adds a template specialization for `REG_TYPE` into the local `RegTraits`. -#define ASMJIT_DEFINE_REG_TRAITS(REG, REG_TYPE, GROUP, SIZE, COUNT, TYPE_ID) \ -template<> \ -struct RegTraits { \ - typedef REG RegT; \ - \ - static constexpr uint32_t kValid = 1; \ - static constexpr uint32_t kCount = COUNT; \ - static constexpr uint32_t kTypeId = TYPE_ID; \ - \ - static constexpr uint32_t kType = REG_TYPE; \ - static constexpr uint32_t kGroup = GROUP; \ - static constexpr uint32_t kSize = SIZE; \ - \ - static constexpr uint32_t kSignature = \ - (Operand::kOpReg << Operand::kSignatureOpTypeShift ) | \ - (kType << Operand::kSignatureRegTypeShift ) | \ - (kGroup << Operand::kSignatureRegGroupShift) | \ - (kSize << Operand::kSignatureSizeShift ) ; \ -} - -//! Adds constructors and member functions to a class that implements abstract -//! register. Abstract register is register that doesn't have type or signature -//! yet, it's a base class like `x86::Reg` or `arm::Reg`. -#define ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \ -public: \ - /*! Default constructor that only setups basics. */ \ - constexpr REG() noexcept \ - : BASE(SignatureAndId(kSignature, kIdBad)) {} \ - \ - /*! Makes a copy of the `other` register operand. */ \ - constexpr REG(const REG& other) noexcept \ - : BASE(other) {} \ - \ - /*! Makes a copy of the `other` register having id set to `rId` */ \ - constexpr REG(const BaseReg& other, uint32_t rId) noexcept \ - : BASE(other, rId) {} \ - \ - /*! Creates a register based on `signature` and `rId`. */ \ - constexpr explicit REG(const SignatureAndId& sid) noexcept \ - : BASE(sid) {} \ - \ - /*! Creates a completely uninitialized REG register operand (garbage). */ \ - inline explicit REG(Globals::NoInit_) noexcept \ - : BASE(Globals::NoInit) {} \ - \ - /*! Creates a new register from register type and id. */ \ - static inline REG fromTypeAndId(uint32_t rType, uint32_t rId) noexcept { \ - return REG(SignatureAndId(signatureOf(rType), rId)); \ - } \ - \ - /*! Creates a new register from register signature and id. */ \ - static inline REG fromSignatureAndId(uint32_t rSgn, uint32_t rId) noexcept {\ - return REG(SignatureAndId(rSgn, rId)); \ - } \ - \ - /*! Clones the register operand. */ \ - constexpr REG clone() const noexcept { return REG(*this); } \ - \ - inline REG& operator=(const REG& other) noexcept = default; - -//! Adds constructors and member functions to a class that implements final -//! register. Final registers MUST HAVE a valid signature. -#define ASMJIT_DEFINE_FINAL_REG(REG, BASE, TRAITS) \ -public: \ - static constexpr uint32_t kThisType = TRAITS::kType; \ - static constexpr uint32_t kThisGroup = TRAITS::kGroup; \ - static constexpr uint32_t kThisSize = TRAITS::kSize; \ - static constexpr uint32_t kSignature = TRAITS::kSignature; \ - \ - ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \ - \ - /*! Creates a register operand having its id set to `rId`. */ \ - constexpr explicit REG(uint32_t rId) noexcept \ - : BASE(SignatureAndId(kSignature, rId)) {} - -//! \addtogroup asmjit_assembler -//! \{ - -// ============================================================================ -// [asmjit::Operand_] -// ============================================================================ - -//! Constructor-less `Operand`. -//! -//! Contains no initialization code and can be used safely to define an array -//! of operands that won't be initialized. This is an `Operand` compatible -//! data structure designed to be statically initialized, static const, or to -//! be used by the user to define an array of operands without having them -//! default initialized. -//! -//! The key difference between `Operand` and `Operand_`: -//! -//! ``` -//! Operand_ xArray[10]; // Not initialized, contains garbage. -//! Operand yArray[10]; // All operands initialized to none. -//! ``` -struct Operand_ { - //! Operand's signature that provides operand type and additional information. - uint32_t _signature; - //! Either base id as used by memory operand or any id as used by others. - uint32_t _baseId; - - //! Data specific to the operand type. - //! - //! The reason we don't use union is that we have `constexpr` constructors that - //! construct operands and other `constexpr` functions that return wither another - //! Operand or something else. These cannot generally work with unions so we also - //! cannot use `union` if we want to be standard compliant. - uint32_t _data[2]; - - //! Indexes to `_data` array. - enum DataIndex : uint32_t { - kDataMemIndexId = 0, - kDataMemOffsetLo = 1, - - kDataImmValueLo = ASMJIT_ARCH_LE ? 0 : 1, - kDataImmValueHi = ASMJIT_ARCH_LE ? 1 : 0 - }; - - //! Operand types that can be encoded in `Operand`. - enum OpType : uint32_t { - //! Not an operand or not initialized. - kOpNone = 0, - //! Operand is a register. - kOpReg = 1, - //! Operand is a memory. - kOpMem = 2, - //! Operand is an immediate value. - kOpImm = 3, - //! Operand is a label. - kOpLabel = 4 - }; - static_assert(kOpMem == kOpReg + 1, "asmjit::Operand requires `kOpMem` to be `kOpReg+1`."); - - //! Label tag. - enum LabelTag { - //! Label tag is used as a sub-type, forming a unique signature across all - //! operand types as 0x1 is never associated with any register type. This - //! means that a memory operand's BASE register can be constructed from - //! virtually any operand (register vs. label) by just assigning its type - //! (register type or label-tag) and operand id. - kLabelTag = 0x1 - }; - - // \cond INTERNAL - enum SignatureBits : uint32_t { - // Operand type (3 least significant bits). - // |........|........|........|.....XXX| - kSignatureOpTypeShift = 0, - kSignatureOpTypeMask = 0x07u << kSignatureOpTypeShift, - - // Register type (5 bits). - // |........|........|........|XXXXX...| - kSignatureRegTypeShift = 3, - kSignatureRegTypeMask = 0x1Fu << kSignatureRegTypeShift, - - // Register group (4 bits). - // |........|........|....XXXX|........| - kSignatureRegGroupShift = 8, - kSignatureRegGroupMask = 0x0Fu << kSignatureRegGroupShift, - - // Memory base type (5 bits). - // |........|........|........|XXXXX...| - kSignatureMemBaseTypeShift = 3, - kSignatureMemBaseTypeMask = 0x1Fu << kSignatureMemBaseTypeShift, - - // Memory index type (5 bits). - // |........|........|...XXXXX|........| - kSignatureMemIndexTypeShift = 8, - kSignatureMemIndexTypeMask = 0x1Fu << kSignatureMemIndexTypeShift, - - // Memory base+index combined (10 bits). - // |........|........|...XXXXX|XXXXX...| - kSignatureMemBaseIndexShift = 3, - kSignatureMemBaseIndexMask = 0x3FFu << kSignatureMemBaseIndexShift, - - // This memory operand represents a home-slot or stack (Compiler) (1 bit). - // |........|........|..X.....|........| - kSignatureMemRegHomeShift = 13, - kSignatureMemRegHomeFlag = 0x01u << kSignatureMemRegHomeShift, - - // Immediate type (1 bit). - // |........|........|........|....X...| - kSignatureImmTypeShift = 4, - kSignatureImmTypeMask = 0x01u << kSignatureImmTypeShift, - - // Predicate used by either registers or immediate values (4 bits). - // |........|XXXX....|........|........| - kSignaturePredicateShift = 20, - kSignaturePredicateMask = 0x0Fu << kSignaturePredicateShift, - - // Operand size (8 most significant bits). - // |XXXXXXXX|........|........|........| - kSignatureSizeShift = 24, - kSignatureSizeMask = 0xFFu << kSignatureSizeShift - }; - //! \endcond - - //! Constants useful for VirtId <-> Index translation. - enum VirtIdConstants : uint32_t { - //! Minimum valid packed-id. - kVirtIdMin = 256, - //! Maximum valid packed-id, excludes Globals::kInvalidId. - kVirtIdMax = Globals::kInvalidId - 1, - //! Count of valid packed-ids. - kVirtIdCount = uint32_t(kVirtIdMax - kVirtIdMin + 1) - }; - - //! Tests whether the given `id` is a valid virtual register id. Since AsmJit - //! supports both physical and virtual registers it must be able to distinguish - //! between these two. The idea is that physical registers are always limited - //! in size, so virtual identifiers start from `kVirtIdMin` and end at `kVirtIdMax`. - static ASMJIT_INLINE bool isVirtId(uint32_t id) noexcept { return id - kVirtIdMin < uint32_t(kVirtIdCount); } - //! Converts a real-id into a packed-id that can be stored in Operand. - static ASMJIT_INLINE uint32_t indexToVirtId(uint32_t id) noexcept { return id + kVirtIdMin; } - //! Converts a packed-id back to real-id. - static ASMJIT_INLINE uint32_t virtIdToIndex(uint32_t id) noexcept { return id - kVirtIdMin; } - - //! \name Construction & Destruction - //! \{ - - //! \cond INTERNAL - //! Initializes a `BaseReg` operand from `signature` and register `id`. - inline void _initReg(uint32_t signature, uint32_t id) noexcept { - _signature = signature; - _baseId = id; - _data[0] = 0; - _data[1] = 0; - } - //! \endcond - - //! Initializes the operand from `other` operand (used by operator overloads). - inline void copyFrom(const Operand_& other) noexcept { memcpy(this, &other, sizeof(Operand_)); } - - //! Resets the `Operand` to none. - //! - //! None operand is defined the following way: - //! - Its signature is zero (kOpNone, and the rest zero as well). - //! - Its id is `0`. - //! - The reserved8_4 field is set to `0`. - //! - The reserved12_4 field is set to zero. - //! - //! In other words, reset operands have all members set to zero. Reset operand - //! must match the Operand state right after its construction. Alternatively, - //! if you have an array of operands, you can simply use `memset()`. - //! - //! ``` - //! using namespace asmjit; - //! - //! Operand a; - //! Operand b; - //! assert(a == b); - //! - //! b = x86::eax; - //! assert(a != b); - //! - //! b.reset(); - //! assert(a == b); - //! - //! memset(&b, 0, sizeof(Operand)); - //! assert(a == b); - //! ``` - inline void reset() noexcept { - _signature = 0; - _baseId = 0; - _data[0] = 0; - _data[1] = 0; - } - - //! \} - - //! \name Operator Overloads - //! \{ - - //! Tests whether this operand is the same as `other`. - constexpr bool operator==(const Operand_& other) const noexcept { return equals(other); } - //! Tests whether this operand is not the same as `other`. - constexpr bool operator!=(const Operand_& other) const noexcept { return !equals(other); } - - //! \} - - //! \name Cast - //! \{ - - //! Casts this operand to `T` type. - template - inline T& as() noexcept { return static_cast(*this); } - - //! Casts this operand to `T` type (const). - template - inline const T& as() const noexcept { return static_cast(*this); } - - //! \} - - //! \name Accessors - //! \{ - - //! Tests whether the operand's signature matches the given signature `sign`. - constexpr bool hasSignature(uint32_t signature) const noexcept { return _signature == signature; } - //! Tests whether the operand's signature matches the signature of the `other` operand. - constexpr bool hasSignature(const Operand_& other) const noexcept { return _signature == other.signature(); } - - //! Returns operand signature as unsigned 32-bit integer. - //! - //! Signature is first 4 bytes of the operand data. It's used mostly for - //! operand checking as it's much faster to check 4 bytes at once than having - //! to check these bytes individually. - constexpr uint32_t signature() const noexcept { return _signature; } - - //! Sets the operand signature, see `signature()`. - //! - //! \note Improper use of `setSignature()` can lead to hard-to-debug errors. - inline void setSignature(uint32_t signature) noexcept { _signature = signature; } - - //! \cond INTERNAL - template - constexpr bool _hasSignaturePart() const noexcept { - return (_signature & mask) != 0; - } - - template - constexpr bool _hasSignaturePart(uint32_t signature) const noexcept { - return (_signature & mask) == signature; - } - - template - constexpr uint32_t _getSignaturePart() const noexcept { - return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask)); - } - - template - inline void _setSignaturePart(uint32_t value) noexcept { - ASMJIT_ASSERT((value & ~(mask >> Support::constCtz(mask))) == 0); - _signature = (_signature & ~mask) | (value << Support::constCtz(mask)); - } - //! \endcond - - //! Returns the type of the operand, see `OpType`. - constexpr uint32_t opType() const noexcept { return _getSignaturePart(); } - //! Tests whether the operand is none (`kOpNone`). - constexpr bool isNone() const noexcept { return _signature == 0; } - //! Tests whether the operand is a register (`kOpReg`). - constexpr bool isReg() const noexcept { return opType() == kOpReg; } - //! Tests whether the operand is a memory location (`kOpMem`). - constexpr bool isMem() const noexcept { return opType() == kOpMem; } - //! Tests whether the operand is an immediate (`kOpImm`). - constexpr bool isImm() const noexcept { return opType() == kOpImm; } - //! Tests whether the operand is a label (`kOpLabel`). - constexpr bool isLabel() const noexcept { return opType() == kOpLabel; } - - //! Tests whether the operand is a physical register. - constexpr bool isPhysReg() const noexcept { return isReg() && _baseId < 0xFFu; } - //! Tests whether the operand is a virtual register. - constexpr bool isVirtReg() const noexcept { return isReg() && _baseId > 0xFFu; } - - //! Tests whether the operand specifies a size (i.e. the size is not zero). - constexpr bool hasSize() const noexcept { return _hasSignaturePart(); } - //! Tests whether the size of the operand matches `size`. - constexpr bool hasSize(uint32_t s) const noexcept { return size() == s; } - - //! Returns the size of the operand in bytes. - //! - //! The value returned depends on the operand type: - //! * None - Should always return zero size. - //! * Reg - Should always return the size of the register. If the register - //! size depends on architecture (like `x86::CReg` and `x86::DReg`) - //! the size returned should be the greatest possible (so it should - //! return 64-bit size in such case). - //! * Mem - Size is optional and will be in most cases zero. - //! * Imm - Should always return zero size. - //! * Label - Should always return zero size. - constexpr uint32_t size() const noexcept { return _getSignaturePart(); } - - //! Returns the operand id. - //! - //! The value returned should be interpreted accordingly to the operand type: - //! * None - Should be `0`. - //! * Reg - Physical or virtual register id. - //! * Mem - Multiple meanings - BASE address (register or label id), or - //! high value of a 64-bit absolute address. - //! * Imm - Should be `0`. - //! * Label - Label id if it was created by using `newLabel()` or - //! `Globals::kInvalidId` if the label is invalid or not - //! initialized. - constexpr uint32_t id() const noexcept { return _baseId; } - - //! Tests whether the operand is 100% equal to `other` operand. - //! - //! \note This basically performs a binary comparison, if aby bit is - //! different the operands are not equal. - constexpr bool equals(const Operand_& other) const noexcept { - return (_signature == other._signature) & - (_baseId == other._baseId ) & - (_data[0] == other._data[0] ) & - (_data[1] == other._data[1] ) ; - } - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use equals() instead") - constexpr bool isEqual(const Operand_& other) const noexcept { return equals(other); } -#endif //!ASMJIT_NO_DEPRECATED - - //! Tests whether the operand is a register matching `rType`. - constexpr bool isReg(uint32_t rType) const noexcept { - return (_signature & (kSignatureOpTypeMask | kSignatureRegTypeMask)) == - ((kOpReg << kSignatureOpTypeShift) | (rType << kSignatureRegTypeShift)); - } - - //! Tests whether the operand is register and of `rType` and `rId`. - constexpr bool isReg(uint32_t rType, uint32_t rId) const noexcept { - return isReg(rType) && id() == rId; - } - - //! Tests whether the operand is a register or memory. - constexpr bool isRegOrMem() const noexcept { - return Support::isBetween(opType(), kOpReg, kOpMem); - } - - //! \} -}; - -// ============================================================================ -// [asmjit::Operand] -// ============================================================================ - -//! Operand can contain register, memory location, immediate, or label. -class Operand : public Operand_ { -public: - //! \name Construction & Destruction - //! \{ - - //! Creates `kOpNone` operand having all members initialized to zero. - constexpr Operand() noexcept - : Operand_{ kOpNone, 0u, { 0u, 0u }} {} - - //! Creates a cloned `other` operand. - constexpr Operand(const Operand& other) noexcept = default; - - //! Creates a cloned `other` operand. - constexpr explicit Operand(const Operand_& other) - : Operand_(other) {} - - //! Creates an operand initialized to raw `[u0, u1, u2, u3]` values. - constexpr Operand(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept - : Operand_{ u0, u1, { u2, u3 }} {} - - //! Creates an uninitialized operand (dangerous). - inline explicit Operand(Globals::NoInit_) noexcept {} - - //! \} - - //! \name Operator Overloads - //! \{ - - inline Operand& operator=(const Operand& other) noexcept = default; - inline Operand& operator=(const Operand_& other) noexcept { return operator=(static_cast(other)); } - - //! \} - - //! \name Utilities - //! \{ - - //! Clones this operand and returns its copy. - constexpr Operand clone() const noexcept { return Operand(*this); } - - //! \} -}; - -static_assert(sizeof(Operand) == 16, "asmjit::Operand must be exactly 16 bytes long"); - -// ============================================================================ -// [asmjit::Label] -// ============================================================================ - -//! Label (jump target or data location). -//! -//! Label represents a location in code typically used as a jump target, but -//! may be also a reference to some data or a static variable. Label has to be -//! explicitly created by BaseEmitter. -//! -//! Example of using labels: -//! -//! ``` -//! // Create some emitter (for example x86::Assembler). -//! x86::Assembler a; -//! -//! // Create Label instance. -//! Label L1 = a.newLabel(); -//! -//! // ... your code ... -//! -//! // Using label. -//! a.jump(L1); -//! -//! // ... your code ... -//! -//! // Bind label to the current position, see `BaseEmitter::bind()`. -//! a.bind(L1); -//! ``` -class Label : public Operand { -public: - //! Type of the Label. - enum LabelType : uint32_t { - //! Anonymous (unnamed) label. - kTypeAnonymous = 0, - //! Local label (always has parentId). - kTypeLocal = 1, - //! Global label (never has parentId). - kTypeGlobal = 2, - //! External label (references an external symbol). - kTypeExternal = 3, - //! Number of label types. - kTypeCount = 4 - }; - - //! \name Construction & Destruction - //! \{ - - //! Creates a label operand without ID (you must set the ID to make it valid). - constexpr Label() noexcept - : Operand(Globals::Init, kOpLabel, Globals::kInvalidId, 0, 0) {} - - //! Creates a cloned label operand of `other`. - constexpr Label(const Label& other) noexcept - : Operand(other) {} - - //! Creates a label operand of the given `id`. - constexpr explicit Label(uint32_t id) noexcept - : Operand(Globals::Init, kOpLabel, id, 0, 0) {} - - inline explicit Label(Globals::NoInit_) noexcept - : Operand(Globals::NoInit) {} - - //! Resets the label, will reset all properties and set its ID to `Globals::kInvalidId`. - inline void reset() noexcept { - _signature = kOpLabel; - _baseId = Globals::kInvalidId; - _data[0] = 0; - _data[1] = 0; - } - - //! \} - - //! \name Overloaded Operators - //! \{ - - inline Label& operator=(const Label& other) noexcept = default; - - //! \} - - //! \name Accessors - //! \{ - - //! Tests whether the label was created by CodeHolder and/or an attached emitter. - constexpr bool isValid() const noexcept { return _baseId != Globals::kInvalidId; } - //! Sets the label `id`. - inline void setId(uint32_t id) noexcept { _baseId = id; } - - //! \} -}; - -// ============================================================================ -// [asmjit::BaseRegTraits] -// ============================================================================ - -//! \cond INTERNAL -//! Default register traits. -struct BaseRegTraits { - //! RegType is not valid by default. - static constexpr uint32_t kValid = 0; - //! Count of registers (0 if none). - static constexpr uint32_t kCount = 0; - //! Everything is void by default. - static constexpr uint32_t kTypeId = 0; - - //! Zero type by default. - static constexpr uint32_t kType = 0; - //! Zero group by default. - static constexpr uint32_t kGroup = 0; - //! No size by default. - static constexpr uint32_t kSize = 0; - - //! Empty signature by default (not even having operand type set to register). - static constexpr uint32_t kSignature = 0; -}; -//! \endcond - -// ============================================================================ -// [asmjit::BaseReg] -// ============================================================================ - -//! Structure that allows to extract a register information based on the signature. -//! -//! This information is compatible with operand's signature (32-bit integer) -//! and `RegInfo` just provides easy way to access it. -struct RegInfo { - inline void reset(uint32_t signature = 0) noexcept { _signature = signature; } - inline void setSignature(uint32_t signature) noexcept { _signature = signature; } - - template - constexpr uint32_t _getSignaturePart() const noexcept { - return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask)); - } - - constexpr bool isValid() const noexcept { return _signature != 0; } - constexpr uint32_t signature() const noexcept { return _signature; } - constexpr uint32_t opType() const noexcept { return _getSignaturePart(); } - constexpr uint32_t group() const noexcept { return _getSignaturePart(); } - constexpr uint32_t type() const noexcept { return _getSignaturePart(); } - constexpr uint32_t size() const noexcept { return _getSignaturePart(); } - - uint32_t _signature; -}; - -//! Physical or virtual register operand. -class BaseReg : public Operand { -public: - static constexpr uint32_t kBaseSignature = - kSignatureOpTypeMask | - kSignatureRegTypeMask | - kSignatureRegGroupMask | - kSignatureSizeMask ; - - //! Architecture neutral register types. - //! - //! These must be reused by any platform that contains that types. All GP - //! and VEC registers are also allowed by design to be part of a BASE|INDEX - //! of a memory operand. - enum RegType : uint32_t { - //! No register - unused, invalid, multiple meanings. - kTypeNone = 0, - - // (1 is used as a LabelTag) - - //! 8-bit low general purpose register (X86). - kTypeGp8Lo = 2, - //! 8-bit high general purpose register (X86). - kTypeGp8Hi = 3, - //! 16-bit general purpose register (X86). - kTypeGp16 = 4, - //! 32-bit general purpose register (X86|ARM). - kTypeGp32 = 5, - //! 64-bit general purpose register (X86|ARM). - kTypeGp64 = 6, - //! 8-bit view of a vector register (ARM). - kTypeVec8 = 7, - //! 16-bit view of a vector register (ARM). - kTypeVec16 = 8, - //! 32-bit view of a vector register (ARM). - kTypeVec32 = 9, - //! 64-bit view of a vector register (ARM). - kTypeVec64 = 10, - //! 128-bit view of a vector register (X86|ARM). - kTypeVec128 = 11, - //! 256-bit view of a vector register (X86). - kTypeVec256 = 12, - //! 512-bit view of a vector register (X86). - kTypeVec512 = 13, - //! 1024-bit view of a vector register (future). - kTypeVec1024 = 14, - //! Other0 register, should match `kOther0` group. - kTypeOther0 = 15, - //! Other1 register, should match `kOther1` group. - kTypeOther1 = 16, - //! Universal id of IP/PC register (if separate). - kTypeIP = 17, - //! Start of platform dependent register types. - kTypeCustom = 18, - //! Maximum possible register type value. - kTypeMax = 31 - }; - - //! Register group (architecture neutral), and some limits. - enum RegGroup : uint32_t { - //! General purpose register group compatible with all backends. - kGroupGp = 0, - //! Vector register group compatible with all backends. - kGroupVec = 1, - //! Group that is architecture dependent. - kGroupOther0 = 2, - //! Group that is architecture dependent. - kGroupOther1 = 3, - //! Count of register groups used by physical and virtual registers. - kGroupVirt = 4, - //! Count of register groups used by physical registers only. - kGroupCount = 16 - }; - - enum Id : uint32_t { - //! None or any register (mostly internal). - kIdBad = 0xFFu - }; - - //! A helper used by constructors. - struct SignatureAndId { - uint32_t _signature; - uint32_t _id; - - inline SignatureAndId() noexcept = default; - constexpr SignatureAndId(const SignatureAndId& other) noexcept = default; - - constexpr explicit SignatureAndId(uint32_t signature, uint32_t id) noexcept - : _signature(signature), - _id(id) {} - - constexpr uint32_t signature() const noexcept { return _signature; } - constexpr uint32_t id() const noexcept { return _id; } - }; - - static constexpr uint32_t kSignature = kOpReg; - - //! \name Construction & Destruction - //! \{ - - //! Creates a dummy register operand. - constexpr BaseReg() noexcept - : Operand(Globals::Init, kSignature, kIdBad, 0, 0) {} - - //! Creates a new register operand which is the same as `other` . - constexpr BaseReg(const BaseReg& other) noexcept - : Operand(other) {} - - //! Creates a new register operand compatible with `other`, but with a different `rId`. - constexpr BaseReg(const BaseReg& other, uint32_t rId) noexcept - : Operand(Globals::Init, other._signature, rId, 0, 0) {} - - //! Creates a register initialized to `signature` and `rId`. - constexpr explicit BaseReg(const SignatureAndId& sid) noexcept - : Operand(Globals::Init, sid._signature, sid._id, 0, 0) {} - - inline explicit BaseReg(Globals::NoInit_) noexcept - : Operand(Globals::NoInit) {} - - /*! Creates a new register from register signature `rSgn` and id. */ - static inline BaseReg fromSignatureAndId(uint32_t rSgn, uint32_t rId) noexcept { - return BaseReg(SignatureAndId(rSgn, rId)); - } - - //! \} - - //! \name Overloaded Operators - //! \{ - - inline BaseReg& operator=(const BaseReg& other) noexcept = default; - - //! \} - - //! \name Accessors - //! \{ - - //! Returns base signature of the register associated with each register type. - //! - //! Base signature only contains the operand type, register type, register - //! group, and register size. It doesn't contain element type, predicate, or - //! other architecture-specific data. Base signature is a signature that is - //! provided by architecture-specific `RegTraits`, like \ref x86::RegTraits. - constexpr uint32_t baseSignature() const noexcept { - return _signature & (kBaseSignature); - } - - //! Tests whether the operand's base signature matches the given signature `sign`. - constexpr bool hasBaseSignature(uint32_t signature) const noexcept { return baseSignature() == signature; } - //! Tests whether the operand's base signature matches the base signature of the `other` operand. - constexpr bool hasBaseSignature(const BaseReg& other) const noexcept { return baseSignature() == other.baseSignature(); } - - //! Tests whether this register is the same as `other`. - //! - //! This is just an optimization. Registers by default only use the first - //! 8 bytes of Operand data, so this method takes advantage of this knowledge - //! and only compares these 8 bytes. If both operands were created correctly - //! both \ref equals() and \ref isSame() should give the same answer, however, - //! if any of these two contains garbage or other metadata in the upper 8 - //! bytes then \ref isSame() may return `true` in cases in which \ref equals() - //! returns false. - constexpr bool isSame(const BaseReg& other) const noexcept { - return (_signature == other._signature) & (_baseId == other._baseId); - } - - //! Tests whether the register is valid (either virtual or physical). - constexpr bool isValid() const noexcept { return (_signature != 0) & (_baseId != kIdBad); } - - //! Tests whether this is a physical register. - constexpr bool isPhysReg() const noexcept { return _baseId < kIdBad; } - //! Tests whether this is a virtual register. - constexpr bool isVirtReg() const noexcept { return _baseId > kIdBad; } - - //! Tests whether the register type matches `type` - same as `isReg(type)`, provided for convenience. - constexpr bool isType(uint32_t type) const noexcept { return (_signature & kSignatureRegTypeMask) == (type << kSignatureRegTypeShift); } - //! Tests whether the register group matches `group`. - constexpr bool isGroup(uint32_t group) const noexcept { return (_signature & kSignatureRegGroupMask) == (group << kSignatureRegGroupShift); } - - //! Tests whether the register is a general purpose register (any size). - constexpr bool isGp() const noexcept { return isGroup(kGroupGp); } - //! Tests whether the register is a vector register. - constexpr bool isVec() const noexcept { return isGroup(kGroupVec); } - - using Operand_::isReg; - - //! Same as `isType()`, provided for convenience. - constexpr bool isReg(uint32_t rType) const noexcept { return isType(rType); } - //! Tests whether the register type matches `type` and register id matches `rId`. - constexpr bool isReg(uint32_t rType, uint32_t rId) const noexcept { return isType(rType) && id() == rId; } - - //! Returns the type of the register. - constexpr uint32_t type() const noexcept { return _getSignaturePart(); } - //! Returns the register group. - constexpr uint32_t group() const noexcept { return _getSignaturePart(); } - - //! Returns operation predicate of the register (ARM/AArch64). - //! - //! The meaning depends on architecture, for example on ARM hardware this - //! describes \ref arm::Predicate::ShiftOp of the register. - constexpr uint32_t predicate() const noexcept { return _getSignaturePart(); } - - //! Sets operation predicate of the register to `predicate` (ARM/AArch64). - //! - //! The meaning depends on architecture, for example on ARM hardware this - //! describes \ref arm::Predicate::ShiftOp of the register. - inline void setPredicate(uint32_t predicate) noexcept { _setSignaturePart(predicate); } - - //! Resets shift operation type of the register to the default value (ARM/AArch64). - inline void resetPredicate() noexcept { _setSignaturePart(0); } - - //! Clones the register operand. - constexpr BaseReg clone() const noexcept { return BaseReg(*this); } - - //! Casts this register to `RegT` by also changing its signature. - //! - //! \note Improper use of `cloneAs()` can lead to hard-to-debug errors. - template - constexpr RegT cloneAs() const noexcept { return RegT(RegT::kSignature, id()); } - - //! Casts this register to `other` by also changing its signature. - //! - //! \note Improper use of `cloneAs()` can lead to hard-to-debug errors. - template - constexpr RegT cloneAs(const RegT& other) const noexcept { return RegT(SignatureAndId(other.signature(), id())); } - - //! Sets the register id to `rId`. - inline void setId(uint32_t rId) noexcept { _baseId = rId; } - - //! Sets a 32-bit operand signature based on traits of `RegT`. - template - inline void setSignatureT() noexcept { _signature = RegT::kSignature; } - - //! Sets the register `signature` and `rId`. - inline void setSignatureAndId(uint32_t signature, uint32_t rId) noexcept { - _signature = signature; - _baseId = rId; - } - - //! \} - - //! \name Static Functions - //! \{ - - //! Tests whether the `op` operand is a general purpose register. - static inline bool isGp(const Operand_& op) noexcept { - // Check operand type and register group. Not interested in register type and size. - const uint32_t kSgn = (kOpReg << kSignatureOpTypeShift ) | - (kGroupGp << kSignatureRegGroupShift) ; - return (op.signature() & (kSignatureOpTypeMask | kSignatureRegGroupMask)) == kSgn; - } - - //! Tests whether the `op` operand is a vector register. - static inline bool isVec(const Operand_& op) noexcept { - // Check operand type and register group. Not interested in register type and size. - const uint32_t kSgn = (kOpReg << kSignatureOpTypeShift ) | - (kGroupVec << kSignatureRegGroupShift) ; - return (op.signature() & (kSignatureOpTypeMask | kSignatureRegGroupMask)) == kSgn; - } - - //! Tests whether the `op` is a general purpose register of the given `rId`. - static inline bool isGp(const Operand_& op, uint32_t rId) noexcept { return isGp(op) & (op.id() == rId); } - //! Tests whether the `op` is a vector register of the given `rId`. - static inline bool isVec(const Operand_& op, uint32_t rId) noexcept { return isVec(op) & (op.id() == rId); } - - //! \} -}; - -// ============================================================================ -// [asmjit::RegOnly] -// ============================================================================ - -//! RegOnly is 8-byte version of `BaseReg` that allows to store either register -//! or nothing. -//! -//! This class was designed to decrease the space consumed by each extra "operand" -//! in `BaseEmitter` and `InstNode` classes. -struct RegOnly { - //! Type of the operand, either `kOpNone` or `kOpReg`. - uint32_t _signature; - //! Physical or virtual register id. - uint32_t _id; - - //! \name Construction & Destruction - //! \{ - - //! Initializes the `RegOnly` instance to hold register `signature` and `id`. - inline void init(uint32_t signature, uint32_t id) noexcept { - _signature = signature; - _id = id; - } - - inline void init(const BaseReg& reg) noexcept { init(reg.signature(), reg.id()); } - inline void init(const RegOnly& reg) noexcept { init(reg.signature(), reg.id()); } - - //! Resets the `RegOnly` members to zeros (none). - inline void reset() noexcept { init(0, 0); } - - //! \} - - //! \name Accessors - //! \{ - - //! Tests whether this ExtraReg is none (same as calling `Operand_::isNone()`). - constexpr bool isNone() const noexcept { return _signature == 0; } - //! Tests whether the register is valid (either virtual or physical). - constexpr bool isReg() const noexcept { return _signature != 0; } - - //! Tests whether this is a physical register. - constexpr bool isPhysReg() const noexcept { return _id < BaseReg::kIdBad; } - //! Tests whether this is a virtual register (used by `BaseCompiler`). - constexpr bool isVirtReg() const noexcept { return _id > BaseReg::kIdBad; } - - //! Returns the register signature or 0 if no register is assigned. - constexpr uint32_t signature() const noexcept { return _signature; } - //! Returns the register id. - //! - //! \note Always check whether the register is assigned before using the - //! returned identifier as non-assigned `RegOnly` instance would return - //! zero id, which is still a valid register id. - constexpr uint32_t id() const noexcept { return _id; } - - //! Sets the register id. - inline void setId(uint32_t id) noexcept { _id = id; } - - //! \cond INTERNAL - //! - //! Extracts information from operand's signature. - template - constexpr uint32_t _getSignaturePart() const noexcept { - return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask)); - } - //! \endcond - - //! Returns the type of the register. - constexpr uint32_t type() const noexcept { return _getSignaturePart(); } - //! Returns the register group. - constexpr uint32_t group() const noexcept { return _getSignaturePart(); } - - //! \} - - //! \name Utilities - //! \{ - - //! Converts this ExtraReg to a real `RegT` operand. - template - constexpr RegT toReg() const noexcept { return RegT(BaseReg::SignatureAndId(_signature, _id)); } - - //! \} -}; - -// ============================================================================ -// [asmjit::BaseMem] -// ============================================================================ - -//! Base class for all memory operands. -//! -//! \note It's tricky to pack all possible cases that define a memory operand -//! into just 16 bytes. The `BaseMem` splits data into the following parts: -//! -//! - BASE - Base register or label - requires 36 bits total. 4 bits are used -//! to encode the type of the BASE operand (label vs. register type) and the -//! remaining 32 bits define the BASE id, which can be a physical or virtual -//! register index. If BASE type is zero, which is never used as a register -//! type and label doesn't use it as well then BASE field contains a high -//! DWORD of a possible 64-bit absolute address, which is possible on X64. -//! -//! - INDEX - Index register (or theoretically Label, which doesn't make sense). -//! Encoding is similar to BASE - it also requires 36 bits and splits the -//! encoding to INDEX type (4 bits defining the register type) and id (32-bits). -//! -//! - OFFSET - A relative offset of the address. Basically if BASE is specified -//! the relative displacement adjusts BASE and an optional INDEX. if BASE is -//! not specified then the OFFSET should be considered as ABSOLUTE address (at -//! least on X86). In that case its low 32 bits are stored in DISPLACEMENT -//! field and the remaining high 32 bits are stored in BASE. -//! -//! - OTHER - There is rest 8 bits that can be used for whatever purpose. For -//! example \ref x86::Mem operand uses these bits to store segment override -//! prefix and index shift (or scale). -class BaseMem : public Operand { -public: - //! \cond INTERNAL - //! Used internally to construct `BaseMem` operand from decomposed data. - struct Decomposed { - uint32_t baseType; - uint32_t baseId; - uint32_t indexType; - uint32_t indexId; - int32_t offset; - uint32_t size; - uint32_t flags; - }; - //! \endcond - - //! \name Construction & Destruction - //! \{ - - //! Creates a default `BaseMem` operand, that points to [0]. - constexpr BaseMem() noexcept - : Operand(Globals::Init, kOpMem, 0, 0, 0) {} - - //! Creates a `BaseMem` operand that is a clone of `other`. - constexpr BaseMem(const BaseMem& other) noexcept - : Operand(other) {} - - //! Creates a `BaseMem` operand from `baseReg` and `offset`. - //! - //! \note This is an architecture independent constructor that can be used to - //! create an architecture independent memory operand to be used in portable - //! code that can handle multiple architectures. - constexpr explicit BaseMem(const BaseReg& baseReg, int32_t offset = 0) noexcept - : Operand(Globals::Init, - kOpMem | (baseReg.type() << kSignatureMemBaseTypeShift), - baseReg.id(), - 0, - uint32_t(offset)) {} - - //! \cond INTERNAL - - //! Creates a `BaseMem` operand from 4 integers as used by `Operand_` struct. - constexpr BaseMem(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept - : Operand(Globals::Init, u0, u1, u2, u3) {} - - constexpr BaseMem(const Decomposed& d) noexcept - : Operand(Globals::Init, - kOpMem | (d.baseType << kSignatureMemBaseTypeShift ) - | (d.indexType << kSignatureMemIndexTypeShift) - | (d.size << kSignatureSizeShift ) - | d.flags, - d.baseId, - d.indexId, - uint32_t(d.offset)) {} - - //! \endcond - - //! Creates a completely uninitialized `BaseMem` operand. - inline explicit BaseMem(Globals::NoInit_) noexcept - : Operand(Globals::NoInit) {} - - //! Resets the memory operand - after the reset the memory points to [0]. - inline void reset() noexcept { - _signature = kOpMem; - _baseId = 0; - _data[0] = 0; - _data[1] = 0; - } - - //! \} - - //! \name Overloaded Operators - //! \{ - - inline BaseMem& operator=(const BaseMem& other) noexcept { copyFrom(other); return *this; } - - //! \} - - //! \name Accessors - //! \{ - - //! Clones the memory operand. - constexpr BaseMem clone() const noexcept { return BaseMem(*this); } - - //! Creates a new copy of this memory operand adjusted by `off`. - inline BaseMem cloneAdjusted(int64_t off) const noexcept { - BaseMem result(*this); - result.addOffset(off); - return result; - } - - //! Tests whether this memory operand is a register home (only used by \ref asmjit_compiler) - constexpr bool isRegHome() const noexcept { return _hasSignaturePart(); } - //! Mark this memory operand as register home (only used by \ref asmjit_compiler). - inline void setRegHome() noexcept { _signature |= kSignatureMemRegHomeFlag; } - //! Marks this operand to not be a register home (only used by \ref asmjit_compiler). - inline void clearRegHome() noexcept { _signature &= ~kSignatureMemRegHomeFlag; } - - //! Tests whether the memory operand has a BASE register or label specified. - constexpr bool hasBase() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0; } - //! Tests whether the memory operand has an INDEX register specified. - constexpr bool hasIndex() const noexcept { return (_signature & kSignatureMemIndexTypeMask) != 0; } - //! Tests whether the memory operand has BASE or INDEX register. - constexpr bool hasBaseOrIndex() const noexcept { return (_signature & kSignatureMemBaseIndexMask) != 0; } - //! Tests whether the memory operand has BASE and INDEX register. - constexpr bool hasBaseAndIndex() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0 && (_signature & kSignatureMemIndexTypeMask) != 0; } - - //! Tests whether the BASE operand is a register (registers start after `kLabelTag`). - constexpr bool hasBaseReg() const noexcept { return (_signature & kSignatureMemBaseTypeMask) > (Label::kLabelTag << kSignatureMemBaseTypeShift); } - //! Tests whether the BASE operand is a label. - constexpr bool hasBaseLabel() const noexcept { return (_signature & kSignatureMemBaseTypeMask) == (Label::kLabelTag << kSignatureMemBaseTypeShift); } - //! Tests whether the INDEX operand is a register (registers start after `kLabelTag`). - constexpr bool hasIndexReg() const noexcept { return (_signature & kSignatureMemIndexTypeMask) > (Label::kLabelTag << kSignatureMemIndexTypeShift); } - - //! Returns the type of the BASE register (0 if this memory operand doesn't - //! use the BASE register). - //! - //! \note If the returned type is one (a value never associated to a register - //! type) the BASE is not register, but it's a label. One equals to `kLabelTag`. - //! You should always check `hasBaseLabel()` before using `baseId()` result. - constexpr uint32_t baseType() const noexcept { return _getSignaturePart(); } - - //! Returns the type of an INDEX register (0 if this memory operand doesn't - //! use the INDEX register). - constexpr uint32_t indexType() const noexcept { return _getSignaturePart(); } - - //! This is used internally for BASE+INDEX validation. - constexpr uint32_t baseAndIndexTypes() const noexcept { return _getSignaturePart(); } - - //! Returns both BASE (4:0 bits) and INDEX (9:5 bits) types combined into a - //! single value. - //! - //! \remarks Returns id of the BASE register or label (if the BASE was - //! specified as label). - constexpr uint32_t baseId() const noexcept { return _baseId; } - - //! Returns the id of the INDEX register. - constexpr uint32_t indexId() const noexcept { return _data[kDataMemIndexId]; } - - //! Sets the id of the BASE register (without modifying its type). - inline void setBaseId(uint32_t rId) noexcept { _baseId = rId; } - //! Sets the id of the INDEX register (without modifying its type). - inline void setIndexId(uint32_t rId) noexcept { _data[kDataMemIndexId] = rId; } - - //! Sets the base register to type and id of the given `base` operand. - inline void setBase(const BaseReg& base) noexcept { return _setBase(base.type(), base.id()); } - //! Sets the index register to type and id of the given `index` operand. - inline void setIndex(const BaseReg& index) noexcept { return _setIndex(index.type(), index.id()); } - - //! \cond INTERNAL - inline void _setBase(uint32_t rType, uint32_t rId) noexcept { - _setSignaturePart(rType); - _baseId = rId; - } - - inline void _setIndex(uint32_t rType, uint32_t rId) noexcept { - _setSignaturePart(rType); - _data[kDataMemIndexId] = rId; - } - //! \endcond - - //! Resets the memory operand's BASE register or label. - inline void resetBase() noexcept { _setBase(0, 0); } - //! Resets the memory operand's INDEX register. - inline void resetIndex() noexcept { _setIndex(0, 0); } - - //! Sets the memory operand size (in bytes). - inline void setSize(uint32_t size) noexcept { _setSignaturePart(size); } - - //! Tests whether the memory operand has a 64-bit offset or absolute address. - //! - //! If this is true then `hasBase()` must always report false. - constexpr bool isOffset64Bit() const noexcept { return baseType() == 0; } - - //! Tests whether the memory operand has a non-zero offset or absolute address. - constexpr bool hasOffset() const noexcept { - return (_data[kDataMemOffsetLo] | uint32_t(_baseId & Support::bitMaskFromBool(isOffset64Bit()))) != 0; - } - - //! Returns either relative offset or absolute address as 64-bit integer. - constexpr int64_t offset() const noexcept { - return isOffset64Bit() ? int64_t(uint64_t(_data[kDataMemOffsetLo]) | (uint64_t(_baseId) << 32)) - : int64_t(int32_t(_data[kDataMemOffsetLo])); // Sign extend 32-bit offset. - } - - //! Returns a 32-bit low part of a 64-bit offset or absolute address. - constexpr int32_t offsetLo32() const noexcept { return int32_t(_data[kDataMemOffsetLo]); } - //! Returns a 32-but high part of a 64-bit offset or absolute address. - //! - //! \note This function is UNSAFE and returns garbage if `isOffset64Bit()` - //! returns false. Never use it blindly without checking it first. - constexpr int32_t offsetHi32() const noexcept { return int32_t(_baseId); } - - //! Sets a 64-bit offset or an absolute address to `offset`. - //! - //! \note This functions attempts to set both high and low parts of a 64-bit - //! offset, however, if the operand has a BASE register it will store only the - //! low 32 bits of the offset / address as there is no way to store both BASE - //! and 64-bit offset, and there is currently no architecture that has such - //! capability targeted by AsmJit. - inline void setOffset(int64_t offset) noexcept { - uint32_t lo = uint32_t(uint64_t(offset) & 0xFFFFFFFFu); - uint32_t hi = uint32_t(uint64_t(offset) >> 32); - uint32_t hiMsk = Support::bitMaskFromBool(isOffset64Bit()); - - _data[kDataMemOffsetLo] = lo; - _baseId = (hi & hiMsk) | (_baseId & ~hiMsk); - } - //! Sets a low 32-bit offset to `offset` (don't use without knowing how BaseMem works). - inline void setOffsetLo32(int32_t offset) noexcept { _data[kDataMemOffsetLo] = uint32_t(offset); } - - //! Adjusts the offset by `offset`. - //! - //! \note This is a fast function that doesn't use the HI 32-bits of a - //! 64-bit offset. Use it only if you know that there is a BASE register - //! and the offset is only 32 bits anyway. - - //! Adjusts the memory operand offset by a `offset`. - inline void addOffset(int64_t offset) noexcept { - if (isOffset64Bit()) { - int64_t result = offset + int64_t(uint64_t(_data[kDataMemOffsetLo]) | (uint64_t(_baseId) << 32)); - _data[kDataMemOffsetLo] = uint32_t(uint64_t(result) & 0xFFFFFFFFu); - _baseId = uint32_t(uint64_t(result) >> 32); - } - else { - _data[kDataMemOffsetLo] += uint32_t(uint64_t(offset) & 0xFFFFFFFFu); - } - } - - //! Adds `offset` to a low 32-bit offset part (don't use without knowing how - //! BaseMem works). - inline void addOffsetLo32(int32_t offset) noexcept { _data[kDataMemOffsetLo] += uint32_t(offset); } - - //! Resets the memory offset to zero. - inline void resetOffset() noexcept { setOffset(0); } - - //! Resets the lo part of the memory offset to zero (don't use without knowing - //! how BaseMem works). - inline void resetOffsetLo32() noexcept { setOffsetLo32(0); } - - //! \} -}; - -// ============================================================================ -// [asmjit::Imm] -// ============================================================================ - -//! Immediate operand. -//! -//! Immediate operand is usually part of instruction itself. It's inlined after -//! or before the instruction opcode. Immediates can be only signed or unsigned -//! integers. -//! -//! To create an immediate operand use `asmjit::imm()` helper, which can be used -//! with any type, not just the default 64-bit int. -class Imm : public Operand { -public: - //! Type of the immediate. - enum Type : uint32_t { - //! Immediate is integer. - kTypeInteger = 0, - //! Immediate is a floating point stored as double-precision. - kTypeDouble = 1 - }; - - //! \name Construction & Destruction - //! \{ - - //! Creates a new immediate value (initial value is 0). - inline constexpr Imm() noexcept - : Operand(Globals::Init, kOpImm, 0, 0, 0) {} - - //! Creates a new immediate value from `other`. - inline constexpr Imm(const Imm& other) noexcept - : Operand(other) {} - - //! Creates a new immediate value from ARM/AArch64 specific `shift`. - inline constexpr Imm(const arm::Shift& shift) noexcept - : Operand(Globals::Init, kOpImm | (shift.op() << kSignaturePredicateShift), - 0, - Support::unpackU32At0(shift.value()), - Support::unpackU32At1(shift.value())) {} - - //! Creates a new signed immediate value, assigning the value to `val` and - //! an architecture-specific predicate to `predicate`. - //! - //! \note Predicate is currently only used by ARM architectures. - template - inline constexpr Imm(const T& val, const uint32_t predicate = 0) noexcept - : Operand(Globals::Init, kOpImm | (predicate << kSignaturePredicateShift), - 0, - Support::unpackU32At0(int64_t(val)), - Support::unpackU32At1(int64_t(val))) {} - - inline Imm(const float& val, const uint32_t predicate = 0) noexcept - : Operand(Globals::Init, kOpImm | (predicate << kSignaturePredicateShift), 0, 0, 0) { setValue(val); } - - inline Imm(const double& val, const uint32_t predicate = 0) noexcept - : Operand(Globals::Init, kOpImm | (predicate << kSignaturePredicateShift), 0, 0, 0) { setValue(val); } - - inline explicit Imm(Globals::NoInit_) noexcept - : Operand(Globals::NoInit) {} - - //! \} - - //! \name Overloaded Operators - //! \{ - - //! Assigns the value of the `other` operand to this immediate. - inline Imm& operator=(const Imm& other) noexcept { copyFrom(other); return *this; } - - //! \} - - //! \name Accessors - //! \{ - - //! Returns immediate type, see \ref Type. - constexpr uint32_t type() const noexcept { return _getSignaturePart(); } - //! Sets the immediate type to `type`, see \ref Type. - inline void setType(uint32_t type) noexcept { _setSignaturePart(type); } - //! Resets immediate type to `kTypeInteger`. - inline void resetType() noexcept { setType(kTypeInteger); } - - //! Returns operation predicate of the immediate. - //! - //! The meaning depends on architecture, for example on ARM hardware this - //! describes \ref arm::Predicate::ShiftOp of the immediate. - constexpr uint32_t predicate() const noexcept { return _getSignaturePart(); } - - //! Sets operation predicate of the immediate to `predicate`. - //! - //! The meaning depends on architecture, for example on ARM hardware this - //! describes \ref arm::Predicate::ShiftOp of the immediate. - inline void setPredicate(uint32_t predicate) noexcept { _setSignaturePart(predicate); } - - //! Resets the shift operation type of the immediate to the default value (no operation). - inline void resetPredicate() noexcept { _setSignaturePart(0); } - - //! Returns the immediate value as `int64_t`, which is the internal format Imm uses. - constexpr int64_t value() const noexcept { - return int64_t((uint64_t(_data[kDataImmValueHi]) << 32) | _data[kDataImmValueLo]); - } - - //! Tests whether this immediate value is integer of any size. - constexpr uint32_t isInteger() const noexcept { return type() == kTypeInteger; } - //! Tests whether this immediate value is a double precision floating point value. - constexpr uint32_t isDouble() const noexcept { return type() == kTypeDouble; } - - //! Tests whether the immediate can be casted to 8-bit signed integer. - constexpr bool isInt8() const noexcept { return type() == kTypeInteger && Support::isInt8(value()); } - //! Tests whether the immediate can be casted to 8-bit unsigned integer. - constexpr bool isUInt8() const noexcept { return type() == kTypeInteger && Support::isUInt8(value()); } - //! Tests whether the immediate can be casted to 16-bit signed integer. - constexpr bool isInt16() const noexcept { return type() == kTypeInteger && Support::isInt16(value()); } - //! Tests whether the immediate can be casted to 16-bit unsigned integer. - constexpr bool isUInt16() const noexcept { return type() == kTypeInteger && Support::isUInt16(value()); } - //! Tests whether the immediate can be casted to 32-bit signed integer. - constexpr bool isInt32() const noexcept { return type() == kTypeInteger && Support::isInt32(value()); } - //! Tests whether the immediate can be casted to 32-bit unsigned integer. - constexpr bool isUInt32() const noexcept { return type() == kTypeInteger && _data[kDataImmValueHi] == 0; } - - //! Returns the immediate value casted to `T`. - //! - //! The value is masked before it's casted to `T` so the returned value is - //! simply the representation of `T` considering the original value's lowest - //! bits. - template - inline T valueAs() const noexcept { return Support::immediateToT(value()); } - - //! Returns low 32-bit signed integer. - constexpr int32_t int32Lo() const noexcept { return int32_t(_data[kDataImmValueLo]); } - //! Returns high 32-bit signed integer. - constexpr int32_t int32Hi() const noexcept { return int32_t(_data[kDataImmValueHi]); } - //! Returns low 32-bit signed integer. - constexpr uint32_t uint32Lo() const noexcept { return _data[kDataImmValueLo]; } - //! Returns high 32-bit signed integer. - constexpr uint32_t uint32Hi() const noexcept { return _data[kDataImmValueHi]; } - - //! Sets immediate value to `val`, the value is casted to a signed 64-bit integer. - template - inline void setValue(const T& val) noexcept { - _setValueInternal(Support::immediateFromT(val), std::is_floating_point::value ? kTypeDouble : kTypeInteger); - } - - inline void _setValueInternal(int64_t val, uint32_t type) noexcept { - setType(type); - _data[kDataImmValueHi] = uint32_t(uint64_t(val) >> 32); - _data[kDataImmValueLo] = uint32_t(uint64_t(val) & 0xFFFFFFFFu); - } - - //! \} - - //! \name Utilities - //! \{ - - //! Clones the immediate operand. - constexpr Imm clone() const noexcept { return Imm(*this); } - - inline void signExtend8Bits() noexcept { setValue(int64_t(valueAs())); } - inline void signExtend16Bits() noexcept { setValue(int64_t(valueAs())); } - inline void signExtend32Bits() noexcept { setValue(int64_t(valueAs())); } - - inline void zeroExtend8Bits() noexcept { setValue(valueAs()); } - inline void zeroExtend16Bits() noexcept { setValue(valueAs()); } - inline void zeroExtend32Bits() noexcept { _data[kDataImmValueHi] = 0u; } - - //! \} - -#ifndef ASMJIT_NO_DEPRECATED - ASMJIT_DEPRECATED("Use valueAs() instead") - inline int8_t i8() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use valueAs() instead") - inline uint8_t u8() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use valueAs() instead") - inline int16_t i16() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use valueAs() instead") - inline uint16_t u16() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use valueAs() instead") - inline int32_t i32() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use valueAs() instead") - inline uint32_t u32() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use value() instead") - inline int64_t i64() const noexcept { return value(); } - - ASMJIT_DEPRECATED("Use valueAs() instead") - inline uint64_t u64() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use valueAs() instead") - inline intptr_t iptr() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use valueAs() instead") - inline uintptr_t uptr() const noexcept { return valueAs(); } - - ASMJIT_DEPRECATED("Use int32Lo() instead") - inline int32_t i32Lo() const noexcept { return int32Lo(); } - - ASMJIT_DEPRECATED("Use uint32Lo() instead") - inline uint32_t u32Lo() const noexcept { return uint32Lo(); } - - ASMJIT_DEPRECATED("Use int32Hi() instead") - inline int32_t i32Hi() const noexcept { return int32Hi(); } - - ASMJIT_DEPRECATED("Use uint32Hi() instead") - inline uint32_t u32Hi() const noexcept { return uint32Hi(); } -#endif // !ASMJIT_NO_DEPRECATED -}; - -//! Creates a new immediate operand. -//! -//! Using `imm(x)` is much nicer than using `Imm(x)` as this is a template -//! which can accept any integer including pointers and function pointers. -template -static constexpr Imm imm(const T& val) noexcept { return Imm(val); } - -//! \} - -// ============================================================================ -// [asmjit::Globals::none] -// ============================================================================ - -namespace Globals { - //! \ingroup asmjit_assembler - //! - //! A default-constructed operand of `Operand_::kOpNone` type. - static constexpr const Operand none; -} - -// ============================================================================ -// [asmjit::Support::ForwardOp] -// ============================================================================ - -//! \cond INTERNAL -namespace Support { - -template -struct ForwardOpImpl { - static ASMJIT_INLINE const T& forward(const T& value) noexcept { return value; } -}; - -template -struct ForwardOpImpl { - static ASMJIT_INLINE Imm forward(const T& value) noexcept { return Imm(value); } -}; - -//! Either forwards operand T or returns a new operand for T if T is a type -//! convertible to operand. At the moment this is only used to convert integers -//! to \ref Imm operands. -template -struct ForwardOp : public ForwardOpImpl::type>::value> {}; - -} - -//! \endcond - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_OPERAND_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils.cpp b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils.cpp deleted file mode 100644 index e2f34ef..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#include "../core/api-build_p.h" -#include "../core/osutils.h" -#include "../core/support.h" - -#if defined(_WIN32) - #include -#elif defined(__APPLE__) - #include -#else - #include - #include -#endif - -ASMJIT_BEGIN_NAMESPACE - -// ============================================================================ -// [asmjit::OSUtils - GetTickCount] -// ============================================================================ - -uint32_t OSUtils::getTickCount() noexcept { -#if defined(_WIN32) - enum HiResStatus : uint32_t { - kHiResUnknown = 0, - kHiResAvailable = 1, - kHiResNotAvailable = 2 - }; - - static std::atomic _hiResStatus(kHiResUnknown); - static volatile double _hiResFreq(0); - - uint32_t status = _hiResStatus.load(); - LARGE_INTEGER now, qpf; - - if (status != kHiResNotAvailable && ::QueryPerformanceCounter(&now)) { - double freq = _hiResFreq; - if (status == kHiResUnknown) { - // Detects the availability of high resolution counter. - if (::QueryPerformanceFrequency(&qpf)) { - freq = double(qpf.QuadPart) / 1000.0; - _hiResFreq = freq; - _hiResStatus.compare_exchange_strong(status, kHiResAvailable); - status = kHiResAvailable; - } - else { - // High resolution not available. - _hiResStatus.compare_exchange_strong(status, kHiResNotAvailable); - } - } - - if (status == kHiResAvailable) - return uint32_t(uint64_t(int64_t(double(now.QuadPart) / freq)) & 0xFFFFFFFFu); - } - - // Bail to `GetTickCount()` if we cannot use high resolution. - return ::GetTickCount(); -#elif defined(__APPLE__) - // See Apple's QA1398. - static mach_timebase_info_data_t _machTime; - - uint32_t denom = _machTime.denom; - if (ASMJIT_UNLIKELY(!denom)) { - if (mach_timebase_info(&_machTime) != KERN_SUCCESS || !(denom = _machTime.denom)) - return 0; - } - - // `mach_absolute_time()` returns nanoseconds, we want milliseconds. - uint64_t t = mach_absolute_time() / 1000000u; - t = (t * _machTime.numer) / _machTime.denom; - return uint32_t(t & 0xFFFFFFFFu); -#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 - struct timespec ts; - if (ASMJIT_UNLIKELY(clock_gettime(CLOCK_MONOTONIC, &ts) != 0)) - return 0; - - uint64_t t = (uint64_t(ts.tv_sec ) * 1000u) + (uint64_t(ts.tv_nsec) / 1000000u); - return uint32_t(t & 0xFFFFFFFFu); -#else - #pragma message("asmjit::OSUtils::getTickCount() doesn't have implementation for the target OS.") - return 0; -#endif -} - -ASMJIT_END_NAMESPACE diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils.h deleted file mode 100644 index a469129..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils.h +++ /dev/null @@ -1,87 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_OSUTILS_H_INCLUDED -#define ASMJIT_CORE_OSUTILS_H_INCLUDED - -#include "../core/globals.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \addtogroup asmjit_utilities -//! \{ - -// ============================================================================ -// [asmjit::OSUtils] -// ============================================================================ - -//! Operating system utilities. -namespace OSUtils { - //! Gets the current CPU tick count, used for benchmarking (1ms resolution). - ASMJIT_API uint32_t getTickCount() noexcept; -}; - -// ============================================================================ -// [asmjit::Lock] -// ============================================================================ - -//! \cond INTERNAL - -//! Lock. -//! -//! Lock is internal, it cannot be used outside of AsmJit, however, its internal -//! layout is exposed as it's used by some other classes, which are public. -class Lock { -public: - ASMJIT_NONCOPYABLE(Lock) - -#if defined(_WIN32) -#pragma pack(push, 8) - struct ASMJIT_MAY_ALIAS Handle { - void* DebugInfo; - long LockCount; - long RecursionCount; - void* OwningThread; - void* LockSemaphore; - unsigned long* SpinCount; - }; - Handle _handle; -#pragma pack(pop) -#elif !defined(__EMSCRIPTEN__) - typedef pthread_mutex_t Handle; - Handle _handle; -#endif - - inline Lock() noexcept; - inline ~Lock() noexcept; - - inline void lock() noexcept; - inline void unlock() noexcept; -}; -//! \endcond - -//! \} - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_OSUTILS_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils_p.h deleted file mode 100644 index 31db308..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/osutils_p.h +++ /dev/null @@ -1,94 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_OSUTILS_P_H_INCLUDED -#define ASMJIT_CORE_OSUTILS_P_H_INCLUDED - -#include "../core/osutils.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \cond INTERNAL -//! \addtogroup asmjit_utilities -//! \{ - -// ============================================================================ -// [asmjit::Lock] -// ============================================================================ - -#if defined(_WIN32) - -// Windows implementation. -static_assert(sizeof(Lock::Handle) == sizeof(CRITICAL_SECTION), "asmjit::Lock::Handle layout must match CRITICAL_SECTION"); -static_assert(alignof(Lock::Handle) == alignof(CRITICAL_SECTION), "asmjit::Lock::Handle alignment must match CRITICAL_SECTION"); - -inline Lock::Lock() noexcept { InitializeCriticalSection(reinterpret_cast(&_handle)); } -inline Lock::~Lock() noexcept { DeleteCriticalSection(reinterpret_cast(&_handle)); } -inline void Lock::lock() noexcept { EnterCriticalSection(reinterpret_cast(&_handle)); } -inline void Lock::unlock() noexcept { LeaveCriticalSection(reinterpret_cast(&_handle)); } - -#elif !defined(__EMSCRIPTEN__) - -// PThread implementation. -#ifdef PTHREAD_MUTEX_INITIALIZER -inline Lock::Lock() noexcept : _handle(PTHREAD_MUTEX_INITIALIZER) {} -#else -inline Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); } -#endif -inline Lock::~Lock() noexcept { pthread_mutex_destroy(&_handle); } -inline void Lock::lock() noexcept { pthread_mutex_lock(&_handle); } -inline void Lock::unlock() noexcept { pthread_mutex_unlock(&_handle); } - -#else - -// Dummy implementation - Emscripten or other unsupported platform. -inline Lock::Lock() noexcept {} -inline Lock::~Lock() noexcept {} -inline void Lock::lock() noexcept {} -inline void Lock::unlock() noexcept {} - -#endif - -// ============================================================================ -// [asmjit::LockGuard] -// ============================================================================ - -//! Scoped lock. -class LockGuard { -public: - ASMJIT_NONCOPYABLE(LockGuard) - - Lock& _target; - - inline LockGuard(Lock& target) noexcept - : _target(target) { _target.lock(); } - inline ~LockGuard() noexcept { _target.unlock(); } -}; - -//! \} -//! \endcond - -ASMJIT_END_NAMESPACE - -#endif // ASMJIT_CORE_OSUTILS_P_H_INCLUDED - diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/raassignment_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/raassignment_p.h deleted file mode 100644 index bcdf1a9..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/raassignment_p.h +++ /dev/null @@ -1,408 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_RAASSIGNMENT_P_H_INCLUDED -#define ASMJIT_CORE_RAASSIGNMENT_P_H_INCLUDED - -#include "../core/api-config.h" -#ifndef ASMJIT_NO_COMPILER - -#include "../core/radefs_p.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \cond INTERNAL -//! \addtogroup asmjit_ra -//! \{ - -// ============================================================================ -// [asmjit::RAAssignment] -// ============================================================================ - -class RAAssignment { - ASMJIT_NONCOPYABLE(RAAssignment) - -public: - enum Ids : uint32_t { - kPhysNone = 0xFF, - kWorkNone = RAWorkReg::kIdNone - }; - - enum DirtyBit : uint32_t { - kClean = 0, - kDirty = 1 - }; - - struct Layout { - //! Index of architecture registers per group. - RARegIndex physIndex; - //! Count of architecture registers per group. - RARegCount physCount; - //! Count of physical registers of all groups. - uint32_t physTotal; - //! Count of work registers. - uint32_t workCount; - //! WorkRegs data (vector). - const RAWorkRegs* workRegs; - - inline void reset() noexcept { - physIndex.reset(); - physCount.reset(); - physTotal = 0; - workCount = 0; - workRegs = nullptr; - } - }; - - struct PhysToWorkMap { - //! Assigned registers (each bit represents one physical reg). - RARegMask assigned; - //! Dirty registers (spill slot out of sync or no spill slot). - RARegMask dirty; - //! PhysReg to WorkReg mapping. - uint32_t workIds[1 /* ... */]; - - static inline size_t sizeOf(size_t count) noexcept { - return sizeof(PhysToWorkMap) - sizeof(uint32_t) + count * sizeof(uint32_t); - } - - inline void reset(size_t count) noexcept { - assigned.reset(); - dirty.reset(); - - for (size_t i = 0; i < count; i++) - workIds[i] = kWorkNone; - } - - inline void copyFrom(const PhysToWorkMap* other, size_t count) noexcept { - size_t size = sizeOf(count); - memcpy(this, other, size); - } - }; - - struct WorkToPhysMap { - //! WorkReg to PhysReg mapping - uint8_t physIds[1 /* ... */]; - - static inline size_t sizeOf(size_t count) noexcept { - return size_t(count) * sizeof(uint8_t); - } - - inline void reset(size_t count) noexcept { - for (size_t i = 0; i < count; i++) - physIds[i] = kPhysNone; - } - - inline void copyFrom(const WorkToPhysMap* other, size_t count) noexcept { - size_t size = sizeOf(count); - if (ASMJIT_LIKELY(size)) - memcpy(this, other, size); - } - }; - - //! Physical registers layout. - Layout _layout; - //! WorkReg to PhysReg mapping. - WorkToPhysMap* _workToPhysMap; - //! PhysReg to WorkReg mapping and assigned/dirty bits. - PhysToWorkMap* _physToWorkMap; - //! Optimization to translate PhysRegs to WorkRegs faster. - uint32_t* _physToWorkIds[BaseReg::kGroupVirt]; - - //! \name Construction & Destruction - //! \{ - - inline RAAssignment() noexcept { - _layout.reset(); - resetMaps(); - } - - inline void initLayout(const RARegCount& physCount, const RAWorkRegs& workRegs) noexcept { - // Layout must be initialized before data. - ASMJIT_ASSERT(_physToWorkMap == nullptr); - ASMJIT_ASSERT(_workToPhysMap == nullptr); - - _layout.physIndex.buildIndexes(physCount); - _layout.physCount = physCount; - _layout.physTotal = uint32_t(_layout.physIndex[BaseReg::kGroupVirt - 1]) + - uint32_t(_layout.physCount[BaseReg::kGroupVirt - 1]) ; - _layout.workCount = workRegs.size(); - _layout.workRegs = &workRegs; - } - - inline void initMaps(PhysToWorkMap* physToWorkMap, WorkToPhysMap* workToPhysMap) noexcept { - _physToWorkMap = physToWorkMap; - _workToPhysMap = workToPhysMap; - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) - _physToWorkIds[group] = physToWorkMap->workIds + _layout.physIndex.get(group); - } - - inline void resetMaps() noexcept { - _physToWorkMap = nullptr; - _workToPhysMap = nullptr; - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) - _physToWorkIds[group] = nullptr; - } - - //! \} - - //! \name Accessors - //! \{ - - inline PhysToWorkMap* physToWorkMap() const noexcept { return _physToWorkMap; } - inline WorkToPhysMap* workToPhysMap() const noexcept { return _workToPhysMap; } - - inline RARegMask& assigned() noexcept { return _physToWorkMap->assigned; } - inline const RARegMask& assigned() const noexcept { return _physToWorkMap->assigned; } - inline uint32_t assigned(uint32_t group) const noexcept { return _physToWorkMap->assigned[group]; } - - inline RARegMask& dirty() noexcept { return _physToWorkMap->dirty; } - inline const RARegMask& dirty() const noexcept { return _physToWorkMap->dirty; } - inline uint32_t dirty(uint32_t group) const noexcept { return _physToWorkMap->dirty[group]; } - - inline uint32_t workToPhysId(uint32_t group, uint32_t workId) const noexcept { - DebugUtils::unused(group); - ASMJIT_ASSERT(workId != kWorkNone); - ASMJIT_ASSERT(workId < _layout.workCount); - return _workToPhysMap->physIds[workId]; - } - - inline uint32_t physToWorkId(uint32_t group, uint32_t physId) const noexcept { - ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs); - return _physToWorkIds[group][physId]; - } - - inline bool isPhysAssigned(uint32_t group, uint32_t physId) const noexcept { - ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs); - return Support::bitTest(_physToWorkMap->assigned[group], physId); - } - - inline bool isPhysDirty(uint32_t group, uint32_t physId) const noexcept { - ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs); - return Support::bitTest(_physToWorkMap->dirty[group], physId); - } - - //! \} - - //! \name Assignment - //! \{ - - // These are low-level allocation helpers that are used to update the current - // mappings between physical and virt/work registers and also to update masks - // that represent allocated and dirty registers. These functions don't emit - // any code; they are only used to update and keep all mappings in sync. - - //! Assign [VirtReg/WorkReg] to a physical register. - ASMJIT_INLINE void assign(uint32_t group, uint32_t workId, uint32_t physId, uint32_t dirty) noexcept { - ASMJIT_ASSERT(workToPhysId(group, workId) == kPhysNone); - ASMJIT_ASSERT(physToWorkId(group, physId) == kWorkNone); - ASMJIT_ASSERT(!isPhysAssigned(group, physId)); - ASMJIT_ASSERT(!isPhysDirty(group, physId)); - - _workToPhysMap->physIds[workId] = uint8_t(physId); - _physToWorkIds[group][physId] = workId; - - uint32_t regMask = Support::bitMask(physId); - _physToWorkMap->assigned[group] |= regMask; - _physToWorkMap->dirty[group] |= regMask & Support::bitMaskFromBool(dirty); - - verify(); - } - - //! Reassign [VirtReg/WorkReg] to `dstPhysId` from `srcPhysId`. - ASMJIT_INLINE void reassign(uint32_t group, uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept { - ASMJIT_ASSERT(dstPhysId != srcPhysId); - ASMJIT_ASSERT(workToPhysId(group, workId) == srcPhysId); - ASMJIT_ASSERT(physToWorkId(group, srcPhysId) == workId); - ASMJIT_ASSERT(isPhysAssigned(group, srcPhysId) == true); - ASMJIT_ASSERT(isPhysAssigned(group, dstPhysId) == false); - - _workToPhysMap->physIds[workId] = uint8_t(dstPhysId); - _physToWorkIds[group][srcPhysId] = kWorkNone; - _physToWorkIds[group][dstPhysId] = workId; - - uint32_t srcMask = Support::bitMask(srcPhysId); - uint32_t dstMask = Support::bitMask(dstPhysId); - - uint32_t dirty = (_physToWorkMap->dirty[group] & srcMask) != 0; - uint32_t regMask = dstMask | srcMask; - - _physToWorkMap->assigned[group] ^= regMask; - _physToWorkMap->dirty[group] ^= regMask & Support::bitMaskFromBool(dirty); - - verify(); - } - - ASMJIT_INLINE void swap(uint32_t group, uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept { - ASMJIT_ASSERT(aPhysId != bPhysId); - ASMJIT_ASSERT(workToPhysId(group, aWorkId) == aPhysId); - ASMJIT_ASSERT(workToPhysId(group, bWorkId) == bPhysId); - ASMJIT_ASSERT(physToWorkId(group, aPhysId) == aWorkId); - ASMJIT_ASSERT(physToWorkId(group, bPhysId) == bWorkId); - ASMJIT_ASSERT(isPhysAssigned(group, aPhysId)); - ASMJIT_ASSERT(isPhysAssigned(group, bPhysId)); - - _workToPhysMap->physIds[aWorkId] = uint8_t(bPhysId); - _workToPhysMap->physIds[bWorkId] = uint8_t(aPhysId); - _physToWorkIds[group][aPhysId] = bWorkId; - _physToWorkIds[group][bPhysId] = aWorkId; - - uint32_t aMask = Support::bitMask(aPhysId); - uint32_t bMask = Support::bitMask(bPhysId); - - uint32_t flipMask = Support::bitMaskFromBool( - ((_physToWorkMap->dirty[group] & aMask) != 0) ^ - ((_physToWorkMap->dirty[group] & bMask) != 0)); - - uint32_t regMask = aMask | bMask; - _physToWorkMap->dirty[group] ^= regMask & flipMask; - - verify(); - } - - //! Unassign [VirtReg/WorkReg] from a physical register. - ASMJIT_INLINE void unassign(uint32_t group, uint32_t workId, uint32_t physId) noexcept { - ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs); - ASMJIT_ASSERT(workToPhysId(group, workId) == physId); - ASMJIT_ASSERT(physToWorkId(group, physId) == workId); - ASMJIT_ASSERT(isPhysAssigned(group, physId)); - - _workToPhysMap->physIds[workId] = kPhysNone; - _physToWorkIds[group][physId] = kWorkNone; - - uint32_t regMask = Support::bitMask(physId); - _physToWorkMap->assigned[group] &= ~regMask; - _physToWorkMap->dirty[group] &= ~regMask; - - verify(); - } - - inline void makeClean(uint32_t group, uint32_t workId, uint32_t physId) noexcept { - DebugUtils::unused(workId); - uint32_t regMask = Support::bitMask(physId); - _physToWorkMap->dirty[group] &= ~regMask; - } - - inline void makeDirty(uint32_t group, uint32_t workId, uint32_t physId) noexcept { - DebugUtils::unused(workId); - uint32_t regMask = Support::bitMask(physId); - _physToWorkMap->dirty[group] |= regMask; - } - - //! \} - - //! \name Utilities - //! \{ - - inline void swap(RAAssignment& other) noexcept { - std::swap(_workToPhysMap, other._workToPhysMap); - std::swap(_physToWorkMap, other._physToWorkMap); - - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) - std::swap(_physToWorkIds[group], other._physToWorkIds[group]); - } - - inline void copyFrom(const PhysToWorkMap* physToWorkMap, const WorkToPhysMap* workToPhysMap) noexcept { - memcpy(_physToWorkMap, physToWorkMap, PhysToWorkMap::sizeOf(_layout.physTotal)); - memcpy(_workToPhysMap, workToPhysMap, WorkToPhysMap::sizeOf(_layout.workCount)); - } - - inline void copyFrom(const RAAssignment& other) noexcept { - copyFrom(other.physToWorkMap(), other.workToPhysMap()); - } - - // Not really useful outside of debugging. - bool equals(const RAAssignment& other) const noexcept { - // Layout should always match. - if (_layout.physIndex != other._layout.physIndex || - _layout.physCount != other._layout.physCount || - _layout.physTotal != other._layout.physTotal || - _layout.workCount != other._layout.workCount || - _layout.workRegs != other._layout.workRegs) - return false; - - uint32_t physTotal = _layout.physTotal; - uint32_t workCount = _layout.workCount; - - for (uint32_t physId = 0; physId < physTotal; physId++) { - uint32_t thisWorkId = _physToWorkMap->workIds[physId]; - uint32_t otherWorkId = other._physToWorkMap->workIds[physId]; - if (thisWorkId != otherWorkId) - return false; - } - - for (uint32_t workId = 0; workId < workCount; workId++) { - uint32_t thisPhysId = _workToPhysMap->physIds[workId]; - uint32_t otherPhysId = other._workToPhysMap->physIds[workId]; - if (thisPhysId != otherPhysId) - return false; - } - - if (_physToWorkMap->assigned != other._physToWorkMap->assigned || - _physToWorkMap->dirty != other._physToWorkMap->dirty ) - return false; - - return true; - } - -#if defined(ASMJIT_BUILD_DEBUG) - ASMJIT_NOINLINE void verify() noexcept { - // Verify WorkToPhysMap. - { - for (uint32_t workId = 0; workId < _layout.workCount; workId++) { - uint32_t physId = _workToPhysMap->physIds[workId]; - if (physId != kPhysNone) { - const RAWorkReg* workReg = _layout.workRegs->at(workId); - uint32_t group = workReg->group(); - ASMJIT_ASSERT(_physToWorkIds[group][physId] == workId); - } - } - } - - // Verify PhysToWorkMap. - { - for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) { - uint32_t physCount = _layout.physCount[group]; - for (uint32_t physId = 0; physId < physCount; physId++) { - uint32_t workId = _physToWorkIds[group][physId]; - if (workId != kWorkNone) { - ASMJIT_ASSERT(_workToPhysMap->physIds[workId] == physId); - } - } - } - } - } -#else - inline void verify() noexcept {} -#endif - - //! \} -}; - -//! \} -//! \endcond - -ASMJIT_END_NAMESPACE - -#endif // !ASMJIT_NO_COMPILER -#endif // ASMJIT_CORE_RAASSIGNMENT_P_H_INCLUDED diff --git a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/rabuilders_p.h b/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/rabuilders_p.h deleted file mode 100644 index 290839f..0000000 --- a/Examples/Theodosius-Kernel/Theodosius-MSREXEC/asmjit/core/rabuilders_p.h +++ /dev/null @@ -1,636 +0,0 @@ -// AsmJit - Machine code generation for C++ -// -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -#ifndef ASMJIT_CORE_RABUILDERS_P_H_INCLUDED -#define ASMJIT_CORE_RABUILDERS_P_H_INCLUDED - -#include "../core/api-config.h" -#ifndef ASMJIT_NO_COMPILER - -#include "../core/formatter.h" -#include "../core/rapass_p.h" - -ASMJIT_BEGIN_NAMESPACE - -//! \cond INTERNAL -//! \addtogroup asmjit_ra -//! \{ - -// ============================================================================ -// [asmjit::RACFGBuilderT] -// ============================================================================ - -template -class RACFGBuilderT { -public: - BaseRAPass* _pass = nullptr; - BaseCompiler* _cc = nullptr; - RABlock* _curBlock = nullptr; - RABlock* _retBlock = nullptr; - FuncNode* _funcNode = nullptr; - RARegsStats _blockRegStats {}; - uint32_t _exitLabelId = Globals::kInvalidId; - ZoneVector _sharedAssignmentsMap {}; - - // Only used by logging, it's fine to be here to prevent more #ifdefs... - bool _hasCode = false; - RABlock* _lastLoggedBlock = nullptr; - -#ifndef ASMJIT_NO_LOGGING - Logger* _logger = nullptr; - uint32_t _logFlags = FormatOptions::kFlagPositions; - StringTmp<512> _sb; -#endif - - static constexpr uint32_t kRootIndentation = 2; - static constexpr uint32_t kCodeIndentation = 4; - - // NOTE: This is a bit hacky. There are some nodes which are processed twice - // (see `onBeforeInvoke()` and `onBeforeRet()`) as they can insert some nodes - // around them. Since we don't have any flags to mark these we just use their - // position that is [at that time] unassigned. - static constexpr uint32_t kNodePositionDidOnBefore = 0xFFFFFFFFu; - - inline RACFGBuilderT(BaseRAPass* pass) noexcept - : _pass(pass), - _cc(pass->cc()) { -#ifndef ASMJIT_NO_LOGGING - _logger = _pass->debugLogger(); - if (_logger) - _logFlags |= _logger->flags(); -#endif - } - - inline BaseCompiler* cc() const noexcept { return _cc; } - - // -------------------------------------------------------------------------- - // [Run] - // -------------------------------------------------------------------------- - - //! Called per function by an architecture-specific CFG builder. - Error run() noexcept { - log("[RAPass::BuildCFG]\n"); - ASMJIT_PROPAGATE(prepare()); - - logNode(_funcNode, kRootIndentation); - logBlock(_curBlock, kRootIndentation); - - RABlock* entryBlock = _curBlock; - BaseNode* node = _funcNode->next(); - if (ASMJIT_UNLIKELY(!node)) - return DebugUtils::errored(kErrorInvalidState); - - _curBlock->setFirst(_funcNode); - _curBlock->setLast(_funcNode); - - RAInstBuilder ib; - ZoneVector blocksWithUnknownJumps; - - for (;;) { - BaseNode* next = node->next(); - ASMJIT_ASSERT(node->position() == 0 || node->position() == kNodePositionDidOnBefore); - - if (node->isInst()) { - // Instruction | Jump | Invoke | Return - // ------------------------------------ - - // Handle `InstNode`, `InvokeNode`, and `FuncRetNode`. All of them - // share the same interface that provides operands that have read/write - // semantics. - if (ASMJIT_UNLIKELY(!_curBlock)) { - // Unreachable code has to be removed, we cannot allocate registers - // in such code as we cannot do proper liveness analysis in such case. - removeNode(node); - node = next; - continue; - } - - _hasCode = true; - - if (node->isInvoke() || node->isFuncRet()) { - if (node->position() != kNodePositionDidOnBefore) { - // Call and Reg are complicated as they may insert some surrounding - // code around them. The simplest approach is to get the previous - // node, call the `onBefore()` handlers and then check whether - // anything changed and restart if so. By restart we mean that the - // current `node` would go back to the first possible inserted node - // by `onBeforeInvoke()` or `onBeforeRet()`. - BaseNode* prev = node->prev(); - - if (node->type() == BaseNode::kNodeInvoke) - ASMJIT_PROPAGATE(static_cast(this)->onBeforeInvoke(node->as())); - else - ASMJIT_PROPAGATE(static_cast(this)->onBeforeRet(node->as())); - - if (prev != node->prev()) { - // If this was the first node in the block and something was - // inserted before it then we have to update the first block. - if (_curBlock->first() == node) - _curBlock->setFirst(prev->next()); - - node->setPosition(kNodePositionDidOnBefore); - node = prev->next(); - - // `onBeforeInvoke()` and `onBeforeRet()` can only insert instructions. - ASMJIT_ASSERT(node->isInst()); - } - - // Necessary if something was inserted after `node`, but nothing before. - next = node->next(); - } - else { - // Change the position back to its original value. - node->setPosition(0); - } - } - - InstNode* inst = node->as(); - logNode(inst, kCodeIndentation); - - uint32_t controlType = BaseInst::kControlNone; - ib.reset(); - ASMJIT_PROPAGATE(static_cast(this)->onInst(inst, controlType, ib)); - - if (node->isInvoke()) { - ASMJIT_PROPAGATE(static_cast(this)->onInvoke(inst->as(), ib)); - } - - if (node->isFuncRet()) { - ASMJIT_PROPAGATE(static_cast(this)->onRet(inst->as(), ib)); - controlType = BaseInst::kControlReturn; - } - - if (controlType == BaseInst::kControlJump) { - uint32_t fixedRegCount = 0; - for (RATiedReg& tiedReg : ib) { - RAWorkReg* workReg = _pass->workRegById(tiedReg.workId()); - if (workReg->group() == BaseReg::kGroupGp) { - uint32_t useId = tiedReg.useId(); - if (useId == BaseReg::kIdBad) { - useId = _pass->_scratchRegIndexes[fixedRegCount++]; - tiedReg.setUseId(useId); - } - _curBlock->addExitScratchGpRegs(Support::bitMask(useId)); - } - } - } - - ASMJIT_PROPAGATE(_pass->assignRAInst(inst, _curBlock, ib)); - _blockRegStats.combineWith(ib._stats); - - if (controlType != BaseInst::kControlNone) { - // Support for conditional and unconditional jumps. - if (controlType == BaseInst::kControlJump || controlType == BaseInst::kControlBranch) { - _curBlock->setLast(node); - _curBlock->addFlags(RABlock::kFlagHasTerminator); - _curBlock->makeConstructed(_blockRegStats); - - if (!(inst->instOptions() & BaseInst::kOptionUnfollow)) { - // Jmp/Jcc/Call/Loop/etc... - uint32_t opCount = inst->opCount(); - const Operand* opArray = inst->operands(); - - // Cannot jump anywhere without operands. - if (ASMJIT_UNLIKELY(!opCount)) - return DebugUtils::errored(kErrorInvalidState); - - if (opArray[opCount - 1].isLabel()) { - // Labels are easy for constructing the control flow. - LabelNode* labelNode; - ASMJIT_PROPAGATE(cc()->labelNodeOf(&labelNode, opArray[opCount - 1].as