Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/aarch64 Implement TRAP_SIGDEBUG for aarch64...



details:   https://anonhg.NetBSD.org/src/rev/61194afc4e98
branches:  trunk
changeset: 991587:61194afc4e98
user:      christos <christos%NetBSD.org@localhost>
date:      Thu Jul 19 18:27:26 2018 +0000

description:
Implement TRAP_SIGDEBUG for aarch64...
ptraced programs die with:
data_abort_handler, 257: pid 199.1 (a.out): signal 11 (trap 0x82000006) @pc 0, addr 0x0, error=Instruction Abort (EL0)

diffstat:

 sys/arch/aarch64/aarch64/fault.c   |   9 ++-
 sys/arch/aarch64/aarch64/trap.c    |  93 ++++++++++++++++++++++++++++++-------
 sys/arch/aarch64/include/machdep.h |  29 ++++++-----
 3 files changed, 95 insertions(+), 36 deletions(-)

diffs (281 lines):

diff -r 1c0ebf10f48e -r 61194afc4e98 sys/arch/aarch64/aarch64/fault.c
--- a/sys/arch/aarch64/aarch64/fault.c  Thu Jul 19 18:04:25 2018 +0000
+++ b/sys/arch/aarch64/aarch64/fault.c  Thu Jul 19 18:27:26 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fault.c,v 1.3 2018/07/17 10:07:49 ryo Exp $    */
+/*     $NetBSD: fault.c,v 1.4 2018/07/19 18:27:26 christos Exp $       */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.3 2018/07/17 10:07:49 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.4 2018/07/19 18:27:26 christos Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -119,7 +119,7 @@
 }
 
 void
-data_abort_handler(struct trapframe *tf, uint32_t eclass, const char *trapname)
+data_abort_handler(struct trapframe *tf, uint32_t eclass)
 {
        struct proc *p;
        struct lwp *l;
@@ -297,7 +297,8 @@
        /*
         * fatal abort. analyze fault status code to show by panic()
         */
-       len = snprintf(panicinfo, sizeof(panicinfo), "Trap: %s:", trapname);
+       len = snprintf(panicinfo, sizeof(panicinfo), "Trap: %s:",
+           eclass_trapname(eclass));
 
        if ((fsc >= __arraycount(fault_status_code)) ||
            ((faultstr = fault_status_code[fsc]) == NULL))
diff -r 1c0ebf10f48e -r 61194afc4e98 sys/arch/aarch64/aarch64/trap.c
--- a/sys/arch/aarch64/aarch64/trap.c   Thu Jul 19 18:04:25 2018 +0000
+++ b/sys/arch/aarch64/aarch64/trap.c   Thu Jul 19 18:27:26 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.5 2018/07/17 00:35:51 christos Exp $ */
+/* $NetBSD: trap.c,v 1.6 2018/07/19 18:27:26 christos Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.5 2018/07/17 00:35:51 christos Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.6 2018/07/19 18:27:26 christos Exp $");
 
 #include "opt_arm_intr_impl.h"
 #include "opt_compat_netbsd32.h"
@@ -118,14 +118,14 @@
        [ESR_EC_VECTOR_CATCH]   = "A32: Vector Catch Exception"
 };
 
-static inline const char *
+const char *
 eclass_trapname(uint32_t eclass)
 {
        static char trapnamebuf[sizeof("Unknown trap 0x????????")];
 
        if (eclass >= __arraycount(trap_names) || trap_names[eclass] == NULL) {
                snprintf(trapnamebuf, sizeof(trapnamebuf),
-                   "Unknown trap 0x%02x", eclass);
+                   "Unknown trap %#02x", eclass);
                return trapnamebuf;
        }
        return trap_names[eclass];
@@ -175,7 +175,6 @@
 {
        const uint32_t esr = tf->tf_esr;
        const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */
-       const char *trapname;
 
        /* re-enable traps and interrupts */
        if (!(tf->tf_spsr & SPSR_I))
@@ -183,12 +182,10 @@
        else
                daif_enable(DAIF_D|DAIF_A);
 
-       trapname = eclass_trapname(eclass);
-
        switch (eclass) {
        case ESR_EC_INSN_ABT_EL1:
        case ESR_EC_DATA_ABT_EL1:
-               data_abort_handler(tf, eclass, trapname);
+               data_abort_handler(tf, eclass);
                break;
 
        case ESR_EC_BRKPNT_EL1:
@@ -218,7 +215,8 @@
        case ESR_EC_ILL_STATE:
        default:
                panic("Trap: fatal %s: pc=%016" PRIx64 "sp=%016" PRIx64
-                   "esr=%08x", trapname, tf->tf_pc, tf->tf_sp, esr);
+                   "esr=%08x", eclass_trapname(eclass), tf->tf_pc, tf->tf_sp,
+                   esr);
                break;
        }
 }
@@ -229,17 +227,14 @@
        struct lwp * const l = curlwp;
        const uint32_t esr = tf->tf_esr;
        const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */
-       const char *trapname;
 
        /* enable traps and interrupts */
        daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F);
 
-       trapname = eclass_trapname(eclass);
-
        switch (eclass) {
        case ESR_EC_INSN_ABT_EL0:
        case ESR_EC_DATA_ABT_EL0:
-               data_abort_handler(tf, eclass, trapname);
+               data_abort_handler(tf, eclass);
                userret(l);
                break;
 
@@ -304,13 +299,10 @@
        struct lwp * const l = curlwp;
        const uint32_t esr = tf->tf_esr;
        const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */
-       const char *trapname;
 
        /* enable traps and interrupts */
        daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F);
 
