summaryrefslogtreecommitdiff
path: root/src/sim/syscall_emul.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/syscall_emul.hh')
-rw-r--r--src/sim/syscall_emul.hh113
1 files changed, 96 insertions, 17 deletions
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 69ef31421..978e0bce7 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -46,9 +46,11 @@
#ifdef __CYGWIN32__
#include <sys/fcntl.h> // for O_BINARY
#endif
+#include <sys/stat.h>
+#include <fcntl.h>
#include <sys/uio.h>
-#include "arch/isa_traits.hh" // for Addr
+#include "sim/host.hh" // for Addr
#include "base/chunk_generator.hh"
#include "base/intmath.hh" // for RoundUp
#include "base/misc.hh"
@@ -305,15 +307,6 @@ SyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num,
Process *p, ThreadContext *tc);
-/// This struct is used to build an target-OS-dependent table that
-/// maps the target's open() flags to the host open() flags.
-struct OpenFlagTransTable {
- int tgtFlag; //!< Target system flag value.
- int hostFlag; //!< Corresponding host system flag value.
-};
-
-
-
/// A readable name for 1,000,000, for converting microseconds to seconds.
const int one_million = 1000000;
@@ -340,6 +333,92 @@ getElapsedTime(T1 &sec, T2 &usec)
//
//////////////////////////////////////////////////////////////////////
+#if NO_STAT64
+ typedef struct stat hst_stat;
+ typedef struct stat hst_stat64;
+#else
+ typedef struct stat hst_stat;
+ typedef struct stat64 hst_stat64;
+#endif
+
+//// Helper function to convert a host stat buffer to a target stat
+//// 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>
+static void
+convertStatBuf(target_stat &tgt, host_stat *host, bool fakeTTY = false)
+{
+ if (fakeTTY)
+ tgt->st_dev = 0xA;
+ else
+ tgt->st_dev = host->st_dev;
+ tgt->st_dev = htog(tgt->st_dev);
+ tgt->st_ino = host->st_ino;
+ tgt->st_ino = htog(tgt->st_ino);
+ if (fakeTTY)
+ tgt->st_rdev = 0x880d;
+ else
+ tgt->st_rdev = host->st_rdev;
+ tgt->st_rdev = htog(tgt->st_rdev);
+ tgt->st_size = host->st_size;
+ tgt->st_size = htog(tgt->st_size);
+ tgt->st_atimeX = host->st_atimeX;
+ tgt->st_atimeX = htog(tgt->st_atimeX);
+ tgt->st_mtimeX = host->st_mtimeX;
+ tgt->st_mtimeX = htog(tgt->st_mtimeX);
+ tgt->st_ctimeX = host->st_ctimeX;
+ tgt->st_ctimeX = htog(tgt->st_ctimeX);
+ tgt->st_blksize = host->st_blksize;
+ tgt->st_blksize = htog(tgt->st_blksize);
+ tgt->st_blocks = host->st_blocks;
+ tgt->st_blocks = htog(tgt->st_blocks);
+}
+
+// Same for stat64
+
+template <typename target_stat, typename host_stat64>
+static void
+convertStat64Buf(target_stat &tgt, host_stat64 *host, bool fakeTTY = false)
+{
+ convertStatBuf<target_stat, host_stat64>(tgt, host, fakeTTY);
+#if defined(STAT_HAVE_NSEC)
+ tgt->st_atime_nsec = host->st_atime_nsec;
+ tgt->st_atime_nsec = htog(tgt->st_atime_nsec);
+ tgt->st_mtime_nsec = host->st_mtime_nsec;
+ tgt->st_mtime_nsec = htog(tgt->st_mtime_nsec);
+ tgt->st_ctime_nsec = host->st_ctime_nsec;
+ tgt->st_ctime_nsec = htog(tgt->st_ctime_nsec);
+#else
+ tgt->st_atime_nsec = 0;
+ tgt->st_mtime_nsec = 0;
+ tgt->st_ctime_nsec = 0;
+#endif
+}
+
+//Here are a couple convenience functions
+template<class OS>
+static void
+copyOutStatBuf(TranslatingPort * 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, fakeTTY);
+ tgt.copyOut(mem);
+}
+
+template<class OS>
+static void
+copyOutStat64Buf(TranslatingPort * mem, Addr addr,
+ hst_stat64 *host, bool fakeTTY = false)
+{
+ typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf;
+ tgt_stat_buf tgt(addr);
+ convertStatBuf<tgt_stat_buf, hst_stat64>(tgt, host, fakeTTY);
+ tgt.copyOut(mem);
+}
+
/// Target ioctl() handler. For the most part, programs call ioctl()
/// only to find out if their stdout is a tty, to determine whether to
/// do line or block buffering.
@@ -492,7 +571,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -521,7 +600,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStat64Buf(tc->getMemPort(), fd, tc->getSyscallArg(1), &hostBuf);
+ copyOutStat64Buf<OS>(tc->getMemPort(), fd, tc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -544,7 +623,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -571,7 +650,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStat64Buf(tc->getMemPort(), -1, tc->getSyscallArg(1), &hostBuf);
+ copyOutStat64Buf<OS>(tc->getMemPort(), -1, tc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -595,7 +674,7 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -618,7 +697,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
+ copyOutStatfsBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -641,7 +720,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
+ copyOutStatfsBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
return 0;
}