42 #ifndef __SIM_SYSCALL_EMUL_HH__
43 #define __SIM_SYSCALL_EMUL_HH__
45 #if (defined(__APPLE__) || defined(__OpenBSD__) || \
46 defined(__FreeBSD__) || defined(__CYGWIN__) || \
59 #if defined(__linux__)
61 #include <sys/eventfd.h>
62 #include <sys/statfs.h>
65 #include <sys/mount.h>
70 #include <sys/fcntl.h>
76 #include <sys/ioctl.h>
78 #include <sys/socket.h>
81 #include <sys/types.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)
138 SyscallReturn
ignoreFunc(SyscallDesc *desc, ThreadContext *tc);
144 SyscallReturn
exitFunc(SyscallDesc *desc, ThreadContext *tc,
int status);
157 SyscallReturn
brkFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> new_brk);
160 SyscallReturn
closeFunc(SyscallDesc *desc, ThreadContext *tc,
int tgt_fd);
163 SyscallReturn
lseekFunc(SyscallDesc *desc, ThreadContext *tc,
164 int tgt_fd, uint64_t offs,
int whence);
167 SyscallReturn
_llseekFunc(SyscallDesc *desc, ThreadContext *tc,
168 int tgt_fd, uint64_t offset_high,
169 uint32_t offset_low, VPtr<> result_ptr,
int whence);
172 SyscallReturn
shutdownFunc(SyscallDesc *desc, ThreadContext *tc,
173 int tgt_fd,
int how);
177 VPtr<> buf_ptr,
int name_len);
180 SyscallReturn
getcwdFunc(SyscallDesc *desc, ThreadContext *tc,
181 VPtr<> buf_ptr,
unsigned long size);
184 SyscallReturn
unlinkFunc(SyscallDesc *desc, ThreadContext *tc,
186 SyscallReturn
unlinkImpl(SyscallDesc *desc, ThreadContext *tc,
190 SyscallReturn
linkFunc(SyscallDesc *desc, ThreadContext *tc,
191 VPtr<> pathname, VPtr<> new_pathname);
194 SyscallReturn
symlinkFunc(SyscallDesc *desc, ThreadContext *tc,
195 VPtr<> pathname, VPtr<> new_pathname);
198 SyscallReturn
mkdirFunc(SyscallDesc *desc, ThreadContext *tc,
199 VPtr<> pathname, mode_t
mode);
200 SyscallReturn
mkdirImpl(SyscallDesc *desc, ThreadContext *tc,
201 std::string path, mode_t
mode);
204 SyscallReturn
mknodFunc(SyscallDesc *desc, ThreadContext *tc,
205 VPtr<> pathname, mode_t
mode, dev_t dev);
206 SyscallReturn
mknodImpl(SyscallDesc *desc, ThreadContext *tc,
207 std::string path, mode_t
mode, dev_t dev);
210 SyscallReturn
chdirFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> pathname);
213 SyscallReturn
rmdirFunc(SyscallDesc *desc, ThreadContext *tc,
215 SyscallReturn
rmdirImpl(SyscallDesc *desc, ThreadContext *tc,
219 SyscallReturn
renameFunc(SyscallDesc *desc, ThreadContext *tc,
220 VPtr<> oldpath, VPtr<> newpath);
221 SyscallReturn
renameImpl(SyscallDesc *desc, ThreadContext *tc,
222 std::string oldpath, std::string newpath);
225 SyscallReturn
truncate64Func(SyscallDesc *desc, ThreadContext *tc,
226 VPtr<> pathname, int64_t length);
230 int tgt_fd, int64_t length);
233 SyscallReturn
umaskFunc(SyscallDesc *desc, ThreadContext *tc);
236 SyscallReturn
gettidFunc(SyscallDesc *desc, ThreadContext *tc);
239 SyscallReturn
chownFunc(SyscallDesc *desc, ThreadContext *tc,
240 VPtr<> pathname, uint32_t owner, uint32_t group);
241 SyscallReturn
chownImpl(SyscallDesc *desc, ThreadContext *tc,
242 std::string path, uint32_t owner, uint32_t group);
245 SyscallReturn
getpgrpFunc(SyscallDesc *desc, ThreadContext *tc);
248 SyscallReturn
setpgidFunc(SyscallDesc *desc, ThreadContext *tc,
252 SyscallReturn
fchownFunc(SyscallDesc *desc, ThreadContext *tc,
253 int tgt_fd, uint32_t owner, uint32_t group);
256 SyscallReturn
dupFunc(SyscallDesc *desc, ThreadContext *tc,
260 SyscallReturn
dup2Func(SyscallDesc *desc, ThreadContext *tc,
261 int old_tgt_fd,
int new_tgt_fd);
264 SyscallReturn
fcntlFunc(SyscallDesc *desc, ThreadContext *tc,
265 int tgt_fd,
int cmd, guest_abi::VarArgs<int> varargs);
268 SyscallReturn
fcntl64Func(SyscallDesc *desc, ThreadContext *tc,
269 int tgt_fd,
int cmd);
272 SyscallReturn
pipeFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> tgt_addr);
275 SyscallReturn
pipe2Func(SyscallDesc *desc, ThreadContext *tc,
276 VPtr<> tgt_addr,
int flags);
279 SyscallReturn
getpidFunc(SyscallDesc *desc, ThreadContext *tc);
283 int tgt_fd, VPtr<> sockAddrPtr,
287 SyscallReturn
bindFunc(SyscallDesc *desc, ThreadContext *tc,
288 int tgt_fd, VPtr<> buf_ptr,
int addrlen);
291 SyscallReturn
listenFunc(SyscallDesc *desc, ThreadContext *tc,
292 int tgt_fd,
int backlog);
295 SyscallReturn
connectFunc(SyscallDesc *desc, ThreadContext *tc,
296 int tgt_fd, VPtr<> buf_ptr,
int addrlen);
298 #if defined(SYS_getdents)
300 SyscallReturn getdentsFunc(SyscallDesc *desc, ThreadContext *tc,
301 int tgt_fd, VPtr<> buf_ptr,
unsigned count);
304 #if defined(SYS_getdents64)
306 SyscallReturn getdents64Func(SyscallDesc *desc, ThreadContext *tc,
307 int tgt_fd, VPtr<> buf_ptr,
unsigned count);
311 SyscallReturn
recvmsgFunc(SyscallDesc *desc, ThreadContext *tc,
312 int tgt_fd, VPtr<> msgPtr,
int flags);
315 SyscallReturn
sendmsgFunc(SyscallDesc *desc, ThreadContext *tc,
316 int tgt_fd, VPtr<> msgPtr,
int flags);
319 SyscallReturn
getuidFunc(SyscallDesc *desc, ThreadContext *tc);
322 SyscallReturn
getgidFunc(SyscallDesc *desc, ThreadContext *tc);
325 SyscallReturn
getppidFunc(SyscallDesc *desc, ThreadContext *tc);
328 SyscallReturn
geteuidFunc(SyscallDesc *desc, ThreadContext *tc);
331 SyscallReturn
getegidFunc(SyscallDesc *desc, ThreadContext *tc);
334 SyscallReturn
accessFunc(SyscallDesc *desc, ThreadContext *tc,
335 VPtr<> pathname, mode_t
mode);
336 SyscallReturn
accessImpl(SyscallDesc *desc, ThreadContext *tc,
337 std::string path, mode_t
mode);
340 SyscallReturn
getsockoptFunc(SyscallDesc *desc, ThreadContext *tc,
341 int tgt_fd,
int level,
int optname,
342 VPtr<> valPtr, VPtr<> lenPtr);
345 SyscallReturn
setsockoptFunc(SyscallDesc *desc, ThreadContext *tc,
346 int tgt_fd,
int level,
int optname,
347 VPtr<> valPtr, socklen_t
len);
349 SyscallReturn
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);
515 SyscallReturn
pipePseudoFunc(SyscallDesc *desc, ThreadContext *tc);
525 template <
class T1,
class T2>
529 static const int OneMillion = 1000 * 1000;
532 sec = elapsed_usecs / OneMillion;
533 usec = elapsed_usecs % OneMillion;
538 template <
class T1,
class T2>
542 static const int OneBillion = 1000 * 1000 * 1000;
545 sec = elapsed_nsecs / OneBillion;
546 nsec = elapsed_nsecs % OneBillion;
569 template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
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);
618 template <
typename OS,
typename TgtStatPtr,
typename HostStatPtr>
623 copyOutStatBuf<OS>(tgt, host, fakeTTY);
624 #if defined(STAT_HAVE_NSEC)
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;
640 template <
class OS,
typename TgtStatPtr,
typename HostStatPtr>
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));
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));
1836 hiov[
i].iov_base =
new char [hiov[
i].iov_len];
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);
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");
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);
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) {
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());
2226 mem_proxy.tryReadString(vect[
inc], *(
Addr*)
b.bufferPtr());
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:
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;
2370 typename OS::time_t sec, usec;
2376 typename OS::time_t
t = sec;
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;
2954 template <
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;
2988 template <
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);
3010 template <
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();
3035 template <
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;
3054 template <
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;
3070 template <
typename OS>
3089 #endif // __SIM_SYSCALL_EMUL_HH__