Make the Quadrics Elan3 clone-hack be controllable by a command-line
flag.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3216 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/core.h b/coregrind/core.h
index 388a776..d15cfe4 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -337,6 +337,9 @@
    client address space bounds */
 extern Bool VG_(clo_pointercheck);
 
+/* HACK: Use hacked version of clone for Quadrics Elan3 drivers */
+extern Bool VG_(clo_support_elan3);
+
 /* Set up the libc freeres wrapper */
 extern void VG_(intercept_libc_freeres_wrapper)(Addr);
 
diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c
index 1eca030..dffdbff 100644
--- a/coregrind/vg_main.c
+++ b/coregrind/vg_main.c
@@ -1498,6 +1498,7 @@
 Bool   VG_(clo_track_fds)      = False;
 Bool   VG_(clo_show_below_main) = False;
 Bool   VG_(clo_pointercheck)   = True;
+Bool   VG_(clo_support_elan3)  = False;
 Bool   VG_(clo_branchpred)     = False;
 
 static Bool   VG_(clo_wait_for_gdb)   = False;
@@ -1535,6 +1536,7 @@
 "    --lowlat-signals=no|yes   improve thread signal wake-up latency [no]\n"
 "    --lowlat-syscalls=no|yes  improve thread syscall wake-up latency [no]\n"
 "    --pointercheck=no|yes     enforce client address space limits [yes]\n"
+"    --support-elan3=no|yes    hacks for Quadrics Elan3 support [no]\n"
 "\n"
 "  user options for Valgrind tools that report errors:\n"
 "    --log-fd=<number>         log messages to file descriptor [2=stderr]\n"
@@ -1748,6 +1750,7 @@
       else VG_BOOL_CLO("--lowlat-signals",   VG_(clo_lowlat_signals))
       else VG_BOOL_CLO("--lowlat-syscalls",  VG_(clo_lowlat_syscalls))
       else VG_BOOL_CLO("--pointercheck",     VG_(clo_pointercheck))
+      else VG_BOOL_CLO("--support-elan3",    VG_(clo_support_elan3))
       else VG_BOOL_CLO("--profile",          VG_(clo_profile))
       else VG_BOOL_CLO("--bbprofile",        VG_(clo_bbprofile))
       else VG_BOOL_CLO("--run-libc-freeres", VG_(clo_run_libc_freeres))
diff --git a/coregrind/x86-linux/syscalls.c b/coregrind/x86-linux/syscalls.c
index 1d72c55..68a3084 100644
--- a/coregrind/x86-linux/syscalls.c
+++ b/coregrind/x86-linux/syscalls.c
@@ -151,9 +151,12 @@
 }
 
 
+/* --- BEGIN Quadrics Elan3 driver hacks (1) --- */
+
 /* Horrible hack.  Do sys_clone, and if you are then the child,
    continue at child_next_eip instead of returning. */
-static Bool  ELAN3_HACK = True;
+/* not even kernel thread-safe due to use of static var, but I think
+   that's ok.  we should not have multiple kernel threads here. */
 static void* child_wherenext;
 static UInt clone_child_native ( void* child_next_eip, UInt arg1, UInt arg2 )
 { 
@@ -174,6 +177,9 @@
    return __res;
 }
 
+/* --- END Quadrics Elan3 driver hacks (1) --- */
+
+
 PRE(sys_clone, Special)
 {
    PRINT("sys_clone ( %d, %p, %p, %p, %p )",ARG1,ARG2,ARG3,ARG4,ARG5);
@@ -192,23 +198,35 @@
       VGA_(gen_sys_fork_after) (tid, tst);
    } 
    else
-   if (ELAN3_HACK) {
+   if (VG_(clo_support_elan3) && ARG1 == 0xF00) {
+      /* --- BEGIN Quadrics Elan3 driver hacks (2) --- */
+      /* The Elan3 user-space driver is trying to clone off a
+         do-nothing-much thread.  So we let it run natively, and hope
+         for the best, but keep the parent running normally on
+         Valgrind. */
       Int res = clone_child_native( (void*)tst->arch.vex.guest_EIP, ARG1, ARG2 );
       /* clone_child_native only returns in the parent's context, and
          so res must be either > 0, in which case it is the pid of the
          child, or < 0, which is an error code.  
       */
       if (1) 
-         VG_(printf)("valgrind: ELAN3_HACK: child pid = %d\n", res);
+         VG_(printf)("valgrind: ELAN3_HACK(x86): "
+                     "parent pid = %d, child pid = %d\n", VG_(getpid)(), res);
       vg_assert(res != 0);
       SET_RESULT(res);
+      /* --- END Quadrics Elan3 driver hacks (2) --- */
    } 
    else {
       VG_(unimplemented)
          ("clone(): not supported by Valgrind.\n   "
-          "We do support programs linked against\n   "
+          "\n"
+          "NOTE(1): We do support programs linked against\n   "
           "libpthread.so, though.  Re-run with -v and ensure that\n   "
-          "you are picking up Valgrind's implementation of libpthread.so.");
+          "you are picking up Valgrind's implementation of libpthread.so.\n"
+          "\n"
+          "NOTE(2): if you are trying to run a program using the Quadrics Elan3\n"
+          "   user-space drivers, you need re-run with the flag:\n"
+          "   --support-elan3=yes\n");
    }
 }