syscall_emul.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 1,024 行 · 第 1/2 页

HH
1,024
字号
    // Adjust path for current working directory    path = process->fullPath(path);    DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str());    // open the file    int fd = open(path.c_str(), hostFlags, mode);    return (fd == -1) ? -errno : process->alloc_fd(fd,path.c_str(),hostFlags,mode, false);}/// Target chmod() handler.template <class OS>SyscallReturnchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,          ThreadContext *tc){    std::string path;    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))        return -EFAULT;    uint32_t mode = tc->getSyscallArg(1);    mode_t hostMode = 0;    // XXX translate mode flags via OS::something???    hostMode = mode;    // Adjust path for current working directory    path = process->fullPath(path);    // do the chmod    int result = chmod(path.c_str(), hostMode);    if (result < 0)        return -errno;    return 0;}/// Target fchmod() handler.template <class OS>SyscallReturnfchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,           ThreadContext *tc){    int fd = tc->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 = tc->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>SyscallReturnstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,         ThreadContext *tc){    std::string path;    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))    return -EFAULT;    // Adjust path for current working directory    path = process->fullPath(path);    struct stat hostBuf;    int result = stat(path.c_str(), &hostBuf);    if (result < 0)        return -errno;    copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);    return 0;}/// Target stat64() handler.template <class OS>SyscallReturnstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,           ThreadContext *tc){    std::string path;    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))        return -EFAULT;    // Adjust path for current working directory    path = process->fullPath(path);#if NO_STAT64    struct stat  hostBuf;    int result = stat(path.c_str(), &hostBuf);#else    struct stat64 hostBuf;    int result = stat64(path.c_str(), &hostBuf);#endif    if (result < 0)        return -errno;    copyOutStat64Buf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);    return 0;}/// Target fstat64() handler.template <class OS>SyscallReturnfstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,            ThreadContext *tc){    int fd = tc->getSyscallArg(0);    if (fd < 0 || process->sim_fd(fd) < 0) {        // doesn't map to any simulator fd: not a valid target fd        return -EBADF;    }#if NO_STAT64    struct stat  hostBuf;    int result = fstat(process->sim_fd(fd), &hostBuf);#else    struct stat64  hostBuf;    int result = fstat64(process->sim_fd(fd), &hostBuf);#endif    if (result < 0)        return -errno;    copyOutStat64Buf<OS>(tc->getMemPort(), tc->getSyscallArg(1),        &hostBuf, (fd == 1));    return 0;}/// Target lstat() handler.template <class OS>SyscallReturnlstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,          ThreadContext *tc){    std::string path;    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))      return -EFAULT;    // Adjust path for current working directory    path = process->fullPath(path);    struct stat hostBuf;    int result = lstat(path.c_str(), &hostBuf);    if (result < 0)        return -errno;    copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);    return 0;}/// Target lstat64() handler.template <class OS>SyscallReturnlstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,            ThreadContext *tc){    std::string path;    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))      return -EFAULT;    // Adjust path for current working directory    path = process->fullPath(path);#if NO_STAT64    struct stat hostBuf;    int result = lstat(path.c_str(), &hostBuf);#else    struct stat64 hostBuf;    int result = lstat64(path.c_str(), &hostBuf);#endif    if (result < 0)        return -errno;    copyOutStat64Buf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);    return 0;}/// Target fstat() handler.template <class OS>SyscallReturnfstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,          ThreadContext *tc){    int fd = process->sim_fd(tc->getSyscallArg(0));    DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd);    if (fd < 0)        return -EBADF;    struct stat hostBuf;    int result = fstat(fd, &hostBuf);    if (result < 0)        return -errno;    copyOutStatBuf<OS>(tc->getMemPort(), tc->getSyscallArg(1),        &hostBuf, (fd == 1));    return 0;}/// Target statfs() handler.template <class OS>SyscallReturnstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,           ThreadContext *tc){    std::string path;    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))      return -EFAULT;    // Adjust path for current working directory    path = process->fullPath(path);    struct statfs hostBuf;    int result = statfs(path.c_str(), &hostBuf);    if (result < 0)        return -errno;    OS::copyOutStatfsBuf(tc->getMemPort(),            (Addr)(tc->getSyscallArg(1)), &hostBuf);    return 0;}/// Target fstatfs() handler.template <class OS>SyscallReturnfstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,            ThreadContext *tc){    int fd = process->sim_fd(tc->getSyscallArg(0));    if (fd < 0)        return -EBADF;    struct statfs hostBuf;    int result = fstatfs(fd, &hostBuf);    if (result < 0)        return -errno;    OS::copyOutStatfsBuf(tc->getMemPort(), tc->getSyscallArg(1),        &hostBuf);    return 0;}/// Target writev() handler.template <class OS>SyscallReturnwritevFunc(SyscallDesc *desc, int callnum, LiveProcess *process,           ThreadContext *tc){    int fd = tc->getSyscallArg(0);    if (fd < 0 || process->sim_fd(fd) < 0) {        // doesn't map to any simulator fd: not a valid target fd        return -EBADF;    }    TranslatingPort *p = tc->getMemPort();    uint64_t tiov_base = tc->getSyscallArg(1);    size_t count = tc->getSyscallArg(2);    struct iovec hiov[count];    for (int i = 0; i < count; ++i)    {        typename OS::tgt_iovec tiov;        p->readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec),                    (uint8_t*)&tiov, sizeof(typename OS::tgt_iovec));        hiov[i].iov_len = gtoh(tiov.iov_len);        hiov[i].iov_base = new char [hiov[i].iov_len];        p->readBlob(gtoh(tiov.iov_base), (uint8_t *)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/// anonymous region or /dev/zero, we can get away with doing basically/// nothing (since memory is initialized to zero and the simulator/// doesn't really check addresses anyway).  Always print a warning,/// since this could be seriously broken if we're not mapping/// /dev/zero.///// Someday we should explicitly check for /dev/zero in open, flag the/// file descriptor, and fail (or implement!) a non-anonymous mmap to/// anything else.template <class OS>SyscallReturnmmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc){    Addr start = tc->getSyscallArg(0);    uint64_t length = tc->getSyscallArg(1);    // int prot = tc->getSyscallArg(2);    int flags = tc->getSyscallArg(3);    // int fd = p->sim_fd(tc->getSyscallArg(4));    // int offset = tc->getSyscallArg(5);    if ((start  % TheISA::VMPageSize) != 0 ||        (length % TheISA::VMPageSize) != 0) {        warn("mmap failing: arguments not page-aligned: "             "start 0x%x length 0x%x",             start, length);        return -EINVAL;    }    if (start != 0) {        warn("mmap: ignoring suggested map address 0x%x, using 0x%x",             start, p->mmap_end);    }    // pick next address from our "mmap region"    start = p->mmap_end;    p->pTable->allocate(start, length);    p->mmap_end += length;    if (!(flags & OS::TGT_MAP_ANONYMOUS)) {        warn("allowing mmap of file @ fd %d. "             "This will break if not /dev/zero.", tc->getSyscallArg(4));    }    return start;}/// Target getrlimit() handler.template <class OS>SyscallReturngetrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,        ThreadContext *tc){    unsigned resource = tc->getSyscallArg(0);    TypedBufferArg<typename OS::rlimit> rlp(tc->getSyscallArg(1));    switch (resource) {        case OS::TGT_RLIMIT_STACK:            // max stack size in bytes: make up a number (2MB for now)            rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024;            rlp->rlim_cur = htog(rlp->rlim_cur);            rlp->rlim_max = htog(rlp->rlim_max);            break;        default:            std::cerr << "getrlimitFunc: unimplemented resource " << resource                << std::endl;            abort();            break;    }    rlp.copyOut(tc->getMemPort());    return 0;}/// Target gettimeofday() handler.template <class OS>SyscallReturngettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process,        ThreadContext *tc){    TypedBufferArg<typename OS::timeval> tp(tc->getSyscallArg(0));    getElapsedTime(tp->tv_sec, tp->tv_usec);    tp->tv_sec += seconds_since_epoch;    tp->tv_sec = htog(tp->tv_sec);    tp->tv_usec = htog(tp->tv_usec);    tp.copyOut(tc->getMemPort());    return 0;}/// Target utimes() handler.template <class OS>SyscallReturnutimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,           ThreadContext *tc){    std::string path;    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))      return -EFAULT;    TypedBufferArg<typename OS::timeval [2]> tp(tc->getSyscallArg(1));    tp.copyIn(tc->getMemPort());    struct timeval hostTimeval[2];    for (int i = 0; i < 2; ++i)    {        hostTimeval[i].tv_sec = gtoh((*tp)[i].tv_sec);        hostTimeval[i].tv_usec = gtoh((*tp)[i].tv_usec);    }    // Adjust path for current working directory    path = process->fullPath(path);    int result = utimes(path.c_str(), hostTimeval);    if (result < 0)        return -errno;    return 0;}/// Target getrusage() function.template <class OS>SyscallReturngetrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process,              ThreadContext *tc){    int who = tc->getSyscallArg(0);	// THREAD, SELF, or CHILDREN    TypedBufferArg<typename OS::rusage> rup(tc->getSyscallArg(1));    rup->ru_utime.tv_sec = 0;    rup->ru_utime.tv_usec = 0;    rup->ru_stime.tv_sec = 0;    rup->ru_stime.tv_usec = 0;    rup->ru_maxrss = 0;    rup->ru_ixrss = 0;    rup->ru_idrss = 0;    rup->ru_isrss = 0;    rup->ru_minflt = 0;    rup->ru_majflt = 0;    rup->ru_nswap = 0;    rup->ru_inblock = 0;    rup->ru_oublock = 0;    rup->ru_msgsnd = 0;    rup->ru_msgrcv = 0;    rup->ru_nsignals = 0;    rup->ru_nvcsw = 0;    rup->ru_nivcsw = 0;    switch (who) {      case OS::TGT_RUSAGE_SELF:        getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec);        rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec);        rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec);        break;      case OS::TGT_RUSAGE_CHILDREN:        // do nothing.  We have no child processes, so they take no time.        break;      default:        // don't really handle THREAD or CHILDREN, but just warn and        // plow ahead        warn("getrusage() only supports RUSAGE_SELF.  Parameter %d ignored.",             who);    }    rup.copyOut(tc->getMemPort());    return 0;}#endif // __SIM_SYSCALL_EMUL_HH__

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?