Apply patch for syscall emulation provided by Antti Miettinen (apm@brigitte.dna.fi). It provides support for more syscalls in syscall emulation mode.

arch/alpha/alpha_linux_process.cc:
sim/syscall_emul.cc:
sim/syscall_emul.hh:
    Apply patch for syscall emulation provided by Antti Miettinen (apm@brigitte.dna.fi).

--HG--
extra : convert_revision : 37fbc78a927110b7798343afd2c5f37a269e42b4
This commit is contained in:
Kevin Lim 2005-11-22 12:08:08 -05:00
parent fb3ae7264f
commit 6da93ea526
3 changed files with 302 additions and 9 deletions

View file

@ -117,6 +117,29 @@ class Linux {
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;
@ -176,6 +199,12 @@ class Linux {
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;
@ -205,7 +234,7 @@ class Linux {
/// 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)
{
@ -228,6 +257,40 @@ class Linux {
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;
@ -297,7 +360,7 @@ class Linux {
}
default:
cerr << "osf_getsysinfo: unknown op " << op << endl;
cerr << "osf_setsysinfo: unknown op " << op << endl;
abort();
break;
}
@ -429,8 +492,8 @@ SyscallDesc Linux::syscallDescs[] = {
/* 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),
@ -535,10 +598,10 @@ SyscallDesc Linux::syscallDescs[] = {
/* 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),
@ -780,7 +843,7 @@ SyscallDesc Linux::syscallDescs[] = {
/* 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),
@ -841,7 +904,24 @@ SyscallDesc Linux::syscallDescs[] = {
/* 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 =

View file

@ -242,3 +242,39 @@ ftruncateFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
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;
}

View file

@ -40,6 +40,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"
@ -226,6 +227,15 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num,
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 {
@ -343,6 +353,59 @@ openFunc(SyscallDesc *desc, int callnum, Process *process,
}
/// 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
@ -366,6 +429,30 @@ statFunc(SyscallDesc *desc, int callnum, Process *process,
}
/// 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
@ -388,6 +475,28 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process,
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
@ -459,6 +568,46 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process,
}
/// 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
@ -543,6 +692,34 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process,
}
/// 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