-       trapname = eclass_trapname(eclass);
-
        switch (eclass) {
        case ESR_EC_FP_ACCESS:
                fpu_load(l);
@@ -319,7 +311,7 @@
 
        case ESR_EC_INSN_ABT_EL0:
        case ESR_EC_DATA_ABT_EL0:
-               data_abort_handler(tf, eclass, trapname);
+               data_abort_handler(tf, eclass);
                userret(l);
                break;
 
@@ -344,14 +336,16 @@
        case ESR_EC_FP_TRAP_A32:
        case ESR_EC_BKPT_INSN_A32:
                /* XXX notyet */
-               printf("%s:%d: %s\n", __func__, __LINE__, trapname);
+               printf("%s:%d: %s\n", __func__, __LINE__,
+                   eclass_trapname(eclass));
                do_trapsignal(l, SIGILL, ILL_ILLTRP, (void *)tf->tf_pc, esr);
                userret(l);
                break;
 #endif /* COMPAT_NETBSD32 */
        default:
                /* XXX notyet */
-               printf("%s:%d: %s\n", __func__, __LINE__, trapname);
+               printf("%s:%d: %s\n", __func__, __LINE__,
+                   eclass_trapname(eclass));
                do_trapsignal(l, SIGILL, ILL_ILLTRP, (void *)tf->tf_pc, esr);
                userret(l);
                break;
@@ -451,3 +445,64 @@
        }
        return error;
 }
+
+#ifdef TRAP_SIGDEBUG
+static void
+frame_dump(const struct trapframe *tf)
+{
+       const struct reg *r = &tf->tf_regs;
+
+       printf("trapframe %p\n", tf);
+       for (size_t i = 0; i < __arraycount(r->r_reg); i++) {
+               printf(" r%.2zu %#018%s" PRIx64, i, r->r_reg[i],
+                   " \n"[i && (i & 1) == 0]);
+       }
+
+       printf("\n");
+       printf("   sp %#018" PRIx64 "    pc %#018" PRIx64 "\n",
+           r->r_sp, r->r_pc);
+       printf(" spsr %#018" PRIx64 " tpidr %#018" PRIx64 "\n",
+           r->r_spsr, r->r_tpidr);
+       printf("  esr %#018" PRIx64 "   far %#018" PRIx64 "\n",
+           tf->tf_esr, tf->tf_far);
+
+       printf("\n");
+       hexdump(printf, "Stack dump", tf, 256);
+}
+
+static void
+sigdebug(const struct trapframe *tf, const ksiginfo_t *ksi)
+{
+       struct lwp *l = curlwp;
+       struct proc *p = l->l_proc;
+       const uint32_t eclass = __SHIFTOUT(ksi->ksi_trap, ESR_EC);
+
+       printf("pid %d.%d (%s): signal %d (trap %#x) "
+           "@pc %#" PRIx64 ", addr %p, error=%s\n",
+           p->p_pid, l->l_lid, p->p_comm, ksi->ksi_signo, ksi->ksi_trap,
+           tf->tf_regs.r_pc, ksi->ksi_addr, eclass_trapname(eclass));
+       frame_dump(tf);
+}
+#endif
+
+void do_trapsignal1(
+#ifdef TRAP_SIGDEBUG
+    const char *func,
+    size_t line,
+    struct trapframe *tf,
+#endif
+    struct lwp *l, int signo, int code, void *addr, int trap)
+{
+       ksiginfo_t ksi;
+
+       KSI_INIT_TRAP(&ksi);
+       ksi.ksi_signo = signo;
+       ksi.ksi_code = code;
+       ksi.ksi_addr = addr;
+       ksi.ksi_trap = trap;
+#ifdef TRAP_SIGDEBUG
+       printf("%s, %zu: ", func, line);
+       sigdebug(tf, &ksi);
+#endif
+       (*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
+}
diff -r 1c0ebf10f48e -r 61194afc4e98 sys/arch/aarch64/include/machdep.h
--- a/sys/arch/aarch64/include/machdep.h        Thu Jul 19 18:04:25 2018 +0000
+++ b/sys/arch/aarch64/include/machdep.h        Thu Jul 19 18:27:26 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.h,v 1.2 2018/07/09 06:19:53 ryo Exp $  */
+/*     $NetBSD: machdep.h,v 1.3 2018/07/19 18:27:26 christos Exp $     */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -77,7 +77,7 @@
 struct trapframe;
 
 /* fault.c */
-void data_abort_handler(struct trapframe *, uint32_t, const char *);
+void data_abort_handler(struct trapframe *, uint32_t);
 
 /* trap.c */
 void lwp_trampoline(void);
@@ -134,18 +134,21 @@
 void load_fpregs(struct fpreg *);
 void save_fpregs(struct fpreg *);
 
-static inline void
-do_trapsignal(struct lwp *l, int signo, int code, void *addr, int trap)
-{
-       ksiginfo_t ksi;
+#ifdef TRAP_SIGDEBUG
+#define do_trapsignal(l, signo, code, addr, trap) \
+    do_trapsignal1(__func__, __LINE__, tf, l, signo, code, addr, trap)
+#else
+#define do_trapsignal(l, signo, code, addr, trap) \
+    do_trapsignal1(l, signo, code, addr, trap)
+#endif
 
-       KSI_INIT_TRAP(&ksi);
-       ksi.ksi_signo = signo;
-       ksi.ksi_code = code;
-       ksi.ksi_addr = addr;
-       ksi.ksi_trap = trap;
-       (*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
-}
+void do_trapsignal1(
+#ifdef TRAP_SIGDEBUG
+    const char *func, size_t line, struct trapframe *tf,
+#endif
+    struct lwp *l, int signo, int code, void *addr, int trap);
+
+const char *eclass_trapname(uint32_t);
 
 #include <sys/pcu.h>
 



Home | Main Index | Thread Index | Old Index