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 --- |