Workaround[lwjgl]: Implement mitigation for an early EMUI linker hang.

This commit is contained in:
artdeell 2024-01-22 22:35:59 +03:00 committed by Maksim Belov
parent 2f98f4c0da
commit 693f90b234
4 changed files with 59 additions and 0 deletions

View File

@ -87,6 +87,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@SuppressWarnings("IOStreamConstructor")
@ -1093,6 +1094,23 @@ public final class Tools {
return t.getMeasuredHeight();
}
/**
* Check if the device is one of the devices that may be affected by the hanging linker issue.
* The device is affected if the linker causes the process to lock up when dlopen() is called within
* dl_iterate_phdr().
* For now, the only affected firmware that I know of is Android 5.1, EMUI 3.1 on MTK-based Huawei
* devices.
* @return if the device is affected by the hanging linker issue.
*/
public static boolean deviceHasHangingLinker() {
// Android Oreo and onwards have GSIs and most phone firmwares at that point were not modified
// *that* intrusively. So assume that we are not affected.
if(SDK_INT >= Build.VERSION_CODES.O) return false;
// Since the affected function in LWJGL is rarely used (and when used, it's mainly for debug prints)
// we can make the search scope a bit more broad and check if we are running on a Huawei device.
return Build.MANUFACTURER.toLowerCase(Locale.ROOT).contains("huawei");
}
public static class RenderersList {
public final List<String> rendererIds;
public final String[] rendererDisplayNames;

View File

@ -196,6 +196,8 @@ public class JREUtils {
envMap.put("POJAV_ZINK_PREFER_SYSTEM_DRIVER", "1");
if(PREF_VSYNC_IN_ZINK)
envMap.put("POJAV_VSYNC_IN_ZINK", "1");
if(Tools.deviceHasHangingLinker())
envMap.put("POJAV_EMUI_ITERATOR_MITIGATE", "1");
// The OPEN GL version is changed according

View File

@ -61,6 +61,7 @@ jint JNI_OnLoad(JavaVM* vm, __attribute__((unused)) void* reserved) {
pojav_environ->mouseDownBuffer = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetDirectBufferAddress(pojav_environ->runtimeJNIEnvPtr_JRE, mouseDownBufferJ);
hookExec();
installLinkerBugMitigation();
installEMUIIteratorMititgation();
}
if(pojav_environ->dalvikJavaVMPtr == vm) {
@ -294,6 +295,43 @@ void installLinkerBugMitigation() {
}
}
/**
* This function is meant as a substitute for SharedLibraryUtil.getLibraryPath() that just returns 0
* (thus making the parent Java function return null). This is done to avoid using the LWJGL's default function,
* which will hang the crappy EMUI linker by dlopen()ing inside of dl_iterate_phdr().
* @return 0, to make the parent Java function return null immediately.
* For reference: https://github.com/PojavLauncherTeam/lwjgl3/blob/fix_huawei_hang/modules/lwjgl/core/src/main/java/org/lwjgl/system/SharedLibraryUtil.java
*/
jint getLibraryPath_fix(__attribute__((unused)) JNIEnv *env,
__attribute__((unused)) jclass class,
__attribute__((unused)) jlong pLibAddress,
__attribute__((unused)) jlong sOutAddress,
__attribute__((unused)) jint bufSize){
return 0;
}
/**
* Install the linker hang mitigation that is meant to prevent linker hangs on old EMUI firmware.
*/
void installEMUIIteratorMititgation() {
if(getenv("POJAV_EMUI_ITERATOR_MITIGATE") == NULL) return;
__android_log_print(ANDROID_LOG_INFO, "EMUIIteratorFix", "Installing...");
JNIEnv* env = pojav_environ->runtimeJNIEnvPtr_JRE;
jclass sharedLibraryUtil = (*env)->FindClass(env, "org/lwjgl/system/SharedLibraryUtil");
if(sharedLibraryUtil == NULL) {
__android_log_print(ANDROID_LOG_ERROR, "EMUIIteratorFix", "Failed to find the target class");
(*env)->ExceptionClear(env);
return;
}
JNINativeMethod getLibraryPathMethod[] = {
{"getLibraryPath", "(JJI)I", &getLibraryPath_fix}
};
if((*env)->RegisterNatives(env, sharedLibraryUtil, getLibraryPathMethod, 1) != 0) {
__android_log_print(ANDROID_LOG_ERROR, "EMUIIteratorFix", "Failed to register the mitigation method");
(*env)->ExceptionClear(env);
}
}
void critical_set_stackqueue(jboolean use_input_stack_queue) {
pojav_environ->isUseStackQueueCall = (int) use_input_stack_queue;
}

View File

@ -11,5 +11,6 @@ jstring convertStringJVM(JNIEnv* srcEnv, JNIEnv* dstEnv, jstring srcStr);
void hookExec();
void installLinkerBugMitigation();
void installEMUIIteratorMititgation();
JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNIEnv* env, jclass clazz, jint action, jbyteArray copySrc);