Mega-merge of my last 2 weeks hacking.  This basically does the groundwork
for pthread_* support.  Major changes:

* Valgrind now contains a (skeletal!) user-space pthreads
  implementation.  The exciting bits are in new file vg_scheduler.c.
  This contains thread management and scheduling, including nasty crud
  to do with making some syscalls (read,write,nanosleep) nonblocking.
  Also implementation of pthread_ functions: create join
  mutex_{create,destroy,lock,unlock} and cancel.

* As a side effect of the above, major improvements to signal handling
  and to the client-request machinery.  This is now used to intercept
  malloc/free etc too; the hacky way this is done before is gone.
  Another side effect is that vg_dispatch.S is greatly simplified.
  Also, the horrible hacks to do with delivering signals to threads
  blocked in syscalls are gone, since the new mechanisms cover this case
  easily.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@52 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/valgrind.h b/valgrind.h
index 5a32ab5..4271cd8 100644
--- a/valgrind.h
+++ b/valgrind.h
@@ -48,19 +48,55 @@
 
 /* This defines the magic code sequence which the JITter spots and
    handles magically.  Don't look too closely at this; it will rot
-   your brain.  
+   your brain.  Valgrind dumps the result value in %EDX, so we first
+   copy the default value there, so that it is returned when not
+   running on Valgrind.  Since %EAX points to a block of mem
+   containing the args, you can pass as many args as you want like
+   this.  Currently this is set up to deal with 4 args since that's
+   the max that we appear to need (pthread_create).  
 */
-#define VALGRIND_MAGIC_SEQUENCE(_zzq_res,_zzq_code,_zzq_addr,_zzq_len)  \
-  asm volatile("movl %1, %%eax\n\t"                                     \
-               "movl %2, %%ebx\n\t"                                     \
-               "movl %3, %%ecx\n\t"                                     \
-               "roll $29, %%eax ; roll $3, %%eax\n\t"                   \
-               "roll $27, %%eax ; roll $5, %%eax\n\t"                   \
-               "movl %%eax, %0\t"                                       \
-               : "=r" (_zzq_res)                                        \
-               : "r" (_zzq_code), "r" (_zzq_addr), "r" (_zzq_len)       \
-               : "eax", "ebx", "ecx", "cc", "memory"                    \
-              );
+#define VALGRIND_MAGIC_SEQUENCE(                                        \
+        _zzq_rlval,   /* result lvalue */                               \
+        _zzq_default, /* result returned when running on real CPU */    \
+        _zzq_request, /* request code */                                \
+        _zzq_arg1,    /* request first param */                         \
+        _zzq_arg2,    /* request second param */                        \
+        _zzq_arg3,    /* request third param */                         \
+        _zzq_arg4     /* request fourth param */ )                      \
+                                                                        \
+  { volatile unsigned int _zzq_args[5];                                 \
+    _zzq_args[0] = (volatile unsigned int)_zzq_request;                 \
+    _zzq_args[1] = (volatile unsigned int)_zzq_arg1;                    \
+    _zzq_args[2] = (volatile unsigned int)_zzq_arg2;                    \
+    _zzq_args[3] = (volatile unsigned int)_zzq_arg3;                    \
+    _zzq_args[4] = (volatile unsigned int)_zzq_arg4;                    \
+    asm volatile("movl %1, %%eax\n\t"                                   \
+                 "movl %2, %%edx\n\t"                                   \
+                 "roll $29, %%eax ; roll $3, %%eax\n\t"                 \
+                 "rorl $27, %%eax ; rorl $5, %%eax\n\t"                 \
+                 "roll $13, %%eax ; roll $19, %%eax\n\t"                \
+                 "movl %%edx, %0\t"                                     \
+                 : "=r" (_zzq_rlval)                                    \
+                 : "r" (&_zzq_args[0]), "r" (_zzq_default)              \
+                 : "eax", "edx", "cc", "memory"                         \
+                );                                                      \
+  }
+
+
+/* Some request codes.  There are many more of these, but most are not
+   exposed to end-user view.  These are the public ones, all of the
+   form 0x1000 + small_number. 
+*/
+
+#define VG_USERREQ__MAKE_NOACCESS        0x1001
+#define VG_USERREQ__MAKE_WRITABLE        0x1002
+#define VG_USERREQ__MAKE_READABLE        0x1003
+#define VG_USERREQ__DISCARD              0x1004
+#define VG_USERREQ__CHECK_WRITABLE       0x1005
+#define VG_USERREQ__CHECK_READABLE       0x1006
+#define VG_USERREQ__MAKE_NOACCESS_STACK  0x1007
+#define VG_USERREQ__RUNNING_ON_VALGRIND  0x1008
+#define VG_USERREQ__DO_LEAK_CHECK        0x1009 /* unimplemented */
 
 
 
@@ -71,7 +107,9 @@
    descriptions Valgrind will use in subsequent error messages. */
 #define VALGRIND_MAKE_NOACCESS(_qzz_addr,_qzz_len)               \
    ({unsigned int _qzz_res;                                      \
-    VALGRIND_MAGIC_SEQUENCE(_qzz_res,1001,_qzz_addr,_qzz_len);   \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* default return */,    \
+                            VG_USERREQ__MAKE_NOACCESS,           \
+                            _qzz_addr, _qzz_len, 0, 0);          \
     _qzz_res;                                                    \
    })
 
