2 // Copyright (C) 2005-2011 Red Hat Inc.
4 // This file is part of systemtap, and is free software. You can
5 // redistribute it and/or modify it under the terms of the GNU General
6 // Public License (GPL); either version 2, or (at your option) any
23 #include <elfutils/libdw.h>
27 // ------------------------------------------------------------------------
32 struct symresolution_info
: public traversing_visitor
35 systemtap_session
& session
;
38 functiondecl
* current_function
;
39 derived_probe
* current_probe
;
40 symresolution_info (systemtap_session
& s
);
42 vardecl
* find_var (const std::string
& name
, int arity
, const token
*tok
);
43 functiondecl
* find_function (const std::string
& name
, unsigned arity
);
45 void visit_block (block
*s
);
46 void visit_symbol (symbol
* e
);
47 void visit_foreach_loop (foreach_loop
* e
);
48 void visit_arrayindex (arrayindex
* e
);
49 void visit_functioncall (functioncall
* e
);
50 void visit_delete_statement (delete_statement
* s
);
54 struct typeresolution_info
: public visitor
56 typeresolution_info (systemtap_session
& s
);
57 systemtap_session
& session
;
58 unsigned num_newly_resolved
;
59 unsigned num_still_unresolved
;
60 bool assert_resolvability
;
61 functiondecl
* current_function
;
62 derived_probe
* current_probe
;
63 std::vector
<const token
*> resolved_toks
; // account for type mis-
64 std::vector
<const token
*> printed_toks
; // matches (BZ 9719)
66 void check_arg_type (exp_type wanted
, expression
* arg
);
67 void check_local (vardecl
* v
);
68 void mismatch (const token
* tok
, exp_type t1
, exp_type t2
);
69 void unresolved (const token
* tok
);
70 void resolved (const token
* tok
, exp_type t
);
71 void invalid (const token
* tok
, exp_type t
);
73 exp_type t
; // implicit parameter for nested visit call; may clobber
75 void visit_block (block
* s
);
76 void visit_try_block (try_block
* s
);
77 void visit_embeddedcode (embeddedcode
* s
);
78 void visit_null_statement (null_statement
* s
);
79 void visit_expr_statement (expr_statement
* s
);
80 void visit_if_statement (if_statement
* s
);
81 void visit_for_loop (for_loop
* s
);
82 void visit_foreach_loop (foreach_loop
* s
);
83 void visit_return_statement (return_statement
* s
);
84 void visit_delete_statement (delete_statement
* s
);
85 void visit_next_statement (next_statement
* s
);
86 void visit_break_statement (break_statement
* s
);
87 void visit_continue_statement (continue_statement
* s
);
88 void visit_literal_string (literal_string
* e
);
89 void visit_literal_number (literal_number
* e
);
90 void visit_embedded_expr (embedded_expr
* e
);
91 void visit_binary_expression (binary_expression
* e
);
92 void visit_unary_expression (unary_expression
* e
);
93 void visit_pre_crement (pre_crement
* e
);
94 void visit_post_crement (post_crement
* e
);
95 void visit_logical_or_expr (logical_or_expr
* e
);
96 void visit_logical_and_expr (logical_and_expr
* e
);
97 void visit_array_in (array_in
* e
);
98 void visit_comparison (comparison
* e
);
99 void visit_concatenation (concatenation
* e
);
100 void visit_ternary_expression (ternary_expression
* e
);
101 void visit_assignment (assignment
* e
);
102 void visit_symbol (symbol
* e
);
103 void visit_target_symbol (target_symbol
* e
);
104 void visit_arrayindex (arrayindex
* e
);
105 void visit_functioncall (functioncall
* e
);
106 void visit_print_format (print_format
* e
);
107 void visit_stat_op (stat_op
* e
);
108 void visit_hist_op (hist_op
* e
);
109 void visit_cast_op (cast_op
* e
);
110 void visit_defined_op (defined_op
* e
);
111 void visit_entry_op (entry_op
* e
);
115 // ------------------------------------------------------------------------
118 // A derived_probe is a probe that has been elaborated by
119 // binding to a matching provider. The locations std::vector
120 // may be smaller or larger than the base probe, since a
121 // provider may transform it.
123 class translator_output
;
124 class derived_probe_group
;
126 struct derived_probe
: public probe
128 derived_probe (probe
* b
, probe_point
* l
, bool rewrite_loc
=false);
129 probe
* base
; // the original parsed probe
130 probe_point
* base_pp
; // the probe_point that led to this derivation
131 virtual const probe
* basest () const { return base
->basest(); }
132 virtual const probe
* almost_basest () const { return base
->almost_basest() ?: this; }
133 virtual ~derived_probe () {}
134 virtual void join_group (systemtap_session
& s
) = 0;
135 virtual probe_point
* sole_location () const;
136 virtual probe_point
* script_location () const;
137 virtual void printsig (std::ostream
&o
) const;
138 // return arguments of probe if there
139 virtual void getargs (std::list
<std::string
> &) const {}
140 void printsig_nested (std::ostream
&o
) const;
141 virtual void collect_derivation_chain (std::vector
<probe
*> &probes_list
);
142 virtual void collect_derivation_pp_chain (std::vector
<probe_point
*> &pp_list
);
143 std::string
derived_locations ();
145 virtual void print_dupe_stamp(std::ostream
&) {}
146 // To aid duplication elimination, print a stamp which uniquely identifies
147 // the code that will be added to the probe body. (Doesn't need to be the
150 virtual void initialize_probe_context_vars (translator_output
*) {}
151 // From within unparser::emit_probe, initialized any extra variables
152 // in this probe's context locals.
154 virtual void emit_probe_local_init (translator_output
*) {}
155 // From within unparser::emit_probe, emit any extra processing block
158 virtual void emit_privilege_assertion (translator_output
*);
159 // From within unparser::emit_probe, emit any unprivileged mode
160 // checking for this probe.
163 static void emit_common_header (translator_output
* o
);
164 // from c_unparser::emit_common_header
165 // XXX: probably can move this stuff to a probe_group::emit_module_decls
167 static void emit_process_owner_assertion (translator_output
*);
168 // From within unparser::emit_probe, emit a check that the current
169 // process belongs to the user.
171 static void print_dupe_stamp_unprivileged(std::ostream
& o
);
172 static void print_dupe_stamp_unprivileged_process_owner(std::ostream
& o
);
174 virtual bool needs_global_locks () { return true; }
175 // by default, probes need locks around global variables
177 // Location of semaphores to activate sdt probes
178 Dwarf_Addr sdt_semaphore_addr
;
180 // index into session.probes[], set and used during translation
181 unsigned session_index
;
184 // ------------------------------------------------------------------------
188 // Various derived classes derived_probe_group manage the
189 // registration/invocation/unregistration of sibling probes.
190 struct derived_probe_group
192 virtual ~derived_probe_group () {}
194 virtual void emit_module_decls (systemtap_session
& s
) = 0;
195 // The _decls-generated code may assume that declarations such as
196 // the context, embedded-C code, function and probe handler bodies
197 // are all already generated. That is, _decls is called near the
198 // end of the code generation process. It should minimize the
199 // number of separate variables (and to a lesser extent, their
202 virtual void emit_module_init (systemtap_session
& s
) = 0;
203 // The _init-generated code may assume that it is called only once.
204 // If that code fails at run time, it must set rc=1 and roll back
205 // any partial initializations, for its _exit friend will NOT be
206 // invoked. The generated code may use pre-declared "int i, j;"
207 // and set "const char* probe_point;".
209 virtual void emit_module_refresh (systemtap_session
& s
) {}
210 // The _refresh-generated code may be called multiple times during
211 // a session run, bracketed by _init and _exit calls.
212 // Upon failure, it must set enough state so that
213 // a subsequent _exit call will clean up everything.
214 // The generated code may use pre-declared "int i, j;".
216 virtual void emit_module_exit (systemtap_session
& s
) = 0;
217 // The _exit-generated code may assume that it is executed exactly
218 // zero times (if the _init-generated code failed) or once. (_exit
219 // itself may be called a few times, to generate the code in a few
220 // different places in the probe module.)
221 // The generated code may use pre-declared "int i, j;".
225 // ------------------------------------------------------------------------
227 typedef std::map
<std::string
, literal
*> literal_map_t
;
229 struct derived_probe_builder
231 virtual void build(systemtap_session
& sess
,
233 probe_point
* location
,
234 literal_map_t
const & parameters
,
235 std::vector
<derived_probe
*> & finished_results
) = 0;
236 virtual ~derived_probe_builder() {}
237 virtual void build_no_more (systemtap_session
&) {}
238 virtual bool is_alias () const { return false; }
240 static bool has_null_param (literal_map_t
const & parameters
,
241 const std::string
& key
);
242 static bool get_param (literal_map_t
const & parameters
,
243 const std::string
& key
, std::string
& value
);
244 static bool get_param (literal_map_t
const & parameters
,
245 const std::string
& key
, int64_t& value
);
254 exp_type parameter_type
;
256 match_key(std::string
const & n
);
257 match_key(probe_point::component
const & c
);
259 match_key
& with_number();
260 match_key
& with_string();
261 std::string
str() const;
262 bool operator<(match_key
const & other
) const;
263 bool globmatch(match_key
const & other
) const;
270 typedef std::map
<match_key
, match_node
*> sub_map_t
;
271 typedef std::map
<match_key
, match_node
*>::iterator sub_map_iterator_t
;
273 std::vector
<derived_probe_builder
*> ends
;
278 void find_and_build (systemtap_session
& s
,
279 probe
* p
, probe_point
*loc
, unsigned pos
,
280 std::vector
<derived_probe
*>& results
);
281 void build_no_more (systemtap_session
&s
);
282 void dump (systemtap_session
&s
, const std::string
&name
= "");
284 match_node
* bind(match_key
const & k
);
285 match_node
* bind(std::string
const & k
);
286 match_node
* bind_str(std::string
const & k
);
287 match_node
* bind_num(std::string
const & k
);
288 match_node
* bind_privilege(privilege_t p
= pr_stapdev
);
289 void bind(derived_probe_builder
* e
);
292 privilege_t privilege
;
295 // ------------------------------------------------------------------------
298 alias_expansion_builder
299 : public derived_probe_builder
303 alias_expansion_builder(probe_alias
* a
)
307 virtual void build(systemtap_session
& sess
,
309 probe_point
* location
,
310 std::map
<std::string
, literal
*> const &,
311 std::vector
<derived_probe
*> & finished_results
);
312 virtual bool is_alias () const { return true; }
314 bool checkForRecursiveExpansion (probe
*use
);
317 // ------------------------------------------------------------------------
319 /* struct systemtap_session moved to session.h */
321 int semantic_pass (systemtap_session
& s
);
322 void derive_probes (systemtap_session
& s
,
323 probe
*p
, std::vector
<derived_probe
*>& dps
,
324 bool optional
= false);
326 // A helper we use here and in translate, for pulling symbols out of lvalue
328 symbol
* get_symbol_within_expression (expression
*e
);
334 #endif // ELABORATE_H
336 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */