Overhaul the way programs are loaded at startup and exec() works.  Now the
checking of programs done in these two places are combined, which avoids
duplicate code and greatly reduces the number of cases in which exec()
fails causing Valgrind to bomb out.

Also, we can now load some programs we could not previously, such as scripts
lacking a "#!" line at the start.  Also, the startup failure messages for
bad programs match the shell's messages very closely.

And I added a whole bunch of regtests to test all this.




git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4918 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/pub_core_ume.h b/coregrind/pub_core_ume.h
index fbf414f..1054e9b 100644
--- a/coregrind/pub_core_ume.h
+++ b/coregrind/pub_core_ume.h
@@ -93,11 +93,17 @@
    char*  interp_args;  // OUT: the args for the interpreter
 };
 
+// Do a number of appropriate checks to see if the file looks executable by
+// the kernel: ie. it's a file, it's readable and executable, and it's in
+// either ELF or "#!" format.  On success, 'out_fd' gets the fd of the file
+// if it's non-NULL.  Otherwise the fd is closed.
+extern SysRes VG_(pre_exec_check)(const Char* exe_name, Int* out_fd);
+
 // Does everything short of actually running 'exe': finds the file,
 // checks execute permissions, sets up interpreter if program is a script, 
 // reads headers, maps file into memory, and returns important info about
 // the program.
-extern int VG_(do_exec)(const char *exe, struct exeinfo *info);
+extern Int VG_(do_exec)(const char *exe, struct exeinfo *info);
 
 /*------------------------------------------------------------*/
 /*--- Finding and dealing with auxv                        ---*/