Dennis Bijwaard wrote:
> 
> Wine does not seem to work when libsafe is installed:
>    http://www.bell-labs.com/org/11356/libsafe.html
> wine does works when I remove /lib/libsafe.so.1 from /etc/ld.so.preload
> libsafe does not show in the logs that there was an illegal access or
> overflow.
> 
> wine just crashes with the following output:
> 
>    bijwaard@jumbo:~$ wine winfile
>    fixme:pthread_atfork
>    Segmentation fault
> 
the attached patch at least let wine start up with libsafe
since it's an ugly patch, it will not be applied to CVS (if someone feels
like having a clean implementation...)
(don't forget to comment out the definition of USE_LIBSAFE in scheduler/pthread.c)

anyway, since libsafe makes extensive use of stack, and since wine often
switches its stack (from 32 to 16 bit code, some X11 function calls, at startup),
I doubt libsafe will be very usefull (AFAICS, libsafe's not even thread safe, 
because of global var stack_stack which cannot hold a different value for each 
32 bit thread - as wine implements)

as a conclusion, specific work must be done in order to have libsafe correctly
handle wine.

A+

-- 
---------------
Eric Pouech (http://perso.wanadoo.fr/eric.pouech/)
"The future will be better tomorrow", Vice President Dan Quayle
Index: scheduler/pthread.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/scheduler/pthread.c,v
retrieving revision 1.6
diff -u -r1.6 pthread.c
--- scheduler/pthread.c 2000/04/29 16:44:20     1.6
+++ scheduler/pthread.c 2000/05/01 08:53:43
@@ -265,9 +265,38 @@
 }
 strong_alias(__pthread_key_delete, pthread_key_delete);
 
+/* to be commented out to turn on LibSafe support in Wine */
+/* #define USE_LIBSAFE */
+
+#ifdef USE_LIBSAFE
+static struct {
+       int pid; 
+       pthread_key_t key; 
+       const void *pointer;
+} cached_initial_pthread;
+#endif
+
 int __pthread_setspecific(pthread_key_t key, const void *pointer)
 {
-  TEB *teb = NtCurrentTeb();
+  TEB *teb;
+
+#ifdef USE_LIBSAFE
+  WORD _fs;
+  __asm__( "mov %%fs,%0" : "=r" (_fs));
+  if (!_fs) {
+         if (cached_initial_pthread.pid) {
+                 *(volatile int*)0 = 0;
+                 return -1;
+         }
+
+         cached_initial_pthread.pid = getpid();
+         cached_initial_pthread.key = key;
+         cached_initial_pthread.pointer = pointer;
+         return 0;
+  }
+#endif
+
+  teb = NtCurrentTeb();
   if (!teb->pthread_data) {
     teb->pthread_data = calloc(MAX_KEYS,sizeof(key_data));
   }
@@ -278,9 +307,30 @@
 
 void *__pthread_getspecific(pthread_key_t key)
 {
-  TEB *teb = NtCurrentTeb();
+  TEB* teb;
+#ifdef USE_LIBSAFE
+  WORD _fs;
+  __asm__( "mov %%fs,%0" : "=r" (_fs));
+  if (!_fs) {
+         if (cached_initial_pthread.pid && 
+                       cached_initial_pthread.pid == getpid() && 
+                       cached_initial_pthread.key == key) {
+                 return cached_initial_pthread.pointer;
+         }
+         return NULL;
+  }
+#endif
+  teb = NtCurrentTeb();
   if (!teb) return NULL;
   if (!teb->pthread_data) return NULL;
+#ifdef USE_LIBSAFE
+  if (cached_initial_pthread.pid && 
+               cached_initial_pthread.pid == getpid() && 
+               cached_initial_pthread.key == key) {
+         __pthread_setspecific(key, cached_initial_pthread.pointer);
+         cached_initial_pthread.pid = 0;
+  }
+#endif
   return (void *)(((key_data*)(teb->pthread_data))[key]);
 }
 strong_alias(__pthread_getspecific, pthread_getspecific);

Reply via email to