xref: /illumos-gate/usr/src/lib/libdtrace/common/dt_cc.c (revision 7f7322febbcfe774b7270abc3b191c094bfcc517)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * DTrace D Language Compiler
31  *
32  * The code in this source file implements the main engine for the D language
33  * compiler.  The driver routine for the compiler is dt_compile(), below.  The
34  * compiler operates on either stdio FILEs or in-memory strings as its input
35  * and can produce either dtrace_prog_t structures from a D program or a single
36  * dtrace_difo_t structure from a D expression.  Multiple entry points are
37  * provided as wrappers around dt_compile() for the various input/output pairs.
38  * The compiler itself is implemented across the following source files:
39  *
40  * dt_lex.l - lex scanner
41  * dt_grammar.y - yacc grammar
42  * dt_parser.c - parse tree creation and semantic checking
43  * dt_decl.c - declaration stack processing
44  * dt_xlator.c - D translator lookup and creation
45  * dt_ident.c - identifier and symbol table routines
46  * dt_pragma.c - #pragma processing and D pragmas
47  * dt_printf.c - D printf() and printa() argument checking and processing
48  * dt_cc.c - compiler driver and dtrace_prog_t construction
49  * dt_cg.c - DIF code generator
50  * dt_as.c - DIF assembler
51  * dt_dof.c - dtrace_prog_t -> DOF conversion
52  *
53  * Several other source files provide collections of utility routines used by
54  * these major files.  The compiler itself is implemented in multiple passes:
55  *
56  * (1) The input program is scanned and parsed by dt_lex.l and dt_grammar.y
57  *     and parse tree nodes are constructed using the routines in dt_parser.c.
58  *     This node construction pass is described further in dt_parser.c.
59  *
60  * (2) The parse tree is "cooked" by assigning each clause a context (see the
61  *     routine dt_setcontext(), below) based on its probe description and then
62  *     recursively descending the tree performing semantic checking.  The cook
63  *     routines are also implemented in dt_parser.c and described there.
64  *
65  * (3) For actions that are DIF expression statements, the DIF code generator
66  *     and assembler are invoked to create a finished DIFO for the statement.
67  *
68  * (4) The dtrace_prog_t data structures for the program clauses and actions
69  *     are built, containing pointers to any DIFOs created in step (3).
70  *
71  * (5) The caller invokes a routine in dt_dof.c to convert the finished program
72  *     into DOF format for use in anonymous tracing or enabling in the kernel.
73  *
74  * In the implementation, steps 2-4 are intertwined in that they are performed
75  * in order for each clause as part of a loop that executes over the clauses.
76  *
77  * The D compiler currently implements nearly no optimization.  The compiler
78  * implements integer constant folding as part of pass (1), and a set of very
79  * simple peephole optimizations as part of pass (3).  As with any C compiler,
80  * a large number of optimizations are possible on both the intermediate data
81  * structures and the generated DIF code.  These possibilities should be
82  * investigated in the context of whether they will have any substantive effect
83  * on the overall DTrace probe effect before they are undertaken.
84  */
85 
86 #include <sys/types.h>
87 #include <sys/wait.h>
88 
89 #include <assert.h>
90 #include <strings.h>
91 #include <signal.h>
92 #include <unistd.h>
93 #include <stdlib.h>
94 #include <stdio.h>
95 #include <errno.h>
96 #include <ucontext.h>
97 #include <limits.h>
98 #include <ctype.h>
99 #include <dirent.h>
100 #include <dt_module.h>
101 #include <dt_program.h>
102 #include <dt_provider.h>
103 #include <dt_printf.h>
104 #include <dt_pid.h>
105 #include <dt_grammar.h>
106 #include <dt_ident.h>
107 #include <dt_string.h>
108 #include <dt_impl.h>
109 
110 static const dtrace_diftype_t dt_void_rtype = {
111 	DIF_TYPE_CTF, CTF_K_INTEGER, 0, 0, 0
112 };
113 
114 static const dtrace_diftype_t dt_int_rtype = {
115 	DIF_TYPE_CTF, CTF_K_INTEGER, 0, 0, sizeof (uint64_t)
116 };
117 
118 /*ARGSUSED*/
119 static int
120 dt_idreset(dt_idhash_t *dhp, dt_ident_t *idp, void *ignored)
121 {
122 	idp->di_flags &= ~(DT_IDFLG_REF | DT_IDFLG_MOD |
123 	    DT_IDFLG_DIFR | DT_IDFLG_DIFW);
124 	return (0);
125 }
126 
127 /*ARGSUSED*/
128 static int
129 dt_idpragma(dt_idhash_t *dhp, dt_ident_t *idp, void *ignored)
130 {
131 	yylineno = idp->di_lineno;
132 	xyerror(D_PRAGMA_UNUSED, "unused #pragma %s\n", (char *)idp->di_iarg);
133 	return (0);
134 }
135 
136 static dtrace_stmtdesc_t *
137 dt_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp,
138     dtrace_attribute_t descattr, dtrace_attribute_t stmtattr)
139 {
140 	dtrace_stmtdesc_t *sdp = dtrace_stmt_create(dtp, edp);
141 
142 	if (sdp == NULL)
143 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
144 
145 	assert(yypcb->pcb_stmt == NULL);
146 	yypcb->pcb_stmt = sdp;
147 
148 	sdp->dtsd_descattr = descattr;
149 	sdp->dtsd_stmtattr = stmtattr;
150 
151 	return (sdp);
152 }
153 
154 static dtrace_actdesc_t *
155 dt_stmt_action(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp)
156 {
157 	dtrace_actdesc_t *new;
158 
159 	if ((new = dtrace_stmt_action(dtp, sdp)) == NULL)
160 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
161 
162 	return (new);
163 }
164 
165 /*
166  * Utility function to determine if a given action description is destructive.
167  * The dtdo_destructive bit is set for us by the DIF assembler (see dt_as.c).
168  */
169 static int
170 dt_action_destructive(const dtrace_actdesc_t *ap)
171 {
172 	return (DTRACEACT_ISDESTRUCTIVE(ap->dtad_kind) || (ap->dtad_kind ==
173 	    DTRACEACT_DIFEXPR && ap->dtad_difo->dtdo_destructive));
174 }
175 
176 static void
177 dt_stmt_append(dtrace_stmtdesc_t *sdp, const dt_node_t *dnp)
178 {
179 	dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc;
180 	dtrace_actdesc_t *ap, *tap;
181 	int commit = 0;
182 	int speculate = 0;
183 	int datarec = 0;
184 
185 	/*
186 	 * Make sure that the new statement jibes with the rest of the ECB.
187 	 */
188 	for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) {
189 		if (ap->dtad_kind == DTRACEACT_COMMIT) {
190 			if (commit) {
191 				dnerror(dnp, D_COMM_COMM, "commit( ) may "
192 				    "not follow commit( )\n");
193 			}
194 
195 			if (datarec) {
196 				dnerror(dnp, D_COMM_DREC, "commit( ) may "
197 				    "not follow data-recording action(s)\n");
198 			}
199 
200 			for (tap = ap; tap != NULL; tap = tap->dtad_next) {
201 				if (!DTRACEACT_ISAGG(tap->dtad_kind))
202 					continue;
203 
204 				dnerror(dnp, D_AGG_COMM, "aggregating actions "
205 				    "may not follow commit( )\n");
206 			}
207 
208 			commit = 1;
209 			continue;
210 		}
211 
212 		if (ap->dtad_kind == DTRACEACT_SPECULATE) {
213 			if (speculate) {
214 				dnerror(dnp, D_SPEC_SPEC, "speculate( ) may "
215 				    "not follow speculate( )\n");
216 			}
217 
218 			if (commit) {
219 				dnerror(dnp, D_SPEC_COMM, "speculate( ) may "
220 				    "not follow commit( )\n");
221 			}
222 
223 			if (datarec) {
224 				dnerror(dnp, D_SPEC_DREC, "speculate( ) may "
225 				    "not follow data-recording action(s)\n");
226 			}
227 
228 			speculate = 1;
229 			continue;
230 		}
231 
232 		if (DTRACEACT_ISAGG(ap->dtad_kind)) {
233 			if (speculate) {
234 				dnerror(dnp, D_AGG_SPEC, "aggregating actions "
235 				    "may not follow speculate( )\n");
236 			}
237 
238 			datarec = 1;
239 			continue;
240 		}
241 
242 		if (speculate) {
243 			if (dt_action_destructive(ap)) {
244 				dnerror(dnp, D_ACT_SPEC, "destructive actions "
245 				    "may not follow speculate( )\n");
246 			}
247 
248 			if (ap->dtad_kind == DTRACEACT_EXIT) {
249 				dnerror(dnp, D_EXIT_SPEC, "exit( ) may not "
250 				    "follow speculate( )\n");
251 			}
252 		}
253 
254 		/*
255 		 * Exclude all non data-recording actions.
256 		 */
257 		if (dt_action_destructive(ap) ||
258 		    ap->dtad_kind == DTRACEACT_DISCARD)
259 			continue;
260 
261 		if (ap->dtad_kind == DTRACEACT_DIFEXPR &&
262 		    ap->dtad_difo->dtdo_rtype.dtdt_kind == DIF_TYPE_CTF &&
263 		    ap->dtad_difo->dtdo_rtype.dtdt_size == 0)
264 			continue;
265 
266 		if (commit) {
267 			dnerror(dnp, D_DREC_COMM, "data-recording actions "
268 			    "may not follow commit( )\n");
269 		}
270 
271 		if (!speculate)
272 			datarec = 1;
273 	}
274 
275 	if (dtrace_stmt_add(yypcb->pcb_hdl, yypcb->pcb_prog, sdp) != 0)
276 		longjmp(yypcb->pcb_jmpbuf, dtrace_errno(yypcb->pcb_hdl));
277 
278 	if (yypcb->pcb_stmt == sdp)
279 		yypcb->pcb_stmt = NULL;
280 }
281 
282 /*
283  * For the first element of an aggregation tuple or for printa(), we create a
284  * simple DIF program that simply returns the immediate value that is the ID
285  * of the aggregation itself.  This could be optimized in the future by
286  * creating a new in-kernel dtad_kind that just returns an integer.
287  */
288 static void
289 dt_action_difconst(dtrace_actdesc_t *ap, uint_t id, dtrace_actkind_t kind)
290 {
291 	dtrace_hdl_t *dtp = yypcb->pcb_hdl;
292 	dtrace_difo_t *dp = dt_zalloc(dtp, sizeof (dtrace_difo_t));
293 
294 	if (dp == NULL)
295 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
296 
297 	dp->dtdo_buf = dt_alloc(dtp, sizeof (dif_instr_t) * 2);
298 	dp->dtdo_inttab = dt_alloc(dtp, sizeof (uint64_t));
299 
300 	if (dp->dtdo_buf == NULL || dp->dtdo_inttab == NULL) {
301 		dt_difo_free(dtp, dp);
302 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
303 	}
304 
305 	dp->dtdo_buf[0] = DIF_INSTR_SETX(0, 1); /* setx	DIF_INTEGER[0], %r1 */
306 	dp->dtdo_buf[1] = DIF_INSTR_RET(1);	/* ret	%r1 */
307 	dp->dtdo_len = 2;
308 	dp->dtdo_inttab[0] = id;
309 	dp->dtdo_intlen = 1;
310 	dp->dtdo_rtype = dt_int_rtype;
311 
312 	ap->dtad_difo = dp;
313 	ap->dtad_kind = kind;
314 }
315 
316 static void
317 dt_action_clear(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
318 {
319 	dt_ident_t *aid;
320 	dtrace_actdesc_t *ap;
321 	dt_node_t *anp;
322 
323 	char n[DT_TYPE_NAMELEN];
324 	int argc = 0;
325 
326 	for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
327 		argc++; /* count up arguments for error messages below */
328 
329 	if (argc != 1) {
330 		dnerror(dnp, D_CLEAR_PROTO,
331 		    "%s( ) prototype mismatch: %d args passed, 1 expected\n",
332 		    dnp->dn_ident->di_name, argc);
333 	}
334 
335 	anp = dnp->dn_args;
336 	assert(anp != NULL);
337 
338 	if (anp->dn_kind != DT_NODE_AGG) {
339 		dnerror(dnp, D_CLEAR_AGGARG,
340 		    "%s( ) argument #1 is incompatible with prototype:\n"
341 		    "\tprototype: aggregation\n\t argument: %s\n",
342 		    dnp->dn_ident->di_name,
343 		    dt_node_type_name(anp, n, sizeof (n)));
344 	}
345 
346 	aid = anp->dn_ident;
347 
348 	if (aid->di_gen == dtp->dt_gen && !(aid->di_flags & DT_IDFLG_MOD)) {
349 		dnerror(dnp, D_CLEAR_AGGBAD,
350 		    "undefined aggregation: @%s\n", aid->di_name);
351 	}
352 
353 	ap = dt_stmt_action(dtp, sdp);
354 	dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_LIBACT);
355 	ap->dtad_arg = DT_ACT_CLEAR;
356 }
357 
358 static void
359 dt_action_normalize(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
360 {
361 	dt_ident_t *aid;
362 	dtrace_actdesc_t *ap;
363 	dt_node_t *anp, *normal;
364 	int denormal = (strcmp(dnp->dn_ident->di_name, "denormalize") == 0);
365 
366 	char n[DT_TYPE_NAMELEN];
367 	int argc = 0;
368 
369 	for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
370 		argc++; /* count up arguments for error messages below */
371 
372 	if ((denormal && argc != 1) || (!denormal && argc != 2)) {
373 		dnerror(dnp, D_NORMALIZE_PROTO,
374 		    "%s( ) prototype mismatch: %d args passed, %d expected\n",
375 		    dnp->dn_ident->di_name, argc, denormal ? 1 : 2);
376 	}
377 
378 	anp = dnp->dn_args;
379 	assert(anp != NULL);
380 
381 	if (anp->dn_kind != DT_NODE_AGG) {
382 		dnerror(dnp, D_NORMALIZE_AGGARG,
383 		    "%s( ) argument #1 is incompatible with prototype:\n"
384 		    "\tprototype: aggregation\n\t argument: %s\n",
385 		    dnp->dn_ident->di_name,
386 		    dt_node_type_name(anp, n, sizeof (n)));
387 	}
388 
389 	if ((normal = anp->dn_list) != NULL && !dt_node_is_scalar(normal)) {
390 		dnerror(dnp, D_NORMALIZE_SCALAR,
391 		    "%s( ) argument #2 must be of scalar type\n",
392 		    dnp->dn_ident->di_name);
393 	}
394 
395 	aid = anp->dn_ident;
396 
397 	if (aid->di_gen == dtp->dt_gen && !(aid->di_flags & DT_IDFLG_MOD)) {
398 		dnerror(dnp, D_NORMALIZE_AGGBAD,
399 		    "undefined aggregation: @%s\n", aid->di_name);
400 	}
401 
402 	ap = dt_stmt_action(dtp, sdp);
403 	dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_LIBACT);
404 
405 	if (denormal) {
406 		ap->dtad_arg = DT_ACT_DENORMALIZE;
407 		return;
408 	}
409 
410 	ap->dtad_arg = DT_ACT_NORMALIZE;
411 
412 	assert(normal != NULL);
413 	ap = dt_stmt_action(dtp, sdp);
414 	dt_cg(yypcb, normal);
415 
416 	ap->dtad_difo = dt_as(yypcb);
417 	ap->dtad_kind = DTRACEACT_LIBACT;
418 	ap->dtad_arg = DT_ACT_NORMALIZE;
419 }
420 
421 static void
422 dt_action_trunc(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
423 {
424 	dt_ident_t *aid;
425 	dtrace_actdesc_t *ap;
426 	dt_node_t *anp, *trunc;
427 
428 	char n[DT_TYPE_NAMELEN];
429 	int argc = 0;
430 
431 	for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
432 		argc++; /* count up arguments for error messages below */
433 
434 	if (argc > 2 || argc < 1) {
435 		dnerror(dnp, D_TRUNC_PROTO,
436 		    "%s( ) prototype mismatch: %d args passed, %s expected\n",
437 		    dnp->dn_ident->di_name, argc,
438 		    argc < 1 ? "at least 1" : "no more than 2");
439 	}
440 
441 	anp = dnp->dn_args;
442 	assert(anp != NULL);
443 	trunc = anp->dn_list;
444 
445 	if (anp->dn_kind != DT_NODE_AGG) {
446 		dnerror(dnp, D_TRUNC_AGGARG,
447 		    "%s( ) argument #1 is incompatible with prototype:\n"
448 		    "\tprototype: aggregation\n\t argument: %s\n",
449 		    dnp->dn_ident->di_name,
450 		    dt_node_type_name(anp, n, sizeof (n)));
451 	}
452 
453 	if (argc == 2) {
454 		assert(trunc != NULL);
455 		if (!dt_node_is_scalar(trunc)) {
456 			dnerror(dnp, D_TRUNC_SCALAR,
457 			    "%s( ) argument #2 must be of scalar type\n",
458 			    dnp->dn_ident->di_name);
459 		}
460 	}
461 
462 	aid = anp->dn_ident;
463 
464 	if (aid->di_gen == dtp->dt_gen && !(aid->di_flags & DT_IDFLG_MOD)) {
465 		dnerror(dnp, D_TRUNC_AGGBAD,
466 		    "undefined aggregation: @%s\n", aid->di_name);
467 	}
468 
469 	ap = dt_stmt_action(dtp, sdp);
470 	dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_LIBACT);
471 	ap->dtad_arg = DT_ACT_TRUNC;
472 
473 	ap = dt_stmt_action(dtp, sdp);
474 
475 	if (argc == 1) {
476 		dt_action_difconst(ap, 0, DTRACEACT_LIBACT);
477 	} else {
478 		assert(trunc != NULL);
479 		dt_cg(yypcb, trunc);
480 		ap->dtad_difo = dt_as(yypcb);
481 		ap->dtad_kind = DTRACEACT_LIBACT;
482 	}
483 
484 	ap->dtad_arg = DT_ACT_TRUNC;
485 }
486 
487 static void
488 dt_action_printa(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
489 {
490 	dt_ident_t *aid, *fid;
491 	dtrace_actdesc_t *ap;
492 	const char *format;
493 	dt_node_t *anp, *proto = NULL;
494 
495 	char n[DT_TYPE_NAMELEN];
496 	int argc = 0, argr = 0;
497 
498 	for (anp = dnp->dn_args; anp != NULL; anp = anp->dn_list)
499 		argc++; /* count up arguments for error messages below */
500 
501 	switch (dnp->dn_args->dn_kind) {
502 	case DT_NODE_STRING:
503 		format = dnp->dn_args->dn_string;
504 		anp = dnp->dn_args->dn_list;
505 		argr = 2;
506 		break;
507 	case DT_NODE_AGG:
508 		format = NULL;
509 		anp = dnp->dn_args;
510 		argr = 1;
511 		break;
512 	default:
513 		format = NULL;
514 		anp = dnp->dn_args;
515 		argr = 1;
516 	}
517 
518 	if (argc < argr) {
519 		dnerror(dnp, D_PRINTA_PROTO,
520 		    "%s( ) prototype mismatch: %d args passed, %d expected\n",
521 		    dnp->dn_ident->di_name, argc, argr);
522 	}
523 
524 	assert(anp != NULL);
525 
526 	while (anp != NULL) {
527 		if (anp->dn_kind != DT_NODE_AGG) {
528 			dnerror(dnp, D_PRINTA_AGGARG,
529 			    "%s( ) argument #%d is incompatible with "
530 			    "prototype:\n\tprototype: aggregation\n"
531 			    "\t argument: %s\n", dnp->dn_ident->di_name, argr,
532 			    dt_node_type_name(anp, n, sizeof (n)));
533 		}
534 
535 		aid = anp->dn_ident;
536 		fid = aid->di_iarg;
537 
538 		if (aid->di_gen == dtp->dt_gen &&
539 		    !(aid->di_flags & DT_IDFLG_MOD)) {
540 			dnerror(dnp, D_PRINTA_AGGBAD,
541 			    "undefined aggregation: @%s\n", aid->di_name);
542 		}
543 
544 		/*
545 		 * If we have multiple aggregations, we must be sure that
546 		 * their key signatures match.
547 		 */
548 		if (proto != NULL) {
549 			dt_printa_validate(proto, anp);
550 		} else {
551 			proto = anp;
552 		}
553 
554 		if (format != NULL) {
555 			yylineno = dnp->dn_line;
556 
557 			sdp->dtsd_fmtdata =
558 			    dt_printf_create(yypcb->pcb_hdl, format);
559 			dt_printf_validate(sdp->dtsd_fmtdata,
560 			    DT_PRINTF_AGGREGATION, dnp->dn_ident, 1,
561 			    fid->di_id, ((dt_idsig_t *)aid->di_data)->dis_args);
562 			format = NULL;
563 		}
564 
565 		ap = dt_stmt_action(dtp, sdp);
566 		dt_action_difconst(ap, anp->dn_ident->di_id, DTRACEACT_PRINTA);
567 
568 		anp = anp->dn_list;
569 		argr++;
570 	}
571 }
572 
573 static void
574 dt_action_printflike(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp,
575     dtrace_actkind_t kind)
576 {
577 	dt_node_t *anp, *arg1;
578 	dtrace_actdesc_t *ap = NULL;
579 	char n[DT_TYPE_NAMELEN], *str;
580 
581 	assert(DTRACEACT_ISPRINTFLIKE(kind));
582 
583 	if (dnp->dn_args->dn_kind != DT_NODE_STRING) {
584 		dnerror(dnp, D_PRINTF_ARG_FMT,
585 		    "%s( ) argument #1 is incompatible with prototype:\n"
586 		    "\tprototype: string constant\n\t argument: %s\n",
587 		    dnp->dn_ident->di_name,
588 		    dt_node_type_name(dnp->dn_args, n, sizeof (n)));
589 	}
590 
591 	arg1 = dnp->dn_args->dn_list;
592 	yylineno = dnp->dn_line;
593 	str = dnp->dn_args->dn_string;
594 
595 
596 	/*
597 	 * If this is an freopen(), we use an empty string to denote that
598 	 * stdout should be restored.  For other printf()-like actions, an
599 	 * empty format string is illegal:  an empty format string would
600 	 * result in malformed DOF, and the compiler thus flags an empty
601 	 * format string as a compile-time error.  To avoid propagating the
602 	 * freopen() special case throughout the system, we simply transpose
603 	 * an empty string into a sentinel string (DT_FREOPEN_RESTORE) that
604 	 * denotes that stdout should be restored.
605 	 */
606 	if (kind == DTRACEACT_FREOPEN) {
607 		if (strcmp(str, DT_FREOPEN_RESTORE) == 0) {
608 			/*
609 			 * Our sentinel is always an invalid argument to
610 			 * freopen(), but if it's been manually specified, we
611 			 * must fail now instead of when the freopen() is
612 			 * actually evaluated.
613 			 */
614 			dnerror(dnp, D_FREOPEN_INVALID,
615 			    "%s( ) argument #1 cannot be \"%s\"\n",
616 			    dnp->dn_ident->di_name, DT_FREOPEN_RESTORE);
617 		}
618 
619 		if (str[0] == '\0')
620 			str = DT_FREOPEN_RESTORE;
621 	}
622 
623 	sdp->dtsd_fmtdata = dt_printf_create(dtp, str);
624 
625 	dt_printf_validate(sdp->dtsd_fmtdata, DT_PRINTF_EXACTLEN,
626 	    dnp->dn_ident, 1, DTRACEACT_AGGREGATION, arg1);
627 
628 	if (arg1 == NULL) {
629 		dif_instr_t *dbuf;
630 		dtrace_difo_t *dp;
631 
632 		if ((dbuf = dt_alloc(dtp, sizeof (dif_instr_t))) == NULL ||
633 		    (dp = dt_zalloc(dtp, sizeof (dtrace_difo_t))) == NULL) {
634 			dt_free(dtp, dbuf);
635 			longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
636 		}
637 
638 		dbuf[0] = DIF_INSTR_RET(DIF_REG_R0); /* ret %r0 */
639 
640 		dp->dtdo_buf = dbuf;
641 		dp->dtdo_len = 1;
642 		dp->dtdo_rtype = dt_int_rtype;
643 
644 		ap = dt_stmt_action(dtp, sdp);
645 		ap->dtad_difo = dp;
646 		ap->dtad_kind = kind;
647 		return;
648 	}
649 
650 	for (anp = arg1; anp != NULL; anp = anp->dn_list) {
651 		ap = dt_stmt_action(dtp, sdp);
652 		dt_cg(yypcb, anp);
653 		ap->dtad_difo = dt_as(yypcb);
654 		ap->dtad_kind = kind;
655 	}
656 }
657 
658 static void
659 dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
660 {
661 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
662 
663 	if (dt_node_is_void(dnp->dn_args)) {
664 		dnerror(dnp->dn_args, D_TRACE_VOID,
665 		    "trace( ) may not be applied to a void expression\n");
666 	}
667 
668 	if (dt_node_is_dynamic(dnp->dn_args)) {
669 		dnerror(dnp->dn_args, D_TRACE_DYN,
670 		    "trace( ) may not be applied to a dynamic expression\n");
671 	}
672 
673 	dt_cg(yypcb, dnp->dn_args);
674 	ap->dtad_difo = dt_as(yypcb);
675 	ap->dtad_kind = DTRACEACT_DIFEXPR;
676 }
677 
678 static void
679 dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
680 {
681 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
682 
683 	dt_node_t *addr = dnp->dn_args;
684 	dt_node_t *size = dnp->dn_args->dn_list;
685 
686 	char n[DT_TYPE_NAMELEN];
687 
688 	if (dt_node_is_integer(addr) == 0 && dt_node_is_pointer(addr) == 0) {
689 		dnerror(addr, D_TRACEMEM_ADDR,
690 		    "tracemem( ) argument #1 is incompatible with "
691 		    "prototype:\n\tprototype: pointer or integer\n"
692 		    "\t argument: %s\n",
693 		    dt_node_type_name(addr, n, sizeof (n)));
694 	}
695 
696 	if (dt_node_is_posconst(size) == 0) {
697 		dnerror(size, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must "
698 		    "be a non-zero positive integral constant expression\n");
699 	}
700 
701 	dt_cg(yypcb, addr);
702 	ap->dtad_difo = dt_as(yypcb);
703 	ap->dtad_kind = DTRACEACT_DIFEXPR;
704 
705 	ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
706 	ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value;
707 }
708 
709 static void
710 dt_action_stack_args(dtrace_hdl_t *dtp, dtrace_actdesc_t *ap, dt_node_t *arg0)
711 {
712 	ap->dtad_kind = DTRACEACT_STACK;
713 
714 	if (dtp->dt_options[DTRACEOPT_STACKFRAMES] != DTRACEOPT_UNSET) {
715 		ap->dtad_arg = dtp->dt_options[DTRACEOPT_STACKFRAMES];
716 	} else {
717 		ap->dtad_arg = 0;
718 	}
719 
720 	if (arg0 != NULL) {
721 		if (arg0->dn_list != NULL) {
722 			dnerror(arg0, D_STACK_PROTO, "stack( ) prototype "
723 			    "mismatch: too many arguments\n");
724 		}
725 
726 		if (dt_node_is_posconst(arg0) == 0) {
727 			dnerror(arg0, D_STACK_SIZE, "stack( ) size must be a "
728 			    "non-zero positive integral constant expression\n");
729 		}
730 
731 		ap->dtad_arg = arg0->dn_value;
732 	}
733 }
734 
735 static void
736 dt_action_stack(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
737 {
738 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
739 	dt_action_stack_args(dtp, ap, dnp->dn_args);
740 }
741 
742 static void
743 dt_action_ustack_args(dtrace_hdl_t *dtp, dtrace_actdesc_t *ap, dt_node_t *dnp)
744 {
745 	uint32_t nframes = 0;
746 	uint32_t strsize = 0;	/* default string table size */
747 	dt_node_t *arg0 = dnp->dn_args;
748 	dt_node_t *arg1 = arg0 != NULL ? arg0->dn_list : NULL;
749 
750 	assert(dnp->dn_ident->di_id == DT_ACT_JSTACK ||
751 	    dnp->dn_ident->di_id == DT_ACT_USTACK);
752 
753 	if (dnp->dn_ident->di_id == DT_ACT_JSTACK) {
754 		if (dtp->dt_options[DTRACEOPT_JSTACKFRAMES] != DTRACEOPT_UNSET)
755 			nframes = dtp->dt_options[DTRACEOPT_JSTACKFRAMES];
756 
757 		if (dtp->dt_options[DTRACEOPT_JSTACKSTRSIZE] != DTRACEOPT_UNSET)
758 			strsize = dtp->dt_options[DTRACEOPT_JSTACKSTRSIZE];
759 
760 		ap->dtad_kind = DTRACEACT_JSTACK;
761 	} else {
762 		assert(dnp->dn_ident->di_id == DT_ACT_USTACK);
763 
764 		if (dtp->dt_options[DTRACEOPT_USTACKFRAMES] != DTRACEOPT_UNSET)
765 			nframes = dtp->dt_options[DTRACEOPT_USTACKFRAMES];
766 
767 		ap->dtad_kind = DTRACEACT_USTACK;
768 	}
769 
770 	if (arg0 != NULL) {
771 		if (!dt_node_is_posconst(arg0)) {
772 			dnerror(arg0, D_USTACK_FRAMES, "ustack( ) argument #1 "
773 			    "must be a non-zero positive integer constant\n");
774 		}
775 		nframes = (uint32_t)arg0->dn_value;
776 	}
777 
778 	if (arg1 != NULL) {
779 		if (arg1->dn_kind != DT_NODE_INT ||
780 		    ((arg1->dn_flags & DT_NF_SIGNED) &&
781 		    (int64_t)arg1->dn_value < 0)) {
782 			dnerror(arg1, D_USTACK_STRSIZE, "ustack( ) argument #2 "
783 			    "must be a positive integer constant\n");
784 		}
785 
786 		if (arg1->dn_list != NULL) {
787 			dnerror(arg1, D_USTACK_PROTO, "ustack( ) prototype "
788 			    "mismatch: too many arguments\n");
789 		}
790 
791 		strsize = (uint32_t)arg1->dn_value;
792 	}
793 
794 	ap->dtad_arg = DTRACE_USTACK_ARG(nframes, strsize);
795 }
796 
797 static void
798 dt_action_ustack(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
799 {
800 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
801 	dt_action_ustack_args(dtp, ap, dnp);
802 }
803 
804 static void
805 dt_action_setopt(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
806 {
807 	dtrace_actdesc_t *ap;
808 	dt_node_t *arg0, *arg1;
809 
810 	/*
811 	 * The prototype guarantees that we are called with either one or
812 	 * two arguments, and that any arguments that are present are strings.
813 	 */
814 	arg0 = dnp->dn_args;
815 	arg1 = arg0->dn_list;
816 
817 	ap = dt_stmt_action(dtp, sdp);
818 	dt_cg(yypcb, arg0);
819 	ap->dtad_difo = dt_as(yypcb);
820 	ap->dtad_kind = DTRACEACT_LIBACT;
821 	ap->dtad_arg = DT_ACT_SETOPT;
822 
823 	ap = dt_stmt_action(dtp, sdp);
824 
825 	if (arg1 == NULL) {
826 		dt_action_difconst(ap, 0, DTRACEACT_LIBACT);
827 	} else {
828 		dt_cg(yypcb, arg1);
829 		ap->dtad_difo = dt_as(yypcb);
830 		ap->dtad_kind = DTRACEACT_LIBACT;
831 	}
832 
833 	ap->dtad_arg = DT_ACT_SETOPT;
834 }
835 
836 /*ARGSUSED*/
837 static void
838 dt_action_symmod_args(dtrace_hdl_t *dtp, dtrace_actdesc_t *ap,
839     dt_node_t *dnp, dtrace_actkind_t kind)
840 {
841 	assert(kind == DTRACEACT_SYM || kind == DTRACEACT_MOD ||
842 	    kind == DTRACEACT_USYM || kind == DTRACEACT_UMOD ||
843 	    kind == DTRACEACT_UADDR);
844 
845 	dt_cg(yypcb, dnp);
846 	ap->dtad_difo = dt_as(yypcb);
847 	ap->dtad_kind = kind;
848 	ap->dtad_difo->dtdo_rtype.dtdt_size = sizeof (uint64_t);
849 }
850 
851 static void
852 dt_action_symmod(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp,
853     dtrace_actkind_t kind)
854 {
855 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
856 	dt_action_symmod_args(dtp, ap, dnp->dn_args, kind);
857 }
858 
859 /*ARGSUSED*/
860 static void
861 dt_action_ftruncate(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
862 {
863 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
864 
865 	/*
866 	 * Library actions need a DIFO that serves as an argument.  As
867 	 * ftruncate() doesn't take an argument, we generate the constant 0
868 	 * in a DIFO; this constant will be ignored when the ftruncate() is
869 	 * processed.
870 	 */
871 	dt_action_difconst(ap, 0, DTRACEACT_LIBACT);
872 	ap->dtad_arg = DT_ACT_FTRUNCATE;
873 }
874 
875 /*ARGSUSED*/
876 static void
877 dt_action_stop(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
878 {
879 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
880 
881 	ap->dtad_kind = DTRACEACT_STOP;
882 	ap->dtad_arg = 0;
883 }
884 
885 /*ARGSUSED*/
886 static void
887 dt_action_breakpoint(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
888 {
889 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
890 
891 	ap->dtad_kind = DTRACEACT_BREAKPOINT;
892 	ap->dtad_arg = 0;
893 }
894 
895 /*ARGSUSED*/
896 static void
897 dt_action_panic(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
898 {
899 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
900 
901 	ap->dtad_kind = DTRACEACT_PANIC;
902 	ap->dtad_arg = 0;
903 }
904 
905 static void
906 dt_action_chill(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
907 {
908 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
909 
910 	dt_cg(yypcb, dnp->dn_args);
911 	ap->dtad_difo = dt_as(yypcb);
912 	ap->dtad_kind = DTRACEACT_CHILL;
913 }
914 
915 static void
916 dt_action_raise(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
917 {
918 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
919 
920 	dt_cg(yypcb, dnp->dn_args);
921 	ap->dtad_difo = dt_as(yypcb);
922 	ap->dtad_kind = DTRACEACT_RAISE;
923 }
924 
925 static void
926 dt_action_exit(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
927 {
928 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
929 
930 	dt_cg(yypcb, dnp->dn_args);
931 	ap->dtad_difo = dt_as(yypcb);
932 	ap->dtad_kind = DTRACEACT_EXIT;
933 	ap->dtad_difo->dtdo_rtype.dtdt_size = sizeof (int);
934 }
935 
936 static void
937 dt_action_speculate(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
938 {
939 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
940 
941 	dt_cg(yypcb, dnp->dn_args);
942 	ap->dtad_difo = dt_as(yypcb);
943 	ap->dtad_kind = DTRACEACT_SPECULATE;
944 }
945 
946 static void
947 dt_action_commit(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
948 {
949 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
950 
951 	dt_cg(yypcb, dnp->dn_args);
952 	ap->dtad_difo = dt_as(yypcb);
953 	ap->dtad_kind = DTRACEACT_COMMIT;
954 }
955 
956 static void
957 dt_action_discard(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
958 {
959 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
960 
961 	dt_cg(yypcb, dnp->dn_args);
962 	ap->dtad_difo = dt_as(yypcb);
963 	ap->dtad_kind = DTRACEACT_DISCARD;
964 }
965 
966 static void
967 dt_compile_fun(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
968 {
969 	switch (dnp->dn_expr->dn_ident->di_id) {
970 	case DT_ACT_BREAKPOINT:
971 		dt_action_breakpoint(dtp, dnp->dn_expr, sdp);
972 		break;
973 	case DT_ACT_CHILL:
974 		dt_action_chill(dtp, dnp->dn_expr, sdp);
975 		break;
976 	case DT_ACT_CLEAR:
977 		dt_action_clear(dtp, dnp->dn_expr, sdp);
978 		break;
979 	case DT_ACT_COMMIT:
980 		dt_action_commit(dtp, dnp->dn_expr, sdp);
981 		break;
982 	case DT_ACT_DENORMALIZE:
983 		dt_action_normalize(dtp, dnp->dn_expr, sdp);
984 		break;
985 	case DT_ACT_DISCARD:
986 		dt_action_discard(dtp, dnp->dn_expr, sdp);
987 		break;
988 	case DT_ACT_EXIT:
989 		dt_action_exit(dtp, dnp->dn_expr, sdp);
990 		break;
991 	case DT_ACT_FREOPEN:
992 		dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_FREOPEN);
993 		break;
994 	case DT_ACT_FTRUNCATE:
995 		dt_action_ftruncate(dtp, dnp->dn_expr, sdp);
996 		break;
997 	case DT_ACT_MOD:
998 		dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_MOD);
999 		break;
1000 	case DT_ACT_NORMALIZE:
1001 		dt_action_normalize(dtp, dnp->dn_expr, sdp);
1002 		break;
1003 	case DT_ACT_PANIC:
1004 		dt_action_panic(dtp, dnp->dn_expr, sdp);
1005 		break;
1006 	case DT_ACT_PRINTA:
1007 		dt_action_printa(dtp, dnp->dn_expr, sdp);
1008 		break;
1009 	case DT_ACT_PRINTF:
1010 		dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_PRINTF);
1011 		break;
1012 	case DT_ACT_RAISE:
1013 		dt_action_raise(dtp, dnp->dn_expr, sdp);
1014 		break;
1015 	case DT_ACT_SETOPT:
1016 		dt_action_setopt(dtp, dnp->dn_expr, sdp);
1017 		break;
1018 	case DT_ACT_SPECULATE:
1019 		dt_action_speculate(dtp, dnp->dn_expr, sdp);
1020 		break;
1021 	case DT_ACT_STACK:
1022 		dt_action_stack(dtp, dnp->dn_expr, sdp);
1023 		break;
1024 	case DT_ACT_STOP:
1025 		dt_action_stop(dtp, dnp->dn_expr, sdp);
1026 		break;
1027 	case DT_ACT_SYM:
1028 		dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_SYM);
1029 		break;
1030 	case DT_ACT_SYSTEM:
1031 		dt_action_printflike(dtp, dnp->dn_expr, sdp, DTRACEACT_SYSTEM);
1032 		break;
1033 	case DT_ACT_TRACE:
1034 		dt_action_trace(dtp, dnp->dn_expr, sdp);
1035 		break;
1036 	case DT_ACT_TRACEMEM:
1037 		dt_action_tracemem(dtp, dnp->dn_expr, sdp);
1038 		break;
1039 	case DT_ACT_TRUNC:
1040 		dt_action_trunc(dtp, dnp->dn_expr, sdp);
1041 		break;
1042 	case DT_ACT_UADDR:
1043 		dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_UADDR);
1044 		break;
1045 	case DT_ACT_UMOD:
1046 		dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_UMOD);
1047 		break;
1048 	case DT_ACT_USYM:
1049 		dt_action_symmod(dtp, dnp->dn_expr, sdp, DTRACEACT_USYM);
1050 		break;
1051 	case DT_ACT_USTACK:
1052 	case DT_ACT_JSTACK:
1053 		dt_action_ustack(dtp, dnp->dn_expr, sdp);
1054 		break;
1055 	default:
1056 		dnerror(dnp->dn_expr, D_UNKNOWN, "tracing function %s( ) is "
1057 		    "not yet supported\n", dnp->dn_expr->dn_ident->di_name);
1058 	}
1059 }
1060 
1061 static void
1062 dt_compile_exp(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
1063 {
1064 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
1065 
1066 	dt_cg(yypcb, dnp->dn_expr);
1067 	ap->dtad_difo = dt_as(yypcb);
1068 	ap->dtad_difo->dtdo_rtype = dt_void_rtype;
1069 	ap->dtad_kind = DTRACEACT_DIFEXPR;
1070 }
1071 
1072 static void
1073 dt_compile_agg(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
1074 {
1075 	dt_ident_t *aid, *fid;
1076 	dt_node_t *anp, *incr = NULL;
1077 	dtrace_actdesc_t *ap;
1078 	uint_t n = 1, argmax;
1079 	uint64_t arg = 0;
1080 
1081 	/*
1082 	 * If the aggregation has no aggregating function applied to it, then
1083 	 * this statement has no effect.  Flag this as a programming error.
1084 	 */
1085 	if (dnp->dn_aggfun == NULL) {
1086 		dnerror(dnp, D_AGG_NULL, "expression has null effect: @%s\n",
1087 		    dnp->dn_ident->di_name);
1088 	}
1089 
1090 	aid = dnp->dn_ident;
1091 	fid = dnp->dn_aggfun->dn_ident;
1092 
1093 	if (dnp->dn_aggfun->dn_args != NULL &&
1094 	    dt_node_is_scalar(dnp->dn_aggfun->dn_args) == 0) {
1095 		dnerror(dnp->dn_aggfun, D_AGG_SCALAR, "%s( ) argument #1 must "
1096 		    "be of scalar type\n", fid->di_name);
1097 	}
1098 
1099 	/*
1100 	 * The ID of the aggregation itself is implicitly recorded as the first
1101 	 * member of each aggregation tuple so we can distinguish them later.
1102 	 */
1103 	ap = dt_stmt_action(dtp, sdp);
1104 	dt_action_difconst(ap, aid->di_id, DTRACEACT_DIFEXPR);
1105 
1106 	for (anp = dnp->dn_aggtup; anp != NULL; anp = anp->dn_list) {
1107 		ap = dt_stmt_action(dtp, sdp);
1108 		n++;
1109 
1110 		if (anp->dn_kind == DT_NODE_FUNC) {
1111 			if (anp->dn_ident->di_id == DT_ACT_STACK) {
1112 				dt_action_stack_args(dtp, ap, anp->dn_args);
1113 				continue;
1114 			}
1115 
1116 			if (anp->dn_ident->di_id == DT_ACT_USTACK ||
1117 			    anp->dn_ident->di_id == DT_ACT_JSTACK) {
1118 				dt_action_ustack_args(dtp, ap, anp);
1119 				continue;
1120 			}
1121 
1122 			switch (anp->dn_ident->di_id) {
1123 			case DT_ACT_UADDR:
1124 				dt_action_symmod_args(dtp, ap,
1125 				    anp->dn_args, DTRACEACT_UADDR);
1126 				continue;
1127 
1128 			case DT_ACT_USYM:
1129 				dt_action_symmod_args(dtp, ap,
1130 				    anp->dn_args, DTRACEACT_USYM);
1131 				continue;
1132 
1133 			case DT_ACT_UMOD:
1134 				dt_action_symmod_args(dtp, ap,
1135 				    anp->dn_args, DTRACEACT_UMOD);
1136 				continue;
1137 
1138 			case DT_ACT_SYM:
1139 				dt_action_symmod_args(dtp, ap,
1140 				    anp->dn_args, DTRACEACT_SYM);
1141 				continue;
1142 
1143 			case DT_ACT_MOD:
1144 				dt_action_symmod_args(dtp, ap,
1145 				    anp->dn_args, DTRACEACT_MOD);
1146 				continue;
1147 
1148 			default:
1149 				break;
1150 			}
1151 		}
1152 
1153 		dt_cg(yypcb, anp);
1154 		ap->dtad_difo = dt_as(yypcb);
1155 		ap->dtad_kind = DTRACEACT_DIFEXPR;
1156 	}
1157 
1158 	if (fid->di_id == DTRACEAGG_LQUANTIZE) {
1159 		/*
1160 		 * For linear quantization, we have between two and four
1161 		 * arguments in addition to the expression:
1162 		 *
1163 		 *    arg1 => Base value
1164 		 *    arg2 => Limit value
1165 		 *    arg3 => Quantization level step size (defaults to 1)
1166 		 *    arg4 => Quantization increment value (defaults to 1)
1167 		 */
1168 		dt_node_t *arg1 = dnp->dn_aggfun->dn_args->dn_list;
1169 		dt_node_t *arg2 = arg1->dn_list;
1170 		dt_node_t *arg3 = arg2->dn_list;
1171 		dt_idsig_t *isp;
1172 		uint64_t nlevels, step = 1, oarg;
1173 		int64_t baseval, limitval;
1174 
1175 		if (arg1->dn_kind != DT_NODE_INT) {
1176 			dnerror(arg1, D_LQUANT_BASETYPE, "lquantize( ) "
1177 			    "argument #1 must be an integer constant\n");
1178 		}
1179 
1180 		baseval = (int64_t)arg1->dn_value;
1181 
1182 		if (baseval < INT32_MIN || baseval > INT32_MAX) {
1183 			dnerror(arg1, D_LQUANT_BASEVAL, "lquantize( ) "
1184 			    "argument #1 must be a 32-bit quantity\n");
1185 		}
1186 
1187 		if (arg2->dn_kind != DT_NODE_INT) {
1188 			dnerror(arg2, D_LQUANT_LIMTYPE, "lquantize( ) "
1189 			    "argument #2 must be an integer constant\n");
1190 		}
1191 
1192 		limitval = (int64_t)arg2->dn_value;
1193 
1194 		if (limitval < INT32_MIN || limitval > INT32_MAX) {
1195 			dnerror(arg2, D_LQUANT_LIMVAL, "lquantize( ) "
1196 			    "argument #2 must be a 32-bit quantity\n");
1197 		}
1198 
1199 		if (limitval < baseval) {
1200 			dnerror(dnp, D_LQUANT_MISMATCH,
1201 			    "lquantize( ) base (argument #1) must be less "
1202 			    "than limit (argument #2)\n");
1203 		}
1204 
1205 		if (arg3 != NULL) {
1206 			if (!dt_node_is_posconst(arg3)) {
1207 				dnerror(arg3, D_LQUANT_STEPTYPE, "lquantize( ) "
1208 				    "argument #3 must be a non-zero positive "
1209 				    "integer constant\n");
1210 			}
1211 
1212 			if ((step = arg3->dn_value) > UINT16_MAX) {
1213 				dnerror(arg3, D_LQUANT_STEPVAL, "lquantize( ) "
1214 				    "argument #3 must be a 16-bit quantity\n");
1215 			}
1216 		}
1217 
1218 		nlevels = (limitval - baseval) / step;
1219 
1220 		if (nlevels == 0) {
1221 			dnerror(dnp, D_LQUANT_STEPLARGE,
1222 			    "lquantize( ) step (argument #3) too large: must "
1223 			    "have at least one quantization level\n");
1224 		}
1225 
1226 		if (nlevels > UINT16_MAX) {
1227 			dnerror(dnp, D_LQUANT_STEPSMALL, "lquantize( ) step "
1228 			    "(argument #3) too small: number of quantization "
1229 			    "levels must be a 16-bit quantity\n");
1230 		}
1231 
1232 		arg = (step << DTRACE_LQUANTIZE_STEPSHIFT) |
1233 		    (nlevels << DTRACE_LQUANTIZE_LEVELSHIFT) |
1234 		    ((baseval << DTRACE_LQUANTIZE_BASESHIFT) &
1235 		    DTRACE_LQUANTIZE_BASEMASK);
1236 
1237 		assert(arg != 0);
1238 
1239 		isp = (dt_idsig_t *)aid->di_data;
1240 
1241 		if (isp->dis_auxinfo == 0) {
1242 			/*
1243 			 * This is the first time we've seen an lquantize()
1244 			 * for this aggregation; we'll store our argument
1245 			 * as the auxiliary signature information.
1246 			 */
1247 			isp->dis_auxinfo = arg;
1248 		} else if ((oarg = isp->dis_auxinfo) != arg) {
1249 			/*
1250 			 * If we have seen this lquantize() before and the
1251 			 * argument doesn't match the original argument, pick
1252 			 * the original argument apart to concisely report the
1253 			 * mismatch.
1254 			 */
1255 			int obaseval = DTRACE_LQUANTIZE_BASE(oarg);
1256 			int onlevels = DTRACE_LQUANTIZE_LEVELS(oarg);
1257 			int ostep = DTRACE_LQUANTIZE_STEP(oarg);
1258 
1259 			if (obaseval != baseval) {
1260 				dnerror(dnp, D_LQUANT_MATCHBASE, "lquantize( ) "
1261 				    "base (argument #1) doesn't match previous "
1262 				    "declaration: expected %d, found %d\n",
1263 				    obaseval, (int)baseval);
1264 			}
1265 
1266 			if (onlevels * ostep != nlevels * step) {
1267 				dnerror(dnp, D_LQUANT_MATCHLIM, "lquantize( ) "
1268 				    "limit (argument #2) doesn't match previous"
1269 				    " declaration: expected %d, found %d\n",
1270 				    obaseval + onlevels * ostep,
1271 				    (int)baseval + (int)nlevels * (int)step);
1272 			}
1273 
1274 			if (ostep != step) {
1275 				dnerror(dnp, D_LQUANT_MATCHSTEP, "lquantize( ) "
1276 				    "step (argument #3) doesn't match previous "
1277 				    "declaration: expected %d, found %d\n",
1278 				    ostep, (int)step);
1279 			}
1280 
1281 			/*
1282 			 * We shouldn't be able to get here -- one of the
1283 			 * parameters must be mismatched if the arguments
1284 			 * didn't match.
1285 			 */
1286 			assert(0);
1287 		}
1288 
1289 		incr = arg3 != NULL ? arg3->dn_list : NULL;
1290 		argmax = 5;
1291 	}
1292 
1293 	if (fid->di_id == DTRACEAGG_QUANTIZE) {
1294 		incr = dnp->dn_aggfun->dn_args->dn_list;
1295 		argmax = 2;
1296 	}
1297 
1298 	if (incr != NULL) {
1299 		if (!dt_node_is_scalar(incr)) {
1300 			dnerror(dnp, D_PROTO_ARG, "%s( ) increment value "
1301 			    "(argument #%d) must be of scalar type\n",
1302 			    fid->di_name, argmax);
1303 		}
1304 
1305 		if ((anp = incr->dn_list) != NULL) {
1306 			int argc = argmax;
1307 
1308 			for (; anp != NULL; anp = anp->dn_list)
1309 				argc++;
1310 
1311 			dnerror(incr, D_PROTO_LEN, "%s( ) prototype "
1312 			    "mismatch: %d args passed, at most %d expected",
1313 			    fid->di_name, argc, argmax);
1314 		}
1315 
1316 		ap = dt_stmt_action(dtp, sdp);
1317 		n++;
1318 
1319 		dt_cg(yypcb, incr);
1320 		ap->dtad_difo = dt_as(yypcb);
1321 		ap->dtad_difo->dtdo_rtype = dt_void_rtype;
1322 		ap->dtad_kind = DTRACEACT_DIFEXPR;
1323 	}
1324 
1325 	assert(sdp->dtsd_aggdata == NULL);
1326 	sdp->dtsd_aggdata = aid;
1327 
1328 	ap = dt_stmt_action(dtp, sdp);
1329 	assert(fid->di_kind == DT_IDENT_AGGFUNC);
1330 	assert(DTRACEACT_ISAGG(fid->di_id));
1331 	ap->dtad_kind = fid->di_id;
1332 	ap->dtad_ntuple = n;
1333 	ap->dtad_arg = arg;
1334 
1335 	if (dnp->dn_aggfun->dn_args != NULL) {
1336 		dt_cg(yypcb, dnp->dn_aggfun->dn_args);
1337 		ap->dtad_difo = dt_as(yypcb);
1338 	}
1339 }
1340 
1341 static void
1342 dt_compile_one_clause(dtrace_hdl_t *dtp, dt_node_t *cnp, dt_node_t *pnp)
1343 {
1344 	dtrace_ecbdesc_t *edp;
1345 	dtrace_stmtdesc_t *sdp;
1346 	dt_node_t *dnp;
1347 
1348 	yylineno = pnp->dn_line;
1349 	dt_setcontext(dtp, pnp->dn_desc);
1350 	(void) dt_node_cook(cnp, DT_IDFLG_REF);
1351 
1352 	if (DT_TREEDUMP_PASS(dtp, 2))
1353 		dt_node_printr(cnp, stderr, 0);
1354 
1355 	if ((edp = dt_ecbdesc_create(dtp, pnp->dn_desc)) == NULL)
1356 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
1357 
1358 	assert(yypcb->pcb_ecbdesc == NULL);
1359 	yypcb->pcb_ecbdesc = edp;
1360 
1361 	if (cnp->dn_pred != NULL) {
1362 		dt_cg(yypcb, cnp->dn_pred);
1363 		edp->dted_pred.dtpdd_difo = dt_as(yypcb);
1364 	}
1365 
1366 	if (cnp->dn_acts == NULL) {
1367 		dt_stmt_append(dt_stmt_create(dtp, edp,
1368 		    cnp->dn_ctxattr, _dtrace_defattr), cnp);
1369 	}
1370 
1371 	for (dnp = cnp->dn_acts; dnp != NULL; dnp = dnp->dn_list) {
1372 		assert(yypcb->pcb_stmt == NULL);
1373 		sdp = dt_stmt_create(dtp, edp, cnp->dn_ctxattr, cnp->dn_attr);
1374 
1375 		switch (dnp->dn_kind) {
1376 		case DT_NODE_DEXPR:
1377 			if (dnp->dn_expr->dn_kind == DT_NODE_AGG)
1378 				dt_compile_agg(dtp, dnp->dn_expr, sdp);
1379 			else
1380 				dt_compile_exp(dtp, dnp, sdp);
1381 			break;
1382 		case DT_NODE_DFUNC:
1383 			dt_compile_fun(dtp, dnp, sdp);
1384 			break;
1385 		case DT_NODE_AGG:
1386 			dt_compile_agg(dtp, dnp, sdp);
1387 			break;
1388 		default:
1389 			dnerror(dnp, D_UNKNOWN, "internal error -- node kind "
1390 			    "%u is not a valid statement\n", dnp->dn_kind);
1391 		}
1392 
1393 		assert(yypcb->pcb_stmt == sdp);
1394 		dt_stmt_append(sdp, dnp);
1395 	}
1396 
1397 	assert(yypcb->pcb_ecbdesc == edp);
1398 	dt_ecbdesc_release(dtp, edp);
1399 	dt_endcontext(dtp);
1400 	yypcb->pcb_ecbdesc = NULL;
1401 }
1402 
1403 static void
1404 dt_compile_clause(dtrace_hdl_t *dtp, dt_node_t *cnp)
1405 {
1406 	dt_node_t *pnp;
1407 
1408 	for (pnp = cnp->dn_pdescs; pnp != NULL; pnp = pnp->dn_list)
1409 		dt_compile_one_clause(dtp, cnp, pnp);
1410 }
1411 
1412 static void
1413 dt_compile_xlator(dt_node_t *dnp)
1414 {
1415 	dt_xlator_t *dxp = dnp->dn_xlator;
1416 	dt_node_t *mnp;
1417 
1418 	for (mnp = dnp->dn_members; mnp != NULL; mnp = mnp->dn_list) {
1419 		assert(dxp->dx_membdif[mnp->dn_membid] == NULL);
1420 		dt_cg(yypcb, mnp);
1421 		dxp->dx_membdif[mnp->dn_membid] = dt_as(yypcb);
1422 	}
1423 }
1424 
1425 void
1426 dt_setcontext(dtrace_hdl_t *dtp, dtrace_probedesc_t *pdp)
1427 {
1428 	const dtrace_pattr_t *pap;
1429 	dt_probe_t *prp;
1430 	dt_ident_t *idp;
1431 	char attrstr[8];
1432 	int err;
1433 
1434 	/*
1435 	 * If the provider name ends with what could be interpreted as a
1436 	 * number, we assume that it's a pid and that we may need to
1437 	 * dynamically create those probes for that process.
1438 	 */
1439 	if (isdigit(pdp->dtpd_provider[strlen(pdp->dtpd_provider) - 1]))
1440 		dt_pid_create_probes(pdp, dtp);
1441 
1442 	/*
1443 	 * Call dt_probe_info() to get the probe arguments and attributes.  If
1444 	 * a representative probe is found, set 'pap' to the probe provider's
1445 	 * attributes.  Otherwise set 'pap' to default Unstable attributes.
1446 	 */
1447 	if ((prp = dt_probe_info(dtp, pdp, &yypcb->pcb_pinfo)) == NULL) {
1448 		pap = &_dtrace_prvdesc;
1449 		err = dtrace_errno(dtp);
1450 		bzero(&yypcb->pcb_pinfo, sizeof (dtrace_probeinfo_t));
1451 		yypcb->pcb_pinfo.dtp_attr = pap->dtpa_provider;
1452 		yypcb->pcb_pinfo.dtp_arga = pap->dtpa_args;
1453 	} else {
1454 		pap = &prp->pr_pvp->pv_desc.dtvd_attr;
1455 		err = 0;
1456 	}
1457 
1458 	if (err == EDT_NOPROBE && !(yypcb->pcb_cflags & DTRACE_C_ZDEFS)) {
1459 		xyerror(D_PDESC_ZERO, "probe description %s:%s:%s:%s does not "
1460 		    "match any probes\n", pdp->dtpd_provider, pdp->dtpd_mod,
1461 		    pdp->dtpd_func, pdp->dtpd_name);
1462 	}
1463 
1464 	if (err != EDT_NOPROBE && err != EDT_UNSTABLE && err != 0)
1465 		xyerror(D_PDESC_INVAL, "%s\n", dtrace_errmsg(dtp, err));
1466 
1467 	dt_dprintf("set context to %s:%s:%s:%s [%u] prp=%p attr=%s argc=%d\n",
1468 	    pdp->dtpd_provider, pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name,
1469 	    pdp->dtpd_id, (void *)prp, dt_attr_str(yypcb->pcb_pinfo.dtp_attr,
1470 	    attrstr, sizeof (attrstr)), yypcb->pcb_pinfo.dtp_argc);
1471 
1472 	/*
1473 	 * Reset the stability attributes of D global variables that vary
1474 	 * based on the attributes of the provider and context itself.
1475 	 */
1476 	if ((idp = dt_idhash_lookup(dtp->dt_globals, "probeprov")) != NULL)
1477 		idp->di_attr = pap->dtpa_provider;
1478 	if ((idp = dt_idhash_lookup(dtp->dt_globals, "probemod")) != NULL)
1479 		idp->di_attr = pap->dtpa_mod;
1480 	if ((idp = dt_idhash_lookup(dtp->dt_globals, "probefunc")) != NULL)
1481 		idp->di_attr = pap->dtpa_func;
1482 	if ((idp = dt_idhash_lookup(dtp->dt_globals, "probename")) != NULL)
1483 		idp->di_attr = pap->dtpa_name;
1484 	if ((idp = dt_idhash_lookup(dtp->dt_globals, "args")) != NULL)
1485 		idp->di_attr = pap->dtpa_args;
1486 
1487 	yypcb->pcb_pdesc = pdp;
1488 	yypcb->pcb_probe = prp;
1489 }
1490 
1491 /*
1492  * Reset context-dependent variables and state at the end of cooking a D probe
1493  * definition clause.  This ensures that external declarations between clauses
1494  * do not reference any stale context-dependent data from the previous clause.
1495  */
1496 void
1497 dt_endcontext(dtrace_hdl_t *dtp)
1498 {
1499 	static const char *const cvars[] = {
1500 		"probeprov", "probemod", "probefunc", "probename", "args", NULL
1501 	};
1502 
1503 	dt_ident_t *idp;
1504 	int i;
1505 
1506 	for (i = 0; cvars[i] != NULL; i++) {
1507 		if ((idp = dt_idhash_lookup(dtp->dt_globals, cvars[i])) != NULL)
1508 			idp->di_attr = _dtrace_defattr;
1509 	}
1510 
1511 	yypcb->pcb_pdesc = NULL;
1512 	yypcb->pcb_probe = NULL;
1513 }
1514 
1515 static int
1516 dt_reduceid(dt_idhash_t *dhp, dt_ident_t *idp, dtrace_hdl_t *dtp)
1517 {
1518 	if (idp->di_vers != 0 && idp->di_vers > dtp->dt_vmax)
1519 		dt_idhash_delete(dhp, idp);
1520 
1521 	return (0);
1522 }
1523 
1524 /*
1525  * When dtrace_setopt() is called for "version", it calls dt_reduce() to remove
1526  * any identifiers or translators that have been previously defined as bound to
1527  * a version greater than the specified version.  Therefore, in our current
1528  * version implementation, establishing a binding is a one-way transformation.
1529  * In addition, no versioning is currently provided for types as our .d library
1530  * files do not define any types and we reserve prefixes DTRACE_ and dtrace_
1531  * for our exclusive use.  If required, type versioning will require more work.
1532  */
1533 int
1534 dt_reduce(dtrace_hdl_t *dtp, dt_version_t v)
1535 {
1536 	char s[DT_VERSION_STRMAX];
1537 	dt_xlator_t *dxp, *nxp;
1538 
1539 	if (v > dtp->dt_vmax)
1540 		return (dt_set_errno(dtp, EDT_VERSREDUCED));
1541 	else if (v == dtp->dt_vmax)
1542 		return (0); /* no reduction necessary */
1543 
1544 	dt_dprintf("reducing api version to %s\n",
1545 	    dt_version_num2str(v, s, sizeof (s)));
1546 
1547 	dtp->dt_vmax = v;
1548 
1549 	for (dxp = dt_list_next(&dtp->dt_xlators); dxp != NULL; dxp = nxp) {
1550 		nxp = dt_list_next(dxp);
1551 		if ((dxp->dx_souid.di_vers != 0 && dxp->dx_souid.di_vers > v) ||
1552 		    (dxp->dx_ptrid.di_vers != 0 && dxp->dx_ptrid.di_vers > v))
1553 			dt_list_delete(&dtp->dt_xlators, dxp);
1554 	}
1555 
1556 	(void) dt_idhash_iter(dtp->dt_macros, (dt_idhash_f *)dt_reduceid, dtp);
1557 	(void) dt_idhash_iter(dtp->dt_aggs, (dt_idhash_f *)dt_reduceid, dtp);
1558 	(void) dt_idhash_iter(dtp->dt_globals, (dt_idhash_f *)dt_reduceid, dtp);
1559 	(void) dt_idhash_iter(dtp->dt_tls, (dt_idhash_f *)dt_reduceid, dtp);
1560 
1561 	return (0);
1562 }
1563 
1564 /*
1565  * Fork and exec the cpp(1) preprocessor to run over the specified input file,
1566  * and return a FILE handle for the cpp output.  We use the /dev/fd filesystem
1567  * here to simplify the code by leveraging file descriptor inheritance.
1568  */
1569 static FILE *
1570 dt_preproc(dtrace_hdl_t *dtp, FILE *ifp)
1571 {
1572 	int argc = dtp->dt_cpp_argc;
1573 	char **argv = malloc(sizeof (char *) * (argc + 5));
1574 	FILE *ofp = tmpfile();
1575 
1576 	char ipath[20], opath[20]; /* big enough for /dev/fd/ + INT_MAX + \0 */
1577 	char verdef[32]; /* big enough for -D__SUNW_D_VERSION=0x%08x + \0 */
1578 
1579 	struct sigaction act, oact;
1580 	sigset_t mask, omask;
1581 
1582 	int wstat, estat;
1583 	pid_t pid;
1584 	off64_t off;
1585 	int c;
1586 
1587 	if (argv == NULL || ofp == NULL) {
1588 		(void) dt_set_errno(dtp, errno);
1589 		goto err;
1590 	}
1591 
1592 	/*
1593 	 * If the input is a seekable file, see if it is an interpreter file.
1594 	 * If we see #!, seek past the first line because cpp will choke on it.
1595 	 * We start cpp just prior to the \n at the end of this line so that
1596 	 * it still sees the newline, ensuring that #line values are correct.
1597 	 */
1598 	if (isatty(fileno(ifp)) == 0 && (off = ftello64(ifp)) != -1) {
1599 		if ((c = fgetc(ifp)) == '#' && (c = fgetc(ifp)) == '!') {
1600 			for (off += 2; c != '\n'; off++) {
1601 				if ((c = fgetc(ifp)) == EOF)
1602 					break;
1603 			}
1604 			if (c == '\n')
1605 				off--; /* start cpp just prior to \n */
1606 		}
1607 		(void) fflush(ifp);
1608 		(void) fseeko64(ifp, off, SEEK_SET);
1609 	}
1610 
1611 	(void) snprintf(ipath, sizeof (ipath), "/dev/fd/%d", fileno(ifp));
1612 	(void) snprintf(opath, sizeof (opath), "/dev/fd/%d", fileno(ofp));
1613 
1614 	bcopy(dtp->dt_cpp_argv, argv, sizeof (char *) * argc);
1615 
1616 	(void) snprintf(verdef, sizeof (verdef),
1617 	    "-D__SUNW_D_VERSION=0x%08x", dtp->dt_vmax);
1618 	argv[argc++] = verdef;
1619 
1620 	switch (dtp->dt_stdcmode) {
1621 	case DT_STDC_XA:
1622 	case DT_STDC_XT:
1623 		argv[argc++] = "-D__STDC__=0";
1624 		break;
1625 	case DT_STDC_XC:
1626 		argv[argc++] = "-D__STDC__=1";
1627 		break;
1628 	}
1629 
1630 	argv[argc++] = ipath;
1631 	argv[argc++] = opath;
1632 	argv[argc] = NULL;
1633 
1634 	/*
1635 	 * libdtrace must be able to be embedded in other programs that may
1636 	 * include application-specific signal handlers.  Therefore, if we
1637 	 * need to fork to run cpp(1), we must avoid generating a SIGCHLD
1638 	 * that could confuse the containing application.  To do this,
1639 	 * we block SIGCHLD and reset its disposition to SIG_DFL.
1640 	 * We restore our signal state once we are done.
1641 	 */
1642 	(void) sigemptyset(&mask);
1643 	(void) sigaddset(&mask, SIGCHLD);
1644 	(void) sigprocmask(SIG_BLOCK, &mask, &omask);
1645 
1646 	bzero(&act, sizeof (act));
1647 	act.sa_handler = SIG_DFL;
1648 	(void) sigaction(SIGCHLD, &act, &oact);
1649 
1650 	if ((pid = fork1()) == -1) {
1651 		(void) sigaction(SIGCHLD, &oact, NULL);
1652 		(void) sigprocmask(SIG_SETMASK, &omask, NULL);
1653 		(void) dt_set_errno(dtp, EDT_CPPFORK);
1654 		goto err;
1655 	}
1656 
1657 	if (pid == 0) {
1658 		(void) execvp(dtp->dt_cpp_path, argv);
1659 		_exit(errno == ENOENT ? 127 : 126);
1660 	}
1661 
1662 	do {
1663 		dt_dprintf("waiting for %s (PID %d)\n", dtp->dt_cpp_path,
1664 		    (int)pid);
1665 	} while (waitpid(pid, &wstat, 0) == -1 && errno == EINTR);
1666 
1667 	(void) sigaction(SIGCHLD, &oact, NULL);
1668 	(void) sigprocmask(SIG_SETMASK, &omask, NULL);
1669 
1670 	dt_dprintf("%s returned exit status 0x%x\n", dtp->dt_cpp_path, wstat);
1671 	estat = WIFEXITED(wstat) ? WEXITSTATUS(wstat) : -1;
1672 
1673 	if (estat != 0) {
1674 		switch (estat) {
1675 		case 126:
1676 			(void) dt_set_errno(dtp, EDT_CPPEXEC);
1677 			break;
1678 		case 127:
1679 			(void) dt_set_errno(dtp, EDT_CPPENT);
1680 			break;
1681 		default:
1682 			(void) dt_set_errno(dtp, EDT_CPPERR);
1683 		}
1684 		goto err;
1685 	}
1686 
1687 	free(argv);
1688 	(void) fflush(ofp);
1689 	(void) fseek(ofp, 0, SEEK_SET);
1690 	return (ofp);
1691 
1692 err:
1693 	free(argv);
1694 	(void) fclose(ofp);
1695 	return (NULL);
1696 }
1697 
1698 /*
1699  * Open all of the .d library files found in the specified directory and try to
1700  * compile each one in order to cache its inlines and translators, etc.  We
1701  * silently ignore any missing directories and other files found therein.
1702  * We only fail (and thereby fail dt_load_libs()) if we fail to compile a
1703  * library and the error is something other than #pragma D depends_on.
1704  * Dependency errors are silently ignored to permit a library directory to
1705  * contain libraries which may not be accessible depending on our privileges.
1706  *
1707  * Note that at present, no ordering is defined between library files found in
1708  * the same directory: if cross-library dependencies are eventually required,
1709  * we will need to extend the #pragma D depends_on directive with an additional
1710  * class for libraries, and this function will need to create a graph of the
1711  * various library pathnames and then perform a topological ordering using the
1712  * dependency information before we attempt to compile any of them.
1713  */
1714 static int
1715 dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path)
1716 {
1717 	struct dirent *dp;
1718 	const char *p;
1719 	DIR *dirp;
1720 
1721 	char fname[PATH_MAX];
1722 	dtrace_prog_t *pgp;
1723 	FILE *fp;
1724 
1725 	if ((dirp = opendir(path)) == NULL) {
1726 		dt_dprintf("skipping lib dir %s: %s\n", path, strerror(errno));
1727 		return (0);
1728 	}
1729 
1730 	while ((dp = readdir(dirp)) != NULL) {
1731 		if ((p = strrchr(dp->d_name, '.')) == NULL || strcmp(p, ".d"))
1732 			continue; /* skip any filename not ending in .d */
1733 
1734 		(void) snprintf(fname, sizeof (fname),
1735 		    "%s/%s", path, dp->d_name);
1736 
1737 		if ((fp = fopen(fname, "r")) == NULL) {
1738 			dt_dprintf("skipping library %s: %s\n",
1739 			    fname, strerror(errno));
1740 			continue;
1741 		}
1742 
1743 		dtp->dt_filetag = fname;
1744 		pgp = dtrace_program_fcompile(dtp, fp, DTRACE_C_EMPTY, 0, NULL);
1745 		(void) fclose(fp);
1746 		dtp->dt_filetag = NULL;
1747 
1748 		if (pgp == NULL && (dtp->dt_errno != EDT_COMPILER ||
1749 		    dtp->dt_errtag != dt_errtag(D_PRAGMA_DEPEND))) {
1750 			(void) closedir(dirp);
1751 			return (-1); /* preserve dt_errno */
1752 		}
1753 
1754 		if (pgp == NULL) {
1755 			dt_dprintf("skipping library: %s\n",
1756 			    dtrace_errmsg(dtp, dtrace_errno(dtp)));
1757 		} else
1758 			dt_program_destroy(dtp, pgp);
1759 	}
1760 
1761 	(void) closedir(dirp);
1762 	return (0);
1763 }
1764 
1765 /*
1766  * Load the contents of any appropriate DTrace .d library files.  These files
1767  * contain inlines and translators that will be cached by the compiler.  We
1768  * defer this activity until the first compile to permit libdtrace clients to
1769  * add their own library directories and so that we can properly report errors.
1770  */
1771 static int
1772 dt_load_libs(dtrace_hdl_t *dtp)
1773 {
1774 	dt_dirpath_t *dirp;
1775 
1776 	if (dtp->dt_cflags & DTRACE_C_NOLIBS)
1777 		return (0); /* libraries already processed */
1778 
1779 	dtp->dt_cflags |= DTRACE_C_NOLIBS;
1780 
1781 	for (dirp = dt_list_next(&dtp->dt_lib_path);
1782 	    dirp != NULL; dirp = dt_list_next(dirp)) {
1783 		if (dt_load_libs_dir(dtp, dirp->dir_path) != 0) {
1784 			dtp->dt_cflags &= ~DTRACE_C_NOLIBS;
1785 			return (-1); /* errno is set for us */
1786 		}
1787 	}
1788 
1789 	return (0);
1790 }
1791 
1792 static void *
1793 dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
1794     uint_t cflags, int argc, char *const argv[], FILE *fp, const char *s)
1795 {
1796 	dt_node_t *dnp;
1797 	dt_decl_t *ddp;
1798 	dt_pcb_t pcb;
1799 	void *rv;
1800 	int err;
1801 
1802 	if ((fp == NULL && s == NULL) || (cflags & ~DTRACE_C_MASK) != 0) {
1803 		(void) dt_set_errno(dtp, EINVAL);
1804 		return (NULL);
1805 	}
1806 
1807 	if (dt_list_next(&dtp->dt_lib_path) != NULL && dt_load_libs(dtp) != 0)
1808 		return (NULL); /* errno is set for us */
1809 
1810 	(void) ctf_discard(dtp->dt_cdefs->dm_ctfp);
1811 	(void) ctf_discard(dtp->dt_ddefs->dm_ctfp);
1812 
1813 	(void) dt_idhash_iter(dtp->dt_globals, dt_idreset, NULL);
1814 	(void) dt_idhash_iter(dtp->dt_tls, dt_idreset, NULL);
1815 
1816 	if (fp && (cflags & DTRACE_C_CPP) && (fp = dt_preproc(dtp, fp)) == NULL)
1817 		return (NULL); /* errno is set for us */
1818 
1819 	dt_pcb_push(dtp, &pcb);
1820 
1821 	pcb.pcb_fileptr = fp;
1822 	pcb.pcb_string = s;
1823 	pcb.pcb_strptr = s;
1824 	pcb.pcb_strlen = s ? strlen(s) : 0;
1825 	pcb.pcb_sargc = argc;
1826 	pcb.pcb_sargv = argv;
1827 	pcb.pcb_sflagv = argc ? calloc(argc, sizeof (ushort_t)) : NULL;
1828 	pcb.pcb_pspec = pspec;
1829 	pcb.pcb_cflags = dtp->dt_cflags | cflags;
1830 	pcb.pcb_amin = dtp->dt_amin;
1831 	pcb.pcb_yystate = -1;
1832 	pcb.pcb_context = context;
1833 	pcb.pcb_token = context;
1834 
1835 	if (context == DT_CTX_DPROG)
1836 		yybegin(YYS_CLAUSE);
1837 	else
1838 		yybegin(YYS_EXPR);
1839 
1840 	if ((err = setjmp(yypcb->pcb_jmpbuf)) != 0)
1841 		goto out;
1842 
1843 	if (yypcb->pcb_sargc != 0 && yypcb->pcb_sflagv == NULL)
1844 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
1845 
1846 	yypcb->pcb_idents = dt_idhash_create("ambiguous", NULL, 0, 0);
1847 	yypcb->pcb_locals = dt_idhash_create("clause local", NULL,
1848 	    DIF_VAR_OTHER_UBASE, DIF_VAR_OTHER_MAX);
1849 
1850 	if (yypcb->pcb_idents == NULL || yypcb->pcb_locals == NULL)
1851 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
1852 
1853 	/*
1854 	 * Invoke the parser to evaluate the D source code.  If any errors
1855 	 * occur during parsing, an error function will be called and we
1856 	 * will longjmp back to pcb_jmpbuf to abort.  If parsing succeeds,
1857 	 * we optionally display the parse tree if debugging is enabled.
1858 	 */
1859 	if (yyparse() != 0 || yypcb->pcb_root == NULL)
1860 		xyerror(D_EMPTY, "empty D program translation unit\n");
1861 
1862 	yybegin(YYS_DONE);
1863 
1864 	if (context != DT_CTX_DTYPE && DT_TREEDUMP_PASS(dtp, 1))
1865 		dt_node_printr(yypcb->pcb_root, stderr, 0);
1866 
1867 	if (yypcb->pcb_pragmas != NULL)
1868 		(void) dt_idhash_iter(yypcb->pcb_pragmas, dt_idpragma, NULL);
1869 
1870 	if (argc > 1 && !(yypcb->pcb_cflags & DTRACE_C_ARGREF) &&
1871 	    !(yypcb->pcb_sflagv[argc - 1] & DT_IDFLG_REF)) {
1872 		xyerror(D_MACRO_UNUSED, "extraneous argument '%s' ($%d is "
1873 		    "not referenced)\n", yypcb->pcb_sargv[argc - 1], argc - 1);
1874 	}
1875 
1876 	/*
1877 	 * If we have successfully created a parse tree for a D program, loop
1878 	 * over the clauses and actions and instantiate the corresponding
1879 	 * libdtrace program.  If we are parsing a D expression, then we
1880 	 * simply run the code generator and assembler on the resulting tree.
1881 	 */
1882 	switch (context) {
1883 	case DT_CTX_DPROG:
1884 		assert(yypcb->pcb_root->dn_kind == DT_NODE_PROG);
1885 
1886 		if ((dnp = yypcb->pcb_root->dn_list) == NULL &&
1887 		    !(yypcb->pcb_cflags & DTRACE_C_EMPTY))
1888 			xyerror(D_EMPTY, "empty D program translation unit\n");
1889 
1890 		if ((yypcb->pcb_prog = dt_program_create(dtp)) == NULL)
1891 			longjmp(yypcb->pcb_jmpbuf, dtrace_errno(dtp));
1892 
1893 		for (; dnp != NULL; dnp = dnp->dn_list) {
1894 			switch (dnp->dn_kind) {
1895 			case DT_NODE_CLAUSE:
1896 				dt_compile_clause(dtp, dnp);
1897 				break;
1898 			case DT_NODE_XLATOR:
1899 				if (dtp->dt_xlatemode == DT_XL_DYNAMIC)
1900 					dt_compile_xlator(dnp);
1901 				break;
1902 			case DT_NODE_PROVIDER:
1903 				(void) dt_node_cook(dnp, DT_IDFLG_REF);
1904 				break;
1905 			}
1906 		}
1907 
1908 		yypcb->pcb_prog->dp_xrefs = yypcb->pcb_asxrefs;
1909 		yypcb->pcb_prog->dp_xrefslen = yypcb->pcb_asxreflen;
1910 		yypcb->pcb_asxrefs = NULL;
1911 		yypcb->pcb_asxreflen = 0;
1912 
1913 		rv = yypcb->pcb_prog;
1914 		break;
1915 
1916 	case DT_CTX_DEXPR:
1917 		(void) dt_node_cook(yypcb->pcb_root, DT_IDFLG_REF);
1918 		dt_cg(yypcb, yypcb->pcb_root);
1919 		rv = dt_as(yypcb);
1920 		break;
1921 
1922 	case DT_CTX_DTYPE:
1923 		ddp = (dt_decl_t *)yypcb->pcb_root; /* root is really a decl */
1924 		err = dt_decl_type(ddp, arg);
1925 		dt_decl_free(ddp);
1926 
1927 		if (err != 0)
1928 			longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
1929 
1930 		rv = NULL;
1931 		break;
1932 	}
1933 
1934 out:
1935 	if (context != DT_CTX_DTYPE && DT_TREEDUMP_PASS(dtp, 3))
1936 		dt_node_printr(yypcb->pcb_root, stderr, 0);
1937 
1938 	if (dtp->dt_cdefs_fd != -1 && (ftruncate64(dtp->dt_cdefs_fd, 0) == -1 ||
1939 	    lseek64(dtp->dt_cdefs_fd, 0, SEEK_SET) == -1 ||
1940 	    ctf_write(dtp->dt_cdefs->dm_ctfp, dtp->dt_cdefs_fd) == CTF_ERR))
1941 		dt_dprintf("failed to update CTF cache: %s\n", strerror(errno));
1942 
1943 	if (dtp->dt_ddefs_fd != -1 && (ftruncate64(dtp->dt_ddefs_fd, 0) == -1 ||
1944 	    lseek64(dtp->dt_ddefs_fd, 0, SEEK_SET) == -1 ||
1945 	    ctf_write(dtp->dt_ddefs->dm_ctfp, dtp->dt_ddefs_fd) == CTF_ERR))
1946 		dt_dprintf("failed to update CTF cache: %s\n", strerror(errno));
1947 
1948 	if (yypcb->pcb_fileptr && (cflags & DTRACE_C_CPP))
1949 		(void) fclose(yypcb->pcb_fileptr); /* close dt_preproc() file */
1950 
1951 	dt_pcb_pop(dtp, err);
1952 	(void) dt_set_errno(dtp, err);
1953 	return (err ? NULL : rv);
1954 }
1955 
1956 dtrace_prog_t *
1957 dtrace_program_strcompile(dtrace_hdl_t *dtp, const char *s,
1958     dtrace_probespec_t spec, uint_t cflags, int argc, char *const argv[])
1959 {
1960 	return (dt_compile(dtp, DT_CTX_DPROG,
1961 	    spec, NULL, cflags, argc, argv, NULL, s));
1962 }
1963 
1964 dtrace_prog_t *
1965 dtrace_program_fcompile(dtrace_hdl_t *dtp, FILE *fp,
1966     uint_t cflags, int argc, char *const argv[])
1967 {
1968 	return (dt_compile(dtp, DT_CTX_DPROG,
1969 	    DTRACE_PROBESPEC_NAME, NULL, cflags, argc, argv, fp, NULL));
1970 }
1971 
1972 int
1973 dtrace_type_strcompile(dtrace_hdl_t *dtp, const char *s, dtrace_typeinfo_t *dtt)
1974 {
1975 	(void) dt_compile(dtp, DT_CTX_DTYPE,
1976 	    DTRACE_PROBESPEC_NONE, dtt, 0, 0, NULL, NULL, s);
1977 	return (dtp->dt_errno ? -1 : 0);
1978 }
1979 
1980 int
1981 dtrace_type_fcompile(dtrace_hdl_t *dtp, FILE *fp, dtrace_typeinfo_t *dtt)
1982 {
1983 	(void) dt_compile(dtp, DT_CTX_DTYPE,
1984 	    DTRACE_PROBESPEC_NONE, dtt, 0, 0, NULL, fp, NULL);
1985 	return (dtp->dt_errno ? -1 : 0);
1986 }
1987