[Spice-commits] 16 commits - configure include/elf.h linux-user/Makefile.objs linux-user/cpu-uname.c linux-user/cpu-uname.h linux-user/elfload.c linux-user/main.c linux-user/signal.c linux-user/syscall.c linux-user/syscall_defs.h linux-user/uname.c linux-user/uname.h

Gerd Hoffmann kraxel at kemper.freedesktop.org
Tue May 6 04:49:58 PDT 2014


 configure                 |    8 -
 include/elf.h             |    1 
 linux-user/Makefile.objs  |    2 
 linux-user/cpu-uname.c    |   72 -----------------
 linux-user/cpu-uname.h    |    1 
 linux-user/elfload.c      |  147 +++++++++++++++++++++++++++++++----
 linux-user/main.c         |    2 
 linux-user/signal.c       |    3 
 linux-user/syscall.c      |  189 +++++++++++++++-------------------------------
 linux-user/syscall_defs.h |   16 +++
 linux-user/uname.c        |  171 +++++++++++++++++++++++++++++++++++++++++
 linux-user/uname.h        |   10 ++
 12 files changed, 392 insertions(+), 230 deletions(-)

New commits:
commit cf972928fc1f8d5f6ecaacf5ef354cbe52d79a90
Merge: fdaad47 a39fb27
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue May 6 10:56:38 2014 +0100

    Merge remote-tracking branch 'remotes/riku/linux-user-for-upstream' into staging
    
    * remotes/riku/linux-user-for-upstream:
      linux-user: fix getrusage and wait4 failures with invalid rusage struct
      linux-user/elfload.c: Support ARM HWCAP2 flags
      linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32
      linux-user/elfload.c: Update ARM HWCAP bits
      linux-user/elfload.c: Fix incorrect ARM HWCAP bits
      linux-user: remove configure option for setting uname release
      linux-user: move uname functions to uname.c
      linux-user: rename cpu-uname -> uname
      linux-user/signal.c: Set fault address in AArch64 signal info
      linux-user: avoid using glibc internals in _syscall5 and in definition of target_sigevent struct
      linux-user: Handle arches with llseek instead of _llseek
      linux-user: Add support for SCM_CREDENTIALS.
      linux-user: Move if-elses to a switch statement.
      linux-user: Assert stack used for auxvec, envp, argv
      linux-user: Add /proc/self/exe open forwarding
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit a39fb273bddd315b440b0617783051456a148242
Author: Petar Jovanovic <petar.jovanovic at imgtec.com>
Date:   Tue Apr 8 19:24:30 2014 +0200

    linux-user: fix getrusage and wait4 failures with invalid rusage struct
    
    Implementations of system calls getrusage and wait4 have not previously
    handled correctly cases when incorrect address of struct rusage is
    passed.
    This change makes sure return values are correctly set for these cases.
    
    Signed-off-by: Petar Jovanovic <petar.jovanovic at imgtec.com>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9fc28bd..6efeeff 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6243,7 +6243,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             struct rusage rusage;
             ret = get_errno(getrusage(arg1, &rusage));
             if (!is_error(ret)) {
-                host_to_target_rusage(arg2, &rusage);
+                ret = host_to_target_rusage(arg2, &rusage);
             }
         }
         break;
@@ -6908,6 +6908,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             abi_long status_ptr = arg2;
             struct rusage rusage, *rusage_ptr;
             abi_ulong target_rusage = arg4;
+            abi_long rusage_err;
             if (target_rusage)
                 rusage_ptr = &rusage;
             else
@@ -6919,8 +6920,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     if (put_user_s32(status, status_ptr))
                         goto efault;
                 }
-                if (target_rusage)
-                    host_to_target_rusage(target_rusage, &rusage);
+                if (target_rusage) {
+                    rusage_err = host_to_target_rusage(target_rusage, &rusage);
+                    if (rusage_err) {
+                        ret = rusage_err;
+                    }
+                }
             }
         }
         break;
commit ad6919dc0ab3b8ae26d772e883aa8e709785d249
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 2 14:45:15 2014 +0100

    linux-user/elfload.c: Support ARM HWCAP2 flags
    
    The ARM kernel has chosen to spill into the HWCAP2 ELF feature bit flags
    early, even though it hasn't yet exhausted all 32 bits of the HWCAP word.
    Add support for setting this in the same way we do for HWCAP.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/include/elf.h b/include/elf.h
index 667af6f..1599ab2 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -254,6 +254,7 @@ typedef int64_t  Elf64_Sxword;
 #define AT_SECURE	23	/* boolean, was exec suid-like? */
 #define AT_BASE_PLATFORM 24	/* string identifying real platforms */
 #define AT_RANDOM	25	/* address of 16 random bytes */
+#define AT_HWCAP2       26      /* extension of AT_HWCAP */
 #define AT_EXECFN	31	/* filename of the executable */
 #define AT_SYSINFO	32	/* address of kernel entry point */
 #define AT_SYSINFO_EHDR	33	/* address of kernel vdso */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ad07c43..995f999 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -20,6 +20,7 @@
 #undef ARCH_DLINFO
 #undef ELF_PLATFORM
 #undef ELF_HWCAP
+#undef ELF_HWCAP2
 #undef ELF_CLASS
 #undef ELF_DATA
 #undef ELF_ARCH
@@ -353,6 +354,14 @@ enum
     ARM_HWCAP_ARM_EVTSTRM   = 1 << 21,
 };
 
