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