Index: head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c =================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c @@ -147,6 +147,9 @@ dh.dofhp_dof = (uintptr_t)dof; dh.dofhp_addr = elf->e_type == ET_DYN ? (uintptr_t) lmp->l_addr : 0; +#ifdef __FreeBSD__ + dh.dofhp_pid = getpid(); +#endif if (lmid == 0) { (void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod), @@ -184,7 +187,7 @@ else { dprintf(1, "DTrace ioctl succeeded for DOF at %p\n", dof); #ifdef __FreeBSD__ - gen = dh.gen; + gen = dh.dofhp_gen; #endif } Index: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c =================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c @@ -1785,11 +1785,17 @@ "failed to open %s: %s", file, strerror(errno))); } #else - snprintf(tfile, sizeof(tfile), "%s.XXXXXX", file); - if ((fd = mkstemp(tfile)) == -1) - return (dt_link_error(dtp, NULL, -1, NULL, - "failed to create temporary file %s: %s", - tfile, strerror(errno))); + if (dtp->dt_lazyload) { + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) + return (dt_link_error(dtp, NULL, -1, NULL, + "failed to open %s: %s", file, strerror(errno))); + } else { + snprintf(tfile, sizeof(tfile), "%s.XXXXXX", file); + if ((fd = mkstemp(tfile)) == -1) + return (dt_link_error(dtp, NULL, -1, NULL, + "failed to create temporary file %s: %s", + tfile, strerror(errno))); + } #endif /* Index: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c =================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c @@ -44,10 +44,15 @@ #include #include #include +#include + #ifndef illumos +#include +#include #include +#include +#include #endif -#include typedef struct dt_pid_probe { dtrace_hdl_t *dpp_dtp; @@ -566,6 +571,12 @@ prsyminfo_t sip; dof_helper_t dh; GElf_Half e_type; +#ifdef __FreeBSD__ + dof_hdr_t hdr; + size_t sz; + uint64_t dofmax; + void *dof; +#endif const char *mname; const char *syms[] = { "___SUNW_dof", "__SUNW_dof" }; int i, fd = -1; @@ -595,17 +606,61 @@ continue; } - dh.dofhp_dof = sym.st_value; +#ifdef __FreeBSD__ dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr; + if (Pread(P, &hdr, sizeof (hdr), sym.st_value) != + sizeof (hdr)) { + dt_dprintf("read of DOF header failed\n"); + continue; + } + + sz = sizeof(dofmax); + if (sysctlbyname("kern.dtrace.dof_maxsize", &dofmax, &sz, + NULL, 0) != 0) { + dt_dprintf("failed to read dof_maxsize: %s\n", + strerror(errno)); + continue; + } + if (dofmax < hdr.dofh_loadsz) { + dt_dprintf("DOF load size exceeds maximum\n"); + continue; + } + + if ((dof = malloc(hdr.dofh_loadsz)) == NULL) + return (-1); + + if (Pread(P, dof, hdr.dofh_loadsz, sym.st_value) != + hdr.dofh_loadsz) { + free(dof); + dt_dprintf("read of DOF section failed\n"); + continue; + } + + dh.dofhp_dof = (uintptr_t)dof; + dh.dofhp_pid = proc_getpid(P); dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod), -#ifdef illumos sip.prs_lmid, mname); + + if (fd == -1 && + (fd = open("/dev/dtrace/helper", O_RDWR, 0)) < 0) { + dt_dprintf("open of helper device failed: %s\n", + strerror(errno)); + free(dof); + return (-1); /* errno is set for us */ + } + + if (ioctl(fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0) + dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod); + + free(dof); #else - 0, mname); -#endif + dh.dofhp_dof = sym.st_value; + dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr; + + dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod), + sip.prs_lmid, mname); -#ifdef illumos if (fd == -1 && (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { dt_dprintf("pr_open of helper device failed: %s\n", @@ -618,8 +673,10 @@ #endif } -#ifdef illumos if (fd != -1) +#ifdef __FreeBSD__ + (void) close(fd); +#else (void) pr_close(P, fd); #endif @@ -634,7 +691,6 @@ int ret = 0; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); -#ifdef illumos (void) Pupdate_maps(P); if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) { ret = -1; @@ -646,9 +702,6 @@ (int)proc_getpid(P), strerror(errno)); #endif } -#else - ret = 0; -#endif /* * Put the module name in its canonical form. Index: head/cddl/lib/libdtrace/libproc_compat.h =================================================================== --- head/cddl/lib/libdtrace/libproc_compat.h +++ head/cddl/lib/libdtrace/libproc_compat.h @@ -59,6 +59,6 @@ #define Pstate proc_state #define Psymbol_iter_by_addr proc_iter_symbyaddr #define Punsetflags proc_clearflags -#define Pupdate_maps(p) do { } while (0) +#define Pupdate_maps proc_rdagent #define Pupdate_syms proc_updatesyms #define Pxecbkpt proc_bkptexec Index: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c =================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -15374,13 +15374,15 @@ } static int -dtrace_helper_destroygen(int gen) +dtrace_helper_destroygen(dtrace_helpers_t *help, int gen) { proc_t *p = curproc; - dtrace_helpers_t *help = p->p_dtrace_helpers; dtrace_vstate_t *vstate; int i; + if (help == NULL) + help = p->p_dtrace_helpers; + ASSERT(MUTEX_HELD(&dtrace_lock)); if (help == NULL || gen > help->dthps_generation) @@ -15478,9 +15480,9 @@ } static int -dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep) +dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep, + dtrace_helpers_t *help) { - dtrace_helpers_t *help; dtrace_helper_action_t *helper, *last; dtrace_actdesc_t *act; dtrace_vstate_t *vstate; @@ -15490,7 +15492,6 @@ if (which < 0 || which >= DTRACE_NHELPER_ACTIONS) return (EINVAL); - help = curproc->p_dtrace_helpers; last = help->dthps_actions[which]; vstate = &help->dthps_vstate; @@ -15614,15 +15615,12 @@ } static int -dtrace_helper_provider_add(dof_helper_t *dofhp, int gen) +dtrace_helper_provider_add(dof_helper_t *dofhp, dtrace_helpers_t *help, int gen) { - dtrace_helpers_t *help; dtrace_helper_provider_t *hprov, **tmp_provs; uint_t tmp_maxprovs, i; ASSERT(MUTEX_HELD(&dtrace_lock)); - - help = curproc->p_dtrace_helpers; ASSERT(help != NULL); /* @@ -15914,13 +15912,28 @@ dtrace_helpers_t *help; dtrace_vstate_t *vstate; dtrace_enabling_t *enab = NULL; + proc_t *p = curproc; int i, gen, rv, nhelpers = 0, nprovs = 0, destroy = 1; uintptr_t daddr = (uintptr_t)dof; ASSERT(MUTEX_HELD(&dtrace_lock)); - if ((help = curproc->p_dtrace_helpers) == NULL) - help = dtrace_helpers_create(curproc); +#ifdef __FreeBSD__ + if (dhp->dofhp_pid != p->p_pid) { + if ((p = pfind(dhp->dofhp_pid)) == NULL) + return (-1); + if (!P_SHOULDSTOP(p) || + (p->p_flag & P_TRACED) == 0 || + p->p_pptr->p_pid != curproc->p_pid) { + PROC_UNLOCK(p); + return (-1); + } + PROC_UNLOCK(p); + } +#endif + + if ((help = p->p_dtrace_helpers) == NULL) + help = dtrace_helpers_create(p); vstate = &help->dthps_vstate; @@ -15968,12 +15981,13 @@ continue; if ((rv = dtrace_helper_action_add(DTRACE_HELPER_ACTION_USTACK, - ep)) != 0) { + ep, help)) != 0) { /* * Adding this helper action failed -- we are now going * to rip out the entire generation and return failure. */ - (void) dtrace_helper_destroygen(help->dthps_generation); + (void) dtrace_helper_destroygen(help, + help->dthps_generation); dtrace_enabling_destroy(enab); dtrace_dof_destroy(dof); return (-1); @@ -15990,9 +16004,9 @@ if (dhp != NULL && nprovs > 0) { dhp->dofhp_dof = (uint64_t)(uintptr_t)dof; - if (dtrace_helper_provider_add(dhp, gen) == 0) { + if (dtrace_helper_provider_add(dhp, help, gen) == 0) { mutex_exit(&dtrace_lock); - dtrace_helper_provider_register(curproc, help, dhp); + dtrace_helper_provider_register(p, help, dhp); mutex_enter(&dtrace_lock); destroy = 0; @@ -16956,7 +16970,7 @@ case DTRACEHIOC_REMOVE: { mutex_enter(&dtrace_lock); - rval = dtrace_helper_destroygen(arg); + rval = dtrace_helper_destroygen(NULL, arg); mutex_exit(&dtrace_lock); return (rval); Index: head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h =================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -1423,8 +1423,9 @@ char dofhp_mod[DTRACE_MODNAMELEN]; /* executable or library name */ uint64_t dofhp_addr; /* base address of object */ uint64_t dofhp_dof; /* address of helper DOF */ -#ifndef illumos - int gen; +#ifdef __FreeBSD__ + pid_t dofhp_pid; /* target process ID */ + int dofhp_gen; #endif } dof_helper_t; Index: head/sys/cddl/dev/dtrace/dtrace_ioctl.c =================================================================== --- head/sys/cddl/dev/dtrace/dtrace_ioctl.c +++ head/sys/cddl/dev/dtrace/dtrace_ioctl.c @@ -32,9 +32,9 @@ dtrace_ioctl_helper(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td) { - int rval; dof_helper_t *dhp = NULL; dof_hdr_t *dof = NULL; + int rval; switch (cmd) { case DTRACEHIOC_ADDDOF: @@ -51,7 +51,7 @@ mutex_enter(&dtrace_lock); if ((rval = dtrace_helper_slurp((dof_hdr_t *)dof, dhp)) != -1) { if (dhp) { - dhp->gen = rval; + dhp->dofhp_gen = rval; copyout(dhp, addr, sizeof(*dhp)); } rval = 0; @@ -59,10 +59,11 @@ rval = EINVAL; } mutex_exit(&dtrace_lock); + return (rval); case DTRACEHIOC_REMOVE: mutex_enter(&dtrace_lock); - rval = dtrace_helper_destroygen((int)*addr); + rval = dtrace_helper_destroygen(NULL, (int)*addr); mutex_exit(&dtrace_lock); return (rval);