From: John Bauman Date: Thu, 8 Aug 2024 17:47:05 +0000 (+0000) Subject: Use ASM unknown function trampolines on GN X-Git-Tag: upstream/1.3.296~22 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ee66877982915c8056d1d729397ac86386a84f68;p=platform%2Fupstream%2FVulkan-Loader.git Use ASM unknown function trampolines on GN The GN build doesn't currently support unknown function trampolines. To fix that, we can use the assembly trampolines. To generate the asm_offset assembly file, we can build it in a static library and pass -S to it; that causes the assembly file to be copied into the .a file. The python script can then extract it. This requires access to the "ar" executable, so this mechanism is only used if a path to ar is specified in //build_overrides/vulkan_loader.gni. To fix incremental builds, "gen_defines.asm" must be included using "#include", not ".include", since .include isn't a preprocessor directive and isn't picked up by clang's depfile creation. --- diff --git a/BUILD.gn b/BUILD.gn index 6fd87194..10c483c5 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -36,9 +36,7 @@ if (is_win) { } config("vulkan_internal_config") { - defines = [ - "VK_ENABLE_BETA_EXTENSIONS", - ] + defines = [ "VK_ENABLE_BETA_EXTENSIONS" ] if (is_clang || !is_win) { cflags = [ "-Wno-conversion", @@ -99,6 +97,52 @@ if (!is_android) { } else { library_type = "static_library" } + support_unknown_function_handling = false + if (ar_path != "" && !is_win && (current_cpu == "arm64" || current_cpu == "x86_64")) { + support_unknown_function_handling = true + static_library("asm_offset") { + sources = [ "loader/asm_offset.c" ] + deps = [ + "$vulkan_headers_dir:vulkan_headers", + ] + + if (is_fuchsia) { + deps += [ + ":dlopen_fuchsia", + ] + } + + # Output raw assembly instead of compiled object file. The assembly will be included as a member of the output ar file. + cflags = [ "-S" ] + configs += [ ":vulkan_internal_config" ] + configs += [ ":vulkan_loader_config" ] + } + + action("gen_defines") { + script = "scripts/parse_asm_values.py" + deps = [ ":asm_offset" ] + + inputs = [ + "$target_out_dir/libasm_offset.a", + ar_path, + ] + if (current_cpu == "arm64") { + cpu = "aarch64" + } else { + cpu = "x86_64" + } + args = [ + rebase_path("$target_gen_dir/gen_defines.asm", root_build_dir), + rebase_path("$target_out_dir/libasm_offset.a", root_build_dir), + "GAS", + "Clang", + cpu, + rebase_path(ar_path, root_build_dir), + "libasm_offset.asm_offset.c.o", + ] + outputs = [ "$target_gen_dir/gen_defines.asm" ] + } + } target(library_type, "libvulkan") { sources = [ @@ -135,8 +179,6 @@ if (!is_android) { "loader/unknown_function_handling.h", "loader/unknown_function_handling.c", "loader/vk_loader_layer.h", - - # TODO(jmadill): Use assembler where available. "loader/vk_loader_platform.h", "loader/wsi.c", "loader/wsi.h", @@ -217,6 +259,19 @@ if (!is_android) { runtime_deps = [ "//sdk/lib/fdio:fdio_sdk" ] } + if (support_unknown_function_handling) { + if (current_cpu == "arm64") { + sources += [ "loader/unknown_ext_chain_gas_aarch.S" ] + } else if (current_cpu == "x86_64") { + sources += [ "loader/unknown_ext_chain_gas_x86.S" ] + } else { + assert(false, "Unexpected CPU $current_cpu") + } + + defines += ["UNKNOWN_FUNCTIONS_SUPPORTED=1"] + deps += [ ":gen_defines" ] + include_dirs = [ "$target_gen_dir" ] + } } } diff --git a/loader/unknown_ext_chain_gas_aarch.S b/loader/unknown_ext_chain_gas_aarch.S index 1176be30..a78a32d3 100644 --- a/loader/unknown_ext_chain_gas_aarch.S +++ b/loader/unknown_ext_chain_gas_aarch.S @@ -24,7 +24,7 @@ // 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" +#include "gen_defines.asm" /* * References: @@ -56,6 +56,7 @@ .macro PhysDevExtTramp num .global vkPhysDevExtTramp\num #if defined(__ELF__) + .type vkPhysDevExtTramp\num, @function .hidden vkPhysDevExtTramp\num #endif .balign 4 @@ -77,6 +78,7 @@ vkPhysDevExtTramp\num: .macro PhysDevExtTermin num .global vkPhysDevExtTermin\num #if defined(__ELF__) + .type vkPhysDevExtTermin\num, @function .hidden vkPhysDevExtTermin\num #endif .balign 4 diff --git a/loader/unknown_ext_chain_gas_x86.S b/loader/unknown_ext_chain_gas_x86.S index de5a9203..5ee02051 100644 --- a/loader/unknown_ext_chain_gas_x86.S +++ b/loader/unknown_ext_chain_gas_x86.S @@ -33,7 +33,7 @@ #endif .intel_syntax noprefix -.include "gen_defines.asm" +#include "gen_defines.asm" .ifdef X86_64 diff --git a/scripts/gn/secondary/build_overrides/vulkan_loader.gni b/scripts/gn/secondary/build_overrides/vulkan_loader.gni index c826fc11..4cf8e827 100644 --- a/scripts/gn/secondary/build_overrides/vulkan_loader.gni +++ b/scripts/gn/secondary/build_overrides/vulkan_loader.gni @@ -21,3 +21,5 @@ vulkan_gen_subdir = "" # Vulkan loader build options vulkan_loader_shared = true +# Path to ar or llvm-ar +ar_path = "" diff --git a/scripts/parse_asm_values.py b/scripts/parse_asm_values.py index cab5ef9d..172a3633 100644 --- a/scripts/parse_asm_values.py +++ b/scripts/parse_asm_values.py @@ -25,6 +25,8 @@ import sys import os.path from os.path import exists import re +import subprocess +import traceback # Where to write the "gen_defines.asm" file @@ -57,12 +59,23 @@ defines = ["VULKAN_LOADER_ERROR_BIT", "DISPATCH_OFFSET_ICD_TERM", "EXT_OFFSET_DEVICE_DISPATCH" ] -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) +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: if assembler_type == "MASM":