+enum {
+    ARM_HWCAP2_ARM_AES      = 1 << 0,
+    ARM_HWCAP2_ARM_PMULL    = 1 << 1,
+    ARM_HWCAP2_ARM_SHA1     = 1 << 2,
+    ARM_HWCAP2_ARM_SHA2     = 1 << 3,
+    ARM_HWCAP2_ARM_CRC32    = 1 << 4,
+};
+
 /* The commpage only exists for 32 bit kernels */
 
 #define TARGET_HAS_VALIDATE_GUEST_SPACE
@@ -416,6 +425,7 @@ static int validate_guest_space(unsigned long guest_base,
 }
 
 #define ELF_HWCAP get_elf_hwcap()
+#define ELF_HWCAP2 get_elf_hwcap2()
 
 static uint32_t get_elf_hwcap(void)
 {
@@ -448,11 +458,22 @@ static uint32_t get_elf_hwcap(void)
      */
     GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPD32);
     GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
-#undef GET_FEATURE
 
     return hwcaps;
 }
 
+static uint32_t get_elf_hwcap2(void)
+{
+    ARMCPU *cpu = ARM_CPU(thread_cpu);
+    uint32_t hwcaps = 0;
+
+    GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP2_ARM_AES);
+    GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP2_ARM_CRC32);
+    return hwcaps;
+}
+
+#undef GET_FEATURE
+
 #else
 /* 64 bit ARM definitions */
 #define ELF_START_MMAP 0x80000000
@@ -1486,6 +1507,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
 #ifdef DLINFO_ARCH_ITEMS
     size += DLINFO_ARCH_ITEMS * 2;
 #endif
+#ifdef ELF_HWCAP2
+    size += 2;
+#endif
     size += envc + argc + 2;
     size += 1;  /* argc itself */
     size *= n;
@@ -1519,6 +1543,10 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
     NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
 
+#ifdef ELF_HWCAP2
+    NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
+#endif
+
     if (k_platform)
         NEW_AUX_ENT(AT_PLATFORM, u_platform);
 #ifdef ARCH_DLINFO
commit 24e76ff06bcd0936ee8b04b15dca42efb7d614d1
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 2 14:45:14 2014 +0100

    linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32
    
    The ARM target-specific code in elfload.c was incorrectly allowing
    the 64-bit ARM target to use most of the existing 32-bit definitions:
    most noticably this meant that our HWCAP bits passed to the guest
    were wrong, and register handling when dumping core was totally
    broken. Fix this by properly separating the 64 and 32 bit code,
    since they have more differences than similarities.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index d372300..ad07c43 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -267,17 +267,15 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
 
 #ifdef TARGET_ARM
 
+#ifndef TARGET_AARCH64
+/* 32 bit ARM definitions */
+
 #define ELF_START_MMAP 0x80000000
 
 #define elf_check_arch(x) ((x) == ELF_MACHINE)
 
 #define ELF_ARCH        ELF_MACHINE
-
-#ifdef TARGET_AARCH64
-#define ELF_CLASS       ELFCLASS64
-#else
 #define ELF_CLASS       ELFCLASS32
-#endif
 
 static inline void init_thread(struct target_pt_regs *regs,
                                struct image_info *infop)
@@ -285,10 +283,6 @@ static inline void init_thread(struct target_pt_regs *regs,
     abi_long stack = infop->start_stack;
     memset(regs, 0, sizeof(*regs));
 
-#ifdef TARGET_AARCH64
-    regs->pc = infop->entry & ~0x3ULL;
-    regs->sp = stack;
-#else
     regs->ARM_cpsr = 0x10;
     if (infop->entry & 1)
         regs->ARM_cpsr |= CPSR_T;
@@ -302,7 +296,6 @@ static inline void init_thread(struct target_pt_regs *regs,
     /* For uClinux PIC binaries.  */
     /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
     regs->ARM_r10 = infop->start_data;
-#endif
 }
 
 #define ELF_NREG    18
@@ -360,7 +353,6 @@ enum
     ARM_HWCAP_ARM_EVTSTRM   = 1 << 21,
 };
 
-#ifndef TARGET_AARCH64
 /* The commpage only exists for 32 bit kernels */
 
 #define TARGET_HAS_VALIDATE_GUEST_SPACE
@@ -422,7 +414,6 @@ static int validate_guest_space(unsigned long guest_base,
 
     return 1; /* All good */
 }
-#endif
 
 #define ELF_HWCAP get_elf_hwcap()
 
@@ -462,7 +453,76 @@ static uint32_t get_elf_hwcap(void)
     return hwcaps;
 }
 
