Alexandre Julliard : wineandroid: Wrap Java calls to preserve %gs on x86_64.
Alexandre Julliard
julliard at winehq.org
Mon Nov 26 16:20:11 CST 2018
Module: wine
Branch: master
Commit: 2b8d787b176d2f977c88925542fd5bbdb20261d2
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2b8d787b176d2f977c88925542fd5bbdb20261d2
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Nov 26 14:42:18 2018 +0100
wineandroid: Wrap Java calls to preserve %gs on x86_64.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/wineandroid.drv/device.c | 40 ++++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c
index c0ff072..c9a9a95 100644
--- a/dlls/wineandroid.drv/device.c
+++ b/dlls/wineandroid.drv/device.c
@@ -240,13 +240,39 @@ static inline BOOL is_client_in_process(void)
return current_client_id() == GetCurrentProcessId();
}
-#ifdef __i386__ /* the Java VM uses %fs for its own purposes, so we need to wrap the calls */
+#ifdef __i386__ /* the Java VM uses %fs/%gs for its own purposes, so we need to wrap the calls */
+
static WORD orig_fs, java_fs;
static inline void wrap_java_call(void) { wine_set_fs( java_fs ); }
static inline void unwrap_java_call(void) { wine_set_fs( orig_fs ); }
+static inline void init_java_thread( JavaVM *java_vm )
+{
+ orig_fs = wine_get_fs();
+ (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 );
+ java_fs = wine_get_fs();
+ wine_set_fs( orig_fs );
+}
+
+#elif defined(__x86_64__)
+
+#include <asm/prctl.h>
+#include <asm/unistd.h>
+static void *orig_teb, *java_teb;
+static inline int arch_prctl( int func, void *ptr ) { return syscall( __NR_arch_prctl, func, ptr ); }
+static inline void wrap_java_call(void) { arch_prctl( ARCH_SET_GS, java_teb ); }
+static inline void unwrap_java_call(void) { arch_prctl( ARCH_SET_GS, orig_teb ); }
+static inline void init_java_thread( JavaVM *java_vm )
+{
+ arch_prctl( ARCH_GET_GS, &orig_teb );
+ (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 );
+ arch_prctl( ARCH_GET_GS, &java_teb );
+ arch_prctl( ARCH_SET_GS, orig_teb );
+}
+
#else
static inline void wrap_java_call(void) { }
static inline void unwrap_java_call(void) { }
+static inline void init_java_thread( JavaVM *java_vm ) { (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); }
#endif /* __i386__ */
static struct native_win_data *data_map[65536];
@@ -1092,15 +1118,7 @@ static DWORD CALLBACK device_thread( void *arg )
if (!(java_vm = wine_get_java_vm())) return 0; /* not running under Java */
-#ifdef __i386__
- orig_fs = wine_get_fs();
- (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 );
- java_fs = wine_get_fs();
- wine_set_fs( orig_fs );
- if (java_fs != orig_fs) TRACE( "%%fs changed from %04x to %04x by Java VM\n", orig_fs, java_fs );
-#else
- (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 );
-#endif
+ init_java_thread( java_vm );
create_desktop_window( GetDesktopWindow() );
@@ -1116,7 +1134,9 @@ static DWORD CALLBACK device_thread( void *arg )
ret = wine_ntoskrnl_main_loop( stop_event );
+ wrap_java_call();
(*java_vm)->DetachCurrentThread( java_vm );
+ unwrap_java_call();
return ret;
}
More information about the wine-cvs
mailing list