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  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 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 <strings.h>
  30 #include <assert.h>
  31 
  32 #include <dt_xlator.h>
  33 #include <dt_parser.h>
  34 #include <dt_grammar.h>
  35 #include <dt_module.h>
  36 #include <dt_impl.h>
  37 
  38 /*
  39  * Create a member node corresponding to one of the output members of a dynamic
  40  * translator.  We set the member's dn_membexpr to a DT_NODE_XLATOR node that
  41  * has dn_op set to DT_TOK_XLATE and refers back to the translator itself.  The
  42  * code generator will then use this as the indicator for dynamic translation.
  43  */
  44 /*ARGSUSED*/
  45 static int
  46 dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
  47 {


  52         if ((enp = dt_node_xalloc(dtp, DT_NODE_XLATOR)) == NULL)
  53                 return (dt_set_errno(dtp, EDT_NOMEM));
  54 
  55         enp->dn_link = dxp->dx_nodes;
  56         dxp->dx_nodes = enp;
  57 
  58         if ((mnp = dt_node_xalloc(dtp, DT_NODE_MEMBER)) == NULL)
  59                 return (dt_set_errno(dtp, EDT_NOMEM));
  60 
  61         mnp->dn_link = dxp->dx_nodes;
  62         dxp->dx_nodes = mnp;
  63 
  64         /*
  65          * For the member expression, we use a DT_NODE_XLATOR/TOK_XLATE whose
  66          * xlator refers back to the translator and whose dn_xmember refers to
  67          * the current member.  These refs will be used by dt_cg.c and dt_as.c.
  68          */
  69         enp->dn_op = DT_TOK_XLATE;
  70         enp->dn_xlator = dxp;
  71         enp->dn_xmember = mnp;
  72         dt_node_type_assign(enp, dxp->dx_dst_ctfp, type);
  73 
  74         /*
  75          * For the member itself, we use a DT_NODE_MEMBER as usual with the
  76          * appropriate name, output type, and member expression set to 'enp'.
  77          */
  78         if (dxp->dx_members != NULL) {
  79                 assert(enp->dn_link->dn_kind == DT_NODE_MEMBER);
  80                 enp->dn_link->dn_list = mnp;
  81         } else
  82                 dxp->dx_members = mnp;
  83 
  84         mnp->dn_membname = strdup(name);
  85         mnp->dn_membexpr = enp;
  86         dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type);
  87 
  88         if (mnp->dn_membname == NULL)
  89                 return (dt_set_errno(dtp, EDT_NOMEM));
  90 
  91         return (0);
  92 }
  93 
  94 dt_xlator_t *
  95 dt_xlator_create(dtrace_hdl_t *dtp,
  96     const dtrace_typeinfo_t *src, const dtrace_typeinfo_t *dst,
  97     const char *name, dt_node_t *members, dt_node_t *nodes)
  98 {
  99         dt_xlator_t *dxp = dt_zalloc(dtp, sizeof (dt_xlator_t));
 100         dtrace_typeinfo_t ptr = *dst;
 101         dt_xlator_t **map;
 102         dt_node_t *dnp;
 103         uint_t kind;
 104 
 105         if (dxp == NULL)
 106                 return (NULL);


 301                     src_ctfp, src_type) &&
 302                     ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
 303                     dst_ctfp, dst_base))
 304                         goto out;
 305         }
 306 
 307         if (flags & DT_XLATE_EXACT)
 308                 goto out; /* skip remaining passes if exact match required */
 309 
 310         for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL;
 311             dxp = dt_list_next(dxp)) {
 312                 if (ctf_type_compat(dxp->dx_src_ctfp, dxp->dx_src_base,
 313                     src_ctfp, src_type) &&
 314                     ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
 315                     dst_ctfp, dst_base))
 316                         goto out;
 317         }
 318 
 319         for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL;
 320             dxp = dt_list_next(dxp)) {
 321                 dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type);

 322                 if (ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
 323                     dst_ctfp, dst_base) && dt_node_is_argcompat(src, &xn))
 324                         goto out;
 325         }
 326 
 327 out:
 328         if (ptr && dxp != NULL && dxp->dx_ptrid.di_type == CTF_ERR)
 329                 return (NULL);  /* no translation available to pointer type */
 330 
 331         if (dxp != NULL || !(flags & DT_XLATE_EXTERN) ||
 332             dtp->dt_xlatemode == DT_XL_STATIC)
 333                 return (dxp);   /* we succeeded or not allowed to extern */
 334 
 335         /*
 336          * If we get here, then we didn't find an existing translator, but the
 337          * caller and xlatemode permit us to create an extern to a dynamic one.
 338          */
 339         src_dtt.dtt_object = dt_module_lookup_by_ctf(dtp, src_ctfp)->dm_name;
 340         src_dtt.dtt_ctfp = src_ctfp;
 341         src_dtt.dtt_type = src_type;




   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright (c) 2013 by Delphix. All rights reserved.
  28  * Copyright (c) 2013 Joyent, Inc. All rights reserved.
  29  */
  30 
  31 #include <strings.h>
  32 #include <assert.h>
  33 
  34 #include <dt_xlator.h>
  35 #include <dt_parser.h>
  36 #include <dt_grammar.h>
  37 #include <dt_module.h>
  38 #include <dt_impl.h>
  39 
  40 /*
  41  * Create a member node corresponding to one of the output members of a dynamic
  42  * translator.  We set the member's dn_membexpr to a DT_NODE_XLATOR node that
  43  * has dn_op set to DT_TOK_XLATE and refers back to the translator itself.  The
  44  * code generator will then use this as the indicator for dynamic translation.
  45  */
  46 /*ARGSUSED*/
  47 static int
  48 dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
  49 {


  54         if ((enp = dt_node_xalloc(dtp, DT_NODE_XLATOR)) == NULL)
  55                 return (dt_set_errno(dtp, EDT_NOMEM));
  56 
  57         enp->dn_link = dxp->dx_nodes;
  58         dxp->dx_nodes = enp;
  59 
  60         if ((mnp = dt_node_xalloc(dtp, DT_NODE_MEMBER)) == NULL)
  61                 return (dt_set_errno(dtp, EDT_NOMEM));
  62 
  63         mnp->dn_link = dxp->dx_nodes;
  64         dxp->dx_nodes = mnp;
  65 
  66         /*
  67          * For the member expression, we use a DT_NODE_XLATOR/TOK_XLATE whose
  68          * xlator refers back to the translator and whose dn_xmember refers to
  69          * the current member.  These refs will be used by dt_cg.c and dt_as.c.
  70          */
  71         enp->dn_op = DT_TOK_XLATE;
  72         enp->dn_xlator = dxp;
  73         enp->dn_xmember = mnp;
  74         dt_node_type_assign(enp, dxp->dx_dst_ctfp, type, B_FALSE);
  75 
  76         /*
  77          * For the member itself, we use a DT_NODE_MEMBER as usual with the
  78          * appropriate name, output type, and member expression set to 'enp'.
  79          */
  80         if (dxp->dx_members != NULL) {
  81                 assert(enp->dn_link->dn_kind == DT_NODE_MEMBER);
  82                 enp->dn_link->dn_list = mnp;
  83         } else
  84                 dxp->dx_members = mnp;
  85 
  86         mnp->dn_membname = strdup(name);
  87         mnp->dn_membexpr = enp;
  88         dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type, B_FALSE);
  89 
  90         if (mnp->dn_membname == NULL)
  91                 return (dt_set_errno(dtp, EDT_NOMEM));
  92 
  93         return (0);
  94 }
  95 
  96 dt_xlator_t *
  97 dt_xlator_create(dtrace_hdl_t *dtp,
  98     const dtrace_typeinfo_t *src, const dtrace_typeinfo_t *dst,
  99     const char *name, dt_node_t *members, dt_node_t *nodes)
 100 {
 101         dt_xlator_t *dxp = dt_zalloc(dtp, sizeof (dt_xlator_t));
 102         dtrace_typeinfo_t ptr = *dst;
 103         dt_xlator_t **map;
 104         dt_node_t *dnp;
 105         uint_t kind;
 106 
 107         if (dxp == NULL)
 108                 return (NULL);


 303                     src_ctfp, src_type) &&
 304                     ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
 305                     dst_ctfp, dst_base))
 306                         goto out;
 307         }
 308 
 309         if (flags & DT_XLATE_EXACT)
 310                 goto out; /* skip remaining passes if exact match required */
 311 
 312         for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL;
 313             dxp = dt_list_next(dxp)) {
 314                 if (ctf_type_compat(dxp->dx_src_ctfp, dxp->dx_src_base,
 315                     src_ctfp, src_type) &&
 316                     ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
 317                     dst_ctfp, dst_base))
 318                         goto out;
 319         }
 320 
 321         for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL;
 322             dxp = dt_list_next(dxp)) {
 323                 dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type,
 324                     B_FALSE);
 325                 if (ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base,
 326                     dst_ctfp, dst_base) && dt_node_is_argcompat(src, &xn))
 327                         goto out;
 328         }
 329 
 330 out:
 331         if (ptr && dxp != NULL && dxp->dx_ptrid.di_type == CTF_ERR)
 332                 return (NULL);  /* no translation available to pointer type */
 333 
 334         if (dxp != NULL || !(flags & DT_XLATE_EXTERN) ||
 335             dtp->dt_xlatemode == DT_XL_STATIC)
 336                 return (dxp);   /* we succeeded or not allowed to extern */
 337 
 338         /*
 339          * If we get here, then we didn't find an existing translator, but the
 340          * caller and xlatemode permit us to create an extern to a dynamic one.
 341          */
 342         src_dtt.dtt_object = dt_module_lookup_by_ctf(dtp, src_ctfp)->dm_name;
 343         src_dtt.dtt_ctfp = src_ctfp;
 344         src_dtt.dtt_type = src_type;