-#endif
+#else
+/* 64 bit ARM definitions */
+#define ELF_START_MMAP 0x80000000
+
+#define elf_check_arch(x) ((x) == ELF_MACHINE)
+
+#define ELF_ARCH        ELF_MACHINE
+#define ELF_CLASS       ELFCLASS64
+#define ELF_PLATFORM    "aarch64"
+
+static inline void init_thread(struct target_pt_regs *regs,
+                               struct image_info *infop)
+{
+    abi_long stack = infop->start_stack;
+    memset(regs, 0, sizeof(*regs));
+
+    regs->pc = infop->entry & ~0x3ULL;
+    regs->sp = stack;
+}
+
+#define ELF_NREG    34
+typedef target_elf_greg_t  target_elf_gregset_t[ELF_NREG];
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+                               const CPUARMState *env)
+{
+    int i;
+
+    for (i = 0; i < 32; i++) {
+        (*regs)[i] = tswapreg(env->xregs[i]);
+    }
+    (*regs)[32] = tswapreg(env->pc);
+    (*regs)[33] = tswapreg(pstate_read((CPUARMState *)env));
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE       4096
+
+enum {
+    ARM_HWCAP_A64_FP            = 1 << 0,
+    ARM_HWCAP_A64_ASIMD         = 1 << 1,
+    ARM_HWCAP_A64_EVTSTRM       = 1 << 2,
+    ARM_HWCAP_A64_AES           = 1 << 3,
+    ARM_HWCAP_A64_PMULL         = 1 << 4,
+    ARM_HWCAP_A64_SHA1          = 1 << 5,
+    ARM_HWCAP_A64_SHA2          = 1 << 6,
+    ARM_HWCAP_A64_CRC32         = 1 << 7,
+};
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+    ARMCPU *cpu = ARM_CPU(thread_cpu);
+    uint32_t hwcaps = 0;
+
+    hwcaps |= ARM_HWCAP_A64_FP;
+    hwcaps |= ARM_HWCAP_A64_ASIMD;
+
+    /* probe for the extra features */
+#define GET_FEATURE(feat, hwcap) \
+    do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+    GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP_A64_PMULL);
+#undef GET_FEATURE
+
+    return hwcaps;
+}
+
+#endif /* not TARGET_AARCH64 */
+#endif /* TARGET_ARM */
 
 #ifdef TARGET_UNICORE32
 
commit 24682654654a2e7b50afc27880f4098e5fca3742
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 2 14:45:13 2014 +0100

    linux-user/elfload.c: Update ARM HWCAP bits
    
    The kernel has added support for a number of new ARM HWCAP bits;
    add them to QEMU, including support for setting them where we have
    a corresponding CPU feature bit.
    
    We were also incorrectly setting the VFPv3D16 HWCAP -- this means
    "only 16 D registers", not "supports 16-bit floating point format";
    since QEMU always has 32 D registers for VFPv3, we can just remove
    the line that incorrectly set this bit.
    
    The kernel does not set the HWCAP_FPA even if it is providing FPA
    emulation via nwfpe, so don't set this bit in QEMU either.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 18ea1b3..d372300 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -351,6 +351,13 @@ enum
     ARM_HWCAP_ARM_NEON      = 1 << 12,
     ARM_HWCAP_ARM_VFPv3     = 1 << 13,
     ARM_HWCAP_ARM_VFPv3D16  = 1 << 14,
+    ARM_HWCAP_ARM_TLS       = 1 << 15,
+    ARM_HWCAP_ARM_VFPv4     = 1 << 16,
+    ARM_HWCAP_ARM_IDIVA     = 1 << 17,
+    ARM_HWCAP_ARM_IDIVT     = 1 << 18,
+    ARM_HWCAP_ARM_VFPD32    = 1 << 19,
+    ARM_HWCAP_ARM_LPAE      = 1 << 20,
+    ARM_HWCAP_ARM_EVTSTRM   = 1 << 21,
 };
 
 #ifndef TARGET_AARCH64
@@ -428,17 +435,28 @@ static uint32_t get_elf_hwcap(void)
     hwcaps |= ARM_HWCAP_ARM_HALF;
     hwcaps |= ARM_HWCAP_ARM_THUMB;
     hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
-    hwcaps |= ARM_HWCAP_ARM_FPA;
 
     /* probe for the extra features */
 #define GET_FEATURE(feat, hwcap) \
     do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+    /* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
+    GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
     GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
     GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
     GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
     GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
     GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
-    GET_FEATURE(ARM_FEATURE_VFP_FP16, ARM_HWCAP_ARM_VFPv3D16);
+    GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
+    GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
+    GET_FEATURE(ARM_FEATURE_ARM_DIV, ARM_HWCAP_ARM_IDIVA);
+    GET_FEATURE(ARM_FEATURE_THUMB_DIV, ARM_HWCAP_ARM_IDIVT);
+    /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
+     * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
+     * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
+     * to our VFP_FP16 feature bit.
+     */
+    GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPD32);
+    GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
 #undef GET_FEATURE
 
     return hwcaps;
commit 43ce393ee5f7b96d2ac22fedc40d6b6fb3f65a3e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 2 14:45:12 2014 +0100

    linux-user/elfload.c: Fix incorrect ARM HWCAP bits
    
    The ELF HWCAP bits for ARM features THUMBEE, NEON, VFPv3 and VFPv3D16 are
    all off by one compared to the kernel definitions. Fix this discrepancy
    and add in the missing CRUNCH bit which was the cause of the off-by-one
    error. (We don't emulate any of the CPUs which have that weird hardware,
    so it's otherwise uninteresting to us.)
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ecf6f35..18ea1b3 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -346,10 +346,11 @@ enum
     ARM_HWCAP_ARM_EDSP      = 1 << 7,
     ARM_HWCAP_ARM_JAVA      = 1 << 8,
     ARM_HWCAP_ARM_IWMMXT    = 1 << 9,
-    ARM_HWCAP_ARM_THUMBEE   = 1 << 10,
-    ARM_HWCAP_ARM_NEON      = 1 << 11,
-    ARM_HWCAP_ARM_VFPv3     = 1 << 12,
-    ARM_HWCAP_ARM_VFPv3D16  = 1 << 13,
+    ARM_HWCAP_ARM_CRUNCH    = 1 << 10,
+    ARM_HWCAP_ARM_THUMBEE   = 1 << 11,
+    ARM_HWCAP_ARM_NEON      = 1 << 12,
+    ARM_HWCAP_ARM_VFPv3     = 1 << 13,
+    ARM_HWCAP_ARM_VFPv3D16  = 1 << 14,
 };
 
 #ifndef TARGET_AARCH64
