[PATCH v6 2/6] syscall.h: add syscall_set_arguments()
Maciej W. Rozycki
macro at orcam.me.uk
Wed Feb 19 17:15:48 UTC 2025
On Mon, 17 Feb 2025, Dmitry V. Levin wrote:
> This function is going to be needed on all HAVE_ARCH_TRACEHOOK
> architectures to implement PTRACE_SET_SYSCALL_INFO API.
>
> This partially reverts commit 7962c2eddbfe ("arch: remove unused
> function syscall_set_arguments()") by reusing some of old
> syscall_set_arguments() implementations.
>
> Signed-off-by: Dmitry V. Levin <ldv at strace.io>
> Tested-by: Charlie Jenkins <charlie at rivosinc.com>
> Reviewed-by: Charlie Jenkins <charlie at rivosinc.com>
> Acked-by: Helge Deller <deller at gmx.de> # parisc
> ---
> arch/arc/include/asm/syscall.h | 14 +++++++++++
> arch/arm/include/asm/syscall.h | 13 ++++++++++
> arch/arm64/include/asm/syscall.h | 13 ++++++++++
> arch/csky/include/asm/syscall.h | 13 ++++++++++
> arch/hexagon/include/asm/syscall.h | 7 ++++++
> arch/loongarch/include/asm/syscall.h | 8 ++++++
> arch/mips/include/asm/syscall.h | 32 ++++++++++++++++++++++++
> arch/nios2/include/asm/syscall.h | 11 ++++++++
> arch/openrisc/include/asm/syscall.h | 7 ++++++
> arch/parisc/include/asm/syscall.h | 12 +++++++++
> arch/powerpc/include/asm/syscall.h | 10 ++++++++
> arch/riscv/include/asm/syscall.h | 9 +++++++
> arch/s390/include/asm/syscall.h | 9 +++++++
> arch/sh/include/asm/syscall_32.h | 12 +++++++++
> arch/sparc/include/asm/syscall.h | 10 ++++++++
> arch/um/include/asm/syscall-generic.h | 14 +++++++++++
> arch/x86/include/asm/syscall.h | 36 +++++++++++++++++++++++++++
> arch/xtensa/include/asm/syscall.h | 11 ++++++++
> include/asm-generic/syscall.h | 16 ++++++++++++
> 19 files changed, 257 insertions(+)
>
> diff --git a/arch/arc/include/asm/syscall.h b/arch/arc/include/asm/syscall.h
> index 9709256e31c8..89c1e1736356 100644
> --- a/arch/arc/include/asm/syscall.h
> +++ b/arch/arc/include/asm/syscall.h
> @@ -67,6 +67,20 @@ syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
> }
> }
>
> +static inline void
> +syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
> + unsigned long *args)
> +{
> + unsigned long *inside_ptregs = ®s->r0;
> + unsigned int n = 6;
> + unsigned int i = 0;
> +
> + while (n--) {
> + *inside_ptregs = args[i++];
> + inside_ptregs--;
> + }
> +}
> +
> static inline int
> syscall_get_arch(struct task_struct *task)
> {
> diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h
> index fe4326d938c1..21927fa0ae2b 100644
> --- a/arch/arm/include/asm/syscall.h
> +++ b/arch/arm/include/asm/syscall.h
> @@ -80,6 +80,19 @@ static inline void syscall_get_arguments(struct task_struct *task,
> memcpy(args, ®s->ARM_r0 + 1, 5 * sizeof(args[0]));
> }
>
> +static inline void syscall_set_arguments(struct task_struct *task,
> + struct pt_regs *regs,
> + const unsigned long *args)
> +{
> + memcpy(®s->ARM_r0, args, 6 * sizeof(args[0]));
> + /*
> + * Also copy the first argument into ARM_ORIG_r0
> + * so that syscall_get_arguments() would return it
> + * instead of the previous value.
> + */
> + regs->ARM_ORIG_r0 = regs->ARM_r0;
> +}
> +
> static inline int syscall_get_arch(struct task_struct *task)
> {
> /* ARM tasks don't change audit architectures on the fly. */
> diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
> index ab8e14b96f68..76020b66286b 100644
> --- a/arch/arm64/include/asm/syscall.h
> +++ b/arch/arm64/include/asm/syscall.h
> @@ -73,6 +73,19 @@ static inline void syscall_get_arguments(struct task_struct *task,
> memcpy(args, ®s->regs[1], 5 * sizeof(args[0]));
> }
>
> +static inline void syscall_set_arguments(struct task_struct *task,
> + struct pt_regs *regs,
> + const unsigned long *args)
> +{
> + memcpy(®s->regs[0], args, 6 * sizeof(args[0]));
> + /*
> + * Also copy the first argument into orig_x0
> + * so that syscall_get_arguments() would return it
> + * instead of the previous value.
> + */
> + regs->orig_x0 = regs->regs[0];
> +}
> +
> /*
> * We don't care about endianness (__AUDIT_ARCH_LE bit) here because
> * AArch64 has the same system calls both on little- and big- endian.
> diff --git a/arch/csky/include/asm/syscall.h b/arch/csky/include/asm/syscall.h
> index 0de5734950bf..30403f7a0487 100644
> --- a/arch/csky/include/asm/syscall.h
> +++ b/arch/csky/include/asm/syscall.h
> @@ -59,6 +59,19 @@ syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
> memcpy(args, ®s->a1, 5 * sizeof(args[0]));
> }
>
> +static inline void
> +syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
> + const unsigned long *args)
> +{
> + memcpy(®s->a0, args, 6 * sizeof(regs->a0));
> + /*
> + * Also copy the first argument into orig_x0
^
Typo here, s/orig_x0/orig_a0/; see below.
> + * so that syscall_get_arguments() would return it
> + * instead of the previous value.
> + */
> + regs->orig_a0 = regs->a0;
Also:
> diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
> index 056aa1b713e2..ea050b23d428 100644
> --- a/arch/mips/include/asm/syscall.h
> +++ b/arch/mips/include/asm/syscall.h
> @@ -120,6 +137,21 @@ static inline void syscall_get_arguments(struct task_struct *task,
> mips_get_syscall_arg(args++, task, regs, i++);
> }
>
> +static inline void syscall_set_arguments(struct task_struct *task,
> + struct pt_regs *regs,
> + unsigned long *args)
> +{
> + unsigned int i = 0;
> + unsigned int n = 6;
> +
> + /* O32 ABI syscall() */
> + if (mips_syscall_is_indirect(task, regs))
> + i++;
-- given MIPS syscall_set_nr() implementation in 3/6 this conditional is
supposed to never be true. Should it be BUG_ON() or discarded entirely?
> +
> + while (n--)
> + mips_set_syscall_arg(args++, task, regs, i++);
> +}
> +
> extern const unsigned long sys_call_table[];
> extern const unsigned long sys32_call_table[];
> extern const unsigned long sysn32_call_table[];
Maciej
More information about the Strace-devel
mailing list