Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20150127' into staging

linux-user updates since last pull request

# gpg: Signature made Tue 27 Jan 2015 20:52:54 GMT using RSA key ID DE3C9BC0
# gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>"
# gpg:                 aka "Riku Voipio <riku.voipio@linaro.org>"

* remotes/riku/tags/pull-linux-user-20150127:
  linux-user: support target-to-host SCM_CREDENTIALS
  linux-user: Fix broken m68k signal handling on 64 bit hosts
  mips64-linux-user: Fix definition of struct sigaltstack
  linux-user: Fix ioctl cmd type mismatch on 64-bit targets
  linux-user: translate resource also for prlimit64
  linux-user/signal.c: Remove unnecessary wrapper copy_siginfo_to_user
  linux-user/main.c: Mark end_exclusive() as possibly unused
  linux-user/main.c: Call cpu_exec_start/end on all target archs
  linux-user/arm/nwfpe: Delete unused aCC array
  linux-user/alpha: Add define for NR_shmat to enable shmat syscall
  linux-user/signal.c: Remove current_exec_domain_sig()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h
index 625f301..dde8d5c 100644
--- a/linux-user/alpha/syscall_nr.h
+++ b/linux-user/alpha/syscall_nr.h
@@ -185,6 +185,10 @@
 #define TARGET_NR_osf_utsname	207
 #define TARGET_NR_lchown		208
 #define TARGET_NR_osf_shmat		209
+/* this has the usual shmat semantics so give it the name syscall.c expects
+ * so that our support for it is enabled.
+ */
+#define TARGET_NR_shmat TARGET_NR_osf_shmat
 #define TARGET_NR_shmctl		210
 #define TARGET_NR_shmdt		211
 #define TARGET_NR_shmget		212
diff --git a/linux-user/arm/nwfpe/fpopcode.c b/linux-user/arm/nwfpe/fpopcode.c
index 0dc5c9c..0ada30c 100644
--- a/linux-user/arm/nwfpe/fpopcode.c
+++ b/linux-user/arm/nwfpe/fpopcode.c
@@ -88,25 +88,3 @@
 
   return(nRc);
 }
-
-/* condition code lookup table
- index into the table is test code: EQ, NE, ... LT, GT, AL, NV
- bit position in short is condition code: NZCV */
-static const unsigned short aCC[16] = {
-    0xF0F0, // EQ == Z set
-    0x0F0F, // NE
-    0xCCCC, // CS == C set
-    0x3333, // CC
-    0xFF00, // MI == N set
-    0x00FF, // PL
-    0xAAAA, // VS == V set
-    0x5555, // VC
-    0x0C0C, // HI == C set && Z clear
-    0xF3F3, // LS == C clear || Z set
-    0xAA55, // GE == (N==V)
-    0x55AA, // LT == (N!=V)
-    0x0A05, // GT == (!Z && (N==V))
-    0xF5FA, // LE == (Z || (N!=V))
-    0xFFFF, // AL always
-    0 // NV
-};
diff --git a/linux-user/main.c b/linux-user/main.c
index 8c70be4..cfa7d07 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -169,7 +169,7 @@
 }
 
 /* Finish an exclusive operation.  */
