diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c index a75dc02d5ad9..5fab935ee94e 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c @@ -147,6 +147,9 @@ dtrace_dof_init(void) 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 @@ dtrace_dof_init(void) else { dprintf(1, "DTrace ioctl succeeded for DOF at %p\n", dof); #ifdef __FreeBSD__ - gen = dh.gen; + gen = dh.dofhp_gen; #endif } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c index ae41269afa16..eaf0961c90c8 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c @@ -1785,11 +1785,17 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, "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 /* diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c index e628e62e9cc4..c61a7106e239 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c @@ -44,11 +44,16 @@ #include #include #include -#ifndef illumos -#include -#endif #include +#ifndef illumos +#include +#include +#include +#include +#include +#endif + typedef struct dt_pid_probe { dtrace_hdl_t *dpp_dtp; dt_pcb_t *dpp_pcb; @@ -566,6 +571,12 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) 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 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) continue; } +#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), + 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 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), -#ifdef illumos sip.prs_lmid, mname); -#else - 0, mname); -#endif -#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 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) #endif } -#ifdef illumos if (fd != -1) +#ifdef __FreeBSD__ + (void) close(fd); +#else (void) pr_close(P, fd); #endif @@ -634,7 +691,6 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, 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 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, (int)proc_getpid(P), strerror(errno)); #endif } -#else - ret = 0; -#endif /* * Put the module name in its canonical form. diff --git a/cddl/lib/libdtrace/libproc_compat.h b/cddl/lib/libdtrace/libproc_compat.h index 0d99d967553a..8704b820df58 100644 --- a/cddl/lib/libdtrace/libproc_compat.h +++ b/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 diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c index 818f18064f89..dc7c283fdd7f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -15374,13 +15374,15 @@ dtrace_helper_action_destroy(dtrace_helper_action_t *helper, } 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 @@ dtrace_helper_validate(dtrace_helper_action_t *helper) } 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 @@ dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep) 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 @@ dtrace_helper_provider_register(proc_t *p, dtrace_helpers_t *help, } 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_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp) 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 @@ dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp) 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 @@ dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp) 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 @@ dtrace_ioctl_helper(int cmd, intptr_t arg, int *rv) case DTRACEHIOC_REMOVE: { mutex_enter(&dtrace_lock); - rval = dtrace_helper_destroygen(arg); + rval = dtrace_helper_destroygen(NULL, arg); mutex_exit(&dtrace_lock); return (rval); diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h index 4605ee52b4c6..dfcdbbfc4e9d 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -1423,8 +1423,9 @@ typedef struct dof_helper { 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; diff --git a/sys/cddl/dev/dtrace/dtrace_ioctl.c b/sys/cddl/dev/dtrace/dtrace_ioctl.c index ef9bed561c15..524e9379ec60 100644 --- a/sys/cddl/dev/dtrace/dtrace_ioctl.c +++ b/sys/cddl/dev/dtrace/dtrace_ioctl.c @@ -32,9 +32,9 @@ static int 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 @@ dtrace_ioctl_helper(struct cdev *dev, u_long cmd, caddr_t addr, int flags, 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 @@ dtrace_ioctl_helper(struct cdev *dev, u_long cmd, caddr_t addr, int flags, 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);