diff --git a/BUILD.gn b/BUILD.gn index 6fd871945..10c483c54 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 1176be30f..a78a32d34 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 de5a92030..5ee020512 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 c826fc112..4cf8e8279 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 cab5ef9dc..172a36339 100644 --- a/scripts/parse_asm_values.py +++ b/scripts/parse_asm_values.py @@ -25,6 +25,8 @@ 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 @@ "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":