-static inline void end_exclusive(void)
+static inline void __attribute__((unused)) end_exclusive(void)
 {
     pending_cpus = 0;
     pthread_cond_broadcast(&exclusive_resume);
@@ -283,7 +283,9 @@
     target_siginfo_t info;
 
     for(;;) {
+        cpu_exec_start(cs);
         trapnr = cpu_x86_exec(env);
+        cpu_exec_end(cs);
         switch(trapnr) {
         case 0x80:
             /* linux syscall from int $0x80 */
@@ -1288,7 +1290,9 @@
     target_siginfo_t info;
 
     while (1) {
+        cpu_exec_start(cs);
         trapnr = cpu_sparc_exec (env);
+        cpu_exec_end(cs);
 
         /* Compute PSR before exposing state.  */
         if (env->cc_op != CC_OP_FLAGS) {
@@ -2656,7 +2660,9 @@
     int trapnr, gdbsig;
 
     for (;;) {
+        cpu_exec_start(cs);
         trapnr = cpu_exec(env);
+        cpu_exec_end(cs);
         gdbsig = 0;
 
         switch (trapnr) {
@@ -2744,7 +2750,9 @@
     target_siginfo_t info;
 
     while (1) {
+        cpu_exec_start(cs);
         trapnr = cpu_sh4_exec (env);
+        cpu_exec_end(cs);
 
         switch (trapnr) {
         case 0x160:
@@ -2804,7 +2812,9 @@
     target_siginfo_t info;
     
     while (1) {
+        cpu_exec_start(cs);
         trapnr = cpu_cris_exec (env);
+        cpu_exec_end(cs);
         switch (trapnr) {
         case 0xaa:
             {
@@ -2863,7 +2873,9 @@
     target_siginfo_t info;
     
     while (1) {
+        cpu_exec_start(cs);
         trapnr = cpu_mb_exec (env);
+        cpu_exec_end(cs);
         switch (trapnr) {
         case 0xaa:
             {
@@ -2966,7 +2978,9 @@
     TaskState *ts = cs->opaque;
 
     for(;;) {
+        cpu_exec_start(cs);
         trapnr = cpu_m68k_exec(env);
+        cpu_exec_end(cs);
         switch(trapnr) {
         case EXCP_ILLEGAL:
             {
@@ -3103,7 +3117,9 @@
     abi_long sysret;
 
     while (1) {
+        cpu_exec_start(cs);
         trapnr = cpu_alpha_exec (env);
+        cpu_exec_end(cs);
 
         /* All of the traps imply a transition through PALcode, which
            implies an REI instruction has been executed.  Which means
@@ -3289,7 +3305,9 @@
     target_ulong addr;
 
     while (1) {
+        cpu_exec_start(cs);
         trapnr = cpu_s390x_exec(env);
+        cpu_exec_end(cs);
         switch (trapnr) {
         case EXCP_INTERRUPT:
             /* Just indicate that signals should be handled asap.  */
diff --git a/linux-user/mips64/target_signal.h b/linux-user/mips64/target_signal.h
index 6e1dc8b..5fb6a2c 100644
--- a/linux-user/mips64/target_signal.h
+++ b/linux-user/mips64/target_signal.h
@@ -8,7 +8,7 @@
 typedef struct target_sigaltstack {
 	abi_long ss_sp;
 	abi_ulong ss_size;
-	abi_long ss_flags;
+	abi_int ss_flags;
 } target_stack_t;
 
 
diff --git a/linux-user/signal.c b/linux-user/signal.c
index e11b208..5bb399e 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -732,18 +732,6 @@
     return ret;
 }
 
-static inline void copy_siginfo_to_user(target_siginfo_t *tinfo,
-                                       const target_siginfo_t *info)
-{
-    tswap_siginfo(tinfo, info);
-}
-
-static inline int current_exec_domain_sig(int sig)
-{
-    return /* current->exec_domain && current->exec_domain->signal_invmap
-	      && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
-}
-
 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
 
 /* from the Linux kernel */
@@ -926,8 +914,7 @@
 	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 		goto give_sigsegv;
 
-    __put_user(current_exec_domain_sig(sig),
-               &frame->sig);
+    __put_user(sig, &frame->sig);
 
 	setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
                          frame_addr + offsetof(struct sigframe, fpstate));
@@ -988,12 +975,12 @@
 	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 		goto give_sigsegv;
 
-    __put_user(current_exec_domain_sig(sig), &frame->sig);
+    __put_user(sig, &frame->sig);
         addr = frame_addr + offsetof(struct rt_sigframe, info);
     __put_user(addr, &frame->pinfo);
         addr = frame_addr + offsetof(struct rt_sigframe, uc);
     __put_user(addr, &frame->puc);
-	copy_siginfo_to_user(&frame->info, info);
+    tswap_siginfo(&frame->info, info);
 
 	/* Create the ucontext.  */
     __put_user(0, &frame->uc.tuc_flags);
@@ -1360,7 +1347,7 @@
     env->pc = ka->_sa_handler;
     env->xregs[30] = return_addr;
     if (info) {
-        copy_siginfo_to_user(&frame->info, info);
+        tswap_siginfo(&frame->info, info);
         env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
         env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
     }
@@ -1777,7 +1764,7 @@
 	__put_user(info_addr, &frame->pinfo);
         uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
 	__put_user(uc_addr, &frame->puc);
-	copy_siginfo_to_user(&frame->info, info);
+        tswap_siginfo(&frame->info, info);
 
 	/* Clear all the bits of the ucontext we don't use.  */
 	memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
@@ -1815,7 +1802,7 @@
 
         info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
         uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
-	copy_siginfo_to_user(&frame->info, info);
+        tswap_siginfo(&frame->info, info);
 
         setup_sigframe_v2(&frame->uc, set, env);
 
@@ -3017,7 +3004,7 @@
 
     install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
 
-    copy_siginfo_to_user(&frame->rs_info, info);
+    tswap_siginfo(&frame->rs_info, info);
 
     __put_user(0, &frame->rs_uc.tuc_flags);
     __put_user(0, &frame->rs_uc.tuc_link);
@@ -3228,14 +3215,11 @@
     abi_ulong frame_addr;
     int i;
     int err = 0;
-    int signal;
 
     frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 	goto give_sigsegv;
 
-    signal = current_exec_domain_sig(sig);
-
     setup_sigcontext(&frame->sc, regs, set->sig[0]);
 
     for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
@@ -3259,7 +3243,7 @@
 
     /* Set up registers for signal handler */
     regs->gregs[15] = frame_addr;
-    regs->gregs[4] = signal; /* Arg for signal handler */
+    regs->gregs[4] = sig; /* Arg for signal handler */
     regs->gregs[5] = 0;
     regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
     regs->pc = (unsigned long) ka->_sa_handler;
@@ -3280,15 +3264,12 @@
     abi_ulong frame_addr;
     int i;
     int err = 0;
-    int signal;
 
     frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 	goto give_sigsegv;
 
-    signal = current_exec_domain_sig(sig);
-
-    copy_siginfo_to_user(&frame->info, info);
+    tswap_siginfo(&frame->info, info);
 
     /* Create the ucontext.  */
     __put_user(0, &frame->uc.tuc_flags);
@@ -3322,7 +3303,7 @@
 
     /* Set up registers for signal handler */
     regs->gregs[15] = frame_addr;
-    regs->gregs[4] = signal; /* Arg for signal handler */
+    regs->gregs[4] = sig; /* Arg for signal handler */
     regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
     regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
     regs->pc = (unsigned long) ka->_sa_handler;
@@ -3947,7 +3928,7 @@
     __put_user(uc_addr, &frame->puc);
 
     if (ka->sa_flags & SA_SIGINFO) {
-        copy_siginfo_to_user(&frame->info, info);
+        tswap_siginfo(&frame->info, info);
     }
 
     /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
@@ -4195,7 +4176,7 @@
     }
 
     qemu_log("%s: 1\n", __FUNCTION__);
-    copy_siginfo_to_user(&frame->info, info);
+    tswap_siginfo(&frame->info, info);
 
     /* Create the ucontext.  */
     __put_user(0, &frame->uc.tuc_flags);
@@ -4680,7 +4661,6 @@
     struct target_sigcontext *sc;
     target_ulong frame_addr, newsp;
     int err = 0;
-    int signal;
 #if defined(TARGET_PPC64)
     struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
 #endif
@@ -4690,8 +4670,6 @@
         goto sigsegv;
     sc = &frame->sctx;
 
-    signal = current_exec_domain_sig(sig);
-
     __put_user(ka->_sa_handler, &sc->handler);
     __put_user(set->sig[0], &sc->oldmask);
 #if TARGET_ABI_BITS == 64
@@ -4724,7 +4702,7 @@
 
     /* Set up registers for signal handler.  */
     env->gpr[1] = newsp;
-    env->gpr[3] = signal;
+    env->gpr[3] = sig;
     env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
 
 #if defined(TARGET_PPC64)
@@ -4765,7 +4743,6 @@
     struct target_mcontext *mctx = 0;
     target_ulong rt_sf_addr, newsp = 0;
     int i, err = 0;
-    int signal;
 #if defined(TARGET_PPC64)
     struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
 #endif
@@ -4774,9 +4751,7 @@
     if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
         goto sigsegv;
 
-    signal = current_exec_domain_sig(sig);
-
-    copy_siginfo_to_user(&rt_sf->info, info);
+    tswap_siginfo(&rt_sf->info, info);
 
     __put_user(0, &rt_sf->uc.tuc_flags);
     __put_user(0, &rt_sf->uc.tuc_link);
@@ -4821,7 +4796,7 @@
 
     /* Set up registers for signal handler.  */
     env->gpr[1] = newsp;
-    env->gpr[3] = (target_ulong) signal;
+    env->gpr[3] = (target_ulong) sig;
     env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
     env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
     env->gpr[6] = (target_ulong) h2g(rt_sf);
@@ -5091,7 +5066,7 @@
     /* moveq #,d0; trap #0 */
 
     __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
-                      (long *)(frame->retcode));
+                      (uint32_t *)(frame->retcode));
 
     /* Set up to return from userspace */
 
@@ -5196,7 +5171,7 @@
     uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
     __put_user(uc_addr, &frame->puc);
 
-    copy_siginfo_to_user(&frame->info, info);
+    tswap_siginfo(&frame->info, info);
 
     /* Create the ucontext */
 
@@ -5225,8 +5200,8 @@
     /* moveq #,d0; notb d0; trap #0 */
 
     __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
-               (long *)(frame->retcode + 0));
-    __put_user(0x4e40, (short *)(frame->retcode + 4));
+               (uint32_t *)(frame->retcode + 0));
+    __put_user(0x4e40, (uint16_t *)(frame->retcode + 4));
 
     if (err)
         goto give_sigsegv;
@@ -5473,7 +5448,7 @@
         goto give_sigsegv;
     }
 
-    copy_siginfo_to_user(&frame->info, info);
+    tswap_siginfo(&frame->info, info);
 
     __put_user(0, &frame->uc.tuc_flags);
     __put_user(0, &frame->uc.tuc_link);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index aaac6a2..d4398b9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1214,16 +1214,26 @@
         cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
         cmsg->cmsg_len = CMSG_LEN(len);
 
-        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
-            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
-            memcpy(data, target_data, len);
-        } else {
+        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);
 
             for (i = 0; i < numfds; i++)
                 fd[i] = tswap32(target_fd[i]);
+        } else if (cmsg->cmsg_level == SOL_SOCKET
+               &&  cmsg->cmsg_type == SCM_CREDENTIALS) {
+            struct ucred *cred = (struct ucred *)data;
+            struct target_ucred *target_cred =
+                (struct target_ucred *)target_data;
+
+            __put_user(target_cred->pid, &cred->pid);
+            __put_user(target_cred->uid, &cred->uid);
+            __put_user(target_cred->gid, &cred->gid);
+        } else {
+            gemu_log("Unsupported ancillary data: %d/%d\n",
+                                        cmsg->cmsg_level, cmsg->cmsg_type);
+            memcpy(data, target_data, len);
         }
 
         cmsg = CMSG_NXTHDR(msgh, cmsg);
@@ -3278,7 +3288,7 @@
                              int fd, abi_long cmd, abi_long arg);
 
 struct IOCTLEntry {
-    unsigned int target_cmd;
+    int target_cmd;
     unsigned int host_cmd;
     const char *name;
     int access;
@@ -9529,6 +9539,7 @@
         /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
         struct target_rlimit64 *target_rnew, *target_rold;
         struct host_rlimit64 rnew, rold, *rnewp = 0;
+        int resource = target_to_host_resource(arg2);
         if (arg3) {
             if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
                 goto efault;
@@ -9539,7 +9550,7 @@
             rnewp = &rnew;
         }
 
-        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
+        ret = get_errno(sys_prlimit64(arg1, resource, rnewp, arg4 ? &rold : 0));
         if (!is_error(ret) && arg4) {
             if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
                 goto efault;