42#ifndef __SIM_SYSCALL_EMUL_HH__
43#define __SIM_SYSCALL_EMUL_HH__
45#if (defined(__APPLE__) || defined(__OpenBSD__) || \
46 defined(__FreeBSD__) || defined(__CYGWIN__) || \
61#include <sys/eventfd.h>
62#include <sys/statfs.h>
78#include <sys/socket.h>
101#include "params/Process.hh"
112#if defined(__APPLE__) && defined(__MACH__) && !defined(CMSG_ALIGN)
113#define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
114#elif defined(__FreeBSD__) && !defined(CMSG_ALIGN)
115#define CMSG_ALIGN(n) _ALIGN(n)
138SyscallReturn
ignoreFunc(SyscallDesc *desc, ThreadContext *tc);
144SyscallReturn
exitFunc(SyscallDesc *desc, ThreadContext *tc,
int status);
157SyscallReturn
brkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> new_brk);
160SyscallReturn
closeFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd);
163SyscallReturn
lseekFunc(SyscallDesc *desc, ThreadContext *tc,
164 int tgt_fd, uint64_t offs,
int whence);
167SyscallReturn
_llseekFunc(SyscallDesc *desc, ThreadContext *tc,
168 int tgt_fd, uint64_t offset_high,
169 uint32_t offset_low, VPtr<> result_ptr,
int whence);
172SyscallReturn
shutdownFunc(SyscallDesc *desc, ThreadContext *tc,
173 int tgt_fd,
int how);
177 VPtr<> buf_ptr,
int name_len);
180SyscallReturn
getcwdFunc(SyscallDesc *desc, ThreadContext *tc,
181 VPtr<> buf_ptr,
unsigned long size);
184SyscallReturn
unlinkFunc(SyscallDesc *desc, ThreadContext *tc,
186SyscallReturn
unlinkImpl(SyscallDesc *desc, ThreadContext *tc,
190SyscallReturn
linkFunc(SyscallDesc *desc, ThreadContext *tc,
191 VPtr<> pathname, VPtr<> new_pathname);
194SyscallReturn
symlinkFunc(SyscallDesc *desc, ThreadContext *tc,
195 VPtr<> pathname, VPtr<> new_pathname);
198SyscallReturn
mkdirFunc(SyscallDesc *desc, ThreadContext *tc,
199 VPtr<> pathname, mode_t
mode);
200SyscallReturn
mkdirImpl(SyscallDesc *desc, ThreadContext *tc,
201 std::string path, mode_t
mode);
204SyscallReturn
mknodFunc(SyscallDesc *desc, ThreadContext *tc,
205 VPtr<> pathname, mode_t
mode, dev_t dev);
206SyscallReturn
mknodImpl(SyscallDesc *desc, ThreadContext *tc,
207 std::string path, mode_t
mode, dev_t dev);
210SyscallReturn
chdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname);
213SyscallReturn
rmdirFunc(SyscallDesc *desc, ThreadContext *tc,
215SyscallReturn
rmdirImpl(SyscallDesc *desc, ThreadContext *tc,
219SyscallReturn
renameFunc(SyscallDesc *desc, ThreadContext *tc,
220 VPtr<> oldpath, VPtr<> newpath);
221SyscallReturn
renameImpl(SyscallDesc *desc, ThreadContext *tc,
222 std::string oldpath, std::string newpath);
226 VPtr<> pathname, int64_t length);
230 int tgt_fd, int64_t length);
233SyscallReturn
umaskFunc(SyscallDesc *desc, ThreadContext *tc);
236SyscallReturn
gettidFunc(SyscallDesc *desc, ThreadContext *tc);
239SyscallReturn
chownFunc(SyscallDesc *desc, ThreadContext *tc,
240 VPtr<> pathname, uint32_t owner, uint32_t group);
241SyscallReturn
chownImpl(SyscallDesc *desc, ThreadContext *tc,
242 std::string path, uint32_t owner, uint32_t group);
245SyscallReturn
getpgrpFunc(SyscallDesc *desc, ThreadContext *tc);
248SyscallReturn
setpgidFunc(SyscallDesc *desc, ThreadContext *tc,
252SyscallReturn
fchownFunc(SyscallDesc *desc, ThreadContext *tc,
253 int tgt_fd, uint32_t owner, uint32_t group);
256SyscallReturn
dupFunc(SyscallDesc *desc, ThreadContext *tc,
260SyscallReturn
dup2Func(SyscallDesc *desc, ThreadContext *tc,
261 int old_tgt_fd,
int new_tgt_fd);
264SyscallReturn
fcntlFunc(SyscallDesc *desc, ThreadContext *tc,
265 int tgt_fd,
int cmd, guest_abi::VarArgs<int> varargs);
268SyscallReturn
fcntl64Func(SyscallDesc *desc, ThreadContext *tc,
269 int tgt_fd,
int cmd);
272SyscallReturn
pipeFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> tgt_addr);
275SyscallReturn
pipe2Func(SyscallDesc *desc, ThreadContext *tc,
276 VPtr<> tgt_addr,
int flags);
279SyscallReturn
getpidFunc(SyscallDesc *desc, ThreadContext *tc);
283 int tgt_fd, VPtr<> sockAddrPtr,
287SyscallReturn
bindFunc(SyscallDesc *desc, ThreadContext *tc,
288 int tgt_fd, VPtr<> buf_ptr,
int addrlen);
291SyscallReturn
listenFunc(SyscallDesc *desc, ThreadContext *tc,
292 int tgt_fd,
int backlog);
295SyscallReturn
connectFunc(SyscallDesc *desc, ThreadContext *tc,
296 int tgt_fd, VPtr<> buf_ptr,
int addrlen);
298#if defined(SYS_getdents)
300SyscallReturn getdentsFunc(SyscallDesc *desc, ThreadContext *tc,
301 int tgt_fd, VPtr<> buf_ptr,
unsigned count);
304#if defined(SYS_getdents64)
306SyscallReturn getdents64Func(SyscallDesc *desc, ThreadContext *tc,
307 int tgt_fd, VPtr<> buf_ptr,
unsigned count);
311SyscallReturn
recvmsgFunc(SyscallDesc *desc, ThreadContext *tc,
312 int tgt_fd, VPtr<> msgPtr,
int flags);
315SyscallReturn
sendmsgFunc(SyscallDesc *desc, ThreadContext *tc,
316 int tgt_fd, VPtr<> msgPtr,
int flags);
319SyscallReturn
getuidFunc(SyscallDesc *desc, ThreadContext *tc);
322SyscallReturn
getgidFunc(SyscallDesc *desc, ThreadContext *tc);
325SyscallReturn
getppidFunc(SyscallDesc *desc, ThreadContext *tc);
328SyscallReturn
geteuidFunc(SyscallDesc *desc, ThreadContext *tc);
331SyscallReturn
getegidFunc(SyscallDesc *desc, ThreadContext *tc);
334SyscallReturn
accessFunc(SyscallDesc *desc, ThreadContext *tc,
335 VPtr<> pathname, mode_t
mode);
336SyscallReturn
accessImpl(SyscallDesc *desc, ThreadContext *tc,
337 std::string path, mode_t
mode);
341 int tgt_fd,
int level,
int optname,
342 VPtr<> valPtr, VPtr<> lenPtr);
346 int tgt_fd,
int level,
int optname,
347 VPtr<> valPtr, socklen_t
len);
349SyscallReturn
getcpuFunc(SyscallDesc *desc, ThreadContext *tc,
350 VPtr<uint32_t> cpu, VPtr<uint32_t> node,
351 VPtr<uint32_t> tcache);
355 int tgt_fd, VPtr<> addrPtr, VPtr<> lenPtr);
362 if (dirfd != OS::TGT_AT_FDCWD && !
startswith(path,
"/")) {
365 std::shared_ptr<FDEntry> fdep = ((*process->fds)[dirfd]);
366 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
371 path = ffdp->getFileName();
373 path = ffdp->getFileName() +
"/" + path;
393 op &= ~OS::TGT_FUTEX_PRIVATE_FLAG;
394 op &= ~OS::TGT_FUTEX_CLOCK_REALTIME_FLAG;
398 if (OS::TGT_FUTEX_WAIT ==
op || OS::TGT_FUTEX_WAIT_BITSET ==
op) {
410 return -OS::TGT_EWOULDBLOCK;
412 if (OS::TGT_FUTEX_WAIT ==
op) {
413 futex_map.
suspend(uaddr, process->tgid(), tc);
419 }
else if (OS::TGT_FUTEX_WAKE ==
op) {
420 return futex_map.
wakeup(uaddr, process->tgid(),
val);
421 }
else if (OS::TGT_FUTEX_WAKE_BITSET ==
op) {
422 return futex_map.
wakeup_bitset(uaddr, process->tgid(), val3);
423 }
else if (OS::TGT_FUTEX_REQUEUE ==
op ||
424 OS::TGT_FUTEX_CMP_REQUEUE ==
op) {
434 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
435 return -OS::TGT_EWOULDBLOCK;
436 return futex_map.
requeue(uaddr, process->tgid(),
val, timeout, uaddr2);
437 }
else if (OS::TGT_FUTEX_WAKE_OP ==
op) {
465 int wake_cmparg = val3 & 0xfff;
466 int wake_oparg = (val3 & 0xfff000) >> 12;
467 int wake_cmp = (val3 & 0xf000000) >> 24;
468 int wake_op = (val3 & 0xf0000000) >> 28;
469 if ((wake_op & OS::TGT_FUTEX_OP_ARG_SHIFT) >> 3 == 1)
470 wake_oparg = (1 << wake_oparg);
471 wake_op &= ~OS::TGT_FUTEX_OP_ARG_SHIFT;
473 if (wake_op == OS::TGT_FUTEX_OP_SET)
475 else if (wake_op == OS::TGT_FUTEX_OP_ADD)
476 newval += wake_oparg;
477 else if (wake_op == OS::TGT_FUTEX_OP_OR)
478 newval |= wake_oparg;
479 else if (wake_op == OS::TGT_FUTEX_OP_ANDN)
480 newval &= ~wake_oparg;
481 else if (wake_op == OS::TGT_FUTEX_OP_XOR)
482 newval ^= wake_oparg;
487 int woken1 = futex_map.
wakeup(uaddr, process->tgid(),
val);
490 bool is_wake2 =
false;
491 if (wake_cmp == OS::TGT_FUTEX_OP_CMP_EQ)
492 is_wake2 = oldval == wake_cmparg;
493 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_NE)
494 is_wake2 = oldval != wake_cmparg;
495 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LT)
496 is_wake2 = oldval < wake_cmparg;
497 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LE)
498 is_wake2 = oldval <= wake_cmparg;
499 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GT)
500 is_wake2 = oldval > wake_cmparg;
501 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GE)
502 is_wake2 = oldval >= wake_cmparg;
505 woken2 = futex_map.
wakeup(uaddr2, process->tgid(), timeout);
507 return woken1 + woken2;
509 warn(
"futex: op %d not implemented; ignoring.",
op);
515SyscallReturn
pipePseudoFunc(SyscallDesc *desc, ThreadContext *tc);
525template <
class T1,
class T2>
529 static const int OneMillion = 1000 * 1000;
532 sec = elapsed_usecs / OneMillion;
533 usec = elapsed_usecs % OneMillion;
538template <
class T1,
class T2>
542 static const int OneBillion = 1000 * 1000 * 1000;
545 sec = elapsed_nsecs / OneBillion;
546 nsec = elapsed_nsecs % OneBillion;
569template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
573 constexpr ByteOrder
bo = OS::byteOrder;
578 tgt->st_dev = host->st_dev;
579 tgt->st_dev =
htog(tgt->st_dev,
bo);
580 tgt->st_ino = host->st_ino;
581 tgt->st_ino =
htog(tgt->st_ino,
bo);
582 tgt->st_mode = host->st_mode;
585 tgt->st_mode &= ~S_IFMT;
586 tgt->st_mode |= S_IFCHR;
588 tgt->st_mode =
htog(tgt->st_mode,
bo);
589 tgt->st_nlink = host->st_nlink;
590 tgt->st_nlink =
htog(tgt->st_nlink,
bo);
591 tgt->st_uid = host->st_uid;
592 tgt->st_uid =
htog(tgt->st_uid,
bo);
593 tgt->st_gid = host->st_gid;
594 tgt->st_gid =
htog(tgt->st_gid,
bo);
596 tgt->st_rdev = 0x880d;
598 tgt->st_rdev = host->st_rdev;
599 tgt->st_rdev =
htog(tgt->st_rdev,
bo);
600 tgt->st_size = host->st_size;
601 tgt->st_size =
htog(tgt->st_size,
bo);
602 tgt->st_atimeX = host->st_atime;
603 tgt->st_atimeX =
htog(tgt->st_atimeX,
bo);
604 tgt->st_mtimeX = host->st_mtime;
605 tgt->st_mtimeX =
htog(tgt->st_mtimeX,
bo);
606 tgt->st_ctimeX = host->st_ctime;
607 tgt->st_ctimeX =
htog(tgt->st_ctimeX,
bo);
610 tgt->st_blksize = 0x2000;
611 tgt->st_blksize =
htog(tgt->st_blksize,
bo);
612 tgt->st_blocks = host->st_blocks;
613 tgt->st_blocks =
htog(tgt->st_blocks,
bo);
618template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
623 copyOutStatBuf<OS>(tgt, host, fakeTTY);
624#if defined(STAT_HAVE_NSEC)
625 constexpr ByteOrder
bo = OS::byteOrder;
627 tgt->st_atime_nsec = host->st_atime_nsec;
628 tgt->st_atime_nsec =
htog(tgt->st_atime_nsec,
bo);
629 tgt->st_mtime_nsec = host->st_mtime_nsec;
630 tgt->st_mtime_nsec =
htog(tgt->st_mtime_nsec,
bo);
631 tgt->st_ctime_nsec = host->st_ctime_nsec;
632 tgt->st_ctime_nsec =
htog(tgt->st_ctime_nsec,
bo);
634 tgt->st_atime_nsec = 0;
635 tgt->st_mtime_nsec = 0;
636 tgt->st_ctime_nsec = 0;
640template <
class OS,
typename TgtStatPtr,
typename HostStatPtr>
644 constexpr ByteOrder
bo = OS::byteOrder;
646 tgt->f_type =
htog(host->f_type,
bo);
647#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
648 tgt->f_bsize =
htog(host->f_iosize,
bo);
650 tgt->f_bsize =
htog(host->f_bsize,
bo);
652 tgt->f_blocks =
htog(host->f_blocks,
bo);
653 tgt->f_bfree =
htog(host->f_bfree,
bo);
654 tgt->f_bavail =
htog(host->f_bavail,
bo);
655 tgt->f_files =
htog(host->f_files,
bo);
656 tgt->f_ffree =
htog(host->f_ffree,
bo);
657 memcpy(&tgt->f_fsid, &host->f_fsid,
sizeof(host->f_fsid));
658#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
659 tgt->f_namelen =
htog(host->f_namemax,
bo);
660 tgt->f_frsize =
htog(host->f_bsize,
bo);
661#elif defined(__APPLE__)
665 tgt->f_namelen =
htog(host->f_namelen,
bo);
666 tgt->f_frsize =
htog(host->f_frsize,
bo);
668#if defined(__linux__)
669 memcpy(&tgt->f_spare, &host->f_spare,
670 std::min(
sizeof(host->f_spare),
sizeof(tgt->f_spare)));
676 memset(&tgt->f_spare, 0,
sizeof(tgt->f_spare));
693 if (OS::isTtyReq(req))
696 auto dfdp = std::dynamic_pointer_cast<DeviceFDEntry>((*
p->fds)[tgt_fd]);
700 return emul_driver->
ioctl(tc, req,
addr);
703 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
712 ifconf *conf = (ifconf*)conf_arg.
bufferPtr();
713 Addr ifc_buf_addr = (
Addr)conf->ifc_buf;
714 BufferArg ifc_buf_arg(ifc_buf_addr, conf->ifc_len);
717 conf->ifc_buf = (
char*)ifc_buf_arg.
bufferPtr();
721 conf->ifc_buf = (
char*)ifc_buf_addr;
729#if defined(__linux__)
734#if defined(__linux__)
753 warn(
"Unsupported ioctl call (return ENOTTY): ioctl(%d, 0x%x, ...) @ \n",
762 int tgt_dirfd,
VPtr<> pathname,
int tgt_flags,
int mode)
775 int host_flags = O_BINARY;
783 for (
const auto &
p: OS::openFlagTable) {
784 if (tgt_flags &
p.first) {
785 tgt_flags &= ~p.first;
786 host_flags |=
p.second;
789 warn_if(tgt_flags,
"%s: cannot decode flags %#x", desc->
name(), tgt_flags);
792 host_flags |= O_BINARY;
807 std::string redir_path = path;
808 std::string abs_path = path;
809 if (tgt_dirfd == OS::TGT_AT_FDCWD) {
810 abs_path =
p->absolutePath(path,
true);
811 redir_path =
p->checkPathRedirect(path);
813 std::shared_ptr<FDEntry> fdep = ((*
p->fds)[tgt_dirfd]);
814 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
817 abs_path = ffdp->getFileName() + path;
818 redir_path =
p->checkPathRedirect(abs_path);
828 std::string filename = abs_path.substr(strlen(
"/dev/"));
832 "driver open with path[%s]\n",
833 desc->
name(), abs_path.c_str());
834 return drv->
open(tc,
mode, host_flags);
867 std::string used_path;
869 {
"/proc/meminfo/",
"/system/",
"/platform/",
"/etc/passwd",
870 "/proc/self/maps",
"/dev/urandom",
871 "/sys/devices/system/cpu/online" };
872 for (
auto entry : special_paths) {
874 sim_fd = OS::openSpecialFile(abs_path,
p, tc);
875 used_path = abs_path;
879 sim_fd = open(redir_path.c_str(), host_flags,
mode);
880 used_path = redir_path;
885 "(inferred from:%s)\n", desc->
name(),
886 used_path.c_str(), path.c_str());
898 auto ffdp = std::make_shared<FileFDEntry>(sim_fd, host_flags, path, 0);
900 ffdp->setFileMode(
mode);
901 int tgt_fd =
p->fds->allocFD(ffdp);
903 "(inferred from:%s)\n", desc->
name(),
904 sim_fd, tgt_fd, used_path.c_str(), path.c_str());
914 return openatFunc<OS>(
915 desc, tc, OS::TGT_AT_FDCWD, pathname, tgt_flags,
mode);
929 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
933 if (
flags & OS::TGT_AT_REMOVEDIR) {
951 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
963 typename OS::size_t bufsiz)
970 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
977 path =
p->checkPathRedirect(path);
982 if (path !=
"/proc/self/exe") {
983 result = readlink(path.c_str(), (
char *)buf.
bufferPtr(), bufsiz);
997 char real_path[PATH_MAX];
998 char *check_real_path = realpath(
p->progName(), real_path);
999 if (!check_real_path) {
1000 fatal(
"readlink('/proc/self/exe') unable to resolve path to "
1001 "executable: %s",
p->progName());
1003 strncpy((
char*)buf.
bufferPtr(), real_path, bufsiz);
1004 typename OS::size_t real_path_len = strlen(real_path);
1005 if (real_path_len > bufsiz) {
1010 result = real_path_len;
1014 warn_once(
"readlink() called on '/proc/self/exe' may yield unexpected "
1015 "results in various settings.\n Returning '%s'\n",
1021 return (result == -1) ? -errno : result;
1029 typename OS::size_t bufsiz)
1031 return readlinkatFunc<OS>(desc, tc, OS::TGT_AT_FDCWD,
1032 pathname, buf_ptr, bufsiz);
1039 int olddirfd,
VPtr<> oldpath,
int newdirfd,
VPtr<> newpath)
1042 std::string old_name;
1046 std::string new_name;
1051 if (
auto res = atSyscallPath<OS>(tc, olddirfd, old_name); !res.successful()) {
1056 if (
auto res = atSyscallPath<OS>(tc, newdirfd, new_name); !res.successful()) {
1060 return renameImpl(desc, tc, old_name, new_name);
1067 int dirfd,
VPtr<> pathname, uint32_t owner, uint32_t group,
1075 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
1079 return chownImpl(desc, tc, path, owner, group);
1093 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
1104 int dirfd,
VPtr<> pathname, mode_t
mode, dev_t dev)
1111 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
1127 sysinfo->totalram = process->system->memSize();
1128 sysinfo->mem_unit = 1;
1144 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
1148 mode_t hostMode = 0;
1158 int result = chmod(path.c_str(), hostMode);
1170 return fchmodatFunc<OS>(desc, tc, OS::TGT_AT_FDCWD, pathname,
mode);
1176 VPtr<> fdsPtr,
int nfds,
int tmout)
1180 BufferArg fdsBuf(fdsPtr,
sizeof(
struct pollfd) * nfds);
1189 int temp_tgt_fds[nfds];
1192 auto tgt_fd = temp_tgt_fds[
index];
1193 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1196 auto host_fd = hbfdp->getSimFD();
1218 if (it->receiver ==
p)
1233 auto tgt_fd = temp_tgt_fds[
index];
1253 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1256 int sim_fd = ffdp->getSimFD();
1258 mode_t hostMode =
mode;
1260 int result = fchmod(sim_fd, hostMode);
1262 return (result < 0) ? -errno : 0;
1269 VPtr<> start, uint64_t old_length, uint64_t new_length, uint64_t
flags,
1273 Addr page_bytes =
p->pTable->pageSize();
1274 uint64_t provided_address = 0;
1275 bool use_provided_address =
flags & OS::TGT_MREMAP_FIXED;
1277 if (use_provided_address)
1278 provided_address = varargs.
get<uint64_t>();
1280 if ((start % page_bytes != 0) ||
1281 (provided_address % page_bytes != 0)) {
1282 warn(
"mremap failing: arguments not page aligned");
1286 new_length =
roundUp(new_length, page_bytes);
1288 if (new_length > old_length) {
1289 Addr mmap_end =
p->memState->getMmapEnd();
1291 if ((start + old_length) == mmap_end &&
1292 (!use_provided_address || provided_address == start)) {
1295 uint64_t diff = new_length - old_length;
1296 p->memState->mapRegion(mmap_end, diff,
"remapped");
1297 p->memState->setMmapEnd(mmap_end + diff);
1300 if (!use_provided_address && !(
flags & OS::TGT_MREMAP_MAYMOVE)) {
1301 warn(
"can't remap here and MREMAP_MAYMOVE flag not set\n");
1304 uint64_t new_start = provided_address;
1305 if (!use_provided_address) {
1306 new_start =
p->mmapGrowsDown() ?
1307 mmap_end - new_length : mmap_end;
1308 mmap_end =
p->mmapGrowsDown() ?
1309 new_start : mmap_end + new_length;
1310 p->memState->setMmapEnd(mmap_end);
1313 warn(
"mremapping to new vaddr %08p-%08p, adding %d\n",
1314 new_start, new_start + new_length,
1315 new_length - old_length);
1318 p->allocateMem(new_start + old_length,
1319 new_length - old_length,
1320 use_provided_address );
1322 if (use_provided_address &&
1323 ((new_start + new_length >
p->memState->getMmapEnd() &&
1324 !
p->mmapGrowsDown()) ||
1325 (new_start < p->memState->getMmapEnd() &&
1326 p->mmapGrowsDown()))) {
1329 warn(
"mmap region limit exceeded with MREMAP_FIXED\n");
1332 warn(
"returning %08p as start\n", new_start);
1333 p->memState->remapRegion(start, new_start, old_length);
1339 if (use_provided_address && provided_address != start)
1340 p->memState->remapRegion(start, provided_address, new_length);
1341 if (new_length != old_length)
1342 p->memState->unmapRegion(start + new_length,
1343 old_length - new_length);
1344 return use_provided_address ? provided_address : (
Addr)start;
1363 struct stat hostBuf;
1364 int result = stat(path.c_str(), &hostBuf);
1369 copyOutStatBuf<OS>(tgt_stat, &hostBuf);
1386 if (path.empty() && !(
flags & OS::TGT_AT_EMPTY_PATH))
1393 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
1400 path =
p->checkPathRedirect(path);
1402 struct stat host_buf;
1403 int result = stat(path.c_str(), &host_buf);
1408 copyOutStatBuf<OS>(tgt_stat, &host_buf);
1417 int dirfd,
VPtr<> pathname,
1425 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
1432 path =
p->checkPathRedirect(path);
1435 struct stat hostBuf;
1436 int result = stat(path.c_str(), &hostBuf);
1438 struct stat64 hostBuf;
1439 int result = stat64(path.c_str(), &hostBuf);
1445 copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
1456 return fstatat64Func<OS>(desc, tc, OS::TGT_AT_FDCWD, pathname, tgt_stat);
1467 auto ffdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1470 int sim_fd = ffdp->getSimFD();
1473 struct stat hostBuf;
1474 int result = fstat(sim_fd, &hostBuf);
1476 struct stat64 hostBuf;
1477 int result = fstat64(sim_fd, &hostBuf);
1483 copyOutStat64Buf<OS>(tgt_stat, &hostBuf, (sim_fd == 1));
1504 struct stat hostBuf;
1505 int result = lstat(path.c_str(), &hostBuf);
1510 copyOutStatBuf<OS>(tgt_stat, &hostBuf);
1531 struct stat hostBuf;
1532 int result = lstat(path.c_str(), &hostBuf);
1534 struct stat64 hostBuf;
1535 int result = lstat64(path.c_str(), &hostBuf);
1541 copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
1556 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1559 int sim_fd = ffdp->getSimFD();
1561 struct stat hostBuf;
1562 int result = fstat(sim_fd, &hostBuf);
1567 copyOutStatBuf<OS>(tgt_stat, &hostBuf, (sim_fd == 1));
1578#if defined(__linux__)
1588 struct statfs hostBuf;
1589 int result = statfs(path.c_str(), &hostBuf);
1594 copyOutStatfsBuf<OS>(tgt_stat, &hostBuf);
1607 DPRINTF(SyscallVerbose,
"Doing clone. pid: %#llx, ctid: %#llx, tls: %#llx"
1608 " flags: %#llx, stack: %#llx\n",
1612 if (((
flags & OS::TGT_CLONE_SIGHAND)&& !(
flags & OS::TGT_CLONE_VM)) ||
1613 ((
flags & OS::TGT_CLONE_THREAD) && !(
flags & OS::TGT_CLONE_SIGHAND)) ||
1614 ((
flags & OS::TGT_CLONE_FS) && (
flags & OS::TGT_CLONE_NEWNS)) ||
1615 ((
flags & OS::TGT_CLONE_NEWIPC) && (
flags & OS::TGT_CLONE_SYSVSEM)) ||
1616 ((
flags & OS::TGT_CLONE_NEWPID) && (
flags & OS::TGT_CLONE_THREAD)) ||
1617 ((
flags & OS::TGT_CLONE_VM) && !(newStack)))
1633 ProcessParams *pp =
new ProcessParams();
1634 pp->executable.assign(*(
new std::string(
p->progName())));
1635 pp->cmd.push_back(*(
new std::string(
p->progName())));
1636 pp->system =
p->system;
1637 pp->cwd.assign(
p->tgtCwd);
1638 pp->input.assign(
"stdin");
1639 pp->output.assign(
"stdout");
1640 pp->errout.assign(
"stderr");
1642 pp->euid =
p->euid();
1644 pp->egid =
p->egid();
1645 pp->release =
p->release;
1648 std::set<int>
const& pids =
p->system->PIDs;
1649 int temp_pid = *pids.begin();
1652 }
while (pids.find(temp_pid) != pids.end());
1654 fatal(
"temp_pid is too large: %d", temp_pid);
1657 pp->ppid = (
flags & OS::TGT_CLONE_THREAD) ?
p->ppid() :
p->pid();
1658 pp->useArchPT =
p->useArchPT;
1659 pp->kvmInSE =
p->kvmInSE;
1670 if (
flags & OS::TGT_CLONE_PARENT_SETTID) {
1671 BufferArg ptidBuf(ptidPtr,
sizeof(
long));
1672 long *ptid = (
long *)ptidBuf.
bufferPtr();
1677 if (
flags & OS::TGT_CLONE_THREAD) {
1685 p->clone(tc, ctc, cp,
flags);
1687 if (
flags & OS::TGT_CLONE_THREAD) {
1690 }
else if (
flags & OS::TGT_SIGCHLD) {
1694 if (
flags & OS::TGT_CLONE_CHILD_SETTID) {
1695 BufferArg ctidBuf(ctidPtr,
sizeof(
long));
1696 long *ctid = (
long *)ctidBuf.
bufferPtr();
1701 if (
flags & OS::TGT_CLONE_CHILD_CLEARTID)
1706 OS::archClone(
flags,
p, cp, tc, ctc, newStack, tlsPtr);
1712 if (
flags & OS::TGT_CLONE_VFORK) {
1729 uint64_t new_stack = cl_args->stack + cl_args->stack_size;
1730 uint64_t
flags = cl_args->flags;
1732 return doClone<OS>(desc, tc,
flags, new_stack, ptidPtr, ctidPtr, tlsPtr);
1740 return doClone<OS>(desc, tc,
flags, newStack, ptidPtr, ctidPtr, tlsPtr);
1749 return cloneFunc<OS>(desc, tc,
flags, newStack, ptidPtr, ctidPtr, tlsPtr);
1760 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1763 int sim_fd = ffdp->getSimFD();
1765 struct statfs hostBuf;
1766 int result = fstatfs(sim_fd, &hostBuf);
1771 copyOutStatfsBuf<OS>(tgt_stat, &hostBuf);
1780 int tgt_fd, uint64_t tiov_base,
1781 typename OS::size_t
count)
1785 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
1788 int sim_fd = ffdp->getSimFD();
1791 typename OS::tgt_iovec tiov[
count];
1792 struct iovec hiov[
count];
1793 for (
typename OS::size_t
i = 0;
i <
count; ++
i) {
1794 prox.
readBlob(tiov_base + (
i *
sizeof(
typename OS::tgt_iovec)),
1795 &tiov[
i],
sizeof(
typename OS::tgt_iovec));
1796 hiov[
i].iov_len =
gtoh(tiov[
i].iov_len, OS::byteOrder);
1797 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1800 int result = readv(sim_fd, hiov,
count);
1801 int local_errno = errno;
1803 for (
typename OS::size_t
i = 0;
i <
count; ++
i) {
1806 hiov[
i].iov_base, hiov[
i].iov_len);
1808 delete [] (
char *)hiov[
i].iov_base;
1811 return (result == -1) ? -local_errno : result;
1818 int tgt_fd, uint64_t tiov_base,
1819 typename OS::size_t
count)
1823 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
1826 int sim_fd = hbfdp->getSimFD();
1829 struct iovec hiov[
count];
1830 for (
typename OS::size_t
i = 0;
i <
count; ++
i) {
1831 typename OS::tgt_iovec tiov;
1833 prox.
readBlob(tiov_base +
i*
sizeof(
typename OS::tgt_iovec),
1834 &tiov,
sizeof(
typename OS::tgt_iovec));
1835 hiov[
i].iov_len =
gtoh(tiov.iov_len, OS::byteOrder);
1836 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
1837 prox.
readBlob(
gtoh(tiov.iov_base, OS::byteOrder), hiov[
i].iov_base,
1841 int result = writev(sim_fd, hiov,
count);
1843 for (
typename OS::size_t
i = 0;
i <
count; ++
i)
1844 delete [] (
char *)hiov[
i].iov_base;
1846 return (result == -1) ? -errno : result;
1853 VPtr<> start,
typename OS::size_t length,
int prot,
1854 int tgt_flags,
int tgt_fd,
typename OS::off_t
offset)
1857 Addr page_bytes =
p->pTable->pageSize();
1859 if (start & (page_bytes - 1) ||
1860 offset & (page_bytes - 1) ||
1861 (tgt_flags & OS::TGT_MAP_PRIVATE &&
1862 tgt_flags & OS::TGT_MAP_SHARED) ||
1863 (!(tgt_flags & OS::TGT_MAP_PRIVATE) &&
1864 !(tgt_flags & OS::TGT_MAP_SHARED)) ||
1869 if ((
prot & PROT_WRITE) && (tgt_flags & OS::TGT_MAP_SHARED)) {
1890 warn_once(
"mmap: writing to shared mmap region is currently "
1891 "unsupported. The write succeeds on the target, but it "
1892 "will not be propagated to the host or shared mappings");
1895 length =
roundUp(length, page_bytes);
1898 if (!(tgt_flags & OS::TGT_MAP_ANONYMOUS)) {
1899 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1901 auto dfdp = std::dynamic_pointer_cast<DeviceFDEntry>(fdep);
1904 return emul_driver->
mmap(tc, start, length,
prot, tgt_flags,
1908 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
1911 sim_fd = ffdp->getSimFD();
1922 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1923 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
1925 ffdp->getFileName()));
1927 ffdp->getFileName());
1930 Addr offset = lib->buildImage().minAddr() + start;
1939 if (!(tgt_flags & OS::TGT_MAP_FIXED)) {
1947 if (!(start &&
p->memState->isUnmapped(start, length))) {
1951 start =
p->memState->extendMmap(length);
1956 start, start + length - 1);
1963 if (tgt_flags & OS::TGT_MAP_FIXED) {
1968 p->memState->unmapRegion(start, length);
1974 std::string region_name;
1975 if (tgt_flags & OS::TGT_MAP_ANONYMOUS) {
1976 region_name =
"anon";
1978 std::shared_ptr<FDEntry> fdep = (*
p->fds)[tgt_fd];
1979 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(fdep);
1980 region_name = ffdp->getFileName();
1987 p->memState->mapRegion(start, length, region_name, sim_fd,
offset);
1999 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
2002 int sim_fd = ffdp->getSimFD();
2010 return (bytes_read == -1) ? -errno : bytes_read;
2020 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
2023 int sim_fd = ffdp->getSimFD();
2028 int bytes_written = pwrite(sim_fd, bufArg.
bufferPtr(), nbytes,
offset);
2030 return (bytes_written == -1) ? -errno : bytes_written;
2037 VPtr<> start,
typename OS::size_t length,
int prot,
2038 int tgt_flags,
int tgt_fd,
typename OS::off_t
offset)
2041 return mmapFunc<OS>(desc, tc, start, length,
prot, tgt_flags,
2042 tgt_fd,
offset * page_size);
2051 const ByteOrder
bo = OS::byteOrder;
2053 case OS::TGT_RLIMIT_STACK:
2055 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
2056 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2057 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2060 case OS::TGT_RLIMIT_DATA:
2062 rlp->rlim_cur = rlp->rlim_max = 256 * 1024 * 1024;
2063 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2064 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2067 case OS::TGT_RLIMIT_NPROC:
2069 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2070 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2074 warn(
"getrlimit: unimplemented resource %d", resource);
2088 warn(
"prlimit: ignoring rlimits for nonzero pid");
2092 warn(
"prlimit: ignoring new rlimit");
2094 const ByteOrder
bo = OS::byteOrder;
2096 case OS::TGT_RLIMIT_STACK:
2098 rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;
2099 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2100 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2102 case OS::TGT_RLIMIT_DATA:
2104 rlp->rlim_cur = rlp->rlim_max = 256*1024*1024;
2105 rlp->rlim_cur =
htog(rlp->rlim_cur,
bo);
2106 rlp->rlim_max =
htog(rlp->rlim_max,
bo);
2109 warn(
"prlimit: unimplemented resource %d", resource);
2125 tp->tv_sec =
htog(tp->tv_sec, OS::byteOrder);
2126 tp->tv_nsec =
htog(tp->tv_nsec, OS::byteOrder);
2152 tp->tv_sec =
htog(tp->tv_sec, OS::byteOrder);
2153 tp->tv_usec =
htog(tp->tv_usec, OS::byteOrder);
2162 int dirfd,
VPtr<> pathname,
VPtr<
typename OS::timeval [2]> tp)
2169 if (
auto res = atSyscallPath<OS>(tc, dirfd, path); !res.successful()) {
2173 struct timeval hostTimeval[2];
2174 for (
int i = 0;
i < 2; ++
i) {
2175 hostTimeval[
i].tv_sec =
gtoh((*tp)[
i].tv_sec, OS::byteOrder);
2176 hostTimeval[
i].tv_usec =
gtoh((*tp)[
i].tv_usec, OS::byteOrder);
2183 int result = utimes(path.c_str(), hostTimeval);
2195 VPtr<
typename OS::timeval [2]> tp)
2197 return futimesatFunc<OS>(desc, tc, OS::TGT_AT_FDCWD, pathname, tp);
2212 if (access(path.c_str(), F_OK) == -1)
2218 for (
int inc = 0; ; inc++) {
2220 b.copyIn(mem_proxy);
2222 if (!*(
Addr*)
b.bufferPtr())
2225 vect.push_back(std::string());
2234 if (!
p->vforkContexts.empty()) {
2246 ProcessParams *pp =
new ProcessParams();
2247 pp->executable = path;
2248 read_in(pp->cmd, mem_proxy, argv_mem_loc);
2249 read_in(pp->env, mem_proxy, envp_mem_loc);
2251 pp->egid =
p->egid();
2252 pp->euid =
p->euid();
2254 pp->ppid =
p->ppid();
2256 pp->input.assign(
"cin");
2257 pp->output.assign(
"cout");
2258 pp->errout.assign(
"cerr");
2259 pp->cwd.assign(
p->tgtCwd);
2260 pp->system =
p->system;
2261 pp->release =
p->release;
2270 p->system->PIDs.erase(
p->pid());
2271 Process *new_p = pp->create();
2280 new_p->
fds =
p->fds;
2281 for (
int i = 0;
i < new_p->
fds->getSize();
i++) {
2282 std::shared_ptr<FDEntry> fdep = (*new_p->
fds)[
i];
2283 if (fdep && fdep->getCOE())
2284 new_p->
fds->closeFDEntry(
i);
2306 rup->ru_utime.tv_sec = 0;
2307 rup->ru_utime.tv_usec = 0;
2308 rup->ru_stime.tv_sec = 0;
2309 rup->ru_stime.tv_usec = 0;
2317 rup->ru_inblock = 0;
2318 rup->ru_oublock = 0;
2321 rup->ru_nsignals = 0;
2326 case OS::TGT_RUSAGE_SELF:
2328 rup->ru_utime.tv_sec =
htog(rup->ru_utime.tv_sec, OS::byteOrder);
2329 rup->ru_utime.tv_usec =
htog(rup->ru_utime.tv_usec, OS::byteOrder);
2332 case OS::TGT_RUSAGE_CHILDREN:
2339 warn(
"getrusage() only supports RUSAGE_SELF. Parameter %d ignored.",
2353 bufp->tms_utime = clocks;
2354 bufp->tms_stime = 0;
2355 bufp->tms_cutime = 0;
2356 bufp->tms_cstime = 0;
2359 bufp->tms_utime =
htog(bufp->tms_utime, OS::byteOrder);
2370 typename OS::time_t sec, usec;
2376 typename OS::time_t
t = sec;
2377 t =
htog(
t, OS::byteOrder);
2378 p.writeBlob(taddr, &
t, (
int)
sizeof(
typename OS::time_t));
2404 for (
auto *tc: sys->
threads) {
2406 if (temp->
pid() == tid) {
2412 if (sig != 0 || sig != OS::TGT_SIGABRT)
2415 if (tgt_proc ==
nullptr)
2418 if (tgid != -1 && tgt_proc->
tgid() != tgid)
2421 if (sig == OS::TGT_SIGABRT)
2438 auto sfdp = std::make_shared<SocketFDEntry>(sim_fd,
domain,
type,
prot);
2439 int tgt_fd =
p->fds->allocFD(sfdp);
2458 auto sfdp1 = std::make_shared<SocketFDEntry>(fds[0],
domain,
type,
prot);
2459 fds[0] =
p->fds->allocFD(sfdp1);
2460 auto sfdp2 = std::make_shared<SocketFDEntry>(fds[1],
domain,
type,
prot);
2461 fds[1] =
p->fds->allocFD(sfdp2);
2485 FD_ZERO(&readfds_h);
2487 FD_ZERO(&writefds_h);
2489 FD_ZERO(&errorfds_h);
2501 std::map<int, int> trans_map;
2502 auto try_add_host_set = [&](
typename OS::fd_set *tgt_set_entry,
2503 fd_set *hst_set_entry,
2511 if (FD_ISSET(iter, (fd_set *)tgt_set_entry)) {
2517 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[iter]);
2520 auto sim_fd = hbfdp->getSimFD();
2527 trans_map[sim_fd] = iter;
2534 nfds_h = std::max(nfds_h - 1, sim_fd + 1);
2540 FD_SET(sim_fd, hst_set_entry);
2545 for (
int i = 0;
i < nfds;
i++) {
2547 bool ebadf = try_add_host_set(readfds, &readfds_h,
i);
2552 bool ebadf = try_add_host_set(writefds, &writefds_h,
i);
2557 bool ebadf = try_add_host_set(errorfds, &errorfds_h,
i);
2571 timeout->tv_sec = 0;
2572 timeout->tv_usec = 0;
2574 retval = select(nfds_h,
2575 readfds ? &readfds_h :
nullptr,
2576 writefds ? &writefds_h :
nullptr,
2577 errorfds ? &errorfds_h :
nullptr,
2578 (timeval *)(
typename OS::timeval *)timeout);
2587 struct timeval tv = { 0, 0 };
2589 retval = select(nfds_h,
2590 readfds ? &readfds_h :
nullptr,
2591 readfds ? &writefds_h :
nullptr,
2592 readfds ? &errorfds_h :
nullptr,
2602 if (sig.receiver ==
p)
2612 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)readfds));
2615 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)writefds));
2618 FD_ZERO(
reinterpret_cast<fd_set *
>((
typename OS::fd_set *)errorfds));
2626 for (
int i = 0;
i < nfds_h;
i++) {
2627 if (readfds && FD_ISSET(
i, &readfds_h))
2628 FD_SET(trans_map[
i],
2629 reinterpret_cast<fd_set *
>(
2630 (
typename OS::fd_set *)readfds));
2632 if (writefds && FD_ISSET(
i, &writefds_h))
2633 FD_SET(trans_map[
i],
2634 reinterpret_cast<fd_set *
>(
2635 (
typename OS::fd_set *)writefds));
2637 if (errorfds && FD_ISSET(
i, &errorfds_h))
2638 FD_SET(trans_map[
i],
2639 reinterpret_cast<fd_set *
>(
2640 (
typename OS::fd_set *)errorfds));
2649 int tgt_fd,
VPtr<> buf_ptr,
int nbytes)
2653 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
2656 int sim_fd = hbfdp->getSimFD();
2660 pfd.events = POLLIN | POLLPRI;
2661 if ((poll(&pfd, 1, 0) == 0)
2662 && !(hbfdp->getFlags() & OS::TGT_O_NONBLOCK))
2666 int bytes_read = read(sim_fd, buf_arg.
bufferPtr(), nbytes);
2671 return (bytes_read == -1) ? -errno : bytes_read;
2677 int tgt_fd,
VPtr<> buf_ptr,
int nbytes)
2681 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*
p->fds)[tgt_fd]);
2684 int sim_fd = hbfdp->getSimFD();
2691 pfd.events = POLLOUT;
2699 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>(hbfdp);
2700 if (ffdp && (ffdp->getFileName() !=
"/dev/random")) {
2701 if (!poll(&pfd, 1, 0) && !(ffdp->getFlags() & OS::TGT_O_NONBLOCK))
2705 int bytes_written = write(sim_fd, buf_arg.
bufferPtr(), nbytes);
2707 if (bytes_written != -1)
2710 return (bytes_written == -1) ? -errno : bytes_written;
2716 pid_t pid,
VPtr<> statPtr,
int options,
VPtr<> rusagePtr)
2721 DPRINTF_SYSCALL(Verbose,
"wait4: rusage pointer provided %lx, however "
2722 "functionality not supported. Ignoring rusage pointer.\n",
2736 if (iter->receiver ==
p) {
2738 if ((iter->sender->pgid() == -pid)
2739 && (iter->signalValue == OS::TGT_SIGCHLD))
2741 }
else if (pid == -1) {
2742 if (iter->signalValue == OS::TGT_SIGCHLD)
2744 }
else if (pid == 0) {
2745 if ((iter->sender->pgid() ==
p->pgid())
2746 && (iter->signalValue == OS::TGT_SIGCHLD))
2749 if ((iter->sender->pid() == pid)
2750 && (iter->signalValue == OS::TGT_SIGCHLD))
2760 const int EXITED = 0;
2761 BufferArg statusBuf(statPtr,
sizeof(
int));
2766 pid_t retval = iter->sender->pid();
2784 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
2787 int sim_fd = sfdp->getSimFD();
2797 pfd.events = POLLIN | POLLPRI;
2798 if ((poll(&pfd, 1, 0) == 0) && !(sfdp->getFlags() & OS::TGT_O_NONBLOCK))
2802 lenBufPtr =
new BufferArg(lenPtr,
sizeof(socklen_t));
2804 memcpy(&addrLen, (socklen_t *)lenBufPtr->
bufferPtr(),
2809 addrBufPtr =
new BufferArg(addrPtr,
sizeof(
struct sockaddr));
2811 memcpy(&
sa, (
struct sockaddr *)addrBufPtr->
bufferPtr(),
2812 sizeof(
struct sockaddr));
2815 host_fd = accept(sim_fd, &
sa, &addrLen);
2827 *(socklen_t *)lenBufPtr->
bufferPtr() = addrLen;
2832 auto afdp = std::make_shared<SocketFDEntry>(host_fd, sfdp->_domain,
2833 sfdp->_type, sfdp->_protocol);
2834 return p->fds->allocFD(afdp);
2841 unsigned initval,
int in_flags)
2843#if defined(__linux__)
2846 int sim_fd = eventfd(initval, in_flags);
2850 bool cloexec = in_flags & OS::TGT_O_CLOEXEC;
2852 int flags = cloexec ? OS::TGT_O_CLOEXEC : 0;
2853 flags |= (in_flags & OS::TGT_O_NONBLOCK) ? OS::TGT_O_NONBLOCK : 0;
2855 auto hbfdp = std::make_shared<HBFDEntry>(
flags, sim_fd, cloexec);
2856 int tgt_fd =
p->fds->allocFD(hbfdp);
2868 pid_t pid,
typename OS::size_t cpusetsize,
2871#if defined(__linux__)
2876 BufferArg maskBuf(cpu_set_mask, cpusetsize);
2879 CPU_SET(
i, (cpu_set_t *)maskBuf.
bufferPtr());
2893 int tgt_fd,
VPtr<> buf_ptr,
typename OS::size_t buf_len,
2898 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
2901 int sim_fd = sfdp->getSimFD();
2909 socklen_t addr_len = 0;
2910 if (addrlen_ptr != 0) {
2912 BufferArg addrlen_buf(addrlen_ptr,
sizeof(socklen_t));
2913 addrlen_buf.
copyIn(proxy);
2914 addr_len = *((socklen_t *)addrlen_buf.
bufferPtr());
2917 struct sockaddr
sa, *sap = NULL;
2918 if (addr_len != 0) {
2921 memcpy(&
sa, (
struct sockaddr *)addr_buf.
bufferPtr(),
2922 sizeof(
struct sockaddr));
2926 ssize_t recvd_size = recvfrom(sim_fd,
2928 buf_len,
flags, sap, (socklen_t *)&addr_len);
2930 if (recvd_size == -1)
2944 if (addr_len != 0) {
2945 BufferArg addrlen_buf(addrlen_ptr,
sizeof(socklen_t));
2946 *(socklen_t *)addrlen_buf.
bufferPtr() = addr_len;
2954template <
typename OS>
2957 int tgt_fd,
VPtr<> buf_ptr,
typename OS::size_t buf_len,
int flags,
2958 VPtr<> addr_ptr, socklen_t addr_len)
2962 auto sfdp = std::dynamic_pointer_cast<SocketFDEntry>((*
p->fds)[tgt_fd]);
2965 int sim_fd = sfdp->getSimFD();
2971 struct sockaddr
sa, *sap =
nullptr;
2972 memset(&
sa, 0,
sizeof(sockaddr));
2973 if (addr_len != 0) {
2976 memcpy(&
sa, (sockaddr*)addr_buf.
bufferPtr(), addr_len);
2980 ssize_t sent_size = sendto(sim_fd,
2982 buf_len,
flags, sap, (socklen_t)addr_len);
2984 return (sent_size == -1) ? -errno : sent_size;
2988template <
typename OS>
2991 typename OS::size_t length)
2999 if (
p->pTable->pageOffset(start))
3002 length =
roundUp(length,
p->pTable->pageSize());
3004 p->memState->unmapRegion(start, length);
3010template <
typename OS>
3013 int tgt_fd,
int mode,
typename OS::off_t
offset,
3014 typename OS::off_t
len)
3016#if defined(__linux__)
3019 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
3022 int sim_fd = ffdp->getSimFD();
3035template <
typename OS>
3038 typename OS::off_t length)
3047 path =
p->checkPathRedirect(path);
3049 int result = truncate(path.c_str(), length);
3050 return (result == -1) ? -errno : result;
3054template <
typename OS>
3057 typename OS::off_t length)
3061 auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*
p->fds)[tgt_fd]);
3064 int sim_fd = ffdp->getSimFD();
3066 int result = ftruncate(sim_fd, length);
3067 return (result == -1) ? -errno : result;
3070template <
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 writeBlob(Addr addr, const void *p, int 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 readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
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.
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)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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)
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.
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_stat > 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 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.