dt_parser.c revision 178567
1178479Sjb/* 2178479Sjb * CDDL HEADER START 3178479Sjb * 4178479Sjb * The contents of this file are subject to the terms of the 5178479Sjb * Common Development and Distribution License, Version 1.0 only 6178479Sjb * (the "License"). You may not use this file except in compliance 7178479Sjb * with the License. 8178479Sjb * 9178479Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10178479Sjb * or http://www.opensolaris.org/os/licensing. 11178479Sjb * See the License for the specific language governing permissions 12178479Sjb * and limitations under the License. 13178479Sjb * 14178479Sjb * When distributing Covered Code, include this CDDL HEADER in each 15178479Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16178479Sjb * If applicable, add the following below this CDDL HEADER, with the 17178479Sjb * fields enclosed by brackets "[]" replaced with your own identifying 18178479Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 19178479Sjb * 20178479Sjb * CDDL HEADER END 21178479Sjb */ 22178479Sjb 23178479Sjb/* 24178479Sjb * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25178479Sjb * Use is subject to license terms. 26178479Sjb */ 27178479Sjb 28178479Sjb#pragma ident "%Z%%M% %I% %E% SMI" 29178479Sjb 30178479Sjb/* 31178479Sjb * DTrace D Language Parser 32178479Sjb * 33178479Sjb * The D Parser is a lex/yacc parser consisting of the lexer dt_lex.l, the 34178479Sjb * parsing grammar dt_grammar.y, and this file, dt_parser.c, which handles 35178479Sjb * the construction of the parse tree nodes and their syntactic validation. 36178479Sjb * The parse tree is constructed of dt_node_t structures (see <dt_parser.h>) 37178479Sjb * that are built in two passes: (1) the "create" pass, where the parse tree 38178479Sjb * nodes are allocated by calls from the grammar to dt_node_*() subroutines, 39178479Sjb * and (2) the "cook" pass, where nodes are coalesced, assigned D types, and 40178479Sjb * validated according to the syntactic rules of the language. 41178479Sjb * 42178479Sjb * All node allocations are performed using dt_node_alloc(). All node frees 43178479Sjb * during the parsing phase are performed by dt_node_free(), which frees node- 44178479Sjb * internal state but does not actually free the nodes. All final node frees 45178479Sjb * are done as part of the end of dt_compile() or as part of destroying 46178479Sjb * persistent identifiers or translators which have embedded nodes. 47178479Sjb * 48178479Sjb * The dt_node_* routines that implement pass (1) may allocate new nodes. The 49178479Sjb * dt_cook_* routines that implement pass (2) may *not* allocate new nodes. 50178479Sjb * They may free existing nodes using dt_node_free(), but they may not actually 51178479Sjb * deallocate any dt_node_t's. Currently dt_cook_op2() is an exception to this 52178479Sjb * rule: see the comments therein for how this issue is resolved. 53178479Sjb * 54178479Sjb * The dt_cook_* routines are responsible for (at minimum) setting the final 55178479Sjb * node type (dn_ctfp/dn_type) and attributes (dn_attr). If dn_ctfp/dn_type 56178479Sjb * are set manually (i.e. not by one of the type assignment functions), then 57178479Sjb * the DT_NF_COOKED flag must be set manually on the node. 58178479Sjb * 59178479Sjb * The cooking pass can be applied to the same parse tree more than once (used 60178479Sjb * in the case of a comma-separated list of probe descriptions). As such, the 61178479Sjb * cook routines must not perform any parse tree transformations which would 62178479Sjb * be invalid if the tree were subsequently cooked using a different context. 63178479Sjb * 64178479Sjb * The dn_ctfp and dn_type fields form the type of the node. This tuple can 65178479Sjb * take on the following set of values, which form our type invariants: 66178479Sjb * 67178479Sjb * 1. dn_ctfp = NULL, dn_type = CTF_ERR 68178479Sjb * 69178479Sjb * In this state, the node has unknown type and is not yet cooked. The 70178479Sjb * DT_NF_COOKED flag is not yet set on the node. 71178479Sjb * 72178479Sjb * 2. dn_ctfp = DT_DYN_CTFP(dtp), dn_type = DT_DYN_TYPE(dtp) 73178479Sjb * 74178479Sjb * In this state, the node is a dynamic D type. This means that generic 75178479Sjb * operations are not valid on this node and only code that knows how to 76178479Sjb * examine the inner details of the node can operate on it. A <DYN> node 77178479Sjb * must have dn_ident set to point to an identifier describing the object 78178479Sjb * and its type. The DT_NF_REF flag is set for all nodes of type <DYN>. 79178479Sjb * At present, the D compiler uses the <DYN> type for: 80178479Sjb * 81178479Sjb * - associative arrays that do not yet have a value type defined 82178479Sjb * - translated data (i.e. the result of the xlate operator) 83178479Sjb * - aggregations 84178479Sjb * 85178479Sjb * 3. dn_ctfp = DT_STR_CTFP(dtp), dn_type = DT_STR_TYPE(dtp) 86178479Sjb * 87178479Sjb * In this state, the node is of type D string. The string type is really 88178479Sjb * a char[0] typedef, but requires special handling throughout the compiler. 89178479Sjb * 90178479Sjb * 4. dn_ctfp != NULL, dn_type = any other type ID 91178479Sjb * 92178479Sjb * In this state, the node is of some known D/CTF type. The normal libctf 93178479Sjb * APIs can be used to learn more about the type name or structure. When 94178479Sjb * the type is assigned, the DT_NF_SIGNED, DT_NF_REF, and DT_NF_BITFIELD 95178479Sjb * flags cache the corresponding attributes of the underlying CTF type. 96178479Sjb */ 97178479Sjb 98178479Sjb#include <sys/param.h> 99178479Sjb#include <limits.h> 100178479Sjb#include <setjmp.h> 101178479Sjb#include <strings.h> 102178479Sjb#include <assert.h> 103178567Sjb#if defined(sun) 104178479Sjb#include <alloca.h> 105178567Sjb#endif 106178479Sjb#include <stdlib.h> 107178479Sjb#include <stdarg.h> 108178479Sjb#include <stdio.h> 109178479Sjb#include <errno.h> 110178479Sjb#include <ctype.h> 111178479Sjb 112178479Sjb#include <dt_impl.h> 113178479Sjb#include <dt_grammar.h> 114178479Sjb#include <dt_module.h> 115178479Sjb#include <dt_provider.h> 116178479Sjb#include <dt_string.h> 117178479Sjb#include <dt_as.h> 118178479Sjb 119178479Sjbdt_pcb_t *yypcb; /* current control block for parser */ 120178479Sjbdt_node_t *yypragma; /* lex token list for control lines */ 121178479Sjbchar yyintprefix; /* int token macro prefix (+/-) */ 122178479Sjbchar yyintsuffix[4]; /* int token suffix string [uU][lL] */ 123178479Sjbint yyintdecimal; /* int token format flag (1=decimal, 0=octal/hex) */ 124178479Sjb 125178479Sjbstatic const char * 126178479Sjbopstr(int op) 127178479Sjb{ 128178479Sjb switch (op) { 129178479Sjb case DT_TOK_COMMA: return (","); 130178479Sjb case DT_TOK_ELLIPSIS: return ("..."); 131178479Sjb case DT_TOK_ASGN: return ("="); 132178479Sjb case DT_TOK_ADD_EQ: return ("+="); 133178479Sjb case DT_TOK_SUB_EQ: return ("-="); 134178479Sjb case DT_TOK_MUL_EQ: return ("*="); 135178479Sjb case DT_TOK_DIV_EQ: return ("/="); 136178479Sjb case DT_TOK_MOD_EQ: return ("%="); 137178479Sjb case DT_TOK_AND_EQ: return ("&="); 138178479Sjb case DT_TOK_XOR_EQ: return ("^="); 139178479Sjb case DT_TOK_OR_EQ: return ("|="); 140178479Sjb case DT_TOK_LSH_EQ: return ("<<="); 141178479Sjb case DT_TOK_RSH_EQ: return (">>="); 142178479Sjb case DT_TOK_QUESTION: return ("?"); 143178479Sjb case DT_TOK_COLON: return (":"); 144178479Sjb case DT_TOK_LOR: return ("||"); 145178479Sjb case DT_TOK_LXOR: return ("^^"); 146178479Sjb case DT_TOK_LAND: return ("&&"); 147178479Sjb case DT_TOK_BOR: return ("|"); 148178479Sjb case DT_TOK_XOR: return ("^"); 149178479Sjb case DT_TOK_BAND: return ("&"); 150178479Sjb case DT_TOK_EQU: return ("=="); 151178479Sjb case DT_TOK_NEQ: return ("!="); 152178479Sjb case DT_TOK_LT: return ("<"); 153178479Sjb case DT_TOK_LE: return ("<="); 154178479Sjb case DT_TOK_GT: return (">"); 155178479Sjb case DT_TOK_GE: return (">="); 156178479Sjb case DT_TOK_LSH: return ("<<"); 157178479Sjb case DT_TOK_RSH: return (">>"); 158178479Sjb case DT_TOK_ADD: return ("+"); 159178479Sjb case DT_TOK_SUB: return ("-"); 160178479Sjb case DT_TOK_MUL: return ("*"); 161178479Sjb case DT_TOK_DIV: return ("/"); 162178479Sjb case DT_TOK_MOD: return ("%"); 163178479Sjb case DT_TOK_LNEG: return ("!"); 164178479Sjb case DT_TOK_BNEG: return ("~"); 165178479Sjb case DT_TOK_ADDADD: return ("++"); 166178479Sjb case DT_TOK_PREINC: return ("++"); 167178479Sjb case DT_TOK_POSTINC: return ("++"); 168178479Sjb case DT_TOK_SUBSUB: return ("--"); 169178479Sjb case DT_TOK_PREDEC: return ("--"); 170178479Sjb case DT_TOK_POSTDEC: return ("--"); 171178479Sjb case DT_TOK_IPOS: return ("+"); 172178479Sjb case DT_TOK_INEG: return ("-"); 173178479Sjb case DT_TOK_DEREF: return ("*"); 174178479Sjb case DT_TOK_ADDROF: return ("&"); 175178479Sjb case DT_TOK_OFFSETOF: return ("offsetof"); 176178479Sjb case DT_TOK_SIZEOF: return ("sizeof"); 177178479Sjb case DT_TOK_STRINGOF: return ("stringof"); 178178479Sjb case DT_TOK_XLATE: return ("xlate"); 179178479Sjb case DT_TOK_LPAR: return ("("); 180178479Sjb case DT_TOK_RPAR: return (")"); 181178479Sjb case DT_TOK_LBRAC: return ("["); 182178479Sjb case DT_TOK_RBRAC: return ("]"); 183178479Sjb case DT_TOK_PTR: return ("->"); 184178479Sjb case DT_TOK_DOT: return ("."); 185178479Sjb case DT_TOK_STRING: return ("<string>"); 186178479Sjb case DT_TOK_IDENT: return ("<ident>"); 187178479Sjb case DT_TOK_TNAME: return ("<type>"); 188178479Sjb case DT_TOK_INT: return ("<int>"); 189178479Sjb default: return ("<?>"); 190178479Sjb } 191178479Sjb} 192178479Sjb 193178479Sjbint 194178479Sjbdt_type_lookup(const char *s, dtrace_typeinfo_t *tip) 195178479Sjb{ 196178479Sjb static const char delimiters[] = " \t\n\r\v\f*`"; 197178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 198178479Sjb const char *p, *q, *end, *obj; 199178479Sjb 200178479Sjb for (p = s, end = s + strlen(s); *p != '\0'; p = q) { 201178479Sjb while (isspace(*p)) 202178479Sjb p++; /* skip leading whitespace prior to token */ 203178479Sjb 204178479Sjb if (p == end || (q = strpbrk(p + 1, delimiters)) == NULL) 205178479Sjb break; /* empty string or single token remaining */ 206178479Sjb 207178479Sjb if (*q == '`') { 208178479Sjb char *object = alloca((size_t)(q - p) + 1); 209178479Sjb char *type = alloca((size_t)(end - s) + 1); 210178479Sjb 211178479Sjb /* 212178479Sjb * Copy from the start of the token (p) to the location 213178479Sjb * backquote (q) to extract the nul-terminated object. 214178479Sjb */ 215178479Sjb bcopy(p, object, (size_t)(q - p)); 216178479Sjb object[(size_t)(q - p)] = '\0'; 217178479Sjb 218178479Sjb /* 219178479Sjb * Copy the original string up to the start of this 220178479Sjb * token (p) into type, and then concatenate everything 221178479Sjb * after q. This is the type name without the object. 222178479Sjb */ 223178479Sjb bcopy(s, type, (size_t)(p - s)); 224178479Sjb bcopy(q + 1, type + (size_t)(p - s), strlen(q + 1) + 1); 225178479Sjb 226178479Sjb if (strchr(q + 1, '`') != NULL) 227178479Sjb return (dt_set_errno(dtp, EDT_BADSCOPE)); 228178479Sjb 229178479Sjb return (dtrace_lookup_by_type(dtp, object, type, tip)); 230178479Sjb } 231178479Sjb } 232178479Sjb 233178479Sjb if (yypcb->pcb_idepth != 0) 234178479Sjb obj = DTRACE_OBJ_CDEFS; 235178479Sjb else 236178479Sjb obj = DTRACE_OBJ_EVERY; 237178479Sjb 238178479Sjb return (dtrace_lookup_by_type(dtp, obj, s, tip)); 239178479Sjb} 240178479Sjb 241178479Sjb/* 242178479Sjb * When we parse type expressions or parse an expression with unary "&", we 243178479Sjb * need to find a type that is a pointer to a previously known type. 244178479Sjb * Unfortunately CTF is limited to a per-container view, so ctf_type_pointer() 245178479Sjb * alone does not suffice for our needs. We provide a more intelligent wrapper 246178479Sjb * for the compiler that attempts to compute a pointer to either the given type 247178479Sjb * or its base (that is, we try both "foo_t *" and "struct foo *"), and also 248178479Sjb * to potentially construct the required type on-the-fly. 249178479Sjb */ 250178479Sjbint 251178479Sjbdt_type_pointer(dtrace_typeinfo_t *tip) 252178479Sjb{ 253178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 254178479Sjb ctf_file_t *ctfp = tip->dtt_ctfp; 255178479Sjb ctf_id_t type = tip->dtt_type; 256178479Sjb ctf_id_t base = ctf_type_resolve(ctfp, type); 257178479Sjb 258178479Sjb dt_module_t *dmp; 259178479Sjb ctf_id_t ptr; 260178479Sjb 261178479Sjb if ((ptr = ctf_type_pointer(ctfp, type)) != CTF_ERR || 262178479Sjb (ptr = ctf_type_pointer(ctfp, base)) != CTF_ERR) { 263178479Sjb tip->dtt_type = ptr; 264178479Sjb return (0); 265178479Sjb } 266178479Sjb 267178479Sjb if (yypcb->pcb_idepth != 0) 268178479Sjb dmp = dtp->dt_cdefs; 269178479Sjb else 270178479Sjb dmp = dtp->dt_ddefs; 271178479Sjb 272178479Sjb if (ctfp != dmp->dm_ctfp && ctfp != ctf_parent_file(dmp->dm_ctfp) && 273178479Sjb (type = ctf_add_type(dmp->dm_ctfp, ctfp, type)) == CTF_ERR) { 274178479Sjb dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp); 275178479Sjb return (dt_set_errno(dtp, EDT_CTF)); 276178479Sjb } 277178479Sjb 278178479Sjb ptr = ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT, type); 279178479Sjb 280178479Sjb if (ptr == CTF_ERR || ctf_update(dmp->dm_ctfp) == CTF_ERR) { 281178479Sjb dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp); 282178479Sjb return (dt_set_errno(dtp, EDT_CTF)); 283178479Sjb } 284178479Sjb 285178479Sjb tip->dtt_object = dmp->dm_name; 286178479Sjb tip->dtt_ctfp = dmp->dm_ctfp; 287178479Sjb tip->dtt_type = ptr; 288178479Sjb 289178479Sjb return (0); 290178479Sjb} 291178479Sjb 292178479Sjbconst char * 293178479Sjbdt_type_name(ctf_file_t *ctfp, ctf_id_t type, char *buf, size_t len) 294178479Sjb{ 295178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 296178479Sjb 297178479Sjb if (ctfp == DT_FPTR_CTFP(dtp) && type == DT_FPTR_TYPE(dtp)) 298178479Sjb (void) snprintf(buf, len, "function pointer"); 299178479Sjb else if (ctfp == DT_FUNC_CTFP(dtp) && type == DT_FUNC_TYPE(dtp)) 300178479Sjb (void) snprintf(buf, len, "function"); 301178479Sjb else if (ctfp == DT_DYN_CTFP(dtp) && type == DT_DYN_TYPE(dtp)) 302178479Sjb (void) snprintf(buf, len, "dynamic variable"); 303178479Sjb else if (ctfp == NULL) 304178479Sjb (void) snprintf(buf, len, "<none>"); 305178479Sjb else if (ctf_type_name(ctfp, type, buf, len) == NULL) 306178479Sjb (void) snprintf(buf, len, "unknown"); 307178479Sjb 308178479Sjb return (buf); 309178479Sjb} 310178479Sjb 311178479Sjb/* 312178479Sjb * Perform the "usual arithmetic conversions" to determine which of the two 313178479Sjb * input operand types should be promoted and used as a result type. The 314178479Sjb * rules for this are described in ISOC[6.3.1.8] and K&R[A6.5]. 315178479Sjb */ 316178479Sjbstatic void 317178479Sjbdt_type_promote(dt_node_t *lp, dt_node_t *rp, ctf_file_t **ofp, ctf_id_t *otype) 318178479Sjb{ 319178479Sjb ctf_file_t *lfp = lp->dn_ctfp; 320178479Sjb ctf_id_t ltype = lp->dn_type; 321178479Sjb 322178479Sjb ctf_file_t *rfp = rp->dn_ctfp; 323178479Sjb ctf_id_t rtype = rp->dn_type; 324178479Sjb 325178479Sjb ctf_id_t lbase = ctf_type_resolve(lfp, ltype); 326178479Sjb uint_t lkind = ctf_type_kind(lfp, lbase); 327178479Sjb 328178479Sjb ctf_id_t rbase = ctf_type_resolve(rfp, rtype); 329178479Sjb uint_t rkind = ctf_type_kind(rfp, rbase); 330178479Sjb 331178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 332178479Sjb ctf_encoding_t le, re; 333178479Sjb uint_t lrank, rrank; 334178479Sjb 335178479Sjb assert(lkind == CTF_K_INTEGER || lkind == CTF_K_ENUM); 336178479Sjb assert(rkind == CTF_K_INTEGER || rkind == CTF_K_ENUM); 337178479Sjb 338178479Sjb if (lkind == CTF_K_ENUM) { 339178479Sjb lfp = DT_INT_CTFP(dtp); 340178479Sjb ltype = lbase = DT_INT_TYPE(dtp); 341178479Sjb } 342178479Sjb 343178479Sjb if (rkind == CTF_K_ENUM) { 344178479Sjb rfp = DT_INT_CTFP(dtp); 345178479Sjb rtype = rbase = DT_INT_TYPE(dtp); 346178479Sjb } 347178479Sjb 348178479Sjb if (ctf_type_encoding(lfp, lbase, &le) == CTF_ERR) { 349178479Sjb yypcb->pcb_hdl->dt_ctferr = ctf_errno(lfp); 350178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_CTF); 351178479Sjb } 352178479Sjb 353178479Sjb if (ctf_type_encoding(rfp, rbase, &re) == CTF_ERR) { 354178479Sjb yypcb->pcb_hdl->dt_ctferr = ctf_errno(rfp); 355178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_CTF); 356178479Sjb } 357178479Sjb 358178479Sjb /* 359178479Sjb * Compute an integer rank based on the size and unsigned status. 360178479Sjb * If rank is identical, pick the "larger" of the equivalent types 361178479Sjb * which we define as having a larger base ctf_id_t. If rank is 362178479Sjb * different, pick the type with the greater rank. 363178479Sjb */ 364178479Sjb lrank = le.cte_bits + ((le.cte_format & CTF_INT_SIGNED) == 0); 365178479Sjb rrank = re.cte_bits + ((re.cte_format & CTF_INT_SIGNED) == 0); 366178479Sjb 367178479Sjb if (lrank == rrank) { 368178479Sjb if (lbase - rbase < 0) 369178479Sjb goto return_rtype; 370178479Sjb else 371178479Sjb goto return_ltype; 372178479Sjb } else if (lrank > rrank) { 373178479Sjb goto return_ltype; 374178479Sjb } else 375178479Sjb goto return_rtype; 376178479Sjb 377178479Sjbreturn_ltype: 378178479Sjb *ofp = lfp; 379178479Sjb *otype = ltype; 380178479Sjb return; 381178479Sjb 382178479Sjbreturn_rtype: 383178479Sjb *ofp = rfp; 384178479Sjb *otype = rtype; 385178479Sjb} 386178479Sjb 387178479Sjbvoid 388178479Sjbdt_node_promote(dt_node_t *lp, dt_node_t *rp, dt_node_t *dnp) 389178479Sjb{ 390178479Sjb dt_type_promote(lp, rp, &dnp->dn_ctfp, &dnp->dn_type); 391178479Sjb dt_node_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type); 392178479Sjb dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 393178479Sjb} 394178479Sjb 395178479Sjbconst char * 396178479Sjbdt_node_name(const dt_node_t *dnp, char *buf, size_t len) 397178479Sjb{ 398178479Sjb char n1[DT_TYPE_NAMELEN]; 399178479Sjb char n2[DT_TYPE_NAMELEN]; 400178479Sjb 401178479Sjb const char *prefix = "", *suffix = ""; 402178479Sjb const dtrace_syminfo_t *dts; 403178479Sjb char *s; 404178479Sjb 405178479Sjb switch (dnp->dn_kind) { 406178479Sjb case DT_NODE_INT: 407178479Sjb (void) snprintf(buf, len, "integer constant 0x%llx", 408178479Sjb (u_longlong_t)dnp->dn_value); 409178479Sjb break; 410178479Sjb case DT_NODE_STRING: 411178479Sjb s = strchr2esc(dnp->dn_string, strlen(dnp->dn_string)); 412178479Sjb (void) snprintf(buf, len, "string constant \"%s\"", 413178479Sjb s != NULL ? s : dnp->dn_string); 414178479Sjb free(s); 415178479Sjb break; 416178479Sjb case DT_NODE_IDENT: 417178479Sjb (void) snprintf(buf, len, "identifier %s", dnp->dn_string); 418178479Sjb break; 419178479Sjb case DT_NODE_VAR: 420178479Sjb case DT_NODE_FUNC: 421178479Sjb case DT_NODE_AGG: 422178479Sjb case DT_NODE_INLINE: 423178479Sjb switch (dnp->dn_ident->di_kind) { 424178479Sjb case DT_IDENT_FUNC: 425178479Sjb case DT_IDENT_AGGFUNC: 426178479Sjb case DT_IDENT_ACTFUNC: 427178479Sjb suffix = "( )"; 428178479Sjb break; 429178479Sjb case DT_IDENT_AGG: 430178479Sjb prefix = "@"; 431178479Sjb break; 432178479Sjb } 433178479Sjb (void) snprintf(buf, len, "%s %s%s%s", 434178479Sjb dt_idkind_name(dnp->dn_ident->di_kind), 435178479Sjb prefix, dnp->dn_ident->di_name, suffix); 436178479Sjb break; 437178479Sjb case DT_NODE_SYM: 438178479Sjb dts = dnp->dn_ident->di_data; 439178479Sjb (void) snprintf(buf, len, "symbol %s`%s", 440178479Sjb dts->dts_object, dts->dts_name); 441178479Sjb break; 442178479Sjb case DT_NODE_TYPE: 443178479Sjb (void) snprintf(buf, len, "type %s", 444178479Sjb dt_node_type_name(dnp, n1, sizeof (n1))); 445178479Sjb break; 446178479Sjb case DT_NODE_OP1: 447178479Sjb case DT_NODE_OP2: 448178479Sjb case DT_NODE_OP3: 449178479Sjb (void) snprintf(buf, len, "operator %s", opstr(dnp->dn_op)); 450178479Sjb break; 451178479Sjb case DT_NODE_DEXPR: 452178479Sjb case DT_NODE_DFUNC: 453178479Sjb if (dnp->dn_expr) 454178479Sjb return (dt_node_name(dnp->dn_expr, buf, len)); 455178479Sjb (void) snprintf(buf, len, "%s", "statement"); 456178479Sjb break; 457178479Sjb case DT_NODE_PDESC: 458178479Sjb if (dnp->dn_desc->dtpd_id == 0) { 459178479Sjb (void) snprintf(buf, len, 460178479Sjb "probe description %s:%s:%s:%s", 461178479Sjb dnp->dn_desc->dtpd_provider, dnp->dn_desc->dtpd_mod, 462178479Sjb dnp->dn_desc->dtpd_func, dnp->dn_desc->dtpd_name); 463178479Sjb } else { 464178479Sjb (void) snprintf(buf, len, "probe description %u", 465178479Sjb dnp->dn_desc->dtpd_id); 466178479Sjb } 467178479Sjb break; 468178479Sjb case DT_NODE_CLAUSE: 469178479Sjb (void) snprintf(buf, len, "%s", "clause"); 470178479Sjb break; 471178479Sjb case DT_NODE_MEMBER: 472178479Sjb (void) snprintf(buf, len, "member %s", dnp->dn_membname); 473178479Sjb break; 474178479Sjb case DT_NODE_XLATOR: 475178479Sjb (void) snprintf(buf, len, "translator <%s> (%s)", 476178479Sjb dt_type_name(dnp->dn_xlator->dx_dst_ctfp, 477178479Sjb dnp->dn_xlator->dx_dst_type, n1, sizeof (n1)), 478178479Sjb dt_type_name(dnp->dn_xlator->dx_src_ctfp, 479178479Sjb dnp->dn_xlator->dx_src_type, n2, sizeof (n2))); 480178479Sjb break; 481178479Sjb case DT_NODE_PROG: 482178479Sjb (void) snprintf(buf, len, "%s", "program"); 483178479Sjb break; 484178479Sjb default: 485178479Sjb (void) snprintf(buf, len, "node <%u>", dnp->dn_kind); 486178479Sjb break; 487178479Sjb } 488178479Sjb 489178479Sjb return (buf); 490178479Sjb} 491178479Sjb 492178479Sjb/* 493178479Sjb * dt_node_xalloc() can be used to create new parse nodes from any libdtrace 494178479Sjb * caller. The caller is responsible for assigning dn_link appropriately. 495178479Sjb */ 496178479Sjbdt_node_t * 497178479Sjbdt_node_xalloc(dtrace_hdl_t *dtp, int kind) 498178479Sjb{ 499178479Sjb dt_node_t *dnp = dt_alloc(dtp, sizeof (dt_node_t)); 500178479Sjb 501178479Sjb if (dnp == NULL) 502178479Sjb return (NULL); 503178479Sjb 504178479Sjb dnp->dn_ctfp = NULL; 505178479Sjb dnp->dn_type = CTF_ERR; 506178479Sjb dnp->dn_kind = (uchar_t)kind; 507178479Sjb dnp->dn_flags = 0; 508178479Sjb dnp->dn_op = 0; 509178479Sjb dnp->dn_line = -1; 510178479Sjb dnp->dn_reg = -1; 511178479Sjb dnp->dn_attr = _dtrace_defattr; 512178479Sjb dnp->dn_list = NULL; 513178479Sjb dnp->dn_link = NULL; 514178479Sjb bzero(&dnp->dn_u, sizeof (dnp->dn_u)); 515178479Sjb 516178479Sjb return (dnp); 517178479Sjb} 518178479Sjb 519178479Sjb/* 520178479Sjb * dt_node_alloc() is used to create new parse nodes from the parser. It 521178479Sjb * assigns the node location based on the current lexer line number and places 522178479Sjb * the new node on the default allocation list. If allocation fails, we 523178479Sjb * automatically longjmp the caller back to the enclosing compilation call. 524178479Sjb */ 525178479Sjbstatic dt_node_t * 526178479Sjbdt_node_alloc(int kind) 527178479Sjb{ 528178479Sjb dt_node_t *dnp = dt_node_xalloc(yypcb->pcb_hdl, kind); 529178479Sjb 530178479Sjb if (dnp == NULL) 531178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 532178479Sjb 533178479Sjb dnp->dn_line = yylineno; 534178479Sjb dnp->dn_link = yypcb->pcb_list; 535178479Sjb yypcb->pcb_list = dnp; 536178479Sjb 537178479Sjb return (dnp); 538178479Sjb} 539178479Sjb 540178479Sjbvoid 541178479Sjbdt_node_free(dt_node_t *dnp) 542178479Sjb{ 543178479Sjb uchar_t kind = dnp->dn_kind; 544178479Sjb 545178479Sjb dnp->dn_kind = DT_NODE_FREE; 546178479Sjb 547178479Sjb switch (kind) { 548178479Sjb case DT_NODE_STRING: 549178479Sjb case DT_NODE_IDENT: 550178479Sjb case DT_NODE_TYPE: 551178479Sjb free(dnp->dn_string); 552178479Sjb dnp->dn_string = NULL; 553178479Sjb break; 554178479Sjb 555178479Sjb case DT_NODE_VAR: 556178479Sjb case DT_NODE_FUNC: 557178479Sjb case DT_NODE_PROBE: 558178479Sjb if (dnp->dn_ident != NULL) { 559178479Sjb if (dnp->dn_ident->di_flags & DT_IDFLG_ORPHAN) 560178479Sjb dt_ident_destroy(dnp->dn_ident); 561178479Sjb dnp->dn_ident = NULL; 562178479Sjb } 563178479Sjb dt_node_list_free(&dnp->dn_args); 564178479Sjb break; 565178479Sjb 566178479Sjb case DT_NODE_OP1: 567178479Sjb if (dnp->dn_child != NULL) { 568178479Sjb dt_node_free(dnp->dn_child); 569178479Sjb dnp->dn_child = NULL; 570178479Sjb } 571178479Sjb break; 572178479Sjb 573178479Sjb case DT_NODE_OP3: 574178479Sjb if (dnp->dn_expr != NULL) { 575178479Sjb dt_node_free(dnp->dn_expr); 576178479Sjb dnp->dn_expr = NULL; 577178479Sjb } 578178479Sjb /*FALLTHRU*/ 579178479Sjb case DT_NODE_OP2: 580178479Sjb if (dnp->dn_left != NULL) { 581178479Sjb dt_node_free(dnp->dn_left); 582178479Sjb dnp->dn_left = NULL; 583178479Sjb } 584178479Sjb if (dnp->dn_right != NULL) { 585178479Sjb dt_node_free(dnp->dn_right); 586178479Sjb dnp->dn_right = NULL; 587178479Sjb } 588178479Sjb break; 589178479Sjb 590178479Sjb case DT_NODE_DEXPR: 591178479Sjb case DT_NODE_DFUNC: 592178479Sjb if (dnp->dn_expr != NULL) { 593178479Sjb dt_node_free(dnp->dn_expr); 594178479Sjb dnp->dn_expr = NULL; 595178479Sjb } 596178479Sjb break; 597178479Sjb 598178479Sjb case DT_NODE_AGG: 599178479Sjb if (dnp->dn_aggfun != NULL) { 600178479Sjb dt_node_free(dnp->dn_aggfun); 601178479Sjb dnp->dn_aggfun = NULL; 602178479Sjb } 603178479Sjb dt_node_list_free(&dnp->dn_aggtup); 604178479Sjb break; 605178479Sjb 606178479Sjb case DT_NODE_PDESC: 607178479Sjb free(dnp->dn_spec); 608178479Sjb dnp->dn_spec = NULL; 609178479Sjb free(dnp->dn_desc); 610178479Sjb dnp->dn_desc = NULL; 611178479Sjb break; 612178479Sjb 613178479Sjb case DT_NODE_CLAUSE: 614178479Sjb if (dnp->dn_pred != NULL) 615178479Sjb dt_node_free(dnp->dn_pred); 616178479Sjb if (dnp->dn_locals != NULL) 617178479Sjb dt_idhash_destroy(dnp->dn_locals); 618178479Sjb dt_node_list_free(&dnp->dn_pdescs); 619178479Sjb dt_node_list_free(&dnp->dn_acts); 620178479Sjb break; 621178479Sjb 622178479Sjb case DT_NODE_MEMBER: 623178479Sjb free(dnp->dn_membname); 624178479Sjb dnp->dn_membname = NULL; 625178479Sjb if (dnp->dn_membexpr != NULL) { 626178479Sjb dt_node_free(dnp->dn_membexpr); 627178479Sjb dnp->dn_membexpr = NULL; 628178479Sjb } 629178479Sjb break; 630178479Sjb 631178479Sjb case DT_NODE_PROVIDER: 632178479Sjb dt_node_list_free(&dnp->dn_probes); 633178479Sjb free(dnp->dn_provname); 634178479Sjb dnp->dn_provname = NULL; 635178479Sjb break; 636178479Sjb 637178479Sjb case DT_NODE_PROG: 638178479Sjb dt_node_list_free(&dnp->dn_list); 639178479Sjb break; 640178479Sjb } 641178479Sjb} 642178479Sjb 643178479Sjbvoid 644178479Sjbdt_node_attr_assign(dt_node_t *dnp, dtrace_attribute_t attr) 645178479Sjb{ 646178479Sjb if ((yypcb->pcb_cflags & DTRACE_C_EATTR) && 647178479Sjb (dt_attr_cmp(attr, yypcb->pcb_amin) < 0)) { 648178479Sjb char a[DTRACE_ATTR2STR_MAX]; 649178479Sjb char s[BUFSIZ]; 650178479Sjb 651178479Sjb dnerror(dnp, D_ATTR_MIN, "attributes for %s (%s) are less than " 652178479Sjb "predefined minimum\n", dt_node_name(dnp, s, sizeof (s)), 653178479Sjb dtrace_attr2str(attr, a, sizeof (a))); 654178479Sjb } 655178479Sjb 656178479Sjb dnp->dn_attr = attr; 657178479Sjb} 658178479Sjb 659178479Sjbvoid 660178479Sjbdt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type) 661178479Sjb{ 662178479Sjb ctf_id_t base = ctf_type_resolve(fp, type); 663178479Sjb uint_t kind = ctf_type_kind(fp, base); 664178479Sjb ctf_encoding_t e; 665178479Sjb 666178479Sjb dnp->dn_flags &= 667178479Sjb ~(DT_NF_SIGNED | DT_NF_REF | DT_NF_BITFIELD | DT_NF_USERLAND); 668178479Sjb 669178479Sjb if (kind == CTF_K_INTEGER && ctf_type_encoding(fp, base, &e) == 0) { 670178479Sjb size_t size = e.cte_bits / NBBY; 671178479Sjb 672178479Sjb if (size > 8 || (e.cte_bits % NBBY) != 0 || (size & (size - 1))) 673178479Sjb dnp->dn_flags |= DT_NF_BITFIELD; 674178479Sjb 675178479Sjb if (e.cte_format & CTF_INT_SIGNED) 676178479Sjb dnp->dn_flags |= DT_NF_SIGNED; 677178479Sjb } 678178479Sjb 679178479Sjb if (kind == CTF_K_FLOAT && ctf_type_encoding(fp, base, &e) == 0) { 680178479Sjb if (e.cte_bits / NBBY > sizeof (uint64_t)) 681178479Sjb dnp->dn_flags |= DT_NF_REF; 682178479Sjb } 683178479Sjb 684178479Sjb if (kind == CTF_K_STRUCT || kind == CTF_K_UNION || 685178479Sjb kind == CTF_K_FORWARD || 686178479Sjb kind == CTF_K_ARRAY || kind == CTF_K_FUNCTION) 687178479Sjb dnp->dn_flags |= DT_NF_REF; 688178479Sjb else if (yypcb != NULL && fp == DT_DYN_CTFP(yypcb->pcb_hdl) && 689178479Sjb type == DT_DYN_TYPE(yypcb->pcb_hdl)) 690178479Sjb dnp->dn_flags |= DT_NF_REF; 691178479Sjb 692178479Sjb dnp->dn_flags |= DT_NF_COOKED; 693178479Sjb dnp->dn_ctfp = fp; 694178479Sjb dnp->dn_type = type; 695178479Sjb} 696178479Sjb 697178479Sjbvoid 698178479Sjbdt_node_type_propagate(const dt_node_t *src, dt_node_t *dst) 699178479Sjb{ 700178479Sjb assert(src->dn_flags & DT_NF_COOKED); 701178479Sjb dst->dn_flags = src->dn_flags & ~DT_NF_LVALUE; 702178479Sjb dst->dn_ctfp = src->dn_ctfp; 703178479Sjb dst->dn_type = src->dn_type; 704178479Sjb} 705178479Sjb 706178479Sjbconst char * 707178479Sjbdt_node_type_name(const dt_node_t *dnp, char *buf, size_t len) 708178479Sjb{ 709178479Sjb if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL) { 710178479Sjb (void) snprintf(buf, len, "%s", 711178479Sjb dt_idkind_name(dt_ident_resolve(dnp->dn_ident)->di_kind)); 712178479Sjb return (buf); 713178479Sjb } 714178479Sjb 715178479Sjb if (dnp->dn_flags & DT_NF_USERLAND) { 716178479Sjb size_t n = snprintf(buf, len, "userland "); 717178479Sjb len = len > n ? len - n : 0; 718178479Sjb (void) dt_type_name(dnp->dn_ctfp, dnp->dn_type, buf + n, len); 719178479Sjb return (buf); 720178479Sjb } 721178479Sjb 722178479Sjb return (dt_type_name(dnp->dn_ctfp, dnp->dn_type, buf, len)); 723178479Sjb} 724178479Sjb 725178479Sjbsize_t 726178479Sjbdt_node_type_size(const dt_node_t *dnp) 727178479Sjb{ 728178479Sjb if (dnp->dn_kind == DT_NODE_STRING) 729178479Sjb return (strlen(dnp->dn_string) + 1); 730178479Sjb 731178479Sjb if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL) 732178479Sjb return (dt_ident_size(dnp->dn_ident)); 733178479Sjb 734178479Sjb return (ctf_type_size(dnp->dn_ctfp, dnp->dn_type)); 735178479Sjb} 736178479Sjb 737178479Sjb/* 738178479Sjb * Determine if the specified parse tree node references an identifier of the 739178479Sjb * specified kind, and if so return a pointer to it; otherwise return NULL. 740178479Sjb * This function resolves the identifier itself, following through any inlines. 741178479Sjb */ 742178479Sjbdt_ident_t * 743178479Sjbdt_node_resolve(const dt_node_t *dnp, uint_t idkind) 744178479Sjb{ 745178479Sjb dt_ident_t *idp; 746178479Sjb 747178479Sjb switch (dnp->dn_kind) { 748178479Sjb case DT_NODE_VAR: 749178479Sjb case DT_NODE_SYM: 750178479Sjb case DT_NODE_FUNC: 751178479Sjb case DT_NODE_AGG: 752178479Sjb case DT_NODE_INLINE: 753178479Sjb case DT_NODE_PROBE: 754178479Sjb idp = dt_ident_resolve(dnp->dn_ident); 755178479Sjb return (idp->di_kind == idkind ? idp : NULL); 756178479Sjb } 757178479Sjb 758178479Sjb if (dt_node_is_dynamic(dnp)) { 759178479Sjb idp = dt_ident_resolve(dnp->dn_ident); 760178479Sjb return (idp->di_kind == idkind ? idp : NULL); 761178479Sjb } 762178479Sjb 763178479Sjb return (NULL); 764178479Sjb} 765178479Sjb 766178479Sjbsize_t 767178479Sjbdt_node_sizeof(const dt_node_t *dnp) 768178479Sjb{ 769178479Sjb dtrace_syminfo_t *sip; 770178479Sjb GElf_Sym sym; 771178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 772178479Sjb 773178479Sjb /* 774178479Sjb * The size of the node as used for the sizeof() operator depends on 775178479Sjb * the kind of the node. If the node is a SYM, the size is obtained 776178479Sjb * from the symbol table; if it is not a SYM, the size is determined 777178479Sjb * from the node's type. This is slightly different from C's sizeof() 778178479Sjb * operator in that (for example) when applied to a function, sizeof() 779178479Sjb * will evaluate to the length of the function rather than the size of 780178479Sjb * the function type. 781178479Sjb */ 782178479Sjb if (dnp->dn_kind != DT_NODE_SYM) 783178479Sjb return (dt_node_type_size(dnp)); 784178479Sjb 785178479Sjb sip = dnp->dn_ident->di_data; 786178479Sjb 787178479Sjb if (dtrace_lookup_by_name(dtp, sip->dts_object, 788178479Sjb sip->dts_name, &sym, NULL) == -1) 789178479Sjb return (0); 790178479Sjb 791178479Sjb return (sym.st_size); 792178479Sjb} 793178479Sjb 794178479Sjbint 795178479Sjbdt_node_is_integer(const dt_node_t *dnp) 796178479Sjb{ 797178479Sjb ctf_file_t *fp = dnp->dn_ctfp; 798178479Sjb ctf_encoding_t e; 799178479Sjb ctf_id_t type; 800178479Sjb uint_t kind; 801178479Sjb 802178479Sjb assert(dnp->dn_flags & DT_NF_COOKED); 803178479Sjb 804178479Sjb type = ctf_type_resolve(fp, dnp->dn_type); 805178479Sjb kind = ctf_type_kind(fp, type); 806178479Sjb 807178479Sjb if (kind == CTF_K_INTEGER && 808178479Sjb ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e)) 809178479Sjb return (0); /* void integer */ 810178479Sjb 811178479Sjb return (kind == CTF_K_INTEGER || kind == CTF_K_ENUM); 812178479Sjb} 813178479Sjb 814178479Sjbint 815178479Sjbdt_node_is_float(const dt_node_t *dnp) 816178479Sjb{ 817178479Sjb ctf_file_t *fp = dnp->dn_ctfp; 818178479Sjb ctf_encoding_t e; 819178479Sjb ctf_id_t type; 820178479Sjb uint_t kind; 821178479Sjb 822178479Sjb assert(dnp->dn_flags & DT_NF_COOKED); 823178479Sjb 824178479Sjb type = ctf_type_resolve(fp, dnp->dn_type); 825178479Sjb kind = ctf_type_kind(fp, type); 826178479Sjb 827178479Sjb return (kind == CTF_K_FLOAT && 828178479Sjb ctf_type_encoding(dnp->dn_ctfp, type, &e) == 0 && ( 829178479Sjb e.cte_format == CTF_FP_SINGLE || e.cte_format == CTF_FP_DOUBLE || 830178479Sjb e.cte_format == CTF_FP_LDOUBLE)); 831178479Sjb} 832178479Sjb 833178479Sjbint 834178479Sjbdt_node_is_scalar(const dt_node_t *dnp) 835178479Sjb{ 836178479Sjb ctf_file_t *fp = dnp->dn_ctfp; 837178479Sjb ctf_encoding_t e; 838178479Sjb ctf_id_t type; 839178479Sjb uint_t kind; 840178479Sjb 841178479Sjb assert(dnp->dn_flags & DT_NF_COOKED); 842178479Sjb 843178479Sjb type = ctf_type_resolve(fp, dnp->dn_type); 844178479Sjb kind = ctf_type_kind(fp, type); 845178479Sjb 846178479Sjb if (kind == CTF_K_INTEGER && 847178479Sjb ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e)) 848178479Sjb return (0); /* void cannot be used as a scalar */ 849178479Sjb 850178479Sjb return (kind == CTF_K_INTEGER || kind == CTF_K_ENUM || 851178479Sjb kind == CTF_K_POINTER); 852178479Sjb} 853178479Sjb 854178479Sjbint 855178479Sjbdt_node_is_arith(const dt_node_t *dnp) 856178479Sjb{ 857178479Sjb ctf_file_t *fp = dnp->dn_ctfp; 858178479Sjb ctf_encoding_t e; 859178479Sjb ctf_id_t type; 860178479Sjb uint_t kind; 861178479Sjb 862178479Sjb assert(dnp->dn_flags & DT_NF_COOKED); 863178479Sjb 864178479Sjb type = ctf_type_resolve(fp, dnp->dn_type); 865178479Sjb kind = ctf_type_kind(fp, type); 866178479Sjb 867178479Sjb if (kind == CTF_K_INTEGER) 868178479Sjb return (ctf_type_encoding(fp, type, &e) == 0 && !IS_VOID(e)); 869178479Sjb else 870178479Sjb return (kind == CTF_K_ENUM); 871178479Sjb} 872178479Sjb 873178479Sjbint 874178479Sjbdt_node_is_vfptr(const dt_node_t *dnp) 875178479Sjb{ 876178479Sjb ctf_file_t *fp = dnp->dn_ctfp; 877178479Sjb ctf_encoding_t e; 878178479Sjb ctf_id_t type; 879178479Sjb uint_t kind; 880178479Sjb 881178479Sjb assert(dnp->dn_flags & DT_NF_COOKED); 882178479Sjb 883178479Sjb type = ctf_type_resolve(fp, dnp->dn_type); 884178479Sjb if (ctf_type_kind(fp, type) != CTF_K_POINTER) 885178479Sjb return (0); /* type is not a pointer */ 886178479Sjb 887178479Sjb type = ctf_type_resolve(fp, ctf_type_reference(fp, type)); 888178479Sjb kind = ctf_type_kind(fp, type); 889178479Sjb 890178479Sjb return (kind == CTF_K_FUNCTION || (kind == CTF_K_INTEGER && 891178479Sjb ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e))); 892178479Sjb} 893178479Sjb 894178479Sjbint 895178479Sjbdt_node_is_dynamic(const dt_node_t *dnp) 896178479Sjb{ 897178479Sjb if (dnp->dn_kind == DT_NODE_VAR && 898178479Sjb (dnp->dn_ident->di_flags & DT_IDFLG_INLINE)) { 899178479Sjb const dt_idnode_t *inp = dnp->dn_ident->di_iarg; 900178479Sjb return (inp->din_root ? dt_node_is_dynamic(inp->din_root) : 0); 901178479Sjb } 902178479Sjb 903178479Sjb return (dnp->dn_ctfp == DT_DYN_CTFP(yypcb->pcb_hdl) && 904178479Sjb dnp->dn_type == DT_DYN_TYPE(yypcb->pcb_hdl)); 905178479Sjb} 906178479Sjb 907178479Sjbint 908178479Sjbdt_node_is_string(const dt_node_t *dnp) 909178479Sjb{ 910178479Sjb return (dnp->dn_ctfp == DT_STR_CTFP(yypcb->pcb_hdl) && 911178479Sjb dnp->dn_type == DT_STR_TYPE(yypcb->pcb_hdl)); 912178479Sjb} 913178479Sjb 914178479Sjbint 915178479Sjbdt_node_is_stack(const dt_node_t *dnp) 916178479Sjb{ 917178479Sjb return (dnp->dn_ctfp == DT_STACK_CTFP(yypcb->pcb_hdl) && 918178479Sjb dnp->dn_type == DT_STACK_TYPE(yypcb->pcb_hdl)); 919178479Sjb} 920178479Sjb 921178479Sjbint 922178479Sjbdt_node_is_symaddr(const dt_node_t *dnp) 923178479Sjb{ 924178479Sjb return (dnp->dn_ctfp == DT_SYMADDR_CTFP(yypcb->pcb_hdl) && 925178479Sjb dnp->dn_type == DT_SYMADDR_TYPE(yypcb->pcb_hdl)); 926178479Sjb} 927178479Sjb 928178479Sjbint 929178479Sjbdt_node_is_usymaddr(const dt_node_t *dnp) 930178479Sjb{ 931178479Sjb return (dnp->dn_ctfp == DT_USYMADDR_CTFP(yypcb->pcb_hdl) && 932178479Sjb dnp->dn_type == DT_USYMADDR_TYPE(yypcb->pcb_hdl)); 933178479Sjb} 934178479Sjb 935178479Sjbint 936178479Sjbdt_node_is_strcompat(const dt_node_t *dnp) 937178479Sjb{ 938178479Sjb ctf_file_t *fp = dnp->dn_ctfp; 939178479Sjb ctf_encoding_t e; 940178479Sjb ctf_arinfo_t r; 941178479Sjb ctf_id_t base; 942178479Sjb uint_t kind; 943178479Sjb 944178479Sjb assert(dnp->dn_flags & DT_NF_COOKED); 945178479Sjb 946178479Sjb base = ctf_type_resolve(fp, dnp->dn_type); 947178479Sjb kind = ctf_type_kind(fp, base); 948178479Sjb 949178479Sjb if (kind == CTF_K_POINTER && 950178479Sjb (base = ctf_type_reference(fp, base)) != CTF_ERR && 951178479Sjb (base = ctf_type_resolve(fp, base)) != CTF_ERR && 952178479Sjb ctf_type_encoding(fp, base, &e) == 0 && IS_CHAR(e)) 953178479Sjb return (1); /* promote char pointer to string */ 954178479Sjb 955178479Sjb if (kind == CTF_K_ARRAY && ctf_array_info(fp, base, &r) == 0 && 956178479Sjb (base = ctf_type_resolve(fp, r.ctr_contents)) != CTF_ERR && 957178479Sjb ctf_type_encoding(fp, base, &e) == 0 && IS_CHAR(e)) 958178479Sjb return (1); /* promote char array to string */ 959178479Sjb 960178479Sjb return (0); 961178479Sjb} 962178479Sjb 963178479Sjbint 964178479Sjbdt_node_is_pointer(const dt_node_t *dnp) 965178479Sjb{ 966178479Sjb ctf_file_t *fp = dnp->dn_ctfp; 967178479Sjb uint_t kind; 968178479Sjb 969178479Sjb assert(dnp->dn_flags & DT_NF_COOKED); 970178479Sjb 971178479Sjb if (dt_node_is_string(dnp)) 972178479Sjb return (0); /* string are pass-by-ref but act like structs */ 973178479Sjb 974178479Sjb kind = ctf_type_kind(fp, ctf_type_resolve(fp, dnp->dn_type)); 975178479Sjb return (kind == CTF_K_POINTER || kind == CTF_K_ARRAY); 976178479Sjb} 977178479Sjb 978178479Sjbint 979178479Sjbdt_node_is_void(const dt_node_t *dnp) 980178479Sjb{ 981178479Sjb ctf_file_t *fp = dnp->dn_ctfp; 982178479Sjb ctf_encoding_t e; 983178479Sjb ctf_id_t type; 984178479Sjb 985178479Sjb if (dt_node_is_dynamic(dnp)) 986178479Sjb return (0); /* <DYN> is an alias for void but not the same */ 987178479Sjb 988178479Sjb if (dt_node_is_stack(dnp)) 989178479Sjb return (0); 990178479Sjb 991178479Sjb if (dt_node_is_symaddr(dnp) || dt_node_is_usymaddr(dnp)) 992178479Sjb return (0); 993178479Sjb 994178479Sjb type = ctf_type_resolve(fp, dnp->dn_type); 995178479Sjb 996178479Sjb return (ctf_type_kind(fp, type) == CTF_K_INTEGER && 997178479Sjb ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e)); 998178479Sjb} 999178479Sjb 1000178479Sjbint 1001178479Sjbdt_node_is_ptrcompat(const dt_node_t *lp, const dt_node_t *rp, 1002178479Sjb ctf_file_t **fpp, ctf_id_t *tp) 1003178479Sjb{ 1004178479Sjb ctf_file_t *lfp = lp->dn_ctfp; 1005178479Sjb ctf_file_t *rfp = rp->dn_ctfp; 1006178479Sjb 1007178479Sjb ctf_id_t lbase = CTF_ERR, rbase = CTF_ERR; 1008178479Sjb ctf_id_t lref = CTF_ERR, rref = CTF_ERR; 1009178479Sjb 1010178479Sjb int lp_is_void, rp_is_void, lp_is_int, rp_is_int, compat; 1011178479Sjb uint_t lkind, rkind; 1012178479Sjb ctf_encoding_t e; 1013178479Sjb ctf_arinfo_t r; 1014178479Sjb 1015178479Sjb assert(lp->dn_flags & DT_NF_COOKED); 1016178479Sjb assert(rp->dn_flags & DT_NF_COOKED); 1017178479Sjb 1018178479Sjb if (dt_node_is_dynamic(lp) || dt_node_is_dynamic(rp)) 1019178479Sjb return (0); /* fail if either node is a dynamic variable */ 1020178479Sjb 1021178479Sjb lp_is_int = dt_node_is_integer(lp); 1022178479Sjb rp_is_int = dt_node_is_integer(rp); 1023178479Sjb 1024178479Sjb if (lp_is_int && rp_is_int) 1025178479Sjb return (0); /* fail if both nodes are integers */ 1026178479Sjb 1027178479Sjb if (lp_is_int && (lp->dn_kind != DT_NODE_INT || lp->dn_value != 0)) 1028178479Sjb return (0); /* fail if lp is an integer that isn't 0 constant */ 1029178479Sjb 1030178479Sjb if (rp_is_int && (rp->dn_kind != DT_NODE_INT || rp->dn_value != 0)) 1031178479Sjb return (0); /* fail if rp is an integer that isn't 0 constant */ 1032178479Sjb 1033178479Sjb if ((lp_is_int == 0 && rp_is_int == 0) && ( 1034178479Sjb (lp->dn_flags & DT_NF_USERLAND) ^ (rp->dn_flags & DT_NF_USERLAND))) 1035178479Sjb return (0); /* fail if only one pointer is a userland address */ 1036178479Sjb 1037178479Sjb /* 1038178479Sjb * Resolve the left-hand and right-hand types to their base type, and 1039178479Sjb * then resolve the referenced type as well (assuming the base type 1040178479Sjb * is CTF_K_POINTER or CTF_K_ARRAY). Otherwise [lr]ref = CTF_ERR. 1041178479Sjb */ 1042178479Sjb if (!lp_is_int) { 1043178479Sjb lbase = ctf_type_resolve(lfp, lp->dn_type); 1044178479Sjb lkind = ctf_type_kind(lfp, lbase); 1045178479Sjb 1046178479Sjb if (lkind == CTF_K_POINTER) { 1047178479Sjb lref = ctf_type_resolve(lfp, 1048178479Sjb ctf_type_reference(lfp, lbase)); 1049178479Sjb } else if (lkind == CTF_K_ARRAY && 1050178479Sjb ctf_array_info(lfp, lbase, &r) == 0) { 1051178479Sjb lref = ctf_type_resolve(lfp, r.ctr_contents); 1052178479Sjb } 1053178479Sjb } 1054178479Sjb 1055178479Sjb if (!rp_is_int) { 1056178479Sjb rbase = ctf_type_resolve(rfp, rp->dn_type); 1057178479Sjb rkind = ctf_type_kind(rfp, rbase); 1058178479Sjb 1059178479Sjb if (rkind == CTF_K_POINTER) { 1060178479Sjb rref = ctf_type_resolve(rfp, 1061178479Sjb ctf_type_reference(rfp, rbase)); 1062178479Sjb } else if (rkind == CTF_K_ARRAY && 1063178479Sjb ctf_array_info(rfp, rbase, &r) == 0) { 1064178479Sjb rref = ctf_type_resolve(rfp, r.ctr_contents); 1065178479Sjb } 1066178479Sjb } 1067178479Sjb 1068178479Sjb /* 1069178479Sjb * We know that one or the other type may still be a zero-valued 1070178479Sjb * integer constant. To simplify the code below, set the integer 1071178479Sjb * type variables equal to the non-integer types and proceed. 1072178479Sjb */ 1073178479Sjb if (lp_is_int) { 1074178479Sjb lbase = rbase; 1075178479Sjb lkind = rkind; 1076178479Sjb lref = rref; 1077178479Sjb lfp = rfp; 1078178479Sjb } else if (rp_is_int) { 1079178479Sjb rbase = lbase; 1080178479Sjb rkind = lkind; 1081178479Sjb rref = lref; 1082178479Sjb rfp = lfp; 1083178479Sjb } 1084178479Sjb 1085178479Sjb lp_is_void = ctf_type_encoding(lfp, lref, &e) == 0 && IS_VOID(e); 1086178479Sjb rp_is_void = ctf_type_encoding(rfp, rref, &e) == 0 && IS_VOID(e); 1087178479Sjb 1088178479Sjb /* 1089178479Sjb * The types are compatible if both are pointers to the same type, or 1090178479Sjb * if either pointer is a void pointer. If they are compatible, set 1091178479Sjb * tp to point to the more specific pointer type and return it. 1092178479Sjb */ 1093178479Sjb compat = (lkind == CTF_K_POINTER || lkind == CTF_K_ARRAY) && 1094178479Sjb (rkind == CTF_K_POINTER || rkind == CTF_K_ARRAY) && 1095178479Sjb (lp_is_void || rp_is_void || ctf_type_compat(lfp, lref, rfp, rref)); 1096178479Sjb 1097178479Sjb if (compat) { 1098178479Sjb if (fpp != NULL) 1099178479Sjb *fpp = rp_is_void ? lfp : rfp; 1100178479Sjb if (tp != NULL) 1101178479Sjb *tp = rp_is_void ? lbase : rbase; 1102178479Sjb } 1103178479Sjb 1104178479Sjb return (compat); 1105178479Sjb} 1106178479Sjb 1107178479Sjb/* 1108178479Sjb * The rules for checking argument types against parameter types are described 1109178479Sjb * in the ANSI-C spec (see K&R[A7.3.2] and K&R[A7.17]). We use the same rule 1110178479Sjb * set to determine whether associative array arguments match the prototype. 1111178479Sjb */ 1112178479Sjbint 1113178479Sjbdt_node_is_argcompat(const dt_node_t *lp, const dt_node_t *rp) 1114178479Sjb{ 1115178479Sjb ctf_file_t *lfp = lp->dn_ctfp; 1116178479Sjb ctf_file_t *rfp = rp->dn_ctfp; 1117178479Sjb 1118178479Sjb assert(lp->dn_flags & DT_NF_COOKED); 1119178479Sjb assert(rp->dn_flags & DT_NF_COOKED); 1120178479Sjb 1121178479Sjb if (dt_node_is_integer(lp) && dt_node_is_integer(rp)) 1122178479Sjb return (1); /* integer types are compatible */ 1123178479Sjb 1124178479Sjb if (dt_node_is_strcompat(lp) && dt_node_is_strcompat(rp)) 1125178479Sjb return (1); /* string types are compatible */ 1126178479Sjb 1127178479Sjb if (dt_node_is_stack(lp) && dt_node_is_stack(rp)) 1128178479Sjb return (1); /* stack types are compatible */ 1129178479Sjb 1130178479Sjb if (dt_node_is_symaddr(lp) && dt_node_is_symaddr(rp)) 1131178479Sjb return (1); /* symaddr types are compatible */ 1132178479Sjb 1133178479Sjb if (dt_node_is_usymaddr(lp) && dt_node_is_usymaddr(rp)) 1134178479Sjb return (1); /* usymaddr types are compatible */ 1135178479Sjb 1136178479Sjb switch (ctf_type_kind(lfp, ctf_type_resolve(lfp, lp->dn_type))) { 1137178479Sjb case CTF_K_FUNCTION: 1138178479Sjb case CTF_K_STRUCT: 1139178479Sjb case CTF_K_UNION: 1140178479Sjb return (ctf_type_compat(lfp, lp->dn_type, rfp, rp->dn_type)); 1141178479Sjb default: 1142178479Sjb return (dt_node_is_ptrcompat(lp, rp, NULL, NULL)); 1143178479Sjb } 1144178479Sjb} 1145178479Sjb 1146178479Sjb/* 1147178479Sjb * We provide dt_node_is_posconst() as a convenience routine for callers who 1148178479Sjb * wish to verify that an argument is a positive non-zero integer constant. 1149178479Sjb */ 1150178479Sjbint 1151178479Sjbdt_node_is_posconst(const dt_node_t *dnp) 1152178479Sjb{ 1153178479Sjb return (dnp->dn_kind == DT_NODE_INT && dnp->dn_value != 0 && ( 1154178479Sjb (dnp->dn_flags & DT_NF_SIGNED) == 0 || (int64_t)dnp->dn_value > 0)); 1155178479Sjb} 1156178479Sjb 1157178479Sjbint 1158178479Sjbdt_node_is_actfunc(const dt_node_t *dnp) 1159178479Sjb{ 1160178479Sjb return (dnp->dn_kind == DT_NODE_FUNC && 1161178479Sjb dnp->dn_ident->di_kind == DT_IDENT_ACTFUNC); 1162178479Sjb} 1163178479Sjb 1164178479Sjb/* 1165178479Sjb * The original rules for integer constant typing are described in K&R[A2.5.1]. 1166178479Sjb * However, since we support long long, we instead use the rules from ISO C99 1167178479Sjb * clause 6.4.4.1 since that is where long longs are formally described. The 1168178479Sjb * rules require us to know whether the constant was specified in decimal or 1169178479Sjb * in octal or hex, which we do by looking at our lexer's 'yyintdecimal' flag. 1170178479Sjb * The type of an integer constant is the first of the corresponding list in 1171178479Sjb * which its value can be represented: 1172178479Sjb * 1173178479Sjb * unsuffixed decimal: int, long, long long 1174178479Sjb * unsuffixed oct/hex: int, unsigned int, long, unsigned long, 1175178479Sjb * long long, unsigned long long 1176178479Sjb * suffix [uU]: unsigned int, unsigned long, unsigned long long 1177178479Sjb * suffix [lL] decimal: long, long long 1178178479Sjb * suffix [lL] oct/hex: long, unsigned long, long long, unsigned long long 1179178479Sjb * suffix [uU][Ll]: unsigned long, unsigned long long 1180178479Sjb * suffix ll/LL decimal: long long 1181178479Sjb * suffix ll/LL oct/hex: long long, unsigned long long 1182178479Sjb * suffix [uU][ll/LL]: unsigned long long 1183178479Sjb * 1184178479Sjb * Given that our lexer has already validated the suffixes by regexp matching, 1185178479Sjb * there is an obvious way to concisely encode these rules: construct an array 1186178479Sjb * of the types in the order int, unsigned int, long, unsigned long, long long, 1187178479Sjb * unsigned long long. Compute an integer array starting index based on the 1188178479Sjb * suffix (e.g. none = 0, u = 1, ull = 5), and compute an increment based on 1189178479Sjb * the specifier (dec/oct/hex) and suffix (u). Then iterate from the starting 1190178479Sjb * index to the end, advancing using the increment, and searching until we 1191178479Sjb * find a limit that matches or we run out of choices (overflow). To make it 1192178479Sjb * even faster, we precompute the table of type information in dtrace_open(). 1193178479Sjb */ 1194178479Sjbdt_node_t * 1195178479Sjbdt_node_int(uintmax_t value) 1196178479Sjb{ 1197178479Sjb dt_node_t *dnp = dt_node_alloc(DT_NODE_INT); 1198178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 1199178479Sjb 1200178479Sjb int n = (yyintdecimal | (yyintsuffix[0] == 'u')) + 1; 1201178479Sjb int i = 0; 1202178479Sjb 1203178479Sjb const char *p; 1204178479Sjb char c; 1205178479Sjb 1206178479Sjb dnp->dn_op = DT_TOK_INT; 1207178479Sjb dnp->dn_value = value; 1208178479Sjb 1209178479Sjb for (p = yyintsuffix; (c = *p) != '\0'; p++) { 1210178479Sjb if (c == 'U' || c == 'u') 1211178479Sjb i += 1; 1212178479Sjb else if (c == 'L' || c == 'l') 1213178479Sjb i += 2; 1214178479Sjb } 1215178479Sjb 1216178479Sjb for (; i < sizeof (dtp->dt_ints) / sizeof (dtp->dt_ints[0]); i += n) { 1217178479Sjb if (value <= dtp->dt_ints[i].did_limit) { 1218178479Sjb dt_node_type_assign(dnp, 1219178479Sjb dtp->dt_ints[i].did_ctfp, 1220178479Sjb dtp->dt_ints[i].did_type); 1221178479Sjb 1222178479Sjb /* 1223178479Sjb * If a prefix character is present in macro text, add 1224178479Sjb * in the corresponding operator node (see dt_lex.l). 1225178479Sjb */ 1226178479Sjb switch (yyintprefix) { 1227178479Sjb case '+': 1228178479Sjb return (dt_node_op1(DT_TOK_IPOS, dnp)); 1229178479Sjb case '-': 1230178479Sjb return (dt_node_op1(DT_TOK_INEG, dnp)); 1231178479Sjb default: 1232178479Sjb return (dnp); 1233178479Sjb } 1234178479Sjb } 1235178479Sjb } 1236178479Sjb 1237178479Sjb xyerror(D_INT_OFLOW, "integer constant 0x%llx cannot be represented " 1238178479Sjb "in any built-in integral type\n", (u_longlong_t)value); 1239178479Sjb /*NOTREACHED*/ 1240178479Sjb return (NULL); /* keep gcc happy */ 1241178479Sjb} 1242178479Sjb 1243178479Sjbdt_node_t * 1244178479Sjbdt_node_string(char *string) 1245178479Sjb{ 1246178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 1247178479Sjb dt_node_t *dnp; 1248178479Sjb 1249178479Sjb if (string == NULL) 1250178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 1251178479Sjb 1252178479Sjb dnp = dt_node_alloc(DT_NODE_STRING); 1253178479Sjb dnp->dn_op = DT_TOK_STRING; 1254178479Sjb dnp->dn_string = string; 1255178479Sjb dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp)); 1256178479Sjb 1257178479Sjb return (dnp); 1258178479Sjb} 1259178479Sjb 1260178479Sjbdt_node_t * 1261178479Sjbdt_node_ident(char *name) 1262178479Sjb{ 1263178479Sjb dt_ident_t *idp; 1264178479Sjb dt_node_t *dnp; 1265178479Sjb 1266178479Sjb if (name == NULL) 1267178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 1268178479Sjb 1269178479Sjb /* 1270178479Sjb * If the identifier is an inlined integer constant, then create an INT 1271178479Sjb * node that is a clone of the inline parse tree node and return that 1272178479Sjb * immediately, allowing this inline to be used in parsing contexts 1273178479Sjb * that require constant expressions (e.g. scalar array sizes). 1274178479Sjb */ 1275178479Sjb if ((idp = dt_idstack_lookup(&yypcb->pcb_globals, name)) != NULL && 1276178479Sjb (idp->di_flags & DT_IDFLG_INLINE)) { 1277178479Sjb dt_idnode_t *inp = idp->di_iarg; 1278178479Sjb 1279178479Sjb if (inp->din_root != NULL && 1280178479Sjb inp->din_root->dn_kind == DT_NODE_INT) { 1281178479Sjb free(name); 1282178479Sjb 1283178479Sjb dnp = dt_node_alloc(DT_NODE_INT); 1284178479Sjb dnp->dn_op = DT_TOK_INT; 1285178479Sjb dnp->dn_value = inp->din_root->dn_value; 1286178479Sjb dt_node_type_propagate(inp->din_root, dnp); 1287178479Sjb 1288178479Sjb return (dnp); 1289178479Sjb } 1290178479Sjb } 1291178479Sjb 1292178479Sjb dnp = dt_node_alloc(DT_NODE_IDENT); 1293178479Sjb dnp->dn_op = name[0] == '@' ? DT_TOK_AGG : DT_TOK_IDENT; 1294178479Sjb dnp->dn_string = name; 1295178479Sjb 1296178479Sjb return (dnp); 1297178479Sjb} 1298178479Sjb 1299178479Sjb/* 1300178479Sjb * Create an empty node of type corresponding to the given declaration. 1301178479Sjb * Explicit references to user types (C or D) are assigned the default 1302178479Sjb * stability; references to other types are _dtrace_typattr (Private). 1303178479Sjb */ 1304178479Sjbdt_node_t * 1305178479Sjbdt_node_type(dt_decl_t *ddp) 1306178479Sjb{ 1307178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 1308178479Sjb dtrace_typeinfo_t dtt; 1309178479Sjb dt_node_t *dnp; 1310178479Sjb char *name = NULL; 1311178479Sjb int err; 1312178479Sjb 1313178479Sjb /* 1314178479Sjb * If 'ddp' is NULL, we get a decl by popping the decl stack. This 1315178479Sjb * form of dt_node_type() is used by parameter rules in dt_grammar.y. 1316178479Sjb */ 1317178479Sjb if (ddp == NULL) 1318178479Sjb ddp = dt_decl_pop_param(&name); 1319178479Sjb 1320178479Sjb err = dt_decl_type(ddp, &dtt); 1321178479Sjb dt_decl_free(ddp); 1322178479Sjb 1323178479Sjb if (err != 0) { 1324178479Sjb free(name); 1325178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 1326178479Sjb } 1327178479Sjb 1328178479Sjb dnp = dt_node_alloc(DT_NODE_TYPE); 1329178479Sjb dnp->dn_op = DT_TOK_IDENT; 1330178479Sjb dnp->dn_string = name; 1331178479Sjb dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); 1332178479Sjb 1333178479Sjb if (dtt.dtt_ctfp == dtp->dt_cdefs->dm_ctfp || 1334178479Sjb dtt.dtt_ctfp == dtp->dt_ddefs->dm_ctfp) 1335178479Sjb dt_node_attr_assign(dnp, _dtrace_defattr); 1336178479Sjb else 1337178479Sjb dt_node_attr_assign(dnp, _dtrace_typattr); 1338178479Sjb 1339178479Sjb return (dnp); 1340178479Sjb} 1341178479Sjb 1342178479Sjb/* 1343178479Sjb * Create a type node corresponding to a varargs (...) parameter by just 1344178479Sjb * assigning it type CTF_ERR. The decl processing code will handle this. 1345178479Sjb */ 1346178479Sjbdt_node_t * 1347178479Sjbdt_node_vatype(void) 1348178479Sjb{ 1349178479Sjb dt_node_t *dnp = dt_node_alloc(DT_NODE_TYPE); 1350178479Sjb 1351178479Sjb dnp->dn_op = DT_TOK_IDENT; 1352178479Sjb dnp->dn_ctfp = yypcb->pcb_hdl->dt_cdefs->dm_ctfp; 1353178479Sjb dnp->dn_type = CTF_ERR; 1354178479Sjb dnp->dn_attr = _dtrace_defattr; 1355178479Sjb 1356178479Sjb return (dnp); 1357178479Sjb} 1358178479Sjb 1359178479Sjb/* 1360178479Sjb * Instantiate a decl using the contents of the current declaration stack. As 1361178479Sjb * we do not currently permit decls to be initialized, this function currently 1362178479Sjb * returns NULL and no parse node is created. When this function is called, 1363178479Sjb * the topmost scope's ds_ident pointer will be set to NULL (indicating no 1364178479Sjb * init_declarator rule was matched) or will point to the identifier to use. 1365178479Sjb */ 1366178479Sjbdt_node_t * 1367178479Sjbdt_node_decl(void) 1368178479Sjb{ 1369178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 1370178479Sjb dt_scope_t *dsp = &yypcb->pcb_dstack; 1371178479Sjb dt_dclass_t class = dsp->ds_class; 1372178479Sjb dt_decl_t *ddp = dt_decl_top(); 1373178479Sjb 1374178479Sjb dt_module_t *dmp; 1375178479Sjb dtrace_typeinfo_t dtt; 1376178479Sjb ctf_id_t type; 1377178479Sjb 1378178479Sjb char n1[DT_TYPE_NAMELEN]; 1379178479Sjb char n2[DT_TYPE_NAMELEN]; 1380178479Sjb 1381178479Sjb if (dt_decl_type(ddp, &dtt) != 0) 1382178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 1383178479Sjb 1384178479Sjb /* 1385178479Sjb * If we have no declaration identifier, then this is either a spurious 1386178479Sjb * declaration of an intrinsic type (e.g. "extern int;") or declaration 1387178479Sjb * or redeclaration of a struct, union, or enum type or tag. 1388178479Sjb */ 1389178479Sjb if (dsp->ds_ident == NULL) { 1390178479Sjb if (ddp->dd_kind != CTF_K_STRUCT && 1391178479Sjb ddp->dd_kind != CTF_K_UNION && ddp->dd_kind != CTF_K_ENUM) 1392178479Sjb xyerror(D_DECL_USELESS, "useless declaration\n"); 1393178479Sjb 1394178479Sjb dt_dprintf("type %s added as id %ld\n", dt_type_name( 1395178479Sjb ddp->dd_ctfp, ddp->dd_type, n1, sizeof (n1)), ddp->dd_type); 1396178479Sjb 1397178479Sjb return (NULL); 1398178479Sjb } 1399178479Sjb 1400178479Sjb if (strchr(dsp->ds_ident, '`') != NULL) { 1401178479Sjb xyerror(D_DECL_SCOPE, "D scoping operator may not be used in " 1402178479Sjb "a declaration name (%s)\n", dsp->ds_ident); 1403178479Sjb } 1404178479Sjb 1405178479Sjb /* 1406178479Sjb * If we are nested inside of a C include file, add the declaration to 1407178479Sjb * the C definition module; otherwise use the D definition module. 1408178479Sjb */ 1409178479Sjb if (yypcb->pcb_idepth != 0) 1410178479Sjb dmp = dtp->dt_cdefs; 1411178479Sjb else 1412178479Sjb dmp = dtp->dt_ddefs; 1413178479Sjb 1414178479Sjb /* 1415178479Sjb * If we see a global or static declaration of a function prototype, 1416178479Sjb * treat this as equivalent to a D extern declaration. 1417178479Sjb */ 1418178479Sjb if (ctf_type_kind(dtt.dtt_ctfp, dtt.dtt_type) == CTF_K_FUNCTION && 1419178479Sjb (class == DT_DC_DEFAULT || class == DT_DC_STATIC)) 1420178479Sjb class = DT_DC_EXTERN; 1421178479Sjb 1422178479Sjb switch (class) { 1423178479Sjb case DT_DC_AUTO: 1424178479Sjb case DT_DC_REGISTER: 1425178479Sjb case DT_DC_STATIC: 1426178479Sjb xyerror(D_DECL_BADCLASS, "specified storage class not " 1427178479Sjb "appropriate in D\n"); 1428178479Sjb /*NOTREACHED*/ 1429178479Sjb 1430178479Sjb case DT_DC_EXTERN: { 1431178479Sjb dtrace_typeinfo_t ott; 1432178479Sjb dtrace_syminfo_t dts; 1433178479Sjb GElf_Sym sym; 1434178479Sjb 1435178479Sjb int exists = dtrace_lookup_by_name(dtp, 1436178479Sjb dmp->dm_name, dsp->ds_ident, &sym, &dts) == 0; 1437178479Sjb 1438178479Sjb if (exists && (dtrace_symbol_type(dtp, &sym, &dts, &ott) != 0 || 1439178479Sjb ctf_type_cmp(dtt.dtt_ctfp, dtt.dtt_type, 1440178479Sjb ott.dtt_ctfp, ott.dtt_type) != 0)) { 1441178479Sjb xyerror(D_DECL_IDRED, "identifier redeclared: %s`%s\n" 1442178479Sjb "\t current: %s\n\tprevious: %s\n", 1443178479Sjb dmp->dm_name, dsp->ds_ident, 1444178479Sjb dt_type_name(dtt.dtt_ctfp, dtt.dtt_type, 1445178479Sjb n1, sizeof (n1)), 1446178479Sjb dt_type_name(ott.dtt_ctfp, ott.dtt_type, 1447178479Sjb n2, sizeof (n2))); 1448178479Sjb } else if (!exists && dt_module_extern(dtp, dmp, 1449178479Sjb dsp->ds_ident, &dtt) == NULL) { 1450178479Sjb xyerror(D_UNKNOWN, 1451178479Sjb "failed to extern %s: %s\n", dsp->ds_ident, 1452178479Sjb dtrace_errmsg(dtp, dtrace_errno(dtp))); 1453178479Sjb } else { 1454178479Sjb dt_dprintf("extern %s`%s type=<%s>\n", 1455178479Sjb dmp->dm_name, dsp->ds_ident, 1456178479Sjb dt_type_name(dtt.dtt_ctfp, dtt.dtt_type, 1457178479Sjb n1, sizeof (n1))); 1458178479Sjb } 1459178479Sjb break; 1460178479Sjb } 1461178479Sjb 1462178479Sjb case DT_DC_TYPEDEF: 1463178479Sjb if (dt_idstack_lookup(&yypcb->pcb_globals, dsp->ds_ident)) { 1464178479Sjb xyerror(D_DECL_IDRED, "global variable identifier " 1465178479Sjb "redeclared: %s\n", dsp->ds_ident); 1466178479Sjb } 1467178479Sjb 1468178479Sjb if (ctf_lookup_by_name(dmp->dm_ctfp, 1469178479Sjb dsp->ds_ident) != CTF_ERR) { 1470178479Sjb xyerror(D_DECL_IDRED, 1471178479Sjb "typedef redeclared: %s\n", dsp->ds_ident); 1472178479Sjb } 1473178479Sjb 1474178479Sjb /* 1475178479Sjb * If the source type for the typedef is not defined in the 1476178479Sjb * target container or its parent, copy the type to the target 1477178479Sjb * container and reset dtt_ctfp and dtt_type to the copy. 1478178479Sjb */ 1479178479Sjb if (dtt.dtt_ctfp != dmp->dm_ctfp && 1480178479Sjb dtt.dtt_ctfp != ctf_parent_file(dmp->dm_ctfp)) { 1481178479Sjb 1482178479Sjb dtt.dtt_type = ctf_add_type(dmp->dm_ctfp, 1483178479Sjb dtt.dtt_ctfp, dtt.dtt_type); 1484178479Sjb dtt.dtt_ctfp = dmp->dm_ctfp; 1485178479Sjb 1486178479Sjb if (dtt.dtt_type == CTF_ERR || 1487178479Sjb ctf_update(dtt.dtt_ctfp) == CTF_ERR) { 1488178479Sjb xyerror(D_UNKNOWN, "failed to copy typedef %s " 1489178479Sjb "source type: %s\n", dsp->ds_ident, 1490178479Sjb ctf_errmsg(ctf_errno(dtt.dtt_ctfp))); 1491178479Sjb } 1492178479Sjb } 1493178479Sjb 1494178479Sjb type = ctf_add_typedef(dmp->dm_ctfp, 1495178479Sjb CTF_ADD_ROOT, dsp->ds_ident, dtt.dtt_type); 1496178479Sjb 1497178479Sjb if (type == CTF_ERR || ctf_update(dmp->dm_ctfp) == CTF_ERR) { 1498178479Sjb xyerror(D_UNKNOWN, "failed to typedef %s: %s\n", 1499178479Sjb dsp->ds_ident, ctf_errmsg(ctf_errno(dmp->dm_ctfp))); 1500178479Sjb } 1501178479Sjb 1502178479Sjb dt_dprintf("typedef %s added as id %ld\n", dsp->ds_ident, type); 1503178479Sjb break; 1504178479Sjb 1505178479Sjb default: { 1506178479Sjb ctf_encoding_t cte; 1507178479Sjb dt_idhash_t *dhp; 1508178479Sjb dt_ident_t *idp; 1509178479Sjb dt_node_t idn; 1510178479Sjb int assc, idkind; 1511178479Sjb uint_t id, kind; 1512178479Sjb ushort_t idflags; 1513178479Sjb 1514178479Sjb switch (class) { 1515178479Sjb case DT_DC_THIS: 1516178479Sjb dhp = yypcb->pcb_locals; 1517178479Sjb idflags = DT_IDFLG_LOCAL; 1518178479Sjb idp = dt_idhash_lookup(dhp, dsp->ds_ident); 1519178479Sjb break; 1520178479Sjb case DT_DC_SELF: 1521178479Sjb dhp = dtp->dt_tls; 1522178479Sjb idflags = DT_IDFLG_TLS; 1523178479Sjb idp = dt_idhash_lookup(dhp, dsp->ds_ident); 1524178479Sjb break; 1525178479Sjb default: 1526178479Sjb dhp = dtp->dt_globals; 1527178479Sjb idflags = 0; 1528178479Sjb idp = dt_idstack_lookup( 1529178479Sjb &yypcb->pcb_globals, dsp->ds_ident); 1530178479Sjb break; 1531178479Sjb } 1532178479Sjb 1533178479Sjb if (ddp->dd_kind == CTF_K_ARRAY && ddp->dd_node == NULL) { 1534178479Sjb xyerror(D_DECL_ARRNULL, 1535178479Sjb "array declaration requires array dimension or " 1536178479Sjb "tuple signature: %s\n", dsp->ds_ident); 1537178479Sjb } 1538178479Sjb 1539178479Sjb if (idp != NULL && idp->di_gen == 0) { 1540178479Sjb xyerror(D_DECL_IDRED, "built-in identifier " 1541178479Sjb "redeclared: %s\n", idp->di_name); 1542178479Sjb } 1543178479Sjb 1544178479Sjb if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_CDEFS, 1545178479Sjb dsp->ds_ident, NULL) == 0 || 1546178479Sjb dtrace_lookup_by_type(dtp, DTRACE_OBJ_DDEFS, 1547178479Sjb dsp->ds_ident, NULL) == 0) { 1548178479Sjb xyerror(D_DECL_IDRED, "typedef identifier " 1549178479Sjb "redeclared: %s\n", dsp->ds_ident); 1550178479Sjb } 1551178479Sjb 1552178479Sjb /* 1553178479Sjb * Cache some attributes of the decl to make the rest of this 1554178479Sjb * code simpler: if the decl is an array which is subscripted 1555178479Sjb * by a type rather than an integer, then it's an associative 1556178479Sjb * array (assc). We then expect to match either DT_IDENT_ARRAY 1557178479Sjb * for associative arrays or DT_IDENT_SCALAR for anything else. 1558178479Sjb */ 1559178479Sjb assc = ddp->dd_kind == CTF_K_ARRAY && 1560178479Sjb ddp->dd_node->dn_kind == DT_NODE_TYPE; 1561178479Sjb 1562178479Sjb idkind = assc ? DT_IDENT_ARRAY : DT_IDENT_SCALAR; 1563178479Sjb 1564178479Sjb /* 1565178479Sjb * Create a fake dt_node_t on the stack so we can determine the 1566178479Sjb * type of any matching identifier by assigning to this node. 1567178479Sjb * If the pre-existing ident has its di_type set, propagate 1568178479Sjb * the type by hand so as not to trigger a prototype check for 1569178479Sjb * arrays (yet); otherwise we use dt_ident_cook() on the ident 1570178479Sjb * to ensure it is fully initialized before looking at it. 1571178479Sjb */ 1572178479Sjb bzero(&idn, sizeof (dt_node_t)); 1573178479Sjb 1574178479Sjb if (idp != NULL && idp->di_type != CTF_ERR) 1575178479Sjb dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type); 1576178479Sjb else if (idp != NULL) 1577178479Sjb (void) dt_ident_cook(&idn, idp, NULL); 1578178479Sjb 1579178479Sjb if (assc) { 1580178479Sjb if (class == DT_DC_THIS) { 1581178479Sjb xyerror(D_DECL_LOCASSC, "associative arrays " 1582178479Sjb "may not be declared as local variables:" 1583178479Sjb " %s\n", dsp->ds_ident); 1584178479Sjb } 1585178479Sjb 1586178479Sjb if (dt_decl_type(ddp->dd_next, &dtt) != 0) 1587178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 1588178479Sjb } 1589178479Sjb 1590178479Sjb if (idp != NULL && (idp->di_kind != idkind || 1591178479Sjb ctf_type_cmp(dtt.dtt_ctfp, dtt.dtt_type, 1592178479Sjb idn.dn_ctfp, idn.dn_type) != 0)) { 1593178479Sjb xyerror(D_DECL_IDRED, "identifier redeclared: %s\n" 1594178479Sjb "\t current: %s %s\n\tprevious: %s %s\n", 1595178479Sjb dsp->ds_ident, dt_idkind_name(idkind), 1596178479Sjb dt_type_name(dtt.dtt_ctfp, 1597178479Sjb dtt.dtt_type, n1, sizeof (n1)), 1598178479Sjb dt_idkind_name(idp->di_kind), 1599178479Sjb dt_node_type_name(&idn, n2, sizeof (n2))); 1600178479Sjb 1601178479Sjb } else if (idp != NULL && assc) { 1602178479Sjb const dt_idsig_t *isp = idp->di_data; 1603178479Sjb dt_node_t *dnp = ddp->dd_node; 1604178479Sjb int argc = 0; 1605178479Sjb 1606178479Sjb for (; dnp != NULL; dnp = dnp->dn_list, argc++) { 1607178479Sjb const dt_node_t *pnp = &isp->dis_args[argc]; 1608178479Sjb 1609178479Sjb if (argc >= isp->dis_argc) 1610178479Sjb continue; /* tuple length mismatch */ 1611178479Sjb 1612178479Sjb if (ctf_type_cmp(dnp->dn_ctfp, dnp->dn_type, 1613178479Sjb pnp->dn_ctfp, pnp->dn_type) == 0) 1614178479Sjb continue; 1615178479Sjb 1616178479Sjb xyerror(D_DECL_IDRED, 1617178479Sjb "identifier redeclared: %s\n" 1618178479Sjb "\t current: %s, key #%d of type %s\n" 1619178479Sjb "\tprevious: %s, key #%d of type %s\n", 1620178479Sjb dsp->ds_ident, 1621178479Sjb dt_idkind_name(idkind), argc + 1, 1622178479Sjb dt_node_type_name(dnp, n1, sizeof (n1)), 1623178479Sjb dt_idkind_name(idp->di_kind), argc + 1, 1624178479Sjb dt_node_type_name(pnp, n2, sizeof (n2))); 1625178479Sjb } 1626178479Sjb 1627178479Sjb if (isp->dis_argc != argc) { 1628178479Sjb xyerror(D_DECL_IDRED, 1629178479Sjb "identifier redeclared: %s\n" 1630178479Sjb "\t current: %s of %s, tuple length %d\n" 1631178479Sjb "\tprevious: %s of %s, tuple length %d\n", 1632178479Sjb dsp->ds_ident, dt_idkind_name(idkind), 1633178479Sjb dt_type_name(dtt.dtt_ctfp, dtt.dtt_type, 1634178479Sjb n1, sizeof (n1)), argc, 1635178479Sjb dt_idkind_name(idp->di_kind), 1636178479Sjb dt_node_type_name(&idn, n2, sizeof (n2)), 1637178479Sjb isp->dis_argc); 1638178479Sjb } 1639178479Sjb 1640178479Sjb } else if (idp == NULL) { 1641178479Sjb type = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type); 1642178479Sjb kind = ctf_type_kind(dtt.dtt_ctfp, type); 1643178479Sjb 1644178479Sjb switch (kind) { 1645178479Sjb case CTF_K_INTEGER: 1646178479Sjb if (ctf_type_encoding(dtt.dtt_ctfp, type, 1647178479Sjb &cte) == 0 && IS_VOID(cte)) { 1648178479Sjb xyerror(D_DECL_VOIDOBJ, "cannot have " 1649178479Sjb "void object: %s\n", dsp->ds_ident); 1650178479Sjb } 1651178479Sjb break; 1652178479Sjb case CTF_K_STRUCT: 1653178479Sjb case CTF_K_UNION: 1654178479Sjb if (ctf_type_size(dtt.dtt_ctfp, type) != 0) 1655178479Sjb break; /* proceed to declaring */ 1656178479Sjb /*FALLTHRU*/ 1657178479Sjb case CTF_K_FORWARD: 1658178479Sjb xyerror(D_DECL_INCOMPLETE, 1659178479Sjb "incomplete struct/union/enum %s: %s\n", 1660178479Sjb dt_type_name(dtt.dtt_ctfp, dtt.dtt_type, 1661178479Sjb n1, sizeof (n1)), dsp->ds_ident); 1662178479Sjb /*NOTREACHED*/ 1663178479Sjb } 1664178479Sjb 1665178479Sjb if (dt_idhash_nextid(dhp, &id) == -1) { 1666178479Sjb xyerror(D_ID_OFLOW, "cannot create %s: limit " 1667178479Sjb "on number of %s variables exceeded\n", 1668178479Sjb dsp->ds_ident, dt_idhash_name(dhp)); 1669178479Sjb } 1670178479Sjb 1671178479Sjb dt_dprintf("declare %s %s variable %s, id=%u\n", 1672178479Sjb dt_idhash_name(dhp), dt_idkind_name(idkind), 1673178479Sjb dsp->ds_ident, id); 1674178479Sjb 1675178479Sjb idp = dt_idhash_insert(dhp, dsp->ds_ident, idkind, 1676178479Sjb idflags | DT_IDFLG_WRITE | DT_IDFLG_DECL, id, 1677178479Sjb _dtrace_defattr, 0, assc ? &dt_idops_assc : 1678178479Sjb &dt_idops_thaw, NULL, dtp->dt_gen); 1679178479Sjb 1680178479Sjb if (idp == NULL) 1681178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 1682178479Sjb 1683178479Sjb dt_ident_type_assign(idp, dtt.dtt_ctfp, dtt.dtt_type); 1684178479Sjb 1685178479Sjb /* 1686178479Sjb * If we are declaring an associative array, use our 1687178479Sjb * fake parse node to cook the new assoc identifier. 1688178479Sjb * This will force the ident code to instantiate the 1689178479Sjb * array type signature corresponding to the list of 1690178479Sjb * types pointed to by ddp->dd_node. We also reset 1691178479Sjb * the identifier's attributes based upon the result. 1692178479Sjb */ 1693178479Sjb if (assc) { 1694178479Sjb idp->di_attr = 1695178479Sjb dt_ident_cook(&idn, idp, &ddp->dd_node); 1696178479Sjb } 1697178479Sjb } 1698178479Sjb } 1699178479Sjb 1700178479Sjb } /* end of switch */ 1701178479Sjb 1702178479Sjb free(dsp->ds_ident); 1703178479Sjb dsp->ds_ident = NULL; 1704178479Sjb 1705178479Sjb return (NULL); 1706178479Sjb} 1707178479Sjb 1708178479Sjbdt_node_t * 1709178479Sjbdt_node_func(dt_node_t *dnp, dt_node_t *args) 1710178479Sjb{ 1711178479Sjb dt_ident_t *idp; 1712178479Sjb 1713178479Sjb if (dnp->dn_kind != DT_NODE_IDENT) { 1714178479Sjb xyerror(D_FUNC_IDENT, 1715178479Sjb "function designator is not of function type\n"); 1716178479Sjb } 1717178479Sjb 1718178479Sjb idp = dt_idstack_lookup(&yypcb->pcb_globals, dnp->dn_string); 1719178479Sjb 1720178479Sjb if (idp == NULL) { 1721178479Sjb xyerror(D_FUNC_UNDEF, 1722178479Sjb "undefined function name: %s\n", dnp->dn_string); 1723178479Sjb } 1724178479Sjb 1725178479Sjb if (idp->di_kind != DT_IDENT_FUNC && 1726178479Sjb idp->di_kind != DT_IDENT_AGGFUNC && 1727178479Sjb idp->di_kind != DT_IDENT_ACTFUNC) { 1728178479Sjb xyerror(D_FUNC_IDKIND, "%s '%s' may not be referenced as a " 1729178479Sjb "function\n", dt_idkind_name(idp->di_kind), idp->di_name); 1730178479Sjb } 1731178479Sjb 1732178479Sjb free(dnp->dn_string); 1733178479Sjb dnp->dn_string = NULL; 1734178479Sjb 1735178479Sjb dnp->dn_kind = DT_NODE_FUNC; 1736178479Sjb dnp->dn_flags &= ~DT_NF_COOKED; 1737178479Sjb dnp->dn_ident = idp; 1738178479Sjb dnp->dn_args = args; 1739178479Sjb dnp->dn_list = NULL; 1740178479Sjb 1741178479Sjb return (dnp); 1742178479Sjb} 1743178479Sjb 1744178479Sjb/* 1745178479Sjb * The offsetof() function is special because it takes a type name as an 1746178479Sjb * argument. It does not actually construct its own node; after looking up the 1747178479Sjb * structure or union offset, we just return an integer node with the offset. 1748178479Sjb */ 1749178479Sjbdt_node_t * 1750178479Sjbdt_node_offsetof(dt_decl_t *ddp, char *s) 1751178479Sjb{ 1752178479Sjb dtrace_typeinfo_t dtt; 1753178479Sjb dt_node_t dn; 1754178479Sjb char *name; 1755178479Sjb int err; 1756178479Sjb 1757178479Sjb ctf_membinfo_t ctm; 1758178479Sjb ctf_id_t type; 1759178479Sjb uint_t kind; 1760178479Sjb 1761178479Sjb name = alloca(strlen(s) + 1); 1762178479Sjb (void) strcpy(name, s); 1763178479Sjb free(s); 1764178479Sjb 1765178479Sjb err = dt_decl_type(ddp, &dtt); 1766178479Sjb dt_decl_free(ddp); 1767178479Sjb 1768178479Sjb if (err != 0) 1769178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 1770178479Sjb 1771178479Sjb type = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type); 1772178479Sjb kind = ctf_type_kind(dtt.dtt_ctfp, type); 1773178479Sjb 1774178479Sjb if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) { 1775178479Sjb xyerror(D_OFFSETOF_TYPE, 1776178479Sjb "offsetof operand must be a struct or union type\n"); 1777178479Sjb } 1778178479Sjb 1779178479Sjb if (ctf_member_info(dtt.dtt_ctfp, type, name, &ctm) == CTF_ERR) { 1780178479Sjb xyerror(D_UNKNOWN, "failed to determine offset of %s: %s\n", 1781178479Sjb name, ctf_errmsg(ctf_errno(dtt.dtt_ctfp))); 1782178479Sjb } 1783178479Sjb 1784178479Sjb bzero(&dn, sizeof (dn)); 1785178479Sjb dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type); 1786178479Sjb 1787178479Sjb if (dn.dn_flags & DT_NF_BITFIELD) { 1788178479Sjb xyerror(D_OFFSETOF_BITFIELD, 1789178479Sjb "cannot take offset of a bit-field: %s\n", name); 1790178479Sjb } 1791178479Sjb 1792178479Sjb return (dt_node_int(ctm.ctm_offset / NBBY)); 1793178479Sjb} 1794178479Sjb 1795178479Sjbdt_node_t * 1796178479Sjbdt_node_op1(int op, dt_node_t *cp) 1797178479Sjb{ 1798178479Sjb dt_node_t *dnp; 1799178479Sjb 1800178479Sjb if (cp->dn_kind == DT_NODE_INT) { 1801178479Sjb switch (op) { 1802178479Sjb case DT_TOK_INEG: 1803178479Sjb /* 1804178479Sjb * If we're negating an unsigned integer, zero out any 1805178479Sjb * extra top bits to truncate the value to the size of 1806178479Sjb * the effective type determined by dt_node_int(). 1807178479Sjb */ 1808178479Sjb cp->dn_value = -cp->dn_value; 1809178479Sjb if (!(cp->dn_flags & DT_NF_SIGNED)) { 1810178479Sjb cp->dn_value &= ~0ULL >> 1811178479Sjb (64 - dt_node_type_size(cp) * NBBY); 1812178479Sjb } 1813178479Sjb /*FALLTHRU*/ 1814178479Sjb case DT_TOK_IPOS: 1815178479Sjb return (cp); 1816178479Sjb case DT_TOK_BNEG: 1817178479Sjb cp->dn_value = ~cp->dn_value; 1818178479Sjb return (cp); 1819178479Sjb case DT_TOK_LNEG: 1820178479Sjb cp->dn_value = !cp->dn_value; 1821178479Sjb return (cp); 1822178479Sjb } 1823178479Sjb } 1824178479Sjb 1825178479Sjb /* 1826178479Sjb * If sizeof is applied to a type_name or string constant, we can 1827178479Sjb * transform 'cp' into an integer constant in the node construction 1828178479Sjb * pass so that it can then be used for arithmetic in this pass. 1829178479Sjb */ 1830178479Sjb if (op == DT_TOK_SIZEOF && 1831178479Sjb (cp->dn_kind == DT_NODE_STRING || cp->dn_kind == DT_NODE_TYPE)) { 1832178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 1833178479Sjb size_t size = dt_node_type_size(cp); 1834178479Sjb 1835178479Sjb if (size == 0) { 1836178479Sjb xyerror(D_SIZEOF_TYPE, "cannot apply sizeof to an " 1837178479Sjb "operand of unknown size\n"); 1838178479Sjb } 1839178479Sjb 1840178479Sjb dt_node_type_assign(cp, dtp->dt_ddefs->dm_ctfp, 1841178479Sjb ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t")); 1842178479Sjb 1843178479Sjb cp->dn_kind = DT_NODE_INT; 1844178479Sjb cp->dn_op = DT_TOK_INT; 1845178479Sjb cp->dn_value = size; 1846178479Sjb 1847178479Sjb return (cp); 1848178479Sjb } 1849178479Sjb 1850178479Sjb dnp = dt_node_alloc(DT_NODE_OP1); 1851178479Sjb assert(op <= USHRT_MAX); 1852178479Sjb dnp->dn_op = (ushort_t)op; 1853178479Sjb dnp->dn_child = cp; 1854178479Sjb 1855178479Sjb return (dnp); 1856178479Sjb} 1857178479Sjb 1858178479Sjbdt_node_t * 1859178479Sjbdt_node_op2(int op, dt_node_t *lp, dt_node_t *rp) 1860178479Sjb{ 1861178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 1862178479Sjb dt_node_t *dnp; 1863178479Sjb 1864178479Sjb /* 1865178479Sjb * First we check for operations that are illegal -- namely those that 1866178479Sjb * might result in integer division by zero, and abort if one is found. 1867178479Sjb */ 1868178479Sjb if (rp->dn_kind == DT_NODE_INT && rp->dn_value == 0 && 1869178479Sjb (op == DT_TOK_MOD || op == DT_TOK_DIV || 1870178479Sjb op == DT_TOK_MOD_EQ || op == DT_TOK_DIV_EQ)) 1871178479Sjb xyerror(D_DIV_ZERO, "expression contains division by zero\n"); 1872178479Sjb 1873178479Sjb /* 1874178479Sjb * If both children are immediate values, we can just perform inline 1875178479Sjb * calculation and return a new immediate node with the result. 1876178479Sjb */ 1877178479Sjb if (lp->dn_kind == DT_NODE_INT && rp->dn_kind == DT_NODE_INT) { 1878178479Sjb uintmax_t l = lp->dn_value; 1879178479Sjb uintmax_t r = rp->dn_value; 1880178479Sjb 1881178479Sjb dnp = dt_node_int(0); /* allocate new integer node for result */ 1882178479Sjb 1883178479Sjb switch (op) { 1884178479Sjb case DT_TOK_LOR: 1885178479Sjb dnp->dn_value = l || r; 1886178479Sjb dt_node_type_assign(dnp, 1887178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1888178479Sjb break; 1889178479Sjb case DT_TOK_LXOR: 1890178479Sjb dnp->dn_value = (l != 0) ^ (r != 0); 1891178479Sjb dt_node_type_assign(dnp, 1892178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1893178479Sjb break; 1894178479Sjb case DT_TOK_LAND: 1895178479Sjb dnp->dn_value = l && r; 1896178479Sjb dt_node_type_assign(dnp, 1897178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1898178479Sjb break; 1899178479Sjb case DT_TOK_BOR: 1900178479Sjb dnp->dn_value = l | r; 1901178479Sjb dt_node_promote(lp, rp, dnp); 1902178479Sjb break; 1903178479Sjb case DT_TOK_XOR: 1904178479Sjb dnp->dn_value = l ^ r; 1905178479Sjb dt_node_promote(lp, rp, dnp); 1906178479Sjb break; 1907178479Sjb case DT_TOK_BAND: 1908178479Sjb dnp->dn_value = l & r; 1909178479Sjb dt_node_promote(lp, rp, dnp); 1910178479Sjb break; 1911178479Sjb case DT_TOK_EQU: 1912178479Sjb dnp->dn_value = l == r; 1913178479Sjb dt_node_type_assign(dnp, 1914178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1915178479Sjb break; 1916178479Sjb case DT_TOK_NEQ: 1917178479Sjb dnp->dn_value = l != r; 1918178479Sjb dt_node_type_assign(dnp, 1919178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1920178479Sjb break; 1921178479Sjb case DT_TOK_LT: 1922178479Sjb dt_node_promote(lp, rp, dnp); 1923178479Sjb if (dnp->dn_flags & DT_NF_SIGNED) 1924178479Sjb dnp->dn_value = (intmax_t)l < (intmax_t)r; 1925178479Sjb else 1926178479Sjb dnp->dn_value = l < r; 1927178479Sjb dt_node_type_assign(dnp, 1928178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1929178479Sjb break; 1930178479Sjb case DT_TOK_LE: 1931178479Sjb dt_node_promote(lp, rp, dnp); 1932178479Sjb if (dnp->dn_flags & DT_NF_SIGNED) 1933178479Sjb dnp->dn_value = (intmax_t)l <= (intmax_t)r; 1934178479Sjb else 1935178479Sjb dnp->dn_value = l <= r; 1936178479Sjb dt_node_type_assign(dnp, 1937178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1938178479Sjb break; 1939178479Sjb case DT_TOK_GT: 1940178479Sjb dt_node_promote(lp, rp, dnp); 1941178479Sjb if (dnp->dn_flags & DT_NF_SIGNED) 1942178479Sjb dnp->dn_value = (intmax_t)l > (intmax_t)r; 1943178479Sjb else 1944178479Sjb dnp->dn_value = l > r; 1945178479Sjb dt_node_type_assign(dnp, 1946178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1947178479Sjb break; 1948178479Sjb case DT_TOK_GE: 1949178479Sjb dt_node_promote(lp, rp, dnp); 1950178479Sjb if (dnp->dn_flags & DT_NF_SIGNED) 1951178479Sjb dnp->dn_value = (intmax_t)l >= (intmax_t)r; 1952178479Sjb else 1953178479Sjb dnp->dn_value = l >= r; 1954178479Sjb dt_node_type_assign(dnp, 1955178479Sjb DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 1956178479Sjb break; 1957178479Sjb case DT_TOK_LSH: 1958178479Sjb dnp->dn_value = l << r; 1959178479Sjb dt_node_type_propagate(lp, dnp); 1960178479Sjb dt_node_attr_assign(rp, 1961178479Sjb dt_attr_min(lp->dn_attr, rp->dn_attr)); 1962178479Sjb break; 1963178479Sjb case DT_TOK_RSH: 1964178479Sjb dnp->dn_value = l >> r; 1965178479Sjb dt_node_type_propagate(lp, dnp); 1966178479Sjb dt_node_attr_assign(rp, 1967178479Sjb dt_attr_min(lp->dn_attr, rp->dn_attr)); 1968178479Sjb break; 1969178479Sjb case DT_TOK_ADD: 1970178479Sjb dnp->dn_value = l + r; 1971178479Sjb dt_node_promote(lp, rp, dnp); 1972178479Sjb break; 1973178479Sjb case DT_TOK_SUB: 1974178479Sjb dnp->dn_value = l - r; 1975178479Sjb dt_node_promote(lp, rp, dnp); 1976178479Sjb break; 1977178479Sjb case DT_TOK_MUL: 1978178479Sjb dnp->dn_value = l * r; 1979178479Sjb dt_node_promote(lp, rp, dnp); 1980178479Sjb break; 1981178479Sjb case DT_TOK_DIV: 1982178479Sjb dt_node_promote(lp, rp, dnp); 1983178479Sjb if (dnp->dn_flags & DT_NF_SIGNED) 1984178479Sjb dnp->dn_value = (intmax_t)l / (intmax_t)r; 1985178479Sjb else 1986178479Sjb dnp->dn_value = l / r; 1987178479Sjb break; 1988178479Sjb case DT_TOK_MOD: 1989178479Sjb dt_node_promote(lp, rp, dnp); 1990178479Sjb if (dnp->dn_flags & DT_NF_SIGNED) 1991178479Sjb dnp->dn_value = (intmax_t)l % (intmax_t)r; 1992178479Sjb else 1993178479Sjb dnp->dn_value = l % r; 1994178479Sjb break; 1995178479Sjb default: 1996178479Sjb dt_node_free(dnp); 1997178479Sjb dnp = NULL; 1998178479Sjb } 1999178479Sjb 2000178479Sjb if (dnp != NULL) { 2001178479Sjb dt_node_free(lp); 2002178479Sjb dt_node_free(rp); 2003178479Sjb return (dnp); 2004178479Sjb } 2005178479Sjb } 2006178479Sjb 2007178479Sjb /* 2008178479Sjb * If an integer constant is being cast to another integer type, we can 2009178479Sjb * perform the cast as part of integer constant folding in this pass. 2010178479Sjb * We must take action when the integer is being cast to a smaller type 2011178479Sjb * or if it is changing signed-ness. If so, we first shift rp's bits 2012178479Sjb * bits high (losing excess bits if narrowing) and then shift them down 2013178479Sjb * with either a logical shift (unsigned) or arithmetic shift (signed). 2014178479Sjb */ 2015178479Sjb if (op == DT_TOK_LPAR && rp->dn_kind == DT_NODE_INT && 2016178479Sjb dt_node_is_integer(lp)) { 2017178479Sjb size_t srcsize = dt_node_type_size(rp); 2018178479Sjb size_t dstsize = dt_node_type_size(lp); 2019178479Sjb 2020178479Sjb if ((dstsize < srcsize) || ((lp->dn_flags & DT_NF_SIGNED) ^ 2021178479Sjb (rp->dn_flags & DT_NF_SIGNED))) { 2022178479Sjb int n = dstsize < srcsize ? 2023178479Sjb (sizeof (uint64_t) * NBBY - dstsize * NBBY) : 2024178479Sjb (sizeof (uint64_t) * NBBY - srcsize * NBBY); 2025178479Sjb 2026178479Sjb rp->dn_value <<= n; 2027178479Sjb if (lp->dn_flags & DT_NF_SIGNED) 2028178479Sjb rp->dn_value = (intmax_t)rp->dn_value >> n; 2029178479Sjb else 2030178479Sjb rp->dn_value = rp->dn_value >> n; 2031178479Sjb } 2032178479Sjb 2033178479Sjb dt_node_type_propagate(lp, rp); 2034178479Sjb dt_node_attr_assign(rp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 2035178479Sjb dt_node_free(lp); 2036178479Sjb 2037178479Sjb return (rp); 2038178479Sjb } 2039178479Sjb 2040178479Sjb /* 2041178479Sjb * If no immediate optimizations are available, create an new OP2 node 2042178479Sjb * and glue the left and right children into place and return. 2043178479Sjb */ 2044178479Sjb dnp = dt_node_alloc(DT_NODE_OP2); 2045178479Sjb assert(op <= USHRT_MAX); 2046178479Sjb dnp->dn_op = (ushort_t)op; 2047178479Sjb dnp->dn_left = lp; 2048178479Sjb dnp->dn_right = rp; 2049178479Sjb 2050178479Sjb return (dnp); 2051178479Sjb} 2052178479Sjb 2053178479Sjbdt_node_t * 2054178479Sjbdt_node_op3(dt_node_t *expr, dt_node_t *lp, dt_node_t *rp) 2055178479Sjb{ 2056178479Sjb dt_node_t *dnp; 2057178479Sjb 2058178479Sjb if (expr->dn_kind == DT_NODE_INT) 2059178479Sjb return (expr->dn_value != 0 ? lp : rp); 2060178479Sjb 2061178479Sjb dnp = dt_node_alloc(DT_NODE_OP3); 2062178479Sjb dnp->dn_op = DT_TOK_QUESTION; 2063178479Sjb dnp->dn_expr = expr; 2064178479Sjb dnp->dn_left = lp; 2065178479Sjb dnp->dn_right = rp; 2066178479Sjb 2067178479Sjb return (dnp); 2068178479Sjb} 2069178479Sjb 2070178479Sjbdt_node_t * 2071178479Sjbdt_node_statement(dt_node_t *expr) 2072178479Sjb{ 2073178479Sjb dt_node_t *dnp; 2074178479Sjb 2075178479Sjb if (expr->dn_kind == DT_NODE_AGG) 2076178479Sjb return (expr); 2077178479Sjb 2078178479Sjb if (expr->dn_kind == DT_NODE_FUNC && 2079178479Sjb expr->dn_ident->di_kind == DT_IDENT_ACTFUNC) 2080178479Sjb dnp = dt_node_alloc(DT_NODE_DFUNC); 2081178479Sjb else 2082178479Sjb dnp = dt_node_alloc(DT_NODE_DEXPR); 2083178479Sjb 2084178479Sjb dnp->dn_expr = expr; 2085178479Sjb return (dnp); 2086178479Sjb} 2087178479Sjb 2088178479Sjbdt_node_t * 2089178479Sjbdt_node_pdesc_by_name(char *spec) 2090178479Sjb{ 2091178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2092178479Sjb dt_node_t *dnp; 2093178479Sjb 2094178479Sjb if (spec == NULL) 2095178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2096178479Sjb 2097178479Sjb dnp = dt_node_alloc(DT_NODE_PDESC); 2098178479Sjb dnp->dn_spec = spec; 2099178479Sjb dnp->dn_desc = malloc(sizeof (dtrace_probedesc_t)); 2100178479Sjb 2101178479Sjb if (dnp->dn_desc == NULL) 2102178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2103178479Sjb 2104178479Sjb if (dtrace_xstr2desc(dtp, yypcb->pcb_pspec, dnp->dn_spec, 2105178479Sjb yypcb->pcb_sargc, yypcb->pcb_sargv, dnp->dn_desc) != 0) { 2106178479Sjb xyerror(D_PDESC_INVAL, "invalid probe description \"%s\": %s\n", 2107178479Sjb dnp->dn_spec, dtrace_errmsg(dtp, dtrace_errno(dtp))); 2108178479Sjb } 2109178479Sjb 2110178479Sjb free(dnp->dn_spec); 2111178479Sjb dnp->dn_spec = NULL; 2112178479Sjb 2113178479Sjb return (dnp); 2114178479Sjb} 2115178479Sjb 2116178479Sjbdt_node_t * 2117178479Sjbdt_node_pdesc_by_id(uintmax_t id) 2118178479Sjb{ 2119178479Sjb static const char *const names[] = { 2120178479Sjb "providers", "modules", "functions" 2121178479Sjb }; 2122178479Sjb 2123178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2124178479Sjb dt_node_t *dnp = dt_node_alloc(DT_NODE_PDESC); 2125178479Sjb 2126178479Sjb if ((dnp->dn_desc = malloc(sizeof (dtrace_probedesc_t))) == NULL) 2127178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2128178479Sjb 2129178479Sjb if (id > UINT_MAX) { 2130178479Sjb xyerror(D_PDESC_INVAL, "identifier %llu exceeds maximum " 2131178479Sjb "probe id\n", (u_longlong_t)id); 2132178479Sjb } 2133178479Sjb 2134178479Sjb if (yypcb->pcb_pspec != DTRACE_PROBESPEC_NAME) { 2135178479Sjb xyerror(D_PDESC_INVAL, "probe identifier %llu not permitted " 2136178479Sjb "when specifying %s\n", (u_longlong_t)id, 2137178479Sjb names[yypcb->pcb_pspec]); 2138178479Sjb } 2139178479Sjb 2140178479Sjb if (dtrace_id2desc(dtp, (dtrace_id_t)id, dnp->dn_desc) != 0) { 2141178479Sjb xyerror(D_PDESC_INVAL, "invalid probe identifier %llu: %s\n", 2142178479Sjb (u_longlong_t)id, dtrace_errmsg(dtp, dtrace_errno(dtp))); 2143178479Sjb } 2144178479Sjb 2145178479Sjb return (dnp); 2146178479Sjb} 2147178479Sjb 2148178479Sjbdt_node_t * 2149178479Sjbdt_node_clause(dt_node_t *pdescs, dt_node_t *pred, dt_node_t *acts) 2150178479Sjb{ 2151178479Sjb dt_node_t *dnp = dt_node_alloc(DT_NODE_CLAUSE); 2152178479Sjb 2153178479Sjb dnp->dn_pdescs = pdescs; 2154178479Sjb dnp->dn_pred = pred; 2155178479Sjb dnp->dn_acts = acts; 2156178479Sjb 2157178479Sjb yybegin(YYS_CLAUSE); 2158178479Sjb return (dnp); 2159178479Sjb} 2160178479Sjb 2161178479Sjbdt_node_t * 2162178479Sjbdt_node_inline(dt_node_t *expr) 2163178479Sjb{ 2164178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2165178479Sjb dt_scope_t *dsp = &yypcb->pcb_dstack; 2166178479Sjb dt_decl_t *ddp = dt_decl_top(); 2167178479Sjb 2168178479Sjb char n[DT_TYPE_NAMELEN]; 2169178479Sjb dtrace_typeinfo_t dtt; 2170178479Sjb 2171178479Sjb dt_ident_t *idp, *rdp; 2172178479Sjb dt_idnode_t *inp; 2173178479Sjb dt_node_t *dnp; 2174178479Sjb 2175178479Sjb if (dt_decl_type(ddp, &dtt) != 0) 2176178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 2177178479Sjb 2178178479Sjb if (dsp->ds_class != DT_DC_DEFAULT) { 2179178479Sjb xyerror(D_DECL_BADCLASS, "specified storage class not " 2180178479Sjb "appropriate for inline declaration\n"); 2181178479Sjb } 2182178479Sjb 2183178479Sjb if (dsp->ds_ident == NULL) 2184178479Sjb xyerror(D_DECL_USELESS, "inline declaration requires a name\n"); 2185178479Sjb 2186178479Sjb if ((idp = dt_idstack_lookup( 2187178479Sjb &yypcb->pcb_globals, dsp->ds_ident)) != NULL) { 2188178479Sjb xyerror(D_DECL_IDRED, "identifier redefined: %s\n\t current: " 2189178479Sjb "inline definition\n\tprevious: %s %s\n", 2190178479Sjb idp->di_name, dt_idkind_name(idp->di_kind), 2191178479Sjb (idp->di_flags & DT_IDFLG_INLINE) ? "inline" : ""); 2192178479Sjb } 2193178479Sjb 2194178479Sjb /* 2195178479Sjb * If we are declaring an inlined array, verify that we have a tuple 2196178479Sjb * signature, and then recompute 'dtt' as the array's value type. 2197178479Sjb */ 2198178479Sjb if (ddp->dd_kind == CTF_K_ARRAY) { 2199178479Sjb if (ddp->dd_node == NULL) { 2200178479Sjb xyerror(D_DECL_ARRNULL, "inline declaration requires " 2201178479Sjb "array tuple signature: %s\n", dsp->ds_ident); 2202178479Sjb } 2203178479Sjb 2204178479Sjb if (ddp->dd_node->dn_kind != DT_NODE_TYPE) { 2205178479Sjb xyerror(D_DECL_ARRNULL, "inline declaration cannot be " 2206178479Sjb "of scalar array type: %s\n", dsp->ds_ident); 2207178479Sjb } 2208178479Sjb 2209178479Sjb if (dt_decl_type(ddp->dd_next, &dtt) != 0) 2210178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 2211178479Sjb } 2212178479Sjb 2213178479Sjb /* 2214178479Sjb * If the inline identifier is not defined, then create it with the 2215178479Sjb * orphan flag set. We do not insert the identifier into dt_globals 2216178479Sjb * until we have successfully cooked the right-hand expression, below. 2217178479Sjb */ 2218178479Sjb dnp = dt_node_alloc(DT_NODE_INLINE); 2219178479Sjb dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); 2220178479Sjb dt_node_attr_assign(dnp, _dtrace_defattr); 2221178479Sjb 2222178479Sjb if (dt_node_is_void(dnp)) { 2223178479Sjb xyerror(D_DECL_VOIDOBJ, 2224178479Sjb "cannot declare void inline: %s\n", dsp->ds_ident); 2225178479Sjb } 2226178479Sjb 2227178479Sjb if (ctf_type_kind(dnp->dn_ctfp, ctf_type_resolve( 2228178479Sjb dnp->dn_ctfp, dnp->dn_type)) == CTF_K_FORWARD) { 2229178479Sjb xyerror(D_DECL_INCOMPLETE, 2230178479Sjb "incomplete struct/union/enum %s: %s\n", 2231178479Sjb dt_node_type_name(dnp, n, sizeof (n)), dsp->ds_ident); 2232178479Sjb } 2233178479Sjb 2234178479Sjb if ((inp = malloc(sizeof (dt_idnode_t))) == NULL) 2235178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2236178479Sjb 2237178479Sjb bzero(inp, sizeof (dt_idnode_t)); 2238178479Sjb 2239178479Sjb idp = dnp->dn_ident = dt_ident_create(dsp->ds_ident, 2240178479Sjb ddp->dd_kind == CTF_K_ARRAY ? DT_IDENT_ARRAY : DT_IDENT_SCALAR, 2241178479Sjb DT_IDFLG_INLINE | DT_IDFLG_REF | DT_IDFLG_DECL | DT_IDFLG_ORPHAN, 0, 2242178479Sjb _dtrace_defattr, 0, &dt_idops_inline, inp, dtp->dt_gen); 2243178479Sjb 2244178479Sjb if (idp == NULL) { 2245178479Sjb free(inp); 2246178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2247178479Sjb } 2248178479Sjb 2249178479Sjb /* 2250178479Sjb * If we're inlining an associative array, create a private identifier 2251178479Sjb * hash containing the named parameters and store it in inp->din_hash. 2252178479Sjb * We then push this hash on to the top of the pcb_globals stack. 2253178479Sjb */ 2254178479Sjb if (ddp->dd_kind == CTF_K_ARRAY) { 2255178479Sjb dt_idnode_t *pinp; 2256178479Sjb dt_ident_t *pidp; 2257178479Sjb dt_node_t *pnp; 2258178479Sjb uint_t i = 0; 2259178479Sjb 2260178479Sjb for (pnp = ddp->dd_node; pnp != NULL; pnp = pnp->dn_list) 2261178479Sjb i++; /* count up parameters for din_argv[] */ 2262178479Sjb 2263178479Sjb inp->din_hash = dt_idhash_create("inline args", NULL, 0, 0); 2264178479Sjb inp->din_argv = calloc(i, sizeof (dt_ident_t *)); 2265178479Sjb 2266178479Sjb if (inp->din_hash == NULL || inp->din_argv == NULL) 2267178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2268178479Sjb 2269178479Sjb /* 2270178479Sjb * Create an identifier for each parameter as a scalar inline, 2271178479Sjb * and store it in din_hash and in position in din_argv[]. The 2272178479Sjb * parameter identifiers also use dt_idops_inline, but we leave 2273178479Sjb * the dt_idnode_t argument 'pinp' zeroed. This will be filled 2274178479Sjb * in by the code generation pass with references to the args. 2275178479Sjb */ 2276178479Sjb for (i = 0, pnp = ddp->dd_node; 2277178479Sjb pnp != NULL; pnp = pnp->dn_list, i++) { 2278178479Sjb 2279178479Sjb if (pnp->dn_string == NULL) 2280178479Sjb continue; /* ignore anonymous parameters */ 2281178479Sjb 2282178479Sjb if ((pinp = malloc(sizeof (dt_idnode_t))) == NULL) 2283178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2284178479Sjb 2285178479Sjb pidp = dt_idhash_insert(inp->din_hash, pnp->dn_string, 2286178479Sjb DT_IDENT_SCALAR, DT_IDFLG_DECL | DT_IDFLG_INLINE, 0, 2287178479Sjb _dtrace_defattr, 0, &dt_idops_inline, 2288178479Sjb pinp, dtp->dt_gen); 2289178479Sjb 2290178479Sjb if (pidp == NULL) { 2291178479Sjb free(pinp); 2292178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2293178479Sjb } 2294178479Sjb 2295178479Sjb inp->din_argv[i] = pidp; 2296178479Sjb bzero(pinp, sizeof (dt_idnode_t)); 2297178479Sjb dt_ident_type_assign(pidp, pnp->dn_ctfp, pnp->dn_type); 2298178479Sjb } 2299178479Sjb 2300178479Sjb dt_idstack_push(&yypcb->pcb_globals, inp->din_hash); 2301178479Sjb } 2302178479Sjb 2303178479Sjb /* 2304178479Sjb * Unlike most constructors, we need to explicitly cook the right-hand 2305178479Sjb * side of the inline definition immediately to prevent recursion. If 2306178479Sjb * the right-hand side uses the inline itself, the cook will fail. 2307178479Sjb */ 2308178479Sjb expr = dt_node_cook(expr, DT_IDFLG_REF); 2309178479Sjb 2310178479Sjb if (ddp->dd_kind == CTF_K_ARRAY) 2311178479Sjb dt_idstack_pop(&yypcb->pcb_globals, inp->din_hash); 2312178479Sjb 2313178479Sjb /* 2314178479Sjb * Set the type, attributes, and flags for the inline. If the right- 2315178479Sjb * hand expression has an identifier, propagate its flags. Then cook 2316178479Sjb * the identifier to fully initialize it: if we're declaring an inline 2317178479Sjb * associative array this will construct a type signature from 'ddp'. 2318178479Sjb */ 2319178479Sjb if (dt_node_is_dynamic(expr)) 2320178479Sjb rdp = dt_ident_resolve(expr->dn_ident); 2321178479Sjb else if (expr->dn_kind == DT_NODE_VAR || expr->dn_kind == DT_NODE_SYM) 2322178479Sjb rdp = expr->dn_ident; 2323178479Sjb else 2324178479Sjb rdp = NULL; 2325178479Sjb 2326178479Sjb if (rdp != NULL) { 2327178479Sjb idp->di_flags |= (rdp->di_flags & 2328178479Sjb (DT_IDFLG_WRITE | DT_IDFLG_USER | DT_IDFLG_PRIM)); 2329178479Sjb } 2330178479Sjb 2331178479Sjb idp->di_attr = dt_attr_min(_dtrace_defattr, expr->dn_attr); 2332178479Sjb dt_ident_type_assign(idp, dtt.dtt_ctfp, dtt.dtt_type); 2333178479Sjb (void) dt_ident_cook(dnp, idp, &ddp->dd_node); 2334178479Sjb 2335178479Sjb /* 2336178479Sjb * Store the parse tree nodes for 'expr' inside of idp->di_data ('inp') 2337178479Sjb * so that they will be preserved with this identifier. Then pop the 2338178479Sjb * inline declaration from the declaration stack and restore the lexer. 2339178479Sjb */ 2340178479Sjb inp->din_list = yypcb->pcb_list; 2341178479Sjb inp->din_root = expr; 2342178479Sjb 2343178479Sjb dt_decl_free(dt_decl_pop()); 2344178479Sjb yybegin(YYS_CLAUSE); 2345178479Sjb 2346178479Sjb /* 2347178479Sjb * Finally, insert the inline identifier into dt_globals to make it 2348178479Sjb * visible, and then cook 'dnp' to check its type against 'expr'. 2349178479Sjb */ 2350178479Sjb dt_idhash_xinsert(dtp->dt_globals, idp); 2351178479Sjb return (dt_node_cook(dnp, DT_IDFLG_REF)); 2352178479Sjb} 2353178479Sjb 2354178479Sjbdt_node_t * 2355178479Sjbdt_node_member(dt_decl_t *ddp, char *name, dt_node_t *expr) 2356178479Sjb{ 2357178479Sjb dtrace_typeinfo_t dtt; 2358178479Sjb dt_node_t *dnp; 2359178479Sjb int err; 2360178479Sjb 2361178479Sjb if (ddp != NULL) { 2362178479Sjb err = dt_decl_type(ddp, &dtt); 2363178479Sjb dt_decl_free(ddp); 2364178479Sjb 2365178479Sjb if (err != 0) 2366178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 2367178479Sjb } 2368178479Sjb 2369178479Sjb dnp = dt_node_alloc(DT_NODE_MEMBER); 2370178479Sjb dnp->dn_membname = name; 2371178479Sjb dnp->dn_membexpr = expr; 2372178479Sjb 2373178479Sjb if (ddp != NULL) 2374178479Sjb dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); 2375178479Sjb 2376178479Sjb return (dnp); 2377178479Sjb} 2378178479Sjb 2379178479Sjbdt_node_t * 2380178479Sjbdt_node_xlator(dt_decl_t *ddp, dt_decl_t *sdp, char *name, dt_node_t *members) 2381178479Sjb{ 2382178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2383178479Sjb dtrace_typeinfo_t src, dst; 2384178479Sjb dt_node_t sn, dn; 2385178479Sjb dt_xlator_t *dxp; 2386178479Sjb dt_node_t *dnp; 2387178479Sjb int edst, esrc; 2388178479Sjb uint_t kind; 2389178479Sjb 2390178479Sjb char n1[DT_TYPE_NAMELEN]; 2391178479Sjb char n2[DT_TYPE_NAMELEN]; 2392178479Sjb 2393178479Sjb edst = dt_decl_type(ddp, &dst); 2394178479Sjb dt_decl_free(ddp); 2395178479Sjb 2396178479Sjb esrc = dt_decl_type(sdp, &src); 2397178479Sjb dt_decl_free(sdp); 2398178479Sjb 2399178479Sjb if (edst != 0 || esrc != 0) { 2400178479Sjb free(name); 2401178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 2402178479Sjb } 2403178479Sjb 2404178479Sjb bzero(&sn, sizeof (sn)); 2405178479Sjb dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type); 2406178479Sjb 2407178479Sjb bzero(&dn, sizeof (dn)); 2408178479Sjb dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type); 2409178479Sjb 2410178479Sjb if (dt_xlator_lookup(dtp, &sn, &dn, DT_XLATE_EXACT) != NULL) { 2411178479Sjb xyerror(D_XLATE_REDECL, 2412178479Sjb "translator from %s to %s has already been declared\n", 2413178479Sjb dt_node_type_name(&sn, n1, sizeof (n1)), 2414178479Sjb dt_node_type_name(&dn, n2, sizeof (n2))); 2415178479Sjb } 2416178479Sjb 2417178479Sjb kind = ctf_type_kind(dst.dtt_ctfp, 2418178479Sjb ctf_type_resolve(dst.dtt_ctfp, dst.dtt_type)); 2419178479Sjb 2420178479Sjb if (kind == CTF_K_FORWARD) { 2421178479Sjb xyerror(D_XLATE_SOU, "incomplete struct/union/enum %s\n", 2422178479Sjb dt_type_name(dst.dtt_ctfp, dst.dtt_type, n1, sizeof (n1))); 2423178479Sjb } 2424178479Sjb 2425178479Sjb if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) { 2426178479Sjb xyerror(D_XLATE_SOU, 2427178479Sjb "translator output type must be a struct or union\n"); 2428178479Sjb } 2429178479Sjb 2430178479Sjb dxp = dt_xlator_create(dtp, &src, &dst, name, members, yypcb->pcb_list); 2431178479Sjb yybegin(YYS_CLAUSE); 2432178479Sjb free(name); 2433178479Sjb 2434178479Sjb if (dxp == NULL) 2435178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2436178479Sjb 2437178479Sjb dnp = dt_node_alloc(DT_NODE_XLATOR); 2438178479Sjb dnp->dn_xlator = dxp; 2439178479Sjb dnp->dn_members = members; 2440178479Sjb 2441178479Sjb return (dt_node_cook(dnp, DT_IDFLG_REF)); 2442178479Sjb} 2443178479Sjb 2444178479Sjbdt_node_t * 2445178479Sjbdt_node_probe(char *s, int protoc, dt_node_t *nargs, dt_node_t *xargs) 2446178479Sjb{ 2447178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2448178479Sjb int nargc, xargc; 2449178479Sjb dt_node_t *dnp; 2450178479Sjb 2451178479Sjb size_t len = strlen(s) + 3; /* +3 for :: and \0 */ 2452178479Sjb char *name = alloca(len); 2453178479Sjb 2454178479Sjb (void) snprintf(name, len, "::%s", s); 2455178479Sjb (void) strhyphenate(name); 2456178479Sjb free(s); 2457178479Sjb 2458178479Sjb if (strchr(name, '`') != NULL) { 2459178479Sjb xyerror(D_PROV_BADNAME, "probe name may not " 2460178479Sjb "contain scoping operator: %s\n", name); 2461178479Sjb } 2462178479Sjb 2463178479Sjb if (strlen(name) - 2 >= DTRACE_NAMELEN) { 2464178479Sjb xyerror(D_PROV_BADNAME, "probe name may not exceed %d " 2465178479Sjb "characters: %s\n", DTRACE_NAMELEN - 1, name); 2466178479Sjb } 2467178479Sjb 2468178479Sjb dnp = dt_node_alloc(DT_NODE_PROBE); 2469178479Sjb 2470178479Sjb dnp->dn_ident = dt_ident_create(name, DT_IDENT_PROBE, 2471178479Sjb DT_IDFLG_ORPHAN, DTRACE_IDNONE, _dtrace_defattr, 0, 2472178479Sjb &dt_idops_probe, NULL, dtp->dt_gen); 2473178479Sjb 2474178479Sjb nargc = dt_decl_prototype(nargs, nargs, 2475178479Sjb "probe input", DT_DP_VOID | DT_DP_ANON); 2476178479Sjb 2477178479Sjb xargc = dt_decl_prototype(xargs, nargs, 2478178479Sjb "probe output", DT_DP_VOID); 2479178479Sjb 2480178479Sjb if (nargc > UINT8_MAX) { 2481178479Sjb xyerror(D_PROV_PRARGLEN, "probe %s input prototype exceeds %u " 2482178479Sjb "parameters: %d params used\n", name, UINT8_MAX, nargc); 2483178479Sjb } 2484178479Sjb 2485178479Sjb if (xargc > UINT8_MAX) { 2486178479Sjb xyerror(D_PROV_PRARGLEN, "probe %s output prototype exceeds %u " 2487178479Sjb "parameters: %d params used\n", name, UINT8_MAX, xargc); 2488178479Sjb } 2489178479Sjb 2490178479Sjb if (dnp->dn_ident == NULL || dt_probe_create(dtp, 2491178479Sjb dnp->dn_ident, protoc, nargs, nargc, xargs, xargc) == NULL) 2492178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2493178479Sjb 2494178479Sjb return (dnp); 2495178479Sjb} 2496178479Sjb 2497178479Sjbdt_node_t * 2498178479Sjbdt_node_provider(char *name, dt_node_t *probes) 2499178479Sjb{ 2500178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2501178479Sjb dt_node_t *dnp = dt_node_alloc(DT_NODE_PROVIDER); 2502178479Sjb dt_node_t *lnp; 2503178479Sjb size_t len; 2504178479Sjb 2505178479Sjb dnp->dn_provname = name; 2506178479Sjb dnp->dn_probes = probes; 2507178479Sjb 2508178479Sjb if (strchr(name, '`') != NULL) { 2509178479Sjb dnerror(dnp, D_PROV_BADNAME, "provider name may not " 2510178479Sjb "contain scoping operator: %s\n", name); 2511178479Sjb } 2512178479Sjb 2513178479Sjb if ((len = strlen(name)) >= DTRACE_PROVNAMELEN) { 2514178479Sjb dnerror(dnp, D_PROV_BADNAME, "provider name may not exceed %d " 2515178479Sjb "characters: %s\n", DTRACE_PROVNAMELEN - 1, name); 2516178479Sjb } 2517178479Sjb 2518178479Sjb if (isdigit(name[len - 1])) { 2519178479Sjb dnerror(dnp, D_PROV_BADNAME, "provider name may not " 2520178479Sjb "end with a digit: %s\n", name); 2521178479Sjb } 2522178479Sjb 2523178479Sjb /* 2524178479Sjb * Check to see if the provider is already defined or visible through 2525178479Sjb * dtrace(7D). If so, set dn_provred to treat it as a re-declaration. 2526178479Sjb * If not, create a new provider and set its interface-only flag. This 2527178479Sjb * flag may be cleared later by calls made to dt_probe_declare(). 2528178479Sjb */ 2529178479Sjb if ((dnp->dn_provider = dt_provider_lookup(dtp, name)) != NULL) 2530178479Sjb dnp->dn_provred = B_TRUE; 2531178479Sjb else if ((dnp->dn_provider = dt_provider_create(dtp, name)) == NULL) 2532178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2533178479Sjb else 2534178479Sjb dnp->dn_provider->pv_flags |= DT_PROVIDER_INTF; 2535178479Sjb 2536178479Sjb /* 2537178479Sjb * Store all parse nodes created since we consumed the DT_KEY_PROVIDER 2538178479Sjb * token with the provider and then restore our lexing state to CLAUSE. 2539178479Sjb * Note that if dnp->dn_provred is true, we may end up storing dups of 2540178479Sjb * a provider's interface and implementation: we eat this space because 2541178479Sjb * the implementation will likely need to redeclare probe members, and 2542178479Sjb * therefore may result in those member nodes becoming persistent. 2543178479Sjb */ 2544178479Sjb for (lnp = yypcb->pcb_list; lnp->dn_link != NULL; lnp = lnp->dn_link) 2545178479Sjb continue; /* skip to end of allocation list */ 2546178479Sjb 2547178479Sjb lnp->dn_link = dnp->dn_provider->pv_nodes; 2548178479Sjb dnp->dn_provider->pv_nodes = yypcb->pcb_list; 2549178479Sjb 2550178479Sjb yybegin(YYS_CLAUSE); 2551178479Sjb return (dnp); 2552178479Sjb} 2553178479Sjb 2554178479Sjbdt_node_t * 2555178479Sjbdt_node_program(dt_node_t *lnp) 2556178479Sjb{ 2557178479Sjb dt_node_t *dnp = dt_node_alloc(DT_NODE_PROG); 2558178479Sjb dnp->dn_list = lnp; 2559178479Sjb return (dnp); 2560178479Sjb} 2561178479Sjb 2562178479Sjb/* 2563178479Sjb * This function provides the underlying implementation of cooking an 2564178479Sjb * identifier given its node, a hash of dynamic identifiers, an identifier 2565178479Sjb * kind, and a boolean flag indicating whether we are allowed to instantiate 2566178479Sjb * a new identifier if the string is not found. This function is either 2567178479Sjb * called from dt_cook_ident(), below, or directly by the various cooking 2568178479Sjb * routines that are allowed to instantiate identifiers (e.g. op2 TOK_ASGN). 2569178479Sjb */ 2570178479Sjbstatic void 2571178479Sjbdt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create) 2572178479Sjb{ 2573178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2574178479Sjb const char *sname = dt_idhash_name(dhp); 2575178479Sjb int uref = 0; 2576178479Sjb 2577178479Sjb dtrace_attribute_t attr = _dtrace_defattr; 2578178479Sjb dt_ident_t *idp; 2579178479Sjb dtrace_syminfo_t dts; 2580178479Sjb GElf_Sym sym; 2581178479Sjb 2582178479Sjb const char *scope, *mark; 2583178479Sjb uchar_t dnkind; 2584178479Sjb char *name; 2585178479Sjb 2586178479Sjb /* 2587178479Sjb * Look for scoping marks in the identifier. If one is found, set our 2588178479Sjb * scope to either DTRACE_OBJ_KMODS or UMODS or to the first part of 2589178479Sjb * the string that specifies the scope using an explicit module name. 2590178479Sjb * If two marks in a row are found, set 'uref' (user symbol reference). 2591178479Sjb * Otherwise we set scope to DTRACE_OBJ_EXEC, indicating that normal 2592178479Sjb * scope is desired and we should search the specified idhash. 2593178479Sjb */ 2594178479Sjb if ((name = strrchr(dnp->dn_string, '`')) != NULL) { 2595178479Sjb if (name > dnp->dn_string && name[-1] == '`') { 2596178479Sjb uref++; 2597178479Sjb name[-1] = '\0'; 2598178479Sjb } 2599178479Sjb 2600178479Sjb if (name == dnp->dn_string + uref) 2601178479Sjb scope = uref ? DTRACE_OBJ_UMODS : DTRACE_OBJ_KMODS; 2602178479Sjb else 2603178479Sjb scope = dnp->dn_string; 2604178479Sjb 2605178479Sjb *name++ = '\0'; /* leave name pointing after scoping mark */ 2606178479Sjb dnkind = DT_NODE_VAR; 2607178479Sjb 2608178479Sjb } else if (idkind == DT_IDENT_AGG) { 2609178479Sjb scope = DTRACE_OBJ_EXEC; 2610178479Sjb name = dnp->dn_string + 1; 2611178479Sjb dnkind = DT_NODE_AGG; 2612178479Sjb } else { 2613178479Sjb scope = DTRACE_OBJ_EXEC; 2614178479Sjb name = dnp->dn_string; 2615178479Sjb dnkind = DT_NODE_VAR; 2616178479Sjb } 2617178479Sjb 2618178479Sjb /* 2619178479Sjb * If create is set to false, and we fail our idhash lookup, preset 2620178479Sjb * the errno code to EDT_NOVAR for our final error message below. 2621178479Sjb * If we end up calling dtrace_lookup_by_name(), it will reset the 2622178479Sjb * errno appropriately and that error will be reported instead. 2623178479Sjb */ 2624178479Sjb (void) dt_set_errno(dtp, EDT_NOVAR); 2625178479Sjb mark = uref ? "``" : "`"; 2626178479Sjb 2627178479Sjb if (scope == DTRACE_OBJ_EXEC && ( 2628178479Sjb (dhp != dtp->dt_globals && 2629178479Sjb (idp = dt_idhash_lookup(dhp, name)) != NULL) || 2630178479Sjb (dhp == dtp->dt_globals && 2631178479Sjb (idp = dt_idstack_lookup(&yypcb->pcb_globals, name)) != NULL))) { 2632178479Sjb /* 2633178479Sjb * Check that we are referencing the ident in the manner that 2634178479Sjb * matches its type if this is a global lookup. In the TLS or 2635178479Sjb * local case, we don't know how the ident will be used until 2636178479Sjb * the time operator -> is seen; more parsing is needed. 2637178479Sjb */ 2638178479Sjb if (idp->di_kind != idkind && dhp == dtp->dt_globals) { 2639178479Sjb xyerror(D_IDENT_BADREF, "%s '%s' may not be referenced " 2640178479Sjb "as %s\n", dt_idkind_name(idp->di_kind), 2641178479Sjb idp->di_name, dt_idkind_name(idkind)); 2642178479Sjb } 2643178479Sjb 2644178479Sjb /* 2645178479Sjb * Arrays and aggregations are not cooked individually. They 2646178479Sjb * have dynamic types and must be referenced using operator []. 2647178479Sjb * This is handled explicitly by the code for DT_TOK_LBRAC. 2648178479Sjb */ 2649178479Sjb if (idp->di_kind != DT_IDENT_ARRAY && 2650178479Sjb idp->di_kind != DT_IDENT_AGG) 2651178479Sjb attr = dt_ident_cook(dnp, idp, NULL); 2652178479Sjb else { 2653178479Sjb dt_node_type_assign(dnp, 2654178479Sjb DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); 2655178479Sjb attr = idp->di_attr; 2656178479Sjb } 2657178479Sjb 2658178479Sjb free(dnp->dn_string); 2659178479Sjb dnp->dn_string = NULL; 2660178479Sjb dnp->dn_kind = dnkind; 2661178479Sjb dnp->dn_ident = idp; 2662178479Sjb dnp->dn_flags |= DT_NF_LVALUE; 2663178479Sjb 2664178479Sjb if (idp->di_flags & DT_IDFLG_WRITE) 2665178479Sjb dnp->dn_flags |= DT_NF_WRITABLE; 2666178479Sjb 2667178479Sjb dt_node_attr_assign(dnp, attr); 2668178479Sjb 2669178479Sjb } else if (dhp == dtp->dt_globals && scope != DTRACE_OBJ_EXEC && 2670178479Sjb dtrace_lookup_by_name(dtp, scope, name, &sym, &dts) == 0) { 2671178479Sjb 2672178479Sjb dt_module_t *mp = dt_module_lookup_by_name(dtp, dts.dts_object); 2673178479Sjb int umod = (mp->dm_flags & DT_DM_KERNEL) == 0; 2674178479Sjb static const char *const kunames[] = { "kernel", "user" }; 2675178479Sjb 2676178479Sjb dtrace_typeinfo_t dtt; 2677178479Sjb dtrace_syminfo_t *sip; 2678178479Sjb 2679178479Sjb if (uref ^ umod) { 2680178479Sjb xyerror(D_SYM_BADREF, "%s module '%s' symbol '%s' may " 2681178479Sjb "not be referenced as a %s symbol\n", kunames[umod], 2682178479Sjb dts.dts_object, dts.dts_name, kunames[uref]); 2683178479Sjb } 2684178479Sjb 2685178479Sjb if (dtrace_symbol_type(dtp, &sym, &dts, &dtt) != 0) { 2686178479Sjb /* 2687178479Sjb * For now, we special-case EDT_DATAMODEL to clarify 2688178479Sjb * that mixed data models are not currently supported. 2689178479Sjb */ 2690178479Sjb if (dtp->dt_errno == EDT_DATAMODEL) { 2691178479Sjb xyerror(D_SYM_MODEL, "cannot use %s symbol " 2692178479Sjb "%s%s%s in a %s D program\n", 2693178479Sjb dt_module_modelname(mp), 2694178479Sjb dts.dts_object, mark, dts.dts_name, 2695178479Sjb dt_module_modelname(dtp->dt_ddefs)); 2696178479Sjb } 2697178479Sjb 2698178479Sjb xyerror(D_SYM_NOTYPES, 2699178479Sjb "no symbolic type information is available for " 2700178479Sjb "%s%s%s: %s\n", dts.dts_object, mark, dts.dts_name, 2701178479Sjb dtrace_errmsg(dtp, dtrace_errno(dtp))); 2702178479Sjb } 2703178479Sjb 2704178479Sjb idp = dt_ident_create(name, DT_IDENT_SYMBOL, 0, 0, 2705178479Sjb _dtrace_symattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen); 2706178479Sjb 2707178479Sjb if (idp == NULL) 2708178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2709178479Sjb 2710178479Sjb if (mp->dm_flags & DT_DM_PRIMARY) 2711178479Sjb idp->di_flags |= DT_IDFLG_PRIM; 2712178479Sjb 2713178479Sjb idp->di_next = dtp->dt_externs; 2714178479Sjb dtp->dt_externs = idp; 2715178479Sjb 2716178479Sjb if ((sip = malloc(sizeof (dtrace_syminfo_t))) == NULL) 2717178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2718178479Sjb 2719178479Sjb bcopy(&dts, sip, sizeof (dtrace_syminfo_t)); 2720178479Sjb idp->di_data = sip; 2721178479Sjb idp->di_ctfp = dtt.dtt_ctfp; 2722178479Sjb idp->di_type = dtt.dtt_type; 2723178479Sjb 2724178479Sjb free(dnp->dn_string); 2725178479Sjb dnp->dn_string = NULL; 2726178479Sjb dnp->dn_kind = DT_NODE_SYM; 2727178479Sjb dnp->dn_ident = idp; 2728178479Sjb dnp->dn_flags |= DT_NF_LVALUE; 2729178479Sjb 2730178479Sjb dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); 2731178479Sjb dt_node_attr_assign(dnp, _dtrace_symattr); 2732178479Sjb 2733178479Sjb if (uref) { 2734178479Sjb idp->di_flags |= DT_IDFLG_USER; 2735178479Sjb dnp->dn_flags |= DT_NF_USERLAND; 2736178479Sjb } 2737178479Sjb 2738178479Sjb } else if (scope == DTRACE_OBJ_EXEC && create == B_TRUE) { 2739178479Sjb uint_t flags = DT_IDFLG_WRITE; 2740178479Sjb uint_t id; 2741178479Sjb 2742178479Sjb if (dt_idhash_nextid(dhp, &id) == -1) { 2743178479Sjb xyerror(D_ID_OFLOW, "cannot create %s: limit on number " 2744178479Sjb "of %s variables exceeded\n", name, sname); 2745178479Sjb } 2746178479Sjb 2747178479Sjb if (dhp == yypcb->pcb_locals) 2748178479Sjb flags |= DT_IDFLG_LOCAL; 2749178479Sjb else if (dhp == dtp->dt_tls) 2750178479Sjb flags |= DT_IDFLG_TLS; 2751178479Sjb 2752178479Sjb dt_dprintf("create %s %s variable %s, id=%u\n", 2753178479Sjb sname, dt_idkind_name(idkind), name, id); 2754178479Sjb 2755178479Sjb if (idkind == DT_IDENT_ARRAY || idkind == DT_IDENT_AGG) { 2756178479Sjb idp = dt_idhash_insert(dhp, name, 2757178479Sjb idkind, flags, id, _dtrace_defattr, 0, 2758178479Sjb &dt_idops_assc, NULL, dtp->dt_gen); 2759178479Sjb } else { 2760178479Sjb idp = dt_idhash_insert(dhp, name, 2761178479Sjb idkind, flags, id, _dtrace_defattr, 0, 2762178479Sjb &dt_idops_thaw, NULL, dtp->dt_gen); 2763178479Sjb } 2764178479Sjb 2765178479Sjb if (idp == NULL) 2766178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 2767178479Sjb 2768178479Sjb /* 2769178479Sjb * Arrays and aggregations are not cooked individually. They 2770178479Sjb * have dynamic types and must be referenced using operator []. 2771178479Sjb * This is handled explicitly by the code for DT_TOK_LBRAC. 2772178479Sjb */ 2773178479Sjb if (idp->di_kind != DT_IDENT_ARRAY && 2774178479Sjb idp->di_kind != DT_IDENT_AGG) 2775178479Sjb attr = dt_ident_cook(dnp, idp, NULL); 2776178479Sjb else { 2777178479Sjb dt_node_type_assign(dnp, 2778178479Sjb DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); 2779178479Sjb attr = idp->di_attr; 2780178479Sjb } 2781178479Sjb 2782178479Sjb free(dnp->dn_string); 2783178479Sjb dnp->dn_string = NULL; 2784178479Sjb dnp->dn_kind = dnkind; 2785178479Sjb dnp->dn_ident = idp; 2786178479Sjb dnp->dn_flags |= DT_NF_LVALUE | DT_NF_WRITABLE; 2787178479Sjb 2788178479Sjb dt_node_attr_assign(dnp, attr); 2789178479Sjb 2790178479Sjb } else if (scope != DTRACE_OBJ_EXEC) { 2791178479Sjb xyerror(D_IDENT_UNDEF, "failed to resolve %s%s%s: %s\n", 2792178479Sjb dnp->dn_string, mark, name, 2793178479Sjb dtrace_errmsg(dtp, dtrace_errno(dtp))); 2794178479Sjb } else { 2795178479Sjb xyerror(D_IDENT_UNDEF, "failed to resolve %s: %s\n", 2796178479Sjb dnp->dn_string, dtrace_errmsg(dtp, dtrace_errno(dtp))); 2797178479Sjb } 2798178479Sjb} 2799178479Sjb 2800178479Sjbstatic dt_node_t * 2801178479Sjbdt_cook_ident(dt_node_t *dnp, uint_t idflags) 2802178479Sjb{ 2803178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2804178479Sjb 2805178479Sjb if (dnp->dn_op == DT_TOK_AGG) 2806178479Sjb dt_xcook_ident(dnp, dtp->dt_aggs, DT_IDENT_AGG, B_FALSE); 2807178479Sjb else 2808178479Sjb dt_xcook_ident(dnp, dtp->dt_globals, DT_IDENT_SCALAR, B_FALSE); 2809178479Sjb 2810178479Sjb return (dt_node_cook(dnp, idflags)); 2811178479Sjb} 2812178479Sjb 2813178479Sjb/* 2814178479Sjb * Since operators [ and -> can instantiate new variables before we know 2815178479Sjb * whether the reference is for a read or a write, we need to check read 2816178479Sjb * references to determine if the identifier is currently dt_ident_unref(). 2817178479Sjb * If so, we report that this first access was to an undefined variable. 2818178479Sjb */ 2819178479Sjbstatic dt_node_t * 2820178479Sjbdt_cook_var(dt_node_t *dnp, uint_t idflags) 2821178479Sjb{ 2822178479Sjb dt_ident_t *idp = dnp->dn_ident; 2823178479Sjb 2824178479Sjb if ((idflags & DT_IDFLG_REF) && dt_ident_unref(idp)) { 2825178479Sjb dnerror(dnp, D_VAR_UNDEF, 2826178479Sjb "%s%s has not yet been declared or assigned\n", 2827178479Sjb (idp->di_flags & DT_IDFLG_LOCAL) ? "this->" : 2828178479Sjb (idp->di_flags & DT_IDFLG_TLS) ? "self->" : "", 2829178479Sjb idp->di_name); 2830178479Sjb } 2831178479Sjb 2832178479Sjb dt_node_attr_assign(dnp, dt_ident_cook(dnp, idp, &dnp->dn_args)); 2833178479Sjb return (dnp); 2834178479Sjb} 2835178479Sjb 2836178479Sjb/*ARGSUSED*/ 2837178479Sjbstatic dt_node_t * 2838178479Sjbdt_cook_func(dt_node_t *dnp, uint_t idflags) 2839178479Sjb{ 2840178479Sjb dt_node_attr_assign(dnp, 2841178479Sjb dt_ident_cook(dnp, dnp->dn_ident, &dnp->dn_args)); 2842178479Sjb 2843178479Sjb return (dnp); 2844178479Sjb} 2845178479Sjb 2846178479Sjbstatic dt_node_t * 2847178479Sjbdt_cook_op1(dt_node_t *dnp, uint_t idflags) 2848178479Sjb{ 2849178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 2850178479Sjb dt_node_t *cp = dnp->dn_child; 2851178479Sjb 2852178479Sjb char n[DT_TYPE_NAMELEN]; 2853178479Sjb dtrace_typeinfo_t dtt; 2854178479Sjb dt_ident_t *idp; 2855178479Sjb 2856178479Sjb ctf_encoding_t e; 2857178479Sjb ctf_arinfo_t r; 2858178479Sjb ctf_id_t type, base; 2859178479Sjb uint_t kind; 2860178479Sjb 2861178479Sjb if (dnp->dn_op == DT_TOK_PREINC || dnp->dn_op == DT_TOK_POSTINC || 2862178479Sjb dnp->dn_op == DT_TOK_PREDEC || dnp->dn_op == DT_TOK_POSTDEC) 2863178479Sjb idflags = DT_IDFLG_REF | DT_IDFLG_MOD; 2864178479Sjb else 2865178479Sjb idflags = DT_IDFLG_REF; 2866178479Sjb 2867178479Sjb /* 2868178479Sjb * We allow the unary ++ and -- operators to instantiate new scalar 2869178479Sjb * variables if applied to an identifier; otherwise just cook as usual. 2870178479Sjb */ 2871178479Sjb if (cp->dn_kind == DT_NODE_IDENT && (idflags & DT_IDFLG_MOD)) 2872178479Sjb dt_xcook_ident(cp, dtp->dt_globals, DT_IDENT_SCALAR, B_TRUE); 2873178479Sjb 2874178479Sjb cp = dnp->dn_child = dt_node_cook(cp, 0); /* don't set idflags yet */ 2875178479Sjb 2876178479Sjb if (cp->dn_kind == DT_NODE_VAR && dt_ident_unref(cp->dn_ident)) { 2877178479Sjb if (dt_type_lookup("int64_t", &dtt) != 0) 2878178479Sjb xyerror(D_TYPE_ERR, "failed to lookup int64_t\n"); 2879178479Sjb 2880178479Sjb dt_ident_type_assign(cp->dn_ident, dtt.dtt_ctfp, dtt.dtt_type); 2881178479Sjb dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type); 2882178479Sjb } 2883178479Sjb 2884178479Sjb if (cp->dn_kind == DT_NODE_VAR) 2885178479Sjb cp->dn_ident->di_flags |= idflags; 2886178479Sjb 2887178479Sjb switch (dnp->dn_op) { 2888178479Sjb case DT_TOK_DEREF: 2889178479Sjb /* 2890178479Sjb * If the deref operator is applied to a translated pointer, 2891178479Sjb * we can just set our output type to the base translation. 2892178479Sjb */ 2893178479Sjb if ((idp = dt_node_resolve(cp, DT_IDENT_XLPTR)) != NULL) { 2894178479Sjb dt_xlator_t *dxp = idp->di_data; 2895178479Sjb 2896178479Sjb dnp->dn_ident = &dxp->dx_souid; 2897178479Sjb dt_node_type_assign(dnp, 2898178479Sjb DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); 2899178479Sjb break; 2900178479Sjb } 2901178479Sjb 2902178479Sjb type = ctf_type_resolve(cp->dn_ctfp, cp->dn_type); 2903178479Sjb kind = ctf_type_kind(cp->dn_ctfp, type); 2904178479Sjb 2905178479Sjb if (kind == CTF_K_ARRAY) { 2906178479Sjb if (ctf_array_info(cp->dn_ctfp, type, &r) != 0) { 2907178479Sjb dtp->dt_ctferr = ctf_errno(cp->dn_ctfp); 2908178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_CTF); 2909178479Sjb } else 2910178479Sjb type = r.ctr_contents; 2911178479Sjb } else if (kind == CTF_K_POINTER) { 2912178479Sjb type = ctf_type_reference(cp->dn_ctfp, type); 2913178479Sjb } else { 2914178479Sjb xyerror(D_DEREF_NONPTR, 2915178479Sjb "cannot dereference non-pointer type\n"); 2916178479Sjb } 2917178479Sjb 2918178479Sjb dt_node_type_assign(dnp, cp->dn_ctfp, type); 2919178479Sjb base = ctf_type_resolve(cp->dn_ctfp, type); 2920178479Sjb kind = ctf_type_kind(cp->dn_ctfp, base); 2921178479Sjb 2922178479Sjb if (kind == CTF_K_INTEGER && ctf_type_encoding(cp->dn_ctfp, 2923178479Sjb base, &e) == 0 && IS_VOID(e)) { 2924178479Sjb xyerror(D_DEREF_VOID, 2925178479Sjb "cannot dereference pointer to void\n"); 2926178479Sjb } 2927178479Sjb 2928178479Sjb if (kind == CTF_K_FUNCTION) { 2929178479Sjb xyerror(D_DEREF_FUNC, 2930178479Sjb "cannot dereference pointer to function\n"); 2931178479Sjb } 2932178479Sjb 2933178479Sjb if (kind != CTF_K_ARRAY || dt_node_is_string(dnp)) 2934178479Sjb dnp->dn_flags |= DT_NF_LVALUE; /* see K&R[A7.4.3] */ 2935178479Sjb 2936178479Sjb /* 2937178479Sjb * If we propagated the l-value bit and the child operand was 2938178479Sjb * a writable D variable or a binary operation of the form 2939178479Sjb * a + b where a is writable, then propagate the writable bit. 2940178479Sjb * This is necessary to permit assignments to scalar arrays, 2941178479Sjb * which are converted to expressions of the form *(a + i). 2942178479Sjb */ 2943178479Sjb if ((cp->dn_flags & DT_NF_WRITABLE) || 2944178479Sjb (cp->dn_kind == DT_NODE_OP2 && cp->dn_op == DT_TOK_ADD && 2945178479Sjb (cp->dn_left->dn_flags & DT_NF_WRITABLE))) 2946178479Sjb dnp->dn_flags |= DT_NF_WRITABLE; 2947178479Sjb 2948178479Sjb if ((cp->dn_flags & DT_NF_USERLAND) && 2949178479Sjb (kind == CTF_K_POINTER || (dnp->dn_flags & DT_NF_REF))) 2950178479Sjb dnp->dn_flags |= DT_NF_USERLAND; 2951178479Sjb break; 2952178479Sjb 2953178479Sjb case DT_TOK_IPOS: 2954178479Sjb case DT_TOK_INEG: 2955178479Sjb if (!dt_node_is_arith(cp)) { 2956178479Sjb xyerror(D_OP_ARITH, "operator %s requires an operand " 2957178479Sjb "of arithmetic type\n", opstr(dnp->dn_op)); 2958178479Sjb } 2959178479Sjb dt_node_type_propagate(cp, dnp); /* see K&R[A7.4.4-6] */ 2960178479Sjb break; 2961178479Sjb 2962178479Sjb case DT_TOK_BNEG: 2963178479Sjb if (!dt_node_is_integer(cp)) { 2964178479Sjb xyerror(D_OP_INT, "operator %s requires an operand of " 2965178479Sjb "integral type\n", opstr(dnp->dn_op)); 2966178479Sjb } 2967178479Sjb dt_node_type_propagate(cp, dnp); /* see K&R[A7.4.4-6] */ 2968178479Sjb break; 2969178479Sjb 2970178479Sjb case DT_TOK_LNEG: 2971178479Sjb if (!dt_node_is_scalar(cp)) { 2972178479Sjb xyerror(D_OP_SCALAR, "operator %s requires an operand " 2973178479Sjb "of scalar type\n", opstr(dnp->dn_op)); 2974178479Sjb } 2975178479Sjb dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 2976178479Sjb break; 2977178479Sjb 2978178479Sjb case DT_TOK_ADDROF: 2979178479Sjb if (cp->dn_kind == DT_NODE_VAR || cp->dn_kind == DT_NODE_AGG) { 2980178479Sjb xyerror(D_ADDROF_VAR, 2981178479Sjb "cannot take address of dynamic variable\n"); 2982178479Sjb } 2983178479Sjb 2984178479Sjb if (dt_node_is_dynamic(cp)) { 2985178479Sjb xyerror(D_ADDROF_VAR, 2986178479Sjb "cannot take address of dynamic object\n"); 2987178479Sjb } 2988178479Sjb 2989178479Sjb if (!(cp->dn_flags & DT_NF_LVALUE)) { 2990178479Sjb xyerror(D_ADDROF_LVAL, /* see K&R[A7.4.2] */ 2991178479Sjb "unacceptable operand for unary & operator\n"); 2992178479Sjb } 2993178479Sjb 2994178479Sjb if (cp->dn_flags & DT_NF_BITFIELD) { 2995178479Sjb xyerror(D_ADDROF_BITFIELD, 2996178479Sjb "cannot take address of bit-field\n"); 2997178479Sjb } 2998178479Sjb 2999178479Sjb dtt.dtt_object = NULL; 3000178479Sjb dtt.dtt_ctfp = cp->dn_ctfp; 3001178479Sjb dtt.dtt_type = cp->dn_type; 3002178479Sjb 3003178479Sjb if (dt_type_pointer(&dtt) == -1) { 3004178479Sjb xyerror(D_TYPE_ERR, "cannot find type for \"&\": %s*\n", 3005178479Sjb dt_node_type_name(cp, n, sizeof (n))); 3006178479Sjb } 3007178479Sjb 3008178479Sjb dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type); 3009178479Sjb 3010178479Sjb if (cp->dn_flags & DT_NF_USERLAND) 3011178479Sjb dnp->dn_flags |= DT_NF_USERLAND; 3012178479Sjb break; 3013178479Sjb 3014178479Sjb case DT_TOK_SIZEOF: 3015178479Sjb if (cp->dn_flags & DT_NF_BITFIELD) { 3016178479Sjb xyerror(D_SIZEOF_BITFIELD, 3017178479Sjb "cannot apply sizeof to a bit-field\n"); 3018178479Sjb } 3019178479Sjb 3020178479Sjb if (dt_node_sizeof(cp) == 0) { 3021178479Sjb xyerror(D_SIZEOF_TYPE, "cannot apply sizeof to an " 3022178479Sjb "operand of unknown size\n"); 3023178479Sjb } 3024178479Sjb 3025178479Sjb dt_node_type_assign(dnp, dtp->dt_ddefs->dm_ctfp, 3026178479Sjb ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t")); 3027178479Sjb break; 3028178479Sjb 3029178479Sjb case DT_TOK_STRINGOF: 3030178479Sjb if (!dt_node_is_scalar(cp) && !dt_node_is_pointer(cp) && 3031178479Sjb !dt_node_is_strcompat(cp)) { 3032178479Sjb xyerror(D_STRINGOF_TYPE, 3033178479Sjb "cannot apply stringof to a value of type %s\n", 3034178479Sjb dt_node_type_name(cp, n, sizeof (n))); 3035178479Sjb } 3036178479Sjb dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp)); 3037178479Sjb break; 3038178479Sjb 3039178479Sjb case DT_TOK_PREINC: 3040178479Sjb case DT_TOK_POSTINC: 3041178479Sjb case DT_TOK_PREDEC: 3042178479Sjb case DT_TOK_POSTDEC: 3043178479Sjb if (dt_node_is_scalar(cp) == 0) { 3044178479Sjb xyerror(D_OP_SCALAR, "operator %s requires operand of " 3045178479Sjb "scalar type\n", opstr(dnp->dn_op)); 3046178479Sjb } 3047178479Sjb 3048178479Sjb if (dt_node_is_vfptr(cp)) { 3049178479Sjb xyerror(D_OP_VFPTR, "operator %s requires an operand " 3050178479Sjb "of known size\n", opstr(dnp->dn_op)); 3051178479Sjb } 3052178479Sjb 3053178479Sjb if (!(cp->dn_flags & DT_NF_LVALUE)) { 3054178479Sjb xyerror(D_OP_LVAL, "operator %s requires modifiable " 3055178479Sjb "lvalue as an operand\n", opstr(dnp->dn_op)); 3056178479Sjb } 3057178479Sjb 3058178479Sjb if (!(cp->dn_flags & DT_NF_WRITABLE)) { 3059178479Sjb xyerror(D_OP_WRITE, "operator %s can only be applied " 3060178479Sjb "to a writable variable\n", opstr(dnp->dn_op)); 3061178479Sjb } 3062178479Sjb 3063178479Sjb dt_node_type_propagate(cp, dnp); /* see K&R[A7.4.1] */ 3064178479Sjb break; 3065178479Sjb 3066178479Sjb default: 3067178479Sjb xyerror(D_UNKNOWN, "invalid unary op %s\n", opstr(dnp->dn_op)); 3068178479Sjb } 3069178479Sjb 3070178479Sjb dt_node_attr_assign(dnp, cp->dn_attr); 3071178479Sjb return (dnp); 3072178479Sjb} 3073178479Sjb 3074178479Sjbstatic dt_node_t * 3075178479Sjbdt_cook_op2(dt_node_t *dnp, uint_t idflags) 3076178479Sjb{ 3077178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 3078178479Sjb dt_node_t *lp = dnp->dn_left; 3079178479Sjb dt_node_t *rp = dnp->dn_right; 3080178479Sjb int op = dnp->dn_op; 3081178479Sjb 3082178479Sjb ctf_membinfo_t m; 3083178479Sjb ctf_file_t *ctfp; 3084178479Sjb ctf_id_t type; 3085178479Sjb int kind, val, uref; 3086178479Sjb dt_ident_t *idp; 3087178479Sjb 3088178479Sjb char n1[DT_TYPE_NAMELEN]; 3089178479Sjb char n2[DT_TYPE_NAMELEN]; 3090178479Sjb 3091178479Sjb /* 3092178479Sjb * The expression E1[E2] is identical by definition to *((E1)+(E2)) so 3093178479Sjb * we convert "[" to "+" and glue on "*" at the end (see K&R[A7.3.1]) 3094178479Sjb * unless the left-hand side is an untyped D scalar, associative array, 3095178479Sjb * or aggregation. In these cases, we proceed to case DT_TOK_LBRAC and 3096178479Sjb * handle associative array and aggregation references there. 3097178479Sjb */ 3098178479Sjb if (op == DT_TOK_LBRAC) { 3099178479Sjb if (lp->dn_kind == DT_NODE_IDENT) { 3100178479Sjb dt_idhash_t *dhp; 3101178479Sjb uint_t idkind; 3102178479Sjb 3103178479Sjb if (lp->dn_op == DT_TOK_AGG) { 3104178479Sjb dhp = dtp->dt_aggs; 3105178479Sjb idp = dt_idhash_lookup(dhp, lp->dn_string + 1); 3106178479Sjb idkind = DT_IDENT_AGG; 3107178479Sjb } else { 3108178479Sjb dhp = dtp->dt_globals; 3109178479Sjb idp = dt_idstack_lookup( 3110178479Sjb &yypcb->pcb_globals, lp->dn_string); 3111178479Sjb idkind = DT_IDENT_ARRAY; 3112178479Sjb } 3113178479Sjb 3114178479Sjb if (idp == NULL || dt_ident_unref(idp)) 3115178479Sjb dt_xcook_ident(lp, dhp, idkind, B_TRUE); 3116178479Sjb else 3117178479Sjb dt_xcook_ident(lp, dhp, idp->di_kind, B_FALSE); 3118178479Sjb } else 3119178479Sjb lp = dnp->dn_left = dt_node_cook(lp, 0); 3120178479Sjb 3121178479Sjb /* 3122178479Sjb * Switch op to '+' for *(E1 + E2) array mode in these cases: 3123178479Sjb * (a) lp is a DT_IDENT_ARRAY variable that has already been 3124178479Sjb * referenced using [] notation (dn_args != NULL). 3125178479Sjb * (b) lp is a non-ARRAY variable that has already been given 3126178479Sjb * a type by assignment or declaration (!dt_ident_unref()) 3127178479Sjb * (c) lp is neither a variable nor an aggregation 3128178479Sjb */ 3129178479Sjb if (lp->dn_kind == DT_NODE_VAR) { 3130178479Sjb if (lp->dn_ident->di_kind == DT_IDENT_ARRAY) { 3131178479Sjb if (lp->dn_args != NULL) 3132178479Sjb op = DT_TOK_ADD; 3133178479Sjb } else if (!dt_ident_unref(lp->dn_ident)) 3134178479Sjb op = DT_TOK_ADD; 3135178479Sjb } else if (lp->dn_kind != DT_NODE_AGG) 3136178479Sjb op = DT_TOK_ADD; 3137178479Sjb } 3138178479Sjb 3139178479Sjb switch (op) { 3140178479Sjb case DT_TOK_BAND: 3141178479Sjb case DT_TOK_XOR: 3142178479Sjb case DT_TOK_BOR: 3143178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3144178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3145178479Sjb 3146178479Sjb if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) { 3147178479Sjb xyerror(D_OP_INT, "operator %s requires operands of " 3148178479Sjb "integral type\n", opstr(op)); 3149178479Sjb } 3150178479Sjb 3151178479Sjb dt_node_promote(lp, rp, dnp); /* see K&R[A7.11-13] */ 3152178479Sjb break; 3153178479Sjb 3154178479Sjb case DT_TOK_LSH: 3155178479Sjb case DT_TOK_RSH: 3156178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3157178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3158178479Sjb 3159178479Sjb if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) { 3160178479Sjb xyerror(D_OP_INT, "operator %s requires operands of " 3161178479Sjb "integral type\n", opstr(op)); 3162178479Sjb } 3163178479Sjb 3164178479Sjb dt_node_type_propagate(lp, dnp); /* see K&R[A7.8] */ 3165178479Sjb dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 3166178479Sjb break; 3167178479Sjb 3168178479Sjb case DT_TOK_MOD: 3169178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3170178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3171178479Sjb 3172178479Sjb if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) { 3173178479Sjb xyerror(D_OP_INT, "operator %s requires operands of " 3174178479Sjb "integral type\n", opstr(op)); 3175178479Sjb } 3176178479Sjb 3177178479Sjb dt_node_promote(lp, rp, dnp); /* see K&R[A7.6] */ 3178178479Sjb break; 3179178479Sjb 3180178479Sjb case DT_TOK_MUL: 3181178479Sjb case DT_TOK_DIV: 3182178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3183178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3184178479Sjb 3185178479Sjb if (!dt_node_is_arith(lp) || !dt_node_is_arith(rp)) { 3186178479Sjb xyerror(D_OP_ARITH, "operator %s requires operands of " 3187178479Sjb "arithmetic type\n", opstr(op)); 3188178479Sjb } 3189178479Sjb 3190178479Sjb dt_node_promote(lp, rp, dnp); /* see K&R[A7.6] */ 3191178479Sjb break; 3192178479Sjb 3193178479Sjb case DT_TOK_LAND: 3194178479Sjb case DT_TOK_LXOR: 3195178479Sjb case DT_TOK_LOR: 3196178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3197178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3198178479Sjb 3199178479Sjb if (!dt_node_is_scalar(lp) || !dt_node_is_scalar(rp)) { 3200178479Sjb xyerror(D_OP_SCALAR, "operator %s requires operands " 3201178479Sjb "of scalar type\n", opstr(op)); 3202178479Sjb } 3203178479Sjb 3204178479Sjb dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 3205178479Sjb dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 3206178479Sjb break; 3207178479Sjb 3208178479Sjb case DT_TOK_LT: 3209178479Sjb case DT_TOK_LE: 3210178479Sjb case DT_TOK_GT: 3211178479Sjb case DT_TOK_GE: 3212178479Sjb case DT_TOK_EQU: 3213178479Sjb case DT_TOK_NEQ: 3214178479Sjb /* 3215178479Sjb * The D comparison operators provide the ability to transform 3216178479Sjb * a right-hand identifier into a corresponding enum tag value 3217178479Sjb * if the left-hand side is an enum type. To do this, we cook 3218178479Sjb * the left-hand side, and then see if the right-hand side is 3219178479Sjb * an unscoped identifier defined in the enum. If so, we 3220178479Sjb * convert into an integer constant node with the tag's value. 3221178479Sjb */ 3222178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3223178479Sjb 3224178479Sjb kind = ctf_type_kind(lp->dn_ctfp, 3225178479Sjb ctf_type_resolve(lp->dn_ctfp, lp->dn_type)); 3226178479Sjb 3227178479Sjb if (kind == CTF_K_ENUM && rp->dn_kind == DT_NODE_IDENT && 3228178479Sjb strchr(rp->dn_string, '`') == NULL && ctf_enum_value( 3229178479Sjb lp->dn_ctfp, lp->dn_type, rp->dn_string, &val) == 0) { 3230178479Sjb 3231178479Sjb if ((idp = dt_idstack_lookup(&yypcb->pcb_globals, 3232178479Sjb rp->dn_string)) != NULL) { 3233178479Sjb xyerror(D_IDENT_AMBIG, 3234178479Sjb "ambiguous use of operator %s: %s is " 3235178479Sjb "both a %s enum tag and a global %s\n", 3236178479Sjb opstr(op), rp->dn_string, 3237178479Sjb dt_node_type_name(lp, n1, sizeof (n1)), 3238178479Sjb dt_idkind_name(idp->di_kind)); 3239178479Sjb } 3240178479Sjb 3241178479Sjb free(rp->dn_string); 3242178479Sjb rp->dn_string = NULL; 3243178479Sjb rp->dn_kind = DT_NODE_INT; 3244178479Sjb rp->dn_flags |= DT_NF_COOKED; 3245178479Sjb rp->dn_op = DT_TOK_INT; 3246178479Sjb rp->dn_value = (intmax_t)val; 3247178479Sjb 3248178479Sjb dt_node_type_assign(rp, lp->dn_ctfp, lp->dn_type); 3249178479Sjb dt_node_attr_assign(rp, _dtrace_symattr); 3250178479Sjb } 3251178479Sjb 3252178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3253178479Sjb 3254178479Sjb /* 3255178479Sjb * The rules for type checking for the relational operators are 3256178479Sjb * described in the ANSI-C spec (see K&R[A7.9-10]). We perform 3257178479Sjb * the various tests in order from least to most expensive. We 3258178479Sjb * also allow derived strings to be compared as a first-class 3259178479Sjb * type (resulting in a strcmp(3C)-style comparison), and we 3260178479Sjb * slightly relax the A7.9 rules to permit void pointer 3261178479Sjb * comparisons as in A7.10. Our users won't be confused by 3262178479Sjb * this since they understand pointers are just numbers, and 3263178479Sjb * relaxing this constraint simplifies the implementation. 3264178479Sjb */ 3265178479Sjb if (ctf_type_compat(lp->dn_ctfp, lp->dn_type, 3266178479Sjb rp->dn_ctfp, rp->dn_type)) 3267178479Sjb /*EMPTY*/; 3268178479Sjb else if (dt_node_is_integer(lp) && dt_node_is_integer(rp)) 3269178479Sjb /*EMPTY*/; 3270178479Sjb else if (dt_node_is_strcompat(lp) && dt_node_is_strcompat(rp) && 3271178479Sjb (dt_node_is_string(lp) || dt_node_is_string(rp))) 3272178479Sjb /*EMPTY*/; 3273178479Sjb else if (dt_node_is_ptrcompat(lp, rp, NULL, NULL) == 0) { 3274178479Sjb xyerror(D_OP_INCOMPAT, "operands have " 3275178479Sjb "incompatible types: \"%s\" %s \"%s\"\n", 3276178479Sjb dt_node_type_name(lp, n1, sizeof (n1)), opstr(op), 3277178479Sjb dt_node_type_name(rp, n2, sizeof (n2))); 3278178479Sjb } 3279178479Sjb 3280178479Sjb dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp)); 3281178479Sjb dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 3282178479Sjb break; 3283178479Sjb 3284178479Sjb case DT_TOK_ADD: 3285178479Sjb case DT_TOK_SUB: { 3286178479Sjb /* 3287178479Sjb * The rules for type checking for the additive operators are 3288178479Sjb * described in the ANSI-C spec (see K&R[A7.7]). Pointers and 3289178479Sjb * integers may be manipulated according to specific rules. In 3290178479Sjb * these cases D permits strings to be treated as pointers. 3291178479Sjb */ 3292178479Sjb int lp_is_ptr, lp_is_int, rp_is_ptr, rp_is_int; 3293178479Sjb 3294178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3295178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3296178479Sjb 3297178479Sjb lp_is_ptr = dt_node_is_string(lp) || 3298178479Sjb (dt_node_is_pointer(lp) && !dt_node_is_vfptr(lp)); 3299178479Sjb lp_is_int = dt_node_is_integer(lp); 3300178479Sjb 3301178479Sjb rp_is_ptr = dt_node_is_string(rp) || 3302178479Sjb (dt_node_is_pointer(rp) && !dt_node_is_vfptr(rp)); 3303178479Sjb rp_is_int = dt_node_is_integer(rp); 3304178479Sjb 3305178479Sjb if (lp_is_int && rp_is_int) { 3306178479Sjb dt_type_promote(lp, rp, &ctfp, &type); 3307178479Sjb uref = 0; 3308178479Sjb } else if (lp_is_ptr && rp_is_int) { 3309178479Sjb ctfp = lp->dn_ctfp; 3310178479Sjb type = lp->dn_type; 3311178479Sjb uref = lp->dn_flags & DT_NF_USERLAND; 3312178479Sjb } else if (lp_is_int && rp_is_ptr && op == DT_TOK_ADD) { 3313178479Sjb ctfp = rp->dn_ctfp; 3314178479Sjb type = rp->dn_type; 3315178479Sjb uref = rp->dn_flags & DT_NF_USERLAND; 3316178479Sjb } else if (lp_is_ptr && rp_is_ptr && op == DT_TOK_SUB && 3317178479Sjb dt_node_is_ptrcompat(lp, rp, NULL, NULL)) { 3318178479Sjb ctfp = dtp->dt_ddefs->dm_ctfp; 3319178479Sjb type = ctf_lookup_by_name(ctfp, "ptrdiff_t"); 3320178479Sjb uref = 0; 3321178479Sjb } else { 3322178479Sjb xyerror(D_OP_INCOMPAT, "operands have incompatible " 3323178479Sjb "types: \"%s\" %s \"%s\"\n", 3324178479Sjb dt_node_type_name(lp, n1, sizeof (n1)), opstr(op), 3325178479Sjb dt_node_type_name(rp, n2, sizeof (n2))); 3326178479Sjb } 3327178479Sjb 3328178479Sjb dt_node_type_assign(dnp, ctfp, type); 3329178479Sjb dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 3330178479Sjb 3331178479Sjb if (uref) 3332178479Sjb dnp->dn_flags |= DT_NF_USERLAND; 3333178479Sjb break; 3334178479Sjb } 3335178479Sjb 3336178479Sjb case DT_TOK_OR_EQ: 3337178479Sjb case DT_TOK_XOR_EQ: 3338178479Sjb case DT_TOK_AND_EQ: 3339178479Sjb case DT_TOK_LSH_EQ: 3340178479Sjb case DT_TOK_RSH_EQ: 3341178479Sjb case DT_TOK_MOD_EQ: 3342178479Sjb if (lp->dn_kind == DT_NODE_IDENT) { 3343178479Sjb dt_xcook_ident(lp, dtp->dt_globals, 3344178479Sjb DT_IDENT_SCALAR, B_TRUE); 3345178479Sjb } 3346178479Sjb 3347178479Sjb lp = dnp->dn_left = 3348178479Sjb dt_node_cook(lp, DT_IDFLG_REF | DT_IDFLG_MOD); 3349178479Sjb 3350178479Sjb rp = dnp->dn_right = 3351178479Sjb dt_node_cook(rp, DT_IDFLG_REF | DT_IDFLG_MOD); 3352178479Sjb 3353178479Sjb if (!dt_node_is_integer(lp) || !dt_node_is_integer(rp)) { 3354178479Sjb xyerror(D_OP_INT, "operator %s requires operands of " 3355178479Sjb "integral type\n", opstr(op)); 3356178479Sjb } 3357178479Sjb goto asgn_common; 3358178479Sjb 3359178479Sjb case DT_TOK_MUL_EQ: 3360178479Sjb case DT_TOK_DIV_EQ: 3361178479Sjb if (lp->dn_kind == DT_NODE_IDENT) { 3362178479Sjb dt_xcook_ident(lp, dtp->dt_globals, 3363178479Sjb DT_IDENT_SCALAR, B_TRUE); 3364178479Sjb } 3365178479Sjb 3366178479Sjb lp = dnp->dn_left = 3367178479Sjb dt_node_cook(lp, DT_IDFLG_REF | DT_IDFLG_MOD); 3368178479Sjb 3369178479Sjb rp = dnp->dn_right = 3370178479Sjb dt_node_cook(rp, DT_IDFLG_REF | DT_IDFLG_MOD); 3371178479Sjb 3372178479Sjb if (!dt_node_is_arith(lp) || !dt_node_is_arith(rp)) { 3373178479Sjb xyerror(D_OP_ARITH, "operator %s requires operands of " 3374178479Sjb "arithmetic type\n", opstr(op)); 3375178479Sjb } 3376178479Sjb goto asgn_common; 3377178479Sjb 3378178479Sjb case DT_TOK_ASGN: 3379178479Sjb /* 3380178479Sjb * If the left-hand side is an identifier, attempt to resolve 3381178479Sjb * it as either an aggregation or scalar variable. We pass 3382178479Sjb * B_TRUE to dt_xcook_ident to indicate that a new variable can 3383178479Sjb * be created if no matching variable exists in the namespace. 3384178479Sjb */ 3385178479Sjb if (lp->dn_kind == DT_NODE_IDENT) { 3386178479Sjb if (lp->dn_op == DT_TOK_AGG) { 3387178479Sjb dt_xcook_ident(lp, dtp->dt_aggs, 3388178479Sjb DT_IDENT_AGG, B_TRUE); 3389178479Sjb } else { 3390178479Sjb dt_xcook_ident(lp, dtp->dt_globals, 3391178479Sjb DT_IDENT_SCALAR, B_TRUE); 3392178479Sjb } 3393178479Sjb } 3394178479Sjb 3395178479Sjb lp = dnp->dn_left = dt_node_cook(lp, 0); /* don't set mod yet */ 3396178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3397178479Sjb 3398178479Sjb /* 3399178479Sjb * If the left-hand side is an aggregation, verify that we are 3400178479Sjb * assigning it the result of an aggregating function. Once 3401178479Sjb * we've done so, hide the func node in the aggregation and 3402178479Sjb * return the aggregation itself up to the parse tree parent. 3403178479Sjb * This transformation is legal since the assigned function 3404178479Sjb * cannot change identity across disjoint cooking passes and 3405178479Sjb * the argument list subtree is retained for later cooking. 3406178479Sjb */ 3407178479Sjb if (lp->dn_kind == DT_NODE_AGG) { 3408178479Sjb const char *aname = lp->dn_ident->di_name; 3409178479Sjb dt_ident_t *oid = lp->dn_ident->di_iarg; 3410178479Sjb 3411178479Sjb if (rp->dn_kind != DT_NODE_FUNC || 3412178479Sjb rp->dn_ident->di_kind != DT_IDENT_AGGFUNC) { 3413178479Sjb xyerror(D_AGG_FUNC, 3414178479Sjb "@%s must be assigned the result of " 3415178479Sjb "an aggregating function\n", aname); 3416178479Sjb } 3417178479Sjb 3418178479Sjb if (oid != NULL && oid != rp->dn_ident) { 3419178479Sjb xyerror(D_AGG_REDEF, 3420178479Sjb "aggregation redefined: @%s\n\t " 3421178479Sjb "current: @%s = %s( )\n\tprevious: @%s = " 3422178479Sjb "%s( ) : line %d\n", aname, aname, 3423178479Sjb rp->dn_ident->di_name, aname, oid->di_name, 3424178479Sjb lp->dn_ident->di_lineno); 3425178479Sjb } else if (oid == NULL) 3426178479Sjb lp->dn_ident->di_iarg = rp->dn_ident; 3427178479Sjb 3428178479Sjb /* 3429178479Sjb * Do not allow multiple aggregation assignments in a 3430178479Sjb * single statement, e.g. (@a = count()) = count(); 3431178479Sjb * We produce a message as if the result of aggregating 3432178479Sjb * function does not propagate DT_NF_LVALUE. 3433178479Sjb */ 3434178479Sjb if (lp->dn_aggfun != NULL) { 3435178479Sjb xyerror(D_OP_LVAL, "operator = requires " 3436178479Sjb "modifiable lvalue as an operand\n"); 3437178479Sjb } 3438178479Sjb 3439178479Sjb lp->dn_aggfun = rp; 3440178479Sjb lp = dt_node_cook(lp, DT_IDFLG_MOD); 3441178479Sjb 3442178479Sjb dnp->dn_left = dnp->dn_right = NULL; 3443178479Sjb dt_node_free(dnp); 3444178479Sjb 3445178479Sjb return (lp); 3446178479Sjb } 3447178479Sjb 3448178479Sjb /* 3449178479Sjb * If the right-hand side is a dynamic variable that is the 3450178479Sjb * output of a translator, our result is the translated type. 3451178479Sjb */ 3452178479Sjb if ((idp = dt_node_resolve(rp, DT_IDENT_XLSOU)) != NULL) { 3453178479Sjb ctfp = idp->di_ctfp; 3454178479Sjb type = idp->di_type; 3455178479Sjb uref = idp->di_flags & DT_IDFLG_USER; 3456178479Sjb } else { 3457178479Sjb ctfp = rp->dn_ctfp; 3458178479Sjb type = rp->dn_type; 3459178479Sjb uref = rp->dn_flags & DT_NF_USERLAND; 3460178479Sjb } 3461178479Sjb 3462178479Sjb /* 3463178479Sjb * If the left-hand side of an assignment statement is a virgin 3464178479Sjb * variable created by this compilation pass, reset the type of 3465178479Sjb * this variable to the type of the right-hand side. 3466178479Sjb */ 3467178479Sjb if (lp->dn_kind == DT_NODE_VAR && 3468178479Sjb dt_ident_unref(lp->dn_ident)) { 3469178479Sjb dt_node_type_assign(lp, ctfp, type); 3470178479Sjb dt_ident_type_assign(lp->dn_ident, ctfp, type); 3471178479Sjb 3472178479Sjb if (uref) { 3473178479Sjb lp->dn_flags |= DT_NF_USERLAND; 3474178479Sjb lp->dn_ident->di_flags |= DT_IDFLG_USER; 3475178479Sjb } 3476178479Sjb } 3477178479Sjb 3478178479Sjb if (lp->dn_kind == DT_NODE_VAR) 3479178479Sjb lp->dn_ident->di_flags |= DT_IDFLG_MOD; 3480178479Sjb 3481178479Sjb /* 3482178479Sjb * The rules for type checking for the assignment operators are 3483178479Sjb * described in the ANSI-C spec (see K&R[A7.17]). We share 3484178479Sjb * most of this code with the argument list checking code. 3485178479Sjb */ 3486178479Sjb if (!dt_node_is_string(lp)) { 3487178479Sjb kind = ctf_type_kind(lp->dn_ctfp, 3488178479Sjb ctf_type_resolve(lp->dn_ctfp, lp->dn_type)); 3489178479Sjb 3490178479Sjb if (kind == CTF_K_ARRAY || kind == CTF_K_FUNCTION) { 3491178479Sjb xyerror(D_OP_ARRFUN, "operator %s may not be " 3492178479Sjb "applied to operand of type \"%s\"\n", 3493178479Sjb opstr(op), 3494178479Sjb dt_node_type_name(lp, n1, sizeof (n1))); 3495178479Sjb } 3496178479Sjb } 3497178479Sjb 3498178479Sjb if (idp != NULL && idp->di_kind == DT_IDENT_XLSOU && 3499178479Sjb ctf_type_compat(lp->dn_ctfp, lp->dn_type, ctfp, type)) 3500178479Sjb goto asgn_common; 3501178479Sjb 3502178479Sjb if (dt_node_is_argcompat(lp, rp)) 3503178479Sjb goto asgn_common; 3504178479Sjb 3505178479Sjb xyerror(D_OP_INCOMPAT, 3506178479Sjb "operands have incompatible types: \"%s\" %s \"%s\"\n", 3507178479Sjb dt_node_type_name(lp, n1, sizeof (n1)), opstr(op), 3508178479Sjb dt_node_type_name(rp, n2, sizeof (n2))); 3509178479Sjb /*NOTREACHED*/ 3510178479Sjb 3511178479Sjb case DT_TOK_ADD_EQ: 3512178479Sjb case DT_TOK_SUB_EQ: 3513178479Sjb if (lp->dn_kind == DT_NODE_IDENT) { 3514178479Sjb dt_xcook_ident(lp, dtp->dt_globals, 3515178479Sjb DT_IDENT_SCALAR, B_TRUE); 3516178479Sjb } 3517178479Sjb 3518178479Sjb lp = dnp->dn_left = 3519178479Sjb dt_node_cook(lp, DT_IDFLG_REF | DT_IDFLG_MOD); 3520178479Sjb 3521178479Sjb rp = dnp->dn_right = 3522178479Sjb dt_node_cook(rp, DT_IDFLG_REF | DT_IDFLG_MOD); 3523178479Sjb 3524178479Sjb if (dt_node_is_string(lp) || dt_node_is_string(rp)) { 3525178479Sjb xyerror(D_OP_INCOMPAT, "operands have " 3526178479Sjb "incompatible types: \"%s\" %s \"%s\"\n", 3527178479Sjb dt_node_type_name(lp, n1, sizeof (n1)), opstr(op), 3528178479Sjb dt_node_type_name(rp, n2, sizeof (n2))); 3529178479Sjb } 3530178479Sjb 3531178479Sjb /* 3532178479Sjb * The rules for type checking for the assignment operators are 3533178479Sjb * described in the ANSI-C spec (see K&R[A7.17]). To these 3534178479Sjb * rules we add that only writable D nodes can be modified. 3535178479Sjb */ 3536178479Sjb if (dt_node_is_integer(lp) == 0 || 3537178479Sjb dt_node_is_integer(rp) == 0) { 3538178479Sjb if (!dt_node_is_pointer(lp) || dt_node_is_vfptr(lp)) { 3539178479Sjb xyerror(D_OP_VFPTR, 3540178479Sjb "operator %s requires left-hand scalar " 3541178479Sjb "operand of known size\n", opstr(op)); 3542178479Sjb } else if (dt_node_is_integer(rp) == 0 && 3543178479Sjb dt_node_is_ptrcompat(lp, rp, NULL, NULL) == 0) { 3544178479Sjb xyerror(D_OP_INCOMPAT, "operands have " 3545178479Sjb "incompatible types: \"%s\" %s \"%s\"\n", 3546178479Sjb dt_node_type_name(lp, n1, sizeof (n1)), 3547178479Sjb opstr(op), 3548178479Sjb dt_node_type_name(rp, n2, sizeof (n2))); 3549178479Sjb } 3550178479Sjb } 3551178479Sjbasgn_common: 3552178479Sjb if (!(lp->dn_flags & DT_NF_LVALUE)) { 3553178479Sjb xyerror(D_OP_LVAL, "operator %s requires modifiable " 3554178479Sjb "lvalue as an operand\n", opstr(op)); 3555178479Sjb /* see K&R[A7.17] */ 3556178479Sjb } 3557178479Sjb 3558178479Sjb if (!(lp->dn_flags & DT_NF_WRITABLE)) { 3559178479Sjb xyerror(D_OP_WRITE, "operator %s can only be applied " 3560178479Sjb "to a writable variable\n", opstr(op)); 3561178479Sjb } 3562178479Sjb 3563178479Sjb dt_node_type_propagate(lp, dnp); /* see K&R[A7.17] */ 3564178479Sjb dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 3565178479Sjb break; 3566178479Sjb 3567178479Sjb case DT_TOK_PTR: 3568178479Sjb /* 3569178479Sjb * If the left-hand side of operator -> is the name "self", 3570178479Sjb * then we permit a TLS variable to be created or referenced. 3571178479Sjb */ 3572178479Sjb if (lp->dn_kind == DT_NODE_IDENT && 3573178479Sjb strcmp(lp->dn_string, "self") == 0) { 3574178479Sjb if (rp->dn_kind != DT_NODE_VAR) { 3575178479Sjb dt_xcook_ident(rp, dtp->dt_tls, 3576178479Sjb DT_IDENT_SCALAR, B_TRUE); 3577178479Sjb } 3578178479Sjb 3579178479Sjb if (idflags != 0) 3580178479Sjb rp = dt_node_cook(rp, idflags); 3581178479Sjb 3582178479Sjb dnp->dn_right = dnp->dn_left; /* avoid freeing rp */ 3583178479Sjb dt_node_free(dnp); 3584178479Sjb return (rp); 3585178479Sjb } 3586178479Sjb 3587178479Sjb /* 3588178479Sjb * If the left-hand side of operator -> is the name "this", 3589178479Sjb * then we permit a local variable to be created or referenced. 3590178479Sjb */ 3591178479Sjb if (lp->dn_kind == DT_NODE_IDENT && 3592178479Sjb strcmp(lp->dn_string, "this") == 0) { 3593178479Sjb if (rp->dn_kind != DT_NODE_VAR) { 3594178479Sjb dt_xcook_ident(rp, yypcb->pcb_locals, 3595178479Sjb DT_IDENT_SCALAR, B_TRUE); 3596178479Sjb } 3597178479Sjb 3598178479Sjb if (idflags != 0) 3599178479Sjb rp = dt_node_cook(rp, idflags); 3600178479Sjb 3601178479Sjb dnp->dn_right = dnp->dn_left; /* avoid freeing rp */ 3602178479Sjb dt_node_free(dnp); 3603178479Sjb return (rp); 3604178479Sjb } 3605178479Sjb 3606178479Sjb /*FALLTHRU*/ 3607178479Sjb 3608178479Sjb case DT_TOK_DOT: 3609178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3610178479Sjb 3611178479Sjb if (rp->dn_kind != DT_NODE_IDENT) { 3612178479Sjb xyerror(D_OP_IDENT, "operator %s must be followed by " 3613178479Sjb "an identifier\n", opstr(op)); 3614178479Sjb } 3615178479Sjb 3616178479Sjb if ((idp = dt_node_resolve(lp, DT_IDENT_XLSOU)) != NULL || 3617178479Sjb (idp = dt_node_resolve(lp, DT_IDENT_XLPTR)) != NULL) { 3618178479Sjb /* 3619178479Sjb * If the left-hand side is a translated struct or ptr, 3620178479Sjb * the type of the left is the translation output type. 3621178479Sjb */ 3622178479Sjb dt_xlator_t *dxp = idp->di_data; 3623178479Sjb 3624178479Sjb if (dt_xlator_member(dxp, rp->dn_string) == NULL) { 3625178479Sjb xyerror(D_XLATE_NOCONV, 3626178479Sjb "translator does not define conversion " 3627178479Sjb "for member: %s\n", rp->dn_string); 3628178479Sjb } 3629178479Sjb 3630178479Sjb ctfp = idp->di_ctfp; 3631178479Sjb type = ctf_type_resolve(ctfp, idp->di_type); 3632178479Sjb uref = idp->di_flags & DT_IDFLG_USER; 3633178479Sjb } else { 3634178479Sjb ctfp = lp->dn_ctfp; 3635178479Sjb type = ctf_type_resolve(ctfp, lp->dn_type); 3636178479Sjb uref = lp->dn_flags & DT_NF_USERLAND; 3637178479Sjb } 3638178479Sjb 3639178479Sjb kind = ctf_type_kind(ctfp, type); 3640178479Sjb 3641178479Sjb if (op == DT_TOK_PTR) { 3642178479Sjb if (kind != CTF_K_POINTER) { 3643178479Sjb xyerror(D_OP_PTR, "operator %s must be " 3644178479Sjb "applied to a pointer\n", opstr(op)); 3645178479Sjb } 3646178479Sjb type = ctf_type_reference(ctfp, type); 3647178479Sjb type = ctf_type_resolve(ctfp, type); 3648178479Sjb kind = ctf_type_kind(ctfp, type); 3649178479Sjb } 3650178479Sjb 3651178479Sjb /* 3652178479Sjb * If we follow a reference to a forward declaration tag, 3653178479Sjb * search the entire type space for the actual definition. 3654178479Sjb */ 3655178479Sjb while (kind == CTF_K_FORWARD) { 3656178479Sjb char *tag = ctf_type_name(ctfp, type, n1, sizeof (n1)); 3657178479Sjb dtrace_typeinfo_t dtt; 3658178479Sjb 3659178479Sjb if (tag != NULL && dt_type_lookup(tag, &dtt) == 0 && 3660178479Sjb (dtt.dtt_ctfp != ctfp || dtt.dtt_type != type)) { 3661178479Sjb ctfp = dtt.dtt_ctfp; 3662178479Sjb type = ctf_type_resolve(ctfp, dtt.dtt_type); 3663178479Sjb kind = ctf_type_kind(ctfp, type); 3664178479Sjb } else { 3665178479Sjb xyerror(D_OP_INCOMPLETE, 3666178479Sjb "operator %s cannot be applied to a " 3667178479Sjb "forward declaration: no %s definition " 3668178479Sjb "is available\n", opstr(op), tag); 3669178479Sjb } 3670178479Sjb } 3671178479Sjb 3672178479Sjb if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) { 3673178479Sjb if (op == DT_TOK_PTR) { 3674178479Sjb xyerror(D_OP_SOU, "operator -> cannot be " 3675178479Sjb "applied to pointer to type \"%s\"; must " 3676178479Sjb "be applied to a struct or union pointer\n", 3677178479Sjb ctf_type_name(ctfp, type, n1, sizeof (n1))); 3678178479Sjb } else { 3679178479Sjb xyerror(D_OP_SOU, "operator %s cannot be " 3680178479Sjb "applied to type \"%s\"; must be applied " 3681178479Sjb "to a struct or union\n", opstr(op), 3682178479Sjb ctf_type_name(ctfp, type, n1, sizeof (n1))); 3683178479Sjb } 3684178479Sjb } 3685178479Sjb 3686178479Sjb if (ctf_member_info(ctfp, type, rp->dn_string, &m) == CTF_ERR) { 3687178479Sjb xyerror(D_TYPE_MEMBER, 3688178479Sjb "%s is not a member of %s\n", rp->dn_string, 3689178479Sjb ctf_type_name(ctfp, type, n1, sizeof (n1))); 3690178479Sjb } 3691178479Sjb 3692178479Sjb type = ctf_type_resolve(ctfp, m.ctm_type); 3693178479Sjb kind = ctf_type_kind(ctfp, type); 3694178479Sjb 3695178479Sjb dt_node_type_assign(dnp, ctfp, m.ctm_type); 3696178479Sjb dt_node_attr_assign(dnp, lp->dn_attr); 3697178479Sjb 3698178479Sjb if (op == DT_TOK_PTR && (kind != CTF_K_ARRAY || 3699178479Sjb dt_node_is_string(dnp))) 3700178479Sjb dnp->dn_flags |= DT_NF_LVALUE; /* see K&R[A7.3.3] */ 3701178479Sjb 3702178479Sjb if (op == DT_TOK_DOT && (lp->dn_flags & DT_NF_LVALUE) && 3703178479Sjb (kind != CTF_K_ARRAY || dt_node_is_string(dnp))) 3704178479Sjb dnp->dn_flags |= DT_NF_LVALUE; /* see K&R[A7.3.3] */ 3705178479Sjb 3706178479Sjb if (lp->dn_flags & DT_NF_WRITABLE) 3707178479Sjb dnp->dn_flags |= DT_NF_WRITABLE; 3708178479Sjb 3709178479Sjb if (uref && (kind == CTF_K_POINTER || 3710178479Sjb (dnp->dn_flags & DT_NF_REF))) 3711178479Sjb dnp->dn_flags |= DT_NF_USERLAND; 3712178479Sjb break; 3713178479Sjb 3714178479Sjb case DT_TOK_LBRAC: { 3715178479Sjb /* 3716178479Sjb * If op is DT_TOK_LBRAC, we know from the special-case code at 3717178479Sjb * the top that lp is either a D variable or an aggregation. 3718178479Sjb */ 3719178479Sjb dt_node_t *lnp; 3720178479Sjb 3721178479Sjb /* 3722178479Sjb * If the left-hand side is an aggregation, just set dn_aggtup 3723178479Sjb * to the right-hand side and return the cooked aggregation. 3724178479Sjb * This transformation is legal since we are just collapsing 3725178479Sjb * nodes to simplify later processing, and the entire aggtup 3726178479Sjb * parse subtree is retained for subsequent cooking passes. 3727178479Sjb */ 3728178479Sjb if (lp->dn_kind == DT_NODE_AGG) { 3729178479Sjb if (lp->dn_aggtup != NULL) { 3730178479Sjb xyerror(D_AGG_MDIM, "improper attempt to " 3731178479Sjb "reference @%s as a multi-dimensional " 3732178479Sjb "array\n", lp->dn_ident->di_name); 3733178479Sjb } 3734178479Sjb 3735178479Sjb lp->dn_aggtup = rp; 3736178479Sjb lp = dt_node_cook(lp, 0); 3737178479Sjb 3738178479Sjb dnp->dn_left = dnp->dn_right = NULL; 3739178479Sjb dt_node_free(dnp); 3740178479Sjb 3741178479Sjb return (lp); 3742178479Sjb } 3743178479Sjb 3744178479Sjb assert(lp->dn_kind == DT_NODE_VAR); 3745178479Sjb idp = lp->dn_ident; 3746178479Sjb 3747178479Sjb /* 3748178479Sjb * If the left-hand side is a non-global scalar that hasn't yet 3749178479Sjb * been referenced or modified, it was just created by self-> 3750178479Sjb * or this-> and we can convert it from scalar to assoc array. 3751178479Sjb */ 3752178479Sjb if (idp->di_kind == DT_IDENT_SCALAR && dt_ident_unref(idp) && 3753178479Sjb (idp->di_flags & (DT_IDFLG_LOCAL | DT_IDFLG_TLS)) != 0) { 3754178479Sjb 3755178479Sjb if (idp->di_flags & DT_IDFLG_LOCAL) { 3756178479Sjb xyerror(D_ARR_LOCAL, 3757178479Sjb "local variables may not be used as " 3758178479Sjb "associative arrays: %s\n", idp->di_name); 3759178479Sjb } 3760178479Sjb 3761178479Sjb dt_dprintf("morph variable %s (id %u) from scalar to " 3762178479Sjb "array\n", idp->di_name, idp->di_id); 3763178479Sjb 3764178479Sjb dt_ident_morph(idp, DT_IDENT_ARRAY, 3765178479Sjb &dt_idops_assc, NULL); 3766178479Sjb } 3767178479Sjb 3768178479Sjb if (idp->di_kind != DT_IDENT_ARRAY) { 3769178479Sjb xyerror(D_IDENT_BADREF, "%s '%s' may not be referenced " 3770178479Sjb "as %s\n", dt_idkind_name(idp->di_kind), 3771178479Sjb idp->di_name, dt_idkind_name(DT_IDENT_ARRAY)); 3772178479Sjb } 3773178479Sjb 3774178479Sjb /* 3775178479Sjb * Now that we've confirmed our left-hand side is a DT_NODE_VAR 3776178479Sjb * of idkind DT_IDENT_ARRAY, we need to splice the [ node from 3777178479Sjb * the parse tree and leave a cooked DT_NODE_VAR in its place 3778178479Sjb * where dn_args for the VAR node is the right-hand 'rp' tree, 3779178479Sjb * as shown in the parse tree diagram below: 3780178479Sjb * 3781178479Sjb * / / 3782178479Sjb * [ OP2 "[" ]=dnp [ VAR ]=dnp 3783178479Sjb * / \ => | 3784178479Sjb * / \ +- dn_args -> [ ??? ]=rp 3785178479Sjb * [ VAR ]=lp [ ??? ]=rp 3786178479Sjb * 3787178479Sjb * Since the final dt_node_cook(dnp) can fail using longjmp we 3788178479Sjb * must perform the transformations as a group first by over- 3789178479Sjb * writing 'dnp' to become the VAR node, so that the parse tree 3790178479Sjb * is guaranteed to be in a consistent state if the cook fails. 3791178479Sjb */ 3792178479Sjb assert(lp->dn_kind == DT_NODE_VAR); 3793178479Sjb assert(lp->dn_args == NULL); 3794178479Sjb 3795178479Sjb lnp = dnp->dn_link; 3796178479Sjb bcopy(lp, dnp, sizeof (dt_node_t)); 3797178479Sjb dnp->dn_link = lnp; 3798178479Sjb 3799178479Sjb dnp->dn_args = rp; 3800178479Sjb dnp->dn_list = NULL; 3801178479Sjb 3802178479Sjb dt_node_free(lp); 3803178479Sjb return (dt_node_cook(dnp, idflags)); 3804178479Sjb } 3805178479Sjb 3806178479Sjb case DT_TOK_XLATE: { 3807178479Sjb dt_xlator_t *dxp; 3808178479Sjb 3809178479Sjb assert(lp->dn_kind == DT_NODE_TYPE); 3810178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3811178479Sjb dxp = dt_xlator_lookup(dtp, rp, lp, DT_XLATE_FUZZY); 3812178479Sjb 3813178479Sjb if (dxp == NULL) { 3814178479Sjb xyerror(D_XLATE_NONE, 3815178479Sjb "cannot translate from \"%s\" to \"%s\"\n", 3816178479Sjb dt_node_type_name(rp, n1, sizeof (n1)), 3817178479Sjb dt_node_type_name(lp, n2, sizeof (n2))); 3818178479Sjb } 3819178479Sjb 3820178479Sjb dnp->dn_ident = dt_xlator_ident(dxp, lp->dn_ctfp, lp->dn_type); 3821178479Sjb dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); 3822178479Sjb dt_node_attr_assign(dnp, 3823178479Sjb dt_attr_min(rp->dn_attr, dnp->dn_ident->di_attr)); 3824178479Sjb break; 3825178479Sjb } 3826178479Sjb 3827178479Sjb case DT_TOK_LPAR: { 3828178479Sjb ctf_id_t ltype, rtype; 3829178479Sjb uint_t lkind, rkind; 3830178479Sjb 3831178479Sjb assert(lp->dn_kind == DT_NODE_TYPE); 3832178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3833178479Sjb 3834178479Sjb ltype = ctf_type_resolve(lp->dn_ctfp, lp->dn_type); 3835178479Sjb lkind = ctf_type_kind(lp->dn_ctfp, ltype); 3836178479Sjb 3837178479Sjb rtype = ctf_type_resolve(rp->dn_ctfp, rp->dn_type); 3838178479Sjb rkind = ctf_type_kind(rp->dn_ctfp, rtype); 3839178479Sjb 3840178479Sjb /* 3841178479Sjb * The rules for casting are loosely explained in K&R[A7.5] 3842178479Sjb * and K&R[A6]. Basically, we can cast to the same type or 3843178479Sjb * same base type, between any kind of scalar values, from 3844178479Sjb * arrays to pointers, and we can cast anything to void. 3845178479Sjb * To these rules D adds casts from scalars to strings. 3846178479Sjb */ 3847178479Sjb if (ctf_type_compat(lp->dn_ctfp, lp->dn_type, 3848178479Sjb rp->dn_ctfp, rp->dn_type)) 3849178479Sjb /*EMPTY*/; 3850178479Sjb else if (dt_node_is_scalar(lp) && 3851178479Sjb (dt_node_is_scalar(rp) || rkind == CTF_K_FUNCTION)) 3852178479Sjb /*EMPTY*/; 3853178479Sjb else if (dt_node_is_void(lp)) 3854178479Sjb /*EMPTY*/; 3855178479Sjb else if (lkind == CTF_K_POINTER && dt_node_is_pointer(rp)) 3856178479Sjb /*EMPTY*/; 3857178479Sjb else if (dt_node_is_string(lp) && (dt_node_is_scalar(rp) || 3858178479Sjb dt_node_is_pointer(rp) || dt_node_is_strcompat(rp))) 3859178479Sjb /*EMPTY*/; 3860178479Sjb else { 3861178479Sjb xyerror(D_CAST_INVAL, 3862178479Sjb "invalid cast expression: \"%s\" to \"%s\"\n", 3863178479Sjb dt_node_type_name(rp, n1, sizeof (n1)), 3864178479Sjb dt_node_type_name(lp, n2, sizeof (n2))); 3865178479Sjb } 3866178479Sjb 3867178479Sjb dt_node_type_propagate(lp, dnp); /* see K&R[A7.5] */ 3868178479Sjb dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 3869178479Sjb break; 3870178479Sjb } 3871178479Sjb 3872178479Sjb case DT_TOK_COMMA: 3873178479Sjb lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF); 3874178479Sjb rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF); 3875178479Sjb 3876178479Sjb if (dt_node_is_dynamic(lp) || dt_node_is_dynamic(rp)) { 3877178479Sjb xyerror(D_OP_DYN, "operator %s operands " 3878178479Sjb "cannot be of dynamic type\n", opstr(op)); 3879178479Sjb } 3880178479Sjb 3881178479Sjb if (dt_node_is_actfunc(lp) || dt_node_is_actfunc(rp)) { 3882178479Sjb xyerror(D_OP_ACT, "operator %s operands " 3883178479Sjb "cannot be actions\n", opstr(op)); 3884178479Sjb } 3885178479Sjb 3886178479Sjb dt_node_type_propagate(rp, dnp); /* see K&R[A7.18] */ 3887178479Sjb dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr)); 3888178479Sjb break; 3889178479Sjb 3890178479Sjb default: 3891178479Sjb xyerror(D_UNKNOWN, "invalid binary op %s\n", opstr(op)); 3892178479Sjb } 3893178479Sjb 3894178479Sjb /* 3895178479Sjb * Complete the conversion of E1[E2] to *((E1)+(E2)) that we started 3896178479Sjb * at the top of our switch() above (see K&R[A7.3.1]). Since E2 is 3897178479Sjb * parsed as an argument_expression_list by dt_grammar.y, we can 3898178479Sjb * end up with a comma-separated list inside of a non-associative 3899178479Sjb * array reference. We check for this and report an appropriate error. 3900178479Sjb */ 3901178479Sjb if (dnp->dn_op == DT_TOK_LBRAC && op == DT_TOK_ADD) { 3902178479Sjb dt_node_t *pnp; 3903178479Sjb 3904178479Sjb if (rp->dn_list != NULL) { 3905178479Sjb xyerror(D_ARR_BADREF, 3906178479Sjb "cannot access %s as an associative array\n", 3907178479Sjb dt_node_name(lp, n1, sizeof (n1))); 3908178479Sjb } 3909178479Sjb 3910178479Sjb dnp->dn_op = DT_TOK_ADD; 3911178479Sjb pnp = dt_node_op1(DT_TOK_DEREF, dnp); 3912178479Sjb 3913178479Sjb /* 3914178479Sjb * Cook callbacks are not typically permitted to allocate nodes. 3915178479Sjb * When we do, we must insert them in the middle of an existing 3916178479Sjb * allocation list rather than having them appended to the pcb 3917178479Sjb * list because the sub-expression may be part of a definition. 3918178479Sjb */ 3919178479Sjb assert(yypcb->pcb_list == pnp); 3920178479Sjb yypcb->pcb_list = pnp->dn_link; 3921178479Sjb 3922178479Sjb pnp->dn_link = dnp->dn_link; 3923178479Sjb dnp->dn_link = pnp; 3924178479Sjb 3925178479Sjb return (dt_node_cook(pnp, DT_IDFLG_REF)); 3926178479Sjb } 3927178479Sjb 3928178479Sjb return (dnp); 3929178479Sjb} 3930178479Sjb 3931178479Sjb/*ARGSUSED*/ 3932178479Sjbstatic dt_node_t * 3933178479Sjbdt_cook_op3(dt_node_t *dnp, uint_t idflags) 3934178479Sjb{ 3935178479Sjb dt_node_t *lp, *rp; 3936178479Sjb ctf_file_t *ctfp; 3937178479Sjb ctf_id_t type; 3938178479Sjb 3939178479Sjb dnp->dn_expr = dt_node_cook(dnp->dn_expr, DT_IDFLG_REF); 3940178479Sjb lp = dnp->dn_left = dt_node_cook(dnp->dn_left, DT_IDFLG_REF); 3941178479Sjb rp = dnp->dn_right = dt_node_cook(dnp->dn_right, DT_IDFLG_REF); 3942178479Sjb 3943178479Sjb if (!dt_node_is_scalar(dnp->dn_expr)) { 3944178479Sjb xyerror(D_OP_SCALAR, 3945178479Sjb "operator ?: expression must be of scalar type\n"); 3946178479Sjb } 3947178479Sjb 3948178479Sjb if (dt_node_is_dynamic(lp) || dt_node_is_dynamic(rp)) { 3949178479Sjb xyerror(D_OP_DYN, 3950178479Sjb "operator ?: operands cannot be of dynamic type\n"); 3951178479Sjb } 3952178479Sjb 3953178479Sjb /* 3954178479Sjb * The rules for type checking for the ternary operator are complex and 3955178479Sjb * are described in the ANSI-C spec (see K&R[A7.16]). We implement 3956178479Sjb * the various tests in order from least to most expensive. 3957178479Sjb */ 3958178479Sjb if (ctf_type_compat(lp->dn_ctfp, lp->dn_type, 3959178479Sjb rp->dn_ctfp, rp->dn_type)) { 3960178479Sjb ctfp = lp->dn_ctfp; 3961178479Sjb type = lp->dn_type; 3962178479Sjb } else if (dt_node_is_integer(lp) && dt_node_is_integer(rp)) { 3963178479Sjb dt_type_promote(lp, rp, &ctfp, &type); 3964178479Sjb } else if (dt_node_is_strcompat(lp) && dt_node_is_strcompat(rp) && 3965178479Sjb (dt_node_is_string(lp) || dt_node_is_string(rp))) { 3966178479Sjb ctfp = DT_STR_CTFP(yypcb->pcb_hdl); 3967178479Sjb type = DT_STR_TYPE(yypcb->pcb_hdl); 3968178479Sjb } else if (dt_node_is_ptrcompat(lp, rp, &ctfp, &type) == 0) { 3969178479Sjb xyerror(D_OP_INCOMPAT, 3970178479Sjb "operator ?: operands must have compatible types\n"); 3971178479Sjb } 3972178479Sjb 3973178479Sjb if (dt_node_is_actfunc(lp) || dt_node_is_actfunc(rp)) { 3974178479Sjb xyerror(D_OP_ACT, "action cannot be " 3975178479Sjb "used in a conditional context\n"); 3976178479Sjb } 3977178479Sjb 3978178479Sjb dt_node_type_assign(dnp, ctfp, type); 3979178479Sjb dt_node_attr_assign(dnp, dt_attr_min(dnp->dn_expr->dn_attr, 3980178479Sjb dt_attr_min(lp->dn_attr, rp->dn_attr))); 3981178479Sjb 3982178479Sjb return (dnp); 3983178479Sjb} 3984178479Sjb 3985178479Sjbstatic dt_node_t * 3986178479Sjbdt_cook_statement(dt_node_t *dnp, uint_t idflags) 3987178479Sjb{ 3988178479Sjb dnp->dn_expr = dt_node_cook(dnp->dn_expr, idflags); 3989178479Sjb dt_node_attr_assign(dnp, dnp->dn_expr->dn_attr); 3990178479Sjb 3991178479Sjb return (dnp); 3992178479Sjb} 3993178479Sjb 3994178479Sjb/* 3995178479Sjb * If dn_aggfun is set, this node is a collapsed aggregation assignment (see 3996178479Sjb * the special case code for DT_TOK_ASGN in dt_cook_op2() above), in which 3997178479Sjb * case we cook both the tuple and the function call. If dn_aggfun is NULL, 3998178479Sjb * this node is just a reference to the aggregation's type and attributes. 3999178479Sjb */ 4000178479Sjb/*ARGSUSED*/ 4001178479Sjbstatic dt_node_t * 4002178479Sjbdt_cook_aggregation(dt_node_t *dnp, uint_t idflags) 4003178479Sjb{ 4004178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 4005178479Sjb 4006178479Sjb if (dnp->dn_aggfun != NULL) { 4007178479Sjb dnp->dn_aggfun = dt_node_cook(dnp->dn_aggfun, DT_IDFLG_REF); 4008178479Sjb dt_node_attr_assign(dnp, dt_ident_cook(dnp, 4009178479Sjb dnp->dn_ident, &dnp->dn_aggtup)); 4010178479Sjb } else { 4011178479Sjb dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); 4012178479Sjb dt_node_attr_assign(dnp, dnp->dn_ident->di_attr); 4013178479Sjb } 4014178479Sjb 4015178479Sjb return (dnp); 4016178479Sjb} 4017178479Sjb 4018178479Sjb/* 4019178479Sjb * Since D permits new variable identifiers to be instantiated in any program 4020178479Sjb * expression, we may need to cook a clause's predicate either before or after 4021178479Sjb * the action list depending on the program code in question. Consider: 4022178479Sjb * 4023178479Sjb * probe-description-list probe-description-list 4024178479Sjb * /x++/ /x == 0/ 4025178479Sjb * { { 4026178479Sjb * trace(x); trace(x++); 4027178479Sjb * } } 4028178479Sjb * 4029178479Sjb * In the left-hand example, the predicate uses operator ++ to instantiate 'x' 4030178479Sjb * as a variable of type int64_t. The predicate must be cooked first because 4031178479Sjb * otherwise the statement trace(x) refers to an unknown identifier. In the 4032178479Sjb * right-hand example, the action list uses ++ to instantiate 'x'; the action 4033178479Sjb * list must be cooked first because otherwise the predicate x == 0 refers to 4034178479Sjb * an unknown identifier. In order to simplify programming, we support both. 4035178479Sjb * 4036178479Sjb * When cooking a clause, we cook the action statements before the predicate by 4037178479Sjb * default, since it seems more common to create or modify identifiers in the 4038178479Sjb * action list. If cooking fails due to an unknown identifier, we attempt to 4039178479Sjb * cook the predicate (i.e. do it first) and then go back and cook the actions. 4040178479Sjb * If this, too, fails (or if we get an error other than D_IDENT_UNDEF) we give 4041178479Sjb * up and report failure back to the user. There are five possible paths: 4042178479Sjb * 4043178479Sjb * cook actions = OK, cook predicate = OK -> OK 4044178479Sjb * cook actions = OK, cook predicate = ERR -> ERR 4045178479Sjb * cook actions = ERR, cook predicate = ERR -> ERR 4046178479Sjb * cook actions = ERR, cook predicate = OK, cook actions = OK -> OK 4047178479Sjb * cook actions = ERR, cook predicate = OK, cook actions = ERR -> ERR 4048178479Sjb * 4049178479Sjb * The programmer can still defeat our scheme by creating circular definition 4050178479Sjb * dependencies between predicates and actions, as in this example clause: 4051178479Sjb * 4052178479Sjb * probe-description-list 4053178479Sjb * /x++ && y == 0/ 4054178479Sjb * { 4055178479Sjb * trace(x + y++); 4056178479Sjb * } 4057178479Sjb * 4058178479Sjb * but it doesn't seem worth the complexity to handle such rare cases. The 4059178479Sjb * user can simply use the D variable declaration syntax to work around them. 4060178479Sjb */ 4061178479Sjbstatic dt_node_t * 4062178479Sjbdt_cook_clause(dt_node_t *dnp, uint_t idflags) 4063178479Sjb{ 4064178479Sjb volatile int err, tries; 4065178479Sjb jmp_buf ojb; 4066178479Sjb 4067178479Sjb /* 4068178479Sjb * Before assigning dn_ctxattr, temporarily assign the probe attribute 4069178479Sjb * to 'dnp' itself to force an attribute check and minimum violation. 4070178479Sjb */ 4071178479Sjb dt_node_attr_assign(dnp, yypcb->pcb_pinfo.dtp_attr); 4072178479Sjb dnp->dn_ctxattr = yypcb->pcb_pinfo.dtp_attr; 4073178479Sjb 4074178479Sjb bcopy(yypcb->pcb_jmpbuf, ojb, sizeof (jmp_buf)); 4075178479Sjb tries = 0; 4076178479Sjb 4077178479Sjb if (dnp->dn_pred != NULL && (err = setjmp(yypcb->pcb_jmpbuf)) != 0) { 4078178479Sjb bcopy(ojb, yypcb->pcb_jmpbuf, sizeof (jmp_buf)); 4079178479Sjb if (tries++ != 0 || err != EDT_COMPILER || ( 4080178479Sjb yypcb->pcb_hdl->dt_errtag != dt_errtag(D_IDENT_UNDEF) && 4081178479Sjb yypcb->pcb_hdl->dt_errtag != dt_errtag(D_VAR_UNDEF))) 4082178479Sjb longjmp(yypcb->pcb_jmpbuf, err); 4083178479Sjb } 4084178479Sjb 4085178479Sjb if (tries == 0) { 4086178479Sjb yylabel("action list"); 4087178479Sjb 4088178479Sjb dt_node_attr_assign(dnp, 4089178479Sjb dt_node_list_cook(&dnp->dn_acts, idflags)); 4090178479Sjb 4091178479Sjb bcopy(ojb, yypcb->pcb_jmpbuf, sizeof (jmp_buf)); 4092178479Sjb yylabel(NULL); 4093178479Sjb } 4094178479Sjb 4095178479Sjb if (dnp->dn_pred != NULL) { 4096178479Sjb yylabel("predicate"); 4097178479Sjb 4098178479Sjb dnp->dn_pred = dt_node_cook(dnp->dn_pred, idflags); 4099178479Sjb dt_node_attr_assign(dnp, 4100178479Sjb dt_attr_min(dnp->dn_attr, dnp->dn_pred->dn_attr)); 4101178479Sjb 4102178479Sjb if (!dt_node_is_scalar(dnp->dn_pred)) { 4103178479Sjb xyerror(D_PRED_SCALAR, 4104178479Sjb "predicate result must be of scalar type\n"); 4105178479Sjb } 4106178479Sjb 4107178479Sjb yylabel(NULL); 4108178479Sjb } 4109178479Sjb 4110178479Sjb if (tries != 0) { 4111178479Sjb yylabel("action list"); 4112178479Sjb 4113178479Sjb dt_node_attr_assign(dnp, 4114178479Sjb dt_node_list_cook(&dnp->dn_acts, idflags)); 4115178479Sjb 4116178479Sjb yylabel(NULL); 4117178479Sjb } 4118178479Sjb 4119178479Sjb return (dnp); 4120178479Sjb} 4121178479Sjb 4122178479Sjb/*ARGSUSED*/ 4123178479Sjbstatic dt_node_t * 4124178479Sjbdt_cook_inline(dt_node_t *dnp, uint_t idflags) 4125178479Sjb{ 4126178479Sjb dt_idnode_t *inp = dnp->dn_ident->di_iarg; 4127178479Sjb dt_ident_t *rdp; 4128178479Sjb 4129178479Sjb char n1[DT_TYPE_NAMELEN]; 4130178479Sjb char n2[DT_TYPE_NAMELEN]; 4131178479Sjb 4132178479Sjb assert(dnp->dn_ident->di_flags & DT_IDFLG_INLINE); 4133178479Sjb assert(inp->din_root->dn_flags & DT_NF_COOKED); 4134178479Sjb 4135178479Sjb /* 4136178479Sjb * If we are inlining a translation, verify that the inline declaration 4137178479Sjb * type exactly matches the type that is returned by the translation. 4138178479Sjb * Otherwise just use dt_node_is_argcompat() to check the types. 4139178479Sjb */ 4140178479Sjb if ((rdp = dt_node_resolve(inp->din_root, DT_IDENT_XLSOU)) != NULL || 4141178479Sjb (rdp = dt_node_resolve(inp->din_root, DT_IDENT_XLPTR)) != NULL) { 4142178479Sjb 4143178479Sjb ctf_file_t *lctfp = dnp->dn_ctfp; 4144178479Sjb ctf_id_t ltype = ctf_type_resolve(lctfp, dnp->dn_type); 4145178479Sjb 4146178479Sjb dt_xlator_t *dxp = rdp->di_data; 4147178479Sjb ctf_file_t *rctfp = dxp->dx_dst_ctfp; 4148178479Sjb ctf_id_t rtype = dxp->dx_dst_base; 4149178479Sjb 4150178479Sjb if (ctf_type_kind(lctfp, ltype) == CTF_K_POINTER) { 4151178479Sjb ltype = ctf_type_reference(lctfp, ltype); 4152178479Sjb ltype = ctf_type_resolve(lctfp, ltype); 4153178479Sjb } 4154178479Sjb 4155178479Sjb if (ctf_type_compat(lctfp, ltype, rctfp, rtype) == 0) { 4156178479Sjb dnerror(dnp, D_OP_INCOMPAT, 4157178479Sjb "inline %s definition uses incompatible types: " 4158178479Sjb "\"%s\" = \"%s\"\n", dnp->dn_ident->di_name, 4159178479Sjb dt_type_name(lctfp, ltype, n1, sizeof (n1)), 4160178479Sjb dt_type_name(rctfp, rtype, n2, sizeof (n2))); 4161178479Sjb } 4162178479Sjb 4163178479Sjb } else if (dt_node_is_argcompat(dnp, inp->din_root) == 0) { 4164178479Sjb dnerror(dnp, D_OP_INCOMPAT, 4165178479Sjb "inline %s definition uses incompatible types: " 4166178479Sjb "\"%s\" = \"%s\"\n", dnp->dn_ident->di_name, 4167178479Sjb dt_node_type_name(dnp, n1, sizeof (n1)), 4168178479Sjb dt_node_type_name(inp->din_root, n2, sizeof (n2))); 4169178479Sjb } 4170178479Sjb 4171178479Sjb return (dnp); 4172178479Sjb} 4173178479Sjb 4174178479Sjbstatic dt_node_t * 4175178479Sjbdt_cook_member(dt_node_t *dnp, uint_t idflags) 4176178479Sjb{ 4177178479Sjb dnp->dn_membexpr = dt_node_cook(dnp->dn_membexpr, idflags); 4178178479Sjb dt_node_attr_assign(dnp, dnp->dn_membexpr->dn_attr); 4179178479Sjb return (dnp); 4180178479Sjb} 4181178479Sjb 4182178479Sjb/*ARGSUSED*/ 4183178479Sjbstatic dt_node_t * 4184178479Sjbdt_cook_xlator(dt_node_t *dnp, uint_t idflags) 4185178479Sjb{ 4186178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 4187178479Sjb dt_xlator_t *dxp = dnp->dn_xlator; 4188178479Sjb dt_node_t *mnp; 4189178479Sjb 4190178479Sjb char n1[DT_TYPE_NAMELEN]; 4191178479Sjb char n2[DT_TYPE_NAMELEN]; 4192178479Sjb 4193178479Sjb dtrace_attribute_t attr = _dtrace_maxattr; 4194178479Sjb ctf_membinfo_t ctm; 4195178479Sjb 4196178479Sjb /* 4197178479Sjb * Before cooking each translator member, we push a reference to the 4198178479Sjb * hash containing translator-local identifiers on to pcb_globals to 4199178479Sjb * temporarily interpose these identifiers in front of other globals. 4200178479Sjb */ 4201178479Sjb dt_idstack_push(&yypcb->pcb_globals, dxp->dx_locals); 4202178479Sjb 4203178479Sjb for (mnp = dnp->dn_members; mnp != NULL; mnp = mnp->dn_list) { 4204178479Sjb if (ctf_member_info(dxp->dx_dst_ctfp, dxp->dx_dst_type, 4205178479Sjb mnp->dn_membname, &ctm) == CTF_ERR) { 4206178479Sjb xyerror(D_XLATE_MEMB, 4207178479Sjb "translator member %s is not a member of %s\n", 4208178479Sjb mnp->dn_membname, ctf_type_name(dxp->dx_dst_ctfp, 4209178479Sjb dxp->dx_dst_type, n1, sizeof (n1))); 4210178479Sjb } 4211178479Sjb 4212178479Sjb (void) dt_node_cook(mnp, DT_IDFLG_REF); 4213178479Sjb dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type); 4214178479Sjb attr = dt_attr_min(attr, mnp->dn_attr); 4215178479Sjb 4216178479Sjb if (dt_node_is_argcompat(mnp, mnp->dn_membexpr) == 0) { 4217178479Sjb xyerror(D_XLATE_INCOMPAT, 4218178479Sjb "translator member %s definition uses " 4219178479Sjb "incompatible types: \"%s\" = \"%s\"\n", 4220178479Sjb mnp->dn_membname, 4221178479Sjb dt_node_type_name(mnp, n1, sizeof (n1)), 4222178479Sjb dt_node_type_name(mnp->dn_membexpr, 4223178479Sjb n2, sizeof (n2))); 4224178479Sjb } 4225178479Sjb } 4226178479Sjb 4227178479Sjb dt_idstack_pop(&yypcb->pcb_globals, dxp->dx_locals); 4228178479Sjb 4229178479Sjb dxp->dx_souid.di_attr = attr; 4230178479Sjb dxp->dx_ptrid.di_attr = attr; 4231178479Sjb 4232178479Sjb dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp)); 4233178479Sjb dt_node_attr_assign(dnp, _dtrace_defattr); 4234178479Sjb 4235178479Sjb return (dnp); 4236178479Sjb} 4237178479Sjb 4238178479Sjbstatic void 4239178479Sjbdt_node_provider_cmp_argv(dt_provider_t *pvp, dt_node_t *pnp, const char *kind, 4240178479Sjb uint_t old_argc, dt_node_t *old_argv, uint_t new_argc, dt_node_t *new_argv) 4241178479Sjb{ 4242178479Sjb dt_probe_t *prp = pnp->dn_ident->di_data; 4243178479Sjb uint_t i; 4244178479Sjb 4245178479Sjb char n1[DT_TYPE_NAMELEN]; 4246178479Sjb char n2[DT_TYPE_NAMELEN]; 4247178479Sjb 4248178479Sjb if (old_argc != new_argc) { 4249178479Sjb dnerror(pnp, D_PROV_INCOMPAT, 4250178479Sjb "probe %s:%s %s prototype mismatch:\n" 4251178479Sjb "\t current: %u arg%s\n\tprevious: %u arg%s\n", 4252178479Sjb pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, kind, 4253178479Sjb new_argc, new_argc != 1 ? "s" : "", 4254178479Sjb old_argc, old_argc != 1 ? "s" : ""); 4255178479Sjb } 4256178479Sjb 4257178479Sjb for (i = 0; i < old_argc; i++, 4258178479Sjb old_argv = old_argv->dn_list, new_argv = new_argv->dn_list) { 4259178479Sjb if (ctf_type_cmp(old_argv->dn_ctfp, old_argv->dn_type, 4260178479Sjb new_argv->dn_ctfp, new_argv->dn_type) == 0) 4261178479Sjb continue; 4262178479Sjb 4263178479Sjb dnerror(pnp, D_PROV_INCOMPAT, 4264178479Sjb "probe %s:%s %s prototype argument #%u mismatch:\n" 4265178479Sjb "\t current: %s\n\tprevious: %s\n", 4266178479Sjb pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, kind, i + 1, 4267178479Sjb dt_node_type_name(new_argv, n1, sizeof (n1)), 4268178479Sjb dt_node_type_name(old_argv, n2, sizeof (n2))); 4269178479Sjb } 4270178479Sjb} 4271178479Sjb 4272178479Sjb/* 4273178479Sjb * Compare a new probe declaration with an existing probe definition (either 4274178479Sjb * from a previous declaration or cached from the kernel). If the existing 4275178479Sjb * definition and declaration both have an input and output parameter list, 4276178479Sjb * compare both lists. Otherwise compare only the output parameter lists. 4277178479Sjb */ 4278178479Sjbstatic void 4279178479Sjbdt_node_provider_cmp(dt_provider_t *pvp, dt_node_t *pnp, 4280178479Sjb dt_probe_t *old, dt_probe_t *new) 4281178479Sjb{ 4282178479Sjb dt_node_provider_cmp_argv(pvp, pnp, "output", 4283178479Sjb old->pr_xargc, old->pr_xargs, new->pr_xargc, new->pr_xargs); 4284178479Sjb 4285178479Sjb if (old->pr_nargs != old->pr_xargs && new->pr_nargs != new->pr_xargs) { 4286178479Sjb dt_node_provider_cmp_argv(pvp, pnp, "input", 4287178479Sjb old->pr_nargc, old->pr_nargs, new->pr_nargc, new->pr_nargs); 4288178479Sjb } 4289178479Sjb 4290178479Sjb if (old->pr_nargs == old->pr_xargs && new->pr_nargs != new->pr_xargs) { 4291178479Sjb if (pvp->pv_flags & DT_PROVIDER_IMPL) { 4292178479Sjb dnerror(pnp, D_PROV_INCOMPAT, 4293178479Sjb "provider interface mismatch: %s\n" 4294178479Sjb "\t current: probe %s:%s has an output prototype\n" 4295178479Sjb "\tprevious: probe %s:%s has no output prototype\n", 4296178479Sjb pvp->pv_desc.dtvd_name, pvp->pv_desc.dtvd_name, 4297178479Sjb new->pr_ident->di_name, pvp->pv_desc.dtvd_name, 4298178479Sjb old->pr_ident->di_name); 4299178479Sjb } 4300178479Sjb 4301178479Sjb if (old->pr_ident->di_gen == yypcb->pcb_hdl->dt_gen) 4302178479Sjb old->pr_ident->di_flags |= DT_IDFLG_ORPHAN; 4303178479Sjb 4304178479Sjb dt_idhash_delete(pvp->pv_probes, old->pr_ident); 4305178479Sjb dt_probe_declare(pvp, new); 4306178479Sjb } 4307178479Sjb} 4308178479Sjb 4309178479Sjbstatic void 4310178479Sjbdt_cook_probe(dt_node_t *dnp, dt_provider_t *pvp) 4311178479Sjb{ 4312178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 4313178479Sjb dt_probe_t *prp = dnp->dn_ident->di_data; 4314178479Sjb 4315178479Sjb dt_xlator_t *dxp; 4316178479Sjb uint_t i; 4317178479Sjb 4318178479Sjb char n1[DT_TYPE_NAMELEN]; 4319178479Sjb char n2[DT_TYPE_NAMELEN]; 4320178479Sjb 4321178479Sjb if (prp->pr_nargs == prp->pr_xargs) 4322178479Sjb return; 4323178479Sjb 4324178479Sjb for (i = 0; i < prp->pr_xargc; i++) { 4325178479Sjb dt_node_t *xnp = prp->pr_xargv[i]; 4326178479Sjb dt_node_t *nnp = prp->pr_nargv[prp->pr_mapping[i]]; 4327178479Sjb 4328178479Sjb if ((dxp = dt_xlator_lookup(dtp, 4329178479Sjb nnp, xnp, DT_XLATE_FUZZY)) != NULL) { 4330178479Sjb if (dt_provider_xref(dtp, pvp, dxp->dx_id) != 0) 4331178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); 4332178479Sjb continue; 4333178479Sjb } 4334178479Sjb 4335178479Sjb if (dt_node_is_argcompat(nnp, xnp)) 4336178479Sjb continue; /* no translator defined and none required */ 4337178479Sjb 4338178479Sjb dnerror(dnp, D_PROV_PRXLATOR, "translator for %s:%s output " 4339178479Sjb "argument #%u from %s to %s is not defined\n", 4340178479Sjb pvp->pv_desc.dtvd_name, dnp->dn_ident->di_name, i + 1, 4341178479Sjb dt_node_type_name(nnp, n1, sizeof (n1)), 4342178479Sjb dt_node_type_name(xnp, n2, sizeof (n2))); 4343178479Sjb } 4344178479Sjb} 4345178479Sjb 4346178479Sjb/*ARGSUSED*/ 4347178479Sjbstatic dt_node_t * 4348178479Sjbdt_cook_provider(dt_node_t *dnp, uint_t idflags) 4349178479Sjb{ 4350178479Sjb dt_provider_t *pvp = dnp->dn_provider; 4351178479Sjb dt_node_t *pnp; 4352178479Sjb 4353178479Sjb /* 4354178479Sjb * If we're declaring a provider for the first time and it is unknown 4355178479Sjb * to dtrace(7D), insert the probe definitions into the provider's hash. 4356178479Sjb * If we're redeclaring a known provider, verify the interface matches. 4357178479Sjb */ 4358178479Sjb for (pnp = dnp->dn_probes; pnp != NULL; pnp = pnp->dn_list) { 4359178479Sjb const char *probename = pnp->dn_ident->di_name; 4360178479Sjb dt_probe_t *prp = dt_probe_lookup(pvp, probename); 4361178479Sjb 4362178479Sjb assert(pnp->dn_kind == DT_NODE_PROBE); 4363178479Sjb 4364178479Sjb if (prp != NULL && dnp->dn_provred) { 4365178479Sjb dt_node_provider_cmp(pvp, pnp, 4366178479Sjb prp, pnp->dn_ident->di_data); 4367178479Sjb } else if (prp == NULL && dnp->dn_provred) { 4368178479Sjb dnerror(pnp, D_PROV_INCOMPAT, 4369178479Sjb "provider interface mismatch: %s\n" 4370178479Sjb "\t current: probe %s:%s defined\n" 4371178479Sjb "\tprevious: probe %s:%s not defined\n", 4372178479Sjb dnp->dn_provname, dnp->dn_provname, 4373178479Sjb probename, dnp->dn_provname, probename); 4374178479Sjb } else if (prp != NULL) { 4375178479Sjb dnerror(pnp, D_PROV_PRDUP, "probe redeclared: %s:%s\n", 4376178479Sjb dnp->dn_provname, probename); 4377178479Sjb } else 4378178479Sjb dt_probe_declare(pvp, pnp->dn_ident->di_data); 4379178479Sjb 4380178479Sjb dt_cook_probe(pnp, pvp); 4381178479Sjb } 4382178479Sjb 4383178479Sjb return (dnp); 4384178479Sjb} 4385178479Sjb 4386178479Sjb/*ARGSUSED*/ 4387178479Sjbstatic dt_node_t * 4388178479Sjbdt_cook_none(dt_node_t *dnp, uint_t idflags) 4389178479Sjb{ 4390178479Sjb return (dnp); 4391178479Sjb} 4392178479Sjb 4393178479Sjbstatic dt_node_t *(*dt_cook_funcs[])(dt_node_t *, uint_t) = { 4394178479Sjb dt_cook_none, /* DT_NODE_FREE */ 4395178479Sjb dt_cook_none, /* DT_NODE_INT */ 4396178479Sjb dt_cook_none, /* DT_NODE_STRING */ 4397178479Sjb dt_cook_ident, /* DT_NODE_IDENT */ 4398178479Sjb dt_cook_var, /* DT_NODE_VAR */ 4399178479Sjb dt_cook_none, /* DT_NODE_SYM */ 4400178479Sjb dt_cook_none, /* DT_NODE_TYPE */ 4401178479Sjb dt_cook_func, /* DT_NODE_FUNC */ 4402178479Sjb dt_cook_op1, /* DT_NODE_OP1 */ 4403178479Sjb dt_cook_op2, /* DT_NODE_OP2 */ 4404178479Sjb dt_cook_op3, /* DT_NODE_OP3 */ 4405178479Sjb dt_cook_statement, /* DT_NODE_DEXPR */ 4406178479Sjb dt_cook_statement, /* DT_NODE_DFUNC */ 4407178479Sjb dt_cook_aggregation, /* DT_NODE_AGG */ 4408178479Sjb dt_cook_none, /* DT_NODE_PDESC */ 4409178479Sjb dt_cook_clause, /* DT_NODE_CLAUSE */ 4410178479Sjb dt_cook_inline, /* DT_NODE_INLINE */ 4411178479Sjb dt_cook_member, /* DT_NODE_MEMBER */ 4412178479Sjb dt_cook_xlator, /* DT_NODE_XLATOR */ 4413178479Sjb dt_cook_none, /* DT_NODE_PROBE */ 4414178479Sjb dt_cook_provider, /* DT_NODE_PROVIDER */ 4415178479Sjb dt_cook_none /* DT_NODE_PROG */ 4416178479Sjb}; 4417178479Sjb 4418178479Sjb/* 4419178479Sjb * Recursively cook the parse tree starting at the specified node. The idflags 4420178479Sjb * parameter is used to indicate the type of reference (r/w) and is applied to 4421178479Sjb * the resulting identifier if it is a D variable or D aggregation. 4422178479Sjb */ 4423178479Sjbdt_node_t * 4424178479Sjbdt_node_cook(dt_node_t *dnp, uint_t idflags) 4425178479Sjb{ 4426178479Sjb int oldlineno = yylineno; 4427178479Sjb 4428178479Sjb yylineno = dnp->dn_line; 4429178479Sjb 4430178479Sjb dnp = dt_cook_funcs[dnp->dn_kind](dnp, idflags); 4431178479Sjb dnp->dn_flags |= DT_NF_COOKED; 4432178479Sjb 4433178479Sjb if (dnp->dn_kind == DT_NODE_VAR || dnp->dn_kind == DT_NODE_AGG) 4434178479Sjb dnp->dn_ident->di_flags |= idflags; 4435178479Sjb 4436178479Sjb yylineno = oldlineno; 4437178479Sjb return (dnp); 4438178479Sjb} 4439178479Sjb 4440178479Sjbdtrace_attribute_t 4441178479Sjbdt_node_list_cook(dt_node_t **pnp, uint_t idflags) 4442178479Sjb{ 4443178479Sjb dtrace_attribute_t attr = _dtrace_defattr; 4444178479Sjb dt_node_t *dnp, *nnp; 4445178479Sjb 4446178479Sjb for (dnp = (pnp != NULL ? *pnp : NULL); dnp != NULL; dnp = nnp) { 4447178479Sjb nnp = dnp->dn_list; 4448178479Sjb dnp = *pnp = dt_node_cook(dnp, idflags); 4449178479Sjb attr = dt_attr_min(attr, dnp->dn_attr); 4450178479Sjb dnp->dn_list = nnp; 4451178479Sjb pnp = &dnp->dn_list; 4452178479Sjb } 4453178479Sjb 4454178479Sjb return (attr); 4455178479Sjb} 4456178479Sjb 4457178479Sjbvoid 4458178479Sjbdt_node_list_free(dt_node_t **pnp) 4459178479Sjb{ 4460178479Sjb dt_node_t *dnp, *nnp; 4461178479Sjb 4462178479Sjb for (dnp = (pnp != NULL ? *pnp : NULL); dnp != NULL; dnp = nnp) { 4463178479Sjb nnp = dnp->dn_list; 4464178479Sjb dt_node_free(dnp); 4465178479Sjb } 4466178479Sjb 4467178479Sjb if (pnp != NULL) 4468178479Sjb *pnp = NULL; 4469178479Sjb} 4470178479Sjb 4471178479Sjbvoid 4472178479Sjbdt_node_link_free(dt_node_t **pnp) 4473178479Sjb{ 4474178479Sjb dt_node_t *dnp, *nnp; 4475178479Sjb 4476178479Sjb for (dnp = (pnp != NULL ? *pnp : NULL); dnp != NULL; dnp = nnp) { 4477178479Sjb nnp = dnp->dn_link; 4478178479Sjb dt_node_free(dnp); 4479178479Sjb } 4480178479Sjb 4481178479Sjb for (dnp = (pnp != NULL ? *pnp : NULL); dnp != NULL; dnp = nnp) { 4482178479Sjb nnp = dnp->dn_link; 4483178479Sjb free(dnp); 4484178479Sjb } 4485178479Sjb 4486178479Sjb if (pnp != NULL) 4487178479Sjb *pnp = NULL; 4488178479Sjb} 4489178479Sjb 4490178479Sjbdt_node_t * 4491178479Sjbdt_node_link(dt_node_t *lp, dt_node_t *rp) 4492178479Sjb{ 4493178479Sjb dt_node_t *dnp; 4494178479Sjb 4495178479Sjb if (lp == NULL) 4496178479Sjb return (rp); 4497178479Sjb else if (rp == NULL) 4498178479Sjb return (lp); 4499178479Sjb 4500178479Sjb for (dnp = lp; dnp->dn_list != NULL; dnp = dnp->dn_list) 4501178479Sjb continue; 4502178479Sjb 4503178479Sjb dnp->dn_list = rp; 4504178479Sjb return (lp); 4505178479Sjb} 4506178479Sjb 4507178479Sjb/* 4508178479Sjb * Compute the DOF dtrace_diftype_t representation of a node's type. This is 4509178479Sjb * called from a variety of places in the library so it cannot assume yypcb 4510178479Sjb * is valid: any references to handle-specific data must be made through 'dtp'. 4511178479Sjb */ 4512178479Sjbvoid 4513178479Sjbdt_node_diftype(dtrace_hdl_t *dtp, const dt_node_t *dnp, dtrace_diftype_t *tp) 4514178479Sjb{ 4515178479Sjb if (dnp->dn_ctfp == DT_STR_CTFP(dtp) && 4516178479Sjb dnp->dn_type == DT_STR_TYPE(dtp)) { 4517178479Sjb tp->dtdt_kind = DIF_TYPE_STRING; 4518178479Sjb tp->dtdt_ckind = CTF_K_UNKNOWN; 4519178479Sjb } else { 4520178479Sjb tp->dtdt_kind = DIF_TYPE_CTF; 4521178479Sjb tp->dtdt_ckind = ctf_type_kind(dnp->dn_ctfp, 4522178479Sjb ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type)); 4523178479Sjb } 4524178479Sjb 4525178479Sjb tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ? DIF_TF_BYREF : 0; 4526178479Sjb tp->dtdt_pad = 0; 4527178479Sjb tp->dtdt_size = ctf_type_size(dnp->dn_ctfp, dnp->dn_type); 4528178479Sjb} 4529178479Sjb 4530178479Sjbvoid 4531178479Sjbdt_node_printr(dt_node_t *dnp, FILE *fp, int depth) 4532178479Sjb{ 4533178479Sjb char n[DT_TYPE_NAMELEN], buf[BUFSIZ], a[8]; 4534178479Sjb const dtrace_syminfo_t *dts; 4535178479Sjb const dt_idnode_t *inp; 4536178479Sjb dt_node_t *arg; 4537178479Sjb 4538178479Sjb (void) fprintf(fp, "%*s", depth * 2, ""); 4539178479Sjb (void) dt_attr_str(dnp->dn_attr, a, sizeof (a)); 4540178479Sjb 4541178479Sjb if (dnp->dn_ctfp != NULL && dnp->dn_type != CTF_ERR && 4542178479Sjb ctf_type_name(dnp->dn_ctfp, dnp->dn_type, n, sizeof (n)) != NULL) { 4543178479Sjb (void) snprintf(buf, BUFSIZ, "type=<%s> attr=%s flags=", n, a); 4544178479Sjb } else { 4545178479Sjb (void) snprintf(buf, BUFSIZ, "type=<%ld> attr=%s flags=", 4546178479Sjb dnp->dn_type, a); 4547178479Sjb } 4548178479Sjb 4549178479Sjb if (dnp->dn_flags != 0) { 4550178479Sjb n[0] = '\0'; 4551178479Sjb if (dnp->dn_flags & DT_NF_SIGNED) 4552178479Sjb (void) strcat(n, ",SIGN"); 4553178479Sjb if (dnp->dn_flags & DT_NF_COOKED) 4554178479Sjb (void) strcat(n, ",COOK"); 4555178479Sjb if (dnp->dn_flags & DT_NF_REF) 4556178479Sjb (void) strcat(n, ",REF"); 4557178479Sjb if (dnp->dn_flags & DT_NF_LVALUE) 4558178479Sjb (void) strcat(n, ",LVAL"); 4559178479Sjb if (dnp->dn_flags & DT_NF_WRITABLE) 4560178479Sjb (void) strcat(n, ",WRITE"); 4561178479Sjb if (dnp->dn_flags & DT_NF_BITFIELD) 4562178479Sjb (void) strcat(n, ",BITF"); 4563178479Sjb if (dnp->dn_flags & DT_NF_USERLAND) 4564178479Sjb (void) strcat(n, ",USER"); 4565178479Sjb (void) strcat(buf, n + 1); 4566178479Sjb } else 4567178479Sjb (void) strcat(buf, "0"); 4568178479Sjb 4569178479Sjb switch (dnp->dn_kind) { 4570178479Sjb case DT_NODE_FREE: 4571178479Sjb (void) fprintf(fp, "FREE <node %p>\n", (void *)dnp); 4572178479Sjb break; 4573178479Sjb 4574178479Sjb case DT_NODE_INT: 4575178479Sjb (void) fprintf(fp, "INT 0x%llx (%s)\n", 4576178479Sjb (u_longlong_t)dnp->dn_value, buf); 4577178479Sjb break; 4578178479Sjb 4579178479Sjb case DT_NODE_STRING: 4580178479Sjb (void) fprintf(fp, "STRING \"%s\" (%s)\n", dnp->dn_string, buf); 4581178479Sjb break; 4582178479Sjb 4583178479Sjb case DT_NODE_IDENT: 4584178479Sjb (void) fprintf(fp, "IDENT %s (%s)\n", dnp->dn_string, buf); 4585178479Sjb break; 4586178479Sjb 4587178479Sjb case DT_NODE_VAR: 4588178479Sjb (void) fprintf(fp, "VARIABLE %s%s (%s)\n", 4589178479Sjb (dnp->dn_ident->di_flags & DT_IDFLG_LOCAL) ? "this->" : 4590178479Sjb (dnp->dn_ident->di_flags & DT_IDFLG_TLS) ? "self->" : "", 4591178479Sjb dnp->dn_ident->di_name, buf); 4592178479Sjb 4593178479Sjb if (dnp->dn_args != NULL) 4594178479Sjb (void) fprintf(fp, "%*s[\n", depth * 2, ""); 4595178479Sjb 4596178479Sjb for (arg = dnp->dn_args; arg != NULL; arg = arg->dn_list) { 4597178479Sjb dt_node_printr(arg, fp, depth + 1); 4598178479Sjb if (arg->dn_list != NULL) 4599178479Sjb (void) fprintf(fp, "%*s,\n", depth * 2, ""); 4600178479Sjb } 4601178479Sjb 4602178479Sjb if (dnp->dn_args != NULL) 4603178479Sjb (void) fprintf(fp, "%*s]\n", depth * 2, ""); 4604178479Sjb break; 4605178479Sjb 4606178479Sjb case DT_NODE_SYM: 4607178479Sjb dts = dnp->dn_ident->di_data; 4608178479Sjb (void) fprintf(fp, "SYMBOL %s`%s (%s)\n", 4609178479Sjb dts->dts_object, dts->dts_name, buf); 4610178479Sjb break; 4611178479Sjb 4612178479Sjb case DT_NODE_TYPE: 4613178479Sjb if (dnp->dn_string != NULL) { 4614178479Sjb (void) fprintf(fp, "TYPE (%s) %s\n", 4615178479Sjb buf, dnp->dn_string); 4616178479Sjb } else 4617178479Sjb (void) fprintf(fp, "TYPE (%s)\n", buf); 4618178479Sjb break; 4619178479Sjb 4620178479Sjb case DT_NODE_FUNC: 4621178479Sjb (void) fprintf(fp, "FUNC %s (%s)\n", 4622178479Sjb dnp->dn_ident->di_name, buf); 4623178479Sjb 4624178479Sjb for (arg = dnp->dn_args; arg != NULL; arg = arg->dn_list) { 4625178479Sjb dt_node_printr(arg, fp, depth + 1); 4626178479Sjb if (arg->dn_list != NULL) 4627178479Sjb (void) fprintf(fp, "%*s,\n", depth * 2, ""); 4628178479Sjb } 4629178479Sjb break; 4630178479Sjb 4631178479Sjb case DT_NODE_OP1: 4632178479Sjb (void) fprintf(fp, "OP1 %s (%s)\n", opstr(dnp->dn_op), buf); 4633178479Sjb dt_node_printr(dnp->dn_child, fp, depth + 1); 4634178479Sjb break; 4635178479Sjb 4636178479Sjb case DT_NODE_OP2: 4637178479Sjb (void) fprintf(fp, "OP2 %s (%s)\n", opstr(dnp->dn_op), buf); 4638178479Sjb dt_node_printr(dnp->dn_left, fp, depth + 1); 4639178479Sjb dt_node_printr(dnp->dn_right, fp, depth + 1); 4640178479Sjb break; 4641178479Sjb 4642178479Sjb case DT_NODE_OP3: 4643178479Sjb (void) fprintf(fp, "OP3 (%s)\n", buf); 4644178479Sjb dt_node_printr(dnp->dn_expr, fp, depth + 1); 4645178479Sjb (void) fprintf(fp, "%*s?\n", depth * 2, ""); 4646178479Sjb dt_node_printr(dnp->dn_left, fp, depth + 1); 4647178479Sjb (void) fprintf(fp, "%*s:\n", depth * 2, ""); 4648178479Sjb dt_node_printr(dnp->dn_right, fp, depth + 1); 4649178479Sjb break; 4650178479Sjb 4651178479Sjb case DT_NODE_DEXPR: 4652178479Sjb case DT_NODE_DFUNC: 4653178479Sjb (void) fprintf(fp, "D EXPRESSION attr=%s\n", a); 4654178479Sjb dt_node_printr(dnp->dn_expr, fp, depth + 1); 4655178479Sjb break; 4656178479Sjb 4657178479Sjb case DT_NODE_AGG: 4658178479Sjb (void) fprintf(fp, "AGGREGATE @%s attr=%s [\n", 4659178479Sjb dnp->dn_ident->di_name, a); 4660178479Sjb 4661178479Sjb for (arg = dnp->dn_aggtup; arg != NULL; arg = arg->dn_list) { 4662178479Sjb dt_node_printr(arg, fp, depth + 1); 4663178479Sjb if (arg->dn_list != NULL) 4664178479Sjb (void) fprintf(fp, "%*s,\n", depth * 2, ""); 4665178479Sjb } 4666178479Sjb 4667178479Sjb if (dnp->dn_aggfun) { 4668178479Sjb (void) fprintf(fp, "%*s] = ", depth * 2, ""); 4669178479Sjb dt_node_printr(dnp->dn_aggfun, fp, depth + 1); 4670178479Sjb } else 4671178479Sjb (void) fprintf(fp, "%*s]\n", depth * 2, ""); 4672178479Sjb 4673178479Sjb if (dnp->dn_aggfun) 4674178479Sjb (void) fprintf(fp, "%*s)\n", depth * 2, ""); 4675178479Sjb break; 4676178479Sjb 4677178479Sjb case DT_NODE_PDESC: 4678178479Sjb (void) fprintf(fp, "PDESC %s:%s:%s:%s [%u]\n", 4679178479Sjb dnp->dn_desc->dtpd_provider, dnp->dn_desc->dtpd_mod, 4680178479Sjb dnp->dn_desc->dtpd_func, dnp->dn_desc->dtpd_name, 4681178479Sjb dnp->dn_desc->dtpd_id); 4682178479Sjb break; 4683178479Sjb 4684178479Sjb case DT_NODE_CLAUSE: 4685178479Sjb (void) fprintf(fp, "CLAUSE attr=%s\n", a); 4686178479Sjb 4687178479Sjb for (arg = dnp->dn_pdescs; arg != NULL; arg = arg->dn_list) 4688178479Sjb dt_node_printr(arg, fp, depth + 1); 4689178479Sjb 4690178479Sjb (void) fprintf(fp, "%*sCTXATTR %s\n", depth * 2, "", 4691178479Sjb dt_attr_str(dnp->dn_ctxattr, a, sizeof (a))); 4692178479Sjb 4693178479Sjb if (dnp->dn_pred != NULL) { 4694178479Sjb (void) fprintf(fp, "%*sPREDICATE /\n", depth * 2, ""); 4695178479Sjb dt_node_printr(dnp->dn_pred, fp, depth + 1); 4696178479Sjb (void) fprintf(fp, "%*s/\n", depth * 2, ""); 4697178479Sjb } 4698178479Sjb 4699178479Sjb for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list) 4700178479Sjb dt_node_printr(arg, fp, depth + 1); 4701178479Sjb break; 4702178479Sjb 4703178479Sjb case DT_NODE_INLINE: 4704178479Sjb inp = dnp->dn_ident->di_iarg; 4705178479Sjb 4706178479Sjb (void) fprintf(fp, "INLINE %s (%s)\n", 4707178479Sjb dnp->dn_ident->di_name, buf); 4708178479Sjb dt_node_printr(inp->din_root, fp, depth + 1); 4709178479Sjb break; 4710178479Sjb 4711178479Sjb case DT_NODE_MEMBER: 4712178479Sjb (void) fprintf(fp, "MEMBER %s (%s)\n", dnp->dn_membname, buf); 4713178479Sjb if (dnp->dn_membexpr) 4714178479Sjb dt_node_printr(dnp->dn_membexpr, fp, depth + 1); 4715178479Sjb break; 4716178479Sjb 4717178479Sjb case DT_NODE_XLATOR: 4718178479Sjb (void) fprintf(fp, "XLATOR (%s)", buf); 4719178479Sjb 4720178479Sjb if (ctf_type_name(dnp->dn_xlator->dx_src_ctfp, 4721178479Sjb dnp->dn_xlator->dx_src_type, n, sizeof (n)) != NULL) 4722178479Sjb (void) fprintf(fp, " from <%s>", n); 4723178479Sjb 4724178479Sjb if (ctf_type_name(dnp->dn_xlator->dx_dst_ctfp, 4725178479Sjb dnp->dn_xlator->dx_dst_type, n, sizeof (n)) != NULL) 4726178479Sjb (void) fprintf(fp, " to <%s>", n); 4727178479Sjb 4728178479Sjb (void) fprintf(fp, "\n"); 4729178479Sjb 4730178479Sjb for (arg = dnp->dn_members; arg != NULL; arg = arg->dn_list) 4731178479Sjb dt_node_printr(arg, fp, depth + 1); 4732178479Sjb break; 4733178479Sjb 4734178479Sjb case DT_NODE_PROBE: 4735178479Sjb (void) fprintf(fp, "PROBE %s\n", dnp->dn_ident->di_name); 4736178479Sjb break; 4737178479Sjb 4738178479Sjb case DT_NODE_PROVIDER: 4739178479Sjb (void) fprintf(fp, "PROVIDER %s (%s)\n", 4740178479Sjb dnp->dn_provname, dnp->dn_provred ? "redecl" : "decl"); 4741178479Sjb for (arg = dnp->dn_probes; arg != NULL; arg = arg->dn_list) 4742178479Sjb dt_node_printr(arg, fp, depth + 1); 4743178479Sjb break; 4744178479Sjb 4745178479Sjb case DT_NODE_PROG: 4746178479Sjb (void) fprintf(fp, "PROGRAM attr=%s\n", a); 4747178479Sjb for (arg = dnp->dn_list; arg != NULL; arg = arg->dn_list) 4748178479Sjb dt_node_printr(arg, fp, depth + 1); 4749178479Sjb break; 4750178479Sjb 4751178479Sjb default: 4752178479Sjb (void) fprintf(fp, "<bad node %p, kind %d>\n", 4753178479Sjb (void *)dnp, dnp->dn_kind); 4754178479Sjb } 4755178479Sjb} 4756178479Sjb 4757178479Sjbint 4758178479Sjbdt_node_root(dt_node_t *dnp) 4759178479Sjb{ 4760178479Sjb yypcb->pcb_root = dnp; 4761178479Sjb return (0); 4762178479Sjb} 4763178479Sjb 4764178479Sjb/*PRINTFLIKE3*/ 4765178479Sjbvoid 4766178479Sjbdnerror(const dt_node_t *dnp, dt_errtag_t tag, const char *format, ...) 4767178479Sjb{ 4768178479Sjb int oldlineno = yylineno; 4769178479Sjb va_list ap; 4770178479Sjb 4771178479Sjb yylineno = dnp->dn_line; 4772178479Sjb 4773178479Sjb va_start(ap, format); 4774178479Sjb xyvwarn(tag, format, ap); 4775178479Sjb va_end(ap); 4776178479Sjb 4777178479Sjb yylineno = oldlineno; 4778178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 4779178479Sjb} 4780178479Sjb 4781178479Sjb/*PRINTFLIKE3*/ 4782178479Sjbvoid 4783178479Sjbdnwarn(const dt_node_t *dnp, dt_errtag_t tag, const char *format, ...) 4784178479Sjb{ 4785178479Sjb int oldlineno = yylineno; 4786178479Sjb va_list ap; 4787178479Sjb 4788178479Sjb yylineno = dnp->dn_line; 4789178479Sjb 4790178479Sjb va_start(ap, format); 4791178479Sjb xyvwarn(tag, format, ap); 4792178479Sjb va_end(ap); 4793178479Sjb 4794178479Sjb yylineno = oldlineno; 4795178479Sjb} 4796178479Sjb 4797178479Sjb/*PRINTFLIKE2*/ 4798178479Sjbvoid 4799178479Sjbxyerror(dt_errtag_t tag, const char *format, ...) 4800178479Sjb{ 4801178479Sjb va_list ap; 4802178479Sjb 4803178479Sjb va_start(ap, format); 4804178479Sjb xyvwarn(tag, format, ap); 4805178479Sjb va_end(ap); 4806178479Sjb 4807178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 4808178479Sjb} 4809178479Sjb 4810178479Sjb/*PRINTFLIKE2*/ 4811178479Sjbvoid 4812178479Sjbxywarn(dt_errtag_t tag, const char *format, ...) 4813178479Sjb{ 4814178479Sjb va_list ap; 4815178479Sjb 4816178479Sjb va_start(ap, format); 4817178479Sjb xyvwarn(tag, format, ap); 4818178479Sjb va_end(ap); 4819178479Sjb} 4820178479Sjb 4821178479Sjbvoid 4822178479Sjbxyvwarn(dt_errtag_t tag, const char *format, va_list ap) 4823178479Sjb{ 4824178479Sjb if (yypcb == NULL) 4825178479Sjb return; /* compiler is not currently active: act as a no-op */ 4826178479Sjb 4827178479Sjb dt_set_errmsg(yypcb->pcb_hdl, dt_errtag(tag), yypcb->pcb_region, 4828178479Sjb yypcb->pcb_filetag, yypcb->pcb_fileptr ? yylineno : 0, format, ap); 4829178479Sjb} 4830178479Sjb 4831178479Sjb/*PRINTFLIKE1*/ 4832178479Sjbvoid 4833178479Sjbyyerror(const char *format, ...) 4834178479Sjb{ 4835178479Sjb va_list ap; 4836178479Sjb 4837178479Sjb va_start(ap, format); 4838178479Sjb yyvwarn(format, ap); 4839178479Sjb va_end(ap); 4840178479Sjb 4841178479Sjb longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER); 4842178479Sjb} 4843178479Sjb 4844178479Sjb/*PRINTFLIKE1*/ 4845178479Sjbvoid 4846178479Sjbyywarn(const char *format, ...) 4847178479Sjb{ 4848178479Sjb va_list ap; 4849178479Sjb 4850178479Sjb va_start(ap, format); 4851178479Sjb yyvwarn(format, ap); 4852178479Sjb va_end(ap); 4853178479Sjb} 4854178479Sjb 4855178479Sjbvoid 4856178479Sjbyyvwarn(const char *format, va_list ap) 4857178479Sjb{ 4858178479Sjb if (yypcb == NULL) 4859178479Sjb return; /* compiler is not currently active: act as a no-op */ 4860178479Sjb 4861178479Sjb dt_set_errmsg(yypcb->pcb_hdl, dt_errtag(D_SYNTAX), yypcb->pcb_region, 4862178479Sjb yypcb->pcb_filetag, yypcb->pcb_fileptr ? yylineno : 0, format, ap); 4863178479Sjb 4864178479Sjb if (strchr(format, '\n') == NULL) { 4865178479Sjb dtrace_hdl_t *dtp = yypcb->pcb_hdl; 4866178479Sjb size_t len = strlen(dtp->dt_errmsg); 4867178479Sjb char *p, *s = dtp->dt_errmsg + len; 4868178479Sjb size_t n = sizeof (dtp->dt_errmsg) - len; 4869178479Sjb 4870178479Sjb if (yytext[0] == '\0') 4871178479Sjb (void) snprintf(s, n, " near end of input"); 4872178479Sjb else if (yytext[0] == '\n') 4873178479Sjb (void) snprintf(s, n, " near end of line"); 4874178479Sjb else { 4875178479Sjb if ((p = strchr(yytext, '\n')) != NULL) 4876178479Sjb *p = '\0'; /* crop at newline */ 4877178479Sjb (void) snprintf(s, n, " near \"%s\"", yytext); 4878178479Sjb } 4879178479Sjb } 4880178479Sjb} 4881178479Sjb 4882178479Sjbvoid 4883178479Sjbyylabel(const char *label) 4884178479Sjb{ 4885178479Sjb dt_dprintf("set label to <%s>\n", label ? label : "NULL"); 4886178479Sjb yypcb->pcb_region = label; 4887178479Sjb} 4888178479Sjb 4889178479Sjbint 4890178479Sjbyywrap(void) 4891178479Sjb{ 4892178479Sjb return (1); /* indicate that lex should return a zero token for EOF */ 4893178479Sjb} 4894