Source-Changes-HG archive

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

[src/trunk]: src/external/cddl/osnet apply the ustack() parts of freebsd r211...



details:   https://anonhg.NetBSD.org/src/rev/059f2b2cc29d
branches:  trunk
changeset: 815395:059f2b2cc29d
user:      chs <chs%NetBSD.org@localhost>
date:      Sat May 14 21:19:05 2016 +0000

description:
apply the ustack() parts of freebsd r211608:

        r211608 | rpaulo | 2010-08-22 03:53:32 -0700 (Sun, 22 Aug 2010) | 8 lines

        Kernel DTrace support for:
        o uregs  (sson@)
        o ustack (sson@)
        o /dev/dtrace/helper device (needed for USDT probes)

        The work done by me was:
        Sponsored by:   The FreeBSD Foundation

plus a few netbsd-specific tweaks from me.
fixes PR 50790.

diffstat:

 external/cddl/osnet/dev/dtrace/amd64/dtrace_isa.c   |  128 ++++++++++-----
 external/cddl/osnet/dev/dtrace/i386/dtrace_asm.S    |   10 +-
 external/cddl/osnet/dev/dtrace/i386/dtrace_isa.c    |  157 ++++++++++++-------
 external/cddl/osnet/dist/uts/common/dtrace/dtrace.c |   32 +---
 4 files changed, 190 insertions(+), 137 deletions(-)

diffs (truncated from 804 to 300 lines):

diff -r 2f06684cd42a -r 059f2b2cc29d external/cddl/osnet/dev/dtrace/amd64/dtrace_isa.c
--- a/external/cddl/osnet/dev/dtrace/amd64/dtrace_isa.c Sat May 14 17:11:30 2016 +0000
+++ b/external/cddl/osnet/dev/dtrace/amd64/dtrace_isa.c Sat May 14 21:19:05 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dtrace_isa.c,v 1.4 2012/06/11 15:18:05 chs Exp $       */
+/*     $NetBSD: dtrace_isa.c,v 1.5 2016/05/14 21:19:05 chs Exp $       */
 
 /*
  * CDDL HEADER START
@@ -32,20 +32,11 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
-//#include <sys/stack.h>
-//#include <sys/pcpu.h>
 
 #include <machine/frame.h>
-//#include <machine/md_var.h>
 #include <machine/reg.h>
-//#include <machine/stack.h>
 
-//#include <vm/vm.h>
-//#include <vm/vm_param.h>
-//#include <vm/pmap.h>
 #include <machine/vmparam.h>
-#include <machine/pmap.h>
-
 
 uint8_t dtrace_fuword8_nocheck(void *);
 uint16_t dtrace_fuword16_nocheck(void *);
@@ -113,19 +104,17 @@
        }
 }
 
-#ifdef notyet
 static int
 dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
     uintptr_t sp)
 {
        volatile uint16_t *flags =
            (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
-       struct amd64_frame *frame;
        int ret = 0;
 
        ASSERT(pcstack == NULL || pcstack_limit > 0);
 
-       while (pc != 0 && sp != 0) {
+       while (pc != 0) {
                ret++;
                if (pcstack != NULL) {
                        *pcstack++ = (uint64_t)pc;
@@ -134,10 +123,12 @@
                                break;
                }
 
-               frame = (struct amd64_frame *) sp;
+               if (sp == 0)
+                       break;
 
-               pc = dtrace_fulword(&frame->f_retaddr);
-               sp = dtrace_fulword(&frame->f_frame);
+               pc = dtrace_fuword64((void *)(sp +
+                       offsetof(struct amd64_frame, f_retaddr)));
+               sp = dtrace_fuword64((void *)sp);
 
                /*
                 * This is totally bogus:  if we faulted, we're going to clear
@@ -156,10 +147,9 @@
 void
 dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
 {
-       klwp_t *lwp = ttolwp(curthread);
        proc_t *p = curproc;
-       struct regs *rp;
-       uintptr_t pc, sp;
+       struct trapframe *tf;
+       uintptr_t pc, sp, fp;
        volatile uint16_t *flags =
            (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
        int n;
@@ -173,7 +163,7 @@
        /*
         * If there's no user context we still need to zero the stack.
         */
