[PATCH V5 19/21] riscv: compat: ptrace: Add compat_arch_ptrace implement

Palmer Dabbelt palmer at dabbelt.com
Tue Feb 22 17:42:56 PST 2022


On Tue, 01 Feb 2022 07:05:43 PST (-0800), guoren at kernel.org wrote:
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Now, you can use native gdb on riscv64 for rv32 app debugging.
>
> $ uname -a
> Linux buildroot 5.16.0-rc4-00036-gbef6b82fdf23-dirty #53 SMP Mon Dec 20 23:06:53 CST 2021 riscv64 GNU/Linux
> $ cat /proc/cpuinfo
> processor       : 0
> hart            : 0
> isa             : rv64imafdcsuh
> mmu             : sv48
>
> $ file /bin/busybox
> /bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
> $ file /usr/bin/gdb
> /usr/bin/gdb: ELF 32-bit LSB shared object, UCB RISC-V, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
> $ /usr/bin/gdb /bin/busybox
> GNU gdb (GDB) 10.2
> Copyright (C) 2021 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> ...
> Reading symbols from /bin/busybox...
> (No debugging symbols found in /bin/busybox)
> (gdb) b main
> Breakpoint 1 at 0x8ddc
> (gdb) r
> Starting program: /bin/busybox
> Failed to read a valid object file image from memory.
>
> Breakpoint 1, 0x555a8ddc in main ()
> (gdb) i r
> ra             0x77df0b74       0x77df0b74
> sp             0x7fdd3d10       0x7fdd3d10
> gp             0x5567e800       0x5567e800 <bb_common_bufsiz1+160>
> tp             0x77f64280       0x77f64280
> t0             0x0      0
> t1             0x555a6fac       1431990188
> t2             0x77dd8db4       2011008436
> fp             0x7fdd3e34       0x7fdd3e34
> s1             0x7fdd3e34       2145205812
> a0             0xffffffff       -1
> a1             0x2000   8192
> a2             0x7fdd3e3c       2145205820
> a3             0x0      0
> a4             0x7fdd3d30       2145205552
> a5             0x555a8dc0       1431997888
> a6             0x77f2c170       2012397936
> a7             0x6a7c7a2f       1786542639
> s2             0x0      0
> s3             0x0      0
> s4             0x555a8dc0       1431997888
> s5             0x77f8a3a8       2012783528
> s6             0x7fdd3e3c       2145205820
> s7             0x5567cecc       1432866508
> --Type <RET> for more, q to quit, c to continue without paging--
> s8             0x1      1
> s9             0x0      0
> s10            0x55634448       1432568904
> s11            0x0      0
> t3             0x77df0bb8       2011106232
> t4             0x42fc   17148
> t5             0x0      0
> t6             0x40     64
> pc             0x555a8ddc       0x555a8ddc <main+28>
> (gdb) si
> 0x555a78f0 in mallopt at plt ()
> (gdb) c
> Continuing.
> BusyBox v1.34.1 (2021-12-19 22:39:48 CST) multi-call binary.
> BusyBox is copyrighted by many authors between 1998-2015.
> Licensed under GPLv2. See source distribution for detailed
> copyright notices.
>
> Usage: busybox [function [arguments]...]
>    or: busybox --list[-full]
> ...
> [Inferior 1 (process 107) exited normally]
> (gdb) q
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Palmer Dabbelt <palmer at dabbelt.com>
> ---
>  arch/riscv/kernel/ptrace.c | 87 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 82 insertions(+), 5 deletions(-)
>
> diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
> index a89243730153..bb387593a121 100644
> --- a/arch/riscv/kernel/ptrace.c
> +++ b/arch/riscv/kernel/ptrace.c
> @@ -12,6 +12,7 @@
>  #include <asm/thread_info.h>
>  #include <asm/switch_to.h>
>  #include <linux/audit.h>
> +#include <linux/compat.h>
>  #include <linux/ptrace.h>
>  #include <linux/elf.h>
>  #include <linux/regset.h>
> @@ -111,11 +112,6 @@ static const struct user_regset_view riscv_user_native_view = {
>  	.n = ARRAY_SIZE(riscv_user_regset),
>  };
>
> -const struct user_regset_view *task_user_regset_view(struct task_struct *task)
> -{
> -	return &riscv_user_native_view;
> -}
> -
>  struct pt_regs_offset {
>  	const char *name;
>  	int offset;
> @@ -273,3 +269,84 @@ __visible void do_syscall_trace_exit(struct pt_regs *regs)
>  		trace_sys_exit(regs, regs_return_value(regs));
>  #endif
>  }
> +
> +#ifdef CONFIG_COMPAT
> +static int compat_riscv_gpr_get(struct task_struct *target,
> +				const struct user_regset *regset,
> +				struct membuf to)
> +{
> +	struct compat_user_regs_struct cregs;
> +
> +	regs_to_cregs(&cregs, task_pt_regs(target));
> +
> +	return membuf_write(&to, &cregs,
> +			    sizeof(struct compat_user_regs_struct));
> +}
> +
> +static int compat_riscv_gpr_set(struct task_struct *target,
> +				const struct user_regset *regset,
> +				unsigned int pos, unsigned int count,
> +				const void *kbuf, const void __user *ubuf)
> +{
> +	int ret;
> +	struct compat_user_regs_struct cregs;
> +
> +	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &cregs, 0, -1);
> +
> +	cregs_to_regs(&cregs, task_pt_regs(target));
> +
> +	return ret;
> +}
> +
> +static const struct user_regset compat_riscv_user_regset[] = {
> +	[REGSET_X] = {
> +		.core_note_type = NT_PRSTATUS,
> +		.n = ELF_NGREG,
> +		.size = sizeof(compat_elf_greg_t),
> +		.align = sizeof(compat_elf_greg_t),
> +		.regset_get = compat_riscv_gpr_get,
> +		.set = compat_riscv_gpr_set,
> +	},
> +#ifdef CONFIG_FPU
> +	[REGSET_F] = {
> +		.core_note_type = NT_PRFPREG,
> +		.n = ELF_NFPREG,
> +		.size = sizeof(elf_fpreg_t),
> +		.align = sizeof(elf_fpreg_t),
> +		.regset_get = riscv_fpr_get,
> +		.set = riscv_fpr_set,
> +	},
> +#endif
> +};
> +
> +static const struct user_regset_view compat_riscv_user_native_view = {
> +	.name = "riscv",
> +	.e_machine = EM_RISCV,
> +	.regsets = compat_riscv_user_regset,
> +	.n = ARRAY_SIZE(compat_riscv_user_regset),
> +};
> +
> +long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
> +			compat_ulong_t caddr, compat_ulong_t cdata)
> +{
> +	long ret = -EIO;
> +
> +	switch (request) {
> +	default:
> +		ret = compat_ptrace_request(child, request, caddr, cdata);
> +		break;
> +	}
> +
> +	return ret;
> +}
> +#endif /* CONFIG_COMPAT */
> +
> +const struct user_regset_view *task_user_regset_view(struct task_struct *task)
> +{
> +#ifdef CONFIG_COMPAT
> +	if (test_tsk_thread_flag(task, TIF_32BIT))
> +		return &compat_riscv_user_native_view;
> +	else
> +#endif
> +		return &riscv_user_native_view;
> +}

Reviewed-by: Palmer Dabbelt <palmer at rivosinc.com>



More information about the linux-riscv mailing list