diff options
-rwxr-xr-x | configure | 66 | ||||
-rw-r--r-- | fesvr/fesvr.ac | 5 | ||||
-rw-r--r-- | fesvr/syscall.cc | 94 | ||||
-rw-r--r-- | fesvr/syscall.h | 1 |
4 files changed, 166 insertions, 0 deletions
@@ -1748,6 +1748,63 @@ fi as_fn_set_status $ac_retval } # ac_fn_cxx_try_link + +# ac_fn_cxx_check_member LINENO AGGR MEMBER VAR INCLUDES +# ------------------------------------------------------ +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_cxx_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_member cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. @@ -4699,6 +4756,15 @@ else fi +ac_fn_cxx_check_member "$LINENO" "struct statx" "stx_mnt_id" "ac_cv_member_struct_statx_stx_mnt_id" "$ac_includes_default" +if test "x$ac_cv_member_struct_statx_stx_mnt_id" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STATX_MNT_ID 1 +_ACEOF + +fi + 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<int64_t> tv_sec; + target_endian<uint32_t> tv_nsec; + target_endian<int32_t> __reserved; +}; + +struct riscv_statx +{ + target_endian<uint32_t> mask; + target_endian<uint32_t> blksize; + target_endian<uint64_t> attributes; + target_endian<uint32_t> nlink; + target_endian<uint32_t> uid; + target_endian<uint32_t> gid; + target_endian<uint16_t> mode; + target_endian<uint16_t> __spare0[1]; + target_endian<uint64_t> ino; + target_endian<uint64_t> size; + target_endian<uint64_t> blocks; + target_endian<uint64_t> attributes_mask; + struct riscv_statx_timestamp atime; + struct riscv_statx_timestamp btime; + struct riscv_statx_timestamp ctime; + struct riscv_statx_timestamp mtime; + target_endian<uint32_t> rdev_major; + target_endian<uint32_t> rdev_minor; + target_endian<uint32_t> dev_major; + target_endian<uint32_t> dev_minor; +#ifdef HAVE_STATX_MNT_ID + target_endian<uint64_t> mnt_id; + target_endian<uint64_t> __spare2; + target_endian<uint64_t> __spare3[12]; +#else + target_endian<uint64_t> __spare2[14]; +#endif + + riscv_statx(const struct statx& s, htif_t* htif) + : mask(htif->to_target<uint32_t>(s.stx_mask)), + blksize(htif->to_target<uint32_t>(s.stx_blksize)), + attributes(htif->to_target<uint64_t>(s.stx_attributes)), + nlink(htif->to_target<uint32_t>(s.stx_nlink)), + uid(htif->to_target<uint32_t>(s.stx_uid)), + gid(htif->to_target<uint32_t>(s.stx_gid)), + mode(htif->to_target<uint16_t>(s.stx_mode)), __spare0(), + ino(htif->to_target<uint64_t>(s.stx_ino)), + size(htif->to_target<uint64_t>(s.stx_size)), + blocks(htif->to_target<uint64_t>(s.stx_blocks)), + attributes_mask(htif->to_target<uint64_t>(s.stx_attributes_mask)), + atime { + htif->to_target<int64_t>(s.stx_atime.tv_sec), + htif->to_target<uint32_t>(s.stx_atime.tv_nsec) + }, + btime { + htif->to_target<int64_t>(s.stx_btime.tv_sec), + htif->to_target<uint32_t>(s.stx_btime.tv_nsec) + }, + ctime { + htif->to_target<int64_t>(s.stx_ctime.tv_sec), + htif->to_target<uint32_t>(s.stx_ctime.tv_nsec) + }, + mtime { + htif->to_target<int64_t>(s.stx_mtime.tv_sec), + htif->to_target<uint32_t>(s.stx_mtime.tv_nsec) + }, + rdev_major(htif->to_target<uint32_t>(s.stx_rdev_major)), + rdev_minor(htif->to_target<uint32_t>(s.stx_rdev_minor)), + dev_major(htif->to_target<uint32_t>(s.stx_dev_major)), + dev_minor(htif->to_target<uint32_t>(s.stx_dev_minor)), +#ifdef HAVE_STATX_MNT_ID + mnt_id(htif->to_target<uint64_t>(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<char> 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); |