syscall_emul.hh (14020:c9bf7a011602) syscall_emul.hh (14024:abe47b13653d)
1/*
2 * Copyright (c) 2012-2013, 2015 ARM Limited
3 * Copyright (c) 2015 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

--- 337 unchanged lines hidden (view full) ---

346 op &= ~OS::TGT_FUTEX_PRIVATE_FLAG;
347 op &= ~OS::TGT_FUTEX_CLOCK_REALTIME_FLAG;
348
349 FutexMap &futex_map = tc->getSystemPtr()->futexMap;
350
351 if (OS::TGT_FUTEX_WAIT == op || OS::TGT_FUTEX_WAIT_BITSET == op) {
352 // Ensure futex system call accessed atomically.
353 BufferArg buf(uaddr, sizeof(int));
1/*
2 * Copyright (c) 2012-2013, 2015 ARM Limited
3 * Copyright (c) 2015 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

--- 337 unchanged lines hidden (view full) ---

346 op &= ~OS::TGT_FUTEX_PRIVATE_FLAG;
347 op &= ~OS::TGT_FUTEX_CLOCK_REALTIME_FLAG;
348
349 FutexMap &futex_map = tc->getSystemPtr()->futexMap;
350
351 if (OS::TGT_FUTEX_WAIT == op || OS::TGT_FUTEX_WAIT_BITSET == op) {
352 // Ensure futex system call accessed atomically.
353 BufferArg buf(uaddr, sizeof(int));
354 buf.copyIn(tc->getMemProxy());
354 buf.copyIn(tc->getVirtProxy());
355 int mem_val = *(int*)buf.bufferPtr();
356
357 /*
358 * The value in memory at uaddr is not equal with the expected val
359 * (a different thread must have changed it before the system call was
360 * invoked). In this case, we need to throw an error.
361 */
362 if (val != mem_val)

--- 10 unchanged lines hidden (view full) ---

373 return futex_map.wakeup(uaddr, process->tgid(), val);
374 } else if (OS::TGT_FUTEX_WAKE_BITSET == op) {
375 return futex_map.wakeup_bitset(uaddr, process->tgid(), val3);
376 } else if (OS::TGT_FUTEX_REQUEUE == op ||
377 OS::TGT_FUTEX_CMP_REQUEUE == op) {
378
379 // Ensure futex system call accessed atomically.
380 BufferArg buf(uaddr, sizeof(int));
355 int mem_val = *(int*)buf.bufferPtr();
356
357 /*
358 * The value in memory at uaddr is not equal with the expected val
359 * (a different thread must have changed it before the system call was
360 * invoked). In this case, we need to throw an error.
361 */
362 if (val != mem_val)

--- 10 unchanged lines hidden (view full) ---

373 return futex_map.wakeup(uaddr, process->tgid(), val);
374 } else if (OS::TGT_FUTEX_WAKE_BITSET == op) {
375 return futex_map.wakeup_bitset(uaddr, process->tgid(), val3);
376 } else if (OS::TGT_FUTEX_REQUEUE == op ||
377 OS::TGT_FUTEX_CMP_REQUEUE == op) {
378
379 // Ensure futex system call accessed atomically.
380 BufferArg buf(uaddr, sizeof(int));
381 buf.copyIn(tc->getMemProxy());
381 buf.copyIn(tc->getVirtProxy());
382 int mem_val = *(int*)buf.bufferPtr();
383 /*
384 * For CMP_REQUEUE, the whole operation is only started only if
385 * val3 is still the value of the futex pointed to by uaddr.
386 */
387 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
388 return -OS::TGT_EWOULDBLOCK;
389 return futex_map.requeue(uaddr, process->tgid(), val, timeout, uaddr2);

--- 16 unchanged lines hidden (view full) ---

406 * +---+---+-----------+-----------+
407 * 4 4 12 12 <== # of bits
408 *
409 * reference: http://man7.org/linux/man-pages/man2/futex.2.html
410 *
411 */
412 // get value from simulated-space
413 BufferArg buf(uaddr2, sizeof(int));
382 int mem_val = *(int*)buf.bufferPtr();
383 /*
384 * For CMP_REQUEUE, the whole operation is only started only if
385 * val3 is still the value of the futex pointed to by uaddr.
386 */
387 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
388 return -OS::TGT_EWOULDBLOCK;
389 return futex_map.requeue(uaddr, process->tgid(), val, timeout, uaddr2);

--- 16 unchanged lines hidden (view full) ---

406 * +---+---+-----------+-----------+
407 * 4 4 12 12 <== # of bits
408 *
409 * reference: http://man7.org/linux/man-pages/man2/futex.2.html
410 *
411 */
412 // get value from simulated-space
413 BufferArg buf(uaddr2, sizeof(int));
414 buf.copyIn(tc->getMemProxy());
414 buf.copyIn(tc->getVirtProxy());
415 int oldval = *(int*)buf.bufferPtr();
416 int newval = oldval;
417 // extract op, oparg, cmp, cmparg from val3
418 int wake_cmparg = val3 & 0xfff;
419 int wake_oparg = (val3 & 0xfff000) >> 12;
420 int wake_cmp = (val3 & 0xf000000) >> 24;
421 int wake_op = (val3 & 0xf0000000) >> 28;
422 if ((wake_op & OS::TGT_FUTEX_OP_ARG_SHIFT) >> 3 == 1)

--- 7 unchanged lines hidden (view full) ---

430 else if (wake_op == OS::TGT_FUTEX_OP_OR)
431 newval |= wake_oparg;
432 else if (wake_op == OS::TGT_FUTEX_OP_ANDN)
433 newval &= ~wake_oparg;
434 else if (wake_op == OS::TGT_FUTEX_OP_XOR)
435 newval ^= wake_oparg;
436 // copy updated value back to simulated-space
437 *(int*)buf.bufferPtr() = newval;
415 int oldval = *(int*)buf.bufferPtr();
416 int newval = oldval;
417 // extract op, oparg, cmp, cmparg from val3
418 int wake_cmparg = val3 & 0xfff;
419 int wake_oparg = (val3 & 0xfff000) >> 12;
420 int wake_cmp = (val3 & 0xf000000) >> 24;
421 int wake_op = (val3 & 0xf0000000) >> 28;
422 if ((wake_op & OS::TGT_FUTEX_OP_ARG_SHIFT) >> 3 == 1)

--- 7 unchanged lines hidden (view full) ---

430 else if (wake_op == OS::TGT_FUTEX_OP_OR)
431 newval |= wake_oparg;
432 else if (wake_op == OS::TGT_FUTEX_OP_ANDN)
433 newval &= ~wake_oparg;
434 else if (wake_op == OS::TGT_FUTEX_OP_XOR)
435 newval ^= wake_oparg;
436 // copy updated value back to simulated-space
437 *(int*)buf.bufferPtr() = newval;
438 buf.copyOut(tc->getMemProxy());
438 buf.copyOut(tc->getVirtProxy());
439 // perform the first wake-up
440 int woken1 = futex_map.wakeup(uaddr, process->tgid(), val);
441 int woken2 = 0;
442 // calculate the condition of the second wake-up
443 bool is_wake2 = false;
444 if (wake_cmp == OS::TGT_FUTEX_OP_CMP_EQ)
445 is_wake2 = oldval == wake_cmparg;
446 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_NE)

--- 247 unchanged lines hidden (view full) ---