commit e586822a58b6609edb5ea929e8a4aa394d32389f
Author: Riku Voipio <riku.voipio at linaro.org>
Date:   Tue Mar 4 04:28:43 2014 +0200

    linux-user: remove configure option for setting uname release
    
    --enable-uname-release was a rather heavyweight hammer, as it allows
    providing values less that UNAME_MINIMUM_RELEASE. Also, it affects
    all built linux-user targets, which in most cases is not what user
    wants.
    
    Now that we have UNAME_MINIMUM_RELEASE for all linux-user platforms,
    we can drop --enable-uname-release and the related CONFIG_UNAME_RELEASE
    define.
    
    Users can still override the variable with QEMU_UNAME=2.6.32 or -r
    command line option. If distributors need to update a minimum version
    for a specific target, it can be done by updating UNAME_MINIMUM_RELEASE.
    
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/configure b/configure
index 870c939..8c50d78 100755
--- a/configure
+++ b/configure
@@ -285,7 +285,6 @@ softmmu="yes"
 linux_user="no"
 bsd_user="no"
 guest_base="yes"
-uname_release=""
 aix="no"
 blobs="yes"
 pkgversion=""
@@ -945,8 +944,6 @@ for opt do
   ;;
   --disable-pie) pie="no"
   ;;
-  --enable-uname-release=*) uname_release="$optarg"
-  ;;
   --enable-werror) werror="yes"
   ;;
   --disable-werror) werror="no"
@@ -1295,7 +1292,6 @@ Advanced options (experts only):
   --fmod-lib               path to FMOD library
   --fmod-inc               path to FMOD includes
   --oss-lib                path to OSS library
-  --enable-uname-release=R Return R for uname -r in usermode emulation
   --cpu=CPU                Build for host CPU [$cpu]
   --disable-uuid           disable uuid support
   --enable-uuid            enable uuid support
@@ -4128,8 +4124,6 @@ echo "xen support       $xen"
 echo "brlapi support    $brlapi"
 echo "bluez  support    $bluez"
 echo "Documentation     $docs"
-[ ! -z "$uname_release" ] && \
-echo "uname -r          $uname_release"
 echo "GUEST_BASE        $guest_base"
 echo "PIE               $pie"
 echo "vde support       $vde"
@@ -4544,8 +4538,6 @@ if [ "$bsd" = "yes" ] ; then
   echo "CONFIG_BSD=y" >> $config_host_mak
 fi
 
-echo "CONFIG_UNAME_RELEASE=\"$uname_release\"" >> $config_host_mak
-
 if test "$zero_malloc" = "yes" ; then
   echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
 fi
diff --git a/linux-user/main.c b/linux-user/main.c
index 947358a..c38fecf 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -69,7 +69,7 @@ unsigned long reserved_va;
 static void usage(void);
 
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
-const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
+const char *qemu_uname_release;
 
 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
    we allocate a bigger stack. Need a better solution, for example
diff --git a/linux-user/uname.c b/linux-user/uname.c
index fa5013e..f5d4c66 100644
--- a/linux-user/uname.c
+++ b/linux-user/uname.c
@@ -155,7 +155,6 @@ void init_qemu_uname_release(void)
      * a specific fake version number, we might want to fake a minimum
      * target kernel version.
      */
-#ifdef UNAME_MINIMUM_RELEASE
     struct new_utsname buf;
 
     if (qemu_uname_release && *qemu_uname_release) {
@@ -169,5 +168,4 @@ void init_qemu_uname_release(void)
     if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
         qemu_uname_release = UNAME_MINIMUM_RELEASE;
     }
-#endif
 }
commit 6d30db19caab3cc71a9353cab772b258f0545503
Author: Riku Voipio <riku.voipio at linaro.org>
Date:   Wed Feb 19 15:35:35 2014 +0200

    linux-user: move uname functions to uname.c
    
    Make syscall.c slightly smaller by moving uname-related
    functions to uname.c.
    
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0f4a092..9fc28bd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -60,7 +60,6 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <sys/statfs.h>
 #include <utime.h>
 #include <sys/sysinfo.h>
-#include <sys/utsname.h>
 //#include <sys/user.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
@@ -92,7 +91,6 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 
 #include <linux/termios.h>
 #include <linux/unistd.h>
-#include <linux/utsname.h>
 #include <linux/cdrom.h>
 #include <linux/hdreg.h>
 #include <linux/soundcard.h>
@@ -287,40 +285,6 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
   { 0, 0, 0, 0 }
 };
 
