Skip to contentSkip to conversation

linux-user fixes for pull

PATCH In review Riku Voipio 5 participants 17 messages Jan 7, 2011 – Jan 10, 2011

lore
Share & tools
lore
#0 lore raw

cover linux-user fixes for pull

From: Riku Voipio <[email protected]>

The following changes since commit 2a704b137f1acfbd972aa6e9f031c5015c7e28cb:

cris: Avoid useless tmp in t_gen_cc_jmp() (2011-01-07 12:50:38 +0100)

are available in the git repository at:
git://gitorious.org/qemu-maemo/qemu.git linux-user-for-upstream

Peter Maydell (5):
linux-user: Implement sync_file_range{,2} syscalls
linux-user: Support ioctls whose parameter size is not constant
linux-user: Implement FS_IOC_FIEMAP ioctl
softfloat: Implement floatx80_is_any_nan() and float128_is_any_nan()
linux-user: Fix incorrect NaN detection in ARM nwfpe emulation

Wolfgang Schildbach (2):
Fix commandline handling for ARM semihosted executables Remove dead code for ARM semihosting commandline handling

 arm-semi.c                        |   79 ++++++++++++++---------
 bsd-user/bsdload.c                |    2 -
 bsd-user/qemu.h                   |    1 -
 configure                         |   18 +++++
 fpu/softfloat.h                   |   11 +++
 linux-user/arm/nwfpe/fpa11_cprt.c |   14 ++--
 linux-user/ioctls.h               |    4 +
 linux-user/linuxload.c            |    2 -
 linux-user/qemu.h                 |    1 -
 linux-user/strace.list            |    6 ++
 linux-user/syscall.c              |  129 ++++++++++++++++++++++++++++++++++++-
 linux-user/syscall_defs.h         |    1 +
 linux-user/syscall_types.h        |   16 +++++
 13 files changed, 238 insertions(+), 46 deletions(-)
#1 lore raw

PATCH 1/7 linux-user: Implement sync_file_range{, 2} syscalls

From: Peter Maydell <[email protected]>

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.

---
 configure              |   18 ++++++++++++++++++
 linux-user/strace.list |    6 ++++++
 linux-user/syscall.c   |   23 +++++++++++++++++++++++
 3 files changed, 47 insertions(+), 0 deletions(-)
configure +18 -0
index 47e4cf0..831a741 100755
@@ -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 <fcntl.h>
+
+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
linux-user/strace.list +6 -0
index 97b7f76..d7be0e7 100644
@@ -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
linux-user/syscall.c +23 -0
index c3e8706..1939a5f 100644
@@ -7365,6 +7365,29 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         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:
         gemu_log("qemu: Unsupported syscall: %d\n", num);
Signature · 1 line
1.6.5
#2 lore raw

PATCH 2/7 linux-user: Support ioctls whose parameter size is not constant

In reply to Riku Voipio

From: Peter Maydell <[email protected]>

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.

---
 linux-user/syscall.c |   18 +++++++++++++++---
 1 files changed, 15 insertions(+), 3 deletions(-)
linux-user/syscall.c +15 -3
index 1939a5f..970efe3 100644
@@ -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 */
Signature · 1 line
1.6.5
#3 lore raw

PATCH 3/7 linux-user: Implement FS_IOC_FIEMAP ioctl

In reply to Riku Voipio

From: Peter Maydell <[email protected]>

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.

---
 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(+), 0 deletions(-)
linux-user/ioctls.h +4 -0
index 769e1bc..538e257 100644
@@ -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)))
linux-user/syscall.c +88 -0

100 lines not on this page · raw message

linux-user/syscall_defs.h +1 -0
index 20c93d0..d02a9bf 100644
@@ -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 */
linux-user/syscall_types.h +16 -0
index 340dbd3..0e67cd8 100644
@@ -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 */
Signature · 1 line
1.6.5
#4 lore raw

Re: [Qemu-devel] [PATCH 3/7] linux-user: Implement FS_IOC_FIEMAP ioctl

Quoted 35 lines · Riku Voipio

From: Peter Maydell <[email protected]>

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.

---
 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(+), 0 deletions(-)
linux-user/ioctls.h +4 -0
index 769e1bc..538e257 100644
@@ -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)))
linux-user/syscall.c +0 -0
index 970efe3..f10e17a 100644

