From e9bee45a36aecd38e79a2d7f149fd3fbda7a3e81 Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Tue, 1 Jul 2025 09:37:29 +0200 Subject: [PATCH] second batch of original vulkan pointers alongside basic hooks --- CMakeLists.txt | 1 + include/vulkan/funcs.hpp | 31 +++++++++++++++++-- include/vulkan/hooks.hpp | 13 ++++++++ src/init.cpp | 8 +++++ src/vulkan/funcs.cpp | 44 +++++++++++++++++++++++++-- src/vulkan/hooks.cpp | 66 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 include/vulkan/hooks.hpp create mode 100644 src/vulkan/hooks.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b34403a..3a10293 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ add_subdirectory(lsfg-vk-gen) file(GLOB SOURCES "src/loader/*.cpp" + "src/vulkan/*.cpp" "src/*.cpp" ) diff --git a/include/vulkan/funcs.hpp b/include/vulkan/funcs.hpp index 9a2428a..0ad93d6 100644 --- a/include/vulkan/funcs.hpp +++ b/include/vulkan/funcs.hpp @@ -10,17 +10,44 @@ namespace Vulkan::Funcs { /// void initialize(); + /// + /// Initialize the instance Vulkan function pointers. + /// + /// @param instance The Vulkan instance to initialize. + /// + void initializeInstance(VkInstance instance); + + /// + /// Initialize the device Vulkan function pointers. + /// + /// @param device The Vulkan device to initialize. + /// + void initializeDevice(VkDevice device); + /// Call to the original vkCreateInstance function. - VkResult vkCreateInstanceOriginal( + VkResult ovkCreateInstance( const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance ); /// Call to the original vkDestroyInstance function. - void vkDestroyInstanceOriginal( + void ovkDestroyInstance( VkInstance instance, const VkAllocationCallbacks* pAllocator ); + + /// Call to the original vkCreateDevice function. + VkResult ovkCreateDevice( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice + ); + /// Call to the original vkDestroyDevice function. + void ovkDestroyDevice( + VkDevice device, + const VkAllocationCallbacks* pAllocator + ); } #endif // FUNCS_HPP diff --git a/include/vulkan/hooks.hpp b/include/vulkan/hooks.hpp new file mode 100644 index 0000000..471a5d5 --- /dev/null +++ b/include/vulkan/hooks.hpp @@ -0,0 +1,13 @@ +#ifndef HOOKS_HPP +#define HOOKS_HPP + +namespace Vulkan::Hooks { + + /// + /// Install overrides for hooked Vulkan functions. + /// + void initialize(); + +} + +#endif // HOOKS_HPP diff --git a/src/init.cpp b/src/init.cpp index 345963f..d016dfe 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,5 +1,7 @@ #include "loader/dl.hpp" #include "loader/vk.hpp" +#include "vulkan/funcs.hpp" +#include "vulkan/hooks.hpp" #include "log.hpp" extern "C" void __attribute__((constructor)) init(); @@ -11,6 +13,12 @@ void init() { // hook loaders Loader::DL::initialize(); Loader::VK::initialize(); + + // setup vulkan stuff + Vulkan::Funcs::initialize(); + Vulkan::Hooks::initialize(); + + Log::info("lsfg-vk: init() completed successfully"); } void deinit() { diff --git a/src/vulkan/funcs.cpp b/src/vulkan/funcs.cpp index 31edaf9..51a74bd 100644 --- a/src/vulkan/funcs.cpp +++ b/src/vulkan/funcs.cpp @@ -1,5 +1,6 @@ #include "vulkan/funcs.hpp" #include "loader/dl.hpp" +#include "loader/vk.hpp" #include "log.hpp" using namespace Vulkan; @@ -7,6 +8,9 @@ using namespace Vulkan; namespace { PFN_vkCreateInstance vkCreateInstance_ptr{}; PFN_vkDestroyInstance vkDestroyInstance_ptr{}; + + PFN_vkCreateDevice vkCreateDevice_ptr{}; + PFN_vkDestroyDevice vkDestroyDevice_ptr{}; } void Funcs::initialize() { @@ -28,17 +32,53 @@ void Funcs::initialize() { Log::debug("lsfg-vk(funcs): Initialized global Vulkan functions with original pointers"); } +void Funcs::initializeInstance(VkInstance instance) { + if (vkCreateDevice_ptr || vkDestroyDevice_ptr) { + Log::warn("lsfg-vk(funcs): Instance Vulkan functions already initialized, did you call it twice?"); + return; + } + + vkCreateDevice_ptr = reinterpret_cast( + Loader::VK::ovkGetInstanceProcAddr(instance, "vkCreateDevice")); + vkDestroyDevice_ptr = reinterpret_cast( + Loader::VK::ovkGetInstanceProcAddr(instance, "vkDestroyDevice")); + if (!vkCreateDevice_ptr || !vkDestroyDevice_ptr) { + Log::error("lsfg-vk(funcs): Failed to initialize Vulkan instance functions, missing symbols"); + exit(EXIT_FAILURE); + } + + Log::debug("lsfg-vk(funcs): Initialized instance Vulkan functions with original pointers"); +} + +void Funcs::initializeDevice(VkDevice device) { + Log::debug("lsfg-vk(funcs): Initialized device Vulkan functions with original pointers"); +} + // original function calls -VkResult Funcs::vkCreateInstanceOriginal( +VkResult Funcs::ovkCreateInstance( const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { return vkCreateInstance_ptr(pCreateInfo, pAllocator, pInstance); } -void Funcs::vkDestroyInstanceOriginal( +void Funcs::ovkDestroyInstance( VkInstance instance, const VkAllocationCallbacks* pAllocator) { vkDestroyInstance_ptr(instance, pAllocator); } + +VkResult Funcs::ovkCreateDevice( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice) { + return vkCreateDevice_ptr(physicalDevice, pCreateInfo, pAllocator, pDevice); +} + +void Funcs::ovkDestroyDevice( + VkDevice device, + const VkAllocationCallbacks* pAllocator) { + vkDestroyDevice_ptr(device, pAllocator); +} diff --git a/src/vulkan/hooks.cpp b/src/vulkan/hooks.cpp new file mode 100644 index 0000000..aef658c --- /dev/null +++ b/src/vulkan/hooks.cpp @@ -0,0 +1,66 @@ +#include "vulkan/hooks.hpp" +#include "vulkan/funcs.hpp" +#include "loader/dl.hpp" +#include "loader/vk.hpp" +#include "log.hpp" + +#include + +using namespace Vulkan; + +namespace { + bool initialized{false}; + + VkResult myvkCreateInstance( + const VkInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance) { + auto res = Funcs::ovkCreateInstance(pCreateInfo, pAllocator, pInstance); + + Funcs::initializeInstance(*pInstance); + + return res; + } + + VkResult myvkCreateDevice( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice) { + auto res = Funcs::ovkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); + + Funcs::initializeDevice(*pDevice); + + return res; + } + +} + +void Hooks::initialize() { + if (initialized) { + Log::warn("Vulkan hooks already initialized, did you call it twice?"); + return; + } + + // register hooks to vulkan loader + Loader::VK::registerSymbol("vkCreateInstance", + reinterpret_cast(myvkCreateInstance)); + Loader::VK::registerSymbol("vkCreateDevice", + reinterpret_cast(myvkCreateDevice)); + + // register hooks to dynamic loader under libvulkan.so.1 + Loader::DL::File vk1("libvulkan.so.1"); + vk1.defineSymbol("vkCreateInstance", + reinterpret_cast(myvkCreateInstance)); + vk1.defineSymbol("vkCreateDevice", + reinterpret_cast(myvkCreateDevice)); + Loader::DL::registerFile(vk1); + + // register hooks to dynamic loader under libvulkan.so + Loader::DL::File vk2("libvulkan.so"); + vk2.defineSymbol("vkCreateInstance", + reinterpret_cast(myvkCreateInstance)); + vk2.defineSymbol("vkCreateDevice", + reinterpret_cast(myvkCreateDevice)); + Loader::DL::registerFile(vk2); +}