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