]> Git Repo - qemu.git/blobdiff - linux-user/syscall.c
Fix building on PPC64
[qemu.git] / linux-user / syscall.c
index 0cf4ba77cb9b977ec64b3df3c4a28d802c9e04bc..5d787bb7530ef4c2b8c0d8ea4dd29ebad102c481 100644 (file)
@@ -15,7 +15,8 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
  */
 #include <stdlib.h>
 #include <stdio.h>
@@ -28,7 +29,6 @@
 #include <fcntl.h>
 #include <time.h>
 #include <limits.h>
-#include <dirent.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
@@ -55,6 +55,9 @@
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <qemu-common.h>
+#ifdef HAVE_GPROF
+#include <sys/gmon.h>
+#endif
 
 #define termios host_termios
 #define winsize host_winsize
@@ -94,8 +97,8 @@
 #endif
 
 //#include <linux/msdos_fs.h>
-#define        VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct dirent [2])
-#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct dirent [2])
+#define        VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct linux_dirent [2])
+#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
 
 
 #undef _syscall0
@@ -153,6 +156,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,   \
 }
 
 
+#define __NR_sys_exit __NR_exit
 #define __NR_sys_uname __NR_uname
 #define __NR_sys_faccessat __NR_faccessat
 #define __NR_sys_fchmodat __NR_fchmodat
@@ -194,6 +198,7 @@ static int gettid(void) {
     return -ENOSYS;
 }
 #endif
+_syscall1(int,sys_exit,int,status)
 _syscall1(int,sys_uname,struct new_utsname *,buf)
 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
@@ -216,10 +221,10 @@ _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
 #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);
+_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
 #endif
 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
-_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
+_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
 #endif
 _syscall2(int, sys_getpriority, int, which, int, who);
 #if !defined (__x86_64__)
@@ -1063,7 +1068,7 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
 {
     struct target_iovec *target_vec;
     abi_ulong base;
-    int i, j;
+    int i;
 
     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
     if (!target_vec)
@@ -1073,8 +1078,8 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
         vec[i].iov_len = tswapl(target_vec[i].iov_len);
         if (vec[i].iov_len != 0) {
             vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
-            if (!vec[i].iov_base && vec[i].iov_len) 
-                goto fail;
+            /* Don't check lock_user return value. We must call writev even
+               if a element has invalid base address. */
         } else {
             /* zero length pointer is ignored */
             vec[i].iov_base = NULL;
@@ -1082,14 +1087,6 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
     }
     unlock_user (target_vec, target_addr, 0);
     return 0;
- fail:
-    /* failure - unwind locks */
-    for (j = 0; j < i; j++) {
-        base = tswapl(target_vec[j].iov_base);
-        unlock_user(vec[j].iov_base, base, 0);
-    }
-    unlock_user (target_vec, target_addr, 0);
-    return -TARGET_EFAULT;
 }
 
 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
@@ -1103,8 +1100,10 @@ static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
     if (!target_vec)
         return -TARGET_EFAULT;
     for(i = 0;i < count; i++) {
-        base = tswapl(target_vec[i].iov_base);
-        unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
+        if (target_vec[i].iov_base) {
+            base = tswapl(target_vec[i].iov_base);
+            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
+        }
     }
     unlock_user (target_vec, target_addr, 0);
 
@@ -1165,7 +1164,7 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr,
 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
                                int flags, int send)
 {
-    abi_long ret;
+    abi_long ret, len;
     struct target_msghdr *msgp;
     struct msghdr msg;
     int count;
@@ -1204,8 +1203,12 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
             ret = get_errno(sendmsg(fd, &msg, flags));
     } else {
         ret = get_errno(recvmsg(fd, &msg, flags));
-        if (!is_error(ret))
+        if (!is_error(ret)) {
+            len = ret;
             ret = host_to_target_cmsg(msgp, &msg);
+            if (!is_error(ret))
+                ret = len;
+        }
     }
     unlock_iovec(vec, target_vec, count, !send);
     unlock_user_struct(msgp, target_msg, send ? 0 : 1);