linux-user/syscall.c int __clone2(int (*fn)(void *), void *child_stack_base, · line 86

Quoted 4 lines
linux-user/syscall.c +1 -0
@@ -83,6 +83,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
  #include <linux/kd.h>
  #include <linux/mtio.h>
  #include <linux/fs.h>
+#include <linux/fiemap.h>

This fails if the file doesn't exist:
CC i386-linux-user/syscall.o
/src/qemu/linux-user/syscall.c:86:26: error: linux/fiemap.h: No such file or directory
/src/qemu/linux-user/syscall.c: In function 'do_ioctl_fs_ioc_fiemap':
/src/qemu/linux-user/syscall.c:3025: error: dereferencing pointer to incomplete type
/src/qemu/linux-user/syscall.c:3025: error: invalid application of 'sizeof' to incomplete type 'struct fiemap' /src/qemu/linux-user/syscall.c:3025: error: invalid application of 'sizeof' to incomplete type 'struct fiemap_extent'
cc1: warnings being treated as errors /src/qemu/linux-user/syscall.c:3025: error: division by zero /src/qemu/linux-user/syscall.c:3029: error: dereferencing pointer to incomplete type
/src/qemu/linux-user/syscall.c:3030: error: invalid application of 'sizeof' to incomplete type 'struct fiemap_extent' /src/qemu/linux-user/syscall.c:3030: error: dereferencing pointer to incomplete type
/src/qemu/linux-user/syscall.c:3040: error: invalid application of 'sizeof' to incomplete type 'struct fiemap' /src/qemu/linux-user/syscall.c:3049: error: dereferencing pointer to incomplete type
/src/qemu/linux-user/syscall.c:3050: error: dereferencing pointer to incomplete type
/src/qemu/linux-user/syscall.c:3058: error: dereferencing pointer to incomplete type
/src/qemu/linux-user/syscall.c:3061: error: dereferencing pointer to incomplete type
/src/qemu/linux-user/syscall.c:3062: error: dereferencing pointer to incomplete type

The fix is to introduce a feature check in configure.

#5 lore raw

Re: [Qemu-devel] [PATCH 3/7] linux-user: Implement FS_IOC_FIEMAP ioctl

Quoted 6 lines · Blue Swirl

This fails if the file doesn't exist:
CC i386-linux-user/syscall.o
/src/qemu/linux-user/syscall.c:86:26: error: linux/fiemap.h: No such file or directory

The fix is to introduce a feature check in configure.

Perhaps we can do without configure check, since FS_IOC_FIEMAP is defined in fs.h if fiemap.h is available. See the attached patch.

Quoted 1 line

From 8c186f5698ce2fa0a3f6faf11122ee0b69d388c8 Mon Sep 17 00:00:00 2001

From: Riku Voipio <[email protected]>
Date: Sun, 9 Jan 2011 19:37:10 +0200
Subject: [PATCH] linux-user: guard fiemap with FS_IOC_FIEMAP

Compilation of linux-user fails if the file doesn't exist:
CC i386-linux-user/syscall.o
/src/qemu/linux-user/syscall.c:86:26: error: linux/fiemap.h: No such file or directory

Since FS_IOC_FIEMAP is defined in fs.h, we can use it #ifdef fiemap support out

---
 linux-user/syscall.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
linux-user/syscall.c +4 -0
index f10e17a..c1f506c 100644
@@ -83,7 +83,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <linux/kd.h>
 #include <linux/mtio.h>
 #include <linux/fs.h>
+#if defined(FS_IOC_FIEMAP)
 #include <linux/fiemap.h>
+#endif
 #include <linux/fb.h>
 #include <linux/vt.h>
 #include "linux_loop.h"
@@ -2986,6 +2988,7 @@ struct IOCTLEntry {
 
 #define MAX_STRUCT_SIZE 4096
 
+#ifdef FS_IOC_FIEMAP
 /* So fiemap access checks don't overflow on 32 bit systems.
  * This is very slightly smaller than the limit imposed by
  * the underlying kernel.
@@ -3072,6 +3075,7 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
     }
     return ret;
 }
+#endif /* FS_IOC_FIEMAP */
 
 static IOCTLEntry ioctl_entries[] = {
 #define IOCTL(cmd, access, ...) \
Signature · 1 line
1.7.1
Acked-by
#6 lore raw

Re: [Qemu-devel] [PATCH 3/7] linux-user: Implement FS_IOC_FIEMAP ioctl

Quoted 11 lines · riku voipio
Quoted 7 lines · Blue Swirl

This fails if the file doesn't exist:
  CC    i386-linux-user/syscall.o /src/qemu/linux-user/syscall.c:86:26: error: linux/fiemap.h: No such file or directory

The fix is to introduce a feature check in configure.

Perhaps we can do without configure check, since FS_IOC_FIEMAP is defined in fs.h if fiemap.h is available. See the attached patch.

It's a bit fragile compared to a configure check, but I confirm it works.

#7 lore raw

Re: [Qemu-devel] [PATCH 3/7] linux-user: Implement FS_IOC_FIEMAP ioctl

Quoted 6 lines · Blue Swirl
Quoted 5 lines · riku voipio
Quoted 4 lines · Blue Swirl

This fails if the file doesn't exist:
  CC    i386-linux-user/syscall.o /src/qemu/linux-user/syscall.c:86:26: error: linux/fiemap.h: No such file or directory

Argh, sorry.

Quoted 5 lines
Quoted 2 lines

Perhaps we can do without configure check, since FS_IOC_FIEMAP is defined in fs.h if fiemap.h is available. See the attached patch.

It's a bit fragile compared to a configure check, but I confirm it works.

I can do you a patch to do a configure check tomorrow if you'd rather have that than the FS_IOC_FIEMAP ifdef.

-- PMM

#8 lore raw

Re: [Qemu-devel] [PATCH 3/7] linux-user: Implement FS_IOC_FIEMAP ioctl

In reply to riku voipio
Quoted 10 lines · riku voipio
Quoted 6 lines · Blue Swirl

This fails if the file doesn't exist:
CC i386-linux-user/syscall.o
/src/qemu/linux-user/syscall.c:86:26: error: linux/fiemap.h: No such file or directory

The fix is to introduce a feature check in configure.

Perhaps we can do without configure check, since FS_IOC_FIEMAP is defined in fs.h if fiemap.h is available. See the attached patch.

I have cross checked building on any Debian, Fedora, Ubuntu and openSUSE hosts I could try for x86 32bit and 64bit hosts and can confirm this variant works of course on these.

I would also be very interested if you could apply my 2 line linux-user change for loop mount ioctl I sent to the ml (yesterday).

#9 lore raw

PATCH 4/7 softfloat: Implement floatx80_is_any_nan() and float128_is_any_nan()

In reply to Riku Voipio

From: Peter Maydell <[email protected]>

Implement versions of float*_is_any_nan() for the floatx80 and float128 types.

---
 fpu/softfloat.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)
fpu/softfloat.h +11 -0
index 15052cc..a6d0f16 100644
@@ -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 */
Signature · 1 line
1.6.5
#10 lore raw

PATCH 5/7 linux-user: Fix incorrect NaN detection in ARM nwfpe emulation

In reply to Riku Voipio

From: Peter Maydell <[email protected]>

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.

---
 linux-user/arm/nwfpe/fpa11_cprt.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
linux-user/arm/nwfpe/fpa11_cprt.c +7 -7
index 0e61b58..be54e95 100644
@@ -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;
Signature · 1 line
1.6.5
#11 lore raw

PATCH 6/7 Fix commandline handling for ARM semihosted executables

In reply to Riku Voipio

From: Wolfgang Schildbach <[email protected]>

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 .

---
 arm-semi.c |   79 +++++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 49 insertions(+), 30 deletions(-)
arm-semi.c +49 -30
index 0687b03..1d5179b 100644
@@ -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;
+
+            if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) {
+                return -1; /* not enough space to store command line */
+            }
 
-            s = cmdline_buffer;
-            while (*arg && len > 2) {
-                int n = strlen(*arg);
+            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);
 
-                if (s != cmdline_buffer) {
-                    *(s++) = ' ';
-                    len--;
-                }
-                if (n >= len)
-                    n = len - 1;
-                memcpy(s, *arg, n);
-                s += n;
-                len -= n;
-                arg++;
+                /* Adjust the commandline length argument. */
+                SET_ARG(1, 0);
+                return 0;
             }
