42 #ifndef __SIM_SYSCALL_EMUL_HH__ 43 #define __SIM_SYSCALL_EMUL_HH__ 45 #if (defined(__APPLE__) || defined(__OpenBSD__) || \ 46 defined(__FreeBSD__) || defined(__CYGWIN__) || \ 59 #if defined(__linux__) 60 #include <sys/eventfd.h> 61 #include <sys/statfs.h> 64 #include <sys/mount.h> 69 #include <sys/fcntl.h> 75 #include <sys/ioctl.h> 77 #include <sys/socket.h> 80 #include <sys/types.h> 89 #include "arch/utility.hh" 95 #include "config/the_isa.hh" 99 #include "params/Process.hh" 109 #if defined(__APPLE__) && defined(__MACH__) && !defined(CMSG_ALIGN) 110 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1)) 160 int tgt_fd, uint64_t offs,
int whence);
164 int tgt_fd, uint64_t offset_high,
165 uint32_t offset_low,
Addr result_ptr,
int whence);
173 int tgt_fd,
int how);
177 Addr buf_ptr,
int name_len);
181 Addr buf_ptr,
unsigned long size);
185 Addr pathname,
Addr buf,
size_t bufsiz);
204 Addr pathname, mode_t
mode, dev_t dev);
224 int tgt_fd, off_t
length);
233 int tgt_fd, int64_t
length);
243 Addr pathname, uint32_t owner, uint32_t group);
254 int tgt_fd, uint32_t owner, uint32_t group);
262 int old_tgt_fd,
int new_tgt_fd);
270 int tgt_fd,
int cmd);
277 Addr tgt_addr,
int flags);
284 int tgt_fd,
Addr sockAddrPtr,
Addr addrlenPtr);
288 int tgt_fd,
Addr buf_ptr,
int addrlen);
292 int tgt_fd,
int backlog);
296 int tgt_fd,
Addr buf_ptr,
int addrlen);
298 #if defined(SYS_getdents) 301 int tgt_fd,
Addr buf_ptr,
unsigned count);
304 #if defined(SYS_getdents64) 307 int tgt_fd,
Addr buf_ptr,
unsigned count);
312 int tgt_fd,
Addr bufrPtr,
size_t bufrLen,
int flags,
313 Addr addrPtr, socklen_t addrLen);
317 int tgt_fd,
Addr bufrPtr,
size_t bufrLen,
318 int flags,
Addr addrPtr,
Addr addrlenPtr);
322 int tgt_fd,
Addr msgPtr,
int flags);
326 int tgt_fd,
Addr msgPtr,
int flags);
349 int tgt_fd,
int level,
int optname,
354 int tgt_fd,
int level,
int optname,
362 int tgt_fd,
Addr addrPtr,
Addr lenPtr);
370 Addr uaddr,
int op,
int val,
int timeout,
Addr uaddr2,
int val3)
380 op &= ~OS::TGT_FUTEX_PRIVATE_FLAG;
381 op &= ~OS::TGT_FUTEX_CLOCK_REALTIME_FLAG;
385 if (OS::TGT_FUTEX_WAIT == op || OS::TGT_FUTEX_WAIT_BITSET == op) {
397 return -OS::TGT_EWOULDBLOCK;
399 if (OS::TGT_FUTEX_WAIT == op) {
400 futex_map.
suspend(uaddr, process->tgid(), tc);
406 }
else if (OS::TGT_FUTEX_WAKE == op) {
407 return futex_map.
wakeup(uaddr, process->tgid(),
val);
408 }
else if (OS::TGT_FUTEX_WAKE_BITSET == op) {
409 return futex_map.
wakeup_bitset(uaddr, process->tgid(), val3);
410 }
else if (OS::TGT_FUTEX_REQUEUE == op ||
411 OS::TGT_FUTEX_CMP_REQUEUE == op) {
421 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
422 return -OS::TGT_EWOULDBLOCK;
423 return futex_map.
requeue(uaddr, process->tgid(),
val, timeout, uaddr2);
424 }
else if (OS::TGT_FUTEX_WAKE_OP == op) {
452 int wake_cmparg = val3 & 0xfff;
453 int wake_oparg = (val3 & 0xfff000) >> 12;
454 int wake_cmp = (val3 & 0xf000000) >> 24;
455 int wake_op = (val3 & 0xf0000000) >> 28;
456 if ((wake_op & OS::TGT_FUTEX_OP_ARG_SHIFT) >> 3 == 1)
457 wake_oparg = (1 << wake_oparg);
458 wake_op &= ~OS::TGT_FUTEX_OP_ARG_SHIFT;
460 if (wake_op == OS::TGT_FUTEX_OP_SET)
462 else if (wake_op == OS::TGT_FUTEX_OP_ADD)
463 newval += wake_oparg;
464 else if (wake_op == OS::TGT_FUTEX_OP_OR)
465 newval |= wake_oparg;
466 else if (wake_op == OS::TGT_FUTEX_OP_ANDN)
467 newval &= ~wake_oparg;
468 else if (wake_op == OS::TGT_FUTEX_OP_XOR)
469 newval ^= wake_oparg;
474 int woken1 = futex_map.
wakeup(uaddr, process->tgid(),
val);
477 bool is_wake2 =
false;
478 if (wake_cmp == OS::TGT_FUTEX_OP_CMP_EQ)
479 is_wake2 = oldval == wake_cmparg;
480 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_NE)
481 is_wake2 = oldval != wake_cmparg;
482 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LT)
483 is_wake2 = oldval < wake_cmparg;
484 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LE)
485 is_wake2 = oldval <= wake_cmparg;
486 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GT)
487 is_wake2 = oldval > wake_cmparg;
488 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GE)
489 is_wake2 = oldval >= wake_cmparg;
492 woken2 = futex_map.
wakeup(uaddr2, process->tgid(), timeout);
494 return woken1 + woken2;
496 warn(
"futex: op %d not implemented; ignoring.", op);
512 template <
class T1,
class T2>
516 static const int OneMillion = 1000 * 1000;
519 sec = elapsed_usecs / OneMillion;
520 usec = elapsed_usecs % OneMillion;
525 template <
class T1,
class T2>
529 static const int OneBillion = 1000 * 1000 * 1000;
532 sec = elapsed_nsecs / OneBillion;
533 nsec = elapsed_nsecs % OneBillion;
556 template <
typename target_stat,
typename host_stat>
564 tgt->st_dev = host->st_dev;
565 tgt->st_dev =
htog(tgt->st_dev, bo);
566 tgt->st_ino = host->st_ino;
567 tgt->st_ino =
htog(tgt->st_ino, bo);
568 tgt->st_mode = host->st_mode;
571 tgt->st_mode &= ~S_IFMT;
572 tgt->st_mode |= S_IFCHR;
574 tgt->st_mode =
htog(tgt->st_mode, bo);
575 tgt->st_nlink = host->st_nlink;
576 tgt->st_nlink =
htog(tgt->st_nlink, bo);
577 tgt->st_uid = host->st_uid;
578 tgt->st_uid =
htog(tgt->st_uid, bo);
579 tgt->st_gid = host->st_gid;
580 tgt->st_gid =
htog(tgt->st_gid, bo);
582 tgt->st_rdev = 0x880d;
584 tgt->st_rdev = host->st_rdev;
585 tgt->st_rdev =
htog(tgt->st_rdev, bo);
586 tgt->st_size = host->st_size;
587 tgt->st_size =
htog(tgt->st_size, bo);
588 tgt->st_atimeX = host->st_atime;
589 tgt->st_atimeX =
htog(tgt->st_atimeX, bo);
590 tgt->st_mtimeX = host->st_mtime;
591 tgt->st_mtimeX =
htog(tgt->st_mtimeX, bo);
592 tgt->st_ctimeX = host->st_ctime;
593 tgt->st_ctimeX =
htog(tgt->st_ctimeX, bo);
596 tgt->st_blksize = 0x2000;
597 tgt->st_blksize =
htog(tgt->st_blksize, bo);
598 tgt->st_blocks = host->st_blocks;
599 tgt->st_blocks =
htog(tgt->st_blocks, bo);
604 template <
typename target_stat,
typename host_stat64>
609 convertStatBuf<target_stat, host_stat64>(tgt, host,
bo, fakeTTY);
610 #if defined(STAT_HAVE_NSEC) 611 tgt->st_atime_nsec = host->st_atime_nsec;
612 tgt->st_atime_nsec =
htog(tgt->st_atime_nsec, bo);
613 tgt->st_mtime_nsec = host->st_mtime_nsec;
614 tgt->st_mtime_nsec =
htog(tgt->st_mtime_nsec, bo);
615 tgt->st_ctime_nsec = host->st_ctime_nsec;
616 tgt->st_ctime_nsec =
htog(tgt->st_ctime_nsec, bo);
618 tgt->st_atime_nsec = 0;
619 tgt->st_mtime_nsec = 0;
620 tgt->st_ctime_nsec = 0;
628 hst_stat *host,
bool fakeTTY =
false)
631 tgt_stat_buf tgt(addr);
632 convertStatBuf<tgt_stat_buf, hst_stat>(tgt, host,
OS::byteOrder, fakeTTY);
642 tgt_stat_buf tgt(addr);
643 convertStat64Buf<tgt_stat_buf, hst_stat64>(
657 tgt->f_type =
htog(host->f_type, bo);
658 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 659 tgt->f_bsize =
htog(host->f_iosize, bo);
661 tgt->f_bsize =
htog(host->f_bsize, bo);
663 tgt->f_blocks =
htog(host->f_blocks, bo);
664 tgt->f_bfree =
htog(host->f_bfree, bo);
665 tgt->f_bavail =
htog(host->f_bavail, bo);
666 tgt->f_files =
htog(host->f_files, bo);
667 tgt->f_ffree =
htog(host->f_ffree, bo);
668 memcpy(&tgt->f_fsid, &host->f_fsid,
sizeof(host->f_fsid));
669 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 670 tgt->f_namelen =
htog(host->f_namemax, bo);
671 tgt->f_frsize =
htog(host->f_bsize, bo);
672 #elif defined(__APPLE__) 676 tgt->f_namelen =
htog(host->f_namelen, bo);
677 tgt->f_frsize =
htog(host->f_frsize, bo);
679 #if defined(__linux__) 680 memcpy(&tgt->f_spare, &host->f_spare,
681 std::min(
sizeof(host->f_spare),
sizeof(tgt->f_spare)));
687 memset(&tgt->f_spare, 0,
sizeof(tgt->f_spare));
700 int tgt_fd,
unsigned req,
Addr addr)
706 if (OS::isTtyReq(req))
709 auto dfdp = std::dynamic_pointer_cast<
DeviceFDEntry>((*
p->fds)[tgt_fd]);
713 return emul_driver->
ioctl(tc, req, addr);
716 auto sfdp = std::dynamic_pointer_cast<
SocketFDEntry>((*
p->fds)[tgt_fd]);
722 BufferArg conf_arg(addr,
sizeof(ifconf));
725 ifconf *conf = (ifconf*)conf_arg.
bufferPtr();
726 Addr ifc_buf_addr = (
Addr)conf->ifc_buf;
727 BufferArg ifc_buf_arg(ifc_buf_addr, conf->ifc_len);
730 conf->ifc_buf = (
char*)ifc_buf_arg.bufferPtr();
732 status = ioctl(sfdp->getSimFD(), req, conf_arg.
bufferPtr());
734 conf->ifc_buf = (
char*)ifc_buf_addr;
742 #if defined(__linux__) 747 #if defined(__linux__) 754 status = ioctl(sfdp->getSimFD(), req, req_arg.
bufferPtr());
766 warn(
"Unsupported ioctl call (return ENOTTY): ioctl(%d, 0x%x, ...) @ \n",
775 int tgt_dirfd,
Addr pathname,
int tgt_flags,
int mode)
788 int host_flags = O_BINARY;
796 for (
int i = 0;
i < OS::NUM_OPEN_FLAGS;
i++) {
797 if (tgt_flags & OS::openFlagTable[
i].tgtFlag) {
798 tgt_flags &= ~OS::openFlagTable[
i].tgtFlag;
799 host_flags |= OS::openFlagTable[
i].hostFlag;
803 warn(
"%s: cannot decode flags %#x", desc->
name(), tgt_flags);
806 host_flags |= O_BINARY;
821 std::string redir_path = path;
822 std::string abs_path = path;
823 if (tgt_dirfd == OS::TGT_AT_FDCWD) {
824 abs_path =
p->absolutePath(path,
true);
825 redir_path =
p->checkPathRedirect(path);
827 std::shared_ptr<FDEntry> fdep = ((*
p->fds)[tgt_dirfd]);
828 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(fdep);
832 redir_path =
p->checkPathRedirect(abs_path);
842 std::string filename = abs_path.substr(strlen(
"/dev/"));
846 "driver open with path[%s]\n",
847 desc->
name(), abs_path.c_str());
848 return drv->
open(tc, mode, host_flags);
881 std::string used_path;
883 {
"/proc/meminfo/",
"/system/",
"/platform/",
"/etc/passwd",
884 "/proc/self/maps",
"/dev/urandom",
885 "/sys/devices/system/cpu/online" };
886 for (
auto entry : special_paths) {
888 sim_fd = OS::openSpecialFile(abs_path,
p, tc);
889 used_path = abs_path;
893 sim_fd = open(redir_path.c_str(), host_flags,
mode);
894 used_path = redir_path;
899 "(inferred from:%s)\n", desc->
name(),
900 used_path.c_str(), path.c_str());
912 auto ffdp = std::make_shared<FileFDEntry>(sim_fd, host_flags, path, 0);
913 int tgt_fd =
p->fds->allocFD(ffdp);
915 "(inferred from:%s)\n", desc->
name(),
916 sim_fd, tgt_fd, used_path.c_str(), path.c_str());
924 Addr pathname,
int tgt_flags,
int mode)
926 return openatFunc<OS>(
927 desc, tc, OS::TGT_AT_FDCWD, pathname, tgt_flags,
mode);
935 if (dirfd != OS::TGT_AT_FDCWD)
936 warn(
"unlinkat: first argument not AT_FDCWD; unlikely to work");
947 if (dirfd != OS::TGT_AT_FDCWD)
948 warn(
"faccessat: first argument not AT_FDCWD; unlikely to work");
956 int dirfd,
Addr pathname,
Addr buf,
size_t bufsiz)
958 if (dirfd != OS::TGT_AT_FDCWD)
959 warn(
"openat: first argument not AT_FDCWD; unlikely to work");
967 int olddirfd,
Addr oldpath,
int newdirfd,
Addr newpath)
969 if (olddirfd != OS::TGT_AT_FDCWD)
970 warn(
"renameat: first argument not AT_FDCWD; unlikely to work");
972 if (newdirfd != OS::TGT_AT_FDCWD)
973 warn(
"renameat: third argument not AT_FDCWD; unlikely to work");
975 return renameFunc(desc, tc, oldpath, newpath);
988 sysinfo->totalram = process->system->memSize();
989 sysinfo->mem_unit = 1;
1007 mode_t hostMode = 0;
1013 path = process->checkPathRedirect(path);
1016 int result = chmod(path.c_str(), hostMode);
1026 Addr fdsPtr,
int nfds,
int tmout)
1030 BufferArg fdsBuf(fdsPtr,
sizeof(
struct pollfd) * nfds);
1039 int temp_tgt_fds[nfds];
1042 auto tgt_fd = temp_tgt_fds[
index];
1043 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
1046 auto host_fd = hbfdp->getSimFD();
1058 status = poll((
struct pollfd *)fdsBuf.
bufferPtr(), nfds, 0);
1068 if (it->receiver ==
p)
1073 status = poll((
struct pollfd *)fdsBuf.
bufferPtr(), nfds, 0);
1083 auto tgt_fd = temp_tgt_fds[
index];
1103 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1106 int sim_fd = ffdp->getSimFD();
1108 mode_t hostMode =
mode;
1110 int result = fchmod(sim_fd, hostMode);
1112 return (result < 0) ? -errno : 0;
1119 Addr start, uint64_t old_length, uint64_t new_length, uint64_t flags,
1124 uint64_t provided_address = 0;
1125 bool use_provided_address = flags & OS::TGT_MREMAP_FIXED;
1127 if (use_provided_address)
1128 provided_address = varargs.
get<uint64_t>();
1130 if ((start % page_bytes != 0) ||
1131 (provided_address % page_bytes != 0)) {
1132 warn(
"mremap failing: arguments not page aligned");
1136 new_length =
roundUp(new_length, page_bytes);
1138 if (new_length > old_length) {
1139 Addr mmap_end =
p->memState->getMmapEnd();
1141 if ((start + old_length) == mmap_end &&
1142 (!use_provided_address || provided_address == start)) {
1145 uint64_t diff = new_length - old_length;
1146 p->memState->mapRegion(mmap_end, diff,
"remapped");
1147 p->memState->setMmapEnd(mmap_end + diff);
1150 if (!use_provided_address && !(flags & OS::TGT_MREMAP_MAYMOVE)) {
1151 warn(
"can't remap here and MREMAP_MAYMOVE flag not set\n");
1154 uint64_t new_start = provided_address;
1155 if (!use_provided_address) {
1156 new_start =
p->mmapGrowsDown() ?
1157 mmap_end - new_length : mmap_end;
1158 mmap_end =
p->mmapGrowsDown() ?
1159 new_start : mmap_end + new_length;
1160 p->memState->setMmapEnd(mmap_end);
1163 warn(
"mremapping to new vaddr %08p-%08p, adding %d\n",
1164 new_start, new_start + new_length,
1165 new_length - old_length);
1168 p->allocateMem(new_start + old_length,
1169 new_length - old_length,
1170 use_provided_address );
1172 if (use_provided_address &&
1173 ((new_start + new_length >
p->memState->getMmapEnd() &&
1174 !
p->mmapGrowsDown()) ||
1175 (new_start < p->memState->getMmapEnd() &&
1176 p->mmapGrowsDown()))) {
1179 warn(
"mmap region limit exceeded with MREMAP_FIXED\n");
1182 warn(
"returning %08p as start\n", new_start);
1183 p->memState->remapRegion(start, new_start, old_length);
1189 if (use_provided_address && provided_address != start)
1190 p->memState->remapRegion(start, provided_address, new_length);
1191 if (new_length != old_length)
1192 p->memState->unmapRegion(start + new_length,
1193 old_length - new_length);
1194 return use_provided_address ? provided_address : start;
1212 struct stat hostBuf;
1213 int result = stat(path.c_str(), &hostBuf);
1218 copyOutStatBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1239 struct stat hostBuf;
1240 int result = stat(path.c_str(), &hostBuf);
1242 struct stat64 hostBuf;
1243 int result = stat64(path.c_str(), &hostBuf);
1249 copyOutStat64Buf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1259 int dirfd,
Addr pathname,
Addr bufPtr)
1262 if (dirfd != OS::TGT_AT_FDCWD)
1263 warn(
"fstatat64: first argument not AT_FDCWD; unlikely to work");
1270 path = process->checkPathRedirect(path);
1273 struct stat hostBuf;
1274 int result = stat(path.c_str(), &hostBuf);
1276 struct stat64 hostBuf;
1277 int result = stat64(path.c_str(), &hostBuf);
1283 copyOutStat64Buf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1296 auto ffdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
1299 int sim_fd = ffdp->getSimFD();
1302 struct stat hostBuf;
1303 int result = fstat(sim_fd, &hostBuf);
1305 struct stat64 hostBuf;
1306 int result = fstat64(sim_fd, &hostBuf);
1312 copyOutStat64Buf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
1332 struct stat hostBuf;
1333 int result = lstat(path.c_str(), &hostBuf);
1338 copyOutStatBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1358 struct stat hostBuf;
1359 int result = lstat(path.c_str(), &hostBuf);
1361 struct stat64 hostBuf;
1362 int result = lstat64(path.c_str(), &hostBuf);
1368 copyOutStat64Buf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1382 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1385 int sim_fd = ffdp->getSimFD();
1387 struct stat hostBuf;
1388 int result = fstat(sim_fd, &hostBuf);
1393 copyOutStatBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
1403 #if defined(__linux__) 1413 struct statfs hostBuf;
1414 int result = statfs(path.c_str(), &hostBuf);
1419 copyOutStatfsBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1434 if (((flags & OS::TGT_CLONE_SIGHAND)&& !(flags & OS::TGT_CLONE_VM)) ||
1435 ((flags & OS::TGT_CLONE_THREAD) && !(flags & OS::TGT_CLONE_SIGHAND)) ||
1436 ((flags & OS::TGT_CLONE_FS) && (flags & OS::TGT_CLONE_NEWNS)) ||
1437 ((flags & OS::TGT_CLONE_NEWIPC) && (flags & OS::TGT_CLONE_SYSVSEM)) ||
1438 ((flags & OS::TGT_CLONE_NEWPID) && (flags & OS::TGT_CLONE_THREAD)) ||
1439 ((flags & OS::TGT_CLONE_VM) && !(newStack)))
1455 ProcessParams *pp =
new ProcessParams();
1456 pp->executable.assign(*(
new std::string(
p->progName())));
1457 pp->cmd.push_back(*(
new std::string(
p->progName())));
1458 pp->system =
p->system;
1459 pp->cwd.assign(
p->tgtCwd);
1460 pp->input.assign(
"stdin");
1461 pp->output.assign(
"stdout");
1462 pp->errout.assign(
"stderr");
1464 pp->euid =
p->euid();
1466 pp->egid =
p->egid();
1469 std::set<int>
const& pids =
p->system->PIDs;
1470 int temp_pid = *pids.begin();
1473 }
while (pids.find(temp_pid) != pids.end());
1475 fatal(
"temp_pid is too large: %d", temp_pid);
1478 pp->ppid = (flags & OS::TGT_CLONE_THREAD) ?
p->ppid() :
p->pid();
1479 pp->useArchPT =
p->useArchPT;
1480 pp->kvmInSE =
p->kvmInSE;
1491 if (flags & OS::TGT_CLONE_PARENT_SETTID) {
1492 BufferArg ptidBuf(ptidPtr,
sizeof(
long));
1493 long *ptid = (
long *)ptidBuf.
bufferPtr();
1498 if (flags & OS::TGT_CLONE_THREAD) {
1503 p->clone(tc, ctc, cp, flags);
1505 if (flags & OS::TGT_CLONE_THREAD) {
1508 }
else if (flags & OS::TGT_SIGCHLD) {
1512 if (flags & OS::TGT_CLONE_CHILD_SETTID) {
1513 BufferArg ctidBuf(ctidPtr,
sizeof(
long));
1514 long *ctid = (
long *)ctidBuf.
bufferPtr();
1519 if (flags & OS::TGT_CLONE_CHILD_CLEARTID)
1524 OS::archClone(flags,
p, cp, tc, ctc, newStack, tlsPtr);
1528 #if THE_ISA == SPARC_ISA 1547 return cloneFunc<OS>(desc, tc, flags, newStack, ptidPtr, ctidPtr, tlsPtr);
1557 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1560 int sim_fd = ffdp->getSimFD();
1562 struct statfs hostBuf;
1563 int result = fstatfs(sim_fd, &hostBuf);
1568 copyOutStatfsBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1577 int tgt_fd, uint64_t tiov_base,
size_t count)
1581 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1584 int sim_fd = ffdp->getSimFD();
1587 typename OS::tgt_iovec tiov[
count];
1588 struct iovec hiov[count];
1589 for (
size_t i = 0;
i <
count; ++
i) {
1590 prox.
readBlob(tiov_base + (
i *
sizeof(
typename OS::tgt_iovec)),
1591 &tiov[
i],
sizeof(
typename OS::tgt_iovec));
1593 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1596 int result = readv(sim_fd, hiov, count);
1597 int local_errno = errno;
1599 for (
size_t i = 0;
i <
count; ++
i) {
1602 hiov[
i].iov_base, hiov[
i].iov_len);
1604 delete [] (
char *)hiov[
i].iov_base;
1607 return (result == -1) ? -local_errno : result;
1614 int tgt_fd, uint64_t tiov_base,
size_t count)
1618 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
1621 int sim_fd = hbfdp->getSimFD();
1624 struct iovec hiov[count];
1625 for (
size_t i = 0;
i <
count; ++
i) {
1626 typename OS::tgt_iovec tiov;
1628 prox.
readBlob(tiov_base +
i*
sizeof(
typename OS::tgt_iovec),
1629 &tiov,
sizeof(
typename OS::tgt_iovec));
1631 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1636 int result = writev(sim_fd, hiov, count);
1639 delete [] (
char *)hiov[
i].iov_base;
1641 return (result == -1) ? -errno : result;
1649 int tgt_flags,
int tgt_fd,
typename OS::off_t
offset)
1654 if (start & (page_bytes - 1) ||
1655 offset & (page_bytes - 1) ||
1656 (tgt_flags & OS::TGT_MAP_PRIVATE &&
1657 tgt_flags & OS::TGT_MAP_SHARED) ||
1658 (!(tgt_flags & OS::TGT_MAP_PRIVATE) &&
1659 !(tgt_flags & OS::TGT_MAP_SHARED)) ||
1664 if ((prot & PROT_WRITE) && (tgt_flags & OS::TGT_MAP_SHARED)) {
1685 warn_once(
"mmap: writing to shared mmap region is currently " 1686 "unsupported. The write succeeds on the target, but it " 1687 "will not be propagated to the host or shared mappings");
1690 length =
roundUp(length, page_bytes);
1693 if (!(tgt_flags & OS::TGT_MAP_ANONYMOUS)) {
1694 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1699 return emul_driver->
mmap(tc, start, length, prot, tgt_flags,
1703 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(fdep);
1716 if (
p->interpImage.contains(tc->
pcState().instAddr())) {
1717 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1718 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(fdep);
1720 ffdp->getFileName()));
1722 ffdp->getFileName());
1726 lib->buildImage().minAddr(), start);
1734 if (!(tgt_flags & OS::TGT_MAP_FIXED)) {
1742 if (!(start &&
p->memState->isUnmapped(start, length))) {
1746 start =
p->memState->extendMmap(length);
1751 start, start + length - 1);
1758 if (tgt_flags & OS::TGT_MAP_FIXED) {
1763 p->memState->unmapRegion(start, length);
1769 std::string region_name;
1770 if (tgt_flags & OS::TGT_MAP_ANONYMOUS) {
1771 region_name =
"anon";
1773 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1774 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(fdep);
1782 p->memState->mapRegion(start, length, region_name, sim_fd, offset);
1790 int tgt_fd,
Addr bufPtr,
int nbytes,
int offset)
1794 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1797 int sim_fd = ffdp->getSimFD();
1805 return (bytes_read == -1) ? -errno : bytes_read;
1811 int tgt_fd,
Addr bufPtr,
int nbytes,
int offset)
1815 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1818 int sim_fd = ffdp->getSimFD();
1823 int bytes_written = pwrite(sim_fd, bufArg.
bufferPtr(), nbytes,
offset);
1825 return (bytes_written == -1) ? -errno : bytes_written;
1833 int tgt_flags,
int tgt_fd,
typename OS::off_t
offset)
1835 return mmapFunc<OS>(desc, tc, start,
length,
prot, tgt_flags,
1836 tgt_fd, offset * tc->getSystemPtr()->getPageBytes());
1843 unsigned resource,
Addr rlim)
1849 case OS::TGT_RLIMIT_STACK:
1851 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
1852 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1853 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1856 case OS::TGT_RLIMIT_DATA:
1858 rlp->rlim_cur = rlp->rlim_max = 256 * 1024 * 1024;
1859 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1860 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1863 case OS::TGT_RLIMIT_NPROC:
1865 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1866 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1870 warn(
"getrlimit: unimplemented resource %d", resource);
1885 warn(
"prlimit: ignoring rlimits for nonzero pid");
1889 warn(
"prlimit: ignoring new rlimit");
1894 case OS::TGT_RLIMIT_STACK:
1896 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
1897 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1898 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1900 case OS::TGT_RLIMIT_DATA:
1902 rlp->rlim_cur = rlp->rlim_max = 256*1024*1024;
1903 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1904 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1907 warn(
"prlimit: unimplemented resource %d", resource);
1920 int clk_id,
Addr tp_ptr)
1983 struct timeval hostTimeval[2];
1984 for (
int i = 0;
i < 2; ++
i) {
1990 path = process->checkPathRedirect(path);
1992 int result = utimes(path.c_str(), hostTimeval);
2012 if (access(path.c_str(), F_OK) == -1)
2018 for (
int inc = 0; ;
inc++) {
2025 vect.push_back(std::string());
2036 ProcessParams *pp =
new ProcessParams();
2037 pp->executable = path;
2038 read_in(pp->cmd, mem_proxy, argv_mem_loc);
2039 read_in(pp->env, mem_proxy, envp_mem_loc);
2041 pp->egid =
p->egid();
2042 pp->euid =
p->euid();
2044 pp->ppid =
p->ppid();
2046 pp->input.assign(
"cin");
2047 pp->output.assign(
"cout");
2048 pp->errout.assign(
"cerr");
2049 pp->cwd.assign(
p->tgtCwd);
2050 pp->system =
p->system;
2059 p->system->PIDs.erase(
p->pid());
2060 Process *new_p = pp->create();
2067 new_p->
fds =
p->fds;
2068 for (
int i = 0;
i < new_p->
fds->getSize();
i++) {
2069 std::shared_ptr<FDEntry> fdep = (*new_p->
fds)[
i];
2070 if (fdep && fdep->getCOE())
2071 new_p->
fds->closeFDEntry(
i);
2083 tc->
setNPC(pcState.instAddr());
2096 rup->ru_utime.tv_sec = 0;
2097 rup->ru_utime.tv_usec = 0;
2098 rup->ru_stime.tv_sec = 0;
2099 rup->ru_stime.tv_usec = 0;
2107 rup->ru_inblock = 0;
2108 rup->ru_oublock = 0;
2111 rup->ru_nsignals = 0;
2116 case OS::TGT_RUSAGE_SELF:
2122 case OS::TGT_RUSAGE_CHILDREN:
2129 warn(
"getrusage() only supports RUSAGE_SELF. Parameter %d ignored.",
2147 bufp->tms_utime = clocks;
2148 bufp->tms_stime = 0;
2149 bufp->tms_cutime = 0;
2150 bufp->tms_cstime = 0;
2167 typename OS::time_t sec, usec;
2172 typename OS::time_t
t = sec;
2175 p.
writeBlob(taddr, &t, (
int)
sizeof(
typename OS::time_t));
2203 if (temp->
pid() == tid) {
2209 if (sig != 0 || sig != OS::TGT_SIGABRT)
2212 if (tgt_proc ==
nullptr)
2215 if (tgid != -1 && tgt_proc->
tgid() != tgid)
2218 if (sig == OS::TGT_SIGABRT)
2231 int sim_fd = socket(domain, type, prot);
2235 auto sfdp = std::make_shared<SocketFDEntry>(sim_fd,
domain,
type,
prot);
2236 int tgt_fd =
p->fds->allocFD(sfdp);
2249 int status = socketpair(domain, type, prot, (
int *)svBuf.
bufferPtr());
2255 auto sfdp1 = std::make_shared<SocketFDEntry>(fds[0],
domain,
type,
prot);
2256 fds[0] =
p->fds->allocFD(sfdp1);
2257 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1],
domain,
type,
prot);
2258 fds[1] =
p->fds->allocFD(sfdp2);
2267 int nfds_t,
Addr fds_read_ptr,
Addr fds_writ_ptr,
2268 Addr fds_excp_ptr,
Addr time_val_ptr)
2311 std::map<int, int> trans_map;
2312 auto try_add_host_set = [&](fd_set *tgt_set_entry,
2313 fd_set *hst_set_entry,
2321 if (FD_ISSET(iter, tgt_set_entry)) {
2327 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[iter]);
2330 auto sim_fd = hbfdp->getSimFD();
2337 trans_map[sim_fd] = iter;
2344 nfds_h = std::max(nfds_h - 1, sim_fd + 1);
2350 FD_SET(sim_fd, hst_set_entry);
2355 for (
int i = 0;
i < nfds_t;
i++) {
2357 bool ebadf = try_add_host_set((fd_set*)&*rd_t, &rd_h,
i);
2358 if (ebadf)
return -EBADF;
2361 bool ebadf = try_add_host_set((fd_set*)&*wr_t, &wr_h,
i);
2362 if (ebadf)
return -EBADF;
2365 bool ebadf = try_add_host_set((fd_set*)&*ex_t, &ex_h,
i);
2366 if (ebadf)
return -EBADF;
2381 retval = select(nfds_h,
2382 fds_read_ptr ? &rd_h :
nullptr,
2383 fds_writ_ptr ? &wr_h :
nullptr,
2384 fds_excp_ptr ? &ex_h :
nullptr,
2394 struct timeval tv = { 0, 0 };
2396 retval = select(nfds_h,
2397 fds_read_ptr ? &rd_h :
nullptr,
2398 fds_writ_ptr ? &wr_h :
nullptr,
2399 fds_excp_ptr ? &ex_h :
nullptr,
2409 if (sig.receiver ==
p)
2418 FD_ZERO((fd_set*)&*rd_t);
2419 FD_ZERO((fd_set*)&*wr_t);
2420 FD_ZERO((fd_set*)&*ex_t);
2427 for (
int i = 0;
i < nfds_h;
i++) {
2429 if (FD_ISSET(
i, &rd_h))
2430 FD_SET(trans_map[
i], (fd_set*)&*rd_t);
2434 if (FD_ISSET(
i, &wr_h))
2435 FD_SET(trans_map[
i], (fd_set*)&*wr_t);
2439 if (FD_ISSET(
i, &ex_h))
2440 FD_SET(trans_map[
i], (fd_set*)&*ex_t);
2459 int tgt_fd,
Addr buf_ptr,
int nbytes)
2463 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
2466 int sim_fd = hbfdp->getSimFD();
2470 pfd.events = POLLIN | POLLPRI;
2471 if ((poll(&pfd, 1, 0) == 0)
2472 && !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK))
2476 int bytes_read = read(sim_fd, buf_arg.
bufferPtr(), nbytes);
2481 return (bytes_read == -1) ? -errno : bytes_read;
2487 int tgt_fd,
Addr buf_ptr,
int nbytes)
2491 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
2494 int sim_fd = hbfdp->getSimFD();
2501 pfd.events = POLLOUT;
2509 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(hbfdp);
2510 if (ffdp && (ffdp->getFileName() !=
"/dev/random")) {
2511 if (!poll(&pfd, 1, 0) && !(ffdp->getFlags() & OS::TGT_O_NONBLOCK))
2515 int bytes_written = write(sim_fd, buf_arg.
bufferPtr(), nbytes);
2517 if (bytes_written != -1)
2520 return (bytes_written == -1) ? -errno : bytes_written;
2526 pid_t pid,
Addr statPtr,
int options,
Addr rusagePtr)
2531 DPRINTF_SYSCALL(Verbose,
"wait4: rusage pointer provided %lx, however " 2532 "functionality not supported. Ignoring rusage pointer.\n",
2546 if (iter->receiver ==
p) {
2548 if ((iter->sender->pgid() == -pid)
2549 && (iter->signalValue == OS::TGT_SIGCHLD))
2551 }
else if (pid == -1) {
2552 if (iter->signalValue == OS::TGT_SIGCHLD)
2554 }
else if (pid == 0) {
2555 if ((iter->sender->pgid() ==
p->pgid())
2556 && (iter->signalValue == OS::TGT_SIGCHLD))
2559 if ((iter->sender->pid() == pid)
2560 && (iter->signalValue == OS::TGT_SIGCHLD))
2570 const int EXITED = 0;
2571 BufferArg statusBuf(statPtr,
sizeof(
int));
2576 pid_t retval = iter->sender->pid();
2584 int tgt_fd,
Addr addrPtr,
Addr lenPtr)
2594 auto sfdp = std::dynamic_pointer_cast<
SocketFDEntry>((*
p->fds)[tgt_fd]);
2597 int sim_fd = sfdp->getSimFD();
2607 pfd.events = POLLIN | POLLPRI;
2608 if ((poll(&pfd, 1, 0) == 0) && !(sfdp->getFlags() & OS::TGT_O_NONBLOCK))
2612 lenBufPtr =
new BufferArg(lenPtr,
sizeof(socklen_t));
2614 memcpy(&addrLen, (socklen_t *)lenBufPtr->
bufferPtr(),
2619 addrBufPtr =
new BufferArg(addrPtr,
sizeof(
struct sockaddr));
2621 memcpy(&sa, (
struct sockaddr *)addrBufPtr->
bufferPtr(),
2622 sizeof(
struct sockaddr));
2625 host_fd = accept(sim_fd, &sa, &addrLen);
2637 *(socklen_t *)lenBufPtr->
bufferPtr() = addrLen;
2642 auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain,
2643 sfdp->_type, sfdp->_protocol);
2644 return p->fds->allocFD(afdp);
2651 unsigned initval,
int in_flags)
2653 #if defined(__linux__) 2656 int sim_fd = eventfd(initval, in_flags);
2660 bool cloexec = in_flags & OS::TGT_O_CLOEXEC;
2662 int flags = cloexec ? OS::TGT_O_CLOEXEC : 0;
2663 flags |= (in_flags & OS::TGT_O_NONBLOCK) ? OS::TGT_O_NONBLOCK : 0;
2665 auto hbfdp = std::make_shared<HBFDEntry>(flags, sim_fd, cloexec);
2666 int tgt_fd =
p->fds->allocFD(hbfdp);
2674 #endif // __SIM_SYSCALL_EMUL_HH__
SyscallReturn gethostnameFunc(SyscallDesc *desc, ThreadContext *tc, Addr buf_ptr, int name_len)
Target gethostname() handler.
This file defines buffer classes used to handle pointer arguments in emulated syscalls.
SyscallReturn writevFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t tiov_base, size_t count)
Target writev() handler.
virtual Addr mmap(ThreadContext *tc, Addr start, uint64_t length, int prot, int tgtFlags, int tgtFd, int offset)
Virtual method, invoked when the user program calls mmap() on the file descriptor returned by a previ...
SyscallReturn fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
Target fstat() handler.
SyscallReturn mremapFunc(SyscallDesc *desc, ThreadContext *tc, Addr start, uint64_t old_length, uint64_t new_length, uint64_t flags, GuestABI::VarArgs< uint64_t > varargs)
Target mremap() handler.
SyscallReturn listenFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int backlog)
virtual System * getSystemPtr()=0
SyscallReturn cloneFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack, Addr ptidPtr, Addr ctidPtr, Addr tlsPtr)
ObjectFile * createObjectFile(const std::string &fname, bool raw)
SyscallReturn getgidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getgid() handler.
SyscallReturn symlinkFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr new_pathname)
Target symlink() handler.
SyscallReturn getpeernameFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr sockAddrPtr, Addr addrlenPtr)
SyscallReturn futexFunc(SyscallDesc *desc, ThreadContext *tc, Addr uaddr, int op, int val, int timeout, Addr uaddr2, int val3)
Futex system call Implemented by Daniel Sanchez Used by printf's in multi-threaded apps...
void revokeThreadContext(int context_id)
After delegating a thread context to a child process no longer should relate to the ThreadContext...
#define fatal(...)
This implements a cprintf based fatal() function.
SyscallReturn connectFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr buf_ptr, int addrlen)
SyscallReturn lstatFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target lstat() handler.
uint64_t childClearTID
Calls a futex wakeup at the address specified by this pointer when this process exits.
T gtoh(T value, ByteOrder guest_byte_order)
SyscallReturn unlinkFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname)
Target unlink() handler.
SyscallReturn getegidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getegid() handler.
void copyOutStatfsBuf(PortProxy &mem, Addr addr, hst_statfs *host)
SyscallReturn bindFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr buf_ptr, int addrlen)
SyscallReturn sysinfoFunc(SyscallDesc *desc, ThreadContext *tc, Addr info)
Target sysinfo() handler.
virtual TheISA::PCState pcState() const =0
SyscallReturn truncateFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, off_t length)
Target truncate() handler.
SyscallReturn getpidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpid() handler.
SyscallReturn rmdirFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname)
bool copyIn(PortProxy &memproxy)
copy data into simulator space (read from target memory)
SyscallReturn socketpairFunc(SyscallDesc *desc, ThreadContext *tc, int domain, int type, int prot, Addr svPtr)
SyscallReturn cloneBackwardsFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack, Addr ptidPtr, Addr tlsPtr, Addr ctidPtr)
SyscallReturn getrlimitFunc(SyscallDesc *desc, ThreadContext *tc, unsigned resource, Addr rlim)
Target getrlimit() handler.
SyscallReturn sendtoFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufrPtr, size_t bufrLen, int flags, Addr addrPtr, socklen_t addrLen)
SyscallReturn fallocateFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int mode, off_t offset, off_t len)
SyscallReturn chmodFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, mode_t mode)
Target chmod() handler.
SyscallReturn umaskFunc(SyscallDesc *desc, ThreadContext *tc)
Target umask() handler.
SyscallReturn getpagesizeFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpagesize() handler.
SyscallReturn getppidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getppid() handler.
SyscallReturn _llseekFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t offset_high, uint32_t offset_low, Addr result_ptr, int whence)
Target _llseek() handler.
virtual PortProxy & getVirtProxy()=0
SyscallReturn pollFunc(SyscallDesc *desc, ThreadContext *tc, Addr fdsPtr, int nfds, int tmout)
virtual Process * getProcessPtr()=0
SyscallReturn ignoreFunc(SyscallDesc *desc, ThreadContext *tc)
Handler for unimplemented syscalls that we never intend to implement (signal handling, etc.) and should not affect the correct behavior of the program.
Holds file descriptors for host-backed files; host-backed files are files which were opened on the ph...
SyscallReturn mmapFunc(SyscallDesc *desc, ThreadContext *tc, Addr start, typename OS::size_t length, int prot, int tgt_flags, int tgt_fd, typename OS::off_t offset)
Target mmap() handler.
SyscallReturn eventfdFunc(SyscallDesc *desc, ThreadContext *tc, unsigned initval, int in_flags)
Target eventfd() function.
Overload hash function for BasicBlockRange type.
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
SyscallReturn readlinkatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, Addr pathname, Addr buf, size_t bufsiz)
Target readlinkat() handler.
void getElapsedTimeMicro(T1 &sec, T2 &usec)
Helper function to convert current elapsed time to seconds and microseconds.
T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
SyscallReturn writeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr buf_ptr, int nbytes)
SyscallReturn openatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_dirfd, Addr pathname, int tgt_flags, int mode)
Target open() handler.
TypedBufferArg is a class template; instances of this template represent typed buffers in target user...
SyscallReturn readFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr buf_ptr, int nbytes)
ThreadContext is the external interface to all thread state for anything outside of the CPU...
int requeue(Addr addr1, uint64_t tgid, int count, int count2, Addr addr2)
This operation wakes a given number (val) of waiters.
SyscallReturn chownFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, uint32_t owner, uint32_t group)
Target chown() handler.
void usage(const char *progname)
SyscallReturn shutdownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int how)
Target shutdown() handler.
SyscallReturn getsockoptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int level, int optname, Addr valPtr, Addr lenPtr)
#define DPRINTF_SYSCALL(FLAGEXT, FMT,...)
This macro is intended to help with readability.
SyscallReturn fcntlFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd, GuestABI::VarArgs< int > varargs)
Target fcntl() handler.
SyscallReturn lstat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target lstat64() handler.
SyscallReturn getpgrpFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpgrpFunc() handler.
SyscallReturn pipePseudoFunc(SyscallDesc *desc, ThreadContext *tc)
Pseudo Funcs - These functions use a different return convension, returning a second value in a regis...
SyscallReturn linkFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr new_pathname)
Target link() handler.
SyscallReturn recvmsgFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr msgPtr, int flags)
SyscallReturn brkFunc(SyscallDesc *desc, ThreadContext *tc, Addr new_brk)
Target brk() handler: set brk address.
SyscallReturn exitFunc(SyscallDesc *desc, ThreadContext *tc, int status)
Target exit() handler: terminate current context.
SyscallReturn exitGroupFunc(SyscallDesc *desc, ThreadContext *tc, int status)
Target exit_group() handler: terminate simulation. (exit all threads)
void copyOutStat64Buf(PortProxy &mem, Addr addr, hst_stat64 *host, bool fakeTTY=false)
SyscallReturn gettidFunc(SyscallDesc *desc, ThreadContext *tc)
Target gettid() handler.
Tick curTick()
The current simulated tick.
virtual int ioctl(ThreadContext *tc, unsigned req, Addr buf)=0
Abstract method, invoked when the user program calls ioctl() on the file descriptor returned by a pre...
SyscallReturn getcwdFunc(SyscallDesc *desc, ThreadContext *tc, Addr buf_ptr, unsigned long size)
Target getcwd() handler.
void assignThreadContext(ContextID context_id)
SyscallReturn fcntl64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd)
Target fcntl64() handler.
void inc(scfx_mant &mant)
T htog(T value, ByteOrder guest_byte_order)
SyscallReturn ftruncateFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, off_t length)
Target ftruncate() handler.
virtual int cpuId() const =0
SyscallReturn socketFunc(SyscallDesc *desc, ThreadContext *tc, int domain, int type, int prot)
SyscallReturn mkdirFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, mode_t mode)
Target mkdir() handler.
virtual void setProcessPtr(Process *p)=0
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
int wakeup(Addr addr, uint64_t tgid, int count)
Wakes up at most count waiting threads on a futex.
SyscallReturn getrusageFunc(SyscallDesc *desc, ThreadContext *tc, int who, Addr usage)
Target getrusage() function.
SyscallReturn timeFunc(SyscallDesc *desc, ThreadContext *tc, Addr taddr)
Target time() function.
SyscallReturn execveFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr argv_mem_loc, Addr envp_mem_loc)
SyscallReturn setpgidFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int pgid)
Target setpgid() handler.
SyscallReturn closeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
Target close() handler.
SyscallReturn wait4Func(SyscallDesc *desc, ThreadContext *tc, pid_t pid, Addr statPtr, int options, Addr rusagePtr)
static SyscallReturn retry()
Pseudo-constructor to create an instance with the retry flag set.
SyscallReturn getcpuFunc(SyscallDesc *desc, ThreadContext *tc, Addr cpu_ptr, Addr node_ptr, Addr tcache_ptr)
std::vector< ThreadContext * > threadContexts
Extends the base class to include a host-backed file descriptor field that records the integer used t...
unsigned numContexts() const
SyscallReturn sendmsgFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr msgPtr, int flags)
void * bufferPtr()
Return a pointer to the internal simulator-space buffer.
SyscallReturn renameFunc(SyscallDesc *desc, ThreadContext *tc, Addr oldpath, Addr newpath)
Target rename() handler.
SyscallReturn getuidFunc(SyscallDesc *desc, ThreadContext *tc)
SyscallReturn timesFunc(SyscallDesc *desc, ThreadContext *tc, Addr bufPtr)
Target times() function.
std::string const & getFileName() const
SyscallReturn tgkillFunc(SyscallDesc *desc, ThreadContext *tc, int tgid, int tid, int sig)
ThreadContext * findFreeContext()
void warnUnsupportedOS(std::string syscall_name)
SyscallReturn truncate64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, int64_t length)
Target truncate64() handler.
SyscallReturn selectFunc(SyscallDesc *desc, ThreadContext *tc, int nfds_t, Addr fds_read_ptr, Addr fds_writ_ptr, Addr fds_excp_ptr, Addr time_val_ptr)
SyscallReturn clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, Addr tp_ptr)
Target clock_getres() function.
virtual void activate()=0
Set the status to Active.
virtual int open(ThreadContext *tc, int mode, int flags)=0
Abstract method, invoked when the user program calls open() on the device driver. ...
void getElapsedTimeNano(T1 &sec, T2 &nsec)
Helper function to convert current elapsed time to seconds and nanoseconds.
virtual void setIntReg(RegIndex reg_idx, RegVal val)=0
SyscallReturn ioctlFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, unsigned req, Addr addr)
Target ioctl() handler.
SyscallReturn fchmodFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t mode)
Target fchmod() handler.
SyscallReturn fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
Target fstatfs() handler.
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
SyscallReturn dupFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
Target dup() handler.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
SyscallReturn fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
Target fstat64() handler.
SyscallReturn geteuidFunc(SyscallDesc *desc, ThreadContext *tc)
Target geteuid() handler.
SyscallReturn readvFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t tiov_base, size_t count)
Target readv() handler.
SyscallReturn unimplementedFunc(SyscallDesc *desc, ThreadContext *tc)
Handler for unimplemented syscalls that we haven't thought about.
std::list< BasicSignal > signalList
bool startswith(const char *s, const char *prefix)
Return true if 's' starts with the prefix string 'prefix'.
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
SyscallReturn statfsFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target statfs() handler.
void copyOutStatBuf(PortProxy &mem, Addr addr, hst_stat *host, bool fakeTTY=false)
This class provides the wrapper interface for the system call implementations which are defined in th...
This object is a proxy for a port or other object which implements the functional response protocol...
EmulationPageTable * pTable
SyscallReturn setTidAddressFunc(SyscallDesc *desc, ThreadContext *tc, uint64_t tidPtr)
Target set_tid_address() handler.
Declarations of a non-full system Page Table.
const int SyscallPseudoReturnReg
void suspend_bitset(Addr addr, uint64_t tgid, ThreadContext *tc, int bitmask)
inserts a futex into the map with one waiting TC associates the waiter with a given bitmask ...
int wakeup_bitset(Addr addr, uint64_t tgid, int bitmask)
Wakes up all waiters waiting on the addr and associated with the given bitset.
SyscallReturn pipe2Func(SyscallDesc *desc, ThreadContext *tc, Addr tgt_addr, int flags)
Target pipe() handler.
SyscallReturn prlimitFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int resource, Addr n, Addr o)
SyscallReturn readlinkFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr buf, size_t bufsiz)
Target readlink() handler.
void suspend(Addr addr, uint64_t tgid, ThreadContext *tc)
Inserts a futex into the map with one waiting TC.
virtual int threadId() const =0
std::string checkPathRedirect(const std::string &filename)
Redirect file path if it matches any keys initialized by system object.
bool copyOut(PortProxy &memproxy)
copy data out of simulator space (write to target memory)
SyscallReturn chdirFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname)
Target chdir() handler.
SyscallReturn pread64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr, int nbytes, int offset)
SyscallReturn accessFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, mode_t mode)
Target access() handler.
FutexMap class holds a map of all futexes used in the system.
virtual ContextID contextId() const =0
SyscallReturn setsockoptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int level, int optname, Addr valPtr, socklen_t len)
void convertStat64Buf(target_stat &tgt, host_stat64 *host, ByteOrder bo, bool fakeTTY=false)
SyscallReturn utimesFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr times)
Target utimes() handler.
SyscallReturn statFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target stat() handler.
SyscallReturn getsocknameFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr addrPtr, Addr lenPtr)
BufferArg represents an untyped buffer in target user space that is passed by reference to an (emulat...
virtual void clearArchRegs()=0
EmulatedDriver is an abstract base class for fake SE-mode device drivers.
SyscallReturn clock_gettimeFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, Addr tp_ptr)
Target clock_gettime() function.
SyscallReturn lseekFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t offs, int whence)
Target lseek() handler.
Holds file descriptors needed to simulate devices opened with pseudo files (commonly with calls to io...
SyscallReturn pwrite64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr, int nbytes, int offset)
SyscallReturn pipeFunc(SyscallDesc *desc, ThreadContext *tc, Addr tgt_addr)
Target pipe() handler.
SyscallReturn mmap2Func(SyscallDesc *desc, ThreadContext *tc, Addr start, typename OS::size_t length, int prot, int tgt_flags, int tgt_fd, typename OS::off_t offset)
Target mmap2() handler.
SyscallReturn ignoreWarnOnceFunc(SyscallDesc *desc, ThreadContext *tc)
Like above, but only prints a warning once per syscall desc it's used with.
SyscallReturn openFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, int tgt_flags, int mode)
Target open() handler.
This class represents the return value from an emulated system call, including any errno setting...
SyscallReturn fstatat64Func(SyscallDesc *desc, ThreadContext *tc, int dirfd, Addr pathname, Addr bufPtr)
Target fstatat64() handler.
SyscallReturn recvfromFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufrPtr, size_t bufrLen, int flags, Addr addrPtr, Addr addrlenPtr)
SyscallReturn stat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target stat64() handler.
void convertStatBuf(target_stat &tgt, host_stat *host, ByteOrder bo, bool fakeTTY=false)
SyscallReturn munmapFunc(SyscallDesc *desc, ThreadContext *tc, Addr start, size_t length)
Target munmap() handler.
bool tryReadString(std::string &str, Addr addr) const
Reads the string at guest address addr into the std::string str.
GenericISA::DelaySlotPCState< MachInst > PCState
SyscallReturn renameatFunc(SyscallDesc *desc, ThreadContext *tc, int olddirfd, Addr oldpath, int newdirfd, Addr newpath)
Target renameat() handler.
virtual void returnInto(ThreadContext *tc, const SyscallReturn &ret)=0
For use within the system call executor if new threads are created and need something returned into t...
const unsigned seconds_since_epoch
Approximate seconds since the epoch (1/1/1970).
SyscallReturn unlinkatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, Addr pathname)
Target unlinkat() handler.
SyscallReturn faccessatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, Addr pathname, int mode)
Target facessat() handler.
SyscallReturn acceptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr addrPtr, Addr lenPtr)
SyscallReturn gettimeofdayFunc(SyscallDesc *desc, ThreadContext *tc, Addr tv_ptr, Addr tz_ptr)
Target gettimeofday() handler.
SyscallReturn dup2Func(SyscallDesc *desc, ThreadContext *tc, int old_tgt_fd, int new_tgt_fd)
Target dup2() handler.
Addr getPageBytes() const
Get the page bytes for the ISA.
SyscallReturn fchownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t owner, uint32_t group)
Target fchown() handler.
SyscallReturn mknodFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, mode_t mode, dev_t dev)
Target mknod() handler.
ByteOrder byteOrder(const ThreadContext *tc)
std::shared_ptr< FDArray > fds
SyscallReturn ftruncate64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int64_t length)
Target ftruncate64() handler.