Author: rpaulo
Date: Tue Aug 24 12:05:58 2010
New Revision: 211744
URL: http://svn.freebsd.org/changeset/base/211744

Log:
  MD fasttrap implementation.
  
  Sponsored by: The FreeBSD Foundation

Modified:
  head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c

Modified: head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c   Tue Aug 
24 11:55:25 2010        (r211743)
+++ head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c   Tue Aug 
24 12:05:58 2010        (r211744)
@@ -17,6 +17,10 @@
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
+ *
+ * Portions Copyright 2010 The FreeBSD Foundation
+ *
+ * $FreeBSD$
  */
 
 /*
@@ -24,20 +28,86 @@
  * Use is subject to license terms.
  */
 
+#if defined(sun)
 #pragma ident  "%Z%%M% %I%     %E% SMI"
+#endif
 
 #include <sys/fasttrap_isa.h>
 #include <sys/fasttrap_impl.h>
 #include <sys/dtrace.h>
 #include <sys/dtrace_impl.h>
 #include <sys/cmn_err.h>
+#if defined(sun)
 #include <sys/regset.h>
 #include <sys/privregs.h>
 #include <sys/segments.h>
 #include <sys/x86_archext.h>
+#else
+#include <cddl/dev/dtrace/dtrace_cddl.h>
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/dtrace_bsd.h>
+#include <cddl/dev/dtrace/i386/regset.h>
+#include <machine/segments.h>
+#include <machine/reg.h>
+#include <machine/pcb.h>
+#endif
 #include <sys/sysmacros.h>
+#if defined(sun)
 #include <sys/trap.h>
 #include <sys/archsystm.h>
