42#ifndef __SIM_SYSCALL_EMUL_HH__
43#define __SIM_SYSCALL_EMUL_HH__
45#if (defined(__APPLE__) || defined(__OpenBSD__) || \
46 defined(__FreeBSD__) || defined(__CYGWIN__) || \
60#include <linux/kdev_t.h>
62#include <sys/eventfd.h>
63#include <sys/statfs.h>
79#include <sys/socket.h>
102#include "params/Process.hh"
113#if defined(__APPLE__) && defined(__MACH__) && !defined(CMSG_ALIGN)
114#define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
115#elif defined(__FreeBSD__) && !defined(CMSG_ALIGN)
116#define CMSG_ALIGN(n) _ALIGN(n)
139SyscallReturn
ignoreFunc(SyscallDesc *desc, ThreadContext *tc);
145SyscallReturn
exitFunc(SyscallDesc *desc, ThreadContext *tc,
int status);
158SyscallReturn
brkFunc(SyscallDesc *desc, ThreadContext *tc,
VPtr<> new_brk);
161SyscallReturn
closeFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd);
164SyscallReturn
lseekFunc(SyscallDesc *desc, ThreadContext *tc,
165 int tgt_fd, uint64_t offs,
int whence);
168SyscallReturn
_llseekFunc(SyscallDesc *desc, ThreadContext *tc,
169 int tgt_fd, uint64_t offset_high,
170 uint32_t offset_low,
VPtr<> result_ptr,
int whence);
173SyscallReturn
shutdownFunc(SyscallDesc *desc, ThreadContext *tc,
174 int tgt_fd,
int how);
178 VPtr<> buf_ptr,
int name_len);
181SyscallReturn
getcwdFunc(SyscallDesc *desc, ThreadContext *tc,
182 VPtr<> buf_ptr,
unsigned long size);
185SyscallReturn
unlinkFunc(SyscallDesc *desc, ThreadContext *tc,
187SyscallReturn
unlinkImpl(SyscallDesc *desc, ThreadContext *tc,
191SyscallReturn
linkFunc(SyscallDesc *desc, ThreadContext *tc,
195SyscallReturn
symlinkFunc(SyscallDesc *desc, ThreadContext *tc,
199SyscallReturn
mkdirFunc(SyscallDesc *desc, ThreadContext *tc,
201SyscallReturn
mkdirImpl(SyscallDesc *desc, ThreadContext *tc,
202 std::string path, mode_t
mode);
205SyscallReturn
mknodFunc(SyscallDesc *desc, ThreadContext *tc,
207SyscallReturn
mknodImpl(SyscallDesc *desc, ThreadContext *tc,
208 std::string path, mode_t
mode, dev_t dev);
211SyscallReturn
chdirFunc(SyscallDesc *desc, ThreadContext *tc,
VPtr<> pathname);
214SyscallReturn
rmdirFunc(SyscallDesc *desc, ThreadContext *tc,
216SyscallReturn
rmdirImpl(SyscallDesc *desc, ThreadContext *tc,
220SyscallReturn
renameFunc(SyscallDesc *desc, ThreadContext *tc,
222SyscallReturn
renameImpl(SyscallDesc *desc, ThreadContext *tc,
223 std::string oldpath, std::string newpath);
227 VPtr<> pathname, int64_t length);
231 int tgt_fd, int64_t length);
234SyscallReturn
umaskFunc(SyscallDesc *desc, ThreadContext *tc);
237SyscallReturn
gettidFunc(SyscallDesc *desc, ThreadContext *tc);
240SyscallReturn
chownFunc(SyscallDesc *desc, ThreadContext *tc,
241 VPtr<> pathname, uint32_t owner, uint32_t group);
242SyscallReturn
chownImpl(SyscallDesc *desc, ThreadContext *tc,
243 std::string path, uint32_t owner, uint32_t group);
246SyscallReturn
getpgrpFunc(SyscallDesc *desc, ThreadContext *tc);
249SyscallReturn
setpgidFunc(SyscallDesc *desc, ThreadContext *tc,
253SyscallReturn
fchownFunc(SyscallDesc *desc, ThreadContext *tc,
254 int tgt_fd, uint32_t owner, uint32_t group);
257SyscallReturn
dupFunc(SyscallDesc *desc, ThreadContext *tc,
261SyscallReturn
dup2Func(SyscallDesc *desc, ThreadContext *tc,
262 int old_tgt_fd,
int new_tgt_fd);
265SyscallReturn
fcntlFunc(SyscallDesc *desc, ThreadContext *tc,
266 int tgt_fd,
int cmd, guest_abi::VarArgs<int> varargs);
269SyscallReturn
fcntl64Func(SyscallDesc *desc, ThreadContext *tc,
270 int tgt_fd,
int cmd);
273SyscallReturn
pipeFunc(SyscallDesc *desc, ThreadContext *tc,
VPtr<> tgt_addr);
276SyscallReturn
pipe2Func(SyscallDesc *desc, ThreadContext *tc,
280SyscallReturn
getpidFunc(SyscallDesc *desc, ThreadContext *tc);
284 int tgt_fd,
VPtr<> sockAddrPtr,
288SyscallReturn
bindFunc(SyscallDesc *desc, ThreadContext *tc,
289 int tgt_fd,
VPtr<> buf_ptr,
int addrlen);
292SyscallReturn
listenFunc(SyscallDesc *desc, ThreadContext *tc,
293 int tgt_fd,
int backlog);
296SyscallReturn
connectFunc(SyscallDesc *desc, ThreadContext *tc,
297 int tgt_fd,
VPtr<> buf_ptr,
int addrlen);
299#if defined(SYS_getdents)
301SyscallReturn getdentsFunc(SyscallDesc *desc, ThreadContext *tc,
305#if defined(SYS_getdents64)
307SyscallReturn getdents64Func(SyscallDesc *desc, ThreadContext *tc,
312SyscallReturn
recvmsgFunc(SyscallDesc *desc, ThreadContext *tc,
316SyscallReturn
sendmsgFunc(SyscallDesc *desc, ThreadContext *tc,
320SyscallReturn
getuidFunc(SyscallDesc *desc, ThreadContext *tc);
323SyscallReturn
getgidFunc(SyscallDesc *desc, ThreadContext *tc);
326SyscallReturn
getppidFunc(SyscallDesc *desc, ThreadContext *tc);
329SyscallReturn
geteuidFunc(SyscallDesc *desc, ThreadContext *tc);
332SyscallReturn
getegidFunc(SyscallDesc *desc, ThreadContext *tc);
335SyscallReturn
accessFunc(SyscallDesc *desc, ThreadContext *tc,
337SyscallReturn
accessImpl(SyscallDesc *desc, ThreadContext *tc,
338 std::string path, mode_t
mode);
342 int tgt_fd,
int level,
int optname,
347 int tgt_fd,
int level,
int optname,
350SyscallReturn
getcpuFunc(SyscallDesc *desc, ThreadContext *tc,
363 if (dirfd != OS::TGT_AT_FDCWD && !
startswith(path,
"/")) {
366 std::shared_ptr<FDEntry> fdep = ((*process->fds)[dirfd]);
367 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
372 path = ffdp->getFileName();
374 path = ffdp->getFileName() +
"/" + path;
394 op &= ~OS::TGT_FUTEX_PRIVATE_FLAG;
395 op &= ~OS::TGT_FUTEX_CLOCK_REALTIME_FLAG;
399 if (OS::TGT_FUTEX_WAIT ==
op || OS::TGT_FUTEX_WAIT_BITSET ==
op) {
411 return -OS::TGT_EWOULDBLOCK;
413 if (OS::TGT_FUTEX_WAIT ==
op) {
414 futex_map.
suspend(uaddr, process->tgid(), tc);
420 }
else if (OS::TGT_FUTEX_WAKE ==
op) {
421 return futex_map.
wakeup(uaddr, process->tgid(),
val);
422 }
else if (OS::TGT_FUTEX_WAKE_BITSET ==
op) {
423 return futex_map.
wakeup_bitset(uaddr, process->tgid(), val3);
424 }
else if (OS::TGT_FUTEX_REQUEUE ==
op ||
425 OS::TGT_FUTEX_CMP_REQUEUE ==
op) {
435 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
436 return -OS::TGT_EWOULDBLOCK;
437 return futex_map.
requeue(uaddr, process->tgid(),
val, timeout, uaddr2);
438 }
else if (OS::TGT_FUTEX_WAKE_OP ==
op) {
466 int wake_cmparg = val3 & 0xfff;
467 int wake_oparg = (val3 & 0xfff000) >> 12;
468 int wake_cmp = (val3 & 0xf000000) >> 24;
469 int wake_op = (val3 & 0xf0000000) >> 28;
470 if ((wake_op & OS::TGT_FUTEX_OP_ARG_SHIFT) >> 3 == 1)
471 wake_oparg = (1 << wake_oparg);
472 wake_op &= ~OS::TGT_FUTEX_OP_ARG_SHIFT;
474 if (wake_op == OS::TGT_FUTEX_OP_SET)
476 else if (wake_op == OS::TGT_FUTEX_OP_ADD)
477 newval += wake_oparg;
478 else if (wake_op == OS::TGT_FUTEX_OP_OR)
479 newval |= wake_oparg;
480 else if (wake_op == OS::TGT_FUTEX_OP_ANDN)
481 newval &= ~wake_oparg;
482 else if (wake_op == OS::TGT_FUTEX_OP_XOR)
483 newval ^= wake_oparg;
488 int woken1 = futex_map.
wakeup(uaddr, process->tgid(),
val);
491 bool is_wake2 =
false;
492 if (wake_cmp == OS::TGT_FUTEX_OP_CMP_EQ)
493 is_wake2 = oldval == wake_cmparg;
494 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_NE)
495 is_wake2 = oldval != wake_cmparg;
496 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LT)
497 is_wake2 = oldval < wake_cmparg;
498 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LE)
499 is_wake2 = oldval <= wake_cmparg;
500 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GT)
501 is_wake2 = oldval > wake_cmparg;
502 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GE)
503 is_wake2 = oldval >= wake_cmparg;
506 woken2 = futex_map.
wakeup(uaddr2, process->tgid(), timeout);
508 return woken1 + woken2;
510 warn(
"futex: op %d not implemented; ignoring.",
op);
516SyscallReturn
pipePseudoFunc(SyscallDesc *desc, ThreadContext *tc);
526template <
class T1,
class T2>
530 static const int OneMillion = 1000 * 1000;
533 sec = elapsed_usecs / OneMillion;
534 usec = elapsed_usecs % OneMillion;
539template <
class T1,
class T2>
543 static const int OneBillion = 1000 * 1000 * 1000;
546 sec = elapsed_nsecs / OneBillion;
547 nsec = elapsed_nsecs % OneBillion;
570template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
574 constexpr ByteOrder
bo = OS::byteOrder;
579 tgt->st_dev = host->st_dev;
580 tgt->st_dev =
htog(tgt->st_dev,
bo);
581 tgt->st_ino = host->st_ino;
582 tgt->st_ino =
htog(tgt->st_ino,
bo);
583 tgt->st_mode = host->st_mode;
586 tgt->st_mode &= ~S_IFMT;
587 tgt->st_mode |= S_IFCHR;
589 tgt->st_mode =
htog(tgt->st_mode,
bo);
590 tgt->st_nlink = host->st_nlink;
591 tgt->st_nlink =
htog(tgt->st_nlink,
bo);
592 tgt->st_uid = host->st_uid;
593 tgt->st_uid =
htog(tgt->st_uid,
bo);
594 tgt->st_gid = host->st_gid;
595 tgt->st_gid =
htog(tgt->st_gid,
bo);
597 tgt->st_rdev = 0x880d;
599 tgt->st_rdev = host->st_rdev;
600 tgt->st_rdev =
htog(tgt->st_rdev,
bo);
601 tgt->st_size = host->st_size;
602 tgt->st_size =
htog(tgt->st_size,
bo);
603 tgt->st_atimeX = host->st_atime;
604 tgt->st_atimeX =
htog(tgt->st_atimeX,
bo);
605 tgt->st_mtimeX = host->st_mtime;
606 tgt->st_mtimeX =
htog(tgt->st_mtimeX,
bo);
607 tgt->st_ctimeX = host->st_ctime;
608 tgt->st_ctimeX =
htog(tgt->st_ctimeX,
bo);
611 tgt->st_blksize = 0x2000;
612 tgt->st_blksize =
htog(tgt->st_blksize,
bo);
613 tgt->st_blocks = host->st_blocks;
614 tgt->st_blocks =
htog(tgt->st_blocks,
bo);
619template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
625#if defined(STAT_HAVE_NSEC)
626 constexpr ByteOrder
bo = OS::byteOrder;
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;
641template <
class OS,
typename TgtStatPtr,
typename HostStatPtr>
645 constexpr ByteOrder
bo = OS::byteOrder;
647 tgt->f_type =
htog(host->f_type,
bo);
648#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
649 tgt->f_bsize =
htog(host->f_iosize,
bo);
651 tgt->f_bsize =
htog(host->f_bsize,
bo);
653 tgt->f_blocks =
htog(host->f_blocks,
bo);
654 tgt->f_bfree =
htog(host->f_bfree,
bo);
655 tgt->f_bavail =
htog(host->f_bavail,
bo);
656 tgt->f_files =
htog(host->f_files,
bo);
657 tgt->f_ffree =
htog(host->f_ffree,
bo);
658 memcpy(&tgt->f_fsid, &host->f_fsid,
sizeof(host->f_fsid));
659#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
660 tgt->f_namelen =
htog(host->f_namemax,
bo);
661 tgt->f_frsize =
htog(host->f_bsize,
bo);
662#elif defined(__APPLE__)
666 tgt->f_namelen =
htog(host->f_namelen,
bo);
667 tgt->f_frsize =
htog(host->f_frsize,
bo);
669#if defined(__linux__)
670 memcpy(&tgt->f_spare, &host->f_spare,
671 std::min(
sizeof(host->f_spare),
sizeof(tgt->f_spare)));
677 memset(&tgt->f_spare, 0,
sizeof(tgt->f_spare));
681template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
685 constexpr ByteOrder
bo = OS::byteOrder;
688 tgt->stx_dev_major = 0x00;
689 tgt->stx_dev_minor = 0x0A;
691 tgt->stx_dev_major = host->st_dev >> 8;
692 tgt->stx_dev_minor = host->st_dev & 0xFF;
694 tgt->stx_dev_major =
htog(tgt->stx_dev_major,
bo);
695 tgt->stx_dev_minor =
htog(tgt->stx_dev_minor,
bo);
696 tgt->stx_ino = host->st_ino;
697 tgt->stx_ino =
htog(tgt->stx_ino,
bo);
698 tgt->stx_mode = host->st_mode;
701 tgt->stx_mode &= ~S_IFMT;
702 tgt->stx_mode |= S_IFCHR;
704 tgt->stx_mode =
htog(tgt->stx_mode,
bo);
705 tgt->stx_nlink = host->st_nlink;
706 tgt->stx_nlink =
htog(tgt->stx_nlink,
bo);
707 tgt->stx_uid = host->st_uid;
708 tgt->stx_uid =
htog(tgt->stx_uid,
bo);
709 tgt->stx_gid = host->st_gid;
710 tgt->stx_gid =
htog(tgt->stx_gid,
bo);
712 tgt->stx_rdev_major = 0x880d >> 8;
713 tgt->stx_rdev_minor = 0x880d & 0xFF;
715 tgt->stx_rdev_major = host->st_rdev >> 8;
716 tgt->stx_rdev_minor = host->st_rdev & 0xFF;
718 tgt->stx_rdev_major =
htog(tgt->stx_rdev_major,
bo);
719 tgt->stx_rdev_minor =
htog(tgt->stx_rdev_minor,
bo);
720 tgt->stx_size = host->st_size;
721 tgt->stx_size =
htog(tgt->stx_size,
bo);
722 tgt->stx_atimeX = host->st_atime;
723 tgt->stx_atimeX =
htog(tgt->stx_atimeX,
bo);
724 tgt->stx_ctimeX = host->st_ctime;
725 tgt->stx_ctimeX =
htog(tgt->stx_ctimeX,
bo);
726 tgt->stx_mtimeX = host->st_mtime;
727 tgt->stx_mtimeX =
htog(tgt->stx_mtimeX,
bo);
730 tgt->stx_blksize = 0x2000;
731 tgt->stx_blksize =
htog(tgt->stx_blksize,
bo);
732 tgt->stx_blocks = host->st_blocks;
733 tgt->stx_blocks =
htog(tgt->stx_blocks,
bo);
734 tgt->stx_mask = 0x000007ffU;
735 tgt->stx_mask =
htog(tgt->stx_mask,
bo);
736 tgt->stx_attributes = 0;
737 tgt->stx_attributes_mask = 0;
738 tgt->stx_attributes_mask =
htog(tgt->stx_attributes_mask,
bo);
754 if (OS::isTtyReq(req))
757 auto dfdp = std::dynamic_pointer_cast<DeviceFDEntry>((*
p->fds)[tgt_fd]);
761 return emul_driver->
ioctl(tc, req,
addr);
764 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
773 ifconf *conf = (ifconf*)conf_arg.
bufferPtr();
774 Addr ifc_buf_addr = (
Addr)conf->ifc_buf;
775 BufferArg ifc_buf_arg(ifc_buf_addr, conf->ifc_len);
778 conf->ifc_buf = (
char*)ifc_buf_arg.
bufferPtr();
782 conf->ifc_buf = (
char*)ifc_buf_addr;
790#if defined(__linux__)
795#if defined(__linux__)
814 warn(
"Unsupported ioctl call (return ENOTTY): ioctl(%d, 0x%x, ...) @ \n",
823 int tgt_dirfd,
VPtr<> pathname,
int tgt_flags,
int mode)
836 int host_flags = O_BINARY;
844 for (
const auto &
p: OS::openFlagTable) {
845 if (tgt_flags &
p.first) {
846 tgt_flags &= ~p.first;
847 host_flags |=
p.second;
850 warn_if(tgt_flags,
"%s: cannot decode flags %#x", desc->
name(), tgt_flags);
853 host_flags |= O_BINARY;
868 std::string redir_path = path;
869 std::string abs_path = path;
870 if (tgt_dirfd == OS::TGT_AT_FDCWD) {
871 abs_path =
p->absolutePath(path,
true);
872 redir_path =
p->checkPathRedirect(path);
874 std::shared_ptr<FDEntry> fdep = ((*
p->fds)[tgt_dirfd]);
875 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
878 abs_path = ffdp->getFileName() + path;
879 redir_path =
p->checkPathRedirect(abs_path);
889 std::string filename = abs_path.substr(strlen(
"/dev/"));
893 "driver open with path[%s]\n",
894 desc->
name(), abs_path.c_str());
895 return drv->
open(tc,
mode, host_flags);
928 std::string used_path;
930 {
"/proc/meminfo",
"/system/",
"/platform/",
"/etc/passwd",
931 "/proc/self/maps",
"/dev/urandom",
932 "/sys/devices/system/cpu/online" };
933 for (
auto entry : special_paths) {
935 sim_fd = OS::openSpecialFile(abs_path,
p, tc);
936 used_path = abs_path;
940 sim_fd = open(redir_path.c_str(), host_flags,
mode);
941 used_path = redir_path;
946 "(inferred from:%s)\n", desc->
name(),
947 used_path.c_str(), path.c_str());
959 auto ffdp = std::make_shared<FileFDEntry>(sim_fd, host_flags, path, 0);
961 ffdp->setFileMode(
mode);
962 int tgt_fd =
p->fds->allocFD(ffdp);
964 "(inferred from:%s)\n", desc->
name(),
965 sim_fd, tgt_fd, used_path.c_str(), path.c_str());
976 desc, tc, OS::TGT_AT_FDCWD, pathname, tgt_flags,
mode);
994 if (
flags & OS::TGT_AT_REMOVEDIR) {
1024 typename OS::size_t bufsiz)
1043 if (path !=
"/proc/self/exe") {
1044 result = readlink(path.c_str(), (
char *)buf.
bufferPtr(), bufsiz);
1058 char real_path[PATH_MAX];
1059 char *check_real_path = realpath(
p->progName(), real_path);
1060 if (!check_real_path) {
1061 fatal(
"readlink('/proc/self/exe') unable to resolve path to "
1062 "executable: %s",
p->progName());
1064 strncpy((
char*)buf.
bufferPtr(), real_path, bufsiz);
1065 typename OS::size_t real_path_len = strlen(real_path);
1066 if (real_path_len > bufsiz) {
1071 result = real_path_len;
1075 warn_once(
"readlink() called on '/proc/self/exe' may yield unexpected "
1076 "results in various settings.\n Returning '%s'\n",
1082 return (result == -1) ? -errno : result;
1090 typename OS::size_t bufsiz)
1093 pathname, buf_ptr, bufsiz);
1100 int olddirfd,
VPtr<> oldpath,
int newdirfd,
VPtr<> newpath)
1103 std::string old_name;
1107 std::string new_name;
1121 return renameImpl(desc, tc, old_name, new_name);
1128 int dirfd,
VPtr<> pathname, uint32_t owner, uint32_t group,
1140 return chownImpl(desc, tc, path, owner, group);
1165 int dirfd,
VPtr<> pathname, mode_t
mode, dev_t dev)
1188 sysinfo->totalram = process->system->memSize();
1189 sysinfo->mem_unit = 1;
1209 mode_t hostMode = 0;
1219 int result = chmod(path.c_str(), hostMode);
1237 VPtr<> fdsPtr,
int nfds,
int tmout)
1241 BufferArg fdsBuf(fdsPtr,
sizeof(
struct pollfd) * nfds);
1250 int temp_tgt_fds[nfds];
1253 auto tgt_fd = temp_tgt_fds[
index];
1254 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1257 auto host_fd = hbfdp->getSimFD();
1279 if (it->receiver ==
p)
1294 auto tgt_fd = temp_tgt_fds[
index];
1314 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1317 int sim_fd = ffdp->getSimFD();
1319 mode_t hostMode =
mode;
1321 int result = fchmod(sim_fd, hostMode);
1323 return (result < 0) ? -errno : 0;
1330 VPtr<> start, uint64_t old_length, uint64_t new_length, uint64_t
flags,
1335 uint64_t provided_address = 0;
1336 bool use_provided_address =
flags & OS::TGT_MREMAP_FIXED;
1338 if (use_provided_address)
1339 provided_address = varargs.
get<uint64_t>();
1341 if ((start % page_bytes != 0) ||
1342 (provided_address % page_bytes != 0)) {
1343 warn(
"mremap failing: arguments not page aligned");
1347 new_length =
roundUp(new_length, page_bytes);
1349 if (new_length > old_length) {
1350 Addr mmap_end =
p->memState->getMmapEnd();
1352 if ((start + old_length) == mmap_end &&
1353 (!use_provided_address || provided_address == start)) {
1356 uint64_t diff = new_length - old_length;
1357 p->memState->mapRegion(mmap_end, diff,
"remapped");
1358 p->memState->setMmapEnd(mmap_end + diff);
1361 if (!use_provided_address && !(
flags & OS::TGT_MREMAP_MAYMOVE)) {
1362 warn(
"can't remap here and MREMAP_MAYMOVE flag not set\n");
1365 uint64_t new_start = provided_address;
1366 if (!use_provided_address) {
1367 new_start =
p->mmapGrowsDown() ?
1368 mmap_end - new_length : mmap_end;
1369 mmap_end =
p->mmapGrowsDown() ?
1370 new_start : mmap_end + new_length;
1371 p->memState->setMmapEnd(mmap_end);
1374 warn(
"mremapping to new vaddr %08p-%08p, adding %d\n",
1375 new_start, new_start + new_length,
1376 new_length - old_length);
1379 p->allocateMem(new_start + old_length,
1380 new_length - old_length,
1381 use_provided_address );
1383 if (use_provided_address &&
1384 ((new_start + new_length >
p->memState->getMmapEnd() &&
1385 !
p->mmapGrowsDown()) ||
1386 (new_start < p->memState->getMmapEnd() &&
1387 p->mmapGrowsDown()))) {
1390 warn(
"mmap region limit exceeded with MREMAP_FIXED\n");
1393 warn(
"returning %08p as start\n", new_start);
1394 p->memState->remapRegion(start, new_start, old_length);
1400 if (use_provided_address && provided_address != start)
1401 p->memState->remapRegion(start, provided_address, new_length);
1402 if (new_length != old_length)
1403 p->memState->unmapRegion(start + new_length,
1404 old_length - new_length);
1405 return use_provided_address ? provided_address : (
Addr)start;
1424 struct stat hostBuf;
1425 int result = stat(path.c_str(), &hostBuf);
1447 if (path.empty() && !(
flags & OS::TGT_AT_EMPTY_PATH))
1463 struct stat host_buf;
1464 int result = stat(path.c_str(), &host_buf);
1478 int dirfd,
VPtr<> pathname,
1496 struct stat hostBuf;
1497 int result = stat(path.c_str(), &hostBuf);
1499 struct stat64 hostBuf;
1500 int result = stat64(path.c_str(), &hostBuf);
1532 if (path.empty() && !(
flags & OS::TGT_AT_EMPTY_PATH))
1548 struct stat host_buf;
1549 int result = stat(path.c_str(), &host_buf);
1567 auto ffdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1570 int sim_fd = ffdp->getSimFD();
1573 struct stat hostBuf;
1574 int result = fstat(sim_fd, &hostBuf);
1576 struct stat64 hostBuf;
1577 int result = fstat64(sim_fd, &hostBuf);
1604 struct stat hostBuf;
1605 int result = lstat(path.c_str(), &hostBuf);
1631 struct stat hostBuf;
1632 int result = lstat(path.c_str(), &hostBuf);
1634 struct stat64 hostBuf;
1635 int result = lstat64(path.c_str(), &hostBuf);
1656 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1659 int sim_fd = ffdp->getSimFD();
1661 struct stat hostBuf;
1662 int result = fstat(sim_fd, &hostBuf);
1678#if defined(__linux__)
1688 struct statfs hostBuf;
1689 int result = statfs(path.c_str(), &hostBuf);
1707 DPRINTF(SyscallVerbose,
"Doing clone. pid: %#llx, ctid: %#llx, tls: %#llx"
1708 " flags: %#llx, stack: %#llx\n",
1712 if (((
flags & OS::TGT_CLONE_SIGHAND)&& !(
flags & OS::TGT_CLONE_VM)) ||
1713 ((
flags & OS::TGT_CLONE_THREAD) && !(
flags & OS::TGT_CLONE_SIGHAND)) ||
1714 ((
flags & OS::TGT_CLONE_FS) && (
flags & OS::TGT_CLONE_NEWNS)) ||
1715 ((
flags & OS::TGT_CLONE_NEWIPC) && (
flags & OS::TGT_CLONE_SYSVSEM)) ||
1716 ((
flags & OS::TGT_CLONE_NEWPID) && (
flags & OS::TGT_CLONE_THREAD)) ||
1717 ((
flags & OS::TGT_CLONE_VM) && !(newStack)))
1733 ProcessParams *pp =
new ProcessParams();
1734 pp->executable.assign(*(
new std::string(
p->progName())));
1735 pp->cmd.push_back(*(
new std::string(
p->progName())));
1736 pp->system =
p->system;
1737 pp->cwd.assign(
p->tgtCwd);
1738 pp->input.assign(
"stdin");
1739 pp->output.assign(
"stdout");
1740 pp->errout.assign(
"stderr");
1742 pp->euid =
p->euid();
1744 pp->egid =
p->egid();
1745 pp->release =
p->release;
1748 std::set<int>
const& pids =
p->system->PIDs;
1749 int temp_pid = *pids.begin();
1752 }
while (pids.find(temp_pid) != pids.end());
1754 fatal(
"temp_pid is too large: %d", temp_pid);
1757 pp->ppid = (
flags & OS::TGT_CLONE_THREAD) ?
p->ppid() :
p->pid();
1758 pp->useArchPT =
p->useArchPT;
1759 pp->kvmInSE =
p->kvmInSE;
1770 if (
flags & OS::TGT_CLONE_PARENT_SETTID) {
1771 BufferArg ptidBuf(ptidPtr,
sizeof(
long));
1772 long *ptid = (
long *)ptidBuf.
bufferPtr();
1777 if (
flags & OS::TGT_CLONE_THREAD) {
1785 p->clone(tc, ctc, cp,
flags);
1787 if (
flags & OS::TGT_CLONE_THREAD) {
1790 }
else if (
flags & OS::TGT_SIGCHLD) {
1794 if (
flags & OS::TGT_CLONE_CHILD_SETTID) {
1795 BufferArg ctidBuf(ctidPtr,
sizeof(
long));
1796 long *ctid = (
long *)ctidBuf.
bufferPtr();
1801 if (
flags & OS::TGT_CLONE_CHILD_CLEARTID)
1806 OS::archClone(
flags,
p, cp, tc, ctc, newStack, tlsPtr);
1812 if (
flags & OS::TGT_CLONE_VFORK) {
1829 uint64_t new_stack = cl_args->stack + cl_args->stack_size;
1830 uint64_t
flags = cl_args->flags;
1860 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1863 int sim_fd = ffdp->getSimFD();
1865 struct statfs hostBuf;
1866 int result = fstatfs(sim_fd, &hostBuf);
1880 int tgt_fd, uint64_t tiov_base,
1881 typename OS::size_t
count)
1885 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1888 int sim_fd = ffdp->getSimFD();
1891 typename OS::tgt_iovec tiov[
count];
1892 struct iovec hiov[
count];
1893 for (
typename OS::size_t
i = 0;
i <
count; ++
i) {
1894 prox.
readBlob(tiov_base + (
i *
sizeof(
typename OS::tgt_iovec)),
1895 &tiov[
i],
sizeof(
typename OS::tgt_iovec));
1896 hiov[
i].iov_len =
gtoh(tiov[
i].iov_len, OS::byteOrder);
1897 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1900 int result = readv(sim_fd, hiov,
count);
1901 int local_errno = errno;
1903 for (
typename OS::size_t
i = 0;
i <
count; ++
i) {
1906 hiov[
i].iov_base, hiov[
i].iov_len);
1908 delete [] (
char *)hiov[
i].iov_base;
1911 return (result == -1) ? -local_errno : result;
1918 int tgt_fd, uint64_t tiov_base,
1919 typename OS::size_t
count)
1923 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1926 int sim_fd = hbfdp->getSimFD();
1929 struct iovec hiov[
count];
1930 for (
typename OS::size_t
i = 0;
i <
count; ++
i) {
1931 typename OS::tgt_iovec tiov;
1933 prox.
readBlob(tiov_base +
i*
sizeof(
typename OS::tgt_iovec),
1934 &tiov,
sizeof(
typename OS::tgt_iovec));
1935 hiov[
i].iov_len =
gtoh(tiov.iov_len, OS::byteOrder);
1936 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1937 prox.
readBlob(
gtoh(tiov.iov_base, OS::byteOrder), hiov[
i].iov_base,
1941 int result = writev(sim_fd, hiov,
count);
1943 for (
typename OS::size_t
i = 0;
i <
count; ++
i)
1944 delete [] (
char *)hiov[
i].iov_base;
1946 return (result == -1) ? -errno : result;
1953 VPtr<> start,
typename OS::size_t length,
int prot,
1954 int tgt_flags,
int tgt_fd,
typename OS::off_t
offset)
1959 if (start & (page_bytes - 1) ||
1960 offset & (page_bytes - 1) ||
1961 (tgt_flags & OS::TGT_MAP_PRIVATE &&
1962 tgt_flags & OS::TGT_MAP_SHARED) ||
1963 (!(tgt_flags & OS::TGT_MAP_PRIVATE) &&
1964 !(tgt_flags & OS::TGT_MAP_SHARED)) ||
1969 if ((
prot & PROT_WRITE) && (tgt_flags & OS::TGT_MAP_SHARED)) {
1990 warn_once(
"mmap: writing to shared mmap region is currently "
1991 "unsupported. The write succeeds on the target, but it "
1992 "will not be propagated to the host or shared mappings");
1995 length =
roundUp(length, page_bytes);
1998 if (!(tgt_flags & OS::TGT_MAP_ANONYMOUS)) {
1999 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
2001 auto dfdp = std::dynamic_pointer_cast<DeviceFDEntry>(fdep);
2004 return emul_driver->
mmap(tc, start, length,
prot, tgt_flags,
2008 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
2011 sim_fd = ffdp->getSimFD();
2022 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
2023 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
2025 ffdp->getFileName()));
2027 ffdp->getFileName());
2030 Addr offset = lib->buildImage().minAddr() + start;
2039 if (!(tgt_flags & OS::TGT_MAP_FIXED)) {
2047 if (!(start &&
p->memState->isUnmapped(start, length))) {
2051 start =
p->memState->extendMmap(length);
2056 start, start + length - 1);
2063 if (tgt_flags & OS::TGT_MAP_FIXED) {
2068 p->memState->unmapRegion(start, length);
2074 std::string region_name;
2075 if (tgt_flags & OS::TGT_MAP_ANONYMOUS) {
2076 region_name =
"anon";
2078 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
2079 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
2080 region_name = ffdp->getFileName();
2087 p->memState->mapRegion(start, length, region_name, sim_fd,
offset);
2099 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
2102 int sim_fd = ffdp->getSimFD();
2110 return (bytes_read == -1) ? -errno : bytes_read;
2120 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
2123 int sim_fd = ffdp->getSimFD();
2128 int bytes_written = pwrite(sim_fd, bufArg.
bufferPtr(), nbytes,
offset);
2130 return (bytes_written == -1) ? -errno : bytes_written;
2137 VPtr<> start,
typename OS::size_t length,
int prot,
2138 int tgt_flags,
int tgt_fd,
typename OS::off_t
offset)
2142 tgt_fd,
offset * page_size);
2151 const ByteOrder
bo = OS::byteOrder;
2153 case OS::TGT_RLIMIT_STACK:
2155 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
2156 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2157 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2160 case OS::TGT_RLIMIT_DATA:
2162 rlp->rlim_cur = rlp->rlim_max = 256 * 1024 * 1024;
2163 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2164 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2167 case OS::TGT_RLIMIT_NPROC:
2169 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2170 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2174 warn(
"getrlimit: unimplemented resource %d", resource);
2188 warn(
"prlimit: ignoring rlimits for nonzero pid");
2192 warn(
"prlimit: ignoring new rlimit");
2194 const ByteOrder
bo = OS::byteOrder;
2196 case OS::TGT_RLIMIT_STACK:
2198 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
2199 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2200 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2202 case OS::TGT_RLIMIT_DATA:
2204 rlp->rlim_cur = rlp->rlim_max = 256*1024*1024;
2205 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2206 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2209 warn(
"prlimit: unimplemented resource %d", resource);
2225 tp->tv_sec =
htog(tp->tv_sec, OS::byteOrder);
2226 tp->tv_nsec =
htog(tp->tv_nsec, OS::byteOrder);
2252 tp->tv_sec =
htog(tp->tv_sec, OS::byteOrder);
2253 tp->tv_usec =
htog(tp->tv_usec, OS::byteOrder);
2262 int dirfd,
VPtr<> pathname,
VPtr<
typename OS::timeval [2]> tp)
2273 struct timeval hostTimeval[2];
2274 for (
int i = 0;
i < 2; ++
i) {
2275 hostTimeval[
i].tv_sec =
gtoh((*tp)[
i].tv_sec, OS::byteOrder);
2276 hostTimeval[
i].tv_usec =
gtoh((*tp)[
i].tv_usec, OS::byteOrder);
2283 int result = utimes(path.c_str(), hostTimeval);
2295 VPtr<
typename OS::timeval [2]> tp)
2312 if (access(path.c_str(), F_OK) == -1)
2318 for (
int inc = 0; ; inc++) {
2320 b.copyIn(mem_proxy);
2322 if (!*(
Addr*)
b.bufferPtr())
2325 vect.push_back(std::string());
2334 if (!
p->vforkContexts.empty()) {
2346 ProcessParams *pp =
new ProcessParams();
2347 pp->executable = path;
2348 read_in(pp->cmd, mem_proxy, argv_mem_loc);
2349 read_in(pp->env, mem_proxy, envp_mem_loc);
2351 pp->egid =
p->egid();
2352 pp->euid =
p->euid();
2354 pp->ppid =
p->ppid();
2356 pp->input.assign(
"cin");
2357 pp->output.assign(
"cout");
2358 pp->errout.assign(
"cerr");
2359 pp->cwd.assign(
p->tgtCwd);
2360 pp->system =
p->system;
2361 pp->release =
p->release;
2370 p->system->PIDs.erase(
p->pid());
2371 Process *new_p = pp->create();
2380 new_p->
fds =
p->fds;
2381 for (
int i = 0;
i < new_p->
fds->getSize();
i++) {
2382 std::shared_ptr<FDEntry> fdep = (*new_p->
fds)[
i];
2383 if (fdep && fdep->getCOE())
2384 new_p->
fds->closeFDEntry(
i);
2406 rup->ru_utime.tv_sec = 0;
2407 rup->ru_utime.tv_usec = 0;
2408 rup->ru_stime.tv_sec = 0;
2409 rup->ru_stime.tv_usec = 0;
2417 rup->ru_inblock = 0;
2418 rup->ru_oublock = 0;
2421 rup->ru_nsignals = 0;
2426 case OS::TGT_RUSAGE_SELF:
2428 rup->ru_utime.tv_sec =
htog(rup->ru_utime.tv_sec, OS::byteOrder);
2429 rup->ru_utime.tv_usec =
htog(rup->ru_utime.tv_usec, OS::byteOrder);
2432 case OS::TGT_RUSAGE_CHILDREN:
2439 warn(
"getrusage() only supports RUSAGE_SELF. Parameter %d ignored.",
2453 bufp->tms_utime = clocks;
2454 bufp->tms_stime = 0;
2455 bufp->tms_cutime = 0;
2456 bufp->tms_cstime = 0;
2459 bufp->tms_utime =
htog(bufp->tms_utime, OS::byteOrder);
2470 typename OS::time_t sec, usec;
2476 typename OS::time_t
t = sec;
2477 t =
htog(
t, OS::byteOrder);
2478 p.writeBlob(taddr, &
t, (
int)
sizeof(
typename OS::time_t));
2504 for (
auto *tc: sys->
threads) {
2506 if (temp->
pid() == tid) {
2512 if (sig != 0 && sig != OS::TGT_SIGABRT)
2515 if (tgt_proc ==
nullptr)
2518 if (tgid != -1 && tgt_proc->
tgid() != tgid)
2521 if (sig == OS::TGT_SIGABRT)
2538 auto sfdp = std::make_shared<SocketFDEntry>(sim_fd,
domain,
type,
prot);
2539 int tgt_fd =
p->fds->allocFD(sfdp);
2558 auto sfdp1 = std::make_shared<SocketFDEntry>(fds[0],
domain,
type,
prot);
2559 fds[0] =
p->fds->allocFD(sfdp1);
2560 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1],
domain,
type,
prot);
2561 fds[1] =
p->fds->allocFD(sfdp2);
2585 FD_ZERO(&readfds_h);
2587 FD_ZERO(&writefds_h);
2589 FD_ZERO(&errorfds_h);
2601 std::map<int, int> trans_map;
2602 auto try_add_host_set = [&](
typename OS::fd_set *tgt_set_entry,
2603 fd_set *hst_set_entry,
2611 if (FD_ISSET(iter, (fd_set *)tgt_set_entry)) {
2617 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[iter]);
2620 auto sim_fd = hbfdp->getSimFD();
2627 trans_map[sim_fd] = iter;
2634 nfds_h = std::max(nfds_h - 1, sim_fd + 1);
2640 FD_SET(sim_fd, hst_set_entry);
2645 for (
int i = 0;
i < nfds;
i++) {
2647 bool ebadf = try_add_host_set(readfds, &readfds_h,
i);
2652 bool ebadf = try_add_host_set(writefds, &writefds_h,
i);
2657 bool ebadf = try_add_host_set(errorfds, &errorfds_h,
i);
2671 timeout->tv_sec = 0;
2672 timeout->tv_usec = 0;
2674 retval = select(nfds_h,
2675 readfds ? &readfds_h :
nullptr,
2676 writefds ? &writefds_h :
nullptr,
2677 errorfds ? &errorfds_h :
nullptr,
2678 (timeval *)(
typename OS::timeval *)timeout);
2687 struct timeval tv = { 0, 0 };
2689 retval = select(nfds_h,
2690 readfds ? &readfds_h :
nullptr,
2691 readfds ? &writefds_h :
nullptr,
2692 readfds ? &errorfds_h :
nullptr,
2702 if (sig.receiver ==
p)
2712 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)readfds));
2715 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)writefds));
2718 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)errorfds));
2726 for (
int i = 0;
i < nfds_h;
i++) {
2727 if (readfds && FD_ISSET(
i, &readfds_h))
2728 FD_SET(trans_map[
i],
2729 reinterpret_cast<fd_set *
>(
2730 (
typename OS::fd_set *)readfds));
2732 if (writefds && FD_ISSET(
i, &writefds_h))
2733 FD_SET(trans_map[
i],
2734 reinterpret_cast<fd_set *
>(
2735 (
typename OS::fd_set *)writefds));
2737 if (errorfds && FD_ISSET(
i, &errorfds_h))
2738 FD_SET(trans_map[
i],
2739 reinterpret_cast<fd_set *
>(
2740 (
typename OS::fd_set *)errorfds));
2749 int tgt_fd,
VPtr<> buf_ptr,
int nbytes)
2753 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
2756 int sim_fd = hbfdp->getSimFD();
2760 pfd.events = POLLIN | POLLPRI;
2761 if ((poll(&pfd, 1, 0) == 0)
2762 && !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK))
2766 int bytes_read = read(sim_fd, buf_arg.
bufferPtr(), nbytes);
2771 return (bytes_read == -1) ? -errno : bytes_read;
2777 int tgt_fd,
VPtr<> buf_ptr,
int nbytes)
2781 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
2784 int sim_fd = hbfdp->getSimFD();
2791 pfd.events = POLLOUT;
2799 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(hbfdp);
2800 if (ffdp && (ffdp->getFileName() !=
"/dev/random")) {
2801 if (!poll(&pfd, 1, 0) && !(ffdp->getFlags() & OS::TGT_O_NONBLOCK))
2805 int bytes_written = write(sim_fd, buf_arg.
bufferPtr(), nbytes);
2807 if (bytes_written != -1)
2810 return (bytes_written == -1) ? -errno : bytes_written;
2816 pid_t pid,
VPtr<> statPtr,
int options,
VPtr<> rusagePtr)
2821 DPRINTF_SYSCALL(Verbose,
"wait4: rusage pointer provided %lx, however "
2822 "functionality not supported. Ignoring rusage pointer.\n",
2836 if (iter->receiver ==
p) {
2838 if ((iter->sender->pgid() == -pid)
2839 && (iter->signalValue == OS::TGT_SIGCHLD))
2841 }
else if (pid == -1) {
2842 if (iter->signalValue == OS::TGT_SIGCHLD)
2844 }
else if (pid == 0) {
2845 if ((iter->sender->pgid() ==
p->pgid())
2846 && (iter->signalValue == OS::TGT_SIGCHLD))
2849 if ((iter->sender->pid() == pid)
2850 && (iter->signalValue == OS::TGT_SIGCHLD))
2860 const int EXITED = 0;
2861 BufferArg statusBuf(statPtr,
sizeof(
int));
2866 pid_t retval = iter->sender->pid();
2884 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
2887 int sim_fd = sfdp->getSimFD();
2897 pfd.events = POLLIN | POLLPRI;
2898 if ((poll(&pfd, 1, 0) == 0) && !(sfdp->getFlags() & OS::TGT_O_NONBLOCK))
2902 lenBufPtr =
new BufferArg(lenPtr,
sizeof(socklen_t));
2904 memcpy(&addrLen, (socklen_t *)lenBufPtr->
bufferPtr(),
2909 addrBufPtr =
new BufferArg(addrPtr,
sizeof(
struct sockaddr));
2911 memcpy(&
sa, (
struct sockaddr *)addrBufPtr->
bufferPtr(),
2912 sizeof(
struct sockaddr));
2915 host_fd = accept(sim_fd, &
sa, &addrLen);
2927 *(socklen_t *)lenBufPtr->
bufferPtr() = addrLen;
2932 auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain,
2933 sfdp->_type, sfdp->_protocol);
2934 return p->fds->allocFD(afdp);
2941 unsigned initval,
int in_flags)
2943#if defined(__linux__)
2946 int sim_fd = eventfd(initval, in_flags);
2950 bool cloexec = in_flags & OS::TGT_O_CLOEXEC;
2952 int flags = cloexec ? OS::TGT_O_CLOEXEC : 0;
2953 flags |= (in_flags & OS::TGT_O_NONBLOCK) ? OS::TGT_O_NONBLOCK : 0;
2955 auto hbfdp = std::make_shared<HBFDEntry>(
flags, sim_fd, cloexec);
2956 int tgt_fd =
p->fds->allocFD(hbfdp);
2968 pid_t pid,
typename OS::size_t cpusetsize,
2971#if defined(__linux__)
2976 BufferArg maskBuf(cpu_set_mask, cpusetsize);
2979 CPU_SET(
i, (cpu_set_t *)maskBuf.
bufferPtr());
2993 int tgt_fd,
VPtr<> buf_ptr,
typename OS::size_t buf_len,
2998 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
3001 int sim_fd = sfdp->getSimFD();
3009 socklen_t addr_len = 0;
3010 if (addrlen_ptr != 0) {
3012 BufferArg addrlen_buf(addrlen_ptr,
sizeof(socklen_t));
3013 addrlen_buf.
copyIn(proxy);
3014 addr_len = *((socklen_t *)addrlen_buf.
bufferPtr());
3017 struct sockaddr
sa, *sap = NULL;
3018 if (addr_len != 0) {
3021 memcpy(&
sa, (
struct sockaddr *)addr_buf.
bufferPtr(),
3022 sizeof(
struct sockaddr));
3026 ssize_t recvd_size = recvfrom(sim_fd,
3028 buf_len,
flags, sap, (socklen_t *)&addr_len);
3030 if (recvd_size == -1)
3044 if (addr_len != 0) {
3045 BufferArg addrlen_buf(addrlen_ptr,
sizeof(socklen_t));
3046 *(socklen_t *)addrlen_buf.
bufferPtr() = addr_len;
3054template <
typename OS>
3057 int tgt_fd,
VPtr<> buf_ptr,
typename OS::size_t buf_len,
int flags,
3058 VPtr<> addr_ptr, socklen_t addr_len)
3062 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
3065 int sim_fd = sfdp->getSimFD();
3071 struct sockaddr
sa, *sap =
nullptr;
3072 memset(&
sa, 0,
sizeof(sockaddr));
3073 if (addr_len != 0) {
3076 memcpy(&
sa, (sockaddr*)addr_buf.
bufferPtr(), addr_len);
3080 ssize_t sent_size = sendto(sim_fd,
3082 buf_len,
flags, sap, (socklen_t)addr_len);
3084 return (sent_size == -1) ? -errno : sent_size;
3088template <
typename OS>
3091 typename OS::size_t length)
3099 if (
p->pTable->pageOffset(start))
3102 length =
roundUp(length,
p->pTable->pageSize());
3104 p->memState->unmapRegion(start, length);
3110template <
typename OS>
3113 int tgt_fd,
int mode,
typename OS::off_t
offset,
3114 typename OS::off_t
len)
3116#if defined(__linux__)
3119 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
3122 int sim_fd = ffdp->getSimFD();
3135template <
typename OS>
3138 typename OS::off_t length)
3149 int result = truncate(path.c_str(), length);
3150 return (result == -1) ? -errno : result;
3154template <
typename OS>
3157 typename OS::off_t length)
3161 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
3164 int sim_fd = ffdp->getSimFD();
3166 int result = ftruncate(sim_fd, length);
3167 return (result == -1) ? -errno : result;
3170template <
typename OS>
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
bool copyIn(const PortProxy &memproxy)
copy data into simulator space (read from target memory)
bool copyOut(const PortProxy &memproxy)
copy data out of simulator space (write to target memory)
BufferArg represents an untyped buffer in target user space that is passed by reference to an (emulat...
void * bufferPtr()
Return a pointer to the internal simulator-space buffer.
EmulatedDriver is an abstract base class for fake SE-mode device drivers.
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...
virtual int open(ThreadContext *tc, int mode, int flags)=0
Abstract method, invoked when the user program calls open() on the device driver.
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...
FutexMap class holds a map of all futexes used in the system.
void suspend_bitset(Addr addr, uint64_t tgid, ThreadContext *tc, int bitmask)
int requeue(Addr addr1, uint64_t tgid, int count, int count2, Addr addr2)
This operation wakes a given number (val) of waiters.
void suspend(Addr addr, uint64_t tgid, ThreadContext *tc)
Inserts a futex into the map with one waiting TC.
int wakeup(Addr addr, uint64_t tgid, int count)
Wakes up at most count waiting threads on a futex.
int wakeup_bitset(Addr addr, uint64_t tgid, int bitmask)
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
This object is a proxy for a port or other object which implements the functional response protocol,...
void readBlob(Addr addr, void *p, uint64_t size) const
Higher level interfaces based on the above.
void writeBlob(Addr addr, const void *p, uint64_t size) const
Same as tryWriteBlob, but insists on success.
bool tryReadString(std::string &str, Addr addr) const
Reads the string at guest address addr into the std::string str.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
std::shared_ptr< FDArray > fds
void assignThreadContext(ContextID context_id)
std::string checkPathRedirect(const std::string &filename)
Redirect file path if it matches any keys initialized by system object.
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
void revokeThreadContext(int context_id)
After delegating a thread context to a child process no longer should relate to the ThreadContext.
EmulationPageTable * pTable
uint64_t childClearTID
Calls a futex wakeup at the address specified by this pointer when this process exits.
This class provides the wrapper interface for the system call implementations which are defined in th...
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...
This class represents the return value from an emulated system call, including any errno setting.
static SyscallReturn retry()
Pseudo-constructor to create an instance with the retry flag set.
bool successful() const
Was the system call successful?
ThreadContext * findFree()
std::list< BasicSignal > signalList
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void activate()=0
Set the status to Active.
virtual System * getSystemPtr()=0
virtual void clearArchRegs()=0
virtual void setProcessPtr(Process *p)=0
@ Suspended
Temporarily inactive.
virtual const PCStateBase & pcState() const =0
virtual int threadId() const =0
virtual Status status() const =0
virtual Process * getProcessPtr()=0
virtual ContextID contextId() const =0
virtual void suspend()=0
Set the status to Suspended.
void setUseForClone(bool new_val)
virtual int cpuId() const =0
TypedBufferArg is a class template; instances of this template represent typed buffers in target user...
bool insert(const Symbol &symbol)
Insert a new symbol in the table if it does not already exist.
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
#define fatal(...)
This implements a cprintf based fatal() function.
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
ObjectFile * createObjectFile(const std::string &fname, bool raw)
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
SyscallReturn linkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> new_pathname)
Target link() handler.
SyscallReturn getppidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getppid() handler.
SyscallReturn exitGroupFunc(SyscallDesc *desc, ThreadContext *tc, int status)
Target exit_group() handler: terminate simulation. (exit all threads)
SyscallReturn gettidFunc(SyscallDesc *desc, ThreadContext *tc)
Target gettid() handler.
SyscallReturn getrandomFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, typename OS::size_t count, unsigned int flags)
SyscallReturn pread64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> bufPtr, int nbytes, int offset)
SyscallReturn recvmsgFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> msgPtr, int flags)
SyscallReturn fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr< typename OS::tgt_stat64 > tgt_stat)
Target fstat64() handler.
SyscallReturn wait4Func(SyscallDesc *desc, ThreadContext *tc, pid_t pid, VPtr<> statPtr, int options, VPtr<> rusagePtr)
SyscallReturn clock_gettimeFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, VPtr< typename OS::timespec > tp)
Target clock_gettime() function.
void warnUnsupportedOS(std::string syscall_name)
SyscallReturn brkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> new_brk)
Target brk() handler: set brk address.
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.
SyscallReturn pipe2Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> tgt_addr, int flags)
Target pipe() handler.
SyscallReturn getpidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpid() handler.
bool startswith(const char *s, const char *prefix)
Return true if 's' starts with the prefix string 'prefix'.
SyscallReturn chdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
Target chdir() handler.
SyscallReturn fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr< typename OS::tgt_stat > tgt_stat)
Target fstat() handler.
SyscallReturn truncate64Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, int64_t length)
Target truncate64() handler.
SyscallReturn getuidFunc(SyscallDesc *desc, ThreadContext *tc)
SyscallReturn getrusageFunc(SyscallDesc *desc, ThreadContext *tc, int who, VPtr< typename OS::rusage > rup)
Target getrusage() function.
SyscallReturn cloneFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack, VPtr<> ptidPtr, VPtr<> ctidPtr, VPtr<> tlsPtr)
SyscallReturn readFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int nbytes)
SyscallReturn pipePseudoFunc(SyscallDesc *desc, ThreadContext *tc)
Pseudo Funcs - These functions use a different return convension, returning a second value in a regis...
SyscallReturn recvfromFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, typename OS::size_t buf_len, int flags, VPtr<> addr_ptr, VPtr<> addrlen_ptr)
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)
SyscallReturn utimesFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::timeval[2]> tp)
Target utimes() handler.
SyscallReturn socketFunc(SyscallDesc *desc, ThreadContext *tc, int domain, int type, int prot)
SyscallReturn chownFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, uint32_t owner, uint32_t group)
Target chown() handler.
SyscallReturn statFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_stat > tgt_stat)
Target stat() handler.
void copyOutStatBuf(TgtStatPtr tgt, HostStatPtr host, bool fakeTTY=false)
SyscallReturn renameImpl(SyscallDesc *desc, ThreadContext *tc, std::string old_name, std::string new_name)
SyscallReturn doClone(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack, VPtr<> ptidPtr, VPtr<> ctidPtr, VPtr<> tlsPtr)
SyscallReturn chmodFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
Target chmod() handler.
SyscallReturn mknodImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, mode_t mode, dev_t dev)
SyscallReturn renameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> oldpath, VPtr<> newpath)
Target rename() handler.
SyscallReturn mknodFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode, dev_t dev)
Target mknod() 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.
Tick curTick()
The universal simulation clock.
SyscallReturn setTidAddressFunc(SyscallDesc *desc, ThreadContext *tc, uint64_t tidPtr)
Target set_tid_address() handler.
SyscallReturn setpgidFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int pgid)
Target setpgid() handler.
SyscallReturn truncateFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, typename OS::off_t length)
Target truncate() handler.
SyscallReturn geteuidFunc(SyscallDesc *desc, ThreadContext *tc)
Target geteuid() handler.
SyscallReturn getcwdFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, unsigned long size)
Target getcwd() handler.
SyscallReturn symlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> new_pathname)
Target symlink() handler.
SyscallReturn atSyscallPath(ThreadContext *tc, int dirfd, std::string &path)
ProxyPtr< T, SETranslatingPortProxy > VPtr
SyscallReturn unlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
Target unlink() handler.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
T gtoh(T value, ByteOrder guest_byte_order)
SyscallReturn accessImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, mode_t mode)
SyscallReturn sysinfoFunc(SyscallDesc *desc, ThreadContext *tc, VPtr< typename OS::tgt_sysinfo > sysinfo)
Target sysinfo() handler.
SyscallReturn fchownatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, uint32_t owner, uint32_t group, int flags)
Target fchownat() handler.
SyscallReturn chownImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, uint32_t owner, uint32_t group)
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, int flags)
Target unlinkat() handler.
SyscallReturn pipeFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> tgt_addr)
Target pipe() handler.
SyscallReturn prlimitFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int resource, VPtr<> n, VPtr< typename OS::rlimit > rlp)
SyscallReturn clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, VPtr< typename OS::timespec > tp)
Target clock_getres() function.
void copyOutStat64Buf(TgtStatPtr tgt, HostStatPtr host, bool fakeTTY=false)
SyscallReturn faccessatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, int mode)
Target facessat() handler.
SyscallReturn getsockoptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int level, int optname, VPtr<> valPtr, VPtr<> lenPtr)
SyscallReturn getrlimitFunc(SyscallDesc *desc, ThreadContext *tc, unsigned resource, VPtr< typename OS::rlimit > rlp)
Target getrlimit() handler.
SyscallReturn mknodatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, mode_t mode, dev_t dev)
Target mknodat() handler.
SyscallReturn fallocateFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int mode, typename OS::off_t offset, typename OS::off_t len)
SyscallReturn fcntl64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd)
Target fcntl64() handler.
SyscallReturn futimesatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, VPtr< typename OS::timeval[2]> tp)
Target futimesat() handler.
SyscallReturn ignoreWarnOnceFunc(SyscallDesc *desc, ThreadContext *tc)
Like above, but only prints a warning once per syscall desc it's used with.
SyscallReturn socketpairFunc(SyscallDesc *desc, ThreadContext *tc, int domain, int type, int prot, VPtr<> svPtr)
void copyOutStatfsBuf(TgtStatPtr tgt, HostStatPtr host)
SyscallReturn ftruncateFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, typename OS::off_t length)
Target ftruncate() handler.
SyscallReturn statfsFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_statfs > tgt_stat)
Target statfs() handler.
SyscallReturn setsockoptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int level, int optname, VPtr<> valPtr, socklen_t len)
SyscallReturn getpagesizeFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpagesize() handler.
SyscallReturn lstatFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_stat > tgt_stat)
Target lstat() handler.
SyscallReturn rmdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname)
SyscallReturn mkdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
Target mkdir() handler.
SyscallReturn readlinkatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, VPtr<> buf_ptr, typename OS::size_t bufsiz)
Target readlinkat() handler.
SyscallReturn getpgrpFunc(SyscallDesc *desc, ThreadContext *tc)
Target getpgrpFunc() handler.
void copyOutStatxBuf(TgtStatPtr tgt, HostStatPtr host, bool fakeTTY=false)
SyscallReturn eventfdFunc(SyscallDesc *desc, ThreadContext *tc, unsigned initval, int in_flags)
Target eventfd() function.
SyscallReturn unlinkImpl(SyscallDesc *desc, ThreadContext *tc, std::string path)
SyscallReturn dupFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
FIXME: The file description is not shared among file descriptors created with dup.
SyscallReturn listenFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int backlog)
SyscallReturn ftruncate64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int64_t length)
Target ftruncate64() handler.
SyscallReturn fchmodatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, mode_t mode)
Target chmod() handler.
SyscallReturn openatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_dirfd, VPtr<> pathname, int tgt_flags, int mode)
Target open() handler.
SyscallReturn fchownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t owner, uint32_t group)
Target fchown() handler.
SyscallReturn munmapFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> start, typename OS::size_t length)
Target munmap() handler.
SyscallReturn readlinkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> buf_ptr, typename OS::size_t bufsiz)
Target readlink() handler.
void getElapsedTimeMicro(T1 &sec, T2 &usec)
Helper function to convert current elapsed time to seconds and microseconds.
const unsigned seconds_since_epoch
Approximate seconds since the epoch (1/1/1970).
SyscallReturn timesFunc(SyscallDesc *desc, ThreadContext *tc, VPtr< typename OS::tms > bufp)
Target times() function.
SyscallReturn fcntlFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int cmd, guest_abi::VarArgs< int > varargs)
Target fcntl() handler.
SyscallReturn openFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, int tgt_flags, int mode)
Target open() handler.
void getElapsedTimeNano(T1 &sec, T2 &nsec)
Helper function to convert current elapsed time to seconds and nanoseconds.
T htog(T value, ByteOrder guest_byte_order)
SyscallReturn schedGetaffinityFunc(SyscallDesc *desc, ThreadContext *tc, pid_t pid, typename OS::size_t cpusetsize, VPtr<> cpu_set_mask)
Target sched_getaffinity.
SyscallReturn bindFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int addrlen)
SyscallReturn pollFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> fdsPtr, int nfds, int tmout)
SyscallReturn getegidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getegid() handler.
SyscallReturn timeFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> taddr)
Target time() function.
SyscallReturn newfstatatFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, VPtr< typename OS::tgt_stat64 > tgt_stat, int flags)
Target newfstatat() handler.
SyscallReturn fchmodFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint32_t mode)
Target fchmod() handler.
SyscallReturn shutdownFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, int how)
Target shutdown() handler.
SyscallReturn renameatFunc(SyscallDesc *desc, ThreadContext *tc, int olddirfd, VPtr<> oldpath, int newdirfd, VPtr<> newpath)
Target renameat() handler.
SyscallReturn getcpuFunc(SyscallDesc *desc, ThreadContext *tc, VPtr< uint32_t > cpu, VPtr< uint32_t > node, VPtr< uint32_t > tcache)
SyscallReturn getsocknameFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> addrPtr, VPtr<> lenPtr)
SyscallReturn clone3Func(SyscallDesc *desc, ThreadContext *tc, VPtr< typename OS::tgt_clone_args > cl_args, RegVal size)
SyscallReturn mkdirImpl(SyscallDesc *desc, ThreadContext *tc, std::string path, mode_t mode)
SyscallReturn ioctlFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, unsigned req, VPtr<> addr)
Target ioctl() handler.
SyscallReturn writevFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t tiov_base, typename OS::size_t count)
Target writev() handler.
SyscallReturn getpeernameFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> sockAddrPtr, VPtr<> addrlenPtr)
SyscallReturn lseekFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t offs, int whence)
Target lseek() handler.
SyscallReturn unimplementedFunc(SyscallDesc *desc, ThreadContext *tc)
Handler for unimplemented syscalls that we haven't thought about.
SyscallReturn gethostnameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, int name_len)
Target gethostname() handler.
SyscallReturn accessFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, mode_t mode)
Target access() handler.
SyscallReturn tgkillFunc(SyscallDesc *desc, ThreadContext *tc, int tgid, int tid, int sig)
SyscallReturn sendmsgFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> msgPtr, int flags)
SyscallReturn cloneBackwardsFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack, VPtr<> ptidPtr, VPtr<> tlsPtr, VPtr<> ctidPtr)
SyscallReturn mremapFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> start, uint64_t old_length, uint64_t new_length, uint64_t flags, guest_abi::VarArgs< uint64_t > varargs)
Target mremap() handler.
SyscallReturn lstat64Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_stat64 > tgt_stat)
Target lstat64() handler.
SyscallReturn pwrite64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> bufPtr, int nbytes, int offset)
SyscallReturn fstatat64Func(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, VPtr< typename OS::tgt_stat64 > tgt_stat)
Target fstatat64() handler.
SyscallReturn ignoreFunc(SyscallDesc *desc, ThreadContext *tc)
Handler for unimplemented syscalls that we never intend to implement (signal handling,...
SyscallReturn rmdirImpl(SyscallDesc *desc, ThreadContext *tc, std::string path)
SyscallReturn acceptFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> addrPtr, VPtr<> lenPtr)
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 fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr< typename OS::tgt_statfs > tgt_stat)
Target fstatfs() handler.
SyscallReturn statxFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, int flags, unsigned int mask, VPtr< typename OS::tgt_statx > tgt_statx)
Target statx() handler.
SyscallReturn stat64Func(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr< typename OS::tgt_stat64 > tgt_stat)
Target stat64() handler.
SyscallReturn connectFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int addrlen)
SyscallReturn execveFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname, VPtr<> argv_mem_loc, VPtr<> envp_mem_loc)
SyscallReturn exitFunc(SyscallDesc *desc, ThreadContext *tc, int status)
Target exit() handler: terminate current context.
SyscallReturn dup2Func(SyscallDesc *desc, ThreadContext *tc, int old_tgt_fd, int new_tgt_fd)
Target dup2() handler.
SyscallReturn getgidFunc(SyscallDesc *desc, ThreadContext *tc)
Target getgid() handler.
SyscallReturn writeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, int nbytes)
SyscallReturn closeFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd)
Target close() handler.
SyscallReturn umaskFunc(SyscallDesc *desc, ThreadContext *tc)
Target umask() 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 sendtoFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, VPtr<> buf_ptr, typename OS::size_t buf_len, int flags, VPtr<> addr_ptr, socklen_t addr_len)
SyscallReturn readvFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, uint64_t tiov_base, typename OS::size_t count)
Target readv() handler.
SyscallReturn mkdiratFunc(SyscallDesc *desc, ThreadContext *tc, int dirfd, VPtr<> pathname, mode_t mode)
Target mkdirat() handler.
Declarations of a non-full system Page Table.
#define DPRINTF_SYSCALL(FLAGEXT, FMT,...)
This macro is intended to help with readability.
This file defines buffer classes used to handle pointer arguments in emulated syscalls.