The attached patch finishes adding support for semctl(). This was
verified on ARM using the semctl test from LTP in the target.


                                Stuart

Stuart R. Anderson                               [EMAIL PROTECTED]
Network & Software Engineering                   http://www.netsweng.com/
1024D/37A79149:                                  0791 D3B8 9A4C 2CDC A31F
                                                 BD03 0A62 E534 37A7 9149
Index: linux-user/syscall.c
===================================================================
RCS file: /sources/qemu/qemu/linux-user/syscall.c,v
retrieving revision 1.93
diff -u -r1.93 syscall.c
--- linux-user/syscall.c        19 Mar 2007 13:32:45 -0000      1.93
+++ linux-user/syscall.c        19 Mar 2007 15:40:57 -0000
@@ -1123,12 +1123,152 @@
     uint32_t   size;
 } shm_regions[N_SHM_REGIONS];
 
+struct target_ipc_perm
+{
+    target_long __key;
+    target_ulong uid;
+    target_ulong gid;
+    target_ulong cuid;
+    target_ulong cgid;
+    unsigned short int mode;
+    unsigned short int __pad1;
+    unsigned short int __seq;
+    unsigned short int __pad2;
+    target_ulong __unused1;
+    target_ulong __unused2;
+};
+
+struct target_semid_ds
+{
+  struct target_ipc_perm sem_perm;
+  target_ulong sem_otime;
+  target_ulong __unused1;
+  target_ulong sem_ctime;
+  target_ulong __unused2;
+  target_ulong sem_nsems;
+  target_ulong __unused3;
+  target_ulong __unused4;
+};
+
+static inline void target_to_host_ipc_perm(struct ipc_perm *ip,
+                                           target_ulong target_addr)
+{
+    struct target_ipc_perm *target_ip;
+    struct target_semid_ds *target_sd;
+
+    lock_user_struct(target_sd, target_addr, 1);
+    target_ip=&(target_sd->sem_perm);
+    ip->__key = tswapl(target_ip->__key);
+    ip->uid = tswapl(target_ip->uid);
+    ip->gid = tswapl(target_ip->gid);
+    ip->cuid = tswapl(target_ip->cuid);
+    ip->cgid = tswapl(target_ip->cgid);
+    ip->mode = tswapl(target_ip->mode);
+    unlock_user_struct(target_sd, target_addr, 0);
+}
+
+static inline void host_to_target_ipc_perm(target_ulong target_addr,
+                                           struct ipc_perm *host_ip)
+{
+    struct target_ipc_perm *target_ip;
+    struct target_semid_ds *target_sd;
+
+    lock_user_struct(target_sd, target_addr, 0);
+    target_ip = &(target_sd->sem_perm);
+    target_ip->__key = tswapl(host_ip->__key);
+    target_ip->uid = tswapl(host_ip->uid);
+    target_ip->gid = tswapl(host_ip->gid);
+    target_ip->cuid = tswapl(host_ip->cuid);
+    target_ip->cgid = tswapl(host_ip->cgid);
+    target_ip->mode = tswapl(host_ip->mode);
+    unlock_user_struct(target_sd, target_addr, 1);
+}
+
+static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
+                                          target_ulong target_addr)
+{
+    struct target_semid_ds *target_sd;
+
+    lock_user_struct(target_sd, target_addr, 1);
+    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
+    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
+    host_sd->sem_otime = tswapl(target_sd->sem_otime);
+    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
+    unlock_user_struct(target_sd, target_addr, 0);
+}
+
+static inline void host_to_target_semid_ds(target_ulong target_addr,
+                                           struct semid_ds *host_sd)
+{
+    struct target_semid_ds *target_sd;
+
+    lock_user_struct(target_sd, target_addr, 0);
+    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
+    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
+    target_sd->sem_otime = tswapl(host_sd->sem_otime);
+    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
+    unlock_user_struct(target_sd, target_addr, 1);
+}
+
 union semun {
        int val;
-       struct senid_ds *buf;
+       struct semid_ds *buf;
        unsigned short *array;
 };
 
