mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-22 07:21:34 +00:00
Compile in interceptor-lib if LLVM is found, and use to hook on android
* Note we still have to use PLT hooking for android_dlopen_ext that libvulkan uses to load layers, since interceptor-lib can't hook that, and otherwise libvulkan will load our library multiple times into the process instead of re-using the existing injected library.
This commit is contained in:
@@ -355,6 +355,25 @@ if(ENABLE_GL OR ENABLE_GLES OR ENABLE_VULKAN)
|
||||
list(APPEND renderdoc_objects $<TARGET_OBJECTS:rdoc_spirv>)
|
||||
endif()
|
||||
|
||||
find_package(LLVM CONFIG)
|
||||
|
||||
# on Android, pull in interceptor-lib only if we have LLVM available
|
||||
if(ANDROID AND LLVM_FOUND)
|
||||
message(STATUS "LLVM found - android hooking using interceptor-lib.")
|
||||
add_subdirectory(3rdparty/interceptor-lib)
|
||||
list(APPEND renderdoc_objects $<TARGET_OBJECTS:interceptor_lib>)
|
||||
link_directories(${LLVM_DIR}/../..)
|
||||
set(RDOC_DEFINITIONS ${RDOC_DEFINITIONS} PRIVATE -DRENDERDOC_HAVE_INTERCEPTOR_LIB)
|
||||
|
||||
foreach(lib ${interceptor_libs})
|
||||
list(APPEND RDOC_LIBRARIES PRIVATE -l${lib})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(ANDROID AND NOT LLVM_FOUND)
|
||||
message(STATUS "LLVM not found - android hooking will use sometimes less reliable PLT-interception method.")
|
||||
endif()
|
||||
|
||||
# always pull in the amd folder
|
||||
add_subdirectory(driver/ihv/amd)
|
||||
list(APPEND renderdoc_objects $<TARGET_OBJECTS:rdoc_amd>)
|
||||
|
||||
@@ -55,35 +55,7 @@ public:
|
||||
}
|
||||
static void libHooked(void *realLib);
|
||||
|
||||
bool CreateHooks(const char *libName)
|
||||
{
|
||||
if(!m_EnabledHooks)
|
||||
return false;
|
||||
|
||||
if(libName)
|
||||
{
|
||||
// register our hooked functions for PLT hooking on android
|
||||
PosixHookFunctions();
|
||||
|
||||
// load the libEGL.so library and when loaded call libHooked which initialises GLES capture
|
||||
PosixHookLibrary("libEGL.so", &libHooked);
|
||||
PosixHookLibrary("libEGL.so.1", NULL);
|
||||
PosixHookLibrary("libGL.so.1", NULL);
|
||||
PosixHookLibrary("libGLESv1_CM.so", NULL);
|
||||
PosixHookLibrary("libGLESv2.so", NULL);
|
||||
PosixHookLibrary("libGLESv2.so.2", NULL);
|
||||
PosixHookLibrary("libGLESv3.so", NULL);
|
||||
}
|
||||
|
||||
bool success = SetupHooks();
|
||||
|
||||
if(!success)
|
||||
return false;
|
||||
|
||||
m_HasHooks = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CreateHooks(const char *libName);
|
||||
|
||||
void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; }
|
||||
void OptionsUpdated(const char *libName) {}
|
||||
@@ -432,13 +404,45 @@ void EGLHook::libHooked(void *realLib)
|
||||
libGLdlsymHandle = realLib;
|
||||
eglhooks.CreateHooks(NULL);
|
||||
eglhooks.GetDriver()->SetDriverType(RDCDriver::OpenGLES);
|
||||
}
|
||||
|
||||
PosixHookFunction("eglCreateContext", (void *)&eglCreateContext);
|
||||
PosixHookFunction("eglGetDisplay", (void *)&eglGetDisplay);
|
||||
PosixHookFunction("eglDestroyContext", (void *)&eglDestroyContext);
|
||||
PosixHookFunction("eglMakeCurrent", (void *)&eglMakeCurrent);
|
||||
PosixHookFunction("eglSwapBuffers", (void *)&eglSwapBuffers);
|
||||
PosixHookFunction("eglGetProcAddress", (void *)&eglGetProcAddress);
|
||||
bool EGLHook::CreateHooks(const char *libName)
|
||||
{
|
||||
if(!m_EnabledHooks)
|
||||
return false;
|
||||
|
||||
if(libName)
|
||||
{
|
||||
// register our hooked functions for PLT hooking on android
|
||||
PosixHookFunctions();
|
||||
|
||||
PosixHookFunction("eglCreateContext", (void *)&eglCreateContext);
|
||||
PosixHookFunction("eglGetDisplay", (void *)&eglGetDisplay);
|
||||
PosixHookFunction("eglDestroyContext", (void *)&eglDestroyContext);
|
||||
PosixHookFunction("eglMakeCurrent", (void *)&eglMakeCurrent);
|
||||
PosixHookFunction("eglSwapBuffers", (void *)&eglSwapBuffers);
|
||||
PosixHookFunction("eglGetProcAddress", (void *)&eglGetProcAddress);
|
||||
|
||||
// load the libEGL.so library and when loaded call libHooked which initialises GLES capture
|
||||
PosixHookLibrary("libEGL.so", &libHooked);
|
||||
PosixHookLibrary("libEGL.so.1", NULL);
|
||||
PosixHookLibrary("libGL.so.1", NULL);
|
||||
PosixHookLibrary("libGLESv1_CM.so", NULL);
|
||||
PosixHookLibrary("libGLESv2.so", NULL);
|
||||
PosixHookLibrary("libGLESv2.so.2", NULL);
|
||||
PosixHookLibrary("libGLESv3.so", NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success = SetupHooks();
|
||||
|
||||
if(!success)
|
||||
return false;
|
||||
|
||||
m_HasHooks = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EGLHook::PopulateHooks()
|
||||
@@ -446,7 +450,14 @@ bool EGLHook::PopulateHooks()
|
||||
SetupHooks();
|
||||
|
||||
// dlsym can return GL symbols during a GLES context
|
||||
return SharedPopulateHooks(false, [](const char *funcName) {
|
||||
bool dlsymFirst = false;
|
||||
|
||||
// however on android we want to use it to look up our trampoline map
|
||||
#if ENABLED(RDOC_ANDROID)
|
||||
dlsymFirst = true;
|
||||
#endif
|
||||
|
||||
return SharedPopulateHooks(dlsymFirst, [](const char *funcName) {
|
||||
// on some android devices we need to hook dlsym, but eglGetProcAddress might call dlsym so we
|
||||
// need to ensure we return the 'real' pointers
|
||||
PosixScopedSuppressHooking suppress;
|
||||
|
||||
@@ -110,7 +110,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
echo ") \\";
|
||||
|
||||
echo -e " { \\";
|
||||
echo -e " SCOPED_LOCK(glLock); \\";
|
||||
echo -e " SCOPED_GLCALL(glLock, function); \\";
|
||||
echo -e " gl_CurChunk = GLChunk::function; \\";
|
||||
if [ $ALIAS -eq 1 ]; then
|
||||
echo -n " return m_GLDriver->realfunc(";
|
||||
@@ -127,7 +127,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
echo ") \\";
|
||||
|
||||
echo -e " { \\";
|
||||
echo -e " SCOPED_LOCK(glLock); \\";
|
||||
echo -e " SCOPED_GLCALL(glLock, function); \\";
|
||||
echo -e " gl_CurChunk = GLChunk::function; \\";
|
||||
if [ $ALIAS -eq 1 ]; then
|
||||
echo -n " return m_GLDriver->realfunc(";
|
||||
@@ -153,6 +153,41 @@ Threading::CriticalSection &GetGLLock()
|
||||
#undef far
|
||||
#endif
|
||||
|
||||
#if ENABLED(RDOC_DEVEL)
|
||||
|
||||
struct ScopedPrinter
|
||||
{
|
||||
ScopedPrinter(const char *f) : func(f)
|
||||
{
|
||||
// RDCLOG("Entering %s", func);
|
||||
depth++;
|
||||
if(depth > 100)
|
||||
RDCFATAL("Infinite recursion detected!");
|
||||
}
|
||||
~ScopedPrinter()
|
||||
{
|
||||
// RDCLOG("Exiting %s", func);
|
||||
depth--;
|
||||
}
|
||||
const char *func = NULL;
|
||||
static int depth;
|
||||
};
|
||||
|
||||
int ScopedPrinter::depth = 0;
|
||||
|
||||
// This checks that we're not infinite looping by calling our own hooks from ourselves. Mostly
|
||||
// useful on android where you can only debug by printf and the stack dumps are often corrupted when
|
||||
// the callstack overflows.
|
||||
#define SCOPED_GLCALL(lock, funcname) \
|
||||
SCOPED_LOCK(lock); \
|
||||
ScopedPrinter CONCAT(scopedprint, __LINE__)(STRINGIZE(funcname));
|
||||
|
||||
#else
|
||||
|
||||
#define SCOPED_GLCALL(lock, funcname) SCOPED_LOCK(lock);
|
||||
|
||||
#endif
|
||||
|
||||
// the _renderdoc_hooked variants are to make sure we always have a function symbol
|
||||
// exported that we can return from glXGetProcAddress. If another library (or the app)
|
||||
// creates a symbol called 'glEnable' we'll return the address of that, and break
|
||||
@@ -163,13 +198,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function() \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)() \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(); \
|
||||
}
|
||||
@@ -178,13 +213,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1); \
|
||||
}
|
||||
@@ -193,13 +228,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1, t2); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2); \
|
||||
}
|
||||
@@ -208,13 +243,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3); \
|
||||
}
|
||||
@@ -223,13 +258,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4); \
|
||||
}
|
||||
@@ -238,13 +273,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5); \
|
||||
}
|
||||
@@ -254,13 +289,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \
|
||||
t5 p5, t6 p6) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6); \
|
||||
}
|
||||
@@ -270,13 +305,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \
|
||||
t5 p5, t6 p6, t7 p7) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7); \
|
||||
}
|
||||
@@ -286,13 +321,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \
|
||||
t5 p5, t6 p6, t7 p7, t8 p8) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8); \
|
||||
}
|
||||
@@ -303,14 +338,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function( \
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); \
|
||||
}
|
||||
@@ -321,14 +356,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function( \
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
|
||||
}
|
||||
@@ -339,14 +374,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function( \
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10, t11 p11) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
|
||||
}
|
||||
@@ -357,14 +392,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function( \
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10, t11 p11, t12 p12) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
|
||||
}
|
||||
@@ -377,14 +412,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
|
||||
}
|
||||
@@ -397,14 +432,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13, t14 p14) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
|
||||
}
|
||||
@@ -417,7 +452,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13, t14 p14, t15 p15) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \
|
||||
} \
|
||||
@@ -425,7 +460,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, \
|
||||
t15 p15) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \
|
||||
}
|
||||
@@ -439,7 +474,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13, t14 p14, t15 p15, t16 p16) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, \
|
||||
p16); \
|
||||
@@ -448,7 +483,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, \
|
||||
t15 p15, t16 p16) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, \
|
||||
p16); \
|
||||
@@ -463,7 +498,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13, t14 p14, t15 p15, t16 p16, t17 p17) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, \
|
||||
p16, p17); \
|
||||
@@ -472,7 +507,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, \
|
||||
t15 p15, t16 p16, t17 p17) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, \
|
||||
p16, p17); \
|
||||
@@ -482,13 +517,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function() \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)() \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(); \
|
||||
}
|
||||
@@ -497,13 +532,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1); \
|
||||
}
|
||||
@@ -512,13 +547,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1, t2); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2); \
|
||||
}
|
||||
@@ -527,13 +562,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3); \
|
||||
}
|
||||
@@ -542,13 +577,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4); \
|
||||
}
|
||||
@@ -557,13 +592,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5); \
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5); \
|
||||
}
|
||||
@@ -573,13 +608,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \
|
||||
t5 p5, t6 p6) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6); \
|
||||
}
|
||||
@@ -590,13 +625,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \
|
||||
t5 p5, t6 p6, t7 p7) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7); \
|
||||
}
|
||||
@@ -607,13 +642,13 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \
|
||||
t5 p5, t6 p6, t7 p7, t8 p8) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8); \
|
||||
}
|
||||
@@ -624,14 +659,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function( \
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9); \
|
||||
}
|
||||
@@ -642,14 +677,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function( \
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
|
||||
}
|
||||
@@ -660,14 +695,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function( \
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10, t11 p11) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
|
||||
}
|
||||
@@ -678,14 +713,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
extern "C" __attribute__((visibility("default"))) ret function( \
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10, t11 p11, t12 p12) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
|
||||
}
|
||||
@@ -698,14 +733,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
|
||||
}
|
||||
@@ -719,14 +754,14 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13, t14 p14) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
|
||||
} \
|
||||
ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
|
||||
}
|
||||
@@ -740,7 +775,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13, t14 p14, t15 p15) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \
|
||||
} \
|
||||
@@ -748,7 +783,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, \
|
||||
t15 p15) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \
|
||||
}
|
||||
@@ -762,7 +797,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13, t14 p14, t15 p15, t16 p16) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, \
|
||||
p16); \
|
||||
@@ -771,7 +806,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, \
|
||||
t15 p15, t16 p16) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, \
|
||||
p16); \
|
||||
@@ -786,7 +821,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \
|
||||
t13 p13, t14 p14, t15 p15, t16 p16, t17 p17) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, \
|
||||
p16, p17); \
|
||||
@@ -795,7 +830,7 @@ Threading::CriticalSection &GetGLLock()
|
||||
t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, \
|
||||
t15 p15, t16 p16, t17 p17) \
|
||||
{ \
|
||||
SCOPED_LOCK(glLock); \
|
||||
SCOPED_GLCALL(glLock, function); \
|
||||
gl_CurChunk = GLChunk::function; \
|
||||
return m_GLDriver->realfunc(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, \
|
||||
p16, p17); \
|
||||
@@ -1178,20 +1213,41 @@ void *SharedLookupFuncPtr(const char *func, void *realFunc)
|
||||
bool SharedPopulateHooks(bool dlsymFirst, void *(*lookupFunc)(const char *))
|
||||
{
|
||||
#undef HookInit
|
||||
#define HookInit(function) \
|
||||
if(GL.function == NULL) \
|
||||
{ \
|
||||
PosixScopedSuppressHooking suppress; \
|
||||
if(dlsymFirst) \
|
||||
GL.function = (CONCAT(function, _hooktype))dlsym(libGLdlsymHandle, STRINGIZE(function)); \
|
||||
lookupFunc((const char *)STRINGIZE(function)); \
|
||||
#define HookInit(function) \
|
||||
if(GL.function == NULL) \
|
||||
{ \
|
||||
PosixScopedSuppressHooking suppress; \
|
||||
if(dlsymFirst && GL.function == NULL) \
|
||||
{ \
|
||||
GL.function = \
|
||||
(CONCAT(function, _hooktype))PosixGetFunction(libGLdlsymHandle, STRINGIZE(function)); \
|
||||
} \
|
||||
lookupFunc((const char *)STRINGIZE(function)); \
|
||||
}
|
||||
|
||||
// cheeky
|
||||
#undef HookExtension
|
||||
#define HookExtension(funcPtrType, function) lookupFunc((const char *)STRINGIZE(function))
|
||||
#define HookExtension(funcPtrType, function) \
|
||||
if(GL.function == NULL) \
|
||||
{ \
|
||||
PosixScopedSuppressHooking suppress; \
|
||||
if(dlsymFirst && GL.function == NULL) \
|
||||
{ \
|
||||
GL.function = (funcPtrType)PosixGetFunction(libGLdlsymHandle, STRINGIZE(function)); \
|
||||
} \
|
||||
lookupFunc((const char *)STRINGIZE(function)); \
|
||||
}
|
||||
#undef HookExtensionAlias
|
||||
#define HookExtensionAlias(funcPtrType, function, alias) lookupFunc((const char *)STRINGIZE(alias))
|
||||
#define HookExtensionAlias(funcPtrType, function, alias) \
|
||||
if(GL.function == NULL) \
|
||||
{ \
|
||||
PosixScopedSuppressHooking suppress; \
|
||||
if(dlsymFirst && GL.function == NULL) \
|
||||
{ \
|
||||
GL.function = (funcPtrType)PosixGetFunction(libGLdlsymHandle, STRINGIZE(alias)); \
|
||||
} \
|
||||
lookupFunc((const char *)STRINGIZE(alias)); \
|
||||
}
|
||||
|
||||
DLLExportHooks();
|
||||
HookCheckGLExtensions();
|
||||
|
||||
@@ -60,23 +60,9 @@ public:
|
||||
m_EnabledHooks = true;
|
||||
}
|
||||
~VRAPIHook() {}
|
||||
bool CreateHooks(const char *libName)
|
||||
{
|
||||
if(!m_EnabledHooks)
|
||||
return false;
|
||||
static void libHooked(void *realLib);
|
||||
|
||||
if(libName)
|
||||
PosixHookLibrary(libName, &libHooked);
|
||||
|
||||
bool success = SetupHooks();
|
||||
|
||||
if(!success)
|
||||
return false;
|
||||
|
||||
m_HasHooks = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CreateHooks(const char *libName);
|
||||
|
||||
void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; }
|
||||
void OptionsUpdated(const char *libName) {}
|
||||
@@ -86,7 +72,6 @@ public:
|
||||
SetupHooks();
|
||||
}
|
||||
|
||||
static void libHooked(void *realLib) { libvrapi_symHandle = realLib; }
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
PFN_vrapi_CreateTextureSwapChain2 vrapi_CreateTextureSwapChain2_real;
|
||||
PFN_vrapi_CreateTextureSwapChain vrapi_CreateTextureSwapChain_real;
|
||||
@@ -103,24 +88,24 @@ public:
|
||||
bool SetupHooks()
|
||||
{
|
||||
if(vrapi_CreateTextureSwapChain2_real == NULL)
|
||||
vrapi_CreateTextureSwapChain2_real = (PFN_vrapi_CreateTextureSwapChain2)dlsym(
|
||||
vrapi_CreateTextureSwapChain2_real = (PFN_vrapi_CreateTextureSwapChain2)PosixGetFunction(
|
||||
libvrapi_symHandle, "vrapi_CreateTextureSwapChain2");
|
||||
if(vrapi_CreateTextureSwapChain_real == NULL)
|
||||
vrapi_CreateTextureSwapChain_real = (PFN_vrapi_CreateTextureSwapChain)dlsym(
|
||||
vrapi_CreateTextureSwapChain_real = (PFN_vrapi_CreateTextureSwapChain)PosixGetFunction(
|
||||
libvrapi_symHandle, "vrapi_CreateTextureSwapChain");
|
||||
if(vrapi_SubmitFrame_real == NULL)
|
||||
vrapi_SubmitFrame_real =
|
||||
(PFN_vrapi_SubmitFrame)dlsym(libvrapi_symHandle, "vrapi_SubmitFrame");
|
||||
(PFN_vrapi_SubmitFrame)PosixGetFunction(libvrapi_symHandle, "vrapi_SubmitFrame");
|
||||
|
||||
if(vrapi_GetTextureSwapChainLength_real == NULL)
|
||||
vrapi_GetTextureSwapChainLength_real = (PFN_vrapi_GetTextureSwapChainLength)dlsym(
|
||||
vrapi_GetTextureSwapChainLength_real = (PFN_vrapi_GetTextureSwapChainLength)PosixGetFunction(
|
||||
libvrapi_symHandle, "vrapi_GetTextureSwapChainLength");
|
||||
if(vrapi_GetTextureSwapChainHandle_real == NULL)
|
||||
vrapi_GetTextureSwapChainHandle_real = (PFN_vrapi_GetTextureSwapChainHandle)dlsym(
|
||||
vrapi_GetTextureSwapChainHandle_real = (PFN_vrapi_GetTextureSwapChainHandle)PosixGetFunction(
|
||||
libvrapi_symHandle, "vrapi_GetTextureSwapChainHandle");
|
||||
if(vrapi_GetSystemPropertyInt_real == NULL)
|
||||
vrapi_GetSystemPropertyInt_real =
|
||||
(PFN_vrapi_GetSystemPropertyInt)dlsym(libvrapi_symHandle, "vrapi_GetSystemPropertyInt");
|
||||
vrapi_GetSystemPropertyInt_real = (PFN_vrapi_GetSystemPropertyInt)PosixGetFunction(
|
||||
libvrapi_symHandle, "vrapi_GetSystemPropertyInt");
|
||||
|
||||
return vrapi_SubmitFrame_real != NULL;
|
||||
}
|
||||
@@ -264,4 +249,35 @@ __attribute__((visibility("default"))) void vrapi_SubmitFrame(ovrMobile *ovr,
|
||||
|
||||
vrapi_hooks.vrapi_SubmitFrame_real(ovr, parms);
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
void VRAPIHook::libHooked(void *realLib)
|
||||
{
|
||||
libvrapi_symHandle = realLib;
|
||||
vrapi_hooks.CreateHooks(NULL);
|
||||
}
|
||||
|
||||
bool VRAPIHook::CreateHooks(const char *libName)
|
||||
{
|
||||
if(!m_EnabledHooks)
|
||||
return false;
|
||||
|
||||
if(libName)
|
||||
{
|
||||
PosixHookFunction("vrapi_CreateTextureSwapChain2", (void *)&vrapi_CreateTextureSwapChain2);
|
||||
PosixHookFunction("vrapi_CreateTextureSwapChain", (void *)&vrapi_CreateTextureSwapChain);
|
||||
PosixHookFunction("vrapi_SubmitFrame", (void *)&vrapi_SubmitFrame);
|
||||
|
||||
PosixHookLibrary(libName, &libHooked);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success = SetupHooks();
|
||||
|
||||
if(!success)
|
||||
return false;
|
||||
|
||||
m_HasHooks = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "gl_library_egl.h"
|
||||
#include <dlfcn.h>
|
||||
#include "os/posix/posix_hook.h"
|
||||
|
||||
bool EGLPointers::LoadSymbolsFrom(void *lib_handle)
|
||||
{
|
||||
@@ -33,16 +34,18 @@ bool EGLPointers::LoadSymbolsFrom(void *lib_handle)
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
RDCDEBUG("Initialising EGL function pointers");
|
||||
|
||||
bool symbols_ok = true;
|
||||
#define LOAD_SYM(SYMBOL_NAME) \
|
||||
do \
|
||||
{ \
|
||||
this->SYMBOL_NAME = (PFN_egl##SYMBOL_NAME)dlsym(lib_handle, "egl" #SYMBOL_NAME); \
|
||||
if(this->SYMBOL_NAME == NULL) \
|
||||
{ \
|
||||
symbols_ok = false; \
|
||||
RDCWARN("Unable to load symbol: %s", #SYMBOL_NAME); \
|
||||
} \
|
||||
#define LOAD_SYM(SYMBOL_NAME) \
|
||||
do \
|
||||
{ \
|
||||
this->SYMBOL_NAME = (PFN_egl##SYMBOL_NAME)PosixGetFunction(lib_handle, "egl" #SYMBOL_NAME); \
|
||||
if(this->SYMBOL_NAME == NULL) \
|
||||
{ \
|
||||
symbols_ok = false; \
|
||||
RDCWARN("Unable to load symbol: %s", #SYMBOL_NAME); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
EGL_SYMBOLS(LOAD_SYM)
|
||||
|
||||
@@ -96,6 +96,37 @@ public:
|
||||
libhooks.insert(name);
|
||||
}
|
||||
|
||||
void AddHookCallback(const std::string &name, dlopenCallback hook)
|
||||
{
|
||||
SCOPED_LOCK(lock);
|
||||
hookcallbacks[name] = hook;
|
||||
}
|
||||
|
||||
std::map<std::string, void *> GetFunctionHooks()
|
||||
{
|
||||
SCOPED_LOCK(lock);
|
||||
return funchooks;
|
||||
}
|
||||
|
||||
void ClearHooks()
|
||||
{
|
||||
SCOPED_LOCK(lock);
|
||||
libhooks.clear();
|
||||
funchooks.clear();
|
||||
}
|
||||
|
||||
std::set<std::string> GetLibHooks()
|
||||
{
|
||||
SCOPED_LOCK(lock);
|
||||
return libhooks;
|
||||
}
|
||||
|
||||
std::map<std::string, dlopenCallback> GetHookCallbacks()
|
||||
{
|
||||
SCOPED_LOCK(lock);
|
||||
return hookcallbacks;
|
||||
}
|
||||
|
||||
void *GetFunctionHook(const std::string &name)
|
||||
{
|
||||
SCOPED_LOCK(lock);
|
||||
@@ -165,6 +196,18 @@ public:
|
||||
hooked_soname_already.insert(soname);
|
||||
}
|
||||
|
||||
void SetTrampoline(const std::string &funcname, void *trampoline)
|
||||
{
|
||||
SCOPED_LOCK(lock);
|
||||
trampolines[funcname] = trampoline;
|
||||
}
|
||||
|
||||
void *GetTrampoline(const std::string &funcname)
|
||||
{
|
||||
SCOPED_LOCK(lock);
|
||||
return trampolines[funcname];
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::string> hooked_soname_already;
|
||||
std::set<void *> hooked_handle_already;
|
||||
@@ -172,6 +215,9 @@ private:
|
||||
std::map<std::string, void *> funchooks;
|
||||
std::set<std::string> libhooks;
|
||||
|
||||
std::map<std::string, dlopenCallback> hookcallbacks;
|
||||
std::map<std::string, void *> trampolines;
|
||||
|
||||
Threading::CriticalSection lock;
|
||||
};
|
||||
|
||||
@@ -191,9 +237,36 @@ void PosixHookLibrary(const char *name, dlopenCallback cb)
|
||||
GetHookInfo().AddLibHook(name);
|
||||
|
||||
if(cb)
|
||||
cb(dlopen(name, RTLD_NOW));
|
||||
{
|
||||
GetHookInfo().AddHookCallback(name, cb);
|
||||
dlopen(name, RTLD_NOW);
|
||||
}
|
||||
}
|
||||
|
||||
void *PosixGetFunction(void *handle, const char *name)
|
||||
{
|
||||
// when we're not using interceptor-lib, this will always return NULL
|
||||
void *ret = GetHookInfo().GetTrampoline(name);
|
||||
if(ret)
|
||||
{
|
||||
HOOK_DEBUG_PRINT("Returning trampoline %p for %s", ret, name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HOOK_DEBUG_PRINT("No trampoline for %s, going to dlsym", name);
|
||||
PosixScopedSuppressHooking suppress;
|
||||
return dlsym(handle, name);
|
||||
}
|
||||
|
||||
void *intercept_dlopen(const char *filename, int flag)
|
||||
{
|
||||
if(GetHookInfo().IsLibHook(filename))
|
||||
return dlopen(RENDERDOC_ANDROID_LIBRARY, flag);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// we need this on both paths since interceptor-lib is unable to hook dlopen in libvulkan.so
|
||||
static int dl_iterate_callback(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
if(info->dlpi_name == NULL)
|
||||
@@ -377,60 +450,21 @@ static int dl_iterate_callback(struct dl_phdr_info *info, size_t size, void *dat
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" __attribute__((visibility("default"))) void *hooked_dlopen(const char *filename, int flag);
|
||||
extern "C" __attribute__((visibility("default"))) void *hooked_dlsym(void *handle,
|
||||
const char *symbol);
|
||||
extern "C" __attribute__((visibility("default"))) void *hooked_android_dlopen_ext(
|
||||
const char *__filename, int __flags, const android_dlextinfo *__info);
|
||||
|
||||
// android has a special dlopen that passes the caller address in.
|
||||
typedef void *(*pfn__loader_dlopen)(const char *filename, int flags, const void *caller_addr);
|
||||
|
||||
pfn__loader_dlopen loader_dlopen = NULL;
|
||||
uint64_t suppressTLS = 0;
|
||||
|
||||
void PosixHookApply()
|
||||
{
|
||||
RDCLOG("Applying hooks");
|
||||
|
||||
suppressTLS = Threading::AllocateTLSSlot();
|
||||
|
||||
// blacklist hooking certain system libraries or ourselves
|
||||
GetHookInfo().SetHooked(RENDERDOC_ANDROID_LIBRARY);
|
||||
GetHookInfo().SetHooked("libc.so");
|
||||
GetHookInfo().SetHooked("libvndksupport.so");
|
||||
|
||||
GetHookInfo().AddLibHook(RENDERDOC_ANDROID_LIBRARY);
|
||||
|
||||
loader_dlopen = (pfn__loader_dlopen)dlsym(RTLD_NEXT, "__loader_dlopen");
|
||||
|
||||
if(loader_dlopen)
|
||||
{
|
||||
PosixHookFunction("dlopen", (void *)&hooked_dlopen);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("Couldn't find __loader_dlopen, falling back to slow path for dlopen hooking");
|
||||
PosixHookFunction("dlsym", (void *)&hooked_dlsym);
|
||||
}
|
||||
|
||||
PosixHookFunction("android_dlopen_ext", (void *)&hooked_android_dlopen_ext);
|
||||
|
||||
dl_iterate_phdr(dl_iterate_callback, NULL);
|
||||
}
|
||||
|
||||
void PosixHookReapply()
|
||||
{
|
||||
dl_iterate_phdr(dl_iterate_callback, NULL);
|
||||
}
|
||||
|
||||
void *intercept_dlopen(const char *filename, int flag)
|
||||
{
|
||||
if(GetHookInfo().IsLibHook(filename))
|
||||
return dlopen(RENDERDOC_ANDROID_LIBRARY, flag);
|
||||
// android has a special dlopen that passes the caller address in.
|
||||
typedef void *(*pfn__loader_dlopen)(const char *filename, int flags, const void *caller_addr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
typedef void *(*pfnandroid_dlopen_ext)(const char *__filename, int __flags,
|
||||
const android_dlextinfo *__info);
|
||||
|
||||
pfnandroid_dlopen_ext real_android_dlopen_ext = NULL;
|
||||
|
||||
pfn__loader_dlopen loader_dlopen = NULL;
|
||||
uint64_t suppressTLS = 0;
|
||||
|
||||
void process_dlopen(const char *filename, int flag)
|
||||
{
|
||||
@@ -478,7 +512,11 @@ extern "C" __attribute__((visibility("default"))) void *hooked_android_dlopen_ex
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
ret = android_dlopen_ext(__filename, __flags, __info);
|
||||
// otherwise return the 'real' result.
|
||||
if(real_android_dlopen_ext == NULL)
|
||||
ret = real_android_dlopen_ext(__filename, __flags, __info);
|
||||
else
|
||||
ret = android_dlopen_ext(__filename, __flags, __info);
|
||||
HOOK_DEBUG_PRINT("Got %p", ret);
|
||||
|
||||
if(__filename && ret)
|
||||
@@ -539,4 +577,154 @@ extern "C" __attribute__((visibility("default"))) void *hooked_dlsym(void *handl
|
||||
dladdr(ret, &info);
|
||||
HOOK_DEBUG_PRINT("real ret is %p in %s", ret, info.dli_fname);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static void PosixHookApplyCommon()
|
||||
{
|
||||
suppressTLS = Threading::AllocateTLSSlot();
|
||||
|
||||
// blacklist hooking certain system libraries or ourselves
|
||||
GetHookInfo().SetHooked(RENDERDOC_ANDROID_LIBRARY);
|
||||
GetHookInfo().SetHooked("libc.so");
|
||||
GetHookInfo().SetHooked("libvndksupport.so");
|
||||
|
||||
GetHookInfo().AddLibHook(RENDERDOC_ANDROID_LIBRARY);
|
||||
|
||||
real_android_dlopen_ext = &android_dlopen_ext;
|
||||
|
||||
loader_dlopen = (pfn__loader_dlopen)dlsym(RTLD_NEXT, "__loader_dlopen");
|
||||
|
||||
if(loader_dlopen)
|
||||
{
|
||||
PosixHookFunction("dlopen", (void *)&hooked_dlopen);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("Couldn't find __loader_dlopen, falling back to slow path for dlopen hooking");
|
||||
PosixHookFunction("dlsym", (void *)&hooked_dlsym);
|
||||
}
|
||||
|
||||
PosixHookFunction("android_dlopen_ext", (void *)&hooked_android_dlopen_ext);
|
||||
}
|
||||
|
||||
#if defined(RENDERDOC_HAVE_INTERCEPTOR_LIB)
|
||||
|
||||
void intercept_error(void *, const char *error_msg)
|
||||
{
|
||||
RDCERR("intercept_error: %s", error_msg);
|
||||
}
|
||||
|
||||
#include "3rdparty/interceptor-lib/include/interceptor.h"
|
||||
|
||||
void PosixHookApply()
|
||||
{
|
||||
RDCLOG("Applying hooks with interceptor-lib");
|
||||
|
||||
// see below - Huawei workaround
|
||||
#if defined(__LP64__)
|
||||
PosixHookLibrary("/system/lib64/libhwgl.so", NULL);
|
||||
#else
|
||||
PosixHookLibrary("/system/lib/libhwgl.so", NULL);
|
||||
#endif
|
||||
|
||||
std::set<std::string> libs = GetHookInfo().GetLibHooks();
|
||||
std::map<std::string, void *> funchooks = GetHookInfo().GetFunctionHooks();
|
||||
|
||||
// we just leak this
|
||||
void *intercept = InitializeInterceptor();
|
||||
|
||||
for(const std::string &lib : libs)
|
||||
{
|
||||
void *handle = dlopen(lib.c_str(), RTLD_NOW);
|
||||
|
||||
bool huawei = lib.find("libhwgl.so") != std::string::npos;
|
||||
|
||||
if(!handle)
|
||||
{
|
||||
HOOK_DEBUG_PRINT("Didn't get handle for %s", lib.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
HOOK_DEBUG_PRINT("Hooking %s = %p", lib.c_str(), handle);
|
||||
|
||||
for(const std::pair<std::string, void *> &hook : funchooks)
|
||||
{
|
||||
void *oldfunc = dlsym(handle, hook.first.c_str());
|
||||
|
||||
// UNTESTED workaround taken directly from GAPID, in installer.cpp. Quoted comment:
|
||||
/*
|
||||
// Huawei implements all functions in this library with prefix,
|
||||
// all GL functions in libGLES*.so are just trampolines to his.
|
||||
// However, we do not support trampoline interception for now,
|
||||
// so try to intercept the internal implementation instead.
|
||||
*/
|
||||
if(huawei && oldfunc == NULL)
|
||||
oldfunc = dlsym(handle, ("hw_" + hook.first).c_str());
|
||||
|
||||
if(GetHookInfo().IsHooked(oldfunc))
|
||||
continue;
|
||||
|
||||
if(!oldfunc)
|
||||
{
|
||||
HOOK_DEBUG_PRINT("%s didn't have %s", lib.c_str(), hook.first.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
HOOK_DEBUG_PRINT("Hooking %s::%s = %p with %p", lib.c_str(), hook.first.c_str(), oldfunc,
|
||||
hook.second);
|
||||
|
||||
void *trampoline = NULL;
|
||||
|
||||
bool success =
|
||||
InterceptFunction(intercept, oldfunc, hook.second, &trampoline, &intercept_error);
|
||||
|
||||
if(success)
|
||||
HOOK_DEBUG_PRINT("Hooked successfully, trampoline is %p", trampoline);
|
||||
else
|
||||
HOOK_DEBUG_PRINT("Failed to hook!");
|
||||
|
||||
GetHookInfo().SetHooked(oldfunc);
|
||||
|
||||
GetHookInfo().SetTrampoline(hook.first, trampoline);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, dlopenCallback> callbacks = GetHookInfo().GetHookCallbacks();
|
||||
for(const std::pair<std::string, dlopenCallback> &cb : callbacks)
|
||||
{
|
||||
HOOK_DEBUG_PRINT("Calling complete callback for %s", cb.first.c_str());
|
||||
cb.second(dlopen(cb.first.c_str(), RTLD_GLOBAL));
|
||||
}
|
||||
|
||||
// we still need to hook android_dlopen_ext with interceptor-lib so that we can intercept the
|
||||
// vulkan loader's attempts to load our library and prevent it from loading a second copy (!!)
|
||||
// into the process.
|
||||
// Unfortunately, interceptor-lib can't hook this function so we need to set up the PLT hooking.
|
||||
// This is just a minimal setup to intercept that one function.
|
||||
GetHookInfo().ClearHooks();
|
||||
|
||||
// this already hooks dlopen (if possible) and android_dlopen_ext, which is enough
|
||||
PosixHookApplyCommon();
|
||||
|
||||
PosixHookReapply();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void PosixHookApply()
|
||||
{
|
||||
RDCLOG("Applying hooks with PLT hooks");
|
||||
|
||||
PosixHookApplyCommon();
|
||||
|
||||
PosixHookReapply();
|
||||
|
||||
std::map<std::string, dlopenCallback> callbacks = GetHookInfo().GetHookCallbacks();
|
||||
for(const std::pair<std::string, dlopenCallback> &cb : callbacks)
|
||||
{
|
||||
HOOK_DEBUG_PRINT("Calling complete callback for %s", cb.first.c_str());
|
||||
cb.second(dlopen(cb.first.c_str(), RTLD_GLOBAL));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -60,3 +60,8 @@ void PosixHookReapply()
|
||||
void PosixHookFunction(char const *, void *)
|
||||
{
|
||||
}
|
||||
|
||||
void *PosixGetFunction(void *handle, const char *name)
|
||||
{
|
||||
return dlsym(handle, name);
|
||||
}
|
||||
@@ -140,3 +140,8 @@ void PosixHookReapply()
|
||||
void PosixHookFunction(char const *, void *)
|
||||
{
|
||||
}
|
||||
|
||||
void *PosixGetFunction(void *handle, const char *name)
|
||||
{
|
||||
return dlsym(handle, name);
|
||||
}
|
||||
@@ -34,6 +34,8 @@ void PosixHookLibrary(const char *name, dlopenCallback cb);
|
||||
|
||||
void PosixHookFunction(const char *name, void *hook);
|
||||
|
||||
void *PosixGetFunction(void *handle, const char *name);
|
||||
|
||||
void PosixHookApply();
|
||||
|
||||
// this is needed on android, when we are PLT hooking to ensure hooks are applied as soon as
|
||||
|
||||
Reference in New Issue
Block a user