From c727f47d59641c43ce171126232fd8049296adf6 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 6 Jan 2011 11:05:10 +0000 Subject: [PATCH 1/7] linux-user: Implement sync_file_range{,2} syscalls Implement the missing syscalls sync_file_range and sync_file_range2. The latter in particular is used by newer versions of apt on Ubuntu for ARM. Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- configure | 18 ++++++++++++++++++ linux-user/strace.list | 6 ++++++ linux-user/syscall.c | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/configure b/configure index 47e4cf04c0..831a741c74 100755 --- a/configure +++ b/configure @@ -2075,6 +2075,21 @@ if compile_prog "$ARCH_CFLAGS" "" ; then fallocate=yes fi +# check for sync_file_range +sync_file_range=no +cat > $TMPC << EOF +#include + +int main(void) +{ + sync_file_range(0, 0, 0, 0); + return 0; +} +EOF +if compile_prog "$ARCH_CFLAGS" "" ; then + sync_file_range=yes +fi + # check for dup3 dup3=no cat > $TMPC << EOF @@ -2613,6 +2628,9 @@ fi if test "$fallocate" = "yes" ; then echo "CONFIG_FALLOCATE=y" >> $config_host_mak fi +if test "$sync_file_range" = "yes" ; then + echo "CONFIG_SYNC_FILE_RANGE=y" >> $config_host_mak +fi if test "$dup3" = "yes" ; then echo "CONFIG_DUP3=y" >> $config_host_mak fi diff --git a/linux-user/strace.list b/linux-user/strace.list index 97b7f7691d..d7be0e7a68 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1518,3 +1518,9 @@ #ifdef TARGET_NR_utimensat { TARGET_NR_utimensat, "utimensat", NULL, print_utimensat, NULL }, #endif +#ifdef TARGET_NR_sync_file_range +{ TARGET_NR_sync_file_range, "sync_file_range", NULL, NULL, NULL }, +#endif +#ifdef TARGET_NR_sync_file_range2 +{ TARGET_NR_sync_file_range2, "sync_file_range2", NULL, NULL, NULL }, +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c3e870654d..1939a5f0ec 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7364,6 +7364,29 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_fallocate: ret = get_errno(fallocate(arg1, arg2, arg3, arg4)); break; +#endif +#if defined(CONFIG_SYNC_FILE_RANGE) +#if defined(TARGET_NR_sync_file_range) + case TARGET_NR_sync_file_range: +#if TARGET_ABI_BITS == 32 + ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3), + target_offset64(arg4, arg5), arg6)); +#else + ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4)); +#endif + break; +#endif +#if defined(TARGET_NR_sync_file_range2) + case TARGET_NR_sync_file_range2: + /* This is like sync_file_range but the arguments are reordered */ +#if TARGET_ABI_BITS == 32 + ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4), + target_offset64(arg5, arg6), arg2)); +#else + ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2)); +#endif + break; +#endif #endif default: unimplemented: From d2ef05bb44e044e30f779ed9c4882c3c8299350d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 6 Jan 2011 15:04:17 +0000 Subject: [PATCH 2/7] linux-user: Support ioctls whose parameter size is not constant Some ioctls (for example FS_IOC_FIEMAP) use structures whose size is not constant. The generic argument conversion code in do_ioctl() cannot handle this, so add support for implementing a special-case handler for a particular ioctl which does the conversion itself. Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/syscall.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 1939a5f0ec..970efe3bdc 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2965,13 +2965,19 @@ enum { #undef STRUCT #undef STRUCT_SPECIAL -typedef struct IOCTLEntry { +typedef struct IOCTLEntry IOCTLEntry; + +typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, abi_long cmd, abi_long arg); + +struct IOCTLEntry { unsigned int target_cmd; unsigned int host_cmd; const char *name; int access; + do_ioctl_fn *do_ioctl; const argtype arg_type[5]; -} IOCTLEntry; +}; #define IOC_R 0x0001 #define IOC_W 0x0002 @@ -2981,7 +2987,9 @@ typedef struct IOCTLEntry { static IOCTLEntry ioctl_entries[] = { #define IOCTL(cmd, access, ...) \ - { TARGET_ ## cmd, cmd, #cmd, access, { __VA_ARGS__ } }, + { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, +#define IOCTL_SPECIAL(cmd, access, dofn, ...) \ + { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } }, #include "ioctls.h" { 0, 0, }, }; @@ -3011,6 +3019,10 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) #if defined(DEBUG) gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name); #endif + if (ie->do_ioctl) { + return ie->do_ioctl(ie, buf_temp, fd, cmd, arg); + } + switch(arg_type[0]) { case TYPE_NULL: /* no argument */ From 285da2b9a83353703d07e141fdb447e82944146c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 6 Jan 2011 15:04:18 +0000 Subject: [PATCH 3/7] linux-user: Implement FS_IOC_FIEMAP ioctl Implement the FS_IOC_FIEMAP ioctl using the new support for custom handling of ioctls; this is needed because the struct that is passed includes a variable-length array. Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/ioctls.h | 4 ++ linux-user/syscall.c | 88 ++++++++++++++++++++++++++++++++++++++ linux-user/syscall_defs.h | 1 + linux-user/syscall_types.h | 16 +++++++ 4 files changed, 109 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 769e1bcb81..538e2572bb 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -76,6 +76,10 @@ #ifdef FIGETBSZ IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG)) #endif +#ifdef FS_IOC_FIEMAP + IOCTL_SPECIAL(FS_IOC_FIEMAP, IOC_W | IOC_R, do_ioctl_fs_ioc_fiemap, + MK_PTR(MK_STRUCT(STRUCT_fiemap))) +#endif IOCTL(SIOCATMARK, 0, TYPE_NULL) IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry))) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 970efe3bdc..f10e17ae23 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -83,6 +83,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include #include #include +#include #include #include #include "linux_loop.h" @@ -2985,6 +2986,93 @@ struct IOCTLEntry { #define MAX_STRUCT_SIZE 4096 +/* So fiemap access checks don't overflow on 32 bit systems. + * This is very slightly smaller than the limit imposed by + * the underlying kernel. + */ +#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \ + / sizeof(struct fiemap_extent)) + +static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, abi_long cmd, abi_long arg) +{ + /* The parameter for this ioctl is a struct fiemap followed + * by an array of struct fiemap_extent whose size is set + * in fiemap->fm_extent_count. The array is filled in by the + * ioctl. + */ + int target_size_in, target_size_out; + struct fiemap *fm; + const argtype *arg_type = ie->arg_type; + const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) }; + void *argptr, *p; + abi_long ret; + int i, extent_size = thunk_type_size(extent_arg_type, 0); + uint32_t outbufsz; + int free_fm = 0; + + assert(arg_type[0] == TYPE_PTR); + assert(ie->access == IOC_RW); + arg_type++; + target_size_in = thunk_type_size(arg_type, 0); + argptr = lock_user(VERIFY_READ, arg, target_size_in, 1); + if (!argptr) { + return -TARGET_EFAULT; + } + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + fm = (struct fiemap *)buf_temp; + if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) { + return -TARGET_EINVAL; + } + + outbufsz = sizeof (*fm) + + (sizeof(struct fiemap_extent) * fm->fm_extent_count); + + if (outbufsz > MAX_STRUCT_SIZE) { + /* We can't fit all the extents into the fixed size buffer. + * Allocate one that is large enough and use it instead. + */ + fm = malloc(outbufsz); + if (!fm) { + return -TARGET_ENOMEM; + } + memcpy(fm, buf_temp, sizeof(struct fiemap)); + free_fm = 1; + } + ret = get_errno(ioctl(fd, ie->host_cmd, fm)); + if (!is_error(ret)) { + target_size_out = target_size_in; + /* An extent_count of 0 means we were only counting the extents + * so there are no structs to copy + */ + if (fm->fm_extent_count != 0) { + target_size_out += fm->fm_mapped_extents * extent_size; + } + argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0); + if (!argptr) { + ret = -TARGET_EFAULT; + } else { + /* Convert the struct fiemap */ + thunk_convert(argptr, fm, arg_type, THUNK_TARGET); + if (fm->fm_extent_count != 0) { + p = argptr + target_size_in; + /* ...and then all the struct fiemap_extents */ + for (i = 0; i < fm->fm_mapped_extents; i++) { + thunk_convert(p, &fm->fm_extents[i], extent_arg_type, + THUNK_TARGET); + p += extent_size; + } + } + unlock_user(argptr, arg, target_size_out); + } + } + if (free_fm) { + free(fm); + } + return ret; +} + static IOCTLEntry ioctl_entries[] = { #define IOCTL(cmd, access, ...) \ { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 20c93d0f7f..d02a9bf401 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -783,6 +783,7 @@ struct target_pollfd { #define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */ #define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */ #define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */ +#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap) /* cdrom commands */ #define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */ diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 340dbd367f..0e67cd8f30 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -165,3 +165,19 @@ STRUCT(vt_stat, TYPE_SHORT, /* v_active */ TYPE_SHORT, /* v_signal */ TYPE_SHORT) /* v_state */ + +STRUCT(fiemap_extent, + TYPE_ULONGLONG, /* fe_logical */ + TYPE_ULONGLONG, /* fe_physical */ + TYPE_ULONGLONG, /* fe_length */ + MK_ARRAY(TYPE_ULONGLONG, 2), /* fe_reserved64[2] */ + TYPE_INT, /* fe_flags */ + MK_ARRAY(TYPE_INT, 3)) /* fe_reserved[3] */ + +STRUCT(fiemap, + TYPE_ULONGLONG, /* fm_start */ + TYPE_ULONGLONG, /* fm_length */ + TYPE_INT, /* fm_flags */ + TYPE_INT, /* fm_mapped_extents */ + TYPE_INT, /* fm_extent_count */ + TYPE_INT) /* fm_reserved */ From 2bed652fc596dee09f27dd7ab20528cf5eaf9203 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 6 Jan 2011 18:34:43 +0000 Subject: [PATCH 4/7] softfloat: Implement floatx80_is_any_nan() and float128_is_any_nan() Implement versions of float*_is_any_nan() for the floatx80 and float128 types. Acked-by: Aurelien Jarno Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- fpu/softfloat.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fpu/softfloat.h b/fpu/softfloat.h index 15052cc470..a6d0f16b42 100644 --- a/fpu/softfloat.h +++ b/fpu/softfloat.h @@ -489,6 +489,11 @@ INLINE int floatx80_is_zero(floatx80 a) return (a.high & 0x7fff) == 0 && a.low == 0; } +INLINE int floatx80_is_any_nan(floatx80 a) +{ + return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1); +} + #endif #ifdef FLOAT128 @@ -556,6 +561,12 @@ INLINE int float128_is_zero(float128 a) return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0; } +INLINE int float128_is_any_nan(float128 a) +{ + return ((a.high >> 48) & 0x7fff) == 0x7fff && + ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0)); +} + #endif #else /* CONFIG_SOFTFLOAT */ From 3ebe80c2993205ad6ad7ee0e800068f08932775c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 6 Jan 2011 18:34:44 +0000 Subject: [PATCH 5/7] linux-user: Fix incorrect NaN detection in ARM nwfpe emulation The code in the linux-user ARM nwfpe emulation was incorrectly checking only for quiet NaNs when it should have been checking for any kind of NaN. This is probably because the code in question was taken from the Linux kernel, whose copy of the softfloat library had been modified so that float*_is_nan() returned true for all NaNs, not just quiet ones. The qemu equivalent function is float*_is_any_nan(), so use that. NB that this code is really obsolete since nobody uses FPE for actual arithmetic now; this is just cleanup following the recent renaming of the NaN related functions. Acked-by: Aurelien Jarno Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/arm/nwfpe/fpa11_cprt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c index 0e61b585a0..be54e9515d 100644 --- a/linux-user/arm/nwfpe/fpa11_cprt.c +++ b/linux-user/arm/nwfpe/fpa11_cprt.c @@ -199,21 +199,21 @@ static unsigned int PerformComparison(const unsigned int opcode) { case typeSingle: //printk("single.\n"); - if (float32_is_quiet_nan(fpa11->fpreg[Fn].fSingle)) + if (float32_is_any_nan(fpa11->fpreg[Fn].fSingle)) goto unordered; rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); break; case typeDouble: //printk("double.\n"); - if (float64_is_quiet_nan(fpa11->fpreg[Fn].fDouble)) + if (float64_is_any_nan(fpa11->fpreg[Fn].fDouble)) goto unordered; rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status); break; case typeExtended: //printk("extended.\n"); - if (floatx80_is_quiet_nan(fpa11->fpreg[Fn].fExtended)) + if (floatx80_is_any_nan(fpa11->fpreg[Fn].fExtended)) goto unordered; rFn = fpa11->fpreg[Fn].fExtended; break; @@ -225,7 +225,7 @@ static unsigned int PerformComparison(const unsigned int opcode) { //printk("Fm is a constant: #%d.\n",Fm); rFm = getExtendedConstant(Fm); - if (floatx80_is_quiet_nan(rFm)) + if (floatx80_is_any_nan(rFm)) goto unordered; } else @@ -235,21 +235,21 @@ static unsigned int PerformComparison(const unsigned int opcode) { case typeSingle: //printk("single.\n"); - if (float32_is_quiet_nan(fpa11->fpreg[Fm].fSingle)) + if (float32_is_any_nan(fpa11->fpreg[Fm].fSingle)) goto unordered; rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); break; case typeDouble: //printk("double.\n"); - if (float64_is_quiet_nan(fpa11->fpreg[Fm].fDouble)) + if (float64_is_any_nan(fpa11->fpreg[Fm].fDouble)) goto unordered; rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status); break; case typeExtended: //printk("extended.\n"); - if (floatx80_is_quiet_nan(fpa11->fpreg[Fm].fExtended)) + if (floatx80_is_any_nan(fpa11->fpreg[Fm].fExtended)) goto unordered; rFm = fpa11->fpreg[Fm].fExtended; break; From 2e8785acc601f72dd10ce19929c455689fc2649d Mon Sep 17 00:00:00 2001 From: Wolfgang Schildbach Date: Mon, 6 Dec 2010 15:06:05 +0000 Subject: [PATCH 6/7] Fix commandline handling for ARM semihosted executables Use the copy of the command line that loader_build_argptr() sets up in guest memory as the command line to return from the ARM SYS_GET_CMDLINE semihosting call. Previously we were using a pointer to memory which had already been freed before the guest program started. This fixes https://bugs.launchpad.net/qemu/+bug/673613 . Signed-off-by: Wolfgang Schildbach Reviewed-by: Peter Maydell Signed-off-by: Riku Voipio --- arm-semi.c | 81 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/arm-semi.c b/arm-semi.c index 0687b03006..1d5179b601 100644 --- a/arm-semi.c +++ b/arm-semi.c @@ -373,45 +373,64 @@ uint32_t do_arm_semihosting(CPUState *env) #ifdef CONFIG_USER_ONLY /* Build a commandline from the original argv. */ { - char **arg = ts->info->host_argv; - int len = ARG(1); - /* lock the buffer on the ARM side */ - char *cmdline_buffer = (char*)lock_user(VERIFY_WRITE, ARG(0), len, 0); + char *arm_cmdline_buffer; + const char *host_cmdline_buffer; - if (!cmdline_buffer) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; + unsigned int i; + unsigned int arm_cmdline_len = ARG(1); + unsigned int host_cmdline_len = + ts->info->arg_end-ts->info->arg_start; - s = cmdline_buffer; - while (*arg && len > 2) { - int n = strlen(*arg); - - if (s != cmdline_buffer) { - *(s++) = ' '; - len--; - } - if (n >= len) - n = len - 1; - memcpy(s, *arg, n); - s += n; - len -= n; - arg++; + if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) { + return -1; /* not enough space to store command line */ } - /* Null terminate the string. */ - *s = 0; - len = s - cmdline_buffer; - /* Unlock the buffer on the ARM side. */ - unlock_user(cmdline_buffer, ARG(0), len); + if (!host_cmdline_len) { + /* We special-case the "empty command line" case (argc==0). + Just provide the terminating 0. */ + arm_cmdline_buffer = lock_user(VERIFY_WRITE, ARG(0), 1, 0); + arm_cmdline_buffer[0] = 0; + unlock_user(arm_cmdline_buffer, ARG(0), 1); - /* Adjust the commandline length argument. */ - SET_ARG(1, len); + /* Adjust the commandline length argument. */ + SET_ARG(1, 0); + return 0; + } - /* Return success if commandline fit into buffer. */ - return *arg ? -1 : 0; + /* lock the buffers on the ARM side */ + arm_cmdline_buffer = + lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0); + host_cmdline_buffer = + lock_user(VERIFY_READ, ts->info->arg_start, + host_cmdline_len, 1); + + if (arm_cmdline_buffer && host_cmdline_buffer) + { + /* the last argument is zero-terminated; + no need for additional termination */ + memcpy(arm_cmdline_buffer, host_cmdline_buffer, + host_cmdline_len); + + /* separate arguments by white spaces */ + for (i = 0; i < host_cmdline_len-1; i++) { + if (arm_cmdline_buffer[i] == 0) { + arm_cmdline_buffer[i] = ' '; + } + } + + /* Adjust the commandline length argument. */ + SET_ARG(1, host_cmdline_len-1); + } + + /* Unlock the buffers on the ARM side. */ + unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len); + unlock_user((void*)host_cmdline_buffer, ts->info->arg_start, 0); + + /* Return success if we could return a commandline. */ + return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1; } #else - return -1; + return -1; #endif case SYS_HEAPINFO: { From 67af42ac5a6227d61a8ef4ba7289ada9418f2fb8 Mon Sep 17 00:00:00 2001 From: Wolfgang Schildbach Date: Mon, 6 Dec 2010 15:06:06 +0000 Subject: [PATCH 7/7] Remove dead code for ARM semihosting commandline handling There are some bits in the code which were used to store the commandline for the semihosting call. These bits are now write-only and can be removed. Signed-off-by: Wolfgang Schildbach Reviewed-by: Peter Maydell Signed-off-by: Riku Voipio --- bsd-user/bsdload.c | 2 -- bsd-user/qemu.h | 1 - linux-user/linuxload.c | 2 -- linux-user/qemu.h | 1 - 4 files changed, 6 deletions(-) diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c index 14a93bf39b..6d9bb6fb4e 100644 --- a/bsd-user/bsdload.c +++ b/bsd-user/bsdload.c @@ -176,8 +176,6 @@ int loader_exec(const char * filename, char ** argv, char ** envp, retval = prepare_binprm(&bprm); - infop->host_argv = argv; - if(retval>=0) { if (bprm.buf[0] == 0x7f && bprm.buf[1] == 'E' diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 976361622d..e343894ab1 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -50,7 +50,6 @@ struct image_info { abi_ulong entry; abi_ulong code_offset; abi_ulong data_offset; - char **host_argv; int personality; }; diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index 9ee27c3558..ac8c486c5f 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -174,8 +174,6 @@ int loader_exec(const char * filename, char ** argv, char ** envp, retval = prepare_binprm(bprm); - infop->host_argv = argv; - if(retval>=0) { if (bprm->buf[0] == 0x7f && bprm->buf[1] == 'E' diff --git a/linux-user/qemu.h b/linux-user/qemu.h index e66a02bce3..32de2413f8 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -50,7 +50,6 @@ struct image_info { abi_ulong saved_auxv; abi_ulong arg_start; abi_ulong arg_end; - char **host_argv; int personality; };