Ken Thomases : kernel32: For Mac 64-bit, re-enable the inlining of various functions, leveraging the TEB self pointer at %gs:0x30.

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


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

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

kernel32: For Mac 64-bit, re-enable the inlining of various functions, leveraging the TEB self pointer at %gs:0x30.

On other platforms, gsbase is set to point to Wine's TEB.  So, these functions
can use %gs-relative addressing with the field offsets to access the fields of
the TEB.

On the Mac, gsbase points to internals of the pthread implementation and that
wouldn't work.  However, Wine hijacks %gs:0x30 and stores the TEB address there.
So, we access the TEB fields by first loading the TEB address and then
accessing its fields relative to that.

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

---

 dlls/kernel32/thread.c | 38 +++++++++++++++++++++++++++++++++++++-
 include/winbase.h      | 32 +++++++++++++++++++++++++++++++-
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index 6630e7f..82ccebe 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -682,7 +682,41 @@ __ASM_STDCALL_FUNC( GetCurrentThreadId, 0, ".byte 0x64\n\tmovl 0x24,%eax\n\tret"
 /* HANDLE WINAPI GetProcessHeap(void) */
 __ASM_STDCALL_FUNC( GetProcessHeap, 0, ".byte 0x64\n\tmovl 0x30,%eax\n\tmovl 0x18(%eax),%eax\n\tret");
 
-#elif defined(__x86_64__) && !defined(__APPLE__)
+#elif defined(__x86_64__)
+
+#ifdef __APPLE__
+
+/***********************************************************************
+ *		SetLastError (KERNEL32.@)
+ */
+/* void WINAPI SetLastError( DWORD error ); */
+__ASM_STDCALL_FUNC( SetLastError, 8, ".byte 0x65\n\tmovq 0x30,%rax\n\tmovl %ecx,0x68(%rax)\n\tret" );
+
+/***********************************************************************
+ *		GetLastError (KERNEL32.@)
+ */
+/* DWORD WINAPI GetLastError(void); */
+__ASM_STDCALL_FUNC( GetLastError, 0, ".byte 0x65\n\tmovq 0x30,%rax\n\tmovl 0x68(%rax),%eax\n\tret" );
+
+/***********************************************************************
+ *		GetCurrentProcessId (KERNEL32.@)
+ */
+/* DWORD WINAPI GetCurrentProcessId(void) */
+__ASM_STDCALL_FUNC( GetCurrentProcessId, 0, ".byte 0x65\n\tmovq 0x30,%rax\n\tmovl 0x40(%rax),%eax\n\tret" );
+
+/***********************************************************************
+ *		GetCurrentThreadId (KERNEL32.@)
+ */
+/* DWORD WINAPI GetCurrentThreadId(void) */
+__ASM_STDCALL_FUNC( GetCurrentThreadId, 0, ".byte 0x65\n\tmovq 0x30,%rax\n\tmovl 0x48(%rax),%eax\n\tret" );
+
+/***********************************************************************
+ *		GetProcessHeap (KERNEL32.@)
+ */
+/* HANDLE WINAPI GetProcessHeap(void) */
+__ASM_STDCALL_FUNC( GetProcessHeap, 0, ".byte 0x65\n\tmovq 0x30,%rax\n\tmovq 0x60(%rax),%rax\n\tmovq 0x30(%rax),%rax\n\tret");
+
+#else
 
 /***********************************************************************
  *		SetLastError (KERNEL32.@)
@@ -714,6 +748,8 @@ __ASM_STDCALL_FUNC( GetCurrentThreadId, 0, ".byte 0x65\n\tmovl 0x48,%eax\n\tret"
 /* HANDLE WINAPI GetProcessHeap(void) */
 __ASM_STDCALL_FUNC( GetProcessHeap, 0, ".byte 0x65\n\tmovq 0x60,%rax\n\tmovq 0x30(%rax),%rax\n\tret");
 
+#endif /* __APPLE__ */
+
 #else  /* __x86_64__ */
 
 /**********************************************************************
diff --git a/include/winbase.h b/include/winbase.h
index 5d8b1ff..220a057 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2904,13 +2904,19 @@ static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest )
 
 /* A few optimizations for gcc */
 
-#if defined(__GNUC__) && !defined(__MINGW32__) && (defined(__i386__) || (defined(__x86_64__) && !defined(__APPLE__))) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
+#if defined(__GNUC__) && !defined(__MINGW32__) && (defined(__i386__) || defined(__x86_64__)) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
 
 static FORCEINLINE DWORD WINAPI GetLastError(void)
 {
     DWORD ret;
 #ifdef __x86_64__
+#ifdef __APPLE__
+    DWORD* teb;
+    __asm__ __volatile__( ".byte 0x65\n\tmovq 0x30,%0" : "=r" (teb) );
+    ret = teb[0x68 / sizeof(DWORD)];
+#else
     __asm__ __volatile__( ".byte 0x65\n\tmovl 0x68,%0" : "=r" (ret) );
+#endif
 #else
     __asm__ __volatile__( ".byte 0x64\n\tmovl 0x34,%0" : "=r" (ret) );
 #endif
@@ -2921,7 +2927,13 @@ static FORCEINLINE DWORD WINAPI GetCurrentProcessId(void)
 {
     DWORD ret;
 #ifdef __x86_64__
+#ifdef __APPLE__
+    DWORD* teb;
+    __asm__ __volatile__( ".byte 0x65\n\tmovq 0x30,%0" : "=r" (teb) );
+    ret = teb[0x40 / sizeof(DWORD)];
+#else
     __asm__ __volatile__( ".byte 0x65\n\tmovl 0x40,%0" : "=r" (ret) );
+#endif
 #else
     __asm__ __volatile__( ".byte 0x64\n\tmovl 0x20,%0" : "=r" (ret) );
 #endif
@@ -2932,7 +2944,13 @@ static FORCEINLINE DWORD WINAPI GetCurrentThreadId(void)
 {
     DWORD ret;
 #ifdef __x86_64__
+#ifdef __APPLE__
+    DWORD* teb;
+    __asm__ __volatile__( ".byte 0x65\n\tmovq 0x30,%0" : "=r" (teb) );
+    ret = teb[0x48 / sizeof(DWORD)];
+#else
     __asm__ __volatile__( ".byte 0x65\n\tmovl 0x48,%0" : "=r" (ret) );
+#endif
 #else
     __asm__ __volatile__( ".byte 0x64\n\tmovl 0x24,%0" : "=r" (ret) );
 #endif
@@ -2942,7 +2960,13 @@ static FORCEINLINE DWORD WINAPI GetCurrentThreadId(void)
 static FORCEINLINE void WINAPI SetLastError( DWORD err )
 {
 #ifdef __x86_64__
+#ifdef __APPLE__
+    DWORD* teb;
+    __asm__ __volatile__( ".byte 0x65\n\tmovq 0x30,%0" : "=r" (teb) );
+    teb[0x68 / sizeof(DWORD)] = err;
+#else
     __asm__ __volatile__( ".byte 0x65\n\tmovl %0,0x68" : : "r" (err) : "memory" );
+#endif
 #else
     __asm__ __volatile__( ".byte 0x64\n\tmovl %0,0x34" : : "r" (err) : "memory" );
 #endif
@@ -2952,7 +2976,13 @@ static FORCEINLINE HANDLE WINAPI GetProcessHeap(void)
 {
     HANDLE *pdb;
 #ifdef __x86_64__
+#ifdef __APPLE__
+    HANDLE** teb;
+    __asm__ __volatile__( ".byte 0x65\n\tmovq 0x30,%0" : "=r" (teb) );
+    pdb = teb[0x60 / sizeof(HANDLE*)];
+#else
     __asm__ __volatile__( ".byte 0x65\n\tmovq 0x60,%0" : "=r" (pdb) );
+#endif
     return pdb[0x30 / sizeof(HANDLE)];  /* get dword at offset 0x30 in pdb */
 #else
     __asm__ __volatile__( ".byte 0x64\n\tmovl 0x30,%0" : "=r" (pdb) );




More information about the wine-cvs mailing list