-#define COPY_UTSNAME_FIELD(dest, src) \
-  do { \
-      /* __NEW_UTS_LEN doesn't include terminating null */ \
-      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
-      (dest)[__NEW_UTS_LEN] = '\0'; \
-  } while (0)
-
-static int sys_uname(struct new_utsname *buf)
-{
-  struct utsname uts_buf;
-
-  if (uname(&uts_buf) < 0)
-      return (-1);
-
-  /*
-   * Just in case these have some differences, we
-   * translate utsname to new_utsname (which is the
-   * struct linux kernel uses).
-   */
-
-  memset(buf, 0, sizeof(*buf));
-  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
-  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
-  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
-  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
-  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
-#ifdef _GNU_SOURCE
-  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
-#endif
-  return (0);
-
-#undef COPY_UTSNAME_FIELD
-}
-
 static int sys_getcwd1(char *buf, size_t size)
 {
   if (getcwd(buf, size) == NULL) {
@@ -4983,72 +4947,6 @@ int host_to_target_waitstatus(int status)
     return status;
 }
 
-static int relstr_to_int(const char *s)
-{
-    /* Convert a uname release string like "2.6.18" to an integer
-     * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
-     */
-    int i, n, tmp;
-
-    tmp = 0;
-    for (i = 0; i < 3; i++) {
-        n = 0;
-        while (*s >= '0' && *s <= '9') {
-            n *= 10;
-            n += *s - '0';
-            s++;
-        }
-        tmp = (tmp << 8) + n;
-        if (*s == '.') {
-            s++;
-        }
-    }
-    return tmp;
-}
-
-int get_osversion(void)
-{
-    static int osversion;
-    struct new_utsname buf;
-    const char *s;
-
-    if (osversion)
-        return osversion;
-    if (qemu_uname_release && *qemu_uname_release) {
-        s = qemu_uname_release;
-    } else {
-        if (sys_uname(&buf))
-            return 0;
-        s = buf.release;
-    }
-    osversion = relstr_to_int(s);
-    return osversion;
-}
-
-void init_qemu_uname_release(void)
-{
-    /* Initialize qemu_uname_release for later use.
-     * If the host kernel is too old and the user hasn't asked for
-     * a specific fake version number, we might want to fake a minimum
-     * target kernel version.
-     */
-#ifdef UNAME_MINIMUM_RELEASE
-    struct new_utsname buf;
-
-    if (qemu_uname_release && *qemu_uname_release) {
-        return;
-    }
-
-    if (sys_uname(&buf)) {
-        return;
-    }
-
-    if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
-        qemu_uname_release = UNAME_MINIMUM_RELEASE;
-    }
-#endif
-}
-
 static int open_self_maps(void *cpu_env, int fd)
 {
 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
diff --git a/linux-user/uname.c b/linux-user/uname.c
index 26e90e5..fa5013e 100644
--- a/linux-user/uname.c
+++ b/linux-user/uname.c
@@ -70,3 +70,104 @@ const char *cpu_to_uname_machine(void *cpu_env)
     return UNAME_MACHINE;
 #endif
 }
+
+
+#define COPY_UTSNAME_FIELD(dest, src) \
+  do { \
+      /* __NEW_UTS_LEN doesn't include terminating null */ \
+      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
+      (dest)[__NEW_UTS_LEN] = '\0'; \
+  } while (0)
+
+int sys_uname(struct new_utsname *buf)
+{
+  struct utsname uts_buf;
+
+  if (uname(&uts_buf) < 0)
+      return (-1);
+
+  /*
+   * Just in case these have some differences, we
+   * translate utsname to new_utsname (which is the
+   * struct linux kernel uses).
+   */
+
+  memset(buf, 0, sizeof(*buf));
+  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
+  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
+  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
+  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
+  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
+#ifdef _GNU_SOURCE
+  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
+#endif
+  return (0);
+
+#undef COPY_UTSNAME_FIELD
+}
+
+static int relstr_to_int(const char *s)
+{
+    /* Convert a uname release string like "2.6.18" to an integer
+     * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
+     */
+    int i, n, tmp;
+
+    tmp = 0;
+    for (i = 0; i < 3; i++) {
+        n = 0;
+        while (*s >= '0' && *s <= '9') {
+            n *= 10;
+            n += *s - '0';
+            s++;
+        }
+        tmp = (tmp << 8) + n;
+        if (*s == '.') {
+            s++;
+        }
+    }
+    return tmp;
+}
+
+int get_osversion(void)
+{
+    static int osversion;
+    struct new_utsname buf;
+    const char *s;
+
+    if (osversion)
+        return osversion;
+    if (qemu_uname_release && *qemu_uname_release) {
+        s = qemu_uname_release;
+    } else {
+        if (sys_uname(&buf))
+            return 0;
+        s = buf.release;
+    }
+    osversion = relstr_to_int(s);
+    return osversion;
+}
+
+void init_qemu_uname_release(void)
+{
+    /* Initialize qemu_uname_release for later use.
+     * If the host kernel is too old and the user hasn't asked for
+     * a specific fake version number, we might want to fake a minimum
+     * target kernel version.
+     */
+#ifdef UNAME_MINIMUM_RELEASE
+    struct new_utsname buf;
+
+    if (qemu_uname_release && *qemu_uname_release) {
+        return;
+    }
+
+    if (sys_uname(&buf)) {
+        return;
+    }
+
+    if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) {
+        qemu_uname_release = UNAME_MINIMUM_RELEASE;
+    }
+#endif
+}
diff --git a/linux-user/uname.h b/linux-user/uname.h
index 32492de..cc62e76 100644
--- a/linux-user/uname.h
+++ b/linux-user/uname.h
@@ -1 +1,10 @@
+#ifndef UNAME_H
+#define UNAME_H 1
+
+#include <sys/utsname.h>
+#include <linux/utsname.h>
+
 const char *cpu_to_uname_machine(void *cpu_env);