+#else
+#include <sys/ptrace.h>
+
+static int
+proc_ops(int op, proc_t *p, void *kaddr, off_t uaddr, size_t len)
+{
+       struct iovec iov;
+       struct uio uio;
+
+       iov.iov_base = kaddr;
+       iov.iov_len = len;
+       uio.uio_offset = uaddr;
+       uio.uio_iov = &iov;
+       uio.uio_resid = len;
+       uio.uio_iovcnt = 1;
+       uio.uio_segflg = UIO_SYSSPACE;
+       uio.uio_td = curthread;
+       uio.uio_rw = op;
+       _PHOLD(p);
+       PROC_UNLOCK(p);
+       if (proc_rwmem(p, &uio) < 0) {
+               PROC_LOCK(p);
+               _PRELE(p);
+               return (-1);
+       }
+       PROC_LOCK(p);
+       _PRELE(p);
+
+       return (0);
+}
+
+static int
+uread(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
+{
+
+       return (proc_ops(UIO_READ, p, kaddr, uaddr, len));
+}
+
+static int
+uwrite(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
+{
+
+       return (proc_ops(UIO_WRITE, p, kaddr, uaddr, len));
+}
+#endif
+#ifdef __i386__
+#define        r_rax   r_eax
+#define        r_rbx   r_ebx
+#define        r_rip   r_eip
+#define        r_rflags r_eflags
+#define        r_rsp   r_esp
+#endif
 
 /*
  * Lossless User-Land Tracing on x86
@@ -188,12 +258,12 @@ static const uint8_t regmap[8] = {
 };
 #endif
 
-static ulong_t fasttrap_getreg(struct regs *, uint_t);
+static ulong_t fasttrap_getreg(struct reg *, uint_t);
 
 static uint64_t
-fasttrap_anarg(struct regs *rp, int function_entry, int argno)
+fasttrap_anarg(struct reg *rp, int function_entry, int argno)
 {
-       uint64_t value;
+       uint64_t value = 0;
        int shift = function_entry ? 1 : 0;
 
 #ifdef __amd64
@@ -207,16 +277,18 @@ fasttrap_anarg(struct regs *rp, int func
                if (argno < 6)
                        return ((&rp->r_rdi)[argno]);
 
-               stack = (uintptr_t *)rp->r_sp;
+               stack = (uintptr_t *)rp->r_rsp;
                DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
                value = dtrace_fulword(&stack[argno - 6 + shift]);
                DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
        } else {
 #endif
-               uint32_t *stack = (uint32_t *)rp->r_sp;
+#ifdef __i386
+               uint32_t *stack = (uint32_t *)rp->r_esp;
                DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
                value = dtrace_fuword32(&stack[argno + shift]);
                DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT | CPU_DTRACE_BADADDR);
+#endif
 #ifdef __amd64
        }
 #endif
@@ -637,35 +709,41 @@ fasttrap_fulword_noerr(const void *uaddr
 {
        uintptr_t ret;
 
-       if (fasttrap_fulword(uaddr, &ret) == 0)
+       if ((ret = fasttrap_fulword(uaddr)) != -1)
                return (ret);
 
        return (0);
 }
 #endif
 
+#ifdef __i386__
 static uint32_t
 fasttrap_fuword32_noerr(const void *uaddr)
 {
        uint32_t ret;
 
-       if (fasttrap_fuword32(uaddr, &ret) == 0)
+       if ((ret = fasttrap_fuword32(uaddr)) != -1)
                return (ret);
 
        return (0);
 }
+#endif
 
 static void
-fasttrap_return_common(struct regs *rp, uintptr_t pc, pid_t pid,
+fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid,
     uintptr_t new_pc)
 {
        fasttrap_tracepoint_t *tp;
        fasttrap_bucket_t *bucket;
        fasttrap_id_t *id;
+#if defined(sun)
        kmutex_t *pid_mtx;
+#endif
 
+#if defined(sun)
        pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
        mutex_enter(pid_mtx);
+#endif
        bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
 
        for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
@@ -680,7 +758,9 @@ fasttrap_return_common(struct regs *rp, 
         * is not essential to the correct execution of the process.
         */
        if (tp == NULL) {
+#if defined(sun)
                mutex_exit(pid_mtx);
+#endif
                return;
        }
 
@@ -698,15 +778,18 @@ fasttrap_return_common(struct regs *rp, 
 
                dtrace_probe(id->fti_probe->ftp_id,
                    pc - id->fti_probe->ftp_faddr,
-                   rp->r_r0, rp->r_r1, 0, 0);
+                   rp->r_rax, rp->r_rbx, 0, 0);
        }
 
+#if defined(sun)
        mutex_exit(pid_mtx);
+#endif
 }
 
 static void
 fasttrap_sigsegv(proc_t *p, kthread_t *t, uintptr_t addr)
 {
+#if defined(sun)
        sigqueue_t *sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
 
        sqp->sq_info.si_signo = SIGSEGV;
@@ -719,15 +802,24 @@ fasttrap_sigsegv(proc_t *p, kthread_t *t
 
        if (t != NULL)
                aston(t);
+#else
+       ksiginfo_t *ksi = kmem_zalloc(sizeof (ksiginfo_t), KM_SLEEP);
+
+       ksiginfo_init(ksi);
+       ksi->ksi_signo = SIGSEGV;
+       ksi->ksi_code = SEGV_MAPERR;
+       ksi->ksi_addr = (caddr_t)addr;
+       (void) tdksignal(t, SIGSEGV, ksi);
+#endif
 }
 
 #ifdef __amd64
 static void
-fasttrap_usdt_args64(fasttrap_probe_t *probe, struct regs *rp, int argc,
+fasttrap_usdt_args64(fasttrap_probe_t *probe, struct reg *rp, int argc,
     uintptr_t *argv)
 {
        int i, x, cap = MIN(argc, probe->ftp_nargs);
-       uintptr_t *stack = (uintptr_t *)rp->r_sp;
+       uintptr_t *stack = (uintptr_t *)rp->r_rsp;
 
        for (i = 0; i < cap; i++) {
                x = probe->ftp_argmap[i];
@@ -744,12 +836,13 @@ fasttrap_usdt_args64(fasttrap_probe_t *p
 }
 #endif
 
+#ifdef __i386__
 static void
-fasttrap_usdt_args32(fasttrap_probe_t *probe, struct regs *rp, int argc,
+fasttrap_usdt_args32(fasttrap_probe_t *probe, struct reg *rp, int argc,
     uint32_t *argv)
 {
        int i, x, cap = MIN(argc, probe->ftp_nargs);
-       uint32_t *stack = (uint32_t *)rp->r_sp;
+       uint32_t *stack = (uint32_t *)rp->r_rsp;
 
        for (i = 0; i < cap; i++) {
                x = probe->ftp_argmap[i];
@@ -761,13 +854,18 @@ fasttrap_usdt_args32(fasttrap_probe_t *p
                argv[i] = 0;
        }
 }
+#endif
 
 static int
-fasttrap_do_seg(fasttrap_tracepoint_t *tp, struct regs *rp, uintptr_t *addr)
+fasttrap_do_seg(fasttrap_tracepoint_t *tp, struct reg *rp, uintptr_t *addr)
 {
        proc_t *p = curproc;
-       user_desc_t *desc;
-       uint16_t sel, ndx, type;
+#ifdef __i386__
+       struct segment_descriptor *desc;
+#else
+       struct user_segment_descriptor *desc;
+#endif
+       uint16_t sel = 0, ndx, type;
        uintptr_t limit;
 
        switch (tp->ftt_segment) {
@@ -795,36 +893,49 @@ fasttrap_do_seg(fasttrap_tracepoint_t *t
         * Make sure the given segment register specifies a user priority
         * selector rather than a kernel selector.
         */
-       if (!SELISUPL(sel))
+       if (ISPL(sel) != SEL_UPL)
                return (-1);
 
-       ndx = SELTOIDX(sel);
+       ndx = IDXSEL(sel);
 
        /*
         * Check the bounds and grab the descriptor out of the specified
         * descriptor table.
         */
-       if (SELISLDT(sel)) {
-               if (ndx > p->p_ldtlimit)
+       if (ISLDT(sel)) {
+#ifdef __i386__
+               if (ndx > p->p_md.md_ldt->ldt_len)
+                       return (-1);
+
+               desc = (struct segment_descriptor *)
+                   p->p_md.md_ldt[ndx].ldt_base;
+#else
+               if (ndx > max_ldt_segment)
                        return (-1);
 
-               desc = p->p_ldt + ndx;
+               desc = (struct user_segment_descriptor *)
+                   p->p_md.md_ldt[ndx].ldt_base;
+#endif
 
        } else {
                if (ndx >= NGDT)
                        return (-1);
 
-               desc = cpu_get_gdt() + ndx;
+#ifdef __i386__
+               desc = &gdt[ndx].sd;
+#else
+               desc = &gdt[ndx];
+#endif
        }
 
        /*
         * The descriptor must have user privilege level and it must be
         * present in memory.
         */
-       if (desc->usd_dpl != SEL_UPL || desc->usd_p != 1)
+       if (desc->sd_dpl != SEL_UPL || desc->sd_p != 1)
                return (-1);
 
-       type = desc->usd_type;
+       type = desc->sd_type;
 
        /*
         * If the S bit in the type field is not set, this descriptor can
@@ -833,7 +944,7 @@ fasttrap_do_seg(fasttrap_tracepoint_t *t
        if ((type & 0x10) != 0x10)
                return (-1);
 
-       limit = USEGD_GETLIMIT(desc) * (desc->usd_gran ? PAGESIZE : 1);
+       limit = USD_GETLIMIT(desc) * (desc->sd_gran ? PAGESIZE : 1);
 
        if (tp->ftt_segment == FASTTRAP_SEG_CS) {
                /*
@@ -861,7 +972,7 @@ fasttrap_do_seg(fasttrap_tracepoint_t *t
                if ((type & 0x4) == 0) {
                        if (*addr > limit)
                                return (-1);
-               } else if (desc->usd_def32) {
+               } else if (desc->sd_def32) {
                        if (*addr < limit + 1 || 0xffff < *addr)
                                return (-1);
                } else {
@@ -870,18 +981,21 @@ fasttrap_do_seg(fasttrap_tracepoint_t *t
                }
        }
 
-       *addr += USEGD_GETBASE(desc);
+       *addr += USD_GETBASE(desc);
 
        return (0);
 }
 
 int
-fasttrap_pid_probe(struct regs *rp)
+fasttrap_pid_probe(struct reg *rp)
 {
        proc_t *p = curproc;
-       uintptr_t pc = rp->r_pc - 1, new_pc = 0;
+       uintptr_t pc = rp->r_rip - 1;
+       uintptr_t new_pc = 0;
        fasttrap_bucket_t *bucket;
+#if defined(sun)
        kmutex_t *pid_mtx;
+#endif
        fasttrap_tracepoint_t *tp, tp_local;
        pid_t pid;
        dtrace_icookie_t cookie;
@@ -911,6 +1025,7 @@ fasttrap_pid_probe(struct regs *rp)
        curthread->t_dtrace_regv = 0;
 #endif
 
+#if defined(sun)
        /*
         * Treat a child created by a call to vfork(2) as if it were its
         * parent. We know that there's only one thread of control in such a
@@ -919,10 +1034,14 @@ fasttrap_pid_probe(struct regs *rp)
        while (p->p_flag & SVFORK) {
                p = p->p_parent;
        }
+#endif
 
+       PROC_LOCK(p);
        pid = p->p_pid;
+#if defined(sun)
        pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
        mutex_enter(pid_mtx);
+#endif
        bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
 
        /*
@@ -940,15 +1059,19 @@ fasttrap_pid_probe(struct regs *rp)
         * fasttrap_ioctl), or somehow we have mislaid this tracepoint.
         */
        if (tp == NULL) {
+#if defined(sun)
                mutex_exit(pid_mtx);
+#endif
+               PROC_UNLOCK(p);
                return (-1);
        }
 
+       printf("found tracepoint\n");
        /*
         * Set the program counter to the address of the traced instruction
         * so that it looks right in ustack() output.
         */
-       rp->r_pc = pc;
+       rp->r_rip = pc;
 
        if (tp->ftt_ids != NULL) {
                fasttrap_id_t *id;
@@ -995,9 +1118,9 @@ fasttrap_pid_probe(struct regs *rp)
                                }
                        }
                } else {
-#endif
+#else /* __amd64 */
                        uintptr_t s0, s1, s2, s3, s4, s5;
-                       uint32_t *stack = (uint32_t *)rp->r_sp;
+                       uint32_t *stack = (uint32_t *)rp->r_esp;
 
                        /*
                         * In 32-bit mode, all arguments are passed on the
@@ -1050,6 +1173,7 @@ fasttrap_pid_probe(struct regs *rp)
                                            t[2], t[3], t[4]);
                                }
                        }
+#endif /* __amd64 */
 #ifdef __amd64
                }
 #endif
@@ -1061,7 +1185,10 @@ fasttrap_pid_probe(struct regs *rp)
         * tracepoint again later if we need to light up any return probes.
         */
        tp_local = *tp;
+       PROC_UNLOCK(p);
+#if defined(sun)
        mutex_exit(pid_mtx);
+#endif
        tp = &tp_local;
 
        /*
@@ -1069,7 +1196,7 @@ fasttrap_pid_probe(struct regs *rp)
         * had completely executed. This ensures that fasttrap_getreg() will
         * report the expected value for REG_RIP.
         */
-       rp->r_pc = pc + tp->ftt_size;
+       rp->r_rip = pc + tp->ftt_size;
 
        /*
         * If there's an is-enabled probe connected to this tracepoint it
@@ -1083,8 +1210,8 @@ fasttrap_pid_probe(struct regs *rp)
         * exotic way to shoot oneself in the foot.
         */
        if (is_enabled) {
-               rp->r_r0 = 1;
-               new_pc = rp->r_pc;
+               rp->r_rax = 1;
+               new_pc = rp->r_rip;
                goto done;
        }
 
@@ -1098,9 +1225,9 @@ fasttrap_pid_probe(struct regs *rp)
        case FASTTRAP_T_RET:
        case FASTTRAP_T_RET16:
        {
-               uintptr_t dst;
-               uintptr_t addr;
-               int ret;
+               uintptr_t dst = 0;
+               uintptr_t addr = 0;
+               int ret = 0;
 
                /*
                 * We have to emulate _every_ facet of the behavior of a ret
@@ -1109,20 +1236,22 @@ fasttrap_pid_probe(struct regs *rp)
                 */
 #ifdef __amd64
                if (p->p_model == DATAMODEL_NATIVE) {
-#endif
-                       ret = fasttrap_fulword((void *)rp->r_sp, &dst);
-                       addr = rp->r_sp + sizeof (uintptr_t);
-#ifdef __amd64
+                       ret = dst = fasttrap_fulword((void *)rp->r_rsp);
+                       addr = rp->r_rsp + sizeof (uintptr_t);
                } else {
+#endif
+#ifdef __i386__
                        uint32_t dst32;
-                       ret = fasttrap_fuword32((void *)rp->r_sp, &dst32);
+                       ret = dst32 = fasttrap_fuword32((void *)rp->r_esp);
                        dst = dst32;
-                       addr = rp->r_sp + sizeof (uint32_t);
+                       addr = rp->r_esp + sizeof (uint32_t);
+#endif
+#ifdef __amd64
                }
 #endif
 
                if (ret == -1) {
-                       fasttrap_sigsegv(p, curthread, rp->r_sp);
+                       fasttrap_sigsegv(p, curthread, rp->r_rsp);
                        new_pc = pc;
                        break;
                }
@@ -1130,71 +1259,71 @@ fasttrap_pid_probe(struct regs *rp)
                if (tp->ftt_type == FASTTRAP_T_RET16)
                        addr += tp->ftt_dest;
 
-               rp->r_sp = addr;
+               rp->r_rsp = addr;
                new_pc = dst;
                break;
        }
 
        case FASTTRAP_T_JCC:
        {
-               uint_t taken;
+               uint_t taken = 0;
 
                switch (tp->ftt_code) {
                case FASTTRAP_JO:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_OF) != 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_OF) != 0;
                        break;
                case FASTTRAP_JNO:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_OF) == 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0;
                        break;
                case FASTTRAP_JB:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_CF) != 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_CF) != 0;
                        break;
                case FASTTRAP_JAE:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_CF) == 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_CF) == 0;
                        break;
                case FASTTRAP_JE:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) != 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) != 0;
                        break;
                case FASTTRAP_JNE:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) == 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) == 0;
                        break;
                case FASTTRAP_JBE:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_CF) != 0 ||