+union target_semun {
+       int val;
+       target_long buf;
+       target_long array;
+};
+
+static inline void target_to_host_semun(unsigned long cmd, union semun 
*host_su,
+                                          target_ulong target_addr, struct 
semid_ds *ds)
+{
+    union target_semun *target_su;
+
+    lock_user_struct(target_su, target_addr, 1);
+    switch( cmd ) {
+       case IPC_STAT:
+       case IPC_SET:
+          target_to_host_semid_ds(ds,target_su->buf);
+          host_su->buf = ds;
+          break;
+       default:
+          host_su->array = tswapl(target_su->array);
+    }
+    unlock_user_struct(target_su, target_addr, 0);
+}
+
+static inline void host_to_target_semun(unsigned long cmd, target_ulong 
target_addr,
+                                           union semun *host_su, struct 
semid_ds *ds)
+{
+    union target_semun *target_su;
+
+    lock_user_struct(target_su, target_addr, 0);
+    switch( cmd ) {
+       case IPC_STAT:
+       case IPC_SET:
+          host_to_target_semid_ds(target_su->buf,ds);
+          break;
+    default:
+       target_su->array = tswapl(host_su->array);
+    }
+    unlock_user_struct(target_su, target_addr, 1);
+}
+
+static inline long do_semctl(long first, long second, long third, long ptr)
+{
+    union semun arg;
+    struct semid_ds dsarg;
+    int cmd = third&0xff;
+    long ret = 0;
+    target_to_host_semun(cmd,&arg,ptr,&dsarg);
+    ret = get_errno(semctl(first, second, cmd, arg));
+    host_to_target_semun(cmd,ptr,&arg,&dsarg);
+    return ret;
+}
+
 /* ??? This only works with linear mappings.  */
 static long do_ipc(long call, long first, long second, long third,
                   long ptr, long fifth)
@@ -1152,8 +1292,7 @@
         break;
 
     case IPCOP_semctl:
-        ret = get_errno(semctl(first, second, third, ((union 
semun*)ptr)->val));
-
+        ret = do_semctl(first, second, third, ptr);
         break;
 
     case IPCOP_semtimedop:
Index: linux-user/i386/syscall.h
===================================================================
RCS file: /sources/qemu/qemu/linux-user/i386/syscall.h,v
retrieving revision 1.2
diff -u -r1.2 syscall.h
--- linux-user/i386/syscall.h   13 Sep 2004 21:41:39 -0000      1.2
+++ linux-user/i386/syscall.h   19 Mar 2007 15:40:57 -0000
@@ -142,80 +142,4 @@
        struct target_vm86plus_info_struct vm86plus;
 };
 
-/* ipcs */
-
-#define TARGET_SEMOP           1
-#define TARGET_SEMGET          2
-#define TARGET_SEMCTL          3 
-#define TARGET_MSGSND          11 
-#define TARGET_MSGRCV          12
-#define TARGET_MSGGET          13
-#define TARGET_MSGCTL          14
-#define TARGET_SHMAT           21
-#define TARGET_SHMDT           22
-#define TARGET_SHMGET          23
-#define TARGET_SHMCTL          24
-
-struct target_msgbuf {
-       int mtype;
-       char mtext[1];
-};
-
-struct target_ipc_kludge {
-       unsigned int    msgp;   /* Really (struct msgbuf *) */
-       int msgtyp;
-};     
-
-struct target_ipc_perm {
-       int     key;
-       unsigned short  uid;
-       unsigned short  gid;
-       unsigned short  cuid;
-       unsigned short  cgid;
-       unsigned short  mode;
-       unsigned short  seq;
-};
-
-struct target_msqid_ds {
-       struct target_ipc_perm  msg_perm;
-       unsigned int            msg_first;      /* really struct target_msg* */
-       unsigned int            msg_last;       /* really struct target_msg* */
-       unsigned int            msg_stime;      /* really target_time_t */
-       unsigned int            msg_rtime;      /* really target_time_t */
-       unsigned int            msg_ctime;      /* really target_time_t */
-       unsigned int            wwait;          /* really struct wait_queue* */
-       unsigned int            rwait;          /* really struct wait_queue* */
-       unsigned short          msg_cbytes;
-       unsigned short          msg_qnum;
-       unsigned short          msg_qbytes;
-       unsigned short          msg_lspid;
-       unsigned short          msg_lrpid;
-};
-
-struct target_shmid_ds {
-       struct target_ipc_perm  shm_perm;
-       int                     shm_segsz;
-       unsigned int            shm_atime;      /* really target_time_t */
-       unsigned int            shm_dtime;      /* really target_time_t */
-       unsigned int            shm_ctime;      /* really target_time_t */
-       unsigned short          shm_cpid;
-       unsigned short          shm_lpid;
-       short                   shm_nattch;
-       unsigned short          shm_npages;
-       unsigned long           *shm_pages;
-       void                    *attaches;      /* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID        0
-#define TARGET_IPC_SET 1
-#define TARGET_IPC_STAT        2
-
-union target_semun {
-    int val;
-    unsigned int buf;  /* really struct semid_ds * */
-    unsigned int array; /* really unsigned short * */
-    unsigned int __buf;        /* really struct seminfo * */
-    unsigned int __pad;        /* really void* */
-};
-
 #define UNAME_MACHINE "i686"
