Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/aarch64 Add support of ptrace(2) for COMPAT_NETBSD32.



details:   https://anonhg.NetBSD.org/src/rev/54e19cae91a8
branches:  trunk
changeset: 935418:54e19cae91a8
user:      rin <rin%NetBSD.org@localhost>
date:      Thu Jul 02 13:04:46 2020 +0000

description:
Add support of ptrace(2) for COMPAT_NETBSD32.

Now, GDB for arm32 is usable for debugging 32bit applications.

OK ryo@

diffstat:

 sys/arch/aarch64/aarch64/netbsd32_machdep.c |  96 +++++++++++++++++++++++++++-
 sys/arch/aarch64/aarch64/trap.c             |  21 +++++-
 sys/arch/aarch64/include/netbsd32_machdep.h |  27 +++++++-
 sys/arch/aarch64/include/ptrace.h           |  21 ++++++-
 4 files changed, 155 insertions(+), 10 deletions(-)

diffs (286 lines):

diff -r 30b6e89fba4a -r 54e19cae91a8 sys/arch/aarch64/aarch64/netbsd32_machdep.c
--- a/sys/arch/aarch64/aarch64/netbsd32_machdep.c       Thu Jul 02 13:04:09 2020 +0000
+++ b/sys/arch/aarch64/aarch64/netbsd32_machdep.c       Thu Jul 02 13:04:46 2020 +0000
@@ -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 <ryo%nerv.org@localhost>
@@ -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 @@
 #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 @@
                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 @@
        (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 @@
        return 0;
 }
 
-static int
+int
 netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *fpregs,
     size_t *lenp)
 {
@@ -164,6 +189,69 @@
 }
 
 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)
 {
diff -r 30b6e89fba4a -r 54e19cae91a8 sys/arch/aarch64/aarch64/trap.c
--- a/sys/arch/aarch64/aarch64/trap.c   Thu Jul 02 13:04:09 2020 +0000
+++ b/sys/arch/aarch64/aarch64/trap.c   Thu Jul 02 13:04:46 2020 +0000
@@ -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 @@
 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 @@
        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.
                 */
diff -r 30b6e89fba4a -r 54e19cae91a8 sys/arch/aarch64/include/netbsd32_machdep.h
--- a/sys/arch/aarch64/include/netbsd32_machdep.h       Thu Jul 02 13:04:09 2020 +0000
+++ b/sys/arch/aarch64/include/netbsd32_machdep.h       Thu Jul 02 13:04:46 2020 +0000
@@ -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 @@
 #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_ */
diff -r 30b6e89fba4a -r 54e19cae91a8 sys/arch/aarch64/include/ptrace.h
--- a/sys/arch/aarch64/include/ptrace.h Thu Jul 02 13:04:09 2020 +0000
+++ b/sys/arch/aarch64/include/ptrace.h Thu Jul 02 13:04:46 2020 +0000
@@ -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>



Home | Main Index | Thread Index | Old Index