45 #ifndef __SIM_SYSCALL_EMUL_HH__ 46 #define __SIM_SYSCALL_EMUL_HH__ 48 #if (defined(__APPLE__) || defined(__OpenBSD__) || \ 49 defined(__FreeBSD__) || defined(__CYGWIN__) || \ 62 #if defined(__linux__) 63 #include <sys/eventfd.h> 64 #include <sys/statfs.h> 67 #include <sys/mount.h> 72 #include <sys/fcntl.h> 78 #include <sys/ioctl.h> 80 #include <sys/socket.h> 83 #include <sys/types.h> 92 #include "arch/utility.hh" 98 #include "config/the_isa.hh" 102 #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)) 166 int tgt_fd, uint64_t offs,
int whence);
170 int tgt_fd, uint64_t offset_high,
171 uint32_t offset_low,
Addr result_ptr,
int whence);
178 int tgt_fd,
int how);
182 Addr buf_ptr,
int name_len);
186 Addr buf_ptr,
unsigned long size);
190 Addr pathname,
Addr buf,
size_t bufsiz);
210 Addr pathname, mode_t
mode, dev_t dev);
232 int tgt_fd, off_t
length);
251 Addr pathname, uint32_t owner, uint32_t group);
262 int tgt_fd, uint32_t owner, uint32_t group);
270 int old_tgt_fd,
int new_tgt_fd);
283 bool pseudo_pipe,
bool is_pipe2=
false);
293 int tgt_fd,
Addr sockAddrPtr,
Addr addrlenPtr);
297 int tgt_fd,
Addr buf_ptr,
int addrlen);
301 int tgt_fd,
int backlog);
305 int tgt_fd,
Addr buf_ptr,
int addrlen);
307 #if defined(SYS_getdents) 310 int tgt_fd,
Addr buf_ptr,
unsigned count);
313 #if defined(SYS_getdents64) 316 int tgt_fd,
Addr buf_ptr,
unsigned count);
321 int tgt_fd,
Addr bufrPtr,
size_t bufrLen,
int flags,
322 Addr addrPtr, socklen_t addrLen);
326 int tgt_fd,
Addr bufrPtr,
size_t bufrLen,
327 int flags,
Addr addrPtr,
Addr addrlenPtr);
331 int tgt_fd,
Addr msgPtr,
int flags);
335 int tgt_fd,
Addr msgPtr,
int flags);
358 int tgt_fd,
int level,
int optname,
363 int tgt_fd,
int level,
int optname,
368 int tgt_fd,
Addr addrPtr,
Addr lenPtr);
376 Addr uaddr,
int op,
int val,
int timeout,
Addr uaddr2,
int val3)
386 op &= ~OS::TGT_FUTEX_PRIVATE_FLAG;
387 op &= ~OS::TGT_FUTEX_CLOCK_REALTIME_FLAG;
391 if (OS::TGT_FUTEX_WAIT == op || OS::TGT_FUTEX_WAIT_BITSET == op) {
403 return -OS::TGT_EWOULDBLOCK;
405 if (OS::TGT_FUTEX_WAIT == op) {
406 futex_map.
suspend(uaddr, process->tgid(), tc);
412 }
else if (OS::TGT_FUTEX_WAKE == op) {
413 return futex_map.
wakeup(uaddr, process->tgid(),
val);
414 }
else if (OS::TGT_FUTEX_WAKE_BITSET == op) {
415 return futex_map.
wakeup_bitset(uaddr, process->tgid(), val3);
416 }
else if (OS::TGT_FUTEX_REQUEUE == op ||
417 OS::TGT_FUTEX_CMP_REQUEUE == op) {
427 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
428 return -OS::TGT_EWOULDBLOCK;
429 return futex_map.
requeue(uaddr, process->tgid(),
val, timeout, uaddr2);
430 }
else if (OS::TGT_FUTEX_WAKE_OP == op) {
458 int wake_cmparg = val3 & 0xfff;
459 int wake_oparg = (val3 & 0xfff000) >> 12;
460 int wake_cmp = (val3 & 0xf000000) >> 24;
461 int wake_op = (val3 & 0xf0000000) >> 28;
462 if ((wake_op & OS::TGT_FUTEX_OP_ARG_SHIFT) >> 3 == 1)
463 wake_oparg = (1 << wake_oparg);
464 wake_op &= ~OS::TGT_FUTEX_OP_ARG_SHIFT;
466 if (wake_op == OS::TGT_FUTEX_OP_SET)
468 else if (wake_op == OS::TGT_FUTEX_OP_ADD)
469 newval += wake_oparg;
470 else if (wake_op == OS::TGT_FUTEX_OP_OR)
471 newval |= wake_oparg;
472 else if (wake_op == OS::TGT_FUTEX_OP_ANDN)
473 newval &= ~wake_oparg;
474 else if (wake_op == OS::TGT_FUTEX_OP_XOR)
475 newval ^= wake_oparg;
480 int woken1 = futex_map.
wakeup(uaddr, process->tgid(),
val);
483 bool is_wake2 =
false;
484 if (wake_cmp == OS::TGT_FUTEX_OP_CMP_EQ)
485 is_wake2 = oldval == wake_cmparg;
486 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_NE)
487 is_wake2 = oldval != wake_cmparg;
488 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LT)
489 is_wake2 = oldval < wake_cmparg;
490 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LE)
491 is_wake2 = oldval <= wake_cmparg;
492 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GT)
493 is_wake2 = oldval > wake_cmparg;
494 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GE)
495 is_wake2 = oldval >= wake_cmparg;
498 woken2 = futex_map.
wakeup(uaddr2, process->tgid(), timeout);
500 return woken1 + woken2;
502 warn(
"futex: op %d not implemented; ignoring.", op);
533 template <
class T1,
class T2>
544 template <
class T1,
class T2>
573 template <
typename target_stat,
typename host_stat>
581 tgt->st_dev = host->st_dev;
582 tgt->st_dev =
htog(tgt->st_dev, bo);
583 tgt->st_ino = host->st_ino;
584 tgt->st_ino =
htog(tgt->st_ino, bo);
585 tgt->st_mode = host->st_mode;
588 tgt->st_mode &= ~S_IFMT;
589 tgt->st_mode |= S_IFCHR;
591 tgt->st_mode =
htog(tgt->st_mode, bo);
592 tgt->st_nlink = host->st_nlink;
593 tgt->st_nlink =
htog(tgt->st_nlink, bo);
594 tgt->st_uid = host->st_uid;
595 tgt->st_uid =
htog(tgt->st_uid, bo);
596 tgt->st_gid = host->st_gid;
597 tgt->st_gid =
htog(tgt->st_gid, bo);
599 tgt->st_rdev = 0x880d;
601 tgt->st_rdev = host->st_rdev;
602 tgt->st_rdev =
htog(tgt->st_rdev, bo);
603 tgt->st_size = host->st_size;
604 tgt->st_size =
htog(tgt->st_size, bo);
605 tgt->st_atimeX = host->st_atime;
606 tgt->st_atimeX =
htog(tgt->st_atimeX, bo);
607 tgt->st_mtimeX = host->st_mtime;
608 tgt->st_mtimeX =
htog(tgt->st_mtimeX, bo);
609 tgt->st_ctimeX = host->st_ctime;
610 tgt->st_ctimeX =
htog(tgt->st_ctimeX, bo);
613 tgt->st_blksize = 0x2000;
614 tgt->st_blksize =
htog(tgt->st_blksize, bo);
615 tgt->st_blocks = host->st_blocks;
616 tgt->st_blocks =
htog(tgt->st_blocks, bo);
621 template <
typename target_stat,
typename host_stat64>
626 convertStatBuf<target_stat, host_stat64>(tgt, host,
bo, fakeTTY);
627 #if defined(STAT_HAVE_NSEC) 628 tgt->st_atime_nsec = host->st_atime_nsec;
629 tgt->st_atime_nsec =
htog(tgt->st_atime_nsec, bo);
630 tgt->st_mtime_nsec = host->st_mtime_nsec;
631 tgt->st_mtime_nsec =
htog(tgt->st_mtime_nsec, bo);
632 tgt->st_ctime_nsec = host->st_ctime_nsec;
633 tgt->st_ctime_nsec =
htog(tgt->st_ctime_nsec, bo);
635 tgt->st_atime_nsec = 0;
636 tgt->st_mtime_nsec = 0;
637 tgt->st_ctime_nsec = 0;
645 hst_stat *host,
bool fakeTTY =
false)
648 tgt_stat_buf tgt(addr);
649 convertStatBuf<tgt_stat_buf, hst_stat>(tgt, host,
OS::byteOrder, fakeTTY);
659 tgt_stat_buf tgt(addr);
660 convertStat64Buf<tgt_stat_buf, hst_stat64>(
674 tgt->f_type =
htog(host->f_type, bo);
675 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 676 tgt->f_bsize =
htog(host->f_iosize, bo);
678 tgt->f_bsize =
htog(host->f_bsize, bo);
680 tgt->f_blocks =
htog(host->f_blocks, bo);
681 tgt->f_bfree =
htog(host->f_bfree, bo);
682 tgt->f_bavail =
htog(host->f_bavail, bo);
683 tgt->f_files =
htog(host->f_files, bo);
684 tgt->f_ffree =
htog(host->f_ffree, bo);
685 memcpy(&tgt->f_fsid, &host->f_fsid,
sizeof(host->f_fsid));
686 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 687 tgt->f_namelen =
htog(host->f_namemax, bo);
688 tgt->f_frsize =
htog(host->f_bsize, bo);
689 #elif defined(__APPLE__) 693 tgt->f_namelen =
htog(host->f_namelen, bo);
694 tgt->f_frsize =
htog(host->f_frsize, bo);
696 #if defined(__linux__) 697 memcpy(&tgt->f_spare, &host->f_spare,
sizeof(host->f_spare));
703 memset(&tgt->f_spare, 0,
sizeof(tgt->f_spare));
720 int tgt_fd =
p->getSyscallArg(tc, index);
721 unsigned req =
p->getSyscallArg(tc, index);
725 if (OS::isTtyReq(req))
728 auto dfdp = std::dynamic_pointer_cast<
DeviceFDEntry>((*
p->fds)[tgt_fd]);
732 return emul_driver->
ioctl(tc, req);
735 auto sfdp = std::dynamic_pointer_cast<
SocketFDEntry>((*
p->fds)[tgt_fd]);
741 Addr conf_addr =
p->getSyscallArg(tc, index);
742 BufferArg conf_arg(conf_addr,
sizeof(ifconf));
745 ifconf *conf = (ifconf*)conf_arg.
bufferPtr();
746 Addr ifc_buf_addr = (
Addr)conf->ifc_buf;
747 BufferArg ifc_buf_arg(ifc_buf_addr, conf->ifc_len);
750 conf->ifc_buf = (
char*)ifc_buf_arg.bufferPtr();
752 status = ioctl(sfdp->getSimFD(), req, conf_arg.
bufferPtr());
754 conf->ifc_buf = (
char*)ifc_buf_addr;
762 #if defined(__linux__) 767 #if defined(__linux__) 771 Addr req_addr =
p->getSyscallArg(tc, index);
772 BufferArg req_arg(req_addr,
sizeof(ifreq));
775 status = ioctl(sfdp->getSimFD(), req, req_arg.
bufferPtr());
787 warn(
"Unsupported ioctl call (return ENOTTY): ioctl(%d, 0x%x, ...) @ \n",
796 int tgt_dirfd,
Addr pathname,
int tgt_flags,
int mode)
809 int host_flags = O_BINARY;
817 for (
int i = 0;
i < OS::NUM_OPEN_FLAGS;
i++) {
818 if (tgt_flags & OS::openFlagTable[
i].tgtFlag) {
819 tgt_flags &= ~OS::openFlagTable[
i].tgtFlag;
820 host_flags |= OS::openFlagTable[
i].hostFlag;
824 warn(
"%s: cannot decode flags %#x", desc->
name(), tgt_flags);
827 host_flags |= O_BINARY;
842 std::string redir_path = path;
843 std::string abs_path = path;
844 if (tgt_dirfd == OS::TGT_AT_FDCWD) {
845 abs_path =
p->absolutePath(path,
true);
846 redir_path =
p->checkPathRedirect(path);
848 std::shared_ptr<FDEntry> fdep = ((*
p->fds)[tgt_dirfd]);
849 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(fdep);
853 redir_path =
p->checkPathRedirect(abs_path);
863 std::string filename = abs_path.substr(strlen(
"/dev/"));
867 "driver open with path[%s]\n",
868 desc->
name(), abs_path.c_str());
869 return drv->
open(tc, mode, host_flags);
902 std::string used_path;
904 {
"/proc/meminfo/",
"/system/",
"/platform/",
"/etc/passwd" };
905 for (
auto entry : special_paths) {
907 sim_fd = OS::openSpecialFile(abs_path,
p, tc);
908 used_path = abs_path;
912 sim_fd = open(redir_path.c_str(), host_flags,
mode);
913 used_path = redir_path;
918 "(inferred from:%s)\n", desc->
name(),
919 used_path.c_str(), path.c_str());
931 auto ffdp = std::make_shared<FileFDEntry>(sim_fd, host_flags, path, 0);
932 int tgt_fd =
p->fds->allocFD(ffdp);
934 "(inferred from:%s)\n", desc->
name(),
935 sim_fd, tgt_fd, used_path.c_str(), path.c_str());
943 Addr pathname,
int tgt_flags,
int mode)
945 return openatFunc<OS>(desc, callnum, tc, OS::TGT_AT_FDCWD,
946 pathname, tgt_flags,
mode);
953 int dirfd,
Addr pathname)
955 if (dirfd != OS::TGT_AT_FDCWD)
956 warn(
"unlinkat: first argument not AT_FDCWD; unlikely to work");
958 return unlinkFunc(desc, callnum, tc, pathname);
967 if (dirfd != OS::TGT_AT_FDCWD)
968 warn(
"faccessat: first argument not AT_FDCWD; unlikely to work");
969 return accessFunc(desc, callnum, tc, pathname, mode);
976 int dirfd,
Addr pathname,
Addr buf,
size_t bufsiz)
978 if (dirfd != OS::TGT_AT_FDCWD)
979 warn(
"openat: first argument not AT_FDCWD; unlikely to work");
980 return readlinkFunc(desc, callnum, tc, pathname, buf, bufsiz);
987 int olddirfd,
Addr oldpath,
int newdirfd,
Addr newpath)
989 if (olddirfd != OS::TGT_AT_FDCWD)
990 warn(
"renameat: first argument not AT_FDCWD; unlikely to work");
992 if (newdirfd != OS::TGT_AT_FDCWD)
993 warn(
"renameat: third argument not AT_FDCWD; unlikely to work");
995 return renameFunc(desc, callnum, tc, oldpath, newpath);
1008 sysinfo->totalram = process->system->memSize();
1009 sysinfo->mem_unit = 1;
1028 mode_t hostMode = 0;
1034 path = process->checkPathRedirect(path);
1037 int result = chmod(path.c_str(), hostMode);
1047 Addr fdsPtr,
int nfds,
int tmout)
1051 BufferArg fdsBuf(fdsPtr,
sizeof(
struct pollfd) * nfds);
1060 int temp_tgt_fds[nfds];
1063 auto tgt_fd = temp_tgt_fds[
index];
1064 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
1067 auto host_fd = hbfdp->getSimFD();
1079 status = poll((
struct pollfd *)fdsBuf.
bufferPtr(), nfds, 0);
1089 if (it->receiver ==
p)
1094 status = poll((
struct pollfd *)fdsBuf.
bufferPtr(), nfds, 0);
1104 auto tgt_fd = temp_tgt_fds[
index];
1121 int tgt_fd, uint32_t
mode)
1125 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1128 int sim_fd = ffdp->getSimFD();
1130 mode_t hostMode =
mode;
1132 int result = fchmod(sim_fd, hostMode);
1134 return (result < 0) ? -errno : 0;
1145 uint64_t old_length = process->getSyscallArg(tc, index);
1146 uint64_t new_length = process->getSyscallArg(tc, index);
1147 uint64_t flags = process->getSyscallArg(tc, index);
1148 uint64_t provided_address = 0;
1149 bool use_provided_address = flags & OS::TGT_MREMAP_FIXED;
1151 if (use_provided_address)
1152 provided_address = process->getSyscallArg(tc, index);
1156 warn(
"mremap failing: arguments not page aligned");
1162 if (new_length > old_length) {
1163 std::shared_ptr<MemState> mem_state = process->memState;
1164 Addr mmap_end = mem_state->getMmapEnd();
1166 if ((start + old_length) == mmap_end &&
1167 (!use_provided_address || provided_address == start)) {
1170 uint64_t diff = new_length - old_length;
1171 process->allocateMem(mmap_end, diff);
1172 mem_state->setMmapEnd(mmap_end + diff);
1175 if (!use_provided_address && !(flags & OS::TGT_MREMAP_MAYMOVE)) {
1176 warn(
"can't remap here and MREMAP_MAYMOVE flag not set\n");
1179 uint64_t new_start = provided_address;
1180 if (!use_provided_address) {
1181 new_start = process->mmapGrowsDown() ?
1182 mmap_end - new_length : mmap_end;
1183 mmap_end = process->mmapGrowsDown() ?
1184 new_start : mmap_end + new_length;
1185 mem_state->setMmapEnd(mmap_end);
1188 process->pTable->remap(start, old_length, new_start);
1189 warn(
"mremapping to new vaddr %08p-%08p, adding %d\n",
1190 new_start, new_start + new_length,
1191 new_length - old_length);
1193 process->allocateMem(new_start + old_length,
1194 new_length - old_length,
1195 use_provided_address );
1196 if (use_provided_address &&
1197 ((new_start + new_length > mem_state->getMmapEnd() &&
1198 !process->mmapGrowsDown()) ||
1199 (new_start < mem_state->getMmapEnd() &&
1200 process->mmapGrowsDown()))) {
1203 warn(
"mmap region limit exceeded with MREMAP_FIXED\n");
1205 warn(
"returning %08p as start\n", new_start);
1210 if (use_provided_address && provided_address != start)
1211 process->pTable->remap(start, new_length, provided_address);
1212 process->pTable->unmap(start + new_length, old_length - new_length);
1213 return use_provided_address ? provided_address : start;
1232 struct stat hostBuf;
1233 int result = stat(path.c_str(), &hostBuf);
1238 copyOutStatBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1260 struct stat hostBuf;
1261 int result = stat(path.c_str(), &hostBuf);
1263 struct stat64 hostBuf;
1264 int result = stat64(path.c_str(), &hostBuf);
1270 copyOutStat64Buf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1280 int dirfd,
Addr pathname,
Addr bufPtr)
1283 if (dirfd != OS::TGT_AT_FDCWD)
1284 warn(
"fstatat64: first argument not AT_FDCWD; unlikely to work");
1291 path = process->checkPathRedirect(path);
1294 struct stat hostBuf;
1295 int result = stat(path.c_str(), &hostBuf);
1297 struct stat64 hostBuf;
1298 int result = stat64(path.c_str(), &hostBuf);
1304 copyOutStat64Buf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1314 int tgt_fd,
Addr bufPtr)
1318 auto ffdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
1321 int sim_fd = ffdp->getSimFD();
1324 struct stat hostBuf;
1325 int result = fstat(sim_fd, &hostBuf);
1327 struct stat64 hostBuf;
1328 int result = fstat64(sim_fd, &hostBuf);
1334 copyOutStat64Buf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
1355 struct stat hostBuf;
1356 int result = lstat(path.c_str(), &hostBuf);
1361 copyOutStatBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1382 struct stat hostBuf;
1383 int result = lstat(path.c_str(), &hostBuf);
1385 struct stat64 hostBuf;
1386 int result = lstat64(path.c_str(), &hostBuf);
1392 copyOutStat64Buf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1401 int tgt_fd,
Addr bufPtr)
1407 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1410 int sim_fd = ffdp->getSimFD();
1412 struct stat hostBuf;
1413 int result = fstat(sim_fd, &hostBuf);
1418 copyOutStatBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
1429 #if defined(__linux__) 1439 struct statfs hostBuf;
1440 int result = statfs(path.c_str(), &hostBuf);
1445 copyOutStatfsBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1460 RegVal flags =
p->getSyscallArg(tc, index);
1461 RegVal newStack =
p->getSyscallArg(tc, index);
1462 Addr ptidPtr =
p->getSyscallArg(tc, index);
1464 #if THE_ISA == RISCV_ISA or THE_ISA == ARM_ISA 1470 Addr tlsPtr =
p->getSyscallArg(tc, index);
1471 Addr ctidPtr =
p->getSyscallArg(tc, index);
1473 Addr ctidPtr =
p->getSyscallArg(tc, index);
1474 Addr tlsPtr =
p->getSyscallArg(tc, index);
1477 if (((flags & OS::TGT_CLONE_SIGHAND)&& !(flags & OS::TGT_CLONE_VM)) ||
1478 ((flags & OS::TGT_CLONE_THREAD) && !(flags & OS::TGT_CLONE_SIGHAND)) ||
1479 ((flags & OS::TGT_CLONE_FS) && (flags & OS::TGT_CLONE_NEWNS)) ||
1480 ((flags & OS::TGT_CLONE_NEWIPC) && (flags & OS::TGT_CLONE_SYSVSEM)) ||
1481 ((flags & OS::TGT_CLONE_NEWPID) && (flags & OS::TGT_CLONE_THREAD)) ||
1482 ((flags & OS::TGT_CLONE_VM) && !(newStack)))
1498 ProcessParams *pp =
new ProcessParams();
1499 pp->executable.assign(*(
new std::string(
p->progName())));
1500 pp->cmd.push_back(*(
new std::string(
p->progName())));
1501 pp->system =
p->system;
1502 pp->cwd.assign(
p->tgtCwd);
1503 pp->input.assign(
"stdin");
1504 pp->output.assign(
"stdout");
1505 pp->errout.assign(
"stderr");
1507 pp->euid =
p->euid();
1509 pp->egid =
p->egid();
1512 std::set<int>
const& pids =
p->system->PIDs;
1513 int temp_pid = *pids.begin();
1516 }
while (pids.find(temp_pid) != pids.end());
1518 fatal(
"temp_pid is too large: %d", temp_pid);
1521 pp->ppid = (flags & OS::TGT_CLONE_THREAD) ?
p->ppid() :
p->pid();
1522 pp->useArchPT =
p->useArchPT;
1523 pp->kvmInSE =
p->kvmInSE;
1534 if (flags & OS::TGT_CLONE_PARENT_SETTID) {
1535 BufferArg ptidBuf(ptidPtr,
sizeof(
long));
1536 long *ptid = (
long *)ptidBuf.
bufferPtr();
1541 if (flags & OS::TGT_CLONE_THREAD) {
1546 p->clone(tc, ctc, cp, flags);
1548 if (flags & OS::TGT_CLONE_THREAD) {
1551 }
else if (flags & OS::TGT_SIGCHLD) {
1555 if (flags & OS::TGT_CLONE_CHILD_SETTID) {
1556 BufferArg ctidBuf(ctidPtr,
sizeof(
long));
1557 long *ctid = (
long *)ctidBuf.
bufferPtr();
1562 if (flags & OS::TGT_CLONE_CHILD_CLEARTID)
1567 OS::archClone(flags,
p, cp, tc, ctc, newStack, tlsPtr);
1571 #if THE_ISA == ALPHA_ISA 1573 #elif THE_ISA == SPARC_ISA 1579 #if THE_ISA == X86_ISA 1582 panic(
"KVM CPU model is not supported for this ISA");
1598 int tgt_fd,
Addr bufPtr)
1602 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1605 int sim_fd = ffdp->getSimFD();
1607 struct statfs hostBuf;
1608 int result = fstatfs(sim_fd, &hostBuf);
1613 copyOutStatfsBuf<OS>(tc->
getVirtProxy(), bufPtr, &hostBuf);
1622 int tgt_fd, uint64_t tiov_base,
size_t count)
1626 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1629 int sim_fd = ffdp->getSimFD();
1632 typename OS::tgt_iovec tiov[
count];
1633 struct iovec hiov[count];
1634 for (
size_t i = 0;
i <
count; ++
i) {
1635 prox.
readBlob(tiov_base + (
i *
sizeof(
typename OS::tgt_iovec)),
1636 &tiov[
i],
sizeof(
typename OS::tgt_iovec));
1638 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1641 int result = readv(sim_fd, hiov, count);
1642 int local_errno = errno;
1644 for (
size_t i = 0;
i <
count; ++
i) {
1647 hiov[
i].iov_base, hiov[
i].iov_len);
1649 delete [] (
char *)hiov[
i].iov_base;
1652 return (result == -1) ? -local_errno : result;
1659 int tgt_fd, uint64_t tiov_base,
size_t count)
1663 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
1666 int sim_fd = hbfdp->getSimFD();
1669 struct iovec hiov[count];
1670 for (
size_t i = 0;
i <
count; ++
i) {
1671 typename OS::tgt_iovec tiov;
1673 prox.
readBlob(tiov_base +
i*
sizeof(
typename OS::tgt_iovec),
1674 &tiov,
sizeof(
typename OS::tgt_iovec));
1676 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1681 int result = writev(sim_fd, hiov, count);
1684 delete [] (
char *)hiov[
i].iov_base;
1686 return (result == -1) ? -errno : result;
1700 (tgt_flags & OS::TGT_MAP_PRIVATE &&
1701 tgt_flags & OS::TGT_MAP_SHARED) ||
1702 (!(tgt_flags & OS::TGT_MAP_PRIVATE) &&
1703 !(tgt_flags & OS::TGT_MAP_SHARED)) ||
1708 if ((prot & PROT_WRITE) && (tgt_flags & OS::TGT_MAP_SHARED)) {
1729 warn(
"mmap: writing to shared mmap region is currently " 1730 "unsupported. The write succeeds on the target, but it " 1731 "will not be propagated to the host or shared mappings");
1737 uint8_t *pmap =
nullptr;
1738 if (!(tgt_flags & OS::TGT_MAP_ANONYMOUS)) {
1739 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1744 return emul_driver->
mmap(tc, start, length, prot, tgt_flags,
1748 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(fdep);
1753 pmap = (decltype(pmap))mmap(
nullptr, length, PROT_READ, MAP_PRIVATE,
1756 if (pmap == (decltype(pmap))-1) {
1757 warn(
"mmap: failed to map file into host address space");
1764 if (!(tgt_flags & OS::TGT_MAP_FIXED)) {
1765 std::shared_ptr<MemState> mem_state =
p->memState;
1766 Addr mmap_end = mem_state->getMmapEnd();
1768 start =
p->mmapGrowsDown() ? mmap_end -
length : mmap_end;
1769 mmap_end =
p->mmapGrowsDown() ? start : mmap_end +
length;
1771 mem_state->setMmapEnd(mmap_end);
1775 start, start + length - 1);
1780 int clobber = tgt_flags & OS::TGT_MAP_FIXED;
1782 for (
auto tc :
p->system->threadContexts) {
1793 p->allocateMem(start, length, clobber);
1797 if (tgt_flags & OS::TGT_MAP_ANONYMOUS) {
1812 struct stat file_stat;
1813 if (fstat(sim_fd, &file_stat) > 0)
1814 fatal(
"mmap: cannot stat file");
1820 uint64_t size = std::min((uint64_t)file_stat.st_size - offset,
1825 munmap(pmap, length);
1833 if (
p->interpImage.contains(tc->
pcState().instAddr())) {
1834 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1835 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(fdep);
1838 process->checkPathRedirect(
1839 ffdp->getFileName()));
1858 int tgt_fd,
Addr bufPtr,
int nbytes,
int offset)
1862 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>((*
p->fds)[tgt_fd]);
1865 int sim_fd = ffdp->getSimFD();
1870 int bytes_written = pwrite(sim_fd, bufArg.
bufferPtr(), nbytes,
offset);
1872 return (bytes_written == -1) ? -errno : bytes_written;
1882 return mmapFunc<OS>(desc, num, tc, start,
length,
prot, tgt_flags,
1883 tgt_fd, offset * tc->getSystemPtr()->getPageBytes());
1890 unsigned resource,
Addr rlim)
1896 case OS::TGT_RLIMIT_STACK:
1898 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
1899 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1900 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1903 case OS::TGT_RLIMIT_DATA:
1905 rlp->rlim_cur = rlp->rlim_max = 256 * 1024 * 1024;
1906 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1907 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1910 case OS::TGT_RLIMIT_NPROC:
1912 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1913 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1917 warn(
"getrlimit: unimplemented resource %d", resource);
1932 warn(
"prlimit: ignoring rlimits for nonzero pid");
1936 warn(
"prlimit: ignoring new rlimit");
1941 case OS::TGT_RLIMIT_STACK:
1943 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
1944 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1945 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1947 case OS::TGT_RLIMIT_DATA:
1949 rlp->rlim_cur = rlp->rlim_max = 256*1024*1024;
1950 rlp->rlim_cur =
htog(rlp->rlim_cur, bo);
1951 rlp->rlim_max =
htog(rlp->rlim_max, bo);
1954 warn(
"prlimit: unimplemented resource %d", resource);
1967 int clk_id,
Addr tp_ptr)
1985 int clk_id,
Addr tp_ptr)
2032 struct timeval hostTimeval[2];
2033 for (
int i = 0;
i < 2; ++
i) {
2039 path = process->checkPathRedirect(path);
2041 int result = utimes(path.c_str(), hostTimeval);
2061 if (access(path.c_str(), F_OK) == -1)
2067 for (
int inc = 0; ;
inc++) {
2074 vect.push_back(std::string());
2085 ProcessParams *pp =
new ProcessParams();
2086 pp->executable = path;
2087 read_in(pp->cmd, mem_proxy, argv_mem_loc);
2088 read_in(pp->env, mem_proxy, envp_mem_loc);
2090 pp->egid =
p->egid();
2091 pp->euid =
p->euid();
2093 pp->ppid =
p->ppid();
2095 pp->input.assign(
"cin");
2096 pp->output.assign(
"cout");
2097 pp->errout.assign(
"cerr");
2098 pp->cwd.assign(
p->tgtCwd);
2099 pp->system =
p->system;
2108 p->system->PIDs.erase(
p->pid());
2109 Process *new_p = pp->create();
2116 new_p->
fds =
p->fds;
2117 for (
int i = 0;
i < new_p->
fds->getSize();
i++) {
2118 std::shared_ptr<FDEntry> fdep = (*new_p->
fds)[
i];
2119 if (fdep && fdep->getCOE())
2120 new_p->
fds->closeFDEntry(
i);
2132 tc->
setNPC(pcState.instAddr());
2145 rup->ru_utime.tv_sec = 0;
2146 rup->ru_utime.tv_usec = 0;
2147 rup->ru_stime.tv_sec = 0;
2148 rup->ru_stime.tv_usec = 0;
2156 rup->ru_inblock = 0;
2157 rup->ru_oublock = 0;
2160 rup->ru_nsignals = 0;
2165 case OS::TGT_RUSAGE_SELF:
2171 case OS::TGT_RUSAGE_CHILDREN:
2178 warn(
"getrusage() only supports RUSAGE_SELF. Parameter %d ignored.",
2196 bufp->tms_utime = clocks;
2197 bufp->tms_stime = 0;
2198 bufp->tms_cutime = 0;
2199 bufp->tms_cstime = 0;
2216 typename OS::time_t sec, usec;
2221 typename OS::time_t
t = sec;
2224 p.
writeBlob(taddr, &t, (
int)
sizeof(
typename OS::time_t));
2232 int tgid,
int tid,
int sig)
2253 if (temp->
pid() == tid) {
2259 if (sig != 0 || sig != OS::TGT_SIGABRT)
2262 if (tgt_proc ==
nullptr)
2265 if (tgid != -1 && tgt_proc->
tgid() != tgid)
2268 if (sig == OS::TGT_SIGABRT)
2281 int sim_fd = socket(domain, type, prot);
2285 auto sfdp = std::make_shared<SocketFDEntry>(sim_fd,
domain,
type,
prot);
2286 int tgt_fd =
p->fds->allocFD(sfdp);
2299 int status = socketpair(domain, type, prot, (
int *)svBuf.
bufferPtr());
2305 auto sfdp1 = std::make_shared<SocketFDEntry>(fds[0],
domain,
type,
prot);
2306 fds[0] =
p->fds->allocFD(sfdp1);
2307 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1],
domain,
type,
prot);
2308 fds[1] =
p->fds->allocFD(sfdp2);
2317 int nfds_t,
Addr fds_read_ptr,
Addr fds_writ_ptr,
2318 Addr fds_excp_ptr,
Addr time_val_ptr)
2361 std::map<int, int> trans_map;
2362 auto try_add_host_set = [&](fd_set *tgt_set_entry,
2363 fd_set *hst_set_entry,
2371 if (FD_ISSET(iter, tgt_set_entry)) {
2377 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[iter]);
2380 auto sim_fd = hbfdp->getSimFD();
2387 trans_map[sim_fd] = iter;
2394 nfds_h = std::max(nfds_h - 1, sim_fd + 1);
2400 FD_SET(sim_fd, hst_set_entry);
2405 for (
int i = 0;
i < nfds_t;
i++) {
2407 bool ebadf = try_add_host_set((fd_set*)&*rd_t, &rd_h,
i);
2408 if (ebadf)
return -EBADF;
2411 bool ebadf = try_add_host_set((fd_set*)&*wr_t, &wr_h,
i);
2412 if (ebadf)
return -EBADF;
2415 bool ebadf = try_add_host_set((fd_set*)&*ex_t, &ex_h,
i);
2416 if (ebadf)
return -EBADF;
2431 retval = select(nfds_h,
2432 fds_read_ptr ? &rd_h :
nullptr,
2433 fds_writ_ptr ? &wr_h :
nullptr,
2434 fds_excp_ptr ? &ex_h :
nullptr,
2444 struct timeval tv = { 0, 0 };
2446 retval = select(nfds_h,
2447 fds_read_ptr ? &rd_h :
nullptr,
2448 fds_writ_ptr ? &wr_h :
nullptr,
2449 fds_excp_ptr ? &ex_h :
nullptr,
2459 if (sig.receiver ==
p)
2468 FD_ZERO((fd_set*)&*rd_t);
2469 FD_ZERO((fd_set*)&*wr_t);
2470 FD_ZERO((fd_set*)&*ex_t);
2477 for (
int i = 0;
i < nfds_h;
i++) {
2479 if (FD_ISSET(
i, &rd_h))
2480 FD_SET(trans_map[
i], (fd_set*)&*rd_t);
2484 if (FD_ISSET(
i, &wr_h))
2485 FD_SET(trans_map[
i], (fd_set*)&*wr_t);
2489 if (FD_ISSET(
i, &ex_h))
2490 FD_SET(trans_map[
i], (fd_set*)&*ex_t);
2509 int tgt_fd,
Addr buf_ptr,
int nbytes)
2513 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
2516 int sim_fd = hbfdp->getSimFD();
2520 pfd.events = POLLIN | POLLPRI;
2521 if ((poll(&pfd, 1, 0) == 0)
2522 && !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK))
2526 int bytes_read = read(sim_fd, buf_arg.
bufferPtr(), nbytes);
2531 return (bytes_read == -1) ? -errno : bytes_read;
2537 int tgt_fd,
Addr buf_ptr,
int nbytes)
2541 auto hbfdp = std::dynamic_pointer_cast<
HBFDEntry>((*
p->fds)[tgt_fd]);
2544 int sim_fd = hbfdp->getSimFD();
2551 pfd.events = POLLOUT;
2559 auto ffdp = std::dynamic_pointer_cast<
FileFDEntry>(hbfdp);
2560 if (ffdp && (ffdp->getFileName() !=
"/dev/random")) {
2561 if (!poll(&pfd, 1, 0) && !(ffdp->getFlags() & OS::TGT_O_NONBLOCK))
2565 int bytes_written = write(sim_fd, buf_arg.
bufferPtr(), nbytes);
2567 if (bytes_written != -1)
2570 return (bytes_written == -1) ? -errno : bytes_written;
2576 pid_t pid,
Addr statPtr,
int options,
Addr rusagePtr)
2581 DPRINTF_SYSCALL(Verbose,
"wait4: rusage pointer provided %lx, however " 2582 "functionality not supported. Ignoring rusage pointer.\n",
2596 if (iter->receiver ==
p) {
2598 if ((iter->sender->pgid() == -pid)
2599 && (iter->signalValue == OS::TGT_SIGCHLD))
2601 }
else if (pid == -1) {
2602 if (iter->signalValue == OS::TGT_SIGCHLD)
2604 }
else if (pid == 0) {
2605 if ((iter->sender->pgid() ==
p->pgid())
2606 && (iter->signalValue == OS::TGT_SIGCHLD))
2609 if ((iter->sender->pid() == pid)
2610 && (iter->signalValue == OS::TGT_SIGCHLD))
2620 const int EXITED = 0;
2621 BufferArg statusBuf(statPtr,
sizeof(
int));
2626 pid_t retval = iter->sender->pid();
2634 int tgt_fd,
Addr addrPtr,
Addr lenPtr)
2644 auto sfdp = std::dynamic_pointer_cast<
SocketFDEntry>((*
p->fds)[tgt_fd]);
2647 int sim_fd = sfdp->getSimFD();
2657 pfd.events = POLLIN | POLLPRI;
2658 if ((poll(&pfd, 1, 0) == 0) && !(sfdp->getFlags() & OS::TGT_O_NONBLOCK))
2662 lenBufPtr =
new BufferArg(lenPtr,
sizeof(socklen_t));
2664 memcpy(&addrLen, (socklen_t *)lenBufPtr->
bufferPtr(),
2669 addrBufPtr =
new BufferArg(addrPtr,
sizeof(
struct sockaddr));
2671 memcpy(&sa, (
struct sockaddr *)addrBufPtr->
bufferPtr(),
2672 sizeof(
struct sockaddr));
2675 host_fd = accept(sim_fd, &sa, &addrLen);
2687 *(socklen_t *)lenBufPtr->
bufferPtr() = addrLen;
2692 auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain,
2693 sfdp->_type, sfdp->_protocol);
2694 return p->fds->allocFD(afdp);
2701 unsigned initval,
int in_flags)
2703 #if defined(__linux__) 2706 int sim_fd = eventfd(initval, in_flags);
2710 bool cloexec = in_flags & OS::TGT_O_CLOEXEC;
2712 int flags = cloexec ? OS::TGT_O_CLOEXEC : 0;
2713 flags |= (in_flags & OS::TGT_O_NONBLOCK) ? OS::TGT_O_NONBLOCK : 0;
2715 auto hbfdp = std::make_shared<HBFDEntry>(flags, sim_fd, cloexec);
2716 int tgt_fd =
p->fds->allocFD(hbfdp);
2724 #endif // __SIM_SYSCALL_EMUL_HH__
SyscallReturn pwrite64Func(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr bufPtr, int nbytes, int offset)
SyscallReturn statFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target stat() handler.
#define panic(...)
This implements a cprintf based panic() function.
SyscallReturn fchmodFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int tgt_fd, uint32_t mode)
Target fchmod() handler.
SyscallReturn writevFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int tgt_fd, uint64_t tiov_base, size_t count)
Target writev() handler.
SyscallReturn exitFunc(SyscallDesc *desc, int num, ThreadContext *tc, int status)
Target exit() handler: terminate current context.
SyscallReturn setTidAddressFunc(SyscallDesc *desc, int num, ThreadContext *tc, uint64_t tidPtr)
Target set_tid_address() handler.
This file defines buffer classes used to handle pointer arguments in emulated syscalls.
SyscallReturn unimplementedFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Handler for unimplemented syscalls that we haven't thought about.
SyscallReturn lstatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target lstat() handler.
virtual void flushAll()=0
Remove all entries from the TLB.
SyscallReturn linkFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, Addr new_pathname)
Target link() handler.
SyscallReturn sysinfoFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr info)
Target sysinfo() 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...
virtual int ioctl(ThreadContext *tc, unsigned req)=0
Abstract method, invoked when the user program calls ioctl() on the file descriptor returned by a pre...
virtual System * getSystemPtr()=0
SyscallReturn _llseekFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, uint64_t offset_high, uint32_t offset_low, Addr result_ptr, int whence)
Target _llseek() handler.
SyscallReturn truncate64Func(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, int64_t length)
Target truncate64() handler.
SyscallReturn geteuidFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target geteuid() handler.
SyscallReturn chmodFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, mode_t mode)
Target chmod() handler.
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.
uint64_t childClearTID
Calls a futex wakeup at the address specified by this pointer when this process exits.
SyscallReturn getsockoptFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, int level, int optname, Addr valPtr, Addr lenPtr)
T gtoh(T value, ByteOrder guest_byte_order)
SyscallReturn prlimitFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int pid, int resource, Addr n, Addr o)
SyscallReturn fcntl64Func(SyscallDesc *desc, int num, ThreadContext *tc)
Target fcntl64() handler.
const int one_million
A readable name for 1,000,000, for converting microseconds to seconds.
virtual BaseTLB * getDTBPtr()=0
void copyOutStatfsBuf(PortProxy &mem, Addr addr, hst_statfs *host)
virtual TheISA::PCState pcState() const =0
virtual RegVal readIntReg(RegIndex reg_idx) const =0
SyscallReturn chownFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, uint32_t owner, uint32_t group)
Target chown() handler.
ObjectFile * createObjectFile(const std::string &fname, bool raw)
SyscallReturn accessFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, mode_t mode)
Target access() handler.
bool copyIn(PortProxy &memproxy)
copy data into simulator space (read from target memory)
SyscallReturn statfsFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target statfs() handler.
SyscallReturn brkFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr new_brk)
Target brk() handler: set brk address.
SyscallReturn pipeFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target pipe() handler.
SyscallReturn openatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int tgt_dirfd, Addr pathname, int tgt_flags, int mode)
Target open() handler.
SyscallReturn fstatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int tgt_fd, Addr bufPtr)
Target fstat() handler.
SyscallReturn recvfromFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr bufrPtr, size_t bufrLen, int flags, Addr addrPtr, Addr addrlenPtr)
const int one_billion
A readable name for 1,000,000,000, for converting nanoseconds to seconds.
SyscallReturn getegidFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getegid() handler.
virtual PortProxy & getVirtProxy()=0
SyscallReturn renameatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int olddirfd, Addr oldpath, int newdirfd, Addr newpath)
Target renameat() handler.
virtual Process * getProcessPtr()=0
Holds file descriptors for host-backed files; host-backed files are files which were opened on the ph...
SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, off_t length)
Target ftruncate() handler.
SymbolTable * debugSymbolTable
Global unified debugging symbol table (for target).
SyscallReturn clock_getresFunc(SyscallDesc *desc, int num, ThreadContext *tc, int clk_id, Addr tp_ptr)
Target clock_getres() function.
Overload hash function for BasicBlockRange type.
SyscallReturn shutdownFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, int how)
Target shutdown() handler.
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
SyscallReturn socketFunc(SyscallDesc *desc, int num, ThreadContext *tc, int domain, int type, int prot)
SyscallReturn ignoreFunc(SyscallDesc *desc, int num, 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.
SyscallReturn getcwdFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr buf_ptr, unsigned long size)
Target getcwd() handler.
SyscallReturn fallocateFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, int mode, off_t offset, off_t len)
SyscallReturn lseekFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, uint64_t offs, int whence)
Target lseek() handler.
SyscallReturn getgidFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getgid() handler.
void getElapsedTimeMicro(T1 &sec, T2 &usec)
Helper function to convert current elapsed time to seconds and microseconds.
SyscallReturn utimesFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, Addr times)
Target utimes() handler.
T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
SyscallReturn unlinkFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname)
Target unlink() handler.
TypedBufferArg is a class template; instances of this template represent typed buffers in target user...
SyscallReturn timeFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr taddr)
Target time() function.
SyscallReturn timesFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr bufPtr)
Target times() function.
SyscallReturn faccessatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int dirfd, Addr pathname, int mode)
Target facessat() handler.
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.
void usage(const char *progname)
#define DPRINTF_SYSCALL(FLAGEXT, FMT,...)
This macro is intended to help with readability.
SyscallReturn lstat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target lstat64() handler.
SyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getpagesize() handler.
SyscallReturn socketpairFunc(SyscallDesc *desc, int num, ThreadContext *tc, int domain, int type, int prot, Addr svPtr)
SyscallReturn readFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr buf_ptr, int nbytes)
SyscallReturn bindFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr buf_ptr, int addrlen)
SyscallReturn truncateFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, off_t length)
Target truncate() handler.
SyscallReturn ioctlFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
Target ioctl() handler.
SyscallReturn closeFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd)
Target close() handler.
SyscallReturn getpgrpFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getpgrpFunc() handler.
SyscallReturn tgkillFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgid, int tid, int sig)
SyscallReturn fstat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc, int tgt_fd, Addr bufPtr)
Target fstat64() handler.
SyscallReturn readvFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int tgt_fd, uint64_t tiov_base, size_t count)
Target readv() handler.
SyscallReturn renameFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr oldpath, Addr newpath)
Target rename() handler.
virtual MemoryImage buildImage() const =0
void copyOutStat64Buf(PortProxy &mem, Addr addr, hst_stat64 *host, bool fakeTTY=false)
Tick curTick()
The current simulated tick.
SyscallReturn gettimeofdayFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr tv_ptr, Addr tz_ptr)
Target gettimeofday() handler.
SyscallReturn chdirFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname)
Target chdir() handler.
void assignThreadContext(ContextID context_id)
void inc(scfx_mant &mant)
ByteOrder byteOrder(ThreadContext *tc)
T htog(T value, ByteOrder guest_byte_order)
SyscallReturn clock_gettimeFunc(SyscallDesc *desc, int num, ThreadContext *tc, int clk_id, Addr tp_ptr)
Target clock_gettime() function.
virtual int cpuId() const =0
virtual void setProcessPtr(Process *p)=0
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
SyscallReturn gethostnameFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr buf_ptr, int name_len)
Target gethostname() handler.
int wakeup(Addr addr, uint64_t tgid, int count)
Wakes up at most count waiting threads on a futex.
SyscallReturn getrusageFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int who, Addr usage)
Target getrusage() function.
SyscallReturn umaskFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target umask() handler.
static SyscallReturn retry()
Pseudo-constructor to create an instance with the retry flag set.
SyscallReturn getuidFunc(SyscallDesc *desc, int num, ThreadContext *tc)
SyscallReturn selectFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int nfds_t, Addr fds_read_ptr, Addr fds_writ_ptr, Addr fds_excp_ptr, Addr time_val_ptr)
virtual RegVal getSyscallArg(ThreadContext *tc, int &i)=0
std::vector< ThreadContext * > threadContexts
SyscallReturn stat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, Addr bufPtr)
Target stat64() handler.
SyscallReturn readlinkatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int dirfd, Addr pathname, Addr buf, size_t bufsiz)
Target readlinkat() handler.
Extends the base class to include a host-backed file descriptor field that records the integer used t...
virtual BaseTLB * getITBPtr()=0
unsigned numContexts() const
SyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getpidPseudo() handler.
void * bufferPtr()
Return a pointer to the internal simulator-space buffer.
SyscallReturn mknodFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, mode_t mode, dev_t dev)
Target mknod() handler.
std::string const & getFileName() const
ThreadContext * findFreeContext()
const RegIndex SyscallPseudoReturnReg
void warnUnsupportedOS(std::string syscall_name)
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.
SyscallReturn gettidFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target gettid() handler.
virtual void setIntReg(RegIndex reg_idx, RegVal val)=0
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
SyscallReturn recvmsgFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr msgPtr, int flags)
SyscallReturn pipeImpl(SyscallDesc *desc, int num, ThreadContext *tc, bool pseudo_pipe, bool is_pipe2=false)
Internal pipe() handler.
std::list< BasicSignal > signalList
SyscallReturn execveFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, Addr argv_mem_loc, Addr envp_mem_loc)
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 dupFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd)
Target dup() handler.
SyscallReturn writeFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr buf_ptr, int nbytes)
SyscallReturn setsockoptFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, int level, int optname, Addr valPtr, socklen_t len)
SyscallReturn setpgidFunc(SyscallDesc *desc, int num, ThreadContext *tc, int pid, int pgid)
Target setpgid() handler.
SyscallReturn cloneFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
SyscallReturn getrlimitFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, unsigned resource, Addr rlim)
Target getrlimit() handler.
void copyOutStatBuf(PortProxy &mem, Addr addr, hst_stat *host, bool fakeTTY=false)
SyscallReturn sendmsgFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr msgPtr, int flags)
SyscallReturn pollFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr fdsPtr, int nfds, int tmout)
This class provides the wrapper interface for the system call implementations which are defined in th...
SyscallReturn pipePseudoFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Pseudo Funcs - These functions use a different return convension, returning a second value in a regis...
SyscallReturn mkdirFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, mode_t mode)
Target mkdir() handler.
This object is a proxy for a port or other object which implements the functional response protocol...
SyscallReturn acceptFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr addrPtr, Addr lenPtr)
SyscallReturn getppidFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getppid() handler.
SyscallReturn eventfdFunc(SyscallDesc *desc, int num, ThreadContext *tc, unsigned initval, int in_flags)
Target eventfd() function.
EmulationPageTable * pTable
Declarations of a non-full system Page Table.
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 rmdirFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname)
SyscallReturn fcntlFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target fcntl() handler.
SyscallReturn wait4Func(SyscallDesc *desc, int num, ThreadContext *tc, pid_t pid, Addr statPtr, int options, Addr rusagePtr)
SyscallReturn readlinkFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, Addr buf, size_t bufsiz)
Target readlink() handler.
SyscallReturn ftruncate64Func(SyscallDesc *desc, int num, ThreadContext *tc)
Target ftruncate64() handler.
SyscallReturn mmap2Func(SyscallDesc *desc, int num, ThreadContext *tc, Addr start, uint64_t length, int prot, int tgt_flags, int tgt_fd, int offset)
Target mmap2() handler.
GenericISA::SimplePCState< MachInst > PCState
SyscallReturn fchownFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, uint32_t owner, uint32_t group)
Target fchown() 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
SyscallReturn symlinkFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr pathname, Addr new_pathname)
Target symlink() handler.
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 mremapFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
Target mremap() handler.
FutexMap class holds a map of all futexes used in the system.
virtual ContextID contextId() const =0
SyscallReturn getuidPseudoFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getuidPseudo() handler.
void convertStat64Buf(target_stat &tgt, host_stat64 *host, ByteOrder bo, bool fakeTTY=false)
SyscallReturn connectFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr buf_ptr, int addrlen)
BufferArg represents an untyped buffer in target user space that is passed by reference to an (emulat...
virtual void clearArchRegs()=0
SyscallReturn openFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr pathname, int tgt_flags, int mode)
Target open() handler.
EmulatedDriver is an abstract base class for fake SE-mode device drivers.
SyscallReturn pipe2Func(SyscallDesc *desc, int num, ThreadContext *tc)
Target pipe() handler.
SyscallReturn getsocknameFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr addrPtr, Addr lenPtr)
Holds file descriptors needed to simulate devices opened with pseudo files (commonly with calls to io...
virtual void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value)=0
This class represents the return value from an emulated system call, including any errno setting...
void convertStatBuf(target_stat &tgt, host_stat *host, ByteOrder bo, bool fakeTTY=false)
SyscallReturn dup2Func(SyscallDesc *desc, int num, ThreadContext *tc, int old_tgt_fd, int new_tgt_fd)
Target dup2() handler.
SyscallReturn sendtoFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr bufrPtr, size_t bufrLen, int flags, Addr addrPtr, socklen_t addrLen)
bool tryReadString(std::string &str, Addr addr) const
Reads the string at guest address addr into the std::string str.
SyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getgidPseudo() handler.
SyscallReturn ignoreWarnOnceFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Like above, but only prints a warning once per syscall desc it's used with.
SyscallReturn fstatat64Func(SyscallDesc *desc, int callnum, ThreadContext *tc, int dirfd, Addr pathname, Addr bufPtr)
Target fstatat64() handler.
SyscallReturn getpeernameFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, Addr sockAddrPtr, Addr addrlenPtr)
const RegIndex SyscallSuccessReg
SyscallReturn mmapFunc(SyscallDesc *desc, int num, ThreadContext *tc, Addr start, uint64_t length, int prot, int tgt_flags, int tgt_fd, int offset)
Target mmap() handler.
const unsigned seconds_since_epoch
Approximate seconds since the epoch (1/1/1970).
virtual bool loadAllSymbols(SymbolTable *symtab, Addr base=0, Addr offset=0, Addr mask=MaxAddr)
SyscallReturn futexFunc(SyscallDesc *desc, int callnum, 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...
SyscallReturn listenFunc(SyscallDesc *desc, int num, ThreadContext *tc, int tgt_fd, int backlog)
SyscallReturn munmapFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target munmap() handler.
SyscallReturn unlinkatFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int dirfd, Addr pathname)
Target unlinkat() handler.
SyscallReturn fstatfsFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, int tgt_fd, Addr bufPtr)
Target fstatfs() handler.
SyscallReturn exitGroupFunc(SyscallDesc *desc, int num, ThreadContext *tc, int status)
Target exit_group() handler: terminate simulation. (exit all threads)
SyscallReturn getpidFunc(SyscallDesc *desc, int num, ThreadContext *tc)
Target getpid() handler.
std::shared_ptr< FDArray > fds