694 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
695 if (sfdp) {
696 int status;
697
698 switch (req) {
699 case SIOCGIFCONF: {
700 Addr conf_addr = p->getSyscallArg(tc, index);
701 BufferArg conf_arg(conf_addr, sizeof(ifconf));
439 // perform the first wake-up
440 int woken1 = futex_map.wakeup(uaddr, process->tgid(), val);
441 int woken2 = 0;
442 // calculate the condition of the second wake-up
443 bool is_wake2 = false;
444 if (wake_cmp == OS::TGT_FUTEX_OP_CMP_EQ)
445 is_wake2 = oldval == wake_cmparg;
446 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_NE)

--- 247 unchanged lines hidden (view full) ---

694 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*p->fds)[tgt_fd]);
695 if (sfdp) {
696 int status;
697
698 switch (req) {
699 case SIOCGIFCONF: {
700 Addr conf_addr = p->getSyscallArg(tc, index);
701 BufferArg conf_arg(conf_addr, sizeof(ifconf));
702 conf_arg.copyIn(tc->getMemProxy());
702 conf_arg.copyIn(tc->getVirtProxy());
703
704 ifconf *conf = (ifconf*)conf_arg.bufferPtr();
705 Addr ifc_buf_addr = (Addr)conf->ifc_buf;
706 BufferArg ifc_buf_arg(ifc_buf_addr, conf->ifc_len);
703
704 ifconf *conf = (ifconf*)conf_arg.bufferPtr();
705 Addr ifc_buf_addr = (Addr)conf->ifc_buf;
706 BufferArg ifc_buf_arg(ifc_buf_addr, conf->ifc_len);
707 ifc_buf_arg.copyIn(tc->getMemProxy());
707 ifc_buf_arg.copyIn(tc->getVirtProxy());
708
709 conf->ifc_buf = (char*)ifc_buf_arg.bufferPtr();
710
711 status = ioctl(sfdp->getSimFD(), req, conf_arg.bufferPtr());
712 if (status != -1) {
713 conf->ifc_buf = (char*)ifc_buf_addr;
708
709 conf->ifc_buf = (char*)ifc_buf_arg.bufferPtr();
710
711 status = ioctl(sfdp->getSimFD(), req, conf_arg.bufferPtr());
712 if (status != -1) {
713 conf->ifc_buf = (char*)ifc_buf_addr;
714 ifc_buf_arg.copyOut(tc->getMemProxy());
715 conf_arg.copyOut(tc->getMemProxy());
714 ifc_buf_arg.copyOut(tc->getVirtProxy());
715 conf_arg.copyOut(tc->getVirtProxy());
716 }
717
718 return status;
719 }
720 case SIOCGIFFLAGS:
721#if defined(__linux__)
722 case SIOCGIFINDEX:
723#endif
724 case SIOCGIFNETMASK:
725 case SIOCGIFADDR:
726#if defined(__linux__)
727 case SIOCGIFHWADDR:
728#endif
729 case SIOCGIFMTU: {
730 Addr req_addr = p->getSyscallArg(tc, index);
731 BufferArg req_arg(req_addr, sizeof(ifreq));
716 }
717
718 return status;
719 }
720 case SIOCGIFFLAGS:
721#if defined(__linux__)
722 case SIOCGIFINDEX:
723#endif
724 case SIOCGIFNETMASK:
725 case SIOCGIFADDR:
726#if defined(__linux__)
727 case SIOCGIFHWADDR:
728#endif
729 case SIOCGIFMTU: {
730 Addr req_addr = p->getSyscallArg(tc, index);
731 BufferArg req_arg(req_addr, sizeof(ifreq));
732 req_arg.copyIn(tc->getMemProxy());
732 req_arg.copyIn(tc->getVirtProxy());
733
734 status = ioctl(sfdp->getSimFD(), req, req_arg.bufferPtr());
735 if (status != -1)
733
734 status = ioctl(sfdp->getSimFD(), req, req_arg.bufferPtr());
735 if (status != -1)
736 req_arg.copyOut(tc->getMemProxy());
736 req_arg.copyOut(tc->getVirtProxy());
737 return status;
738 }
739 }
740 }
741
742 /**
743 * For lack of a better return code, return ENOTTY. Ideally, we should
744 * return something better here, but at least we issue the warning.

--- 18 unchanged lines hidden (view full) ---

763 if (isopenat)
764 tgt_dirfd = p->getSyscallArg(tc, index);
765
766 /**
767 * Retrieve the simulated process' memory proxy and then read in the path
768 * string from that memory space into the host's working memory space.
769 */
770 std::string path;
737 return status;
738 }
739 }
740 }
741
742 /**
743 * For lack of a better return code, return ENOTTY. Ideally, we should
744 * return something better here, but at least we issue the warning.

--- 18 unchanged lines hidden (view full) ---

763 if (isopenat)
764 tgt_dirfd = p->getSyscallArg(tc, index);
765
766 /**
767 * Retrieve the simulated process' memory proxy and then read in the path
768 * string from that memory space into the host's working memory space.
769 */
770 std::string path;
771 if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
771 if (!tc->getVirtProxy().tryReadString(path, p->getSyscallArg(tc, index)))
772 return -EFAULT;
773
774#ifdef __CYGWIN32__
775 int host_flags = O_BINARY;
776#else
777 int host_flags = 0;
778#endif
779 /**

--- 191 unchanged lines hidden (view full) ---

971 auto process = tc->getProcessPtr();
972
973 int olddirfd = process->getSyscallArg(tc, index);
974 if (olddirfd != OS::TGT_AT_FDCWD)
975 warn("renameat: first argument not AT_FDCWD; unlikely to work");
976
977 std::string old_name;
978
772 return -EFAULT;
773
774#ifdef __CYGWIN32__
775 int host_flags = O_BINARY;
776#else
777 int host_flags = 0;
778#endif
779 /**

--- 191 unchanged lines hidden (view full) ---

971 auto process = tc->getProcessPtr();
972
973 int olddirfd = process->getSyscallArg(tc, index);
974 if (olddirfd != OS::TGT_AT_FDCWD)
975 warn("renameat: first argument not AT_FDCWD; unlikely to work");
976
977 std::string old_name;
978
979 if (!tc->getMemProxy().tryReadString(old_name,
979 if (!tc->getVirtProxy().tryReadString(old_name,
980 process->getSyscallArg(tc, index)))
981 return -EFAULT;
982
983 int newdirfd = process->getSyscallArg(tc, index);
984 if (newdirfd != OS::TGT_AT_FDCWD)
985 warn("renameat: third argument not AT_FDCWD; unlikely to work");
986
987 std::string new_name;
988
980 process->getSyscallArg(tc, index)))
981 return -EFAULT;
982
983 int newdirfd = process->getSyscallArg(tc, index);
984 if (newdirfd != OS::TGT_AT_FDCWD)
985 warn("renameat: third argument not AT_FDCWD; unlikely to work");
986
987 std::string new_name;
988
989 if (!tc->getMemProxy().tryReadString(new_name,
989 if (!tc->getVirtProxy().tryReadString(new_name,
990 process->getSyscallArg(tc, index)))
991 return -EFAULT;
992
993 // Adjust path for cwd and redirection
994 old_name = process->checkPathRedirect(old_name);
995 new_name = process->checkPathRedirect(new_name);
996
997 int result = rename(old_name.c_str(), new_name.c_str());

--- 10 unchanged lines hidden (view full) ---

1008
1009 TypedBufferArg<typename OS::tgt_sysinfo>
1010 sysinfo(process->getSyscallArg(tc, index));
1011
1012 sysinfo->uptime = seconds_since_epoch;
1013 sysinfo->totalram = process->system->memSize();
1014 sysinfo->mem_unit = 1;
1015
990 process->getSyscallArg(tc, index)))
991 return -EFAULT;
992
993 // Adjust path for cwd and redirection
994 old_name = process->checkPathRedirect(old_name);
995 new_name = process->checkPathRedirect(new_name);
996
997 int result = rename(old_name.c_str(), new_name.c_str());

--- 10 unchanged lines hidden (view full) ---

1008
1009 TypedBufferArg<typename OS::tgt_sysinfo>
1010 sysinfo(process->getSyscallArg(tc, index));
1011
1012 sysinfo->uptime = seconds_since_epoch;
1013 sysinfo->totalram = process->system->memSize();
1014 sysinfo->mem_unit = 1;
1015
1016 sysinfo.copyOut(tc->getMemProxy());
1016 sysinfo.copyOut(tc->getVirtProxy());
1017
1018 return 0;
1019}
1020
1021/// Target chmod() handler.
1022template <class OS>
1023SyscallReturn
1024chmodFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1025{
1026 std::string path;
1027 auto process = tc->getProcessPtr();
1028
1029 int index = 0;
1017
1018 return 0;
1019}
1020
1021/// Target chmod() handler.
1022template <class OS>
1023SyscallReturn
1024chmodFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1025{
1026 std::string path;
1027 auto process = tc->getProcessPtr();
1028
1029 int index = 0;
1030 if (!tc->getMemProxy().tryReadString(path,
1030 if (!tc->getVirtProxy().tryReadString(path,
1031 process->getSyscallArg(tc, index))) {
1032 return -EFAULT;
1033 }
1034
1035 uint32_t mode = process->getSyscallArg(tc, index);
1036 mode_t hostMode = 0;
1037
1038 // XXX translate mode flags via OS::something???

--- 16 unchanged lines hidden (view full) ---

1055{
1056 int index = 0;
1057 auto p = tc->getProcessPtr();
1058 Addr fdsPtr = p->getSyscallArg(tc, index);
1059 int nfds = p->getSyscallArg(tc, index);
1060 int tmout = p->getSyscallArg(tc, index);
1061
1062 BufferArg fdsBuf(fdsPtr, sizeof(struct pollfd) * nfds);
1031 process->getSyscallArg(tc, index))) {
1032 return -EFAULT;
1033 }
1034
1035 uint32_t mode = process->getSyscallArg(tc, index);
1036 mode_t hostMode = 0;
1037
1038 // XXX translate mode flags via OS::something???

--- 16 unchanged lines hidden (view full) ---

1055{
1056 int index = 0;
1057 auto p = tc->getProcessPtr();
1058 Addr fdsPtr = p->getSyscallArg(tc, index);
1059 int nfds = p->getSyscallArg(tc, index);
1060 int tmout = p->getSyscallArg(tc, index);
1061
1062 BufferArg fdsBuf(fdsPtr, sizeof(struct pollfd) * nfds);
1063 fdsBuf.copyIn(tc->getMemProxy());
1063 fdsBuf.copyIn(tc->getVirtProxy());
1064
1065 /**
1066 * Record the target file descriptors in a local variable. We need to
1067 * replace them with host file descriptors but we need a temporary copy
1068 * for later. Afterwards, replace each target file descriptor in the
1069 * poll_fd array with its host_fd.
1070 */
1071 int temp_tgt_fds[nfds];

