* [Qemu-devel] [PATCH] Fix vfork() syscall emulation @ 2008-09-08 14:03 Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix getgroups() " Kirill A. Shutemov 2008-09-13 19:41 ` [Qemu-devel] Linux user emulator maintainer Kirill A. Shutemov 0 siblings, 2 replies; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-08 14:03 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov vfork() is a kind of fork, not thread despite CLONE_VM Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index eba2c02..ae7a5a2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2787,7 +2787,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, sigset_t sigmask; #endif - if (flags & CLONE_VM) { + if (!(flags & CLONE_VFORK) && (flags & CLONE_VM)) { #if defined(USE_NPTL) new_thread_info info; pthread_attr_t attr; @@ -2856,8 +2856,8 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, #endif #endif } else { - /* if no CLONE_VM, we consider it is a fork */ - if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) + /* we consider it is a fork or vfork */ + if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2 | CLONE_VFORK | CLONE_VM)) != 0) return -EINVAL; fork_start(); ret = fork(); -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Fix getgroups() syscall emulation 2008-09-08 14:03 [Qemu-devel] [PATCH] Fix vfork() syscall emulation Kirill A. Shutemov @ 2008-09-08 14:03 ` Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Swap only altered elements of the grouplist Kirill A. Shutemov 2008-09-13 19:41 ` [Qemu-devel] Linux user emulator maintainer Kirill A. Shutemov 1 sibling, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-08 14:03 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov According to man page getgroups(2): If size is zero, list is not modified, but the total number of supplementary group IDs for the process is returned. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ae7a5a2..9d8542d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5242,6 +5242,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, grouplist = alloca(gidsetsize * sizeof(gid_t)); ret = get_errno(getgroups(gidsetsize, grouplist)); + if (gidsetsize == 0) + break; if (!is_error(ret)) { target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0); if (!target_grouplist) @@ -5392,6 +5394,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, grouplist = alloca(gidsetsize * sizeof(gid_t)); ret = get_errno(getgroups(gidsetsize, grouplist)); + if (gidsetsize == 0) + break; if (!is_error(ret)) { target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0); if (!target_grouplist) { -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Swap only altered elements of the grouplist 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix getgroups() " Kirill A. Shutemov @ 2008-09-08 14:03 ` Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-08 14:03 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov getgroups returns the number of supplementary group IDs is returned. So it's unnessary to swap the entire array. It can dramatically speed up the syscall: on recent Linux kernel NGROUPS_MAX=65536. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9d8542d..8112a56 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5248,7 +5248,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0); if (!target_grouplist) goto efault; - for(i = 0;i < gidsetsize; i++) + for(i = 0;i < ret; i++) target_grouplist[i] = tswap16(grouplist[i]); unlock_user(target_grouplist, arg2, gidsetsize * 2); } @@ -5402,7 +5402,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = -TARGET_EFAULT; goto fail; } - for(i = 0;i < gidsetsize; i++) + for(i = 0;i < ret; i++) target_grouplist[i] = tswap32(grouplist[i]); unlock_user(target_grouplist, arg2, gidsetsize * 4); } -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Swap only altered elements of the grouplist Kirill A. Shutemov @ 2008-09-08 14:03 ` Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Implement syscall fstatat64() Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-08 14:03 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov pread() and pwrite() have differences with arguments on ARM EABI and OABI. Please, see arch/arm/kernel/entry-common.S in Linux kernel source for additional information. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8112a56..88954eb 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5042,12 +5042,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_pread case TARGET_NR_pread: +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) + { + arg4 = arg5; + } +#endif if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) goto efault; ret = get_errno(pread(arg1, p, arg3, arg4)); unlock_user(p, arg2, ret); break; case TARGET_NR_pwrite: +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) + { + arg4 = arg5; + } +#endif if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) goto efault; ret = get_errno(pwrite(arg1, p, arg3, arg4)); -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Implement syscall fstatat64() 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI Kirill A. Shutemov @ 2008-09-08 14:03 ` Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Implement futimesat() syscall Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-08 14:03 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov Move transformation of struct stat64 into the separate function and implement fstatat64() using it. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 136 ++++++++++++++++++++++++++++--------------------- 1 files changed, 78 insertions(+), 58 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 88954eb..863e319 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3148,6 +3148,67 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr, return 0; } +#ifdef TARGET_NR_stat64 +static inline abi_long host_to_target_stat64(void *cpu_env, + abi_ulong target_addr, + struct stat *host_st) +{ +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) { + struct target_eabi_stat64 *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) + return -TARGET_EFAULT; + memset(target_st, 0, sizeof(struct target_eabi_stat64)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO + __put_user(host_st->st_ino, &target_st->__st_ino); +#endif + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_atime, &target_st->target_st_atime); + __put_user(host_st->st_mtime, &target_st->target_st_mtime); + __put_user(host_st->st_ctime, &target_st->target_st_ctime); + unlock_user_struct(target_st, target_addr, 1); + } else +#endif + { + struct target_stat64 *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) + return -TARGET_EFAULT; + memset(target_st, 0, sizeof(struct target_stat64)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO + __put_user(host_st->st_ino, &target_st->__st_ino); +#endif + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + /* XXX: better use of kernel struct */ + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_atime, &target_st->target_st_atime); + __put_user(host_st->st_mtime, &target_st->target_st_mtime); + __put_user(host_st->st_ctime, &target_st->target_st_ctime); + unlock_user_struct(target_st, target_addr, 1); + } + + return 0; +} +#endif + #if defined(USE_NPTL) /* ??? Using host futex calls even when target atomic operations are not really atomic probably breaks things. However implementing @@ -5149,7 +5210,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto efault; ret = get_errno(stat(path(p), &st)); unlock_user(p, arg1, 0); - goto do_stat64; + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif #ifdef TARGET_NR_lstat64 case TARGET_NR_lstat64: @@ -5157,67 +5220,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto efault; ret = get_errno(lstat(path(p), &st)); unlock_user(p, arg1, 0); - goto do_stat64; + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif #ifdef TARGET_NR_fstat64 case TARGET_NR_fstat64: - { - ret = get_errno(fstat(arg1, &st)); - do_stat64: - if (!is_error(ret)) { -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) { - struct target_eabi_stat64 *target_st; - - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0)) - goto efault; - memset(target_st, 0, sizeof(struct target_eabi_stat64)); - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO - __put_user(st.st_ino, &target_st->__st_ino); -#endif - __put_user(st.st_mode, &target_st->st_mode); - __put_user(st.st_nlink, &target_st->st_nlink); - __put_user(st.st_uid, &target_st->st_uid); - __put_user(st.st_gid, &target_st->st_gid); - __put_user(st.st_rdev, &target_st->st_rdev); - __put_user(st.st_size, &target_st->st_size); - __put_user(st.st_blksize, &target_st->st_blksize); - __put_user(st.st_blocks, &target_st->st_blocks); - __put_user(st.st_atime, &target_st->target_st_atime); - __put_user(st.st_mtime, &target_st->target_st_mtime); - __put_user(st.st_ctime, &target_st->target_st_ctime); - unlock_user_struct(target_st, arg2, 1); - } else + ret = get_errno(fstat(arg1, &st)); + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif - { - struct target_stat64 *target_st; - - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0)) - goto efault; - memset(target_st, 0, sizeof(struct target_stat64)); - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO - __put_user(st.st_ino, &target_st->__st_ino); -#endif - __put_user(st.st_mode, &target_st->st_mode); - __put_user(st.st_nlink, &target_st->st_nlink); - __put_user(st.st_uid, &target_st->st_uid); - __put_user(st.st_gid, &target_st->st_gid); - __put_user(st.st_rdev, &target_st->st_rdev); - /* XXX: better use of kernel struct */ - __put_user(st.st_size, &target_st->st_size); - __put_user(st.st_blksize, &target_st->st_blksize); - __put_user(st.st_blocks, &target_st->st_blocks); - __put_user(st.st_atime, &target_st->target_st_atime); - __put_user(st.st_mtime, &target_st->target_st_mtime); - __put_user(st.st_ctime, &target_st->target_st_ctime); - unlock_user_struct(target_st, arg2, 1); - } - } - } +#ifdef TARGET_NR_fstatat64 + case TARGET_NR_fstatat64: + if (!(p = lock_user_string(arg2))) + goto efault; + ret = get_errno(fstatat(arg1, p, &st, arg4)); + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg3, &st); break; #endif #ifdef USE_UID16 -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Implement futimesat() syscall 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Implement syscall fstatat64() Kirill A. Shutemov @ 2008-09-08 14:03 ` Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-08 14:03 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 863e319..faf0003 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3656,6 +3656,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, unlock_user(p, arg1, 0); } break; +#ifdef TARGET_NR_futimesat + case TARGET_NR_futimesat: + { + struct timeval *tvp, tv[2]; + if (arg3) { + if (copy_from_user_timeval(&tv[0], arg3) + || copy_from_user_timeval(&tv[1], + arg3 + sizeof(struct target_timeval))) + goto efault; + tvp = tv; + } else { + tvp = NULL; + } + if (!(p = lock_user_string(arg2))) + goto efault; + ret = get_errno(futimesat(arg1, p, tvp)); + unlock_user(p, arg2, 0); + } + break; +#endif #ifdef TARGET_NR_stty case TARGET_NR_stty: goto unimplemented; -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Implement futimesat() syscall Kirill A. Shutemov @ 2008-09-08 14:03 ` Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Introduce option -binfmt-misc-friendly Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-08 14:03 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/ioctls.h | 4 ++++ linux-user/syscall.c | 1 + linux-user/syscall_defs.h | 4 ++++ linux-user/syscall_types.h | 6 ++++++ 4 files changed, 15 insertions(+), 0 deletions(-) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index c1ca2d5..685cc71 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -310,3 +310,7 @@ IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64))) #endif IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT) + + IOCTL(MTIOCTOP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_mtop))) + IOCTL(MTIOCGET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtget))) + IOCTL(MTIOCPOS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtpos))) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index faf0003..5810d65 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -69,6 +69,7 @@ #include <linux/soundcard.h> #include <linux/dirent.h> #include <linux/kd.h> +#include <linux/mtio.h> #include "linux_loop.h" #include "qemu.h" diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 52242b6..9896522 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1923,6 +1923,10 @@ struct target_eabi_flock64 { #define TARGET_VFAT_IOCTL_READDIR_BOTH TARGET_IORU('r', 1) #define TARGET_VFAT_IOCTL_READDIR_SHORT TARGET_IORU('r', 2) +#define TARGET_MTIOCTOP TARGET_IOW('m', 1, struct mtop) +#define TARGET_MTIOCGET TARGET_IOR('m', 2, struct mtget) +#define TARGET_MTIOCPOS TARGET_IOR('m', 3, struct mtpos) + struct target_sysinfo { abi_long uptime; /* Seconds since boot */ abi_ulong loads[3]; /* 1, 5, and 15 minute load averages */ diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index bb4fb4e..283d32d 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -108,3 +108,9 @@ STRUCT(loop_info64, MK_ARRAY(TYPE_CHAR, 64), /* lo_crypt_name */ MK_ARRAY(TYPE_CHAR, 32), /* lo_encrypt_key */ MK_ARRAY(TYPE_ULONGLONG, 2)) /* lo_init */ + + +STRUCT(mtop, TYPE_SHORT, TYPE_INT) +STRUCT(mtget, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, + TYPE_INT, TYPE_INT) +STRUCT(mtpos, TYPE_LONG) -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Introduce option -binfmt-misc-friendly 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS Kirill A. Shutemov @ 2008-09-08 14:03 ` Kirill A. Shutemov 0 siblings, 0 replies; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-08 14:03 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov -binfmt-misc-friendly 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 <kirill@shutemov.name> --- linux-user/linuxload.c | 7 +---- linux-user/main.c | 54 ++++++++++++++++++++++++++++++++++++++++------- linux-user/qemu.h | 2 +- 3 files changed, 49 insertions(+), 14 deletions(-) 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 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ bprm.page[i] = 0; - retval = open(filename, O_RDONLY); - if (retval < 0) - return retval; - bprm.fd = retval; + bprm.fd = fd; bprm.filename = (char *)filename; bprm.argc = count(argv); bprm.argv = argv; diff --git a/linux-user/main.c b/linux-user/main.c index 4bf739e..d3223f2 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -26,6 +26,7 @@ #include "qemu.h" #include "qemu-common.h" +#include "elf.h" /* For tb_lock */ #include "exec-all.h" @@ -2180,12 +2181,13 @@ static void usage(void) "Linux CPU emulator (compiled for %s emulation)\n" "\n" "Standard options:\n" - "-h print this help\n" - "-g port wait gdb connection to port\n" - "-L path set the elf interpreter prefix (default=%s)\n" - "-s size set the stack size in bytes (default=%ld)\n" - "-cpu model select CPU (-cpu ? for list)\n" - "-drop-ld-preload drop LD_PRELOAD for target process\n" + "-h print this help\n" + "-g port wait gdb connection to port\n" + "-L path set the elf interpreter prefix (default=%s)\n" + "-s size set the stack size in bytes (default=%ld)\n" + "-cpu model select CPU (-cpu ? for list)\n" + "-drop-ld-preload drop LD_PRELOAD for target process\n" + "-binfmt-misc-friendly make qemu compatible with binfmt_misc's flags 'O' and 'P' \n" "\n" "Debug options:\n" "-d options activate log (logfile=%s)\n" @@ -2218,9 +2220,10 @@ void init_task_state(TaskState *ts) ts->sigqueue_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; @@ -2230,6 +2233,7 @@ int main(int argc, char **argv) const char *r; int gdbstub_port = 0; int drop_ld_preload = 0, environ_count = 0; + int binfmt_misc_friendly = 0; char **target_environ, **wrk, **dst; if (argc <= 1) @@ -2302,6 +2306,8 @@ int main(int argc, char **argv) drop_ld_preload = 1; } else if (!strcmp(r, "strace")) { do_strace = 1; + } else if (!strcmp(r, "binfmt-misc-friendly")) { + binfmt_misc_friendly = 1; } else { usage(); @@ -2381,7 +2387,39 @@ int main(int argc, char **argv) } *dst = NULL; /* NULL terminate target_environ */ - if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) { + if (binfmt_misc_friendly) { +#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); + } + } + + 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 a12cc9b..216e2f8 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.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] Linux user emulator maintainer 2008-09-08 14:03 [Qemu-devel] [PATCH] Fix vfork() syscall emulation Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix getgroups() " Kirill A. Shutemov @ 2008-09-13 19:41 ` Kirill A. Shutemov 1 sibling, 0 replies; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-13 19:41 UTC (permalink / raw) To: Fabrice Bellard, Paul Brook; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 523 bytes --] Linux user emulator doesn't have active maintainer. Nobody reviews patches to linux-user. It's very sad :( I'm porting ALT Linux Sisyphus to the ARM architecture using qemu-arm. I'm very interested in properly work of Linux user emulator. I have series of patches ready for upstream and I can prepare some patches shortly (including some IPC improvements). If you will allow, I can perform maintenance duties. -- Regards, Kirill A. Shutemov + Belarus, Minsk + ALT Linux Team, http://www.altlinux.com/ [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Fix vfork() syscall emulation @ 2008-09-18 15:06 Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Fix getgroups() " Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-18 15:06 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov vfork() is a kind of fork, not thread despite CLONE_VM Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 56b4138..124d14e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2788,7 +2788,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, sigset_t sigmask; #endif - if (flags & CLONE_VM) { + if (!(flags & CLONE_VFORK) && (flags & CLONE_VM)) { #if defined(USE_NPTL) new_thread_info info; pthread_attr_t attr; @@ -2857,8 +2857,8 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, #endif #endif } else { - /* if no CLONE_VM, we consider it is a fork */ - if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) + /* we consider it is a fork or vfork */ + if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2 | CLONE_VFORK | CLONE_VM)) != 0) return -EINVAL; fork_start(); ret = fork(); -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Fix getgroups() syscall emulation 2008-09-18 15:06 [Qemu-devel] [PATCH] Fix vfork() syscall emulation Kirill A. Shutemov @ 2008-09-18 15:07 ` Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Swap only altered elements of the grouplist Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-18 15:07 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov According to man page getgroups(2): If size is zero, list is not modified, but the total number of supplementary group IDs for the process is returned. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 124d14e..948ea3b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5247,6 +5247,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, grouplist = alloca(gidsetsize * sizeof(gid_t)); ret = get_errno(getgroups(gidsetsize, grouplist)); + if (gidsetsize == 0) + break; if (!is_error(ret)) { target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0); if (!target_grouplist) @@ -5397,6 +5399,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, grouplist = alloca(gidsetsize * sizeof(gid_t)); ret = get_errno(getgroups(gidsetsize, grouplist)); + if (gidsetsize == 0) + break; if (!is_error(ret)) { target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0); if (!target_grouplist) { -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Swap only altered elements of the grouplist 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Fix getgroups() " Kirill A. Shutemov @ 2008-09-18 15:07 ` Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-18 15:07 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov getgroups returns the number of supplementary group IDs is returned. So it's unnessary to swap the entire array. It can dramatically speed up the syscall: on recent Linux kernel NGROUPS_MAX=65536. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 948ea3b..ba7cde1 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5253,7 +5253,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0); if (!target_grouplist) goto efault; - for(i = 0;i < gidsetsize; i++) + for(i = 0;i < ret; i++) target_grouplist[i] = tswap16(grouplist[i]); unlock_user(target_grouplist, arg2, gidsetsize * 2); } @@ -5407,7 +5407,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = -TARGET_EFAULT; goto fail; } - for(i = 0;i < gidsetsize; i++) + for(i = 0;i < ret; i++) target_grouplist[i] = tswap32(grouplist[i]); unlock_user(target_grouplist, arg2, gidsetsize * 4); } -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Swap only altered elements of the grouplist Kirill A. Shutemov @ 2008-09-18 15:07 ` Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Implement fstatat64() syscall Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-18 15:07 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov pread() and pwrite() have differences with arguments on ARM EABI and OABI. Please, see arch/arm/kernel/entry-common.S in Linux kernel source for additional information. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ba7cde1..88b44b8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5047,12 +5047,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_pread case TARGET_NR_pread: +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) + { + arg4 = arg5; + } +#endif if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) goto efault; ret = get_errno(pread(arg1, p, arg3, arg4)); unlock_user(p, arg2, ret); break; case TARGET_NR_pwrite: +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) + { + arg4 = arg5; + } +#endif if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) goto efault; ret = get_errno(pwrite(arg1, p, arg3, arg4)); -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Implement fstatat64() syscall 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI Kirill A. Shutemov @ 2008-09-18 15:07 ` Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Implement futimesat() syscall Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-18 15:07 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov Move transformation of struct stat64 into the separate function and implement fstatat64() using it. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 141 +++++++++++++++++++++++++++++-------------------- 1 files changed, 83 insertions(+), 58 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 88b44b8..ac7e7d9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -156,6 +156,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ #define __NR_sys_faccessat __NR_faccessat #define __NR_sys_fchmodat __NR_fchmodat #define __NR_sys_fchownat __NR_fchownat +#define __NR_sys_fstatat64 __NR_fstatat64 #define __NR_sys_getcwd1 __NR_getcwd #define __NR_sys_getdents __NR_getdents #define __NR_sys_getdents64 __NR_getdents64 @@ -200,6 +201,10 @@ _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname, _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname, uid_t,owner,gid_t,group,int,flags) #endif +#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64) +_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname, + struct stat *,buf,int,flags) +#endif _syscall2(int,sys_getcwd1,char *,buf,size_t,size) #if TARGET_ABI_BITS == 32 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count); @@ -3149,6 +3154,67 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr, return 0; } +#ifdef TARGET_NR_stat64 +static inline abi_long host_to_target_stat64(void *cpu_env, + abi_ulong target_addr, + struct stat *host_st) +{ +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) { + struct target_eabi_stat64 *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) + return -TARGET_EFAULT; + memset(target_st, 0, sizeof(struct target_eabi_stat64)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO + __put_user(host_st->st_ino, &target_st->__st_ino); +#endif + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_atime, &target_st->target_st_atime); + __put_user(host_st->st_mtime, &target_st->target_st_mtime); + __put_user(host_st->st_ctime, &target_st->target_st_ctime); + unlock_user_struct(target_st, target_addr, 1); + } else +#endif + { + struct target_stat64 *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) + return -TARGET_EFAULT; + memset(target_st, 0, sizeof(struct target_stat64)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO + __put_user(host_st->st_ino, &target_st->__st_ino); +#endif + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + /* XXX: better use of kernel struct */ + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_atime, &target_st->target_st_atime); + __put_user(host_st->st_mtime, &target_st->target_st_mtime); + __put_user(host_st->st_ctime, &target_st->target_st_ctime); + unlock_user_struct(target_st, target_addr, 1); + } + + return 0; +} +#endif + #if defined(USE_NPTL) /* ??? Using host futex calls even when target atomic operations are not really atomic probably breaks things. However implementing @@ -5154,7 +5220,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto efault; ret = get_errno(stat(path(p), &st)); unlock_user(p, arg1, 0); - goto do_stat64; + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif #ifdef TARGET_NR_lstat64 case TARGET_NR_lstat64: @@ -5162,67 +5230,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto efault; ret = get_errno(lstat(path(p), &st)); unlock_user(p, arg1, 0); - goto do_stat64; + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif #ifdef TARGET_NR_fstat64 case TARGET_NR_fstat64: - { - ret = get_errno(fstat(arg1, &st)); - do_stat64: - if (!is_error(ret)) { -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) { - struct target_eabi_stat64 *target_st; - - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0)) - goto efault; - memset(target_st, 0, sizeof(struct target_eabi_stat64)); - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO - __put_user(st.st_ino, &target_st->__st_ino); -#endif - __put_user(st.st_mode, &target_st->st_mode); - __put_user(st.st_nlink, &target_st->st_nlink); - __put_user(st.st_uid, &target_st->st_uid); - __put_user(st.st_gid, &target_st->st_gid); - __put_user(st.st_rdev, &target_st->st_rdev); - __put_user(st.st_size, &target_st->st_size); - __put_user(st.st_blksize, &target_st->st_blksize); - __put_user(st.st_blocks, &target_st->st_blocks); - __put_user(st.st_atime, &target_st->target_st_atime); - __put_user(st.st_mtime, &target_st->target_st_mtime); - __put_user(st.st_ctime, &target_st->target_st_ctime); - unlock_user_struct(target_st, arg2, 1); - } else + ret = get_errno(fstat(arg1, &st)); + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif - { - struct target_stat64 *target_st; - - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0)) - goto efault; - memset(target_st, 0, sizeof(struct target_stat64)); - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO - __put_user(st.st_ino, &target_st->__st_ino); -#endif - __put_user(st.st_mode, &target_st->st_mode); - __put_user(st.st_nlink, &target_st->st_nlink); - __put_user(st.st_uid, &target_st->st_uid); - __put_user(st.st_gid, &target_st->st_gid); - __put_user(st.st_rdev, &target_st->st_rdev); - /* XXX: better use of kernel struct */ - __put_user(st.st_size, &target_st->st_size); - __put_user(st.st_blksize, &target_st->st_blksize); - __put_user(st.st_blocks, &target_st->st_blocks); - __put_user(st.st_atime, &target_st->target_st_atime); - __put_user(st.st_mtime, &target_st->target_st_mtime); - __put_user(st.st_ctime, &target_st->target_st_ctime); - unlock_user_struct(target_st, arg2, 1); - } - } - } +#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64) + case TARGET_NR_fstatat64: + if (!(p = lock_user_string(arg2))) + goto efault; + ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4)); + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg3, &st); break; #endif #ifdef USE_UID16 -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Implement futimesat() syscall 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Implement fstatat64() syscall Kirill A. Shutemov @ 2008-09-18 15:07 ` Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS Kirill A. Shutemov 0 siblings, 1 reply; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-18 15:07 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/syscall.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ac7e7d9..e90f100 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -157,6 +157,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ #define __NR_sys_fchmodat __NR_fchmodat #define __NR_sys_fchownat __NR_fchownat #define __NR_sys_fstatat64 __NR_fstatat64 +#define __NR_sys_futimesat __NR_futimesat #define __NR_sys_getcwd1 __NR_getcwd #define __NR_sys_getdents __NR_getdents #define __NR_sys_getdents64 __NR_getdents64 @@ -205,6 +206,10 @@ _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname, _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname, struct stat *,buf,int,flags) #endif +#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat) +_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname, + const struct timeval *,times) +#endif _syscall2(int,sys_getcwd1,char *,buf,size_t,size) #if TARGET_ABI_BITS == 32 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count); @@ -3662,6 +3667,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, unlock_user(p, arg1, 0); } break; +#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat) + case TARGET_NR_futimesat: + { + struct timeval *tvp, tv[2]; + if (arg3) { + if (copy_from_user_timeval(&tv[0], arg3) + || copy_from_user_timeval(&tv[1], + arg3 + sizeof(struct target_timeval))) + goto efault; + tvp = tv; + } else { + tvp = NULL; + } + if (!(p = lock_user_string(arg2))) + goto efault; + ret = get_errno(sys_futimesat(arg1, path(p), tvp)); + unlock_user(p, arg2, 0); + } + break; +#endif #ifdef TARGET_NR_stty case TARGET_NR_stty: goto unimplemented; -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Implement futimesat() syscall Kirill A. Shutemov @ 2008-09-18 15:07 ` Kirill A. Shutemov 0 siblings, 0 replies; 10+ messages in thread From: Kirill A. Shutemov @ 2008-09-18 15:07 UTC (permalink / raw) To: qemu-devel; +Cc: Kirill A. Shutemov Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- linux-user/ioctls.h | 4 ++++ linux-user/syscall.c | 1 + linux-user/syscall_defs.h | 4 ++++ linux-user/syscall_types.h | 6 ++++++ 4 files changed, 15 insertions(+), 0 deletions(-) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index c1ca2d5..685cc71 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -310,3 +310,7 @@ IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64))) #endif IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT) + + IOCTL(MTIOCTOP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_mtop))) + IOCTL(MTIOCGET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtget))) + IOCTL(MTIOCPOS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtpos))) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index e90f100..ce99cf6 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -70,6 +70,7 @@ #include <linux/soundcard.h> #include <linux/dirent.h> #include <linux/kd.h> +#include <linux/mtio.h> #include "linux_loop.h" #include "qemu.h" diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 52242b6..9896522 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1923,6 +1923,10 @@ struct target_eabi_flock64 { #define TARGET_VFAT_IOCTL_READDIR_BOTH TARGET_IORU('r', 1) #define TARGET_VFAT_IOCTL_READDIR_SHORT TARGET_IORU('r', 2) +#define TARGET_MTIOCTOP TARGET_IOW('m', 1, struct mtop) +#define TARGET_MTIOCGET TARGET_IOR('m', 2, struct mtget) +#define TARGET_MTIOCPOS TARGET_IOR('m', 3, struct mtpos) + struct target_sysinfo { abi_long uptime; /* Seconds since boot */ abi_ulong loads[3]; /* 1, 5, and 15 minute load averages */ diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index bb4fb4e..283d32d 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -108,3 +108,9 @@ STRUCT(loop_info64, MK_ARRAY(TYPE_CHAR, 64), /* lo_crypt_name */ MK_ARRAY(TYPE_CHAR, 32), /* lo_encrypt_key */ MK_ARRAY(TYPE_ULONGLONG, 2)) /* lo_init */ + + +STRUCT(mtop, TYPE_SHORT, TYPE_INT) +STRUCT(mtget, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, + TYPE_INT, TYPE_INT) +STRUCT(mtpos, TYPE_LONG) -- 1.5.6.5.GIT ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-09-18 15:06 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-09-08 14:03 [Qemu-devel] [PATCH] Fix vfork() syscall emulation Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix getgroups() " Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Swap only altered elements of the grouplist Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Implement syscall fstatat64() Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Implement futimesat() syscall Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS Kirill A. Shutemov 2008-09-08 14:03 ` [Qemu-devel] [PATCH] Introduce option -binfmt-misc-friendly Kirill A. Shutemov 2008-09-13 19:41 ` [Qemu-devel] Linux user emulator maintainer Kirill A. Shutemov -- strict thread matches above, loose matches on Subject: below -- 2008-09-18 15:06 [Qemu-devel] [PATCH] Fix vfork() syscall emulation Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Fix getgroups() " Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Swap only altered elements of the grouplist Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Fix pread() and pwrite() syscall on ARM EABI Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Implement fstatat64() syscall Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Implement futimesat() syscall Kirill A. Shutemov 2008-09-18 15:07 ` [Qemu-devel] [PATCH] Imaplement ioctls MTIOCTOP, MTIOCGET and MTIOCPOS Kirill A. Shutemov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).