From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L7pu7-0007yZ-Dj for qemu-devel@nongnu.org; Wed, 03 Dec 2008 06:28:28 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L7ptz-0007sZ-TO for qemu-devel@nongnu.org; Wed, 03 Dec 2008 06:28:22 -0500 Received: from [199.232.76.173] (port=33391 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L7pty-0007s4-Vr for qemu-devel@nongnu.org; Wed, 03 Dec 2008 06:28:19 -0500 Received: from ug-out-1314.google.com ([66.249.92.174]:6267) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1L7ptu-0004Bc-1u for qemu-devel@nongnu.org; Wed, 03 Dec 2008 06:28:15 -0500 Received: by ug-out-1314.google.com with SMTP id 29so3354828ugc.36 for ; Wed, 03 Dec 2008 03:27:29 -0800 (PST) From: "Kirill A. Shutemov" Date: Wed, 3 Dec 2008 13:29:36 +0200 Message-Id: <1228303789-25653-1-git-send-email-kirill@shutemov.name> Subject: [Qemu-devel] [PATCH] Introduce --enable-binfmt-misc configure option Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Kirill A. Shutemov" It makes qemu compatible with binfmt_misc's flags 'P' and 'O'. 'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite the original argv[0] with the full path to the binary. When this flag is included, binfmt_misc will add an argument to the argument vector for this purpose, thus preserving the original argv[0]. 'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path of the binary to the interpreter as an argument. When this flag is included, binfmt_misc will open the file for reading and pass its descriptor as an argument, instead of the full path, thus allowing the interpreter to execute non-readable binaries. Signed-off-by: Kirill A. Shutemov --- configure | 90 ++++++++++++++++++++++++++---------------------- linux-user/linuxload.c | 7 +--- linux-user/main.c | 39 ++++++++++++++++++++- linux-user/qemu.h | 2 +- 4 files changed, 89 insertions(+), 49 deletions(-) diff --git a/configure b/configure index 57b3b5a..aeeae72 100755 --- a/configure +++ b/configure @@ -122,6 +122,7 @@ kvm="yes" kerneldir="" aix="no" blobs="yes" +binfmt_misc="no" # OS specific targetos=`uname -s` @@ -380,6 +381,8 @@ for opt do ;; --kerneldir=*) kerneldir="$optarg" ;; + --enable-binfmt-misc) binfmt_misc="yes" + ;; *) echo "ERROR: unknown option $opt"; show_help="yes" ;; esac @@ -491,6 +494,7 @@ echo " --disable-vde disable support for vde network" echo " --disable-aio disable AIO support" echo " --disable-blobs disable installing provided firmware blobs" echo " --kerneldir=PATH look for kernel includes in PATH" +echo " --enable-binfmt-misc makes usermode compatible with binfmt_misc's flags 'P' and 'O'" echo "" echo "NOTE: The object files are built at the place where configure is launched" exit 1 @@ -1041,57 +1045,58 @@ else binsuffix="/bin" fi -echo "Install prefix $prefix" -echo "BIOS directory $prefix$datasuffix" -echo "binary directory $prefix$binsuffix" +echo "Install prefix $prefix" +echo "BIOS directory $prefix$datasuffix" +echo "binary directory $prefix$binsuffix" if test "$mingw32" = "no" ; then -echo "Manual directory $prefix$mansuffix" -echo "ELF interp prefix $interp_prefix" -fi -echo "Source path $source_path" -echo "C compiler $cc" -echo "Host C compiler $host_cc" -echo "ARCH_CFLAGS $ARCH_CFLAGS" -echo "make $make" -echo "install $install" -echo "host CPU $cpu" -echo "host big endian $bigendian" -echo "target list $target_list" -echo "gprof enabled $gprof" -echo "sparse enabled $sparse" -echo "profiler $profiler" -echo "static build $static" -echo "-Werror enabled $werror" +echo "Manual directory $prefix$mansuffix" +echo "ELF interp prefix $interp_prefix" +fi +echo "Source path $source_path" +echo "C compiler $cc" +echo "Host C compiler $host_cc" +echo "ARCH_CFLAGS $ARCH_CFLAGS" +echo "make $make" +echo "install $install" +echo "host CPU $cpu" +echo "host big endian $bigendian" +echo "target list $target_list" +echo "gprof enabled $gprof" +echo "sparse enabled $sparse" +echo "profiler $profiler" +echo "static build $static" +echo "-Werror enabled $werror" if test "$darwin" = "yes" ; then - echo "Cocoa support $cocoa" + echo "Cocoa support $cocoa" fi echo "SDL support $sdl" if test "$sdl" != "no" ; then - echo "SDL static link $sdl_static" -fi -echo "curses support $curses" -echo "mingw32 support $mingw32" -echo "Audio drivers $audio_drv_list" -echo "Extra audio cards $audio_card_list" -echo "Mixer emulation $mixemu" -echo "VNC TLS support $vnc_tls" + echo "SDL static link $sdl_static" +fi +echo "curses support $curses" +echo "mingw32 support $mingw32" +echo "Audio drivers $audio_drv_list" +echo "Extra audio cards $audio_card_list" +echo "Mixer emulation $mixemu" +echo "VNC TLS support $vnc_tls" if test "$vnc_tls" = "yes" ; then - echo " TLS CFLAGS $vnc_tls_cflags" - echo " TLS LIBS $vnc_tls_libs" + echo " TLS CFLAGS $vnc_tls_cflags" + echo " TLS LIBS $vnc_tls_libs" fi if test -n "$sparc_cpu"; then - echo "Target Sparc Arch $sparc_cpu" + echo "Target Sparc Arch $sparc_cpu" fi -echo "kqemu support $kqemu" -echo "brlapi support $brlapi" -echo "Documentation $build_docs" +echo "kqemu support $kqemu" +echo "brlapi support $brlapi" +echo "Documentation $build_docs" [ ! -z "$uname_release" ] && \ -echo "uname -r $uname_release" -echo "NPTL support $nptl" -echo "vde support $vde" -echo "AIO support $aio" -echo "Install blobs $blobs" -echo "KVM support $kvm" +echo "uname -r $uname_release" +echo "NPTL support $nptl" +echo "vde support $vde" +echo "AIO support $aio" +echo "Install blobs $blobs" +echo "KVM support $kvm" +echo "binfmt_misc support $binfmt_misc" if test $sdl_too_old = "yes"; then echo "-> Your SDL version is too old - please upgrade to have SDL support" @@ -1709,6 +1714,9 @@ if test "$target_bsd_user" = "yes" ; then echo "CONFIG_BSD_USER=yes" >> $config_mak echo "#define CONFIG_BSD_USER 1" >> $config_h fi +if test "$target_user_only" = "yes" -a "$binfmt_misc" = "yes"; then + echo "#define BINFMT_MISC 1" >> $config_h +fi test -f ${config_h}~ && cmp -s $config_h ${config_h}~ && mv ${config_h}~ $config_h diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index ada7c69..cbd90f7 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -154,7 +154,7 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, return sp; } -int loader_exec(const char * filename, char ** argv, char ** envp, +int loader_exec(int fd, const char * filename, char ** argv, char ** envp, struct target_pt_regs * regs, struct image_info *infop) { struct linux_binprm bprm; @@ -164,10 +164,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp, bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); for (i=0 ; isigqueue_table[i].next = NULL; } -int main(int argc, char **argv) +int main(int argc, char **argv, char **envp) { const char *filename; + int fd = -1; const char *cpu_model; struct target_pt_regs regs1, *regs = ®s1; struct image_info info1, *info = &info1; @@ -2377,7 +2379,40 @@ int main(int argc, char **argv) } *dst = NULL; /* NULL terminate target_environ */ - if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) { +#ifdef BINFMT_MISC +#if HOST_LONG_BITS == 32 +#define Elf_Dyn Elf32_Dyn +#else +#define Elf_Dyn Elf64_Dyn +#endif + { + Elf_Dyn *auxv; + + optind++; /* Handle binfmt_misc's option 'P' */ + + /* Handle binfmt_misc's option 'O' */ + while(*envp++ != NULL); /* skip envp. we are on auxv now */ + for(auxv = (Elf_Dyn *)envp; auxv->d_tag != AT_NULL; auxv++) { + if( auxv->d_tag == AT_EXECFD) { + fd = auxv->d_un.d_val; + break; + } + } + + if (fd < 0) { + printf("Cannot find binary file descriptor\n"); + _exit(1); + } + } +#else + fd = open(filename, O_RDONLY); + if (fd < 0) { + printf("Cannot open file %s: %s\n", filename, strerror(errno)); + _exit(1); + } +#endif + + if (loader_exec(fd, filename, argv+optind, target_environ, regs, info) != 0) { printf("Error loading %s\n", filename); _exit(1); } diff --git a/linux-user/qemu.h b/linux-user/qemu.h index a2abe51..52835ec 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -168,7 +168,7 @@ struct linux_binprm { void do_init_thread(struct target_pt_regs *regs, struct image_info *infop); abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, abi_ulong stringp, int push_ptr); -int loader_exec(const char * filename, char ** argv, char ** envp, +int loader_exec(int fd, const char * filename, char ** argv, char ** envp, struct target_pt_regs * regs, struct image_info *infop); int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, -- 1.6.0.2.GIT