--- 43 unchanged lines hidden (view full) ---

1115 auto tgt_fd = temp_tgt_fds[index];
1116 ((struct pollfd *)fdsBuf.bufferPtr())[index].fd = tgt_fd;
1117 }
1118
1119 /**
1120 * Copy out the pollfd struct because the host may have updated fields
1121 * in the structure.
1122 */
1064
1065 /**
1066 * Record the target file descriptors in a local variable. We need to
1067 * replace them with host file descriptors but we need a temporary copy
1068 * for later. Afterwards, replace each target file descriptor in the
1069 * poll_fd array with its host_fd.
1070 */
1071 int temp_tgt_fds[nfds];

--- 43 unchanged lines hidden (view full) ---

1115 auto tgt_fd = temp_tgt_fds[index];
1116 ((struct pollfd *)fdsBuf.bufferPtr())[index].fd = tgt_fd;
1117 }
1118
1119 /**
1120 * Copy out the pollfd struct because the host may have updated fields
1121 * in the structure.
1122 */
1123 fdsBuf.copyOut(tc->getMemProxy());
1123 fdsBuf.copyOut(tc->getVirtProxy());
1124
1125 return status;
1126}
1127
1128/// Target fchmod() handler.
1129template <class OS>
1130SyscallReturn
1131fchmodFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)

--- 99 unchanged lines hidden (view full) ---

1231template <class OS>
1232SyscallReturn
1233statFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1234{
1235 std::string path;
1236 auto process = tc->getProcessPtr();
1237
1238 int index = 0;
1124
1125 return status;
1126}
1127
1128/// Target fchmod() handler.
1129template <class OS>
1130SyscallReturn
1131fchmodFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)

--- 99 unchanged lines hidden (view full) ---

1231template <class OS>
1232SyscallReturn
1233statFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1234{
1235 std::string path;
1236 auto process = tc->getProcessPtr();
1237
1238 int index = 0;
1239 if (!tc->getMemProxy().tryReadString(path,
1239 if (!tc->getVirtProxy().tryReadString(path,
1240 process->getSyscallArg(tc, index))) {
1241 return -EFAULT;
1242 }
1243 Addr bufPtr = process->getSyscallArg(tc, index);
1244
1245 // Adjust path for cwd and redirection
1246 path = process->checkPathRedirect(path);
1247
1248 struct stat hostBuf;
1249 int result = stat(path.c_str(), &hostBuf);
1250
1251 if (result < 0)
1252 return -errno;
1253
1240 process->getSyscallArg(tc, index))) {
1241 return -EFAULT;
1242 }
1243 Addr bufPtr = process->getSyscallArg(tc, index);
1244
1245 // Adjust path for cwd and redirection
1246 path = process->checkPathRedirect(path);
1247
1248 struct stat hostBuf;
1249 int result = stat(path.c_str(), &hostBuf);
1250
1251 if (result < 0)
1252 return -errno;
1253
1254 copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
1254 copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
1255
1256 return 0;
1257}
1258
1259
1260/// Target stat64() handler.
1261template <class OS>
1262SyscallReturn
1263stat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
1264{
1265 std::string path;
1266 auto process = tc->getProcessPtr();
1267
1268 int index = 0;
1255
1256 return 0;
1257}
1258
1259
1260/// Target stat64() handler.
1261template <class OS>
1262SyscallReturn
1263stat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
1264{
1265 std::string path;
1266 auto process = tc->getProcessPtr();
1267
1268 int index = 0;
1269 if (!tc->getMemProxy().tryReadString(path,
1269 if (!tc->getVirtProxy().tryReadString(path,
1270 process->getSyscallArg(tc, index)))
1271 return -EFAULT;
1272 Addr bufPtr = process->getSyscallArg(tc, index);
1273
1274 // Adjust path for cwd and redirection
1275 path = process->checkPathRedirect(path);
1276
1277#if NO_STAT64
1278 struct stat hostBuf;
1279 int result = stat(path.c_str(), &hostBuf);
1280#else
1281 struct stat64 hostBuf;
1282 int result = stat64(path.c_str(), &hostBuf);
1283#endif
1284
1285 if (result < 0)
1286 return -errno;
1287
1270 process->getSyscallArg(tc, index)))
1271 return -EFAULT;
1272 Addr bufPtr = process->getSyscallArg(tc, index);
1273
1274 // Adjust path for cwd and redirection
1275 path = process->checkPathRedirect(path);
1276
1277#if NO_STAT64
1278 struct stat hostBuf;
1279 int result = stat(path.c_str(), &hostBuf);
1280#else
1281 struct stat64 hostBuf;
1282 int result = stat64(path.c_str(), &hostBuf);
1283#endif
1284
1285 if (result < 0)
1286 return -errno;
1287
1288 copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
1288 copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
1289
1290 return 0;
1291}
1292
1293
1294/// Target fstatat64() handler.
1295template <class OS>
1296SyscallReturn
1297fstatat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
1298{
1299 int index = 0;
1300 auto process = tc->getProcessPtr();
1301 int dirfd = process->getSyscallArg(tc, index);
1302 if (dirfd != OS::TGT_AT_FDCWD)
1303 warn("fstatat64: first argument not AT_FDCWD; unlikely to work");
1304
1305 std::string path;
1289
1290 return 0;
1291}
1292
1293
1294/// Target fstatat64() handler.
1295template <class OS>
1296SyscallReturn
1297fstatat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
1298{
1299 int index = 0;
1300 auto process = tc->getProcessPtr();
1301 int dirfd = process->getSyscallArg(tc, index);
1302 if (dirfd != OS::TGT_AT_FDCWD)
1303 warn("fstatat64: first argument not AT_FDCWD; unlikely to work");
1304
1305 std::string path;
1306 if (!tc->getMemProxy().tryReadString(path,
1306 if (!tc->getVirtProxy().tryReadString(path,
1307 process->getSyscallArg(tc, index)))
1308 return -EFAULT;
1309 Addr bufPtr = process->getSyscallArg(tc, index);
1310
1311 // Adjust path for cwd and redirection
1312 path = process->checkPathRedirect(path);
1313
1314#if NO_STAT64
1315 struct stat hostBuf;
1316 int result = stat(path.c_str(), &hostBuf);
1317#else
1318 struct stat64 hostBuf;
1319 int result = stat64(path.c_str(), &hostBuf);
1320#endif
1321
1322 if (result < 0)
1323 return -errno;
1324
1307 process->getSyscallArg(tc, index)))
1308 return -EFAULT;
1309 Addr bufPtr = process->getSyscallArg(tc, index);
1310
1311 // Adjust path for cwd and redirection
1312 path = process->checkPathRedirect(path);
1313
1314#if NO_STAT64
1315 struct stat hostBuf;
1316 int result = stat(path.c_str(), &hostBuf);
1317#else
1318 struct stat64 hostBuf;
1319 int result = stat64(path.c_str(), &hostBuf);
1320#endif
1321
1322 if (result < 0)
1323 return -errno;
1324
1325 copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
1325 copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
1326
1327 return 0;
1328}
1329
1330
1331/// Target fstat64() handler.
1332template <class OS>
1333SyscallReturn

