Try and give at least some minimal binding for all functions exported
by the real libpthread.so.  In the process fix a bunch of stuff, including
adding thread-specific h_errno and resolver state storage.  This fixes
licq crashing at startup.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@149 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/vg_libpthread.c b/vg_libpthread.c
index 12c1843..370acec 100644
--- a/vg_libpthread.c
+++ b/vg_libpthread.c
@@ -126,6 +126,16 @@
    }
 }
 
+void vgPlain_unimp ( char* what )
+{
+   char* ig = "vg_libpthread.so: UNIMPLEMENTED FUNCTION: ";
+   write(2, ig, strlen(ig));
+   write(2, what, strlen(what));
+   ig = "\n";
+   write(2, ig, strlen(ig));
+   barf("Please report this bug to me at: jseward@acm.org");
+}
+
 
 /* ---------------------------------------------------------------------
    Pass pthread_ calls to Valgrind's request mechanism.
@@ -236,19 +246,16 @@
 }
 
 
-static int thread_specific_errno[VG_N_THREADS];
-
-int* __errno_location ( void )
+pthread_t pthread_self(void)
 {
    int tid;
-   /* ensure_valgrind("__errno_location"); */
+   ensure_valgrind("pthread_self");
    VALGRIND_MAGIC_SEQUENCE(tid, 0 /* default */,
                            VG_USERREQ__PTHREAD_GET_THREADID,
                            0, 0, 0, 0);
-   /* 'cos I'm paranoid ... */
    if (tid < 0 || tid >= VG_N_THREADS)
-      barf("__errno_location: invalid ThreadId");
-   return & thread_specific_errno[tid];
+      barf("pthread_self: invalid ThreadId");
+   return tid;
 }
 
 
@@ -265,10 +272,10 @@
 int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
 {
    switch (type) {
-#ifndef GLIBC_2_1    
+#     ifndef GLIBC_2_1    
       case PTHREAD_MUTEX_TIMED_NP:
       case PTHREAD_MUTEX_ADAPTIVE_NP:
-#endif
+#     endif
       case PTHREAD_MUTEX_RECURSIVE_NP:
       case PTHREAD_MUTEX_ERRORCHECK_NP:
          attr->__mutexkind = type;
@@ -577,34 +584,52 @@
 
 
 /* ---------------------------------------------------
-   MISC
+   LIBRARY-PRIVATE THREAD SPECIFIC STATE
    ------------------------------------------------ */
 
-/* What are these?  Anybody know?  I don't. */
+#include <resolv.h>
+static int thread_specific_errno[VG_N_THREADS];
+static int thread_specific_h_errno[VG_N_THREADS];
+static struct __res_state
+           thread_specific_res_state[VG_N_THREADS];
 
-void _pthread_cleanup_push_defer ( void )
-{
-  //  char* str = "_pthread_cleanup_push_defer\n";
-  //  write(2, str, strlen(str));
-}
-
-void _pthread_cleanup_pop_restore ( void )
-{
-  //  char* str = "_pthread_cleanup_pop_restore\n";
-  //  write(2, str, strlen(str));
-}
-
-
-pthread_t pthread_self(void)
+int* __errno_location ( void )
 {
    int tid;
-   ensure_valgrind("pthread_self");
-   VALGRIND_MAGIC_SEQUENCE(tid, 0 /* default */,
+   /* ensure_valgrind("__errno_location"); */
+   VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */,
                            VG_USERREQ__PTHREAD_GET_THREADID,
                            0, 0, 0, 0);
+   /* 'cos I'm paranoid ... */
    if (tid < 0 || tid >= VG_N_THREADS)
-      barf("pthread_self: invalid ThreadId");
-   return tid;
+      barf("__errno_location: invalid ThreadId");
+   return & thread_specific_errno[tid];
+}
+
+int* __h_errno_location ( void )
+{
+   int tid;
+   /* ensure_valgrind("__h_errno_location"); */
+   VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */,
+                           VG_USERREQ__PTHREAD_GET_THREADID,
+                           0, 0, 0, 0);
+   /* 'cos I'm paranoid ... */
+   if (tid < 0 || tid >= VG_N_THREADS)
+      barf("__h_errno_location: invalid ThreadId");
+   return & thread_specific_h_errno[tid];
+}
+
+struct __res_state* __res_state ( void )
+{
+   int tid;
+   /* ensure_valgrind("__res_state"); */
+   VALGRIND_MAGIC_SEQUENCE(tid, 1 /* default */,
+                           VG_USERREQ__PTHREAD_GET_THREADID,
+                           0, 0, 0, 0);
+   /* 'cos I'm paranoid ... */
+   if (tid < 0 || tid >= VG_N_THREADS)
+      barf("__res_state: invalid ThreadId");
+   return & thread_specific_res_state[tid];
 }
 
 
@@ -802,26 +827,10 @@
 }
 
 
