From 02c023eebbd6b6afda10d12d3f5a98fc437f10a3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 7 May 2020 04:18:04 -0700 Subject: [PATCH] sim: Convert stat functions to use VPtr. Change-Id: I1fe43ad7508b5fbbcbf6c84195858455fc8f3e85 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/29402 Reviewed-by: Matthew Poremba Maintainer: Gabe Black Tested-by: kokoro --- src/sim/syscall_emul.hh | 264 +++++++++++++++------------------------- 1 file changed, 97 insertions(+), 167 deletions(-) diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 55695781b..f793dfd5e 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -554,11 +554,12 @@ getElapsedTimeNano(T1 &sec, T2 &nsec) //// buffer. Also copies the target buffer out to the simulated //// memory space. Used by stat(), fstat(), and lstat(). -template +template void -convertStatBuf(target_stat &tgt, host_stat *host, - ByteOrder bo, bool fakeTTY=false) +copyOutStatBuf(TgtStatPtr tgt, HostStatPtr host, bool fakeTTY=false) { + constexpr ByteOrder bo = OS::byteOrder; + if (fakeTTY) tgt->st_dev = 0xA; else @@ -602,13 +603,15 @@ convertStatBuf(target_stat &tgt, host_stat *host, // Same for stat64 -template +template void -convertStat64Buf(target_stat &tgt, host_stat64 *host, - ByteOrder bo, bool fakeTTY=false) +copyOutStat64Buf(TgtStatPtr tgt, HostStatPtr host, + bool fakeTTY=false) { - convertStatBuf(tgt, host, bo, fakeTTY); + copyOutStatBuf(tgt, host, fakeTTY); #if defined(STAT_HAVE_NSEC) + constexpr ByteOrder bo = OS::byteOrder; + tgt->st_atime_nsec = host->st_atime_nsec; tgt->st_atime_nsec = htog(tgt->st_atime_nsec, bo); tgt->st_mtime_nsec = host->st_mtime_nsec; @@ -622,38 +625,11 @@ convertStat64Buf(target_stat &tgt, host_stat64 *host, #endif } -// Here are a couple of convenience functions -template -void -copyOutStatBuf(PortProxy &mem, Addr addr, - hst_stat *host, bool fakeTTY = false) -{ - typedef TypedBufferArg tgt_stat_buf; - tgt_stat_buf tgt(addr); - convertStatBuf(tgt, host, OS::byteOrder, fakeTTY); - tgt.copyOut(mem); -} - -template -void -copyOutStat64Buf(PortProxy &mem, Addr addr, - hst_stat64 *host, bool fakeTTY = false) -{ - typedef TypedBufferArg tgt_stat_buf; - tgt_stat_buf tgt(addr); - convertStat64Buf( - tgt, host, OS::byteOrder, fakeTTY); - tgt.copyOut(mem); -} - -template +template void -copyOutStatfsBuf(PortProxy &mem, Addr addr, - hst_statfs *host) +copyOutStatfsBuf(TgtStatPtr tgt, HostStatPtr host) { - TypedBufferArg tgt(addr); - - const ByteOrder bo = OS::byteOrder; + constexpr ByteOrder bo = OS::byteOrder; tgt->f_type = htog(host->f_type, bo); #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) @@ -687,8 +663,6 @@ copyOutStatfsBuf(PortProxy &mem, Addr addr, */ memset(&tgt->f_spare, 0, sizeof(tgt->f_spare)); #endif - - tgt.copyOut(mem); } /// Target ioctl() handler. For the most part, programs call ioctl() @@ -979,18 +953,15 @@ renameatFunc(SyscallDesc *desc, ThreadContext *tc, /// Target sysinfo() handler. template SyscallReturn -sysinfoFunc(SyscallDesc *desc, ThreadContext *tc, Addr info) +sysinfoFunc(SyscallDesc *desc, ThreadContext *tc, + VPtr sysinfo) { auto process = tc->getProcessPtr(); - TypedBufferArg sysinfo(info); - sysinfo->uptime = seconds_since_epoch; sysinfo->totalram = process->system->memSize(); sysinfo->mem_unit = 1; - sysinfo.copyOut(tc->getVirtProxy()); - return 0; } @@ -1199,7 +1170,8 @@ mremapFunc(SyscallDesc *desc, ThreadContext *tc, /// Target stat() handler. template SyscallReturn -statFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) +statFunc(SyscallDesc *desc, ThreadContext *tc, + Addr pathname, VPtr tgt_stat) { std::string path; auto process = tc->getProcessPtr(); @@ -1216,7 +1188,7 @@ statFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) if (result < 0) return -errno; - copyOutStatBuf(tc->getVirtProxy(), bufPtr, &hostBuf); + copyOutStatBuf(tgt_stat, &hostBuf); return 0; } @@ -1225,7 +1197,8 @@ statFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) /// Target stat64() handler. template SyscallReturn -stat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) +stat64Func(SyscallDesc *desc, ThreadContext *tc, + Addr pathname, VPtr tgt_stat) { std::string path; auto process = tc->getProcessPtr(); @@ -1247,7 +1220,7 @@ stat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) if (result < 0) return -errno; - copyOutStat64Buf(tc->getVirtProxy(), bufPtr, &hostBuf); + copyOutStat64Buf(tgt_stat, &hostBuf); return 0; } @@ -1257,7 +1230,7 @@ stat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) template SyscallReturn fstatat64Func(SyscallDesc *desc, ThreadContext *tc, - int dirfd, Addr pathname, Addr bufPtr) + int dirfd, Addr pathname, VPtr tgt_stat) { auto process = tc->getProcessPtr(); if (dirfd != OS::TGT_AT_FDCWD) @@ -1281,7 +1254,7 @@ fstatat64Func(SyscallDesc *desc, ThreadContext *tc, if (result < 0) return -errno; - copyOutStat64Buf(tc->getVirtProxy(), bufPtr, &hostBuf); + copyOutStat64Buf(tgt_stat, &hostBuf); return 0; } @@ -1290,7 +1263,8 @@ fstatat64Func(SyscallDesc *desc, ThreadContext *tc, /// Target fstat64() handler. template SyscallReturn -fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr) +fstat64Func(SyscallDesc *desc, ThreadContext *tc, + int tgt_fd, VPtr tgt_stat) { auto p = tc->getProcessPtr(); @@ -1310,7 +1284,7 @@ fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr) if (result < 0) return -errno; - copyOutStat64Buf(tc->getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1)); + copyOutStat64Buf(tgt_stat, &hostBuf, (sim_fd == 1)); return 0; } @@ -1319,7 +1293,8 @@ fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr) /// Target lstat() handler. template SyscallReturn -lstatFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) +lstatFunc(SyscallDesc *desc, ThreadContext *tc, + Addr pathname, VPtr tgt_stat) { std::string path; auto process = tc->getProcessPtr(); @@ -1336,7 +1311,7 @@ lstatFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) if (result < 0) return -errno; - copyOutStatBuf(tc->getVirtProxy(), bufPtr, &hostBuf); + copyOutStatBuf(tgt_stat, &hostBuf); return 0; } @@ -1344,7 +1319,8 @@ lstatFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) /// Target lstat64() handler. template SyscallReturn -lstat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) +lstat64Func(SyscallDesc *desc, ThreadContext *tc, + Addr pathname, VPtr tgt_stat) { std::string path; auto process = tc->getProcessPtr(); @@ -1366,7 +1342,7 @@ lstat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) if (result < 0) return -errno; - copyOutStat64Buf(tc->getVirtProxy(), bufPtr, &hostBuf); + copyOutStat64Buf(tgt_stat, &hostBuf); return 0; } @@ -1374,7 +1350,8 @@ lstat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) /// Target fstat() handler. template SyscallReturn -fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr) +fstatFunc(SyscallDesc *desc, ThreadContext *tc, + int tgt_fd, VPtr tgt_stat) { auto p = tc->getProcessPtr(); @@ -1391,7 +1368,7 @@ fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr) if (result < 0) return -errno; - copyOutStatBuf(tc->getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1)); + copyOutStatBuf(tgt_stat, &hostBuf, (sim_fd == 1)); return 0; } @@ -1399,7 +1376,8 @@ fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr) /// Target statfs() handler. template SyscallReturn -statfsFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) +statfsFunc(SyscallDesc *desc, ThreadContext *tc, + Addr pathname, VPtr tgt_stat) { #if defined(__linux__) std::string path; @@ -1417,7 +1395,7 @@ statfsFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr) if (result < 0) return -errno; - copyOutStatfsBuf(tc->getVirtProxy(), bufPtr, &hostBuf); + copyOutStatfsBuf(tgt_stat, &hostBuf); return 0; #else warnUnsupportedOS("statfs"); @@ -1551,7 +1529,8 @@ cloneBackwardsFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, /// Target fstatfs() handler. template SyscallReturn -fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr) +fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, + int tgt_fd, VPtr tgt_stat) { auto p = tc->getProcessPtr(); @@ -1566,7 +1545,7 @@ fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr) if (result < 0) return -errno; - copyOutStatfsBuf(tc->getVirtProxy(), bufPtr, &hostBuf); + copyOutStatfsBuf(tgt_stat, &hostBuf); return 0; } @@ -1841,10 +1820,8 @@ mmap2Func(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn getrlimitFunc(SyscallDesc *desc, ThreadContext *tc, - unsigned resource, Addr rlim) + unsigned resource, VPtr rlp) { - TypedBufferArg rlp(rlim); - const ByteOrder bo = OS::byteOrder; switch (resource) { case OS::TGT_RLIMIT_STACK: @@ -1873,24 +1850,22 @@ getrlimitFunc(SyscallDesc *desc, ThreadContext *tc, break; } - rlp.copyOut(tc->getVirtProxy()); return 0; } template SyscallReturn prlimitFunc(SyscallDesc *desc, ThreadContext *tc, - int pid, int resource, Addr n, Addr o) + int pid, int resource, Addr n, VPtr rlp) { if (pid != 0) { warn("prlimit: ignoring rlimits for nonzero pid"); return -EPERM; } - if (n != 0) + if (n) warn("prlimit: ignoring new rlimit"); - if (o != 0) { + if (rlp) { const ByteOrder bo = OS::byteOrder; - TypedBufferArg rlp(o); switch (resource) { case OS::TGT_RLIMIT_STACK: // max stack size in bytes: make up a number (8MB for now) @@ -1909,7 +1884,6 @@ prlimitFunc(SyscallDesc *desc, ThreadContext *tc, return -EINVAL; break; } - rlp.copyOut(tc->getVirtProxy()); } return 0; } @@ -1918,33 +1892,26 @@ prlimitFunc(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn clock_gettimeFunc(SyscallDesc *desc, ThreadContext *tc, - int clk_id, Addr tp_ptr) + int clk_id, VPtr tp) { - TypedBufferArg tp(tp_ptr); - getElapsedTimeNano(tp->tv_sec, tp->tv_nsec); tp->tv_sec += seconds_since_epoch; tp->tv_sec = htog(tp->tv_sec, OS::byteOrder); tp->tv_nsec = htog(tp->tv_nsec, OS::byteOrder); - tp.copyOut(tc->getVirtProxy()); - return 0; } /// Target clock_getres() function. template SyscallReturn -clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, Addr tp_ptr) +clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, + VPtr tp) { - TypedBufferArg tp(tp_ptr); - // Set resolution at ns, which is what clock_gettime() returns tp->tv_sec = 0; tp->tv_nsec = 1; - tp.copyOut(tc->getVirtProxy()); - return 0; } @@ -1952,17 +1919,13 @@ clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, Addr tp_ptr) template SyscallReturn gettimeofdayFunc(SyscallDesc *desc, ThreadContext *tc, - Addr tv_ptr, Addr tz_ptr) + VPtr tp, Addr tz_ptr) { - TypedBufferArg tp(tv_ptr); - getElapsedTimeMicro(tp->tv_sec, tp->tv_usec); tp->tv_sec += seconds_since_epoch; tp->tv_sec = htog(tp->tv_sec, OS::byteOrder); tp->tv_usec = htog(tp->tv_usec, OS::byteOrder); - tp.copyOut(tc->getVirtProxy()); - return 0; } @@ -2090,10 +2053,9 @@ execveFunc(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn getrusageFunc(SyscallDesc *desc, ThreadContext *tc, - int who /* THREAD, SELF, or CHILDREN */, Addr usage) + int who /* THREAD, SELF, or CHILDREN */, + VPtr rup) { - TypedBufferArg rup(usage); - rup->ru_utime.tv_sec = 0; rup->ru_utime.tv_usec = 0; rup->ru_stime.tv_sec = 0; @@ -2131,18 +2093,14 @@ getrusageFunc(SyscallDesc *desc, ThreadContext *tc, who); } - rup.copyOut(tc->getVirtProxy()); - return 0; } /// Target times() function. template SyscallReturn -timesFunc(SyscallDesc *desc, ThreadContext *tc, Addr bufPtr) +timesFunc(SyscallDesc *desc, ThreadContext *tc, VPtr bufp) { - TypedBufferArg bufp(bufPtr); - // Fill in the time structure (in clocks) int64_t clocks = curTick() * OS::M5_SC_CLK_TCK / SimClock::Int::s; bufp->tms_utime = clocks; @@ -2153,9 +2111,6 @@ timesFunc(SyscallDesc *desc, ThreadContext *tc, Addr bufPtr) // Convert to host endianness bufp->tms_utime = htog(bufp->tms_utime, OS::byteOrder); - // Write back - bufp.copyOut(tc->getVirtProxy()); - // Return clock ticks since system boot return clocks; } @@ -2264,40 +2219,27 @@ socketpairFunc(SyscallDesc *desc, ThreadContext *tc, template SyscallReturn -selectFunc(SyscallDesc *desc, ThreadContext *tc, - int nfds_t, Addr fds_read_ptr, Addr fds_writ_ptr, - Addr fds_excp_ptr, Addr time_val_ptr) +selectFunc(SyscallDesc *desc, ThreadContext *tc, int nfds, + VPtr readfds, + VPtr writefds, + VPtr errorfds, + VPtr timeout) { int retval; auto p = tc->getProcessPtr(); - TypedBufferArg rd_t(fds_read_ptr); - TypedBufferArg wr_t(fds_writ_ptr); - TypedBufferArg ex_t(fds_excp_ptr); - TypedBufferArg tp(time_val_ptr); - /** * Host fields. Notice that these use the definitions from the system * headers instead of the gem5 headers and libraries. If the host and * target have different header file definitions, this will not work. */ - fd_set rd_h; - FD_ZERO(&rd_h); - fd_set wr_h; - FD_ZERO(&wr_h); - fd_set ex_h; - FD_ZERO(&ex_h); - - /** - * Copy in the fd_set from the target. - */ - if (fds_read_ptr) - rd_t.copyIn(tc->getVirtProxy()); - if (fds_writ_ptr) - wr_t.copyIn(tc->getVirtProxy()); - if (fds_excp_ptr) - ex_t.copyIn(tc->getVirtProxy()); + fd_set readfds_h; + FD_ZERO(&readfds_h); + fd_set writefds_h; + FD_ZERO(&writefds_h); + fd_set errorfds_h; + FD_ZERO(&errorfds_h); /** * We need to translate the target file descriptor set into a host file @@ -2310,7 +2252,7 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc, */ int nfds_h = 0; std::map trans_map; - auto try_add_host_set = [&](fd_set *tgt_set_entry, + auto try_add_host_set = [&](typename OS::fd_set *tgt_set_entry, fd_set *hst_set_entry, int iter) -> bool { @@ -2319,7 +2261,7 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc, * descriptor set on the target. We need to check if the target file * descriptor value passed in as iter is part of the set. */ - if (FD_ISSET(iter, tgt_set_entry)) { + if (FD_ISSET(iter, (fd_set *)tgt_set_entry)) { /** * We know that the target file descriptor belongs to the set, * but we do not yet know if the file descriptor is valid or @@ -2353,22 +2295,25 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc, return false; }; - for (int i = 0; i < nfds_t; i++) { - if (fds_read_ptr) { - bool ebadf = try_add_host_set((fd_set*)&*rd_t, &rd_h, i); - if (ebadf) return -EBADF; + for (int i = 0; i < nfds; i++) { + if (readfds) { + bool ebadf = try_add_host_set(readfds, &readfds_h, i); + if (ebadf) + return -EBADF; } - if (fds_writ_ptr) { - bool ebadf = try_add_host_set((fd_set*)&*wr_t, &wr_h, i); - if (ebadf) return -EBADF; + if (writefds) { + bool ebadf = try_add_host_set(writefds, &writefds_h, i); + if (ebadf) + return -EBADF; } - if (fds_excp_ptr) { - bool ebadf = try_add_host_set((fd_set*)&*ex_t, &ex_h, i); - if (ebadf) return -EBADF; + if (errorfds) { + bool ebadf = try_add_host_set(errorfds, &errorfds_h, i); + if (ebadf) + return -EBADF; } } - if (time_val_ptr) { + if (timeout) { /** * It might be possible to decrement the timeval based on some * derivation of wall clock determined from elapsed simulator ticks @@ -2376,14 +2321,14 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc, * zero timeout. (There is no reason to block during the simulation * as it only decreases simulator performance.) */ - tp->tv_sec = 0; - tp->tv_usec = 0; + timeout->tv_sec = 0; + timeout->tv_usec = 0; retval = select(nfds_h, - fds_read_ptr ? &rd_h : nullptr, - fds_writ_ptr ? &wr_h : nullptr, - fds_excp_ptr ? &ex_h : nullptr, - (timeval*)&*tp); + readfds ? &readfds_h : nullptr, + writefds ? &writefds_h : nullptr, + errorfds ? &errorfds_h : nullptr, + (timeval *)(typename OS::timeval *)timeout); } else { /** * If the timeval pointer is null, setup a new timeval structure to @@ -2395,9 +2340,9 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc, struct timeval tv = { 0, 0 }; retval = select(nfds_h, - fds_read_ptr ? &rd_h : nullptr, - fds_writ_ptr ? &wr_h : nullptr, - fds_excp_ptr ? &ex_h : nullptr, + readfds ? &readfds_h : nullptr, + readfds ? &writefds_h : nullptr, + readfds ? &errorfds_h : nullptr, &tv); if (retval == 0) { @@ -2416,9 +2361,9 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc, if (retval == -1) return -errno; - FD_ZERO((fd_set*)&*rd_t); - FD_ZERO((fd_set*)&*wr_t); - FD_ZERO((fd_set*)&*ex_t); + FD_ZERO(readfds); + FD_ZERO(writefds); + FD_ZERO(errorfds); /** * We need to translate the host file descriptor set into a target file @@ -2426,31 +2371,16 @@ selectFunc(SyscallDesc *desc, ThreadContext *tc, * and the fd_set defined in header files. */ for (int i = 0; i < nfds_h; i++) { - if (fds_read_ptr) { - if (FD_ISSET(i, &rd_h)) - FD_SET(trans_map[i], (fd_set*)&*rd_t); - } + if (readfds && FD_ISSET(i, &readfds_h)) + FD_SET(trans_map[i], readfds); - if (fds_writ_ptr) { - if (FD_ISSET(i, &wr_h)) - FD_SET(trans_map[i], (fd_set*)&*wr_t); - } + if (writefds && FD_ISSET(i, &writefds_h)) + FD_SET(trans_map[i], writefds); - if (fds_excp_ptr) { - if (FD_ISSET(i, &ex_h)) - FD_SET(trans_map[i], (fd_set*)&*ex_t); - } + if (errorfds && FD_ISSET(i, &errorfds_h)) + FD_SET(trans_map[i], errorfds); } - if (fds_read_ptr) - rd_t.copyOut(tc->getVirtProxy()); - if (fds_writ_ptr) - wr_t.copyOut(tc->getVirtProxy()); - if (fds_excp_ptr) - ex_t.copyOut(tc->getVirtProxy()); - if (time_val_ptr) - tp.copyOut(tc->getVirtProxy()); - return retval; } -- 2.30.2