Index: linux-user/ppc/syscall.h
===================================================================
RCS file: /sources/qemu/qemu/linux-user/ppc/syscall.h,v
retrieving revision 1.2
diff -u -r1.2 syscall.h
--- linux-user/ppc/syscall.h    13 Sep 2004 21:41:39 -0000      1.2
+++ linux-user/ppc/syscall.h    19 Mar 2007 15:40:57 -0000
@@ -51,80 +51,4 @@
  * flags masks
  */
 
-/* ipcs */
-
-#define TARGET_SEMOP           1
-#define TARGET_SEMGET          2
-#define TARGET_SEMCTL          3 
-#define TARGET_MSGSND          11 
-#define TARGET_MSGRCV          12
-#define TARGET_MSGGET          13
-#define TARGET_MSGCTL          14
-#define TARGET_SHMAT           21
-#define TARGET_SHMDT           22
-#define TARGET_SHMGET          23
-#define TARGET_SHMCTL          24
-
-struct target_msgbuf {
-       int mtype;
-       char mtext[1];
-};
-
-struct target_ipc_kludge {
-       unsigned int    msgp;   /* Really (struct msgbuf *) */
-       int msgtyp;
-};     
-
-struct target_ipc_perm {
-       int     key;
-       unsigned short  uid;
-       unsigned short  gid;
-       unsigned short  cuid;
-       unsigned short  cgid;
-       unsigned short  mode;
-       unsigned short  seq;
-};
-
-struct target_msqid_ds {
-       struct target_ipc_perm  msg_perm;
-       unsigned int            msg_first;      /* really struct target_msg* */
-       unsigned int            msg_last;       /* really struct target_msg* */
-       unsigned int            msg_stime;      /* really target_time_t */
-       unsigned int            msg_rtime;      /* really target_time_t */
-       unsigned int            msg_ctime;      /* really target_time_t */
-       unsigned int            wwait;          /* really struct wait_queue* */
-       unsigned int            rwait;          /* really struct wait_queue* */
-       unsigned short          msg_cbytes;
-       unsigned short          msg_qnum;
-       unsigned short          msg_qbytes;
-       unsigned short          msg_lspid;
-       unsigned short          msg_lrpid;
-};
-
-struct target_shmid_ds {
-       struct target_ipc_perm  shm_perm;
-       int                     shm_segsz;
-       unsigned int            shm_atime;      /* really target_time_t */
-       unsigned int            shm_dtime;      /* really target_time_t */
-       unsigned int            shm_ctime;      /* really target_time_t */
-       unsigned short          shm_cpid;
-       unsigned short          shm_lpid;
-       short                   shm_nattch;
-       unsigned short          shm_npages;
-       unsigned long           *shm_pages;
-       void                    *attaches;      /* really struct shm_desc * */
-};
-
-#define TARGET_IPC_RMID        0
-#define TARGET_IPC_SET 1
-#define TARGET_IPC_STAT        2
-
-union target_semun {
-    int val;
-    unsigned int buf;  /* really struct semid_ds * */
-    unsigned int array; /* really unsigned short * */
-    unsigned int __buf;        /* really struct seminfo * */
-    unsigned int __pad;        /* really void* */
-};
-
 #define UNAME_MACHINE "ppc"
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to