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>


   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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.


  24  */
  25 
  26 #include <sys/sysmacros.h>
  27 #include <strings.h>
  28 #include <stdlib.h>
  29 #include <alloca.h>
  30 #include <assert.h>
  31 #include <errno.h>
  32 #include <ctype.h>
  33 #include <sys/procfs_isa.h>
  34 #include <limits.h>
  35 
  36 #include <dt_ident.h>
  37 #include <dt_parser.h>
  38 #include <dt_provider.h>
  39 #include <dt_strtab.h>
  40 #include <dt_impl.h>
  41 
  42 /*
  43  * Common code for cooking an identifier that uses a typed signature list (we


  78 
  79         for (i = 0; i < arglimit; i++, args = args->dn_list) {
  80                 if (isp->dis_args[i].dn_ctfp != NULL)
  81                         compat = dt_node_is_argcompat(&isp->dis_args[i], args);
  82                 else
  83                         compat = 1; /* "@" matches any type */
  84 
  85                 if (!compat) {
  86                         xyerror(D_PROTO_ARG,
  87                             "%s%s%s %s #%d is incompatible with "
  88                             "prototype:\n\tprototype: %s\n\t%9s: %s\n",
  89                             prefix, idp->di_name, suffix,
  90                             iskey ? "key" : "argument", i + 1,
  91                             dt_node_type_name(&isp->dis_args[i], n1,
  92                             sizeof (n1)),
  93                             iskey ? "key" : "argument",
  94                             dt_node_type_name(args, n2, sizeof (n2)));
  95                 }
  96         }
  97 
  98         dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
  99 }
 100 
 101 /*
 102  * Cook an associative array identifier.  If this is the first time we are
 103  * cooking this array, create its signature based on the argument list.
 104  * Otherwise validate the argument list against the existing signature.
 105  */
 106 static void
 107 dt_idcook_assc(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 108 {
 109         if (idp->di_data == NULL) {
 110                 dt_idsig_t *isp = idp->di_data = malloc(sizeof (dt_idsig_t));
 111                 char n[DT_TYPE_NAMELEN];
 112                 int i;
 113 
 114                 if (isp == NULL)
 115                         longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 116 
 117                 isp->dis_varargs = -1;
 118                 isp->dis_optargs = -1;


 137                 if (!(idp->di_flags & DT_IDFLG_DECL)) {
 138                         idp->di_ctfp = DT_DYN_CTFP(yypcb->pcb_hdl);
 139                         idp->di_type = DT_DYN_TYPE(yypcb->pcb_hdl);
 140                 }
 141 
 142                 for (i = 0; i < argc; i++, args = args->dn_list) {
 143                         if (dt_node_is_dynamic(args) || dt_node_is_void(args)) {
 144                                 xyerror(D_KEY_TYPE, "%s expression may not be "
 145                                     "used as %s index: key #%d\n",
 146                                     dt_node_type_name(args, n, sizeof (n)),
 147                                     dt_idkind_name(idp->di_kind), i + 1);
 148                         }
 149 
 150                         dt_node_type_propagate(args, &isp->dis_args[i]);
 151                         isp->dis_args[i].dn_list = &isp->dis_args[i + 1];
 152                 }
 153 
 154                 if (argc != 0)
 155                         isp->dis_args[argc - 1].dn_list = NULL;
 156 
 157                 dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
 158 
 159         } else {
 160                 dt_idcook_sign(dnp, idp, argc, args,
 161                     idp->di_kind == DT_IDENT_AGG ? "@" : "", "[ ]");
 162         }
 163 }
 164 
 165 /*
 166  * Cook a function call.  If this is the first time we are cooking this
 167  * identifier, create its type signature based on predefined prototype stored
 168  * in di_iarg.  We then validate the argument list against this signature.
 169  */
 170 static void
 171 dt_idcook_func(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 172 {
 173         if (idp->di_data == NULL) {
 174                 dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 175                 dtrace_typeinfo_t dtt;
 176                 dt_idsig_t *isp;
 177                 char *s, *p1, *p2;


 277                                 }
 278 
 279                                 if (isp->dis_optargs == -1)
 280                                         isp->dis_optargs = i;
 281 
 282                                 p1[strlen(p1) - 1] = '\0';
 283                                 p1++;
 284                         } else if (isp->dis_optargs != -1) {
 285                                 xyerror(D_UNKNOWN, "required arg#%d may not "
 286                                     "follow optional arg#%d\n", i + 1,
 287                                     isp->dis_optargs + 1);
 288                         }
 289 
 290                         if (dt_type_lookup(p1, &dtt) == -1) {
 291                                 xyerror(D_UNKNOWN, "failed to resolve type of "
 292                                     "%s arg#%d (%s): %s\n", idp->di_name, i + 1,
 293                                     p1, dtrace_errmsg(dtp, dtrace_errno(dtp)));
 294                         }
 295 
 296                         dt_node_type_assign(&isp->dis_args[i],
 297                             dtt.dtt_ctfp, dtt.dtt_type);
 298                 }
 299         }
 300 
 301         dt_idcook_sign(dnp, idp, argc, args, "", "( )");
 302 }
 303 
 304 /*
 305  * Cook a reference to the dynamically typed args[] array.  We verify that the
 306  * reference is using a single integer constant, and then construct a new ident
 307  * representing the appropriate type or translation specifically for this node.
 308  */
 309 static void
 310 dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
 311 {
 312         dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 313         dt_probe_t *prp = yypcb->pcb_probe;
 314 
 315         dt_node_t tag, *nnp, *xnp;
 316         dt_xlator_t *dxp;
 317         dt_ident_t *xidp;


 364                 xyerror(D_ARGS_TYPE, "failed to resolve translated type for "
 365                     "%s[%lld]\n", idp->di_name, (longlong_t)ap->dn_value);
 366         }
 367 
 368         if (nnp->dn_type == CTF_ERR) {
 369                 xyerror(D_ARGS_TYPE, "failed to resolve native type for "
 370                     "%s[%lld]\n", idp->di_name, (longlong_t)ap->dn_value);
 371         }
 372 
 373         if (dtp->dt_xlatemode == DT_XL_STATIC && (
 374             nnp == xnp || dt_node_is_argcompat(nnp, xnp))) {
 375                 dnp->dn_ident = dt_ident_create(idp->di_name, idp->di_kind,
 376                     idp->di_flags | DT_IDFLG_ORPHAN, idp->di_id, idp->di_attr,
 377                     idp->di_vers, idp->di_ops, idp->di_iarg, idp->di_gen);
 378 
 379                 if (dnp->dn_ident == NULL)
 380                         longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 381 
 382                 dt_node_type_assign(dnp,
 383                     prp->pr_argv[ap->dn_value].dtt_ctfp,
 384                     prp->pr_argv[ap->dn_value].dtt_type);


 385 
 386         } else if ((dxp = dt_xlator_lookup(dtp,
 387             nnp, xnp, DT_XLATE_FUZZY)) != NULL || (
 388             dxp = dt_xlator_lookup(dtp, dt_probe_tag(prp, ap->dn_value, &tag),
 389             xnp, DT_XLATE_EXACT | DT_XLATE_EXTERN)) != NULL) {
 390 
 391                 xidp = dt_xlator_ident(dxp, xnp->dn_ctfp, xnp->dn_type);
 392 
 393                 dnp->dn_ident = dt_ident_create(idp->di_name, xidp->di_kind,
 394                     xidp->di_flags | DT_IDFLG_ORPHAN, idp->di_id, idp->di_attr,
 395                     idp->di_vers, idp->di_ops, idp->di_iarg, idp->di_gen);
 396 
 397                 if (dnp->dn_ident == NULL)
 398                         longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 399 
 400                 if (dt_xlator_dynamic(dxp))
 401                         dxp->dx_arg = (int)ap->dn_value;
 402 
 403                 /*
 404                  * Propagate relevant members from the translator's internal
 405                  * dt_ident_t.  This code must be kept in sync with the state
 406                  * that is initialized for idents in dt_xlator_create().
 407                  */
 408                 dnp->dn_ident->di_data = xidp->di_data;
 409                 dnp->dn_ident->di_ctfp = xidp->di_ctfp;
 410                 dnp->dn_ident->di_type = xidp->di_type;
 411 
 412                 dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));

 413 
 414         } else {
 415                 xyerror(D_ARGS_XLATOR, "translator for %s[%lld] from %s to %s "
 416                     "is not defined\n", idp->di_name, (longlong_t)ap->dn_value,
 417                     dt_node_type_name(nnp, n1, sizeof (n1)),
 418                     dt_node_type_name(xnp, n2, sizeof (n2)));
 419         }
 420 
 421         assert(dnp->dn_ident->di_flags & DT_IDFLG_ORPHAN);
 422         assert(dnp->dn_ident->di_id == idp->di_id);
 423 }
 424 
 425 static void
 426 dt_idcook_regs(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
 427 {
 428         dtrace_typeinfo_t dtt;
 429         dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 430         char n[DT_TYPE_NAMELEN];
 431 
 432         if (argc != 1) {


 438         if (ap->dn_kind != DT_NODE_INT) {
 439                 xyerror(D_PROTO_ARG, "%s[ ] argument #1 is incompatible with "
 440                     "prototype:\n\tprototype: %s\n\t argument: %s\n",
 441                     idp->di_name, "integer constant",
 442                     dt_type_name(ap->dn_ctfp, ap->dn_type, n, sizeof (n)));
 443         }
 444 
 445         if ((ap->dn_flags & DT_NF_SIGNED) && (int64_t)ap->dn_value < 0) {
 446                 xyerror(D_REGS_IDX, "index %lld is out of range for array %s\n",
 447                     (longlong_t)ap->dn_value, idp->di_name);
 448         }
 449 
 450         if (dt_type_lookup("uint64_t", &dtt) == -1) {
 451                 xyerror(D_UNKNOWN, "failed to resolve type of %s: %s\n",
 452                     idp->di_name, dtrace_errmsg(dtp, dtrace_errno(dtp)));
 453         }
 454 
 455         idp->di_ctfp = dtt.dtt_ctfp;
 456         idp->di_type = dtt.dtt_type;
 457 
 458         dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
 459 }
 460 
 461 /*ARGSUSED*/
 462 static void
 463 dt_idcook_type(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 464 {
 465         if (idp->di_type == CTF_ERR) {
 466                 dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 467                 dtrace_typeinfo_t dtt;
 468 
 469                 if (dt_type_lookup(idp->di_iarg, &dtt) == -1) {
 470                         xyerror(D_UNKNOWN,
 471                             "failed to resolve type %s for identifier %s: %s\n",
 472                             (const char *)idp->di_iarg, idp->di_name,
 473                             dtrace_errmsg(dtp, dtrace_errno(dtp)));
 474                 }
 475 
 476                 idp->di_ctfp = dtt.dtt_ctfp;
 477                 idp->di_type = dtt.dtt_type;
 478         }
 479 
 480         dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
 481 }
 482 
 483 /*ARGSUSED*/
 484 static void
 485 dt_idcook_thaw(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 486 {
 487         if (idp->di_ctfp != NULL && idp->di_type != CTF_ERR)
 488                 dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
 489 }
 490 
 491 static void
 492 dt_idcook_inline(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 493 {
 494         if (idp->di_kind == DT_IDENT_ARRAY)
 495                 dt_idcook_assc(dnp, idp, argc, args);
 496         else
 497                 dt_idcook_thaw(dnp, idp, argc, args);
 498 }
 499 
 500 static void
 501 dt_iddtor_sign(dt_ident_t *idp)
 502 {
 503         if (idp->di_data != NULL)
 504                 free(((dt_idsig_t *)idp->di_data)->dis_args);
 505         free(idp->di_data);
 506 }
 507 
 508 static void




   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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2013 by Delphix. All rights reserved.
  25  * Copyright (c) 2013 Joyent, Inc. All rights reserved.
  26  */
  27 
  28 #include <sys/sysmacros.h>
  29 #include <strings.h>
  30 #include <stdlib.h>
  31 #include <alloca.h>
  32 #include <assert.h>
  33 #include <errno.h>
  34 #include <ctype.h>
  35 #include <sys/procfs_isa.h>
  36 #include <limits.h>
  37 
  38 #include <dt_ident.h>
  39 #include <dt_parser.h>
  40 #include <dt_provider.h>
  41 #include <dt_strtab.h>
  42 #include <dt_impl.h>
  43 
  44 /*
  45  * Common code for cooking an identifier that uses a typed signature list (we


  80 
  81         for (i = 0; i < arglimit; i++, args = args->dn_list) {
  82                 if (isp->dis_args[i].dn_ctfp != NULL)
  83                         compat = dt_node_is_argcompat(&isp->dis_args[i], args);
  84                 else
  85                         compat = 1; /* "@" matches any type */
  86 
  87                 if (!compat) {
  88                         xyerror(D_PROTO_ARG,
  89                             "%s%s%s %s #%d is incompatible with "
  90                             "prototype:\n\tprototype: %s\n\t%9s: %s\n",
  91                             prefix, idp->di_name, suffix,
  92                             iskey ? "key" : "argument", i + 1,
  93                             dt_node_type_name(&isp->dis_args[i], n1,
  94                             sizeof (n1)),
  95                             iskey ? "key" : "argument",
  96                             dt_node_type_name(args, n2, sizeof (n2)));
  97                 }
  98         }
  99 
 100         dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 101 }
 102 
 103 /*
 104  * Cook an associative array identifier.  If this is the first time we are
 105  * cooking this array, create its signature based on the argument list.
 106  * Otherwise validate the argument list against the existing signature.
 107  */
 108 static void
 109 dt_idcook_assc(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 110 {
 111         if (idp->di_data == NULL) {
 112                 dt_idsig_t *isp = idp->di_data = malloc(sizeof (dt_idsig_t));
 113                 char n[DT_TYPE_NAMELEN];
 114                 int i;
 115 
 116                 if (isp == NULL)
 117                         longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 118 
 119                 isp->dis_varargs = -1;
 120                 isp->dis_optargs = -1;


 139                 if (!(idp->di_flags & DT_IDFLG_DECL)) {
 140                         idp->di_ctfp = DT_DYN_CTFP(yypcb->pcb_hdl);
 141                         idp->di_type = DT_DYN_TYPE(yypcb->pcb_hdl);
 142                 }
 143 
 144                 for (i = 0; i < argc; i++, args = args->dn_list) {
 145                         if (dt_node_is_dynamic(args) || dt_node_is_void(args)) {
 146                                 xyerror(D_KEY_TYPE, "%s expression may not be "
 147                                     "used as %s index: key #%d\n",
 148                                     dt_node_type_name(args, n, sizeof (n)),
 149                                     dt_idkind_name(idp->di_kind), i + 1);
 150                         }
 151 
 152                         dt_node_type_propagate(args, &isp->dis_args[i]);
 153                         isp->dis_args[i].dn_list = &isp->dis_args[i + 1];
 154                 }
 155 
 156                 if (argc != 0)
 157                         isp->dis_args[argc - 1].dn_list = NULL;
 158 
 159                 dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 160 
 161         } else {
 162                 dt_idcook_sign(dnp, idp, argc, args,
 163                     idp->di_kind == DT_IDENT_AGG ? "@" : "", "[ ]");
 164         }
 165 }
 166 
 167 /*
 168  * Cook a function call.  If this is the first time we are cooking this
 169  * identifier, create its type signature based on predefined prototype stored
 170  * in di_iarg.  We then validate the argument list against this signature.
 171  */
 172 static void
 173 dt_idcook_func(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 174 {
 175         if (idp->di_data == NULL) {
 176                 dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 177                 dtrace_typeinfo_t dtt;
 178                 dt_idsig_t *isp;
 179                 char *s, *p1, *p2;


 279                                 }
 280 
 281                                 if (isp->dis_optargs == -1)
 282                                         isp->dis_optargs = i;
 283 
 284                                 p1[strlen(p1) - 1] = '\0';
 285                                 p1++;
 286                         } else if (isp->dis_optargs != -1) {
 287                                 xyerror(D_UNKNOWN, "required arg#%d may not "
 288                                     "follow optional arg#%d\n", i + 1,
 289                                     isp->dis_optargs + 1);
 290                         }
 291 
 292                         if (dt_type_lookup(p1, &dtt) == -1) {
 293                                 xyerror(D_UNKNOWN, "failed to resolve type of "
 294                                     "%s arg#%d (%s): %s\n", idp->di_name, i + 1,
 295                                     p1, dtrace_errmsg(dtp, dtrace_errno(dtp)));
 296                         }
 297 
 298                         dt_node_type_assign(&isp->dis_args[i],
 299                             dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
 300                 }
 301         }
 302 
 303         dt_idcook_sign(dnp, idp, argc, args, "", "( )");
 304 }
 305 
 306 /*
 307  * Cook a reference to the dynamically typed args[] array.  We verify that the
 308  * reference is using a single integer constant, and then construct a new ident
 309  * representing the appropriate type or translation specifically for this node.
 310  */
 311 static void
 312 dt_idcook_args(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
 313 {
 314         dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 315         dt_probe_t *prp = yypcb->pcb_probe;
 316 
 317         dt_node_t tag, *nnp, *xnp;
 318         dt_xlator_t *dxp;
 319         dt_ident_t *xidp;


 366                 xyerror(D_ARGS_TYPE, "failed to resolve translated type for "
 367                     "%s[%lld]\n", idp->di_name, (longlong_t)ap->dn_value);
 368         }
 369 
 370         if (nnp->dn_type == CTF_ERR) {
 371                 xyerror(D_ARGS_TYPE, "failed to resolve native type for "
 372                     "%s[%lld]\n", idp->di_name, (longlong_t)ap->dn_value);
 373         }
 374 
 375         if (dtp->dt_xlatemode == DT_XL_STATIC && (
 376             nnp == xnp || dt_node_is_argcompat(nnp, xnp))) {
 377                 dnp->dn_ident = dt_ident_create(idp->di_name, idp->di_kind,
 378                     idp->di_flags | DT_IDFLG_ORPHAN, idp->di_id, idp->di_attr,
 379                     idp->di_vers, idp->di_ops, idp->di_iarg, idp->di_gen);
 380 
 381                 if (dnp->dn_ident == NULL)
 382                         longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 383 
 384                 dt_node_type_assign(dnp,
 385                     prp->pr_argv[ap->dn_value].dtt_ctfp,
 386                     prp->pr_argv[ap->dn_value].dtt_type,
 387                     prp->pr_argv[ap->dn_value].dtt_flags & DTT_FL_USER ?
 388                     B_TRUE : B_FALSE);
 389 
 390         } else if ((dxp = dt_xlator_lookup(dtp,
 391             nnp, xnp, DT_XLATE_FUZZY)) != NULL || (
 392             dxp = dt_xlator_lookup(dtp, dt_probe_tag(prp, ap->dn_value, &tag),
 393             xnp, DT_XLATE_EXACT | DT_XLATE_EXTERN)) != NULL) {
 394 
 395                 xidp = dt_xlator_ident(dxp, xnp->dn_ctfp, xnp->dn_type);
 396 
 397                 dnp->dn_ident = dt_ident_create(idp->di_name, xidp->di_kind,
 398                     xidp->di_flags | DT_IDFLG_ORPHAN, idp->di_id, idp->di_attr,
 399                     idp->di_vers, idp->di_ops, idp->di_iarg, idp->di_gen);
 400 
 401                 if (dnp->dn_ident == NULL)
 402                         longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 403 
 404                 if (dt_xlator_dynamic(dxp))
 405                         dxp->dx_arg = (int)ap->dn_value;
 406 
 407                 /*
 408                  * Propagate relevant members from the translator's internal
 409                  * dt_ident_t.  This code must be kept in sync with the state
 410                  * that is initialized for idents in dt_xlator_create().
 411                  */
 412                 dnp->dn_ident->di_data = xidp->di_data;
 413                 dnp->dn_ident->di_ctfp = xidp->di_ctfp;
 414                 dnp->dn_ident->di_type = xidp->di_type;
 415 
 416                 dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp),
 417                     B_FALSE);
 418 
 419         } else {
 420                 xyerror(D_ARGS_XLATOR, "translator for %s[%lld] from %s to %s "
 421                     "is not defined\n", idp->di_name, (longlong_t)ap->dn_value,
 422                     dt_node_type_name(nnp, n1, sizeof (n1)),
 423                     dt_node_type_name(xnp, n2, sizeof (n2)));
 424         }
 425 
 426         assert(dnp->dn_ident->di_flags & DT_IDFLG_ORPHAN);
 427         assert(dnp->dn_ident->di_id == idp->di_id);
 428 }
 429 
 430 static void
 431 dt_idcook_regs(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *ap)
 432 {
 433         dtrace_typeinfo_t dtt;
 434         dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 435         char n[DT_TYPE_NAMELEN];
 436 
 437         if (argc != 1) {


 443         if (ap->dn_kind != DT_NODE_INT) {
 444                 xyerror(D_PROTO_ARG, "%s[ ] argument #1 is incompatible with "
 445                     "prototype:\n\tprototype: %s\n\t argument: %s\n",
 446                     idp->di_name, "integer constant",
 447                     dt_type_name(ap->dn_ctfp, ap->dn_type, n, sizeof (n)));
 448         }
 449 
 450         if ((ap->dn_flags & DT_NF_SIGNED) && (int64_t)ap->dn_value < 0) {
 451                 xyerror(D_REGS_IDX, "index %lld is out of range for array %s\n",
 452                     (longlong_t)ap->dn_value, idp->di_name);
 453         }
 454 
 455         if (dt_type_lookup("uint64_t", &dtt) == -1) {
 456                 xyerror(D_UNKNOWN, "failed to resolve type of %s: %s\n",
 457                     idp->di_name, dtrace_errmsg(dtp, dtrace_errno(dtp)));
 458         }
 459 
 460         idp->di_ctfp = dtt.dtt_ctfp;
 461         idp->di_type = dtt.dtt_type;
 462 
 463         dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 464 }
 465 
 466 /*ARGSUSED*/
 467 static void
 468 dt_idcook_type(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 469 {
 470         if (idp->di_type == CTF_ERR) {
 471                 dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 472                 dtrace_typeinfo_t dtt;
 473 
 474                 if (dt_type_lookup(idp->di_iarg, &dtt) == -1) {
 475                         xyerror(D_UNKNOWN,
 476                             "failed to resolve type %s for identifier %s: %s\n",
 477                             (const char *)idp->di_iarg, idp->di_name,
 478                             dtrace_errmsg(dtp, dtrace_errno(dtp)));
 479                 }
 480 
 481                 idp->di_ctfp = dtt.dtt_ctfp;
 482                 idp->di_type = dtt.dtt_type;
 483         }
 484 
 485         dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 486 }
 487 
 488 /*ARGSUSED*/
 489 static void
 490 dt_idcook_thaw(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 491 {
 492         if (idp->di_ctfp != NULL && idp->di_type != CTF_ERR)
 493                 dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 494 }
 495 
 496 static void
 497 dt_idcook_inline(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 498 {
 499         if (idp->di_kind == DT_IDENT_ARRAY)
 500                 dt_idcook_assc(dnp, idp, argc, args);
 501         else
 502                 dt_idcook_thaw(dnp, idp, argc, args);
 503 }
 504 
 505 static void
 506 dt_iddtor_sign(dt_ident_t *idp)
 507 {
 508         if (idp->di_data != NULL)
 509                 free(((dt_idsig_t *)idp->di_data)->dis_args);
 510         free(idp->di_data);
 511 }
 512 
 513 static void