-                           (rp->r_ps & FASTTRAP_EFLAGS_ZF) != 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_CF) != 0 ||
+                           (rp->r_rflags & FASTTRAP_EFLAGS_ZF) != 0;
                        break;
                case FASTTRAP_JA:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_CF) == 0 &&
-                           (rp->r_ps & FASTTRAP_EFLAGS_ZF) == 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_CF) == 0 &&
+                           (rp->r_rflags & FASTTRAP_EFLAGS_ZF) == 0;
                        break;
                case FASTTRAP_JS:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_SF) != 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_SF) != 0;
                        break;
                case FASTTRAP_JNS:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_SF) == 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0;
                        break;
                case FASTTRAP_JP:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_PF) != 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_PF) != 0;
                        break;
                case FASTTRAP_JNP:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_PF) == 0;
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_PF) == 0;
                        break;
                case FASTTRAP_JL:
-                       taken = ((rp->r_ps & FASTTRAP_EFLAGS_SF) == 0) !=
-                           ((rp->r_ps & FASTTRAP_EFLAGS_OF) == 0);
+                       taken = ((rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0) !=
+                           ((rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0);
                        break;
                case FASTTRAP_JGE:
-                       taken = ((rp->r_ps & FASTTRAP_EFLAGS_SF) == 0) ==
-                           ((rp->r_ps & FASTTRAP_EFLAGS_OF) == 0);
+                       taken = ((rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0) ==
+                           ((rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0);
                        break;
                case FASTTRAP_JLE:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) != 0 ||
-                           ((rp->r_ps & FASTTRAP_EFLAGS_SF) == 0) !=
-                           ((rp->r_ps & FASTTRAP_EFLAGS_OF) == 0);
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) != 0 ||
+                           ((rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0) !=
+                           ((rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0);
                        break;
                case FASTTRAP_JG:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) == 0 &&
-                           ((rp->r_ps & FASTTRAP_EFLAGS_SF) == 0) ==
-                           ((rp->r_ps & FASTTRAP_EFLAGS_OF) == 0);
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) == 0 &&
+                           ((rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0) ==
+                           ((rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0);
                        break;
 
                }
@@ -1208,7 +1337,7 @@ fasttrap_pid_probe(struct regs *rp)
 
        case FASTTRAP_T_LOOP:
        {
-               uint_t taken;
+               uint_t taken = 0;
 #ifdef __amd64
                greg_t cx = rp->r_rcx--;
 #else
@@ -1217,11 +1346,11 @@ fasttrap_pid_probe(struct regs *rp)
 
                switch (tp->ftt_code) {
                case FASTTRAP_LOOPNZ:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) == 0 &&
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) == 0 &&
                            cx != 0;
                        break;
                case FASTTRAP_LOOPZ:
-                       taken = (rp->r_ps & FASTTRAP_EFLAGS_ZF) != 0 &&
+                       taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) != 0 &&
                            cx != 0;
                        break;
                case FASTTRAP_LOOP:
@@ -1253,18 +1382,19 @@ fasttrap_pid_probe(struct regs *rp)
 
        case FASTTRAP_T_PUSHL_EBP:
        {
-               int ret;
-               uintptr_t addr;
+               int ret = 0;
+               uintptr_t addr = 0;
 #ifdef __amd64
                if (p->p_model == DATAMODEL_NATIVE) {
+                       addr = rp->r_rsp - sizeof (uintptr_t);
+                       ret = fasttrap_sulword((void *)addr, &rp->r_rsp);
+               } else {
+#endif
+#ifdef __i386__
+                       addr = rp->r_rsp - sizeof (uint32_t);
+                       ret = fasttrap_suword32((void *)addr, &rp->r_rsp);
 #endif
-                       addr = rp->r_sp - sizeof (uintptr_t);
-                       ret = fasttrap_sulword((void *)addr, rp->r_fp);
 #ifdef __amd64
-               } else {
-                       addr = rp->r_sp - sizeof (uint32_t);
-                       ret = fasttrap_suword32((void *)addr,
-                           (uint32_t)rp->r_fp);
                }
 #endif
 
@@ -1274,7 +1404,7 @@ fasttrap_pid_probe(struct regs *rp)
                        break;
                }
 
-               rp->r_sp = addr;
+               rp->r_rsp = addr;
                new_pc = pc + tp->ftt_size;
                break;
        }
@@ -1288,7 +1418,10 @@ fasttrap_pid_probe(struct regs *rp)
                if (tp->ftt_code == 0) {
                        new_pc = tp->ftt_dest;
                } else {
-                       uintptr_t value, addr = tp->ftt_dest;
+#ifdef __amd64
+                       uintptr_t value;
+#endif
+                       uintptr_t addr = tp->ftt_dest;
 
                        if (tp->ftt_base != FASTTRAP_NOREG)
                                addr += fasttrap_getreg(rp, tp->ftt_base);
@@ -1312,32 +1445,34 @@ fasttrap_pid_probe(struct regs *rp)
 
 #ifdef __amd64
                                if (p->p_model == DATAMODEL_NATIVE) {
-#endif
-                                       if (fasttrap_fulword((void *)addr,
-                                           &value) == -1) {
+                                       if ((value = fasttrap_fulword((void 
*)addr))
+                                            == -1) {
                                                fasttrap_sigsegv(p, curthread,
                                                    addr);
                                                new_pc = pc;
                                                break;
                                        }
                                        new_pc = value;
-#ifdef __amd64
                                } else {
+#endif
+#ifdef __i386__
                                        uint32_t value32;
                                        addr = (uintptr_t)(uint32_t)addr;
-                                       if (fasttrap_fuword32((void *)addr,
-                                           &value32) == -1) {
+                                       if ((value32 = fasttrap_fuword32((void 
*)addr))
+                                           == -1) {
                                                fasttrap_sigsegv(p, curthread,
                                                    addr);
                                                new_pc = pc;
                                                break;
                                        }
                                        new_pc = value32;
-                               }
 #endif
+                               }
+#ifdef __amd64
                        } else {
                                new_pc = addr;
                        }
+#endif
                }
 
                /*
@@ -1347,18 +1482,20 @@ fasttrap_pid_probe(struct regs *rp)
                 * this instruction weren't traced.
                 */
                if (tp->ftt_type == FASTTRAP_T_CALL) {
-                       int ret;
-                       uintptr_t addr;
+                       int ret = 0;
+                       uintptr_t addr = 0, pcps;
 #ifdef __amd64
                        if (p->p_model == DATAMODEL_NATIVE) {
-                               addr = rp->r_sp - sizeof (uintptr_t);
-                               ret = fasttrap_sulword((void *)addr,
-                                   pc + tp->ftt_size);
+                               addr = rp->r_rsp - sizeof (uintptr_t);
+                               pcps = pc + tp->ftt_size;
+                               ret = fasttrap_sulword((void *)addr, &pcps);
                        } else {
 #endif
-                               addr = rp->r_sp - sizeof (uint32_t);
-                               ret = fasttrap_suword32((void *)addr,
-                                   (uint32_t)(pc + tp->ftt_size));
+#ifdef __i386__
+                               addr = rp->r_rsp - sizeof (uint32_t);
+                               pcps = (uint32_t)(pc + tp->ftt_size);
+                               ret = fasttrap_suword32((void *)addr, &pcps);
+#endif
 #ifdef __amd64
                        }
 #endif
@@ -1369,7 +1506,7 @@ fasttrap_pid_probe(struct regs *rp)
                                break;
                        }
 
-                       rp->r_sp = addr;
+                       rp->r_rsp = addr;
                }
 
                break;
