[PATCH] loader: Implement setting of %gs for wine64
mlankhorst
mlankhorst at dhcp-172-29-61-127.smo.corp.google.com
Tue Nov 25 01:50:37 CST 2008
---
loader/pthread.c | 29 +++++++++++++++++++++++++++--
1 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/loader/pthread.c b/loader/pthread.c
index 4951d97..3277846 100644
--- a/loader/pthread.c
+++ b/loader/pthread.c
@@ -48,10 +48,19 @@
static int init_done;
static int nb_threads = 1;
-#ifndef __i386__
+#if !defined(__i386__) && !defined(__x86_64__)
static pthread_key_t teb_key;
#endif
+#if defined(__x86_64__) && defined(__linux__)
+
+#include <asm/prctl.h>
+
+/* Helper function for arch_prctl */
+extern int arch_prctl(int func, void *ptr);
+
+#endif
+
/***********************************************************************
* init_process
*
@@ -125,7 +134,6 @@ static int create_thread( struct wine_pthread_thread_info *info )
return ret;
}
-
/***********************************************************************
* init_current_teb
*
@@ -135,12 +143,24 @@ static void init_current_teb( struct wine_pthread_thread_info *info )
{
#ifdef __i386__
/* On the i386, the current thread is in the %fs register */
+ /* On x86_64, it's in %gs (but the functions here are called the same) */
LDT_ENTRY fs_entry;
wine_ldt_set_base( &fs_entry, info->teb_base );
wine_ldt_set_limit( &fs_entry, info->teb_size - 1 );
wine_ldt_set_flags( &fs_entry, WINE_LDT_FLAGS_DATA|WINE_LDT_FLAGS_32BIT );
wine_ldt_init_fs( info->teb_sel, &fs_entry );
+#elif defined(__x86_64__) && defined(__linux__)
+ int ret;
+
+ /* Use the arch_prctl syscall to set the %gs selector to teb */
+ ret = arch_prctl(ARCH_SET_GS, info->teb_base);
+ if (ret < 0)
+ perror("Could not set %%gs:");
+#elif defined(__x86_64__)
+ /* All programs I've seen so far bomb out immediately if they can't
+ * manipulate %gs directly. Only winelib would work. */
+#error Please define setting %%gs for your architecture
#else
if (!init_done) /* first thread */
pthread_key_create( &teb_key, NULL );
@@ -174,6 +194,11 @@ static void *get_current_teb(void)
void *ret;
__asm__( ".byte 0x64\n\tmovl 0x18,%0" : "=r" (ret) );
return ret;
+#elif defined(__x86_64__)
+ void *ret;
+ /* Teb == ((TEB *)%gs)->Tib.Self (at offset 0x30) */
+ __asm__( ".byte 0x65\n\tmovq 0x30,%0" : "=r" (ret) );
+ return ret;
#else
return pthread_getspecific( teb_key );
#endif
--
1.5.6.5
--------------070607030701080400050602--
More information about the wine-patches
mailing list