diff --git a/linux-user/aarch64/syscall_nr.h b/linux-user/aarch64/syscall_nr.h index a3c9a3b..b4cb46a 100644 --- a/linux-user/aarch64/syscall_nr.h +++ b/linux-user/aarch64/syscall_nr.h @@ -273,4 +273,5 @@ #define TARGET_NR_membarrier 283 #define TARGET_NR_mlock2 284 #define TARGET_NR_copy_file_range 285 +#define TARGET_NR_statx 291 diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 643b883..6122951 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -313,6 +313,16 @@ _syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, idx1, unsigned long, idx2) #endif +#if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root) +_syscall2(int, pivot_root, const char *, new_root, + const char *, put_old); +#endif + +#if defined(TARGET_NR_statx) && defined(__NR_statx) +_syscall5(int, statx, int, dirfd, const char *, pathname, + int, flags, unsigned int, mask, struct statx *, statxbuf); +#endif + static bitmask_transtbl fcntl_flags_tbl[] = { { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, }, { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, }, @@ -9865,6 +9875,45 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } } break; +#ifdef TARGET_NR_statx + case TARGET_NR_statx: + { + struct statx stx, *target_stx; + if (!(p = lock_user_string(arg2))) + goto efault; + ret = get_errno(statx(arg1, path(p), arg3, arg4, &stx)); + if (!is_error(ret)) { + if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) + goto efault; + memset(target_stx, 0, sizeof(*target_stx)); + __put_user(stx.stx_mask, &target_stx->stx_mask); + __put_user(stx.stx_blksize, &target_stx->stx_blksize); + __put_user(stx.stx_attributes, &target_stx->stx_attributes); + __put_user(stx.stx_nlink, &target_stx->stx_nlink); + __put_user(stx.stx_uid, &target_stx->stx_uid); + __put_user(stx.stx_gid, &target_stx->stx_gid); + __put_user(stx.stx_mode, &target_stx->stx_mode); + __put_user(stx.stx_ino, &target_stx->stx_ino); + __put_user(stx.stx_size, &target_stx->stx_size); + __put_user(stx.stx_blocks, &target_stx->stx_blocks); + __put_user(stx.stx_attributes_mask, &target_stx->stx_attributes_mask); + __put_user(stx.stx_atime.tv_sec, &target_stx->stx_atime.tv_sec); + __put_user(stx.stx_atime.tv_nsec, &target_stx->stx_atime.tv_nsec); + __put_user(stx.stx_btime.tv_sec, &target_stx->stx_btime.tv_sec); + __put_user(stx.stx_btime.tv_nsec, &target_stx->stx_btime.tv_nsec); + __put_user(stx.stx_mtime.tv_sec, &target_stx->stx_mtime.tv_sec); + __put_user(stx.stx_mtime.tv_nsec, &target_stx->stx_mtime.tv_nsec); + __put_user(stx.stx_ctime.tv_sec, &target_stx->stx_ctime.tv_sec); + __put_user(stx.stx_ctime.tv_nsec, &target_stx->stx_ctime.tv_nsec); + __put_user(stx.stx_rdev_major, &target_stx->stx_rdev_major); + __put_user(stx.stx_rdev_minor, &target_stx->stx_rdev_minor); + __put_user(stx.stx_dev_major, &target_stx->stx_dev_major); + __put_user(stx.stx_dev_minor, &target_stx->stx_dev_minor); + unlock_user_struct(target_stx, arg5, 1); + } + } + break; +#endif #ifdef TARGET_NR_olduname case TARGET_NR_olduname: goto unimplemented; @@ -11493,9 +11542,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(setfsgid(arg1)); break; #endif - +#ifdef TARGET_NR_pivot_root case TARGET_NR_pivot_root: - goto unimplemented; + { + void *p, *n; + p = lock_user_string(arg1); + n = lock_user_string(arg2); + ret = get_errno(pivot_root(p, n)); + unlock_user(p, arg1, 0); + unlock_user(n, arg2, 0); + } + break; +#endif #ifdef TARGET_NR_mincore case TARGET_NR_mincore: { diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 23f5bcc..d4e4dba 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1411,6 +1411,35 @@ struct target_winsize { #define TARGET_MAP_UNINITIALIZED 0x4000000 /* for anonymous mmap, memory could be uninitialized */ #endif +struct statx_timestamp { + int64_t tv_sec; + uint32_t tv_nsec; + int32_t __reserved; +}; + +struct statx { + uint32_t stx_mask; + uint32_t stx_blksize; + uint64_t stx_attributes; + uint32_t stx_nlink; + uint32_t stx_uid; + uint32_t stx_gid; + uint16_t stx_mode; + uint16_t __spare0[1]; + uint64_t stx_ino; + uint64_t stx_size; + uint64_t stx_blocks; + uint64_t stx_attributes_mask; + struct statx_timestamp stx_atime; + struct statx_timestamp stx_btime; + struct statx_timestamp stx_ctime; + struct statx_timestamp stx_mtime; + uint32_t stx_rdev_major; + uint32_t stx_rdev_minor; + uint32_t stx_dev_major; + uint32_t stx_dev_minor; + uint64_t __spare2[14]; +}; #if (defined(TARGET_I386) && defined(TARGET_ABI32)) \ || (defined(TARGET_ARM) && defined(TARGET_ABI32)) \ || defined(TARGET_CRIS)