Go to the documentation of this file.
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"
100 #include "params/Process.hh"
111 #if defined(__APPLE__) && defined(__MACH__) && !defined(CMSG_ALIGN)
112 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
113 #elif defined(__FreeBSD__) && !defined(CMSG_ALIGN)
114 #define CMSG_ALIGN(n) _ALIGN(n)
164 int tgt_fd, uint64_t offs,
int whence);
168 int tgt_fd, uint64_t offset_high,
169 uint32_t offset_low,
VPtr<> result_ptr,
int whence);
177 int tgt_fd,
int how);
181 VPtr<> buf_ptr,
int name_len);
185 VPtr<> buf_ptr,
unsigned long size);
224 VPtr<> pathname, off_t length);
229 int tgt_fd, off_t length);
234 VPtr<> pathname, int64_t length);
238 int tgt_fd, int64_t length);
248 VPtr<> pathname, uint32_t owner, uint32_t group);
259 int tgt_fd, uint32_t owner, uint32_t group);
267 int old_tgt_fd,
int new_tgt_fd);
275 int tgt_fd,
int cmd);
282 VPtr<> tgt_addr,
int flags);
289 int tgt_fd,
VPtr<> sockAddrPtr,
294 int tgt_fd,
VPtr<> buf_ptr,
int addrlen);
298 int tgt_fd,
int backlog);
302 int tgt_fd,
VPtr<> buf_ptr,
int addrlen);
304 #if defined(SYS_getdents)
310 #if defined(SYS_getdents64)
318 int tgt_fd,
VPtr<> bufrPtr,
size_t bufrLen,
int flags,
319 VPtr<> addrPtr, socklen_t addrLen);
323 int tgt_fd,
VPtr<> bufrPtr,
size_t bufrLen,
328 int tgt_fd,
VPtr<> msgPtr,
int flags);
332 int tgt_fd,
VPtr<> msgPtr,
int flags);
355 int tgt_fd,
int level,
int optname,
360 int tgt_fd,
int level,
int optname,
385 op &= ~OS::TGT_FUTEX_PRIVATE_FLAG;
386 op &= ~OS::TGT_FUTEX_CLOCK_REALTIME_FLAG;
390 if (OS::TGT_FUTEX_WAIT ==
op || OS::TGT_FUTEX_WAIT_BITSET ==
op) {
402 return -OS::TGT_EWOULDBLOCK;
404 if (OS::TGT_FUTEX_WAIT ==
op) {
405 futex_map.
suspend(uaddr, process->tgid(), tc);
411 }
else if (OS::TGT_FUTEX_WAKE ==
op) {
412 return futex_map.
wakeup(uaddr, process->tgid(),
val);
413 }
else if (OS::TGT_FUTEX_WAKE_BITSET ==
op) {
414 return futex_map.
wakeup_bitset(uaddr, process->tgid(), val3);
415 }
else if (OS::TGT_FUTEX_REQUEUE ==
op ||
416 OS::TGT_FUTEX_CMP_REQUEUE ==
op) {
426 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
427 return -OS::TGT_EWOULDBLOCK;
428 return futex_map.
requeue(uaddr, process->tgid(),
val, timeout, uaddr2);
429 }
else if (OS::TGT_FUTEX_WAKE_OP ==
op) {
457 int wake_cmparg = val3 & 0xfff;
458 int wake_oparg = (val3 & 0xfff000) >> 12;
459 int wake_cmp = (val3 & 0xf000000) >> 24;
460 int wake_op = (val3 & 0xf0000000) >> 28;
461 if ((wake_op & OS::TGT_FUTEX_OP_ARG_SHIFT) >> 3 == 1)
462 wake_oparg = (1 << wake_oparg);
463 wake_op &= ~OS::TGT_FUTEX_OP_ARG_SHIFT;
465 if (wake_op == OS::TGT_FUTEX_OP_SET)
467 else if (wake_op == OS::TGT_FUTEX_OP_ADD)
468 newval += wake_oparg;
469 else if (wake_op == OS::TGT_FUTEX_OP_OR)
470 newval |= wake_oparg;
471 else if (wake_op == OS::TGT_FUTEX_OP_ANDN)
472 newval &= ~wake_oparg;
473 else if (wake_op == OS::TGT_FUTEX_OP_XOR)
474 newval ^= wake_oparg;
479 int woken1 = futex_map.
wakeup(uaddr, process->tgid(),
val);
482 bool is_wake2 =
false;
483 if (wake_cmp == OS::TGT_FUTEX_OP_CMP_EQ)
484 is_wake2 = oldval == wake_cmparg;
485 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_NE)
486 is_wake2 = oldval != wake_cmparg;
487 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LT)
488 is_wake2 = oldval < wake_cmparg;
489 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LE)
490 is_wake2 = oldval <= wake_cmparg;
491 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GT)
492 is_wake2 = oldval > wake_cmparg;
493 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GE)
494 is_wake2 = oldval >= wake_cmparg;
497 woken2 = futex_map.
wakeup(uaddr2, process->tgid(), timeout);
499 return woken1 + woken2;
501 warn(
"futex: op %d not implemented; ignoring.",
op);
517 template <
class T1,
class T2>
521 static const int OneMillion = 1000 * 1000;
524 sec = elapsed_usecs / OneMillion;
525 usec = elapsed_usecs % OneMillion;
530 template <
class T1,
class T2>
534 static const int OneBillion = 1000 * 1000 * 1000;
537 sec = elapsed_nsecs / OneBillion;
538 nsec = elapsed_nsecs % OneBillion;
561 template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
570 tgt->st_dev = host->st_dev;
571 tgt->st_dev =
htog(tgt->st_dev,
bo);
572 tgt->st_ino = host->st_ino;
573 tgt->st_ino =
htog(tgt->st_ino,
bo);
574 tgt->st_mode = host->st_mode;
577 tgt->st_mode &= ~S_IFMT;
578 tgt->st_mode |= S_IFCHR;
580 tgt->st_mode =
htog(tgt->st_mode,
bo);
581 tgt->st_nlink = host->st_nlink;
582 tgt->st_nlink =
htog(tgt->st_nlink,
bo);
583 tgt->st_uid = host->st_uid;
584 tgt->st_uid =
htog(tgt->st_uid,
bo);
585 tgt->st_gid = host->st_gid;
586 tgt->st_gid =
htog(tgt->st_gid,
bo);
588 tgt->st_rdev = 0x880d;
590 tgt->st_rdev = host->st_rdev;
591 tgt->st_rdev =
htog(tgt->st_rdev,
bo);
592 tgt->st_size = host->st_size;
593 tgt->st_size =
htog(tgt->st_size,
bo);
594 tgt->st_atimeX = host->st_atime;
595 tgt->st_atimeX =
htog(tgt->st_atimeX,
bo);
596 tgt->st_mtimeX = host->st_mtime;
597 tgt->st_mtimeX =
htog(tgt->st_mtimeX,
bo);
598 tgt->st_ctimeX = host->st_ctime;
599 tgt->st_ctimeX =
htog(tgt->st_ctimeX,
bo);
602 tgt->st_blksize = 0x2000;
603 tgt->st_blksize =
htog(tgt->st_blksize,
bo);
604 tgt->st_blocks = host->st_blocks;
605 tgt->st_blocks =
htog(tgt->st_blocks,
bo);
610 template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
615 copyOutStatBuf<OS>(tgt, host, fakeTTY);
616 #if defined(STAT_HAVE_NSEC)
619 tgt->st_atime_nsec = host->st_atime_nsec;
620 tgt->st_atime_nsec =
htog(tgt->st_atime_nsec,
bo);
621 tgt->st_mtime_nsec = host->st_mtime_nsec;
622 tgt->st_mtime_nsec =
htog(tgt->st_mtime_nsec,
bo);
623 tgt->st_ctime_nsec = host->st_ctime_nsec;
624 tgt->st_ctime_nsec =
htog(tgt->st_ctime_nsec,
bo);
626 tgt->st_atime_nsec = 0;
627 tgt->st_mtime_nsec = 0;
628 tgt->st_ctime_nsec = 0;
632 template <
class OS,
typename TgtStatPtr,
typename HostStatPtr>
638 tgt->f_type =
htog(host->f_type,
bo);
639 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
640 tgt->f_bsize =
htog(host->f_iosize,
bo);
642 tgt->f_bsize =
htog(host->f_bsize,
bo);
644 tgt->f_blocks =
htog(host->f_blocks,
bo);
645 tgt->f_bfree =
htog(host->f_bfree,
bo);
646 tgt->f_bavail =
htog(host->f_bavail,
bo);
647 tgt->f_files =
htog(host->f_files,
bo);
648 tgt->f_ffree =
htog(host->f_ffree,
bo);
649 memcpy(&tgt->f_fsid, &host->f_fsid,
sizeof(host->f_fsid));
650 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
651 tgt->f_namelen =
htog(host->f_namemax,
bo);
652 tgt->f_frsize =
htog(host->f_bsize,
bo);
653 #elif defined(__APPLE__)
657 tgt->f_namelen =
htog(host->f_namelen,
bo);
658 tgt->f_frsize =
htog(host->f_frsize,
bo);
660 #if defined(__linux__)
661 memcpy(&tgt->f_spare, &host->f_spare,
662 std::min(
sizeof(host->f_spare),
sizeof(tgt->f_spare)));
668 memset(&tgt->f_spare, 0,
sizeof(tgt->f_spare));
685 if (OS::isTtyReq(req))
688 auto dfdp = std::dynamic_pointer_cast<DeviceFDEntry>((*
p->fds)[tgt_fd]);
692 return emul_driver->
ioctl(tc, req,
addr);
695 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
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);
709 conf->ifc_buf = (
char*)ifc_buf_arg.bufferPtr();
713 conf->ifc_buf = (
char*)ifc_buf_addr;
721 #if defined(__linux__)
726 #if defined(__linux__)
745 warn(
"Unsupported ioctl call (return ENOTTY): ioctl(%d, 0x%x, ...) @ \n",
754 int tgt_dirfd,
VPtr<> pathname,
int tgt_flags,
int mode)
767 int host_flags = O_BINARY;
775 for (
int i = 0;
i < OS::NUM_OPEN_FLAGS;
i++) {
776 if (tgt_flags & OS::openFlagTable[
i].tgtFlag) {
777 tgt_flags &= ~OS::openFlagTable[
i].tgtFlag;
778 host_flags |= OS::openFlagTable[
i].hostFlag;
782 warn(
"%s: cannot decode flags %#x", desc->
name(), tgt_flags);
785 host_flags |= O_BINARY;
800 std::string redir_path = path;
801 std::string abs_path = path;
802 if (tgt_dirfd == OS::TGT_AT_FDCWD) {
803 abs_path =
p->absolutePath(path,
true);
804 redir_path =
p->checkPathRedirect(path);
806 std::shared_ptr<FDEntry> fdep = ((*
p->fds)[tgt_dirfd]);
807 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
810 abs_path = ffdp->getFileName() + path;
811 redir_path =
p->checkPathRedirect(abs_path);
821 std::string filename = abs_path.substr(strlen(
"/dev/"));
825 "driver open with path[%s]\n",
826 desc->
name(), abs_path.c_str());
827 return drv->
open(tc,
mode, host_flags);
860 std::string used_path;
862 {
"/proc/meminfo/",
"/system/",
"/platform/",
"/etc/passwd",
863 "/proc/self/maps",
"/dev/urandom",
864 "/sys/devices/system/cpu/online" };
865 for (
auto entry : special_paths) {
867 sim_fd = OS::openSpecialFile(abs_path,
p, tc);
868 used_path = abs_path;
872 sim_fd = open(redir_path.c_str(), host_flags,
mode);
873 used_path = redir_path;
878 "(inferred from:%s)\n", desc->
name(),
879 used_path.c_str(), path.c_str());
891 auto ffdp = std::make_shared<FileFDEntry>(sim_fd, host_flags, path, 0);
892 int tgt_fd =
p->fds->allocFD(ffdp);
894 "(inferred from:%s)\n", desc->
name(),
895 sim_fd, tgt_fd, used_path.c_str(), path.c_str());
905 return openatFunc<OS>(
906 desc, tc, OS::TGT_AT_FDCWD, pathname, tgt_flags,
mode);
914 if (dirfd != OS::TGT_AT_FDCWD)
915 warn(
"unlinkat: first argument not AT_FDCWD; unlikely to work");
926 if (dirfd != OS::TGT_AT_FDCWD)
927 warn(
"faccessat: first argument not AT_FDCWD; unlikely to work");
937 if (dirfd != OS::TGT_AT_FDCWD)
938 warn(
"openat: first argument not AT_FDCWD; unlikely to work");
946 int olddirfd,
VPtr<> oldpath,
int newdirfd,
VPtr<> newpath)
948 if (olddirfd != OS::TGT_AT_FDCWD)
949 warn(
"renameat: first argument not AT_FDCWD; unlikely to work");
951 if (newdirfd != OS::TGT_AT_FDCWD)
952 warn(
"renameat: third argument not AT_FDCWD; unlikely to work");
954 return renameFunc(desc, tc, oldpath, newpath);
966 sysinfo->totalram = process->system->memSize();
967 sysinfo->mem_unit = 1;
989 path = process->checkPathRedirect(path);
992 int result = chmod(path.c_str(), hostMode);
1002 VPtr<> fdsPtr,
int nfds,
int tmout)
1006 BufferArg fdsBuf(fdsPtr,
sizeof(
struct pollfd) * nfds);
1015 int temp_tgt_fds[nfds];
1018 auto tgt_fd = temp_tgt_fds[
index];
1019 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1022 auto host_fd = hbfdp->getSimFD();
1044 if (it->receiver ==
p)
1059 auto tgt_fd = temp_tgt_fds[
index];
1079 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1082 int sim_fd = ffdp->getSimFD();
1084 mode_t hostMode =
mode;
1086 int result = fchmod(sim_fd, hostMode);
1088 return (result < 0) ? -errno : 0;
1095 VPtr<> start, uint64_t old_length, uint64_t new_length, uint64_t flags,
1099 Addr page_bytes =
p->pTable->pageSize();
1100 uint64_t provided_address = 0;
1101 bool use_provided_address = flags & OS::TGT_MREMAP_FIXED;
1103 if (use_provided_address)
1104 provided_address = varargs.
get<uint64_t>();
1106 if ((start % page_bytes != 0) ||
1107 (provided_address % page_bytes != 0)) {
1108 warn(
"mremap failing: arguments not page aligned");
1112 new_length =
roundUp(new_length, page_bytes);
1114 if (new_length > old_length) {
1115 Addr mmap_end =
p->memState->getMmapEnd();
1117 if ((start + old_length) == mmap_end &&
1118 (!use_provided_address || provided_address == start)) {
1121 uint64_t diff = new_length - old_length;
1122 p->memState->mapRegion(mmap_end, diff,
"remapped");
1123 p->memState->setMmapEnd(mmap_end + diff);
1126 if (!use_provided_address && !(flags & OS::TGT_MREMAP_MAYMOVE)) {
1127 warn(
"can't remap here and MREMAP_MAYMOVE flag not set\n");
1130 uint64_t new_start = provided_address;
1131 if (!use_provided_address) {
1132 new_start =
p->mmapGrowsDown() ?
1133 mmap_end - new_length : mmap_end;
1134 mmap_end =
p->mmapGrowsDown() ?
1135 new_start : mmap_end + new_length;
1136 p->memState->setMmapEnd(mmap_end);
1139 warn(
"mremapping to new vaddr %08p-%08p, adding %d\n",
1140 new_start, new_start + new_length,
1141 new_length - old_length);
1144 p->allocateMem(new_start + old_length,
1145 new_length - old_length,
1146 use_provided_address );
1148 if (use_provided_address &&
1149 ((new_start + new_length >
p->memState->getMmapEnd() &&
1150 !
p->mmapGrowsDown()) ||
1151 (new_start < p->memState->getMmapEnd() &&
1152 p->mmapGrowsDown()))) {
1155 warn(
"mmap region limit exceeded with MREMAP_FIXED\n");
1158 warn(
"returning %08p as start\n", new_start);
1159 p->memState->remapRegion(start, new_start, old_length);
1165 if (use_provided_address && provided_address != start)
1166 p->memState->remapRegion(start, provided_address, new_length);
1167 if (new_length != old_length)
1168 p->memState->unmapRegion(start + new_length,
1169 old_length - new_length);
1170 return use_provided_address ? provided_address : (
Addr)start;
1189 struct stat hostBuf;
1190 int result = stat(path.c_str(), &hostBuf);
1195 copyOutStatBuf<OS>(tgt_stat, &hostBuf);
1217 struct stat hostBuf;
1218 int result = stat(path.c_str(), &hostBuf);
1220 struct stat64 hostBuf;
1221 int result = stat64(path.c_str(), &hostBuf);
1227 copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
1237 int dirfd,
VPtr<> pathname,
1241 if (dirfd != OS::TGT_AT_FDCWD)
1242 warn(
"fstatat64: first argument not AT_FDCWD; unlikely to work");
1249 path = process->checkPathRedirect(path);
1252 struct stat hostBuf;
1253 int result = stat(path.c_str(), &hostBuf);
1255 struct stat64 hostBuf;
1256 int result = stat64(path.c_str(), &hostBuf);
1262 copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
1276 auto ffdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1279 int sim_fd = ffdp->getSimFD();
1282 struct stat hostBuf;
1283 int result = fstat(sim_fd, &hostBuf);
1285 struct stat64 hostBuf;
1286 int result = fstat64(sim_fd, &hostBuf);
1292 copyOutStat64Buf<OS>(tgt_stat, &hostBuf, (sim_fd == 1));
1313 struct stat hostBuf;
1314 int result = lstat(path.c_str(), &hostBuf);
1319 copyOutStatBuf<OS>(tgt_stat, &hostBuf);
1340 struct stat hostBuf;
1341 int result = lstat(path.c_str(), &hostBuf);
1343 struct stat64 hostBuf;
1344 int result = lstat64(path.c_str(), &hostBuf);
1350 copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
1365 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1368 int sim_fd = ffdp->getSimFD();
1370 struct stat hostBuf;
1371 int result = fstat(sim_fd, &hostBuf);
1376 copyOutStatBuf<OS>(tgt_stat, &hostBuf, (sim_fd == 1));
1387 #if defined(__linux__)
1397 struct statfs hostBuf;
1398 int result = statfs(path.c_str(), &hostBuf);
1403 copyOutStatfsBuf<OS>(tgt_stat, &hostBuf);
1418 if (((flags & OS::TGT_CLONE_SIGHAND)&& !(flags & OS::TGT_CLONE_VM)) ||
1419 ((flags & OS::TGT_CLONE_THREAD) && !(flags & OS::TGT_CLONE_SIGHAND)) ||
1420 ((flags & OS::TGT_CLONE_FS) && (flags & OS::TGT_CLONE_NEWNS)) ||
1421 ((flags & OS::TGT_CLONE_NEWIPC) && (flags & OS::TGT_CLONE_SYSVSEM)) ||
1422 ((flags & OS::TGT_CLONE_NEWPID) && (flags & OS::TGT_CLONE_THREAD)) ||
1423 ((flags & OS::TGT_CLONE_VM) && !(newStack)))
1439 ProcessParams *pp =
new ProcessParams();
1440 pp->executable.assign(*(
new std::string(
p->progName())));
1441 pp->cmd.push_back(*(
new std::string(
p->progName())));
1442 pp->system =
p->system;
1443 pp->cwd.assign(
p->tgtCwd);
1444 pp->input.assign(
"stdin");
1445 pp->output.assign(
"stdout");
1446 pp->errout.assign(
"stderr");
1448 pp->euid =
p->euid();
1450 pp->egid =
p->egid();
1453 std::set<int>
const& pids =
p->system->PIDs;
1454 int temp_pid = *pids.begin();
1457 }
while (pids.find(temp_pid) != pids.end());
1459 fatal(
"temp_pid is too large: %d", temp_pid);
1462 pp->ppid = (flags & OS::TGT_CLONE_THREAD) ?
p->ppid() :
p->pid();
1463 pp->useArchPT =
p->useArchPT;
1464 pp->kvmInSE =
p->kvmInSE;
1475 if (flags & OS::TGT_CLONE_PARENT_SETTID) {
1476 BufferArg ptidBuf(ptidPtr,
sizeof(
long));
1477 long *ptid = (
long *)ptidBuf.
bufferPtr();
1482 if (flags & OS::TGT_CLONE_THREAD) {
1483 cp->pTable->shared =
true;
1484 cp->useForClone =
true;
1489 p->clone(tc, ctc,
cp, flags);
1491 if (flags & OS::TGT_CLONE_THREAD) {
1493 cp->sigchld =
p->sigchld;
1494 }
else if (flags & OS::TGT_SIGCHLD) {
1495 *
cp->sigchld =
true;
1498 if (flags & OS::TGT_CLONE_CHILD_SETTID) {
1499 BufferArg ctidBuf(ctidPtr,
sizeof(
long));
1500 long *ctid = (
long *)ctidBuf.
bufferPtr();
1505 if (flags & OS::TGT_CLONE_CHILD_CLEARTID)
1506 cp->childClearTID = (uint64_t)ctidPtr;
1510 OS::archClone(flags,
p,
cp, tc, ctc, newStack, tlsPtr);
1528 return cloneFunc<OS>(desc, tc, flags, newStack, ptidPtr, ctidPtr, tlsPtr);
1539 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1542 int sim_fd = ffdp->getSimFD();
1544 struct statfs hostBuf;
1545 int result = fstatfs(sim_fd, &hostBuf);
1550 copyOutStatfsBuf<OS>(tgt_stat, &hostBuf);
1559 int tgt_fd, uint64_t tiov_base,
size_t count)
1563 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1566 int sim_fd = ffdp->getSimFD();
1569 typename OS::tgt_iovec tiov[
count];
1570 struct iovec hiov[
count];
1571 for (
size_t i = 0;
i <
count; ++
i) {
1572 prox.
readBlob(tiov_base + (
i *
sizeof(
typename OS::tgt_iovec)),
1573 &tiov[
i],
sizeof(
typename OS::tgt_iovec));
1575 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1578 int result = readv(sim_fd, hiov,
count);
1579 int local_errno = errno;
1581 for (
size_t i = 0;
i <
count; ++
i) {
1584 hiov[
i].iov_base, hiov[
i].iov_len);
1586 delete [] (
char *)hiov[
i].iov_base;
1589 return (result == -1) ? -local_errno : result;
1596 int tgt_fd, uint64_t tiov_base,
size_t count)
1600 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1603 int sim_fd = hbfdp->getSimFD();
1606 struct iovec hiov[
count];
1607 for (
size_t i = 0;
i <
count; ++
i) {
1608 typename OS::tgt_iovec tiov;
1610 prox.
readBlob(tiov_base +
i*
sizeof(
typename OS::tgt_iovec),
1611 &tiov,
sizeof(
typename OS::tgt_iovec));
1613 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1618 int result = writev(sim_fd, hiov,
count);
1621 delete [] (
char *)hiov[
i].iov_base;
1623 return (result == -1) ? -errno : result;
1630 VPtr<> start,
typename OS::size_t length,
int prot,
1631 int tgt_flags,
int tgt_fd,
typename OS::off_t
offset)
1634 Addr page_bytes =
p->pTable->pageSize();
1636 if (start & (page_bytes - 1) ||
1637 offset & (page_bytes - 1) ||
1638 (tgt_flags & OS::TGT_MAP_PRIVATE &&
1639 tgt_flags & OS::TGT_MAP_SHARED) ||
1640 (!(tgt_flags & OS::TGT_MAP_PRIVATE) &&
1641 !(tgt_flags & OS::TGT_MAP_SHARED)) ||
1646 if ((
prot & PROT_WRITE) && (tgt_flags & OS::TGT_MAP_SHARED)) {
1667 warn_once(
"mmap: writing to shared mmap region is currently "
1668 "unsupported. The write succeeds on the target, but it "
1669 "will not be propagated to the host or shared mappings");
1672 length =
roundUp(length, page_bytes);
1675 if (!(tgt_flags & OS::TGT_MAP_ANONYMOUS)) {
1676 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1678 auto dfdp = std::dynamic_pointer_cast<DeviceFDEntry>(fdep);
1681 return emul_driver->
mmap(tc, start, length,
prot, tgt_flags,
1685 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
1688 sim_fd = ffdp->getSimFD();
1698 if (
p->interpImage.contains(tc->
pcState().instAddr())) {
1699 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1700 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
1702 ffdp->getFileName()));
1704 ffdp->getFileName());
1707 Addr offset = lib->buildImage().minAddr() + start;
1716 if (!(tgt_flags & OS::TGT_MAP_FIXED)) {
1724 if (!(start &&
p->memState->isUnmapped(start, length))) {
1728 start =
p->memState->extendMmap(length);
1733 start, start + length - 1);
1740 if (tgt_flags & OS::TGT_MAP_FIXED) {
1745 p->memState->unmapRegion(start, length);
1751 std::string region_name;
1752 if (tgt_flags & OS::TGT_MAP_ANONYMOUS) {
1753 region_name =
"anon";
1755 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1756 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
1757 region_name = ffdp->getFileName();
1764 p->memState->mapRegion(start, length, region_name, sim_fd,
offset);
1776 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1779 int sim_fd = ffdp->getSimFD();
1787 return (bytes_read == -1) ? -errno : bytes_read;
1797 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1800 int sim_fd = ffdp->getSimFD();
1805 int bytes_written = pwrite(sim_fd, bufArg.
bufferPtr(), nbytes,
offset);
1807 return (bytes_written == -1) ? -errno : bytes_written;
1814 VPtr<> start,
typename OS::size_t length,
int prot,
1815 int tgt_flags,
int tgt_fd,
typename OS::off_t
offset)
1818 return mmapFunc<OS>(desc, tc, start, length,
prot, tgt_flags,
1819 tgt_fd,
offset * page_size);
1830 case OS::TGT_RLIMIT_STACK:
1832 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
1833 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
1834 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
1837 case OS::TGT_RLIMIT_DATA:
1839 rlp->rlim_cur = rlp->rlim_max = 256 * 1024 * 1024;
1840 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
1841 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
1844 case OS::TGT_RLIMIT_NPROC:
1846 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
1847 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
1851 warn(
"getrlimit: unimplemented resource %d", resource);
1865 warn(
"prlimit: ignoring rlimits for nonzero pid");
1869 warn(
"prlimit: ignoring new rlimit");
1873 case OS::TGT_RLIMIT_STACK:
1875 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
1876 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
1877 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
1879 case OS::TGT_RLIMIT_DATA:
1881 rlp->rlim_cur = rlp->rlim_max = 256*1024*1024;
1882 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
1883 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
1886 warn(
"prlimit: unimplemented resource %d", resource);
1940 VPtr<
typename OS::timeval [2]> tp)
1948 struct timeval hostTimeval[2];
1949 for (
int i = 0;
i < 2; ++
i) {
1955 path = process->checkPathRedirect(path);
1957 int result = utimes(path.c_str(), hostTimeval);
1977 if (access(path.c_str(), F_OK) == -1)
1983 for (
int inc = 0; ;
inc++) {
1985 b.copyIn(mem_proxy);
1987 if (!*(
Addr*)
b.bufferPtr())
1990 vect.push_back(std::string());
1991 mem_proxy.tryReadString(vect[
inc], *(
Addr*)
b.bufferPtr());
2001 ProcessParams *pp =
new ProcessParams();
2002 pp->executable = path;
2003 read_in(pp->cmd, mem_proxy, argv_mem_loc);
2004 read_in(pp->env, mem_proxy, envp_mem_loc);
2006 pp->egid =
p->egid();
2007 pp->euid =
p->euid();
2009 pp->ppid =
p->ppid();
2011 pp->input.assign(
"cin");
2012 pp->output.assign(
"cout");
2013 pp->errout.assign(
"cerr");
2014 pp->cwd.assign(
p->tgtCwd);
2015 pp->system =
p->system;
2024 p->system->PIDs.erase(
p->pid());
2025 Process *new_p = pp->create();
2032 new_p->
fds =
p->fds;
2033 for (
int i = 0;
i < new_p->
fds->getSize();
i++) {
2034 std::shared_ptr<FDEntry> fdep = (*new_p->
fds)[
i];
2035 if (fdep && fdep->getCOE())
2036 new_p->
fds->closeFDEntry(
i);
2048 tc->
setNPC(pcState.instAddr());
2060 rup->ru_utime.tv_sec = 0;
2061 rup->ru_utime.tv_usec = 0;
2062 rup->ru_stime.tv_sec = 0;
2063 rup->ru_stime.tv_usec = 0;
2071 rup->ru_inblock = 0;
2072 rup->ru_oublock = 0;
2075 rup->ru_nsignals = 0;
2080 case OS::TGT_RUSAGE_SELF:
2086 case OS::TGT_RUSAGE_CHILDREN:
2093 warn(
"getrusage() only supports RUSAGE_SELF. Parameter %d ignored.",
2107 bufp->tms_utime = clocks;
2108 bufp->tms_stime = 0;
2109 bufp->tms_cutime = 0;
2110 bufp->tms_cstime = 0;
2124 typename OS::time_t sec, usec;
2129 typename OS::time_t
t = sec;
2132 p.writeBlob(taddr, &
t, (
int)
sizeof(
typename OS::time_t));
2158 for (
auto *tc: sys->
threads) {
2160 if (temp->
pid() == tid) {
2166 if (sig != 0 || sig != OS::TGT_SIGABRT)
2169 if (tgt_proc ==
nullptr)
2172 if (tgid != -1 && tgt_proc->
tgid() != tgid)
2175 if (sig == OS::TGT_SIGABRT)
2192 auto sfdp = std::make_shared<SocketFDEntry>(sim_fd,
domain,
type,
prot);
2193 int tgt_fd =
p->fds->allocFD(sfdp);
2212 auto sfdp1 = std::make_shared<SocketFDEntry>(fds[0],
domain,
type,
prot);
2213 fds[0] =
p->fds->allocFD(sfdp1);
2214 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1],
domain,
type,
prot);
2215 fds[1] =
p->fds->allocFD(sfdp2);
2239 FD_ZERO(&readfds_h);
2241 FD_ZERO(&writefds_h);
2243 FD_ZERO(&errorfds_h);
2255 std::map<int, int> trans_map;
2256 auto try_add_host_set = [&](
typename OS::fd_set *tgt_set_entry,
2257 fd_set *hst_set_entry,
2265 if (FD_ISSET(iter, (fd_set *)tgt_set_entry)) {
2271 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[iter]);
2274 auto sim_fd = hbfdp->getSimFD();
2281 trans_map[sim_fd] = iter;
2288 nfds_h = std::max(nfds_h - 1, sim_fd + 1);
2294 FD_SET(sim_fd, hst_set_entry);
2299 for (
int i = 0;
i < nfds;
i++) {
2301 bool ebadf = try_add_host_set(readfds, &readfds_h,
i);
2306 bool ebadf = try_add_host_set(writefds, &writefds_h,
i);
2311 bool ebadf = try_add_host_set(errorfds, &errorfds_h,
i);
2325 timeout->tv_sec = 0;
2326 timeout->tv_usec = 0;
2328 retval = select(nfds_h,
2329 readfds ? &readfds_h :
nullptr,
2330 writefds ? &writefds_h :
nullptr,
2331 errorfds ? &errorfds_h :
nullptr,
2332 (timeval *)(
typename OS::timeval *)timeout);
2341 struct timeval tv = { 0, 0 };
2343 retval = select(nfds_h,
2344 readfds ? &readfds_h :
nullptr,
2345 readfds ? &writefds_h :
nullptr,
2346 readfds ? &errorfds_h :
nullptr,
2356 if (sig.receiver ==
p)
2365 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)readfds));
2366 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)writefds));
2367 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)errorfds));
2374 for (
int i = 0;
i < nfds_h;
i++) {
2375 if (readfds && FD_ISSET(
i, &readfds_h))
2376 FD_SET(trans_map[
i], readfds);
2378 if (writefds && FD_ISSET(
i, &writefds_h))
2379 FD_SET(trans_map[
i], writefds);
2381 if (errorfds && FD_ISSET(
i, &errorfds_h))
2382 FD_SET(trans_map[
i], errorfds);
2391 int tgt_fd,
VPtr<> buf_ptr,
int nbytes)
2395 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
2398 int sim_fd = hbfdp->getSimFD();
2402 pfd.events = POLLIN | POLLPRI;
2403 if ((poll(&pfd, 1, 0) == 0)
2404 && !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK))
2408 int bytes_read = read(sim_fd, buf_arg.
bufferPtr(), nbytes);
2413 return (bytes_read == -1) ? -errno : bytes_read;
2419 int tgt_fd,
VPtr<> buf_ptr,
int nbytes)
2423 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
2426 int sim_fd = hbfdp->getSimFD();
2433 pfd.events = POLLOUT;
2441 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(hbfdp);
2442 if (ffdp && (ffdp->getFileName() !=
"/dev/random")) {
2443 if (!poll(&pfd, 1, 0) && !(ffdp->getFlags() & OS::TGT_O_NONBLOCK))
2447 int bytes_written = write(sim_fd, buf_arg.
bufferPtr(), nbytes);
2449 if (bytes_written != -1)
2452 return (bytes_written == -1) ? -errno : bytes_written;
2458 pid_t pid,
VPtr<> statPtr,
int options,
VPtr<> rusagePtr)
2463 DPRINTF_SYSCALL(Verbose,
"wait4: rusage pointer provided %lx, however "
2464 "functionality not supported. Ignoring rusage pointer.\n",
2478 if (iter->receiver ==
p) {
2480 if ((iter->sender->pgid() == -pid)
2481 && (iter->signalValue == OS::TGT_SIGCHLD))
2483 }
else if (pid == -1) {
2484 if (iter->signalValue == OS::TGT_SIGCHLD)
2486 }
else if (pid == 0) {
2487 if ((iter->sender->pgid() ==
p->pgid())
2488 && (iter->signalValue == OS::TGT_SIGCHLD))
2491 if ((iter->sender->pid() == pid)
2492 && (iter->signalValue == OS::TGT_SIGCHLD))
2502 const int EXITED = 0;
2503 BufferArg statusBuf(statPtr,
sizeof(
int));
2508 pid_t retval = iter->sender->pid();
2526 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
2529 int sim_fd = sfdp->getSimFD();
2539 pfd.events = POLLIN | POLLPRI;
2540 if ((poll(&pfd, 1, 0) == 0) && !(sfdp->getFlags() & OS::TGT_O_NONBLOCK))
2544 lenBufPtr =
new BufferArg(lenPtr,
sizeof(socklen_t));
2546 memcpy(&addrLen, (socklen_t *)lenBufPtr->
bufferPtr(),
2551 addrBufPtr =
new BufferArg(addrPtr,
sizeof(
struct sockaddr));
2553 memcpy(&
sa, (
struct sockaddr *)addrBufPtr->
bufferPtr(),
2554 sizeof(
struct sockaddr));
2557 host_fd = accept(sim_fd, &
sa, &addrLen);
2569 *(socklen_t *)lenBufPtr->
bufferPtr() = addrLen;
2574 auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain,
2575 sfdp->_type, sfdp->_protocol);
2576 return p->fds->allocFD(afdp);
2583 unsigned initval,
int in_flags)
2585 #if defined(__linux__)
2588 int sim_fd = eventfd(initval, in_flags);
2592 bool cloexec = in_flags & OS::TGT_O_CLOEXEC;
2594 int flags = cloexec ? OS::TGT_O_CLOEXEC : 0;
2595 flags |= (in_flags & OS::TGT_O_NONBLOCK) ? OS::TGT_O_NONBLOCK : 0;
2597 auto hbfdp = std::make_shared<HBFDEntry>(flags, sim_fd, cloexec);
2598 int tgt_fd =
p->fds->allocFD(hbfdp);
2606 #endif // __SIM_SYSCALL_EMUL_HH__
std::list< BasicSignal > signalList
#define fatal(...)
This implements a cprintf based fatal() function.
SyscallReturn writeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int nbytes)
void suspend(Addr addr, uint64_t tgid, ThreadContext *tc)
Inserts a futex into the map with one waiting TC.
SyscallReturn getpeernameFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> sockAddrPtr, VPtr<> addrlenPtr)
SyscallReturn dup2Func(SyscallDesc *desc, ThreadContext *tc, int old_tgt_fd, int new_tgt_fd)
Target dup2() handler.
SyscallReturn chdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
Target chdir() handler.
virtual int open(ThreadContext *tc, int mode, int flags)=0
Abstract method, invoked when the user program calls open() on the device driver.
SyscallReturn getrusageFunc(SyscallDesc *desc, ThreadContext *tc, int who, VPtr< typename OS::rusage > rup)
Target getrusage() function.
void setUseForClone(bool new_val)
SyscallReturn tgkillFunc(SyscallDesc *desc, ThreadContext *tc, int tgid, int tid, int sig)
SyscallReturn ioctlFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, unsigned req, VPtr<> addr)
Target ioctl() handler.
int wakeup(Addr addr, uint64_t tgid, int count)
Wakes up at most count waiting threads on a futex.
SyscallReturn execveFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> argv_mem_loc, VPtr<> envp_mem_loc)
SyscallReturn readvFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t tiov_base, size_t count)
Target readv() handler.
virtual void activate()=0
Set the status to Active.
SyscallReturn fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr< typename OS::tgt_statfs > tgt_stat)
Target fstatfs() handler.
SyscallReturn symlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> new_pathname)
Target symlink() handler.
void warnUnsupportedOS(std::string syscall_name)
SyscallReturn rmdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
SyscallReturn sendtoFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> bufrPtr, size_t bufrLen, int flags, VPtr<> addrPtr, socklen_t addrLen)
ByteOrder byteOrder(const ThreadContext *tc)
std::shared_ptr< FDArray > fds
SyscallReturn fstatat64Func(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, VPtr< typename OS::tgt_stat64 > tgt_stat)
Target fstatat64() handler.
void assignThreadContext(ContextID context_id)
SyscallReturn openatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_dirfd, VPtr<> pathname, int tgt_flags, int mode)
Target open() handler.
SyscallReturn accessFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
Target access() handler.
void suspend_bitset(Addr addr, uint64_t tgid, ThreadContext *tc, int bitmask)
SyscallReturn brkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> new_brk)
Target brk() handler: set brk address.
SyscallReturn stat64Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_stat64 > tgt_stat)
Target stat64() handler.
SyscallReturn getpgrpFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpgrpFunc() handler.
SyscallReturn ignoreFunc(SyscallDesc *desc, ThreadContext *tc)
Handler for unimplemented syscalls that we never intend to implement (signal handling,...
SyscallReturn gettimeofdayFunc(SyscallDesc *desc, ThreadContext *tc, VPtr< typename OS::timeval > tp, VPtr<> tz_ptr)
Target gettimeofday() handler.
SyscallReturn unlinkatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname)
Target unlinkat() handler.
SyscallReturn acceptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> addrPtr, VPtr<> lenPtr)
ObjectFile * createObjectFile(const std::string &fname, bool raw)
EmulationPageTable * pTable
SyscallReturn chmodFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
Target chmod() handler.
SyscallReturn faccessatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, int mode)
Target facessat() handler.
FutexMap class holds a map of all futexes used in the system.
SyscallReturn wait4Func(SyscallDesc *desc, ThreadContext *tc, pid_t pid, VPtr<> statPtr, int options, VPtr<> rusagePtr)
virtual Process * getProcessPtr()=0
SyscallReturn pwrite64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> bufPtr, int nbytes, int offset)
void copyOutStatBuf(TgtStatPtr tgt, HostStatPtr host, bool fakeTTY=false)
SyscallReturn pread64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> bufPtr, int nbytes, int offset)
SyscallReturn setpgidFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int pgid)
Target setpgid() handler.
SyscallReturn _llseekFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t offset_high, uint32_t offset_low, VPtr<> result_ptr, int whence)
Target _llseek() handler.
void copyOutStatfsBuf(TgtStatPtr tgt, HostStatPtr host)
SyscallReturn getppidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getppid() handler.
virtual int threadId() const =0
ThreadContext * findFree()
void inc(scfx_mant &mant)
SyscallReturn fallocateFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int mode, off_t offset, off_t len)
SyscallReturn socketFunc(SyscallDesc *desc, ThreadContext *tc, int domain, int type, int prot)
SyscallReturn pipeFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> tgt_addr)
Target pipe() handler.
SyscallReturn timesFunc(SyscallDesc *desc, ThreadContext *tc, VPtr< typename OS::tms > bufp)
Target times() function.
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
void revokeThreadContext(int context_id)
After delegating a thread context to a child process no longer should relate to the ThreadContext.
EmulatedDriver is an abstract base class for fake SE-mode device drivers.
SyscallReturn sendmsgFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> msgPtr, int flags)
SyscallReturn utimesFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::timeval[2]> tp)
Target utimes() handler.
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
virtual void clearArchRegs()=0
SyscallReturn mknodFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode, dev_t dev)
Target mknod() handler.
SyscallReturn unlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
Target unlink() handler.
void getElapsedTimeNano(T1 &sec, T2 &nsec)
Helper function to convert current elapsed time to seconds and nanoseconds.
SyscallReturn ftruncateFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, off_t length)
Target ftruncate() handler.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
SyscallReturn timeFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> taddr)
Target time() function.
SyscallReturn socketpairFunc(SyscallDesc *desc, ThreadContext *tc, int domain, int type, int prot, VPtr<> svPtr)
SyscallReturn exitGroupFunc(SyscallDesc *desc, ThreadContext *tc, int status)
Target exit_group() handler: terminate simulation. (exit all threads)
SyscallReturn setsockoptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int level, int optname, VPtr<> valPtr, socklen_t len)
std::string checkPathRedirect(const std::string &filename)
Redirect file path if it matches any keys initialized by system object.
SyscallReturn recvfromFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> bufrPtr, size_t bufrLen, int flags, VPtr<> addrPtr, VPtr<> addrlenPtr)
SyscallReturn lseekFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t offs, int whence)
Target lseek() handler.
SyscallReturn getegidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getegid() handler.
#define DPRINTF_SYSCALL(FLAGEXT, FMT,...)
This macro is intended to help with readability.
SyscallReturn exitFunc(SyscallDesc *desc, ThreadContext *tc, int status)
Target exit() handler: terminate current context.
T htog(T value, ByteOrder guest_byte_order)
SyscallReturn linkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> new_pathname)
Target link() handler.
SyscallReturn listenFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int backlog)
SyscallReturn readlinkatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, VPtr<> buf, size_t bufsiz)
Target readlinkat() handler.
SyscallReturn setTidAddressFunc(SyscallDesc *desc, ThreadContext *tc, uint64_t tidPtr)
Target set_tid_address() handler.
SyscallReturn getpidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpid() handler.
SyscallReturn openFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, int tgt_flags, int mode)
Target open() handler.
SyscallReturn mmap2Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> start, typename OS::size_t length, int prot, int tgt_flags, int tgt_fd, typename OS::off_t offset)
Target mmap2() handler.
SyscallReturn statfsFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_statfs > tgt_stat)
Target statfs() handler.
SyscallReturn selectFunc(SyscallDesc *desc, ThreadContext *tc, int nfds, VPtr< typename OS::fd_set > readfds, VPtr< typename OS::fd_set > writefds, VPtr< typename OS::fd_set > errorfds, VPtr< typename OS::timeval > timeout)
virtual int cpuId() const =0
SyscallReturn sysinfoFunc(SyscallDesc *desc, ThreadContext *tc, VPtr< typename OS::tgt_sysinfo > sysinfo)
Target sysinfo() handler.
virtual ContextID contextId() const =0
SyscallReturn clock_gettimeFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, VPtr< typename OS::timespec > tp)
Target clock_gettime() function.
SyscallReturn fchownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t owner, uint32_t group)
Target fchown() handler.
SyscallReturn cloneFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack, VPtr<> ptidPtr, VPtr<> ctidPtr, VPtr<> tlsPtr)
SyscallReturn getgidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getgid() handler.
SyscallReturn umaskFunc(SyscallDesc *desc, ThreadContext *tc)
Target umask() handler.
SyscallReturn ftruncate64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int64_t length)
Target ftruncate64() handler.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
SyscallReturn mremapFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> start, uint64_t old_length, uint64_t new_length, uint64_t flags, GuestABI::VarArgs< uint64_t > varargs)
Target mremap() handler.
virtual Addr mmap(ThreadContext *tc, Addr start, uint64_t length, int prot, int tgtFlags, int tgtFd, off_t offset)
Virtual method, invoked when the user program calls mmap() on the file descriptor returned by a previ...
This class represents the return value from an emulated system call, including any errno setting.
SyscallReturn connectFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int addrlen)
SyscallReturn eventfdFunc(SyscallDesc *desc, ThreadContext *tc, unsigned initval, int in_flags)
Target eventfd() function.
SyscallReturn clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, VPtr< typename OS::timespec > tp)
Target clock_getres() function.
bool copyIn(PortProxy &memproxy)
copy data into simulator space (read from target memory)
SyscallReturn munmapFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> start, size_t length)
Target munmap() handler.
SyscallReturn lstatFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_stat > tgt_stat)
Target lstat() handler.
void * bufferPtr()
Return a pointer to the internal simulator-space buffer.
SyscallReturn getrlimitFunc(SyscallDesc *desc, ThreadContext *tc, unsigned resource, VPtr< typename OS::rlimit > rlp)
Target getrlimit() handler.
virtual TheISA::PCState pcState() const =0
SyscallReturn recvmsgFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> msgPtr, int flags)
SyscallReturn lstat64Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_stat64 > tgt_stat)
Target lstat64() handler.
SyscallReturn pipePseudoFunc(SyscallDesc *desc, ThreadContext *tc)
Pseudo Funcs - These functions use a different return convension, returning a second value in a regis...
virtual PortProxy & getVirtProxy()=0
int requeue(Addr addr1, uint64_t tgid, int count, int count2, Addr addr2)
This operation wakes a given number (val) of waiters.
void copyOutStat64Buf(TgtStatPtr tgt, HostStatPtr host, bool fakeTTY=false)
SyscallReturn truncate64Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, int64_t length)
Target truncate64() handler.
This object is a proxy for a port or other object which implements the functional response protocol,...
SyscallReturn fcntlFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd, GuestABI::VarArgs< int > varargs)
Target fcntl() handler.
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 fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr< typename OS::tgt_stat > tgt_stat)
Target fstat() handler.
SyscallReturn getcpuFunc(SyscallDesc *desc, ThreadContext *tc, VPtr< uint32_t > cpu, VPtr< uint32_t > node, VPtr< uint32_t > tcache)
GenericISA::DelaySlotPCState< MachInst > PCState
bool startswith(const char *s, const char *prefix)
Return true if 's' starts with the prefix string 'prefix'.
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
SyscallReturn chownFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, uint32_t owner, uint32_t group)
Target chown() handler.
SyscallReturn ignoreWarnOnceFunc(SyscallDesc *desc, ThreadContext *tc)
Like above, but only prints a warning once per syscall desc it's used with.
int wakeup_bitset(Addr addr, uint64_t tgid, int bitmask)
SyscallReturn cloneBackwardsFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack, VPtr<> ptidPtr, VPtr<> tlsPtr, VPtr<> ctidPtr)
SyscallReturn getpagesizeFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpagesize() 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...
SyscallReturn futexFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> uaddr, int op, int val, int timeout, VPtr<> uaddr2, int val3)
Futex system call Implemented by Daniel Sanchez Used by printf's in multi-threaded apps.
SyscallReturn geteuidFunc(SyscallDesc *desc, ThreadContext *tc)
Target geteuid() handler.
SyscallReturn statFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_stat > tgt_stat)
Target stat() handler.
void getElapsedTimeMicro(T1 &sec, T2 &usec)
Helper function to convert current elapsed time to seconds and microseconds.
SyscallReturn writevFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t tiov_base, size_t count)
Target writev() handler.
SyscallReturn truncateFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, off_t length)
Target truncate() handler.
Tick curTick()
The universal simulation clock.
SyscallReturn gettidFunc(SyscallDesc *desc, ThreadContext *tc)
Target gettid() handler.
T gtoh(T value, ByteOrder guest_byte_order)
bool insert(const Symbol &symbol)
SyscallReturn getuidFunc(SyscallDesc *desc, ThreadContext *tc)
SyscallReturn fcntl64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd)
Target fcntl64() handler.
SyscallReturn renameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> oldpath, VPtr<> newpath)
Target rename() handler.
SyscallReturn fchmodFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t mode)
Target fchmod() handler.
static SyscallReturn retry()
Pseudo-constructor to create an instance with the retry flag set.
SyscallReturn shutdownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int how)
Target shutdown() handler.
SyscallReturn pipe2Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> tgt_addr, int flags)
Target pipe() handler.
SyscallReturn mmapFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> start, typename OS::size_t length, int prot, int tgt_flags, int tgt_fd, typename OS::off_t offset)
Target mmap() handler.
BufferArg represents an untyped buffer in target user space that is passed by reference to an (emulat...
SyscallReturn closeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
Target close() handler.
SyscallReturn fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr< typename OS::tgt_stat64 > tgt_stat)
Target fstat64() handler.
SyscallReturn mkdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
Target mkdir() handler.
SyscallReturn renameatFunc(SyscallDesc *desc, ThreadContext *tc, int olddirfd, VPtr<> oldpath, int newdirfd, VPtr<> newpath)
Target renameat() handler.
SyscallReturn getsockoptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int level, int optname, VPtr<> valPtr, VPtr<> lenPtr)
const unsigned seconds_since_epoch
Approximate seconds since the epoch (1/1/1970).
SyscallReturn gethostnameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, int name_len)
Target gethostname() handler.
SyscallReturn bindFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int addrlen)
SyscallReturn readlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> buf, size_t bufsiz)
Target readlink() handler.
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
bool tryReadString(std::string &str, Addr addr) const
Reads the string at guest address addr into the std::string str.
SyscallReturn getsocknameFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> addrPtr, VPtr<> lenPtr)
SyscallReturn getcwdFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, unsigned long size)
Target getcwd() handler.
SyscallReturn unimplementedFunc(SyscallDesc *desc, ThreadContext *tc)
Handler for unimplemented syscalls that we haven't thought about.
SyscallReturn readFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int nbytes)
This class provides the wrapper interface for the system call implementations which are defined in th...
SyscallReturn prlimitFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int resource, VPtr<> n, VPtr< typename OS::rlimit > rlp)
SyscallReturn pollFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> fdsPtr, int nfds, int tmout)
virtual void setProcessPtr(Process *p)=0
virtual System * getSystemPtr()=0
bool copyOut(PortProxy &memproxy)
copy data out of simulator space (write to target memory)
SyscallReturn dupFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
Target dup() handler.
Generated on Tue Mar 23 2021 19:41:28 for gem5 by doxygen 1.8.17