Change the way Valgrind exits.

Until now, valgrind waited for ld.so to call the .fini code in
valgrind.so, and took this as its cue to switch back to the real CPU
for the rest of the journey.

This is a problem if ld.so subsequently calls other .so's .fini code
and threading is in use, because they do pthread_* calls which cannot
be handled by valgrind's libpthread.so without valgrind actually being
active.

So we ignore the call to valgrind's .fini code, and run the program
all the way up to the point where it calls syscall exit() to
disappear.  This makes the order in which the .fini sections are run
irrelevant, since Valgrind has control during all of them, and so
threading facilities are still available for all of them.

This change means Mozilla 1.0RC1 now exits a lot more cleanly than it
did.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@201 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_startup.S b/coregrind/vg_startup.S
index 5616421..a0bb4ea 100644
--- a/coregrind/vg_startup.S
+++ b/coregrind/vg_startup.S
@@ -104,40 +104,20 @@
 
 
 
-.global VG_(shutdown)	
 VG_(shutdown):
-	# ld.so will call here after execution of the program proper
-	# is complete, to allow libraries to close down cleanly.
-	# Note that we will enter here on the synthetic CPU, not
-	# the real one!  So the interpreter must notice when this
-	# procedure is called, and use that as its cue to switch
-	# back to the real CPU.  As usual we have a client request
-	# to do this.  To make sense of this you need to read the
-	# definition of VALGRIND_MAGIC_SEQUENCE in valgrind.h.
-	pushl	%eax
-	pushl	%edx
-	subl	$20, %esp	# allocate arg block
-	movl	%esp, %eax	# %eax == &_zzq_args[0]
-	movl	$VG_USERREQ__SHUTDOWN_VALGRIND, 0(%eax)	# request
-	# dont bother to fill in arg1 .. 4, not important
-	# and now the magic sequence itself:
-	roll $29, %eax
-	roll $3, %eax
-	rorl $27, %eax
-	rorl $5, %eax
-	roll $13, %eax
-	roll $19, %eax
-	# valgrind now exits.  the following insns are
-	# executed on the real CPU.
-	addl	$20, %esp
-	popl	%edx
-	popl	%eax
+	# Just return, and ignore any attempt by ld.so to call
+	# valgrind.sos exit function.  We just run the client all
+	# the way to the final exit() syscall.  This sidesteps
+	# problems caused by ld.so calling the finalisation code
+	# of other .sos *after* it shuts down valgrind, which
+	# was causing big problems with threads.
 	ret
+
+	
 	
 .global	VG_(switch_to_real_CPU)
 VG_(switch_to_real_CPU):
-	# Once Valgrind has decided it needs to exit, either
-	# because it has detected a call to vg_shutdown, or
+	# Once Valgrind has decided it needs to exit,
 	# because the specified number of insns have been completed
 	# during a debugging run, it jumps here, which copies the
 	# simulators state into the real machine state.  Execution