summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2015-04-08 02:36:37 +0000
committerMark Johnston <markj@FreeBSD.org>2015-04-08 02:36:37 +0000
commit67cf27b70f80c25edfc6f0c57be9b2dd413ea97c (patch)
tree48267c7be89f3f03d035711a7b82b3453bab848e
parent5f01ba81aefd6e2be3bd010d12a7c207a362bfb4 (diff)
Notes
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/drti.c5
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c16
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c75
-rw-r--r--cddl/lib/libdtrace/libproc_compat.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c46
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h5
-rw-r--r--sys/cddl/dev/dtrace/dtrace_ioctl.c7
7 files changed, 117 insertions, 39 deletions
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,10 +44,15 @@
#include <dt_program.h>
#include <dt_pid.h>
#include <dt_string.h>
+#include <dt_module.h>
+
#ifndef illumos
+#include <sys/sysctl.h>
+#include <unistd.h>
#include <libproc_compat.h>
+#include <libelf.h>
+#include <gelf.h>
#endif
-#include <dt_module.h>
typedef struct dt_pid_probe {
dtrace_hdl_t *dpp_dtp;
@@ -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;
}
- 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 @@ 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);