diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 008b71da4..12edad1ab 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -68,6 +68,7 @@ endif() set(NORMAL_LOADER_SRCS allocation.c allocation.h + asm_offsets.c cJSON.c cJSON.h debug_utils.c @@ -215,30 +216,12 @@ end endif() if(ASM_COMPILER_WORKS) - add_executable(asm_offset asm_offset.c) - target_link_libraries(asm_offset PRIVATE loader_specific_options) - # If am emulator is provided (Like Wine), or running on native, run asm_offset to generate gen_defines.asm - if (CMAKE_CROSSCOMPILING_EMULATOR OR NOT CMAKE_CROSSCOMPILING) - add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset ${LOADER_ASM_DIALECT}) - else() - # Forces compiler to write the intermediate asm file, needed so that we can get sizeof/offset of info out of it. - target_compile_options(asm_offset PRIVATE "/Fa$/asm_offset.asm" /FA) - # Force off optimization so that the output assembly includes all the necessary info - optimizer would get rid of it otherwise. - target_compile_options(asm_offset PRIVATE /Od) - - find_package(Python3 REQUIRED QUIET) - # Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on - add_custom_command(TARGET asm_offset POST_BUILD - COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm" - "$/asm_offset.asm" "${LOADER_ASM_DIALECT}" "${CMAKE_C_COMPILER_ID}" "${SYSTEM_PROCESSOR}" - BYPRODUCTS gen_defines.asm - ) - endif() - add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm) - set_target_properties(loader_asm_gen_files PROPERTIES FOLDER ${LOADER_HELPER_FOLDER}) - if(SYSTEM_PROCESSOR MATCHES "arm") - list(APPEND OPT_LOADER_SRCS unknown_ext_chain_marmasm.asm) + if(SYSTEM_PROCESSOR MATCHES "aarch64|arm64") + list(APPEND OPT_LOADER_SRCS unknown_ext_chain_marmasm64.asm) + else() + list(APPEND OPT_LOADER_SRCS unknown_ext_chain_marmasm32.asm) + endif() else() list(APPEND OPT_LOADER_SRCS unknown_ext_chain_masm.asm) endif() @@ -296,67 +279,14 @@ elseif(UNIX OR MINGW OR (WIN32 AND USE_GAS)) # i.e.: Linux & Apple & MinGW & Win endif() endif() - # When compiling for x86 on x64, we can't use CMAKE_SYSTEM_PROCESSOR to determine which architecture to use, - # Instead, check the size of void* and if its 4, set ASM_OFFSET_SYSTEM_PROCESSOR to x86 if we aren't on arm - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(ASM_OFFSET_SYSTEM_PROCESSOR ${SYSTEM_PROCESSOR}) # x86_64 or aarch64/arm64 - string(REPLACE amd64 x86_64 ASM_OFFSET_SYSTEM_PROCESSOR "${ASM_OFFSET_SYSTEM_PROCESSOR}") - else() - if(${SYSTEM_PROCESSOR} MATCHES "86") - set(ASM_OFFSET_SYSTEM_PROCESSOR "x86") - else() - set(ASM_OFFSET_SYSTEM_PROCESSOR ${SYSTEM_PROCESSOR}) - endif() - endif() - if(ASSEMBLER_WORKS) - add_executable(asm_offset asm_offset.c) - target_link_libraries(asm_offset loader_specific_options) - # If not cross compiling, run asm_offset to generate gen_defines.asm - if (NOT CMAKE_CROSSCOMPILING) - add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset GAS) - else() - # Forces compiler to write the intermediate asm file, needed so that we can get sizeof/offset of info out of it. - # If with lto, compiler will output IR instead of asm, so we need to explicitly disable lto here. - if(CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_compile_options(asm_offset PRIVATE -save-temps=obj -fno-lto) - elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang") - target_compile_options(asm_offset PRIVATE -save-temps=obj -fno-lto -fno-whole-program-vtables -fno-virtual-function-elimination) - else() - target_compile_options(asm_offset PRIVATE -save-temps=obj) - endif() - if(CMAKE_C_COMPILER_ID STREQUAL "GNU") - set(ASM_OFFSET_EXECUTABLE_LOCATION "$/gen_defines.asm") - set(ASM_OFFSET_INTERMEDIATE_LOCATION "$/CMakeFiles/asm_offset.dir/asm_offset.c.s") - elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang") - set(ASM_OFFSET_EXECUTABLE_LOCATION "$/gen_defines.asm") - set(ASM_OFFSET_INTERMEDIATE_LOCATION "$/CMakeFiles/asm_offset.dir/asm_offset.s") - elseif(CMAKE_C_COMPILER_ID STREQUAL "AppleClang") - # Need to use the current binary dir since the asm_offset.s file is in that folder rather than the bundle - set(ASM_OFFSET_EXECUTABLE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm") - set(ASM_OFFSET_INTERMEDIATE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/asm_offset.dir/asm_offset.s") - else() - message(FATAL_ERROR "C_COMPILER_ID not supported!") - endif() - message(STATUS "CMAKE_CROSSCOMPILING FALSE") - - find_package(Python3 REQUIRED QUIET) - # Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on - add_custom_command(TARGET asm_offset POST_BUILD - COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${ASM_OFFSET_EXECUTABLE_LOCATION}" - "${ASM_OFFSET_INTERMEDIATE_LOCATION}" "GAS" "${CMAKE_C_COMPILER_ID}" "${ASM_OFFSET_SYSTEM_PROCESSOR}" - BYPRODUCTS gen_defines.asm - ) - endif() - add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm) - if (APPLE) set(MODIFY_UNKNOWN_FUNCTION_DECLS ON) endif() set(UNKNOWN_FUNCTIONS_SUPPORTED ON) else() if(USE_GAS) - message(WARNING "Could not find working ${ASM_OFFSET_SYSTEM_PROCESSOR} GAS assembler\n${ASM_FAILURE_MSG}") + message(WARNING "Could not find working ${SYSTEM_PROCESSOR} GAS assembler\n${ASM_FAILURE_MSG}") else() message(WARNING "Assembly sources have been disabled\n${ASM_FAILURE_MSG}") endif() @@ -455,10 +385,6 @@ else() add_library(vulkan-framework SHARED) target_sources(vulkan-framework PRIVATE ${NORMAL_LOADER_SRCS} ${FRAMEWORK_HEADERS}) - if (UNKNOWN_FUNCTIONS_SUPPORTED) - add_dependencies(vulkan-framework loader_asm_gen_files) - endif() - target_link_libraries(vulkan-framework ${CMAKE_DL_LIBS} Threads::Threads -lm "-framework CoreFoundation") target_link_libraries(vulkan-framework loader_specific_options) @@ -514,7 +440,6 @@ add_library(Vulkan::Loader ALIAS vulkan) if (UNKNOWN_FUNCTIONS_SUPPORTED) target_compile_definitions(vulkan PRIVATE UNKNOWN_FUNCTIONS_SUPPORTED) - add_dependencies(vulkan loader_asm_gen_files) endif() if (BUILD_TESTS) diff --git a/loader/asm_offset.c b/loader/asm_offset.c deleted file mode 100644 index 4d01f8bfc..000000000 --- a/loader/asm_offset.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2017-2024 The Khronos Group Inc. - * Copyright (c) 2017-2024 Valve Corporation - * Copyright (c) 2017-2024 LunarG, Inc. - * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Lenny Komow - * Author: Charles Giessen - */ - -// This code generates an assembly file which provides offsets to get struct members from assembly code. - -// __USE_MINGW_ANSI_STDIO is needed to use the %zu format specifier with mingw-w64. -// Otherwise the compiler will complain about an unknown format specifier. -#if defined(__MINGW32__) && !defined(__USE_MINGW_ANSI_STDIO) -#define __USE_MINGW_ANSI_STDIO 1 -#endif - -#include -#include "loader_common.h" -#include "log.h" - -#if defined(__GNUC__) || defined(__clang__) -void produce_asm_define() { - // GCC and clang make it easy to print easy to regex for values - __asm__("# VULKAN_LOADER_ERROR_BIT = %c0" : : "i"(VULKAN_LOADER_ERROR_BIT)); - __asm__("# PTR_SIZE = %c0" : : "i"(sizeof(void *))); - __asm__("# CHAR_PTR_SIZE = %c0" : : "i"(sizeof(char *))); - __asm__("# FUNCTION_OFFSET_INSTANCE = %c0" : : "i"(offsetof(struct loader_instance, phys_dev_ext_disp_functions))); - __asm__("# PHYS_DEV_OFFSET_INST_DISPATCH = %c0" : : "i"(offsetof(struct loader_instance_dispatch_table, phys_dev_ext))); - __asm__("# PHYS_DEV_OFFSET_PHYS_DEV_TRAMP = %c0" : : "i"(offsetof(struct loader_physical_device_tramp, phys_dev))); - __asm__("# ICD_TERM_OFFSET_PHYS_DEV_TERM = %c0" : : "i"(offsetof(struct loader_physical_device_term, this_icd_term))); - __asm__("# PHYS_DEV_OFFSET_PHYS_DEV_TERM = %c0" : : "i"(offsetof(struct loader_physical_device_term, phys_dev))); - __asm__("# INSTANCE_OFFSET_ICD_TERM = %c0" : : "i"(offsetof(struct loader_icd_term, this_instance))); - __asm__("# DISPATCH_OFFSET_ICD_TERM = %c0" : : "i"(offsetof(struct loader_icd_term, phys_dev_ext))); - __asm__("# EXT_OFFSET_DEVICE_DISPATCH = %c0" : : "i"(offsetof(struct loader_dev_dispatch_table, ext_dispatch))); -} -#elif defined(_WIN32) -// MSVC will print the name of the value and the value in hex -// Must disable optimization for this translation unit, otherwise the compiler strips out the variables -static const uint32_t PTR_SIZE = sizeof(void *); -static const uint32_t CHAR_PTR_SIZE = sizeof(char *); -static const uint32_t FUNCTION_OFFSET_INSTANCE = offsetof(struct loader_instance, phys_dev_ext_disp_functions); -static const uint32_t PHYS_DEV_OFFSET_INST_DISPATCH = offsetof(struct loader_instance_dispatch_table, phys_dev_ext); -static const uint32_t PHYS_DEV_OFFSET_PHYS_DEV_TRAMP = offsetof(struct loader_physical_device_tramp, phys_dev); -static const uint32_t ICD_TERM_OFFSET_PHYS_DEV_TERM = offsetof(struct loader_physical_device_term, this_icd_term); -static const uint32_t PHYS_DEV_OFFSET_PHYS_DEV_TERM = offsetof(struct loader_physical_device_term, phys_dev); -static const uint32_t INSTANCE_OFFSET_ICD_TERM = offsetof(struct loader_icd_term, this_instance); -static const uint32_t DISPATCH_OFFSET_ICD_TERM = offsetof(struct loader_icd_term, phys_dev_ext); -static const uint32_t EXT_OFFSET_DEVICE_DISPATCH = offsetof(struct loader_dev_dispatch_table, ext_dispatch); -#else -#warning asm_offset.c variable declarations need to be defined for this platform -#endif - -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -#define SIZE_T_FMT "%-8zu" -#elif defined(__GNUC__) || defined(__clang__) -#define SIZE_T_FMT "%-8lu" -#else -#warning asm_offset.c SIZE_T_FMT must be defined for this platform -#endif - -struct ValueInfo { - const char *name; - size_t value; - const char *comment; -}; - -enum Assembler { - UNKNOWN = 0, - MASM = 1, - MARMASM = 2, - GAS = 3, -}; - -// This file can both be executed to produce gen_defines.asm and contains all the relevant data which -// the parse_asm_values.py script needs to write gen_defines.asm, necessary for cross compilation -int main(int argc, char **argv) { - enum Assembler assembler = UNKNOWN; - for (int i = 0; i < argc; ++i) { - if (!strcmp(argv[i], "MASM")) { - assembler = MASM; - } else if (!strcmp(argv[i], "MARMASM")) { - assembler = MARMASM; - } else if (!strcmp(argv[i], "GAS")) { - assembler = GAS; - } - } - if (assembler == UNKNOWN) { - return -1; - } - - struct ValueInfo values[] = { - // clang-format off - { .name = "VULKAN_LOADER_ERROR_BIT", .value = (size_t) VULKAN_LOADER_ERROR_BIT, - .comment = "The numerical value of the enum value 'VULKAN_LOADER_ERROR_BIT'" }, - { .name = "PTR_SIZE", .value = sizeof(void*), - .comment = "The size of a pointer" }, - { .name = "CHAR_PTR_SIZE", .value = sizeof(char *), - .comment = "The size of a 'const char *' struct" }, - { .name = "FUNCTION_OFFSET_INSTANCE", .value = offsetof(struct loader_instance, phys_dev_ext_disp_functions), - .comment = "The offset of 'phys_dev_ext_disp_functions' within a 'loader_instance' struct" }, - { .name = "PHYS_DEV_OFFSET_INST_DISPATCH", .value = offsetof(struct loader_instance_dispatch_table, phys_dev_ext), - .comment = "The offset of 'phys_dev_ext' within in 'loader_instance_dispatch_table' struct" }, - { .name = "PHYS_DEV_OFFSET_PHYS_DEV_TRAMP", .value = offsetof(struct loader_physical_device_tramp, phys_dev), - .comment = "The offset of 'phys_dev' within a 'loader_physical_device_tramp' struct" }, - { .name = "ICD_TERM_OFFSET_PHYS_DEV_TERM", .value = offsetof(struct loader_physical_device_term, this_icd_term), - .comment = "The offset of 'this_icd_term' within a 'loader_physical_device_term' struct" }, - { .name = "PHYS_DEV_OFFSET_PHYS_DEV_TERM", .value = offsetof(struct loader_physical_device_term, phys_dev), - .comment = "The offset of 'phys_dev' within a 'loader_physical_device_term' struct" }, - { .name = "INSTANCE_OFFSET_ICD_TERM", .value = offsetof(struct loader_icd_term, this_instance), - .comment = "The offset of 'this_instance' within a 'loader_icd_term' struct" }, - { .name = "DISPATCH_OFFSET_ICD_TERM", .value = offsetof(struct loader_icd_term, phys_dev_ext), - .comment = "The offset of 'phys_dev_ext' within a 'loader_icd_term' struct" }, - { .name = "EXT_OFFSET_DEVICE_DISPATCH", .value = offsetof(struct loader_dev_dispatch_table, ext_dispatch), - .comment = "The offset of 'ext_dispatch' within a 'loader_dev_dispatch_table' struct" }, - // clang-format on - }; - - FILE *file = loader_fopen("gen_defines.asm", "w"); - fprintf(file, "\n"); - if (assembler == MASM) { - for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) { - fprintf(file, "%-32s equ " SIZE_T_FMT "; %s\n", values[i].name, values[i].value, values[i].comment); - } - } else if (assembler == MARMASM) { - fprintf(file, " AREA loader_structs_details, DATA,READONLY\n"); -#if defined(__aarch64__) || defined(_M_ARM64) - fprintf(file, "AARCH_64 EQU 1\n"); -#else - fprintf(file, "AARCH_64 EQU 0\n"); -#endif - for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) { - fprintf(file, "%-32s EQU " SIZE_T_FMT "; %s\n", values[i].name, values[i].value, values[i].comment); - } - fprintf(file, " END\n"); - } else if (assembler == GAS) { -#if defined(__x86_64__) || defined(__i386__) - const char *comment_delimiter = "#"; -#if defined(__x86_64__) - fprintf(file, ".set X86_64, 1\n"); -#endif // defined(__x86_64__) -#elif defined(__aarch64__) || defined(__arm__) - const char *comment_delimiter = "//"; -#if defined(__aarch64__) - fprintf(file, ".set AARCH_64, 1\n"); -#else - fprintf(file, ".set AARCH_64, 0\n"); -#endif -#else - // Default comment delimiter - const char *comment_delimiter = "#"; -#endif - for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i) { - fprintf(file, ".set %-32s, " SIZE_T_FMT "%s %s\n", values[i].name, values[i].value, comment_delimiter, - values[i].comment); - } - } - return fclose(file); -} diff --git a/loader/asm_offsets.c b/loader/asm_offsets.c new file mode 100644 index 000000000..bee9edfd5 --- /dev/null +++ b/loader/asm_offsets.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017-2024 The Khronos Group Inc. + * Copyright (c) 2017-2024 Valve Corporation + * Copyright (c) 2017-2024 LunarG, Inc. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author: Charles Giessen + */ + +#include +#include "loader_common.h" +#include "log.h" + +#if VK_USE_64_BIT_PTR_DEFINES == 1 +#define INT_TYPE uint64_t +#else +#define INT_TYPE uint32_t +#endif + +// Apple's ABI is to prefix the symbol with an underscore. Because we are using the symbols in assembly, we don't want to have to +// worry about it. The fix is to use `foo __asm__("foo")` in order to change the symbol name as it appears to the linker. +#if defined(__APPLE__) +#define DEF(x) x __asm__(#x) +#else +#define DEF(x) x +#endif + +const INT_TYPE DEF(VULKAN_LOADER_ERROR_BIT_VALUE) = VULKAN_LOADER_ERROR_BIT; +const INT_TYPE DEF(FUNCTION_OFFSET_INSTANCE) = offsetof(struct loader_instance, phys_dev_ext_disp_functions); +const INT_TYPE DEF(PHYS_DEV_OFFSET_INST_DISPATCH) = offsetof(struct loader_instance_dispatch_table, phys_dev_ext); +const INT_TYPE DEF(PHYS_DEV_OFFSET_PHYS_DEV_TRAMP) = offsetof(struct loader_physical_device_tramp, phys_dev); +const INT_TYPE DEF(ICD_TERM_OFFSET_PHYS_DEV_TERM) = offsetof(struct loader_physical_device_term, this_icd_term); +const INT_TYPE DEF(PHYS_DEV_OFFSET_PHYS_DEV_TERM) = offsetof(struct loader_physical_device_term, phys_dev); +const INT_TYPE DEF(INSTANCE_OFFSET_ICD_TERM) = offsetof(struct loader_icd_term, this_instance); +const INT_TYPE DEF(DISPATCH_OFFSET_ICD_TERM) = offsetof(struct loader_icd_term, phys_dev_ext); +const INT_TYPE DEF(EXT_OFFSET_DEVICE_DISPATCH) = offsetof(struct loader_dev_dispatch_table, ext_dispatch); diff --git a/loader/unknown_ext_chain_gas_aarch.S b/loader/unknown_ext_chain_gas_aarch.S index a78a32d34..e736f7931 100644 --- a/loader/unknown_ext_chain_gas_aarch.S +++ b/loader/unknown_ext_chain_gas_aarch.S @@ -24,7 +24,15 @@ // VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then // jump to the next function in the call chain -#include "gen_defines.asm" +.extern VULKAN_LOADER_ERROR_BIT_VALUE +.extern FUNCTION_OFFSET_INSTANCE +.extern PHYS_DEV_OFFSET_INST_DISPATCH +.extern PHYS_DEV_OFFSET_PHYS_DEV_TRAMP +.extern ICD_TERM_OFFSET_PHYS_DEV_TERM +.extern PHYS_DEV_OFFSET_PHYS_DEV_TERM +.extern INSTANCE_OFFSET_ICD_TERM +.extern DISPATCH_OFFSET_ICD_TERM +.extern EXT_OFFSET_DEVICE_DISPATCH /* * References: @@ -51,7 +59,26 @@ #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 #endif -.if AARCH_64 +#ifdef __aarch64__ + +.set PTR_SIZE, 8 +.set CHAR_PTR_SIZE, 8 + +// Loads the specified symol into the register. +// Necessary to account for differences in linux and apple platforms +.macro LOAD_SYMBOL register symbol num +#if defined(__APPLE__) +L1\register\symbol\num: + adrp \register, :got:\symbol@PAGE +L2\register\symbol\num: + ldr \register, [\register, :got:\symbol@PAGEOFF] + // Optimization if the offset to the symbol is small enough (and turn it into an adr+nop) + .loh AdrpLdr L1\register\symbol\num, L2\register\symbol\num +#else + ldr \register, \symbol +#endif + +.endm .macro PhysDevExtTramp num .global vkPhysDevExtTramp\num @@ -68,11 +95,13 @@ */ vkPhysDevExtTramp\num: BTI_C - ldr x9, [x0] // Load the loader_instance_dispatch_table* into x9 - ldr x0, [x0, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] // Load the unwrapped VkPhysicalDevice into x0 - mov x10, (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num)) // Put the offset of the entry in the dispatch table for the function - ldr x16, [x9, x10] // Load the address to branch to out of the dispatch table - br x16 // Branch to the next member of the dispatch chain + ldr x9, [x0] // Load the loader_instance_dispatch_table* into x9 + LOAD_SYMBOL x10, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP, \num // Load the offset of the physical device into x10 + ldr x0, [x0, x10] // Load the unwrapped VkPhysicalDevice into x0 using the offset in x10 + LOAD_SYMBOL x11, PHYS_DEV_OFFSET_INST_DISPATCH, \num // Load the offset of the instance dispatch table into x11 + add x11, x11, (PTR_SIZE * \num) // Add the offset of the entry in the dispatch table for the function + ldr x16, [x9, x11] // Load the address to branch to out of the dispatch table + br x16 // Branch to the next member of the dispatch chain .endm .macro PhysDevExtTermin num @@ -84,23 +113,27 @@ vkPhysDevExtTramp\num: .balign 4 vkPhysDevExtTermin\num: BTI_C - ldr x9, [x0, ICD_TERM_OFFSET_PHYS_DEV_TERM] // Load the loader_icd_term* in x9 - mov x11, (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num)) // Put the offset into the dispatch table in x11 - ldr x16, [x9, x11] // Load the address of the next function in the dispatch chain - cbz x16, terminError\num // Go to the error section if the next function in the chain is NULL - ldr x0, [x0, PHYS_DEV_OFFSET_PHYS_DEV_TERM] // Unwrap the VkPhysicalDevice in x0 + LOAD_SYMBOL x9, ICD_TERM_OFFSET_PHYS_DEV_TERM, \num // Load the offset of the loader_icd_term into x9 + ldr x9, [x0, x9] // Load the loader_icd_term* in x9 from the VkPhysicalDevice in x0 + LOAD_SYMBOL x11, DISPATCH_OFFSET_ICD_TERM, \num // Load the offset of the dispatch table in the loader_icd_term into x11 + add x11, x11, (PTR_SIZE * \num) // Add the function offset into the dispatch table in x11 + ldr x16, [x9, x11] // Load the address of the next function in the dispatch chain + cbz x16, terminError\num // Go to the error section if the next function in the chain is NULL + LOAD_SYMBOL x11, PHYS_DEV_OFFSET_PHYS_DEV_TERM, \num // Load the offset of the wrapped physical device in loader_icd_term + ldr x0, [x0, x11] // Unwrap the VkPhysicalDevice in x0 br x16 // Jump to the next function in the chain terminError\num: BTI_J - mov x10, (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num)) // Offset of the function name string in the instance - ldr x11, [x9, INSTANCE_OFFSET_ICD_TERM] // Load the instance pointer - mov x0, x11 // Vulkan instance pointer (first arg) - mov x1, VULKAN_LOADER_ERROR_BIT // The error logging bit (second arg) - mov x2, #0 // Zero (third arg) - ldr x3, [x11, x10] // The function name (fourth arg) - bl loader_log_asm_function_not_supported // Log the error message before we crash + LOAD_SYMBOL x10, FUNCTION_OFFSET_INSTANCE, \num // Load the offset of the function name string in the sintance + add x10, x10, (CHAR_PTR_SIZE * \num) // Add the offset of the entry into x10 + LOAD_SYMBOL x12, INSTANCE_OFFSET_ICD_TERM, \num // Load the offset of the instance in the loader_icd_term + ldr x0, [x9, x12] // Load the Vulkan instance pointer into x0 (first arg) + LOAD_SYMBOL x1, VULKAN_LOADER_ERROR_BIT_VALUE, \num // The error logging bit (second arg) + mov x2, #0 // Zero (third arg) + ldr x3, [x0, x10] // The function name (fourth arg) is instance pointer + function name string offset + bl loader_log_asm_function_not_supported // Log the error message before we crash mov x0, #0 - br x0 // Crash intentionally by jumping to address zero + br x0 // Crash intentionally by jumping to address zero .endm .macro DevExtTramp num @@ -111,13 +144,17 @@ terminError\num: .balign 4 vkdev_ext\num: BTI_C - ldr x9, [x0] // Load the loader_instance_dispatch_table* into x9 - mov x10, (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num)) // Offset of the desired function in the dispatch table - ldr x16, [x9, x10] // Load the function address + ldr x9, [x0] // Load the loader_instance_dispatch_table* into x9 + LOAD_SYMBOL x10, EXT_OFFSET_DEVICE_DISPATCH, \num // Load the offset of the device dispatch table into x10 + add x10, x10, (PTR_SIZE * \num) // Offset of the desired function in the dispatch table + ldr x16, [x9, x10] // Load the function address br x16 .endm -.else // AARCH_32 +#else // AARCH_32 + +.set PTR_SIZE, 4 +.set CHAR_PTR_SIZE, 4 .macro PhysDevExtTramp num .global vkPhysDevExtTramp\num @@ -125,14 +162,19 @@ vkdev_ext\num: .hidden vkPhysDevExtTramp\num #endif .balign 4 - -vkPhysDevExtTrampDispatchEntry\num: .word PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num) +.ltorg +vkPhysDevExtTrampDispatchEntry\num: .word PTR_SIZE * \num vkPhysDevExtTramp\num: - ldr r4, [r0] // Load the loader_instance_dispatch_table* into r4 - ldr r0, [r0, #PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] // Load the unwrapped VkPhysicalDevice into r0 - ldr r5, vkPhysDevExtTrampDispatchEntry\num // Put the offset of the entry in the dispatch table for the function - ldr r6, [r4, r5] // Load the address to branch to out of the dispatch table - bx r6 // Branch to the next member of the dispatch chain + ldr r4, [r0] // Load the loader_instance_dispatch_table* into r4 + ldr r5, =PHYS_DEV_OFFSET_PHYS_DEV_TRAMP // Load the address of PHYS_DEV_OFFSET_PHYS_DEV_TRAMP into r5 + ldr r5, [r5] // Deref to put the offset of the unwrapped VkPhysicalDevice into r5 + ldr r0, [r0, r5] // Load the unwrapped VkPhysicalDevice into r0 + ldr r5, =PHYS_DEV_OFFSET_INST_DISPATCH // Load the address of PHYS_DEV_OFFSET_INST_DISPATCH into r5 + ldr r5, [r5] // Deref to put the offset of the Instance dispatch table into r5 + ldr r6, vkPhysDevExtTrampDispatchEntry\num // Load the offset of the entry in the dispatch table into r6 + add r5, r5, r6 // Add the offset of the entry in the dispatch table for the function + ldr r6, [r4, r5] // Load the address to branch to out of the dispatch table + bx r6 // Branch to the next member of the dispatch chain .endm @@ -142,26 +184,39 @@ vkPhysDevExtTramp\num: .hidden vkPhysDevExtTermin\num #endif .balign 4 -vkPhysDevExtTerminDispatchEntry\num: .word DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num) -vkPhysDevExtTerminFunctionNameEntry\num: .word FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num) +.ltorg +vkPhysDevExtTerminDispatchEntry\num: .word PTR_SIZE * \num +vkPhysDevExtTerminFunctionNameEntry\num: .word CHAR_PTR_SIZE * \num vkPhysDevExtTermin\num: - ldr r4, [r0, #ICD_TERM_OFFSET_PHYS_DEV_TERM] // Load the loader_icd_term* in r4 - ldr r6, vkPhysDevExtTerminDispatchEntry\num // Put the offset into the dispatch table in r6 - ldr r5, [r4, r6] // Load the address of the next function in the dispatch chain - cmp r5, #0 - beq terminError\num // Go to the error section if the next function in the chain is NULL - ldr r0, [r0, #PHYS_DEV_OFFSET_PHYS_DEV_TERM] // Unwrap the VkPhysicalDevice in r0 + ldr r4, =ICD_TERM_OFFSET_PHYS_DEV_TERM // Load the address of ICD_TERM_OFFSET_PHYS_DEV_TERM into r4 + ldr r4, [r4] // Deref to put the offset of the loader_icd_term* + ldr r4, [r0, r4] // Deref the VkPhysicalDevice in r0 with the offset to get the loader_icd_term* in r4 + ldr r6, =DISPATCH_OFFSET_ICD_TERM // Load the address of DISPATCH_OFFSET_ICD_TERM + ldr r6, [r6] // Deref to get the offset of the dispatch table + ldr r5, vkPhysDevExtTerminDispatchEntry\num // Load the offset of this entry in r5 + add r5, r5, r6 // Add DISPATCH_OFFSET_ICD_TERM + vkPhysDevExtTerminDispatchEntry to get the offset of the next function in the dispatch chain + ldr r5, [r4, r5] // Deref to get the address of the next function in the dispatch chain + cmp r5, #0 // Check if the next function is NULL + beq terminError\num // Go to the error section if the next function in the chain is NULL + ldr r6, =PHYS_DEV_OFFSET_PHYS_DEV_TERM // Load the address of PHYS_DEV_OFFSET_PHYS_DEV_TERM inro r6 + ldr r6, [r6] // Deref to put the offset of the unwrapped VkPhysicalDevice into r6 + ldr r0, [r0, r6] // Load the unwrapped VkPhysicalDevice using the offset into r0 bx r5 // Jump to the next function in the chain terminError\num: - ldr r5, vkPhysDevExtTerminFunctionNameEntry\num // Offset of the function name string in the instance - ldr r6, [r4, #INSTANCE_OFFSET_ICD_TERM] // Load the instance pointer - mov r0, r6 // Vulkan instance pointer (first arg) - mov r1, #VULKAN_LOADER_ERROR_BIT // The error logging bit (second arg) - mov r2, #0 // Zero (third arg) - ldr r3, [r6, r5] // The function name (fourth arg) - bl loader_log_asm_function_not_supported // Log the error message before we crash + ldr r5, =FUNCTION_OFFSET_INSTANCE // Load the address of FUNCTION_OFFSET_INSTANCE in r5 + ldr r5, [r5] // Deref to put the base of the function name string list in r5 + ldr r6, vkPhysDevExtTerminFunctionNameEntry\num // Load the offset of the function name string in the instance for this entry + add r5, r5, r6 // Add the base and offset + ldr r6, =INSTANCE_OFFSET_ICD_TERM // Load the address of INSTANCE_OFFSET_ICD_TERM + ldr r6, [r6] // Deref to put the offset of the VkInstance for the loader_icd_term in r6 + ldr r0, [r4, r6] // Load the Vulkan instance pointer (first arg) + ldr r1, =VULKAN_LOADER_ERROR_BIT_VALUE // Load the address of the error bit value + ldr r1, [r1] // Deref to put the error logging bit (second arg) + mov r2, #0 // Zero (third arg) + ldr r3, [r0, r5] // The function name (fourth arg) + bl loader_log_asm_function_not_supported // Log the error message before we crash mov r0, #0 - bx r0 // Crash intentionally by jumping to address zero + bx r0 // Crash intentionally by jumping to address zero .endm .macro DevExtTramp num @@ -170,15 +225,19 @@ terminError\num: .hidden vkdev_ext\num #endif .balign 4 -vkdev_ext_dispatch_entry\num: .word EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num) +.ltorg +vkdev_ext_dispatch_entry\num: .word PTR_SIZE * \num vkdev_ext\num: - ldr r4, [r0] // Load the loader_instance_dispatch_table* into r4 - ldr r5, vkdev_ext_dispatch_entry\num // Offset of the desired function in the dispatch table - ldr r6, [r4, r5] // Load the function address + ldr r4, [r0] // Load the loader_instance_dispatch_table* into r4 + ldr r5, =EXT_OFFSET_DEVICE_DISPATCH // Load the address of EXT_OFFSET_DEVICE_DISPATCH + ldr r5, [r5] // Deref to get the offset into the device dispatch table + ldr r6, vkdev_ext_dispatch_entry\num // Load the offset for current function in the table + add r5, r5, r6 // Add the EXT_OFFSET_DEVICE_DISPATCH and current entry offset + ldr r6, [r4, r5] // Load the function address at loader_instance_dispatch_table + offset bx r6 .endm -.endif +#endif #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/loader/unknown_ext_chain_gas_x86.S b/loader/unknown_ext_chain_gas_x86.S index 2a9bb81b3..778e8fb43 100644 --- a/loader/unknown_ext_chain_gas_x86.S +++ b/loader/unknown_ext_chain_gas_x86.S @@ -33,9 +33,11 @@ #endif .intel_syntax noprefix -#include "gen_defines.asm" -.ifdef X86_64 +#ifdef __x86_64__ + +.set PTR_SIZE , 8 # The size of a pointer +.set CHAR_PTR_SIZE , 8 # The size of a 'const char *' struct .macro PhysDevExtTramp num .global vkPhysDevExtTramp\num @@ -44,9 +46,11 @@ #endif vkPhysDevExtTramp\num: _CET_ENDBR - mov rax, [rdi] - mov rdi, [rdi + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] - jmp [rax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num))] + mov rax, [rdi] # rdi contains the wrapped VkPhysicalDevice, deref and put loader_physical_device_tramp* into rax + add rdi, [rip + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] # + mov rdi, [rdi] # deref to get unwrapped VkPhysicalDevice + add rax, [rip + PHYS_DEV_OFFSET_INST_DISPATCH] + jmp [rax + (PTR_SIZE * \num)] .endm .macro PhysDevExtTermin num @@ -56,18 +60,27 @@ vkPhysDevExtTramp\num: #endif vkPhysDevExtTermin\num: _CET_ENDBR - mov rax, [rdi + ICD_TERM_OFFSET_PHYS_DEV_TERM] # Store the loader_icd_term* in rax - cmp qword ptr [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))], 0 # Check if the next function in the chain is NULL + add rdi, [rip + ICD_TERM_OFFSET_PHYS_DEV_TERM] + mov rax, [rdi] # Store the loader_icd_term* in rax + add rax, [rip + DISPATCH_OFFSET_ICD_TERM] + cmp qword ptr [rax + (PTR_SIZE * \num)], 0 # Check if the next function in the chain is NULL je terminError\num # Go to the error section if it is NULL - mov rdi, [rdi + PHYS_DEV_OFFSET_PHYS_DEV_TERM] # Load the unwrapped VkPhysicalDevice into the first arg - jmp [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))] # Jump to the next function in the chain + sub rdi, [rip + ICD_TERM_OFFSET_PHYS_DEV_TERM] + add rdi, [rip + PHYS_DEV_OFFSET_PHYS_DEV_TERM] + mov rdi, [rdi] # Load the unwrapped VkPhysicalDevice into the first arg + jmp [rax + (PTR_SIZE * \num)] # Jump to the next function in the chain terminError\num: sub rsp, 56 # Create the stack frame - mov rdi, [rax + INSTANCE_OFFSET_ICD_TERM] # Load the loader_instance into rdi (first arg) - lea rsi, [VULKAN_LOADER_ERROR_BIT] # Write the error logging bit to rsi (second arg) + sub rax, [rip + DISPATCH_OFFSET_ICD_TERM] + add rax, [rip + INSTANCE_OFFSET_ICD_TERM] + mov rdi, [rax] # Load the loader_instance into rdi (first arg) + sub rax, [rip + INSTANCE_OFFSET_ICD_TERM] + lea rsi, [rip + VULKAN_LOADER_ERROR_BIT_VALUE] # Write the error logging bit to rsi (second arg) xor rdx, rdx # Set rdx to zero (third arg) lea rcx, [rip + termin_error_string] # Load the error string into rcx (fourth arg) - mov r8, [rdi + (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num))] # Load the func name into r8 (fifth arg) + add rdi, [rip + FUNCTION_OFFSET_INSTANCE] + mov r8, [rdi + (CHAR_PTR_SIZE * \num)] # Load the func name into r8 (fifth arg) + sub rdi, [rip + FUNCTION_OFFSET_INSTANCE] call loader_log # Log the error message before we crash add rsp, 56 # Clean up the stack frame mov rax, 0 @@ -82,10 +95,14 @@ terminError\num: vkdev_ext\num: _CET_ENDBR mov rax, [rdi] # Dereference the handle to get the dispatch table - jmp [rax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num))] # Jump to the appropriate call chain + add rax, [rip + EXT_OFFSET_DEVICE_DISPATCH] + jmp [rax + (PTR_SIZE * \num)] # Jump to the appropriate call chain .endm -.else +#else + +.set PTR_SIZE , 4 # The size of a pointer +.set CHAR_PTR_SIZE , 4 # The size of a 'const char *' struct .macro PhysDevExtTramp num #if defined(_WIN32) @@ -100,10 +117,13 @@ vkPhysDevExtTramp\num: #endif _CET_ENDBR mov eax, [esp + 4] # Load the wrapped VkPhysicalDevice into eax - mov ecx, [eax + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] # Load the unwrapped VkPhysicalDevice into ecx + add eax, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP + mov ecx, [eax] # Load the unwrapped VkPhysicalDevice into ecx + sub eax, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP mov [esp + 4], ecx # Overwrite the wrapped VkPhysicalDevice with the unwrapped one (on the stack) mov eax, [eax] # Dereference the wrapped VkPhysicalDevice to get the dispatch table in eax - jmp [eax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num))] # Dereference the wrapped VkPhysicalDevice to get the dispatch table in eax + add eax, PHYS_DEV_OFFSET_INST_DISPATCH + jmp [eax + (PTR_SIZE * \num)] # Dereference the wrapped VkPhysicalDevice to get the dispatch table in eax .endm .macro PhysDevExtTermin num @@ -119,17 +139,25 @@ vkPhysDevExtTermin\num: #endif _CET_ENDBR mov ecx, [esp + 4] # Move the wrapped VkPhysicalDevice into ecx - mov eax, [ecx + ICD_TERM_OFFSET_PHYS_DEV_TERM] # Store the loader_icd_term* in eax - cmp dword ptr [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))], 0 # Check if the next function in the chain is NULL + add ecx, ICD_TERM_OFFSET_PHYS_DEV_TERM + mov eax, [ecx] # Store the loader_icd_term* in eax + add eax, DISPATCH_OFFSET_ICD_TERM + cmp dword ptr [eax + (PTR_SIZE * \num)], 0 # Check if the next function in the chain is NULL je terminError\num # Go to the error section if it is NULL - mov ecx, [ecx + PHYS_DEV_OFFSET_PHYS_DEV_TERM] # Unwrap the VkPhysicalDevice in ecx + sub ecx, ICD_TERM_OFFSET_PHYS_DEV_TERM + add ecx, PHYS_DEV_OFFSET_PHYS_DEV_TERM + mov ecx, [ecx] # Unwrap the VkPhysicalDevice in ecx mov [esp + 4], ecx # Copy the unwrapped VkPhysicalDevice into the first arg - jmp [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))] # Jump to the next function in the chain + jmp [eax + (PTR_SIZE * \num)] # Jump to the next function in the chain terminError\num: - mov eax, dword ptr [eax + INSTANCE_OFFSET_ICD_TERM] # Load the loader_instance into eax - push dword ptr [eax + (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * \num))] # Push the func name (fourth arg) + sub eax, DISPATCH_OFFSET_ICD_TERM + add eax, INSTANCE_OFFSET_ICD_TERM + mov eax, dword ptr [eax] # Load the loader_instance into eax + add eax, FUNCTION_OFFSET_INSTANCE + push dword ptr [eax + (CHAR_PTR_SIZE * \num)] # Push the func name (fourth arg) + sub eax, FUNCTION_OFFSET_INSTANCE push 0 # Push zero (third arg) - push VULKAN_LOADER_ERROR_BIT # Push the error logging bit (second arg) + push VULKAN_LOADER_ERROR_BIT_VALUE # Push the error logging bit (second arg) push eax # Push the loader_instance (first arg) #if defined(_WIN32) call _loader_log_asm_function_not_supported # Log the error message before we crash @@ -155,10 +183,11 @@ vkdev_ext\num: _CET_ENDBR mov eax, dword ptr [esp + 4] # Dereference the handle to get the dispatch table mov eax, dword ptr [eax] # Dereference the chain_device to get the loader_dispatch - jmp dword ptr [eax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num))] # Jump to the appropriate call chain + add eax, EXT_OFFSET_DEVICE_DISPATCH + jmp dword ptr [eax + (PTR_SIZE * \num)] # Jump to the appropriate call chain .endm -.endif +#endif #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/loader/unknown_ext_chain_marmasm32.asm b/loader/unknown_ext_chain_marmasm32.asm new file mode 100644 index 000000000..7cb795cb8 --- /dev/null +++ b/loader/unknown_ext_chain_marmasm32.asm @@ -0,0 +1,870 @@ +; +; Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +; Copyright (c) 2024 Valve Corporation +; Copyright (c) 2024 LunarG, Inc. +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; +; Author: Eric Sullivan +; Author: Charles Giessen +; + +; This code is used to pass on device (including physical device) extensions through the call chain. It must do this without +; creating a stack frame, because the actual parameters of the call are not known. Since the first parameter is known to be a +; VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then +; jump to the next function in the call chain + + + EXTERN loader_log_asm_function_not_supported + +PTR_SIZE equ 4 ; The size of a pointer +CHAR_PTR_SIZE equ 4 ; The size of a 'const char *' struct + + EXTERN VULKAN_LOADER_ERROR_BIT_VALUE + EXTERN FUNCTION_OFFSET_INSTANCE + EXTERN PHYS_DEV_OFFSET_INST_DISPATCH + EXTERN PHYS_DEV_OFFSET_PHYS_DEV_TRAMP + EXTERN ICD_TERM_OFFSET_PHYS_DEV_TERM + EXTERN PHYS_DEV_OFFSET_PHYS_DEV_TERM + EXTERN INSTANCE_OFFSET_ICD_TERM + EXTERN DISPATCH_OFFSET_ICD_TERM + EXTERN EXT_OFFSET_DEVICE_DISPATCH + + MACRO + PhysDevExtTramp $num + ALIGN + EXPORT vkPhysDevExtTramp$num [FUNC] +vkPhysDevExtTramp$num FUNCTION + ldr r4, [r0] ; Load the loader_instance_dispatch_table* into r4 + ldr r5, =PHYS_DEV_OFFSET_PHYS_DEV_TRAMP + ldr r5, [r5] + ldr r0, [r0, r5] ; Load the unwrapped VkPhysicalDevice into r0 + ldr r5, =PHYS_DEV_OFFSET_INST_DISPATCH + ldr r5, [r5] + add r5, r5, #(PTR_SIZE * $num) ; Put the offset of the entry in the dispatch table for the function + ldr r6, [r4, r5] ; Load the address to branch to out of the dispatch table + bx r6 ; Branch to the next member of the dispatch chain + ENDFUNC + LTORG + MEND + + MACRO +$label PhysDevExtTermin $num + ALIGN + EXPORT vkPhysDevExtTermin$num [FUNC] +vkPhysDevExtTermin$num FUNCTION + ldr r4, =ICD_TERM_OFFSET_PHYS_DEV_TERM + ldr r4, [r4] + ldr r4, [r0, r4] ; Load the loader_icd_term* in r4 + ldr r6, =DISPATCH_OFFSET_ICD_TERM + ldr r6, [r6] + mov r5, #(PTR_SIZE * $num) ; Put the offset into the dispatch table in r6 + add r5, r5, r6 ; Load the address of the next function in the dispatch chain + cbz r5, terminError$num ; Go to the error section if the next function in the chain is NULL + ldr r6, =PHYS_DEV_OFFSET_PHYS_DEV_TERM + ldr r6, [r6] + ldr r0, [r0, r6] ; Unwrap the VkPhysicalDevice in r0 + bx r5 ; Jump to the next function in the chain +terminError$num + ldr r5, =FUNCTION_OFFSET_INSTANCE + ldr r5, [r5] + mov r6, #(CHAR_PTR_SIZE * $num) ; Offset of the function name string in the instance + add r5, r5, r6 + ldr r6, =INSTANCE_OFFSET_ICD_TERM + ldr r0, [r4, r6] ; Load the instance pointer ; Vulkan instance pointer (first arg) + ldr r1, =VULKAN_LOADER_ERROR_BIT_VALUE + ldr r1, [r1] ; The error logging bit (second arg) + mov r2, #0 ; Zero (third arg) + ldr r3, [r0, r5] ; The function name (fourth arg) + bl loader_log_asm_function_not_supported ; Log the error message before we crash + mov r0, #0 + bx r0 ; Crash intentionally by jumping to address zero + ENDFUNC + LTORG + MEND + + MACRO + DevExtTramp $num + ALIGN + EXPORT vkdev_ext$num [FUNC] +vkdev_ext$num FUNCTION + ldr r4, [r0] ; Load the loader_instance_dispatch_table* into r4 + ldr r5, =EXT_OFFSET_DEVICE_DISPATCH + ldr r5, [r5] + mov r6, #(PTR_SIZE * $num) ; Offset of the desired function in the dispatch table + add r5, r5, r6 + ldr r6, [r4, r5] ; Load the function address + bx r6 + ENDFUNC + LTORG + MEND + AREA terminator_string_data, DATA, READONLY + +termin_error_string DCB "Function %s not supported for this physical device", 0 + + AREA UnknownFunctionImpl, CODE, READONLY + + PhysDevExtTramp 0 + PhysDevExtTramp 1 + PhysDevExtTramp 2 + PhysDevExtTramp 3 + PhysDevExtTramp 4 + PhysDevExtTramp 5 + PhysDevExtTramp 6 + PhysDevExtTramp 7 + PhysDevExtTramp 8 + PhysDevExtTramp 9 + PhysDevExtTramp 10 + PhysDevExtTramp 11 + PhysDevExtTramp 12 + PhysDevExtTramp 13 + PhysDevExtTramp 14 + PhysDevExtTramp 15 + PhysDevExtTramp 16 + PhysDevExtTramp 17 + PhysDevExtTramp 18 + PhysDevExtTramp 19 + PhysDevExtTramp 20 + PhysDevExtTramp 21 + PhysDevExtTramp 22 + PhysDevExtTramp 23 + PhysDevExtTramp 24 + PhysDevExtTramp 25 + PhysDevExtTramp 26 + PhysDevExtTramp 27 + PhysDevExtTramp 28 + PhysDevExtTramp 29 + PhysDevExtTramp 30 + PhysDevExtTramp 31 + PhysDevExtTramp 32 + PhysDevExtTramp 33 + PhysDevExtTramp 34 + PhysDevExtTramp 35 + PhysDevExtTramp 36 + PhysDevExtTramp 37 + PhysDevExtTramp 38 + PhysDevExtTramp 39 + PhysDevExtTramp 40 + PhysDevExtTramp 41 + PhysDevExtTramp 42 + PhysDevExtTramp 43 + PhysDevExtTramp 44 + PhysDevExtTramp 45 + PhysDevExtTramp 46 + PhysDevExtTramp 47 + PhysDevExtTramp 48 + PhysDevExtTramp 49 + PhysDevExtTramp 50 + PhysDevExtTramp 51 + PhysDevExtTramp 52 + PhysDevExtTramp 53 + PhysDevExtTramp 54 + PhysDevExtTramp 55 + PhysDevExtTramp 56 + PhysDevExtTramp 57 + PhysDevExtTramp 58 + PhysDevExtTramp 59 + PhysDevExtTramp 60 + PhysDevExtTramp 61 + PhysDevExtTramp 62 + PhysDevExtTramp 63 + PhysDevExtTramp 64 + PhysDevExtTramp 65 + PhysDevExtTramp 66 + PhysDevExtTramp 67 + PhysDevExtTramp 68 + PhysDevExtTramp 69 + PhysDevExtTramp 70 + PhysDevExtTramp 71 + PhysDevExtTramp 72 + PhysDevExtTramp 73 + PhysDevExtTramp 74 + PhysDevExtTramp 75 + PhysDevExtTramp 76 + PhysDevExtTramp 77 + PhysDevExtTramp 78 + PhysDevExtTramp 79 + PhysDevExtTramp 80 + PhysDevExtTramp 81 + PhysDevExtTramp 82 + PhysDevExtTramp 83 + PhysDevExtTramp 84 + PhysDevExtTramp 85 + PhysDevExtTramp 86 + PhysDevExtTramp 87 + PhysDevExtTramp 88 + PhysDevExtTramp 89 + PhysDevExtTramp 90 + PhysDevExtTramp 91 + PhysDevExtTramp 92 + PhysDevExtTramp 93 + PhysDevExtTramp 94 + PhysDevExtTramp 95 + PhysDevExtTramp 96 + PhysDevExtTramp 97 + PhysDevExtTramp 98 + PhysDevExtTramp 99 + PhysDevExtTramp 100 + PhysDevExtTramp 101 + PhysDevExtTramp 102 + PhysDevExtTramp 103 + PhysDevExtTramp 104 + PhysDevExtTramp 105 + PhysDevExtTramp 106 + PhysDevExtTramp 107 + PhysDevExtTramp 108 + PhysDevExtTramp 109 + PhysDevExtTramp 110 + PhysDevExtTramp 111 + PhysDevExtTramp 112 + PhysDevExtTramp 113 + PhysDevExtTramp 114 + PhysDevExtTramp 115 + PhysDevExtTramp 116 + PhysDevExtTramp 117 + PhysDevExtTramp 118 + PhysDevExtTramp 119 + PhysDevExtTramp 120 + PhysDevExtTramp 121 + PhysDevExtTramp 122 + PhysDevExtTramp 123 + PhysDevExtTramp 124 + PhysDevExtTramp 125 + PhysDevExtTramp 126 + PhysDevExtTramp 127 + PhysDevExtTramp 128 + PhysDevExtTramp 129 + PhysDevExtTramp 130 + PhysDevExtTramp 131 + PhysDevExtTramp 132 + PhysDevExtTramp 133 + PhysDevExtTramp 134 + PhysDevExtTramp 135 + PhysDevExtTramp 136 + PhysDevExtTramp 137 + PhysDevExtTramp 138 + PhysDevExtTramp 139 + PhysDevExtTramp 140 + PhysDevExtTramp 141 + PhysDevExtTramp 142 + PhysDevExtTramp 143 + PhysDevExtTramp 144 + PhysDevExtTramp 145 + PhysDevExtTramp 146 + PhysDevExtTramp 147 + PhysDevExtTramp 148 + PhysDevExtTramp 149 + PhysDevExtTramp 150 + PhysDevExtTramp 151 + PhysDevExtTramp 152 + PhysDevExtTramp 153 + PhysDevExtTramp 154 + PhysDevExtTramp 155 + PhysDevExtTramp 156 + PhysDevExtTramp 157 + PhysDevExtTramp 158 + PhysDevExtTramp 159 + PhysDevExtTramp 160 + PhysDevExtTramp 161 + PhysDevExtTramp 162 + PhysDevExtTramp 163 + PhysDevExtTramp 164 + PhysDevExtTramp 165 + PhysDevExtTramp 166 + PhysDevExtTramp 167 + PhysDevExtTramp 168 + PhysDevExtTramp 169 + PhysDevExtTramp 170 + PhysDevExtTramp 171 + PhysDevExtTramp 172 + PhysDevExtTramp 173 + PhysDevExtTramp 174 + PhysDevExtTramp 175 + PhysDevExtTramp 176 + PhysDevExtTramp 177 + PhysDevExtTramp 178 + PhysDevExtTramp 179 + PhysDevExtTramp 180 + PhysDevExtTramp 181 + PhysDevExtTramp 182 + PhysDevExtTramp 183 + PhysDevExtTramp 184 + PhysDevExtTramp 185 + PhysDevExtTramp 186 + PhysDevExtTramp 187 + PhysDevExtTramp 188 + PhysDevExtTramp 189 + PhysDevExtTramp 190 + PhysDevExtTramp 191 + PhysDevExtTramp 192 + PhysDevExtTramp 193 + PhysDevExtTramp 194 + PhysDevExtTramp 195 + PhysDevExtTramp 196 + PhysDevExtTramp 197 + PhysDevExtTramp 198 + PhysDevExtTramp 199 + PhysDevExtTramp 200 + PhysDevExtTramp 201 + PhysDevExtTramp 202 + PhysDevExtTramp 203 + PhysDevExtTramp 204 + PhysDevExtTramp 205 + PhysDevExtTramp 206 + PhysDevExtTramp 207 + PhysDevExtTramp 208 + PhysDevExtTramp 209 + PhysDevExtTramp 210 + PhysDevExtTramp 211 + PhysDevExtTramp 212 + PhysDevExtTramp 213 + PhysDevExtTramp 214 + PhysDevExtTramp 215 + PhysDevExtTramp 216 + PhysDevExtTramp 217 + PhysDevExtTramp 218 + PhysDevExtTramp 219 + PhysDevExtTramp 220 + PhysDevExtTramp 221 + PhysDevExtTramp 222 + PhysDevExtTramp 223 + PhysDevExtTramp 224 + PhysDevExtTramp 225 + PhysDevExtTramp 226 + PhysDevExtTramp 227 + PhysDevExtTramp 228 + PhysDevExtTramp 229 + PhysDevExtTramp 230 + PhysDevExtTramp 231 + PhysDevExtTramp 232 + PhysDevExtTramp 233 + PhysDevExtTramp 234 + PhysDevExtTramp 235 + PhysDevExtTramp 236 + PhysDevExtTramp 237 + PhysDevExtTramp 238 + PhysDevExtTramp 239 + PhysDevExtTramp 240 + PhysDevExtTramp 241 + PhysDevExtTramp 242 + PhysDevExtTramp 243 + PhysDevExtTramp 244 + PhysDevExtTramp 245 + PhysDevExtTramp 246 + PhysDevExtTramp 247 + PhysDevExtTramp 248 + PhysDevExtTramp 249 + + PhysDevExtTermin 0 + PhysDevExtTermin 1 + PhysDevExtTermin 2 + PhysDevExtTermin 3 + PhysDevExtTermin 4 + PhysDevExtTermin 5 + PhysDevExtTermin 6 + PhysDevExtTermin 7 + PhysDevExtTermin 8 + PhysDevExtTermin 9 + PhysDevExtTermin 10 + PhysDevExtTermin 11 + PhysDevExtTermin 12 + PhysDevExtTermin 13 + PhysDevExtTermin 14 + PhysDevExtTermin 15 + PhysDevExtTermin 16 + PhysDevExtTermin 17 + PhysDevExtTermin 18 + PhysDevExtTermin 19 + PhysDevExtTermin 20 + PhysDevExtTermin 21 + PhysDevExtTermin 22 + PhysDevExtTermin 23 + PhysDevExtTermin 24 + PhysDevExtTermin 25 + PhysDevExtTermin 26 + PhysDevExtTermin 27 + PhysDevExtTermin 28 + PhysDevExtTermin 29 + PhysDevExtTermin 30 + PhysDevExtTermin 31 + PhysDevExtTermin 32 + PhysDevExtTermin 33 + PhysDevExtTermin 34 + PhysDevExtTermin 35 + PhysDevExtTermin 36 + PhysDevExtTermin 37 + PhysDevExtTermin 38 + PhysDevExtTermin 39 + PhysDevExtTermin 40 + PhysDevExtTermin 41 + PhysDevExtTermin 42 + PhysDevExtTermin 43 + PhysDevExtTermin 44 + PhysDevExtTermin 45 + PhysDevExtTermin 46 + PhysDevExtTermin 47 + PhysDevExtTermin 48 + PhysDevExtTermin 49 + PhysDevExtTermin 50 + PhysDevExtTermin 51 + PhysDevExtTermin 52 + PhysDevExtTermin 53 + PhysDevExtTermin 54 + PhysDevExtTermin 55 + PhysDevExtTermin 56 + PhysDevExtTermin 57 + PhysDevExtTermin 58 + PhysDevExtTermin 59 + PhysDevExtTermin 60 + PhysDevExtTermin 61 + PhysDevExtTermin 62 + PhysDevExtTermin 63 + PhysDevExtTermin 64 + PhysDevExtTermin 65 + PhysDevExtTermin 66 + PhysDevExtTermin 67 + PhysDevExtTermin 68 + PhysDevExtTermin 69 + PhysDevExtTermin 70 + PhysDevExtTermin 71 + PhysDevExtTermin 72 + PhysDevExtTermin 73 + PhysDevExtTermin 74 + PhysDevExtTermin 75 + PhysDevExtTermin 76 + PhysDevExtTermin 77 + PhysDevExtTermin 78 + PhysDevExtTermin 79 + PhysDevExtTermin 80 + PhysDevExtTermin 81 + PhysDevExtTermin 82 + PhysDevExtTermin 83 + PhysDevExtTermin 84 + PhysDevExtTermin 85 + PhysDevExtTermin 86 + PhysDevExtTermin 87 + PhysDevExtTermin 88 + PhysDevExtTermin 89 + PhysDevExtTermin 90 + PhysDevExtTermin 91 + PhysDevExtTermin 92 + PhysDevExtTermin 93 + PhysDevExtTermin 94 + PhysDevExtTermin 95 + PhysDevExtTermin 96 + PhysDevExtTermin 97 + PhysDevExtTermin 98 + PhysDevExtTermin 99 + PhysDevExtTermin 100 + PhysDevExtTermin 101 + PhysDevExtTermin 102 + PhysDevExtTermin 103 + PhysDevExtTermin 104 + PhysDevExtTermin 105 + PhysDevExtTermin 106 + PhysDevExtTermin 107 + PhysDevExtTermin 108 + PhysDevExtTermin 109 + PhysDevExtTermin 110 + PhysDevExtTermin 111 + PhysDevExtTermin 112 + PhysDevExtTermin 113 + PhysDevExtTermin 114 + PhysDevExtTermin 115 + PhysDevExtTermin 116 + PhysDevExtTermin 117 + PhysDevExtTermin 118 + PhysDevExtTermin 119 + PhysDevExtTermin 120 + PhysDevExtTermin 121 + PhysDevExtTermin 122 + PhysDevExtTermin 123 + PhysDevExtTermin 124 + PhysDevExtTermin 125 + PhysDevExtTermin 126 + PhysDevExtTermin 127 + PhysDevExtTermin 128 + PhysDevExtTermin 129 + PhysDevExtTermin 130 + PhysDevExtTermin 131 + PhysDevExtTermin 132 + PhysDevExtTermin 133 + PhysDevExtTermin 134 + PhysDevExtTermin 135 + PhysDevExtTermin 136 + PhysDevExtTermin 137 + PhysDevExtTermin 138 + PhysDevExtTermin 139 + PhysDevExtTermin 140 + PhysDevExtTermin 141 + PhysDevExtTermin 142 + PhysDevExtTermin 143 + PhysDevExtTermin 144 + PhysDevExtTermin 145 + PhysDevExtTermin 146 + PhysDevExtTermin 147 + PhysDevExtTermin 148 + PhysDevExtTermin 149 + PhysDevExtTermin 150 + PhysDevExtTermin 151 + PhysDevExtTermin 152 + PhysDevExtTermin 153 + PhysDevExtTermin 154 + PhysDevExtTermin 155 + PhysDevExtTermin 156 + PhysDevExtTermin 157 + PhysDevExtTermin 158 + PhysDevExtTermin 159 + PhysDevExtTermin 160 + PhysDevExtTermin 161 + PhysDevExtTermin 162 + PhysDevExtTermin 163 + PhysDevExtTermin 164 + PhysDevExtTermin 165 + PhysDevExtTermin 166 + PhysDevExtTermin 167 + PhysDevExtTermin 168 + PhysDevExtTermin 169 + PhysDevExtTermin 170 + PhysDevExtTermin 171 + PhysDevExtTermin 172 + PhysDevExtTermin 173 + PhysDevExtTermin 174 + PhysDevExtTermin 175 + PhysDevExtTermin 176 + PhysDevExtTermin 177 + PhysDevExtTermin 178 + PhysDevExtTermin 179 + PhysDevExtTermin 180 + PhysDevExtTermin 181 + PhysDevExtTermin 182 + PhysDevExtTermin 183 + PhysDevExtTermin 184 + PhysDevExtTermin 185 + PhysDevExtTermin 186 + PhysDevExtTermin 187 + PhysDevExtTermin 188 + PhysDevExtTermin 189 + PhysDevExtTermin 190 + PhysDevExtTermin 191 + PhysDevExtTermin 192 + PhysDevExtTermin 193 + PhysDevExtTermin 194 + PhysDevExtTermin 195 + PhysDevExtTermin 196 + PhysDevExtTermin 197 + PhysDevExtTermin 198 + PhysDevExtTermin 199 + PhysDevExtTermin 200 + PhysDevExtTermin 201 + PhysDevExtTermin 202 + PhysDevExtTermin 203 + PhysDevExtTermin 204 + PhysDevExtTermin 205 + PhysDevExtTermin 206 + PhysDevExtTermin 207 + PhysDevExtTermin 208 + PhysDevExtTermin 209 + PhysDevExtTermin 210 + PhysDevExtTermin 211 + PhysDevExtTermin 212 + PhysDevExtTermin 213 + PhysDevExtTermin 214 + PhysDevExtTermin 215 + PhysDevExtTermin 216 + PhysDevExtTermin 217 + PhysDevExtTermin 218 + PhysDevExtTermin 219 + PhysDevExtTermin 220 + PhysDevExtTermin 221 + PhysDevExtTermin 222 + PhysDevExtTermin 223 + PhysDevExtTermin 224 + PhysDevExtTermin 225 + PhysDevExtTermin 226 + PhysDevExtTermin 227 + PhysDevExtTermin 228 + PhysDevExtTermin 229 + PhysDevExtTermin 230 + PhysDevExtTermin 231 + PhysDevExtTermin 232 + PhysDevExtTermin 233 + PhysDevExtTermin 234 + PhysDevExtTermin 235 + PhysDevExtTermin 236 + PhysDevExtTermin 237 + PhysDevExtTermin 238 + PhysDevExtTermin 239 + PhysDevExtTermin 240 + PhysDevExtTermin 241 + PhysDevExtTermin 242 + PhysDevExtTermin 243 + PhysDevExtTermin 244 + PhysDevExtTermin 245 + PhysDevExtTermin 246 + PhysDevExtTermin 247 + PhysDevExtTermin 248 + PhysDevExtTermin 249 + + DevExtTramp 0 + DevExtTramp 1 + DevExtTramp 2 + DevExtTramp 3 + DevExtTramp 4 + DevExtTramp 5 + DevExtTramp 6 + DevExtTramp 7 + DevExtTramp 8 + DevExtTramp 9 + DevExtTramp 10 + DevExtTramp 11 + DevExtTramp 12 + DevExtTramp 13 + DevExtTramp 14 + DevExtTramp 15 + DevExtTramp 16 + DevExtTramp 17 + DevExtTramp 18 + DevExtTramp 19 + DevExtTramp 20 + DevExtTramp 21 + DevExtTramp 22 + DevExtTramp 23 + DevExtTramp 24 + DevExtTramp 25 + DevExtTramp 26 + DevExtTramp 27 + DevExtTramp 28 + DevExtTramp 29 + DevExtTramp 30 + DevExtTramp 31 + DevExtTramp 32 + DevExtTramp 33 + DevExtTramp 34 + DevExtTramp 35 + DevExtTramp 36 + DevExtTramp 37 + DevExtTramp 38 + DevExtTramp 39 + DevExtTramp 40 + DevExtTramp 41 + DevExtTramp 42 + DevExtTramp 43 + DevExtTramp 44 + DevExtTramp 45 + DevExtTramp 46 + DevExtTramp 47 + DevExtTramp 48 + DevExtTramp 49 + DevExtTramp 50 + DevExtTramp 51 + DevExtTramp 52 + DevExtTramp 53 + DevExtTramp 54 + DevExtTramp 55 + DevExtTramp 56 + DevExtTramp 57 + DevExtTramp 58 + DevExtTramp 59 + DevExtTramp 60 + DevExtTramp 61 + DevExtTramp 62 + DevExtTramp 63 + DevExtTramp 64 + DevExtTramp 65 + DevExtTramp 66 + DevExtTramp 67 + DevExtTramp 68 + DevExtTramp 69 + DevExtTramp 70 + DevExtTramp 71 + DevExtTramp 72 + DevExtTramp 73 + DevExtTramp 74 + DevExtTramp 75 + DevExtTramp 76 + DevExtTramp 77 + DevExtTramp 78 + DevExtTramp 79 + DevExtTramp 80 + DevExtTramp 81 + DevExtTramp 82 + DevExtTramp 83 + DevExtTramp 84 + DevExtTramp 85 + DevExtTramp 86 + DevExtTramp 87 + DevExtTramp 88 + DevExtTramp 89 + DevExtTramp 90 + DevExtTramp 91 + DevExtTramp 92 + DevExtTramp 93 + DevExtTramp 94 + DevExtTramp 95 + DevExtTramp 96 + DevExtTramp 97 + DevExtTramp 98 + DevExtTramp 99 + DevExtTramp 100 + DevExtTramp 101 + DevExtTramp 102 + DevExtTramp 103 + DevExtTramp 104 + DevExtTramp 105 + DevExtTramp 106 + DevExtTramp 107 + DevExtTramp 108 + DevExtTramp 109 + DevExtTramp 110 + DevExtTramp 111 + DevExtTramp 112 + DevExtTramp 113 + DevExtTramp 114 + DevExtTramp 115 + DevExtTramp 116 + DevExtTramp 117 + DevExtTramp 118 + DevExtTramp 119 + DevExtTramp 120 + DevExtTramp 121 + DevExtTramp 122 + DevExtTramp 123 + DevExtTramp 124 + DevExtTramp 125 + DevExtTramp 126 + DevExtTramp 127 + DevExtTramp 128 + DevExtTramp 129 + DevExtTramp 130 + DevExtTramp 131 + DevExtTramp 132 + DevExtTramp 133 + DevExtTramp 134 + DevExtTramp 135 + DevExtTramp 136 + DevExtTramp 137 + DevExtTramp 138 + DevExtTramp 139 + DevExtTramp 140 + DevExtTramp 141 + DevExtTramp 142 + DevExtTramp 143 + DevExtTramp 144 + DevExtTramp 145 + DevExtTramp 146 + DevExtTramp 147 + DevExtTramp 148 + DevExtTramp 149 + DevExtTramp 150 + DevExtTramp 151 + DevExtTramp 152 + DevExtTramp 153 + DevExtTramp 154 + DevExtTramp 155 + DevExtTramp 156 + DevExtTramp 157 + DevExtTramp 158 + DevExtTramp 159 + DevExtTramp 160 + DevExtTramp 161 + DevExtTramp 162 + DevExtTramp 163 + DevExtTramp 164 + DevExtTramp 165 + DevExtTramp 166 + DevExtTramp 167 + DevExtTramp 168 + DevExtTramp 169 + DevExtTramp 170 + DevExtTramp 171 + DevExtTramp 172 + DevExtTramp 173 + DevExtTramp 174 + DevExtTramp 175 + DevExtTramp 176 + DevExtTramp 177 + DevExtTramp 178 + DevExtTramp 179 + DevExtTramp 180 + DevExtTramp 181 + DevExtTramp 182 + DevExtTramp 183 + DevExtTramp 184 + DevExtTramp 185 + DevExtTramp 186 + DevExtTramp 187 + DevExtTramp 188 + DevExtTramp 189 + DevExtTramp 190 + DevExtTramp 191 + DevExtTramp 192 + DevExtTramp 193 + DevExtTramp 194 + DevExtTramp 195 + DevExtTramp 196 + DevExtTramp 197 + DevExtTramp 198 + DevExtTramp 199 + DevExtTramp 200 + DevExtTramp 201 + DevExtTramp 202 + DevExtTramp 203 + DevExtTramp 204 + DevExtTramp 205 + DevExtTramp 206 + DevExtTramp 207 + DevExtTramp 208 + DevExtTramp 209 + DevExtTramp 210 + DevExtTramp 211 + DevExtTramp 212 + DevExtTramp 213 + DevExtTramp 214 + DevExtTramp 215 + DevExtTramp 216 + DevExtTramp 217 + DevExtTramp 218 + DevExtTramp 219 + DevExtTramp 220 + DevExtTramp 221 + DevExtTramp 222 + DevExtTramp 223 + DevExtTramp 224 + DevExtTramp 225 + DevExtTramp 226 + DevExtTramp 227 + DevExtTramp 228 + DevExtTramp 229 + DevExtTramp 230 + DevExtTramp 231 + DevExtTramp 232 + DevExtTramp 233 + DevExtTramp 234 + DevExtTramp 235 + DevExtTramp 236 + DevExtTramp 237 + DevExtTramp 238 + DevExtTramp 239 + DevExtTramp 240 + DevExtTramp 241 + DevExtTramp 242 + DevExtTramp 243 + DevExtTramp 244 + DevExtTramp 245 + DevExtTramp 246 + DevExtTramp 247 + DevExtTramp 248 + DevExtTramp 249 + + END diff --git a/loader/unknown_ext_chain_marmasm.asm b/loader/unknown_ext_chain_marmasm64.asm similarity index 83% rename from loader/unknown_ext_chain_marmasm.asm rename to loader/unknown_ext_chain_marmasm64.asm index f2f352a17..ab6811862 100644 --- a/loader/unknown_ext_chain_marmasm.asm +++ b/loader/unknown_ext_chain_marmasm64.asm @@ -25,11 +25,19 @@ ; jump to the next function in the call chain - GET gen_defines.asm +PTR_SIZE EQU 8 ; The size of a pointer +CHAR_PTR_SIZE EQU 8 ; The size of a 'const char *' struct EXTERN loader_log_asm_function_not_supported - - IF AARCH_64==1 + EXTERN VULKAN_LOADER_ERROR_BIT_VALUE + EXTERN FUNCTION_OFFSET_INSTANCE + EXTERN PHYS_DEV_OFFSET_INST_DISPATCH + EXTERN PHYS_DEV_OFFSET_PHYS_DEV_TRAMP + EXTERN ICD_TERM_OFFSET_PHYS_DEV_TERM + EXTERN PHYS_DEV_OFFSET_PHYS_DEV_TERM + EXTERN INSTANCE_OFFSET_ICD_TERM + EXTERN DISPATCH_OFFSET_ICD_TERM + EXTERN EXT_OFFSET_DEVICE_DISPATCH MACRO PhysDevExtTramp $num @@ -37,8 +45,12 @@ EXPORT vkPhysDevExtTramp$num [FUNC] vkPhysDevExtTramp$num FUNCTION ldr x9, [x0] ; Load the loader_instance_dispatch_table* into x9 - ldr x0, [x0, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] ; Load the unwrapped VkPhysicalDevice into x0 - mov x10, #(PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * $num)) ; Put the offset of the entry in the dispatch table for the function + ldr x10, =PHYS_DEV_OFFSET_PHYS_DEV_TRAMP + ldr x10, [x10] + ldr x0, [x0, x10] ; Load the unwrapped VkPhysicalDevice into x0 + ldr x10, =PHYS_DEV_OFFSET_INST_DISPATCH + ldr x10, [x10] + add x10, x10, #(PTR_SIZE * $num) ; Put the offset of the entry in the dispatch table for the function ldr x11, [x9, x10] ; Load the address to branch to out of the dispatch table br x11 ; Branch to the next member of the dispatch chain ENDFUNC @@ -49,19 +61,29 @@ $label PhysDevExtTermin $num ALIGN EXPORT vkPhysDevExtTermin$num [FUNC] vkPhysDevExtTermin$num FUNCTION - ldr x9, [x0, ICD_TERM_OFFSET_PHYS_DEV_TERM] ; Load the loader_icd_term* in x9 - mov x11, (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * $num)) ; Put the offset into the dispatch table in x11 + ldr x9, =ICD_TERM_OFFSET_PHYS_DEV_TERM + ldr x9, [x9] + ldr x9, [x0, x9] ; Load the loader_icd_term* in x9 + ldr x11, =DISPATCH_OFFSET_ICD_TERM + ldr x11, [x11] + add x11, x11, (PTR_SIZE * $num) ; Put the offset into the dispatch table in x11 ldr x10, [x9, x11] ; Load the address of the next function in the dispatch chain cbz x10, terminError$num ; Go to the error section if the next function in the chain is NULL - ldr x0, [x0, PHYS_DEV_OFFSET_PHYS_DEV_TERM] ; Unwrap the VkPhysicalDevice in x0 + ldr x11, =PHYS_DEV_OFFSET_PHYS_DEV_TERM + ldr x11, [x11] + ldr x0, [x0, x11] ; Unwrap the VkPhysicalDevice in x0 br x10 ; Jump to the next function in the chain terminError$num - mov x10, (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * $num)) ; Offset of the function name string in the instance - ldr x11, [x9, INSTANCE_OFFSET_ICD_TERM] ; Load the instance pointer - mov x0, x11 ; Vulkan instance pointer (first arg) - mov x1, VULKAN_LOADER_ERROR_BIT ; The error logging bit (second arg) + ldr x10, =FUNCTION_OFFSET_INSTANCE + ldr x10, [x10] + add x10, x10, (CHAR_PTR_SIZE * $num) ; Offset of the function name string in the instance + ldr x11, =INSTANCE_OFFSET_ICD_TERM + ldr x11, [x11] + ldr x0, [x9, x11] ; Load the Vulkan instance pointer (first arg) + ldr x1, =VULKAN_LOADER_ERROR_BIT_VALUE ; The error logging bit (second arg) + ldr x1, [x1] mov x2, #0 ; Zero (third arg) - ldr x3, [x11, x10] ; The function name (fourth arg) + ldr x3, [x0, x10] ; The function name (fourth arg) bl loader_log_asm_function_not_supported ; Log the error message before we crash mov x0, #0 br x0 ; Crash intentionally by jumping to address zero @@ -74,66 +96,14 @@ terminError$num EXPORT vkdev_ext$num [FUNC] vkdev_ext$num FUNCTION ldr x9, [x0] ; Load the loader_instance_dispatch_table* into x9 - mov x10, (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * $num)) ; Offset of the desired function in the dispatch table + ldr x10, =EXT_OFFSET_DEVICE_DISPATCH + ldr x10, [x10] + add x10, x10, (PTR_SIZE * $num) ; Offset of the desired function in the dispatch table ldr x11, [x9, x10] ; Load the function address br x11 ENDFUNC MEND -; 32 bit (armhf) assembly - ELSE - - MACRO - PhysDevExtTramp $num - ALIGN - EXPORT vkPhysDevExtTramp$num [FUNC] -vkPhysDevExtTramp$num FUNCTION - ldr r4, [r0] ; Load the loader_instance_dispatch_table* into r4 - ldr r0, [r0, #PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] ; Load the unwrapped VkPhysicalDevice into r0 - mov r5, #(PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * $num)) ; Put the offset of the entry in the dispatch table for the function - ldr r6, [r4, r5] ; Load the address to branch to out of the dispatch table - bx r6 ; Branch to the next member of the dispatch chain - ENDFUNC - MEND - - MACRO -$label PhysDevExtTermin $num - ALIGN - EXPORT vkPhysDevExtTermin$num [FUNC] -vkPhysDevExtTermin$num FUNCTION - ldr r4, [r0, #ICD_TERM_OFFSET_PHYS_DEV_TERM] ; Load the loader_icd_term* in r4 - mov r6, #(DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * $num)) ; Put the offset into the dispatch table in r6 - ldr r5, [r4, r6] ; Load the address of the next function in the dispatch chain - cbz r5, terminError$num ; Go to the error section if the next function in the chain is NULL - ldr r0, [r0, #PHYS_DEV_OFFSET_PHYS_DEV_TERM] ; Unwrap the VkPhysicalDevice in r0 - bx r5 ; Jump to the next function in the chain -terminError$num - mov r5, #(FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * $num)) ; Offset of the function name string in the instance - ldr r6, [r4, #INSTANCE_OFFSET_ICD_TERM] ; Load the instance pointer - mov r0, r6 ; Vulkan instance pointer (first arg) - mov r1, #VULKAN_LOADER_ERROR_BIT ; The error logging bit (second arg) - mov r2, #0 ; Zero (third arg) - ldr r3, [r6, r5] ; The function name (fourth arg) - bl loader_log_asm_function_not_supported ; Log the error message before we crash - mov r0, #0 - bx r0 ; Crash intentionally by jumping to address zero - ENDFUNC - MEND - - MACRO - DevExtTramp $num - ALIGN - EXPORT vkdev_ext$num [FUNC] -vkdev_ext$num FUNCTION - ldr r4, [r0] ; Load the loader_instance_dispatch_table* into r4 - mov r5, #(EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * $num)) ; Offset of the desired function in the dispatch table - ldr r6, [r4, r5] ; Load the function address - bx r6 - ENDFUNC - MEND - - ENDIF - AREA terminator_string_data, DATA, READONLY termin_error_string DCB "Function %s not supported for this physical device", 0 diff --git a/loader/unknown_ext_chain_masm.asm b/loader/unknown_ext_chain_masm.asm index 46d13de47..7605470cd 100644 --- a/loader/unknown_ext_chain_masm.asm +++ b/loader/unknown_ext_chain_masm.asm @@ -24,38 +24,59 @@ ; VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then ; jump to the next function in the call chain -; Codegen defines a number of values, chiefly offsets of members within structs and sizes of data types within gen_defines.asm. +; asm_offsets.c defines number of values and offsets needed by the assembly code. They are placed in static memory so that the assembly code can access them. ; Struct member offsets are defined in the format "XX_OFFSET_YY" where XX indicates the member within the struct and YY indicates ; the struct type that it is a member of. Data type sizes are defined in the format "XX_SIZE" where XX indicates the data type. -INCLUDE gen_defines.asm ; 64-bit values and macro IFDEF rax +PTR_SIZE equ 8 ; The size of a pointer +CHAR_PTR_SIZE equ 8 ; The size of a 'const char *' struct +EXTERN VULKAN_LOADER_ERROR_BIT_VALUE:QWORD +EXTERN FUNCTION_OFFSET_INSTANCE:QWORD +EXTERN PHYS_DEV_OFFSET_INST_DISPATCH:QWORD +EXTERN PHYS_DEV_OFFSET_PHYS_DEV_TRAMP:QWORD +EXTERN ICD_TERM_OFFSET_PHYS_DEV_TERM:QWORD +EXTERN PHYS_DEV_OFFSET_PHYS_DEV_TERM:QWORD +EXTERN INSTANCE_OFFSET_ICD_TERM:QWORD +EXTERN DISPATCH_OFFSET_ICD_TERM:QWORD +EXTERN EXT_OFFSET_DEVICE_DISPATCH:QWORD + PhysDevExtTramp macro num:req public vkPhysDevExtTramp&num& vkPhysDevExtTramp&num&: mov rax, qword ptr [rcx] ; Dereference the wrapped VkPhysicalDevice to get the dispatch table in rax - mov rcx, qword ptr [rcx + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] ; Load the unwrapped VkPhysicalDevice into rcx - jmp qword ptr [rax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * num))] ; Jump to the next function in the chain, preserving the args in other registers + add rcx, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP + mov rcx, qword ptr [rcx] ; Load the unwrapped VkPhysicalDevice into rcx + add rax, PHYS_DEV_OFFSET_INST_DISPATCH + jmp qword ptr [rax + PTR_SIZE * num] ; Jump to the next function in the chain, preserving the args in other registers endm PhysDevExtTermin macro num public vkPhysDevExtTermin&num& vkPhysDevExtTermin&num&: - mov rax, qword ptr [rcx + ICD_TERM_OFFSET_PHYS_DEV_TERM] ; Store the loader_icd_term* in rax - cmp qword ptr [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * num))], 0 ; Check if the next function in the chain is NULL + add rcx, ICD_TERM_OFFSET_PHYS_DEV_TERM + mov rax, qword ptr [rcx] ; Store the loader_icd_term* in rax + sub rcx, ICD_TERM_OFFSET_PHYS_DEV_TERM + add rax, DISPATCH_OFFSET_ICD_TERM + cmp qword ptr [rax + PTR_SIZE * num], 0 ; Check if the next function in the chain is NULL je terminError&num& ; Go to the error section if it is NULL - mov rcx, qword ptr [rcx + PHYS_DEV_OFFSET_PHYS_DEV_TERM] ; Load the unwrapped VkPhysicalDevice into the first arg - jmp qword ptr [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * num))] ; Jump to the next function in the chain + add rcx, PHYS_DEV_OFFSET_PHYS_DEV_TERM + mov rcx, qword ptr [rcx] ; Load the unwrapped VkPhysicalDevice into the first arg + jmp qword ptr [rax + PTR_SIZE * num] ; Jump to the next function in the chain terminError&num&: sub rsp, 56 ; Create the stack frame - mov rcx, qword ptr [rax + INSTANCE_OFFSET_ICD_TERM] ; Load the loader_instance into rcx (first arg) - mov rax, qword ptr [rcx + (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * num))] ; Load the func name into rax + sub rax, DISPATCH_OFFSET_ICD_TERM + add rax, INSTANCE_OFFSET_ICD_TERM + mov rcx, qword ptr [rax] ; Load the loader_instance into rcx (first arg) + add rcx, FUNCTION_OFFSET_INSTANCE + mov rax, qword ptr [rcx + CHAR_PTR_SIZE * num] ; Load the func name into rax + sub rcx, FUNCTION_OFFSET_INSTANCE lea r9, termin_error_string ; Load the error string into r9 (fourth arg) xor r8d, r8d ; Set r8 to zero (third arg) mov qword ptr [rsp + 32], rax ; Move the func name onto the stack (fifth arg) - lea edx, [r8 + VULKAN_LOADER_ERROR_BIT] ; Write the error logging bit to rdx (second arg) + lea edx, VULKAN_LOADER_ERROR_BIT_VALUE ; Write the error logging bit to rdx (second arg) call loader_log ; Log the error message before we crash add rsp, 56 ; Clean up the stack frame mov rax, 0 @@ -66,38 +87,62 @@ DevExtTramp macro num public vkdev_ext&num& vkdev_ext&num&: mov rax, qword ptr [rcx] ; Dereference the handle to get the dispatch table - jmp qword ptr [rax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * num))] ; Jump to the appropriate call chain + add rax, EXT_OFFSET_DEVICE_DISPATCH + jmp qword ptr [rax + PTR_SIZE * num] ; Jump to the appropriate call chain endm ; 32-bit values and macro ELSE +PTR_SIZE equ 4 ; The size of a pointer +CHAR_PTR_SIZE equ 4 ; The size of a 'const char *' struct +EXTERN C VULKAN_LOADER_ERROR_BIT_VALUE:DWORD +EXTERN C FUNCTION_OFFSET_INSTANCE:DWORD +EXTERN C PHYS_DEV_OFFSET_INST_DISPATCH:DWORD +EXTERN C PHYS_DEV_OFFSET_PHYS_DEV_TRAMP:DWORD +EXTERN C ICD_TERM_OFFSET_PHYS_DEV_TERM:DWORD +EXTERN C PHYS_DEV_OFFSET_PHYS_DEV_TERM:DWORD +EXTERN C INSTANCE_OFFSET_ICD_TERM:DWORD +EXTERN C DISPATCH_OFFSET_ICD_TERM:DWORD +EXTERN C EXT_OFFSET_DEVICE_DISPATCH:DWORD + PhysDevExtTramp macro num public _vkPhysDevExtTramp&num&@4 _vkPhysDevExtTramp&num&@4: mov eax, dword ptr [esp + 4] ; Load the wrapped VkPhysicalDevice into eax - mov ecx, [eax + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] ; Load the unwrapped VkPhysicalDevice into ecx + add eax, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP + mov ecx, [eax] ; Load the unwrapped VkPhysicalDevice into ecx + sub eax, PHYS_DEV_OFFSET_PHYS_DEV_TRAMP mov [esp + 4], ecx ; Overwrite the wrapped VkPhysicalDevice with the unwrapped one (on the stack) mov eax, [eax] ; Dereference the wrapped VkPhysicalDevice to get the dispatch table in eax - jmp dword ptr [eax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * num))] ; Jump to the next function in the chain, preserving the args on the stack + add eax, PHYS_DEV_OFFSET_INST_DISPATCH + jmp dword ptr [eax + (PTR_SIZE * num)] ; Jump to the next function in the chain, preserving the args on the stack endm PhysDevExtTermin macro num public _vkPhysDevExtTermin&num&@4 _vkPhysDevExtTermin&num&@4: mov ecx, dword ptr [esp + 4] ; Move the wrapped VkPhysicalDevice into ecx - mov eax, dword ptr [ecx + ICD_TERM_OFFSET_PHYS_DEV_TERM] ; Store the loader_icd_term* in eax - cmp dword ptr [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * num))], 0 ; Check if the next function in the chain is NULL - je terminError&num& ; Go to the error section if it is NULL - mov ecx, dword ptr [ecx + PHYS_DEV_OFFSET_PHYS_DEV_TERM] ; Unwrap the VkPhysicalDevice in ecx + add ecx, ICD_TERM_OFFSET_PHYS_DEV_TERM + mov eax, dword ptr [ecx] ; Store the loader_icd_term* in eax + sub ecx, ICD_TERM_OFFSET_PHYS_DEV_TERM + add eax, DISPATCH_OFFSET_ICD_TERM + cmp dword ptr [eax + (PTR_SIZE * num)], 0 ; Check if the next function in the chain is NULL + je terminError&num& + add ecx, PHYS_DEV_OFFSET_PHYS_DEV_TERM ; Go to the error section if it is NULL + mov ecx, dword ptr [ecx] ; Unwrap the VkPhysicalDevice in ecx mov dword ptr [esp + 4], ecx ; Copy the unwrapped VkPhysicalDevice into the first arg - jmp dword ptr [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * num))] ; Jump to the next function in the chain + jmp dword ptr [eax + (PTR_SIZE * num)] ; Jump to the next function in the chain terminError&num&: - mov eax, dword ptr [eax + INSTANCE_OFFSET_ICD_TERM] ; Load the loader_instance into eax - push dword ptr [eax + (FUNCTION_OFFSET_INSTANCE + (CHAR_PTR_SIZE * num))] ; Push the func name (fifth arg) + sub eax, DISPATCH_OFFSET_ICD_TERM + add eax, INSTANCE_OFFSET_ICD_TERM + mov eax, dword ptr [eax] ; Load the loader_instance into eax + add eax, FUNCTION_OFFSET_INSTANCE + push dword ptr [eax + (CHAR_PTR_SIZE * num)] ; Push the func name (fifth arg) + sub eax, FUNCTION_OFFSET_INSTANCE push offset termin_error_string ; Push the error string (fourth arg) push 0 ; Push zero (third arg) - push VULKAN_LOADER_ERROR_BIT ; Push the error logging bit (second arg) + push VULKAN_LOADER_ERROR_BIT_VALUE ; Push the error logging bit (second arg) push eax ; Push the loader_instance (first arg) call _loader_log ; Log the error message before we crash add esp, 20 ; Clean up the args @@ -110,7 +155,8 @@ public _vkdev_ext&num&@4 _vkdev_ext&num&@4: mov eax, dword ptr [esp + 4] ; Dereference the handle to get VkDevice chain_device mov eax, dword ptr [eax] ; Dereference the chain_device to get the loader_dispatch - jmp dword ptr [eax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * num))] ; Jump to the appropriate call chain + add eax, EXT_OFFSET_DEVICE_DISPATCH + jmp dword ptr [eax + (PTR_SIZE * num)] ; Jump to the appropriate call chain endm ; This is also needed for 32-bit only diff --git a/scripts/parse_asm_values.py b/scripts/parse_asm_values.py deleted file mode 100644 index 157fb7d5e..000000000 --- a/scripts/parse_asm_values.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/python3 -i -# -# Copyright (c) 2022 The Khronos Group Inc. -# Copyright (c) 2022 LunarG, Inc. - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Author: Charles Giessen - -# This script reads in the 'intermediate output' of a compiler to look for sizeof/offsetof information -# necessary for the assembler portions of the loader. This is achieved by forcing the compiler to output -# the intermediate assembly output and looking for specific patterns which contain the relevant information - -import sys -import os.path -from os.path import exists -import re -import subprocess -import traceback - - -# Where to write the "gen_defines.asm" file -destination_file = sys.argv[1] -# The location the build system puts the intermediate asm file which depends on the compiler -source_asm_file = sys.argv[2] -# Whether we are using "MASM", "MARMASM" or "GAS" for the assembler -assembler_type = sys.argv[3] -# Whether we are using gcc, clang, or msvc -compiler = sys.argv[4] -# taken from CMAKE_SYSTEM_PROCESSOR - x86_64, aarch64|arm64, x86, aarch32|armhf -# Only used with GAS/MARMASM - MASM doesn't need this, as it has its own way to determine x86 vs x64 -arch = sys.argv[5] - -POSIX_COMPILERS = ["GNU", "Clang", "AppleClang"] - -if destination_file is None or source_asm_file is None or assembler_type is None or compiler is None or arch is None: - print("Required command line arguments were not provided") - sys.exit(1) - -defines = ["VULKAN_LOADER_ERROR_BIT", - "PTR_SIZE", - "CHAR_PTR_SIZE", - "FUNCTION_OFFSET_INSTANCE", - "PHYS_DEV_OFFSET_INST_DISPATCH", - "PHYS_DEV_OFFSET_PHYS_DEV_TRAMP", - "ICD_TERM_OFFSET_PHYS_DEV_TERM", - "PHYS_DEV_OFFSET_PHYS_DEV_TERM", - "INSTANCE_OFFSET_ICD_TERM", - "DISPATCH_OFFSET_ICD_TERM", - "EXT_OFFSET_DEVICE_DISPATCH" ] - -if os.path.splitext(source_asm_file)[1] == ".a": - try: - ar_path = sys.argv[6] - asm_archive_member = sys.argv[7] - subprocess_result = subprocess.Popen([ar_path, "p", source_asm_file, asm_archive_member], stdout=subprocess.PIPE) - asm_intermediate_file = subprocess_result.stdout.read().decode("utf-8") - except IOError: - print("Could not open assembler archive file:", source_asm_file) - traceback.print_exc() - sys.exit(1) -else: - try: - with open(source_asm_file, 'r') as f: - asm_intermediate_file = f.read() - except IOError: - print("Could not open assembler file:", source_asm_file) - sys.exit(1) - -with open(destination_file, "w", encoding="utf-8") as dest: - # special case vulkan error bit due to it not appearing in the asm - its defined in the header as 8 so it shouldn't change - if assembler_type == "MASM": - dest.write("VULKAN_LOADER_ERROR_BIT equ 8;\n") - elif assembler_type == 'MARMASM': - dest.write(' AREA loader_structs_details, DATA,READONLY\n') - if arch == "aarch64" or arch == "arm64": - dest.write("AARCH_64 EQU 1\n") - elif arch in ["aarch32", "armhf", "arm"]: - dest.write("AARCH_64 EQU 0\n") - else: - print('The parameter "arch" has value of ', arch, ' which is not recognized') - dest.write("VULKAN_LOADER_ERROR_BIT EQU 8\n") - elif assembler_type == "GAS": - # let the assembler know which platform to use - if arch == "x86_64": - dest.write(".set X86_64, 1\n") - elif arch == "aarch64" or arch == "arm64": - dest.write(".set AARCH_64, 1\n") - elif arch in ["aarch32", "armhf", "arm"]: - dest.write(".set AARCH_64, 0\n") - else: - print('The parameter "arch" has value of ', arch, ' which is not recognized') - # Nothing to write in the x86 case - - for d in defines: - match = None - if compiler == "MSVC": - if d == "VULKAN_LOADER_ERROR_BIT": - continue # skip due to special case - if 'arm' in arch.lower(): - match = re.search('\\|'+ d + '\\| DCD[\t ]*0x([0-9a-f]+)', asm_intermediate_file) - else: - match = re.search(d + " DD [ ]*([0-9a-f]+)H", asm_intermediate_file) - elif compiler in POSIX_COMPILERS: - match = re.search(d + " = ([0-9]+)", asm_intermediate_file) - - if len(match.groups()) > 0: - if compiler == "MSVC": - value = str(int(match.group(1), 16)) - elif compiler in POSIX_COMPILERS: - value = match.group(1) - - # MASM uses hex values, decode them here - if assembler_type == "MASM": - dest.write(d + " equ " + value +";\n") - elif assembler_type == 'MARMASM': - dest.write(d + ' EQU ' + value +'\n') - elif assembler_type == "GAS": - dest.write(".set " + d + ", " + value + "\n") - else: - print("Couldn't find ", d) - sys.exit(1) - if assembler_type == 'MARMASM': - dest.write(" END\n") -