+int sys_uname(struct new_utsname *buf);
+
+#endif /* UNAME _H */
commit 18cb008865d078c30f8efcd28c774788ae13d6a3
Author: Riku Voipio <riku.voipio at linaro.org>
Date:   Wed Feb 19 12:59:58 2014 +0200

    linux-user: rename cpu-uname -> uname
    
    To move more uname related functions out of syscall.c,
    rename cpu-uname.{c,h} to uname.{c.h}
    
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
index 5899d72..fd50217 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,5 +1,5 @@
 obj-y = main.o syscall.o strace.o mmap.o signal.o \
-	elfload.o linuxload.o uaccess.o cpu-uname.o
+	elfload.o linuxload.o uaccess.o uname.o
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 obj-$(TARGET_I386) += vm86.o
diff --git a/linux-user/cpu-uname.c b/linux-user/cpu-uname.c
deleted file mode 100644
index 5db6e89..0000000
--- a/linux-user/cpu-uname.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  cpu to uname machine name map
- *
- *  Copyright (c) 2009 Loïc Minier
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-
-#include "qemu.h"
-//#include "qemu-common.h"
-#include "cpu-uname.h"
-
-/* return highest utsname machine name for emulated instruction set
- *
- * NB: the default emulated CPU ("any") might not match any existing CPU, e.g.
- * on ARM it has all features turned on, so there is no perfect arch string to
- * return here */
-const char *cpu_to_uname_machine(void *cpu_env)
-{
-#if defined(TARGET_ARM) && !defined(TARGET_AARCH64)
-
-    /* utsname machine name on linux arm is CPU arch name + endianness, e.g.
-     * armv7l; to get a list of CPU arch names from the linux source, use:
-     *     grep arch_name: -A1 linux/arch/arm/mm/proc-*.S
-     * see arch/arm/kernel/setup.c: setup_processor()
-     */
-
-    /* in theory, endianness is configurable on some ARM CPUs, but this isn't
-     * used in user mode emulation */
-#ifdef TARGET_WORDS_BIGENDIAN
-#define utsname_suffix "b"
-#else
-#define utsname_suffix "l"
-#endif
-    if (arm_feature(cpu_env, ARM_FEATURE_V7))
-        return "armv7" utsname_suffix;
-    if (arm_feature(cpu_env, ARM_FEATURE_V6))
-        return "armv6" utsname_suffix;
-    /* earliest emulated CPU is ARMv5TE; qemu can emulate the 1026, but not its
-     * Jazelle support */
-    return "armv5te" utsname_suffix;
-#elif defined(TARGET_X86_64)
-    return "x86-64";
-#elif defined(TARGET_I386)
-    /* see arch/x86/kernel/cpu/bugs.c: check_bugs(), 386, 486, 586, 686 */
-    CPUState *cpu = ENV_GET_CPU((CPUX86State *)cpu_env);
-    int family = object_property_get_int(OBJECT(cpu), "family", NULL);
-    if (family == 4) {
-        return "i486";
-    }
-    if (family == 5) {
-        return "i586";
-    }
-    return "i686";
-#else
-    /* default is #define-d in each arch/ subdir */
-    return UNAME_MACHINE;
-#endif
-}
diff --git a/linux-user/cpu-uname.h b/linux-user/cpu-uname.h
deleted file mode 100644
index 32492de..0000000
--- a/linux-user/cpu-uname.h
+++ /dev/null
@@ -1 +0,0 @@
-const char *cpu_to_uname_machine(void *cpu_env);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index af0bb35..0f4a092 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -110,7 +110,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <linux/filter.h>
 #include <linux/blkpg.h>
 #include "linux_loop.h"
-#include "cpu-uname.h"
+#include "uname.h"
 
 #include "qemu.h"
 
