diff options
author | mws <none@none> | 2005-07-31 12:13:11 -0700 |
---|---|---|
committer | mws <none@none> | 2005-07-31 12:13:11 -0700 |
commit | 1a7c1b724419d3cb5fa6eea75123c6b2060ba31b (patch) | |
tree | 13e6c764697ec107ff0ef2977245f3c20f361006 /usr/src/lib/libdtrace/common/dt_provider.c | |
parent | 3fd6cc295d1c8c721b4b8abb49bbe0fefe51d034 (diff) | |
download | illumos-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.c | 106 |
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 */ } |