-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat[lwjgl]: add vulkan to lwjgl dlopen hook, move hook to new file
- Loading branch information
Showing
4 changed files
with
74 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// | ||
// Created by maks on 06.01.2025. | ||
// | ||
|
||
#include <android/api-level.h> | ||
#include <android/log.h> | ||
#include <jni.h> | ||
|
||
#include <environ/environ.h> | ||
|
||
#include <dlfcn.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
|
||
extern void* maybe_load_vulkan(); | ||
|
||
/** | ||
* Basically a verbatim implementation of ndlopen(), found at | ||
* https://github.com/PojavLauncherTeam/lwjgl3/blob/3.3.1/modules/lwjgl/core/src/generated/c/linux/org_lwjgl_system_linux_DynamicLinkLoader.c#L11 | ||
* but with our own additions for stuff like vulkanmod. | ||
*/ | ||
static jlong ndlopen_bugfix(__attribute__((unused)) JNIEnv *env, | ||
__attribute__((unused)) jclass class, | ||
jlong filename_ptr, | ||
jint jmode) { | ||
const char* filename = (const char*) filename_ptr; | ||
|
||
// Oveeride vulkan loading to let us load vulkan ourselves | ||
if(strstr(filename, "libvulkan.so") == filename) { | ||
printf("LWJGL linkerhook: replacing load for libvulkan.so with custom driver\n"); | ||
return (jlong) maybe_load_vulkan(); | ||
} | ||
|
||
// This hook also serves the task of mitigating a bug: the idea is that since, on Android 10 and | ||
// earlier, the linker doesn't really do namespace nesting. | ||
// It is not a problem as most of the libraries are in the launcher path, but when you try to run | ||
// VulkanMod which loads shaderc outside of the default jni libs directory through this method, | ||
// it can't load it because the path is not in the allowed paths for the anonymous namesapce. | ||
// This method fixes the issue by being in libpojavexec, and thus being in the classloader namespace | ||
|
||
int mode = (int)jmode; | ||
return (jlong) dlopen(filename, mode); | ||
} | ||
|
||
/** | ||
* Install the LWJGL dlopen hook. This allows us to mitigate linker bugs and add custom library overrides. | ||
*/ | ||
void installLinkerBugMitigation() { | ||
__android_log_print(ANDROID_LOG_INFO, "LwjglLinkerHook", "API < 30 detected, installing linker bug mitigation"); | ||
JNIEnv* env = pojav_environ->runtimeJNIEnvPtr_JRE; | ||
jclass dynamicLinkLoader = (*env)->FindClass(env, "org/lwjgl/system/linux/DynamicLinkLoader"); | ||
if(dynamicLinkLoader == NULL) { | ||
__android_log_print(ANDROID_LOG_ERROR, "LwjglLinkerHook", "Failed to find the target class"); | ||
(*env)->ExceptionClear(env); | ||
return; | ||
} | ||
JNINativeMethod ndlopenMethod[] = { | ||
{"ndlopen", "(JI)J", &ndlopen_bugfix} | ||
}; | ||
if((*env)->RegisterNatives(env, dynamicLinkLoader, ndlopenMethod, 1) != 0) { | ||
__android_log_print(ANDROID_LOG_ERROR, "LwjglLinkerHook", "Failed to register the hooked method"); | ||
(*env)->ExceptionClear(env); | ||
} | ||
} |