4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011, Joyent Inc. All rights reserved.
25 * Copyright (c) 2012 by Delphix. All rights reserved.
26 */
27
28 /*
29 * DTrace D Language Compiler
30 *
31 * The code in this source file implements the main engine for the D language
32 * compiler. The driver routine for the compiler is dt_compile(), below. The
33 * compiler operates on either stdio FILEs or in-memory strings as its input
34 * and can produce either dtrace_prog_t structures from a D program or a single
35 * dtrace_difo_t structure from a D expression. Multiple entry points are
36 * provided as wrappers around dt_compile() for the various input/output pairs.
37 * The compiler itself is implemented across the following source files:
38 *
39 * dt_lex.l - lex scanner
40 * dt_grammar.y - yacc grammar
41 * dt_parser.c - parse tree creation and semantic checking
42 * dt_decl.c - declaration stack processing
43 * dt_xlator.c - D translator lookup and creation
44 * dt_ident.c - identifier and symbol table routines
645 dp->dtdo_len = 1;
646 dp->dtdo_rtype = dt_int_rtype;
647
648 ap = dt_stmt_action(dtp, sdp);
649 ap->dtad_difo = dp;
650 ap->dtad_kind = kind;
651 return;
652 }
653
654 for (anp = arg1; anp != NULL; anp = anp->dn_list) {
655 ap = dt_stmt_action(dtp, sdp);
656 dt_cg(yypcb, anp);
657 ap->dtad_difo = dt_as(yypcb);
658 ap->dtad_kind = kind;
659 }
660 }
661
662 static void
663 dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
664 {
665 dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
666 boolean_t istrace = (dnp->dn_ident->di_id == DT_ACT_TRACE);
667 const char *act = istrace ? "trace" : "print";
668
669 if (dt_node_is_void(dnp->dn_args)) {
670 dnerror(dnp->dn_args, istrace ? D_TRACE_VOID : D_PRINT_VOID,
671 "%s( ) may not be applied to a void expression\n", act);
672 }
673
674 if (dt_node_resolve(dnp->dn_args, DT_IDENT_XLPTR) != NULL) {
675 dnerror(dnp->dn_args, istrace ? D_TRACE_DYN : D_PRINT_DYN,
676 "%s( ) may not be applied to a translated pointer\n", act);
677 }
678
679 if (dnp->dn_args->dn_kind == DT_NODE_AGG) {
680 dnerror(dnp->dn_args, istrace ? D_TRACE_AGG : D_PRINT_AGG,
681 "%s( ) may not be applied to an aggregation%s\n", act,
682 istrace ? "" : " -- did you mean printa()?");
683 }
684
685 dt_cg(yypcb, dnp->dn_args);
686
687 /*
688 * The print() action behaves identically to trace(), except that it
689 * stores the CTF type of the argument (if present) within the DOF for
690 * the DIFEXPR action. To do this, we set the 'dtsd_strdata' to point
691 * to the fully-qualified CTF type ID for the result of the DIF
692 * action. We use the ID instead of the name to handles complex types
693 * like arrays and function pointers that can't be resolved by
694 * ctf_type_lookup(). This is later processed by dtrace_dof_create()
695 * and turned into a reference into the string table so that we can
696 * get the type information when we process the data after the fact.
697 */
698 if (dnp->dn_ident->di_id == DT_ACT_PRINT) {
699 dt_node_t *dret;
700 size_t n;
701 dt_module_t *dmp;
702
703 dret = yypcb->pcb_dret;
704 dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp);
705
706 n = snprintf(NULL, 0, "%s`%d", dmp->dm_name, dret->dn_type) + 1;
707 sdp->dtsd_strdata = dt_alloc(dtp, n);
708 if (sdp->dtsd_strdata == NULL)
709 longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
710 (void) snprintf(sdp->dtsd_strdata, n, "%s`%d", dmp->dm_name,
711 dret->dn_type);
712 }
713
714 ap->dtad_difo = dt_as(yypcb);
715 ap->dtad_kind = DTRACEACT_DIFEXPR;
716 }
717
718 static void
719 dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
720 {
721 dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
722
723 dt_node_t *addr = dnp->dn_args;
724 dt_node_t *max = dnp->dn_args->dn_list;
725 dt_node_t *size;
726
727 char n[DT_TYPE_NAMELEN];
728
729 if (dt_node_is_integer(addr) == 0 && dt_node_is_pointer(addr) == 0) {
730 dnerror(addr, D_TRACEMEM_ADDR,
731 "tracemem( ) argument #1 is incompatible with "
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013, Joyent Inc. All rights reserved.
25 * Copyright (c) 2012 by Delphix. All rights reserved.
26 */
27
28 /*
29 * DTrace D Language Compiler
30 *
31 * The code in this source file implements the main engine for the D language
32 * compiler. The driver routine for the compiler is dt_compile(), below. The
33 * compiler operates on either stdio FILEs or in-memory strings as its input
34 * and can produce either dtrace_prog_t structures from a D program or a single
35 * dtrace_difo_t structure from a D expression. Multiple entry points are
36 * provided as wrappers around dt_compile() for the various input/output pairs.
37 * The compiler itself is implemented across the following source files:
38 *
39 * dt_lex.l - lex scanner
40 * dt_grammar.y - yacc grammar
41 * dt_parser.c - parse tree creation and semantic checking
42 * dt_decl.c - declaration stack processing
43 * dt_xlator.c - D translator lookup and creation
44 * dt_ident.c - identifier and symbol table routines
645 dp->dtdo_len = 1;
646 dp->dtdo_rtype = dt_int_rtype;
647
648 ap = dt_stmt_action(dtp, sdp);
649 ap->dtad_difo = dp;
650 ap->dtad_kind = kind;
651 return;
652 }
653
654 for (anp = arg1; anp != NULL; anp = anp->dn_list) {
655 ap = dt_stmt_action(dtp, sdp);
656 dt_cg(yypcb, anp);
657 ap->dtad_difo = dt_as(yypcb);
658 ap->dtad_kind = kind;
659 }
660 }
661
662 static void
663 dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
664 {
665 int ctflib;
666
667 dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
668 boolean_t istrace = (dnp->dn_ident->di_id == DT_ACT_TRACE);
669 const char *act = istrace ? "trace" : "print";
670
671 if (dt_node_is_void(dnp->dn_args)) {
672 dnerror(dnp->dn_args, istrace ? D_TRACE_VOID : D_PRINT_VOID,
673 "%s( ) may not be applied to a void expression\n", act);
674 }
675
676 if (dt_node_resolve(dnp->dn_args, DT_IDENT_XLPTR) != NULL) {
677 dnerror(dnp->dn_args, istrace ? D_TRACE_DYN : D_PRINT_DYN,
678 "%s( ) may not be applied to a translated pointer\n", act);
679 }
680
681 if (dnp->dn_args->dn_kind == DT_NODE_AGG) {
682 dnerror(dnp->dn_args, istrace ? D_TRACE_AGG : D_PRINT_AGG,
683 "%s( ) may not be applied to an aggregation%s\n", act,
684 istrace ? "" : " -- did you mean printa()?");
685 }
686
687 dt_cg(yypcb, dnp->dn_args);
688
689 /*
690 * The print() action behaves identically to trace(), except that it
691 * stores the CTF type of the argument (if present) within the DOF for
692 * the DIFEXPR action. To do this, we set the 'dtsd_strdata' to point
693 * to the fully-qualified CTF type ID for the result of the DIF
694 * action. We use the ID instead of the name to handles complex types
695 * like arrays and function pointers that can't be resolved by
696 * ctf_type_lookup(). This is later processed by dtrace_dof_create()
697 * and turned into a reference into the string table so that we can
698 * get the type information when we process the data after the fact. In
699 * the case where we are referring to userland CTF data, we also need to
700 * to identify which ctf container in question we care about and encode
701 * that within the name.
702 */
703 if (dnp->dn_ident->di_id == DT_ACT_PRINT) {
704 dt_node_t *dret;
705 size_t n;
706 dt_module_t *dmp;
707
708 dret = yypcb->pcb_dret;
709 dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp);
710
711 if (dmp->dm_pid != 0) {
712 ctflib = dt_module_getlibid(dtp, dmp, dret->dn_ctfp);
713 assert(ctflib >= 0);
714 n = snprintf(NULL, 0, "%s`%d`%d", dmp->dm_name,
715 ctflib, dret->dn_type) + 1;
716 } else {
717 n = snprintf(NULL, 0, "%s`%d", dmp->dm_name,
718 dret->dn_type) + 1;
719 }
720 sdp->dtsd_strdata = dt_alloc(dtp, n);
721 if (sdp->dtsd_strdata == NULL)
722 longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
723 if (dmp->dm_pid != 0) {
724 (void) snprintf(sdp->dtsd_strdata, n, "%s`%d`%d",
725 dmp->dm_name, ctflib, dret->dn_type);
726 } else {
727 (void) snprintf(sdp->dtsd_strdata, n, "%s`%d",
728 dmp->dm_name, dret->dn_type);
729 }
730 }
731
732 ap->dtad_difo = dt_as(yypcb);
733 ap->dtad_kind = DTRACEACT_DIFEXPR;
734 }
735
736 static void
737 dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
738 {
739 dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
740
741 dt_node_t *addr = dnp->dn_args;
742 dt_node_t *max = dnp->dn_args->dn_list;
743 dt_node_t *size;
744
745 char n[DT_TYPE_NAMELEN];
746
747 if (dt_node_is_integer(addr) == 0 && dt_node_is_pointer(addr) == 0) {
748 dnerror(addr, D_TRACEMEM_ADDR,
749 "tracemem( ) argument #1 is incompatible with "
|