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