-/*--------------------------------------------------*/
-
-/* I've no idea what these are, but they get called quite a lot.
-   Anybody know? */
-
-#undef _IO_flockfile
-void _IO_flockfile ( _IO_FILE * file )
-{
-  //  char* str = "_IO_flockfile\n";
-  //  write(2, str, strlen(str));
-  //  barf("_IO_flockfile");
-}
-
-#undef _IO_funlockfile
-void _IO_funlockfile ( _IO_FILE * file )
-{
-  //  char* str = "_IO_funlockfile\n";
-  //  write(2, str, strlen(str));
-  //barf("_IO_funlockfile");
-}
+/* ---------------------------------------------------------------------
+   Nonblocking implementations of select() and poll().  This stuff will
+   surely rot your mind.
+   ------------------------------------------------------------------ */
 
 /*--------------------------------------------------*/
 
@@ -1123,3 +1132,66 @@
                            (int)(&nanosleep_interval), (int)NULL);
    }
 }
+
+
+/* ---------------------------------------------------------------------
+   B'stard.
+   ------------------------------------------------------------------ */
+
+# define strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+
+strong_alias(pthread_mutex_lock, __pthread_mutex_lock)
+strong_alias(pthread_mutex_unlock, __pthread_mutex_unlock)
+strong_alias(pthread_mutexattr_init, __pthread_mutexattr_init)
+strong_alias(pthread_mutexattr_settype, __pthread_mutexattr_settype)
+strong_alias(pthread_mutex_init, __pthread_mutex_init)
+strong_alias(pthread_mutexattr_destroy, __pthread_mutexattr_destroy)
+strong_alias(pthread_mutex_destroy, __pthread_mutex_destroy)
+strong_alias(pthread_once, __pthread_once)
+
+strong_alias(close, __close)
+strong_alias(write, __write)
+strong_alias(read, __read)
+strong_alias(open, __open)
+strong_alias(sigaction, __sigaction)
+
+strong_alias(pthread_key_create, __pthread_key_create)
+strong_alias(pthread_getspecific, __pthread_getspecific)
+strong_alias(pthread_setspecific, __pthread_setspecific)
+strong_alias(open64, __open64)
+strong_alias(fcntl, __fcntl)
+strong_alias(connect, __connect)
+
+/*--------------------------------------------------*/
+
+/* I've no idea what these are, but they get called quite a lot.
+   Anybody know? */
+
+#undef _IO_flockfile
+void _IO_flockfile ( _IO_FILE * file )
+{
+   //   char* str = "_IO_flockfile\n";
+   //   write(2, str, strlen(str));
+   //  barf("_IO_flockfile");
+}
+
+#undef _IO_funlockfile
+void _IO_funlockfile ( _IO_FILE * file )
+{
+   //   char* str = "_IO_funlockfile\n";
+   //   write(2, str, strlen(str));
+   //  barf("_IO_funlockfile");
+}
+
+void _pthread_cleanup_push_defer ( void )
+{
+   //    char* str = "_pthread_cleanup_push_defer\n";
+   //    write(2, str, strlen(str));
+}
+
+void _pthread_cleanup_pop_restore ( void )
+{
+   //    char* str = "_pthread_cleanup_pop_restore\n";
+   //    write(2, str, strlen(str));
+}