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 (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 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. |
23 | * Use is subject to license terms. |
24 | */ |
25 | /* |
26 | * Copyright (c) 2013, 2016 by Delphix. All rights reserved. |
27 | * Copyright (c) 2013 Joyent, Inc. All rights reserved. |
28 | */ |
29 | |
30 | #ifndef _DT_PARSER_H |
31 | #define _DT_PARSER_H |
32 | |
33 | #include <sys/types.h> |
34 | #include <sys/dtrace.h> |
35 | |
36 | #include <libctf.h> |
37 | #include <stdarg.h> |
38 | #include <stdio.h> |
39 | |
40 | #ifdef __cplusplus |
41 | extern "C" { |
42 | #endif |
43 | |
44 | #include <dt_errtags.h> |
45 | #include <dt_ident.h> |
46 | #include <dt_decl.h> |
47 | #include <dt_xlator.h> |
48 | #include <dt_list.h> |
49 | |
50 | typedef struct dt_node { |
51 | ctf_file_t *dn_ctfp; /* CTF type container for node's type */ |
52 | ctf_id_t dn_type; /* CTF type reference for node's type */ |
53 | uchar_t dn_kind; /* node kind (DT_NODE_*, defined below) */ |
54 | uchar_t dn_flags; /* node flags (DT_NF_*, defined below) */ |
55 | ushort_t dn_op; /* operator (DT_TOK_*, defined by lex) */ |
56 | int dn_line; /* line number for error messages */ |
57 | int dn_reg; /* register allocated by cg */ |
58 | dtrace_attribute_t dn_attr; /* node stability attributes */ |
59 | |
60 | /* |
61 | * D compiler nodes, as is the usual style, contain a union of the |
62 | * different sub-elements required by the various kinds of nodes. |
63 | * These sub-elements are accessed using the macros defined below. |
64 | */ |
65 | union { |
66 | struct { |
67 | uintmax_t _value; /* integer value */ |
68 | char *_string; /* string value */ |
69 | } _const; |
70 | |
71 | struct { |
72 | dt_ident_t *_ident; /* identifier reference */ |
73 | struct dt_node *_links[3]; /* child node pointers */ |
74 | } _nodes; |
75 | |
76 | struct { |
77 | struct dt_node *_descs; /* list of descriptions */ |
78 | struct dt_node *_pred; /* predicate expression */ |
79 | struct dt_node *_acts; /* action statement list */ |
80 | dt_idhash_t *_locals; /* local variable hash */ |
81 | dtrace_attribute_t _attr; /* context attributes */ |
82 | } _clause; |
83 | |
84 | struct { |
85 | char *_spec; /* specifier string (if any) */ |
86 | dtrace_probedesc_t *_desc; /* final probe description */ |
87 | } _pdesc; |
88 | |
89 | struct { |
90 | char *_name; /* string name of member */ |
91 | struct dt_node *_expr; /* expression node pointer */ |
92 | dt_xlator_t *_xlator; /* translator reference */ |
93 | uint_t _id; /* member identifier */ |
94 | } _member; |
95 | |
96 | struct { |
97 | dt_xlator_t *_xlator; /* translator reference */ |
98 | struct dt_node *_xmemb; /* individual xlator member */ |
99 | struct dt_node *_membs; /* list of member nodes */ |
100 | } _xlator; |
101 | |
102 | struct { |
103 | char *_name; /* string name of provider */ |
104 | struct dt_provider *_pvp; /* provider references */ |
105 | struct dt_node *_probes; /* list of probe nodes */ |
106 | int _redecl; /* provider redeclared */ |
107 | } _provider; |
108 | |
109 | struct { |
110 | struct dt_node *_conditional; |
111 | struct dt_node *_body; |
112 | struct dt_node *_alternate_body; |
113 | } _conditional; |
114 | } dn_u; |
115 | |
116 | struct dt_node *dn_list; /* parse tree list link */ |
117 | struct dt_node *dn_link; /* allocation list link */ |
118 | } dt_node_t; |
119 | |
120 | #define dn_value dn_u._const._value /* DT_NODE_INT */ |
121 | #define dn_string dn_u._const._string /* STRING, IDENT, TYPE */ |
122 | #define dn_ident dn_u._nodes._ident /* VAR,SYM,FUN,AGG,INL,PROBE */ |
123 | #define dn_args dn_u._nodes._links[0] /* DT_NODE_VAR, FUNC */ |
124 | #define dn_child dn_u._nodes._links[0] /* DT_NODE_OP1 */ |
125 | #define dn_left dn_u._nodes._links[0] /* DT_NODE_OP2, OP3 */ |
126 | #define dn_right dn_u._nodes._links[1] /* DT_NODE_OP2, OP3 */ |
127 | #define dn_expr dn_u._nodes._links[2] /* DT_NODE_OP3, DEXPR */ |
128 | #define dn_aggfun dn_u._nodes._links[0] /* DT_NODE_AGG */ |
129 | #define dn_aggtup dn_u._nodes._links[1] /* DT_NODE_AGG */ |
130 | #define dn_pdescs dn_u._clause._descs /* DT_NODE_CLAUSE */ |
131 | #define dn_pred dn_u._clause._pred /* DT_NODE_CLAUSE */ |
132 | #define dn_acts dn_u._clause._acts /* DT_NODE_CLAUSE */ |
133 | #define dn_locals dn_u._clause._locals /* DT_NODE_CLAUSE */ |
134 | #define dn_ctxattr dn_u._clause._attr /* DT_NODE_CLAUSE */ |
135 | #define dn_spec dn_u._pdesc._spec /* DT_NODE_PDESC */ |
136 | #define dn_desc dn_u._pdesc._desc /* DT_NODE_PDESC */ |
137 | #define dn_membname dn_u._member._name /* DT_NODE_MEMBER */ |
138 | #define dn_membexpr dn_u._member._expr /* DT_NODE_MEMBER */ |
139 | #define dn_membxlator dn_u._member._xlator /* DT_NODE_MEMBER */ |
140 | #define dn_membid dn_u._member._id /* DT_NODE_MEMBER */ |
141 | #define dn_xlator dn_u._xlator._xlator /* DT_NODE_XLATOR */ |
142 | #define dn_xmember dn_u._xlator._xmemb /* DT_NODE_XLATOR */ |
143 | #define dn_members dn_u._xlator._membs /* DT_NODE_XLATOR */ |
144 | #define dn_provname dn_u._provider._name /* DT_NODE_PROVIDER */ |
145 | #define dn_provider dn_u._provider._pvp /* DT_NODE_PROVIDER */ |
146 | #define dn_provred dn_u._provider._redecl /* DT_NODE_PROVIDER */ |
147 | #define dn_probes dn_u._provider._probes /* DT_NODE_PROVIDER */ |
148 | |
149 | /* DT_NODE_IF: */ |
150 | #define dn_conditional dn_u._conditional._conditional |
151 | #define dn_body dn_u._conditional._body |
152 | #define dn_alternate_body dn_u._conditional._alternate_body |
153 | |
154 | #define DT_NODE_FREE 0 /* unused node (waiting to be freed) */ |
155 | #define DT_NODE_INT 1 /* integer value */ |
156 | #define DT_NODE_STRING 2 /* string value */ |
157 | #define DT_NODE_IDENT 3 /* identifier */ |
158 | #define DT_NODE_VAR 4 /* variable reference */ |
159 | #define DT_NODE_SYM 5 /* symbol reference */ |
160 | #define DT_NODE_TYPE 6 /* type reference or formal parameter */ |
161 | #define DT_NODE_FUNC 7 /* function call */ |
162 | #define DT_NODE_OP1 8 /* unary operator */ |
163 | #define DT_NODE_OP2 9 /* binary operator */ |
164 | #define DT_NODE_OP3 10 /* ternary operator */ |
165 | #define DT_NODE_DEXPR 11 /* D expression action */ |
166 | #define DT_NODE_DFUNC 12 /* D function action */ |
167 | #define DT_NODE_AGG 13 /* aggregation */ |
168 | #define DT_NODE_PDESC 14 /* probe description */ |
169 | #define DT_NODE_CLAUSE 15 /* clause definition */ |
170 | #define DT_NODE_INLINE 16 /* inline definition */ |
171 | #define DT_NODE_MEMBER 17 /* member definition */ |
172 | #define DT_NODE_XLATOR 18 /* translator definition */ |
173 | #define DT_NODE_PROBE 19 /* probe definition */ |
174 | #define DT_NODE_PROVIDER 20 /* provider definition */ |
175 | #define DT_NODE_PROG 21 /* program translation unit */ |
176 | #define DT_NODE_IF 22 /* if statement */ |
177 | |
178 | #define DT_NF_SIGNED 0x01 /* data is a signed quantity (else unsigned) */ |
179 | #define DT_NF_COOKED 0x02 /* data is a known type (else still cooking) */ |
180 | #define DT_NF_REF 0x04 /* pass by reference (array, struct, union) */ |
181 | #define DT_NF_LVALUE 0x08 /* node is an l-value according to ANSI-C */ |
182 | #define DT_NF_WRITABLE 0x10 /* node is writable (can be modified) */ |
183 | #define DT_NF_BITFIELD 0x20 /* node is an integer bitfield */ |
184 | #define DT_NF_USERLAND 0x40 /* data is a userland address */ |
185 | |
186 | #define DT_TYPE_NAMELEN 128 /* reasonable size for ctf_type_name() */ |
187 | |
188 | extern int dt_node_is_integer(const dt_node_t *); |
189 | extern int dt_node_is_float(const dt_node_t *); |
190 | extern int dt_node_is_scalar(const dt_node_t *); |
191 | extern int dt_node_is_arith(const dt_node_t *); |
192 | extern int dt_node_is_vfptr(const dt_node_t *); |
193 | extern int dt_node_is_dynamic(const dt_node_t *); |
194 | extern int dt_node_is_stack(const dt_node_t *); |
195 | extern int dt_node_is_symaddr(const dt_node_t *); |
196 | extern int dt_node_is_usymaddr(const dt_node_t *); |
197 | extern int dt_node_is_string(const dt_node_t *); |
198 | extern int dt_node_is_strcompat(const dt_node_t *); |
199 | extern int dt_node_is_pointer(const dt_node_t *); |
200 | extern int dt_node_is_void(const dt_node_t *); |
201 | extern int dt_node_is_ptrcompat(const dt_node_t *, const dt_node_t *, |
202 | ctf_file_t **, ctf_id_t *); |
203 | extern int dt_node_is_argcompat(const dt_node_t *, const dt_node_t *); |
204 | extern int dt_node_is_posconst(const dt_node_t *); |
205 | extern int dt_node_is_actfunc(const dt_node_t *); |
206 | |
207 | extern dt_node_t *dt_node_int(uintmax_t); |
208 | extern dt_node_t *dt_node_string(char *); |
209 | extern dt_node_t *dt_node_ident(char *); |
210 | extern dt_node_t *dt_node_type(dt_decl_t *); |
211 | extern dt_node_t *dt_node_vatype(void); |
212 | extern dt_node_t *dt_node_decl(void); |
213 | extern dt_node_t *dt_node_func(dt_node_t *, dt_node_t *); |
214 | extern dt_node_t *dt_node_offsetof(dt_decl_t *, char *); |
215 | extern dt_node_t *dt_node_op1(int, dt_node_t *); |
216 | extern dt_node_t *dt_node_op2(int, dt_node_t *, dt_node_t *); |
217 | extern dt_node_t *dt_node_op3(dt_node_t *, dt_node_t *, dt_node_t *); |
218 | extern dt_node_t *dt_node_statement(dt_node_t *); |
219 | extern dt_node_t *dt_node_pdesc_by_name(char *); |
220 | extern dt_node_t *dt_node_pdesc_by_id(uintmax_t); |
221 | extern dt_node_t *dt_node_clause(dt_node_t *, dt_node_t *, dt_node_t *); |
222 | extern dt_node_t *dt_node_inline(dt_node_t *); |
223 | extern dt_node_t *dt_node_member(dt_decl_t *, char *, dt_node_t *); |
224 | extern dt_node_t *dt_node_xlator(dt_decl_t *, dt_decl_t *, char *, dt_node_t *); |
225 | extern dt_node_t *dt_node_probe(char *, int, dt_node_t *, dt_node_t *); |
226 | extern dt_node_t *dt_node_provider(char *, dt_node_t *); |
227 | extern dt_node_t *dt_node_program(dt_node_t *); |
228 | extern dt_node_t *dt_node_if(dt_node_t *, dt_node_t *, dt_node_t *); |
229 | |
230 | extern dt_node_t *dt_node_link(dt_node_t *, dt_node_t *); |
231 | extern dt_node_t *dt_node_cook(dt_node_t *, uint_t); |
232 | |
233 | extern dt_node_t *dt_node_xalloc(dtrace_hdl_t *, int); |
234 | extern void dt_node_free(dt_node_t *); |
235 | |
236 | extern dtrace_attribute_t dt_node_list_cook(dt_node_t **, uint_t); |
237 | extern void dt_node_list_free(dt_node_t **); |
238 | extern void dt_node_link_free(dt_node_t **); |
239 | |
240 | extern void dt_node_attr_assign(dt_node_t *, dtrace_attribute_t); |
241 | extern void dt_node_type_assign(dt_node_t *, ctf_file_t *, ctf_id_t, boolean_t); |
242 | extern void dt_node_type_propagate(const dt_node_t *, dt_node_t *); |
243 | extern const char *dt_node_type_name(const dt_node_t *, char *, size_t); |
244 | extern size_t dt_node_type_size(const dt_node_t *); |
245 | |
246 | extern dt_ident_t *dt_node_resolve(const dt_node_t *, uint_t); |
247 | extern size_t dt_node_sizeof(const dt_node_t *); |
248 | extern void dt_node_promote(dt_node_t *, dt_node_t *, dt_node_t *); |
249 | |
250 | extern void dt_node_diftype(dtrace_hdl_t *, |
251 | const dt_node_t *, dtrace_diftype_t *); |
252 | extern void dt_node_printr(dt_node_t *, FILE *, int); |
253 | extern void dt_printd(dt_node_t *, FILE *, int); |
254 | extern const char *dt_node_name(const dt_node_t *, char *, size_t); |
255 | extern int dt_node_root(dt_node_t *); |
256 | |
257 | struct dtrace_typeinfo; /* see <dtrace.h> */ |
258 | struct dt_pcb; /* see <dt_impl.h> */ |
259 | |
260 | #define IS_CHAR(e) \ |
261 | (((e).cte_format & (CTF_INT_CHAR | CTF_INT_SIGNED)) == \ |
262 | (CTF_INT_CHAR | CTF_INT_SIGNED) && (e).cte_bits == NBBY) |
263 | |
264 | #define IS_VOID(e) \ |
265 | ((e).cte_offset == 0 && (e).cte_bits == 0) |
266 | |
267 | extern int dt_type_lookup(const char *, struct dtrace_typeinfo *); |
268 | extern int dt_type_pointer(struct dtrace_typeinfo *); |
269 | extern const char *dt_type_name(ctf_file_t *, ctf_id_t, char *, size_t); |
270 | |
271 | typedef enum { |
272 | YYS_CLAUSE, /* lex/yacc state for finding program clauses */ |
273 | YYS_DEFINE, /* lex/yacc state for parsing persistent definitions */ |
274 | YYS_EXPR, /* lex/yacc state for parsing D expressions */ |
275 | YYS_DONE, /* lex/yacc state for indicating parse tree is done */ |
276 | YYS_CONTROL /* lex/yacc state for parsing control lines */ |
277 | } yystate_t; |
278 | |
279 | extern void dnerror(const dt_node_t *, dt_errtag_t, const char *, ...) |
280 | __printflike(3, 4) __dead; |
281 | extern void dnwarn(const dt_node_t *, dt_errtag_t, const char *, ...) |
282 | __printflike(3, 4); |
283 | |
284 | extern void xyerror(dt_errtag_t, const char *, ...) __printflike(2, 3) |
285 | __dead; |
286 | extern void xywarn(dt_errtag_t, const char *, ...) __printflike(2, 3); |
287 | extern void xyvwarn(dt_errtag_t, const char *, va_list) __printflike(2, 0); |
288 | |
289 | extern void yyerror(const char *, ...) __printflike(1, 2) __dead; |
290 | extern void yywarn(const char *, ...) __printflike(1, 2); |
291 | extern void yyvwarn(const char *, va_list) __printflike(1, 0); |
292 | |
293 | extern void yylabel(const char *); |
294 | extern void yybegin(yystate_t); |
295 | extern void yyinit(struct dt_pcb *); |
296 | |
297 | extern int yyparse(void); |
298 | extern int yyinput(void); |
299 | |
300 | #ifdef __cplusplus |
301 | } |
302 | #endif |
303 | |
304 | #endif /* _DT_PARSER_H */ |
305 | |