Print this page
4474 DTrace Userland CTF Support
4475 DTrace userland Keyword
4476 DTrace tests should be better citizens
4479 pid provider types
4480 dof emulation missing checks
Reviewed by: Bryan Cantrill <bryan@joyent.com>


   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)