//// buffer. Also copies the target buffer out to the simulated
//// memory space. Used by stat(), fstat(), and lstat().
-template <typename target_stat, typename host_stat>
+template <typename OS, typename TgtStatPtr, typename HostStatPtr>
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
// Same for stat64
-template <typename target_stat, typename host_stat64>
+template <typename OS, typename TgtStatPtr, typename HostStatPtr>
void
-convertStat64Buf(target_stat &tgt, host_stat64 *host,
- ByteOrder bo, bool fakeTTY=false)
+copyOutStat64Buf(TgtStatPtr tgt, HostStatPtr host,
+ bool fakeTTY=false)
{
- convertStatBuf<target_stat, host_stat64>(tgt, host, bo, fakeTTY);
+ copyOutStatBuf<OS>(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;
#endif
}
-// Here are a couple of convenience functions
-template<class OS>
-void
-copyOutStatBuf(PortProxy &mem, Addr addr,
- hst_stat *host, bool fakeTTY = false)
-{
- typedef TypedBufferArg<typename OS::tgt_stat> tgt_stat_buf;
- tgt_stat_buf tgt(addr);
- convertStatBuf<tgt_stat_buf, hst_stat>(tgt, host, OS::byteOrder, fakeTTY);
- tgt.copyOut(mem);
-}
-
-template<class OS>
-void
-copyOutStat64Buf(PortProxy &mem, Addr addr,
- hst_stat64 *host, bool fakeTTY = false)
-{
- typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf;
- tgt_stat_buf tgt(addr);
- convertStat64Buf<tgt_stat_buf, hst_stat64>(
- tgt, host, OS::byteOrder, fakeTTY);
- tgt.copyOut(mem);
-}
-
-template <class OS>
+template <class OS, typename TgtStatPtr, typename HostStatPtr>
void
-copyOutStatfsBuf(PortProxy &mem, Addr addr,
- hst_statfs *host)
+copyOutStatfsBuf(TgtStatPtr tgt, HostStatPtr host)
{
- TypedBufferArg<typename OS::tgt_statfs> 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__)
*/
memset(&tgt->f_spare, 0, sizeof(tgt->f_spare));
#endif
-
- tgt.copyOut(mem);
}
/// Target ioctl() handler. For the most part, programs call ioctl()
/// Target sysinfo() handler.
template <class OS>
SyscallReturn
-sysinfoFunc(SyscallDesc *desc, ThreadContext *tc, Addr info)
+sysinfoFunc(SyscallDesc *desc, ThreadContext *tc,
+ VPtr<typename OS::tgt_sysinfo> sysinfo)
{
auto process = tc->getProcessPtr();
- TypedBufferArg<typename OS::tgt_sysinfo> sysinfo(info);
-
sysinfo->uptime = seconds_since_epoch;
sysinfo->totalram = process->system->memSize();
sysinfo->mem_unit = 1;
- sysinfo.copyOut(tc->getVirtProxy());
-
return 0;
}
/// Target stat() handler.
template <class OS>
SyscallReturn
-statFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
+statFunc(SyscallDesc *desc, ThreadContext *tc,
+ Addr pathname, VPtr<typename OS::tgt_stat> tgt_stat)
{
std::string path;
auto process = tc->getProcessPtr();
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
+ copyOutStatBuf<OS>(tgt_stat, &hostBuf);
return 0;
}
/// Target stat64() handler.
template <class OS>
SyscallReturn
-stat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
+stat64Func(SyscallDesc *desc, ThreadContext *tc,
+ Addr pathname, VPtr<typename OS::tgt_stat64> tgt_stat)
{
std::string path;
auto process = tc->getProcessPtr();
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
+ copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
return 0;
}
template <class OS>
SyscallReturn
fstatat64Func(SyscallDesc *desc, ThreadContext *tc,
- int dirfd, Addr pathname, Addr bufPtr)
+ int dirfd, Addr pathname, VPtr<typename OS::tgt_stat64> tgt_stat)
{
auto process = tc->getProcessPtr();
if (dirfd != OS::TGT_AT_FDCWD)
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
+ copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
return 0;
}
/// Target fstat64() handler.
template <class OS>
SyscallReturn
-fstat64Func(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
+fstat64Func(SyscallDesc *desc, ThreadContext *tc,
+ int tgt_fd, VPtr<typename OS::tgt_stat64> tgt_stat)
{
auto p = tc->getProcessPtr();
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
+ copyOutStat64Buf<OS>(tgt_stat, &hostBuf, (sim_fd == 1));
return 0;
}
/// Target lstat() handler.
template <class OS>
SyscallReturn
-lstatFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
+lstatFunc(SyscallDesc *desc, ThreadContext *tc,
+ Addr pathname, VPtr<typename OS::tgt_stat> tgt_stat)
{
std::string path;
auto process = tc->getProcessPtr();
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
+ copyOutStatBuf<OS>(tgt_stat, &hostBuf);
return 0;
}
/// Target lstat64() handler.
template <class OS>
SyscallReturn
-lstat64Func(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
+lstat64Func(SyscallDesc *desc, ThreadContext *tc,
+ Addr pathname, VPtr<typename OS::tgt_stat64> tgt_stat)
{
std::string path;
auto process = tc->getProcessPtr();
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
+ copyOutStat64Buf<OS>(tgt_stat, &hostBuf);
return 0;
}
/// Target fstat() handler.
template <class OS>
SyscallReturn
-fstatFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
+fstatFunc(SyscallDesc *desc, ThreadContext *tc,
+ int tgt_fd, VPtr<typename OS::tgt_stat> tgt_stat)
{
auto p = tc->getProcessPtr();
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf, (sim_fd == 1));
+ copyOutStatBuf<OS>(tgt_stat, &hostBuf, (sim_fd == 1));
return 0;
}
/// Target statfs() handler.
template <class OS>
SyscallReturn
-statfsFunc(SyscallDesc *desc, ThreadContext *tc, Addr pathname, Addr bufPtr)
+statfsFunc(SyscallDesc *desc, ThreadContext *tc,
+ Addr pathname, VPtr<typename OS::tgt_statfs> tgt_stat)
{
#if defined(__linux__)
std::string path;
if (result < 0)
return -errno;
- copyOutStatfsBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
+ copyOutStatfsBuf<OS>(tgt_stat, &hostBuf);
return 0;
#else
warnUnsupportedOS("statfs");
/// Target fstatfs() handler.
template <class OS>
SyscallReturn
-fstatfsFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_fd, Addr bufPtr)
+fstatfsFunc(SyscallDesc *desc, ThreadContext *tc,
+ int tgt_fd, VPtr<typename OS::tgt_statfs> tgt_stat)
{
auto p = tc->getProcessPtr();
if (result < 0)
return -errno;
- copyOutStatfsBuf<OS>(tc->getVirtProxy(), bufPtr, &hostBuf);
+ copyOutStatfsBuf<OS>(tgt_stat, &hostBuf);
return 0;
}
template <class OS>
SyscallReturn
getrlimitFunc(SyscallDesc *desc, ThreadContext *tc,
- unsigned resource, Addr rlim)
+ unsigned resource, VPtr<typename OS::rlimit> rlp)
{
- TypedBufferArg<typename OS::rlimit> rlp(rlim);
-
const ByteOrder bo = OS::byteOrder;
switch (resource) {
case OS::TGT_RLIMIT_STACK:
break;
}
- rlp.copyOut(tc->getVirtProxy());
return 0;
}
template <class OS>
SyscallReturn
prlimitFunc(SyscallDesc *desc, ThreadContext *tc,
- int pid, int resource, Addr n, Addr o)
+ int pid, int resource, Addr n, VPtr<typename OS::rlimit> 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<typename OS::rlimit> rlp(o);
switch (resource) {
case OS::TGT_RLIMIT_STACK:
// max stack size in bytes: make up a number (8MB for now)
return -EINVAL;
break;
}
- rlp.copyOut(tc->getVirtProxy());
}
return 0;
}
template <class OS>
SyscallReturn
clock_gettimeFunc(SyscallDesc *desc, ThreadContext *tc,
- int clk_id, Addr tp_ptr)
+ int clk_id, VPtr<typename OS::timespec> tp)
{
- TypedBufferArg<typename OS::timespec> 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 <class OS>
SyscallReturn
-clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id, Addr tp_ptr)
+clock_getresFunc(SyscallDesc *desc, ThreadContext *tc, int clk_id,
+ VPtr<typename OS::timespec> tp)
{
- TypedBufferArg<typename OS::timespec> 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;
}
template <class OS>
SyscallReturn
gettimeofdayFunc(SyscallDesc *desc, ThreadContext *tc,
- Addr tv_ptr, Addr tz_ptr)
+ VPtr<typename OS::timeval> tp, Addr tz_ptr)
{
- TypedBufferArg<typename OS::timeval> 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;
}
template <class OS>
SyscallReturn
getrusageFunc(SyscallDesc *desc, ThreadContext *tc,
- int who /* THREAD, SELF, or CHILDREN */, Addr usage)
+ int who /* THREAD, SELF, or CHILDREN */,
+ VPtr<typename OS::rusage> rup)
{
- TypedBufferArg<typename OS::rusage> rup(usage);
-
rup->ru_utime.tv_sec = 0;
rup->ru_utime.tv_usec = 0;
rup->ru_stime.tv_sec = 0;
who);
}
- rup.copyOut(tc->getVirtProxy());
-
return 0;
}
/// Target times() function.
template <class OS>
SyscallReturn
-timesFunc(SyscallDesc *desc, ThreadContext *tc, Addr bufPtr)
+timesFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<typename OS::tms> bufp)
{
- TypedBufferArg<typename OS::tms> 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;
// 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;
}
template <class OS>
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<typename OS::fd_set> readfds,
+ VPtr<typename OS::fd_set> writefds,
+ VPtr<typename OS::fd_set> errorfds,
+ VPtr<typename OS::timeval> timeout)
{
int retval;
auto p = tc->getProcessPtr();
- TypedBufferArg<typename OS::fd_set> rd_t(fds_read_ptr);
- TypedBufferArg<typename OS::fd_set> wr_t(fds_writ_ptr);
- TypedBufferArg<typename OS::fd_set> ex_t(fds_excp_ptr);
- TypedBufferArg<typename OS::timeval> 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
*/
int nfds_h = 0;
std::map<int, int> 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
{
* 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
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
* 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
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) {
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
* 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;
}