--- 15 unchanged lines hidden (view full) ---

1349#else
1350 struct stat64 hostBuf;
1351 int result = fstat64(sim_fd, &hostBuf);
1352#endif
1353
1354 if (result < 0)
1355 return -errno;
1356
1326
1327 return 0;
1328}
1329
1330
1331/// Target fstat64() handler.
1332template <class OS>
1333SyscallReturn

--- 15 unchanged lines hidden (view full) ---

1349#else
1350 struct stat64 hostBuf;
1351 int result = fstat64(sim_fd, &hostBuf);
1352#endif
1353
1354 if (result < 0)
1355 return -errno;
1356
1357 copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (sim_fd == 1));
1357 copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
1358
1359 return 0;
1360}
1361
1362
1363/// Target lstat() handler.
1364template <class OS>
1365SyscallReturn
1366lstatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1367{
1368 std::string path;
1369 auto process = tc->getProcessPtr();
1370
1371 int index = 0;
1358
1359 return 0;
1360}
1361
1362
1363/// Target lstat() handler.
1364template <class OS>
1365SyscallReturn
1366lstatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1367{
1368 std::string path;
1369 auto process = tc->getProcessPtr();
1370
1371 int index = 0;
1372 if (!tc->getMemProxy().tryReadString(path,
1372 if (!tc->getVirtProxy().tryReadString(path,
1373 process->getSyscallArg(tc, index))) {
1374 return -EFAULT;
1375 }
1376 Addr bufPtr = process->getSyscallArg(tc, index);
1377
1378 // Adjust path for cwd and redirection
1379 path = process->checkPathRedirect(path);
1380
1381 struct stat hostBuf;
1382 int result = lstat(path.c_str(), &hostBuf);
1383
1384 if (result < 0)
1385 return -errno;
1386
1373 process->getSyscallArg(tc, index))) {
1374 return -EFAULT;
1375 }
1376 Addr bufPtr = process->getSyscallArg(tc, index);
1377
1378 // Adjust path for cwd and redirection
1379 path = process->checkPathRedirect(path);
1380
1381 struct stat hostBuf;
1382 int result = lstat(path.c_str(), &hostBuf);
1383
1384 if (result < 0)
1385 return -errno;
1386
1387 copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
1387 copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
1388
1389 return 0;
1390}
1391
1392/// Target lstat64() handler.
1393template <class OS>
1394SyscallReturn
1395lstat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
1396{
1397 std::string path;
1398 auto process = tc->getProcessPtr();
1399
1400 int index = 0;
1388
1389 return 0;
1390}
1391
1392/// Target lstat64() handler.
1393template <class OS>
1394SyscallReturn
1395lstat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
1396{
1397 std::string path;
1398 auto process = tc->getProcessPtr();
1399
1400 int index = 0;
1401 if (!tc->getMemProxy().tryReadString(path,
1401 if (!tc->getVirtProxy().tryReadString(path,
1402 process->getSyscallArg(tc, index))) {
1403 return -EFAULT;
1404 }
1405 Addr bufPtr = process->getSyscallArg(tc, index);
1406
1407 // Adjust path for cwd and redirection
1408 path = process->checkPathRedirect(path);
1409
1410#if NO_STAT64
1411 struct stat hostBuf;
1412 int result = lstat(path.c_str(), &hostBuf);
1413#else
1414 struct stat64 hostBuf;
1415 int result = lstat64(path.c_str(), &hostBuf);
1416#endif
1417
1418 if (result < 0)
1419 return -errno;
1420
1402 process->getSyscallArg(tc, index))) {
1403 return -EFAULT;
1404 }
1405 Addr bufPtr = process->getSyscallArg(tc, index);
1406
1407 // Adjust path for cwd and redirection
1408 path = process->checkPathRedirect(path);
1409
1410#if NO_STAT64
1411 struct stat hostBuf;
1412 int result = lstat(path.c_str(), &hostBuf);
1413#else
1414 struct stat64 hostBuf;
1415 int result = lstat64(path.c_str(), &hostBuf);
1416#endif
1417
1418 if (result < 0)
1419 return -errno;
1420
1421 copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
1421 copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
1422
1423 return 0;
1424}
1425
1426/// Target fstat() handler.
1427template <class OS>
1428SyscallReturn
1429fstatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)

--- 11 unchanged lines hidden (view full) ---

1441 int sim_fd = ffdp->getSimFD();
1442
1443 struct stat hostBuf;
1444 int result = fstat(sim_fd, &hostBuf);
1445
1446 if (result < 0)
1447 return -errno;
1448
1422
1423 return 0;
1424}
1425
1426/// Target fstat() handler.
1427template <class OS>
1428SyscallReturn
1429fstatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)

--- 11 unchanged lines hidden (view full) ---

1441 int sim_fd = ffdp->getSimFD();
1442
1443 struct stat hostBuf;
1444 int result = fstat(sim_fd, &hostBuf);
1445
1446 if (result < 0)
1447 return -errno;
1448
1449 copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (sim_fd == 1));
1449 copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
1450
1451 return 0;
1452}
1453
1454/// Target statfs() handler.
1455template <class OS>
1456SyscallReturn
1457statfsFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1458{
1459#if defined(__linux__)
1460 std::string path;
1461 auto process = tc->getProcessPtr();
1462
1463 int index = 0;
1450
1451 return 0;
1452}
1453
1454/// Target statfs() handler.
1455template <class OS>
1456SyscallReturn
1457statfsFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1458{
1459#if defined(__linux__)
1460 std::string path;
1461 auto process = tc->getProcessPtr();
1462
1463 int index = 0;
1464 if (!tc->getMemProxy().tryReadString(path,
1464 if (!tc->getVirtProxy().tryReadString(path,
1465 process->getSyscallArg(tc, index))) {
1466 return -EFAULT;
1467 }
1468 Addr bufPtr = process->getSyscallArg(tc, index);
1469
1470 // Adjust path for cwd and redirection
1471 path = process->checkPathRedirect(path);
1472
1473 struct statfs hostBuf;
1474 int result = statfs(path.c_str(), &hostBuf);
1475
1476 if (result < 0)
1477 return -errno;
1478
1465 process->getSyscallArg(tc, index))) {
1466 return -EFAULT;
1467 }
1468 Addr bufPtr = process->getSyscallArg(tc, index);
1469
1470 // Adjust path for cwd and redirection
1471 path = process->checkPathRedirect(path);
1472
1473 struct statfs hostBuf;
1474 int result = statfs(path.c_str(), &hostBuf);
1475
1476 if (result < 0)
1477 return -errno;
1478
1479 copyOutStatfsBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
1479 copyOutStatfsBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
1480 return 0;
1481#else
1482 warnUnsupportedOS("statfs");
1483 return -1;
1484#endif
1485}
1486
1487template <class OS>

--- 74 unchanged lines hidden (view full) ---

1562 ctc->setProcessPtr(cp);
1563 cp->assignThreadContext(ctc->contextId());
1564 owner->revokeThreadContext(ctc->contextId());
1565
1566 if (flags & OS::TGT_CLONE_PARENT_SETTID) {
1567 BufferArg ptidBuf(ptidPtr, sizeof(long));
1568 long *ptid = (long *)ptidBuf.bufferPtr();
1569 *ptid = cp->pid();
1480 return 0;
1481#else
1482 warnUnsupportedOS("statfs");
1483 return -1;
1484#endif
1485}
1486
1487template <class OS>

--- 74 unchanged lines hidden (view full) ---

1562 ctc->setProcessPtr(cp);
1563 cp->assignThreadContext(ctc->contextId());
1564 owner->revokeThreadContext(ctc->contextId());
1565
1566 if (flags & OS::TGT_CLONE_PARENT_SETTID) {
1567 BufferArg ptidBuf(ptidPtr, sizeof(long));
1568 long *ptid = (long *)ptidBuf.bufferPtr();
1569 *ptid = cp->pid();
1570 ptidBuf.copyOut(tc->getMemProxy());
1570 ptidBuf.copyOut(tc->getVirtProxy());
1571 }
1572
1573 if (flags & OS::TGT_CLONE_THREAD) {
1574 cp->pTable->shared = true;
1575 cp->useForClone = true;
1576 }
1577 cp->initState();
1578 p->clone(tc, ctc, cp, flags);

--- 4 unchanged lines hidden (view full) ---