-       if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL)
+       if (p == NULL || (tf = curlwp->l_md.md_regs) == NULL)
                goto zero;
 
        *pcstack++ = (uint64_t)p->p_pid;
@@ -182,19 +172,29 @@
        if (pcstack_limit <= 0)
                return;
 
-       pc = rp->r_rip;
-       sp = rp->r_rsp;
+       pc = tf->tf_rip;
+       fp = tf->tf_rbp;
+       sp = tf->tf_rsp;
 
        if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
+               /* 
+                * In an entry probe.  The frame pointer has not yet been
+                * pushed (that happens in the function prologue).  The
+                * best approach is to add the current pc as a missing top
+                * of stack and back the pc up to the caller, which is stored
+                * at the current stack pointer address since the call 
+                * instruction puts it there right before the branch.
+                */
+
                *pcstack++ = (uint64_t)pc;
                pcstack_limit--;
                if (pcstack_limit <= 0)
                        return;
 
-               pc = dtrace_fulword((void *) sp);
+               pc = dtrace_fuword64((void *) sp);
        }
 
-       n = dtrace_getustack_common(pcstack, pcstack_limit, pc, sp);
+       n = dtrace_getustack_common(pcstack, pcstack_limit, pc, fp);
        ASSERT(n >= 0);
        ASSERT(n <= pcstack_limit);
 
@@ -209,18 +209,52 @@
 int
 dtrace_getustackdepth(void)
 {
+       proc_t *p = curproc;
+       struct trapframe *tf;
+       uintptr_t pc, fp, sp;
+       int n = 0;
+
+       if (p == NULL || (tf = curlwp->l_md.md_regs) == NULL)
+               return (0);
+
+       if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT))
+               return (-1);
+
+       pc = tf->tf_rip;
+       fp = tf->tf_rbp;
+       sp = tf->tf_rsp;
+
+       if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
+               /* 
+                * In an entry probe.  The frame pointer has not yet been
+                * pushed (that happens in the function prologue).  The
+                * best approach is to add the current pc as a missing top
+                * of stack and back the pc up to the caller, which is stored
+                * at the current stack pointer address since the call 
+                * instruction puts it there right before the branch.
+                */
+
+               pc = dtrace_fuword64((void *) sp);
+               n++;
+       }
+
+       n += dtrace_getustack_common(NULL, 0, pc, fp);
+
+       return (n);
 }
 
 void
 dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
 {
-       klwp_t *lwp = ttolwp(curthread);
        proc_t *p = curproc;
-       struct regs *rp;
-       uintptr_t pc, sp, oldcontext;
+       struct trapframe *tf;
+       uintptr_t pc, sp, fp;
        volatile uint16_t *flags =
            (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
+#ifdef notyet  /* XXX signal stack */
+       uintptr_t oldcontext;
        size_t s1, s2;
+#endif
 
        if (*flags & CPU_DTRACE_FAULT)
                return;
@@ -231,7 +265,7 @@
        /*
         * If there's no user context we still need to zero the stack.
         */
-       if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL)
+       if (p == NULL || (tf = curlwp->l_md.md_regs) == NULL)
                goto zero;
 
        *pcstack++ = (uint64_t)p->p_pid;
@@ -240,12 +274,15 @@
        if (pcstack_limit <= 0)
                return;
 
-       pc = rp->r_pc;
-       sp = rp->r_fp;
+       pc = tf->tf_rip;
+       sp = tf->tf_rsp;
+       fp = tf->tf_rbp;
+
+#ifdef notyet /* XXX signal stack */
        oldcontext = lwp->lwp_oldcontext;
-
        s1 = sizeof (struct xframe) + 2 * sizeof (long);
        s2 = s1 + sizeof (siginfo_t);
+#endif
 
        if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
                *pcstack++ = (uint64_t)pc;
@@ -254,19 +291,20 @@
                if (pcstack_limit <= 0)
                        return;
 
-               if (p->p_model == DATAMODEL_NATIVE)
-                       pc = dtrace_fulword((void *)rp->r_sp);
-               else
-                       pc = dtrace_fuword32((void *)rp->r_sp);
+               pc = dtrace_fuword64((void *)sp);
        }
 
