From 934dc31e442510800cbd9d3d47ba58174ef30d56 Mon Sep 17 00:00:00 2001 From: jackun Date: Tue, 21 Apr 2020 16:56:46 +0300 Subject: [PATCH] Add utility lib with dlsym hooking --- bin/mangohud.in | 4 ++-- build.sh | 2 ++ src/gl/inject_egl.cpp | 4 ++-- src/gl/inject_glx.cpp | 6 +++--- src/hook_dlsym.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/meson.build | 23 +++++++++++++++++++++++ src/real_dlsym.cpp | 8 ++++---- 7 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 src/hook_dlsym.cpp diff --git a/bin/mangohud.in b/bin/mangohud.in index 0d4f5cdc..4ea9c182 100755 --- a/bin/mangohud.in +++ b/bin/mangohud.in @@ -1,8 +1,8 @@ #!/bin/sh MANGOHUD_LIB_NAME="libMangoHud.so" -if [ "$MANGOHUD_NODLSYM" = "1" ]; then - MANGOHUD_LIB_NAME="libMangoHud_nodlsym.so" +if [ "$MANGOHUD_DLSYM" = "1" ]; then + MANGOHUD_LIB_NAME="libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}" fi if [ "$#" -eq 0 ]; then diff --git a/build.sh b/build.sh index 6c4eaea2..0213f726 100755 --- a/build.sh +++ b/build.sh @@ -185,6 +185,8 @@ install() { /usr/bin/install -vm644 -D ./build/release/usr/lib/mangohud/lib32/libMangoHud.so /usr/lib/mangohud/lib32/libMangoHud.so /usr/bin/install -vm644 -D ./build/release/usr/lib/mangohud/lib64/libMangoHud.so /usr/lib/mangohud/lib64/libMangoHud.so + /usr/bin/install -vm644 -D ./build/release/usr/lib/mangohud/lib32/libMangoHud_dlsym.so /usr/lib/mangohud/lib32/libMangoHud_dlsym.so + /usr/bin/install -vm644 -D ./build/release/usr/lib/mangohud/lib64/libMangoHud_dlsym.so /usr/lib/mangohud/lib64/libMangoHud_dlsym.so /usr/bin/install -vm644 -D ./build/release/usr/share/vulkan/implicit_layer.d/MangoHud.x86.json /usr/share/vulkan/implicit_layer.d/MangoHud.x86.json /usr/bin/install -vm644 -D ./build/release/usr/share/vulkan/implicit_layer.d/MangoHud.x86_64.json /usr/share/vulkan/implicit_layer.d/MangoHud.x86_64.json /usr/bin/install -vm644 -D ./build/release/usr/share/doc/mangohud/MangoHud.conf.example /usr/share/doc/mangohud/MangoHud.conf.example diff --git a/src/gl/inject_egl.cpp b/src/gl/inject_egl.cpp index a65c4f1b..cbdd8ea3 100644 --- a/src/gl/inject_egl.cpp +++ b/src/gl/inject_egl.cpp @@ -84,7 +84,7 @@ static std::array name_to_funcptr_map = {{ #undef ADD_HOOK }}; -void *find_egl_ptr(const char *name) +EXPORT_C_(void *) mangohud_find_egl_ptr(const char *name) { if (is_blacklisted()) return nullptr; @@ -100,7 +100,7 @@ void *find_egl_ptr(const char *name) EXPORT_C_(void *) eglGetProcAddress(const char* procName) { //std::cerr << __func__ << ": " << procName << std::endl; - void* func = find_egl_ptr(procName); + void* func = mangohud_find_egl_ptr(procName); if (func) return func; diff --git a/src/gl/inject_glx.cpp b/src/gl/inject_glx.cpp index 82d8c1b2..be2aeb06 100644 --- a/src/gl/inject_glx.cpp +++ b/src/gl/inject_glx.cpp @@ -200,7 +200,7 @@ static std::array name_to_funcptr_map = {{ #undef ADD_HOOK }}; -void *find_glx_ptr(const char *name) +EXPORT_C_(void *) mangohud_find_glx_ptr(const char *name) { if (is_blacklisted()) return nullptr; @@ -216,7 +216,7 @@ void *find_glx_ptr(const char *name) EXPORT_C_(void *) glXGetProcAddress(const unsigned char* procName) { //std::cerr << __func__ << ":" << procName << std::endl; - void* func = find_glx_ptr( (const char*)procName ); + void* func = mangohud_find_glx_ptr( (const char*)procName ); if (func) return func; @@ -226,7 +226,7 @@ EXPORT_C_(void *) glXGetProcAddress(const unsigned char* procName) { EXPORT_C_(void *) glXGetProcAddressARB(const unsigned char* procName) { //std::cerr << __func__ << ":" << procName << std::endl; - void* func = find_glx_ptr( (const char*)procName ); + void* func = mangohud_find_glx_ptr( (const char*)procName ); if (func) return func; diff --git a/src/hook_dlsym.cpp b/src/hook_dlsym.cpp new file mode 100644 index 00000000..97649e4e --- /dev/null +++ b/src/hook_dlsym.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include "real_dlsym.h" + +EXPORT_C_(void*) dlsym(void * handle, const char * name) +{ + void *(*find_glx_ptr)(const char *name) = nullptr; + void *(*find_egl_ptr)(const char *name) = nullptr; + + if (!find_glx_ptr) + find_glx_ptr = reinterpret_cast (real_dlsym(RTLD_NEXT, "mangohud_find_glx_ptr")); + + if (!find_egl_ptr) + find_egl_ptr = reinterpret_cast (real_dlsym(RTLD_NEXT, "mangohud_find_egl_ptr")); + + void* func = nullptr; + + if (find_glx_ptr) { + func = find_glx_ptr(name); + if (func) { + //fprintf(stderr,"%s: local: %s\n", __func__ , name); + return func; + } + } + + if (find_egl_ptr) { + func = find_egl_ptr(name); + if (func) { + //fprintf(stderr,"%s: local: %s\n", __func__ , name); + return func; + } + } + + //fprintf(stderr,"%s: foreign: %s\n", __func__ , name); + return real_dlsym(handle, name); +} diff --git a/src/meson.build b/src/meson.build index f00cf59d..e82bd9d8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -140,6 +140,29 @@ vklayer_mesa_overlay = shared_library( install : true ) +mangohud_dlsym = shared_library( + 'MangoHud_dlsym', + files( + 'elfhacks.cpp', + 'real_dlsym.cpp', + 'hook_dlsym.cpp', + ), + c_args : [ + pre_args, + c_vis_args, + no_override_init_args, + ], + cpp_args : [ + pre_args, + cpp_vis_args, + ], + dependencies : [dep_dl], + include_directories : [inc_common], + link_args : cc.get_supported_link_arguments(['-Wl,-Bsymbolic-functions', '-Wl,-z,relro', '-Wl,--exclude-libs,ALL']), + install_dir : libdir_mangohud, + install : true +) + configure_file(input : 'mangohud.json.in', output : '@0@.@1@.json'.format(meson.project_name(), target_machine.cpu_family()), configuration : {'libdir_mangohud' : libdir_mangohud + '/', diff --git a/src/real_dlsym.cpp b/src/real_dlsym.cpp index ac6ed35f..241a986c 100644 --- a/src/real_dlsym.cpp +++ b/src/real_dlsym.cpp @@ -91,21 +91,21 @@ void* get_proc_address(const char* name) { } #ifdef HOOK_DLSYM -extern void *find_glx_ptr(const char *name); -extern void *find_egl_ptr(const char *name); +EXPORT_C_(void *) mangohud_find_glx_ptr(const char *name); +EXPORT_C_(void *) mangohud_find_egl_ptr(const char *name); EXPORT_C_(void*) dlsym(void * handle, const char * name) { void* func = nullptr; #ifdef HAVE_X11 - func = find_glx_ptr(name); + func = mangohud_find_glx_ptr(name); if (func) { //fprintf(stderr,"%s: local: %s\n", __func__ , name); return func; } #endif - func = find_egl_ptr(name); + func = mangohud_find_egl_ptr(name); if (func) { //fprintf(stderr,"%s: local: %s\n", __func__ , name); return func;