1583 } else if (flags & OS::TGT_SIGCHLD) {
1584 *cp->sigchld = true;
1585 }
1586
1587 if (flags & OS::TGT_CLONE_CHILD_SETTID) {
1588 BufferArg ctidBuf(ctidPtr, sizeof(long));
1589 long *ctid = (long *)ctidBuf.bufferPtr();
1590 *ctid = cp->pid();
1571 }
1572
1573 if (flags & OS::TGT_CLONE_THREAD) {
1574 cp->pTable->shared = true;
1575 cp->useForClone = true;
1576 }
1577 cp->initState();
1578 p->clone(tc, ctc, cp, flags);

--- 4 unchanged lines hidden (view full) ---

1583 } else if (flags & OS::TGT_SIGCHLD) {
1584 *cp->sigchld = true;
1585 }
1586
1587 if (flags & OS::TGT_CLONE_CHILD_SETTID) {
1588 BufferArg ctidBuf(ctidPtr, sizeof(long));
1589 long *ctid = (long *)ctidBuf.bufferPtr();
1590 *ctid = cp->pid();
1591 ctidBuf.copyOut(ctc->getMemProxy());
1591 ctidBuf.copyOut(ctc->getVirtProxy());
1592 }
1593
1594 if (flags & OS::TGT_CLONE_CHILD_CLEARTID)
1595 cp->childClearTID = (uint64_t)ctidPtr;
1596
1597 ctc->clearArchRegs();
1598
1599 OS::archClone(flags, p, cp, tc, ctc, newStack, tlsPtr);

--- 39 unchanged lines hidden (view full) ---

1639 int sim_fd = ffdp->getSimFD();
1640
1641 struct statfs hostBuf;
1642 int result = fstatfs(sim_fd, &hostBuf);
1643
1644 if (result < 0)
1645 return -errno;
1646
1592 }
1593
1594 if (flags & OS::TGT_CLONE_CHILD_CLEARTID)
1595 cp->childClearTID = (uint64_t)ctidPtr;
1596
1597 ctc->clearArchRegs();
1598
1599 OS::archClone(flags, p, cp, tc, ctc, newStack, tlsPtr);

--- 39 unchanged lines hidden (view full) ---

1639 int sim_fd = ffdp->getSimFD();
1640
1641 struct statfs hostBuf;
1642 int result = fstatfs(sim_fd, &hostBuf);
1643
1644 if (result < 0)
1645 return -errno;
1646
1647 copyOutStatfsBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
1647 copyOutStatfsBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
1648
1649 return 0;
1650}
1651
1652/// Target readv() handler.
1653template <class OS>
1654SyscallReturn
1655readvFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1656{
1657 int index = 0;
1658 auto p = tc->getProcessPtr();
1659 int tgt_fd = p->getSyscallArg(tc, index);
1660
1661 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
1662 if (!ffdp)
1663 return -EBADF;
1664 int sim_fd = ffdp->getSimFD();
1665
1648
1649 return 0;
1650}
1651
1652/// Target readv() handler.
1653template <class OS>
1654SyscallReturn
1655readvFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1656{
1657 int index = 0;
1658 auto p = tc->getProcessPtr();
1659 int tgt_fd = p->getSyscallArg(tc, index);
1660
1661 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
1662 if (!ffdp)
1663 return -EBADF;
1664 int sim_fd = ffdp->getSimFD();
1665
1666 PortProxy &prox = tc->getMemProxy();
1666 PortProxy &prox = tc->getVirtProxy();
1667 uint64_t tiov_base = p->getSyscallArg(tc, index);
1668 size_t count = p->getSyscallArg(tc, index);
1669 typename OS::tgt_iovec tiov[count];
1670 struct iovec hiov[count];
1671 for (size_t i = 0; i < count; ++i) {
1672 prox.readBlob(tiov_base + (i * sizeof(typename OS::tgt_iovec)),
1673 &tiov[i], sizeof(typename OS::tgt_iovec));
1674 hiov[i].iov_len = TheISA::gtoh(tiov[i].iov_len);

--- 23 unchanged lines hidden (view full) ---

1698 auto p = tc->getProcessPtr();
1699 int tgt_fd = p->getSyscallArg(tc, index);
1700
1701 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
1702 if (!hbfdp)
1703 return -EBADF;
1704 int sim_fd = hbfdp->getSimFD();
1705
1667 uint64_t tiov_base = p->getSyscallArg(tc, index);
1668 size_t count = p->getSyscallArg(tc, index);
1669 typename OS::tgt_iovec tiov[count];
1670 struct iovec hiov[count];
1671 for (size_t i = 0; i < count; ++i) {
1672 prox.readBlob(tiov_base + (i * sizeof(typename OS::tgt_iovec)),
1673 &tiov[i], sizeof(typename OS::tgt_iovec));
1674 hiov[i].iov_len = TheISA::gtoh(tiov[i].iov_len);

--- 23 unchanged lines hidden (view full) ---

1698 auto p = tc->getProcessPtr();
1699 int tgt_fd = p->getSyscallArg(tc, index);
1700
1701 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
1702 if (!hbfdp)
1703 return -EBADF;
1704 int sim_fd = hbfdp->getSimFD();
1705
1706 PortProxy &prox = tc->getMemProxy();
1706 PortProxy &prox = tc->getVirtProxy();
1707 uint64_t tiov_base = p->getSyscallArg(tc, index);
1708 size_t count = p->getSyscallArg(tc, index);
1709 struct iovec hiov[count];
1710 for (size_t i = 0; i < count; ++i) {
1711 typename OS::tgt_iovec tiov;
1712
1713 prox.readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec),
1714 &tiov, sizeof(typename OS::tgt_iovec));

--- 121 unchanged lines hidden (view full) ---

1836 }
1837
1838 // Allocate physical memory and map it in. If the page table is already
1839 // mapped and clobber is not set, the simulator will issue throw a
1840 // fatal and bail out of the simulation.
1841 p->allocateMem(start, length, clobber);
1842
1843 // Transfer content into target address space.
1707 uint64_t tiov_base = p->getSyscallArg(tc, index);
1708 size_t count = p->getSyscallArg(tc, index);
1709 struct iovec hiov[count];
1710 for (size_t i = 0; i < count; ++i) {
1711 typename OS::tgt_iovec tiov;
1712
1713 prox.readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec),
1714 &tiov, sizeof(typename OS::tgt_iovec));

--- 121 unchanged lines hidden (view full) ---

1836 }
1837
1838 // Allocate physical memory and map it in. If the page table is already
1839 // mapped and clobber is not set, the simulator will issue throw a
1840 // fatal and bail out of the simulation.
1841 p->allocateMem(start, length, clobber);
1842
1843 // Transfer content into target address space.
1844 PortProxy &tp = tc->getMemProxy();
1844 PortProxy &tp = tc->getVirtProxy();
1845 if (tgt_flags & OS::TGT_MAP_ANONYMOUS) {
1846 // In general, we should zero the mapped area for anonymous mappings,
1847 // with something like:
1848 // tp.memsetBlob(start, 0, length);
1849 // However, given that we don't support sparse mappings, and
1850 // some applications can map a couple of gigabytes of space
1851 // (intending sparse usage), that can get painfully expensive.
1852 // Fortunately, since we don't properly implement munmap either,

--- 64 unchanged lines hidden (view full) ---

1917 int offset = p->getSyscallArg(tc, index);
1918
1919 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
1920 if (!ffdp)
1921 return -EBADF;
1922 int sim_fd = ffdp->getSimFD();
1923
1924 BufferArg bufArg(bufPtr, nbytes);
1845 if (tgt_flags & OS::TGT_MAP_ANONYMOUS) {
1846 // In general, we should zero the mapped area for anonymous mappings,
1847 // with something like:
1848 // tp.memsetBlob(start, 0, length);
1849 // However, given that we don't support sparse mappings, and
1850 // some applications can map a couple of gigabytes of space
1851 // (intending sparse usage), that can get painfully expensive.
1852 // Fortunately, since we don't properly implement munmap either,

--- 64 unchanged lines hidden (view full) ---

1917 int offset = p->getSyscallArg(tc, index);
1918
1919 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
1920 if (!ffdp)
1921 return -EBADF;
1922 int sim_fd = ffdp->getSimFD();
1923
1924 BufferArg bufArg(bufPtr, nbytes);
1925 bufArg.copyIn(tc->getMemProxy());
1925 bufArg.copyIn(tc->getVirtProxy());
1926
1927 int bytes_written = pwrite(sim_fd, bufArg.bufferPtr(), nbytes, offset);
1928
1929 return (bytes_written == -1) ? -errno : bytes_written;
1930}
1931
1932/// Target mmap() handler.
1933template <class OS>

--- 37 unchanged lines hidden (view full) ---

1971 break;
1972
1973 default:
1974 warn("getrlimit: unimplemented resource %d", resource);
1975 return -EINVAL;
1976 break;
1977 }
1978
1926
1927 int bytes_written = pwrite(sim_fd, bufArg.bufferPtr(), nbytes, offset);
1928
1929 return (bytes_written == -1) ? -errno : bytes_written;
1930}
1931
1932/// Target mmap() handler.
1933template <class OS>

