6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/types.h>
30 #include <sys/sysmacros.h>
31
32 #include <assert.h>
33 #include <limits.h>
34 #include <strings.h>
35 #include <stdlib.h>
36 #include <alloca.h>
37 #include <unistd.h>
38 #include <errno.h>
39
40 #include <dt_provider.h>
41 #include <dt_module.h>
42 #include <dt_string.h>
43 #include <dt_list.h>
44
45 static dt_provider_t *
46 dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h)
47 {
48 dt_list_append(&dtp->dt_provlist, pvp);
49
50 pvp->pv_next = dtp->dt_provs[h];
51 dtp->dt_provs[h] = pvp;
52 dtp->dt_nprovs++;
53
54 return (pvp);
55 }
56
57 dt_provider_t *
58 dt_provider_lookup(dtrace_hdl_t *dtp, const char *name)
59 {
60 uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_provbuckets;
61 dtrace_providerdesc_t desc;
62 dt_provider_t *pvp;
63
252 for (nc = -1, i = 0; i < adc; i++, adp++) {
253 bzero(adp, sizeof (dtrace_argdesc_t));
254 adp->dtargd_ndx = i;
255 adp->dtargd_id = pdp->dtpd_id;
256
257 if (dt_ioctl(dtp, DTRACEIOC_PROBEARG, adp) != 0) {
258 (void) dt_set_errno(dtp, errno);
259 return (NULL);
260 }
261
262 if (adp->dtargd_ndx == DTRACE_ARGNONE)
263 break; /* all argument descs have been retrieved */
264
265 nc = MAX(nc, adp->dtargd_mapping);
266 }
267
268 xc = i;
269 nc++;
270
271 /*
272 * Now that we have discovered the number of native and translated
273 * arguments from the argument descriptions, allocate a new probe ident
274 * and corresponding dt_probe_t and hash it into the provider.
275 */
276 xargs = dt_probe_alloc_args(pvp, xc);
277 nargs = dt_probe_alloc_args(pvp, nc);
278
279 if ((xc != 0 && xargs == NULL) || (nc != 0 && nargs == NULL))
280 return (NULL); /* dt_errno is set for us */
281
282 idp = dt_ident_create(name, DT_IDENT_PROBE,
283 DT_IDFLG_ORPHAN, pdp->dtpd_id, _dtrace_defattr, 0,
284 &dt_idops_probe, NULL, dtp->dt_gen);
285
286 if (idp == NULL) {
287 (void) dt_set_errno(dtp, EDT_NOMEM);
288 return (NULL);
289 }
290
291 if ((prp = dt_probe_create(dtp, idp, 2,
297 dt_probe_declare(pvp, prp);
298
299 /*
300 * Once our new dt_probe_t is fully constructed, iterate over the
301 * cached argument descriptions and assign types to prp->pr_nargv[]
302 * and prp->pr_xargv[] and assign mappings to prp->pr_mapping[].
303 */
304 for (adp = adv, i = 0; i < xc; i++, adp++) {
305 if (dtrace_type_strcompile(dtp,
306 adp->dtargd_native, &dtt) != 0) {
307 dt_dprintf("failed to resolve input type %s "
308 "for %s:%s arg #%d: %s\n", adp->dtargd_native,
309 pvp->pv_desc.dtvd_name, name, i + 1,
310 dtrace_errmsg(dtp, dtrace_errno(dtp)));
311
312 dtt.dtt_object = NULL;
313 dtt.dtt_ctfp = NULL;
314 dtt.dtt_type = CTF_ERR;
315 } else {
316 dt_node_type_assign(prp->pr_nargv[adp->dtargd_mapping],
317 dtt.dtt_ctfp, dtt.dtt_type);
318 }
319
320 if (dtt.dtt_type != CTF_ERR && (adp->dtargd_xlate[0] == '\0' ||
321 strcmp(adp->dtargd_native, adp->dtargd_xlate) == 0)) {
322 dt_node_type_propagate(prp->pr_nargv[
323 adp->dtargd_mapping], prp->pr_xargv[i]);
324 } else if (dtrace_type_strcompile(dtp,
325 adp->dtargd_xlate, &dtt) != 0) {
326 dt_dprintf("failed to resolve output type %s "
327 "for %s:%s arg #%d: %s\n", adp->dtargd_xlate,
328 pvp->pv_desc.dtvd_name, name, i + 1,
329 dtrace_errmsg(dtp, dtrace_errno(dtp)));
330
331 dtt.dtt_object = NULL;
332 dtt.dtt_ctfp = NULL;
333 dtt.dtt_type = CTF_ERR;
334 } else {
335 dt_node_type_assign(prp->pr_xargv[i],
336 dtt.dtt_ctfp, dtt.dtt_type);
337 }
338
339 prp->pr_mapping[i] = adp->dtargd_mapping;
340 prp->pr_argv[i] = dtt;
341 }
342
343 return (prp);
344 }
345
346 /*
347 * Lookup a probe declaration based on a known provider and full or partially
348 * specified module, function, and name. If the probe is not known to us yet,
349 * ask dtrace(7D) to match the description and then cache any useful results.
350 */
351 dt_probe_t *
352 dt_probe_lookup(dt_provider_t *pvp, const char *s)
353 {
354 dtrace_hdl_t *dtp = pvp->pv_hdl;
355 dtrace_probedesc_t pd;
356 dt_ident_t *idp;
617
618 (void) snprintf(tag, len + 1, "__dtrace_%s___%s_arg%u",
619 prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn);
620
621 if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_DDEFS, tag, &dtt) != 0) {
622 dtt.dtt_object = DTRACE_OBJ_DDEFS;
623 dtt.dtt_ctfp = DT_DYN_CTFP(dtp);
624 dtt.dtt_type = ctf_add_typedef(DT_DYN_CTFP(dtp),
625 CTF_ADD_ROOT, tag, DT_DYN_TYPE(dtp));
626
627 if (dtt.dtt_type == CTF_ERR ||
628 ctf_update(dtt.dtt_ctfp) == CTF_ERR) {
629 xyerror(D_UNKNOWN, "cannot define type %s: %s\n",
630 tag, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
631 }
632 }
633
634 bzero(dnp, sizeof (dt_node_t));
635 dnp->dn_kind = DT_NODE_TYPE;
636
637 dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
638 dt_node_attr_assign(dnp, _dtrace_defattr);
639
640 return (dnp);
641 }
642
643 /*ARGSUSED*/
644 static int
645 dt_probe_desc(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *arg)
646 {
647 if (((dtrace_probedesc_t *)arg)->dtpd_id == DTRACE_IDNONE) {
648 bcopy(pdp, arg, sizeof (dtrace_probedesc_t));
649 return (0);
650 }
651
652 return (1);
653 }
654
655 dt_probe_t *
656 dt_probe_info(dtrace_hdl_t *dtp,
657 const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip)
|
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 */
29
30 #include <sys/types.h>
31 #include <sys/sysmacros.h>
32
33 #include <assert.h>
34 #include <limits.h>
35 #include <strings.h>
36 #include <stdlib.h>
37 #include <alloca.h>
38 #include <unistd.h>
39 #include <errno.h>
40
41 #include <dt_provider.h>
42 #include <dt_module.h>
43 #include <dt_string.h>
44 #include <dt_list.h>
45 #include <dt_pid.h>
46 #include <dtrace.h>
47
48 static dt_provider_t *
49 dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h)
50 {
51 dt_list_append(&dtp->dt_provlist, pvp);
52
53 pvp->pv_next = dtp->dt_provs[h];
54 dtp->dt_provs[h] = pvp;
55 dtp->dt_nprovs++;
56
57 return (pvp);
58 }
59
60 dt_provider_t *
61 dt_provider_lookup(dtrace_hdl_t *dtp, const char *name)
62 {
63 uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_provbuckets;
64 dtrace_providerdesc_t desc;
65 dt_provider_t *pvp;
66
255 for (nc = -1, i = 0; i < adc; i++, adp++) {
256 bzero(adp, sizeof (dtrace_argdesc_t));
257 adp->dtargd_ndx = i;
258 adp->dtargd_id = pdp->dtpd_id;
259
260 if (dt_ioctl(dtp, DTRACEIOC_PROBEARG, adp) != 0) {
261 (void) dt_set_errno(dtp, errno);
262 return (NULL);
263 }
264
265 if (adp->dtargd_ndx == DTRACE_ARGNONE)
266 break; /* all argument descs have been retrieved */
267
268 nc = MAX(nc, adp->dtargd_mapping);
269 }
270
271 xc = i;
272 nc++;
273
274 /*
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.
281 */
282 if (xc == 0 && nc == 0 &&
283 strncmp(pvp->pv_desc.dtvd_name, "pid", 3) == 0) {
284 nc = adc;
285 dt_pid_get_types(dtp, pdp, adv, &nc);
286 xc = nc;
287 }
288
289 /*
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.
293 */
294 xargs = dt_probe_alloc_args(pvp, xc);
295 nargs = dt_probe_alloc_args(pvp, nc);
296
297 if ((xc != 0 && xargs == NULL) || (nc != 0 && nargs == NULL))
298 return (NULL); /* dt_errno is set for us */
299
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);
303
304 if (idp == NULL) {
305 (void) dt_set_errno(dtp, EDT_NOMEM);
306 return (NULL);
307 }
308
309 if ((prp = dt_probe_create(dtp, idp, 2,
315 dt_probe_declare(pvp, prp);
316
317 /*
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[].
321 */
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)));
329
330 dtt.dtt_object = NULL;
331 dtt.dtt_ctfp = NULL;
332 dtt.dtt_type = CTF_ERR;
333 } else {
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);
337 }
338
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)));
349
350 dtt.dtt_object = NULL;
351 dtt.dtt_ctfp = NULL;
352 dtt.dtt_type = CTF_ERR;
353 } else {
354 dt_node_type_assign(prp->pr_xargv[i],
355 dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
356 }
357
358 prp->pr_mapping[i] = adp->dtargd_mapping;
359 prp->pr_argv[i] = dtt;
360 }
361
362 return (prp);
363 }
364
365 /*
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.
369 */
370 dt_probe_t *
371 dt_probe_lookup(dt_provider_t *pvp, const char *s)
372 {
373 dtrace_hdl_t *dtp = pvp->pv_hdl;
374 dtrace_probedesc_t pd;
375 dt_ident_t *idp;
636
637 (void) snprintf(tag, len + 1, "__dtrace_%s___%s_arg%u",
638 prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn);
639
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));
645
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)));
650 }
651 }
652
653 bzero(dnp, sizeof (dt_node_t));
654 dnp->dn_kind = DT_NODE_TYPE;
655
656 dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
657 dt_node_attr_assign(dnp, _dtrace_defattr);
658
659 return (dnp);
660 }
661
662 /*ARGSUSED*/
663 static int
664 dt_probe_desc(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *arg)
665 {
666 if (((dtrace_probedesc_t *)arg)->dtpd_id == DTRACE_IDNONE) {
667 bcopy(pdp, arg, sizeof (dtrace_probedesc_t));
668 return (0);
669 }
670
671 return (1);
672 }
673
674 dt_probe_t *
675 dt_probe_info(dtrace_hdl_t *dtp,
676 const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip)
|