From c1df5afc01165a16dd79125669a69e8fb965def2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=A9=A720201110?= Date: Wed, 13 Nov 2024 19:47:37 +0800 Subject: [PATCH] linux-user: Add pidfd_open(), pidfd_send_signal() and pidfd_getfd() syscalls I noticed those were missing when running the glib2.0 testsuite. Add the syscalls including the strace output. Signed-off-by: Helge Deller Reviewed-by: Laurent Vivier Message-Id: <20220918194555.83535-4-deller@gmx.de> Signed-off-by: Laurent Vivier Signed-off-by: Liu Jing --- linux-user/strace.c | 28 ++++++++++++++++++++++++++++ linux-user/strace.list | 9 +++++++++ linux-user/syscall.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/linux-user/strace.c b/linux-user/strace.c index 37d66d0dff..00dd0511c6 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -3274,6 +3274,34 @@ print_openat(void *cpu_env, const struct syscallname *name, } #endif +#ifdef TARGET_NR_pidfd_send_signal +static void +print_pidfd_send_signal(CPUArchState *cpu_env, const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + void *p; + target_siginfo_t uinfo; + + print_syscall_prologue(name); + print_raw_param("%d", arg0, 0); + print_signal(arg1, 0); + + p = lock_user(VERIFY_READ, arg2, sizeof(target_siginfo_t), 1); + if (p) { + get_target_siginfo(&uinfo, p); + print_siginfo(&uinfo); + + unlock_user(p, arg2, 0); + } else { + print_pointer(arg2, 1); + } + + print_raw_param("%u", arg3, 0); + print_syscall_epilogue(name); +} +#endif + #ifdef TARGET_NR_mq_unlink static void print_mq_unlink(void *cpu_env, const struct syscallname *name, diff --git a/linux-user/strace.list b/linux-user/strace.list index 544869f1ab..b96a1447c3 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1662,6 +1662,15 @@ #ifdef TARGET_NR_pipe2 { TARGET_NR_pipe2, "pipe2", NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_pidfd_open +{ TARGET_NR_pidfd_open, "pidfd_open", "%s(%d,%u)", NULL, NULL }, +#endif +#ifdef TARGET_NR_pidfd_send_signal +{ TARGET_NR_pidfd_send_signal, "pidfd_send_signal", NULL, print_pidfd_send_signal, NULL }, +#endif +#ifdef TARGET_NR_pidfd_getfd +{ TARGET_NR_pidfd_getfd, "pidfd_getfd", "%s(%d,%d,%u)", NULL, NULL }, +#endif #ifdef TARGET_NR_atomic_cmpxchg_32 { TARGET_NR_atomic_cmpxchg_32, "atomic_cmpxchg_32", NULL, NULL, NULL }, #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c4951d449f..5f1bdfe857 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -333,6 +333,16 @@ _syscall6(int,sys_futex,int *,uaddr,int,op,int,val, _syscall6(int,sys_futex_time64,int *,uaddr,int,op,int,val, const struct timespec *,timeout,int *,uaddr2,int,val3) #endif +#if defined(__NR_pidfd_open) && defined(TARGET_NR_pidfd_open) +_syscall2(int, pidfd_open, pid_t, pid, unsigned int, flags); +#endif +#if defined(__NR_pidfd_send_signal) && defined(TARGET_NR_pidfd_send_signal) +_syscall4(int, pidfd_send_signal, int, pidfd, int, sig, siginfo_t *, info, + unsigned int, flags); +#endif +#if defined(__NR_pidfd_getfd) && defined(TARGET_NR_pidfd_getfd) +_syscall3(int, pidfd_getfd, int, pidfd, int, targetfd, unsigned int, flags); +#endif #define __NR_sys_sched_getaffinity __NR_sched_getaffinity _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len, unsigned long *, user_mask_ptr); @@ -8435,6 +8445,30 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, ret = do_open_by_handle_at(arg1, arg2, arg3); fd_trans_unregister(ret); return ret; +#endif +#if defined(__NR_pidfd_open) && defined(TARGET_NR_pidfd_open) + case TARGET_NR_pidfd_open: + return get_errno(pidfd_open(arg1, arg2)); +#endif +#if defined(__NR_pidfd_send_signal) && defined(TARGET_NR_pidfd_send_signal) + case TARGET_NR_pidfd_send_signal: + { + siginfo_t uinfo; + + p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1); + if (!p) { + return -TARGET_EFAULT; + } + target_to_host_siginfo(&uinfo, p); + unlock_user(p, arg3, 0); + ret = get_errno(pidfd_send_signal(arg1, target_to_host_signal(arg2), + &uinfo, arg4)); + } + return ret; +#endif +#if defined(__NR_pidfd_getfd) && defined(TARGET_NR_pidfd_getfd) + case TARGET_NR_pidfd_getfd: + return get_errno(pidfd_getfd(arg1, arg2, arg3)); #endif case TARGET_NR_close: fd_trans_unregister(arg1); -- 2.41.0.windows.1