svn commit: r269557 - in stable/10/sys/cddl: contrib/opensolaris/uts/common/sys dev/dtrace/amd64 dev/dtrace/i386

Mark Johnston markj at FreeBSD.org
Tue Aug 5 01:53:16 UTC 2014


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);


More information about the svn-src-all mailing list