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