diff options
author | brendan <none@none> | 2008-06-13 19:06:55 -0700 |
---|---|---|
committer | brendan <none@none> | 2008-06-13 19:06:55 -0700 |
commit | 10e6dadfe63181edabc58c8f42e3c56a1cd9ec95 (patch) | |
tree | 95d4edf9068228f58a3abddd6b718c98d6f0b919 /usr/src/uts/intel/dtrace/sdt.c | |
parent | 90bcde942a3919300ffc73f98ea903b58386c395 (diff) | |
download | illumos-joyent-10e6dadfe63181edabc58c8f42e3c56a1cd9ec95.tar.gz |
PSARC 2008/302 DTrace IP Provider
6640019 DTrace IP Provider
6655707 sdt arguments are off-by-one past the 5th
6667364 /usr/demo/dtrace/index.html: URLs to dtrace guide chapters wrong
--HG--
rename : usr/src/lib/libdtrace/common/net.d => deleted_files/usr/src/lib/libdtrace/common/net.d
Diffstat (limited to 'usr/src/uts/intel/dtrace/sdt.c')
-rw-r--r-- | usr/src/uts/intel/dtrace/sdt.c | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/usr/src/uts/intel/dtrace/sdt.c b/usr/src/uts/intel/dtrace/sdt.c index aa31d84d14..55724b3d89 100644 --- a/usr/src/uts/intel/dtrace/sdt.c +++ b/usr/src/uts/intel/dtrace/sdt.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -33,6 +33,11 @@ #include <sys/conf.h> #include <vm/seg_kmem.h> #include <sys/stack.h> +#include <sys/frame.h> +#include <sys/dtrace_impl.h> +#include <sys/cmn_err.h> +#include <sys/sysmacros.h> +#include <sys/privregs.h> #include <sys/sdt_impl.h> #define SDT_PATCHVAL 0xf0 @@ -289,6 +294,72 @@ err: ; } +/*ARGSUSED*/ +uint64_t +sdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno, int aframes) +{ + uintptr_t val; + struct frame *fp = (struct frame *)dtrace_getfp(); + uintptr_t *stack; + int i; +#if defined(__amd64) + /* + * A total of 6 arguments are passed via registers; any argument with + * index of 5 or lower is therefore in a register. + */ + int inreg = 5; +#endif + + for (i = 1; i <= aframes; i++) { + fp = (struct frame *)(fp->fr_savfp); + + if (fp->fr_savpc == (pc_t)dtrace_invop_callsite) { +#if !defined(__amd64) + /* + * If we pass through the invalid op handler, we will + * use the pointer that it passed to the stack as the + * second argument to dtrace_invop() as the pointer to + * the stack. When using this stack, we must step + * beyond the EIP/RIP that was pushed when the trap was + * taken -- hence the "+ 1" below. + */ + stack = ((uintptr_t **)&fp[1])[1]; +#else + /* + * In the case of amd64, we will use the pointer to the + * regs structure that was pushed when we took the + * trap. To get this structure, we must increment + * beyond the frame structure, and then again beyond + * the calling RIP stored in dtrace_invop(). If the + * argument that we're seeking is passed on the stack, + * 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 + * load it directly. + */ + struct regs *rp = (struct regs *)((uintptr_t)&fp[1] + + sizeof (uintptr_t)); + + if (argno <= inreg) { + stack = (uintptr_t *)&rp->r_rdi; + } else { + stack = (uintptr_t *)(rp->r_rsp); + argno -= inreg; + } +#endif + goto load; + } + } + +load: + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); + val = stack[argno]; + DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); + + return (val); +} + static dtrace_pops_t sdt_pops = { NULL, sdt_provide_module, @@ -297,7 +368,7 @@ static dtrace_pops_t sdt_pops = { NULL, NULL, sdt_getargdesc, - NULL, + sdt_getarg, NULL, sdt_destroy }; |