Commit 3eb6b04433a337068eb90030c07d43012a28a54f
1 parent
4be456f1
Semaphore structure mapping, by Stuart Anderson.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2929 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
203 additions
and
229 deletions
linux-user/alpha/syscall.h
... | ... | @@ -38,78 +38,4 @@ struct target_pt_regs { |
38 | 38 | target_ulong unique; |
39 | 39 | }; |
40 | 40 | |
41 | -#define TARGET_SEMOP 1 | |
42 | -#define TARGET_SEMGET 2 | |
43 | -#define TARGET_SEMCTL 3 | |
44 | -#define TARGET_MSGSND 11 | |
45 | -#define TARGET_MSGRCV 12 | |
46 | -#define TARGET_MSGGET 13 | |
47 | -#define TARGET_MSGCTL 14 | |
48 | -#define TARGET_SHMAT 21 | |
49 | -#define TARGET_SHMDT 22 | |
50 | -#define TARGET_SHMGET 23 | |
51 | -#define TARGET_SHMCTL 24 | |
52 | - | |
53 | -struct target_msgbuf { | |
54 | - int mtype; | |
55 | - char mtext[1]; | |
56 | -}; | |
57 | - | |
58 | -struct target_ipc_kludge { | |
59 | - unsigned int msgp; /* Really (struct msgbuf *) */ | |
60 | - int msgtyp; | |
61 | -}; | |
62 | - | |
63 | -struct target_ipc_perm { | |
64 | - int key; | |
65 | - unsigned short uid; | |
66 | - unsigned short gid; | |
67 | - unsigned short cuid; | |
68 | - unsigned short cgid; | |
69 | - unsigned short mode; | |
70 | - unsigned short seq; | |
71 | -}; | |
72 | - | |
73 | -struct target_msqid_ds { | |
74 | - struct target_ipc_perm msg_perm; | |
75 | - unsigned int msg_first; /* really struct target_msg* */ | |
76 | - unsigned int msg_last; /* really struct target_msg* */ | |
77 | - unsigned int msg_stime; /* really target_time_t */ | |
78 | - unsigned int msg_rtime; /* really target_time_t */ | |
79 | - unsigned int msg_ctime; /* really target_time_t */ | |
80 | - unsigned int wwait; /* really struct wait_queue* */ | |
81 | - unsigned int rwait; /* really struct wait_queue* */ | |
82 | - unsigned short msg_cbytes; | |
83 | - unsigned short msg_qnum; | |
84 | - unsigned short msg_qbytes; | |
85 | - unsigned short msg_lspid; | |
86 | - unsigned short msg_lrpid; | |
87 | -}; | |
88 | - | |
89 | -struct target_shmid_ds { | |
90 | - struct target_ipc_perm shm_perm; | |
91 | - int shm_segsz; | |
92 | - unsigned int shm_atime; /* really target_time_t */ | |
93 | - unsigned int shm_dtime; /* really target_time_t */ | |
94 | - unsigned int shm_ctime; /* really target_time_t */ | |
95 | - unsigned short shm_cpid; | |
96 | - unsigned short shm_lpid; | |
97 | - short shm_nattch; | |
98 | - unsigned short shm_npages; | |
99 | - unsigned long *shm_pages; | |
100 | - void *attaches; /* really struct shm_desc * */ | |
101 | -}; | |
102 | - | |
103 | -#define TARGET_IPC_RMID 0 | |
104 | -#define TARGET_IPC_SET 1 | |
105 | -#define TARGET_IPC_STAT 2 | |
106 | - | |
107 | -union target_semun { | |
108 | - int val; | |
109 | - unsigned int buf; /* really struct semid_ds * */ | |
110 | - unsigned int array; /* really unsigned short * */ | |
111 | - unsigned int __buf; /* really struct seminfo * */ | |
112 | - unsigned int __pad; /* really void* */ | |
113 | -}; | |
114 | - | |
115 | 41 | #define UNAME_MACHINE "alpha" | ... | ... |
linux-user/i386/syscall.h
... | ... | @@ -142,80 +142,4 @@ struct target_vm86plus_struct { |
142 | 142 | struct target_vm86plus_info_struct vm86plus; |
143 | 143 | }; |
144 | 144 | |
145 | -/* ipcs */ | |
146 | - | |
147 | -#define TARGET_SEMOP 1 | |
148 | -#define TARGET_SEMGET 2 | |
149 | -#define TARGET_SEMCTL 3 | |
150 | -#define TARGET_MSGSND 11 | |
151 | -#define TARGET_MSGRCV 12 | |
152 | -#define TARGET_MSGGET 13 | |
153 | -#define TARGET_MSGCTL 14 | |
154 | -#define TARGET_SHMAT 21 | |
155 | -#define TARGET_SHMDT 22 | |
156 | -#define TARGET_SHMGET 23 | |
157 | -#define TARGET_SHMCTL 24 | |
158 | - | |
159 | -struct target_msgbuf { | |
160 | - int mtype; | |
161 | - char mtext[1]; | |
162 | -}; | |
163 | - | |
164 | -struct target_ipc_kludge { | |
165 | - unsigned int msgp; /* Really (struct msgbuf *) */ | |
166 | - int msgtyp; | |
167 | -}; | |
168 | - | |
169 | -struct target_ipc_perm { | |
170 | - int key; | |
171 | - unsigned short uid; | |
172 | - unsigned short gid; | |
173 | - unsigned short cuid; | |
174 | - unsigned short cgid; | |
175 | - unsigned short mode; | |
176 | - unsigned short seq; | |
177 | -}; | |
178 | - | |
179 | -struct target_msqid_ds { | |
180 | - struct target_ipc_perm msg_perm; | |
181 | - unsigned int msg_first; /* really struct target_msg* */ | |
182 | - unsigned int msg_last; /* really struct target_msg* */ | |
183 | - unsigned int msg_stime; /* really target_time_t */ | |
184 | - unsigned int msg_rtime; /* really target_time_t */ | |
185 | - unsigned int msg_ctime; /* really target_time_t */ | |
186 | - unsigned int wwait; /* really struct wait_queue* */ | |
187 | - unsigned int rwait; /* really struct wait_queue* */ | |
188 | - unsigned short msg_cbytes; | |
189 | - unsigned short msg_qnum; | |
190 | - unsigned short msg_qbytes; | |
191 | - unsigned short msg_lspid; | |
192 | - unsigned short msg_lrpid; | |
193 | -}; | |
194 | - | |
195 | -struct target_shmid_ds { | |
196 | - struct target_ipc_perm shm_perm; | |
197 | - int shm_segsz; | |
198 | - unsigned int shm_atime; /* really target_time_t */ | |
199 | - unsigned int shm_dtime; /* really target_time_t */ | |
200 | - unsigned int shm_ctime; /* really target_time_t */ | |
201 | - unsigned short shm_cpid; | |
202 | - unsigned short shm_lpid; | |
203 | - short shm_nattch; | |
204 | - unsigned short shm_npages; | |
205 | - unsigned long *shm_pages; | |
206 | - void *attaches; /* really struct shm_desc * */ | |
207 | -}; | |
208 | - | |
209 | -#define TARGET_IPC_RMID 0 | |
210 | -#define TARGET_IPC_SET 1 | |
211 | -#define TARGET_IPC_STAT 2 | |
212 | - | |
213 | -union target_semun { | |
214 | - int val; | |
215 | - unsigned int buf; /* really struct semid_ds * */ | |
216 | - unsigned int array; /* really unsigned short * */ | |
217 | - unsigned int __buf; /* really struct seminfo * */ | |
218 | - unsigned int __pad; /* really void* */ | |
219 | -}; | |
220 | - | |
221 | 145 | #define UNAME_MACHINE "i686" | ... | ... |
linux-user/ppc/syscall.h
... | ... | @@ -51,80 +51,4 @@ struct target_revectored_struct { |
51 | 51 | * flags masks |
52 | 52 | */ |
53 | 53 | |
54 | -/* ipcs */ | |
55 | - | |
56 | -#define TARGET_SEMOP 1 | |
57 | -#define TARGET_SEMGET 2 | |
58 | -#define TARGET_SEMCTL 3 | |
59 | -#define TARGET_MSGSND 11 | |
60 | -#define TARGET_MSGRCV 12 | |
61 | -#define TARGET_MSGGET 13 | |
62 | -#define TARGET_MSGCTL 14 | |
63 | -#define TARGET_SHMAT 21 | |
64 | -#define TARGET_SHMDT 22 | |
65 | -#define TARGET_SHMGET 23 | |
66 | -#define TARGET_SHMCTL 24 | |
67 | - | |
68 | -struct target_msgbuf { | |
69 | - int mtype; | |
70 | - char mtext[1]; | |
71 | -}; | |
72 | - | |
73 | -struct target_ipc_kludge { | |
74 | - unsigned int msgp; /* Really (struct msgbuf *) */ | |
75 | - int msgtyp; | |
76 | -}; | |
77 | - | |
78 | -struct target_ipc_perm { | |
79 | - int key; | |
80 | - unsigned short uid; | |
81 | - unsigned short gid; | |
82 | - unsigned short cuid; | |
83 | - unsigned short cgid; | |
84 | - unsigned short mode; | |
85 | - unsigned short seq; | |
86 | -}; | |
87 | - | |
88 | -struct target_msqid_ds { | |
89 | - struct target_ipc_perm msg_perm; | |
90 | - unsigned int msg_first; /* really struct target_msg* */ | |
91 | - unsigned int msg_last; /* really struct target_msg* */ | |
92 | - unsigned int msg_stime; /* really target_time_t */ | |
93 | - unsigned int msg_rtime; /* really target_time_t */ | |
94 | - unsigned int msg_ctime; /* really target_time_t */ | |
95 | - unsigned int wwait; /* really struct wait_queue* */ | |
96 | - unsigned int rwait; /* really struct wait_queue* */ | |
97 | - unsigned short msg_cbytes; | |
98 | - unsigned short msg_qnum; | |
99 | - unsigned short msg_qbytes; | |
100 | - unsigned short msg_lspid; | |
101 | - unsigned short msg_lrpid; | |
102 | -}; | |
103 | - | |
104 | -struct target_shmid_ds { | |
105 | - struct target_ipc_perm shm_perm; | |
106 | - int shm_segsz; | |
107 | - unsigned int shm_atime; /* really target_time_t */ | |
108 | - unsigned int shm_dtime; /* really target_time_t */ | |
109 | - unsigned int shm_ctime; /* really target_time_t */ | |
110 | - unsigned short shm_cpid; | |
111 | - unsigned short shm_lpid; | |
112 | - short shm_nattch; | |
113 | - unsigned short shm_npages; | |
114 | - unsigned long *shm_pages; | |
115 | - void *attaches; /* really struct shm_desc * */ | |
116 | -}; | |
117 | - | |
118 | -#define TARGET_IPC_RMID 0 | |
119 | -#define TARGET_IPC_SET 1 | |
120 | -#define TARGET_IPC_STAT 2 | |
121 | - | |
122 | -union target_semun { | |
123 | - int val; | |
124 | - unsigned int buf; /* really struct semid_ds * */ | |
125 | - unsigned int array; /* really unsigned short * */ | |
126 | - unsigned int __buf; /* really struct seminfo * */ | |
127 | - unsigned int __pad; /* really void* */ | |
128 | -}; | |
129 | - | |
130 | 54 | #define UNAME_MACHINE "ppc" | ... | ... |
linux-user/syscall.c
... | ... | @@ -1230,12 +1230,213 @@ static struct shm_region { |
1230 | 1230 | uint32_t size; |
1231 | 1231 | } shm_regions[N_SHM_REGIONS]; |
1232 | 1232 | |
1233 | +struct target_ipc_perm | |
1234 | +{ | |
1235 | + target_long __key; | |
1236 | + target_ulong uid; | |
1237 | + target_ulong gid; | |
1238 | + target_ulong cuid; | |
1239 | + target_ulong cgid; | |
1240 | + unsigned short int mode; | |
1241 | + unsigned short int __pad1; | |
1242 | + unsigned short int __seq; | |
1243 | + unsigned short int __pad2; | |
1244 | + target_ulong __unused1; | |
1245 | + target_ulong __unused2; | |
1246 | +}; | |
1247 | + | |
1248 | +struct target_semid_ds | |
1249 | +{ | |
1250 | + struct target_ipc_perm sem_perm; | |
1251 | + target_ulong sem_otime; | |
1252 | + target_ulong __unused1; | |
1253 | + target_ulong sem_ctime; | |
1254 | + target_ulong __unused2; | |
1255 | + target_ulong sem_nsems; | |
1256 | + target_ulong __unused3; | |
1257 | + target_ulong __unused4; | |
1258 | +}; | |
1259 | + | |
1260 | +static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip, | |
1261 | + target_ulong target_addr) | |
1262 | +{ | |
1263 | + struct target_ipc_perm *target_ip; | |
1264 | + struct target_semid_ds *target_sd; | |
1265 | + | |
1266 | + lock_user_struct(target_sd, target_addr, 1); | |
1267 | + target_ip=&(target_sd->sem_perm); | |
1268 | + host_ip->__key = tswapl(target_ip->__key); | |
1269 | + host_ip->uid = tswapl(target_ip->uid); | |
1270 | + host_ip->gid = tswapl(target_ip->gid); | |
1271 | + host_ip->cuid = tswapl(target_ip->cuid); | |
1272 | + host_ip->cgid = tswapl(target_ip->cgid); | |
1273 | + host_ip->mode = tswapl(target_ip->mode); | |
1274 | + unlock_user_struct(target_sd, target_addr, 0); | |
1275 | +} | |
1276 | + | |
1277 | +static inline void host_to_target_ipc_perm(target_ulong target_addr, | |
1278 | + struct ipc_perm *host_ip) | |
1279 | +{ | |
1280 | + struct target_ipc_perm *target_ip; | |
1281 | + struct target_semid_ds *target_sd; | |
1282 | + | |
1283 | + lock_user_struct(target_sd, target_addr, 0); | |
1284 | + target_ip = &(target_sd->sem_perm); | |
1285 | + target_ip->__key = tswapl(host_ip->__key); | |
1286 | + target_ip->uid = tswapl(host_ip->uid); | |
1287 | + target_ip->gid = tswapl(host_ip->gid); | |
1288 | + target_ip->cuid = tswapl(host_ip->cuid); | |
1289 | + target_ip->cgid = tswapl(host_ip->cgid); | |
1290 | + target_ip->mode = tswapl(host_ip->mode); | |
1291 | + unlock_user_struct(target_sd, target_addr, 1); | |
1292 | +} | |
1293 | + | |
1294 | +static inline void target_to_host_semid_ds(struct semid_ds *host_sd, | |
1295 | + target_ulong target_addr) | |
1296 | +{ | |
1297 | + struct target_semid_ds *target_sd; | |
1298 | + | |
1299 | + lock_user_struct(target_sd, target_addr, 1); | |
1300 | + target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr); | |
1301 | + host_sd->sem_nsems = tswapl(target_sd->sem_nsems); | |
1302 | + host_sd->sem_otime = tswapl(target_sd->sem_otime); | |
1303 | + host_sd->sem_ctime = tswapl(target_sd->sem_ctime); | |
1304 | + unlock_user_struct(target_sd, target_addr, 0); | |
1305 | +} | |
1306 | + | |
1307 | +static inline void host_to_target_semid_ds(target_ulong target_addr, | |
1308 | + struct semid_ds *host_sd) | |
1309 | +{ | |
1310 | + struct target_semid_ds *target_sd; | |
1311 | + | |
1312 | + lock_user_struct(target_sd, target_addr, 0); | |
1313 | + host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)); | |
1314 | + target_sd->sem_nsems = tswapl(host_sd->sem_nsems); | |
1315 | + target_sd->sem_otime = tswapl(host_sd->sem_otime); | |
1316 | + target_sd->sem_ctime = tswapl(host_sd->sem_ctime); | |
1317 | + unlock_user_struct(target_sd, target_addr, 1); | |
1318 | +} | |
1319 | + | |
1233 | 1320 | union semun { |
1234 | 1321 | int val; |
1235 | - struct senid_ds *buf; | |
1322 | + struct semid_ds *buf; | |
1236 | 1323 | unsigned short *array; |
1237 | 1324 | }; |
1238 | 1325 | |
1326 | +union target_semun { | |
1327 | + int val; | |
1328 | + target_long buf; | |
1329 | + unsigned short int *array; | |
1330 | +}; | |
1331 | + | |
1332 | +static inline void target_to_host_semun(unsigned long cmd, | |
1333 | + union semun *host_su, | |
1334 | + target_ulong target_addr, | |
1335 | + struct semid_ds *ds) | |
1336 | +{ | |
1337 | + union target_semun *target_su; | |
1338 | + | |
1339 | + switch( cmd ) { | |
1340 | + case IPC_STAT: | |
1341 | + case IPC_SET: | |
1342 | + lock_user_struct(target_su, target_addr, 1); | |
1343 | + target_to_host_semid_ds(ds,target_su->buf); | |
1344 | + host_su->buf = ds; | |
1345 | + unlock_user_struct(target_su, target_addr, 0); | |
1346 | + break; | |
1347 | + case GETVAL: | |
1348 | + case SETVAL: | |
1349 | + lock_user_struct(target_su, target_addr, 1); | |
1350 | + host_su->val = tswapl(target_su->val); | |
1351 | + unlock_user_struct(target_su, target_addr, 0); | |
1352 | + break; | |
1353 | + case GETALL: | |
1354 | + case SETALL: | |
1355 | + lock_user_struct(target_su, target_addr, 1); | |
1356 | + *host_su->array = tswap16(*target_su->array); | |
1357 | + unlock_user_struct(target_su, target_addr, 0); | |
1358 | + break; | |
1359 | + default: | |
1360 | + gemu_log("semun operation not fully supported: %d\n", (int)cmd); | |
1361 | + } | |
1362 | +} | |
1363 | + | |
1364 | +static inline void host_to_target_semun(unsigned long cmd, | |
1365 | + target_ulong target_addr, | |
1366 | + union semun *host_su, | |
1367 | + struct semid_ds *ds) | |
1368 | +{ | |
1369 | + union target_semun *target_su; | |
1370 | + | |
1371 | + switch( cmd ) { | |
1372 | + case IPC_STAT: | |
1373 | + case IPC_SET: | |
1374 | + lock_user_struct(target_su, target_addr, 0); | |
1375 | + host_to_target_semid_ds(target_su->buf,ds); | |
1376 | + unlock_user_struct(target_su, target_addr, 1); | |
1377 | + break; | |
1378 | + case GETVAL: | |
1379 | + case SETVAL: | |
1380 | + lock_user_struct(target_su, target_addr, 0); | |
1381 | + target_su->val = tswapl(host_su->val); | |
1382 | + unlock_user_struct(target_su, target_addr, 1); | |
1383 | + break; | |
1384 | + case GETALL: | |
1385 | + case SETALL: | |
1386 | + lock_user_struct(target_su, target_addr, 0); | |
1387 | + *target_su->array = tswap16(*host_su->array); | |
1388 | + unlock_user_struct(target_su, target_addr, 1); | |
1389 | + break; | |
1390 | + default: | |
1391 | + gemu_log("semun operation not fully supported: %d\n", (int)cmd); | |
1392 | + } | |
1393 | +} | |
1394 | + | |
1395 | +static inline long do_semctl(long first, long second, long third, long ptr) | |
1396 | +{ | |
1397 | + union semun arg; | |
1398 | + struct semid_ds dsarg; | |
1399 | + int cmd = third&0xff; | |
1400 | + long ret = 0; | |
1401 | + | |
1402 | + switch( cmd ) { | |
1403 | + case GETVAL: | |
1404 | + target_to_host_semun(cmd,&arg,ptr,&dsarg); | |
1405 | + ret = get_errno(semctl(first, second, cmd, arg)); | |
1406 | + host_to_target_semun(cmd,ptr,&arg,&dsarg); | |
1407 | + break; | |
1408 | + case SETVAL: | |
1409 | + target_to_host_semun(cmd,&arg,ptr,&dsarg); | |
1410 | + ret = get_errno(semctl(first, second, cmd, arg)); | |
1411 | + host_to_target_semun(cmd,ptr,&arg,&dsarg); | |
1412 | + break; | |
1413 | + case GETALL: | |
1414 | + target_to_host_semun(cmd,&arg,ptr,&dsarg); | |
1415 | + ret = get_errno(semctl(first, second, cmd, arg)); | |
1416 | + host_to_target_semun(cmd,ptr,&arg,&dsarg); | |
1417 | + break; | |
1418 | + case SETALL: | |
1419 | + target_to_host_semun(cmd,&arg,ptr,&dsarg); | |
1420 | + ret = get_errno(semctl(first, second, cmd, arg)); | |
1421 | + host_to_target_semun(cmd,ptr,&arg,&dsarg); | |
1422 | + break; | |
1423 | + case IPC_STAT: | |
1424 | + target_to_host_semun(cmd,&arg,ptr,&dsarg); | |
1425 | + ret = get_errno(semctl(first, second, cmd, arg)); | |
1426 | + host_to_target_semun(cmd,ptr,&arg,&dsarg); | |
1427 | + break; | |
1428 | + case IPC_SET: | |
1429 | + target_to_host_semun(cmd,&arg,ptr,&dsarg); | |
1430 | + ret = get_errno(semctl(first, second, cmd, arg)); | |
1431 | + host_to_target_semun(cmd,ptr,&arg,&dsarg); | |
1432 | + break; | |
1433 | + default: | |
1434 | + ret = get_errno(semctl(first, second, cmd, arg)); | |
1435 | + } | |
1436 | + | |
1437 | + return ret; | |
1438 | +} | |
1439 | + | |
1239 | 1440 | /* ??? This only works with linear mappings. */ |
1240 | 1441 | static long do_ipc(long call, long first, long second, long third, |
1241 | 1442 | long ptr, long fifth) |
... | ... | @@ -1259,8 +1460,7 @@ static long do_ipc(long call, long first, long second, long third, |
1259 | 1460 | break; |
1260 | 1461 | |
1261 | 1462 | case IPCOP_semctl: |
1262 | - ret = get_errno(semctl(first, second, third, ((union semun*)ptr)->val)); | |
1263 | - | |
1463 | + ret = do_semctl(first, second, third, ptr); | |
1264 | 1464 | break; |
1265 | 1465 | |
1266 | 1466 | case IPCOP_semtimedop: | ... | ... |