--- 37 unchanged lines hidden (view full) ---

1971 break;
1972
1973 default:
1974 warn("getrlimit: unimplemented resource %d", resource);
1975 return -EINVAL;
1976 break;
1977 }
1978
1979 rlp.copyOut(tc->getMemProxy());
1979 rlp.copyOut(tc->getVirtProxy());
1980 return 0;
1981}
1982
1983template <class OS>
1984SyscallReturn
1985prlimitFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1986{
1987 int index = 0;

--- 24 unchanged lines hidden (view full) ---

2012 rlp->rlim_cur = TheISA::htog(rlp->rlim_cur);
2013 rlp->rlim_max = TheISA::htog(rlp->rlim_max);
2014 break;
2015 default:
2016 warn("prlimit: unimplemented resource %d", resource);
2017 return -EINVAL;
2018 break;
2019 }
1980 return 0;
1981}
1982
1983template <class OS>
1984SyscallReturn
1985prlimitFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
1986{
1987 int index = 0;

--- 24 unchanged lines hidden (view full) ---

2012 rlp->rlim_cur = TheISA::htog(rlp->rlim_cur);
2013 rlp->rlim_max = TheISA::htog(rlp->rlim_max);
2014 break;
2015 default:
2016 warn("prlimit: unimplemented resource %d", resource);
2017 return -EINVAL;
2018 break;
2019 }
2020 rlp.copyOut(tc->getMemProxy());
2020 rlp.copyOut(tc->getVirtProxy());
2021 }
2022 return 0;
2023}
2024
2025/// Target clock_gettime() function.
2026template <class OS>
2027SyscallReturn
2028clock_gettimeFunc(SyscallDesc *desc, int num, ThreadContext *tc)
2029{
2030 int index = 1;
2031 auto p = tc->getProcessPtr();
2032 //int clk_id = p->getSyscallArg(tc, index);
2033 TypedBufferArg<typename OS::timespec> tp(p->getSyscallArg(tc, index));
2034
2035 getElapsedTimeNano(tp->tv_sec, tp->tv_nsec);
2036 tp->tv_sec += seconds_since_epoch;
2037 tp->tv_sec = TheISA::htog(tp->tv_sec);
2038 tp->tv_nsec = TheISA::htog(tp->tv_nsec);
2039
2021 }
2022 return 0;
2023}
2024
2025/// Target clock_gettime() function.
2026template <class OS>
2027SyscallReturn
2028clock_gettimeFunc(SyscallDesc *desc, int num, ThreadContext *tc)
2029{
2030 int index = 1;
2031 auto p = tc->getProcessPtr();
2032 //int clk_id = p->getSyscallArg(tc, index);
2033 TypedBufferArg<typename OS::timespec> tp(p->getSyscallArg(tc, index));
2034
2035 getElapsedTimeNano(tp->tv_sec, tp->tv_nsec);
2036 tp->tv_sec += seconds_since_epoch;
2037 tp->tv_sec = TheISA::htog(tp->tv_sec);
2038 tp->tv_nsec = TheISA::htog(tp->tv_nsec);
2039
2040 tp.copyOut(tc->getMemProxy());
2040 tp.copyOut(tc->getVirtProxy());
2041
2042 return 0;
2043}
2044
2045/// Target clock_getres() function.
2046template <class OS>
2047SyscallReturn
2048clock_getresFunc(SyscallDesc *desc, int num, ThreadContext *tc)
2049{
2050 int index = 1;
2051 auto p = tc->getProcessPtr();
2052 TypedBufferArg<typename OS::timespec> tp(p->getSyscallArg(tc, index));
2053
2054 // Set resolution at ns, which is what clock_gettime() returns
2055 tp->tv_sec = 0;
2056 tp->tv_nsec = 1;
2057
2041
2042 return 0;
2043}
2044
2045/// Target clock_getres() function.
2046template <class OS>
2047SyscallReturn
2048clock_getresFunc(SyscallDesc *desc, int num, ThreadContext *tc)
2049{
2050 int index = 1;
2051 auto p = tc->getProcessPtr();
2052 TypedBufferArg<typename OS::timespec> tp(p->getSyscallArg(tc, index));
2053
2054 // Set resolution at ns, which is what clock_gettime() returns
2055 tp->tv_sec = 0;
2056 tp->tv_nsec = 1;
2057
2058 tp.copyOut(tc->getMemProxy());
2058 tp.copyOut(tc->getVirtProxy());
2059
2060 return 0;
2061}
2062
2063/// Target gettimeofday() handler.
2064template <class OS>
2065SyscallReturn
2066gettimeofdayFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
2067{
2068 int index = 0;
2069 auto process = tc->getProcessPtr();
2070 TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, index));
2071
2072 getElapsedTimeMicro(tp->tv_sec, tp->tv_usec);
2073 tp->tv_sec += seconds_since_epoch;
2074 tp->tv_sec = TheISA::htog(tp->tv_sec);
2075 tp->tv_usec = TheISA::htog(tp->tv_usec);
2076
2059
2060 return 0;
2061}
2062
2063/// Target gettimeofday() handler.
2064template <class OS>
2065SyscallReturn
2066gettimeofdayFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
2067{
2068 int index = 0;
2069 auto process = tc->getProcessPtr();
2070 TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, index));
2071
2072 getElapsedTimeMicro(tp->tv_sec, tp->tv_usec);
2073 tp->tv_sec += seconds_since_epoch;
2074 tp->tv_sec = TheISA::htog(tp->tv_sec);
2075 tp->tv_usec = TheISA::htog(tp->tv_usec);
2076
2077 tp.copyOut(tc->getMemProxy());
2077 tp.copyOut(tc->getVirtProxy());
2078
2079 return 0;
2080}
2081
2082
2083/// Target utimes() handler.
2084template <class OS>
2085SyscallReturn
2086utimesFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
2087{
2088 std::string path;
2089 auto process = tc->getProcessPtr();
2090
2091 int index = 0;
2078
2079 return 0;
2080}
2081
2082
2083/// Target utimes() handler.
2084template <class OS>
2085SyscallReturn
2086utimesFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
2087{
2088 std::string path;
2089 auto process = tc->getProcessPtr();
2090
2091 int index = 0;
2092 if (!tc->getMemProxy().tryReadString(path,
2092 if (!tc->getVirtProxy().tryReadString(path,
2093 process->getSyscallArg(tc, index))) {
2094 return -EFAULT;
2095 }
2096
2097 TypedBufferArg<typename OS::timeval [2]>
2098 tp(process->getSyscallArg(tc, index));
2093 process->getSyscallArg(tc, index))) {
2094 return -EFAULT;
2095 }
2096
2097 TypedBufferArg<typename OS::timeval [2]>
2098 tp(process->getSyscallArg(tc, index));
2099 tp.copyIn(tc->getMemProxy());
2099 tp.copyIn(tc->getVirtProxy());
2100
2101 struct timeval hostTimeval[2];
2102 for (int i = 0; i < 2; ++i) {
2103 hostTimeval[i].tv_sec = TheISA::gtoh((*tp)[i].tv_sec);
2104 hostTimeval[i].tv_usec = TheISA::gtoh((*tp)[i].tv_usec);
2105 }
2106
2107 // Adjust path for cwd and redirection

--- 11 unchanged lines hidden (view full) ---

2119SyscallReturn
2120execveFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
2121{
2122 desc->setFlags(0);
2123 auto p = tc->getProcessPtr();
2124
2125 int index = 0;
2126 std::string path;
2100
2101 struct timeval hostTimeval[2];
2102 for (int i = 0; i < 2; ++i) {
2103 hostTimeval[i].tv_sec = TheISA::gtoh((*tp)[i].tv_sec);
2104 hostTimeval[i].tv_usec = TheISA::gtoh((*tp)[i].tv_usec);
2105 }
2106
2107 // Adjust path for cwd and redirection

--- 11 unchanged lines hidden (view full) ---

2119SyscallReturn
2120execveFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
2121{
2122 desc->setFlags(0);
2123 auto p = tc->getProcessPtr();
2124
2125 int index = 0;
2126 std::string path;
2127 PortProxy & mem_proxy = tc->getMemProxy();
2127 PortProxy & mem_proxy = tc->getVirtProxy();
2128 if (!mem_proxy.tryReadString(path, p->getSyscallArg(tc, index)))
2129 return -EFAULT;
2130
2131 if (access(path.c_str(), F_OK) == -1)
2132 return -EACCES;
2133
2134 auto read_in = [](std::vector<std::string> &vect,
2135 PortProxy &mem_proxy, Addr mem_loc)

--- 113 unchanged lines hidden (view full) ---

2249
2250 default:
2251 // don't really handle THREAD or CHILDREN, but just warn and
2252 // plow ahead
2253 warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.",
2254 who);
2255 }
2256
2128 if (!mem_proxy.tryReadString(path, p->getSyscallArg(tc, index)))
2129 return -EFAULT;
2130
2131 if (access(path.c_str(), F_OK) == -1)
2132 return -EACCES;
2133
2134 auto read_in = [](std::vector<std::string> &vect,
2135 PortProxy &mem_proxy, Addr mem_loc)

--- 113 unchanged lines hidden (view full) ---

2249
2250 default:
2251 // don't really handle THREAD or CHILDREN, but just warn and
2252 // plow ahead
2253 warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.",
2254 who);
2255 }
2256
2257 rup.copyOut(tc->getMemProxy());
2257 rup.copyOut(tc->getVirtProxy());
2258
2259 return 0;
2260}
2261
2262/// Target times() function.
2263template <class OS>
2264SyscallReturn
2265timesFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)

