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