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