Commit 1bc012f65a9b269ec373ca7586032c205d112d8a
1 parent
3eb6b044
IPC message translation.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2930 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
123 additions
and
12 deletions
linux-user/syscall.c
| @@ -1437,6 +1437,117 @@ static inline long do_semctl(long first, long second, long third, long ptr) | @@ -1437,6 +1437,117 @@ static inline long do_semctl(long first, long second, long third, long ptr) | ||
| 1437 | return ret; | 1437 | return ret; |
| 1438 | } | 1438 | } |
| 1439 | 1439 | ||
| 1440 | +struct target_msqid_ds | ||
| 1441 | +{ | ||
| 1442 | + struct target_ipc_perm msg_perm; | ||
| 1443 | + target_ulong msg_stime; | ||
| 1444 | + target_ulong __unused1; | ||
| 1445 | + target_ulong msg_rtime; | ||
| 1446 | + target_ulong __unused2; | ||
| 1447 | + target_ulong msg_ctime; | ||
| 1448 | + target_ulong __unused3; | ||
| 1449 | + target_ulong __msg_cbytes; | ||
| 1450 | + target_ulong msg_qnum; | ||
| 1451 | + target_ulong msg_qbytes; | ||
| 1452 | + target_ulong msg_lspid; | ||
| 1453 | + target_ulong msg_lrpid; | ||
| 1454 | + target_ulong __unused4; | ||
| 1455 | + target_ulong __unused5; | ||
| 1456 | +}; | ||
| 1457 | + | ||
| 1458 | +static inline void target_to_host_msqid_ds(struct msqid_ds *host_md, | ||
| 1459 | + target_ulong target_addr) | ||
| 1460 | +{ | ||
| 1461 | + struct target_msqid_ds *target_md; | ||
| 1462 | + | ||
| 1463 | + lock_user_struct(target_md, target_addr, 1); | ||
| 1464 | + target_to_host_ipc_perm(&(host_md->msg_perm),target_addr); | ||
| 1465 | + host_md->msg_stime = tswapl(target_md->msg_stime); | ||
| 1466 | + host_md->msg_rtime = tswapl(target_md->msg_rtime); | ||
| 1467 | + host_md->msg_ctime = tswapl(target_md->msg_ctime); | ||
| 1468 | + host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes); | ||
| 1469 | + host_md->msg_qnum = tswapl(target_md->msg_qnum); | ||
| 1470 | + host_md->msg_qbytes = tswapl(target_md->msg_qbytes); | ||
| 1471 | + host_md->msg_lspid = tswapl(target_md->msg_lspid); | ||
| 1472 | + host_md->msg_lrpid = tswapl(target_md->msg_lrpid); | ||
| 1473 | + unlock_user_struct(target_md, target_addr, 0); | ||
| 1474 | +} | ||
| 1475 | + | ||
| 1476 | +static inline void host_to_target_msqid_ds(target_ulong target_addr, | ||
| 1477 | + struct msqid_ds *host_md) | ||
| 1478 | +{ | ||
| 1479 | + struct target_msqid_ds *target_md; | ||
| 1480 | + | ||
| 1481 | + lock_user_struct(target_md, target_addr, 0); | ||
| 1482 | + host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)); | ||
| 1483 | + target_md->msg_stime = tswapl(host_md->msg_stime); | ||
| 1484 | + target_md->msg_rtime = tswapl(host_md->msg_rtime); | ||
| 1485 | + target_md->msg_ctime = tswapl(host_md->msg_ctime); | ||
| 1486 | + target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes); | ||
| 1487 | + target_md->msg_qnum = tswapl(host_md->msg_qnum); | ||
| 1488 | + target_md->msg_qbytes = tswapl(host_md->msg_qbytes); | ||
| 1489 | + target_md->msg_lspid = tswapl(host_md->msg_lspid); | ||
| 1490 | + target_md->msg_lrpid = tswapl(host_md->msg_lrpid); | ||
| 1491 | + unlock_user_struct(target_md, target_addr, 1); | ||
| 1492 | +} | ||
| 1493 | + | ||
| 1494 | +static inline long do_msgctl(long first, long second, long ptr) | ||
| 1495 | +{ | ||
| 1496 | + struct msqid_ds dsarg; | ||
| 1497 | + int cmd = second&0xff; | ||
| 1498 | + long ret = 0; | ||
| 1499 | + switch( cmd ) { | ||
| 1500 | + case IPC_STAT: | ||
| 1501 | + case IPC_SET: | ||
| 1502 | + target_to_host_msqid_ds(&dsarg,ptr); | ||
| 1503 | + ret = get_errno(msgctl(first, cmd, &dsarg)); | ||
| 1504 | + host_to_target_msqid_ds(ptr,&dsarg); | ||
| 1505 | + default: | ||
| 1506 | + ret = get_errno(msgctl(first, cmd, &dsarg)); | ||
| 1507 | + } | ||
| 1508 | + return ret; | ||
| 1509 | +} | ||
| 1510 | + | ||
| 1511 | +struct target_msgbuf { | ||
| 1512 | + target_ulong mtype; | ||
| 1513 | + char mtext[1]; | ||
| 1514 | +}; | ||
| 1515 | + | ||
| 1516 | +static inline long do_msgsnd(long msqid, long msgp, long msgsz, long msgflg) | ||
| 1517 | +{ | ||
| 1518 | + struct target_msgbuf *target_mb; | ||
| 1519 | + struct msgbuf *host_mb; | ||
| 1520 | + long ret = 0; | ||
| 1521 | + | ||
| 1522 | + lock_user_struct(target_mb,msgp,0); | ||
| 1523 | + host_mb = malloc(msgsz+sizeof(long)); | ||
| 1524 | + host_mb->mtype = tswapl(target_mb->mtype); | ||
| 1525 | + memcpy(host_mb->mtext,target_mb->mtext,msgsz); | ||
| 1526 | + ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg)); | ||
| 1527 | + free(host_mb); | ||
| 1528 | + unlock_user_struct(target_mb, msgp, 0); | ||
| 1529 | + | ||
| 1530 | + return ret; | ||
| 1531 | +} | ||
| 1532 | + | ||
| 1533 | +static inline long do_msgrcv(long msqid, long msgp, long msgsz, long msgtype, long msgflg) | ||
| 1534 | +{ | ||
| 1535 | + struct target_msgbuf *target_mb; | ||
| 1536 | + struct msgbuf *host_mb; | ||
| 1537 | + long ret = 0; | ||
| 1538 | + | ||
| 1539 | + lock_user_struct(target_mb, msgp, 0); | ||
| 1540 | + host_mb = malloc(msgsz+sizeof(long)); | ||
| 1541 | + ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg)); | ||
| 1542 | + if (ret > 0) | ||
| 1543 | + memcpy(target_mb->mtext, host_mb->mtext, ret); | ||
| 1544 | + target_mb->mtype = tswapl(host_mb->mtype); | ||
| 1545 | + free(host_mb); | ||
| 1546 | + unlock_user_struct(target_mb, msgp, 0); | ||
| 1547 | + | ||
| 1548 | + return ret; | ||
| 1549 | +} | ||
| 1550 | + | ||
| 1440 | /* ??? This only works with linear mappings. */ | 1551 | /* ??? This only works with linear mappings. */ |
| 1441 | static long do_ipc(long call, long first, long second, long third, | 1552 | static long do_ipc(long call, long first, long second, long third, |
| 1442 | long ptr, long fifth) | 1553 | long ptr, long fifth) |
| @@ -1473,27 +1584,27 @@ static long do_ipc(long call, long first, long second, long third, | @@ -1473,27 +1584,27 @@ static long do_ipc(long call, long first, long second, long third, | ||
| 1473 | break; | 1584 | break; |
| 1474 | 1585 | ||
| 1475 | case IPCOP_msgsnd: | 1586 | case IPCOP_msgsnd: |
| 1476 | - ret = get_errno(msgsnd(first, (struct msgbuf *) ptr, second, third)); | 1587 | + ret = do_msgsnd(first, ptr, second, third); |
| 1477 | break; | 1588 | break; |
| 1478 | 1589 | ||
| 1479 | case IPCOP_msgctl: | 1590 | case IPCOP_msgctl: |
| 1480 | - ret = get_errno(msgctl(first, second, (struct msqid_ds *) ptr)); | 1591 | + ret = do_msgctl(first, second, ptr); |
| 1481 | break; | 1592 | break; |
| 1482 | 1593 | ||
| 1483 | case IPCOP_msgrcv: | 1594 | case IPCOP_msgrcv: |
| 1484 | - { | ||
| 1485 | - struct ipc_kludge | ||
| 1486 | - { | ||
| 1487 | - void *__unbounded msgp; | ||
| 1488 | - long int msgtyp; | ||
| 1489 | - }; | 1595 | + { |
| 1596 | + struct ipc_kludge | ||
| 1597 | + { | ||
| 1598 | + void *__unbounded msgp; | ||
| 1599 | + long int msgtyp; | ||
| 1600 | + }; | ||
| 1490 | 1601 | ||
| 1491 | - struct ipc_kludge *foo = (struct ipc_kludge *) ptr; | ||
| 1492 | - struct msgbuf *msgp = (struct msgbuf *) foo->msgp; | 1602 | + struct ipc_kludge *foo = (struct ipc_kludge *) ptr; |
| 1603 | + struct msgbuf *msgp = (struct msgbuf *) foo->msgp; | ||
| 1493 | 1604 | ||
| 1494 | - ret = get_errno(msgrcv(first, msgp, second, 0, third)); | 1605 | + ret = do_msgrcv(first, (long)msgp, second, 0, third); |
| 1495 | 1606 | ||
| 1496 | - } | 1607 | + } |
| 1497 | break; | 1608 | break; |
| 1498 | 1609 | ||
| 1499 | case IPCOP_shmat: | 1610 | case IPCOP_shmat: |