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 <dt_program.h>
 #include <dt_pid.h>
 #include <dt_string.h>
-#ifndef illumos
-#include <libproc_compat.h>
-#endif
 #include <dt_module.h>
 
+#ifndef illumos
+#include <sys/sysctl.h>
+#include <unistd.h>
+#include <libproc_compat.h>
+#include <libelf.h>
+#include <gelf.h>
+#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);