1 /* 2 * CDDL HEADER START 3 * 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. 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 #if defined(sun) 31 #include <sys/sysmacros.h> 32 #endif 33 34 #include <assert.h> 35 #include <limits.h> 36 #include <strings.h> 37 #include <stdlib.h> 38 #if defined(sun) 39 #include <alloca.h> 40 #endif 41 #include <unistd.h> 42 #include <errno.h> 43 44 #include <dt_provider.h> 45 #include <dt_module.h> 46 #include <dt_string.h> 47 #include <dt_list.h> 48 49 static dt_provider_t * 50 dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h) 51 { 52 dt_list_append(&dtp->dt_provlist, pvp); 53 54 pvp->pv_next = dtp->dt_provs[h]; 55 dtp->dt_provs[h] = pvp; 56 dtp->dt_nprovs++; 57 58 return (pvp); 59 } 60 61 dt_provider_t * 62 dt_provider_lookup(dtrace_hdl_t *dtp, const char *name) 63 { 64 uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_provbuckets; 65 dtrace_providerdesc_t desc; 66 dt_provider_t *pvp; 67 68 for (pvp = dtp->dt_provs[h]; pvp != NULL; pvp = pvp->pv_next) { 69 if (strcmp(pvp->pv_desc.dtvd_name, name) == 0) 70 return (pvp); 71 } 72 73 if (strisglob(name) || name[0] == '\0') { 74 (void) dt_set_errno(dtp, EDT_NOPROV); 75 return (NULL); 76 } 77 78 bzero(&desc, sizeof (desc)); 79 (void) strlcpy(desc.dtvd_name, name, DTRACE_PROVNAMELEN); 80 81 if (dt_ioctl(dtp, DTRACEIOC_PROVIDER, &desc) == -1) { 82 (void) dt_set_errno(dtp, errno == ESRCH ? EDT_NOPROV : errno); 83 return (NULL); 84 } 85 86 if ((pvp = dt_provider_create(dtp, name)) == NULL) 87 return (NULL); /* dt_errno is set for us */ 88 89 bcopy(&desc, &pvp->pv_desc, sizeof (desc)); 90 pvp->pv_flags |= DT_PROVIDER_IMPL; 91 return (pvp); 92 } 93 94 dt_provider_t * 95 dt_provider_create(dtrace_hdl_t *dtp, const char *name) 96 { 97 dt_provider_t *pvp; 98 99 if ((pvp = dt_zalloc(dtp, sizeof (dt_provider_t))) == NULL) 100 return (NULL); 101 102 (void) strlcpy(pvp->pv_desc.dtvd_name, name, DTRACE_PROVNAMELEN); 103 pvp->pv_probes = dt_idhash_create(pvp->pv_desc.dtvd_name, NULL, 0, 0); 104 pvp->pv_gen = dtp->dt_gen; 105 pvp->pv_hdl = dtp; 106 107 if (pvp->pv_probes == NULL) { 108 dt_free(dtp, pvp); 109 (void) dt_set_errno(dtp, EDT_NOMEM); 110 return (NULL); 111 } 112 113 pvp->pv_desc.dtvd_attr.dtpa_provider = _dtrace_prvattr; 114 pvp->pv_desc.dtvd_attr.dtpa_mod = _dtrace_prvattr; 115 pvp->pv_desc.dtvd_attr.dtpa_func = _dtrace_prvattr; 116 pvp->pv_desc.dtvd_attr.dtpa_name = _dtrace_prvattr; 117 pvp->pv_desc.dtvd_attr.dtpa_args = _dtrace_prvattr; 118 119 return (dt_provider_insert(dtp, pvp, 120 dt_strtab_hash(name, NULL) % dtp->dt_provbuckets)); 121 } 122 123 void 124 dt_provider_destroy(dtrace_hdl_t *dtp, dt_provider_t *pvp) 125 { 126 dt_provider_t **pp; 127 uint_t h; 128 129 assert(pvp->pv_hdl == dtp); 130 131 h = dt_strtab_hash(pvp->pv_desc.dtvd_name, NULL) % dtp->dt_provbuckets; 132 pp = &dtp->dt_provs[h]; 133 134 while (*pp != NULL && *pp != pvp) 135 pp = &(*pp)->pv_next; 136 137 assert(*pp != NULL && *pp == pvp); 138 *pp = pvp->pv_next; 139 140 dt_list_delete(&dtp->dt_provlist, pvp); 141 dtp->dt_nprovs--; 142 143 if (pvp->pv_probes != NULL) 144 dt_idhash_destroy(pvp->pv_probes); 145 146 dt_node_link_free(&pvp->pv_nodes); 147 dt_free(dtp, pvp->pv_xrefs); 148 dt_free(dtp, pvp); 149 } 150 151 int 152 dt_provider_xref(dtrace_hdl_t *dtp, dt_provider_t *pvp, id_t id) 153 { 154 size_t oldsize = BT_SIZEOFMAP(pvp->pv_xrmax); 155 size_t newsize = BT_SIZEOFMAP(dtp->dt_xlatorid); 156 157 assert(id >= 0 && id < dtp->dt_xlatorid); 158 159 if (newsize > oldsize) { 160 ulong_t *xrefs = dt_zalloc(dtp, newsize); 161 162 if (xrefs == NULL) 163 return (-1); 164 165 bcopy(pvp->pv_xrefs, xrefs, oldsize); 166 dt_free(dtp, pvp->pv_xrefs); 167 168 pvp->pv_xrefs = xrefs; 169 pvp->pv_xrmax = dtp->dt_xlatorid; 170 } 171 172 BT_SET(pvp->pv_xrefs, id); 173 return (0); 174 } 175 176 static uint8_t 177 dt_probe_argmap(dt_node_t *xnp, dt_node_t *nnp) 178 { 179 uint8_t i; 180 181 for (i = 0; nnp != NULL; i++) { 182 if (nnp->dn_string != NULL && 183 strcmp(nnp->dn_string, xnp->dn_string) == 0) 184 break; 185 else 186 nnp = nnp->dn_list; 187 } 188 189 return (i); 190 } 191 192 static dt_node_t * 193 dt_probe_alloc_args(dt_provider_t *pvp, int argc) 194 { 195 dt_node_t *args = NULL, *pnp = NULL, *dnp; 196 int i; 197 198 for (i = 0; i < argc; i++, pnp = dnp) { 199 if ((dnp = dt_node_xalloc(pvp->pv_hdl, DT_NODE_TYPE)) == NULL) 200 return (NULL); 201 202 dnp->dn_link = pvp->pv_nodes; 203 pvp->pv_nodes = dnp; 204 205 if (args == NULL) 206 args = dnp; 207 else 208 pnp->dn_list = dnp; 209 } 210 211 return (args); 212 } 213 214 static size_t 215 dt_probe_keylen(const dtrace_probedesc_t *pdp) 216 { 217 return (strlen(pdp->dtpd_mod) + 1 + 218 strlen(pdp->dtpd_func) + 1 + strlen(pdp->dtpd_name) + 1); 219 } 220 221 static char * 222 dt_probe_key(const dtrace_probedesc_t *pdp, char *s) 223 { 224 (void) snprintf(s, INT_MAX, "%s:%s:%s", 225 pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name); 226 return (s); 227 } 228 229 /* 230 * If a probe was discovered from the kernel, ask dtrace(7D) for a description 231 * of each of its arguments, including native and translated types. 232 */ 233 static dt_probe_t * 234 dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp) 235 { 236 dtrace_hdl_t *dtp = pvp->pv_hdl; 237 char *name = dt_probe_key(pdp, alloca(dt_probe_keylen(pdp))); 238 239 dt_node_t *xargs, *nargs; 240 dt_ident_t *idp; 241 dt_probe_t *prp; 242 243 dtrace_typeinfo_t dtt; 244 int i, nc, xc; 245 246 int adc = _dtrace_argmax; 247 dtrace_argdesc_t *adv = alloca(sizeof (dtrace_argdesc_t) * adc); 248 dtrace_argdesc_t *adp = adv; 249 250 assert(strcmp(pvp->pv_desc.dtvd_name, pdp->dtpd_provider) == 0); 251 assert(pdp->dtpd_id != DTRACE_IDNONE); 252 253 dt_dprintf("discovering probe %s:%s id=%d\n", 254 pvp->pv_desc.dtvd_name, name, pdp->dtpd_id); 255 256 for (nc = -1, i = 0; i < adc; i++, adp++) { 257 bzero(adp, sizeof (dtrace_argdesc_t)); 258 adp->dtargd_ndx = i; 259 adp->dtargd_id = pdp->dtpd_id; 260 261 if (dt_ioctl(dtp, DTRACEIOC_PROBEARG, adp) != 0) { 262 (void) dt_set_errno(dtp, errno); 263 return (NULL); 264 } 265 266 if (adp->dtargd_ndx == DTRACE_ARGNONE) 267 break; /* all argument descs have been retrieved */ 268 269 nc = MAX(nc, adp->dtargd_mapping); 270 } 271 272 xc = i; 273 nc++; 274 275 /* 276 * Now that we have discovered the number of native and translated 277 * arguments from the argument descriptions, allocate a new probe ident 278 * and corresponding dt_probe_t and hash it into the provider. 279 */ 280 xargs = dt_probe_alloc_args(pvp, xc); 281 nargs = dt_probe_alloc_args(pvp, nc); 282 283 if ((xc != 0 && xargs == NULL) || (nc != 0 && nargs == NULL)) 284 return (NULL); /* dt_errno is set for us */ 285 286 idp = dt_ident_create(name, DT_IDENT_PROBE, 287 DT_IDFLG_ORPHAN, pdp->dtpd_id, _dtrace_defattr, 0, 288 &dt_idops_probe, NULL, dtp->dt_gen); 289 290 if (idp == NULL) { 291 (void) dt_set_errno(dtp, EDT_NOMEM); 292 return (NULL); 293 } 294 295 if ((prp = dt_probe_create(dtp, idp, 2, 296 nargs, nc, xargs, xc)) == NULL) { 297 dt_ident_destroy(idp); 298 return (NULL); 299 } 300 301 dt_probe_declare(pvp, prp); 302 303 /* 304 * Once our new dt_probe_t is fully constructed, iterate over the 305 * cached argument descriptions and assign types to prp->pr_nargv[] 306 * and prp->pr_xargv[] and assign mappings to prp->pr_mapping[]. 307 */ 308 for (adp = adv, i = 0; i < xc; i++, adp++) { 309 if (dtrace_type_strcompile(dtp, 310 adp->dtargd_native, &dtt) != 0) { 311 dt_dprintf("failed to resolve input type %s " 312 "for %s:%s arg #%d: %s\n", adp->dtargd_native, 313 pvp->pv_desc.dtvd_name, name, i + 1, 314 dtrace_errmsg(dtp, dtrace_errno(dtp))); 315 316 dtt.dtt_object = NULL; 317 dtt.dtt_ctfp = NULL; 318 dtt.dtt_type = CTF_ERR; 319 } else { 320 dt_node_type_assign(prp->pr_nargv[adp->dtargd_mapping], 321 dtt.dtt_ctfp, dtt.dtt_type); 322 } 323 324 if (dtt.dtt_type != CTF_ERR && (adp->dtargd_xlate[0] == '\0' || 325 strcmp(adp->dtargd_native, adp->dtargd_xlate) == 0)) { 326 dt_node_type_propagate(prp->pr_nargv[ 327 adp->dtargd_mapping], prp->pr_xargv[i]); 328 } else if (dtrace_type_strcompile(dtp, 329 adp->dtargd_xlate, &dtt) != 0) { 330 dt_dprintf("failed to resolve output type %s " 331 "for %s:%s arg #%d: %s\n", adp->dtargd_xlate, 332 pvp->pv_desc.dtvd_name, name, i + 1, 333 dtrace_errmsg(dtp, dtrace_errno(dtp))); 334 335 dtt.dtt_object = NULL; 336 dtt.dtt_ctfp = NULL; 337 dtt.dtt_type = CTF_ERR; 338 } else { 339 dt_node_type_assign(prp->pr_xargv[i], 340 dtt.dtt_ctfp, dtt.dtt_type); 341 } 342 343 prp->pr_mapping[i] = adp->dtargd_mapping; 344 prp->pr_argv[i] = dtt; 345 } 346 347 return (prp); 348 } 349 350 /* 351 * Lookup a probe declaration based on a known provider and full or partially 352 * specified module, function, and name. If the probe is not known to us yet, 353 * ask dtrace(7D) to match the description and then cache any useful results. 354 */ 355 dt_probe_t * 356 dt_probe_lookup(dt_provider_t *pvp, const char *s) 357 { 358 dtrace_hdl_t *dtp = pvp->pv_hdl; 359 dtrace_probedesc_t pd; 360 dt_ident_t *idp; 361 size_t keylen; 362 char *key; 363 364 if (dtrace_str2desc(dtp, DTRACE_PROBESPEC_NAME, s, &pd) != 0) 365 return (NULL); /* dt_errno is set for us */ 366 367 keylen = dt_probe_keylen(&pd); 368 key = dt_probe_key(&pd, alloca(keylen)); 369 370 /* 371 * If the probe is already declared, then return the dt_probe_t from 372 * the existing identifier. This could come from a static declaration 373 * or it could have been cached from an earlier call to this function. 374 */ 375 if ((idp = dt_idhash_lookup(pvp->pv_probes, key)) != NULL) 376 return (idp->di_data); 377 378 /* 379 * If the probe isn't known, use the probe description computed above 380 * to ask dtrace(7D) to find the first matching probe. 381 */ 382 if (dt_ioctl(dtp, DTRACEIOC_PROBEMATCH, &pd) == 0) 383 return (dt_probe_discover(pvp, &pd)); 384 385 if (errno == ESRCH || errno == EBADF) 386 (void) dt_set_errno(dtp, EDT_NOPROBE); 387 else 388 (void) dt_set_errno(dtp, errno); 389 390 return (NULL); 391 } 392 393 dt_probe_t * 394 dt_probe_create(dtrace_hdl_t *dtp, dt_ident_t *idp, int protoc, 395 dt_node_t *nargs, uint_t nargc, dt_node_t *xargs, uint_t xargc) 396 { 397 dt_module_t *dmp; 398 dt_probe_t *prp; 399 const char *p; 400 uint_t i; 401 402 assert(idp->di_kind == DT_IDENT_PROBE); 403 assert(idp->di_data == NULL); 404 405 /* 406 * If only a single prototype is given, set xargc/s to nargc/s to 407 * simplify subsequent use. Note that we can have one or both of nargs 408 * and xargs be specified but set to NULL, indicating a void prototype. 409 */ 410 if (protoc < 2) { 411 assert(xargs == NULL); 412 assert(xargc == 0); 413 xargs = nargs; 414 xargc = nargc; 415 } 416 417 if ((prp = dt_alloc(dtp, sizeof (dt_probe_t))) == NULL) 418 return (NULL); 419 420 prp->pr_pvp = NULL; 421 prp->pr_ident = idp; 422 423 p = strrchr(idp->di_name, ':'); 424 assert(p != NULL); 425 prp->pr_name = p + 1; 426 427 prp->pr_nargs = nargs; 428 prp->pr_nargv = dt_alloc(dtp, sizeof (dt_node_t *) * nargc); 429 prp->pr_nargc = nargc; 430 prp->pr_xargs = xargs; 431 prp->pr_xargv = dt_alloc(dtp, sizeof (dt_node_t *) * xargc); 432 prp->pr_xargc = xargc; 433 prp->pr_mapping = dt_alloc(dtp, sizeof (uint8_t) * xargc); 434 prp->pr_inst = NULL; 435 prp->pr_argv = dt_alloc(dtp, sizeof (dtrace_typeinfo_t) * xargc); 436 prp->pr_argc = xargc; 437 438 if ((prp->pr_nargc != 0 && prp->pr_nargv == NULL) || 439 (prp->pr_xargc != 0 && prp->pr_xargv == NULL) || 440 (prp->pr_xargc != 0 && prp->pr_mapping == NULL) || 441 (prp->pr_argc != 0 && prp->pr_argv == NULL)) { 442 dt_probe_destroy(prp); 443 return (NULL); 444 } 445 446 for (i = 0; i < xargc; i++, xargs = xargs->dn_list) { 447 if (xargs->dn_string != NULL) 448 prp->pr_mapping[i] = dt_probe_argmap(xargs, nargs); 449 else 450 prp->pr_mapping[i] = i; 451 452 prp->pr_xargv[i] = xargs; 453 454 if ((dmp = dt_module_lookup_by_ctf(dtp, 455 xargs->dn_ctfp)) != NULL) 456 prp->pr_argv[i].dtt_object = dmp->dm_name; 457 else 458 prp->pr_argv[i].dtt_object = NULL; 459 460 prp->pr_argv[i].dtt_ctfp = xargs->dn_ctfp; 461 prp->pr_argv[i].dtt_type = xargs->dn_type; 462 } 463 464 for (i = 0; i < nargc; i++, nargs = nargs->dn_list) 465 prp->pr_nargv[i] = nargs; 466 467 idp->di_data = prp; 468 return (prp); 469 } 470 471 void 472 dt_probe_declare(dt_provider_t *pvp, dt_probe_t *prp) 473 { 474 assert(prp->pr_ident->di_kind == DT_IDENT_PROBE); 475 assert(prp->pr_ident->di_data == prp); 476 assert(prp->pr_pvp == NULL); 477 478 if (prp->pr_xargs != prp->pr_nargs) 479 pvp->pv_flags &= ~DT_PROVIDER_INTF; 480 481 prp->pr_pvp = pvp; 482 dt_idhash_xinsert(pvp->pv_probes, prp->pr_ident); 483 } 484 485 void 486 dt_probe_destroy(dt_probe_t *prp) 487 { 488 dt_probe_instance_t *pip, *pip_next; 489 dtrace_hdl_t *dtp; 490 491 if (prp->pr_pvp != NULL) 492 dtp = prp->pr_pvp->pv_hdl; 493 else 494 dtp = yypcb->pcb_hdl; 495 496 dt_node_list_free(&prp->pr_nargs); 497 dt_node_list_free(&prp->pr_xargs); 498 499 dt_free(dtp, prp->pr_nargv); 500 dt_free(dtp, prp->pr_xargv); 501 502 for (pip = prp->pr_inst; pip != NULL; pip = pip_next) { 503 pip_next = pip->pi_next; 504 dt_free(dtp, pip->pi_offs); 505 dt_free(dtp, pip->pi_enoffs); 506 dt_free(dtp, pip); 507 } 508 509 dt_free(dtp, prp->pr_mapping); 510 dt_free(dtp, prp->pr_argv); 511 dt_free(dtp, prp); 512 } 513 514 int 515 dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp, 516 const char *fname, const char *rname, uint32_t offset, int isenabled) 517 { 518 dtrace_hdl_t *dtp = pvp->pv_hdl; 519 dt_probe_instance_t *pip; 520 uint32_t **offs; 521 uint_t *noffs, *maxoffs; 522 523 assert(fname != NULL); 524 525 for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) { 526 if (strcmp(pip->pi_fname, fname) == 0 && 527 ((rname == NULL && pip->pi_rname[0] == '\0') || 528 (rname != NULL && strcmp(pip->pi_rname, rname)) == 0)) 529 break; 530 } 531 532 if (pip == NULL) { 533 if ((pip = dt_zalloc(dtp, sizeof (*pip))) == NULL) 534 return (-1); 535 536 if ((pip->pi_offs = dt_zalloc(dtp, 537 sizeof (uint32_t))) == NULL) { 538 dt_free(dtp, pip); 539 return (-1); 540 } 541 542 if ((pip->pi_enoffs = dt_zalloc(dtp, 543 sizeof (uint32_t))) == NULL) { 544 dt_free(dtp, pip->pi_offs); 545 dt_free(dtp, pip); 546 return (-1); 547 } 548 549 (void) strlcpy(pip->pi_fname, fname, sizeof (pip->pi_fname)); 550 if (rname != NULL) { 551 if (strlen(rname) + 1 > sizeof (pip->pi_rname)) { 552 dt_free(dtp, pip->pi_offs); 553 dt_free(dtp, pip); 554 return (dt_set_errno(dtp, EDT_COMPILER)); 555 } 556 (void) strcpy(pip->pi_rname, rname); 557 } 558 559 pip->pi_noffs = 0; 560 pip->pi_maxoffs = 1; 561 pip->pi_nenoffs = 0; 562 pip->pi_maxenoffs = 1; 563 564 pip->pi_next = prp->pr_inst; 565 566 prp->pr_inst = pip; 567 } 568 569 if (isenabled) { 570 offs = &pip->pi_enoffs; 571 noffs = &pip->pi_nenoffs; 572 maxoffs = &pip->pi_maxenoffs; 573 } else { 574 offs = &pip->pi_offs; 575 noffs = &pip->pi_noffs; 576 maxoffs = &pip->pi_maxoffs; 577 } 578 579 if (*noffs == *maxoffs) { 580 uint_t new_max = *maxoffs * 2; 581 uint32_t *new_offs = dt_alloc(dtp, sizeof (uint32_t) * new_max); 582 583 if (new_offs == NULL) 584 return (-1); 585 586 bcopy(*offs, new_offs, sizeof (uint32_t) * *maxoffs); 587 588 dt_free(dtp, *offs); 589 *maxoffs = new_max; 590 *offs = new_offs; 591 } 592 593 dt_dprintf("defined probe %s %s:%s %s() +0x%x (%s)\n", 594 isenabled ? "(is-enabled)" : "", 595 pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, fname, offset, 596 rname != NULL ? rname : fname); 597 598 assert(*noffs < *maxoffs); 599 (*offs)[(*noffs)++] = offset; 600 601 return (0); 602 } 603 604 /* 605 * Lookup the dynamic translator type tag for the specified probe argument and 606 * assign the type to the specified node. If the type is not yet defined, add 607 * it to the "D" module's type container as a typedef for an unknown type. 608 */ 609 dt_node_t * 610 dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp) 611 { 612 dtrace_hdl_t *dtp = prp->pr_pvp->pv_hdl; 613 dtrace_typeinfo_t dtt; 614 size_t len; 615 char *tag; 616 617 len = snprintf(NULL, 0, "__dtrace_%s___%s_arg%u", 618 prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn); 619 620 tag = alloca(len + 1); 621 622 (void) snprintf(tag, len + 1, "__dtrace_%s___%s_arg%u", 623 prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn); 624 625 if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_DDEFS, tag, &dtt) != 0) { 626 dtt.dtt_object = DTRACE_OBJ_DDEFS; 627 dtt.dtt_ctfp = DT_DYN_CTFP(dtp); 628 dtt.dtt_type = ctf_add_typedef(DT_DYN_CTFP(dtp), 629 CTF_ADD_ROOT, tag, DT_DYN_TYPE(dtp)); 630 631 if (dtt.dtt_type == CTF_ERR || 632 ctf_update(dtt.dtt_ctfp) == CTF_ERR) { 633 xyerror(D_UNKNOWN, "cannot define type %s: %s\n", 634 tag, ctf_errmsg(ctf_errno(dtt.dtt_ctfp))); 635 } 636 } 637 638 bzero(dnp, sizeof (dt_node_t)); 639 dnp->dn_kind = DT_NODE_TYPE; 640 641 dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); 642 dt_node_attr_assign(dnp, _dtrace_defattr); 643 644 return (dnp); 645 } 646 647 /*ARGSUSED*/ 648 static int 649 dt_probe_desc(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *arg) 650 { 651 if (((dtrace_probedesc_t *)arg)->dtpd_id == DTRACE_IDNONE) { 652 bcopy(pdp, arg, sizeof (dtrace_probedesc_t)); 653 return (0); 654 } 655 656 return (1); 657 } 658 659 dt_probe_t * 660 dt_probe_info(dtrace_hdl_t *dtp, 661 const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip) 662 { 663 int m_is_glob = pdp->dtpd_mod[0] == '\0' || strisglob(pdp->dtpd_mod); 664 int f_is_glob = pdp->dtpd_func[0] == '\0' || strisglob(pdp->dtpd_func); 665 int n_is_glob = pdp->dtpd_name[0] == '\0' || strisglob(pdp->dtpd_name); 666 667 dt_probe_t *prp = NULL; 668 const dtrace_pattr_t *pap; 669 dt_provider_t *pvp; 670 dt_ident_t *idp; 671 672 /* 673 * Attempt to lookup the probe in our existing cache for this provider. 674 * If none is found and an explicit probe ID was specified, discover 675 * that specific probe and cache its description and arguments. 676 */ 677 if ((pvp = dt_provider_lookup(dtp, pdp->dtpd_provider)) != NULL) { 678 size_t keylen = dt_probe_keylen(pdp); 679 char *key = dt_probe_key(pdp, alloca(keylen)); 680 681 if ((idp = dt_idhash_lookup(pvp->pv_probes, key)) != NULL) 682 prp = idp->di_data; 683 else if (pdp->dtpd_id != DTRACE_IDNONE) 684 prp = dt_probe_discover(pvp, pdp); 685 } 686 687 /* 688 * If no probe was found in our cache, convert the caller's partial 689 * probe description into a fully-formed matching probe description by 690 * iterating over up to at most two probes that match 'pdp'. We then 691 * call dt_probe_discover() on the resulting probe identifier. 692 */ 693 if (prp == NULL) { 694 dtrace_probedesc_t pd; 695 int m; 696 697 bzero(&pd, sizeof (pd)); 698 pd.dtpd_id = DTRACE_IDNONE; 699 700 /* 701 * Call dtrace_probe_iter() to find matching probes. Our 702 * dt_probe_desc() callback will produce the following results: 703 * 704 * m < 0 dtrace_probe_iter() found zero matches (or failed). 705 * m > 0 dtrace_probe_iter() found more than one match. 706 * m = 0 dtrace_probe_iter() found exactly one match. 707 */ 708 if ((m = dtrace_probe_iter(dtp, pdp, dt_probe_desc, &pd)) < 0) 709 return (NULL); /* dt_errno is set for us */ 710 711 if ((pvp = dt_provider_lookup(dtp, pd.dtpd_provider)) == NULL) 712 return (NULL); /* dt_errno is set for us */ 713 714 /* 715 * If more than one probe was matched, then do not report probe 716 * information if either of the following conditions is true: 717 * 718 * (a) The Arguments Data stability of the matched provider is 719 * less than Evolving. 720 * 721 * (b) Any description component that is at least Evolving is 722 * empty or is specified using a globbing expression. 723 * 724 * These conditions imply that providers that provide Evolving 725 * or better Arguments Data stability must guarantee that all 726 * probes with identical field names in a field of Evolving or 727 * better Name stability have identical argument signatures. 728 */ 729 if (m > 0) { 730 if (pvp->pv_desc.dtvd_attr.dtpa_args.dtat_data < 731 DTRACE_STABILITY_EVOLVING) { 732 (void) dt_set_errno(dtp, EDT_UNSTABLE); 733 return (NULL); 734 } 735 736 737 if (pvp->pv_desc.dtvd_attr.dtpa_mod.dtat_name >= 738 DTRACE_STABILITY_EVOLVING && m_is_glob) { 739 (void) dt_set_errno(dtp, EDT_UNSTABLE); 740 return (NULL); 741 } 742 743 if (pvp->pv_desc.dtvd_attr.dtpa_func.dtat_name >= 744 DTRACE_STABILITY_EVOLVING && f_is_glob) { 745 (void) dt_set_errno(dtp, EDT_UNSTABLE); 746 return (NULL); 747 } 748 749 if (pvp->pv_desc.dtvd_attr.dtpa_name.dtat_name >= 750 DTRACE_STABILITY_EVOLVING && n_is_glob) { 751 (void) dt_set_errno(dtp, EDT_UNSTABLE); 752 return (NULL); 753 } 754 } 755 756 /* 757 * If we matched a probe exported by dtrace(7D), then discover 758 * the real attributes. Otherwise grab the static declaration. 759 */ 760 if (pd.dtpd_id != DTRACE_IDNONE) 761 prp = dt_probe_discover(pvp, &pd); 762 else 763 prp = dt_probe_lookup(pvp, pd.dtpd_name); 764 765 if (prp == NULL) 766 return (NULL); /* dt_errno is set for us */ 767 } 768 769 assert(pvp != NULL && prp != NULL); 770 771 /* 772 * Compute the probe description attributes by taking the minimum of 773 * the attributes of the specified fields. If no provider is specified 774 * or a glob pattern is used for the provider, use Unstable attributes. 775 */ 776 if (pdp->dtpd_provider[0] == '\0' || strisglob(pdp->dtpd_provider)) 777 pap = &_dtrace_prvdesc; 778 else 779 pap = &pvp->pv_desc.dtvd_attr; 780 781 pip->dtp_attr = pap->dtpa_provider; 782 783 if (!m_is_glob) 784 pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_mod); 785 if (!f_is_glob) 786 pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_func); 787 if (!n_is_glob) 788 pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_name); 789 790 pip->dtp_arga = pap->dtpa_args; 791 pip->dtp_argv = prp->pr_argv; 792 pip->dtp_argc = prp->pr_argc; 793 794 return (prp); 795 } 796 797 int 798 dtrace_probe_info(dtrace_hdl_t *dtp, 799 const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip) 800 { 801 return (dt_probe_info(dtp, pdp, pip) != NULL ? 0 : -1); 802 } 803 804 /*ARGSUSED*/ 805 static int 806 dt_probe_iter(dt_idhash_t *ihp, dt_ident_t *idp, dt_probe_iter_t *pit) 807 { 808 const dt_probe_t *prp = idp->di_data; 809 810 if (!dt_gmatch(prp->pr_name, pit->pit_pat)) 811 return (0); /* continue on and examine next probe in hash */ 812 813 (void) strlcpy(pit->pit_desc.dtpd_name, prp->pr_name, DTRACE_NAMELEN); 814 pit->pit_desc.dtpd_id = idp->di_id; 815 pit->pit_matches++; 816 817 return (pit->pit_func(pit->pit_hdl, &pit->pit_desc, pit->pit_arg)); 818 } 819 820 int 821 dtrace_probe_iter(dtrace_hdl_t *dtp, 822 const dtrace_probedesc_t *pdp, dtrace_probe_f *func, void *arg) 823 { 824 const char *provider = pdp ? pdp->dtpd_provider : NULL; 825 dtrace_id_t id = DTRACE_IDNONE; 826 827 dtrace_probedesc_t pd; 828 dt_probe_iter_t pit; 829 int cmd, rv; 830 831 bzero(&pit, sizeof (pit)); 832 pit.pit_hdl = dtp; 833 pit.pit_func = func; 834 pit.pit_arg = arg; 835 pit.pit_pat = pdp ? pdp->dtpd_name : NULL; 836 837 for (pit.pit_pvp = dt_list_next(&dtp->dt_provlist); 838 pit.pit_pvp != NULL; pit.pit_pvp = dt_list_next(pit.pit_pvp)) { 839 840 if (pit.pit_pvp->pv_flags & DT_PROVIDER_IMPL) 841 continue; /* we'll get these later using dt_ioctl() */ 842 843 if (!dt_gmatch(pit.pit_pvp->pv_desc.dtvd_name, provider)) 844 continue; 845 846 (void) strlcpy(pit.pit_desc.dtpd_provider, 847 pit.pit_pvp->pv_desc.dtvd_name, DTRACE_PROVNAMELEN); 848 849 if ((rv = dt_idhash_iter(pit.pit_pvp->pv_probes, 850 (dt_idhash_f *)dt_probe_iter, &pit)) != 0) 851 return (rv); 852 } 853 854 if (pdp != NULL) 855 cmd = DTRACEIOC_PROBEMATCH; 856 else 857 cmd = DTRACEIOC_PROBES; 858 859 for (;;) { 860 if (pdp != NULL) 861 bcopy(pdp, &pd, sizeof (pd)); 862 863 pd.dtpd_id = id; 864 865 if (dt_ioctl(dtp, cmd, &pd) != 0) 866 break; 867 else if ((rv = func(dtp, &pd, arg)) != 0) 868 return (rv); 869 870 pit.pit_matches++; 871 id = pd.dtpd_id + 1; 872 } 873 874 switch (errno) { 875 case ESRCH: 876 case EBADF: 877 return (pit.pit_matches ? 0 : dt_set_errno(dtp, EDT_NOPROBE)); 878 case EINVAL: 879 return (dt_set_errno(dtp, EDT_BADPGLOB)); 880 default: 881 return (dt_set_errno(dtp, errno)); 882 } 883 } 884