Here's the patch I mentioned in the previous email... I didn't realize
it hadn't originally gone to the list. This code will be incorporated
into the 2.0 release, but here it is in case you need it sooner.
(Thanks again, Antti.)
Steve
-------- Original Message --------
Subject: More system calls
Resent-Date: Sun, 20 Nov 2005 17:21:00 -0500
Resent-From: [EMAIL PROTECTED]
Date: Mon, 21 Nov 2005 00:20:52 +0200 (EET)
From: Antti P Miettinen <[EMAIL PROTECTED]>
Reply-To: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
I downloaded the m5 1.1 from sf.net and have been playing with it
during the weekend. Currently I'm mostly interested in the syscall
emulation mode.
Seems that the SF project page does not have any kind of revision
control repo link so don't know if someone has already more syscalls
implemented, but since implementing some seemed easy enough, for what
its worth, a patch is attached. Probably not very pretty and
practically untested but with these I can run gzip (not all of them
are needed for gzip).
Has anyone thought of adding support for dynamically linked binaries? I
tried by running alpha ld.so with some arguments but so far I haven't
been able to run dynamically linked binaries.
What about the licensing conditions of M5 given the m5/encumbered
directory. If I do
from DetailedUniConfig import *
[..]
root = DetailedStandAlone()
am I invoking something from the encumbered directory?
Have you considered mirroring your mailing lists to gmane.org?
Is anyone working on ARM ISA? :-)
--- m5_1.1-orig/m5/arch/alpha/alpha_linux_process.cc 2005-10-06
21:01:28.000000000 +0300
+++ m5_1.1-apm/m5/arch/alpha/alpha_linux_process.cc 2005-11-20
00:59:42.000000000 +0200
@@ -120,6 +120,29 @@
uint32_t st_gen; //!< unknown
};
+ // same for stat64
+ struct tgt_stat64 {
+ uint64_t st_dev;
+ uint64_t st_ino;
+ uint64_t st_rdev;
+ int64_t st_size;
+ uint64_t st_blocks;
+
+ uint32_t st_mode;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint32_t st_blksize;
+ uint32_t st_nlink;
+ uint32_t __pad0;
+
+ uint64_t tgt_st_atime;
+ uint64_t st_atime_nsec;
+ uint64_t tgt_st_mtime;
+ uint64_t st_mtime_nsec;
+ uint64_t tgt_st_ctime;
+ uint64_t st_ctime_nsec;
+ int64_t __unused[3];
+ };
/// Length of strings in struct utsname (plus 1 for null char).
static const int _SYS_NMLN = 65;
@@ -179,6 +202,12 @@
int64_t tv_usec; //!< microseconds
};
+ // For writev/readv
+ struct tgt_iovec {
+ uint64_t iov_base; // void *
+ uint64_t iov_len;
+ };
+
//@{
/// For getrusage().
static const int RUSAGE_SELF = 0;
@@ -208,7 +237,7 @@
/// Helper function to convert a host stat buffer to a target stat
/// buffer. Also copies the target buffer out to the simulated
- /// memorty space. Used by stat(), fstat(), and lstat().
+ /// memory space. Used by stat(), fstat(), and lstat().
static void
copyOutStatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
{
@@ -231,6 +260,40 @@
tgt.copyOut(mem);
}
+ // Same for stat64
+ static void
+ copyOutStat64Buf(FunctionalMemory *mem, Addr addr, struct stat64 *host)
+ {
+ TypedBufferArg<Linux::tgt_stat64> tgt(addr);
+
+ // XXX byteswaps
+ tgt->st_dev = host->st_dev;
+ // XXX What about STAT64_HAS_BROKEN_ST_INO ???
+ tgt->st_ino = host->st_ino;
+ tgt->st_rdev = host->st_rdev;
+ tgt->st_size = host->st_size;
+ tgt->st_blocks = host->st_blocks;
+
+ tgt->st_mode = host->st_mode;
+ tgt->st_uid = host->st_uid;
+ tgt->st_gid = host->st_gid;
+ tgt->st_blksize = host->st_blksize;
+ tgt->st_nlink = host->st_nlink;
+ tgt->tgt_st_atime = host->st_atime;
+ tgt->tgt_st_mtime = host->st_mtime;
+ tgt->tgt_st_ctime = host->st_ctime;
+#ifdef STAT_HAVE_NSEC
+ tgt->st_atime_nsec = host->st_atime_nsec;
+ tgt->st_mtime_nsec = host->st_mtime_nsec;
+ tgt->st_ctime_nsec = host->st_ctime_nsec;
+#else
+ tgt->st_atime_nsec = 0;
+ tgt->st_mtime_nsec = 0;
+ tgt->st_ctime_nsec = 0;
+#endif
+ tgt.copyOut(mem);
+ }
+
/// The target system's hostname.
static const char *hostname;
@@ -300,7 +363,7 @@
}
default:
- cerr << "osf_getsysinfo: unknown op " << op << endl;
+ cerr << "osf_setsysinfo: unknown op " << op << endl;
abort();
break;
}
@@ -432,8 +495,8 @@
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
/* 13 */ SyscallDesc("fchdir", unimplementedFunc),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
- /* 15 */ SyscallDesc("chmod", unimplementedFunc),
- /* 16 */ SyscallDesc("chown", unimplementedFunc),
+ /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
+ /* 16 */ SyscallDesc("chown", chownFunc),
/* 17 */ SyscallDesc("brk", obreakFunc),
/* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
@@ -538,10 +601,10 @@
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
/* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc),
/* 120 */ SyscallDesc("readv", unimplementedFunc),
- /* 121 */ SyscallDesc("writev", unimplementedFunc),
+ /* 121 */ SyscallDesc("writev", writevFunc<Linux>),
/* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc),
- /* 123 */ SyscallDesc("fchown", unimplementedFunc),
- /* 124 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 123 */ SyscallDesc("fchown", fchownFunc),
+ /* 124 */ SyscallDesc("fchmod", fchmodFunc<Linux>),
/* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
/* 126 */ SyscallDesc("setreuid", unimplementedFunc),
/* 127 */ SyscallDesc("setregid", unimplementedFunc),
@@ -783,7 +846,7 @@
/* 360 */ SyscallDesc("settimeofday", unimplementedFunc),
/* 361 */ SyscallDesc("getitimer", unimplementedFunc),
/* 362 */ SyscallDesc("setitimer", unimplementedFunc),
- /* 363 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 363 */ SyscallDesc("utimes", utimesFunc<Linux>),
/* 364 */ SyscallDesc("getrusage", getrusageFunc<Linux>),
/* 365 */ SyscallDesc("wait4", unimplementedFunc),
/* 366 */ SyscallDesc("adjtimex", unimplementedFunc),
@@ -844,7 +907,24 @@
/* 421 */ SyscallDesc("clock_getres", unimplementedFunc),
/* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
/* 423 */ SyscallDesc("semtimedop", unimplementedFunc),
- /* 424 */ SyscallDesc("tgkill", unimplementedFunc)
+ /* 424 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 425 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 426 */ SyscallDesc("lstat64", lstat64Func<Linux>),
+ /* 427 */ SyscallDesc("fstat64", fstat64Func<Linux>),
+ /* 428 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 429 */ SyscallDesc("mbind", unimplementedFunc),
+ /* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc),
+ /* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc),
+ /* 432 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 433 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 436 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 438 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 439 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 440 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 441 */ SyscallDesc("keyctl", unimplementedFunc)
};
const int Linux::Num_Syscall_Descs =
--- m5_1.1-orig/m5/sim/syscall_emul.hh 2005-10-06 21:01:28.000000000 +0300
+++ m5_1.1-apm/m5/sim/syscall_emul.hh 2005-11-20 01:08:49.000000000 +0200
@@ -43,6 +43,7 @@
#ifdef __CYGWIN32__
#include <sys/fcntl.h> // for O_BINARY
#endif
+#include <sys/uio.h>
#include "base/intmath.hh" // for RoundUp
#include "mem/functional/functional.hh"
@@ -229,6 +230,15 @@
Process *p, ExecContext *xc);
+/// Target chown() handler.
+SyscallReturn chownFunc(SyscallDesc *desc, int num,
+ Process *p, ExecContext *xc);
+
+
+/// Target fchown() handler.
+SyscallReturn fchownFunc(SyscallDesc *desc, int num,
+ Process *p, ExecContext *xc);
+
/// 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 {
@@ -346,6 +356,59 @@
}
+/// Target chmod() handler.
+template <class OS>
+SyscallReturn
+chmodFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ std::string path;
+
+ if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
+ return -EFAULT;
+
+ uint32_t mode = xc->getSyscallArg(1);
+ mode_t hostMode = 0;
+
+ // XXX translate mode flags via OS::something???
+ hostMode = mode;
+
+ // do the chmod
+ int result = chmod(path.c_str(), hostMode);
+ if (result < 0)
+ return errno;
+
+ return 0;
+}
+
+
+/// Target fchmod() handler.
+template <class OS>
+SyscallReturn
+fchmodFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ int fd = xc->getSyscallArg(0);
+ if (fd < 0 || process->sim_fd(fd) < 0) {
+ // doesn't map to any simulator fd: not a valid target fd
+ return -EBADF;
+ }
+
+ uint32_t mode = xc->getSyscallArg(1);
+ mode_t hostMode = 0;
+
+ // XXX translate mode flags via OS::someting???
+ hostMode = mode;
+
+ // do the fchmod
+ int result = fchmod(process->sim_fd(fd), hostMode);
+ if (result < 0)
+ return errno;
+
+ return 0;
+}
+
+
/// Target stat() handler.
template <class OS>
SyscallReturn
@@ -369,6 +432,30 @@
}
+/// Target fstat64() handler.
+template <class OS>
+SyscallReturn
+fstat64Func(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ int fd = xc->getSyscallArg(0);
+ if (fd < 0 || process->sim_fd(fd) < 0) {
+ // doesn't map to any simulator fd: not a valid target fd
+ return -EBADF;
+ }
+
+ struct stat64 hostBuf;
+ int result = fstat64(process->sim_fd(fd), &hostBuf);
+
+ if (result < 0)
+ return errno;
+
+ OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf);
+
+ return 0;
+}
+
+
/// Target lstat() handler.
template <class OS>
SyscallReturn
@@ -391,6 +478,28 @@
return 0;
}
+/// Target lstat64() handler.
+template <class OS>
+SyscallReturn
+lstat64Func(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ std::string path;
+
+ if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
+ return -EFAULT;
+
+ struct stat64 hostBuf;
+ int result = lstat64(path.c_str(), &hostBuf);
+
+ if (result < 0)
+ return -errno;
+
+ OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf);
+
+ return 0;
+}
+
/// Target fstat() handler.
template <class OS>
SyscallReturn
@@ -462,6 +571,46 @@
}
+/// Target writev() handler.
+template <class OS>
+SyscallReturn
+writevFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ int fd = xc->getSyscallArg(0);
+ if (fd < 0 || process->sim_fd(fd) < 0) {
+ // doesn't map to any simulator fd: not a valid target fd
+ return -EBADF;
+ }
+
+ uint64_t tiov_base = xc->getSyscallArg(1);
+ size_t count = xc->getSyscallArg(2);
+ struct iovec hiov[count];
+ for (int i = 0; i < count; ++i)
+ {
+ typename OS::tgt_iovec tiov;
+ xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec),
+ &tiov, sizeof(typename OS::tgt_iovec));
+ hiov[i].iov_len = tiov.iov_len;
+ hiov[i].iov_base = new char [hiov[i].iov_len];
+ xc->mem->access(Read, tiov.iov_base,
+ hiov[i].iov_base, hiov[i].iov_len);
+ }
+
+ int result = writev(process->sim_fd(fd), hiov, count);
+
+ for (int i = 0; i < count; ++i)
+ {
+ delete [] (char *)hiov[i].iov_base;
+ }
+
+ if (result < 0)
+ return errno;
+
+ return 0;
+}
+
+
/// Target mmap() handler.
///
/// We don't really handle mmap(). If the target is mmaping an
@@ -546,6 +695,34 @@
}
+/// Target utimes() handler.
+template <class OS>
+SyscallReturn
+utimesFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ std::string path;
+
+ if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
+ return -EFAULT;
+
+ TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1));
+ tp.copyIn(xc->mem);
+
+ struct timeval hostTimeval[2];
+ for (int i = 0; i < 2; ++i)
+ {
+ hostTimeval[i].tv_sec = (*tp)[i].tv_sec;
+ hostTimeval[i].tv_usec = (*tp)[i].tv_usec;
+ }
+ int result = utimes(path.c_str(), hostTimeval);
+
+ if (result < 0)
+ return -errno;
+
+ return 0;
+}
+
/// Target getrusage() function.
template <class OS>
SyscallReturn
--- m5_1.1-orig/m5/sim/syscall_emul.cc 2005-10-06 21:01:28.000000000 +0300
+++ m5_1.1-apm/m5/sim/syscall_emul.cc 2005-11-19 13:24:16.000000000 +0200
@@ -249,3 +249,39 @@
int result = ftruncate(fd, length);
return (result == -1) ? -errno : result;
}
+
+SyscallReturn
+chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+{
+ string path;
+
+ if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
+ return -EFAULT;
+
+ /* XXX endianess */
+ uint32_t owner = xc->getSyscallArg(1);
+ uid_t hostOwner = owner;
+ uint32_t group = xc->getSyscallArg(2);
+ gid_t hostGroup = group;
+
+ int result = chown(path.c_str(), hostOwner, hostGroup);
+ return (result == -1) ? -errno : result;
+}
+
+SyscallReturn
+fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
+{
+ int fd = process->sim_fd(xc->getSyscallArg(0));
+
+ if (fd < 0)
+ return -EBADF;
+
+ /* XXX endianess */
+ uint32_t owner = xc->getSyscallArg(1);
+ uid_t hostOwner = owner;
+ uint32_t group = xc->getSyscallArg(2);
+ gid_t hostGroup = group;
+
+ int result = fchown(fd, hostOwner, hostGroup);
+ return (result == -1) ? -errno : result;
+}