Semaphore structure mapping, by Stuart Anderson.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2929 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
4be456f126
commit
3eb6b04433
@ -38,78 +38,4 @@ struct target_pt_regs {
|
|||||||
target_ulong unique;
|
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"
|
#define UNAME_MACHINE "alpha"
|
||||||
|
@ -142,80 +142,4 @@ struct target_vm86plus_struct {
|
|||||||
struct target_vm86plus_info_struct vm86plus;
|
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"
|
#define UNAME_MACHINE "i686"
|
||||||
|
@ -51,80 +51,4 @@ struct target_revectored_struct {
|
|||||||
* flags masks
|
* 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"
|
#define UNAME_MACHINE "ppc"
|
||||||
|
@ -1230,12 +1230,213 @@ static struct shm_region {
|
|||||||
uint32_t size;
|
uint32_t size;
|
||||||
} shm_regions[N_SHM_REGIONS];
|
} 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 {
|
union semun {
|
||||||
int val;
|
int val;
|
||||||
struct senid_ds *buf;
|
struct semid_ds *buf;
|
||||||
unsigned short *array;
|
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. */
|
/* ??? This only works with linear mappings. */
|
||||||
static long do_ipc(long call, long first, long second, long third,
|
static long do_ipc(long call, long first, long second, long third,
|
||||||
long ptr, long fifth)
|
long ptr, long fifth)
|
||||||
@ -1259,8 +1460,7 @@ static long do_ipc(long call, long first, long second, long third,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IPCOP_semctl:
|
case IPCOP_semctl:
|
||||||
ret = get_errno(semctl(first, second, third, ((union semun*)ptr)->val));
|
ret = do_semctl(first, second, third, ptr);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPCOP_semtimedop:
|
case IPCOP_semtimedop:
|
||||||
|
Loading…
Reference in New Issue
Block a user