-       while (pc != 0 && sp != 0) {
+       while (pc != 0) {
                *pcstack++ = (uint64_t)pc;
-               *fpstack++ = sp;
+               *fpstack++ = fp;
                pcstack_limit--;
                if (pcstack_limit <= 0)
                        break;
 
+               if (fp == 0)
+                       break;
+
+#ifdef notyet /* XXX signal stack */
                if (oldcontext == sp + s1 || oldcontext == sp + s2) {
                        ucontext_t *ucp = (ucontext_t *)oldcontext;
                        greg_t *gregs = ucp->uc_mcontext.gregs;
@@ -275,11 +313,12 @@
                        pc = dtrace_fulword(&gregs[REG_PC]);
 
                        oldcontext = dtrace_fulword(&ucp->uc_link);
-               } else {
-                       struct xframe *fr = (struct xframe *)sp;
-
-                       pc = dtrace_fulword(&fr->fr_savpc);
-                       sp = dtrace_fulword(&fr->fr_savfp);
+               } else
+#endif /* XXX */
+               {
+                       pc = dtrace_fuword64((void *)(fp +
+                               offsetof(struct amd64_frame, f_retaddr)));
+                       fp = dtrace_fuword64((void *)fp);
                }
 
                /*
@@ -295,9 +334,8 @@
 
 zero:
        while (pcstack_limit-- > 0)
-               *pcstack++ = NULL;
+               *pcstack++ = 0;
 }
-#endif
 
 /*ARGSUSED*/
 uint64_t
@@ -328,7 +366,7 @@
                         * we'll pull the true stack pointer out of the saved
                         * registers and decrement our argument by the number
                         * of arguments passed in registers; if the argument
-                        * we're seeking is passed in regsiters, we can just
+                        * we're seeking is passed in registers, we can just
                         * load it directly.
                         */
                        struct reg *rp = (struct reg *)((uintptr_t)&fp[1] +
diff -r 2f06684cd42a -r 059f2b2cc29d external/cddl/osnet/dev/dtrace/i386/dtrace_asm.S
--- a/external/cddl/osnet/dev/dtrace/i386/dtrace_asm.S  Sat May 14 17:11:30 2016 +0000
+++ b/external/cddl/osnet/dev/dtrace/i386/dtrace_asm.S  Sat May 14 21:19:05 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dtrace_asm.S,v 1.3 2010/03/13 22:31:15 christos Exp $  */
+/*     $NetBSD: dtrace_asm.S,v 1.4 2016/05/14 21:19:05 chs Exp $       */
 
 /*
  * CDDL HEADER START
@@ -48,14 +48,8 @@
         * dtrace_invop wants us to do.
         */
        call    dtrace_invop
-
-       /*
-        * We pushed 3 times for the arguments to dtrace_invop,
-        * so we need to increment the stack pointer to get rid of
-        * those values.
-        */
+       ALTENTRY(dtrace_invop_callsite)
        addl    $12, %esp
-//     ALTENTRY(dtrace_invop_callsite)
        cmpl    $DTRACE_INVOP_PUSHL_EBP, %eax
        je      invop_push
        cmpl    $DTRACE_INVOP_POPL_EBP, %eax
diff -r 2f06684cd42a -r 059f2b2cc29d external/cddl/osnet/dev/dtrace/i386/dtrace_isa.c
--- a/external/cddl/osnet/dev/dtrace/i386/dtrace_isa.c  Sat May 14 17:11:30 2016 +0000
+++ b/external/cddl/osnet/dev/dtrace/i386/dtrace_isa.c  Sat May 14 21:19:05 2016 +0000



Home | Main Index | Thread Index | Old Index