Date: Tue, 5 Aug 2014 01:53:15 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r269557 - in stable/10/sys/cddl: contrib/opensolaris/uts/common/sys dev/dtrace/amd64 dev/dtrace/i386 Message-ID: <53e0390c.5bd6.2dd54011@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Tue Aug 5 01:53:15 2014 New Revision: 269557 URL: http://svnweb.freebsd.org/changeset/base/269557 Log: MFC r267759, r267761 r267759: Fix a couple of bugs on amd64 when fetching probe arguments beyond the first five for probes entered through a UD fault (i.e. FBT probes). Specifically, handle the fact that dtrace_invop_callsite must be 16 byte-aligned and thus may not immediately follow the call to dtrace_invop() in dtrace_invop_start(). Also fetch register arguments and the stack pointer through a struct trapframe instead of a struct reg. r267761: Fix some bugs when fetching probe arguments in i386. Firstly ensure that the 4 byte-aligned dtrace_invop_callsite can be found and that it immediately follows the call to dtrace_invop(). Secondly, fix some pointer arithmetic to account for differences between struct i386_frame and illumos' struct frame. Finally, ensure that dtrace_getarg() isn't inlined. It works by following a fixed number of frame pointers to the probe site, so inlining breaks it. PR: 191260 Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h stable/10/sys/cddl/dev/dtrace/amd64/dtrace_isa.c stable/10/sys/cddl/dev/dtrace/i386/dtrace_asm.S stable/10/sys/cddl/dev/dtrace/i386/dtrace_isa.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h ============================================================================== --- stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h Tue Aug 5 01:53:14 2014 (r269556) +++ stable/10/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h Tue Aug 5 01:53:15 2014 (r269557) @@ -1270,7 +1270,11 @@ typedef struct dtrace_toxrange { uintptr_t dtt_limit; /* limit of toxic range */ } dtrace_toxrange_t; +#if defined(sun) extern uint64_t dtrace_getarg(int, int); +#else +extern uint64_t __noinline dtrace_getarg(int, int); +#endif extern greg_t dtrace_getfp(void); extern int dtrace_getipl(void); extern uintptr_t dtrace_caller(int); Modified: stable/10/sys/cddl/dev/dtrace/amd64/dtrace_isa.c ============================================================================== --- stable/10/sys/cddl/dev/dtrace/amd64/dtrace_isa.c Tue Aug 5 01:53:14 2014 (r269556) +++ stable/10/sys/cddl/dev/dtrace/amd64/dtrace_isa.c Tue Aug 5 01:53:15 2014 (r269557) @@ -349,7 +349,8 @@ dtrace_getarg(int arg, int aframes) for (i = 1; i <= aframes; i++) { fp = fp->f_frame; - if (fp->f_retaddr == (long)dtrace_invop_callsite) { + if (P2ROUNDUP(fp->f_retaddr, 16) == + (long)dtrace_invop_callsite) { /* * In the case of amd64, we will use the pointer to the * regs structure that was pushed when we took the @@ -363,33 +364,33 @@ dtrace_getarg(int arg, int aframes) * we're seeking is passed in regsiters, we can just * load it directly. */ - struct reg *rp = (struct reg *)((uintptr_t)&fp[1] + - sizeof (uintptr_t)); + struct trapframe *tf = + (struct trapframe *)((uintptr_t)&fp[1]); if (arg <= inreg) { switch (arg) { case 0: - stack = (uintptr_t *)&rp->r_rdi; + stack = (uintptr_t *)&tf->tf_rdi; break; case 1: - stack = (uintptr_t *)&rp->r_rsi; + stack = (uintptr_t *)&tf->tf_rsi; break; case 2: - stack = (uintptr_t *)&rp->r_rdx; + stack = (uintptr_t *)&tf->tf_rdx; break; case 3: - stack = (uintptr_t *)&rp->r_rcx; + stack = (uintptr_t *)&tf->tf_rcx; break; case 4: - stack = (uintptr_t *)&rp->r_r8; + stack = (uintptr_t *)&tf->tf_r8; break; case 5: - stack = (uintptr_t *)&rp->r_r9; + stack = (uintptr_t *)&tf->tf_r9; break; } arg = 0; } else { - stack = (uintptr_t *)(rp->r_rsp); + stack = (uintptr_t *)(tf->tf_rsp); arg -= inreg; } goto load; Modified: stable/10/sys/cddl/dev/dtrace/i386/dtrace_asm.S ============================================================================== --- stable/10/sys/cddl/dev/dtrace/i386/dtrace_asm.S Tue Aug 5 01:53:14 2014 (r269556) +++ stable/10/sys/cddl/dev/dtrace/i386/dtrace_asm.S Tue Aug 5 01:53:15 2014 (r269557) @@ -49,14 +49,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. - */ - addl $12, %esp ALTENTRY(dtrace_invop_callsite) + addl $12, %esp cmpl $DTRACE_INVOP_PUSHL_EBP, %eax je invop_push cmpl $DTRACE_INVOP_POPL_EBP, %eax Modified: stable/10/sys/cddl/dev/dtrace/i386/dtrace_isa.c ============================================================================== --- stable/10/sys/cddl/dev/dtrace/i386/dtrace_isa.c Tue Aug 5 01:53:14 2014 (r269556) +++ stable/10/sys/cddl/dev/dtrace/i386/dtrace_isa.c Tue Aug 5 01:53:15 2014 (r269557) @@ -413,7 +413,8 @@ dtrace_getarg(int arg, int aframes) for (i = 1; i <= aframes; i++) { fp = fp->f_frame; - if (fp->f_retaddr == (long)dtrace_invop_callsite) { + if (P2ROUNDUP(fp->f_retaddr, 4) == + (long)dtrace_invop_callsite) { /* * If we pass through the invalid op handler, we will * use the pointer that it passed to the stack as the @@ -422,7 +423,7 @@ dtrace_getarg(int arg, int aframes) * beyond the EIP/RIP that was pushed when the trap was * taken -- hence the "+ 1" below. */ - stack = ((uintptr_t **)&fp[1])[1] + 1; + stack = ((uintptr_t **)&fp[1])[0] + 1; goto load; } @@ -438,7 +439,7 @@ dtrace_getarg(int arg, int aframes) */ arg++; - stack = (uintptr_t *)&fp[1]; + stack = (uintptr_t *)fp + 2; load: DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53e0390c.5bd6.2dd54011>