Add a --assume-2.4=yes|no CLO.  This overrides the normal check to see
if the kernel has enough capabilities to run in 2.6 mode (ie, futex,
the right kind of clone, correct signal handling properties), and always
uses 2.4 mode.  This will often not work on a 2.6 or RH9 2.4 kernel, but
it does help avoid a bug in the SuSE 8.2 (and possibly 9) kernels, which
look like they support enough to run in 2.6 mode, but get it wrong.
TODO: make the startup script/configure actually use this option.

Also some cleanup in printing debugging messages from vg_proxylwp.c, and
a small fix in the handling of ERESTARTSYS (assume that every syscall will
get interrupted from the outset, until it actually completes).


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1965 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h
index e8f53d3..52ed302 100644
--- a/coregrind/vg_include.h
+++ b/coregrind/vg_include.h
@@ -249,6 +249,8 @@
 /* How often we should poll for signals, assuming we need to poll for
    signals. */
 extern Int   VG_(clo_signal_polltime);
+/* Assume we're running on a plain 2.4 kernel */
+extern Bool  VG_(clo_assume_24);
 
 /* Low latency syscalls and signals */
 extern Bool  VG_(clo_lowlat_syscalls);
diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c
index 43a2315..727fce5 100644
--- a/coregrind/vg_main.c
+++ b/coregrind/vg_main.c
@@ -565,6 +565,9 @@
    default. */
 Int    VG_(clo_signal_polltime) = 50;
 
+/* If true, assume we're running on a plain 2.4 kernel */
+Bool   VG_(clo_assume_24) = False;
+
 /* These flags reduce thread wakeup latency on syscall completion and
    signal delivery, respectively.  The downside is possible unfairness. */
 Bool   VG_(clo_lowlat_syscalls) = False; /* low-latency syscalls */
@@ -661,6 +664,7 @@
 "			       a signal [no]\n"
 "    --lowlat-syscalls=no|yes  improve wake-up latency when a thread's\n"
 "			       syscall completes [no]\n"
+"    --assume-2.4=no|yes       assume we're running on a 2.4 kernel [no]\n"
 "\n"
 "  %s skin user options:\n";
 
@@ -1098,6 +1102,11 @@
       else if (VG_CLO_STREQ(argv[i], "--lowlat-syscalls=no"))
 	 VG_(clo_lowlat_syscalls) = False;
 
+      else if (VG_CLO_STREQ(argv[i], "--assume-2.4=yes"))
+	 VG_(clo_assume_24) = True;
+      else if (VG_CLO_STREQ(argv[i], "--assume-2.4=no"))
+	 VG_(clo_assume_24) = False;
+
       else if (VG_CLO_STREQN(13, argv[i], "--stop-after="))
          VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
 
diff --git a/coregrind/vg_proxylwp.c b/coregrind/vg_proxylwp.c
index e7fa5cb..6716b0a 100644
--- a/coregrind/vg_proxylwp.c
+++ b/coregrind/vg_proxylwp.c
@@ -257,7 +257,7 @@
 }
 
 #define PROXYLWP_OFFSET	(VKI_BYTES_PER_PAGE - sizeof(ProxyLWP))
-#define ROUNDDN(p)	((UChar *)((UInt)(p) & ~(VKI_BYTES_PER_PAGE-1)))
+#define ROUNDDN(p)	((UChar *)((Addr)(p) & ~(VKI_BYTES_PER_PAGE-1)))
 
 /* 
    Allocate a page for the ProxyLWP and its stack.
@@ -478,7 +478,7 @@
    ThreadState *tst = px->tst;
    vki_ksigset_t allsig;
    vki_ksigset_t appsigmask;	/* signal mask the client has asked for */
-   Int ret = 0;
+   Int ret = 1000;
    static const vki_kstack_t ss = { .ss_flags = VKI_SS_DISABLE };
 
    /* Block everything until we're told otherwise (LWP should have
@@ -655,8 +655,10 @@
 	 /* process message with signals blocked */
 	 VG_(ksigprocmask)(VKI_SIG_SETMASK, &allsig, NULL);
 
-	 if (res == 0)
+	 if (res == 0) {
+	    ret = 0;
 	    goto out;		/* EOF - we're quitting */
+	 }
 	 
 	 if (res < 0) {
 	    px_printf("read(frommain) failed %d\n", res);
@@ -714,7 +716,7 @@
 	 case PX_RunSyscall:
 	    /* Run a syscall for our thread; results will be poked
 	       back into tst */
-	    reply.syscallno = tst->m_eax;
+	    reply.syscallno = tst->syscallno;
 
 	    vg_assert(px->state == PXS_WaitReq || 
 		      px->state == PXS_SigACK);
@@ -728,7 +730,7 @@
 			 reply.syscallno);
 	       tst->m_eax = -VKI_ERESTARTSYS;
 	    } else {
-	       Int syscallno = tst->m_eax;
+	       Int syscallno = tst->syscallno;
 	       
 	       px->state = PXS_RunSyscall;
 	       /* If we're interrupted before we get to the syscall
@@ -896,6 +898,9 @@
 {
    Int ret;
 
+   if (VG_(clo_assume_24))
+      have_futex = 0;
+
    if (have_futex == -1)
       have_futex = do_futex(NULL, VKI_FUTEX_WAKE, 0, NULL, NULL) != -VKI_ENOSYS;
 
@@ -1263,7 +1268,10 @@
    vg_assert(proxy->tid == tid);
 
    req.request = PX_RunSyscall;
-   
+
+   tst->syscallno = tst->m_eax;
+   tst->m_eax = -VKI_ERESTARTSYS;
+
    /* clear the results pipe before we try to write to a proxy to
       prevent a deadlock */
    VG_(proxy_results)();
@@ -1293,7 +1301,7 @@
 	 continue;
 
       if (tst->proxy == NULL) {
-	 VG_(printf)("TID %d: NULL proxy");
+	 VG_(message)(Vg_DebugMsg, "TID %d: NULL proxy");
 	 sane = False;
 	 continue;
       }
@@ -1301,14 +1309,16 @@
       px = tst->proxy;
 
       if (px->tid != tid) {
-	 VG_(printf)("TID %d: proxy LWP %d doesn't have right tid (%d)\n",
-		     tid, px->lwp, px->tid);
+	 VG_(message)(Vg_DebugMsg, 
+		      "TID %d: proxy LWP %d doesn't have right tid (%d)\n",
+		      tid, px->lwp, px->tid);
 	 sane = False;
       }
 
       if (proxy_wait(px, False, &status)) {
-	 VG_(printf)("TID %d: proxy LWP %d exited with status %d\n",
-		     tid, px->lwp, status);
+	 VG_(message)(Vg_DebugMsg,
+		      "TID %d: proxy LWP %d exited with status %d\n",
+		      tid, px->lwp, status);
 	 sane = False;
 	 continue;
       }
@@ -1318,8 +1328,9 @@
       if (tst->status != VgTs_WaitSys) {
 	 ret = VG_(write)(px->topx, &req, sizeof(req));
 	 if (ret != sizeof(req)) {
-	    VG_(printf)("TID %d: failed to write PX_Ping to lwp %d: %d\n",
-			tid, px->lwp, ret);
+	    VG_(message)(Vg_DebugMsg,
+			 "TID %d: failed to write PX_Ping to lwp %d: %d\n",
+			 tid, px->lwp, ret);
 	    sane = False;
 	 }
 	 sys_wait_results(True, tid, PX_Ping);