@@ -1383,7 +1520,9 @@ fasttrap_pid_probe(struct regs *rp)
                uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 7];
 #endif
                uint_t i = 0;
+#if defined(sun)
                klwp_t *lwp = ttolwp(curthread);
+#endif
 
                /*
                 * Compute the address of the ulwp_t and step over the
@@ -1391,6 +1530,7 @@ fasttrap_pid_probe(struct regs *rp)
                 * thread pointer is very different on 32- and 64-bit
                 * kernels.
                 */
+#if defined(sun)
 #if defined(__amd64)
                if (p->p_model == DATAMODEL_LP64) {
                        addr = lwp->lwp_pcb.pcb_fsbase;
@@ -1400,9 +1540,16 @@ fasttrap_pid_probe(struct regs *rp)
                        addr += sizeof (caddr32_t);
                }
 #else
-               addr = USEGD_GETBASE(&lwp->lwp_pcb.pcb_gsdesc);
+               addr = USD_GETBASE(&lwp->lwp_pcb.pcb_gsdesc);
                addr += sizeof (void *);
 #endif
+#endif /* sun */
+#ifdef __i386__
+               addr = USD_GETBASE(&curthread->td_pcb->pcb_gsd);
+#else
+               addr = curthread->td_pcb->pcb_gsbase;
+#endif
+               addr += sizeof (void *);
 
                /*
                 * Generic Instruction Tracing
@@ -1495,7 +1642,7 @@ fasttrap_pid_probe(struct regs *rp)
 
 #ifdef __amd64
                if (tp->ftt_ripmode != 0) {
-                       greg_t *reg;
+                       greg_t *reg = NULL;
 
                        ASSERT(p->p_model == DATAMODEL_LP64);
                        ASSERT(tp->ftt_ripmode &
@@ -1566,6 +1713,7 @@ fasttrap_pid_probe(struct regs *rp)
                        i += sizeof (uint64_t);
                } else {
 #endif
+#ifdef __i386__
                        /*
                         * Set up the jmp to the next instruction; note that
                         * the size of the traced instruction cancels out.
@@ -1574,6 +1722,7 @@ fasttrap_pid_probe(struct regs *rp)
                        /* LINTED - alignment */
                        *(uint32_t *)&scratch[i] = pc - addr - 5;
                        i += sizeof (uint32_t);
