summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdtrace/common/dt_provider.c
diff options
context:
space:
mode:
authormws <none@none>2005-07-31 12:13:11 -0700
committermws <none@none>2005-07-31 12:13:11 -0700
commit1a7c1b724419d3cb5fa6eea75123c6b2060ba31b (patch)
tree13e6c764697ec107ff0ef2977245f3c20f361006 /usr/src/lib/libdtrace/common/dt_provider.c
parent3fd6cc295d1c8c721b4b8abb49bbe0fefe51d034 (diff)
downloadillumos-joyent-1a7c1b724419d3cb5fa6eea75123c6b2060ba31b.tar.gz
6275414 unary operator * doesn't work properly when applied to args[] elements
6282291 D compiler core dumps in dt_node_dynamic() for inline parameter 6295808 dtrace could warn about /* w/i a comment 6301080 dtrace debugging support should be easier to maintain 6301082 mdb should provide raw target support for DOF 6301083 dt_probe_discover() fails assertion when matching unpublished provider 6301084 Pscantext() leaks prmap_t buffer every time it is called 6301086 dtrace(1M) should always dtrace_close() before returning 6301087 dtrace_close() deadlock in dt_proc_destroy() when processes are idle 6301088 dtrace_program_link() leaks ELF handles for object files 6301091 D compiler support for USDT translators (part 2)
Diffstat (limited to 'usr/src/lib/libdtrace/common/dt_provider.c')
-rw-r--r--usr/src/lib/libdtrace/common/dt_provider.c106
1 files changed, 98 insertions, 8 deletions
diff --git a/usr/src/lib/libdtrace/common/dt_provider.c b/usr/src/lib/libdtrace/common/dt_provider.c
index f55e91e932..50917074c7 100644
--- a/usr/src/lib/libdtrace/common/dt_provider.c
+++ b/usr/src/lib/libdtrace/common/dt_provider.c
@@ -58,6 +58,7 @@ dt_provider_t *
dt_provider_lookup(dtrace_hdl_t *dtp, const char *name)
{
uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_provbuckets;
+ dtrace_providerdesc_t desc;
dt_provider_t *pvp;
for (pvp = dtp->dt_provs[h]; pvp != NULL; pvp = pvp->pv_next) {
@@ -70,15 +71,18 @@ dt_provider_lookup(dtrace_hdl_t *dtp, const char *name)
return (NULL);
}
- if ((pvp = dt_provider_create(dtp, name)) == NULL)
- return (NULL); /* dt_errno is set for us */
+ bzero(&desc, sizeof (desc));
+ (void) strlcpy(desc.dtvd_name, name, DTRACE_PROVNAMELEN);
- if (dt_ioctl(dtp, DTRACEIOC_PROVIDER, &pvp->pv_desc) == -1) {
+ if (dt_ioctl(dtp, DTRACEIOC_PROVIDER, &desc) == -1) {
(void) dt_set_errno(dtp, errno == ESRCH ? EDT_NOPROV : errno);
- dt_provider_destroy(dtp, pvp);
return (NULL);
}
+ if ((pvp = dt_provider_create(dtp, name)) == NULL)
+ return (NULL); /* dt_errno is set for us */
+
+ bcopy(&desc, &pvp->pv_desc, sizeof (desc));
pvp->pv_flags |= DT_PROVIDER_IMPL;
return (pvp);
}
@@ -136,9 +140,35 @@ dt_provider_destroy(dtrace_hdl_t *dtp, dt_provider_t *pvp)
dt_idhash_destroy(pvp->pv_probes);
dt_node_link_free(&pvp->pv_nodes);
+ dt_free(dtp, pvp->pv_xrefs);
dt_free(dtp, pvp);
}
+int
+dt_provider_xref(dtrace_hdl_t *dtp, dt_provider_t *pvp, id_t id)
+{
+ size_t oldsize = BT_SIZEOFMAP(pvp->pv_xrmax);
+ size_t newsize = BT_SIZEOFMAP(dtp->dt_xlatorid);
+
+ assert(id >= 0 && id < dtp->dt_xlatorid);
+
+ if (newsize > oldsize) {
+ ulong_t *xrefs = dt_zalloc(dtp, newsize);
+
+ if (xrefs == NULL)
+ return (-1);
+
+ bcopy(pvp->pv_xrefs, xrefs, oldsize);
+ dt_free(dtp, pvp->pv_xrefs);
+
+ pvp->pv_xrefs = xrefs;
+ pvp->pv_xrmax = dtp->dt_xlatorid;
+ }
+
+ BT_SET(pvp->pv_xrefs, id);
+ return (0);
+}
+
static uint8_t
dt_probe_argmap(dt_node_t *xnp, dt_node_t *nnp)
{
@@ -258,7 +288,8 @@ dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp)
return (NULL);
}
- if ((prp = dt_probe_create(dtp, idp, nargs, nc, xargs, xc)) == NULL) {
+ if ((prp = dt_probe_create(dtp, idp, 2,
+ nargs, nc, xargs, xc)) == NULL) {
dt_ident_destroy(idp);
return (NULL);
}
@@ -356,7 +387,7 @@ dt_probe_lookup(dt_provider_t *pvp, const char *s)
}
dt_probe_t *
-dt_probe_create(dtrace_hdl_t *dtp, dt_ident_t *idp,
+dt_probe_create(dtrace_hdl_t *dtp, dt_ident_t *idp, int protoc,
dt_node_t *nargs, uint_t nargc, dt_node_t *xargs, uint_t xargc)
{
dt_module_t *dmp;
@@ -367,7 +398,14 @@ dt_probe_create(dtrace_hdl_t *dtp, dt_ident_t *idp,
assert(idp->di_kind == DT_IDENT_PROBE);
assert(idp->di_data == NULL);
- if (xargs == NULL) {
+ /*
+ * If only a single prototype is given, set xargc/s to nargc/s to
+ * simplify subsequent use. Note that we can have one or both of nargs
+ * and xargs be specified but set to NULL, indicating a void prototype.
+ */
+ if (protoc < 2) {
+ assert(xargs == NULL);
+ assert(xargc == 0);
xargs = nargs;
xargc = nargc;
}
@@ -519,6 +557,49 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
return (0);
}
+/*
+ * Lookup the dynamic translator type tag for the specified probe argument and
+ * assign the type to the specified node. If the type is not yet defined, add
+ * it to the "D" module's type container as a typedef for an unknown type.
+ */
+dt_node_t *
+dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp)
+{
+ dtrace_hdl_t *dtp = prp->pr_pvp->pv_hdl;
+ dtrace_typeinfo_t dtt;
+ size_t len;
+ char *tag;
+
+ len = snprintf(NULL, 0, "__dtrace_%s___%s_arg%u",
+ prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn);
+
+ tag = alloca(len + 1);
+
+ (void) snprintf(tag, len + 1, "__dtrace_%s___%s_arg%u",
+ prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn);
+
+ if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_DDEFS, tag, &dtt) != 0) {
+ dtt.dtt_object = DTRACE_OBJ_DDEFS;
+ dtt.dtt_ctfp = DT_DYN_CTFP(dtp);
+ dtt.dtt_type = ctf_add_typedef(DT_DYN_CTFP(dtp),
+ CTF_ADD_ROOT, tag, DT_DYN_TYPE(dtp));
+
+ if (dtt.dtt_type == CTF_ERR ||
+ ctf_update(dtt.dtt_ctfp) == CTF_ERR) {
+ xyerror(D_UNKNOWN, "cannot define type %s: %s\n",
+ tag, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
+ }
+ }
+
+ bzero(dnp, sizeof (dt_node_t));
+ dnp->dn_kind = DT_NODE_TYPE;
+
+ dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+ dt_node_attr_assign(dnp, _dtrace_defattr);
+
+ return (dnp);
+}
+
/*ARGSUSED*/
static int
dt_probe_desc(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *arg)
@@ -628,7 +709,16 @@ dt_probe_info(dtrace_hdl_t *dtp,
}
}
- if ((prp = dt_probe_discover(pvp, &pd)) == NULL)
+ /*
+ * If we matched a probe exported by dtrace(7D), then discover
+ * the real attributes. Otherwise grab the static declaration.
+ */
+ if (pd.dtpd_id != DTRACE_IDNONE)
+ prp = dt_probe_discover(pvp, &pd);
+ else
+ prp = dt_probe_lookup(pvp, pd.dtpd_name);
+
+ if (prp == NULL)
return (NULL); /* dt_errno is set for us */
}