mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 14:00:16 +02:00
Thunks: Fixes symbol conflict between GL and Vulkan
Fixes crash that occurs in applications that use both GL and Vulkan, Like UE5 Vulkan native games. Fixes Ender Magnolia. The issue here is that UE5 loads libGL first, which initializes our libGL thunks, setting its X11Manager's functions. It then loads libvulkan, which calls our oninit constructor, which because of the symbol conflict, calls in to the libGL thunk's host functions to reinitialize its function pointers, never initializing the Vulkan X11Manager's functions. It would then crash as soon as an X11 function was used. Give them unique symbol names so we don't accidentally look up the incorrect symbol.
This commit is contained in:
6 files changed
+28
-28
No files matched your search
@@ -80,10 +80,10 @@ static void* malloc_wrapper(size_t size) {
|
||||
}
|
||||
|
||||
static void OnInit() {
|
||||
fexfn_pack_SetGuestMalloc((uintptr_t)malloc_wrapper, (uintptr_t)CallbackUnpack<decltype(malloc_wrapper)>::Unpack);
|
||||
fexfn_pack_SetGuestXSync((uintptr_t)XSync, (uintptr_t)CallbackUnpack<decltype(XSync)>::Unpack);
|
||||
fexfn_pack_SetGuestXGetVisualInfo((uintptr_t)XGetVisualInfo, (uintptr_t)CallbackUnpack<decltype(XGetVisualInfo)>::Unpack);
|
||||
fexfn_pack_SetGuestXDisplayString((uintptr_t)XDisplayString, (uintptr_t)CallbackUnpack<decltype(XDisplayString)>::Unpack);
|
||||
fexfn_pack_GL_SetGuestMalloc((uintptr_t)malloc_wrapper, (uintptr_t)CallbackUnpack<decltype(malloc_wrapper)>::Unpack);
|
||||
fexfn_pack_GL_SetGuestXSync((uintptr_t)XSync, (uintptr_t)CallbackUnpack<decltype(XSync)>::Unpack);
|
||||
fexfn_pack_GL_SetGuestXGetVisualInfo((uintptr_t)XGetVisualInfo, (uintptr_t)CallbackUnpack<decltype(XGetVisualInfo)>::Unpack);
|
||||
fexfn_pack_GL_SetGuestXDisplayString((uintptr_t)XDisplayString, (uintptr_t)CallbackUnpack<decltype(XDisplayString)>::Unpack);
|
||||
}
|
||||
|
||||
// libGL.so must pull in libX11.so as a dependency. Referencing some libX11
|
||||
|
||||
@@ -50,19 +50,19 @@ host_layout<_XDisplay*>::~host_layout() {
|
||||
// Functions returning _XDisplay* should be handled explicitly via ptr_passthrough
|
||||
guest_layout<_XDisplay*> to_guest(host_layout<_XDisplay*>) = delete;
|
||||
|
||||
static void fexfn_impl_libGL_SetGuestMalloc(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
static void fexfn_impl_libGL_GL_SetGuestMalloc(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
MakeHostTrampolineForGuestFunctionAt(GuestTarget, GuestUnpacker, &GuestMalloc);
|
||||
}
|
||||
|
||||
static void fexfn_impl_libGL_SetGuestXGetVisualInfo(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
static void fexfn_impl_libGL_GL_SetGuestXGetVisualInfo(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
MakeHostTrampolineForGuestFunctionAt(GuestTarget, GuestUnpacker, &x11_manager.GuestXGetVisualInfo);
|
||||
}
|
||||
|
||||
static void fexfn_impl_libGL_SetGuestXSync(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
static void fexfn_impl_libGL_GL_SetGuestXSync(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
MakeHostTrampolineForGuestFunctionAt(GuestTarget, GuestUnpacker, &x11_manager.GuestXSync);
|
||||
}
|
||||
|
||||
static void fexfn_impl_libGL_SetGuestXDisplayString(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
static void fexfn_impl_libGL_GL_SetGuestXDisplayString(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
MakeHostTrampolineForGuestFunctionAt(GuestTarget, GuestUnpacker, &x11_manager.GuestXDisplayString);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,18 +22,18 @@ template<>
|
||||
struct fex_gen_config<glXGetProcAddress> : fexgen::custom_host_impl, fexgen::custom_guest_entrypoint, fexgen::returns_guest_pointer {};
|
||||
|
||||
// internal use
|
||||
void SetGuestMalloc(uintptr_t, uintptr_t);
|
||||
void SetGuestXSync(uintptr_t, uintptr_t);
|
||||
void SetGuestXGetVisualInfo(uintptr_t, uintptr_t);
|
||||
void SetGuestXDisplayString(uintptr_t, uintptr_t);
|
||||
void GL_SetGuestMalloc(uintptr_t, uintptr_t);
|
||||
void GL_SetGuestXSync(uintptr_t, uintptr_t);
|
||||
void GL_SetGuestXGetVisualInfo(uintptr_t, uintptr_t);
|
||||
void GL_SetGuestXDisplayString(uintptr_t, uintptr_t);
|
||||
template<>
|
||||
struct fex_gen_config<SetGuestMalloc> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
struct fex_gen_config<GL_SetGuestMalloc> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
template<>
|
||||
struct fex_gen_config<SetGuestXSync> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
struct fex_gen_config<GL_SetGuestXSync> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
template<>
|
||||
struct fex_gen_config<SetGuestXGetVisualInfo> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
struct fex_gen_config<GL_SetGuestXGetVisualInfo> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
template<>
|
||||
struct fex_gen_config<SetGuestXDisplayString> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
struct fex_gen_config<GL_SetGuestXDisplayString> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
|
||||
template<typename>
|
||||
struct fex_gen_type {};
|
||||
|
||||
@@ -87,9 +87,9 @@ PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance a_0, const char* a_1) {
|
||||
void OnInit() {
|
||||
// TODO: Load libX11 on-demand instead
|
||||
void* libx11 = dlopen("libX11.so.6", RTLD_LAZY);
|
||||
fexfn_pack_SetGuestXSync((uintptr_t)dlsym(libx11, "XSync"), (uintptr_t)CallbackUnpack<decltype(XSync)>::Unpack);
|
||||
fexfn_pack_SetGuestXGetVisualInfo((uintptr_t)dlsym(libx11, "XGetVisualInfo"), (uintptr_t)CallbackUnpack<decltype(XGetVisualInfo)>::Unpack);
|
||||
fexfn_pack_SetGuestXDisplayString((uintptr_t)dlsym(libx11, "XDisplayString"), (uintptr_t)CallbackUnpack<decltype(XDisplayString)>::Unpack);
|
||||
fexfn_pack_Vulkan_SetGuestXSync((uintptr_t)dlsym(libx11, "XSync"), (uintptr_t)CallbackUnpack<decltype(XSync)>::Unpack);
|
||||
fexfn_pack_Vulkan_SetGuestXGetVisualInfo((uintptr_t)dlsym(libx11, "XGetVisualInfo"), (uintptr_t)CallbackUnpack<decltype(XGetVisualInfo)>::Unpack);
|
||||
fexfn_pack_Vulkan_SetGuestXDisplayString((uintptr_t)dlsym(libx11, "XDisplayString"), (uintptr_t)CallbackUnpack<decltype(XDisplayString)>::Unpack);
|
||||
}
|
||||
|
||||
LOAD_LIB_INIT(libvulkan, OnInit)
|
||||
@@ -63,15 +63,15 @@ static void DoSetupWithInstance(VkInstance instance) {
|
||||
|
||||
static X11Manager x11_manager;
|
||||
|
||||
static void fexfn_impl_libvulkan_SetGuestXGetVisualInfo(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
static void fexfn_impl_libvulkan_Vulkan_SetGuestXGetVisualInfo(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
MakeHostTrampolineForGuestFunctionAt(GuestTarget, GuestUnpacker, &x11_manager.GuestXGetVisualInfo);
|
||||
}
|
||||
|
||||
static void fexfn_impl_libvulkan_SetGuestXSync(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
static void fexfn_impl_libvulkan_Vulkan_SetGuestXSync(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
MakeHostTrampolineForGuestFunctionAt(GuestTarget, GuestUnpacker, &x11_manager.GuestXSync);
|
||||
}
|
||||
|
||||
static void fexfn_impl_libvulkan_SetGuestXDisplayString(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
static void fexfn_impl_libvulkan_Vulkan_SetGuestXDisplayString(uintptr_t GuestTarget, uintptr_t GuestUnpacker) {
|
||||
MakeHostTrampolineForGuestFunctionAt(GuestTarget, GuestUnpacker, &x11_manager.GuestXDisplayString);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,15 +29,15 @@ template<typename>
|
||||
struct fex_gen_type {};
|
||||
|
||||
// internal use
|
||||
void SetGuestXSync(uintptr_t, uintptr_t);
|
||||
void SetGuestXGetVisualInfo(uintptr_t, uintptr_t);
|
||||
void SetGuestXDisplayString(uintptr_t, uintptr_t);
|
||||
void Vulkan_SetGuestXSync(uintptr_t, uintptr_t);
|
||||
void Vulkan_SetGuestXGetVisualInfo(uintptr_t, uintptr_t);
|
||||
void Vulkan_SetGuestXDisplayString(uintptr_t, uintptr_t);
|
||||
template<>
|
||||
struct fex_gen_config<SetGuestXSync> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
struct fex_gen_config<Vulkan_SetGuestXSync> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
template<>
|
||||
struct fex_gen_config<SetGuestXGetVisualInfo> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
struct fex_gen_config<Vulkan_SetGuestXGetVisualInfo> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
template<>
|
||||
struct fex_gen_config<SetGuestXDisplayString> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
struct fex_gen_config<Vulkan_SetGuestXDisplayString> : fexgen::custom_guest_entrypoint, fexgen::custom_host_impl {};
|
||||
|
||||
// So-called "dispatchable" handles are represented as opaque pointers.
|
||||
// In addition to marking them as such, API functions that create these objects
|
||||
|
||||
Reference in new issue
Block a user