Browse Source

Add `statx` syscall

pull/681/head
huaixv 5 years ago
parent
commit
c0cd8a68dc
  1. 66
      configure
  2. 5
      fesvr/fesvr.ac
  3. 94
      fesvr/syscall.cc
  4. 1
      fesvr/syscall.h

66
configure

@ -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

5
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.]),
,
)

94
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__))

1
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);

Loading…
Cancel
Save