Ken Thomases : ntdll: For Mac 64-bit, poke the TEB address to %gs: 0x30 and re-enable the inlining of NtCurrentTeb().

Alexandre Julliard julliard at winehq.org
Thu Jul 28 09:38:53 CDT 2016


Module: wine
Branch: master
Commit: 7501942008f91a9a137fe598ce5ce7cb47de5522
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7501942008f91a9a137fe598ce5ce7cb47de5522

Author: Ken Thomases <ken at codeweavers.com>
Date:   Wed Jul 27 10:42:29 2016 -0500

ntdll: For Mac 64-bit, poke the TEB address to %gs:0x30 and re-enable the inlining of NtCurrentTeb().

64-bit Windows apps have hard-coded accesses to %gs:0x30 baked into them.  They
need to find the TEB self pointer there.

Technically, the gsbase register and the memory it points to belong to the
pthread implementation on macOS.  It's used for the pthread TLS implementation.
However, study of the sources and experimentation reveal that TLS slot 6
(offset 0x30) is not currently used.  Furthermore, Apple has promised to not
use that slot in the future.  So, we hijack it for our purposes.

Signed-off-by: Ken Thomases <ken at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/ntdll.spec      |  2 +-
 dlls/ntdll/signal_x86_64.c | 34 +++-------------------------------
 include/winnt.h            |  2 +-
 3 files changed, 5 insertions(+), 33 deletions(-)

diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index f6e7edf..e0c0746 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -149,7 +149,7 @@
 @ stdcall NtCreateTimer(ptr long ptr long)
 @ stub NtCreateToken
 # @ stub NtCreateWaitablePort
-@ stdcall NtCurrentTeb()
+@ stdcall -arch=win32,arm64 NtCurrentTeb()
 # @ stub NtDebugActiveProcess
 # @ stub NtDebugContinue
 @ stdcall NtDelayExecution(long ptr)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 1db3a23..10faaea 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -241,8 +241,6 @@ static inline int arch_prctl( int func, void *ptr ) { return syscall( __NR_arch_
 
 #define FPU_sig(context)   ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.__fpregs))
 #elif defined (__APPLE__)
-static pthread_key_t teb_key;
-
 #define RAX_sig(context)     ((context)->uc_mcontext->__ss.__rax)
 #define RBX_sig(context)     ((context)->uc_mcontext->__ss.__rbx)
 #define RCX_sig(context)     ((context)->uc_mcontext->__ss.__rcx)
@@ -2834,13 +2832,6 @@ void signal_free_thread( TEB *teb )
     NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
 }
 
-#ifdef __APPLE__
-static void init_teb_key(void)
-{
-    pthread_key_create( &teb_key, NULL );
-}
-#endif
-
 /**********************************************************************
  *		signal_init_thread
  */
@@ -2849,10 +2840,6 @@ void signal_init_thread( TEB *teb )
     const WORD fpu_cw = 0x27f;
     stack_t ss;
 
-#ifdef __APPLE__
-    static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-#endif
-
 #if defined __linux__
     arch_prctl( ARCH_SET_GS, teb );
 #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
@@ -2860,9 +2847,9 @@ void signal_init_thread( TEB *teb )
 #elif defined(__NetBSD__)
     sysarch( X86_64_SET_GSBASE, &teb );
 #elif defined (__APPLE__)
-    /* FIXME: Actually setting %gs needs support from the OS */
-    pthread_once( &init_once, init_teb_key );
-    pthread_setspecific( teb_key, teb );
+    __asm__ volatile (".byte 0x65\n\tmovq %0,%c1"
+                      :
+                      : "r" (teb->Tib.Self), "n" (FIELD_OFFSET(TEB, Tib.Self)));
 #else
 # error Please define setting %gs for your architecture
 #endif
@@ -3847,19 +3834,4 @@ __ASM_STDCALL_FUNC( DbgBreakPoint, 0, "int $3; ret")
  */
 __ASM_STDCALL_FUNC( DbgUserBreakPoint, 0, "int $3; ret")
 
-/**********************************************************************
- *              NtCurrentTeb  (NTDLL.@)
- *
- * FIXME: This isn't exported from NTDLL on real NT.  This should be
- *        removed if and when we can set the GSBASE MSR on Mac OS X.
- */
-#ifdef __APPLE__
-TEB * WINAPI NtCurrentTeb(void)
-{
-    return pthread_getspecific( teb_key );
-}
-#else
-__ASM_STDCALL_FUNC( NtCurrentTeb, 0, ".byte 0x65\n\tmovq 0x30,%rax\n\tret" )
-#endif
-
 #endif  /* __x86_64__ */
diff --git a/include/winnt.h b/include/winnt.h
index 2705373..96722a4 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -2331,7 +2331,7 @@ static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void)
   __asm mov teb, eax;
   return teb;
 }
-#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__APPLE__)
+#elif defined(__x86_64__) && defined(__GNUC__)
 static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void)
 {
     struct _TEB *teb;




More information about the wine-cvs mailing list