Skip to content

Commit

Permalink
Move dlsym code to shim
Browse files Browse the repository at this point in the history
  • Loading branch information
Etaash-mathamsetty committed Dec 29, 2024
1 parent c515999 commit dda4875
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 101 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ Or alternatively, add `MANGOHUD=1` to your shell profile (Vulkan only).

## OpenGL

OpenGL games may also need `dlsym` hooking. Add `--dlsym` to your command like `mangohud --dlsym %command%` for Steam.
OpenGL games may also need `dlsym` hooking, which is now enabled by default. Set the `MANGOHUD_DLSYM` env to `0` to disable like `MANGOHUD_DLSYM=0 %command%` for Steam.

Some Linux native OpenGL games overrides LD_PRELOAD and stops MangoHud from working. You can sometimes fix this by editing LD_PRELOAD in the start script
`LD_PRELOAD=/path/to/mangohud/lib/`
Expand Down Expand Up @@ -321,6 +321,8 @@ You can also specify configuration file with `MANGOHUD_CONFIGFILE=/path/to/confi

You can also specify presets file with `MANGOHUD_PRESETSFILE=/path/to/config`. This is especially useful when running mangohud in a sandbox such as flatpak.

You can also specify custom hud libraries using `MANGOHUD_OPENGL_LIBS=/path/to/libMangoHud_opengl.so`. This is useful for testing MangoHud without modifying the installation on your system.

A partial list of parameters are below. See the config file for a complete list.
Parameters that are enabled by default have to be explicitly disabled. These (currently) are `fps`, `frame_timing`, `cpu_stats` (cpu load), `gpu_stats` (gpu load), and each can be disabled by setting the corresponding variable to 0 (e.g., fps=0).

Expand Down
4 changes: 2 additions & 2 deletions bin/mangohud-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ mangohud_install() {

echo DEFAULTLIB: $DEFAULTLIB
/usr/bin/install -Dvm644 ./usr/lib/mangohud/lib64/libMangoHud.so /usr/lib/mangohud/lib64/libMangoHud.so
/usr/bin/install -Dvm644 ./usr/lib/mangohud/lib64/libMangoHud_dlsym.so /usr/lib/mangohud/lib64/libMangoHud_dlsym.so
/usr/bin/install -Dvm644 ./usr/lib/mangohud/lib32/libMangoHud.so /usr/lib/mangohud/lib32/libMangoHud.so
/usr/bin/install -Dvm644 ./usr/lib/mangohud/lib32/libMangoHud_dlsym.so /usr/lib/mangohud/lib32/libMangoHud_dlsym.so
/usr/bin/install -Dvm644 ./usr/lib/mangohud/lib64/libMangoHud_opengl.so /usr/lib/mangohud/lib64/libMangoHud_opengl.so
/usr/bin/install -Dvm644 ./usr/lib/mangohud/lib32/libMangoHud_opengl.so /usr/lib/mangohud/lib32/libMangoHud_opengl.so
/usr/bin/install -Dvm644 ./usr/lib/mangohud/lib64/libMangoHud_shim.so /usr/lib/mangohud/lib64/libMangoHud_shim.so
/usr/bin/install -Dvm644 ./usr/lib/mangohud/lib32/libMangoHud_shim.so /usr/lib/mangohud/lib32/libMangoHud_shim.so
/usr/bin/install -Dvm644 ./usr/share/vulkan/implicit_layer.d/MangoHud.x86_64.json /usr/share/vulkan/implicit_layer.d/MangoHud.x86_64.json
/usr/bin/install -Dvm644 ./usr/share/vulkan/implicit_layer.d/MangoHud.x86.json /usr/share/vulkan/implicit_layer.d/MangoHud.x86.json
/usr/bin/install -Dvm644 ./usr/share/man/man1/mangohud.1 /usr/share/man/man1/mangohud.1
Expand Down
7 changes: 0 additions & 7 deletions bin/mangohud.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ DISABLE_LD_PRELOAD="cs2.sh

MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_shim.so"

if [ "$1" = "--dlsym" ]; then
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}"
shift # shift will only be executed if $1 is "--dlsym"
elif [ "$MANGOHUD_DLSYM" = "1" ]; then
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}"
fi

if [ "$1" = "--version" ]; then
echo @version@
exit 0
Expand Down
2 changes: 0 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,10 @@ install() {

echo DEFAULTLIB: $DEFAULTLIB
/usr/bin/install -Dvm644 ./build/release/usr/lib/mangohud/lib64/libMangoHud.so /usr/lib/mangohud/lib64/libMangoHud.so
/usr/bin/install -Dvm644 ./build/release/usr/lib/mangohud/lib64/libMangoHud_dlsym.so /usr/lib/mangohud/lib64/libMangoHud_dlsym.so
/usr/bin/install -Dvm644 ./build/release/usr/lib/mangohud/lib64/libMangoHud_opengl.so /usr/lib/mangohud/lib64/libMangoHud_opengl.so
/usr/bin/install -Dvm644 ./build/release/usr/lib/mangohud/lib64/libMangoHud_shim.so /usr/lib/mangohud/lib64/libMangoHud_shim.so
if [ "$MACHINE" = "x86_64" ]; then
/usr/bin/install -Dvm644 ./build/release/usr/lib/mangohud/lib32/libMangoHud.so /usr/lib/mangohud/lib32/libMangoHud.so
/usr/bin/install -Dvm644 ./build/release/usr/lib/mangohud/lib32/libMangoHud_dlsym.so /usr/lib/mangohud/lib32/libMangoHud_dlsym.so
/usr/bin/install -Dvm644 ./build/release/usr/lib/mangohud/lib32/libMangoHud_opengl.so /usr/lib/mangohud/lib32/libMangoHud_opengl.so
/usr/bin/install -Dvm644 ./build/release/usr/lib/mangohud/lib32/libMangoHud_shim.so /usr/lib/mangohud/lib32/libMangoHud_shim.so
fi
Expand Down
2 changes: 1 addition & 1 deletion src/elfhacks.cpp → src/elfhacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ int eh_find_callback(struct dl_phdr_info *info, size_t size, void *argptr)

int eh_iterate_callback(struct dl_phdr_info *info, size_t size, void *argptr)
{
struct eh_iterate_callback_args *args = (eh_iterate_callback_args *)argptr;
struct eh_iterate_callback_args *args = argptr;
eh_obj_t obj;
int ret = 0;

Expand Down
3 changes: 2 additions & 1 deletion src/gl/gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ int glXQueryDrawable(void *dpy, void* glxdraw, int attr, unsigned int * value);
int64_t glXSwapBuffersMscOML(void* dpy, void* drawable, int64_t target_msc, int64_t divisor, int64_t remainder);

unsigned int eglSwapBuffers( void*, void* );
void* eglGetPlatformDisplay( unsigned int, void*, const intptr_t*);
void* eglGetPlatformDisplay( unsigned int, void*, const intptr_t* );
void* eglGetDisplay( void* );
void* eglGetProcAddress( const char* );

#ifdef __cplusplus
}
Expand Down
118 changes: 106 additions & 12 deletions src/gl/shim.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdint.h>
#include "gl.h"
#include "real_dlsym.h"
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
Expand All @@ -27,7 +28,7 @@ static void loadMangoHud() {

while (lib != NULL)
{
handle = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
handle = dlopen(lib, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);

if (handle)
{
Expand All @@ -42,19 +43,19 @@ static void loadMangoHud() {

if (!mangoHudLoaded)
{
handle = dlopen("${ORIGIN}/libMangoHud_opengl.so", RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
handle = dlopen("${ORIGIN}/libMangoHud_opengl.so", RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
if (handle) mangoHudLoaded = true;
}
}

void glXSwapBuffers(void* dpy, void* drawable) {
loadMangoHud();

void (*pglXSwapBuffers)(void*, void*) = dlsym(handle, "glXSwapBuffers");
void (*pglXSwapBuffers)(void*, void*) = real_dlsym(handle, "glXSwapBuffers");
if (pglXSwapBuffers) {
pglXSwapBuffers(dpy, drawable);
} else {
pglXSwapBuffers = dlsym(RTLD_NEXT, "glXSwapBuffers");
pglXSwapBuffers = real_dlsym(RTLD_NEXT, "glXSwapBuffers");
if (pglXSwapBuffers)
pglXSwapBuffers(dpy, drawable);
}
Expand All @@ -63,11 +64,11 @@ void glXSwapBuffers(void* dpy, void* drawable) {
void* eglGetDisplay(void *native_dpy) {
loadMangoHud();

void* (*peglGetDisplay)(void*) = dlsym(handle, "eglGetDisplay");
void* (*peglGetDisplay)(void*) = real_dlsym(handle, "eglGetDisplay");
if (peglGetDisplay) {
return peglGetDisplay(native_dpy);
} else {
peglGetDisplay = dlsym(RTLD_NEXT, "eglGetDisplay");
peglGetDisplay = real_dlsym(RTLD_NEXT, "eglGetDisplay");
if (peglGetDisplay)
return peglGetDisplay(native_dpy);
}
Expand All @@ -79,11 +80,11 @@ void* eglGetPlatformDisplay(unsigned int platform, void* native_display, const i
{
loadMangoHud();

void* (*peglGetPlatformDisplay)(unsigned int, void*, const intptr_t*) = dlsym(handle, "eglGetPlatformDisplay");
void* (*peglGetPlatformDisplay)(unsigned int, void*, const intptr_t*) = real_dlsym(handle, "eglGetPlatformDisplay");
if (peglGetPlatformDisplay) {
return peglGetPlatformDisplay(platform, native_display, attrib_list);
} else {
peglGetPlatformDisplay = dlsym(RTLD_NEXT, "eglGetPlatformDisplay");
peglGetPlatformDisplay = real_dlsym(RTLD_NEXT, "eglGetPlatformDisplay");
if (peglGetPlatformDisplay)
return peglGetPlatformDisplay(platform, native_display, attrib_list);
}
Expand All @@ -95,12 +96,12 @@ unsigned int eglSwapBuffers(void* dpy, void* surf) {
loadMangoHud();

// Get the hooked eglSwapBuffers function from the loaded library if available
unsigned int (*peglSwapBuffers)(void*, void*) = dlsym(handle, "eglSwapBuffers");
unsigned int (*peglSwapBuffers)(void*, void*) = real_dlsym(handle, "eglSwapBuffers");
if (peglSwapBuffers) {
return peglSwapBuffers(dpy, surf);
} else {
// Fall back to the original eglSwapBuffers function
peglSwapBuffers = dlsym(RTLD_NEXT, "eglSwapBuffers");
peglSwapBuffers = real_dlsym(RTLD_NEXT, "eglSwapBuffers");
if (peglSwapBuffers) {
return peglSwapBuffers(dpy, surf);
}
Expand All @@ -113,16 +114,109 @@ int64_t glXSwapBuffersMscOML(void* dpy, void* drawable, int64_t target_msc, int6
loadMangoHud();

// Get the hooked glXSwapBuffersMscOML function from the loaded library if available
int64_t (*pglXSwapBuffersMscOML)(void*, void*, int64_t, int64_t, int64_t) = dlsym(handle, "glXSwapBuffersMscOML");
int64_t (*pglXSwapBuffersMscOML)(void*, void*, int64_t, int64_t, int64_t) = real_dlsym(handle, "glXSwapBuffersMscOML");
if (pglXSwapBuffersMscOML) {
return pglXSwapBuffersMscOML(dpy, drawable, target_msc, divisor, remainder);
} else {
// Fall back to the original glXSwapBuffersMscOML function
pglXSwapBuffersMscOML = dlsym(RTLD_NEXT, "glXSwapBuffersMscOML");
pglXSwapBuffersMscOML = real_dlsym(RTLD_NEXT, "glXSwapBuffersMscOML");
if (pglXSwapBuffersMscOML) {
return pglXSwapBuffersMscOML(dpy, drawable, target_msc, divisor, remainder);
}
}

return -1;
}

void* glXGetProcAddress(const unsigned char* procName)
{
loadMangoHud();

void* (*pglXGetProcAddress)(const unsigned char*) = real_dlsym(handle, "glXGetProcAddress");
if (pglXGetProcAddress) {
return pglXGetProcAddress(procName);
} else {
pglXGetProcAddress = real_dlsym(RTLD_NEXT, "glXGetProcAddress");
if (pglXGetProcAddress) {
return pglXGetProcAddress(procName);
}
}

return NULL;
}

void* glXGetProcAddressARB(const unsigned char* procName)
{
loadMangoHud();

void* (*pglXGetProcAddressARB)(const unsigned char*) = real_dlsym(handle, "glXGetProcAddressARB");
if (pglXGetProcAddressARB) {
return pglXGetProcAddressARB(procName);
} else {
pglXGetProcAddressARB = real_dlsym(RTLD_NEXT, "glXGetProcAddressARB");
if (pglXGetProcAddressARB) {
return pglXGetProcAddressARB(procName);
}
}

return NULL;
}

void* eglGetProcAddress(const char *procName)
{
loadMangoHud();

void* (*peglGetProcAddress)(const char*) = real_dlsym(handle, "eglGetProcAddress");
if (peglGetProcAddress) {
return peglGetProcAddress(procName);
} else {
peglGetProcAddress = real_dlsym(RTLD_NEXT, "eglGetProcAddress");
if (peglGetProcAddress) {
return peglGetProcAddress(procName);
}
}

return NULL;
}

struct func_ptr {
const char* name;
void* ptr;
};

#define ADD_HOOK(fn) { #fn, (void*)fn }
static struct func_ptr hooks[] = {
ADD_HOOK(glXGetProcAddress),
ADD_HOOK(glXGetProcAddressARB),
ADD_HOOK(glXSwapBuffers),
ADD_HOOK(glXSwapBuffersMscOML),
ADD_HOOK(eglSwapBuffers),
ADD_HOOK(eglGetPlatformDisplay),
ADD_HOOK(eglGetDisplay),
ADD_HOOK(eglGetProcAddress)
};
#undef ADD_HOOK

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(arr[0])
#endif

void* dlsym(void *handle, const char *name)
{
const char* dlsym_enabled = getenv("MANGOHUD_DLSYM");
void* is_angle = real_dlsym(handle, "eglStreamPostD3DTextureANGLE");
void* fn_ptr = real_dlsym(handle, name);

if (!is_angle && fn_ptr && (!dlsym_enabled || dlsym_enabled[0] != '0'))
{
for (unsigned i = 0; i < ARRAY_SIZE(hooks); i++)
{
if (!strcmp(hooks[i].name, name))
{
return hooks[i].ptr;
}
}
}

return fn_ptr;
}
39 changes: 0 additions & 39 deletions src/hook_dlsym.cpp

This file was deleted.

31 changes: 5 additions & 26 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ if is_unixy
'memory.cpp',
'iostats.cpp',
'notify.cpp',
'elfhacks.cpp',
'real_dlsym.cpp',
'elfhacks.c',
'real_dlsym.c',
'pci_ids.cpp',
'battery.cpp',
'control.cpp',
Expand Down Expand Up @@ -250,30 +250,6 @@ mangohud_opengl_shared_lib = shared_library(
install: true
)

if is_unixy
mangohud_dlsym = shared_library(
'MangoHud_dlsym',
files(
'elfhacks.cpp',
'real_dlsym.cpp',
'hook_dlsym.cpp',
),
c_args : [
pre_args,
],
cpp_args : [
pre_args,
],
gnu_symbol_visibility : 'hidden',
dependencies : [dep_dl],
include_directories : [inc_common],
link_args : link_args,
link_with: mangohud_static_lib,
install_dir : libdir_mangohud,
install : true
)
endif

if get_option('mangoapp')
if not get_option('with_x11').enabled()
error('mangoapp also needs \'with_x11\'')
Expand Down Expand Up @@ -328,10 +304,13 @@ if is_unixy
'MangoHud_shim',
files(
'gl/shim.c',
'real_dlsym.c',
'elfhacks.c'
),
dependencies : [
dep_dl
],
include_directories : [inc_common],
install_dir : libdir_mangohud,
install: true
)
Expand Down
Loading

0 comments on commit dda4875

Please sign in to comment.