Author: markj
Date: Mon Jun 23 02:00:14 2014
New Revision: 267761
URL: http://svnweb.freebsd.org/changeset/base/267761

Log:
  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.
  
  MFC after:    3 weeks

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h
  head/sys/cddl/dev/dtrace/i386/dtrace_asm.S
  head/sys/cddl/dev/dtrace/i386/dtrace_isa.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h      Mon Jun 
23 01:28:18 2014        (r267760)
+++ head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h      Mon Jun 
23 02:00:14 2014        (r267761)
@@ -1268,7 +1268,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: head/sys/cddl/dev/dtrace/i386/dtrace_asm.S
==============================================================================
--- head/sys/cddl/dev/dtrace/i386/dtrace_asm.S  Mon Jun 23 01:28:18 2014        
(r267760)
+++ head/sys/cddl/dev/dtrace/i386/dtrace_asm.S  Mon Jun 23 02:00:14 2014        
(r267761)
@@ -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: head/sys/cddl/dev/dtrace/i386/dtrace_isa.c
==============================================================================
--- head/sys/cddl/dev/dtrace/i386/dtrace_isa.c  Mon Jun 23 01:28:18 2014        
(r267760)
+++ head/sys/cddl/dev/dtrace/i386/dtrace_isa.c  Mon Jun 23 02:00:14 2014        
(r267761)
@@ -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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to