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;
|