diff --git a/linux-user/uname.c b/linux-user/uname.c
new file mode 100644
index 0000000..26e90e5
--- /dev/null
+++ b/linux-user/uname.c
@@ -0,0 +1,72 @@
+/*
+ *  cpu to uname machine name map
+ *
+ *  Copyright (c) 2009 Loïc Minier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include "qemu.h"
+//#include "qemu-common.h"
+#include "uname.h"
+
+/* return highest utsname machine name for emulated instruction set
+ *
+ * NB: the default emulated CPU ("any") might not match any existing CPU, e.g.
+ * on ARM it has all features turned on, so there is no perfect arch string to
+ * return here */
+const char *cpu_to_uname_machine(void *cpu_env)
+{
+#if defined(TARGET_ARM) && !defined(TARGET_AARCH64)
+
+    /* utsname machine name on linux arm is CPU arch name + endianness, e.g.
+     * armv7l; to get a list of CPU arch names from the linux source, use:
+     *     grep arch_name: -A1 linux/arch/arm/mm/proc-*.S
+     * see arch/arm/kernel/setup.c: setup_processor()
+     */
+
+    /* in theory, endianness is configurable on some ARM CPUs, but this isn't
+     * used in user mode emulation */
+#ifdef TARGET_WORDS_BIGENDIAN
+#define utsname_suffix "b"
+#else
+#define utsname_suffix "l"
+#endif
+    if (arm_feature(cpu_env, ARM_FEATURE_V7))
+        return "armv7" utsname_suffix;
+    if (arm_feature(cpu_env, ARM_FEATURE_V6))
+        return "armv6" utsname_suffix;
+    /* earliest emulated CPU is ARMv5TE; qemu can emulate the 1026, but not its
+     * Jazelle support */
+    return "armv5te" utsname_suffix;
+#elif defined(TARGET_X86_64)
+    return "x86-64";
+#elif defined(TARGET_I386)
+    /* see arch/x86/kernel/cpu/bugs.c: check_bugs(), 386, 486, 586, 686 */
+    CPUState *cpu = ENV_GET_CPU((CPUX86State *)cpu_env);
+    int family = object_property_get_int(OBJECT(cpu), "family", NULL);
+    if (family == 4) {
+        return "i486";
+    }
+    if (family == 5) {
+        return "i586";
+    }
+    return "i686";
+#else
+    /* default is #define-d in each arch/ subdir */
+    return UNAME_MACHINE;
+#endif
+}
diff --git a/linux-user/uname.h b/linux-user/uname.h
new file mode 100644
index 0000000..32492de
--- /dev/null
+++ b/linux-user/uname.h
@@ -0,0 +1 @@
+const char *cpu_to_uname_machine(void *cpu_env);
commit 7af03928b1194befa1ad12e25b0e53e6770ba18c
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 1 18:36:17 2014 +0100

    linux-user/signal.c: Set fault address in AArch64 signal info
    
    Set the fault address correctly in the signal information passed
    to a signal handler for AArch64 guests.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 7d6246f..5b8a01f 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -1242,8 +1242,7 @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
     __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
     __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
 
-    __put_user(/*current->thread.fault_address*/ 0,
-            &sf->uc.tuc_mcontext.fault_address);
+    __put_user(env->exception.vaddress, &sf->uc.tuc_mcontext.fault_address);
 
     for (i = 0; i < TARGET_NSIG_WORDS; i++) {
         __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
commit 34d6086236baeb59f4b46e2380f2b271acd6f6cf
Author: Natanael Copa <ncopa at alpinelinux.org>
Date:   Tue Apr 29 13:11:20 2014 +0200

    linux-user: avoid using glibc internals in _syscall5 and in definition of target_sigevent struct
    
    Use the public sigset_t instead of the glibc specific internal
    __sigset_t in _syscall.
    
    Calculate the sigevent pad size is calculated in similar way as kernel
    does it instead of using glibc internal field _pad.
    
    This is needed for building with musl libc.
    
    Signed-off-by: Natanael Copa <ncopa at alpinelinux.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 15de6f8..af0bb35 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -411,7 +411,7 @@ static int sys_inotify_init1(int flags)
 #endif
 #define __NR_sys_ppoll __NR_ppoll
 _syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
-          struct timespec *, timeout, const __sigset_t *, sigmask,
+          struct timespec *, timeout, const sigset_t *, sigmask,
           size_t, sigsetsize)
 #endif
 
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index fdf9a47..69c3982 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2552,12 +2552,26 @@ struct target_timer_t {
     abi_ulong ptr;
 };
 
