From c0cd8a68dc3d922733b5c455ecc3bfc23a76f042 Mon Sep 17 00:00:00 2001 From: huaixv <44743118+huaixv@users.noreply.github.com> Date: Thu, 25 Mar 2021 21:40:59 +0800 Subject: Add `statx` syscall --- fesvr/fesvr.ac | 5 +++ fesvr/syscall.cc | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fesvr/syscall.h | 1 + 3 files changed, 100 insertions(+) (limited to 'fesvr') diff --git a/fesvr/fesvr.ac b/fesvr/fesvr.ac index 60e6c57..9a211b1 100644 --- a/fesvr/fesvr.ac +++ b/fesvr/fesvr.ac @@ -1 +1,6 @@ AC_CHECK_LIB(pthread, pthread_create, [], [AC_MSG_ERROR([libpthread is required])]) + +AC_CHECK_MEMBER(struct statx.stx_mnt_id, + AC_DEFINE_UNQUOTED(HAVE_STATX_MNT_ID, 1, [Define to 1 if struct statx has stx_mnt_id.]), + , +) diff --git a/fesvr/syscall.cc b/fesvr/syscall.cc index fb2c3f8..8a9b29b 100644 --- a/fesvr/syscall.cc +++ b/fesvr/syscall.cc @@ -57,6 +57,84 @@ struct riscv_stat __unused4(), __unused5() {} }; + +struct riscv_statx_timestamp { + target_endian tv_sec; + target_endian tv_nsec; + target_endian __reserved; +}; + +struct riscv_statx +{ + target_endian mask; + target_endian blksize; + target_endian attributes; + target_endian nlink; + target_endian uid; + target_endian gid; + target_endian mode; + target_endian __spare0[1]; + target_endian ino; + target_endian size; + target_endian blocks; + target_endian attributes_mask; + struct riscv_statx_timestamp atime; + struct riscv_statx_timestamp btime; + struct riscv_statx_timestamp ctime; + struct riscv_statx_timestamp mtime; + target_endian rdev_major; + target_endian rdev_minor; + target_endian dev_major; + target_endian dev_minor; +#ifdef HAVE_STATX_MNT_ID + target_endian mnt_id; + target_endian __spare2; + target_endian __spare3[12]; +#else + target_endian __spare2[14]; +#endif + + riscv_statx(const struct statx& s, htif_t* htif) + : mask(htif->to_target(s.stx_mask)), + blksize(htif->to_target(s.stx_blksize)), + attributes(htif->to_target(s.stx_attributes)), + nlink(htif->to_target(s.stx_nlink)), + uid(htif->to_target(s.stx_uid)), + gid(htif->to_target(s.stx_gid)), + mode(htif->to_target(s.stx_mode)), __spare0(), + ino(htif->to_target(s.stx_ino)), + size(htif->to_target(s.stx_size)), + blocks(htif->to_target(s.stx_blocks)), + attributes_mask(htif->to_target(s.stx_attributes_mask)), + atime { + htif->to_target(s.stx_atime.tv_sec), + htif->to_target(s.stx_atime.tv_nsec) + }, + btime { + htif->to_target(s.stx_btime.tv_sec), + htif->to_target(s.stx_btime.tv_nsec) + }, + ctime { + htif->to_target(s.stx_ctime.tv_sec), + htif->to_target(s.stx_ctime.tv_nsec) + }, + mtime { + htif->to_target(s.stx_mtime.tv_sec), + htif->to_target(s.stx_mtime.tv_nsec) + }, + rdev_major(htif->to_target(s.stx_rdev_major)), + rdev_minor(htif->to_target(s.stx_rdev_minor)), + dev_major(htif->to_target(s.stx_dev_major)), + dev_minor(htif->to_target(s.stx_dev_minor)), +#ifdef HAVE_STATX_MNT_ID + mnt_id(htif->to_target(s.stx_mnt_id)), + __spare2(), __spare3() +#else + __spare2() +#endif + {} +}; + syscall_t::syscall_t(htif_t* htif) : htif(htif), memif(&htif->memif()), table(2048) { @@ -79,6 +157,7 @@ syscall_t::syscall_t(htif_t* htif) table[79] = &syscall_t::sys_fstatat; table[80] = &syscall_t::sys_fstat; table[93] = &syscall_t::sys_exit; + table[291] = &syscall_t::sys_statx; table[1039] = &syscall_t::sys_lstat; table[2011] = &syscall_t::sys_getmainvars; @@ -222,6 +301,21 @@ reg_t syscall_t::sys_lstat(reg_t pname, reg_t len, reg_t pbuf, reg_t a3, reg_t a return ret; } +reg_t syscall_t::sys_statx(reg_t fd, reg_t pname, reg_t len, reg_t flags, reg_t mask, reg_t pbuf, reg_t a6) +{ + std::vector name(len); + memif->read(pname, len, &name[0]); + + struct statx buf; + reg_t ret = sysret_errno(statx(fds.lookup(fd), do_chroot(&name[0]).c_str(), flags, mask, &buf)); + if (ret != (reg_t)-1) + { + riscv_statx rbuf(buf, htif); + memif->write(pbuf, sizeof(rbuf), &rbuf); + } + return ret; +} + #define AT_SYSCALL(syscall, fd, name, ...) \ (syscall(fds.lookup(fd), int(fd) == RISCV_AT_FDCWD ? do_chroot(name).c_str() : (name), __VA_ARGS__)) diff --git a/fesvr/syscall.h b/fesvr/syscall.h index 8294696..4915efd 100644 --- a/fesvr/syscall.h +++ b/fesvr/syscall.h @@ -56,6 +56,7 @@ class syscall_t : public device_t reg_t sys_lseek(reg_t, reg_t, reg_t, reg_t, reg_t, reg_t, reg_t); reg_t sys_fstat(reg_t, reg_t, reg_t, reg_t, reg_t, reg_t, reg_t); reg_t sys_lstat(reg_t, reg_t, reg_t, reg_t, reg_t, reg_t, reg_t); + reg_t sys_statx(reg_t, reg_t, reg_t, reg_t, reg_t, reg_t, reg_t); reg_t sys_fstatat(reg_t, reg_t, reg_t, reg_t, reg_t, reg_t, reg_t); reg_t sys_faccessat(reg_t, reg_t, reg_t, reg_t, reg_t, reg_t, reg_t); reg_t sys_fcntl(reg_t, reg_t, reg_t, reg_t, reg_t, reg_t, reg_t); -- cgit v1.1