+#endif
 #ifdef __amd64
                }
 #endif
@@ -1632,7 +1781,7 @@ done:
                         * output. We had previously set it to the end of the
                         * instruction to simplify %rip-relative addressing.
                         */
-                       rp->r_pc = pc;
+                       rp->r_rip = pc;
 
                        fasttrap_return_common(rp, pc, pid, new_pc);
                } else {
@@ -1643,13 +1792,14 @@ done:
                }
        }
 
-       rp->r_pc = new_pc;
+       rp->r_rip = new_pc;
+       set_regs(curthread, rp);
 
        return (0);
 }
 
 int
-fasttrap_return_probe(struct regs *rp)
+fasttrap_return_probe(struct reg *rp)
 {
        proc_t *p = curproc;
        uintptr_t pc = curthread->t_dtrace_pc;
@@ -1660,6 +1810,7 @@ fasttrap_return_probe(struct regs *rp)
        curthread->t_dtrace_scrpc = 0;
        curthread->t_dtrace_astpc = 0;
 
+#if defined(sun)
        /*
         * Treat a child created by a call to vfork(2) as if it were its
         * parent. We know that there's only one thread of control in such a
@@ -1668,15 +1819,16 @@ fasttrap_return_probe(struct regs *rp)
        while (p->p_flag & SVFORK) {
                p = p->p_parent;
        }
+#endif
 
        /*
-        * We set rp->r_pc to the address of the traced instruction so
+        * We set rp->r_rip to the address of the traced instruction so
         * that it appears to dtrace_probe() that we're on the original
         * instruction, and so that the user can't easily detect our
         * complex web of lies. dtrace_return_probe() (our caller)
         * will correctly set %pc after we return.
         */
-       rp->r_pc = pc;
+       rp->r_rip = pc;
 
        fasttrap_return_common(rp, pc, p->p_pid, npc);
 
@@ -1688,7 +1840,11 @@ uint64_t
 fasttrap_pid_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
     int aframes)
 {
-       return (fasttrap_anarg(ttolwp(curthread)->lwp_regs, 1, argno));
+       struct reg r;
+
+       fill_regs(curthread, &r);
+
+       return (fasttrap_anarg(&r, 1, argno));
 }
 
 /*ARGSUSED*/
