Commit 3eb6b044 authored by ths's avatar ths
Browse files

Semaphore structure mapping, by Stuart Anderson.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2929 c046a42c-6fe2-441c-8c8c-71466251a162
parent 4be456f1
......@@ -38,78 +38,4 @@ struct target_pt_regs {
target_ulong unique;
};
#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 "alpha"
......@@ -142,80 +142,4 @@ struct target_vm86plus_struct {
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"
......@@ -51,80 +51,4 @@ struct target_revectored_struct {
* 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"
......@@ -1230,12 +1230,213 @@ static struct shm_region {
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 *host_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);
host_ip->__key = tswapl(target_ip->__key);
host_ip->uid = tswapl(target_ip->uid);
host_ip->gid = tswapl(target_ip->gid);
host_ip->cuid = tswapl(target_ip->cuid);
host_ip->cgid = tswapl(target_ip->cgid);
host_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;
unsigned short int *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;
switch( cmd ) {
case IPC_STAT:
case IPC_SET:
lock_user_struct(target_su, target_addr, 1);
target_to_host_semid_ds(ds,target_su->buf);
host_su->buf = ds;
unlock_user_struct(target_su, target_addr, 0);
break;
case GETVAL:
case SETVAL:
lock_user_struct(target_su, target_addr, 1);
host_su->val = tswapl(target_su->val);
unlock_user_struct(target_su, target_addr, 0);
break;
case GETALL:
case SETALL:
lock_user_struct(target_su, target_addr, 1);
*host_su->array = tswap16(*target_su->array);
unlock_user_struct(target_su, target_addr, 0);
break;
default:
gemu_log("semun operation not fully supported: %d\n", (int)cmd);
}
}
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;
switch( cmd ) {
case IPC_STAT:
case IPC_SET:
lock_user_struct(target_su, target_addr, 0);
host_to_target_semid_ds(target_su->buf,ds);
unlock_user_struct(target_su, target_addr, 1);
break;
case GETVAL:
case SETVAL:
lock_user_struct(target_su, target_addr, 0);
target_su->val = tswapl(host_su->val);
unlock_user_struct(target_su, target_addr, 1);
break;
case GETALL:
case SETALL:
lock_user_struct(target_su, target_addr, 0);
*target_su->array = tswap16(*host_su->array);
unlock_user_struct(target_su, target_addr, 1);
break;
default:
gemu_log("semun operation not fully supported: %d\n", (int)cmd);
}
}
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;
switch( cmd ) {
case GETVAL:
target_to_host_semun(cmd,&arg,ptr,&dsarg);
ret = get_errno(semctl(first, second, cmd, arg));
host_to_target_semun(cmd,ptr,&arg,&dsarg);
break;
case SETVAL:
target_to_host_semun(cmd,&arg,ptr,&dsarg);
ret = get_errno(semctl(first, second, cmd, arg));
host_to_target_semun(cmd,ptr,&arg,&dsarg);
break;
case GETALL:
target_to_host_semun(cmd,&arg,ptr,&dsarg);
ret = get_errno(semctl(first, second, cmd, arg));
host_to_target_semun(cmd,ptr,&arg,&dsarg);
break;
case SETALL:
target_to_host_semun(cmd,&arg,ptr,&dsarg);
ret = get_errno(semctl(first, second, cmd, arg));
host_to_target_semun(cmd,ptr,&arg,&dsarg);
break;
case IPC_STAT:
target_to_host_semun(cmd,&arg,ptr,&dsarg);
ret = get_errno(semctl(first, second, cmd, arg));
host_to_target_semun(cmd,ptr,&arg,&dsarg);
break;
case IPC_SET:
target_to_host_semun(cmd,&arg,ptr,&dsarg);
ret = get_errno(semctl(first, second, cmd, arg));
host_to_target_semun(cmd,ptr,&arg,&dsarg);
break;
default:
ret = get_errno(semctl(first, second, cmd, arg));
}
return ret;
}
/* ??? This only works with linear mappings. */
static long do_ipc(long call, long first, long second, long third,
long ptr, long fifth)
......@@ -1259,8 +1460,7 @@ static long do_ipc(long call, long first, long second, long third,
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:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment