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");
}
}