@@ -1696,11 +1852,15 @@ uint64_t
 fasttrap_usdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
     int aframes)
 {
-       return (fasttrap_anarg(ttolwp(curthread)->lwp_regs, 0, argno));
+       struct reg r;
+
+       fill_regs(curthread, &r);
+
+       return (fasttrap_anarg(&r, 0, argno));
 }
 
 static ulong_t
-fasttrap_getreg(struct regs *rp, uint_t reg)
+fasttrap_getreg(struct reg *rp, uint_t reg)
 {
 #ifdef __amd64
        switch (reg) {
@@ -1723,20 +1883,23 @@ fasttrap_getreg(struct regs *rp, uint_t 
        case REG_ERR:           return (rp->r_err);
        case REG_RIP:           return (rp->r_rip);
        case REG_CS:            return (rp->r_cs);
+#if defined(sun)
        case REG_RFL:           return (rp->r_rfl);
+#endif
        case REG_RSP:           return (rp->r_rsp);
        case REG_SS:            return (rp->r_ss);
        case REG_FS:            return (rp->r_fs);
        case REG_GS:            return (rp->r_gs);
        case REG_DS:            return (rp->r_ds);
        case REG_ES:            return (rp->r_es);
-       case REG_FSBASE:        return (rdmsr(MSR_AMD_FSBASE));
-       case REG_GSBASE:        return (rdmsr(MSR_AMD_GSBASE));
+       case REG_FSBASE:        return (rdmsr(MSR_FSBASE));
+       case REG_GSBASE:        return (rdmsr(MSR_GSBASE));
        }
 
        panic("dtrace: illegal register constant");
        /*NOTREACHED*/
 #else
+#define _NGREG 19
        if (reg >= _NGREG)
                panic("dtrace: illegal register constant");
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to