@@ -79,7 +117,9 @@
    for _qzz_len bytes. */
 #define VALGRIND_MAKE_WRITABLE(_qzz_addr,_qzz_len)               \
    ({unsigned int _qzz_res;                                      \
-    VALGRIND_MAGIC_SEQUENCE(_qzz_res,1002,_qzz_addr,_qzz_len);   \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* default return */,    \
+                            VG_USERREQ__MAKE_WRITABLE,           \
+                            _qzz_addr,_ qzz_len, 0, 0);          \
     _qzz_res;                                                    \
    })
 
@@ -87,7 +127,9 @@
    for _qzz_len bytes. */
 #define VALGRIND_MAKE_READABLE(_qzz_addr,_qzz_len)               \
    ({unsigned int _qzz_res;                                      \
-    VALGRIND_MAGIC_SEQUENCE(_qzz_res,1003,_qzz_addr,_qzz_len);   \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* default return */,    \
+                            VG_USERREQ__MAKE_READABLE,           \
+                            _qzz_addr, _qzz_len, 0, 0);          \
     _qzz_res;                                                    \
    })
 
@@ -99,7 +141,9 @@
    handle. */
 #define VALGRIND_DISCARD(_qzz_blkindex)                          \
    ({unsigned int _qzz_res;                                      \
-    VALGRIND_MAGIC_SEQUENCE(_qzz_res,2004,0,_qzz_blkindex);      \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* default return */,    \
+                            VG_USERREQ__DISCARD,                 \
+                            0, _qzz_blkindex, 0, 0);             \
     _qzz_res;                                                    \
    })
 
@@ -111,20 +155,24 @@
    If suitable addressibility is not established, Valgrind prints an
    error message and returns the address of the first offending byte.
    Otherwise it returns zero. */
-#define VALGRIND_CHECK_WRITABLE(_qzz_addr,_qzz_len)              \
-   ({unsigned int _qzz_res;                                      \
-    VALGRIND_MAGIC_SEQUENCE(_qzz_res,2002,_qzz_addr,_qzz_len);   \
-    _qzz_res;                                                    \
+#define VALGRIND_CHECK_WRITABLE(_qzz_addr,_qzz_len)                \
+   ({unsigned int _qzz_res;                                        \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0,                           \
+                            VG_USERREQ__CHECK_WRITABLE,            \
+                            _qzz_addr, _qzz_len, 0, 0);            \
+    _qzz_res;                                                      \
    })
 
 /* Check that memory at _qzz_addr is addressible and defined for
    _qzz_len bytes.  If suitable addressibility and definedness are not
    established, Valgrind prints an error message and returns the
    address of the first offending byte.  Otherwise it returns zero. */
-#define VALGRIND_CHECK_READABLE(_qzz_addr,_qzz_len)              \
-   ({unsigned int _qzz_res;                                      \
-    VALGRIND_MAGIC_SEQUENCE(_qzz_res,2003,_qzz_addr,_qzz_len);   \
-    _qzz_res;                                                    \
+#define VALGRIND_CHECK_READABLE(_qzz_addr,_qzz_len)                \
+   ({unsigned int _qzz_res;                                        \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0,                           \
+                            VG_USERREQ__CHECK_READABLE,            \
+                            _qzz_addr, _qzz_len, 0, 0);            \
+    _qzz_res;                                                      \
    })
 
 
@@ -133,10 +181,10 @@
    are not established, Valgrind prints an error message and returns
    the address of the first offending byte.  Otherwise it returns
    zero. */
-#define VALGRIND_CHECK_DEFINED(__lvalue)                         \
-   (void)                                                        \
-   VALGRIND_CHECK_READABLE(                                      \
-      (volatile unsigned char *)&(__lvalue),                     \
+#define VALGRIND_CHECK_DEFINED(__lvalue)                           \
+   (void)                                                          \
+   VALGRIND_CHECK_READABLE(                                        \
+      (volatile unsigned char *)&(__lvalue),                       \
                       (unsigned int)(sizeof (__lvalue)))
 
 
@@ -146,11 +194,38 @@
    value.  The record associated with this setting will be
    automatically removed by Valgrind when the containing routine
    exits. */
-#define VALGRIND_MAKE_NOACCESS_STACK(_qzz_addr,_qzz_len)         \
-   ({unsigned int _qzz_res;                                      \
-    VALGRIND_MAGIC_SEQUENCE(_qzz_res,3001,_qzz_addr,_qzz_len);   \
-    _qzz_res;                                                    \
+#define VALGRIND_MAKE_NOACCESS_STACK(_qzz_addr,_qzz_len)           \
+   {unsigned int _qzz_res;                                         \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0,                           \
+                            VG_USERREQ__MAKE_NOACCESS_STACK,       \
+                            _qzz_addr, _qzz_len, 0, 0);            \
+   }
+
+
+/* Returns 1 if running on Valgrind, 0 if running on the real CPU. 
+   Currently implemented but untested. */
+#define RUNNING_ON_VALGRIND                                        \
+   ({unsigned int _qzz_res;                                        \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* returned if not */,     \
+                            VG_USERREQ__RUNNING_ON_VALGRIND,       \
+                            0, 0, 0, 0);                           \
+    _qzz_res;                                                      \
    })
 
 
+/* Mark memory, intended to be on the client's stack, at _qzz_addr as
+   unaddressible and undefined for _qzz_len bytes.  Does not return a
+   value.  The record associated with this setting will be
+   automatically removed by Valgrind when the containing routine
+   exits.  
+
+   Currently implemented but untested.
+*/
+#define VALGRIND_DO_LEAK_CHECK                                     \
+   {unsigned int _qzz_res;                                         \
+    VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0,                           \
+                            VG_USERREQ__DO_LEAK_CHECK,             \
+                            0, 0, 0, 0);                           \
+   }
+
 #endif