Module Name: src Committed By: rin Date: Thu Jul 2 13:04:47 UTC 2020
Modified Files: src/sys/arch/aarch64/aarch64: netbsd32_machdep.c trap.c src/sys/arch/aarch64/include: netbsd32_machdep.h ptrace.h Log Message: Add support of ptrace(2) for COMPAT_NETBSD32. Now, GDB for arm32 is usable for debugging 32bit applications. OK ryo@ To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/sys/arch/aarch64/aarch64/netbsd32_machdep.c cvs rdiff -u -r1.29 -r1.30 src/sys/arch/aarch64/aarch64/trap.c cvs rdiff -u -r1.3 -r1.4 src/sys/arch/aarch64/include/netbsd32_machdep.h cvs rdiff -u -r1.9 -r1.10 src/sys/arch/aarch64/include/ptrace.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/aarch64/aarch64/netbsd32_machdep.c diff -u src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.13 src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.14 --- src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.13 Sat May 23 18:08:59 2020 +++ src/sys/arch/aarch64/aarch64/netbsd32_machdep.c Thu Jul 2 13:04:46 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.13 2020/05/23 18:08:59 ryo Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.14 2020/07/02 13:04:46 rin Exp $ */ /* * Copyright (c) 2018 Ryo Shimizu <r...@nerv.org> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.13 2020/05/23 18:08:59 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.14 2020/07/02 13:04:46 rin Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_mac #include <sys/core.h> #include <sys/exec.h> #include <sys/lwp.h> +#include <sys/ptrace.h> #include <sys/ras.h> #include <sys/signalvar.h> #include <sys/syscallargs.h> @@ -92,6 +93,30 @@ netbsd32_setregs(struct lwp *l, struct e tf->tf_spsr |= SPSR_A32_T; } +int +netbsd32_ptrace_translate_request(int req) +{ + + switch (req) { + case 0 ... PT_FIRSTMACH - 1: + return req; + case PT32_GETREGS: + return PT_GETREGS; + case PT32_SETREGS: + return PT_SETREGS; + case PT32_GETFPREGS: + return PT_GETFPREGS; + case PT32_SETFPREGS: + return PT_SETFPREGS; + /* not implemented for arm32 */ + case PT32_STEP: + case PT32_SETSTEP: + case PT32_CLEARSTEP: + default: + return -1; + } +} + /* aarch32 fpscr register is assigned to two registers fpsr/fpcr on aarch64 */ #define FPSR_BITS \ (FPSR_N32|FPSR_Z32|FPSR_C32|FPSR_V32|FPSR_QC| \ @@ -100,7 +125,7 @@ netbsd32_setregs(struct lwp *l, struct e (FPCR_AHP|FPCR_DN|FPCR_FZ|FPCR_RMODE|FPCR_STRIDE|FPCR_LEN| \ FPCR_IDE|FPCR_IXE|FPCR_UFE|FPCR_OFE|FPCR_DZE|FPCR_IOE) -static int +int netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs) { struct proc * const p = l->l_proc; @@ -124,7 +149,7 @@ netbsd32_process_read_regs(struct lwp *l return 0; } -static int +int netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *fpregs, size_t *lenp) { @@ -164,6 +189,69 @@ netbsd32_process_read_fpregs(struct lwp } int +netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs) +{ + struct proc * const p = l->l_proc; + struct trapframe *tf = l->l_md.md_utf; + int i; + + if ((p->p_flag & PK_32) == 0) + return EINVAL; + + if ((regs->r_cpsr & ~(SPSR_NZCV | SPSR_A32_T)) != 0 || + regs->r_pc >= VM_MAXUSER_ADDRESS32 || + regs->r_sp >= VM_MAXUSER_ADDRESS32) + return EINVAL; + + for (i = 0; i < 13; i++) + tf->tf_reg[i] = regs->r[i]; /* r0-r12 */ + tf->tf_reg[13] = regs->r_sp; /* r13 = sp */ + tf->tf_reg[14] = regs->r_lr; /* r14 = lr */ + tf->tf_pc = regs->r_pc; /* r15 = pc */ + tf->tf_spsr &= ~(SPSR_NZCV | SPSR_A32_T); + tf->tf_spsr |= regs->r_cpsr; + + /* THUMB CODE? */ + if (regs->r_pc & 1) + tf->tf_spsr |= SPSR_A32_T; + + return 0; +} + +int +netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *fpregs, + size_t len) +{ + struct proc * const p = l->l_proc; + struct pcb * const pcb = lwp_getpcb(l); + int i; + + if ((p->p_flag & PK_32) == 0) + return EINVAL; + + KASSERT(len <= sizeof(*fpregs)); + fpu_discard(l, true); // set used flag + + pcb->pcb_fpregs.fpsr = fpregs->fpr_vfp.vfp_fpscr & FPSR_BITS; + pcb->pcb_fpregs.fpcr = fpregs->fpr_vfp.vfp_fpscr & FPCR_BITS; + + CTASSERT(__arraycount(fpregs->fpr_vfp.vfp_regs) == + __arraycount(pcb->pcb_fpregs.fp_reg) + 1); + for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) { +#ifdef __AARCH64EB__ + pcb->pcb_fpregs.fp_reg[i].u64[0] = 0; + pcb->pcb_fpregs.fp_reg[i].u64[1] = +#else + pcb->pcb_fpregs.fp_reg[i].u64[1] = 0; + pcb->pcb_fpregs.fp_reg[i].u64[0] = +#endif + fpregs->fpr_vfp.vfp_regs[i]; + } + + return 0; +} + +int cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie, struct core32 *chdr) { Index: src/sys/arch/aarch64/aarch64/trap.c diff -u src/sys/arch/aarch64/aarch64/trap.c:1.29 src/sys/arch/aarch64/aarch64/trap.c:1.30 --- src/sys/arch/aarch64/aarch64/trap.c:1.29 Wed Jul 1 08:02:13 2020 +++ src/sys/arch/aarch64/aarch64/trap.c Thu Jul 2 13:04:46 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.29 2020/07/01 08:02:13 ryo Exp $ */ +/* $NetBSD: trap.c,v 1.30 2020/07/02 13:04:46 rin Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.29 2020/07/01 08:02:13 ryo Exp $"); +__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.30 2020/07/02 13:04:46 rin Exp $"); #include "opt_arm_intr_impl.h" #include "opt_compat_netbsd32.h" @@ -553,6 +553,7 @@ fetch_arm_insn(struct trapframe *tf, uin static enum emul_arm_result emul_arm_insn(struct trapframe *tf) { + struct lwp * const l = curlwp; uint32_t insn; int insn_size; @@ -562,12 +563,28 @@ emul_arm_insn(struct trapframe *tf) case 2: /* T32-16bit instruction */ + /* + * Breakpoint used by GDB. + */ + if (insn == 0xdefe) + goto trap; + /* XXX: some T32 IT instruction deprecated should be emulated */ break; case 4: /* T32-32bit instruction, or A32 instruction */ /* + * Breakpoint used by GDB. + */ + if (insn == 0xe6000011 || insn == 0xe7ffdefe) { + trap: + do_trapsignal(l, SIGTRAP, TRAP_BRKPT, + (void *)tf->tf_pc, 0); + return 0; + } + + /* * Emulate ARMv6 instructions with cache operations * register (c7), that can be used in user mode. */ Index: src/sys/arch/aarch64/include/netbsd32_machdep.h diff -u src/sys/arch/aarch64/include/netbsd32_machdep.h:1.3 src/sys/arch/aarch64/include/netbsd32_machdep.h:1.4 --- src/sys/arch/aarch64/include/netbsd32_machdep.h:1.3 Sun Nov 24 04:08:36 2019 +++ src/sys/arch/aarch64/include/netbsd32_machdep.h Thu Jul 2 13:04:47 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.h,v 1.3 2019/11/24 04:08:36 rin Exp $ */ +/* $NetBSD: netbsd32_machdep.h,v 1.4 2020/07/02 13:04:47 rin Exp $ */ #ifndef _MACHINE_NETBSD32_H_ #define _MACHINE_NETBSD32_H_ @@ -7,6 +7,18 @@ #include <compat/sys/ucontext.h> #include <compat/sys/siginfo.h> +/* + * arm ptrace constants + * Please keep in sync with sys/arch/arm/include/ptrace.h. + */ +#define PT32_STEP (PT_FIRSTMACH + 0) /* Not implemented */ +#define PT32_GETREGS (PT_FIRSTMACH + 1) +#define PT32_SETREGS (PT_FIRSTMACH + 2) +#define PT32_GETFPREGS (PT_FIRSTMACH + 5) +#define PT32_SETFPREGS (PT_FIRSTMACH + 6) +#define PT32_SETSTEP (PT_FIRSTMACH + 7) /* Not implemented */ +#define PT32_CLEARSTEP (PT_FIRSTMACH + 8) /* Not implemented */ + #define NETBSD32_POINTER_TYPE uint32_t typedef struct { NETBSD32_POINTER_TYPE i32; } netbsd32_pointer_t; @@ -103,11 +115,20 @@ struct netbsd32_cpustate { #define ARM_FPU_USED 3 struct netbsd32_arm_sync_icache_args { - netbsd32_uintptr_t addr; /* Virtual start address */ - netbsd32_size_t len; /* Region size */ + uint32_t addr; /* Virtual start address */ + uint32_t len; /* Region size */ }; /* Support varying ABI names for netbsd32 */ #define PROC_MACHINE_ARCH32(P) ((P)->p_md.md_march32) +/* Translate ptrace() PT_* request from 32-bit userland to kernel. */ +int netbsd32_ptrace_translate_request(int); + +int netbsd32_process_read_regs(struct lwp *, struct reg32 *); +int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *); + +int netbsd32_process_write_regs(struct lwp *, const struct reg32 *); +int netbsd32_process_write_fpregs(struct lwp *, const struct fpreg32 *, size_t); + #endif /* _MACHINE_NETBSD32_H_ */ Index: src/sys/arch/aarch64/include/ptrace.h diff -u src/sys/arch/aarch64/include/ptrace.h:1.9 src/sys/arch/aarch64/include/ptrace.h:1.10 --- src/sys/arch/aarch64/include/ptrace.h:1.9 Tue Jun 18 21:18:11 2019 +++ src/sys/arch/aarch64/include/ptrace.h Thu Jul 2 13:04:47 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ptrace.h,v 1.9 2019/06/18 21:18:11 kamil Exp $ */ +/* $NetBSD: ptrace.h,v 1.10 2020/07/02 13:04:47 rin Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -66,6 +66,25 @@ #define PTRACE_BREAKPOINT_ASM __asm __volatile("brk #13" ::: "memory") #define PTRACE_BREAKPOINT_SIZE 4 +#ifdef _KERNEL_OPT +#include "opt_compat_netbsd32.h" +#endif + +#ifdef COMPAT_NETBSD32 +#include <machine/netbsd32_machdep.h> + +#define process_read_regs32 netbsd32_process_read_regs +#define process_read_fpregs32 netbsd32_process_read_fpregs + +#define process_write_regs32 netbsd32_process_write_regs +#define process_write_fpregs32 netbsd32_process_write_fpregs + +#define process_reg32 struct reg32 +#define process_fpreg32 struct fpreg32 + +#define PTRACE_TRANSLATE_REQUEST32(x) netbsd32_ptrace_translate_request(x) +#endif /* COMPAT_NETBSD32 */ + #elif defined(__arm__) #include <arm/ptrace.h>