Commit 1bc012f65a9b269ec373ca7586032c205d112d8a

Authored by ths
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 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 1551 /* ??? This only works with linear mappings. */
1441 1552 static long do_ipc(long call, long first, long second, long third,
1442 1553 long ptr, long fifth)
... ... @@ -1473,27 +1584,27 @@ static long do_ipc(long call, long first, long second, long third,
1473 1584 break;
1474 1585  
1475 1586 case IPCOP_msgsnd:
1476   - ret = get_errno(msgsnd(first, (struct msgbuf *) ptr, second, third));
  1587 + ret = do_msgsnd(first, ptr, second, third);
1477 1588 break;
1478 1589  
1479 1590 case IPCOP_msgctl:
1480   - ret = get_errno(msgctl(first, second, (struct msqid_ds *) ptr));
  1591 + ret = do_msgctl(first, second, ptr);
1481 1592 break;
1482 1593  
1483 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 1608 break;
1498 1609  
1499 1610 case IPCOP_shmat:
... ...