17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 26*a386cc11SRobert Mustacchi /* 27*a386cc11SRobert Mustacchi * Copyright (c) 2013 by Delphix. All rights reserved. 28*a386cc11SRobert Mustacchi * Copyright (c) 2013 Joyent, Inc. All rights reserved. 29*a386cc11SRobert Mustacchi */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <strings.h> 321a7c1b72Smws #include <assert.h> 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include <dt_xlator.h> 351a7c1b72Smws #include <dt_parser.h> 361a7c1b72Smws #include <dt_grammar.h> 371a7c1b72Smws #include <dt_module.h> 387c478bd9Sstevel@tonic-gate #include <dt_impl.h> 397c478bd9Sstevel@tonic-gate 401a7c1b72Smws /* 411a7c1b72Smws * Create a member node corresponding to one of the output members of a dynamic 421a7c1b72Smws * translator. We set the member's dn_membexpr to a DT_NODE_XLATOR node that 431a7c1b72Smws * has dn_op set to DT_TOK_XLATE and refers back to the translator itself. The 441a7c1b72Smws * code generator will then use this as the indicator for dynamic translation. 451a7c1b72Smws */ 461a7c1b72Smws /*ARGSUSED*/ 471a7c1b72Smws static int 481a7c1b72Smws dt_xlator_create_member(const char *name, ctf_id_t type, ulong_t off, void *arg) 491a7c1b72Smws { 501a7c1b72Smws dt_xlator_t *dxp = arg; 511a7c1b72Smws dtrace_hdl_t *dtp = dxp->dx_hdl; 521a7c1b72Smws dt_node_t *enp, *mnp; 531a7c1b72Smws 541a7c1b72Smws if ((enp = dt_node_xalloc(dtp, DT_NODE_XLATOR)) == NULL) 551a7c1b72Smws return (dt_set_errno(dtp, EDT_NOMEM)); 561a7c1b72Smws 571a7c1b72Smws enp->dn_link = dxp->dx_nodes; 581a7c1b72Smws dxp->dx_nodes = enp; 591a7c1b72Smws 601a7c1b72Smws if ((mnp = dt_node_xalloc(dtp, DT_NODE_MEMBER)) == NULL) 611a7c1b72Smws return (dt_set_errno(dtp, EDT_NOMEM)); 621a7c1b72Smws 631a7c1b72Smws mnp->dn_link = dxp->dx_nodes; 641a7c1b72Smws dxp->dx_nodes = mnp; 651a7c1b72Smws 661a7c1b72Smws /* 671a7c1b72Smws * For the member expression, we use a DT_NODE_XLATOR/TOK_XLATE whose 681a7c1b72Smws * xlator refers back to the translator and whose dn_xmember refers to 691a7c1b72Smws * the current member. These refs will be used by dt_cg.c and dt_as.c. 701a7c1b72Smws */ 711a7c1b72Smws enp->dn_op = DT_TOK_XLATE; 721a7c1b72Smws enp->dn_xlator = dxp; 731a7c1b72Smws enp->dn_xmember = mnp; 74*a386cc11SRobert Mustacchi dt_node_type_assign(enp, dxp->dx_dst_ctfp, type, B_FALSE); 751a7c1b72Smws 761a7c1b72Smws /* 771a7c1b72Smws * For the member itself, we use a DT_NODE_MEMBER as usual with the 781a7c1b72Smws * appropriate name, output type, and member expression set to 'enp'. 791a7c1b72Smws */ 801a7c1b72Smws if (dxp->dx_members != NULL) { 811a7c1b72Smws assert(enp->dn_link->dn_kind == DT_NODE_MEMBER); 821a7c1b72Smws enp->dn_link->dn_list = mnp; 831a7c1b72Smws } else 841a7c1b72Smws dxp->dx_members = mnp; 851a7c1b72Smws 861a7c1b72Smws mnp->dn_membname = strdup(name); 871a7c1b72Smws mnp->dn_membexpr = enp; 88*a386cc11SRobert Mustacchi dt_node_type_assign(mnp, dxp->dx_dst_ctfp, type, B_FALSE); 891a7c1b72Smws 901a7c1b72Smws if (mnp->dn_membname == NULL) 911a7c1b72Smws return (dt_set_errno(dtp, EDT_NOMEM)); 921a7c1b72Smws 931a7c1b72Smws return (0); 941a7c1b72Smws } 951a7c1b72Smws 967c478bd9Sstevel@tonic-gate dt_xlator_t * 977c478bd9Sstevel@tonic-gate dt_xlator_create(dtrace_hdl_t *dtp, 987c478bd9Sstevel@tonic-gate const dtrace_typeinfo_t *src, const dtrace_typeinfo_t *dst, 997c478bd9Sstevel@tonic-gate const char *name, dt_node_t *members, dt_node_t *nodes) 1007c478bd9Sstevel@tonic-gate { 1011a7c1b72Smws dt_xlator_t *dxp = dt_zalloc(dtp, sizeof (dt_xlator_t)); 1027c478bd9Sstevel@tonic-gate dtrace_typeinfo_t ptr = *dst; 1031a7c1b72Smws dt_xlator_t **map; 1041a7c1b72Smws dt_node_t *dnp; 1051a7c1b72Smws uint_t kind; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate if (dxp == NULL) 1087c478bd9Sstevel@tonic-gate return (NULL); 1097c478bd9Sstevel@tonic-gate 1101a7c1b72Smws dxp->dx_hdl = dtp; 1111a7c1b72Smws dxp->dx_id = dtp->dt_xlatorid++; 1121a7c1b72Smws dxp->dx_gen = dtp->dt_gen; 1131a7c1b72Smws dxp->dx_arg = -1; 1141a7c1b72Smws 1151a7c1b72Smws if ((map = dt_alloc(dtp, sizeof (void *) * (dxp->dx_id + 1))) == NULL) { 1161a7c1b72Smws dt_free(dtp, dxp); 1171a7c1b72Smws return (NULL); 1181a7c1b72Smws } 1191a7c1b72Smws 1201a7c1b72Smws dt_list_append(&dtp->dt_xlators, dxp); 1211a7c1b72Smws bcopy(dtp->dt_xlatormap, map, sizeof (void *) * dxp->dx_id); 1221a7c1b72Smws dt_free(dtp, dtp->dt_xlatormap); 1231a7c1b72Smws dtp->dt_xlatormap = map; 1241a7c1b72Smws dtp->dt_xlatormap[dxp->dx_id] = dxp; 1251a7c1b72Smws 1267c478bd9Sstevel@tonic-gate if (dt_type_pointer(&ptr) == -1) { 1277c478bd9Sstevel@tonic-gate ptr.dtt_ctfp = NULL; 1287c478bd9Sstevel@tonic-gate ptr.dtt_type = CTF_ERR; 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate 1311a7c1b72Smws dxp->dx_ident = dt_ident_create(name ? name : "T", 1321a7c1b72Smws DT_IDENT_SCALAR, DT_IDFLG_REF | DT_IDFLG_ORPHAN, 0, 1331a7c1b72Smws _dtrace_defattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen); 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate if (dxp->dx_ident == NULL) 1367c478bd9Sstevel@tonic-gate goto err; /* no memory for identifier */ 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate dxp->dx_ident->di_ctfp = src->dtt_ctfp; 1397c478bd9Sstevel@tonic-gate dxp->dx_ident->di_type = src->dtt_type; 1407c478bd9Sstevel@tonic-gate 1411a7c1b72Smws /* 1421a7c1b72Smws * If an input parameter name is given, this is a static translator 1431a7c1b72Smws * definition: create an idhash and identifier for the parameter. 1441a7c1b72Smws */ 1451a7c1b72Smws if (name != NULL) { 1461a7c1b72Smws dxp->dx_locals = dt_idhash_create("xlparams", NULL, 0, 0); 1471a7c1b72Smws 1481a7c1b72Smws if (dxp->dx_locals == NULL) 1491a7c1b72Smws goto err; /* no memory for identifier hash */ 1501a7c1b72Smws 1511a7c1b72Smws dt_idhash_xinsert(dxp->dx_locals, dxp->dx_ident); 1521a7c1b72Smws } 1531a7c1b72Smws 1547c478bd9Sstevel@tonic-gate dxp->dx_souid.di_name = "translator"; 1557c478bd9Sstevel@tonic-gate dxp->dx_souid.di_kind = DT_IDENT_XLSOU; 1567c478bd9Sstevel@tonic-gate dxp->dx_souid.di_flags = DT_IDFLG_REF; 1571a7c1b72Smws dxp->dx_souid.di_id = dxp->dx_id; 1587c478bd9Sstevel@tonic-gate dxp->dx_souid.di_attr = _dtrace_defattr; 1597c478bd9Sstevel@tonic-gate dxp->dx_souid.di_ops = &dt_idops_thaw; 1607c478bd9Sstevel@tonic-gate dxp->dx_souid.di_data = dxp; 1617c478bd9Sstevel@tonic-gate dxp->dx_souid.di_ctfp = dst->dtt_ctfp; 1627c478bd9Sstevel@tonic-gate dxp->dx_souid.di_type = dst->dtt_type; 1637c478bd9Sstevel@tonic-gate dxp->dx_souid.di_gen = dtp->dt_gen; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_name = "translator"; 1667c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_kind = DT_IDENT_XLPTR; 1677c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_flags = DT_IDFLG_REF; 1681a7c1b72Smws dxp->dx_ptrid.di_id = dxp->dx_id; 1697c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_attr = _dtrace_defattr; 1707c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_ops = &dt_idops_thaw; 1717c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_data = dxp; 1727c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_ctfp = ptr.dtt_ctfp; 1737c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_type = ptr.dtt_type; 1747c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_gen = dtp->dt_gen; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /* 1777c478bd9Sstevel@tonic-gate * If a deferred pragma is pending on the keyword "translator", run all 1787c478bd9Sstevel@tonic-gate * the deferred pragmas on dx_souid and then copy results to dx_ptrid. 1797c478bd9Sstevel@tonic-gate * See the code in dt_pragma.c for details on deferred ident pragmas. 1807c478bd9Sstevel@tonic-gate */ 1817c478bd9Sstevel@tonic-gate if (dtp->dt_globals->dh_defer != NULL && yypcb->pcb_pragmas != NULL && 1827c478bd9Sstevel@tonic-gate dt_idhash_lookup(yypcb->pcb_pragmas, "translator") != NULL) { 1837c478bd9Sstevel@tonic-gate dtp->dt_globals->dh_defer(dtp->dt_globals, &dxp->dx_souid); 1847c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_attr = dxp->dx_souid.di_attr; 1857c478bd9Sstevel@tonic-gate dxp->dx_ptrid.di_vers = dxp->dx_souid.di_vers; 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate dxp->dx_src_ctfp = src->dtt_ctfp; 1897c478bd9Sstevel@tonic-gate dxp->dx_src_type = src->dtt_type; 1907c478bd9Sstevel@tonic-gate dxp->dx_src_base = ctf_type_resolve(src->dtt_ctfp, src->dtt_type); 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate dxp->dx_dst_ctfp = dst->dtt_ctfp; 1937c478bd9Sstevel@tonic-gate dxp->dx_dst_type = dst->dtt_type; 1947c478bd9Sstevel@tonic-gate dxp->dx_dst_base = ctf_type_resolve(dst->dtt_ctfp, dst->dtt_type); 1957c478bd9Sstevel@tonic-gate 1961a7c1b72Smws kind = ctf_type_kind(dst->dtt_ctfp, dxp->dx_dst_base); 1971a7c1b72Smws assert(kind == CTF_K_STRUCT || kind == CTF_K_UNION); 1981a7c1b72Smws 1991a7c1b72Smws /* 2001a7c1b72Smws * If no input parameter is given, we're making a dynamic translator: 2011a7c1b72Smws * create member nodes for every member of the output type. Otherwise 2021a7c1b72Smws * retain the member and allocation node lists presented by the parser. 2031a7c1b72Smws */ 2041a7c1b72Smws if (name == NULL) { 2051a7c1b72Smws if (ctf_member_iter(dxp->dx_dst_ctfp, dxp->dx_dst_base, 2061a7c1b72Smws dt_xlator_create_member, dxp) != 0) 2071a7c1b72Smws goto err; 2081a7c1b72Smws } else { 2097c478bd9Sstevel@tonic-gate dxp->dx_members = members; 2107c478bd9Sstevel@tonic-gate dxp->dx_nodes = nodes; 2111a7c1b72Smws } 2121a7c1b72Smws 2131a7c1b72Smws /* 2141a7c1b72Smws * Assign member IDs to each member and allocate space for DIFOs 2151a7c1b72Smws * if and when this translator is eventually compiled. 2161a7c1b72Smws */ 2171a7c1b72Smws for (dnp = dxp->dx_members; dnp != NULL; dnp = dnp->dn_list) { 2181a7c1b72Smws dnp->dn_membxlator = dxp; 2191a7c1b72Smws dnp->dn_membid = dxp->dx_nmembers++; 2201a7c1b72Smws } 2211a7c1b72Smws 2221a7c1b72Smws dxp->dx_membdif = dt_zalloc(dtp, 2231a7c1b72Smws sizeof (dtrace_difo_t *) * dxp->dx_nmembers); 2241a7c1b72Smws 2251a7c1b72Smws if (dxp->dx_membdif == NULL) { 2261a7c1b72Smws dxp->dx_nmembers = 0; 2271a7c1b72Smws goto err; 2281a7c1b72Smws } 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate return (dxp); 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate err: 2337c478bd9Sstevel@tonic-gate dt_xlator_destroy(dtp, dxp); 2347c478bd9Sstevel@tonic-gate return (NULL); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate void 2387c478bd9Sstevel@tonic-gate dt_xlator_destroy(dtrace_hdl_t *dtp, dt_xlator_t *dxp) 2397c478bd9Sstevel@tonic-gate { 2401a7c1b72Smws uint_t i; 2411a7c1b72Smws 2427c478bd9Sstevel@tonic-gate dt_node_link_free(&dxp->dx_nodes); 2431a7c1b72Smws 2441a7c1b72Smws if (dxp->dx_locals != NULL) 2457c478bd9Sstevel@tonic-gate dt_idhash_destroy(dxp->dx_locals); 2461a7c1b72Smws else if (dxp->dx_ident != NULL) 2471a7c1b72Smws dt_ident_destroy(dxp->dx_ident); 2481a7c1b72Smws 2491a7c1b72Smws for (i = 0; i < dxp->dx_nmembers; i++) 2501a7c1b72Smws dt_difo_free(dtp, dxp->dx_membdif[i]); 2511a7c1b72Smws 2521a7c1b72Smws dt_free(dtp, dxp->dx_membdif); 2537c478bd9Sstevel@tonic-gate dt_list_delete(&dtp->dt_xlators, dxp); 2541a7c1b72Smws dt_free(dtp, dxp); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate dt_xlator_t * 2581a7c1b72Smws dt_xlator_lookup(dtrace_hdl_t *dtp, dt_node_t *src, dt_node_t *dst, int flags) 2597c478bd9Sstevel@tonic-gate { 2607c478bd9Sstevel@tonic-gate ctf_file_t *src_ctfp = src->dn_ctfp; 2617c478bd9Sstevel@tonic-gate ctf_id_t src_type = src->dn_type; 2627c478bd9Sstevel@tonic-gate ctf_id_t src_base = ctf_type_resolve(src_ctfp, src_type); 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate ctf_file_t *dst_ctfp = dst->dn_ctfp; 2657c478bd9Sstevel@tonic-gate ctf_id_t dst_type = dst->dn_type; 2667c478bd9Sstevel@tonic-gate ctf_id_t dst_base = ctf_type_resolve(dst_ctfp, dst_type); 2671a7c1b72Smws uint_t dst_kind = ctf_type_kind(dst_ctfp, dst_base); 2687c478bd9Sstevel@tonic-gate 2691a7c1b72Smws int ptr = dst_kind == CTF_K_POINTER; 2701a7c1b72Smws dtrace_typeinfo_t src_dtt, dst_dtt; 2717c478bd9Sstevel@tonic-gate dt_node_t xn = { 0 }; 2721a7c1b72Smws dt_xlator_t *dxp = NULL; 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate if (src_base == CTF_ERR || dst_base == CTF_ERR) 2757c478bd9Sstevel@tonic-gate return (NULL); /* fail if these are unresolvable types */ 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate /* 2787c478bd9Sstevel@tonic-gate * Translators are always defined using a struct or union type, so if 2797c478bd9Sstevel@tonic-gate * we are attempting to translate to type "T *", we internally look 2807c478bd9Sstevel@tonic-gate * for a translation to type "T" by following the pointer reference. 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate if (ptr) { 2837c478bd9Sstevel@tonic-gate dst_type = ctf_type_reference(dst_ctfp, dst_type); 2847c478bd9Sstevel@tonic-gate dst_base = ctf_type_resolve(dst_ctfp, dst_type); 2851a7c1b72Smws dst_kind = ctf_type_kind(dst_ctfp, dst_base); 2867c478bd9Sstevel@tonic-gate } 2877c478bd9Sstevel@tonic-gate 2881a7c1b72Smws if (dst_kind != CTF_K_UNION && dst_kind != CTF_K_STRUCT) 2891a7c1b72Smws return (NULL); /* fail if the output isn't a struct or union */ 2901a7c1b72Smws 2917c478bd9Sstevel@tonic-gate /* 2927c478bd9Sstevel@tonic-gate * In order to find a matching translator, we iterate over the set of 2937c478bd9Sstevel@tonic-gate * available translators in three passes. First, we look for a 2947c478bd9Sstevel@tonic-gate * translation from the exact source type to the resolved destination. 2957c478bd9Sstevel@tonic-gate * Second, we look for a translation from the resolved source type to 2967c478bd9Sstevel@tonic-gate * the resolved destination. Third, we look for a translation from a 2977c478bd9Sstevel@tonic-gate * compatible source type (using the same rules as parameter formals) 2987c478bd9Sstevel@tonic-gate * to the resolved destination. If all passes fail, return NULL. 2997c478bd9Sstevel@tonic-gate */ 3007c478bd9Sstevel@tonic-gate for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL; 3017c478bd9Sstevel@tonic-gate dxp = dt_list_next(dxp)) { 3027c478bd9Sstevel@tonic-gate if (ctf_type_compat(dxp->dx_src_ctfp, dxp->dx_src_type, 3037c478bd9Sstevel@tonic-gate src_ctfp, src_type) && 3047c478bd9Sstevel@tonic-gate ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base, 3057c478bd9Sstevel@tonic-gate dst_ctfp, dst_base)) 3067c478bd9Sstevel@tonic-gate goto out; 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3091a7c1b72Smws if (flags & DT_XLATE_EXACT) 3107c478bd9Sstevel@tonic-gate goto out; /* skip remaining passes if exact match required */ 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL; 3137c478bd9Sstevel@tonic-gate dxp = dt_list_next(dxp)) { 3147c478bd9Sstevel@tonic-gate if (ctf_type_compat(dxp->dx_src_ctfp, dxp->dx_src_base, 3157c478bd9Sstevel@tonic-gate src_ctfp, src_type) && 3167c478bd9Sstevel@tonic-gate ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base, 3177c478bd9Sstevel@tonic-gate dst_ctfp, dst_base)) 3187c478bd9Sstevel@tonic-gate goto out; 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL; 3227c478bd9Sstevel@tonic-gate dxp = dt_list_next(dxp)) { 323*a386cc11SRobert Mustacchi dt_node_type_assign(&xn, dxp->dx_src_ctfp, dxp->dx_src_type, 324*a386cc11SRobert Mustacchi B_FALSE); 3257c478bd9Sstevel@tonic-gate if (ctf_type_compat(dxp->dx_dst_ctfp, dxp->dx_dst_base, 3267c478bd9Sstevel@tonic-gate dst_ctfp, dst_base) && dt_node_is_argcompat(src, &xn)) 3277c478bd9Sstevel@tonic-gate goto out; 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate out: 3317c478bd9Sstevel@tonic-gate if (ptr && dxp != NULL && dxp->dx_ptrid.di_type == CTF_ERR) 3327c478bd9Sstevel@tonic-gate return (NULL); /* no translation available to pointer type */ 3337c478bd9Sstevel@tonic-gate 3341a7c1b72Smws if (dxp != NULL || !(flags & DT_XLATE_EXTERN) || 3351a7c1b72Smws dtp->dt_xlatemode == DT_XL_STATIC) 3361a7c1b72Smws return (dxp); /* we succeeded or not allowed to extern */ 3371a7c1b72Smws 3381a7c1b72Smws /* 3391a7c1b72Smws * If we get here, then we didn't find an existing translator, but the 3401a7c1b72Smws * caller and xlatemode permit us to create an extern to a dynamic one. 3411a7c1b72Smws */ 3421a7c1b72Smws src_dtt.dtt_object = dt_module_lookup_by_ctf(dtp, src_ctfp)->dm_name; 3431a7c1b72Smws src_dtt.dtt_ctfp = src_ctfp; 3441a7c1b72Smws src_dtt.dtt_type = src_type; 3451a7c1b72Smws 3461a7c1b72Smws dst_dtt.dtt_object = dt_module_lookup_by_ctf(dtp, dst_ctfp)->dm_name; 3471a7c1b72Smws dst_dtt.dtt_ctfp = dst_ctfp; 3481a7c1b72Smws dst_dtt.dtt_type = dst_type; 3491a7c1b72Smws 3501a7c1b72Smws return (dt_xlator_create(dtp, &src_dtt, &dst_dtt, NULL, NULL, NULL)); 3511a7c1b72Smws } 3521a7c1b72Smws 3531a7c1b72Smws dt_xlator_t * 3541a7c1b72Smws dt_xlator_lookup_id(dtrace_hdl_t *dtp, id_t id) 3551a7c1b72Smws { 3561a7c1b72Smws assert(id >= 0 && id < dtp->dt_xlatorid); 3571a7c1b72Smws return (dtp->dt_xlatormap[id]); 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate dt_ident_t * 3617c478bd9Sstevel@tonic-gate dt_xlator_ident(dt_xlator_t *dxp, ctf_file_t *ctfp, ctf_id_t type) 3627c478bd9Sstevel@tonic-gate { 3637c478bd9Sstevel@tonic-gate if (ctf_type_kind(ctfp, ctf_type_resolve(ctfp, type)) == CTF_K_POINTER) 3647c478bd9Sstevel@tonic-gate return (&dxp->dx_ptrid); 3657c478bd9Sstevel@tonic-gate else 3667c478bd9Sstevel@tonic-gate return (&dxp->dx_souid); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate dt_node_t * 3707c478bd9Sstevel@tonic-gate dt_xlator_member(dt_xlator_t *dxp, const char *name) 3717c478bd9Sstevel@tonic-gate { 3727c478bd9Sstevel@tonic-gate dt_node_t *dnp; 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate for (dnp = dxp->dx_members; dnp != NULL; dnp = dnp->dn_list) { 3757c478bd9Sstevel@tonic-gate if (strcmp(dnp->dn_membname, name) == 0) 3767c478bd9Sstevel@tonic-gate return (dnp); 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate return (NULL); 3807c478bd9Sstevel@tonic-gate } 3811a7c1b72Smws 3821a7c1b72Smws int 3831a7c1b72Smws dt_xlator_dynamic(const dt_xlator_t *dxp) 3841a7c1b72Smws { 3851a7c1b72Smws return (dxp->dx_locals == NULL); 3861a7c1b72Smws } 387