qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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; 11+ 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] 11+ 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; 11+ 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] 11+ 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; 11+ 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] 11+ 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; 11+ 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] 11+ 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; 11+ 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] 11+ 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; 11+ 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] 11+ 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; 11+ 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] 11+ 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; 11+ 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 = &regs1;
     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] 11+ 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; 11+ 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] 11+ 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-19 14:04           ` Riku Voipio
  0 siblings, 1 reply; 11+ 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] 11+ messages in thread

* Re: [Qemu-devel] [PATCH] Implement futimesat() syscall
  2008-09-18 15:07         ` [Qemu-devel] [PATCH] Implement futimesat() syscall Kirill A. Shutemov
@ 2008-09-19 14:04           ` Riku Voipio
  0 siblings, 0 replies; 11+ messages in thread
From: Riku Voipio @ 2008-09-19 14:04 UTC (permalink / raw)
  To: qemu-devel

On Thu, Sep 18, 2008 at 06:07:04PM +0300, Kirill A. Shutemov wrote:
> Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>

Acked-by: Riku Voipio <riku.voipio@iki.fi>

> ---
>  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
> 
> 

-- 
"rm -rf" only sounds scary if you don't have backups

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2008-09-19 14:04 UTC | newest]

Thread overview: 11+ 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-19 14:04           ` Riku Voipio

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).