@@ -1619,6 +1622,7 @@ static struct shm_region {
     abi_ulong  start;
     abi_ulong  size;
 } shm_regions[N_SHM_REGIONS];
+#endif
 
 struct target_ipc_perm
 {
@@ -1846,20 +1850,26 @@ static inline abi_long do_semctl(int first, int second, int third,
 
 struct target_msqid_ds
 {
-  struct target_ipc_perm msg_perm;
-  abi_ulong msg_stime;
-  abi_ulong __unused1;
-  abi_ulong msg_rtime;
-  abi_ulong __unused2;
-  abi_ulong msg_ctime;
-  abi_ulong __unused3;
-  abi_ulong __msg_cbytes;
-  abi_ulong msg_qnum;
-  abi_ulong msg_qbytes;
-  abi_ulong msg_lspid;
-  abi_ulong msg_lrpid;
-  abi_ulong __unused4;
-  abi_ulong __unused5;
+    struct target_ipc_perm msg_perm;
+    abi_ulong msg_stime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong msg_rtime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong msg_ctime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_ulong __msg_cbytes;
+    abi_ulong msg_qnum;
+    abi_ulong msg_qbytes;
+    abi_ulong msg_lspid;
+    abi_ulong msg_lrpid;
+    abi_ulong __unused4;
+    abi_ulong __unused5;
 };
 
 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
@@ -1869,7 +1879,8 @@ static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
 
     if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
         return -TARGET_EFAULT;
-    target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
+    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
+        return -TARGET_EFAULT;
     host_md->msg_stime = tswapl(target_md->msg_stime);
     host_md->msg_rtime = tswapl(target_md->msg_rtime);
     host_md->msg_ctime = tswapl(target_md->msg_ctime);
@@ -1889,7 +1900,8 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
 
     if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
         return -TARGET_EFAULT;
-    host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
+    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
+        return -TARGET_EFAULT;
     target_md->msg_stime = tswapl(host_md->msg_stime);
     target_md->msg_rtime = tswapl(host_md->msg_rtime);
     target_md->msg_ctime = tswapl(host_md->msg_ctime);
@@ -1902,26 +1914,70 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
     return 0;
 }
 
-static inline abi_long do_msgctl(int first, int second, abi_long ptr)
+struct target_msginfo {
+    int msgpool;
+    int msgmap;
+    int msgmax;
+    int msgmnb;
+    int msgmni;
+    int msgssz;
+    int msgtql;
+    unsigned short int msgseg;
+};
+
+static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
+                                              struct msginfo *host_msginfo)
+{
+    struct target_msginfo *target_msginfo;
+    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
+        return -TARGET_EFAULT;
+    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
+    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
+    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
+    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
+    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
+    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
+    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
+    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
+    unlock_user_struct(target_msginfo, target_addr, 1);
+    return 0;
+}
+
+static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
 {
     struct msqid_ds dsarg;
-    int cmd = second&0xff;
-    abi_long ret = 0;
-    switch( cmd ) {
+    struct msginfo msginfo;
+    abi_long ret = -TARGET_EINVAL;
+
+    cmd &= 0xff;
+
+    switch (cmd) {
     case IPC_STAT:
     case IPC_SET:
-        target_to_host_msqid_ds(&dsarg,ptr);
-        ret = get_errno(msgctl(first, cmd, &dsarg));
-        host_to_target_msqid_ds(ptr,&dsarg);
-    default:
-        ret = get_errno(msgctl(first, cmd, &dsarg));
+    case MSG_STAT:
+        if (target_to_host_msqid_ds(&dsarg,ptr))
+            return -TARGET_EFAULT;
+        ret = get_errno(msgctl(msgid, cmd, &dsarg));
+        if (host_to_target_msqid_ds(ptr,&dsarg))
+            return -TARGET_EFAULT;
+        break;
+    case IPC_RMID:
+        ret = get_errno(msgctl(msgid, cmd, NULL));
+        break;
+    case IPC_INFO:
+    case MSG_INFO:
+        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
+        if (host_to_target_msginfo(ptr, &msginfo))
+            return -TARGET_EFAULT;
+        break;
     }
+
     return ret;
 }
 
 struct target_msgbuf {
-       abi_ulong mtype;
-       char    mtext[1];
+    abi_long mtype;
+    char       mtext[1];
 };
 
 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
@@ -1934,8 +1990,8 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
     if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
         return -TARGET_EFAULT;
     host_mb = malloc(msgsz+sizeof(long));
-    host_mb->mtype = tswapl(target_mb->mtype);
-    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
+    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
+    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
     ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
     free(host_mb);
     unlock_user_struct(target_mb, msgp, 0);
@@ -1944,7 +2000,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
 }
 
 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