--- 8 unchanged lines hidden (view full) ---

2274 bufp->tms_stime = 0;
2275 bufp->tms_cutime = 0;
2276 bufp->tms_cstime = 0;
2277
2278 // Convert to host endianness
2279 bufp->tms_utime = TheISA::htog(bufp->tms_utime);
2280
2281 // Write back
2258
2259 return 0;
2260}
2261
2262/// Target times() function.
2263template <class OS>
2264SyscallReturn
2265timesFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)

--- 8 unchanged lines hidden (view full) ---

2274 bufp->tms_stime = 0;
2275 bufp->tms_cutime = 0;
2276 bufp->tms_cstime = 0;
2277
2278 // Convert to host endianness
2279 bufp->tms_utime = TheISA::htog(bufp->tms_utime);
2280
2281 // Write back
2282 bufp.copyOut(tc->getMemProxy());
2282 bufp.copyOut(tc->getVirtProxy());
2283
2284 // Return clock ticks since system boot
2285 return clocks;
2286}
2287
2288/// Target time() function.
2289template <class OS>
2290SyscallReturn

--- 4 unchanged lines hidden (view full) ---

2295 sec += seconds_since_epoch;
2296
2297 int index = 0;
2298 auto process = tc->getProcessPtr();
2299 Addr taddr = (Addr)process->getSyscallArg(tc, index);
2300 if (taddr != 0) {
2301 typename OS::time_t t = sec;
2302 t = TheISA::htog(t);
2283
2284 // Return clock ticks since system boot
2285 return clocks;
2286}
2287
2288/// Target time() function.
2289template <class OS>
2290SyscallReturn

--- 4 unchanged lines hidden (view full) ---

2295 sec += seconds_since_epoch;
2296
2297 int index = 0;
2298 auto process = tc->getProcessPtr();
2299 Addr taddr = (Addr)process->getSyscallArg(tc, index);
2300 if (taddr != 0) {
2301 typename OS::time_t t = sec;
2302 t = TheISA::htog(t);
2303 PortProxy &p = tc->getMemProxy();
2303 PortProxy &p = tc->getVirtProxy();
2304 p.writeBlob(taddr, &t, (int)sizeof(typename OS::time_t));
2305 }
2306 return sec;
2307}
2308
2309template <class OS>
2310SyscallReturn
2311tgkillFunc(SyscallDesc *desc, int num, ThreadContext *tc)

--- 81 unchanged lines hidden (view full) ---

2393 return -errno;
2394
2395 int *fds = (int *)svBuf.bufferPtr();
2396
2397 auto sfdp1 = std::make_shared<SocketFDEntry>(fds[0], domain, type, prot);
2398 fds[0] = p->fds->allocFD(sfdp1);
2399 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1], domain, type, prot);
2400 fds[1] = p->fds->allocFD(sfdp2);
2304 p.writeBlob(taddr, &t, (int)sizeof(typename OS::time_t));
2305 }
2306 return sec;
2307}
2308
2309template <class OS>
2310SyscallReturn
2311tgkillFunc(SyscallDesc *desc, int num, ThreadContext *tc)

--- 81 unchanged lines hidden (view full) ---

