|
|
|
/**
|
|
|
|
* \author Pyry Haulos <pyry.haulos@gmail.com>
|
|
|
|
* \date 2007-2008
|
|
|
|
* For conditions of distribution and use, see copyright notice in elfhacks.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <dlfcn.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "real_dlsym.h"
|
|
|
|
#include "elfhacks.h"
|
|
|
|
|
|
|
|
void *(*__dlopen)(const char *, int) = nullptr;
|
|
|
|
void *(*__dlsym)(void *, const char *) = nullptr;
|
|
|
|
static bool print_dlopen = getenv("MANGOHUD_DEBUG_DLOPEN") != nullptr;
|
|
|
|
static bool print_dlsym = getenv("MANGOHUD_DEBUG_DLSYM") != nullptr;
|
|
|
|
|
|
|
|
void get_real_functions()
|
|
|
|
{
|
|
|
|
eh_obj_t libdl;
|
|
|
|
|
|
|
|
if (eh_find_obj(&libdl, "*libdl.so*")) {
|
|
|
|
fprintf(stderr, "can't get libdl.so\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (eh_find_sym(&libdl, "dlopen", (void **) &__dlopen)) {
|
|
|
|
fprintf(stderr, "can't get dlopen()\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (eh_find_sym(&libdl, "dlsym", (void **) &__dlsym)) {
|
|
|
|
fprintf(stderr, "can't get dlsym()\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
eh_destroy_obj(&libdl);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief dlopen() wrapper, just passes calls to real dlopen()
|
|
|
|
* and writes information to standard output
|
|
|
|
*/
|
|
|
|
void *real_dlopen(const char *filename, int flag)
|
|
|
|
{
|
|
|
|
if (__dlopen == nullptr)
|
|
|
|
get_real_functions();
|
|
|
|
|
|
|
|
void *result = __dlopen(filename, flag);
|
|
|
|
|
|
|
|
if (print_dlopen) {
|
|
|
|
printf("dlopen(%s, ", filename);
|
|
|
|
const char *fmt = "%s";
|
|
|
|
#define FLAG(test) if (flag & test) { printf(fmt, #test); fmt = "|%s"; }
|
|
|
|
FLAG(RTLD_LAZY)
|
|
|
|
FLAG(RTLD_NOW)
|
|
|
|
FLAG(RTLD_GLOBAL)
|
|
|
|
FLAG(RTLD_LOCAL)
|
|
|
|
FLAG(RTLD_NODELETE)
|
|
|
|
FLAG(RTLD_NOLOAD)
|
|
|
|
#ifdef RTLD_DEEPBIND
|
|
|
|
FLAG(RTLD_DEEPBIND)
|
|
|
|
#endif
|
|
|
|
#undef FLAG
|
|
|
|
printf(") = %p\n", result);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief dlsym() wrapper, passes calls to real dlsym() and
|
|
|
|
* writes information to standard output
|
|
|
|
*/
|
|
|
|
void *real_dlsym(void *handle, const char *symbol)
|
|
|
|
{
|
|
|
|
if (__dlsym == nullptr)
|
|
|
|
get_real_functions();
|
|
|
|
|
|
|
|
void *result = __dlsym(handle, symbol);
|
|
|
|
|
|
|
|
if (print_dlsym)
|
|
|
|
printf("dlsym(%p, %s) = %p\n", handle, symbol, result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* get_proc_address(const char* name) {
|
|
|
|
void (*func)() = (void (*)())real_dlsym(RTLD_NEXT, name);
|
|
|
|
return (void*)func;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HOOK_DLSYM
|
|
|
|
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 = mangohud_find_glx_ptr(name);
|
|
|
|
if (func) {
|
|
|
|
//fprintf(stderr,"%s: local: %s\n", __func__ , name);
|
|
|
|
return func;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
func = mangohud_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);
|
|
|
|
}
|
|
|
|
#endif
|