-                                 unsigned int msgsz, int msgtype,
+                                 unsigned int msgsz, abi_long msgtyp,
                                  int msgflg)
 {
     struct target_msgbuf *target_mb;
@@ -1954,8 +2010,10 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
 
     if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
         return -TARGET_EFAULT;
+
     host_mb = malloc(msgsz+sizeof(long));
-    ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
+    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
+
     if (ret > 0) {
         abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
         target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
@@ -1963,9 +2021,10 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
             ret = -TARGET_EFAULT;
             goto end;
         }
-       memcpy(target_mb->mtext, host_mb->mtext, ret);
+        memcpy(target_mb->mtext, host_mb->mtext, ret);
         unlock_user(target_mtext, target_mtext_addr, ret);
     }
+
     target_mb->mtype = tswapl(host_mb->mtype);
     free(host_mb);
 
@@ -1975,6 +2034,7 @@ end:
     return ret;
 }
 
+#ifdef TARGET_NR_ipc
 /* ??? This only works with linear mappings.  */
 /* do_ipc() must return target values and target errnos. */
 static abi_long do_ipc(unsigned int call, int first,
@@ -2007,34 +2067,41 @@ static abi_long do_ipc(unsigned int call, int first,
         ret = -TARGET_ENOSYS;
         break;
 
-       case IPCOP_msgget:
-               ret = get_errno(msgget(first, second));
-               break;
+    case IPCOP_msgget:
+        ret = get_errno(msgget(first, second));
+        break;
 
-       case IPCOP_msgsnd:
-               ret = do_msgsnd(first, ptr, second, third);
-               break;
+    case IPCOP_msgsnd:
+        ret = do_msgsnd(first, ptr, second, third);
+        break;
 
-       case IPCOP_msgctl:
-               ret = do_msgctl(first, second, ptr);
-               break;
+    case IPCOP_msgctl:
+        ret = do_msgctl(first, second, ptr);
+        break;
 
-       case IPCOP_msgrcv:
-                {
-                      /* XXX: this code is not correct */
-                      struct ipc_kludge
-                      {
-                              void *__unbounded msgp;
-                              long int msgtyp;
-                      };
+    case IPCOP_msgrcv:
+        switch (version) {
+        case 0:
+            {
+                struct target_ipc_kludge {
+                    abi_long msgp;
+                    abi_long msgtyp;
+                } *tmp;
 
-                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
-                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
+                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
+                    ret = -TARGET_EFAULT;
+                    break;
+                }
 
-                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
+                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
 
-                }
-               break;
+                unlock_user_struct(tmp, ptr, 0);
+                break;
+            }
+        default:
+            ret = do_msgrcv(first, ptr, second, fifth, third);
+        }
+        break;
 
     case IPCOP_shmat:
         {
@@ -2119,7 +2186,7 @@ enum {
 #undef STRUCT
 #undef STRUCT_SPECIAL
 
-#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
+#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
 #define STRUCT_SPECIAL(name)
 #include "syscall_types.h"
 #undef STRUCT
@@ -2439,7 +2506,7 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
 #if defined(TARGET_I386)
 
 /* NOTE: there is really one LDT for all the threads */
-uint8_t *ldt_table;
+static uint8_t *ldt_table;
 
 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
 {
@@ -2501,12 +2568,16 @@ static abi_long write_ldt(CPUX86State *env,
     }
     /* allocate the LDT */
     if (!ldt_table) {
-        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
-        if (!ldt_table)
+        env->ldt.base = target_mmap(0,
+                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
+                                    PROT_READ|PROT_WRITE,
+                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+        if (env->ldt.base == -1)
             return -TARGET_ENOMEM;
-        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
-        env->ldt.base = h2g((unsigned long)ldt_table);
+        memset(g2h(env->ldt.base), 0,
+               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
         env->ldt.limit = 0xffff;
+        ldt_table = g2h(env->ldt.base);
     }
 
     /* NOTE: same code as Linux kernel */
@@ -2890,17 +2961,17 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
             return -EINVAL;
         fork_start();
         ret = fork();
-#if defined(USE_NPTL)
-        /* There is a race condition here.  The parent process could
-           theoretically read the TID in the child process before the child
-           tid is set.  This would require using either ptrace
-           (not implemented) or having *_tidptr to point at a shared memory
-           mapping.  We can't repeat the spinlock hack used above because
-           the child process gets its own copy of the lock.  */
         if (ret == 0) {
+            /* Child Process.  */
             cpu_clone_regs(env, newsp);
             fork_end(1);
-            /* Child Process.  */
+#if defined(USE_NPTL)
+            /* There is a race condition here.  The parent process could
+               theoretically read the TID in the child process before the child
+               tid is set.  This would require using either ptrace
+               (not implemented) or having *_tidptr to point at a shared memory
+               mapping.  We can't repeat the spinlock hack used above because
+               the child process gets its own copy of the lock.  */
             if (flags & CLONE_CHILD_SETTID)
                 put_user_u32(gettid(), child_tidptr);
             if (flags & CLONE_PARENT_SETTID)
@@ -2909,14 +2980,10 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
             if (flags & CLONE_SETTLS)
                 cpu_set_tls (env, newtls);
             /* TODO: Implement CLONE_CHILD_CLEARTID.  */
+#endif
         } else {
             fork_end(0);
         }
-#else
-        if (ret == 0) {
-            cpu_clone_regs(env, newsp);
-        }
-#endif
     }
     return ret;
 }
@@ -3334,7 +3401,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
         gdb_exit(cpu_env, arg1);
         /* XXX: should free thread stack and CPU env */
-        _exit(arg1);
+        sys_exit(arg1);
         ret = 0; /* avoid warning */
         break;
     case TARGET_NR_read:
@@ -4769,12 +4836,35 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
        break;
 #endif
+
+#ifdef TARGET_NR_msgctl
+    case TARGET_NR_msgctl:
+        ret = do_msgctl(arg1, arg2, arg3);
+        break;
+#endif
+#ifdef TARGET_NR_msgget
+    case TARGET_NR_msgget:
+        ret = get_errno(msgget(arg1, arg2));
+        break;
+#endif
+#ifdef TARGET_NR_msgrcv
+    case TARGET_NR_msgrcv:
+        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
+        break;
+#endif
+#ifdef TARGET_NR_msgsnd
+    case TARGET_NR_msgsnd:
+        ret = do_msgsnd(arg1, arg2, arg3, arg4);
+        break;
+#endif
     case TARGET_NR_fsync:
         ret = get_errno(fsync(arg1));
         break;
     case TARGET_NR_clone:
 #if defined(TARGET_SH4)
         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
+#elif defined(TARGET_CRIS)
+        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
 #else
         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
 #endif
@@ -4782,6 +4872,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef __NR_exit_group
         /* new thread calls */
     case TARGET_NR_exit_group:
+#ifdef HAVE_GPROF
+        _mcleanup();
+#endif
         gdb_exit(cpu_env, arg1);
         ret = get_errno(exit_group(arg1));
         break;
@@ -4879,7 +4972,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
         {
             struct target_dirent *target_dirp;
-            struct dirent *dirp;
+            struct linux_dirent *dirp;
             abi_long count = arg3;
 
            dirp = malloc(count);
@@ -4890,7 +4983,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 
             ret = get_errno(sys_getdents(arg1, dirp, count));
             if (!is_error(ret)) {
-                struct dirent *de;
+                struct linux_dirent *de;
                struct target_dirent *tde;
                 int len = ret;
                 int reclen, treclen;
@@ -4911,8 +5004,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                    if (tnamelen > 256)
                         tnamelen = 256;
                     /* XXX: may not be correct */
-                   strncpy(tde->d_name, de->d_name, tnamelen);
-                    de = (struct dirent *)((char *)de + reclen);
+                    pstrcpy(tde->d_name, tnamelen, de->d_name);
+                    de = (struct linux_dirent *)((char *)de + reclen);
                     len -= reclen;
                     tde = (struct target_dirent *)((char *)tde + treclen);
                    count1 += treclen;
@@ -4924,14 +5017,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
 #else
         {
-            struct dirent *dirp;
+            struct linux_dirent *dirp;
             abi_long count = arg3;
 
             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                 goto efault;
             ret = get_errno(sys_getdents(arg1, dirp, count));
             if (!is_error(ret)) {
-                struct dirent *de;
+                struct linux_dirent *de;
                 int len = ret;
                 int reclen;
                 de = dirp;
@@ -4942,7 +5035,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     de->d_reclen = tswap16(reclen);
                     tswapls(&de->d_ino);
                     tswapls(&de->d_off);
-                    de = (struct dirent *)((char *)de + reclen);
+                    de = (struct linux_dirent *)((char *)de + reclen);
                     len -= reclen;
                 }
             }
@@ -4953,13 +5046,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
     case TARGET_NR_getdents64:
         {
-            struct dirent64 *dirp;
+            struct linux_dirent64 *dirp;
             abi_long count = arg3;
             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
                 goto efault;
             ret = get_errno(sys_getdents64(arg1, dirp, count));
             if (!is_error(ret)) {
-                struct dirent64 *de;
+                struct linux_dirent64 *de;
                 int len = ret;
                 int reclen;
                 de = dirp;
@@ -4970,7 +5063,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     de->d_reclen = tswap16(reclen);
                     tswap64s((uint64_t *)&de->d_ino);
                     tswap64s((uint64_t *)&de->d_off);
-                    de = (struct dirent64 *)((char *)de + reclen);
+                    de = (struct linux_dirent64 *)((char *)de + reclen);
                     len -= reclen;
                 }
             }
@@ -5441,6 +5534,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(getuid());
         break;
 #endif
+
+#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
+   /* Alpha specific */
+    case TARGET_NR_getxuid:
+        {
+           uid_t euid;
+           euid=geteuid();
+           ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
+        }
+        ret = get_errno(getuid());
+        break;
+#endif
+#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
+   /* Alpha specific */
+    case TARGET_NR_getxgid:
+        {
+           uid_t egid;
+           egid=getegid();
+           ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
+        }
+        ret = get_errno(getgid());
+        break;
+#endif
+
 #ifdef TARGET_NR_getgid32
     case TARGET_NR_getgid32:
         ret = get_errno(getgid());
@@ -5761,7 +5878,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #ifdef TARGET_NR_readahead
     case TARGET_NR_readahead:
-        goto unimplemented;
+#if TARGET_ABI_BITS == 32
+#ifdef TARGET_ARM
+        if (((CPUARMState *)cpu_env)->eabi)
+        {
+            arg2 = arg3;
+            arg3 = arg4;
+            arg4 = arg5;
+        }
+#endif
+        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
+#else
+        ret = get_errno(readahead(arg1, arg2, arg3));
+#endif
+        break;
 #endif
 #ifdef TARGET_NR_setxattr
     case TARGET_NR_setxattr:
@@ -5784,6 +5914,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
       ((CPUMIPSState *) cpu_env)->tls_value = arg1;
       ret = 0;
       break;
+#elif defined(TARGET_CRIS)
+      if (arg1 & 0xff)
+          ret = -TARGET_EINVAL;
+      else {
+          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
+          ret = 0;
+      }
+      break;
 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
       ret = do_set_thread_area(cpu_env, arg1);
       break;
This page took 0.046974 seconds and 4 git commands to generate.