2393 return -errno;
2394
2395 int *fds = (int *)svBuf.bufferPtr();
2396
2397 auto sfdp1 = std::make_shared<SocketFDEntry>(fds[0], domain, type, prot);
2398 fds[0] = p->fds->allocFD(sfdp1);
2399 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1], domain, type, prot);
2400 fds[1] = p->fds->allocFD(sfdp2);
2401 svBuf.copyOut(tc->getMemProxy());
2401 svBuf.copyOut(tc->getVirtProxy());
2402
2403 return status;
2404}
2405
2406template <class OS>
2407SyscallReturn
2408selectFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
2409{

--- 23 unchanged lines hidden (view full) ---

2433 FD_ZERO(&wr_h);
2434 fd_set ex_h;
2435 FD_ZERO(&ex_h);
2436
2437 /**
2438 * Copy in the fd_set from the target.
2439 */
2440 if (fds_read_ptr)
2402
2403 return status;
2404}
2405
2406template <class OS>
2407SyscallReturn
2408selectFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
2409{

--- 23 unchanged lines hidden (view full) ---

2433 FD_ZERO(&wr_h);
2434 fd_set ex_h;
2435 FD_ZERO(&ex_h);
2436
2437 /**
2438 * Copy in the fd_set from the target.
2439 */
2440 if (fds_read_ptr)
2441 rd_t.copyIn(tc->getMemProxy());
2441 rd_t.copyIn(tc->getVirtProxy());
2442 if (fds_writ_ptr)
2442 if (fds_writ_ptr)
2443 wr_t.copyIn(tc->getMemProxy());
2443 wr_t.copyIn(tc->getVirtProxy());
2444 if (fds_excp_ptr)
2444 if (fds_excp_ptr)
2445 ex_t.copyIn(tc->getMemProxy());
2445 ex_t.copyIn(tc->getVirtProxy());
2446
2447 /**
2448 * We need to translate the target file descriptor set into a host file
2449 * descriptor set. This involves both our internal process fd array
2450 * and the fd_set defined in Linux header files. The nfds field also
2451 * needs to be updated as it will be only target specific after
2452 * retrieving it from the target; the nfds value is expected to be the
2453 * highest file descriptor that needs to be checked, so we need to extend

--- 129 unchanged lines hidden (view full) ---

2583
2584 if (fds_excp_ptr) {
2585 if (FD_ISSET(i, &ex_h))
2586 FD_SET(trans_map[i], (fd_set*)&*ex_t);
2587 }
2588 }
2589
2590 if (fds_read_ptr)
2446
2447 /**
2448 * We need to translate the target file descriptor set into a host file
2449 * descriptor set. This involves both our internal process fd array
2450 * and the fd_set defined in Linux header files. The nfds field also
2451 * needs to be updated as it will be only target specific after
2452 * retrieving it from the target; the nfds value is expected to be the
2453 * highest file descriptor that needs to be checked, so we need to extend

--- 129 unchanged lines hidden (view full) ---

2583
2584 if (fds_excp_ptr) {
2585 if (FD_ISSET(i, &ex_h))
2586 FD_SET(trans_map[i], (fd_set*)&*ex_t);
2587 }
2588 }
2589
2590 if (fds_read_ptr)
2591 rd_t.copyOut(tc->getMemProxy());
2591 rd_t.copyOut(tc->getVirtProxy());
2592 if (fds_writ_ptr)
2592 if (fds_writ_ptr)
2593 wr_t.copyOut(tc->getMemProxy());
2593 wr_t.copyOut(tc->getVirtProxy());
2594 if (fds_excp_ptr)
2594 if (fds_excp_ptr)
2595 ex_t.copyOut(tc->getMemProxy());
2595 ex_t.copyOut(tc->getVirtProxy());
2596 if (time_val_ptr)
2596 if (time_val_ptr)
2597 tp.copyOut(tc->getMemProxy());
2597 tp.copyOut(tc->getVirtProxy());
2598
2599 return retval;
2600}
2601
2602template <class OS>
2603SyscallReturn
2604readFunc(SyscallDesc *desc, int num, ThreadContext *tc)
2605{

--- 14 unchanged lines hidden (view full) ---

2620 if ((poll(&pfd, 1, 0) == 0)
2621 && !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK))
2622 return SyscallReturn::retry();
2623
2624 BufferArg buf_arg(buf_ptr, nbytes);
2625 int bytes_read = read(sim_fd, buf_arg.bufferPtr(), nbytes);
2626
2627 if (bytes_read > 0)
2598
2599 return retval;
2600}
2601
2602template <class OS>
2603SyscallReturn
2604readFunc(SyscallDesc *desc, int num, ThreadContext *tc)
2605{

--- 14 unchanged lines hidden (view full) ---

2620 if ((poll(&pfd, 1, 0) == 0)
2621 && !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK))
2622 return SyscallReturn::retry();
2623
2624 BufferArg buf_arg(buf_ptr, nbytes);
2625 int bytes_read = read(sim_fd, buf_arg.bufferPtr(), nbytes);
2626
2627 if (bytes_read > 0)
2628 buf_arg.copyOut(tc->getMemProxy());
2628 buf_arg.copyOut(tc->getVirtProxy());
2629
2630 return (bytes_read == -1) ? -errno : bytes_read;
2631}
2632
2633template <class OS>
2634SyscallReturn
2635writeFunc(SyscallDesc *desc, int num, ThreadContext *tc)
2636{

--- 4 unchanged lines hidden (view full) ---

2641 int nbytes = p->getSyscallArg(tc, index);
2642
2643 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
2644 if (!hbfdp)
2645 return -EBADF;
2646 int sim_fd = hbfdp->getSimFD();
2647
2648 BufferArg buf_arg(buf_ptr, nbytes);
2629
2630 return (bytes_read == -1) ? -errno : bytes_read;
2631}
2632
2633template <class OS>
2634SyscallReturn
2635writeFunc(SyscallDesc *desc, int num, ThreadContext *tc)
2636{

--- 4 unchanged lines hidden (view full) ---

2641 int nbytes = p->getSyscallArg(tc, index);
2642
2643 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
2644 if (!hbfdp)
2645 return -EBADF;
2646 int sim_fd = hbfdp->getSimFD();
2647
2648 BufferArg buf_arg(buf_ptr, nbytes);
2649 buf_arg.copyIn(tc->getMemProxy());
2649 buf_arg.copyIn(tc->getVirtProxy());
2650
2651 struct pollfd pfd;
2652 pfd.fd = sim_fd;
2653 pfd.events = POLLOUT;
2654
2655 /**
2656 * We don't want to poll on /dev/random. The kernel will not enable the
2657 * file descriptor for writing unless the entropy in the system falls

--- 63 unchanged lines hidden (view full) ---

2721
2722 return (options & OS::TGT_WNOHANG) ? 0 : SyscallReturn::retry();
2723
2724success:
2725 // Set status to EXITED for WIFEXITED evaluations.
2726 const int EXITED = 0;
2727 BufferArg statusBuf(statPtr, sizeof(int));
2728 *(int *)statusBuf.bufferPtr() = EXITED;
2650
2651 struct pollfd pfd;
2652 pfd.fd = sim_fd;
2653 pfd.events = POLLOUT;
2654
2655 /**
2656 * We don't want to poll on /dev/random. The kernel will not enable the
2657 * file descriptor for writing unless the entropy in the system falls

--- 63 unchanged lines hidden (view full) ---

2721
2722 return (options & OS::TGT_WNOHANG) ? 0 : SyscallReturn::retry();
2723
2724success:
2725 // Set status to EXITED for WIFEXITED evaluations.
2726 const int EXITED = 0;
2727 BufferArg statusBuf(statPtr, sizeof(int));
2728 *(int *)statusBuf.bufferPtr() = EXITED;
2729 statusBuf.copyOut(tc->getMemProxy());
2729 statusBuf.copyOut(tc->getVirtProxy());
2730
2731 // Return the child PID.
2732 pid_t retval = iter->sender->pid();
2733 sysh->signalList.erase(iter);
2734 return retval;
2735}
2736
2737template <class OS>

--- 27 unchanged lines hidden (view full) ---

2765 pfd.fd = sim_fd;
2766 pfd.events = POLLIN | POLLPRI;
2767 if ((poll(&pfd, 1, 0) == 0)
2768 && !(sfdp->getFlags() & OS::TGT_O_NONBLOCK))
2769 return SyscallReturn::retry();
2770
2771 if (lenPtr) {
2772 lenBufPtr = new BufferArg(lenPtr, sizeof(socklen_t));
2730
2731 // Return the child PID.
2732 pid_t retval = iter->sender->pid();
2733 sysh->signalList.erase(iter);
2734 return retval;
2735}
2736
2737template <class OS>

--- 27 unchanged lines hidden (view full) ---

2765 pfd.fd = sim_fd;
2766 pfd.events = POLLIN | POLLPRI;
2767 if ((poll(&pfd, 1, 0) == 0)
2768 && !(sfdp->getFlags() & OS::TGT_O_NONBLOCK))
2769 return SyscallReturn::retry();
2770
2771 if (lenPtr) {
2772 lenBufPtr = new BufferArg(lenPtr, sizeof(socklen_t));
2773 lenBufPtr->copyIn(tc->getMemProxy());
2773 lenBufPtr->copyIn(tc->getVirtProxy());
2774 memcpy(&addrLen, (socklen_t *)lenBufPtr->bufferPtr(),
2775 sizeof(socklen_t));
2776 }
2777
2778 if (addrPtr) {
2779 addrBufPtr = new BufferArg(addrPtr, sizeof(struct sockaddr));
2774 memcpy(&addrLen, (socklen_t *)lenBufPtr->bufferPtr(),
2775 sizeof(socklen_t));
2776 }
2777
2778 if (addrPtr) {
2779 addrBufPtr = new BufferArg(addrPtr, sizeof(struct sockaddr));
2780 addrBufPtr->copyIn(tc->getMemProxy());
2780 addrBufPtr->copyIn(tc->getVirtProxy());
2781 memcpy(&sa, (struct sockaddr *)addrBufPtr->bufferPtr(),
2782 sizeof(struct sockaddr));
2783 }
2784
2785 host_fd = accept(sim_fd, &sa, &addrLen);
2786
2787 if (host_fd == -1)
2788 return -errno;
2789
2790 if (addrPtr) {
2791 memcpy(addrBufPtr->bufferPtr(), &sa, sizeof(sa));
2781 memcpy(&sa, (struct sockaddr *)addrBufPtr->bufferPtr(),
2782 sizeof(struct sockaddr));
2783 }
2784
2785 host_fd = accept(sim_fd, &sa, &addrLen);
2786
2787 if (host_fd == -1)
2788 return -errno;
2789
2790 if (addrPtr) {
2791 memcpy(addrBufPtr->bufferPtr(), &sa, sizeof(sa));
2792 addrBufPtr->copyOut(tc->getMemProxy());
2792 addrBufPtr->copyOut(tc->getVirtProxy());
2793 delete(addrBufPtr);
2794 }
2795
2796 if (lenPtr) {
2797 *(socklen_t *)lenBufPtr->bufferPtr() = addrLen;
2793 delete(addrBufPtr);
2794 }
2795
2796 if (lenPtr) {
2797 *(socklen_t *)lenBufPtr->bufferPtr() = addrLen;
2798 lenBufPtr->copyOut(tc->getMemProxy());
2798 lenBufPtr->copyOut(tc->getVirtProxy());
2799 delete(lenBufPtr);
2800 }
2801
2802 auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain,
2803 sfdp->_type, sfdp->_protocol);
2804 return p->fds->allocFD(afdp);
2805}
2806

--- 30 unchanged lines hidden ---
2799 delete(lenBufPtr);
2800 }
2801
2802 auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain,
2803 sfdp->_type, sfdp->_protocol);
2804 return p->fds->allocFD(afdp);
2805}
2806

--- 30 unchanged lines hidden ---