4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
30 #include <sys/types.h>
31 #include <sys/sysmacros.h>
41 #include <dt_provider.h>
42 #include <dt_module.h>
43 #include <dt_string.h>
48 static dt_provider_t
*
49 dt_provider_insert(dtrace_hdl_t
*dtp
, dt_provider_t
*pvp
, uint_t h
)
51 dt_list_append(&dtp
->dt_provlist
, pvp
);
53 pvp
->pv_next
= dtp
->dt_provs
[h
];
54 dtp
->dt_provs
[h
] = pvp
;
61 dt_provider_lookup(dtrace_hdl_t
*dtp
, const char *name
)
63 uint_t h
= dt_strtab_hash(name
, NULL
) % dtp
->dt_provbuckets
;
64 dtrace_providerdesc_t desc
;
67 for (pvp
= dtp
->dt_provs
[h
]; pvp
!= NULL
; pvp
= pvp
->pv_next
) {
68 if (strcmp(pvp
->pv_desc
.dtvd_name
, name
) == 0)
72 if (strisglob(name
) || name
[0] == '\0') {
73 (void) dt_set_errno(dtp
, EDT_NOPROV
);
77 bzero(&desc
, sizeof (desc
));
78 (void) strlcpy(desc
.dtvd_name
, name
, DTRACE_PROVNAMELEN
);
80 if (dt_ioctl(dtp
, DTRACEIOC_PROVIDER
, &desc
) == -1) {
81 (void) dt_set_errno(dtp
, errno
== ESRCH
? EDT_NOPROV
: errno
);
85 if ((pvp
= dt_provider_create(dtp
, name
)) == NULL
)
86 return (NULL
); /* dt_errno is set for us */
88 bcopy(&desc
, &pvp
->pv_desc
, sizeof (desc
));
89 pvp
->pv_flags
|= DT_PROVIDER_IMPL
;
94 dt_provider_create(dtrace_hdl_t
*dtp
, const char *name
)
98 if ((pvp
= dt_zalloc(dtp
, sizeof (dt_provider_t
))) == NULL
)
101 (void) strlcpy(pvp
->pv_desc
.dtvd_name
, name
, DTRACE_PROVNAMELEN
);
102 pvp
->pv_probes
= dt_idhash_create(pvp
->pv_desc
.dtvd_name
, NULL
, 0, 0);
103 pvp
->pv_gen
= dtp
->dt_gen
;
106 if (pvp
->pv_probes
== NULL
) {
108 (void) dt_set_errno(dtp
, EDT_NOMEM
);
112 pvp
->pv_desc
.dtvd_attr
.dtpa_provider
= _dtrace_prvattr
;
113 pvp
->pv_desc
.dtvd_attr
.dtpa_mod
= _dtrace_prvattr
;
114 pvp
->pv_desc
.dtvd_attr
.dtpa_func
= _dtrace_prvattr
;
115 pvp
->pv_desc
.dtvd_attr
.dtpa_name
= _dtrace_prvattr
;
116 pvp
->pv_desc
.dtvd_attr
.dtpa_args
= _dtrace_prvattr
;
118 return (dt_provider_insert(dtp
, pvp
,
119 dt_strtab_hash(name
, NULL
) % dtp
->dt_provbuckets
));
123 dt_provider_destroy(dtrace_hdl_t
*dtp
, dt_provider_t
*pvp
)
128 assert(pvp
->pv_hdl
== dtp
);
130 h
= dt_strtab_hash(pvp
->pv_desc
.dtvd_name
, NULL
) % dtp
->dt_provbuckets
;
131 pp
= &dtp
->dt_provs
[h
];
133 while (*pp
!= NULL
&& *pp
!= pvp
)
134 pp
= &(*pp
)->pv_next
;
136 assert(*pp
!= NULL
&& *pp
== pvp
);
139 dt_list_delete(&dtp
->dt_provlist
, pvp
);
142 if (pvp
->pv_probes
!= NULL
)
143 dt_idhash_destroy(pvp
->pv_probes
);
145 dt_node_link_free(&pvp
->pv_nodes
);
146 dt_free(dtp
, pvp
->pv_xrefs
);
151 dt_provider_xref(dtrace_hdl_t
*dtp
, dt_provider_t
*pvp
, id_t id
)
153 size_t oldsize
= BT_SIZEOFMAP(pvp
->pv_xrmax
);
154 size_t newsize
= BT_SIZEOFMAP(dtp
->dt_xlatorid
);
156 assert(id
>= 0 && id
< dtp
->dt_xlatorid
);
158 if (newsize
> oldsize
) {
159 ulong_t
*xrefs
= dt_zalloc(dtp
, newsize
);
164 bcopy(pvp
->pv_xrefs
, xrefs
, oldsize
);
165 dt_free(dtp
, pvp
->pv_xrefs
);
167 pvp
->pv_xrefs
= xrefs
;
168 pvp
->pv_xrmax
= dtp
->dt_xlatorid
;
171 BT_SET(pvp
->pv_xrefs
, id
);
176 dt_probe_argmap(dt_node_t
*xnp
, dt_node_t
*nnp
)
180 for (i
= 0; nnp
!= NULL
; i
++) {
181 if (nnp
->dn_string
!= NULL
&&
182 strcmp(nnp
->dn_string
, xnp
->dn_string
) == 0)
192 dt_probe_alloc_args(dt_provider_t
*pvp
, int argc
)
194 dt_node_t
*args
= NULL
, *pnp
= NULL
, *dnp
;
197 for (i
= 0; i
< argc
; i
++, pnp
= dnp
) {
198 if ((dnp
= dt_node_xalloc(pvp
->pv_hdl
, DT_NODE_TYPE
)) == NULL
)
201 dnp
->dn_link
= pvp
->pv_nodes
;
214 dt_probe_keylen(const dtrace_probedesc_t
*pdp
)
216 return (strlen(pdp
->dtpd_mod
) + 1 +
217 strlen(pdp
->dtpd_func
) + 1 + strlen(pdp
->dtpd_name
) + 1);
221 dt_probe_key(const dtrace_probedesc_t
*pdp
, char *s
)
223 (void) snprintf(s
, INT_MAX
, "%s:%s:%s",
224 pdp
->dtpd_mod
, pdp
->dtpd_func
, pdp
->dtpd_name
);
229 * If a probe was discovered from the kernel, ask dtrace(7D) for a description
230 * of each of its arguments, including native and translated types.
233 dt_probe_discover(dt_provider_t
*pvp
, const dtrace_probedesc_t
*pdp
)
235 dtrace_hdl_t
*dtp
= pvp
->pv_hdl
;
236 char *name
= dt_probe_key(pdp
, alloca(dt_probe_keylen(pdp
)));
238 dt_node_t
*xargs
, *nargs
;
242 dtrace_typeinfo_t dtt
;
245 int adc
= _dtrace_argmax
;
246 dtrace_argdesc_t
*adv
= alloca(sizeof (dtrace_argdesc_t
) * adc
);
247 dtrace_argdesc_t
*adp
= adv
;
249 assert(strcmp(pvp
->pv_desc
.dtvd_name
, pdp
->dtpd_provider
) == 0);
250 assert(pdp
->dtpd_id
!= DTRACE_IDNONE
);
252 dt_dprintf("discovering probe %s:%s id=%d\n",
253 pvp
->pv_desc
.dtvd_name
, name
, pdp
->dtpd_id
);
255 for (nc
= -1, i
= 0; i
< adc
; i
++, adp
++) {
256 bzero(adp
, sizeof (dtrace_argdesc_t
));
258 adp
->dtargd_id
= pdp
->dtpd_id
;
260 if (dt_ioctl(dtp
, DTRACEIOC_PROBEARG
, adp
) != 0) {
261 (void) dt_set_errno(dtp
, errno
);
265 if (adp
->dtargd_ndx
== DTRACE_ARGNONE
)
266 break; /* all argument descs have been retrieved */
268 nc
= MAX(nc
, adp
->dtargd_mapping
);
275 * The pid provider believes in giving the kernel a break. No reason to
276 * give the kernel all the ctf containers that we're keeping ourselves
277 * just to get it back from it. So if we're coming from a pid provider
278 * probe and the kernel gave us no argument information we'll get some
279 * here. If for some crazy reason the kernel knows about our userland
280 * types then we just ignore this.
282 if (xc
== 0 && nc
== 0 &&
283 strncmp(pvp
->pv_desc
.dtvd_name
, "pid", 3) == 0) {
285 dt_pid_get_types(dtp
, pdp
, adv
, &nc
);
290 * Now that we have discovered the number of native and translated
291 * arguments from the argument descriptions, allocate a new probe ident
292 * and corresponding dt_probe_t and hash it into the provider.
294 xargs
= dt_probe_alloc_args(pvp
, xc
);
295 nargs
= dt_probe_alloc_args(pvp
, nc
);
297 if ((xc
!= 0 && xargs
== NULL
) || (nc
!= 0 && nargs
== NULL
))
298 return (NULL
); /* dt_errno is set for us */
300 idp
= dt_ident_create(name
, DT_IDENT_PROBE
,
301 DT_IDFLG_ORPHAN
, pdp
->dtpd_id
, _dtrace_defattr
, 0,
302 &dt_idops_probe
, NULL
, dtp
->dt_gen
);
305 (void) dt_set_errno(dtp
, EDT_NOMEM
);
309 if ((prp
= dt_probe_create(dtp
, idp
, 2,
310 nargs
, nc
, xargs
, xc
)) == NULL
) {
311 dt_ident_destroy(idp
);
315 dt_probe_declare(pvp
, prp
);
318 * Once our new dt_probe_t is fully constructed, iterate over the
319 * cached argument descriptions and assign types to prp->pr_nargv[]
320 * and prp->pr_xargv[] and assign mappings to prp->pr_mapping[].
322 for (adp
= adv
, i
= 0; i
< xc
; i
++, adp
++) {
323 if (dtrace_type_strcompile(dtp
,
324 adp
->dtargd_native
, &dtt
) != 0) {
325 dt_dprintf("failed to resolve input type %s "
326 "for %s:%s arg #%d: %s\n", adp
->dtargd_native
,
327 pvp
->pv_desc
.dtvd_name
, name
, i
+ 1,
328 dtrace_errmsg(dtp
, dtrace_errno(dtp
)));
330 dtt
.dtt_object
= NULL
;
332 dtt
.dtt_type
= CTF_ERR
;
334 dt_node_type_assign(prp
->pr_nargv
[adp
->dtargd_mapping
],
335 dtt
.dtt_ctfp
, dtt
.dtt_type
,
336 dtt
.dtt_flags
& DTT_FL_USER
? B_TRUE
: B_FALSE
);
339 if (dtt
.dtt_type
!= CTF_ERR
&& (adp
->dtargd_xlate
[0] == '\0' ||
340 strcmp(adp
->dtargd_native
, adp
->dtargd_xlate
) == 0)) {
341 dt_node_type_propagate(prp
->pr_nargv
[
342 adp
->dtargd_mapping
], prp
->pr_xargv
[i
]);
343 } else if (dtrace_type_strcompile(dtp
,
344 adp
->dtargd_xlate
, &dtt
) != 0) {
345 dt_dprintf("failed to resolve output type %s "
346 "for %s:%s arg #%d: %s\n", adp
->dtargd_xlate
,
347 pvp
->pv_desc
.dtvd_name
, name
, i
+ 1,
348 dtrace_errmsg(dtp
, dtrace_errno(dtp
)));
350 dtt
.dtt_object
= NULL
;
352 dtt
.dtt_type
= CTF_ERR
;
354 dt_node_type_assign(prp
->pr_xargv
[i
],
355 dtt
.dtt_ctfp
, dtt
.dtt_type
, B_FALSE
);
358 prp
->pr_mapping
[i
] = adp
->dtargd_mapping
;
359 prp
->pr_argv
[i
] = dtt
;
366 * Lookup a probe declaration based on a known provider and full or partially
367 * specified module, function, and name. If the probe is not known to us yet,
368 * ask dtrace(7D) to match the description and then cache any useful results.
371 dt_probe_lookup(dt_provider_t
*pvp
, const char *s
)
373 dtrace_hdl_t
*dtp
= pvp
->pv_hdl
;
374 dtrace_probedesc_t pd
;
379 if (dtrace_str2desc(dtp
, DTRACE_PROBESPEC_NAME
, s
, &pd
) != 0)
380 return (NULL
); /* dt_errno is set for us */
382 keylen
= dt_probe_keylen(&pd
);
383 key
= dt_probe_key(&pd
, alloca(keylen
));
386 * If the probe is already declared, then return the dt_probe_t from
387 * the existing identifier. This could come from a static declaration
388 * or it could have been cached from an earlier call to this function.
390 if ((idp
= dt_idhash_lookup(pvp
->pv_probes
, key
)) != NULL
)
391 return (idp
->di_data
);
394 * If the probe isn't known, use the probe description computed above
395 * to ask dtrace(7D) to find the first matching probe.
397 if (dt_ioctl(dtp
, DTRACEIOC_PROBEMATCH
, &pd
) == 0)
398 return (dt_probe_discover(pvp
, &pd
));
400 if (errno
== ESRCH
|| errno
== EBADF
)
401 (void) dt_set_errno(dtp
, EDT_NOPROBE
);
403 (void) dt_set_errno(dtp
, errno
);
409 dt_probe_create(dtrace_hdl_t
*dtp
, dt_ident_t
*idp
, int protoc
,
410 dt_node_t
*nargs
, uint_t nargc
, dt_node_t
*xargs
, uint_t xargc
)
417 assert(idp
->di_kind
== DT_IDENT_PROBE
);
418 assert(idp
->di_data
== NULL
);
421 * If only a single prototype is given, set xargc/s to nargc/s to
422 * simplify subsequent use. Note that we can have one or both of nargs
423 * and xargs be specified but set to NULL, indicating a void prototype.
426 assert(xargs
== NULL
);
432 if ((prp
= dt_alloc(dtp
, sizeof (dt_probe_t
))) == NULL
)
438 p
= strrchr(idp
->di_name
, ':');
440 prp
->pr_name
= p
+ 1;
442 prp
->pr_nargs
= nargs
;
443 prp
->pr_nargv
= dt_alloc(dtp
, sizeof (dt_node_t
*) * nargc
);
444 prp
->pr_nargc
= nargc
;
445 prp
->pr_xargs
= xargs
;
446 prp
->pr_xargv
= dt_alloc(dtp
, sizeof (dt_node_t
*) * xargc
);
447 prp
->pr_xargc
= xargc
;
448 prp
->pr_mapping
= dt_alloc(dtp
, sizeof (uint8_t) * xargc
);
450 prp
->pr_argv
= dt_alloc(dtp
, sizeof (dtrace_typeinfo_t
) * xargc
);
451 prp
->pr_argc
= xargc
;
453 if ((prp
->pr_nargc
!= 0 && prp
->pr_nargv
== NULL
) ||
454 (prp
->pr_xargc
!= 0 && prp
->pr_xargv
== NULL
) ||
455 (prp
->pr_xargc
!= 0 && prp
->pr_mapping
== NULL
) ||
456 (prp
->pr_argc
!= 0 && prp
->pr_argv
== NULL
)) {
457 dt_probe_destroy(prp
);
461 for (i
= 0; i
< xargc
; i
++, xargs
= xargs
->dn_list
) {
462 if (xargs
->dn_string
!= NULL
)
463 prp
->pr_mapping
[i
] = dt_probe_argmap(xargs
, nargs
);
465 prp
->pr_mapping
[i
] = i
;
467 prp
->pr_xargv
[i
] = xargs
;
469 if ((dmp
= dt_module_lookup_by_ctf(dtp
,
470 xargs
->dn_ctfp
)) != NULL
)
471 prp
->pr_argv
[i
].dtt_object
= dmp
->dm_name
;
473 prp
->pr_argv
[i
].dtt_object
= NULL
;
475 prp
->pr_argv
[i
].dtt_ctfp
= xargs
->dn_ctfp
;
476 prp
->pr_argv
[i
].dtt_type
= xargs
->dn_type
;
479 for (i
= 0; i
< nargc
; i
++, nargs
= nargs
->dn_list
)
480 prp
->pr_nargv
[i
] = nargs
;
487 dt_probe_declare(dt_provider_t
*pvp
, dt_probe_t
*prp
)
489 assert(prp
->pr_ident
->di_kind
== DT_IDENT_PROBE
);
490 assert(prp
->pr_ident
->di_data
== prp
);
491 assert(prp
->pr_pvp
== NULL
);
493 if (prp
->pr_xargs
!= prp
->pr_nargs
)
494 pvp
->pv_flags
&= ~DT_PROVIDER_INTF
;
497 dt_idhash_xinsert(pvp
->pv_probes
, prp
->pr_ident
);
501 dt_probe_destroy(dt_probe_t
*prp
)
503 dt_probe_instance_t
*pip
, *pip_next
;
506 if (prp
->pr_pvp
!= NULL
)
507 dtp
= prp
->pr_pvp
->pv_hdl
;
509 dtp
= yypcb
->pcb_hdl
;
511 dt_node_list_free(&prp
->pr_nargs
);
512 dt_node_list_free(&prp
->pr_xargs
);
514 dt_free(dtp
, prp
->pr_nargv
);
515 dt_free(dtp
, prp
->pr_xargv
);
517 for (pip
= prp
->pr_inst
; pip
!= NULL
; pip
= pip_next
) {
518 pip_next
= pip
->pi_next
;
519 dt_free(dtp
, pip
->pi_offs
);
520 dt_free(dtp
, pip
->pi_enoffs
);
524 dt_free(dtp
, prp
->pr_mapping
);
525 dt_free(dtp
, prp
->pr_argv
);
530 dt_probe_define(dt_provider_t
*pvp
, dt_probe_t
*prp
,
531 const char *fname
, const char *rname
, uint32_t offset
, int isenabled
)
533 dtrace_hdl_t
*dtp
= pvp
->pv_hdl
;
534 dt_probe_instance_t
*pip
;
536 uint_t
*noffs
, *maxoffs
;
538 assert(fname
!= NULL
);
540 for (pip
= prp
->pr_inst
; pip
!= NULL
; pip
= pip
->pi_next
) {
541 if (strcmp(pip
->pi_fname
, fname
) == 0 &&
542 ((rname
== NULL
&& pip
->pi_rname
[0] == '\0') ||
543 (rname
!= NULL
&& strcmp(pip
->pi_rname
, rname
)) == 0))
548 if ((pip
= dt_zalloc(dtp
, sizeof (*pip
))) == NULL
)
551 if ((pip
->pi_offs
= dt_zalloc(dtp
,
552 sizeof (uint32_t))) == NULL
) {
557 if ((pip
->pi_enoffs
= dt_zalloc(dtp
,
558 sizeof (uint32_t))) == NULL
) {
559 dt_free(dtp
, pip
->pi_offs
);
564 (void) strlcpy(pip
->pi_fname
, fname
, sizeof (pip
->pi_fname
));
566 if (strlen(rname
) + 1 > sizeof (pip
->pi_rname
)) {
567 dt_free(dtp
, pip
->pi_offs
);
569 return (dt_set_errno(dtp
, EDT_COMPILER
));
571 (void) strcpy(pip
->pi_rname
, rname
);
577 pip
->pi_maxenoffs
= 1;
579 pip
->pi_next
= prp
->pr_inst
;
585 offs
= &pip
->pi_enoffs
;
586 noffs
= &pip
->pi_nenoffs
;
587 maxoffs
= &pip
->pi_maxenoffs
;
589 offs
= &pip
->pi_offs
;
590 noffs
= &pip
->pi_noffs
;
591 maxoffs
= &pip
->pi_maxoffs
;
594 if (*noffs
== *maxoffs
) {
595 uint_t new_max
= *maxoffs
* 2;
596 uint32_t *new_offs
= dt_alloc(dtp
, sizeof (uint32_t) * new_max
);
598 if (new_offs
== NULL
)
601 bcopy(*offs
, new_offs
, sizeof (uint32_t) * *maxoffs
);
608 dt_dprintf("defined probe %s %s:%s %s() +0x%x (%s)\n",
609 isenabled
? "(is-enabled)" : "",
610 pvp
->pv_desc
.dtvd_name
, prp
->pr_ident
->di_name
, fname
, offset
,
611 rname
!= NULL
? rname
: fname
);
613 assert(*noffs
< *maxoffs
);
614 (*offs
)[(*noffs
)++] = offset
;
620 * Lookup the dynamic translator type tag for the specified probe argument and
621 * assign the type to the specified node. If the type is not yet defined, add
622 * it to the "D" module's type container as a typedef for an unknown type.
625 dt_probe_tag(dt_probe_t
*prp
, uint_t argn
, dt_node_t
*dnp
)
627 dtrace_hdl_t
*dtp
= prp
->pr_pvp
->pv_hdl
;
628 dtrace_typeinfo_t dtt
;
632 len
= snprintf(NULL
, 0, "__dtrace_%s___%s_arg%u",
633 prp
->pr_pvp
->pv_desc
.dtvd_name
, prp
->pr_name
, argn
);
635 tag
= alloca(len
+ 1);
637 (void) snprintf(tag
, len
+ 1, "__dtrace_%s___%s_arg%u",
638 prp
->pr_pvp
->pv_desc
.dtvd_name
, prp
->pr_name
, argn
);
640 if (dtrace_lookup_by_type(dtp
, DTRACE_OBJ_DDEFS
, tag
, &dtt
) != 0) {
641 dtt
.dtt_object
= DTRACE_OBJ_DDEFS
;
642 dtt
.dtt_ctfp
= DT_DYN_CTFP(dtp
);
643 dtt
.dtt_type
= ctf_add_typedef(DT_DYN_CTFP(dtp
),
644 CTF_ADD_ROOT
, tag
, DT_DYN_TYPE(dtp
));
646 if (dtt
.dtt_type
== CTF_ERR
||
647 ctf_update(dtt
.dtt_ctfp
) == CTF_ERR
) {
648 xyerror(D_UNKNOWN
, "cannot define type %s: %s\n",
649 tag
, ctf_errmsg(ctf_errno(dtt
.dtt_ctfp
)));
653 bzero(dnp
, sizeof (dt_node_t
));
654 dnp
->dn_kind
= DT_NODE_TYPE
;
656 dt_node_type_assign(dnp
, dtt
.dtt_ctfp
, dtt
.dtt_type
, B_FALSE
);
657 dt_node_attr_assign(dnp
, _dtrace_defattr
);
664 dt_probe_desc(dtrace_hdl_t
*dtp
, const dtrace_probedesc_t
*pdp
, void *arg
)
666 if (((dtrace_probedesc_t
*)arg
)->dtpd_id
== DTRACE_IDNONE
) {
667 bcopy(pdp
, arg
, sizeof (dtrace_probedesc_t
));
675 dt_probe_info(dtrace_hdl_t
*dtp
,
676 const dtrace_probedesc_t
*pdp
, dtrace_probeinfo_t
*pip
)
678 int m_is_glob
= pdp
->dtpd_mod
[0] == '\0' || strisglob(pdp
->dtpd_mod
);
679 int f_is_glob
= pdp
->dtpd_func
[0] == '\0' || strisglob(pdp
->dtpd_func
);
680 int n_is_glob
= pdp
->dtpd_name
[0] == '\0' || strisglob(pdp
->dtpd_name
);
682 dt_probe_t
*prp
= NULL
;
683 const dtrace_pattr_t
*pap
;
688 * Attempt to lookup the probe in our existing cache for this provider.
689 * If none is found and an explicit probe ID was specified, discover
690 * that specific probe and cache its description and arguments.
692 if ((pvp
= dt_provider_lookup(dtp
, pdp
->dtpd_provider
)) != NULL
) {
693 size_t keylen
= dt_probe_keylen(pdp
);
694 char *key
= dt_probe_key(pdp
, alloca(keylen
));
696 if ((idp
= dt_idhash_lookup(pvp
->pv_probes
, key
)) != NULL
)
698 else if (pdp
->dtpd_id
!= DTRACE_IDNONE
)
699 prp
= dt_probe_discover(pvp
, pdp
);
703 * If no probe was found in our cache, convert the caller's partial
704 * probe description into a fully-formed matching probe description by
705 * iterating over up to at most two probes that match 'pdp'. We then
706 * call dt_probe_discover() on the resulting probe identifier.
709 dtrace_probedesc_t pd
;
712 bzero(&pd
, sizeof (pd
));
713 pd
.dtpd_id
= DTRACE_IDNONE
;
716 * Call dtrace_probe_iter() to find matching probes. Our
717 * dt_probe_desc() callback will produce the following results:
719 * m < 0 dtrace_probe_iter() found zero matches (or failed).
720 * m > 0 dtrace_probe_iter() found more than one match.
721 * m = 0 dtrace_probe_iter() found exactly one match.
723 if ((m
= dtrace_probe_iter(dtp
, pdp
, dt_probe_desc
, &pd
)) < 0)
724 return (NULL
); /* dt_errno is set for us */
726 if ((pvp
= dt_provider_lookup(dtp
, pd
.dtpd_provider
)) == NULL
)
727 return (NULL
); /* dt_errno is set for us */
730 * If more than one probe was matched, then do not report probe
731 * information if either of the following conditions is true:
733 * (a) The Arguments Data stability of the matched provider is
734 * less than Evolving.
736 * (b) Any description component that is at least Evolving is
737 * empty or is specified using a globbing expression.
739 * These conditions imply that providers that provide Evolving
740 * or better Arguments Data stability must guarantee that all
741 * probes with identical field names in a field of Evolving or
742 * better Name stability have identical argument signatures.
745 if (pvp
->pv_desc
.dtvd_attr
.dtpa_args
.dtat_data
<
746 DTRACE_STABILITY_EVOLVING
) {
747 (void) dt_set_errno(dtp
, EDT_UNSTABLE
);
752 if (pvp
->pv_desc
.dtvd_attr
.dtpa_mod
.dtat_name
>=
753 DTRACE_STABILITY_EVOLVING
&& m_is_glob
) {
754 (void) dt_set_errno(dtp
, EDT_UNSTABLE
);
758 if (pvp
->pv_desc
.dtvd_attr
.dtpa_func
.dtat_name
>=
759 DTRACE_STABILITY_EVOLVING
&& f_is_glob
) {
760 (void) dt_set_errno(dtp
, EDT_UNSTABLE
);
764 if (pvp
->pv_desc
.dtvd_attr
.dtpa_name
.dtat_name
>=
765 DTRACE_STABILITY_EVOLVING
&& n_is_glob
) {
766 (void) dt_set_errno(dtp
, EDT_UNSTABLE
);
772 * If we matched a probe exported by dtrace(7D), then discover
773 * the real attributes. Otherwise grab the static declaration.
775 if (pd
.dtpd_id
!= DTRACE_IDNONE
)
776 prp
= dt_probe_discover(pvp
, &pd
);
778 prp
= dt_probe_lookup(pvp
, pd
.dtpd_name
);
781 return (NULL
); /* dt_errno is set for us */
784 assert(pvp
!= NULL
&& prp
!= NULL
);
787 * Compute the probe description attributes by taking the minimum of
788 * the attributes of the specified fields. If no provider is specified
789 * or a glob pattern is used for the provider, use Unstable attributes.
791 if (pdp
->dtpd_provider
[0] == '\0' || strisglob(pdp
->dtpd_provider
))
792 pap
= &_dtrace_prvdesc
;
794 pap
= &pvp
->pv_desc
.dtvd_attr
;
796 pip
->dtp_attr
= pap
->dtpa_provider
;
799 pip
->dtp_attr
= dt_attr_min(pip
->dtp_attr
, pap
->dtpa_mod
);
801 pip
->dtp_attr
= dt_attr_min(pip
->dtp_attr
, pap
->dtpa_func
);
803 pip
->dtp_attr
= dt_attr_min(pip
->dtp_attr
, pap
->dtpa_name
);
805 pip
->dtp_arga
= pap
->dtpa_args
;
806 pip
->dtp_argv
= prp
->pr_argv
;
807 pip
->dtp_argc
= prp
->pr_argc
;
813 dtrace_probe_info(dtrace_hdl_t
*dtp
,
814 const dtrace_probedesc_t
*pdp
, dtrace_probeinfo_t
*pip
)
816 return (dt_probe_info(dtp
, pdp
, pip
) != NULL
? 0 : -1);
821 dt_probe_iter(dt_idhash_t
*ihp
, dt_ident_t
*idp
, dt_probe_iter_t
*pit
)
823 const dt_probe_t
*prp
= idp
->di_data
;
825 if (!dt_gmatch(prp
->pr_name
, pit
->pit_pat
))
826 return (0); /* continue on and examine next probe in hash */
828 (void) strlcpy(pit
->pit_desc
.dtpd_name
, prp
->pr_name
, DTRACE_NAMELEN
);
829 pit
->pit_desc
.dtpd_id
= idp
->di_id
;
832 return (pit
->pit_func(pit
->pit_hdl
, &pit
->pit_desc
, pit
->pit_arg
));
836 dtrace_probe_iter(dtrace_hdl_t
*dtp
,
837 const dtrace_probedesc_t
*pdp
, dtrace_probe_f
*func
, void *arg
)
839 const char *provider
= pdp
? pdp
->dtpd_provider
: NULL
;
840 dtrace_id_t id
= DTRACE_IDNONE
;
842 dtrace_probedesc_t pd
;
846 bzero(&pit
, sizeof (pit
));
850 pit
.pit_pat
= pdp
? pdp
->dtpd_name
: NULL
;
852 for (pit
.pit_pvp
= dt_list_next(&dtp
->dt_provlist
);
853 pit
.pit_pvp
!= NULL
; pit
.pit_pvp
= dt_list_next(pit
.pit_pvp
)) {
855 if (pit
.pit_pvp
->pv_flags
& DT_PROVIDER_IMPL
)
856 continue; /* we'll get these later using dt_ioctl() */
858 if (!dt_gmatch(pit
.pit_pvp
->pv_desc
.dtvd_name
, provider
))
861 (void) strlcpy(pit
.pit_desc
.dtpd_provider
,
862 pit
.pit_pvp
->pv_desc
.dtvd_name
, DTRACE_PROVNAMELEN
);
864 if ((rv
= dt_idhash_iter(pit
.pit_pvp
->pv_probes
,
865 (dt_idhash_f
*)dt_probe_iter
, &pit
)) != 0)
870 cmd
= DTRACEIOC_PROBEMATCH
;
872 cmd
= DTRACEIOC_PROBES
;
876 bcopy(pdp
, &pd
, sizeof (pd
));
880 if (dt_ioctl(dtp
, cmd
, &pd
) != 0)
882 else if ((rv
= func(dtp
, &pd
, arg
)) != 0)
892 return (pit
.pit_matches
? 0 : dt_set_errno(dtp
, EDT_NOPROBE
));
894 return (dt_set_errno(dtp
, EDT_BADPGLOB
));
896 return (dt_set_errno(dtp
, errno
));