syscall_emul.cc (13568:9c11b79e3223) | syscall_emul.cc (13569:47a2291177a7) |
---|---|
1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 1290 unchanged lines hidden (view full) --- 1299 int sim_fd = sfdp->getSimFD(); 1300 1301 int status = connect(sim_fd, 1302 (struct sockaddr *)addr.bufferPtr(), 1303 (socklen_t)addrlen); 1304 1305 return (status == -1) ? -errno : status; 1306} | 1/* 2 * Copyright (c) 2003-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 1290 unchanged lines hidden (view full) --- 1299 int sim_fd = sfdp->getSimFD(); 1300 1301 int status = connect(sim_fd, 1302 (struct sockaddr *)addr.bufferPtr(), 1303 (socklen_t)addrlen); 1304 1305 return (status == -1) ? -errno : status; 1306} |
1307 1308SyscallReturn 1309recvfromFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 1310{ 1311 int index = 0; 1312 int tgt_fd = p->getSyscallArg(tc, index); 1313 Addr bufrPtr = p->getSyscallArg(tc, index); 1314 size_t bufrLen = p->getSyscallArg(tc, index); 1315 int flags = p->getSyscallArg(tc, index); 1316 Addr addrPtr = p->getSyscallArg(tc, index); 1317 Addr addrlenPtr = p->getSyscallArg(tc, index); 1318 1319 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]); 1320 if (!sfdp) 1321 return -EBADF; 1322 int sim_fd = sfdp->getSimFD(); 1323 1324 // Reserve buffer space. 1325 BufferArg bufrBuf(bufrPtr, bufrLen); 1326 1327 // Get address length. 1328 socklen_t addrLen = 0; 1329 if (addrlenPtr != 0) { 1330 // Read address length parameter. 1331 BufferArg addrlenBuf(addrlenPtr, sizeof(socklen_t)); 1332 addrlenBuf.copyIn(tc->getMemProxy()); 1333 addrLen = *((socklen_t *)addrlenBuf.bufferPtr()); 1334 } 1335 1336 struct sockaddr sa, *sap = NULL; 1337 if (addrLen != 0) { 1338 BufferArg addrBuf(addrPtr, addrLen); 1339 addrBuf.copyIn(tc->getMemProxy()); 1340 memcpy(&sa, (struct sockaddr *)addrBuf.bufferPtr(), 1341 sizeof(struct sockaddr)); 1342 sap = &sa; 1343 } 1344 1345 ssize_t recvd_size = recvfrom(sim_fd, 1346 (void *)bufrBuf.bufferPtr(), 1347 bufrLen, flags, sap, (socklen_t *)&addrLen); 1348 1349 if (recvd_size == -1) 1350 return -errno; 1351 1352 // Pass the received data out. 1353 bufrBuf.copyOut(tc->getMemProxy()); 1354 1355 // Copy address to addrPtr and pass it on. 1356 if (sap != NULL) { 1357 BufferArg addrBuf(addrPtr, addrLen); 1358 memcpy(addrBuf.bufferPtr(), sap, sizeof(sa)); 1359 addrBuf.copyOut(tc->getMemProxy()); 1360 } 1361 1362 // Copy len to addrlenPtr and pass it on. 1363 if (addrLen != 0) { 1364 BufferArg addrlenBuf(addrlenPtr, sizeof(socklen_t)); 1365 *(socklen_t *)addrlenBuf.bufferPtr() = addrLen; 1366 addrlenBuf.copyOut(tc->getMemProxy()); 1367 } 1368 1369 return recvd_size; 1370} 1371 1372SyscallReturn 1373sendtoFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 1374{ 1375 int index = 0; 1376 int tgt_fd = p->getSyscallArg(tc, index); 1377 Addr bufrPtr = p->getSyscallArg(tc, index); 1378 size_t bufrLen = p->getSyscallArg(tc, index); 1379 int flags = p->getSyscallArg(tc, index); 1380 Addr addrPtr = p->getSyscallArg(tc, index); 1381 socklen_t addrLen = p->getSyscallArg(tc, index); 1382 1383 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]); 1384 if (!sfdp) 1385 return -EBADF; 1386 int sim_fd = sfdp->getSimFD(); 1387 1388 // Reserve buffer space. 1389 BufferArg bufrBuf(bufrPtr, bufrLen); 1390 bufrBuf.copyIn(tc->getMemProxy()); 1391 1392 struct sockaddr sa, *sap = nullptr; 1393 memset(&sa, 0, sizeof(sockaddr)); 1394 if (addrLen != 0) { 1395 BufferArg addrBuf(addrPtr, addrLen); 1396 addrBuf.copyIn(tc->getMemProxy()); 1397 memcpy(&sa, (sockaddr*)addrBuf.bufferPtr(), addrLen); 1398 sap = &sa; 1399 } 1400 1401 ssize_t sent_size = sendto(sim_fd, 1402 (void *)bufrBuf.bufferPtr(), 1403 bufrLen, flags, sap, (socklen_t)addrLen); 1404 1405 return (sent_size == -1) ? -errno : sent_size; 1406} 1407 1408SyscallReturn 1409recvmsgFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 1410{ 1411 int index = 0; 1412 int tgt_fd = p->getSyscallArg(tc, index); 1413 Addr msgPtr = p->getSyscallArg(tc, index); 1414 int flags = p->getSyscallArg(tc, index); 1415 1416 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]); 1417 if (!sfdp) 1418 return -EBADF; 1419 int sim_fd = sfdp->getSimFD(); 1420 1421 /** 1422 * struct msghdr { 1423 * void *msg_name; // optional address 1424 * socklen_t msg_namelen; // size of address 1425 * struct iovec *msg_iov; // iovec array 1426 * size_t msg_iovlen; // number entries in msg_iov 1427 * i // entries correspond to buffer 1428 * void *msg_control; // ancillary data 1429 * size_t msg_controllen; // ancillary data buffer len 1430 * int msg_flags; // flags on received message 1431 * }; 1432 * 1433 * struct iovec { 1434 * void *iov_base; // starting address 1435 * size_t iov_len; // number of bytes to transfer 1436 * }; 1437 */ 1438 1439 /** 1440 * The plan with this system call is to replace all of the pointers in the 1441 * structure and the substructure with BufferArg class pointers. We will 1442 * copy every field from the structures into our BufferArg classes. 1443 */ 1444 BufferArg msgBuf(msgPtr, sizeof(struct msghdr)); 1445 msgBuf.copyIn(tc->getMemProxy()); 1446 struct msghdr *msgHdr = (struct msghdr *)msgBuf.bufferPtr(); 1447 1448 /** 1449 * We will use these address place holders to retain the pointers which 1450 * we are going to replace with our own buffers in our simulator address 1451 * space. 1452 */ 1453 Addr msg_name_phold = 0; 1454 Addr msg_iov_phold = 0; 1455 Addr iovec_base_phold[msgHdr->msg_iovlen]; 1456 Addr msg_control_phold = 0; 1457 1458 /** 1459 * Record msg_name pointer then replace with buffer pointer. 1460 */ 1461 BufferArg *nameBuf = NULL; 1462 if (msgHdr->msg_name) { 1463 /*1*/msg_name_phold = (Addr)msgHdr->msg_name; 1464 /*2*/nameBuf = new BufferArg(msg_name_phold, msgHdr->msg_namelen); 1465 /*3*/nameBuf->copyIn(tc->getMemProxy()); 1466 /*4*/msgHdr->msg_name = nameBuf->bufferPtr(); 1467 } 1468 1469 /** 1470 * Record msg_iov pointer then replace with buffer pointer. Also, setup 1471 * an array of buffer pointers for the iovec structs record and replace 1472 * their pointers with buffer pointers. 1473 */ 1474 BufferArg *iovBuf = NULL; 1475 BufferArg *iovecBuf[msgHdr->msg_iovlen]; 1476 for (int i = 0; i < msgHdr->msg_iovlen; i++) { 1477 iovec_base_phold[i] = 0; 1478 iovecBuf[i] = NULL; 1479 } 1480 1481 if (msgHdr->msg_iov) { 1482 /*1*/msg_iov_phold = (Addr)msgHdr->msg_iov; 1483 /*2*/iovBuf = new BufferArg(msg_iov_phold, msgHdr->msg_iovlen * 1484 sizeof(struct iovec)); 1485 /*3*/iovBuf->copyIn(tc->getMemProxy()); 1486 for (int i = 0; i < msgHdr->msg_iovlen; i++) { 1487 if (((struct iovec *)iovBuf->bufferPtr())[i].iov_base) { 1488 /*1*/iovec_base_phold[i] = 1489 (Addr)((struct iovec *)iovBuf->bufferPtr())[i].iov_base; 1490 /*2*/iovecBuf[i] = new BufferArg(iovec_base_phold[i], 1491 ((struct iovec *)iovBuf->bufferPtr())[i].iov_len); 1492 /*3*/iovecBuf[i]->copyIn(tc->getMemProxy()); 1493 /*4*/((struct iovec *)iovBuf->bufferPtr())[i].iov_base = 1494 iovecBuf[i]->bufferPtr(); 1495 } 1496 } 1497 /*4*/msgHdr->msg_iov = (struct iovec *)iovBuf->bufferPtr(); 1498 } 1499 1500 /** 1501 * Record msg_control pointer then replace with buffer pointer. 1502 */ 1503 BufferArg *controlBuf = NULL; 1504 if (msgHdr->msg_control) { 1505 /*1*/msg_control_phold = (Addr)msgHdr->msg_control; 1506 /*2*/controlBuf = new BufferArg(msg_control_phold, 1507 CMSG_ALIGN(msgHdr->msg_controllen)); 1508 /*3*/controlBuf->copyIn(tc->getMemProxy()); 1509 /*4*/msgHdr->msg_control = controlBuf->bufferPtr(); 1510 } 1511 1512 ssize_t recvd_size = recvmsg(sim_fd, msgHdr, flags); 1513 1514 if (recvd_size < 0) 1515 return -errno; 1516 1517 if (msgHdr->msg_name) { 1518 nameBuf->copyOut(tc->getMemProxy()); 1519 delete(nameBuf); 1520 msgHdr->msg_name = (void *)msg_name_phold; 1521 } 1522 1523 if (msgHdr->msg_iov) { 1524 for (int i = 0; i< msgHdr->msg_iovlen; i++) { 1525 if (((struct iovec *)iovBuf->bufferPtr())[i].iov_base) { 1526 iovecBuf[i]->copyOut(tc->getMemProxy()); 1527 delete iovecBuf[i]; 1528 ((struct iovec *)iovBuf->bufferPtr())[i].iov_base = 1529 (void *)iovec_base_phold[i]; 1530 } 1531 } 1532 iovBuf->copyOut(tc->getMemProxy()); 1533 delete iovBuf; 1534 msgHdr->msg_iov = (struct iovec *)msg_iov_phold; 1535 } 1536 1537 if (msgHdr->msg_control) { 1538 controlBuf->copyOut(tc->getMemProxy()); 1539 delete(controlBuf); 1540 msgHdr->msg_control = (void *)msg_control_phold; 1541 } 1542 1543 msgBuf.copyOut(tc->getMemProxy()); 1544 1545 return recvd_size; 1546} 1547 1548SyscallReturn 1549sendmsgFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc) 1550{ 1551 int index = 0; 1552 int tgt_fd = p->getSyscallArg(tc, index); 1553 Addr msgPtr = p->getSyscallArg(tc, index); 1554 int flags = p->getSyscallArg(tc, index); 1555 1556 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]); 1557 if (!sfdp) 1558 return -EBADF; 1559 int sim_fd = sfdp->getSimFD(); 1560 1561 /** 1562 * Reserve buffer space. 1563 */ 1564 BufferArg msgBuf(msgPtr, sizeof(struct msghdr)); 1565 msgBuf.copyIn(tc->getMemProxy()); 1566 struct msghdr msgHdr = *((struct msghdr *)msgBuf.bufferPtr()); 1567 1568 /** 1569 * Assuming msgHdr.msg_iovlen >= 1, then there is no point calling 1570 * recvmsg without a buffer. 1571 */ 1572 struct iovec *iovPtr = msgHdr.msg_iov; 1573 BufferArg iovBuf((Addr)iovPtr, sizeof(struct iovec) * msgHdr.msg_iovlen); 1574 iovBuf.copyIn(tc->getMemProxy()); 1575 struct iovec *iov = (struct iovec *)iovBuf.bufferPtr(); 1576 msgHdr.msg_iov = iov; 1577 1578 /** 1579 * Cannot instantiate buffers till inside the loop. 1580 * Create array to hold buffer addresses, to be used during copyIn of 1581 * send data. 1582 */ 1583 BufferArg **bufferArray = (BufferArg **)malloc(msgHdr.msg_iovlen 1584 * sizeof(BufferArg *)); 1585 1586 /** 1587 * Iterate through the iovec structures: 1588 * Get the base buffer addreses, reserve iov_len amount of space for each. 1589 * Put the buf address into the bufferArray for later retrieval. 1590 */ 1591 for (int iovIndex = 0 ; iovIndex < msgHdr.msg_iovlen; iovIndex++) { 1592 Addr basePtr = (Addr) iov[iovIndex].iov_base; 1593 bufferArray[iovIndex] = new BufferArg(basePtr, iov[iovIndex].iov_len); 1594 bufferArray[iovIndex]->copyIn(tc->getMemProxy()); 1595 iov[iovIndex].iov_base = bufferArray[iovIndex]->bufferPtr(); 1596 } 1597 1598 ssize_t sent_size = sendmsg(sim_fd, &msgHdr, flags); 1599 int local_errno = errno; 1600 1601 /** 1602 * Free dynamically allocated memory. 1603 */ 1604 for (int iovIndex = 0 ; iovIndex < msgHdr.msg_iovlen; iovIndex++) { 1605 BufferArg *baseBuf = ( BufferArg *)bufferArray[iovIndex]; 1606 delete(baseBuf); 1607 } 1608 1609 /** 1610 * Malloced above. 1611 */ 1612 free(bufferArray); 1613 1614 return (sent_size < 0) ? -local_errno : sent_size; 1615} 1616 |
|