]> sourceware.org Git - systemtap.git/blob - elaborate.cxx
systemtap.bpf/asm_tests :: fix documentation / expected result
[systemtap.git] / elaborate.cxx
1 // elaboration functions
2 // Copyright (C) 2005-2018 Red Hat Inc.
3 // Copyright (C) 2008 Intel Corporation
4 //
5 // This file is part of systemtap, and is free software. You can
6 // redistribute it and/or modify it under the terms of the GNU General
7 // Public License (GPL); either version 2, or (at your option) any
8 // later version.
9
10 #include "config.h"
11 #include "elaborate.h"
12 #include "translate.h"
13 #include "parse.h"
14 #include "tapsets.h"
15 #include "session.h"
16 #include "util.h"
17 #include "task_finder.h"
18 #include "stapregex.h"
19 #include "stringtable.h"
20
21 extern "C" {
22 #include <sys/utsname.h>
23 #include <fnmatch.h>
24 #define __STDC_FORMAT_MACROS
25 #include <inttypes.h>
26 }
27
28 #include <algorithm>
29 #include <fstream>
30 #include <map>
31 #include <cassert>
32 #include <set>
33 #include <vector>
34 #include <algorithm>
35 #include <iterator>
36 #include <climits>
37
38
39 using namespace std;
40
41
42 // ------------------------------------------------------------------------
43
44 // Used in probe_point condition construction. Either argument may be
45 // NULL; if both, return NULL too. Resulting expression is a deep
46 // copy for symbol resolution purposes.
47 expression* add_condition (expression* a, expression* b)
48 {
49 if (!a && !b) return 0;
50 if (! a) return deep_copy_visitor::deep_copy(b);
51 if (! b) return deep_copy_visitor::deep_copy(a);
52 logical_and_expr la;
53 la.op = "&&";
54 la.left = a;
55 la.right = b;
56 la.tok = a->tok; // or could be b->tok
57 return deep_copy_visitor::deep_copy(& la);
58 }
59
60 // ------------------------------------------------------------------------
61
62
63
64 derived_probe::derived_probe (probe *p, probe_point *l, bool rewrite_loc):
65 base (p), base_pp(l), group(NULL), sdt_semaphore_addr(0),
66 session_index((unsigned)-1)
67 {
68 assert (p);
69 this->tok = p->tok;
70 this->privileged = p->privileged;
71 this->synthetic = p->synthetic;
72 this->body = deep_copy_visitor::deep_copy(p->body);
73
74 assert (l);
75 // make a copy for subclasses which want to rewrite the location
76 if (rewrite_loc)
77 l = new probe_point(*l);
78 this->locations.push_back (l);
79 }
80
81
82 void
83 derived_probe::printsig (ostream& o) const
84 {
85 probe::printsig (o);
86 printsig_nested (o);
87 }
88
89 void
90 derived_probe::printsig_nested (ostream& o) const
91 {
92 // We'd like to enclose the probe derivation chain in a /* */
93 // comment delimiter. But just printing /* base->printsig() */ is
94 // not enough, since base might itself be a derived_probe. So we,
95 // er, "cleverly" encode our nesting state as a formatting flag for
96 // the ostream.
97 ios::fmtflags f = o.flags (ios::internal);
98 if (f & ios::internal)
99 {
100 // already nested
101 o << " <- ";
102 base->printsig (o);
103 }
104 else
105 {
106 // outermost nesting
107 o << " /* <- ";
108 base->printsig (o);
109 o << " */";
110 }
111 // restore flags
112 (void) o.flags (f);
113 }
114
115
116 void
117 derived_probe::collect_derivation_chain (std::vector<probe*> &probes_list) const
118 {
119 probes_list.push_back(const_cast<derived_probe*>(this));
120 base->collect_derivation_chain(probes_list);
121 }
122
123
124 void
125 derived_probe::collect_derivation_pp_chain (std::vector<probe_point*> &pp_list) const
126 {
127 pp_list.push_back(const_cast<probe_point*>(this->sole_location()));
128 base->collect_derivation_pp_chain(pp_list);
129 }
130
131
132 string
133 derived_probe::derived_locations (bool firstFrom)
134 {
135 ostringstream o;
136 vector<probe_point*> reference_point;
137 collect_derivation_pp_chain(reference_point);
138 if (reference_point.size() > 0)
139 for(unsigned i=1; i<reference_point.size(); ++i)
140 {
141 if (firstFrom || i>1)
142 o << " from: ";
143 o << reference_point[i]->str(false); // no ?,!,etc
144 }
145 return o.str();
146 }
147
148
149 probe_point*
150 derived_probe::sole_location () const
151 {
152 if (locations.size() == 0 || locations.size() > 1)
153 throw SEMANTIC_ERROR (_N("derived_probe with no locations",
154 "derived_probe with too many locations",
155 locations.size()), this->tok);
156 else
157 return locations[0];
158 }
159
160
161 probe_point*
162 derived_probe::script_location () const
163 {
164 // This feeds function::pn() in the tapset, which is documented as the
165 // script-level probe point expression, *after wildcard expansion*.
166 vector<probe_point*> chain;
167 collect_derivation_pp_chain (chain);
168
169 // Go backwards until we hit the first well-formed probe point
170 for (int i=chain.size()-1; i>=0; i--)
171 if (chain[i]->well_formed)
172 return chain[i];
173
174 // If that didn't work, just fallback to -something-.
175 return sole_location();
176 }
177
178
179 void
180 derived_probe::emit_privilege_assertion (translator_output* o)
181 {
182 // Emit code which will cause compilation to fail if it is compiled in
183 // unprivileged mode.
184 o->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
185 o->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
186 o->newline() << "#error Internal Error: Probe ";
187 probe::printsig (o->line());
188 o->line() << " generated in --unprivileged mode";
189 o->newline() << "#endif";
190 }
191
192
193 void
194 derived_probe::emit_process_owner_assertion (translator_output* o)
195 {
196 // Emit code which will abort should the current target not belong to the
197 // user in unprivileged mode.
198 o->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
199 o->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
200 o->newline(1) << "if (! is_myproc ()) {";
201 o->newline(1) << "snprintf(c->error_buffer, sizeof(c->error_buffer),";
202 o->newline() << " \"Internal Error: Process %d does not belong to user %d in probe %s in --unprivileged mode\",";
203 o->newline() << " current->tgid, _stp_uid, c->probe_point);";
204 o->newline() << "c->last_error = c->error_buffer;";
205 // NB: since this check occurs before probe locking, its exit should
206 // not be a "goto out", which would attempt unlocking.
207 o->newline() << "return;";
208 o->newline(-1) << "}";
209 o->newline(-1) << "#endif";
210 }
211
212 void
213 derived_probe::print_dupe_stamp_unprivileged(ostream& o)
214 {
215 o << _("unprivileged users: authorized") << endl;
216 }
217
218 void
219 derived_probe::print_dupe_stamp_unprivileged_process_owner(ostream& o)
220 {
221 o << _("unprivileged users: authorized for process owner") << endl;
222 }
223
224 // ------------------------------------------------------------------------
225 // Members of derived_probe_builder
226
227 void
228 derived_probe_builder::build_with_suffix(systemtap_session &,
229 probe *,
230 probe_point *,
231 literal_map_t const &,
232 std::vector<derived_probe *> &,
233 std::vector<probe_point::component *>
234 const &) {
235 // XXX perhaps build the probe if suffix is empty?
236 // if (suffix.empty()) {
237 // build (sess, use, location, parameters, finished_results);
238 // return;
239 // }
240 throw SEMANTIC_ERROR (_("invalid suffix for probe"));
241 }
242
243 bool
244 derived_probe_builder::get_param (literal_map_t const & params,
245 interned_string key,
246 interned_string& value)
247 {
248 literal_map_t::const_iterator i = params.find (key);
249 if (i == params.end())
250 return false;
251 literal_string * ls = dynamic_cast<literal_string *>(i->second);
252 if (!ls)
253 return false;
254 value = ls->value;
255 return true;
256 }
257
258
259 bool
260 derived_probe_builder::get_param (literal_map_t const & params,
261 interned_string key,
262 int64_t& value)
263 {
264 literal_map_t::const_iterator i = params.find (key);
265 if (i == params.end())
266 return false;
267 if (i->second == NULL)
268 return false;
269 literal_number * ln = dynamic_cast<literal_number *>(i->second);
270 if (!ln)
271 return false;
272 value = ln->value;
273 return true;
274 }
275
276
277 bool
278 derived_probe_builder::has_null_param (literal_map_t const & params,
279 interned_string key)
280 {
281 literal_map_t::const_iterator i = params.find(key);
282 return (i != params.end() && i->second == NULL);
283 }
284
285 bool
286 derived_probe_builder::has_param (literal_map_t const & params,
287 interned_string key)
288 {
289 return (params.find(key) != params.end());
290 }
291
292 // ------------------------------------------------------------------------
293 // Members of match_key.
294
295 match_key::match_key(interned_string n)
296 : name(n),
297 have_parameter(false),
298 parameter_type(pe_unknown)
299 {
300 }
301
302 match_key::match_key(probe_point::component const & c)
303 : name(c.functor),
304 have_parameter(c.arg != NULL),
305 parameter_type(c.arg ? c.arg->type : pe_unknown)
306 {
307 }
308
309 match_key &
310 match_key::with_number()
311 {
312 have_parameter = true;
313 parameter_type = pe_long;
314 return *this;
315 }
316
317 match_key &
318 match_key::with_string()
319 {
320 have_parameter = true;
321 parameter_type = pe_string;
322 return *this;
323 }
324
325 string
326 match_key::str() const
327 {
328 string n = name;
329 if (have_parameter)
330 switch (parameter_type)
331 {
332 case pe_string: return n + "(string)";
333 case pe_long: return n + "(number)";
334 default: return n + "(...)";
335 }
336 return n;
337 }
338
339 bool
340 match_key::operator<(match_key const & other) const
341 {
342 return ((name < other.name)
343
344 || (name == other.name
345 && have_parameter < other.have_parameter)
346
347 || (name == other.name
348 && have_parameter == other.have_parameter
349 && parameter_type < other.parameter_type));
350 }
351
352
353 // NB: these are only used in the probe point name components, where
354 // only "*" is permitted.
355 //
356 // Within module("bar"), function("foo"), process("baz") strings, real
357 // wildcards are permitted too. See also util.h:contains_glob_chars
358
359 static bool
360 isglob(interned_string str)
361 {
362 return(str.find('*') != str.npos);
363 }
364
365 static bool
366 isdoubleglob(interned_string str)
367 {
368 return(str.find("**") != str.npos);
369 }
370
371 bool
372 match_key::globmatch(match_key const & other) const
373 {
374 const string & name_str = name;
375 const string & other_str = other.name;
376
377 return ((fnmatch(name_str.c_str(), other_str.c_str(), FNM_NOESCAPE) == 0)
378 && have_parameter == other.have_parameter
379 && parameter_type == other.parameter_type);
380 }
381
382 // ------------------------------------------------------------------------
383 // Members of match_node
384 // ------------------------------------------------------------------------
385
386 match_node::match_node() :
387 privilege(privilege_t (pr_stapdev | pr_stapsys))
388 {
389 }
390
391 match_node *
392 match_node::bind(match_key const & k)
393 {
394 if (k.name == "*")
395 throw SEMANTIC_ERROR(_("invalid use of wildcard probe point component"));
396
397 map<match_key, match_node *>::const_iterator i = sub.find(k);
398 if (i != sub.end())
399 return i->second;
400 match_node * n = new match_node();
401 sub.insert(make_pair(k, n));
402 return n;
403 }
404
405 void
406 match_node::bind(derived_probe_builder * e)
407 {
408 ends.push_back (e);
409 }
410
411 match_node *
412 match_node::bind(interned_string k)
413 {
414 return bind(match_key(k));
415 }
416
417 match_node *
418 match_node::bind_str(string const & k)
419 {
420 return bind(match_key(k).with_string());
421 }
422
423 match_node *
424 match_node::bind_num(string const & k)
425 {
426 return bind(match_key(k).with_number());
427 }
428
429 match_node *
430 match_node::bind_privilege(privilege_t p)
431 {
432 privilege = p;
433 return this;
434 }
435
436 void
437 match_node::find_and_build (systemtap_session& s,
438 probe* p, probe_point *loc, unsigned pos,
439 vector<derived_probe *>& results,
440 set<string>& builders)
441 {
442 save_and_restore<unsigned> costly(& s.suppress_costly_diagnostics,
443 s.suppress_costly_diagnostics + (loc->optional || loc->sufficient ? 1 : 0));
444
445 assert (pos <= loc->components.size());
446 if (pos == loc->components.size()) // matched all probe point components so far
447 {
448 if (ends.empty())
449 {
450 string alternatives;
451 for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
452 alternatives += string(" ") + i->first.str();
453
454 throw SEMANTIC_ERROR (_F("probe point truncated (follow: %s)",
455 alternatives.c_str()),
456 loc->components.back()->tok);
457 }
458
459 if (! pr_contains (privilege, s.privilege))
460 {
461 throw SEMANTIC_ERROR (_F("probe point is not allowed for --privilege=%s",
462 pr_name (s.privilege)),
463 loc->components.back()->tok);
464 }
465
466 literal_map_t param_map;
467 for (unsigned i=0; i<pos; i++)
468 param_map[loc->components[i]->functor] = loc->components[i]->arg;
469 // maybe 0
470
471 unsigned int num_results = results.size();
472
473 // Iterate over all bound builders
474 for (unsigned k=0; k<ends.size(); k++)
475 {
476 derived_probe_builder *b = ends[k];
477 b->build (s, p, loc, param_map, results);
478 }
479
480 // Collect names of builders attempted for error reporting
481 if (results.size() == num_results)
482 {
483 for (unsigned k=0; k<ends.size(); k++)
484 builders.insert(ends[k]->name());
485 }
486 }
487 else if (isdoubleglob(loc->components[pos]->functor)) // ** wildcard?
488 {
489 unsigned int num_results = results.size();
490
491 // When faced with "foo**bar", we try "foo*bar" and "foo*.**bar"
492
493 const probe_point::component *comp = loc->components[pos];
494 string functor = comp->functor;
495 size_t glob_start = functor.find("**");
496 size_t glob_end = functor.find_first_not_of('*', glob_start);
497 string prefix = functor.substr(0, glob_start);
498 string suffix = ((glob_end != string::npos) ?
499 functor.substr(glob_end) : "");
500
501 // Synthesize "foo*bar"
502 probe_point *simple_pp = new probe_point(*loc);
503 probe_point::component *simple_comp = new probe_point::component(*comp);
504 simple_comp->functor = prefix + "*" + suffix;
505 simple_comp->from_glob = true;
506 simple_pp->components[pos] = simple_comp;
507 try
508 {
509 find_and_build (s, p, simple_pp, pos, results, builders);
510 }
511 catch (const semantic_error& e)
512 {
513 // Ignore semantic_errors.
514 }
515
516 // Cleanup if we didn't find anything
517 if (results.size() == num_results)
518 {
519 delete simple_pp;
520 delete simple_comp;
521 }
522
523 num_results = results.size();
524
525 // Synthesize "foo*.**bar"
526 // NB: any component arg should attach to the latter part only
527 probe_point *expanded_pp = new probe_point(*loc);
528 probe_point::component *expanded_comp_pre = new probe_point::component(*comp);
529 expanded_comp_pre->functor = prefix + "*";
530 expanded_comp_pre->from_glob = true;
531 expanded_comp_pre->arg = NULL;
532 probe_point::component *expanded_comp_post = new probe_point::component(*comp);
533 expanded_comp_post->functor = string("**") + suffix;
534 expanded_pp->components[pos] = expanded_comp_pre;
535 expanded_pp->components.insert(expanded_pp->components.begin() + pos + 1,
536 expanded_comp_post);
537 try
538 {
539 find_and_build (s, p, expanded_pp, pos, results, builders);
540 }
541 catch (const semantic_error& e)
542 {
543 // Ignore semantic_errors.
544 }
545
546 // Cleanup if we didn't find anything
547 if (results.size() == num_results)
548 {
549 delete expanded_pp;
550 delete expanded_comp_pre;
551 delete expanded_comp_post;
552 }
553
554 // Try suffix expansion only if no matches found:
555 if (num_results == results.size())
556 this->try_suffix_expansion (s, p, loc, pos, results);
557
558 if (! loc->optional && num_results == results.size())
559 {
560 // We didn't find any wildcard matches (since the size of
561 // the result vector didn't change). Throw an error.
562 string sugs = suggest_functors(s, functor);
563 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
564 sugs.empty() ? "" : (" (similar: " + sugs + ")").c_str()),
565 comp->tok);
566 }
567 }
568 else if (isglob(loc->components[pos]->functor)) // wildcard?
569 {
570 match_key match (* loc->components[pos]);
571
572 // Call find_and_build for each possible match. Ignore errors -
573 // unless we don't find any match.
574 unsigned int num_results = results.size();
575 for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
576 {
577 const match_key& subkey = i->first;
578 match_node* subnode = i->second;
579
580 assert_no_interrupts();
581
582 if (match.globmatch(subkey))
583 {
584 if (s.verbose > 2)
585 clog << _F("wildcard '%s' matched '%s'",
586 loc->components[pos]->functor.to_string().c_str(),
587 subkey.name.to_string().c_str()) << endl;
588
589 // When we have a wildcard, we need to create a copy of
590 // the probe point. Then we'll create a copy of the
591 // wildcard component, and substitute the non-wildcard
592 // functor.
593 probe_point *non_wildcard_pp = new probe_point(*loc);
594 probe_point::component *non_wildcard_component
595 = new probe_point::component(*loc->components[pos]);
596 non_wildcard_component->functor = subkey.name;
597 non_wildcard_component->from_glob = true;
598 non_wildcard_pp->components[pos] = non_wildcard_component;
599
600 // NB: probe conditions are not attached at the wildcard
601 // (component/functor) level, but at the overall
602 // probe_point level.
603
604 unsigned int inner_results = results.size();
605
606 // recurse (with the non-wildcard probe point)
607 try
608 {
609 subnode->find_and_build (s, p, non_wildcard_pp, pos+1,
610 results, builders);
611 }
612 catch (const semantic_error& e)
613 {
614 // Ignore semantic_errors while expanding wildcards.
615 // If we get done and nothing was expanded, the code
616 // following the loop will complain.
617 }
618
619 if (results.size() == inner_results)
620 {
621 // If this wildcard didn't match, cleanup.
622 delete non_wildcard_pp;
623 delete non_wildcard_component;
624 }
625 }
626 }
627
628 // Try suffix expansion only if no matches found:
629 if (num_results == results.size())
630 this->try_suffix_expansion (s, p, loc, pos, results);
631
632 if (! loc->optional && num_results == results.size())
633 {
634 // We didn't find any wildcard matches (since the size of
635 // the result vector didn't change). Throw an error.
636 string sugs = suggest_functors(s, loc->components[pos]->functor);
637 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
638 sugs.empty() ? "" : (" (similar: " + sugs + ")").c_str()),
639 loc->components[pos]->tok);
640 }
641 }
642 else
643 {
644 match_key match (* loc->components[pos]);
645 sub_map_iterator_t i = sub.find (match);
646
647 if (i != sub.end()) // match found
648 {
649 match_node* subnode = i->second;
650 // recurse
651 subnode->find_and_build (s, p, loc, pos+1, results, builders);
652 return;
653 }
654
655 unsigned int num_results = results.size();
656 this->try_suffix_expansion (s, p, loc, pos, results);
657
658 // XXX: how to correctly report alternatives + position numbers
659 // for alias suffixes? file a separate PR to address the issue
660 if (! loc->optional && num_results == results.size())
661 {
662 // We didn't find any alias suffixes (since the size of the
663 // result vector didn't change). Throw an error.
664 string sugs = suggest_functors(s, loc->components[pos]->functor);
665 throw SEMANTIC_ERROR (_F("probe point mismatch%s",
666 sugs.empty() ? "" : (" (similar: " + sugs + ")").c_str()),
667 loc->components[pos]->tok);
668 }
669 }
670 }
671
672 string
673 match_node::suggest_functors(systemtap_session& s, string functor)
674 {
675 // only use prefix if globby (and prefix is non-empty)
676 size_t glob = functor.find('*');
677 if (glob != string::npos && glob != 0)
678 functor.erase(glob);
679 if (functor.empty())
680 return "";
681
682 // PR18577: There isn't any point in generating a suggestion list if
683 // we're not going to display it.
684 if ((s.dump_mode == systemtap_session::dump_matched_probes
685 || s.dump_mode == systemtap_session::dump_matched_probes_vars)
686 && s.verbose < 2)
687 return "";
688
689 set<string> functors;
690 for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
691 {
692 string ftor = i->first.str();
693 if (ftor.find('(') != string::npos) // trim any parameter
694 ftor.erase(ftor.find('('));
695 functors.insert(ftor);
696 }
697 return levenshtein_suggest(functor, functors, 5); // print top 5
698 }
699
700 void
701 match_node::try_suffix_expansion (systemtap_session& s,
702 probe *p, probe_point *loc, unsigned pos,
703 vector<derived_probe *>& results)
704 {
705 // PR12210: match alias suffixes. If the components thus far
706 // have been matched, but there is an additional unknown
707 // suffix, we have a potential alias suffix on our hands. We
708 // need to expand the preceding components as probe aliases,
709 // reattach the suffix, and re-run derive_probes() on the
710 // resulting expansion. This is done by the routine
711 // build_with_suffix().
712
713 if (strverscmp(s.compatible.c_str(), "2.0") >= 0)
714 {
715 // XXX: technically, param_map isn't used here. So don't
716 // bother actually assembling it unless some
717 // derived_probe_builder appears that actually takes
718 // suffixes *and* consults parameters (currently no such
719 // builders exist).
720 literal_map_t param_map;
721 // for (unsigned i=0; i<pos; i++)
722 // param_map[loc->components[i]->functor] = loc->components[i]->arg;
723 // maybe 0
724
725 vector<probe_point::component *> suffix (loc->components.begin()+pos,
726 loc->components.end());
727
728 // Multiple derived_probe_builders may be bound at a
729 // match_node due to the possibility of multiply defined
730 // aliases.
731 for (unsigned k=0; k < ends.size(); k++)
732 {
733 derived_probe_builder *b = ends[k];
734 try
735 {
736 b->build_with_suffix (s, p, loc, param_map, results, suffix);
737 }
738 catch (const recursive_expansion_error &e)
739 {
740 // Re-throw:
741 throw semantic_error(e);
742 }
743 catch (const semantic_error &e)
744 {
745 // Adjust source coordinate and re-throw:
746 if (! loc->optional)
747 throw semantic_error(e.errsrc, e.what(), loc->components[pos]->tok);
748 }
749 }
750 }
751 }
752
753
754 void
755 match_node::build_no_more (systemtap_session& s)
756 {
757 for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
758 i->second->build_no_more (s);
759 for (unsigned k=0; k<ends.size(); k++)
760 {
761 derived_probe_builder *b = ends[k];
762 b->build_no_more (s);
763 }
764 }
765
766 void
767 match_node::dump (systemtap_session &s, const string &name)
768 {
769 // Dump this node, if it is complete.
770 for (unsigned k=0; k<ends.size(); k++)
771 {
772 // Don't print aliases at all (for now) until we can figure out how to determine whether
773 // the probes they resolve to are ok in unprivileged mode.
774 if (ends[k]->is_alias ())
775 continue;
776
777 // In unprivileged mode, don't show the probes which are not allowed for unprivileged
778 // users.
779 if (pr_contains (privilege, s.privilege))
780 {
781 cout << name << endl;
782 break; // we need only print one instance.
783 }
784 }
785
786 // Recursively dump the children of this node
787 string dot;
788 if (! name.empty ())
789 dot = ".";
790 for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
791 {
792 i->second->dump (s, name + dot + i->first.str());
793 }
794 }
795
796
797 // ------------------------------------------------------------------------
798 // Alias probes
799 // ------------------------------------------------------------------------
800
801 struct alias_derived_probe: public derived_probe
802 {
803 alias_derived_probe (probe* base, probe_point *l, const probe_alias *a,
804 const vector<probe_point::component *> *suffix = 0);
805 ~alias_derived_probe();
806
807 void upchuck () { throw SEMANTIC_ERROR (_("inappropriate"), this->tok); }
808
809 // Alias probes are immediately expanded to other derived_probe
810 // types, and are not themselves emitted or listed in
811 // systemtap_session.probes
812
813 void join_group (systemtap_session&) { upchuck (); }
814
815 virtual const probe_alias *get_alias () const { return alias; }
816 virtual probe_point *get_alias_loc () const { return alias_loc; }
817 virtual probe_point *sole_location () const;
818
819 private:
820 const probe_alias *alias; // Used to check for recursion
821 probe_point *alias_loc; // Hack to recover full probe name
822 };
823
824
825 alias_derived_probe::alias_derived_probe(probe *base, probe_point *l,
826 const probe_alias *a,
827 const vector<probe_point::component *>
828 *suffix):
829 derived_probe (base, l), alias(a)
830 {
831 // XXX pretty nasty -- this was cribbed from printscript() in main.cxx
832 assert (alias->alias_names.size() >= 1);
833 alias_loc = new probe_point(*alias->alias_names[0]); // XXX: [0] is arbitrary; it would make just as much sense to collect all of the names
834 alias_loc->well_formed = true;
835 vector<probe_point::component*>::const_iterator it;
836 for (it = suffix->begin(); it != suffix->end(); ++it)
837 {
838 alias_loc->components.push_back(*it);
839 if (isglob((*it)->functor))
840 alias_loc->well_formed = false; // needs further derivation
841 }
842 }
843
844 alias_derived_probe::~alias_derived_probe ()
845 {
846 delete alias_loc;
847 }
848
849
850 probe_point*
851 alias_derived_probe::sole_location () const
852 {
853 return const_cast<probe_point*>(alias_loc);
854 }
855
856
857 void
858 alias_expansion_builder::build(systemtap_session & sess,
859 probe * use,
860 probe_point * location,
861 literal_map_t const & parameters,
862 vector<derived_probe *> & finished_results)
863 {
864 vector<probe_point::component *> empty_suffix;
865 build_with_suffix (sess, use, location, parameters,
866 finished_results, empty_suffix);
867 }
868
869 void
870 alias_expansion_builder::build_with_suffix(systemtap_session & sess,
871 probe * use,
872 probe_point * location,
873 literal_map_t const &,
874 vector<derived_probe *>
875 & finished_results,
876 vector<probe_point::component *>
877 const & suffix)
878 {
879 // Don't build the alias expansion if infinite recursion is detected.
880 if (checkForRecursiveExpansion (use)) {
881 stringstream msg;
882 msg << _F("recursive loop in alias expansion of %s at %s",
883 lex_cast(*location).c_str(), lex_cast(location->components.front()->tok->location).c_str());
884 // semantic_errors thrown here might be ignored, so we need a special class:
885 throw recursive_expansion_error (msg.str());
886 // XXX The point of throwing this custom error is to suppress a
887 // cascade of "probe mismatch" messages that appear in addition to
888 // the error. The current approach suppresses most of the error
889 // cascade, but leaves one spurious error; in any case, the way
890 // this particular error is reported could be improved.
891 }
892
893 // We're going to build a new probe and wrap it up in an
894 // alias_expansion_probe so that the expansion loop recognizes it as
895 // such and re-expands its expansion.
896
897 alias_derived_probe * n = new alias_derived_probe (use, location /* soon overwritten */, this->alias, &suffix);
898 n->body = new block();
899
900 // The new probe gets a deep copy of the location list of the alias
901 // (with incoming condition joined) plus the suffix (if any),
902 n->locations.clear();
903 for (unsigned i=0; i<alias->locations.size(); i++)
904 {
905 probe_point *pp = new probe_point(*alias->locations[i]);
906 pp->components.insert(pp->components.end(), suffix.begin(), suffix.end());
907 pp->condition = add_condition (pp->condition, location->condition);
908 n->locations.push_back(pp);
909 }
910
911 // the token location of the alias,
912 n->tok = location->components.front()->tok;
913
914 // and statements representing the concatenation of the alias'
915 // body with the use's.
916 //
917 // NB: locals are *not* copied forward, from either alias or
918 // use. The expansion should have its locals re-inferred since
919 // there's concatenated code here and we only want one vardecl per
920 // resulting variable.
921
922 if (alias->epilogue_style)
923 n->body = new block (use->body, alias->body);
924 else
925 n->body = new block (alias->body, use->body);
926
927 unsigned old_num_results = finished_results.size();
928 // If expanding for an alias suffix, be sure to pass on any errors
929 // to the caller instead of printing them in derive_probes():
930 derive_probes (sess, n, finished_results, location->optional, !suffix.empty());
931
932 // Check whether we resolved something. If so, put the
933 // whole library into the queue if not already there.
934 if (finished_results.size() > old_num_results)
935 {
936 stapfile *f = alias->tok->location.file;
937 if (find (sess.files.begin(), sess.files.end(), f)
938 == sess.files.end())
939 sess.files.push_back (f);
940 }
941 }
942
943 bool
944 alias_expansion_builder::checkForRecursiveExpansion (probe *use)
945 {
946 // Collect the derivation chain of this probe.
947 vector<probe*>derivations;
948 use->collect_derivation_chain (derivations);
949
950 // Check all probe points in the alias expansion against the currently-being-expanded probe point
951 // of each of the probes in the derivation chain, looking for a match. This
952 // indicates infinite recursion.
953 // The first element of the derivation chain will be the derived_probe representing 'use', so
954 // start the search with the second element.
955 assert (derivations.size() > 0);
956 assert (derivations[0] == use);
957 for (unsigned d = 1; d < derivations.size(); ++d) {
958 if (use->get_alias() == derivations[d]->get_alias())
959 return true; // recursion detected
960 }
961 return false;
962 }
963
964
965 // ------------------------------------------------------------------------
966 // Pattern matching
967 // ------------------------------------------------------------------------
968
969 // The match-and-expand loop.
970 void
971 derive_probes (systemtap_session& s,
972 probe *p, vector<derived_probe*>& dps,
973 bool optional,
974 bool rethrow_errors)
975 {
976 // We need a static to track whether the current probe is optional so that
977 // even if we recurse into derive_probes with optional = false, errors will
978 // still be ignored. The undo_parent_optional bool ensures we reset the
979 // static at the same level we had it set.
980 static bool parent_optional = false;
981 bool undo_parent_optional = false;
982
983 if (optional && !parent_optional)
984 {
985 parent_optional = true;
986 undo_parent_optional = true;
987 }
988
989 vector <semantic_error> optional_errs;
990
991 for (unsigned i = 0; i < p->locations.size(); ++i)
992 {
993 set<string> builders;
994 assert_no_interrupts();
995
996 probe_point *loc = p->locations[i];
997
998 if (s.verbose > 1)
999 clog << "derive-probes (location #" << i << "): " << *loc << " of " << *p->tok << endl;
1000
1001 try
1002 {
1003 unsigned num_atbegin = dps.size();
1004
1005 try
1006 {
1007 s.pattern_root->find_and_build (s, p, loc, 0, dps, builders); // <-- actual derivation!
1008 }
1009 catch (const semantic_error& e)
1010 {
1011 if (!loc->optional && !parent_optional)
1012 throw semantic_error(e);
1013 else /* tolerate failure for optional probe */
1014 {
1015 // remember err, we will print it (in catch block) if any
1016 // non-optional loc fails to resolve
1017 semantic_error err(ERR_SRC, _("while resolving probe point"),
1018 loc->components[0]->tok, NULL, &e);
1019 optional_errs.push_back(err);
1020 continue;
1021 }
1022 }
1023
1024 unsigned num_atend = dps.size();
1025
1026 if (! (loc->optional||parent_optional) && // something required, but
1027 num_atbegin == num_atend) // nothing new derived!
1028 throw SEMANTIC_ERROR (_("no match"));
1029
1030 if (loc->sufficient && (num_atend > num_atbegin))
1031 {
1032 if (s.verbose > 1)
1033 {
1034 clog << "Probe point ";
1035 p->locations[i]->print(clog);
1036 clog << " sufficient, skipped";
1037 for (unsigned j = i+1; j < p->locations.size(); ++j)
1038 {
1039 clog << " ";
1040 p->locations[j]->print(clog);
1041 }
1042 clog << endl;
1043 }
1044 break; // we need not try to derive for any other locations
1045 }
1046 }
1047 catch (const semantic_error& e)
1048 {
1049 // The rethrow_errors parameter lets the caller decide an
1050 // alternative to printing the error. This is necessary when
1051 // calling derive_probes() recursively during expansion of
1052 // an alias with suffix -- any message printed here would
1053 // point to the alias declaration and not the invalid suffix
1054 // usage, so the caller needs to catch the error themselves
1055 // and print a more appropriate message.
1056 if (rethrow_errors)
1057 {
1058 throw semantic_error(e);
1059 }
1060 // Only output in dump mode if -vv is supplied:
1061 else if (!s.dump_mode || (s.verbose > 1))
1062 {
1063 // print this one manually first because it's more important than
1064 // the optional errs
1065 semantic_error err(ERR_SRC, _("while resolving probe point"),
1066 loc->components[0]->tok, NULL, &e);
1067 // provide some details about which builders were tried
1068 if (s.verbose > 0 && !builders.empty())
1069 {
1070 string msg;
1071 for (auto it = builders.begin(); it != builders.end(); ++it)
1072 {
1073 if (it != builders.begin())
1074 msg.append(", ");
1075 msg.append(*it);
1076 }
1077 semantic_error err2(ERR_SRC, _F("resolution failed in %s", msg.c_str()));
1078 err2.set_chain(err);
1079 s.print_error(err2);
1080 }
1081 else
1082 {
1083 s.print_error(err);
1084 }
1085
1086 // print optional errs accumulated while visiting other probe points
1087 for (vector<semantic_error>::const_iterator it = optional_errs.begin();
1088 it != optional_errs.end(); ++it)
1089 {
1090 s.print_error(*it);
1091 }
1092 }
1093 }
1094 }
1095
1096 if (undo_parent_optional)
1097 {
1098 parent_optional = false;
1099 }
1100 }
1101
1102
1103
1104 // ------------------------------------------------------------------------
1105 //
1106 // Indexable usage checks
1107 //
1108
1109 struct symbol_fetcher
1110 : public throwing_visitor
1111 {
1112 symbol *&sym;
1113
1114 symbol_fetcher (symbol *&sym): sym(sym)
1115 {}
1116
1117 void visit_symbol (symbol* e)
1118 {
1119 sym = e;
1120 }
1121
1122 void visit_arrayindex (arrayindex* e)
1123 {
1124 e->base->visit (this);
1125 }
1126
1127 void throwone (const token* t)
1128 {
1129 throw SEMANTIC_ERROR (_("Expecting symbol or array index expression"), t);
1130 }
1131 };
1132
1133 symbol *
1134 get_symbol_within_expression (expression *e)
1135 {
1136 symbol *sym = NULL;
1137 symbol_fetcher fetcher(sym);
1138 e->visit (&fetcher);
1139 return sym; // NB: may be null!
1140 }
1141
1142 static symbol *
1143 get_symbol_within_indexable (indexable *ix)
1144 {
1145 symbol *array = NULL;
1146 hist_op *hist = NULL;
1147 classify_indexable(ix, array, hist);
1148 if (array)
1149 return array;
1150 else
1151 return get_symbol_within_expression (hist->stat);
1152 }
1153
1154 struct mutated_var_collector
1155 : public traversing_visitor
1156 {
1157 set<vardecl *> * mutated_vars;
1158
1159 mutated_var_collector (set<vardecl *> * mm)
1160 : mutated_vars (mm)
1161 {}
1162
1163 void visit_assignment(assignment* e)
1164 {
1165 if (e->type == pe_stats && e->op == "<<<")
1166 {
1167 vardecl *vd = get_symbol_within_expression (e->left)->referent;
1168 if (vd)
1169 mutated_vars->insert (vd);
1170 }
1171 traversing_visitor::visit_assignment(e);
1172 }
1173
1174 void visit_arrayindex (arrayindex *e)
1175 {
1176 if (is_active_lvalue (e))
1177 {
1178 symbol *sym;
1179 if (e->base->is_symbol (sym))
1180 mutated_vars->insert (sym->referent);
1181 else
1182 throw SEMANTIC_ERROR(_("Assignment to read-only histogram bucket"), e->tok);
1183 }
1184 traversing_visitor::visit_arrayindex (e);
1185 }
1186 };
1187
1188
1189 struct no_var_mutation_during_iteration_check
1190 : public traversing_visitor
1191 {
1192 systemtap_session & session;
1193 map<functiondecl *,set<vardecl *> *> & function_mutates_vars;
1194 vector<vardecl *> vars_being_iterated;
1195
1196 no_var_mutation_during_iteration_check
1197 (systemtap_session & sess,
1198 map<functiondecl *,set<vardecl *> *> & fmv)
1199 : session(sess), function_mutates_vars (fmv)
1200 {}
1201
1202 void visit_arrayindex (arrayindex *e)
1203 {
1204 if (is_active_lvalue(e))
1205 {
1206 vardecl *vd = get_symbol_within_indexable (e->base)->referent;
1207 if (vd)
1208 {
1209 for (unsigned i = 0; i < vars_being_iterated.size(); ++i)
1210 {
1211 vardecl *v = vars_being_iterated[i];
1212 if (v == vd)
1213 {
1214 string err = _F("variable '%s' modified during 'foreach' iteration",
1215 v->unmangled_name.to_string().c_str());
1216 session.print_error (SEMANTIC_ERROR (err, e->tok));
1217 }
1218 }
1219 }
1220 }
1221 traversing_visitor::visit_arrayindex (e);
1222 }
1223
1224 void visit_functioncall (functioncall* e)
1225 {
1226 for (unsigned fd = 0; fd < e->referents.size(); fd++)
1227 {
1228 map<functiondecl *,set<vardecl *> *>::const_iterator i
1229 = function_mutates_vars.find (e->referents[fd]);
1230
1231 if (i != function_mutates_vars.end())
1232 {
1233 for (unsigned j = 0; j < vars_being_iterated.size(); ++j)
1234 {
1235 vardecl *m = vars_being_iterated[j];
1236 if (i->second->find (m) != i->second->end())
1237 {
1238 string err = _F("function call modifies var '%s' during 'foreach' iteration",
1239 m->unmangled_name.to_string().c_str());
1240 session.print_error (SEMANTIC_ERROR (err, e->tok));
1241 }
1242 }
1243 }
1244 }
1245
1246 traversing_visitor::visit_functioncall (e);
1247 }
1248
1249 void visit_foreach_loop(foreach_loop* s)
1250 {
1251 vardecl *vd = get_symbol_within_indexable (s->base)->referent;
1252
1253 if (vd)
1254 vars_being_iterated.push_back (vd);
1255
1256 traversing_visitor::visit_foreach_loop (s);
1257
1258 if (vd)
1259 vars_being_iterated.pop_back();
1260 }
1261 };
1262
1263
1264 // ------------------------------------------------------------------------
1265
1266 struct stat_decl_collector
1267 : public traversing_visitor
1268 {
1269 systemtap_session & session;
1270
1271 stat_decl_collector(systemtap_session & sess)
1272 : session(sess)
1273 {}
1274
1275 void visit_stat_op (stat_op* e)
1276 {
1277 symbol *sym = get_symbol_within_expression (e->stat);
1278 statistic_decl new_stat = statistic_decl();
1279 int bit_shift = (e->params.size() == 0) ? 0 : e->params[0];
1280 int stat_op = STAT_OP_NONE;
1281
1282 if ((bit_shift < 0) || (bit_shift > 62))
1283 throw SEMANTIC_ERROR (_F("bit shift (%d) out of range <0..62>",
1284 bit_shift),
1285 e->tok);
1286
1287 // The following helps to track which statistical operators are being
1288 // used with given global/local variable. This information later helps
1289 // to optimize the runtime behaviour.
1290
1291 if (e->ctype == sc_count)
1292 stat_op = STAT_OP_COUNT;
1293 else if (e->ctype == sc_sum)
1294 stat_op = STAT_OP_SUM;
1295 else if (e->ctype == sc_min)
1296 stat_op = STAT_OP_MIN;
1297 else if (e->ctype == sc_max)
1298 stat_op = STAT_OP_MAX;
1299 else if (e->ctype == sc_average)
1300 stat_op = STAT_OP_AVG;
1301 else if (e->ctype == sc_variance)
1302 stat_op = STAT_OP_VARIANCE;
1303
1304 new_stat.bit_shift = bit_shift;
1305 new_stat.stat_ops |= stat_op;
1306
1307 map<interned_string, statistic_decl>::iterator i = session.stat_decls.find(sym->name);
1308 if (i == session.stat_decls.end())
1309 session.stat_decls[sym->name] = new_stat;
1310 else
1311 {
1312 i->second.stat_ops |= stat_op;
1313
1314 // The @variance operator for given stat S (i.e. call to
1315 // _stp_stat_init()) is optionally parametrizeable
1316 // (@variance(S[, N]), where N is a bit shift (the default is
1317 // N=0). The bit_shift helps to improve precision if integer
1318 // arithemtic, namely divisions ().
1319 //
1320 // Ref: https://en.wikipedia.org/wiki/Scale_factor_%28computer_science%29
1321 //
1322 if (e->tok->content != "@variance")
1323 return;
1324 else if ((i->second.bit_shift != 0)
1325 && (i->second.bit_shift != bit_shift))
1326 {
1327 // FIXME: Support multiple co-declared bit shifts
1328 // (analogy to multiple co-declared histogram types)
1329 throw SEMANTIC_ERROR (_F("conflicting bit shifts declared (previously %d)",
1330 i->second.bit_shift),
1331 e->tok);
1332 }
1333 else
1334 {
1335 i->second.bit_shift = bit_shift;
1336 }
1337 }
1338 }
1339
1340 void visit_foreach_loop (foreach_loop* s)
1341 {
1342 symbol *array;
1343 hist_op *hist;
1344
1345 classify_indexable (s->base, array, hist);
1346
1347 if (array && array->type == pe_stats
1348 && s->sort_direction
1349 && s->sort_column == 0)
1350 {
1351 int stat_op = STAT_OP_NONE;
1352
1353 switch (s->sort_aggr) {
1354 default: case sc_none: case sc_count: stat_op = STAT_OP_COUNT; break;
1355 case sc_sum: stat_op = STAT_OP_SUM; break;
1356 case sc_min: stat_op = STAT_OP_MIN; break;
1357 case sc_max: stat_op = STAT_OP_MAX; break;
1358 case sc_average: stat_op = STAT_OP_AVG; break;
1359 }
1360
1361 map<interned_string, statistic_decl>::iterator i
1362 = session.stat_decls.find(array->name);
1363
1364 if (i == session.stat_decls.end())
1365 session.stat_decls[array->name] = statistic_decl(stat_op);
1366 else
1367 i->second.stat_ops |= stat_op;
1368 }
1369
1370 traversing_visitor::visit_foreach_loop (s);
1371 }
1372
1373 void visit_assignment (assignment* e)
1374 {
1375 if (e->op == "<<<")
1376 {
1377 symbol *sym = get_symbol_within_expression (e->left);
1378 if (session.stat_decls.find(sym->name) == session.stat_decls.end())
1379 session.stat_decls[sym->name] = statistic_decl();
1380 }
1381 else
1382 traversing_visitor::visit_assignment(e);
1383 }
1384
1385 void visit_hist_op (hist_op* e)
1386 {
1387 symbol *sym = get_symbol_within_expression (e->stat);
1388 statistic_decl new_stat;
1389
1390 if (e->htype == hist_linear)
1391 {
1392 new_stat.type = statistic_decl::linear;
1393 assert (e->params.size() == 3);
1394 new_stat.linear_low = e->params[0];
1395 new_stat.linear_high = e->params[1];
1396 new_stat.linear_step = e->params[2];
1397 }
1398 else
1399 {
1400 assert (e->htype == hist_log);
1401 new_stat.type = statistic_decl::logarithmic;
1402 assert (e->params.size() == 0);
1403 }
1404
1405 map<interned_string, statistic_decl>::iterator i = session.stat_decls.find(sym->name);
1406 if (i == session.stat_decls.end())
1407 session.stat_decls[sym->name] = new_stat;
1408 else
1409 {
1410 statistic_decl & old_stat = i->second;
1411 if (!(old_stat == new_stat))
1412 {
1413 if (old_stat.type == statistic_decl::none)
1414 {
1415 i->second.type = new_stat.type;
1416 i->second.linear_low = new_stat.linear_low;
1417 i->second.linear_high = new_stat.linear_high;
1418 i->second.linear_step = new_stat.linear_step;
1419 }
1420 else
1421 {
1422 // FIXME: Support multiple co-declared histogram types
1423 semantic_error se(ERR_SRC, _F("multiple histogram types declared on '%s'",
1424 sym->name.to_string().c_str()), e->tok);
1425 session.print_error (se);
1426 }
1427 }
1428 }
1429 }
1430
1431 };
1432
1433 static int
1434 semantic_pass_stats (systemtap_session & sess)
1435 {
1436 stat_decl_collector sdc(sess);
1437
1438 for (map<string,functiondecl*>::iterator it = sess.functions.begin(); it != sess.functions.end(); it++)
1439 it->second->body->visit (&sdc);
1440
1441 for (unsigned i = 0; i < sess.probes.size(); ++i)
1442 sess.probes[i]->body->visit (&sdc);
1443
1444 for (unsigned i = 0; i < sess.globals.size(); ++i)
1445 {
1446 vardecl *v = sess.globals[i];
1447 if (v->type == pe_stats)
1448 {
1449
1450 if (sess.stat_decls.find(v->name) == sess.stat_decls.end())
1451 {
1452 semantic_error se(ERR_SRC, _F("unable to infer statistic parameters for global '%s'",
1453 v->unmangled_name.to_string().c_str()));
1454 sess.print_error (se);
1455 }
1456 }
1457 }
1458
1459 return sess.num_errors();
1460 }
1461
1462 // ------------------------------------------------------------------------
1463
1464 // Enforce variable-related invariants: no modification of
1465 // a foreach()-iterated array.
1466 static int
1467 semantic_pass_vars (systemtap_session & sess)
1468 {
1469
1470 map<functiondecl *, set<vardecl *> *> fmv;
1471 no_var_mutation_during_iteration_check chk(sess, fmv);
1472
1473 for (map<string,functiondecl*>::iterator it = sess.functions.begin(); it != sess.functions.end(); it++)
1474 {
1475 functiondecl * fn = it->second;
1476 if (fn->body)
1477 {
1478 set<vardecl *> * m = new set<vardecl *>();
1479 mutated_var_collector mc (m);
1480 fn->body->visit (&mc);
1481 fmv[fn] = m;
1482 }
1483 }
1484
1485 for (map<string,functiondecl*>::iterator it = sess.functions.begin(); it != sess.functions.end(); it++)
1486 {
1487 functiondecl * fn = it->second;
1488 if (fn->body) fn->body->visit (&chk);
1489 }
1490
1491 for (unsigned i = 0; i < sess.probes.size(); ++i)
1492 {
1493 if (sess.probes[i]->body)
1494 sess.probes[i]->body->visit (&chk);
1495 }
1496
1497 return sess.num_errors();
1498 }
1499
1500
1501 // ------------------------------------------------------------------------
1502
1503 // Rewrite probe condition expressions into probe bodies. Tricky and
1504 // exciting business, this. This:
1505 //
1506 // probe foo if (g1 || g2) { ... }
1507 // probe bar { ... g1 ++ ... }
1508 //
1509 // becomes:
1510 //
1511 // probe foo { if (! (g1 || g2)) next; ... }
1512 // probe bar { ... g1 ++ ...;
1513 // if (g1 || g2) %{ enable_probe_foo %} else %{ disable_probe_foo %}
1514 // }
1515 //
1516 // In other words, we perform two transformations:
1517 // (1) Inline probe condition into its body.
1518 // (2) For each probe that modifies a global var in use in any probe's
1519 // condition, re-evaluate those probes' condition at the end of that
1520 // probe's body.
1521 //
1522 // Here, we do all of (1), and half of (2): we simply collect the dependency
1523 // info between probes, which the translator will use to emit the affected
1524 // probes' condition re-evaluation. The translator will also ensure that the
1525 // conditions are evaluated using the globals' starting values prior to any
1526 // probes starting.
1527
1528 // Adds the condition expression to the front of the probe's body
1529 static void
1530 derived_probe_condition_inline (derived_probe *p)
1531 {
1532 expression* e = p->sole_location()->condition;
1533 assert(e);
1534
1535 if_statement *ifs = new if_statement ();
1536 ifs->tok = e->tok;
1537 ifs->thenblock = new next_statement ();
1538 ifs->thenblock->tok = e->tok;
1539 ifs->elseblock = NULL;
1540 unary_expression *notex = new unary_expression ();
1541 notex->op = "!";
1542 notex->tok = e->tok;
1543 notex->operand = e;
1544 ifs->condition = notex;
1545 p->body = new block (ifs, p->body);
1546 }
1547
1548 static int
1549 semantic_pass_conditions (systemtap_session & sess)
1550 {
1551 map<derived_probe*, set<vardecl*> > vars_read_in_cond;
1552 map<derived_probe*, set<vardecl*> > vars_written_in_body;
1553
1554 // do a first pass through the probes to ensure safety, inline any condition,
1555 // and collect var usage
1556 for (unsigned i = 0; i < sess.probes.size(); ++i)
1557 {
1558 if (pending_interrupts) return 1;
1559
1560 derived_probe* p = sess.probes[i];
1561 expression* e = p->sole_location()->condition;
1562
1563 if (e)
1564 {
1565 varuse_collecting_visitor vcv_cond(sess);
1566 e->visit (& vcv_cond);
1567
1568 if (!vcv_cond.written.empty())
1569 sess.print_error (SEMANTIC_ERROR (_("probe condition must not "
1570 "modify any variables"),
1571 e->tok));
1572 else if (vcv_cond.embedded_seen)
1573 sess.print_error (SEMANTIC_ERROR (_("probe condition must not "
1574 "include impure embedded-C"),
1575 e->tok));
1576
1577 derived_probe_condition_inline(p);
1578
1579 vars_read_in_cond[p].insert(vcv_cond.read.begin(),
1580 vcv_cond.read.end());
1581 }
1582
1583 varuse_collecting_visitor vcv_body(sess);
1584 p->body->visit (& vcv_body);
1585
1586 vars_written_in_body[p].insert(vcv_body.written.begin(),
1587 vcv_body.written.end());
1588 }
1589
1590 // do a second pass to collect affected probes
1591 for (unsigned i = 0; i < sess.probes.size(); ++i)
1592 {
1593 if (pending_interrupts) return 1;
1594
1595 derived_probe *p = sess.probes[i];
1596
1597 // for each variable this probe modifies...
1598 set<vardecl*>::const_iterator var;
1599 for (var = vars_written_in_body[p].begin();
1600 var != vars_written_in_body[p].end(); ++var)
1601 {
1602 // collect probes which could be affected
1603 for (unsigned j = 0; j < sess.probes.size(); ++j)
1604 {
1605 if (vars_read_in_cond[sess.probes[j]].count(*var))
1606 {
1607 if (!p->probes_with_affected_conditions.count(sess.probes[j]))
1608 {
1609 p->probes_with_affected_conditions.insert(sess.probes[j]);
1610 if (sess.verbose > 2)
1611 clog << "probe " << i << " can affect condition of "
1612 "probe " << j << endl;
1613 }
1614 }
1615 }
1616 }
1617 }
1618
1619 // PR18115: We create a begin probe which is artificially registered as
1620 // affecting every other probe. This will serve as the initializer so that
1621 // other probe types with false conditions can be skipped (or registered as
1622 // disabled) during module initialization.
1623
1624 set<derived_probe*> targets;
1625 for (unsigned i = 0; i < sess.probes.size(); ++i)
1626 if (!vars_read_in_cond[sess.probes[i]].empty())
1627 targets.insert(sess.probes[i]);
1628
1629 if (!targets.empty())
1630 {
1631 stringstream ss("probe begin {}");
1632
1633 // no good token to choose here... let's just use the condition expression
1634 // of one of the probes as the token
1635 const token *tok = (*targets.begin())->sole_location()->condition->tok;
1636
1637 probe *p = parse_synthetic_probe(sess, ss, tok);
1638 if (!p)
1639 throw SEMANTIC_ERROR (_("can't create cond initializer probe"), tok);
1640
1641 vector<derived_probe*> dps;
1642 derive_probes(sess, p, dps);
1643
1644 // there should only be one
1645 assert(dps.size() == 1);
1646
1647 derived_probe* dp = dps[0];
1648 dp->probes_with_affected_conditions.insert(targets.begin(),
1649 targets.end());
1650 sess.probes.push_back (dp);
1651 dp->join_group (sess);
1652
1653 // no need to manually do symresolution since body is empty
1654 }
1655
1656 return sess.num_errors();
1657 }
1658
1659 // ------------------------------------------------------------------------
1660
1661
1662 // Simple visitor that just goes through all embedded code blocks that
1663 // are available at the end all the optimizations to register any
1664 // relevant pragmas or other indicators found, so that session flags can
1665 // be set that can be inspected at translation time to trigger any
1666 // necessary initialization of code needed by the embedded code functions.
1667
1668 // This is only for pragmas that don't have any other side-effect than
1669 // needing some initialization at module init time. Currently handles
1670 // /* pragma:vma */ /* pragma:unwind */ /* pragma:symbols */ /* pragma:lines */
1671
1672 // /* pragma:uprobes */ is handled during the typeresolution_info pass.
1673 // /* pure */, /* unprivileged */. /* myproc-unprivileged */ and /* guru */
1674 // are handled by the varuse_collecting_visitor.
1675
1676 struct embeddedcode_info: public functioncall_traversing_visitor
1677 {
1678 protected:
1679 systemtap_session& session;
1680 void examine (const interned_string &, const token *tok);
1681
1682 public:
1683 embeddedcode_info (systemtap_session& s): session(s) { }
1684
1685 void visit_embeddedcode (embeddedcode* c) { examine (c->code, c->tok); }
1686 void visit_embedded_expr (embedded_expr* e) { examine (e->code, e->tok); }
1687 };
1688
1689 void
1690 embeddedcode_info::examine (const interned_string &code, const token *tok)
1691 {
1692 if (! vma_tracker_enabled(session)
1693 && code.find("/* pragma:vma */") != string::npos)
1694 {
1695 if (session.verbose > 2)
1696 clog << _F("Turning on task_finder vma_tracker, pragma:vma found in %s",
1697 current_function->unmangled_name.to_string().c_str()) << endl;
1698
1699 // PR15052: stapdyn doesn't have VMA-tracking yet.
1700 if (session.runtime_usermode_p())
1701 throw SEMANTIC_ERROR(_("VMA-tracking is only supported by the kernel runtime (PR15052)"), tok);
1702
1703 enable_vma_tracker(session);
1704 }
1705
1706 if (! session.need_unwind
1707 && code.find("/* pragma:unwind */") != string::npos)
1708 {
1709 if (session.verbose > 2)
1710 clog << _F("Turning on unwind support, pragma:unwind found in %s",
1711 current_function->unmangled_name.to_string().c_str()) << endl;
1712 session.need_unwind = true;
1713 }
1714
1715 if (! session.need_symbols
1716 && code.find("/* pragma:symbols */") != string::npos)
1717 {
1718 if (session.verbose > 2)
1719 clog << _F("Turning on symbol data collecting, pragma:symbols found in %s",
1720 current_function->unmangled_name.to_string().c_str()) << endl;
1721 session.need_symbols = true;
1722 }
1723
1724 if (! session.need_lines
1725 && code.find("/* pragma:lines */") != string::npos)
1726 {
1727 if (session.verbose > 2)
1728 clog << _F("Turning on debug line data collecting, pragma:lines found in %s",
1729 current_function->unmangled_name.to_string().c_str()) << endl;
1730 session.need_lines = true;
1731 }
1732 }
1733
1734 void embeddedcode_info_pass (systemtap_session& s)
1735 {
1736 embeddedcode_info eci (s);
1737 for (unsigned i=0; i<s.probes.size(); i++)
1738 s.probes[i]->body->visit (& eci);
1739
1740 for (map<string,functiondecl*>::iterator it = s.functions.begin();
1741 it != s.functions.end(); it++)
1742 it->second->body->visit (& eci);
1743 }
1744
1745 // ------------------------------------------------------------------------
1746
1747
1748 // Simple visitor that collects all the regular expressions in the
1749 // file and adds them to the session DFA table.
1750
1751 struct regex_collecting_visitor: public functioncall_traversing_visitor
1752 {
1753 protected:
1754 systemtap_session& session;
1755
1756 public:
1757 regex_collecting_visitor (systemtap_session& s): session(s) { }
1758
1759 void visit_regex_query (regex_query *q) {
1760 functioncall_traversing_visitor::visit_regex_query (q);
1761
1762 string re = q->right->value;
1763 regex_to_stapdfa (&session, re, q->right->tok);
1764 }
1765 };
1766
1767 // Go through the regex match invocations and generate corresponding DFAs.
1768 int gen_dfa_table (systemtap_session& s)
1769 {
1770 regex_collecting_visitor rcv(s);
1771
1772 for (unsigned i=0; i<s.probes.size(); i++)
1773 {
1774 try
1775 {
1776 s.probes[i]->body->visit (& rcv);
1777
1778 if (s.probes[i]->sole_location()->condition)
1779 s.probes[i]->sole_location()->condition->visit (& rcv);
1780 }
1781 catch (const semantic_error& e)
1782 {
1783 s.print_error (e);
1784 }
1785 }
1786
1787 return s.num_errors();
1788 }
1789
1790 // ------------------------------------------------------------------------
1791
1792
1793 static int semantic_pass_symbols (systemtap_session&);
1794 static int semantic_pass_optimize1 (systemtap_session&);
1795 static int semantic_pass_optimize2 (systemtap_session&);
1796 static int semantic_pass_types (systemtap_session&);
1797 static int semantic_pass_vars (systemtap_session&);
1798 static int semantic_pass_stats (systemtap_session&);
1799 static int semantic_pass_conditions (systemtap_session&);
1800
1801
1802 struct expression_build_no_more_visitor : public expression_visitor
1803 {
1804 // Clear extra details from every expression, like DWARF type info, so that
1805 // builders can safely release them in build_no_more. From here on out,
1806 // we're back to basic types only.
1807 void visit_expression(expression *e)
1808 {
1809 e->type_details.reset();
1810 }
1811 };
1812
1813 static void
1814 build_no_more (systemtap_session& s)
1815 {
1816 expression_build_no_more_visitor v;
1817
1818 for (unsigned i=0; i<s.probes.size(); i++)
1819 s.probes[i]->body->visit(&v);
1820
1821 for (map<string,functiondecl*>::iterator it = s.functions.begin();
1822 it != s.functions.end(); it++)
1823 it->second->body->visit(&v);
1824
1825 // Inform all derived_probe builders that we're done with
1826 // all resolution, so it's time to release caches.
1827 s.pattern_root->build_no_more (s);
1828 }
1829
1830
1831
1832 // Link up symbols to their declarations. Set the session's
1833 // files/probes/functions/globals vectors from the transitively
1834 // reached set of stapfiles in s.library_files, starting from
1835 // s.user_file. Perform automatic tapset inclusion and probe
1836 // alias expansion.
1837 static int
1838 semantic_pass_symbols (systemtap_session& s)
1839 {
1840 symresolution_info sym (s);
1841
1842 // If we're listing functions, then we need to include all the files. Probe
1843 // aliases won't be visited/derived so all we gain are the functions, global
1844 // variables, and any real probes (e.g. begin probes). NB: type resolution for
1845 // a specific function arg may fail if it could only be determined from a
1846 // function call in one of the skipped aliases.
1847 if (s.dump_mode == systemtap_session::dump_functions)
1848 {
1849 s.files.insert(s.files.end(), s.library_files.begin(),
1850 s.library_files.end());
1851 }
1852 else if (!s.user_files.empty())
1853 {
1854 // Normal run: seed s.files with user_files and let it grow through the
1855 // find_* functions. NB: s.files can grow during this iteration, so
1856 // size() can return gradually increasing numbers.
1857 s.files.insert (s.files.end(), s.user_files.begin(), s.user_files.end());
1858 }
1859
1860 for (unsigned i = 0; i < s.files.size(); i++)
1861 {
1862 assert_no_interrupts();
1863 stapfile* dome = s.files[i];
1864
1865 // Pass 1: add globals and functions to systemtap-session master list,
1866 // so the find_* functions find them
1867 //
1868 // NB: tapset global/function definitions may duplicate or conflict
1869 // with those already in s.globals/functions. We need to deconflict
1870 // here.
1871
1872 for (unsigned i=0; i<dome->globals.size(); i++)
1873 {
1874 vardecl* g = dome->globals[i];
1875 for (unsigned j=0; j<s.globals.size(); j++)
1876 {
1877 vardecl* g2 = s.globals[j];
1878 if (g->name == g2->name)
1879 {
1880 s.print_error (SEMANTIC_ERROR (_("conflicting global variables"),
1881 g->tok, g2->tok));
1882 }
1883 }
1884 s.globals.push_back (g);
1885 }
1886
1887 for (unsigned i=0; i<dome->functions.size(); i++)
1888 {
1889 functiondecl* f = dome->functions[i];
1890 functiondecl* f2 = s.functions[f->name];
1891 if (f2 && f != f2)
1892 {
1893 s.print_error (SEMANTIC_ERROR (_("conflicting functions"),
1894 f->tok, f2->tok));
1895 }
1896 s.functions[f->name] = f;
1897 }
1898
1899 // NB: embeds don't conflict with each other
1900 for (unsigned i=0; i<dome->embeds.size(); i++)
1901 s.embeds.push_back (dome->embeds[i]);
1902
1903 // Pass 2: derive probes and resolve any further symbols in the
1904 // derived results.
1905
1906 for (unsigned i=0; i<dome->probes.size(); i++)
1907 {
1908 assert_no_interrupts();
1909 probe* p = dome->probes [i];
1910 vector<derived_probe*> dps;
1911
1912 // much magic happens here: probe alias expansion, wildcard
1913 // matching, low-level derived_probe construction.
1914 derive_probes (s, p, dps);
1915
1916 for (unsigned j=0; j<dps.size(); j++)
1917 {
1918 assert_no_interrupts();
1919 derived_probe* dp = dps[j];
1920 s.probes.push_back (dp);
1921 dp->join_group (s);
1922
1923 if (s.verbose > 2)
1924 {
1925 clog << _("symbol resolution for derived-probe ");
1926 dp->printsig(clog);
1927 clog << endl;
1928 }
1929
1930 try
1931 {
1932 update_visitor_loop (s, s.code_filters, dp->body);
1933
1934 sym.current_function = 0;
1935 sym.current_probe = dp;
1936 dp->body->visit (& sym);
1937
1938 // Process the probe-point condition expression.
1939 sym.current_function = 0;
1940 sym.current_probe = 0;
1941 if (dp->sole_location()->condition)
1942 dp->sole_location()->condition->visit (& sym);
1943 }
1944 catch (const semantic_error& e)
1945 {
1946 s.print_error (e);
1947 }
1948 }
1949 }
1950
1951 // Pass 3: process functions - incl. the synthetic ones,
1952 // so s.functions[] rather than dome->functions[]
1953
1954 for (auto it = s.functions.begin(); it != s.functions.end(); it++)
1955 {
1956 assert_no_interrupts();
1957 functiondecl* fd = it->second;
1958 if (s.verbose > 2)
1959 clog << _("symbol resolution for function ") << fd->name << endl;
1960
1961 try
1962 {
1963 update_visitor_loop (s, s.code_filters, fd->body);
1964
1965 sym.current_function = fd;
1966 sym.current_probe = 0;
1967 fd->body->visit (& sym);
1968 }
1969 catch (const semantic_error& e)
1970 {
1971 s.print_error (e);
1972 }
1973 }
1974 }
1975
1976 if(s.systemtap_v_check){
1977 for(unsigned i=0;i<s.globals.size();i++){
1978 if(s.globals[i]->systemtap_v_conditional)
1979 s.print_warning(_("This global uses tapset constructs that are dependent on systemtap version"), s.globals[i]->tok);
1980 }
1981
1982 for(map<string, functiondecl*>::const_iterator i=s.functions.begin();i != s.functions.end();++i){
1983 if(i->second->systemtap_v_conditional)
1984 s.print_warning(_("This function uses tapset constructs that are dependent on systemtap version"), i->second->tok);
1985 }
1986
1987 for(unsigned i=0;i<s.probes.size();i++){
1988 vector<probe*> sysvc;
1989 s.probes[i]->collect_derivation_chain(sysvc);
1990 for(unsigned j=0;j<sysvc.size();j++){
1991 if(sysvc[j]->systemtap_v_conditional)
1992 s.print_warning(_("This probe uses tapset constructs that are dependent on systemtap version"), sysvc[j]->tok);
1993 if(sysvc[j]->get_alias() && sysvc[j]->get_alias()->systemtap_v_conditional)
1994 s.print_warning(_("This alias uses tapset constructs that are dependent on systemtap version"), sysvc[j]->get_alias()->tok);
1995 }
1996 }
1997 }
1998
1999 return s.num_errors(); // all those print_error calls
2000 }
2001
2002
2003 // Keep unread global variables for probe end value display.
2004 void add_global_var_display (systemtap_session& s)
2005 {
2006 // Don't generate synthetic end probes when in listing mode; it would clutter
2007 // up the list of probe points with "end ...". In fact, don't bother in any
2008 // dump mode at all, since it'll never be used.
2009 if (s.dump_mode) return;
2010
2011 // The bpf runtime currently lacks support for foreach statements which
2012 // this function might generate.
2013 if (s.runtime_mode == systemtap_session::bpf_runtime) return;
2014
2015 // User has specified not to display unread global variables.
2016 if (s.no_global_var_display) return;
2017
2018 varuse_collecting_visitor vut(s);
2019
2020 for (unsigned i=0; i<s.probes.size(); i++)
2021 {
2022 s.probes[i]->body->visit (& vut);
2023
2024 if (s.probes[i]->sole_location()->condition)
2025 s.probes[i]->sole_location()->condition->visit (& vut);
2026 }
2027
2028 for (unsigned g=0; g < s.globals.size(); g++)
2029 {
2030 vardecl* l = s.globals[g];
2031 if ((vut.read.find (l) != vut.read.end()
2032 && vut.used.find (l) != vut.used.end())
2033 || vut.written.find (l) == vut.written.end())
2034 continue;
2035
2036 // Don't generate synthetic end probes for unread globals
2037 // declared only within tapsets. (RHBZ 468139), but rather
2038 // only within the end-user script.
2039
2040 bool tapset_global = false;
2041 for (size_t m=0; m < s.library_files.size(); m++)
2042 {
2043 for (size_t n=0; n < s.library_files[m]->globals.size(); n++)
2044 {
2045 if (l->name == s.library_files[m]->globals[n]->name)
2046 {tapset_global = true; break;}
2047 }
2048 }
2049 if (tapset_global)
2050 continue;
2051
2052 stringstream code;
2053 code << "probe end {" << endl;
2054
2055 string format = l->unmangled_name;
2056
2057 string indexes;
2058 string foreach_value;
2059 if (!l->index_types.empty())
2060 {
2061 // Add index values to the printf format, and prepare
2062 // a simple list of indexes for passing around elsewhere
2063 format += "[";
2064 for (size_t i = 0; i < l->index_types.size(); ++i)
2065 {
2066 if (i > 0)
2067 {
2068 indexes += ",";
2069 format += ",";
2070 }
2071 indexes += "__idx" + lex_cast(i);
2072 if (l->index_types[i] == pe_string)
2073 format += "\\\"%#s\\\"";
2074 else
2075 format += "%#d";
2076 }
2077 format += "]";
2078
2079 // Iterate over all indexes in the array, sorted by decreasing value
2080 code << "foreach (";
2081 if (l->type != pe_stats)
2082 {
2083 foreach_value = "__val";
2084 code << foreach_value << " = ";
2085 }
2086 code << "[" << indexes << "] in " << l->unmangled_name << "-)" << endl;
2087 }
2088 else if (l->type == pe_stats)
2089 {
2090 // PR7053: Check scalar globals for empty aggregate
2091 code << "if (@count(" << l->unmangled_name << ") == 0)" << endl;
2092 code << "printf(\"" << l->unmangled_name << " @count=0x0\\n\")" << endl;
2093 code << "else" << endl;
2094 }
2095
2096 static const string stats[] = { "@count", "@min", "@max", "@sum", "@avg" };
2097 const string stats_format =
2098 (strverscmp(s.compatible.c_str(), "1.4") >= 0) ? "%#d" : "%#x";
2099
2100 // Fill in the printf format for values
2101 if (l->type == pe_stats)
2102 for (size_t i = 0; i < sizeof(stats)/sizeof(stats[0]); ++i)
2103 format += " " + stats[i] + "=" + stats_format;
2104 else if (l->type == pe_string)
2105 format += "=\\\"%#s\\\"";
2106 else
2107 format += "=%#x";
2108 format += "\\n";
2109
2110 // Output the actual printf
2111 code << "printf (\"" << format << "\"";
2112
2113 // Feed indexes to the printf, and include them in the value
2114 string value = !foreach_value.empty() ? foreach_value : string(l->unmangled_name);
2115 if (!l->index_types.empty())
2116 {
2117 code << "," << indexes;
2118 if (foreach_value.empty())
2119 value += "[" + indexes + "]";
2120 }
2121
2122 // Feed the actual values to the printf
2123 if (l->type == pe_stats)
2124 for (size_t i = 0; i < sizeof(stats)/sizeof(stats[0]); ++i)
2125 code << "," << stats[i] << "(" << value << ")";
2126 else
2127 code << "," << value;
2128 code << ")" << endl;
2129
2130 // End of probe
2131 code << "}" << endl;
2132
2133 probe *p = parse_synthetic_probe (s, code, l->tok);
2134 if (!p)
2135 throw SEMANTIC_ERROR (_("can't create global var display"), l->tok);
2136
2137 vector<derived_probe*> dps;
2138 derive_probes (s, p, dps);
2139 for (unsigned i = 0; i < dps.size(); i++)
2140 {
2141 derived_probe* dp = dps[i];
2142 s.probes.push_back (dp);
2143 dp->join_group (s);
2144
2145 // Repopulate symbol and type info
2146 symresolution_info sym (s);
2147 sym.current_function = 0;
2148 sym.current_probe = dp;
2149 dp->body->visit (& sym);
2150 }
2151
2152 semantic_pass_types(s);
2153 // Mark that variable is read
2154 vut.read.insert (l);
2155 }
2156 }
2157
2158 static void gen_monitor_data(systemtap_session& s)
2159 {
2160 vardecl* v;
2161 embeddedcode* ec;
2162
2163 v = new vardecl;
2164 v->unmangled_name = v->name = "__global___monitor_module_start";
2165 v->set_arity(0, 0);
2166 v->type = pe_long;
2167 v->synthetic = true;
2168 s.globals.push_back(v);
2169
2170 ec = new embeddedcode;
2171 ec->code = "#define STAP_MONITOR_READ 8192\n"
2172 "static char _monitor_buf[STAP_MONITOR_READ];";
2173 s.embeds.push_back(ec);
2174
2175 functiondecl* fd = new functiondecl;
2176 fd->synthetic = true;
2177 fd->unmangled_name = fd->name = "__private___monitor_data_function_probes";
2178 fd->type = pe_string;
2179 v = new vardecl;
2180 v->type = pe_long;
2181 v->unmangled_name = v->name = "index";
2182 fd->formal_args.push_back(v);
2183 ec = new embeddedcode;
2184 string code;
2185 code = "/* unprivileged */ /* pure */"
2186 "const struct stap_probe *const p = &stap_probes[STAP_ARG_index];\n"
2187 "if (likely (probe_timing(STAP_ARG_index))) {\n"
2188 "struct stat_data *stats = _stp_stat_get (probe_timing(STAP_ARG_index), 0);\n"
2189 "if (stats->count) {\n"
2190 "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);\n"
2191 "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
2192 "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %lld, "
2193 "\\\"min\\\": %lld, \\\"avg\\\": %lld, \\\"max\\\": %lld, \",\n"
2194 "p->index, p->cond_enabled ? \"on\" : \"off\", (long long) stats->count,\n"
2195 "(long long) stats->min, (long long) avg, (long long) stats->max);\n"
2196 "} else {\n"
2197 "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
2198 "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %d, "
2199 "\\\"min\\\": %d, \\\"avg\\\": %d, \\\"max\\\": %d, \",\n"
2200 "p->index, p->cond_enabled ? \"on\" : \"off\", 0, 0, 0, 0);}}\n"
2201 "STAP_RETURN(_monitor_buf);\n";
2202 ec->code = code;
2203 fd->body = ec;
2204 s.functions[fd->name] = fd;
2205
2206 stringstream probe_code;
2207 probe_code << "probe begin {" << endl;
2208 probe_code << "__monitor_module_start = jiffies()" << endl;
2209 probe_code << "}" << endl;
2210
2211 probe* p = parse_synthetic_probe(s, probe_code, 0);
2212 if (!p)
2213 throw SEMANTIC_ERROR (_("can't create begin probe"), 0);
2214
2215 vector<derived_probe*> dps;
2216 derive_probes (s, p, dps);
2217
2218 derived_probe* dp = dps[0];
2219 s.probes.push_back (dp);
2220 dp->join_group (s);
2221
2222 // Repopulate symbol info
2223 symresolution_info sym (s);
2224 sym.current_function = 0;
2225 sym.current_probe = dp;
2226 dp->body->visit (&sym);
2227 }
2228
2229 static void monitor_mode_read(systemtap_session& s)
2230 {
2231 if (!s.monitor) return;
2232
2233 gen_monitor_data(s);
2234
2235 stringstream code;
2236
2237 unsigned long rough_max_json_size = 100 +
2238 s.globals.size() * 100 +
2239 s.probes.size() * 200;
2240
2241 code << "probe procfs(\"monitor_status\").read.maxsize(" << rough_max_json_size << ") {" << endl;
2242 code << "try {"; // absorb .= overflows!
2243 code << "elapsed = (jiffies()-__monitor_module_start)/HZ()" << endl;
2244 code << "hrs = elapsed/3600; mins = elapsed%3600/60; secs = elapsed%3600%60;" << endl;
2245 code << "$value .= sprintf(\"{\\n\")" << endl;
2246 code << "$value .= sprintf(\"\\\"uptime\\\": \\\"%02d:%02d:%02d\\\",\\n\", hrs, mins, secs)" << endl;
2247 code << "$value .= sprintf(\"\\\"uid\\\": \\\"%d\\\",\\n\", uid())" << endl;
2248 code << "$value .= sprintf(\"\\\"memory\\\": \\\"%s\\\",\\n\", module_size())" << endl;
2249 code << "$value .= sprintf(\"\\\"module_name\\\": \\\"%s\\\",\\n\", module_name())" << endl;
2250
2251 code << "$value .= sprintf(\"\\\"globals\\\": {\\n\")" << endl;
2252 for (auto it = s.globals.cbegin(); it != s.globals.cend(); ++it)
2253 {
2254 if ((*it)->synthetic) continue;
2255
2256 if (it != s.globals.cbegin())
2257 code << "$value .= sprintf(\",\\n\")" << endl;
2258
2259 code << "$value .= sprintf(\"\\\"%s\\\":\", \"" << (*it)->unmangled_name << "\")" << endl;
2260 if ((*it)->arity == 0)
2261 {
2262 if ((*it)->type == pe_stats)
2263 code << "$value .= sprintf(\"\\\"%d(count)\\\"\", @count(" << (*it)->name << "))" << endl;
2264 else if ((*it)->type == pe_string)
2265 code << "$value .= string_quoted(sprintf(\"\\\"%s\\\"\"," << (*it)->name << "))" << endl;
2266 else
2267 code << "$value .= string_quoted(sprint(" << (*it)->name << "))" << endl;
2268 }
2269 else if ((*it)->arity > 0)
2270 code << "$value .= sprintf(\"\\\"[%d]\\\"\", " << (*it)->maxsize << ")" << endl;
2271 }
2272 code << "$value .= sprintf(\"\\n},\\n\")" << endl;
2273
2274 code << "$value .= sprintf(\"\\\"probe_list\\\": [\\n\")" << endl;
2275 for (auto it = s.probes.cbegin(); it != s.probes.cend(); ++it)
2276 {
2277 if ((*it)->synthetic) continue;
2278
2279 if (it != s.probes.cbegin())
2280 code << "$value .= sprintf(\",\\n\")" << endl;
2281
2282 istringstream probe_point((*it)->sole_location()->str());
2283 string name;
2284 probe_point >> name;
2285 /* Escape quotes once for systemtap parser and once more for json parser */
2286 name = lex_cast_qstring(lex_cast_qstring(name));
2287
2288 code << "$value .= sprintf(\"{%s\", __private___monitor_data_function_probes("
2289 << it-s.probes.begin() << "))" << endl;
2290 code << "$value .= sprintf(\"\\\"name\\\": %s}\", " << name << ")" << endl;
2291 }
2292 code << "$value .= sprintf(\"\\n],\\n\")" << endl;
2293
2294 code << "$value .= sprintf(\"}\\n\")" << endl;
2295
2296 code << "} catch(ex) { warn(\"JSON construction error: \" . ex) }" << endl;
2297 code << "}" << endl;
2298 probe* p = parse_synthetic_probe(s, code, 0);
2299 if (!p)
2300 throw SEMANTIC_ERROR (_("can't create procfs probe"), 0);
2301
2302 vector<derived_probe*> dps;
2303 derive_probes (s, p, dps);
2304
2305 derived_probe* dp = dps[0];
2306 s.probes.push_back (dp);
2307 dp->join_group (s);
2308
2309 // Repopulate symbol info
2310 symresolution_info sym (s);
2311 sym.current_function = 0;
2312 sym.current_probe = dp;
2313 dp->body->visit (&sym);
2314
2315 // Resolve types for variables used in the new procfs probe
2316 semantic_pass_types(s);
2317 }
2318
2319 static void monitor_mode_write(systemtap_session& s)
2320 {
2321 if (!s.monitor) return;
2322
2323 for (auto it = s.probes.cbegin(); it != s.probes.cend(); ++it)
2324 {
2325 vardecl* v = new vardecl;
2326 v->unmangled_name = v->name = "__monitor_" + lex_cast(it-s.probes.begin()) + "_enabled";
2327 v->tok = (*it)->tok;
2328 v->set_arity(0, (*it)->tok);
2329 v->type = pe_long;
2330 v->init = new literal_number(1);
2331 v->synthetic = true;
2332 s.globals.push_back(v);
2333
2334 symbol* sym = new symbol;
2335 sym->name = v->name;
2336 sym->tok = v->tok;
2337 sym->type = pe_long;
2338 sym->referent = v;
2339
2340 if ((*it)->sole_location()->condition)
2341 {
2342 logical_and_expr *e = new logical_and_expr;
2343 e->tok = v->tok;
2344 e->left = sym;
2345 e->op = "&&";
2346 e->type = pe_long;
2347 e->right = (*it)->sole_location()->condition;
2348 (*it)->sole_location()->condition = e;
2349 }
2350 else
2351 {
2352 (*it)->sole_location()->condition = sym;
2353 }
2354 }
2355
2356 stringstream code;
2357
2358 code << "probe procfs(\"monitor_control\").write {" << endl;
2359
2360 code << "if ($value == \"clear\") {";
2361 for (auto it = s.globals.cbegin(); it != s.globals.cend(); ++it)
2362 {
2363 vardecl* v = *it;
2364
2365 if (v->synthetic) continue;
2366
2367 if (v->arity == 0 && v->init)
2368 {
2369 if (v->type == pe_long)
2370 {
2371 literal_number* ln = dynamic_cast<literal_number*>(v->init);
2372 if (ln == 0)
2373 throw SEMANTIC_ERROR (_("expected literal number"), 0);
2374 code << v->name << " = " << ln->value << endl;
2375 }
2376 else if (v->type == pe_string)
2377 {
2378 literal_string* ln = dynamic_cast<literal_string*>(v->init);
2379 if (ln == 0)
2380 throw SEMANTIC_ERROR (_("expected literal string"), 0);
2381 code << v->name << " = " << lex_cast_qstring(ln->value) << endl;
2382 }
2383 }
2384 else
2385 {
2386 // For scalar elements with no initial values, we reset to 0 or empty as
2387 // done with arrays and aggregates.
2388 code << "delete " << v->name << endl;
2389 }
2390 }
2391
2392 code << "} else if ($value == \"resume\") {" << endl;
2393 for (auto it = s.probes.cbegin(); it != s.probes.cend(); ++it)
2394 {
2395 code << " __monitor_" << it-s.probes.begin() << "_enabled" << " = 1" << endl;
2396 }
2397
2398 code << "} else if ($value == \"pause\") {" << endl;
2399 for (auto it = s.probes.cbegin(); it != s.probes.cend(); ++it)
2400 {
2401 code << " __monitor_" << it-s.probes.begin() << "_enabled" << " = 0" << endl;
2402 }
2403 code << "} else if ($value == \"quit\") {" << endl;
2404 code << " exit()" << endl;
2405 code << "}";
2406
2407 for (auto it = s.probes.cbegin(); it != s.probes.cend(); ++it)
2408 {
2409 code << " if ($value == \"" << it-s.probes.begin() << "\")"
2410 << " __monitor_" << it-s.probes.begin() << "_enabled" << " ^= 1" << endl;
2411 }
2412
2413 code << "}" << endl;
2414
2415 probe* p = parse_synthetic_probe(s, code, 0);
2416 if (!p)
2417 throw SEMANTIC_ERROR (_("can't create procfs probe"), 0);
2418
2419 vector<derived_probe*> dps;
2420 derive_probes (s, p, dps);
2421
2422 derived_probe* dp = dps[0];
2423 s.probes.push_back (dp);
2424 dp->join_group (s);
2425
2426 // Repopulate symbol info
2427 symresolution_info sym (s, /* omniscient-unmangled */ true);
2428 sym.current_function = 0;
2429 sym.current_probe = dp;
2430 dp->body->visit (&sym);
2431 }
2432
2433 static void setup_timeout(systemtap_session& s)
2434 {
2435 if (!s.timeout) return;
2436
2437 stringstream code;
2438 code << "probe timer.ms(" << s.timeout << ") {exit()}";
2439 probe* p = parse_synthetic_probe(s, code, 0);
2440 if (!p)
2441 throw SEMANTIC_ERROR (_("can't create timer probe"), 0);
2442
2443 vector<derived_probe*> dps;
2444 derive_probes (s, p, dps);
2445
2446 derived_probe* dp = dps[0];
2447 s.probes.push_back (dp);
2448 dp->join_group (s);
2449
2450 // Repopulate symbol info
2451 symresolution_info sym (s);
2452 sym.current_function = 0;
2453 sym.current_probe = dp;
2454 dp->body->visit (&sym);
2455 }
2456
2457 int
2458 semantic_pass (systemtap_session& s)
2459 {
2460 int rc = 0;
2461
2462 try
2463 {
2464 // FIXME: interactive mode, register_library_aliases handles
2465 // both aliases from library files *and* user scripts. It would
2466 // be nice to have them in separate lists and register them
2467 // separately.
2468 s.register_library_aliases();
2469 register_standard_tapsets(s);
2470
2471 if (rc == 0) setup_timeout(s);
2472 if (rc == 0) rc = semantic_pass_symbols (s);
2473 if (rc == 0) monitor_mode_write (s);
2474 if (rc == 0) rc = semantic_pass_conditions (s);
2475 if (rc == 0) rc = semantic_pass_optimize1 (s);
2476 if (rc == 0) rc = semantic_pass_types (s);
2477 if (rc == 0) rc = gen_dfa_table(s);
2478 if (rc == 0) add_global_var_display (s);
2479 if (rc == 0) monitor_mode_read(s);
2480 if (rc == 0) rc = semantic_pass_optimize2 (s);
2481 if (rc == 0) rc = semantic_pass_vars (s);
2482 if (rc == 0) rc = semantic_pass_stats (s);
2483 if (rc == 0) embeddedcode_info_pass (s);
2484 }
2485 catch (const semantic_error& e)
2486 {
2487 s.print_error (e);
2488 rc ++;
2489 }
2490
2491 bool no_primary_probes = true;
2492 for (unsigned i = 0; i < s.probes.size(); i++)
2493 if (s.is_primary_probe(s.probes[i]))
2494 no_primary_probes = false;
2495
2496 if (s.num_errors() == 0 && no_primary_probes && !s.dump_mode)
2497 {
2498 s.print_error(SEMANTIC_ERROR(_("no probes found")));
2499 rc ++;
2500 }
2501
2502 build_no_more (s);
2503
2504 // PR11443
2505 // NB: listing mode only cares whether we have any probes,
2506 // so all previous error conditions are disregarded.
2507 if (s.dump_mode == systemtap_session::dump_matched_probes ||
2508 s.dump_mode == systemtap_session::dump_matched_probes_vars)
2509 rc = no_primary_probes;
2510
2511 // If we're dumping functions, only error out if no functions were found
2512 if (s.dump_mode == systemtap_session::dump_functions)
2513 rc = s.functions.empty();
2514
2515 return rc;
2516 }
2517
2518
2519 // ------------------------------------------------------------------------
2520 // semantic processing: symbol resolution
2521
2522
2523 symresolution_info::symresolution_info (systemtap_session& s, bool omniscient_unmangled):
2524 session (s), unmangled_p(omniscient_unmangled), current_function (0), current_probe (0)
2525 {
2526 }
2527
2528
2529 void
2530 symresolution_info::visit_block (block* e)
2531 {
2532 for (unsigned i=0; i<e->statements.size(); i++)
2533 {
2534 try
2535 {
2536 e->statements[i]->visit (this);
2537 }
2538 catch (const semantic_error& e)
2539 {
2540 session.print_error (e);
2541 }
2542 }
2543 }
2544
2545
2546 void
2547 symresolution_info::visit_foreach_loop (foreach_loop* e)
2548 {
2549 for (unsigned i=0; i<e->indexes.size(); i++)
2550 e->indexes[i]->visit (this);
2551 for (unsigned i=0; i<e->array_slice.size(); i++)
2552 if (e->array_slice[i])
2553 e->array_slice[i]->visit(this);
2554
2555 symbol *array = NULL;
2556 hist_op *hist = NULL;
2557 classify_indexable (e->base, array, hist);
2558
2559 if (array)
2560 {
2561 if (!array->referent)
2562 {
2563 vardecl* d = find_var (array->name, e->indexes.size (), array->tok);
2564 if (d)
2565 {
2566 array->referent = d;
2567 array->name = d->name;
2568 }
2569 else
2570 {
2571 stringstream msg;
2572 msg << _F("unresolved arity-%zu global array %s, missing global declaration?",
2573 e->indexes.size(), array->name.to_string().c_str());
2574 throw SEMANTIC_ERROR (msg.str(), array->tok);
2575 }
2576 }
2577
2578 if (!e->array_slice.empty() && e->array_slice.size() != e->indexes.size())
2579 {
2580 stringstream msg;
2581 msg << _F("unresolved arity-%zu global array %s, missing global declaration?",
2582 e->array_slice.size(), array->name.to_string().c_str());
2583 throw SEMANTIC_ERROR (msg.str(), array->tok);
2584 }
2585 }
2586 else
2587 {
2588 assert (hist);
2589 hist->visit (this);
2590 }
2591
2592 if (e->value)
2593 e->value->visit (this);
2594
2595 if (e->limit)
2596 e->limit->visit (this);
2597
2598 e->block->visit (this);
2599 }
2600
2601
2602 struct
2603 delete_statement_symresolution_info:
2604 public traversing_visitor
2605 {
2606 symresolution_info *parent;
2607
2608 delete_statement_symresolution_info (symresolution_info *p):
2609 parent(p)
2610 {}
2611
2612 void visit_arrayindex (arrayindex* e)
2613 {
2614 parent->visit_arrayindex(e, true);
2615 }
2616
2617 void visit_functioncall (functioncall* e)
2618 {
2619 parent->visit_functioncall (e);
2620 }
2621
2622 void visit_symbol (symbol* e)
2623 {
2624 if (e->referent)
2625 return;
2626
2627 vardecl* d = parent->find_var (e->name, -1, e->tok);
2628 if (d)
2629 e->referent = d;
2630 else
2631 throw SEMANTIC_ERROR (_("unresolved array in delete statement"), e->tok);
2632 }
2633 };
2634
2635 void
2636 symresolution_info::visit_delete_statement (delete_statement* s)
2637 {
2638 delete_statement_symresolution_info di (this);
2639 s->value->visit (&di);
2640 }
2641
2642
2643 void
2644 symresolution_info::visit_symbol (symbol* e)
2645 {
2646 if (e->referent)
2647 return;
2648
2649 if (session.verbose > 3)
2650 clog << _F("Resolving symbol symbol %p (%s) ...", (void*) e, ((string)e->name).c_str());
2651 vardecl* d = find_var (e->name, 0, e->tok);
2652 if (session.verbose > 3)
2653 clog << endl;
2654 if (d)
2655 {
2656 e->referent = d;
2657 e->name = d->name;
2658 }
2659 else
2660 {
2661 // new local
2662 vardecl* v = new vardecl;
2663 v->unmangled_name = v->name = e->name;
2664 v->tok = e->tok;
2665 v->set_arity(0, e->tok);
2666 if (current_function)
2667 current_function->locals.push_back (v);
2668 else if (current_probe)
2669 current_probe->locals.push_back (v);
2670 else
2671 // must be probe-condition expression
2672 throw SEMANTIC_ERROR (_("probe condition must not reference undeclared global"), e->tok);
2673 e->referent = v;
2674 }
2675 }
2676
2677
2678 void
2679 symresolution_info::visit_arrayindex (arrayindex* e)
2680 {
2681 visit_arrayindex(e, false);
2682 }
2683
2684 void
2685 symresolution_info::visit_arrayindex (arrayindex* e, bool wildcard_ok)
2686 {
2687 for (unsigned i=0; i<e->indexes.size(); i++)
2688 {
2689 // assuming that if NULL, it was originally a wildcard (*)
2690 if (e->indexes[i] == NULL)
2691 {
2692 if (!wildcard_ok)
2693 throw SEMANTIC_ERROR(_("wildcard not allowed in array index"), e->tok);
2694 }
2695 else
2696 e->indexes[i]->visit (this);
2697 }
2698
2699 symbol *array = NULL;
2700 hist_op *hist = NULL;
2701 classify_indexable(e->base, array, hist);
2702
2703 if (array)
2704 {
2705 if (array->referent)
2706 return;
2707
2708 vardecl* d = find_var (array->name, e->indexes.size (), array->tok);
2709 if (d)
2710 {
2711 array->referent = d;
2712 array->name = d->name;
2713 }
2714 else
2715 {
2716 stringstream msg;
2717 msg << _F("unresolved arity-%zu global array %s, missing global declaration?",
2718 e->indexes.size(), array->name.to_string().c_str());
2719 throw SEMANTIC_ERROR (msg.str(), e->tok);
2720 }
2721 }
2722 else
2723 {
2724 assert (hist);
2725 hist->visit (this);
2726 }
2727 }
2728
2729
2730 void
2731 symresolution_info::visit_array_in (array_in* e)
2732 {
2733 visit_arrayindex(e->operand, true);
2734 }
2735
2736
2737 void
2738 symresolution_info::visit_functioncall (functioncall* e)
2739 {
2740 // XXX: we could relax this, if we're going to examine the
2741 // vartracking data recursively. See testsuite/semko/fortytwo.stp.
2742 if (! (current_function || current_probe))
2743 {
2744 // must be probe-condition expression
2745 throw SEMANTIC_ERROR (_("probe condition must not reference function"), e->tok);
2746 }
2747
2748 for (unsigned i=0; i<e->args.size(); i++)
2749 e->args[i]->visit (this);
2750
2751 // already resolved?
2752 if (!e->referents.empty())
2753 return;
2754
2755 vector<functiondecl*> fds = find_functions (e, e->function, e->args.size (), e->tok);
2756 if (!fds.empty())
2757 {
2758 e->referents = fds;
2759 function_priority_order order;
2760 stable_sort(e->referents.begin(), e->referents.end(), order); // preserve declaration order
2761 e->function = e->referents[0]->name;
2762 }
2763 else
2764 {
2765 string sugs = levenshtein_suggest(e->function, collect_functions(), 5); // print 5 funcs
2766 throw SEMANTIC_ERROR(_F("unresolved function%s",
2767 sugs.empty() ? "" : (_(" (similar: ") + sugs + ")").c_str()),
2768 e->tok);
2769 }
2770
2771 // In monitor mode, tapset functions used in the synthetic probe are not resolved and added
2772 // to the master list at the same time as the other functions so we must add them here to
2773 // allow the translator to generate the functions in the module.
2774 if (session.monitor && session.functions.find(e->function) == session.functions.end())
2775 session.functions[e->function] = fds[0]; // no overload
2776 }
2777
2778 /*find_var will return an argument other than zero if the name matches the var
2779 * name ie, if the current local name matches the name passed to find_var*/
2780 vardecl*
2781 symresolution_info::find_var (interned_string name, int arity, const token* tok)
2782 {
2783 if (current_function || current_probe)
2784 {
2785 // search locals
2786 vector<vardecl*>& locals = (current_function ?
2787 current_function->locals :
2788 current_probe->locals);
2789
2790
2791 for (unsigned i=0; i<locals.size(); i++)
2792 if (locals[i]->name == name)
2793 {
2794 if (session.verbose > 3)
2795 clog << _F("to local (%p/%p) vardecl %p",
2796 (void*) current_function, (void*) current_probe, (void*) locals[i]);
2797
2798 locals[i]->set_arity (arity, tok);
2799 return locals[i];
2800 }
2801 }
2802
2803 // search function formal parameters (for scalars)
2804 if (arity == 0 && current_function)
2805 for (unsigned i=0; i<current_function->formal_args.size(); i++)
2806 if (current_function->formal_args[i]->name == name)
2807 {
2808 // NB: no need to check arity here: formal args always scalar
2809 if (session.verbose > 3)
2810 clog << _F("to %p param vardecl %p", (void*) current_function, (void*) current_function->formal_args[i]);
2811
2812 current_function->formal_args[i]->set_arity (0, tok);
2813 return current_function->formal_args[i];
2814 }
2815
2816 // search processed globals
2817 string gname, pname;
2818 if (unmangled_p)
2819 {
2820 gname = pname = string(name);
2821 }
2822 else
2823 {
2824 gname = "__global_" + string(name);
2825 pname = "__private_" + detox_path(tok->location.file->name) + string(name);
2826 }
2827 for (unsigned i=0; i<session.globals.size(); i++)
2828 {
2829 if ((session.globals[i]->name == name && startswith(name, "__global_")) ||
2830 (session.globals[i]->name == gname) ||
2831 (session.globals[i]->name == pname))
2832 {
2833 if (session.verbose > 3)
2834 clog << _F("to global vardecl %p", (void*) session.globals[i]);
2835
2836 if (! session.suppress_warnings)
2837 {
2838 vardecl* v = session.globals[i];
2839 stapfile* f = tok->location.file;
2840 // clog << "resolved " << *tok << " to global " << *v->tok << endl;
2841 if (v->tok && v->tok->location.file != f && !f->synthetic)
2842 {
2843 session.print_warning (_F("cross-file global variable reference to %s from",
2844 lex_cast(*v->tok).c_str()), tok);
2845 }
2846 }
2847 session.globals[i]->set_arity (arity, tok);
2848 return session.globals[i];
2849 }
2850 }
2851
2852 // search library globals
2853 for (unsigned i=0; i<session.library_files.size(); i++)
2854 {
2855 stapfile* f = session.library_files[i];
2856 for (unsigned j=0; j<f->globals.size(); j++)
2857 {
2858 vardecl* g = f->globals[j];
2859 if ((g->name == gname) ||
2860 (g->name == pname)) // private global within tapset probe alias
2861 {
2862 if (session.verbose > 3)
2863 clog << _F("to tapset global vardecl %p", (void*) g);
2864
2865 g->set_arity (arity, tok);
2866
2867 // put library into the queue if not already there
2868 if (find (session.files.begin(), session.files.end(), f)
2869 == session.files.end())
2870 session.files.push_back (f);
2871
2872 return g;
2873 }
2874 }
2875 }
2876
2877 return 0;
2878 }
2879
2880
2881 class functioncall_security_check: public traversing_visitor
2882 {
2883 systemtap_session& session;
2884 functioncall* call;
2885 functiondecl* current_function;
2886 public:
2887 functioncall_security_check(systemtap_session&s, functioncall* c): session(s),call(c) {}
2888 void traverse (functiondecl* d)
2889 {
2890 current_function = d;
2891 current_function->body->visit(this);
2892 }
2893
2894 void visit_embeddedcode (embeddedcode *s)
2895 {
2896 // Don't allow embedded C functions in unprivileged mode unless
2897 // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
2898 // or we're in a usermode runtime.
2899 if (! pr_contains (session.privilege, pr_stapdev) &&
2900 ! pr_contains (session.privilege, pr_stapsys) &&
2901 ! session.runtime_usermode_p () &&
2902 s->code.find ("/* unprivileged */") == string::npos &&
2903 s->code.find ("/* myproc-unprivileged */") == string::npos)
2904 throw SEMANTIC_ERROR (_F("function may not be used when --privilege=%s is specified",
2905 pr_name (session.privilege)),
2906 current_function->tok);
2907
2908 // Allow only /* bpf */ functions in bpf mode.
2909 if ((session.runtime_mode == systemtap_session::bpf_runtime)
2910 != (s->code.find ("/* bpf */") != string::npos))
2911 {
2912 if (session.runtime_mode == systemtap_session::bpf_runtime)
2913 throw SEMANTIC_ERROR (_("function may not be used with bpf runtime"),
2914 current_function->tok);
2915 else
2916 throw SEMANTIC_ERROR (_("function requires bpf runtime"),
2917 current_function->tok);
2918 }
2919
2920 // Don't allow /* guru */ functions unless caller is privileged.
2921 if (!call->tok->location.file->privileged && s->code.find ("/* guru */") != string::npos)
2922 throw SEMANTIC_ERROR (_("function may not be used unless -g is specified"),
2923 call->tok);
2924 }
2925 };
2926
2927
2928 vector<functiondecl*>
2929 symresolution_info::find_functions (functioncall *call, const string& name, unsigned arity, const token *tok)
2930 {
2931 vector<functiondecl*> functions;
2932 functiondecl* last = 0; // used for error message
2933
2934 // the common path
2935
2936 // internal global functions bypassing the parser, such as __global_dwarf_tvar_[gs]et
2937 if ((session.functions.find(name) != session.functions.end()) && startswith(name, "__private_"))
2938 {
2939 functiondecl* fd = session.functions[name];
2940 assert (fd->name == name);
2941 if (fd->formal_args.size() == arity)
2942 functions.push_back(fd);
2943 else
2944 last = fd;
2945 }
2946
2947 // functions scanned by the parser are overloaded
2948 unsigned alternatives = session.overload_count[name];
2949 for (unsigned alt = 0; alt < alternatives; alt++)
2950 {
2951 bool found = false; // multiple inclusion guard
2952 string gname = "__global_" + string(name) + "__overload_" + lex_cast(alt);
2953 string pname = "__private_" + detox_path(tok->location.file->name) + string(name) +
2954 "__overload_" + lex_cast(alt);
2955
2956 // tapset or user script global functions coming from the parser
2957 if (!found && session.functions.find(gname) != session.functions.end())
2958 {
2959 functiondecl* fd = session.functions[gname];
2960 assert (fd->name == gname);
2961 if (fd->formal_args.size() == arity)
2962 {
2963 functions.push_back(fd);
2964 found = true;
2965 }
2966 else
2967 last = fd;
2968 }
2969
2970 // tapset or user script private functions coming from the parser
2971 if (!found && session.functions.find(pname) != session.functions.end())
2972 {
2973 functiondecl* fd = session.functions[pname];
2974 assert (fd->name == pname);
2975 if (fd->formal_args.size() == arity)
2976 {
2977 functions.push_back(fd);
2978 found = true;
2979 }
2980 else
2981 last = fd;
2982 }
2983
2984 // search library functions
2985 for (unsigned i=0; !found && i<session.library_files.size(); i++)
2986 {
2987 stapfile* f = session.library_files[i];
2988 for (unsigned j=0; !found && j<f->functions.size(); j++)
2989 {
2990 if ((f->functions[j]->name == gname) ||
2991 (f->functions[j]->name == pname))
2992 {
2993 if (f->functions[j]->formal_args.size() == arity)
2994 {
2995 // put library into the queue if not already there
2996 if (0) // session.verbose_resolution
2997 cerr << _F(" function %s is defined from %s",
2998 name.c_str(), f->name.c_str()) << endl;
2999
3000 if (find (session.files.begin(), session.files.end(), f)
3001 == session.files.end())
3002 session.files.push_back (f);
3003 // else .. print different message?
3004
3005 functions.push_back(f->functions[j]);
3006 found = true;
3007 }
3008 else
3009 last = f->functions[j];
3010 }
3011 }
3012 }
3013 }
3014
3015 // suggest last found function with matching name
3016 if (last && functions.empty())
3017 {
3018 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
3019 name.c_str(), last->formal_args.size()), tok, last->tok);
3020 }
3021
3022 // check every function for safety/security constraints
3023 functioncall_security_check fsc(session, call);
3024 for (auto gi = functions.begin(); gi != functions.end(); gi++)
3025 fsc.traverse(*gi);
3026
3027 return functions;
3028 }
3029
3030 set<string>
3031 symresolution_info::collect_functions(void)
3032 {
3033 set<string> funcs;
3034
3035 for (map<string,functiondecl*>::const_iterator it = session.functions.begin();
3036 it != session.functions.end(); ++it)
3037 funcs.insert(it->second->unmangled_name);
3038
3039 // search library functions
3040 for (unsigned i=0; i<session.library_files.size(); i++)
3041 {
3042 stapfile* f = session.library_files[i];
3043 for (unsigned j=0; j<f->functions.size(); j++)
3044 if (! f->functions[j]->name.starts_with("__private_"))
3045 funcs.insert(f->functions[j]->unmangled_name);
3046 }
3047
3048 return funcs;
3049 }
3050
3051 // ------------------------------------------------------------------------
3052 // optimization
3053
3054
3055 // Do away with functiondecls that are never (transitively) called
3056 // from probes.
3057 void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p)
3058 {
3059 functioncall_traversing_visitor ftv;
3060 for (unsigned i=0; i<s.probes.size(); i++)
3061 {
3062 s.probes[i]->body->visit (& ftv);
3063 if (s.probes[i]->sole_location()->condition)
3064 s.probes[i]->sole_location()->condition->visit (& ftv);
3065 }
3066 vector<functiondecl*> new_unused_functions;
3067 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
3068 {
3069 functiondecl* fd = it->second;
3070 if (ftv.seen.find(fd) == ftv.seen.end())
3071 {
3072 if (! fd->synthetic && s.is_user_file(fd->tok->location.file->name))
3073 s.print_warning (_F("Eliding unused function '%s'",
3074 fd->unmangled_name.to_string().c_str()),
3075 fd->tok);
3076 // s.functions.erase (it); // NB: can't, since we're already iterating upon it
3077 new_unused_functions.push_back (fd);
3078 relaxed_p = false;
3079 }
3080 }
3081 for (unsigned i=0; i<new_unused_functions.size(); i++)
3082 {
3083 map<string,functiondecl*>::iterator where = s.functions.find (new_unused_functions[i]->name);
3084 assert (where != s.functions.end());
3085 s.functions.erase (where);
3086 if (s.tapset_compile_coverage)
3087 s.unused_functions.push_back (new_unused_functions[i]);
3088 }
3089 }
3090
3091
3092 // ------------------------------------------------------------------------
3093
3094 // Do away with local & global variables that are never
3095 // written nor read.
3096 void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterations)
3097 {
3098 varuse_collecting_visitor vut(s);
3099
3100 for (unsigned i=0; i<s.probes.size(); i++)
3101 {
3102 s.probes[i]->body->visit (& vut);
3103
3104 if (s.probes[i]->sole_location()->condition)
3105 s.probes[i]->sole_location()->condition->visit (& vut);
3106 }
3107
3108 // NB: Since varuse_collecting_visitor also traverses down
3109 // actually called functions, we don't need to explicitly
3110 // iterate over them. Uncalled ones should have been pruned
3111 // in _opt1 above.
3112 //
3113 // for (unsigned i=0; i<s.functions.size(); i++)
3114 // s.functions[i]->body->visit (& vut);
3115
3116 // Now in vut.read/written, we have a mixture of all locals, globals
3117
3118 for (unsigned i=0; i<s.probes.size(); i++)
3119 for (unsigned j=0; j<s.probes[i]->locals.size(); /* see below */)
3120 {
3121 vardecl* l = s.probes[i]->locals[j];
3122
3123 // skip over "special" locals
3124 if (l->synthetic) { j++; continue; }
3125
3126 if (vut.read.find (l) == vut.read.end() &&
3127 vut.written.find (l) == vut.written.end())
3128 {
3129 if (!l->tok->location.file->synthetic && s.is_user_file(l->tok->location.file->name))
3130 s.print_warning (_F("Eliding unused variable '%s'",
3131 l->unmangled_name.to_string().c_str()),
3132 l->tok);
3133 if (s.tapset_compile_coverage) {
3134 s.probes[i]->unused_locals.push_back
3135 (s.probes[i]->locals[j]);
3136 }
3137 s.probes[i]->locals.erase(s.probes[i]->locals.begin() + j);
3138 relaxed_p = false;
3139 // don't increment j
3140 }
3141 else
3142 {
3143 if (vut.written.find (l) == vut.written.end())
3144 if (iterations == 0 && ! s.suppress_warnings)
3145 {
3146 set<string> vars;
3147
3148 // like collect_functions()
3149 vector<vardecl*>::iterator it;
3150 for (it = s.probes[i]->locals.begin(); it != s.probes[i]->locals.end(); it++)
3151 vars.insert((*it)->unmangled_name);
3152 for (it = s.globals.begin(); it != s.globals.end(); it++)
3153 if (! (*it)->unmangled_name.starts_with("__private_"))
3154 vars.insert((*it)->unmangled_name);
3155
3156 vars.erase(l->name);
3157 string sugs = levenshtein_suggest(l->name, vars, 5); // suggest top 5 vars
3158 s.print_warning (_F("never-assigned local variable '%s'%s",
3159 l->unmangled_name.to_string().c_str(),
3160 (sugs.empty() ? "" :
3161 (_(" (similar: ") + sugs + ")")).c_str()), l->tok);
3162 }
3163 j++;
3164 }
3165 }
3166
3167 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
3168 {
3169 functiondecl *fd = it->second;
3170 for (unsigned j=0; j<fd->locals.size(); /* see below */)
3171 {
3172 vardecl* l = fd->locals[j];
3173 if (vut.read.find (l) == vut.read.end() &&
3174 vut.written.find (l) == vut.written.end())
3175 {
3176 if (!l->tok->location.file->synthetic && s.is_user_file(l->tok->location.file->name))
3177 s.print_warning (_F("Eliding unused variable '%s'",
3178 l->unmangled_name.to_string().c_str()),
3179 l->tok);
3180 if (s.tapset_compile_coverage) {
3181 fd->unused_locals.push_back (fd->locals[j]);
3182 }
3183 fd->locals.erase(fd->locals.begin() + j);
3184 relaxed_p = false;
3185 // don't increment j
3186 }
3187 else
3188 {
3189 if (vut.written.find (l) == vut.written.end())
3190 if (iterations == 0 && ! s.suppress_warnings)
3191 {
3192 set<string> vars;
3193 vector<vardecl*>::iterator it;
3194 for (it = fd->formal_args.begin() ;
3195 it != fd->formal_args.end(); it++)
3196 vars.insert((*it)->unmangled_name);
3197 for (it = fd->locals.begin(); it != fd->locals.end(); it++)
3198 vars.insert((*it)->unmangled_name);
3199 for (it = s.globals.begin(); it != s.globals.end(); it++)
3200 if (! (*it)->unmangled_name.starts_with("__private_"))
3201 vars.insert((*it)->unmangled_name);
3202
3203 vars.erase(l->name);
3204 string sugs = levenshtein_suggest(l->name, vars, 5); // suggest top 5 vars
3205 s.print_warning (_F("never-assigned local variable '%s'%s",
3206 l->unmangled_name.to_string().c_str(),
3207 (sugs.empty() ? "" :
3208 (_(" (similar: ") + sugs + ")")).c_str()), l->tok);
3209 }
3210
3211 j++;
3212 }
3213 }
3214 }
3215 for (unsigned i=0; i<s.globals.size(); /* see below */)
3216 {
3217 vardecl* l = s.globals[i];
3218 if (vut.read.find (l) == vut.read.end() &&
3219 vut.written.find (l) == vut.written.end())
3220 {
3221 if (!l->tok->location.file->synthetic && s.is_user_file(l->tok->location.file->name))
3222 s.print_warning (_F("Eliding unused variable '%s'",
3223 l->unmangled_name.to_string().c_str()),
3224 l->tok);
3225 if (s.tapset_compile_coverage) {
3226 s.unused_globals.push_back(s.globals[i]);
3227 }
3228 s.globals.erase(s.globals.begin() + i);
3229 relaxed_p = false;
3230 // don't increment i
3231 }
3232 else
3233 {
3234 if (vut.written.find (l) == vut.written.end() && ! l->init) // no initializer
3235 if (iterations == 0 && ! s.suppress_warnings)
3236 {
3237 // check if it was initialized on the command line via
3238 // a '-G' option
3239 bool init_by_gopt = false;
3240 string init_prefix (l->unmangled_name.to_string() + "=");
3241 for (auto gi = s.globalopts.begin(); gi != s.globalopts.end();
3242 gi++)
3243 if (! gi->compare(0, init_prefix.size(), init_prefix))
3244 {
3245 init_by_gopt = true;
3246 break;
3247 }
3248 if (! init_by_gopt)
3249 {
3250 set<string> vars;
3251 for (auto it = s.globals.begin(); it != s.globals.end();
3252 it++)
3253 if (l->name != (*it)->unmangled_name)
3254 if (! (*it)->unmangled_name.starts_with("__private_"))
3255 vars.insert((*it)->unmangled_name);
3256
3257 // suggest top 5 vars
3258 string sugs = levenshtein_suggest(l->name, vars, 5);
3259 s.print_warning (_F("never-assigned global variable '%s'%s",
3260 l->unmangled_name.to_string().c_str(),
3261 (sugs.empty() ? "" :
3262 (_(" (similar: ") + sugs + ")")).c_str()),
3263 l->tok);
3264 }
3265 }
3266
3267 i++;
3268 }
3269 }
3270 }
3271
3272
3273 // ------------------------------------------------------------------------
3274
3275 struct dead_assignment_remover: public update_visitor
3276 {
3277 systemtap_session& session;
3278 bool& relaxed_p;
3279 const varuse_collecting_visitor& vut;
3280
3281 dead_assignment_remover(systemtap_session& s, bool& r,
3282 const varuse_collecting_visitor& v):
3283 update_visitor(s.verbose), session(s), relaxed_p(r), vut(v) {}
3284
3285 void visit_assignment (assignment* e);
3286 void visit_try_block (try_block *s);
3287 };
3288
3289
3290 // symbol_fetcher augmented to allow target-symbol types, but NULLed.
3291 struct assignment_symbol_fetcher
3292 : public symbol_fetcher
3293 {
3294 const token* assignment_t;
3295
3296 assignment_symbol_fetcher (symbol *&sym, const token* a_t): symbol_fetcher(sym),
3297 assignment_t(a_t)
3298 {}
3299
3300 void visit_target_symbol (target_symbol*)
3301 {
3302 sym = NULL;
3303 }
3304
3305 void visit_atvar_op (atvar_op*)
3306 {
3307 sym = NULL;
3308 }
3309
3310 void visit_cast_op (cast_op*)
3311 {
3312 sym = NULL;
3313 }
3314
3315 void visit_autocast_op (autocast_op*)
3316 {
3317 sym = NULL;
3318 }
3319
3320 void visit_target_deref (target_deref*)
3321 {
3322 sym = NULL;
3323 }
3324
3325 void visit_target_register (target_register*)
3326 {
3327 sym = NULL;
3328 }
3329
3330 void throwone (const token* t)
3331 {
3332 if (t->type == tok_operator && t->content == ".")
3333 // guess someone misused . in $foo->bar.baz expression
3334 // XXX why are we only checking this in lvalues?
3335 throw SEMANTIC_ERROR (_("Expecting lvalue for assignment, try -> instead"),
3336 assignment_t, t);
3337 else
3338 throw SEMANTIC_ERROR (_("Expecting lvalue for assignment"), assignment_t, t);
3339 }
3340 };
3341
3342 symbol *
3343 get_assignment_symbol_within_expression (expression *e, const token *a_t)
3344 {
3345 symbol *sym = NULL;
3346 assignment_symbol_fetcher fetcher(sym, a_t);
3347 e->visit (&fetcher);
3348 return sym; // NB: may be null!
3349 }
3350
3351
3352 void
3353 dead_assignment_remover::visit_assignment (assignment* e)
3354 {
3355 replace (e->left);
3356 replace (e->right);
3357
3358 symbol* left = get_assignment_symbol_within_expression (e->left, e->tok);
3359 if (left) // not unresolved $target, so intended sideeffect may be elided
3360 {
3361 vardecl* leftvar = left->referent;
3362 if (vut.read.find(leftvar) == vut.read.end()) // var never read?
3363 {
3364 // NB: Not so fast! The left side could be an array whose
3365 // index expressions may have side-effects. This would be
3366 // OK if we could replace the array assignment with a
3367 // statement-expression containing all the index expressions
3368 // and the rvalue... but we can't.
3369 // Another possibility is that we have an unread global variable
3370 // which are kept for probe end value display.
3371
3372 bool is_global = false;
3373 vector<vardecl*>::iterator it;
3374 for (it = session.globals.begin(); it != session.globals.end(); it++)
3375 if (leftvar->name == (*it)->name)
3376 {
3377 is_global = true;
3378 break;
3379 }
3380
3381 varuse_collecting_visitor lvut(session);
3382 e->left->visit (& lvut);
3383 if (lvut.side_effect_free () && !is_global // XXX: use _wrt() once we track focal_vars
3384 && !leftvar->synthetic) // don't elide assignment to synthetic $context variables
3385 {
3386 /* PR 1119: NB: This is not necessary here. A write-only
3387 variable will also be elided soon at the next _opt2 iteration.
3388 if (e->left->tok->location.file->name == session.user_file->name) // !tapset
3389 session.print_warning("eliding write-only ", *e->left->tok);
3390 else
3391 */
3392 if (!e->left->tok->location.file->synthetic && session.is_user_file(e->left->tok->location.file->name))
3393 session.print_warning(_F("Eliding assignment to '%s'",
3394 leftvar->unmangled_name.to_string().c_str()), e->tok);
3395 provide (e->right); // goodbye assignment*
3396 relaxed_p = false;
3397 return;
3398 }
3399 }
3400 }
3401 provide (e);
3402 }
3403
3404
3405 void
3406 dead_assignment_remover::visit_try_block (try_block *s)
3407 {
3408 replace (s->try_block);
3409 if (s->catch_error_var)
3410 {
3411 vardecl* errvar = s->catch_error_var->referent;
3412 if (vut.read.find(errvar) == vut.read.end()) // never read?
3413 {
3414 if (session.verbose>2)
3415 clog << _F("Eliding unused error string catcher %s at %s",
3416 errvar->unmangled_name.to_string().c_str(),
3417 lex_cast(*s->tok).c_str()) << endl;
3418 s->catch_error_var = 0;
3419 }
3420 }
3421 replace (s->catch_block);
3422 provide (s);
3423 }
3424
3425
3426 // Let's remove assignments to variables that are never read. We
3427 // rewrite "(foo = expr)" as "(expr)". This makes foo a candidate to
3428 // be optimized away as an unused variable, and expr a candidate to be
3429 // removed as a side-effect-free statement expression. Wahoo!
3430 void semantic_pass_opt3 (systemtap_session& s, bool& relaxed_p)
3431 {
3432 // Recompute the varuse data, which will probably match the opt2
3433 // copy of the computation, except for those totally unused
3434 // variables that opt2 removed.
3435 varuse_collecting_visitor vut(s);
3436 for (unsigned i=0; i<s.probes.size(); i++)
3437 s.probes[i]->body->visit (& vut); // includes reachable functions too
3438
3439 dead_assignment_remover dar (s, relaxed_p, vut);
3440 // This instance may be reused for multiple probe/function body trims.
3441
3442 for (unsigned i=0; i<s.probes.size(); i++)
3443 dar.replace (s.probes[i]->body);
3444 for (map<string,functiondecl*>::iterator it = s.functions.begin();
3445 it != s.functions.end(); it++)
3446 dar.replace (it->second->body);
3447 // The rewrite operation is performed within the visitor.
3448
3449 // XXX: we could also zap write-only globals here
3450 }
3451
3452
3453 // ------------------------------------------------------------------------
3454
3455 struct dead_stmtexpr_remover: public update_visitor
3456 {
3457 systemtap_session& session;
3458 bool& relaxed_p;
3459 set<vardecl*> focal_vars; // vars considered subject to side-effects
3460
3461 dead_stmtexpr_remover(systemtap_session& s, bool& r):
3462 update_visitor(s.verbose), session(s), relaxed_p(r) {}
3463
3464 void visit_block (block *s);
3465 void visit_try_block (try_block *s);
3466 void visit_null_statement (null_statement *s);
3467 void visit_if_statement (if_statement* s);
3468 void visit_foreach_loop (foreach_loop *s);
3469 void visit_for_loop (for_loop *s);
3470 // XXX: and other places where stmt_expr's might be nested
3471
3472 void visit_expr_statement (expr_statement *s);
3473 };
3474
3475
3476 void
3477 dead_stmtexpr_remover::visit_null_statement (null_statement *s)
3478 {
3479 // easy!
3480 if (session.verbose>2)
3481 clog << _("Eliding side-effect-free null statement ") << *s->tok << endl;
3482 s = 0;
3483 provide (s);
3484 }
3485
3486
3487 void
3488 dead_stmtexpr_remover::visit_block (block *s)
3489 {
3490 vector<statement*> new_stmts;
3491 for (unsigned i=0; i<s->statements.size(); i++ )
3492 {
3493 statement* new_stmt = require (s->statements[i], true);
3494 if (new_stmt != 0)
3495 {
3496 // flatten nested blocks into this one
3497 block *b = dynamic_cast<block *>(new_stmt);
3498 if (b)
3499 {
3500 if (session.verbose>2)
3501 clog << _("Flattening nested block ") << *b->tok << endl;
3502 new_stmts.insert(new_stmts.end(),
3503 b->statements.begin(), b->statements.end());
3504 relaxed_p = false;
3505 }
3506 else
3507 new_stmts.push_back (new_stmt);
3508 }
3509 }
3510 if (new_stmts.size() == 0)
3511 {
3512 if (session.verbose>2)
3513 clog << _("Eliding side-effect-free empty block ") << *s->tok << endl;
3514 s = 0;
3515 }
3516 else if (new_stmts.size() == 1)
3517 {
3518 if (session.verbose>2)
3519 clog << _("Eliding side-effect-free singleton block ") << *s->tok << endl;
3520 provide (new_stmts[0]);
3521 return;
3522 }
3523 else
3524 s->statements = new_stmts;
3525 provide (s);
3526 }
3527
3528
3529 void
3530 dead_stmtexpr_remover::visit_try_block (try_block *s)
3531 {
3532 replace (s->try_block, true);
3533 replace (s->catch_block, true); // null catch{} is ok and useful
3534 if (s->try_block == 0)
3535 {
3536 if (session.verbose>2)
3537 clog << _("Eliding empty try {} block ") << *s->tok << endl;
3538 s = 0;
3539 }
3540 provide (s);
3541 }
3542
3543
3544 void
3545 dead_stmtexpr_remover::visit_if_statement (if_statement *s)
3546 {
3547 replace (s->thenblock, true);
3548 replace (s->elseblock, true);
3549
3550 if (s->thenblock == 0)
3551 {
3552 if (s->elseblock == 0)
3553 {
3554 // We may be able to elide this statement, if the condition
3555 // expression is side-effect-free.
3556 varuse_collecting_visitor vct(session);
3557 s->condition->visit(& vct);
3558 if (vct.side_effect_free ())
3559 {
3560 if (session.verbose>2)
3561 clog << _("Eliding side-effect-free if statement ")
3562 << *s->tok << endl;
3563 s = 0; // yeah, baby
3564 }
3565 else
3566 {
3567 // We can still turn it into a simple expr_statement though...
3568 if (session.verbose>2)
3569 clog << _("Creating simple evaluation from if statement ")
3570 << *s->tok << endl;
3571 expr_statement *es = new expr_statement;
3572 es->value = s->condition;
3573 es->tok = es->value->tok;
3574 provide (es);
3575 return;
3576 }
3577 }
3578 else
3579 {
3580 // For an else without a then, we can invert the condition logic to
3581 // avoid having a null statement in the thenblock
3582 if (session.verbose>2)
3583 clog << _("Inverting the condition of if statement ")
3584 << *s->tok << endl;
3585 unary_expression *ue = new unary_expression;
3586 ue->operand = s->condition;
3587 ue->tok = ue->operand->tok;
3588 ue->op = "!";
3589 s->condition = ue;
3590 s->thenblock = s->elseblock;
3591 s->elseblock = 0;
3592 }
3593 }
3594 provide (s);
3595 }
3596
3597 void
3598 dead_stmtexpr_remover::visit_foreach_loop (foreach_loop *s)
3599 {
3600 replace (s->block, true);
3601
3602 if (s->block == 0)
3603 {
3604 // XXX what if s->limit has side effects?
3605 // XXX what about s->indexes or s->value used outside the loop?
3606 if(session.verbose > 2)
3607 clog << _("Eliding side-effect-free foreach statement ") << *s->tok << endl;
3608 s = 0; // yeah, baby
3609 }
3610 provide (s);
3611 }
3612
3613 void
3614 dead_stmtexpr_remover::visit_for_loop (for_loop *s)
3615 {
3616 replace (s->block, true);
3617
3618 if (s->block == 0)
3619 {
3620 // We may be able to elide this statement, if the condition
3621 // expression is side-effect-free.
3622 varuse_collecting_visitor vct(session);
3623 if (s->init) s->init->visit(& vct);
3624 s->cond->visit(& vct);
3625 if (s->incr) s->incr->visit(& vct);
3626 if (vct.side_effect_free ())
3627 {
3628 if (session.verbose>2)
3629 clog << _("Eliding side-effect-free for statement ") << *s->tok << endl;
3630 s = 0; // yeah, baby
3631 }
3632 else
3633 {
3634 // Can't elide this whole statement; put a null in there.
3635 s->block = new null_statement(s->tok);
3636 }
3637 }
3638 provide (s);
3639 }
3640
3641
3642
3643 void
3644 dead_stmtexpr_remover::visit_expr_statement (expr_statement *s)
3645 {
3646 // Run a varuse query against the operand expression. If it has no
3647 // side-effects, replace the entire statement expression by a null
3648 // statement with the provide() call.
3649 //
3650 // Unlike many other visitors, we do *not* traverse this outermost
3651 // one into the expression subtrees. There is no need - no
3652 // expr_statement nodes will be found there. (Function bodies
3653 // need to be visited explicitly by our caller.)
3654 //
3655 // NB. While we don't share nodes in the parse tree, let's not
3656 // deallocate *s anyway, just in case...
3657
3658 varuse_collecting_visitor vut(session);
3659 s->value->visit (& vut);
3660
3661 if (vut.side_effect_free_wrt (focal_vars))
3662 {
3663 /* PR 1119: NB: this message is not a good idea here. It can
3664 name some arbitrary RHS expression of an assignment.
3665 if (s->value->tok->location.file->name == session.user_file->name) // not tapset
3666 session.print_warning("eliding never-assigned ", *s->value->tok);
3667 else
3668 */
3669 if (!s->value->tok->location.file->synthetic && session.is_user_file(s->value->tok->location.file->name))
3670 session.print_warning("Eliding side-effect-free expression ", s->tok);
3671
3672 // NB: this 0 pointer is invalid to leave around for any length of
3673 // time, but the parent parse tree objects above handle it.
3674 s = 0;
3675 relaxed_p = false;
3676 }
3677 provide (s);
3678 }
3679
3680
3681 void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
3682 {
3683 // Finally, let's remove some statement-expressions that have no
3684 // side-effect. These should be exactly those whose private varuse
3685 // visitors come back with an empty "written" and "embedded" lists.
3686
3687 dead_stmtexpr_remover duv (s, relaxed_p);
3688 // This instance may be reused for multiple probe/function body trims.
3689
3690 for (unsigned i=0; i<s.probes.size(); i++)
3691 {
3692 assert_no_interrupts();
3693
3694 derived_probe* p = s.probes[i];
3695
3696 duv.focal_vars.clear ();
3697 duv.focal_vars.insert (s.globals.begin(),
3698 s.globals.end());
3699 duv.focal_vars.insert (p->locals.begin(),
3700 p->locals.end());
3701
3702 duv.replace (p->body, true);
3703 if (p->body == 0)
3704 {
3705 if (! s.timing && // PR10070
3706 !(p->base->tok->location.file->synthetic)) // don't warn for synthetic probes
3707 s.print_warning (_("side-effect-free probe"), p->tok);
3708
3709 p->body = new null_statement(p->tok);
3710
3711 // XXX: possible duplicate warnings; see below
3712 }
3713 }
3714 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
3715 {
3716 assert_no_interrupts();
3717
3718 functiondecl* fn = it->second;
3719 duv.focal_vars.clear ();
3720 duv.focal_vars.insert (fn->locals.begin(),
3721 fn->locals.end());
3722 duv.focal_vars.insert (fn->formal_args.begin(),
3723 fn->formal_args.end());
3724 duv.focal_vars.insert (s.globals.begin(),
3725 s.globals.end());
3726
3727 duv.replace (fn->body, true);
3728 if (fn->body == 0)
3729 {
3730 s.print_warning (_F("side-effect-free function '%s'",
3731 fn->unmangled_name.to_string().c_str()),
3732 fn->tok);
3733
3734 fn->body = new null_statement(fn->tok);
3735
3736 // XXX: the next iteration of the outer optimization loop may
3737 // take this new null_statement away again, and thus give us a
3738 // fresh warning. It would be better if this fixup was performed
3739 // only after the relaxation iterations.
3740 // XXX: or else see bug #6469.
3741 }
3742 }
3743 }
3744
3745
3746 // ------------------------------------------------------------------------
3747
3748 // The goal of this visitor is to reduce top-level expressions in void context
3749 // into separate statements that evaluate each subcomponent of the expression.
3750 // The dead-statement-remover can later remove some parts if they have no side
3751 // effects.
3752 //
3753 // All expressions must be overridden here so we never visit their subexpressions
3754 // accidentally. Thus, the only visited expressions should be value of an
3755 // expr_statement.
3756 //
3757 // For an expression to replace its expr_statement with something else, it will
3758 // let the new statement provide(), and then provide(0) for itself. The
3759 // expr_statement will take this as a sign that it's been replaced.
3760 struct void_statement_reducer: public update_visitor
3761 {
3762 systemtap_session& session;
3763 bool& relaxed_p;
3764 set<vardecl*> focal_vars; // vars considered subject to side-effects
3765
3766 void_statement_reducer(systemtap_session& s, bool& r):
3767 update_visitor(s.verbose), session(s), relaxed_p(r) {}
3768
3769 void visit_expr_statement (expr_statement* s);
3770
3771 // expressions in conditional / loop controls are definitely a side effect,
3772 // but still recurse into the child statements
3773 void visit_if_statement (if_statement* s);
3774 void visit_for_loop (for_loop* s);
3775 void visit_foreach_loop (foreach_loop* s);
3776
3777 // these expressions get rewritten into their statement equivalents
3778 void visit_logical_or_expr (logical_or_expr* e);
3779 void visit_logical_and_expr (logical_and_expr* e);
3780 void visit_ternary_expression (ternary_expression* e);
3781
3782 // all of these can (usually) be reduced into simpler statements
3783 void visit_binary_expression (binary_expression* e);
3784 void visit_unary_expression (unary_expression* e);
3785 void visit_regex_query (regex_query* e); // XXX depends on subexpr extraction
3786 void visit_comparison (comparison* e);
3787 void visit_concatenation (concatenation* e);
3788 void visit_functioncall (functioncall* e);
3789 void visit_print_format (print_format* e);
3790 void visit_target_symbol (target_symbol* e);
3791 void visit_atvar_op (atvar_op* e);
3792 void visit_cast_op (cast_op* e);
3793 void visit_autocast_op (autocast_op* e);
3794 void visit_defined_op (defined_op* e);
3795
3796 // these are a bit hairy to grok due to the intricacies of indexables and
3797 // stats, so I'm chickening out and skipping them...
3798 void visit_array_in (array_in* e) { provide (e); }
3799 void visit_arrayindex (arrayindex* e) { provide (e); }
3800 void visit_stat_op (stat_op* e) { provide (e); }
3801 void visit_hist_op (hist_op* e) { provide (e); }
3802
3803 // these can't be reduced because they always have an effect
3804 void visit_return_statement (return_statement* s) { provide (s); }
3805 void visit_delete_statement (delete_statement* s) { provide (s); }
3806 void visit_pre_crement (pre_crement* e) { provide (e); }
3807 void visit_post_crement (post_crement* e) { provide (e); }
3808 void visit_assignment (assignment* e) { provide (e); }
3809
3810 private:
3811 void reduce_target_symbol (target_symbol* e, expression* operand=NULL);
3812 };
3813
3814
3815 void
3816 void_statement_reducer::visit_expr_statement (expr_statement* s)
3817 {
3818 replace (s->value, true);
3819
3820 // if the expression provides 0, that's our signal that a new
3821 // statement has been provided, so we shouldn't provide this one.
3822 if (s->value != 0)
3823 provide(s);
3824 }
3825
3826 void
3827 void_statement_reducer::visit_if_statement (if_statement* s)
3828 {
3829 // s->condition is never void
3830 replace (s->thenblock);
3831 replace (s->elseblock);
3832 provide (s);
3833 }
3834
3835 void
3836 void_statement_reducer::visit_for_loop (for_loop* s)
3837 {
3838 // s->init/cond/incr are never void
3839 replace (s->block);
3840 provide (s);
3841 }
3842
3843 void
3844 void_statement_reducer::visit_foreach_loop (foreach_loop* s)
3845 {
3846 // s->indexes/base/value/limit are never void
3847 replace (s->block);
3848 provide (s);
3849 }
3850
3851 void
3852 void_statement_reducer::visit_logical_or_expr (logical_or_expr* e)
3853 {
3854 // In void context, the evaluation of "a || b" is exactly like
3855 // "if (!a) b", so let's do that instead.
3856
3857 if (session.verbose>2)
3858 clog << _("Creating if statement from unused logical-or ")
3859 << *e->tok << endl;
3860
3861 if_statement *is = new if_statement;
3862 is->tok = e->tok;
3863 is->elseblock = 0;
3864
3865 unary_expression *ue = new unary_expression;
3866 ue->operand = e->left;
3867 ue->tok = e->tok;
3868 ue->op = "!";
3869 is->condition = ue;
3870
3871 expr_statement *es = new expr_statement;
3872 es->value = e->right;
3873 es->tok = es->value->tok;
3874 is->thenblock = es;
3875
3876 is->visit(this);
3877 relaxed_p = false;
3878 e = 0;
3879 provide (e);
3880 }
3881
3882 void
3883 void_statement_reducer::visit_logical_and_expr (logical_and_expr* e)
3884 {
3885 // In void context, the evaluation of "a && b" is exactly like
3886 // "if (a) b", so let's do that instead.
3887
3888 if (session.verbose>2)
3889 clog << _("Creating if statement from unused logical-and ")
3890 << *e->tok << endl;
3891
3892 if_statement *is = new if_statement;
3893 is->tok = e->tok;
3894 is->elseblock = 0;
3895 is->condition = e->left;
3896
3897 expr_statement *es = new expr_statement;
3898 es->value = e->right;
3899 es->tok = es->value->tok;
3900 is->thenblock = es;
3901
3902 is->visit(this);
3903 relaxed_p = false;
3904 e = 0;
3905 provide (e);
3906 }
3907
3908 void
3909 void_statement_reducer::visit_ternary_expression (ternary_expression* e)
3910 {
3911 // In void context, the evaluation of "a ? b : c" is exactly like
3912 // "if (a) b else c", so let's do that instead.
3913
3914 if (session.verbose>2)
3915 clog << _("Creating if statement from unused ternary expression ")
3916 << *e->tok << endl;
3917
3918 if_statement *is = new if_statement;
3919 is->tok = e->tok;
3920 is->condition = e->cond;
3921
3922 expr_statement *es = new expr_statement;
3923 es->value = e->truevalue;
3924 es->tok = es->value->tok;
3925 is->thenblock = es;
3926
3927 es = new expr_statement;
3928 es->value = e->falsevalue;
3929 es->tok = es->value->tok;
3930 is->elseblock = es;
3931
3932 is->visit(this);
3933 relaxed_p = false;
3934 e = 0;
3935 provide (e);
3936 }
3937
3938 void
3939 void_statement_reducer::visit_binary_expression (binary_expression* e)
3940 {
3941 // When the result of a binary operation isn't needed, it's just as good to
3942 // evaluate the operands as sequential statements in a block.
3943
3944 if (session.verbose>2)
3945 clog << _("Eliding unused binary ") << *e->tok << endl;
3946
3947 block *b = new block;
3948 b->tok = e->tok;
3949
3950 expr_statement *es = new expr_statement;
3951 es->value = e->left;
3952 es->tok = es->value->tok;
3953 b->statements.push_back(es);
3954
3955 es = new expr_statement;
3956 es->value = e->right;
3957 es->tok = es->value->tok;
3958 b->statements.push_back(es);
3959
3960 b->visit(this);
3961 relaxed_p = false;
3962 e = 0;
3963 provide (e);
3964 }
3965
3966 void
3967 void_statement_reducer::visit_unary_expression (unary_expression* e)
3968 {
3969 // When the result of a unary operation isn't needed, it's just as good to
3970 // evaluate the operand directly
3971
3972 if (session.verbose>2)
3973 clog << _("Eliding unused unary ") << *e->tok << endl;
3974
3975 relaxed_p = false;
3976 e->operand->visit(this);
3977 }
3978
3979 void
3980 void_statement_reducer::visit_regex_query (regex_query* e)
3981 {
3982 // TODOXXX After subexpression extraction is implemented,
3983 // regular expression matches *may* have side-effects in
3984 // terms of producing matched subexpressions, e.g.:
3985 //
3986 // str =~ "pat"; println(matched(0));
3987 //
3988 // It's debatable if we want to actually allow this, though.
3989
3990 // Treat e as a unary expression on the left operand -- since the
3991 // right hand side must be a literal (as verified by the parser),
3992 // evaluating it never has side effects.
3993
3994 if (session.verbose>2)
3995 clog << _("Eliding regex query ") << *e->tok << endl;
3996
3997 relaxed_p = false;
3998 e->left->visit(this);
3999 }
4000
4001 void
4002 void_statement_reducer::visit_comparison (comparison* e)
4003 {
4004 visit_binary_expression(e);
4005 }
4006
4007 void
4008 void_statement_reducer::visit_concatenation (concatenation* e)
4009 {
4010 visit_binary_expression(e);
4011 }
4012
4013 void
4014 void_statement_reducer::visit_functioncall (functioncall* e)
4015 {
4016 // If a function call is pure and its result ignored, we can elide the call
4017 // and just evaluate the arguments in sequence
4018
4019 if (e->args.empty())
4020 {
4021 provide (e);
4022 return;
4023 }
4024
4025 bool side_effect_free = true;
4026 for (unsigned i = 0; i < e->referents.size(); i++)
4027 {
4028 varuse_collecting_visitor vut(session);
4029 vut.seen.insert (e->referents[i]);
4030 vut.current_function = e->referents[i];
4031 e->referents[i]->body->visit (& vut);
4032 if (!vut.side_effect_free_wrt(focal_vars))
4033 {
4034 side_effect_free = false;
4035 break;
4036 }
4037 }
4038
4039 if (!side_effect_free)
4040 {
4041 provide (e);
4042 return;
4043 }
4044
4045 if (session.verbose>2)
4046 clog << _("Eliding side-effect-free function call ") << *e->tok << endl;
4047
4048 block *b = new block;
4049 b->tok = e->tok;
4050
4051 for (unsigned i=0; i<e->args.size(); i++ )
4052 {
4053 expr_statement *es = new expr_statement;
4054 es->value = e->args[i];
4055 es->tok = es->value->tok;
4056 b->statements.push_back(es);
4057 }
4058
4059 b->visit(this);
4060 relaxed_p = false;
4061 e = 0;
4062 provide (e);
4063 }
4064
4065 void
4066 void_statement_reducer::visit_print_format (print_format* e)
4067 {
4068 // When an sprint's return value is ignored, we can simply evaluate the
4069 // arguments in sequence
4070
4071 if (e->print_to_stream || !e->args.size())
4072 {
4073 provide (e);
4074 return;
4075 }
4076
4077 if (session.verbose>2)
4078 clog << _("Eliding unused print ") << *e->tok << endl;
4079
4080 block *b = new block;
4081 b->tok = e->tok;
4082
4083 for (unsigned i=0; i<e->args.size(); i++ )
4084 {
4085 expr_statement *es = new expr_statement;
4086 es->value = e->args[i];
4087 es->tok = es->value->tok;
4088 b->statements.push_back(es);
4089 }
4090
4091 b->visit(this);
4092 relaxed_p = false;
4093 e = 0;
4094 provide (e);
4095 }
4096
4097 void
4098 void_statement_reducer::reduce_target_symbol (target_symbol* e,
4099 expression* operand)
4100 {
4101 // When the result of any target_symbol isn't needed, it's just as good to
4102 // evaluate the operand and any array indexes directly
4103
4104 block *b = new block;
4105 b->tok = e->tok;
4106
4107 if (operand)
4108 {
4109 expr_statement *es = new expr_statement;
4110 es->value = operand;
4111 es->tok = es->value->tok;
4112 b->statements.push_back(es);
4113 }
4114
4115 for (unsigned i=0; i<e->components.size(); i++ )
4116 {
4117 if (e->components[i].type != target_symbol::comp_expression_array_index)
4118 continue;
4119
4120 expr_statement *es = new expr_statement;
4121 es->value = e->components[i].expr_index;
4122 es->tok = es->value->tok;
4123 b->statements.push_back(es);
4124 }
4125
4126 b->visit(this);
4127 relaxed_p = false;
4128 e = 0;
4129 provide (e);
4130 }
4131
4132 void
4133 void_statement_reducer::visit_atvar_op (atvar_op* e)
4134 {
4135 if (session.verbose>2)
4136 clog << _("Eliding unused target symbol ") << *e->tok << endl;
4137 reduce_target_symbol (e);
4138 }
4139
4140 void
4141 void_statement_reducer::visit_target_symbol (target_symbol* e)
4142 {
4143 if (session.verbose>2)
4144 clog << _("Eliding unused target symbol ") << *e->tok << endl;
4145 reduce_target_symbol (e);
4146 }
4147
4148 void
4149 void_statement_reducer::visit_cast_op (cast_op* e)
4150 {
4151 if (session.verbose>2)
4152 clog << _("Eliding unused typecast ") << *e->tok << endl;
4153 reduce_target_symbol (e, e->operand);
4154 }
4155
4156 void
4157 void_statement_reducer::visit_autocast_op (autocast_op* e)
4158 {
4159 if (session.verbose>2)
4160 clog << _("Eliding unused autocast ") << *e->tok << endl;
4161 reduce_target_symbol (e, e->operand);
4162 }
4163
4164
4165 void
4166 void_statement_reducer::visit_defined_op (defined_op* e)
4167 {
4168 // When the result of a @defined operation isn't needed, just elide
4169 // it entirely. Its operand $expression must already be
4170 // side-effect-free.
4171
4172 if (session.verbose>2)
4173 clog << _("Eliding unused check ") << *e->tok << endl;
4174
4175 relaxed_p = false;
4176 e = 0;
4177 provide (e);
4178 }
4179
4180 void semantic_pass_opt5 (systemtap_session& s, bool& relaxed_p)
4181 {
4182 // Let's simplify statements with unused computed values.
4183
4184 void_statement_reducer vuv (s, relaxed_p);
4185 // This instance may be reused for multiple probe/function body trims.
4186
4187 vuv.focal_vars.insert (s.globals.begin(), s.globals.end());
4188
4189 for (unsigned i=0; i<s.probes.size(); i++)
4190 vuv.replace (s.probes[i]->body);
4191 for (map<string,functiondecl*>::iterator it = s.functions.begin();
4192 it != s.functions.end(); it++)
4193 vuv.replace (it->second->body);
4194 }
4195
4196
4197
4198 void
4199 const_folder::get_literal(expression*& e,
4200 literal_number*& n,
4201 literal_string*& s)
4202 {
4203 replace (e);
4204 n = (e == last_number) ? last_number : NULL;
4205 s = (e == last_string) ? last_string : NULL;
4206 }
4207
4208 literal_number*
4209 const_folder::get_number(expression*& e)
4210 {
4211 replace (e);
4212 return (e == last_number) ? last_number : NULL;
4213 }
4214
4215 void
4216 const_folder::visit_literal_number (literal_number* e)
4217 {
4218 last_number = e;
4219 provide (e);
4220 }
4221
4222 literal_string*
4223 const_folder::get_string(expression*& e)
4224 {
4225 replace (e);
4226 return (e == last_string) ? last_string : NULL;
4227 }
4228
4229 void
4230 const_folder::visit_literal_string (literal_string* e)
4231 {
4232 last_string = e;
4233 provide (e);
4234 }
4235
4236 void
4237 const_folder::visit_if_statement (if_statement* s)
4238 {
4239 literal_number* cond = get_number (s->condition);
4240 if (!cond)
4241 {
4242 replace (s->thenblock);
4243 replace (s->elseblock);
4244 provide (s);
4245 }
4246 else
4247 {
4248 if (session.verbose>2)
4249 clog << _F("Collapsing constant-%" PRIi64 " if-statement %s",
4250 cond->value, lex_cast(*s->tok).c_str()) << endl;
4251 relaxed_p = false;
4252
4253 statement* n = cond->value ? s->thenblock : s->elseblock;
4254 if (n)
4255 n->visit (this);
4256 else
4257 provide (new null_statement (s->tok));
4258 }
4259 }
4260
4261 void
4262 const_folder::visit_for_loop (for_loop* s)
4263 {
4264 literal_number* cond = get_number (s->cond);
4265 if (!cond || cond->value)
4266 {
4267 replace (s->init);
4268 replace (s->incr);
4269 replace (s->block);
4270 provide (s);
4271 }
4272 else
4273 {
4274 if (session.verbose>2)
4275 clog << _("Collapsing constantly-false for-loop ") << *s->tok << endl;
4276 relaxed_p = false;
4277
4278 if (s->init)
4279 s->init->visit (this);
4280 else
4281 provide (new null_statement (s->tok));
4282 }
4283 }
4284
4285 void
4286 const_folder::visit_foreach_loop (foreach_loop* s)
4287 {
4288 literal_number* limit = get_number (s->limit);
4289 if (!limit || limit->value > 0)
4290 {
4291 for (unsigned i = 0; i < s->indexes.size(); ++i)
4292 replace (s->indexes[i]);
4293 replace (s->base);
4294 replace (s->value);
4295 replace (s->block);
4296 provide (s);
4297 }
4298 else
4299 {
4300 if (session.verbose>2)
4301 clog << _("Collapsing constantly-limited foreach-loop ") << *s->tok << endl;
4302 relaxed_p = false;
4303
4304 provide (new null_statement (s->tok));
4305 }
4306 }
4307
4308 void
4309 const_folder::visit_binary_expression (binary_expression* e)
4310 {
4311 int64_t value;
4312 literal_number* left = get_number (e->left);
4313 literal_number* right = get_number (e->right);
4314
4315 if (right && !right->value && (e->op == "/" || e->op == "%"))
4316 {
4317 // Give divide-by-zero a chance to be optimized out elsewhere,
4318 // and if not it will be a runtime error anyway...
4319 provide (e);
4320 return;
4321 }
4322
4323 if (left && right)
4324 {
4325 if (e->op == "+")
4326 value = left->value + right->value;
4327 else if (e->op == "-")
4328 value = left->value - right->value;
4329 else if (e->op == "*")
4330 value = left->value * right->value;
4331 else if (e->op == "&")
4332 value = left->value & right->value;
4333 else if (e->op == "|")
4334 value = left->value | right->value;
4335 else if (e->op == "^")
4336 value = left->value ^ right->value;
4337 else if (e->op == ">>")
4338 value = left->value >> max(min(right->value, (int64_t)64), (int64_t)0);
4339 else if (e->op == "<<")
4340 value = left->value << max(min(right->value, (int64_t)64), (int64_t)0);
4341 else if (e->op == "/")
4342 value = (left->value == LLONG_MIN && right->value == -1) ? LLONG_MIN :
4343 left->value / right->value;
4344 else if (e->op == "%")
4345 value = (left->value == LLONG_MIN && right->value == -1) ? 0 :
4346 left->value % right->value;
4347 else
4348 throw SEMANTIC_ERROR (_("unsupported binary operator ") + (string)e->op);
4349 }
4350
4351 else if ((left && ((left->value == 0 && (e->op == "*" || e->op == "&" ||
4352 e->op == ">>" || e->op == "<<" )) ||
4353 (left->value ==-1 && (e->op == "|" || e->op == ">>"))))
4354 ||
4355 (right && ((right->value == 0 && (e->op == "*" || e->op == "&")) ||
4356 (right->value == 1 && (e->op == "%")) ||
4357 (right->value ==-1 && (e->op == "%" || e->op == "|")))))
4358 {
4359 expression* other = left ? e->right : e->left;
4360 varuse_collecting_visitor vu(session);
4361 other->visit(&vu);
4362 if (!vu.side_effect_free())
4363 {
4364 provide (e);
4365 return;
4366 }
4367
4368 // we'll pass on type=pe_long inference to the expression
4369 if (other->type == pe_unknown)
4370 other->type = pe_long;
4371 else if (other->type != pe_long)
4372 {
4373 // this mismatch was not caught in the initial type resolution pass,
4374 // generate a mismatch (left doesn't match right) error
4375 typeresolution_info ti(session);
4376 ti.assert_resolvability = true; // need this to get it throw errors
4377 ti.mismatch_complexity = 1; // also needed to throw errors
4378 ti.mismatch(e);
4379 }
4380
4381 if (left)
4382 value = left->value;
4383 else if (e->op == "%")
4384 value = 0;
4385 else
4386 value = right->value;
4387 }
4388
4389 else if ((left && ((left->value == 0 && (e->op == "+" || e->op == "|" ||
4390 e->op == "^")) ||
4391 (left->value == 1 && (e->op == "*")) ||
4392 (left->value ==-1 && (e->op == "&"))))
4393 ||
4394 (right && ((right->value == 0 && (e->op == "+" || e->op == "-" ||
4395 e->op == "|" || e->op == "^")) ||
4396 (right->value == 1 && (e->op == "*" || e->op == "/")) ||
4397 (right->value ==-1 && (e->op == "&")) ||
4398 (right->value <= 0 && (e->op == ">>" || e->op == "<<")))))
4399 {
4400 if (session.verbose>2)
4401 clog << _("Collapsing constant-identity binary operator ") << *e->tok << endl;
4402 relaxed_p = false;
4403
4404 // we'll pass on type=pe_long inference to the expression
4405 expression* other = left ? e->right : e->left;
4406 if (other->type == pe_unknown)
4407 other->type = pe_long;
4408 else if (other->type != pe_long)
4409 {
4410 // this mismatch was not caught in the initial type resolution pass,
4411 // generate a mismatch (left doesn't match right) error
4412 typeresolution_info ti(session);
4413 ti.assert_resolvability = true; // need this to get it throw errors
4414 ti.mismatch_complexity = 1; // also needed to throw errors
4415 ti.mismatch(e);
4416 }
4417
4418 provide (other);
4419 return;
4420 }
4421
4422 else
4423 {
4424 provide (e);
4425 return;
4426 }
4427
4428 if (session.verbose>2)
4429 clog << _F("Collapsing constant-%" PRIi64 " binary operator %s",
4430 value, lex_cast(*e->tok).c_str()) << endl;
4431 relaxed_p = false;
4432
4433 literal_number* n = new literal_number(value);
4434 n->tok = e->tok;
4435 n->visit (this);
4436 }
4437
4438 void
4439 const_folder::visit_unary_expression (unary_expression* e)
4440 {
4441 literal_number* operand = get_number (e->operand);
4442 if (!operand)
4443 provide (e);
4444 else
4445 {
4446 if (session.verbose>2)
4447 clog << _("Collapsing constant unary ") << *e->tok << endl;
4448 relaxed_p = false;
4449
4450 literal_number* n = new literal_number (*operand);
4451 n->tok = e->tok;
4452 if (e->op == "+")
4453 ; // nothing to do
4454 else if (e->op == "-")
4455 n->value = -n->value;
4456 else if (e->op == "!")
4457 n->value = !n->value;
4458 else if (e->op == "~")
4459 n->value = ~n->value;
4460 else
4461 throw SEMANTIC_ERROR (_("unsupported unary operator ") + (string)e->op);
4462 n->visit (this);
4463 }
4464 }
4465
4466 void
4467 const_folder::visit_logical_or_expr (logical_or_expr* e)
4468 {
4469 int64_t value;
4470 literal_number* left = get_number (e->left);
4471 literal_number* right = get_number (e->right);
4472
4473 if (left && right)
4474 value = left->value || right->value;
4475
4476 else if ((left && left->value) || (right && right->value))
4477 {
4478 // If the const is on the left, we get to short-circuit the right
4479 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
4480 if (right)
4481 {
4482 varuse_collecting_visitor vu(session);
4483 e->left->visit(&vu);
4484 if (!vu.side_effect_free())
4485 {
4486 provide (e);
4487 return;
4488 }
4489 }
4490
4491 value = 1;
4492 }
4493
4494 // We might also get rid of useless "0||x" and "x||0", except it does
4495 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
4496 // that this would gain us much.
4497
4498 else
4499 {
4500 provide (e);
4501 return;
4502 }
4503
4504 if (session.verbose>2)
4505 clog << _("Collapsing constant logical-OR ") << *e->tok << endl;
4506 relaxed_p = false;
4507
4508 literal_number* n = new literal_number(value);
4509 n->tok = e->tok;
4510 n->visit (this);
4511 }
4512
4513 void
4514 const_folder::visit_logical_and_expr (logical_and_expr* e)
4515 {
4516 int64_t value;
4517 literal_number* left = get_number (e->left);
4518 literal_number* right = get_number (e->right);
4519
4520 if (left && right)
4521 value = left->value && right->value;
4522
4523 else if ((left && !left->value) || (right && !right->value))
4524 {
4525 // If the const is on the left, we get to short-circuit the right
4526 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
4527 if (right)
4528 {
4529 varuse_collecting_visitor vu(session);
4530 e->left->visit(&vu);
4531 if (!vu.side_effect_free())
4532 {
4533 provide (e);
4534 return;
4535 }
4536 }
4537
4538 value = 0;
4539 }
4540
4541 // We might also get rid of useless "1&&x" and "x&&1", except it does
4542 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
4543 // that this would gain us much.
4544
4545 else
4546 {
4547 provide (e);
4548 return;
4549 }
4550
4551 if (session.verbose>2)
4552 clog << _("Collapsing constant logical-AND ") << *e->tok << endl;
4553 relaxed_p = false;
4554
4555 literal_number* n = new literal_number(value);
4556 n->tok = e->tok;
4557 n->visit (this);
4558 }
4559
4560 void
4561 const_folder::visit_compound_expression (compound_expression* e)
4562 {
4563 replace(e->left, true);
4564 replace(e->right, false);
4565
4566 // If the LHS is pure, we can eliminate it.
4567 // ??? This is unlikely, given how these are created in loc2stap.cxx.
4568 if (e->left)
4569 {
4570 varuse_collecting_visitor vu(session);
4571 e->left->visit(&vu);
4572 if (!vu.side_effect_free())
4573 {
4574 provide(e);
4575 return;
4576 }
4577 }
4578
4579 if (session.verbose > 2)
4580 clog << _("Collapsing compound expression") << *e->tok << endl;
4581
4582 provide(e->right);
4583 }
4584
4585 void
4586 const_folder::visit_comparison (comparison* e)
4587 {
4588 int comp;
4589
4590 literal_number *left_num, *right_num;
4591 literal_string *left_str, *right_str;
4592 get_literal(e->left, left_num, left_str);
4593 get_literal(e->right, right_num, right_str);
4594
4595 if (left_str && right_str)
4596 comp = left_str->value.compare(right_str->value);
4597
4598 else if (left_num && right_num)
4599 comp = left_num->value < right_num->value ? -1 :
4600 left_num->value > right_num->value ? 1 : 0;
4601
4602 else if ((left_num && ((left_num->value == LLONG_MIN &&
4603 (e->op == "<=" || e->op == ">")) ||
4604 (left_num->value == LLONG_MAX &&
4605 (e->op == ">=" || e->op == "<"))))
4606 ||
4607 (right_num && ((right_num->value == LLONG_MIN &&
4608 (e->op == ">=" || e->op == "<")) ||
4609 (right_num->value == LLONG_MAX &&
4610 (e->op == "<=" || e->op == ">")))))
4611 {
4612 expression* other = left_num ? e->right : e->left;
4613 varuse_collecting_visitor vu(session);
4614 other->visit(&vu);
4615 if (!vu.side_effect_free())
4616 provide (e);
4617 else
4618 {
4619 if (session.verbose>2)
4620 clog << _("Collapsing constant-boundary comparison ") << *e->tok << endl;
4621 relaxed_p = false;
4622
4623 // ops <= and >= are true, < and > are false
4624 literal_number* n = new literal_number( e->op.length() == 2 );
4625 n->tok = e->tok;
4626 n->visit (this);
4627 }
4628 return;
4629 }
4630
4631 else
4632 {
4633 provide (e);
4634 return;
4635 }
4636
4637 if (session.verbose>2)
4638 clog << _("Collapsing constant comparison ") << *e->tok << endl;
4639 relaxed_p = false;
4640
4641 int64_t value;
4642 if (e->op == "==")
4643 value = comp == 0;
4644 else if (e->op == "!=")
4645 value = comp != 0;
4646 else if (e->op == "<")
4647 value = comp < 0;
4648 else if (e->op == ">")
4649 value = comp > 0;
4650 else if (e->op == "<=")
4651 value = comp <= 0;
4652 else if (e->op == ">=")
4653 value = comp >= 0;
4654 else
4655 throw SEMANTIC_ERROR (_("unsupported comparison operator ") + (string)e->op);
4656
4657 literal_number* n = new literal_number(value);
4658 n->tok = e->tok;
4659 n->visit (this);
4660 }
4661
4662 void
4663 const_folder::visit_concatenation (concatenation* e)
4664 {
4665 literal_string* left = get_string (e->left);
4666 literal_string* right = get_string (e->right);
4667
4668 if (left && right)
4669 {
4670 if (session.verbose>2)
4671 clog << _("Collapsing constant concatenation ") << *e->tok << endl;
4672 relaxed_p = false;
4673
4674 literal_string* n = new literal_string (*left);
4675 n->tok = e->tok;
4676 n->value = (string)n->value + (string)right->value;
4677 n->visit (this);
4678 }
4679 else if ((left && left->value.empty()) ||
4680 (right && right->value.empty()))
4681 {
4682 if (session.verbose>2)
4683 clog << _("Collapsing identity concatenation ") << *e->tok << endl;
4684 relaxed_p = false;
4685 provide(left ? e->right : e->left);
4686 }
4687 else
4688 provide (e);
4689 }
4690
4691 void
4692 const_folder::visit_ternary_expression (ternary_expression* e)
4693 {
4694 literal_number* cond = get_number (e->cond);
4695 if (!cond)
4696 {
4697 replace (e->truevalue);
4698 replace (e->falsevalue);
4699 provide (e);
4700 }
4701 else
4702 {
4703 if (session.verbose>2)
4704 clog << _F("Collapsing constant-%" PRIi64 " ternary %s",
4705 cond->value, lex_cast(*e->tok).c_str()) << endl;
4706 relaxed_p = false;
4707
4708 expression* n = cond->value ? e->truevalue : e->falsevalue;
4709 n->visit (this);
4710 }
4711 }
4712
4713 void
4714 const_folder::visit_defined_op (defined_op* e)
4715 {
4716 // If a @defined makes it this far, then it was not resolved by
4717 // previous efforts. We could assume that therefore it is a big fat
4718 // zero, but for the @defined(autocast) case PR18079, this just
4719 // means that we didn't know yet.
4720 int64_t value = 0;
4721 bool collapse_this = false;
4722
4723 /* PR20672: not true; we run a const_folder iteratively during
4724 initial probe body variable-expansion, when other @defined()s may
4725 be as-yet-unprocessed. We can't presume to map them to zero.
4726
4727 // We do know that plain target_symbols aren't going anywhere though.
4728 if (get_target_symbol (e->operand))
4729 {
4730 if (session.verbose>2)
4731 clog << _("Collapsing target_symbol @defined check ") << *e->tok << endl;
4732 collapse_this = true;
4733 }
4734 else
4735 */
4736 if (collapse_defines_p && relaxed_p)
4737 {
4738 if (session.verbose>2)
4739 clog << _("Collapsing untouched @defined check ") << *e->tok << endl;
4740
4741 // If we got to an expression with a known type, call it defined.
4742 if (e->operand->type != pe_unknown)
4743 value = 1;
4744 collapse_this = true;
4745 }
4746
4747 if (collapse_this)
4748 {
4749 // Don't be greedy... we'll only collapse one at a time so type
4750 // resolution can have another go at it.
4751 relaxed_p = false;
4752 literal_number* n = new literal_number (value);
4753 n->tok = e->tok;
4754 n->visit (this);
4755 }
4756 else
4757 {
4758 if (session.verbose>2)
4759 clog << _("Preserving unresolved @defined check ") << *e->tok << endl;
4760 provide (e);
4761 }
4762 }
4763
4764 target_symbol*
4765 const_folder::get_target_symbol(expression*& e)
4766 {
4767 replace (e);
4768 return (e == last_target_symbol) ? last_target_symbol : NULL;
4769 }
4770
4771 void
4772 const_folder::visit_target_symbol (target_symbol* e)
4773 {
4774 if (collapse_defines_p && session.skip_badvars)
4775 {
4776 // Upon user request for ignoring context, the symbol is replaced
4777 // with a literal 0 and a warning message displayed
4778 // ... but don't do this during early runs of the const_folder, only
4779 // during the final (collapse_defines_p) one. (Otherwise, during
4780 // a dwarf_var "@defined($foo) ? $foo : 0", the inner $foo could
4781 // get premature mapping to 0.
4782 //
4783 // XXX this ignores possible side-effects, e.g. in array indexes
4784 literal_number* ln_zero = new literal_number (0);
4785 ln_zero->tok = e->tok;
4786 provide (ln_zero);
4787 session.print_warning (_("Bad $context variable being substituted with literal 0"),
4788 e->tok);
4789 relaxed_p = false;
4790 }
4791 else
4792 {
4793 update_visitor::visit_target_symbol (e);
4794 last_target_symbol = e;
4795 }
4796 }
4797
4798 static int initial_typeres_pass(systemtap_session& s);
4799 static int semantic_pass_const_fold (systemtap_session& s, bool& relaxed_p)
4800 {
4801 // attempt an initial type resolution pass to see if there are any type
4802 // mismatches before we starting whisking away vars that get switched out
4803 // with a const.
4804
4805 // return if the initial type resolution pass reported errors (type mismatches)
4806 int rc = initial_typeres_pass(s);
4807 if (rc)
4808 {
4809 relaxed_p = true;
4810 return rc;
4811 }
4812
4813 // Let's simplify statements with constant values.
4814 const_folder cf (s, relaxed_p, true /* collapse remaining @defined()->0 now */ );
4815 // This instance may be reused for multiple probe/function body trims.
4816
4817 for (unsigned i=0; i<s.probes.size(); i++)
4818 cf.replace (s.probes[i]->body);
4819 for (map<string,functiondecl*>::iterator it = s.functions.begin();
4820 it != s.functions.end(); it++)
4821 cf.replace (it->second->body);
4822 return 0;
4823 }
4824
4825
4826 struct dead_control_remover: public traversing_visitor
4827 {
4828 systemtap_session& session;
4829 bool& relaxed_p;
4830 statement* control;
4831
4832 dead_control_remover(systemtap_session& s, bool& r):
4833 session(s), relaxed_p(r), control(NULL) {}
4834
4835 void visit_block (block *b);
4836
4837 // When a block contains any of these, the following statements are dead.
4838 void visit_return_statement (return_statement* s) { control = s; }
4839 void visit_next_statement (next_statement* s) { control = s; }
4840 void visit_break_statement (break_statement* s) { control = s; }
4841 void visit_continue_statement (continue_statement* s) { control = s; }
4842 };
4843
4844
4845 void dead_control_remover::visit_block (block* b)
4846 {
4847 vector<statement*>& vs = b->statements;
4848 if (vs.size() == 0) /* else (size_t) size()-1 => very big */
4849 return;
4850 for (size_t i = 0; i < vs.size() - 1; ++i)
4851 {
4852 vs[i]->visit (this);
4853 if (vs[i] == control)
4854 {
4855 session.print_warning(_("statement will never be reached"),
4856 vs[i + 1]->tok);
4857 vs.erase(vs.begin() + i + 1, vs.end());
4858 relaxed_p = false;
4859 break;
4860 }
4861 }
4862 }
4863
4864
4865 static void semantic_pass_dead_control (systemtap_session& s, bool& relaxed_p)
4866 {
4867 // Let's remove code that follow unconditional control statements
4868
4869 dead_control_remover dc (s, relaxed_p);
4870
4871 for (unsigned i=0; i<s.probes.size(); i++)
4872 s.probes[i]->body->visit(&dc);
4873
4874 for (map<string,functiondecl*>::iterator it = s.functions.begin();
4875 it != s.functions.end(); it++)
4876 it->second->body->visit(&dc);
4877 }
4878
4879
4880 // Looks for next statements in function declarations and marks
4881 // them.
4882 struct function_next_check : public traversing_visitor
4883 {
4884 functiondecl* current_function;
4885
4886 function_next_check()
4887 : current_function(0) { }
4888
4889 void visit_next_statement(next_statement*)
4890 {
4891 current_function->has_next = true;
4892 }
4893
4894 void visit_embeddedcode(embeddedcode* s)
4895 {
4896 if (s->code.find("STAP_NEXT;") != string::npos)
4897 current_function->has_next = true;
4898 }
4899 };
4900
4901 struct dead_overload_remover : public traversing_visitor
4902 {
4903 systemtap_session& s;
4904 bool& relaxed_p;
4905
4906 dead_overload_remover(systemtap_session& sess,
4907 bool& r)
4908 : s(sess), relaxed_p(r) { }
4909
4910 void visit_functioncall(functioncall* e);
4911 };
4912
4913 void dead_overload_remover::visit_functioncall(functioncall *e)
4914 {
4915 unsigned reachable = 1;
4916 bool chained = true;
4917
4918 for (unsigned fd = 0; fd < e->referents.size(); fd++)
4919 {
4920 functiondecl* r = e->referents[fd];
4921
4922 // Note that this is not a sound inference but it suffices for most
4923 // cases. It may be the case that there is a 'next' statement in the
4924 // function that will never be executed by the control flow.
4925 // We simply use the presence of a 'next' statement as an indicator
4926 // of a potential fall through. Once a function can't be 'nexted' the
4927 // remaining functions are unreachable.
4928 if (chained && r->has_next)
4929 reachable++;
4930 else
4931 chained = false;
4932 }
4933
4934 if (reachable < e->referents.size())
4935 {
4936 for (unsigned fd = reachable; fd < e->referents.size(); fd++)
4937 {
4938 functiondecl* r = e->referents[fd];
4939 s.print_warning(_("instance of overloaded function will "
4940 "never be reached"), r->tok);
4941 }
4942 e->referents.erase(e->referents.begin()+reachable, e->referents.end());
4943 relaxed_p = false;
4944 }
4945 }
4946
4947 static void semantic_pass_overload(systemtap_session& s, bool& relaxed_p)
4948 {
4949 set<functiondecl*> function_next;
4950 function_next_check fnc;
4951
4952 for (auto it = s.functions.begin(); it != s.functions.end(); ++it)
4953 {
4954 functiondecl* fn = it->second;
4955 fnc.current_function = fn;
4956 fn->body->visit(&fnc);
4957 }
4958
4959 for (auto it = s.probes.begin(); it != s.probes.end(); ++it)
4960 {
4961 dead_overload_remover ovr(s, relaxed_p);
4962 (*it)->body->visit(&ovr);
4963 }
4964
4965 for (auto it = s.functions.begin(); it != s.functions.end(); ++it)
4966 {
4967 dead_overload_remover ovr(s, relaxed_p);
4968 it->second->body->visit(&ovr);
4969 }
4970 }
4971
4972
4973 struct duplicate_function_remover: public functioncall_traversing_visitor
4974 {
4975 systemtap_session& s;
4976 map<functiondecl*, functiondecl*>& duplicate_function_map;
4977
4978 duplicate_function_remover(systemtap_session& sess,
4979 map<functiondecl*, functiondecl*>&dfm):
4980 s(sess), duplicate_function_map(dfm) {};
4981
4982 void visit_functioncall (functioncall* e);
4983 };
4984
4985 void
4986 duplicate_function_remover::visit_functioncall (functioncall *e)
4987 {
4988 functioncall_traversing_visitor::visit_functioncall (e);
4989
4990 // If any of the current function call references points to a function that
4991 // is a duplicate, replace it.
4992 for (unsigned i = 0; i < e->referents.size(); i++)
4993 {
4994 functiondecl* referent = e->referents[i];
4995 if (duplicate_function_map.count(referent) != 0)
4996 {
4997 if (s.verbose>2)
4998 clog << _F("Changing %s reference to %s reference\n",
4999 referent->unmangled_name.to_string().c_str(),
5000 duplicate_function_map[referent]->unmangled_name.to_string().c_str());
5001 e->tok = duplicate_function_map[referent]->tok;
5002 e->function = duplicate_function_map[referent]->name;
5003 e->referents[i] = duplicate_function_map[referent];
5004 }
5005 }
5006 }
5007
5008 static string
5009 get_functionsig (functiondecl* f)
5010 {
5011 ostringstream s;
5012
5013 // Get the "name:args body" of the function in s. We have to
5014 // include the args since the function 'x1(a, b)' is different than
5015 // the function 'x2(b, a)' even if the bodies of the two functions
5016 // are exactly the same.
5017 f->printsig(s);
5018 f->body->print(s);
5019
5020 // printsig puts f->name + ':' on the front. Remove this
5021 // (otherwise, functions would never compare equal).
5022 string str = s.str().erase(0, f->unmangled_name.size() + 1);
5023
5024 // Return the function signature.
5025 return str;
5026 }
5027
5028 void semantic_pass_opt6 (systemtap_session& s, bool& relaxed_p)
5029 {
5030 // Walk through all the functions, looking for duplicates.
5031 map<string, functiondecl*> functionsig_map;
5032 map<functiondecl*, functiondecl*> duplicate_function_map;
5033
5034
5035 vector<functiondecl*> newly_zapped_functions;
5036 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
5037 {
5038 functiondecl *fd = it->second;
5039 string functionsig = get_functionsig(fd);
5040
5041 if (functionsig_map.count(functionsig) == 0)
5042 {
5043 // This function is unique. Remember it.
5044 functionsig_map[functionsig] = fd;
5045 }
5046 else
5047 {
5048 // This function is a duplicate.
5049 duplicate_function_map[fd] = functionsig_map[functionsig];
5050 newly_zapped_functions.push_back (fd);
5051 relaxed_p = false;
5052 }
5053 }
5054 for (unsigned i=0; i<newly_zapped_functions.size(); i++)
5055 {
5056 map<string,functiondecl*>::iterator where = s.functions.find (newly_zapped_functions[i]->name);
5057 assert (where != s.functions.end());
5058 s.functions.erase (where);
5059 }
5060
5061
5062 // If we have duplicate functions, traverse down the tree, replacing
5063 // the appropriate function calls.
5064 // duplicate_function_remover::visit_functioncall() handles the
5065 // details of replacing the function calls.
5066 if (duplicate_function_map.size() != 0)
5067 {
5068 duplicate_function_remover dfr (s, duplicate_function_map);
5069
5070 for (unsigned i=0; i < s.probes.size(); i++)
5071 s.probes[i]->body->visit(&dfr);
5072 }
5073 }
5074
5075 struct stable_analysis: public nop_visitor
5076 {
5077 bool stable;
5078 stable_analysis(): stable(false) {};
5079
5080 void visit_embeddedcode (embeddedcode* s);
5081 };
5082
5083 void stable_analysis::visit_embeddedcode (embeddedcode* s)
5084 {
5085 if (s->tagged_p("/* stable */"))
5086 stable = true;
5087 if (stable && !s->tagged_p("/* pure */"))
5088 throw SEMANTIC_ERROR(_("stable function must also be /* pure */"),
5089 s->tok);
5090 }
5091
5092 // Examines entire subtree for any stable functioncalls.
5093 struct stable_finder: public traversing_visitor
5094 {
5095 bool stable;
5096 set<string>& stable_fcs;
5097 stable_finder(set<string>&s): stable(false), stable_fcs(s) {};
5098 void visit_functioncall (functioncall* e);
5099 };
5100
5101 void stable_finder::visit_functioncall (functioncall* e)
5102 {
5103 if (stable_fcs.find(e->function) != stable_fcs.end())
5104 stable = true;
5105 traversing_visitor::visit_functioncall(e);
5106 }
5107
5108 // Examines current level of block for stable functioncalls.
5109 // Does not descend into sublevels.
5110 struct level_check: public traversing_visitor
5111 {
5112 bool stable;
5113 set<string>& stable_fcs;
5114 level_check(set<string>& s): stable(false), stable_fcs(s) {};
5115
5116 void visit_block (block* s);
5117 void visit_try_block (try_block *s);
5118 void visit_if_statement (if_statement* s);
5119 void visit_for_loop (for_loop* s);
5120 void visit_foreach_loop (foreach_loop* s);
5121 void visit_functioncall (functioncall* s);
5122 };
5123
5124 void level_check::visit_block (block*)
5125 {
5126 }
5127
5128 void level_check::visit_try_block (try_block* s)
5129 {
5130 if (s->catch_error_var)
5131 s->catch_error_var->visit(this);
5132 }
5133
5134 void level_check::visit_if_statement (if_statement* s)
5135 {
5136 s->condition->visit(this);
5137 }
5138
5139 void level_check::visit_for_loop (for_loop* s)
5140 {
5141 if (s->init) s->init->visit(this);
5142 s->cond->visit(this);
5143 if (s->incr) s->incr->visit(this);
5144 }
5145
5146 void level_check::visit_foreach_loop (foreach_loop* s)
5147 {
5148 s->base->visit(this);
5149
5150 for (unsigned i=0; i<s->indexes.size(); i++)
5151 s->indexes[i]->visit(this);
5152
5153 if (s->value)
5154 s->value->visit(this);
5155
5156 if (s->limit)
5157 s->limit->visit(this);
5158 }
5159
5160 void level_check::visit_functioncall (functioncall* e)
5161 {
5162 if (stable_fcs.find(e->function) != stable_fcs.end())
5163 stable = true;
5164 traversing_visitor::visit_functioncall(e);
5165 }
5166
5167 struct stable_functioncall_visitor: public update_visitor
5168 {
5169 systemtap_session& session;
5170 functiondecl* current_function;
5171 derived_probe* current_probe;
5172 set<string>& stable_fcs;
5173 set<string> scope_vars;
5174 map<string,vardecl*> new_vars;
5175 vector<pair<expr_statement*,block*> > new_stmts;
5176 unsigned loop_depth;
5177 block* top_scope;
5178 block* curr_scope;
5179 stable_functioncall_visitor(systemtap_session& s, set<string>& sfc):
5180 update_visitor(s.verbose),
5181 session(s), current_function(0), current_probe(0), stable_fcs(sfc),
5182 loop_depth(0), top_scope(0), curr_scope(0) {};
5183
5184 statement* convert_stmt(statement* s);
5185 void visit_block (block* s);
5186 void visit_try_block (try_block* s);
5187 void visit_if_statement (if_statement* s);
5188 void visit_for_loop (for_loop* s);
5189 void visit_foreach_loop (foreach_loop* s);
5190 void visit_functioncall (functioncall* e);
5191 };
5192
5193 statement* stable_functioncall_visitor::convert_stmt (statement* s)
5194 {
5195 if (top_scope == 0 &&
5196 (dynamic_cast<for_loop*>(s) || dynamic_cast<foreach_loop*>(s)))
5197 {
5198 stable_finder sf(stable_fcs);
5199 s->visit(&sf);
5200 if (sf.stable)
5201 {
5202 block* b = new block;
5203 b->tok = s->tok;
5204 b->statements.push_back(s);
5205 return b;
5206 }
5207 }
5208 else if (top_scope == 0 && !dynamic_cast<block*>(s))
5209 {
5210 level_check lc(stable_fcs);
5211 s->visit(&lc);
5212 if (lc.stable)
5213 {
5214 block* b = new block;
5215 b->tok = s->tok;
5216 b->statements.push_back(s);
5217 return b;
5218 }
5219 }
5220
5221 return s;
5222 }
5223
5224 void stable_functioncall_visitor::visit_block (block* s)
5225 {
5226 block* prev_top_scope = top_scope;
5227 block* prev_scope = curr_scope;
5228 if (loop_depth == 0)
5229 top_scope = s;
5230 curr_scope = s;
5231 set<string> current_vars = scope_vars;
5232
5233 update_visitor::visit_block(s);
5234
5235 if (loop_depth == 0)
5236 top_scope = prev_top_scope;
5237 curr_scope = prev_scope;
5238 scope_vars = current_vars;
5239 }
5240
5241 void stable_functioncall_visitor::visit_try_block (try_block* s)
5242 {
5243 if (s->try_block)
5244 s->try_block = convert_stmt(s->try_block);
5245 replace(s->try_block);
5246 replace(s->catch_error_var);
5247 if (s->catch_block)
5248 s->catch_block = convert_stmt(s->catch_block);
5249 replace(s->catch_block);
5250 provide(s);
5251 }
5252
5253 void stable_functioncall_visitor::visit_if_statement (if_statement* s)
5254 {
5255 block* prev_top_scope = top_scope;
5256
5257 if (loop_depth == 0)
5258 top_scope = 0;
5259 replace(s->condition);
5260 s->thenblock = convert_stmt(s->thenblock);
5261 replace(s->thenblock);
5262 if (loop_depth == 0)
5263 top_scope = 0;
5264 if (s->elseblock)
5265 s->elseblock = convert_stmt(s->elseblock);
5266 replace(s->elseblock);
5267 provide(s);
5268
5269 top_scope = prev_top_scope;
5270 }
5271
5272 void stable_functioncall_visitor::visit_for_loop (for_loop* s)
5273 {
5274 replace(s->init);
5275 replace(s->cond);
5276 replace(s->incr);
5277 loop_depth++;
5278 s->block = convert_stmt(s->block);
5279 replace(s->block);
5280 loop_depth--;
5281 provide(s);
5282 }
5283
5284 void stable_functioncall_visitor::visit_foreach_loop (foreach_loop* s)
5285 {
5286 for (unsigned i = 0; i < s->indexes.size(); ++i)
5287 replace(s->indexes[i]);
5288 replace(s->base);
5289 replace(s->value);
5290 replace(s->limit);
5291 loop_depth++;
5292 s->block = convert_stmt(s->block);
5293 replace(s->block);
5294 loop_depth--;
5295 provide(s);
5296 }
5297
5298 void stable_functioncall_visitor::visit_functioncall (functioncall* e)
5299 {
5300 for (unsigned i = 0; i < e->args.size(); ++i)
5301 replace (e->args[i]);
5302
5303 if (stable_fcs.find(e->function) != stable_fcs.end())
5304 {
5305 string name("__stable_");
5306 name.append(e->function).append("_value");
5307
5308 // Variable potentially not in scope since it is in a sibling block
5309 if (scope_vars.find(e->function) == scope_vars.end())
5310 {
5311 if (new_vars.find(e->function) == new_vars.end())
5312 {
5313 // New variable declaration to store result of function call
5314 vardecl* v = new vardecl;
5315 v->unmangled_name = v->name = name;
5316 v->tok = e->tok;
5317 v->set_arity(0, e->tok);
5318 v->type = e->type;
5319 if (current_function)
5320 current_function->locals.push_back(v);
5321 else
5322 current_probe->locals.push_back(v);
5323 new_vars[e->function] = v;
5324 }
5325
5326 symbol* sym = new symbol;
5327 sym->name = name;
5328 sym->tok = e->tok;
5329 sym->referent = new_vars[e->function];
5330 sym->type = e->type;
5331
5332 functioncall* fc = new functioncall;
5333 fc->tok = e->tok;
5334 fc->function = e->function;
5335 fc->referents = e->referents;
5336 fc->type = e->type;
5337
5338 assignment* a = new assignment;
5339 a->tok = e->tok;
5340 a->op = "=";
5341 a->left = sym;
5342 a->right = fc;
5343 a->type = e->type;
5344
5345 expr_statement* es = new expr_statement;
5346 es->tok = e->tok;
5347 es->value = a;
5348
5349 // Store location of the block to put new declaration.
5350 if (loop_depth != 0)
5351 {
5352 assert(top_scope);
5353 new_stmts.push_back(make_pair(es,top_scope));
5354 }
5355 else
5356 {
5357 assert(curr_scope);
5358 new_stmts.push_back(make_pair(es,curr_scope));
5359 }
5360
5361 scope_vars.insert(e->function);
5362
5363 provide(sym);
5364 }
5365 else
5366 {
5367 symbol* sym = new symbol;
5368 sym->name = name;
5369 sym->tok = e->tok;
5370 sym->referent = new_vars[e->function];
5371 sym->type = e->type;
5372 provide(sym);
5373 }
5374 return;
5375 }
5376
5377 provide(e);
5378 }
5379
5380 // Cache stable embedded-c functioncall results and replace
5381 // all calls with same name using that value to reduce duplicate
5382 // functioncall overhead. Functioncalls are pulled out of any
5383 // top-level loops and put into if/try blocks.
5384 void semantic_pass_opt7(systemtap_session& s)
5385 {
5386 set<string> stable_fcs;
5387 for (map<string,functiondecl*>::iterator it = s.functions.begin();
5388 it != s.functions.end(); ++it)
5389 {
5390 functiondecl* fn = (*it).second;
5391 stable_analysis sa;
5392 fn->body->visit(&sa);
5393 if (sa.stable && fn->formal_args.size() == 0)
5394 stable_fcs.insert(fn->name);
5395 }
5396
5397 for (vector<derived_probe*>::iterator it = s.probes.begin();
5398 it != s.probes.end(); ++it)
5399 {
5400 stable_functioncall_visitor t(s, stable_fcs);
5401 t.current_probe = *it;
5402 (*it)->body = t.convert_stmt((*it)->body);
5403 t.replace((*it)->body);
5404
5405 for (vector<pair<expr_statement*,block*> >::iterator st = t.new_stmts.begin();
5406 st != t.new_stmts.end(); ++st)
5407 st->second->statements.insert(st->second->statements.begin(), st->first);
5408 }
5409
5410 for (map<string,functiondecl*>::iterator it = s.functions.begin();
5411 it != s.functions.end(); ++it)
5412 {
5413 functiondecl* fn = (*it).second;
5414 stable_functioncall_visitor t(s, stable_fcs);
5415 t.current_function = fn;
5416 fn->body = t.convert_stmt(fn->body);
5417 t.replace(fn->body);
5418
5419 for (vector<pair<expr_statement*,block*> >::iterator st = t.new_stmts.begin();
5420 st != t.new_stmts.end(); ++st)
5421 st->second->statements.insert(st->second->statements.begin(), st->first);
5422 }
5423 }
5424
5425 static int
5426 semantic_pass_optimize1 (systemtap_session& s)
5427 {
5428 // In this pass, we attempt to rewrite probe/function bodies to
5429 // eliminate some blatantly unnecessary code. This is run before
5430 // type inference, but after symbol resolution and derived_probe
5431 // creation. We run an outer "relaxation" loop that repeats the
5432 // optimizations until none of them find anything to remove.
5433
5434 int rc = 0;
5435
5436 // Save the old value of suppress_warnings, as we will be changing
5437 // it below.
5438 save_and_restore<bool> suppress_warnings(& s.suppress_warnings);
5439
5440 bool relaxed_p = false;
5441 unsigned iterations = 0;
5442 while (! relaxed_p)
5443 {
5444 assert_no_interrupts();
5445
5446 relaxed_p = true; // until proven otherwise
5447
5448 // If the verbosity is high enough, always print warnings (overrides -w),
5449 // or if not, always suppress warnings for every itteration after the first.
5450 if(s.verbose > 2)
5451 s.suppress_warnings = false;
5452 else if (iterations > 0)
5453 s.suppress_warnings = true;
5454
5455 if (!s.unoptimized)
5456 {
5457 semantic_pass_opt1 (s, relaxed_p);
5458 semantic_pass_opt2 (s, relaxed_p, iterations); // produce some warnings only on iteration=0
5459 semantic_pass_opt3 (s, relaxed_p);
5460 semantic_pass_opt4 (s, relaxed_p);
5461 semantic_pass_opt5 (s, relaxed_p);
5462 }
5463
5464 // For listing mode, we need const-folding regardless of optimization so
5465 // that @defined expressions can be properly resolved. PR11360
5466 // We also want it in case variables are used in if/case expressions,
5467 // so enable always. PR11366
5468 // rc is incremented if there is an error that got reported.
5469 rc += semantic_pass_const_fold (s, relaxed_p);
5470
5471 if (!s.unoptimized)
5472 semantic_pass_dead_control (s, relaxed_p);
5473
5474 if (!s.unoptimized)
5475 semantic_pass_overload (s, relaxed_p);
5476
5477 iterations ++;
5478 }
5479
5480 return rc;
5481 }
5482
5483
5484 static int
5485 semantic_pass_optimize2 (systemtap_session& s)
5486 {
5487 // This is run after type inference. We run an outer "relaxation"
5488 // loop that repeats the optimizations until none of them find
5489 // anything to remove.
5490
5491 int rc = 0;
5492
5493 // Save the old value of suppress_warnings, as we will be changing
5494 // it below.
5495 save_and_restore<bool> suppress_warnings(& s.suppress_warnings);
5496
5497 bool relaxed_p = false;
5498 unsigned iterations = 0;
5499 while (! relaxed_p)
5500 {
5501 assert_no_interrupts();
5502 relaxed_p = true; // until proven otherwise
5503
5504 // If the verbosity is high enough, always print warnings (overrides -w),
5505 // or if not, always suppress warnings for every itteration after the first.
5506 if(s.verbose > 2)
5507 s.suppress_warnings = false;
5508 else if (iterations > 0)
5509 s.suppress_warnings = true;
5510
5511 if (!s.unoptimized)
5512 semantic_pass_opt6 (s, relaxed_p);
5513
5514 iterations++;
5515 }
5516
5517 if (!s.unoptimized)
5518 semantic_pass_opt7(s);
5519
5520 return rc;
5521 }
5522
5523
5524
5525 // ------------------------------------------------------------------------
5526 // type resolution
5527
5528 struct autocast_expanding_visitor: public var_expanding_visitor
5529 {
5530 typeresolution_info& ti;
5531 autocast_expanding_visitor (systemtap_session& s, typeresolution_info& ti):
5532 var_expanding_visitor(s), ti(ti) {}
5533
5534 void resolve_functioncall (functioncall* fc)
5535 {
5536 // This is a very limited version of semantic_pass_symbols, but
5537 // we're late in the game at this point (after basic symbol
5538 // resolution already took place). We won't get a chance to
5539 // optimize, but for now the only functions we expect are
5540 // kernel/user_string from pretty-printing, which don't need
5541 // optimization.
5542
5543 systemtap_session& s = ti.session;
5544 size_t nfiles = s.files.size();
5545
5546 symresolution_info sym (s);
5547 sym.current_function = ti.current_function;
5548 sym.current_probe = ti.current_probe;
5549 fc->visit (&sym);
5550
5551 // NB: synthetic functions get tacked onto the origin file, so we won't
5552 // see them growing s.files[]. Traverse it directly.
5553 for (unsigned i = 0; i < fc->referents.size(); i++)
5554 {
5555 functiondecl* fd = fc->referents[i];
5556 sym.current_function = fd;
5557 sym.current_probe = 0;
5558 fd->body->visit (&sym);
5559 }
5560
5561 while (nfiles < s.files.size())
5562 {
5563 stapfile* dome = s.files[nfiles++];
5564 for (size_t i = 0; i < dome->functions.size(); ++i)
5565 {
5566 functiondecl* fd = dome->functions[i];
5567 sym.current_function = fd;
5568 sym.current_probe = 0;
5569 fd->body->visit (&sym);
5570 // NB: not adding to s.functions just yet...
5571 }
5572 }
5573
5574 // Add only the direct functions we need.
5575 functioncall_traversing_visitor ftv;
5576 fc->visit (&ftv);
5577 for (set<functiondecl*>::iterator it = ftv.seen.begin();
5578 it != ftv.seen.end(); ++it)
5579 {
5580 functiondecl* fd = *it;
5581 pair<map<string,functiondecl*>::iterator,bool> inserted =
5582 s.functions.insert (make_pair (fd->name, fd));
5583 if (!inserted.second && inserted.first->second != fd)
5584 throw SEMANTIC_ERROR
5585 (_F("resolved function '%s' conflicts with an existing function",
5586 fd->unmangled_name.to_string().c_str()), fc->tok);
5587 }
5588 }
5589
5590 void visit_autocast_op (autocast_op* e)
5591 {
5592 const bool lvalue = is_active_lvalue (e);
5593 const exp_type_ptr& details = e->operand->type_details;
5594 if (details && !e->saved_conversion_error)
5595 {
5596 functioncall* fc = details->expand (e, lvalue);
5597 if (fc)
5598 {
5599 ti.num_newly_resolved++;
5600
5601 resolve_functioncall (fc);
5602 // NB: at this stage, the functioncall object has one
5603 // argument too few if we're in lvalue context. It will
5604 // be filled in only later (as the
5605 // var_expanding_visitor::visit_assignment bit rolls
5606 // back up). But nevertheless we must resolve the fc,
5607 // otherwise, symresolution_info::visit_functioncall will
5608 // throw a mismatched-arity error. (semok/autocast08.stp)
5609
5610 if (lvalue)
5611 provide_lvalue_call (fc);
5612
5613 fc->visit (this);
5614 return;
5615 }
5616 }
5617 var_expanding_visitor::visit_autocast_op (e);
5618 }
5619 };
5620
5621
5622 struct initial_typeresolution_info : public typeresolution_info
5623 {
5624 initial_typeresolution_info (systemtap_session& s): typeresolution_info(s)
5625 {}
5626
5627 // these expressions are not supposed to make its way to the typeresolution
5628 // pass. they probably get substituted/replaced, but since this is an initial pass
5629 // and not all substitutions are done, replace the functions that throw errors.
5630 void visit_target_symbol (target_symbol*) {}
5631 void visit_atvar_op (atvar_op*) {}
5632 void visit_defined_op (defined_op*) {}
5633 void visit_entry_op (entry_op*) {}
5634 void visit_cast_op (cast_op*) {}
5635 };
5636
5637 static int initial_typeres_pass(systemtap_session& s)
5638 {
5639 // minimal type resolution based off of semantic_pass_types(), without
5640 // checking for complete type resolutions or autocast expanding
5641 initial_typeresolution_info ti(s);
5642
5643 // Globals never have detailed types.
5644 // If we null them now, then all remaining vardecls can be detailed.
5645 for (unsigned j=0; j<s.globals.size(); j++)
5646 {
5647 vardecl* gd = s.globals[j];
5648 if (!gd->type_details)
5649 gd->type_details = ti.null_type;
5650 }
5651
5652 ti.assert_resolvability = false;
5653 while (1)
5654 {
5655 assert_no_interrupts();
5656
5657 ti.num_newly_resolved = 0;
5658 ti.num_still_unresolved = 0;
5659 ti.num_available_autocasts = 0;
5660
5661 for (map<string,functiondecl*>::iterator it = s.functions.begin();
5662 it != s.functions.end(); it++)
5663 {
5664 assert_no_interrupts();
5665
5666 functiondecl* fd = it->second;
5667 ti.current_probe = 0;
5668 ti.current_function = fd;
5669 ti.t = pe_unknown;
5670 fd->body->visit (& ti);
5671 }
5672
5673 for (unsigned j=0; j<s.probes.size(); j++)
5674 {
5675 assert_no_interrupts();
5676
5677 derived_probe* pn = s.probes[j];
5678 ti.current_function = 0;
5679 ti.current_probe = pn;
5680 ti.t = pe_unknown;
5681 pn->body->visit (& ti);
5682
5683 probe_point* pp = pn->sole_location();
5684 if (pp->condition)
5685 {
5686 ti.current_function = 0;
5687 ti.current_probe = 0;
5688 ti.t = pe_long; // NB: expected type
5689 pp->condition->visit (& ti);
5690 }
5691 }
5692 if (ti.num_newly_resolved == 0) // converged
5693 {
5694 // take into account that if there are mismatches, we'd want to know
5695 // about them incase they get whisked away, later in this process
5696 if (!ti.assert_resolvability && ti.mismatch_complexity > 0) // found a mismatch!!
5697 {
5698 ti.assert_resolvability = true; // report errors
5699 if (s.verbose > 0)
5700 ti.mismatch_complexity = 1; // print out mismatched but not unresolved type mismatches
5701 }
5702 else
5703 break;
5704 }
5705 else
5706 ti.mismatch_complexity = 0;
5707 }
5708
5709 return s.num_errors();
5710 }
5711
5712 static int
5713 semantic_pass_types (systemtap_session& s)
5714 {
5715 int rc = 0;
5716
5717 // next pass: type inference
5718 unsigned iterations = 0;
5719 typeresolution_info ti (s);
5720
5721 // Globals never have detailed types.
5722 // If we null them now, then all remaining vardecls can be detailed.
5723 for (unsigned j=0; j<s.globals.size(); j++)
5724 {
5725 vardecl* gd = s.globals[j];
5726 if (!gd->type_details)
5727 gd->type_details = ti.null_type;
5728 }
5729
5730 ti.assert_resolvability = false;
5731 while (1)
5732 {
5733 assert_no_interrupts();
5734
5735 iterations ++;
5736 ti.num_newly_resolved = 0;
5737 ti.num_still_unresolved = 0;
5738 ti.num_available_autocasts = 0;
5739
5740 for (map<string,functiondecl*>::iterator it = s.functions.begin();
5741 it != s.functions.end(); it++)
5742 try
5743 {
5744 assert_no_interrupts();
5745
5746 functiondecl* fd = it->second;
5747 ti.current_probe = 0;
5748 ti.current_function = fd;
5749 ti.t = pe_unknown;
5750
5751 fd->body->visit (& ti);
5752 // NB: we don't have to assert a known type for
5753 // functions here, to permit a "void" function.
5754 // The translator phase will omit the "retvalue".
5755 //
5756 // if (fd->type == pe_unknown)
5757 // ti.unresolved (fd->tok);
5758 for (unsigned i=0; i < fd->locals.size(); ++i)
5759 ti.check_local (fd->locals[i]);
5760
5761 // Check and run the autocast expanding visitor.
5762 if (ti.num_available_autocasts > 0)
5763 {
5764 autocast_expanding_visitor aev (s, ti);
5765 aev.replace (fd->body);
5766
5767 // PR18079, rerun the const-folder / dead-block-remover
5768 // if autocast evaluation enabled a @defined()
5769 if (! aev.relaxed())
5770 {
5771 bool relaxed_p = true;
5772 const_folder cf (s, relaxed_p);
5773 cf.replace (fd->body);
5774 if (! s.unoptimized)
5775 {
5776 dead_control_remover dc (s, relaxed_p);
5777 fd->body->visit (&dc);
5778 }
5779 (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
5780 }
5781
5782 ti.num_available_autocasts = 0;
5783 }
5784 }
5785 catch (const semantic_error& e)
5786 {
5787 throw SEMANTIC_ERROR(_F("while processing function %s",
5788 it->second->unmangled_name.to_string().c_str())).set_chain(e);
5789 }
5790
5791 for (unsigned j=0; j<s.probes.size(); j++)
5792 try
5793 {
5794 assert_no_interrupts();
5795
5796 derived_probe* pn = s.probes[j];
5797 ti.current_function = 0;
5798 ti.current_probe = pn;
5799 ti.t = pe_unknown;
5800
5801 pn->body->visit (& ti);
5802 for (unsigned i=0; i < pn->locals.size(); ++i)
5803 ti.check_local (pn->locals[i]);
5804
5805 // Check and run the autocast expanding visitor.
5806 if (ti.num_available_autocasts > 0)
5807 {
5808 autocast_expanding_visitor aev (s, ti);
5809 var_expand_const_fold_loop (s, pn->body, aev);
5810 // PR18079, rerun the const-folder / dead-block-remover
5811 // if autocast evaluation enabled a @defined()
5812 if (! s.unoptimized)
5813 {
5814 bool relaxed_p;
5815 dead_control_remover dc (s, relaxed_p);
5816 pn->body->visit (&dc);
5817 (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag
5818 }
5819
5820 ti.num_available_autocasts = 0;
5821 }
5822
5823 probe_point* pp = pn->sole_location();
5824 if (pp->condition)
5825 {
5826 ti.current_function = 0;
5827 ti.current_probe = 0;
5828 ti.t = pe_long; // NB: expected type
5829 pp->condition->visit (& ti);
5830 }
5831 }
5832 catch (const semantic_error& e)
5833 {
5834 throw SEMANTIC_ERROR(_F("while processing probe %s",
5835 s.probes[j]->derived_locations(false).c_str())).set_chain(e);
5836 }
5837
5838 for (unsigned j=0; j<s.globals.size(); j++)
5839 {
5840 vardecl* gd = s.globals[j];
5841 if (gd->type == pe_unknown)
5842 ti.unresolved (gd->tok);
5843 if(gd->arity == 0 && gd->wrap == true)
5844 {
5845 throw SEMANTIC_ERROR(_("wrapping not supported for scalars"), gd->tok);
5846 }
5847 }
5848
5849 if (ti.num_newly_resolved == 0) // converged
5850 {
5851 if (ti.num_still_unresolved == 0)
5852 break; // successfully
5853 else if (! ti.assert_resolvability)
5854 {
5855 // PR18079, before we go asserting anything, try to nullify any
5856 // still-unresolved @defined ops.
5857 bool relaxed_p = true;
5858 const_folder cf (s, relaxed_p, true); // NB: true: collapse remaining @defined's
5859
5860 for (auto it = s.probes.begin(); it != s.probes.end(); ++it)
5861 cf.replace ((*it)->body);
5862 for (auto it = s.functions.begin(); it != s.functions.end(); ++it)
5863 cf.replace (it->second->body);
5864
5865 if (! s.unoptimized)
5866 semantic_pass_dead_control (s, relaxed_p);
5867
5868 if (! relaxed_p)
5869 ti.mismatch_complexity = 0; // reset for next pass
5870 else
5871 {
5872 ti.assert_resolvability = true; // last pass, with error msgs
5873 if (s.verbose > 0)
5874 ti.mismatch_complexity = 0; // print every kind of mismatch
5875 }
5876 }
5877 else
5878 { // unsuccessful conclusion
5879 rc ++;
5880 break;
5881 }
5882 }
5883 else
5884 ti.mismatch_complexity = 0; // reset for next pass
5885 }
5886
5887 return rc + s.num_errors();
5888 }
5889
5890
5891 struct exp_type_null : public exp_type_details
5892 {
5893 uintptr_t id () const { return 0; }
5894 bool expandable() const { return false; }
5895 functioncall *expand(autocast_op*, bool) { return NULL; }
5896 };
5897
5898 typeresolution_info::typeresolution_info (systemtap_session& s):
5899 session(s), num_newly_resolved(0), num_still_unresolved(0),
5900 num_available_autocasts(0),
5901 assert_resolvability(false), mismatch_complexity(0),
5902 current_function(0), current_probe(0), t(pe_unknown),
5903 null_type(make_shared<exp_type_null>())
5904 {
5905 }
5906
5907
5908 void
5909 typeresolution_info::visit_literal_number (literal_number* e)
5910 {
5911 assert (e->type == pe_long);
5912 if ((t == e->type) || (t == pe_unknown))
5913 return;
5914
5915 mismatch (e->tok, t, e->type);
5916 }
5917
5918
5919 void
5920 typeresolution_info::visit_literal_string (literal_string* e)
5921 {
5922 assert (e->type == pe_string);
5923 if ((t == e->type) || (t == pe_unknown))
5924 return;
5925
5926 mismatch (e->tok, t, e->type);
5927 }
5928
5929
5930 void
5931 typeresolution_info::visit_logical_or_expr (logical_or_expr *e)
5932 {
5933 visit_binary_expression (e);
5934 }
5935
5936
5937 void
5938 typeresolution_info::visit_logical_and_expr (logical_and_expr *e)
5939 {
5940 visit_binary_expression (e);
5941 }
5942
5943 void
5944 typeresolution_info::visit_regex_query (regex_query *e)
5945 {
5946 // NB: result of regex query is an integer!
5947 if (t == pe_stats || t == pe_string)
5948 invalid (e->tok, t);
5949
5950 t = pe_string;
5951 e->left->visit (this);
5952 t = pe_string;
5953 e->right->visit (this); // parser ensures this is a literal known at compile time
5954
5955 if (e->type == pe_unknown)
5956 {
5957 e->type = pe_long;
5958 resolved (e->tok, e->type);
5959 }
5960 }
5961
5962 void
5963 typeresolution_info::visit_compound_expression (compound_expression* e)
5964 {
5965 // Incoming type inference applies to the RHS.
5966 e->right->visit(this);
5967
5968 // No incoming data for the LHS.
5969 t = pe_unknown;
5970 e->left->visit(this);
5971 }
5972
5973
5974 void
5975 typeresolution_info::visit_comparison (comparison *e)
5976 {
5977 // NB: result of any comparison is an integer!
5978 if (t == pe_stats || t == pe_string)
5979 invalid (e->tok, t);
5980
5981 t = (e->right->type != pe_unknown) ? e->right->type : pe_unknown;
5982 e->left->visit (this);
5983 t = (e->left->type != pe_unknown) ? e->left->type : pe_unknown;
5984 e->right->visit (this);
5985
5986 if (e->left->type != pe_unknown &&
5987 e->right->type != pe_unknown &&
5988 e->left->type != e->right->type)
5989 mismatch (e);
5990
5991 if (e->type == pe_unknown)
5992 {
5993 e->type = pe_long;
5994 resolved (e->tok, e->type);
5995 }
5996 }
5997
5998
5999 void
6000 typeresolution_info::visit_concatenation (concatenation *e)
6001 {
6002 if (t != pe_unknown && t != pe_string)
6003 invalid (e->tok, t);
6004
6005 t = pe_string;
6006 e->left->visit (this);
6007 t = pe_string;
6008 e->right->visit (this);
6009
6010 if (e->type == pe_unknown)
6011 {
6012 e->type = pe_string;
6013 resolved (e->tok, e->type);
6014 }
6015 }
6016
6017
6018 void
6019 typeresolution_info::visit_assignment (assignment *e)
6020 {
6021 if (t == pe_stats)
6022 invalid (e->tok, t);
6023
6024 if (e->op == "<<<") // stats aggregation
6025 {
6026 if (t == pe_string)
6027 invalid (e->tok, t);
6028
6029 t = pe_stats;
6030 e->left->visit (this);
6031 t = pe_long;
6032 e->right->visit (this);
6033 if (e->type == pe_unknown ||
6034 e->type == pe_stats)
6035 {
6036 e->type = pe_long;
6037 resolved (e->tok, e->type);
6038 }
6039 }
6040
6041 else if (e->left->type == pe_stats)
6042 invalid (e->left->tok, e->left->type);
6043
6044 else if (e->right->type == pe_stats)
6045 invalid (e->right->tok, e->right->type);
6046
6047 else if (e->op == "+=" || // numeric only
6048 e->op == "-=" ||
6049 e->op == "*=" ||
6050 e->op == "/=" ||
6051 e->op == "%=" ||
6052 e->op == "&=" ||
6053 e->op == "^=" ||
6054 e->op == "|=" ||
6055 e->op == "<<=" ||
6056 e->op == ">>=" ||
6057 false)
6058 {
6059 visit_binary_expression (e);
6060 }
6061 else if (e->op == ".=" || // string only
6062 false)
6063 {
6064 if (t == pe_long || t == pe_stats)
6065 invalid (e->tok, t);
6066
6067 t = pe_string;
6068 e->left->visit (this);
6069 t = pe_string;
6070 e->right->visit (this);
6071 if (e->type == pe_unknown)
6072 {
6073 e->type = pe_string;
6074 resolved (e->tok, e->type);
6075 }
6076 }
6077 else if (e->op == "=") // overloaded = for string & numeric operands
6078 {
6079 // logic similar to ternary_expression
6080 exp_type sub_type = t;
6081
6082 // Infer types across the l/r values
6083 if (sub_type == pe_unknown && e->type != pe_unknown)
6084 sub_type = e->type;
6085
6086 t = (sub_type != pe_unknown) ? sub_type :
6087 (e->right->type != pe_unknown) ? e->right->type :
6088 pe_unknown;
6089 e->left->visit (this);
6090 t = (sub_type != pe_unknown) ? sub_type :
6091 (e->left->type != pe_unknown) ? e->left->type :
6092 pe_unknown;
6093 e->right->visit (this);
6094
6095 if ((sub_type != pe_unknown) && (e->type == pe_unknown))
6096 {
6097 e->type = sub_type;
6098 resolved (e->tok, e->type);
6099 }
6100 if ((sub_type == pe_unknown) && (e->left->type != pe_unknown))
6101 {
6102 e->type = e->left->type;
6103 resolved (e->tok, e->type);
6104 }
6105
6106 if (e->left->type != pe_unknown &&
6107 e->right->type != pe_unknown &&
6108 e->left->type != e->right->type)
6109 mismatch (e);
6110
6111 // Propagate type details from the RHS to the assignment
6112 if (e->type == e->right->type &&
6113 e->right->type_details && !e->type_details)
6114 resolved_details(e->right->type_details, e->type_details);
6115
6116 // Propagate type details from the assignment to the LHS
6117 if (e->type == e->left->type && e->type_details)
6118 {
6119 if (e->left->type_details &&
6120 *e->left->type_details != *e->type_details &&
6121 *e->left->type_details != *null_type)
6122 resolved_details(null_type, e->left->type_details);
6123 else if (!e->left->type_details)
6124 resolved_details(e->type_details, e->left->type_details);
6125 }
6126 }
6127 else
6128 throw SEMANTIC_ERROR (_("unsupported assignment operator ") + (string)e->op);
6129 }
6130
6131
6132 void
6133 typeresolution_info::visit_embedded_expr (embedded_expr *e)
6134 {
6135 if (e->type == pe_unknown)
6136 {
6137 if (e->code.find ("/* string */") != string::npos)
6138 e->type = pe_string;
6139 else // if (e->code.find ("/* long */") != string::npos)
6140 e->type = pe_long;
6141
6142 resolved (e->tok, e->type);
6143 }
6144 }
6145
6146
6147 void
6148 typeresolution_info::visit_binary_expression (binary_expression* e)
6149 {
6150 if (t == pe_stats || t == pe_string)
6151 invalid (e->tok, t);
6152
6153 t = pe_long;
6154 e->left->visit (this);
6155 t = pe_long;
6156 e->right->visit (this);
6157
6158 if (e->left->type != pe_unknown &&
6159 e->right->type != pe_unknown &&
6160 e->left->type != e->right->type)
6161 mismatch (e);
6162
6163 if (e->type == pe_unknown)
6164 {
6165 e->type = pe_long;
6166 resolved (e->tok, e->type);
6167 }
6168 }
6169
6170
6171 void
6172 typeresolution_info::visit_pre_crement (pre_crement *e)
6173 {
6174 visit_unary_expression (e);
6175 }
6176
6177
6178 void
6179 typeresolution_info::visit_post_crement (post_crement *e)
6180 {
6181 visit_unary_expression (e);
6182 }
6183
6184
6185 void
6186 typeresolution_info::visit_unary_expression (unary_expression* e)
6187 {
6188 if (t == pe_stats || t == pe_string)
6189 invalid (e->tok, t);
6190
6191 t = pe_long;
6192 e->operand->visit (this);
6193
6194 if (e->type == pe_unknown)
6195 {
6196 e->type = pe_long;
6197 resolved (e->tok, e->type);
6198 }
6199 }
6200
6201
6202 void
6203 typeresolution_info::visit_ternary_expression (ternary_expression* e)
6204 {
6205 exp_type sub_type = t;
6206
6207 t = pe_long;
6208 e->cond->visit (this);
6209
6210 // Infer types across the true/false arms of the ternary expression.
6211
6212 if (sub_type == pe_unknown && e->type != pe_unknown)
6213 sub_type = e->type;
6214 t = sub_type;
6215 e->truevalue->visit (this);
6216 t = sub_type;
6217 e->falsevalue->visit (this);
6218
6219 if ((sub_type == pe_unknown) && (e->type != pe_unknown))
6220 ; // already resolved
6221 else if ((sub_type != pe_unknown) && (e->type == pe_unknown))
6222 {
6223 e->type = sub_type;
6224 resolved (e->tok, e->type);
6225 }
6226 else if ((sub_type == pe_unknown) && (e->truevalue->type != pe_unknown))
6227 {
6228 e->type = e->truevalue->type;
6229 resolved (e->tok, e->type);
6230 }
6231 else if ((sub_type == pe_unknown) && (e->falsevalue->type != pe_unknown))
6232 {
6233 e->type = e->falsevalue->type;
6234 resolved (e->tok, e->type);
6235 }
6236 else if (e->type != sub_type)
6237 mismatch (e->tok, sub_type, e->type);
6238
6239 // Propagate type details from both true/false branches
6240 if (!e->type_details &&
6241 e->type == e->truevalue->type && e->type == e->falsevalue->type &&
6242 e->truevalue->type_details && e->falsevalue->type_details &&
6243 *e->truevalue->type_details == *e->falsevalue->type_details)
6244 resolved_details(e->truevalue->type_details, e->type_details);
6245 }
6246
6247
6248 template <class Referrer, class Referent>
6249 void resolve_2types (Referrer* referrer, Referent* referent,
6250 typeresolution_info* r, exp_type t, bool accept_unknown = false)
6251 {
6252 exp_type& re_type = referrer->type;
6253 const token* re_tok = referrer->tok;
6254 exp_type& te_type = referent->type;
6255
6256 if (t != pe_unknown && re_type == t && re_type == te_type)
6257 ; // do nothing: all three e->types in agreement
6258 else if (t == pe_unknown && re_type != pe_unknown && re_type == te_type)
6259 ; // do nothing: two known e->types in agreement
6260 else if (re_type != pe_unknown && te_type != pe_unknown && re_type != te_type)
6261 r->mismatch (re_tok, re_type, referent); // referrer-referent
6262 else if (re_type != pe_unknown && t != pe_unknown && re_type != t)
6263 r->mismatch (re_tok, t, referent); // referrer-t
6264 else if (te_type != pe_unknown && t != pe_unknown && te_type != t)
6265 r->mismatch (re_tok, t, referent); // referent-t
6266 else if (re_type == pe_unknown && t != pe_unknown)
6267 {
6268 // propagate from upstream
6269 re_type = t;
6270 r->resolved (re_tok, re_type);
6271 // catch re_type/te_type mismatch later
6272 }
6273 else if (re_type == pe_unknown && te_type != pe_unknown)
6274 {
6275 // propagate from referent
6276 re_type = te_type;
6277 r->resolved (re_tok, re_type);
6278 // catch re_type/t mismatch later
6279 }
6280 else if (re_type != pe_unknown && te_type == pe_unknown)
6281 {
6282 // propagate to referent
6283 te_type = re_type;
6284 r->resolved (re_tok, re_type, referent);
6285 // catch re_type/t mismatch later
6286 }
6287 else if (! accept_unknown)
6288 r->unresolved (re_tok);
6289 }
6290
6291
6292 void
6293 typeresolution_info::visit_symbol (symbol* e)
6294 {
6295 if (e->referent == 0)
6296 throw SEMANTIC_ERROR (_F("internal error: unresolved symbol '%s'",
6297 e->name.to_string().c_str()), e->tok);
6298
6299 resolve_2types (e, e->referent, this, t);
6300
6301 if (e->type == e->referent->type)
6302 {
6303 // If both have type details, then they either must agree;
6304 // otherwise force them both to null.
6305 if (e->type_details && e->referent->type_details &&
6306 *e->type_details != *e->referent->type_details)
6307 {
6308 resolved_details(null_type, e->type_details);
6309 resolved_details(null_type, e->referent->type_details);
6310 }
6311 else if (e->type_details && !e->referent->type_details)
6312 resolved_details(e->type_details, e->referent->type_details);
6313 else if (!e->type_details && e->referent->type_details)
6314 resolved_details(e->referent->type_details, e->type_details);
6315 }
6316 }
6317
6318 void
6319 typeresolution_info::visit_target_register (target_register* e)
6320 {
6321 if (t != pe_long)
6322 invalid (e->tok, t);
6323 if (e->type == pe_unknown)
6324 {
6325 e->type = pe_long;
6326 resolved (e->tok, e->type);
6327 }
6328 }
6329
6330 void
6331 typeresolution_info::visit_target_deref (target_deref* e)
6332 {
6333 // Both the target_deref result as well as the address must both be longs.
6334 if (t != pe_long)
6335 invalid (e->tok, t);
6336 e->addr->visit (this);
6337
6338 if (e->type == pe_unknown)
6339 {
6340 e->type = pe_long;
6341 resolved (e->tok, e->type);
6342 }
6343 }
6344
6345 void
6346 typeresolution_info::visit_target_bitfield (target_bitfield*)
6347 {
6348 // These are all expanded much earlier.
6349 abort();
6350 }
6351
6352 void
6353 typeresolution_info::visit_target_symbol (target_symbol* e)
6354 {
6355 // This occurs only if a target symbol was not resolved over in
6356 // tapset.cxx land, that error was properly suppressed, and the
6357 // later unused-expression-elimination pass didn't get rid of it
6358 // either. So we have a target symbol that is believed to be of
6359 // genuine use, yet unresolved by the provider.
6360 //
6361 // PR18079, or it can happen if a $target expression is nested within
6362 // a @defined() test that has not yet been resolved (but can be soon).
6363 if (! assert_resolvability)
6364 {
6365 num_still_unresolved ++;
6366 return;
6367 }
6368
6369 if (session.verbose > 2)
6370 {
6371 clog << _("Resolution problem with ");
6372 if (current_function)
6373 {
6374 clog << "function " << current_function->name << endl;
6375 current_function->body->print (clog);
6376 clog << endl;
6377 }
6378 else if (current_probe)
6379 {
6380 clog << "probe " << *current_probe->sole_location() << endl;
6381 current_probe->body->print (clog);
6382 clog << endl;
6383 }
6384 else
6385 //TRANSLATORS: simply saying not an issue with a probe or function
6386 clog << _("other") << endl;
6387 }
6388
6389 if (e->saved_conversion_error)
6390 throw (* (e->saved_conversion_error));
6391 else
6392 throw SEMANTIC_ERROR(_("unresolved target-symbol expression"), e->tok);
6393 }
6394
6395
6396 void
6397 typeresolution_info::visit_atvar_op (atvar_op* e)
6398 {
6399 // This occurs only if an @var() was not resolved over in
6400 // tapset.cxx land, that error was properly suppressed, and the
6401 // later unused-expression-elimination pass didn't get rid of it
6402 // either. So we have an @var() that is believed to be of
6403 // genuine use, yet unresolved by the provider.
6404
6405 if (session.verbose > 2)
6406 {
6407 clog << _("Resolution problem with ");
6408 if (current_function)
6409 {
6410 clog << "function " << current_function->name << endl;
6411 current_function->body->print (clog);
6412 clog << endl;
6413 }
6414 else if (current_probe)
6415 {
6416 clog << "probe " << *current_probe->sole_location() << endl;
6417 current_probe->body->print (clog);
6418 clog << endl;
6419 }
6420 else
6421 //TRANSLATORS: simply saying not an issue with a probe or function
6422 clog << _("other") << endl;
6423 }
6424
6425 if (e->saved_conversion_error)
6426 throw (* (e->saved_conversion_error));
6427 else
6428 throw SEMANTIC_ERROR(_("unresolved @var() expression"), e->tok);
6429 }
6430
6431
6432 void
6433 typeresolution_info::visit_defined_op (defined_op* e)
6434 {
6435 // PR18079: if a @defined is still around, it may have a parameter that
6436 // wasn't resolvable one way or another earlier. Maybe an autocast_op.
6437 // Let's give it a visit just in case.
6438 e->operand->visit(this);
6439
6440 if (assert_resolvability)
6441 throw SEMANTIC_ERROR(_("unexpected @defined"), e->tok);
6442 else
6443 num_still_unresolved ++;
6444 }
6445
6446
6447 void
6448 typeresolution_info::visit_entry_op (entry_op* e)
6449 {
6450 throw SEMANTIC_ERROR(_("@entry is only valid in .return probes"), e->tok);
6451 }
6452
6453
6454 void
6455 typeresolution_info::visit_cast_op (cast_op* e)
6456 {
6457 // Like target_symbol, a cast_op shouldn't survive this far
6458 // unless it was not resolved and its value is really needed.
6459 if (e->saved_conversion_error)
6460 throw (* (e->saved_conversion_error));
6461 else
6462 throw SEMANTIC_ERROR(_F("type definition '%s' not found in '%s'",
6463 e->type_name.to_string().c_str(),
6464 e->module.to_string().c_str()), e->tok);
6465 }
6466
6467
6468 void
6469 typeresolution_info::visit_autocast_op (autocast_op* e)
6470 {
6471 // Like cast_op, a implicit autocast_op shouldn't survive this far
6472 // unless it was not resolved and its value is really needed.
6473 if (assert_resolvability && e->saved_conversion_error)
6474 throw (* (e->saved_conversion_error));
6475 else if (assert_resolvability)
6476 throw SEMANTIC_ERROR(_("unknown type in dereference"), e->tok);
6477
6478 t = pe_long;
6479 e->operand->visit (this);
6480
6481 num_still_unresolved++;
6482 if (e->operand->type_details &&
6483 e->operand->type_details->expandable())
6484 num_available_autocasts++;
6485 }
6486
6487
6488 void
6489 typeresolution_info::visit_perf_op (perf_op* e)
6490 {
6491 // A perf_op should already be resolved
6492 if (t == pe_stats || t == pe_string)
6493 invalid (e->tok, t);
6494
6495 e->type = pe_long;
6496 // XXX: ... but but but ... ::visit_defined_op interprets this ->type
6497 // as meaning that @defined(@perf("JUNK JUNK JUNK")) is valid.
6498 // The dwarf_var_expanding_visitor::visit_perf_op() code that validates
6499 // the JUNK parameter is not even called in time.
6500
6501 // (There is no real need to visit our operand - by parser
6502 // construction, it's always a string literal, with its type already
6503 // set.)
6504 t = pe_string;
6505 e->operand->visit (this);
6506 }
6507
6508
6509 void
6510 typeresolution_info::visit_arrayindex (arrayindex* e)
6511 {
6512
6513 symbol *array = NULL;
6514 hist_op *hist = NULL;
6515 classify_indexable(e->base, array, hist);
6516
6517 // Every hist_op has type [int]:int, that is to say, every hist_op
6518 // is a pseudo-one-dimensional integer array type indexed by
6519 // integers (bucket numbers).
6520
6521 if (hist)
6522 {
6523 if (e->indexes.size() != 1)
6524 unresolved (e->tok);
6525 t = pe_long;
6526 e->indexes[0]->visit (this);
6527 if (e->indexes[0]->type != pe_long)
6528 unresolved (e->tok);
6529 hist->visit (this);
6530 if (e->type != pe_long)
6531 {
6532 e->type = pe_long;
6533 resolved (e->tok, e->type);
6534 }
6535 return;
6536 }
6537
6538 // Now we are left with "normal" map inference and index checking.
6539
6540 assert (array);
6541 assert (array->referent != 0);
6542 resolve_2types (e, array->referent, this, t);
6543
6544 // now resolve the array indexes
6545
6546 // if (e->referent->index_types.size() == 0)
6547 // // redesignate referent as array
6548 // e->referent->set_arity (e->indexes.size ());
6549
6550 if (e->indexes.size() != array->referent->index_types.size())
6551 unresolved (e->tok); // symbol resolution should prevent this
6552 else for (unsigned i=0; i<e->indexes.size(); i++)
6553 {
6554 if (e->indexes[i])
6555 {
6556 expression* ee = e->indexes[i];
6557 exp_type& ft = array->referent->index_types [i];
6558 t = ft;
6559 ee->visit (this);
6560 exp_type at = ee->type;
6561
6562 if ((at == pe_string || at == pe_long) && ft == pe_unknown)
6563 {
6564 // propagate to formal type
6565 ft = at;
6566 resolved (ee->tok, ft, array->referent, i);
6567 }
6568 if (at == pe_stats)
6569 invalid (ee->tok, at);
6570 if (ft == pe_stats)
6571 invalid (ee->tok, ft);
6572 if (at != pe_unknown && ft != pe_unknown && ft != at)
6573 mismatch (ee->tok, ee->type, array->referent, i);
6574 if (at == pe_unknown)
6575 unresolved (ee->tok);
6576 }
6577 }
6578 }
6579
6580
6581 void
6582 typeresolution_info::visit_functioncall (functioncall* e)
6583 {
6584 if (e->referents.empty())
6585 throw SEMANTIC_ERROR (_F("internal error: unresolved function call to '%s'",
6586 e->function.to_string().c_str()), e->tok);
6587
6588 exp_type original = t;
6589 for (unsigned fd = 0; fd < e->referents.size(); fd++)
6590 {
6591 t = original; // type may be changed by overloaded functions so restore it
6592 functiondecl* referent = e->referents[fd];
6593 resolve_2types (e, referent, this, t, true); // accept unknown type
6594
6595 if (e->type == pe_stats)
6596 invalid (e->tok, e->type);
6597
6598 const exp_type_ptr& func_type = referent->type_details;
6599 if (func_type && referent->type == e->type
6600 && (!e->type_details || *func_type != *e->type_details))
6601 resolved_details(referent->type_details, e->type_details);
6602
6603 // now resolve the function parameters
6604 if (e->args.size() != referent->formal_args.size())
6605 unresolved (e->tok); // symbol resolution should prevent this
6606 else for (unsigned i=0; i<e->args.size(); i++)
6607 {
6608 expression* ee = e->args[i];
6609 exp_type& ft = referent->formal_args[i]->type;
6610 const token* fe_tok = referent->formal_args[i]->tok;
6611 t = ft;
6612 ee->visit (this);
6613 exp_type at = ee->type;
6614
6615 if (((at == pe_string) || (at == pe_long)) && ft == pe_unknown)
6616 {
6617 // propagate to formal arg
6618 ft = at;
6619 resolved (ee->tok, ft, referent->formal_args[i], i);
6620 }
6621 if (at == pe_stats)
6622 invalid (ee->tok, at);
6623 if (ft == pe_stats)
6624 invalid (fe_tok, ft);
6625 if (at != pe_unknown && ft != pe_unknown && ft != at)
6626 mismatch (ee->tok, ee->type, referent->formal_args[i], i);
6627 if (at == pe_unknown)
6628 unresolved (ee->tok);
6629 }
6630 }
6631 }
6632
6633
6634 void
6635 typeresolution_info::visit_block (block* e)
6636 {
6637 for (unsigned i=0; i<e->statements.size(); i++)
6638 {
6639 t = pe_unknown;
6640 e->statements[i]->visit (this);
6641 }
6642 }
6643
6644
6645 void
6646 typeresolution_info::visit_try_block (try_block* e)
6647 {
6648 if (e->try_block)
6649 e->try_block->visit (this);
6650 if (e->catch_error_var)
6651 {
6652 t = pe_string;
6653 e->catch_error_var->visit (this);
6654 }
6655 if (e->catch_block)
6656 e->catch_block->visit (this);
6657 }
6658
6659
6660 void
6661 typeresolution_info::visit_embeddedcode (embeddedcode* s)
6662 {
6663 // PR11573. If we have survived thus far with a piece of embedded
6664 // code that requires uprobes, we need to track this.
6665 //
6666 // This is an odd place for this check, as opposed
6667 // to a separate 'optimization' pass, or c_unparser::visit_embeddedcode
6668 // over yonder in pass 3. However, we want to do it during pass 2 so
6669 // that cached sessions also get the uprobes treatment.
6670 if (! session.need_uprobes
6671 && s->code.find("/* pragma:uprobes */") != string::npos)
6672 {
6673 if (session.verbose > 2)
6674 clog << _("Activating uprobes support because /* pragma:uprobes */ seen.") << endl;
6675 session.need_uprobes = true;
6676 }
6677
6678 // PR15065. Likewise, we need to detect /* pragma:tagged_dfa */
6679 // before the gen_dfa_table pass. Again, the typechecking part of
6680 // pass 2 is a good place for this.
6681 if (! session.need_tagged_dfa
6682 && s->code.find("/* pragma:tagged_dfa */") != string::npos)
6683 {
6684 if (session.verbose > 2)
6685 clog << _("Turning on DFA subexpressions because /* pragma:tagged_dfa */ seen") << endl;
6686 session.need_tagged_dfa = true;
6687 // TODOXXX throw SEMANTIC_ERROR (_("Tagged DFA support is not yet available"), s->tok);
6688 }
6689 }
6690
6691
6692 void
6693 typeresolution_info::visit_if_statement (if_statement* e)
6694 {
6695 t = pe_long;
6696 e->condition->visit (this);
6697
6698 t = pe_unknown;
6699 e->thenblock->visit (this);
6700
6701 if (e->elseblock)
6702 {
6703 t = pe_unknown;
6704 e->elseblock->visit (this);
6705 }
6706 }
6707
6708
6709 void
6710 typeresolution_info::visit_for_loop (for_loop* e)
6711 {
6712 t = pe_unknown;
6713 if (e->init) e->init->visit (this);
6714 t = pe_long;
6715 e->cond->visit (this);
6716 t = pe_unknown;
6717 if (e->incr) e->incr->visit (this);
6718 t = pe_unknown;
6719 e->block->visit (this);
6720 }
6721
6722
6723 void
6724 typeresolution_info::visit_foreach_loop (foreach_loop* e)
6725 {
6726 // See also visit_arrayindex.
6727 // This is different in that, being a statement, we can't assign
6728 // a type to the outer array, only propagate to/from the indexes
6729
6730 // if (e->referent->index_types.size() == 0)
6731 // // redesignate referent as array
6732 // e->referent->set_arity (e->indexes.size ());
6733
6734 exp_type wanted_value = pe_unknown;
6735 symbol *array = NULL;
6736 hist_op *hist = NULL;
6737 classify_indexable(e->base, array, hist);
6738
6739 if (hist)
6740 {
6741 if (e->indexes.size() != 1)
6742 unresolved (e->tok);
6743 t = pe_long;
6744 e->indexes[0]->visit (this);
6745 if (e->indexes[0]->type != pe_long)
6746 unresolved (e->tok);
6747 hist->visit (this);
6748 wanted_value = pe_long;
6749 }
6750 else
6751 {
6752 assert (array);
6753 if (e->indexes.size() != array->referent->index_types.size())
6754 unresolved (e->tok); // symbol resolution should prevent this
6755 else
6756 {
6757 for (unsigned i=0; i<e->indexes.size(); i++)
6758 {
6759 expression* ee = e->indexes[i];
6760 exp_type& ft = array->referent->index_types [i];
6761 t = ft;
6762 ee->visit (this);
6763 exp_type at = ee->type;
6764
6765 if ((at == pe_string || at == pe_long) && ft == pe_unknown)
6766 {
6767 // propagate to formal type
6768 ft = at;
6769 resolved (ee->tok, ee->type, array->referent, i);
6770 }
6771 if (at == pe_stats)
6772 invalid (ee->tok, at);
6773 if (ft == pe_stats)
6774 invalid (ee->tok, ft);
6775 if (at != pe_unknown && ft != pe_unknown && ft != at)
6776 mismatch (ee->tok, ee->type, array->referent, i);
6777 if (at == pe_unknown)
6778 unresolved (ee->tok);
6779 }
6780 for (unsigned i=0; i<e->array_slice.size(); i++)
6781 if (e->array_slice[i])
6782 {
6783 expression* ee = e->array_slice[i];
6784 exp_type& ft = array->referent->index_types [i];
6785 t = ft;
6786 ee->visit (this);
6787 exp_type at = ee->type;
6788
6789 if ((at == pe_string || at == pe_long) && ft == pe_unknown)
6790 {
6791 // propagate to formal type
6792 ft = at;
6793 resolved (ee->tok, ee->type, array->referent, i);
6794 }
6795 if (at == pe_stats)
6796 invalid (ee->tok, at);
6797 if (ft == pe_stats)
6798 invalid (ee->tok, ft);
6799 if (at != pe_unknown && ft != pe_unknown && ft != at)
6800 mismatch (ee->tok, ee->type, array->referent, i);
6801 if (at == pe_unknown)
6802 unresolved (ee->tok);
6803 }
6804 }
6805 t = pe_unknown;
6806 array->visit (this);
6807 wanted_value = array->type;
6808 }
6809
6810 if (e->value)
6811 {
6812 if (wanted_value == pe_stats)
6813 invalid(e->value->tok, wanted_value);
6814 else if (wanted_value != pe_unknown)
6815 check_arg_type(wanted_value, e->value);
6816 else
6817 {
6818 t = pe_unknown;
6819 e->value->visit (this);
6820 }
6821 }
6822
6823 /* Prevent @sum etc. aggregate sorting on non-statistics arrays. */
6824 if (wanted_value != pe_unknown)
6825 if (e->sort_aggr != sc_none && wanted_value != pe_stats)
6826 invalid (array->tok, wanted_value);
6827
6828 if (e->limit)
6829 {
6830 t = pe_long;
6831 e->limit->visit (this);
6832 }
6833
6834 t = pe_unknown;
6835 e->block->visit (this);
6836 }
6837
6838
6839 void
6840 typeresolution_info::visit_null_statement (null_statement*)
6841 {
6842 }
6843
6844
6845 void
6846 typeresolution_info::visit_expr_statement (expr_statement* e)
6847 {
6848 t = pe_unknown;
6849 e->value->visit (this);
6850 }
6851
6852
6853 struct delete_statement_typeresolution_info:
6854 public throwing_visitor
6855 {
6856 typeresolution_info *parent;
6857 delete_statement_typeresolution_info (typeresolution_info *p):
6858 throwing_visitor (_("invalid operand of delete expression")),
6859 parent (p)
6860 {}
6861
6862 void visit_arrayindex (arrayindex* e)
6863 {
6864 parent->visit_arrayindex (e);
6865 }
6866
6867 void visit_symbol (symbol* e)
6868 {
6869 exp_type ignored = pe_unknown;
6870 assert (e->referent != 0);
6871 resolve_2types (e, e->referent, parent, ignored);
6872 }
6873 };
6874
6875
6876 void
6877 typeresolution_info::visit_delete_statement (delete_statement* e)
6878 {
6879 delete_statement_typeresolution_info di (this);
6880 t = pe_unknown;
6881 e->value->visit (&di);
6882 }
6883
6884
6885 void
6886 typeresolution_info::visit_next_statement (next_statement*)
6887 {
6888 }
6889
6890
6891 void
6892 typeresolution_info::visit_break_statement (break_statement*)
6893 {
6894 }
6895
6896
6897 void
6898 typeresolution_info::visit_continue_statement (continue_statement*)
6899 {
6900 }
6901
6902
6903 void
6904 typeresolution_info::visit_array_in (array_in* e)
6905 {
6906 // all unary operators only work on numerics
6907 exp_type t1 = t;
6908 t = pe_unknown; // array value can be anything
6909 e->operand->visit (this);
6910
6911 if (t1 == pe_unknown && e->type != pe_unknown)
6912 ; // already resolved
6913 else if (t1 == pe_string || t1 == pe_stats)
6914 mismatch (e->tok, t1, pe_long);
6915 else if (e->type == pe_unknown)
6916 {
6917 e->type = pe_long;
6918 resolved (e->tok, e->type);
6919 }
6920 }
6921
6922
6923 void
6924 typeresolution_info::visit_return_statement (return_statement* e)
6925 {
6926 // This is like symbol, where the referent is
6927 // the return value of the function.
6928
6929 // translation pass will print error
6930 if (current_function == 0)
6931 return;
6932
6933 exp_type& e_type = current_function->type;
6934 t = current_function->type;
6935
6936 if (!e->value)
6937 {
6938 if (e_type != pe_unknown)
6939 mismatch (e->tok, pe_unknown, current_function);
6940 return;
6941 }
6942
6943 e->value->visit (this);
6944
6945 if (e_type != pe_unknown && e->value->type != pe_unknown
6946 && e_type != e->value->type)
6947 mismatch (e->value->tok, e->value->type, current_function);
6948 if (e_type == pe_unknown &&
6949 (e->value->type == pe_long || e->value->type == pe_string))
6950 {
6951 // propagate non-statistics from value
6952 e_type = e->value->type;
6953 resolved (e->value->tok, e_type, current_function);
6954 }
6955 if (e->value->type == pe_stats)
6956 invalid (e->value->tok, e->value->type);
6957
6958 const exp_type_ptr& value_type = e->value->type_details;
6959 if (value_type && current_function->type == e->value->type)
6960 {
6961 exp_type_ptr& func_type = current_function->type_details;
6962 if (!func_type)
6963 // The function can take on the type details of the return value.
6964 resolved_details(value_type, func_type);
6965 else if (*func_type != *value_type && *func_type != *null_type)
6966 // Conflicting return types? NO TYPE FOR YOU!
6967 resolved_details(null_type, func_type);
6968 }
6969 }
6970
6971 void
6972 typeresolution_info::visit_print_format (print_format* e)
6973 {
6974 size_t unresolved_args = 0;
6975
6976 if (e->hist)
6977 {
6978 e->hist->visit(this);
6979 }
6980
6981 else if (e->print_with_format)
6982 {
6983 // If there's a format string, we can do both inference *and*
6984 // checking.
6985
6986 // First we extract the subsequence of formatting components
6987 // which are conversions (not just literal string components)
6988
6989 unsigned expected_num_args = 0;
6990 std::vector<print_format::format_component> components;
6991 for (size_t i = 0; i < e->components.size(); ++i)
6992 {
6993 if (e->components[i].type == print_format::conv_unspecified)
6994 throw SEMANTIC_ERROR (_("Unspecified conversion in print operator format string"),
6995 e->tok);
6996 else if (e->components[i].type == print_format::conv_literal)
6997 continue;
6998 components.push_back(e->components[i]);
6999 ++expected_num_args;
7000 if (e->components[i].widthtype == print_format::width_dynamic)
7001 ++expected_num_args;
7002 if (e->components[i].prectype == print_format::prec_dynamic)
7003 ++expected_num_args;
7004 }
7005
7006 // Then we check that the number of conversions and the number
7007 // of args agree.
7008
7009 if (expected_num_args != e->args.size())
7010 throw SEMANTIC_ERROR (_("Wrong number of args to formatted print operator"),
7011 e->tok);
7012
7013 // Then we check that the types of the conversions match the types
7014 // of the args.
7015 unsigned argno = 0;
7016 for (size_t i = 0; i < components.size(); ++i)
7017 {
7018 // Check the dynamic width, if specified
7019 if (components[i].widthtype == print_format::width_dynamic)
7020 {
7021 check_arg_type (pe_long, e->args[argno]);
7022 ++argno;
7023 }
7024
7025 // Check the dynamic precision, if specified
7026 if (components[i].prectype == print_format::prec_dynamic)
7027 {
7028 check_arg_type (pe_long, e->args[argno]);
7029 ++argno;
7030 }
7031
7032 exp_type wanted = pe_unknown;
7033
7034 switch (components[i].type)
7035 {
7036 case print_format::conv_unspecified:
7037 case print_format::conv_literal:
7038 assert (false);
7039 break;
7040
7041 case print_format::conv_pointer:
7042 case print_format::conv_number:
7043 case print_format::conv_binary:
7044 case print_format::conv_char:
7045 case print_format::conv_memory:
7046 case print_format::conv_memory_hex:
7047 wanted = pe_long;
7048 break;
7049
7050 case print_format::conv_string:
7051 wanted = pe_string;
7052 break;
7053 }
7054
7055 assert (wanted != pe_unknown);
7056 check_arg_type (wanted, e->args[argno]);
7057 ++argno;
7058 }
7059 }
7060 else
7061 {
7062 // Without a format string, the best we can do is require that
7063 // each argument resolve to a concrete type.
7064 for (size_t i = 0; i < e->args.size(); ++i)
7065 {
7066 t = pe_unknown;
7067 e->args[i]->visit (this);
7068 if (e->args[i]->type == pe_unknown)
7069 {
7070 unresolved (e->args[i]->tok);
7071 ++unresolved_args;
7072 }
7073 }
7074 }
7075
7076 if (unresolved_args == 0)
7077 {
7078 if (e->type == pe_unknown)
7079 {
7080 if (e->print_to_stream)
7081 e->type = pe_long;
7082 else
7083 e->type = pe_string;
7084 resolved (e->tok, e->type);
7085 }
7086 }
7087 else
7088 {
7089 e->type = pe_unknown;
7090 unresolved (e->tok);
7091 }
7092 }
7093
7094
7095 void
7096 typeresolution_info::visit_stat_op (stat_op* e)
7097 {
7098 t = pe_stats;
7099 e->stat->visit (this);
7100 if (e->type == pe_unknown)
7101 {
7102 e->type = pe_long;
7103 resolved (e->tok, e->type);
7104 }
7105 else if (e->type != pe_long)
7106 mismatch (e->tok, pe_long, e->type);
7107 }
7108
7109 void
7110 typeresolution_info::visit_hist_op (hist_op* e)
7111 {
7112 t = pe_stats;
7113 e->stat->visit (this);
7114 }
7115
7116
7117 void
7118 typeresolution_info::check_arg_type (exp_type wanted, expression* arg)
7119 {
7120 t = wanted;
7121 arg->visit (this);
7122
7123 if (arg->type == pe_unknown)
7124 {
7125 arg->type = wanted;
7126 resolved (arg->tok, arg->type);
7127 }
7128 else if (arg->type != wanted)
7129 {
7130 mismatch (arg->tok, wanted, arg->type);
7131 }
7132 }
7133
7134
7135 void
7136 typeresolution_info::check_local (vardecl* v)
7137 {
7138 if (v->arity != 0)
7139 {
7140 num_still_unresolved ++;
7141 if (assert_resolvability)
7142 session.print_error
7143 (SEMANTIC_ERROR (_("array locals not supported, missing global declaration? "), v->tok));
7144 }
7145
7146 if (v->type == pe_unknown)
7147 unresolved (v->tok);
7148 else if (v->type == pe_stats)
7149 {
7150 num_still_unresolved ++;
7151 if (assert_resolvability)
7152 session.print_error
7153 (SEMANTIC_ERROR (_("stat locals not supported, missing global declaration? "), v->tok));
7154 }
7155 else if (!(v->type == pe_long || v->type == pe_string))
7156 invalid (v->tok, v->type);
7157 }
7158
7159
7160 void
7161 typeresolution_info::unresolved (const token* tok)
7162 {
7163 num_still_unresolved ++;
7164
7165 if (assert_resolvability && mismatch_complexity <= 0)
7166 {
7167 stringstream msg;
7168 msg << _("unresolved type ");
7169 session.print_error (SEMANTIC_ERROR (msg.str(), tok));
7170 }
7171 }
7172
7173
7174 void
7175 typeresolution_info::invalid (const token* tok, exp_type pe)
7176 {
7177 num_still_unresolved ++;
7178
7179 if (assert_resolvability)
7180 {
7181 stringstream msg;
7182 if (tok && tok->type == tok_operator)
7183 msg << _("invalid operator");
7184 else
7185 msg << _("invalid type ") << pe;
7186 session.print_error (SEMANTIC_ERROR (msg.str(), tok));
7187 }
7188 }
7189
7190 void
7191 typeresolution_info::mismatch (const binary_expression* e)
7192 {
7193 num_still_unresolved ++;
7194
7195 if (assert_resolvability && mismatch_complexity <= 1)
7196 {
7197 stringstream msg;
7198 msg << _F("type mismatch: left and right sides don't agree (%s vs %s)",
7199 lex_cast(e->left->type).c_str(), lex_cast(e->right->type).c_str());
7200 session.print_error (SEMANTIC_ERROR (msg.str(), e->tok));
7201 }
7202 else if (!assert_resolvability)
7203 mismatch_complexity = max(1, mismatch_complexity);
7204 }
7205
7206 /* tok token where mismatch occurred
7207 * t1 type we expected (the 'good' type)
7208 * t2 type we received (the 'bad' type)
7209 * */
7210 void
7211 typeresolution_info::mismatch (const token* tok, exp_type t1, exp_type t2)
7212 {
7213 num_still_unresolved ++;
7214
7215 if (assert_resolvability && mismatch_complexity <= 2)
7216 {
7217 stringstream msg;
7218 msg << _F("type mismatch: expected %s", lex_cast(t1).c_str());
7219 if (t2 != pe_unknown)
7220 msg << _F(" but found %s", lex_cast(t2).c_str());
7221 session.print_error (SEMANTIC_ERROR (msg.str(), tok));
7222 }
7223 else if (!assert_resolvability)
7224 mismatch_complexity = max(2, mismatch_complexity);
7225 }
7226
7227 /* tok token where the mismatch happened
7228 * type type we received (the 'bad' type)
7229 * decl declaration of mismatched symbol
7230 * index if index-based (array index or function arg)
7231 * */
7232 void
7233 typeresolution_info::mismatch (const token *tok, exp_type type,
7234 const symboldecl* decl, int index)
7235 {
7236 num_still_unresolved ++;
7237
7238 if (assert_resolvability && mismatch_complexity <= 3)
7239 {
7240 assert(decl != NULL);
7241
7242 // If mismatch is against a function parameter from within the function
7243 // itself (rather than a function call), then the index will be -1. We
7244 // check here if the decl corresponds to one of the params and if so,
7245 // adjust the index.
7246 if (current_function != NULL && index == -1)
7247 {
7248 vector<vardecl*>& args = current_function->formal_args;
7249 for (unsigned i = 0; i < args.size() && index < 0; i++)
7250 if (args[i] == decl)
7251 index = i;
7252 }
7253
7254 // get the declaration's original type and token
7255 const resolved_type *original = NULL;
7256 for (vector<resolved_type>::const_iterator it = resolved_types.begin();
7257 it != resolved_types.end() && original == NULL; ++it)
7258 {
7259 if (it->decl == decl && it->index == index)
7260 original = &(*it);
7261 }
7262
7263 // print basic mismatch msg if we couldn't find the decl (this can happen
7264 // for explicitly typed decls e.g. myvar:long or for fabricated (already
7265 // resolved) decls e.g. __perf_read_*)
7266 if (original == NULL)
7267 {
7268 session.print_error (SEMANTIC_ERROR (
7269 _F("type mismatch: expected %s but found %s",
7270 lex_cast(type).c_str(),
7271 lex_cast(decl->type).c_str()),
7272 tok));
7273 return;
7274 }
7275
7276 // print where mismatch happened and chain with origin of decl type
7277 // resolution
7278 stringstream msg;
7279
7280 if (index >= 0)
7281 msg << _F("index %d ", index);
7282 msg << _F("type mismatch (%s)", lex_cast(type).c_str());
7283 semantic_error err(ERR_SRC, msg.str(), tok);
7284
7285 stringstream chain_msg;
7286 chain_msg << _("type");
7287 if (index >= 0)
7288 chain_msg << _F(" of index %d", index);
7289 chain_msg << _F(" was first inferred here (%s)",
7290 lex_cast(decl->type).c_str());
7291 semantic_error chain(ERR_SRC, chain_msg.str(), original->tok);
7292
7293 err.set_chain(chain);
7294 session.print_error (err);
7295 }
7296 else if (!assert_resolvability)
7297 mismatch_complexity = max(3, mismatch_complexity);
7298 }
7299
7300
7301 /* tok token where resolution occurred
7302 * type type to which we resolved
7303 * decl declaration of resolved symbol
7304 * index if index-based (array index or function arg)
7305 * */
7306 void
7307 typeresolution_info::resolved (const token *tok, exp_type,
7308 const symboldecl* decl, int index)
7309 {
7310 num_newly_resolved ++;
7311
7312 // We only use the resolved_types vector to give better mismatch messages
7313 // involving symbols. So don't bother adding it if we're not given a decl
7314 if (decl != NULL)
7315 {
7316 // As a fail-safe, if the decl & index is already in the vector, then
7317 // modify it instead of adding another one to ensure uniqueness. This
7318 // should never happen since we only call resolved once for each decl &
7319 // index, but better safe than sorry. (IE. if it does happen, better have
7320 // the latest resolution info for better mismatch reporting later).
7321 for (unsigned i = 0; i < resolved_types.size(); i++)
7322 {
7323 if (resolved_types[i].decl == decl
7324 && resolved_types[i].index == index)
7325 {
7326 resolved_types[i].tok = tok;
7327 return;
7328 }
7329 }
7330 resolved_type res(tok, decl, index);
7331 resolved_types.push_back(res);
7332 }
7333 }
7334
7335 void
7336 typeresolution_info::resolved_details (const exp_type_ptr& src,
7337 exp_type_ptr& dest)
7338 {
7339 num_newly_resolved ++;
7340 dest = src;
7341 }
7342
7343 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.391184 seconds and 5 git commands to generate.