-            /* Null terminate the string.  */
-            *s = 0;
-            len = s - cmdline_buffer;
 
-            /* Unlock the buffer on the ARM side.  */
-            unlock_user(cmdline_buffer, ARG(0), len);
+            /* 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);
 
-            /* Adjust the commandline length argument.  */
-            SET_ARG(1, len);
+            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);
 
-            /* Return success if commandline fit into buffer.  */
-            return *arg ? -1 : 0;
+                /* 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:
         {
Signature · 1 line
1.6.5
#12 lore raw

PATCH 7/7 Remove dead code for ARM semihosting commandline handling

In reply to Riku Voipio

From: Wolfgang Schildbach <[email protected]>

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.

---
 bsd-user/bsdload.c     |    2 --
 bsd-user/qemu.h        |    1 -
 linux-user/linuxload.c |    2 --
 linux-user/qemu.h      |    1 -
 4 files changed, 0 insertions(+), 6 deletions(-)
bsd-user/bsdload.c +0 -2
index 14a93bf..6d9bb6f 100644
@@ -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'
bsd-user/qemu.h +0 -1
index 9763616..e343894 100644
@@ -50,7 +50,6 @@ struct image_info {
     abi_ulong entry;
     abi_ulong code_offset;
     abi_ulong data_offset;
-    char      **host_argv;
     int       personality;
 };
 
linux-user/linuxload.c +0 -2
index 9ee27c3..ac8c486 100644
@@ -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'
linux-user/qemu.h +0 -1
index e66a02b..32de241 100644
@@ -50,7 +50,6 @@ struct image_info {
         abi_ulong       saved_auxv;
         abi_ulong       arg_start;
         abi_ulong       arg_end;
-        char            **host_argv;
 	int		personality;
 };
 
Signature · 1 line
1.6.5
#13 lore raw
In reply to Riku Voipio
Quoted 20 lines · Riku Voipio

From: Riku Voipio <[email protected]>

The following changes since commit 2a704b137f1acfbd972aa6e9f031c5015c7e28cb:

cris: Avoid useless tmp in t_gen_cc_jmp() (2011-01-07 12:50:38 +0100)

are available in the git repository at:
git://gitorious.org/qemu-maemo/qemu.git linux-user-for-upstream

Peter Maydell (5):
linux-user: Implement sync_file_range{,2} syscalls
linux-user: Support ioctls whose parameter size is not constant
linux-user: Implement FS_IOC_FIEMAP ioctl
softfloat: Implement floatx80_is_any_nan() and float128_is_any_nan()
linux-user: Fix incorrect NaN detection in ARM nwfpe emulation

Wolfgang Schildbach (2):
Fix commandline handling for ARM semihosted executables Remove dead code for ARM semihosting commandline handling

Quoted 15 lines
 arm-semi.c                        |   79 ++++++++++++++---------
 bsd-user/bsdload.c                |    2 -
 bsd-user/qemu.h                   |    1 -
 configure                         |   18 +++++
 fpu/softfloat.h                   |   11 +++
 linux-user/arm/nwfpe/fpa11_cprt.c |   14 ++--
 linux-user/ioctls.h               |    4 +
 linux-user/linuxload.c            |    2 -
 linux-user/qemu.h                 |    1 -
 linux-user/strace.list            |    6 ++
 linux-user/syscall.c              |  129 ++++++++++++++++++++++++++++++++++++-
 linux-user/syscall_defs.h         |    1 +
 linux-user/syscall_types.h        |   16 +++++
 13 files changed, 238 insertions(+), 46 deletions(-)

Thanks, pulled.

Signature · 2 lines
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
[email protected]                 http://www.aurel32.net
#14 lore raw

PATCH 1/1 linux-user: fix for loopmount ioctl

In reply to Riku Voipio

Hi,

I had fixed the loopmount ioctl for linux-user, working correctly for arm, mips, ppc32 and sh4.

Martin

From: Martin Mohring <[email protected]>

In case a chrooted build uses XEN or KVM, a looped mount needs to be done to setup the chroot. The ioctl for loop mount works correctly for arm, mips, ppc32 and sh4, so its now activated.

---

/linux-user/ioctls.h +0 -2
diff -u -r qemu-0.14git2011.01.06.2243.orig//linux-user/ioctls.h qemu-0.14git2011.01.06.2243//linux-user/ioctls.h
@@ -312,10 +312,8 @@
   IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
   IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
   IOCTL(LOOP_GET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
-#if 0 /* These have some problems - not fully tested */
   IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
   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)))

Only in qemu-0.14git2011.01.06.2243//linux-user: ioctls.h.orig Only in qemu-0.14git2011.01.06.2243//linux-user: ioctls.h~

#15 lore raw

Re: [Qemu-devel] [PATCH] linux-user: fix for loopmount ioctl

Quoted 7 lines · Martin Mohring

Hi,

I had fixed the loopmount ioctl for linux-user, working correctly for arm, mips, ppc32 and sh4.

Martin

ping

Aurelien, Riku, is that patch ok? Its only 2 lines of change to activate an ioctl.

#16 lore raw

Re: [Qemu-devel] [PATCH] linux-user: fix for loopmount ioctl

Quoted 8 lines · Martin Mohring
Quoted 3 lines · Martin Mohring

Hi,

I had fixed the loopmount ioctl for linux-user, working correctly for arm, mips, ppc32 and sh4.

ping

Aurelien, Riku, is that patch ok? Its only 2 lines of change to activate an ioctl.

Dont worry, I'm looking on it. The original comment suggested the ioctl had problems, so I'd like to close look on it first.

Riku