+#define TARGET_SIGEV_MAX_SIZE 64
+
+/* This is architecture-specific but most architectures use the default */
+#ifdef TARGET_MIPS
+#define TARGET_SIGEV_PREAMBLE_SIZE (sizeof(int32_t) * 2 + sizeof(abi_long))
+#else
+#define TARGET_SIGEV_PREAMBLE_SIZE (sizeof(int32_t) * 2 \
+                                    + sizeof(target_sigval_t))
+#endif
+
+#define TARGET_SIGEV_PAD_SIZE ((TARGET_SIGEV_MAX_SIZE \
+                                - TARGET_SIGEV_PREAMBLE_SIZE) \
+                               / sizeof(int32_t))
+
 struct target_sigevent {
     target_sigval_t sigev_value;
     int32_t sigev_signo;
     int32_t sigev_notify;
     union {
-        int32_t _pad[ARRAY_SIZE(((struct sigevent *)0)->_sigev_un._pad)];
+        int32_t _pad[TARGET_SIGEV_PAD_SIZE];
         int32_t _tid;
 
         struct {
commit a29e5ba21f3dc01cd7f12aac9216e06e7bdd0e9e
Author: James Hogan <james.hogan at imgtec.com>
Date:   Tue Mar 25 21:51:08 2014 +0000

    linux-user: Handle arches with llseek instead of _llseek
    
    Recently merged kernel ports (such as OpenRISC and Meta) have an llseek
    system call instead of _llseek. This is handled for the host
    architecture by defining __NR__llseek as __NR_llseek, but not for the
    target architecture.
    
    Handle it in the same way for these architectures, defining
    TARGET_NR__llseek as TARGET_NR_llseek.
    
    Signed-off-by: James Hogan <james.hogan at imgtec.com>
    Cc: Riku Voipio <riku.voipio at iki.fi>
    Cc: Jia Liu <proljc at gmail.com>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 27073b1..15de6f8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -198,6 +198,11 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
 #define __NR__llseek __NR_lseek
 #endif
 
+/* Newer kernel ports have llseek() instead of _llseek() */
+#if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek)
+#define TARGET_NR__llseek TARGET_NR_llseek
+#endif
+
 #ifdef __NR_gettid
 _syscall0(int, gettid)
 #else
commit 4bc2975698773afdca2f79ebcff9f3b588f646fc
Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Apr 17 14:02:48 2014 +0100

    linux-user: Add support for SCM_CREDENTIALS.
    
    Signed-off-by: Huw Davies <huw at codeweavers.com>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 52bd000..27073b1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1269,6 +1269,17 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
                 target_tv->tv_usec = tswapal(tv->tv_usec);
                 break;
             }
+            case SCM_CREDENTIALS:
+            {
+                struct ucred *cred = (struct ucred *)data;
+                struct target_ucred *target_cred =
+                    (struct target_ucred *)target_data;
+
+                __put_user(cred->pid, &target_cred->pid);
+                __put_user(cred->uid, &target_cred->uid);
+                __put_user(cred->gid, &target_cred->gid);
+                break;
+            }
             default:
                 goto unimplemented;
             }
commit 52b6549442988e0a0819b6b7fb36ded164952a34
Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Apr 17 14:02:47 2014 +0100

    linux-user: Move if-elses to a switch statement.
    
    This makes adding more message types cleaner.
    
    Signed-off-by: Huw Davies <huw at codeweavers.com>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5203cc4..52bd000 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1242,25 +1242,40 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
         target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
         target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
 
-        if ((cmsg->cmsg_level == SOL_SOCKET) &&
-                                (cmsg->cmsg_type == SCM_RIGHTS)) {
-            int *fd = (int *)data;
-            int *target_fd = (int *)target_data;
-            int i, numfds = len / sizeof(int);
+        switch (cmsg->cmsg_level) {
+        case SOL_SOCKET:
+            switch (cmsg->cmsg_type) {
+            case SCM_RIGHTS:
+            {
+                int *fd = (int *)data;
+                int *target_fd = (int *)target_data;
+                int i, numfds = len / sizeof(int);
 
-            for (i = 0; i < numfds; i++)
-                target_fd[i] = tswap32(fd[i]);
-        } else if ((cmsg->cmsg_level == SOL_SOCKET) &&
-                                (cmsg->cmsg_type == SO_TIMESTAMP) &&
-                                (len == sizeof(struct timeval))) {
-            /* copy struct timeval to target */
-            struct timeval *tv = (struct timeval *)data;
-            struct target_timeval *target_tv =
-                                        (struct target_timeval *)target_data;
-
-            target_tv->tv_sec = tswapal(tv->tv_sec);
-            target_tv->tv_usec = tswapal(tv->tv_usec);
-        } else {
+                for (i = 0; i < numfds; i++)
+                    target_fd[i] = tswap32(fd[i]);
+                break;
+            }
+            case SO_TIMESTAMP:
+            {
+                struct timeval *tv = (struct timeval *)data;
+                struct target_timeval *target_tv =
+                    (struct target_timeval *)target_data;
+
+                if (len != sizeof(struct timeval))
+                    goto unimplemented;
+
+                /* copy struct timeval to target */
+                target_tv->tv_sec = tswapal(tv->tv_sec);
+                target_tv->tv_usec = tswapal(tv->tv_usec);
+                break;
+            }
+            default:
+                goto unimplemented;
+            }
+            break;
+
+        default:
+        unimplemented:
             gemu_log("Unsupported ancillary data: %d/%d\n",
                                         cmsg->cmsg_level, cmsg->cmsg_type);
             memcpy(target_data, data, len);
commit 8c0f0a60d48a6f62c20f4ce77dceb82047d3d57f
Author: James Hogan <james.hogan at imgtec.com>
Date:   Tue Mar 25 23:21:50 2014 +0000

    linux-user: Assert stack used for auxvec, envp, argv
    
    Assert that the amount of stack space used for auxvec, envp & argv
    exactly matches the amount allocated. This catches if DLINFO_ITEMS isn't
    updated when another NEW_AUX_ENT is added.
    
    Signed-off-by: James Hogan <james.hogan at imgtec.com>
    Cc: Riku Voipio <riku.voipio at iki.fi>
    Cc: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index d2380b6..ecf6f35 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1455,6 +1455,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     info->auxv_len = sp_auxv - sp;
 
     sp = loader_build_argptr(envc, argc, sp, p, 0);
+    /* Check the right amount of stack was allocated for auxvec, envp & argv. */
+    assert(sp_auxv - sp == size);
     return sp;
 }
 
commit aa07f5ecf9828bb2ff8d796cb0b17ad8534201c7
Author: Maxim Ostapenko <m.ostapenko at partner.samsung.com>
Date:   Fri May 2 11:17:07 2014 +0300

    linux-user: Add /proc/self/exe open forwarding
    
    QEMU already supports /proc/self/{maps,stat,auxv} so addition of
    /proc/self/exe is rather trivial.
    
    Fixes https://bugs.launchpad.net/qemu/+bug/1299190
    
    Signed-off-by: Maxim Ostapenko <m.ostapenko at partner.samsung.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9864813..5203cc4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5225,6 +5225,11 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
         { NULL, NULL, NULL }
     };
 
+    if (is_proc_myself(pathname, "exe")) {
+        int execfd = qemu_getauxval(AT_EXECFD);
+        return execfd ? execfd : get_errno(open(exec_path, flags, mode));
+    }
+
     for (fake_open = fakes; fake_open->filename; fake_open++) {
         if (fake_open->cmp(pathname, fake_open->filename)) {
             break;


More information about the Spice-commits mailing list