]> sourceware.org Git - systemtap.git/blob - translate.cxx
Merge branch 'master' of git://sources.redhat.com/git/systemtap
[systemtap.git] / translate.cxx
1 // translation pass
2 // Copyright (C) 2005-2009 Red Hat Inc.
3 // Copyright (C) 2005-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 "staptree.h"
12 #include "elaborate.h"
13 #include "translate.h"
14 #include "session.h"
15 #include "tapsets.h"
16 #include "util.h"
17 #include "dwarf_wrappers.h"
18
19 #include <cstdlib>
20 #include <iostream>
21 #include <set>
22 #include <sstream>
23 #include <string>
24 #include <cassert>
25 #include <cstring>
26
27 extern "C" {
28 #include <elfutils/libdwfl.h>
29 #ifdef HAVE_ELFUTILS_VERSION_H
30 #include <elfutils/version.h>
31 #endif
32 }
33
34 using namespace std;
35
36 struct var;
37 struct tmpvar;
38 struct aggvar;
39 struct mapvar;
40 struct itervar;
41
42 struct c_unparser: public unparser, public visitor
43 {
44 systemtap_session* session;
45 translator_output* o;
46
47 derived_probe* current_probe;
48 functiondecl* current_function;
49 unsigned tmpvar_counter;
50 unsigned label_counter;
51 unsigned action_counter;
52 bool probe_or_function_needs_deref_fault_handler;
53
54 varuse_collecting_visitor vcv_needs_global_locks;
55
56 map<string, string> probe_contents;
57
58 c_unparser (systemtap_session* ss):
59 session (ss), o (ss->op), current_probe(0), current_function (0),
60 tmpvar_counter (0), label_counter (0) {}
61 ~c_unparser () {}
62
63 void emit_map_type_instantiations ();
64 void emit_common_header ();
65 void emit_global (vardecl* v);
66 void emit_global_init (vardecl* v);
67 void emit_global_param (vardecl* v);
68 void emit_functionsig (functiondecl* v);
69 void emit_unprivileged_user_check ();
70 void emit_module_init ();
71 void emit_module_exit ();
72 void emit_function (functiondecl* v);
73 void emit_locks (const varuse_collecting_visitor& v);
74 void emit_probe (derived_probe* v);
75 void emit_unlocks (const varuse_collecting_visitor& v);
76
77 // for use by stats (pmap) foreach
78 set<string> aggregations_active;
79
80 // for use by looping constructs
81 vector<string> loop_break_labels;
82 vector<string> loop_continue_labels;
83
84 string c_typename (exp_type e);
85 string c_varname (const string& e);
86 string c_expression (expression* e);
87
88 void c_assign (var& lvalue, const string& rvalue, const token* tok);
89 void c_assign (const string& lvalue, expression* rvalue, const string& msg);
90 void c_assign (const string& lvalue, const string& rvalue, exp_type type,
91 const string& msg, const token* tok);
92
93 void c_declare(exp_type ty, const string &name);
94 void c_declare_static(exp_type ty, const string &name);
95
96 void c_strcat (const string& lvalue, const string& rvalue);
97 void c_strcat (const string& lvalue, expression* rvalue);
98
99 void c_strcpy (const string& lvalue, const string& rvalue);
100 void c_strcpy (const string& lvalue, expression* rvalue);
101
102 bool is_local (vardecl const* r, token const* tok);
103
104 tmpvar gensym(exp_type ty);
105 aggvar gensym_aggregate();
106
107 var getvar(vardecl* v, token const* tok = NULL);
108 itervar getiter(symbol* s);
109 mapvar getmap(vardecl* v, token const* tok = NULL);
110
111 void load_map_indices(arrayindex* e,
112 vector<tmpvar> & idx);
113
114 void load_aggregate (expression *e, aggvar & agg, bool pre_agg=false);
115 string histogram_index_check(var & vase, tmpvar & idx) const;
116
117 void collect_map_index_types(vector<vardecl* > const & vars,
118 set< pair<vector<exp_type>, exp_type> > & types);
119
120 void record_actions (unsigned actions, bool update=false);
121
122 void visit_block (block* s);
123 void visit_embeddedcode (embeddedcode* s);
124 void visit_null_statement (null_statement* s);
125 void visit_expr_statement (expr_statement* s);
126 void visit_if_statement (if_statement* s);
127 void visit_for_loop (for_loop* s);
128 void visit_foreach_loop (foreach_loop* s);
129 void visit_return_statement (return_statement* s);
130 void visit_delete_statement (delete_statement* s);
131 void visit_next_statement (next_statement* s);
132 void visit_break_statement (break_statement* s);
133 void visit_continue_statement (continue_statement* s);
134 void visit_literal_string (literal_string* e);
135 void visit_literal_number (literal_number* e);
136 void visit_binary_expression (binary_expression* e);
137 void visit_unary_expression (unary_expression* e);
138 void visit_pre_crement (pre_crement* e);
139 void visit_post_crement (post_crement* e);
140 void visit_logical_or_expr (logical_or_expr* e);
141 void visit_logical_and_expr (logical_and_expr* e);
142 void visit_array_in (array_in* e);
143 void visit_comparison (comparison* e);
144 void visit_concatenation (concatenation* e);
145 void visit_ternary_expression (ternary_expression* e);
146 void visit_assignment (assignment* e);
147 void visit_symbol (symbol* e);
148 void visit_target_symbol (target_symbol* e);
149 void visit_arrayindex (arrayindex* e);
150 void visit_functioncall (functioncall* e);
151 void visit_print_format (print_format* e);
152 void visit_stat_op (stat_op* e);
153 void visit_hist_op (hist_op* e);
154 void visit_cast_op (cast_op* e);
155 };
156
157 // A shadow visitor, meant to generate temporary variable declarations
158 // for function or probe bodies. Member functions should exactly match
159 // the corresponding c_unparser logic and traversal sequence,
160 // to ensure interlocking naming and declaration of temp variables.
161 struct c_tmpcounter:
162 public traversing_visitor
163 {
164 c_unparser* parent;
165 c_tmpcounter (c_unparser* p):
166 parent (p)
167 {
168 parent->tmpvar_counter = 0;
169 }
170
171 void load_map_indices(arrayindex* e);
172
173 void visit_block (block *s);
174 void visit_for_loop (for_loop* s);
175 void visit_foreach_loop (foreach_loop* s);
176 // void visit_return_statement (return_statement* s);
177 void visit_delete_statement (delete_statement* s);
178 void visit_binary_expression (binary_expression* e);
179 // void visit_unary_expression (unary_expression* e);
180 void visit_pre_crement (pre_crement* e);
181 void visit_post_crement (post_crement* e);
182 // void visit_logical_or_expr (logical_or_expr* e);
183 // void visit_logical_and_expr (logical_and_expr* e);
184 void visit_array_in (array_in* e);
185 // void visit_comparison (comparison* e);
186 void visit_concatenation (concatenation* e);
187 // void visit_ternary_expression (ternary_expression* e);
188 void visit_assignment (assignment* e);
189 void visit_arrayindex (arrayindex* e);
190 void visit_functioncall (functioncall* e);
191 void visit_print_format (print_format* e);
192 void visit_stat_op (stat_op* e);
193 };
194
195 struct c_unparser_assignment:
196 public throwing_visitor
197 {
198 c_unparser* parent;
199 string op;
200 expression* rvalue;
201 bool post; // true == value saved before modify operator
202 c_unparser_assignment (c_unparser* p, const string& o, expression* e):
203 throwing_visitor ("invalid lvalue type"),
204 parent (p), op (o), rvalue (e), post (false) {}
205 c_unparser_assignment (c_unparser* p, const string& o, bool pp):
206 throwing_visitor ("invalid lvalue type"),
207 parent (p), op (o), rvalue (0), post (pp) {}
208
209 void prepare_rvalue (string const & op,
210 tmpvar & rval,
211 token const* tok);
212
213 void c_assignop(tmpvar & res,
214 var const & lvar,
215 tmpvar const & tmp,
216 token const* tok);
217
218 // only symbols and arrayindex nodes are possible lvalues
219 void visit_symbol (symbol* e);
220 void visit_arrayindex (arrayindex* e);
221 };
222
223
224 struct c_tmpcounter_assignment:
225 public traversing_visitor
226 // leave throwing for illegal lvalues to the c_unparser_assignment instance
227 {
228 c_tmpcounter* parent;
229 const string& op;
230 expression* rvalue;
231 bool post; // true == value saved before modify operator
232 c_tmpcounter_assignment (c_tmpcounter* p, const string& o, expression* e, bool pp = false):
233 parent (p), op (o), rvalue (e), post (pp) {}
234
235 void prepare_rvalue (tmpvar & rval);
236
237 void c_assignop(tmpvar & res);
238
239 // only symbols and arrayindex nodes are possible lvalues
240 void visit_symbol (symbol* e);
241 void visit_arrayindex (arrayindex* e);
242 };
243
244
245 ostream & operator<<(ostream & o, var const & v);
246
247
248 /*
249 Some clarification on the runtime structures involved in statistics:
250
251 The basic type for collecting statistics in the runtime is struct
252 stat_data. This contains the count, min, max, sum, and possibly
253 histogram fields.
254
255 There are two places struct stat_data shows up.
256
257 1. If you declare a statistic variable of any sort, you want to make
258 a struct _Stat. A struct _Stat* is also called a Stat. Struct _Stat
259 contains a per-CPU array of struct stat_data values, as well as a
260 struct stat_data which it aggregates into. Writes into a Struct
261 _Stat go into the per-CPU struct stat. Reads involve write-locking
262 the struct _Stat, aggregating into its aggregate struct stat_data,
263 unlocking, read-locking the struct _Stat, then reading values out of
264 the aggregate and unlocking.
265
266 2. If you declare a statistic-valued map, you want to make a
267 pmap. This is a per-CPU array of maps, each of which holds struct
268 stat_data values, as well as an aggregate *map*. Writes into a pmap
269 go into the per-CPU map. Reads involve write-locking the pmap,
270 aggregating into its aggregate map, unlocking, read-locking the
271 pmap, then reading values out of its aggregate (which is a normal
272 map) and unlocking.
273
274 Because, at the moment, the runtime does not support the concept of
275 a statistic which collects multiple histogram types, we may need to
276 instantiate one pmap or struct _Stat for each histogram variation
277 the user wants to track.
278 */
279
280 class var
281 {
282
283 protected:
284 bool local;
285 exp_type ty;
286 statistic_decl sd;
287 string name;
288
289 public:
290
291 var(bool local, exp_type ty, statistic_decl const & sd, string const & name)
292 : local(local), ty(ty), sd(sd), name(name)
293 {}
294
295 var(bool local, exp_type ty, string const & name)
296 : local(local), ty(ty), name(name)
297 {}
298
299 virtual ~var() {}
300
301 bool is_local() const
302 {
303 return local;
304 }
305
306 statistic_decl const & sdecl() const
307 {
308 return sd;
309 }
310
311 void assert_hist_compatible(hist_op const & hop)
312 {
313 // Semantic checks in elaborate should have caught this if it was
314 // false. This is just a double-check.
315 switch (sd.type)
316 {
317 case statistic_decl::linear:
318 assert(hop.htype == hist_linear);
319 assert(hop.params.size() == 3);
320 assert(hop.params[0] == sd.linear_low);
321 assert(hop.params[1] == sd.linear_high);
322 assert(hop.params[2] == sd.linear_step);
323 break;
324 case statistic_decl::logarithmic:
325 assert(hop.htype == hist_log);
326 assert(hop.params.size() == 0);
327 break;
328 case statistic_decl::none:
329 assert(false);
330 }
331 }
332
333 exp_type type() const
334 {
335 return ty;
336 }
337
338 string value() const
339 {
340 if (local)
341 return "l->" + name;
342 else
343 return "global.s_" + name;
344 }
345
346 virtual string hist() const
347 {
348 assert (ty == pe_stats);
349 assert (sd.type != statistic_decl::none);
350 return "(&(" + value() + "->hist))";
351 }
352
353 virtual string buckets() const
354 {
355 assert (ty == pe_stats);
356 assert (sd.type != statistic_decl::none);
357 return "(" + value() + "->hist.buckets)";
358 }
359
360 string init() const
361 {
362 switch (type())
363 {
364 case pe_string:
365 if (! local)
366 return ""; // module_param
367 else
368 return value() + "[0] = '\\0';";
369 case pe_long:
370 if (! local)
371 return ""; // module_param
372 else
373 return value() + " = 0;";
374 case pe_stats:
375 {
376 // See also mapvar::init().
377
378 string prefix = value() + " = _stp_stat_init (";
379 // Check for errors during allocation.
380 string suffix = "if (" + value () + " == NULL) rc = -ENOMEM;";
381
382 switch (sd.type)
383 {
384 case statistic_decl::none:
385 prefix += "HIST_NONE";
386 break;
387
388 case statistic_decl::linear:
389 prefix += string("HIST_LINEAR")
390 + ", " + stringify(sd.linear_low)
391 + ", " + stringify(sd.linear_high)
392 + ", " + stringify(sd.linear_step);
393 break;
394
395 case statistic_decl::logarithmic:
396 prefix += string("HIST_LOG");
397 break;
398
399 default:
400 throw semantic_error("unsupported stats type for " + value());
401 }
402
403 prefix = prefix + "); ";
404 return string (prefix + suffix);
405 }
406
407 default:
408 throw semantic_error("unsupported initializer for " + value());
409 }
410 }
411
412 string fini () const
413 {
414 switch (type())
415 {
416 case pe_string:
417 case pe_long:
418 return ""; // no action required
419 case pe_stats:
420 return "_stp_stat_del (" + value () + ");";
421 default:
422 throw semantic_error("unsupported deallocator for " + value());
423 }
424 }
425
426 void declare(c_unparser &c) const
427 {
428 c.c_declare(ty, name);
429 }
430 };
431
432 ostream & operator<<(ostream & o, var const & v)
433 {
434 return o << v.value();
435 }
436
437 struct stmt_expr
438 {
439 c_unparser & c;
440 stmt_expr(c_unparser & c) : c(c)
441 {
442 c.o->newline() << "({";
443 c.o->indent(1);
444 }
445 ~stmt_expr()
446 {
447 c.o->newline(-1) << "})";
448 }
449 };
450
451
452 struct tmpvar
453 : public var
454 {
455 protected:
456 bool overridden;
457 string override_value;
458
459 public:
460 tmpvar(exp_type ty,
461 unsigned & counter)
462 : var(true, ty, ("__tmp" + stringify(counter++))), overridden(false)
463 {}
464
465 tmpvar(const var& source)
466 : var(source), overridden(false)
467 {}
468
469 void override(const string &value)
470 {
471 overridden = true;
472 override_value = value;
473 }
474
475 string value() const
476 {
477 if (overridden)
478 return override_value;
479 else
480 return var::value();
481 }
482 };
483
484 ostream & operator<<(ostream & o, tmpvar const & v)
485 {
486 return o << v.value();
487 }
488
489 struct aggvar
490 : public var
491 {
492 aggvar(unsigned & counter)
493 : var(true, pe_stats, ("__tmp" + stringify(counter++)))
494 {}
495
496 string init() const
497 {
498 assert (type() == pe_stats);
499 return value() + " = NULL;";
500 }
501
502 void declare(c_unparser &c) const
503 {
504 assert (type() == pe_stats);
505 c.o->newline() << "struct stat_data *" << name << ";";
506 }
507 };
508
509 struct mapvar
510 : public var
511 {
512 vector<exp_type> index_types;
513 int maxsize;
514 mapvar (bool local, exp_type ty,
515 statistic_decl const & sd,
516 string const & name,
517 vector<exp_type> const & index_types,
518 int maxsize)
519 : var (local, ty, sd, name),
520 index_types (index_types),
521 maxsize (maxsize)
522 {}
523
524 static string shortname(exp_type e);
525 static string key_typename(exp_type e);
526 static string value_typename(exp_type e);
527
528 string keysym () const
529 {
530 string result;
531 vector<exp_type> tmp = index_types;
532 tmp.push_back (type ());
533 for (unsigned i = 0; i < tmp.size(); ++i)
534 {
535 switch (tmp[i])
536 {
537 case pe_long:
538 result += 'i';
539 break;
540 case pe_string:
541 result += 's';
542 break;
543 case pe_stats:
544 result += 'x';
545 break;
546 default:
547 throw semantic_error("unknown type of map");
548 break;
549 }
550 }
551 return result;
552 }
553
554 string call_prefix (string const & fname, vector<tmpvar> const & indices, bool pre_agg=false) const
555 {
556 string mtype = (is_parallel() && !pre_agg) ? "pmap" : "map";
557 string result = "_stp_" + mtype + "_" + fname + "_" + keysym() + " (";
558 result += pre_agg? fetch_existing_aggregate() : value();
559 for (unsigned i = 0; i < indices.size(); ++i)
560 {
561 if (indices[i].type() != index_types[i])
562 throw semantic_error("index type mismatch");
563 result += ", ";
564 result += indices[i].value();
565 }
566
567 return result;
568 }
569
570 bool is_parallel() const
571 {
572 return type() == pe_stats;
573 }
574
575 string calculate_aggregate() const
576 {
577 if (!is_parallel())
578 throw semantic_error("aggregating non-parallel map type");
579
580 return "_stp_pmap_agg (" + value() + ")";
581 }
582
583 string fetch_existing_aggregate() const
584 {
585 if (!is_parallel())
586 throw semantic_error("fetching aggregate of non-parallel map type");
587
588 return "_stp_pmap_get_agg(" + value() + ")";
589 }
590
591 string del (vector<tmpvar> const & indices) const
592 {
593 return (call_prefix("del", indices) + ")");
594 }
595
596 string exists (vector<tmpvar> const & indices) const
597 {
598 if (type() == pe_long || type() == pe_string)
599 return (call_prefix("exists", indices) + ")");
600 else if (type() == pe_stats)
601 return ("((uintptr_t)" + call_prefix("get", indices)
602 + ") != (uintptr_t) 0)");
603 else
604 throw semantic_error("checking existence of an unsupported map type");
605 }
606
607 string get (vector<tmpvar> const & indices, bool pre_agg=false) const
608 {
609 // see also itervar::get_key
610 if (type() == pe_string)
611 // impedance matching: NULL -> empty strings
612 return ("({ char *v = " + call_prefix("get", indices, pre_agg) + ");"
613 + "if (!v) v = \"\"; v; })");
614 else if (type() == pe_long || type() == pe_stats)
615 return call_prefix("get", indices, pre_agg) + ")";
616 else
617 throw semantic_error("getting a value from an unsupported map type");
618 }
619
620 string add (vector<tmpvar> const & indices, tmpvar const & val) const
621 {
622 string res = "{ int rc = ";
623
624 // impedance matching: empty strings -> NULL
625 if (type() == pe_stats)
626 res += (call_prefix("add", indices) + ", " + val.value() + ")");
627 else
628 throw semantic_error("adding a value of an unsupported map type");
629
630 res += "; if (unlikely(rc)) { c->last_error = \"Array overflow, check " +
631 stringify(maxsize > 0 ?
632 "size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES")
633 + "\"; goto out; }}";
634
635 return res;
636 }
637
638 string set (vector<tmpvar> const & indices, tmpvar const & val) const
639 {
640 string res = "{ int rc = ";
641
642 // impedance matching: empty strings -> NULL
643 if (type() == pe_string)
644 res += (call_prefix("set", indices)
645 + ", (" + val.value() + "[0] ? " + val.value() + " : NULL))");
646 else if (type() == pe_long)
647 res += (call_prefix("set", indices) + ", " + val.value() + ")");
648 else
649 throw semantic_error("setting a value of an unsupported map type");
650
651 res += "; if (unlikely(rc)) { c->last_error = \"Array overflow, check " +
652 stringify(maxsize > 0 ?
653 "size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES")
654 + "\"; goto out; }}";
655
656 return res;
657 }
658
659 string hist() const
660 {
661 assert (ty == pe_stats);
662 assert (sd.type != statistic_decl::none);
663 return "(&(" + fetch_existing_aggregate() + "->hist))";
664 }
665
666 string buckets() const
667 {
668 assert (ty == pe_stats);
669 assert (sd.type != statistic_decl::none);
670 return "(" + fetch_existing_aggregate() + "->hist.buckets)";
671 }
672
673 string init () const
674 {
675 string mtype = is_parallel() ? "pmap" : "map";
676 string prefix = value() + " = _stp_" + mtype + "_new_" + keysym() + " (" +
677 (maxsize > 0 ? stringify(maxsize) : "MAXMAPENTRIES") ;
678
679 // See also var::init().
680
681 // Check for errors during allocation.
682 string suffix = "if (" + value () + " == NULL) rc = -ENOMEM;";
683
684 if (type() == pe_stats)
685 {
686 switch (sdecl().type)
687 {
688 case statistic_decl::none:
689 prefix = prefix + ", HIST_NONE";
690 break;
691
692 case statistic_decl::linear:
693 // FIXME: check for "reasonable" values in linear stats
694 prefix = prefix + ", HIST_LINEAR"
695 + ", " + stringify(sdecl().linear_low)
696 + ", " + stringify(sdecl().linear_high)
697 + ", " + stringify(sdecl().linear_step);
698 break;
699
700 case statistic_decl::logarithmic:
701 prefix = prefix + ", HIST_LOG";
702 break;
703 }
704 }
705
706 prefix = prefix + "); ";
707 return (prefix + suffix);
708 }
709
710 string fini () const
711 {
712 // NB: fini() is safe to call even for globals that have not
713 // successfully initialized (that is to say, on NULL pointers),
714 // because the runtime specifically tolerates that in its _del
715 // functions.
716
717 if (is_parallel())
718 return "_stp_pmap_del (" + value() + ");";
719 else
720 return "_stp_map_del (" + value() + ");";
721 }
722 };
723
724
725 class itervar
726 {
727 exp_type referent_ty;
728 string name;
729
730 public:
731
732 itervar (symbol* e, unsigned & counter)
733 : referent_ty(e->referent->type),
734 name("__tmp" + stringify(counter++))
735 {
736 if (referent_ty == pe_unknown)
737 throw semantic_error("iterating over unknown reference type", e->tok);
738 }
739
740 string declare () const
741 {
742 return "struct map_node *" + name + ";";
743 }
744
745 string start (mapvar const & mv) const
746 {
747 string res;
748
749 if (mv.type() != referent_ty)
750 throw semantic_error("inconsistent iterator type in itervar::start()");
751
752 if (mv.is_parallel())
753 return "_stp_map_start (" + mv.fetch_existing_aggregate() + ")";
754 else
755 return "_stp_map_start (" + mv.value() + ")";
756 }
757
758 string next (mapvar const & mv) const
759 {
760 if (mv.type() != referent_ty)
761 throw semantic_error("inconsistent iterator type in itervar::next()");
762
763 if (mv.is_parallel())
764 return "_stp_map_iter (" + mv.fetch_existing_aggregate() + ", " + value() + ")";
765 else
766 return "_stp_map_iter (" + mv.value() + ", " + value() + ")";
767 }
768
769 string value () const
770 {
771 return "l->" + name;
772 }
773
774 string get_key (exp_type ty, unsigned i) const
775 {
776 // bug translator/1175: runtime uses base index 1 for the first dimension
777 // see also mapval::get
778 switch (ty)
779 {
780 case pe_long:
781 return "_stp_key_get_int64 ("+ value() + ", " + stringify(i+1) + ")";
782 case pe_string:
783 // impedance matching: NULL -> empty strings
784 return "({ char *v = "
785 "_stp_key_get_str ("+ value() + ", " + stringify(i+1) + "); "
786 "if (! v) v = \"\"; "
787 "v; })";
788 default:
789 throw semantic_error("illegal key type");
790 }
791 }
792 };
793
794 ostream & operator<<(ostream & o, itervar const & v)
795 {
796 return o << v.value();
797 }
798
799 // ------------------------------------------------------------------------
800
801
802 translator_output::translator_output (ostream& f):
803 buf(0), o2 (0), o (f), tablevel (0)
804 {
805 }
806
807
808 translator_output::translator_output (const string& filename, size_t bufsize):
809 buf (new char[bufsize]),
810 o2 (new ofstream (filename.c_str ())),
811 o (*o2),
812 tablevel (0)
813 {
814 o2->rdbuf()->pubsetbuf(buf, bufsize);
815 }
816
817
818 translator_output::~translator_output ()
819 {
820 delete o2;
821 delete [] buf;
822 }
823
824
825 ostream&
826 translator_output::newline (int indent)
827 {
828 if (! (indent > 0 || tablevel >= (unsigned)-indent)) o.flush ();
829 assert (indent > 0 || tablevel >= (unsigned)-indent);
830
831 tablevel += indent;
832 o << "\n";
833 for (unsigned i=0; i<tablevel; i++)
834 o << " ";
835 return o;
836 }
837
838
839 void
840 translator_output::indent (int indent)
841 {
842 if (! (indent > 0 || tablevel >= (unsigned)-indent)) o.flush ();
843 assert (indent > 0 || tablevel >= (unsigned)-indent);
844 tablevel += indent;
845 }
846
847
848 ostream&
849 translator_output::line ()
850 {
851 return o;
852 }
853
854
855 // ------------------------------------------------------------------------
856
857 void
858 c_unparser::emit_common_header ()
859 {
860 o->newline();
861 o->newline() << "typedef char string_t[MAXSTRINGLEN];";
862 o->newline();
863 o->newline() << "#define STAP_SESSION_STARTING 0";
864 o->newline() << "#define STAP_SESSION_RUNNING 1";
865 o->newline() << "#define STAP_SESSION_ERROR 2";
866 o->newline() << "#define STAP_SESSION_STOPPING 3";
867 o->newline() << "#define STAP_SESSION_STOPPED 4";
868 o->newline() << "static atomic_t session_state = ATOMIC_INIT (STAP_SESSION_STARTING);";
869 o->newline() << "static atomic_t error_count = ATOMIC_INIT (0);";
870 o->newline() << "static atomic_t skipped_count = ATOMIC_INIT (0);";
871 o->newline() << "static atomic_t skipped_count_lowstack = ATOMIC_INIT (0);";
872 o->newline() << "static atomic_t skipped_count_reentrant = ATOMIC_INIT (0);";
873 o->newline() << "static atomic_t skipped_count_uprobe_reg = ATOMIC_INIT (0);";
874 o->newline() << "static atomic_t skipped_count_uprobe_unreg = ATOMIC_INIT (0);";
875 o->newline();
876 o->newline() << "struct context {";
877 o->newline(1) << "atomic_t busy;";
878 o->newline() << "const char *probe_point;";
879 o->newline() << "int actionremaining;";
880 o->newline() << "unsigned nesting;";
881 o->newline() << "string_t error_buffer;";
882 o->newline() << "const char *last_error;";
883 // NB: last_error is used as a health flag within a probe.
884 // While it's 0, execution continues
885 // When it's "something", probe code unwinds, _stp_error's, sets error state
886 o->newline() << "const char *last_stmt;";
887 o->newline() << "struct pt_regs *regs;";
888 o->newline() << "unsigned long *unwaddr;";
889 // unwaddr is caching unwound address in each probe handler on ia64.
890 o->newline() << "struct kretprobe_instance *pi;";
891 o->newline() << "int regparm;";
892 o->newline() << "va_list *mark_va_list;";
893 o->newline() << "const char * marker_name;";
894 o->newline() << "const char * marker_format;";
895 o->newline() << "void *data;";
896 o->newline() << "#ifdef STP_TIMING";
897 o->newline() << "Stat *statp;";
898 o->newline() << "#endif";
899 o->newline() << "#ifdef STP_OVERLOAD";
900 o->newline() << "cycles_t cycles_base;";
901 o->newline() << "cycles_t cycles_sum;";
902 o->newline() << "#endif";
903 o->newline() << "union {";
904 o->indent(1);
905
906 // To elide context variables for probe handler functions that
907 // themselves are about to get duplicate-eliminated, we XXX
908 // duplicate the parse-tree-hash method from ::emit_probe().
909 map<string, string> tmp_probe_contents;
910 // The reason we don't use c_unparser::probe_contents itself
911 // for this is that we don't want to muck up the data for
912 // that later routine.
913
914 for (unsigned i=0; i<session->probes.size(); i++)
915 {
916 derived_probe* dp = session->probes[i];
917
918 // NB: see c_unparser::emit_probe() for original copy of duplicate-hashing logic.
919 ostringstream oss;
920 oss << "c->statp = & time_" << dp->basest()->name << ";" << endl; // -t anti-dupe
921 oss << "# needs_global_locks: " << dp->needs_global_locks () << endl;
922 dp->print_dupe_stamp (oss);
923 dp->body->print(oss);
924 // NB: dependent probe conditions *could* be listed here, but don't need to be.
925 // That's because they're only dependent on the probe body, which is already
926 // "hashed" in above.
927
928
929 if (tmp_probe_contents.count(oss.str()) == 0) // unique
930 {
931 tmp_probe_contents[oss.str()] = dp->name; // save it
932
933 // XXX: probe locals need not be recursion-nested, only function locals
934
935 o->newline() << "struct " << dp->name << "_locals {";
936 o->indent(1);
937 for (unsigned j=0; j<dp->locals.size(); j++)
938 {
939 vardecl* v = dp->locals[j];
940 try
941 {
942 o->newline() << c_typename (v->type) << " "
943 << c_varname (v->name) << ";";
944 } catch (const semantic_error& e) {
945 semantic_error e2 (e);
946 if (e2.tok1 == 0) e2.tok1 = v->tok;
947 throw e2;
948 }
949 }
950
951 // NB: This part is finicky. The logic here must
952 // match up with
953 c_tmpcounter ct (this);
954 dp->emit_probe_context_vars (o);
955 dp->body->visit (& ct);
956
957 o->newline(-1) << "} " << dp->name << ";";
958 }
959 }
960
961 for (map<string,functiondecl*>::iterator it = session->functions.begin(); it != session->functions.end(); it++)
962 {
963 functiondecl* fd = it->second;
964 o->newline()
965 << "struct function_" << c_varname (fd->name) << "_locals {";
966 o->indent(1);
967 for (unsigned j=0; j<fd->locals.size(); j++)
968 {
969 vardecl* v = fd->locals[j];
970 try
971 {
972 o->newline() << c_typename (v->type) << " "
973 << c_varname (v->name) << ";";
974 } catch (const semantic_error& e) {
975 semantic_error e2 (e);
976 if (e2.tok1 == 0) e2.tok1 = v->tok;
977 throw e2;
978 }
979 }
980 for (unsigned j=0; j<fd->formal_args.size(); j++)
981 {
982 vardecl* v = fd->formal_args[j];
983 try
984 {
985 o->newline() << c_typename (v->type) << " "
986 << c_varname (v->name) << ";";
987 } catch (const semantic_error& e) {
988 semantic_error e2 (e);
989 if (e2.tok1 == 0) e2.tok1 = v->tok;
990 throw e2;
991 }
992 }
993 c_tmpcounter ct (this);
994 fd->body->visit (& ct);
995 if (fd->type == pe_unknown)
996 o->newline() << "/* no return value */";
997 else
998 {
999 o->newline() << c_typename (fd->type) << " __retvalue;";
1000 }
1001 o->newline(-1) << "} function_" << c_varname (fd->name) << ";";
1002 }
1003 o->newline(-1) << "} locals [MAXNESTING];";
1004 o->newline(-1) << "};\n";
1005 o->newline() << "static void *contexts = NULL; /* alloc_percpu */\n";
1006
1007 emit_map_type_instantiations ();
1008
1009 if (!session->stat_decls.empty())
1010 o->newline() << "#include \"stat.c\"\n";
1011
1012 o->newline();
1013 }
1014
1015
1016 void
1017 c_unparser::emit_global_param (vardecl *v)
1018 {
1019 string vn = c_varname (v->name);
1020
1021 // NB: systemtap globals can collide with linux macros,
1022 // e.g. VM_FAULT_MAJOR. We want the parameter name anyway. This
1023 // #undef is spit out at the end of the C file, so that removing the
1024 // definition won't affect any other embedded-C or generated code.
1025 // XXX: better not have a global variable named module_param_named etc.!
1026 o->newline() << "#undef " << vn;
1027
1028 // Emit module_params for this global, if its type is convenient.
1029 if (v->arity == 0 && v->type == pe_long)
1030 {
1031 o->newline() << "module_param_named (" << vn << ", "
1032 << "global.s_" << vn << ", int64_t, 0);";
1033 }
1034 else if (v->arity == 0 && v->type == pe_string)
1035 {
1036 // NB: no special copying is needed.
1037 o->newline() << "module_param_string (" << vn << ", "
1038 << "global.s_" << vn
1039 << ", MAXSTRINGLEN, 0);";
1040 }
1041 }
1042
1043
1044 void
1045 c_unparser::emit_global (vardecl *v)
1046 {
1047 string vn = c_varname (v->name);
1048
1049 if (v->arity == 0)
1050 o->newline() << c_typename (v->type) << " s_" << vn << ";";
1051 else if (v->type == pe_stats)
1052 o->newline() << "PMAP s_" << vn << ";";
1053 else
1054 o->newline() << "MAP s_" << vn << ";";
1055 o->newline() << "rwlock_t s_" << vn << "_lock;";
1056 o->newline() << "#ifdef STP_TIMING";
1057 o->newline() << "atomic_t s_" << vn << "_lock_skip_count;";
1058 o->newline() << "#endif\n";
1059 }
1060
1061
1062 void
1063 c_unparser::emit_global_init (vardecl *v)
1064 {
1065 string vn = c_varname (v->name);
1066
1067 if (v->arity == 0) // can only statically initialize some scalars
1068 {
1069 if (v->init)
1070 {
1071 o->newline() << ".s_" << vn << " = ";
1072 v->init->visit(this);
1073 o->line() << ",";
1074 }
1075 }
1076 o->newline() << "#ifdef STP_TIMING";
1077 o->newline() << ".s_" << vn << "_lock_skip_count = ATOMIC_INIT(0),";
1078 o->newline() << "#endif";
1079 }
1080
1081
1082
1083 void
1084 c_unparser::emit_functionsig (functiondecl* v)
1085 {
1086 o->newline() << "static void function_" << v->name
1087 << " (struct context * __restrict__ c);";
1088 }
1089
1090
1091 void
1092 c_unparser::emit_unprivileged_user_check ()
1093 {
1094 // If the --unprivileged option was specified then the module
1095 // will be safe for unprivileged users, if it is successfully generated,
1096 // so no check need be emitted.
1097 if (session->unprivileged)
1098 return;
1099
1100 // Otherwise, generate code to check whether the user is unprivileged.
1101 // If so, then generate an error and indicate that the check has failed.
1102 o->newline();
1103 o->newline() << "static int systemtap_unprivileged_user_check (void) {";
1104 o->newline(1) << "if (! _stp_unprivileged_user)";
1105 o->newline(1) << "return 0;";
1106
1107 o->newline(-1) << "_stp_error (\"You are attempting to run stap as an ordinary user.\");";
1108 o->newline() << "_stp_error (\"Your module must be compiled using the --unprivileged option.\");";
1109 o->newline() << "return 1;";
1110
1111 o->newline(-1) << "}\n";
1112 }
1113
1114
1115 void
1116 c_unparser::emit_module_init ()
1117 {
1118 vector<derived_probe_group*> g = all_session_groups (*session);
1119 for (unsigned i=0; i<g.size(); i++)
1120 g[i]->emit_module_decls (*session);
1121
1122 o->newline();
1123 o->newline() << "static int systemtap_module_init (void) {";
1124 o->newline(1) << "int rc = 0;";
1125 o->newline() << "int i=0, j=0;"; // for derived_probe_group use
1126 o->newline() << "const char *probe_point = \"\";";
1127
1128 // Compare actual and targeted kernel releases/machines. Sometimes
1129 // one may install the incorrect debuginfo or -devel RPM, and try to
1130 // run a probe compiled for a different version. Catch this early,
1131 // just in case modversions didn't.
1132 o->newline() << "{";
1133 o->newline(1) << "const char* release = UTS_RELEASE;";
1134
1135 // NB: This UTS_RELEASE compile-time macro directly checks only that
1136 // the compile-time kbuild tree matches the compile-time debuginfo/etc.
1137 // It does not check the run time kernel value. However, this is
1138 // probably OK since the kbuild modversions system aims to prevent
1139 // mismatches between kbuild and runtime versions at module-loading time.
1140
1141 // o->newline() << "const char* machine = UTS_MACHINE;";
1142 // NB: We could compare UTS_MACHINE too, but on x86 it lies
1143 // (UTS_MACHINE=i386, but uname -m is i686). Sheesh.
1144
1145 o->newline() << "if (strcmp (release, "
1146 << lex_cast_qstring (session->kernel_release) << ")) {";
1147 o->newline(1) << "_stp_error (\"module release mismatch (%s vs %s)\", "
1148 << "release, "
1149 << lex_cast_qstring (session->kernel_release)
1150 << ");";
1151 o->newline() << "rc = -EINVAL;";
1152 o->newline(-1) << "}";
1153
1154 // perform buildid-based checking if able
1155 o->newline() << "if (_stp_module_check()) rc = -EINVAL;";
1156
1157 o->newline(-1) << "}";
1158
1159 if (! session->unprivileged) {
1160 // Check whether the user is unprivileged.
1161 o->newline() << "if (systemtap_unprivileged_user_check ()) rc = -EINVAL;";
1162 }
1163
1164 o->newline() << "if (rc) goto out;";
1165
1166 o->newline() << "(void) probe_point;";
1167 o->newline() << "(void) i;";
1168 o->newline() << "(void) j;";
1169 o->newline() << "atomic_set (&session_state, STAP_SESSION_STARTING);";
1170 // This signals any other probes that may be invoked in the next little
1171 // while to abort right away. Currently running probes are allowed to
1172 // terminate. These may set STAP_SESSION_ERROR!
1173
1174 // per-cpu context
1175 o->newline() << "if (sizeof (struct context) <= 131072)";
1176 o->newline(1) << "contexts = alloc_percpu (struct context);";
1177 o->newline(-1) << "if (contexts == NULL) {";
1178 o->newline(1) << "_stp_error (\"percpu context (size %lu) allocation failed\", sizeof (struct context));";
1179 o->newline() << "rc = -ENOMEM;";
1180 o->newline() << "goto out;";
1181 o->newline(-1) << "}";
1182
1183 for (unsigned i=0; i<session->globals.size(); i++)
1184 {
1185 vardecl* v = session->globals[i];
1186 if (v->index_types.size() > 0)
1187 o->newline() << getmap (v).init();
1188 else
1189 o->newline() << getvar (v).init();
1190 // NB: in case of failure of allocation, "rc" will be set to non-zero.
1191 // Allocation can in general continue.
1192
1193 o->newline() << "if (rc) {";
1194 o->newline(1) << "_stp_error (\"global variable " << v->name << " allocation failed\");";
1195 o->newline() << "goto out;";
1196 o->newline(-1) << "}";
1197
1198 o->newline() << "rwlock_init (& global.s_" << c_varname (v->name) << "_lock);";
1199 }
1200
1201 // initialize each Stat used for timing information
1202 o->newline() << "#ifdef STP_TIMING";
1203 set<string> basest_names;
1204 for (unsigned i=0; i<session->probes.size(); i++)
1205 {
1206 string nm = session->probes[i]->basest()->name;
1207 if (basest_names.find(nm) == basest_names.end())
1208 {
1209 o->newline() << "time_" << nm << " = _stp_stat_init (HIST_NONE);";
1210 // NB: we don't check for null return here, but instead at
1211 // passage to probe handlers and at final printing.
1212 basest_names.insert (nm);
1213 }
1214 }
1215 o->newline() << "#endif";
1216
1217 // Print a message to the kernel log about this module. This is
1218 // intended to help debug problems with systemtap modules.
1219
1220 o->newline() << "_stp_print_kernel_info("
1221 << "\"" << VERSION
1222 << "/" << dwfl_version (NULL) << "\""
1223 << ", (num_online_cpus() * sizeof(struct context))"
1224 << ", " << session->probes.size()
1225 << ");";
1226
1227 // Run all probe registrations. This actually runs begin probes.
1228
1229 for (unsigned i=0; i<g.size(); i++)
1230 {
1231 g[i]->emit_module_init (*session);
1232 // NB: this gives O(N**2) amount of code, but luckily there
1233 // are only seven or eight derived_probe_groups, so it's ok.
1234 o->newline() << "if (rc) {";
1235 o->newline(1) << "_stp_error (\"probe %s registration error (rc %d)\", probe_point, rc);";
1236 // NB: we need to be in the error state so timers can shutdown cleanly,
1237 // and so end probes don't run. OTOH, error probes can run.
1238 o->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);";
1239 if (i>0)
1240 for (int j=i-1; j>=0; j--)
1241 g[j]->emit_module_exit (*session);
1242 o->newline() << "goto out;";
1243 o->newline(-1) << "}";
1244 }
1245
1246 // All registrations were successful. Consider the system started.
1247 o->newline() << "if (atomic_read (&session_state) == STAP_SESSION_STARTING)";
1248 // NB: only other valid state value is ERROR, in which case we don't
1249 o->newline(1) << "atomic_set (&session_state, STAP_SESSION_RUNNING);";
1250 o->newline(-1) << "return 0;";
1251
1252 // Error handling path; by now all partially registered probe groups
1253 // have been unregistered.
1254 o->newline(-1) << "out:";
1255 o->indent(1);
1256
1257 // If any registrations failed, we will need to deregister the globals,
1258 // as this is our only chance.
1259 for (unsigned i=0; i<session->globals.size(); i++)
1260 {
1261 vardecl* v = session->globals[i];
1262 if (v->index_types.size() > 0)
1263 o->newline() << getmap (v).fini();
1264 else
1265 o->newline() << getvar (v).fini();
1266 }
1267
1268 // For any partially registered/unregistered kernel facilities.
1269 o->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
1270 o->newline() << "synchronize_sched();";
1271 o->newline() << "#endif";
1272
1273 o->newline() << "return rc;";
1274 o->newline(-1) << "}\n";
1275 }
1276
1277
1278 void
1279 c_unparser::emit_module_exit ()
1280 {
1281 o->newline() << "static void systemtap_module_exit (void) {";
1282 // rc?
1283 o->newline(1) << "int holdon;";
1284 o->newline() << "int i=0, j=0;"; // for derived_probe_group use
1285
1286 o->newline() << "(void) i;";
1287 o->newline() << "(void) j;";
1288 // If we aborted startup, then everything has been cleaned up already, and
1289 // module_exit shouldn't even have been called. But since it might be, let's
1290 // beat a hasty retreat to avoid double uninitialization.
1291 o->newline() << "if (atomic_read (&session_state) == STAP_SESSION_STARTING)";
1292 o->newline(1) << "return;";
1293 o->indent(-1);
1294
1295 o->newline() << "if (atomic_read (&session_state) == STAP_SESSION_RUNNING)";
1296 // NB: only other valid state value is ERROR, in which case we don't
1297 o->newline(1) << "atomic_set (&session_state, STAP_SESSION_STOPPING);";
1298 o->indent(-1);
1299 // This signals any other probes that may be invoked in the next little
1300 // while to abort right away. Currently running probes are allowed to
1301 // terminate. These may set STAP_SESSION_ERROR!
1302
1303 // We're processing the derived_probe_group list in reverse
1304 // order. This ensures that probes get unregistered in reverse
1305 // order of the way they were registered.
1306 vector<derived_probe_group*> g = all_session_groups (*session);
1307 for (vector<derived_probe_group*>::reverse_iterator i = g.rbegin();
1308 i != g.rend(); i++)
1309 (*i)->emit_module_exit (*session); // NB: runs "end" probes
1310
1311 // But some other probes may have launched too during unregistration.
1312 // Let's wait a while to make sure they're all done, done, done.
1313
1314 // cargo cult prologue
1315 o->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
1316 o->newline() << "synchronize_sched();";
1317 o->newline() << "#endif";
1318
1319 // NB: systemtap_module_exit is assumed to be called from ordinary
1320 // user context, say during module unload. Among other things, this
1321 // means we can sleep a while.
1322 o->newline() << "do {";
1323 o->newline(1) << "int i;";
1324 o->newline() << "holdon = 0;";
1325 o->newline() << "for (i=0; i < NR_CPUS; i++)";
1326 o->newline(1) << "if (cpu_possible (i) && "
1327 << "atomic_read (& ((struct context *)per_cpu_ptr(contexts, i))->busy)) "
1328 << "holdon = 1;";
1329 // NB: we run at least one of these during the shutdown sequence:
1330 o->newline () << "yield ();"; // aka schedule() and then some
1331 o->newline(-2) << "} while (holdon);";
1332
1333 // cargo cult epilogue
1334 o->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
1335 o->newline() << "synchronize_sched();";
1336 o->newline() << "#endif";
1337
1338 // XXX: might like to have an escape hatch, in case some probe is
1339 // genuinely stuck somehow
1340
1341 for (unsigned i=0; i<session->globals.size(); i++)
1342 {
1343 vardecl* v = session->globals[i];
1344 if (v->index_types.size() > 0)
1345 o->newline() << getmap (v).fini();
1346 else
1347 o->newline() << getvar (v).fini();
1348 }
1349
1350 o->newline() << "free_percpu (contexts);";
1351
1352 // print probe timing statistics
1353 {
1354 o->newline() << "#ifdef STP_TIMING";
1355 o->newline() << "{";
1356 o->indent(1);
1357 set<string> basest_names;
1358 for (unsigned i=0; i<session->probes.size(); i++)
1359 {
1360 probe* p = session->probes[i]->basest();
1361 string nm = p->name;
1362 if (basest_names.find(nm) == basest_names.end())
1363 {
1364 basest_names.insert (nm);
1365 // NB: check for null stat object
1366 o->newline() << "if (likely (time_" << p->name << ")) {";
1367 o->newline(1) << "const char *probe_point = "
1368 << lex_cast_qstring (* p->locations[0])
1369 << (p->locations.size() > 1 ? "\"+\"" : "")
1370 << (p->locations.size() > 1 ? lex_cast_qstring(p->locations.size()-1) : "")
1371 << ";";
1372 o->newline() << "const char *decl_location = "
1373 << lex_cast_qstring (p->tok->location)
1374 << ";";
1375 o->newline() << "struct stat_data *stats = _stp_stat_get (time_"
1376 << p->name
1377 << ", 0);";
1378 o->newline() << "if (stats->count) {";
1379 o->newline(1) << "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);";
1380 o->newline() << "_stp_printf (\"probe %s (%s), hits: %lld, cycles: %lldmin/%lldavg/%lldmax\\n\",";
1381 o->newline() << "probe_point, decl_location, (long long) stats->count, (long long) stats->min, (long long) avg, (long long) stats->max);";
1382 o->newline(-1) << "}";
1383 o->newline() << "_stp_stat_del (time_" << p->name << ");";
1384 o->newline(-1) << "}";
1385 }
1386 }
1387 o->newline() << "_stp_print_flush();";
1388 o->newline(-1) << "}";
1389 o->newline() << "#endif";
1390 }
1391
1392 // print final error/skipped counts if non-zero
1393 o->newline() << "if (atomic_read (& skipped_count) || "
1394 << "atomic_read (& error_count) || "
1395 << "atomic_read (& skipped_count_reentrant)) {"; // PR9967
1396 o->newline(1) << "_stp_warn (\"Number of errors: %d, "
1397 << "skipped probes: %d\\n\", "
1398 << "(int) atomic_read (& error_count), "
1399 << "(int) atomic_read (& skipped_count));";
1400 o->newline() << "#ifdef STP_TIMING";
1401 o->newline() << "{";
1402 o->newline(1) << "int ctr;";
1403 for (unsigned i=0; i<session->globals.size(); i++)
1404 {
1405 string vn = c_varname (session->globals[i]->name);
1406 o->newline() << "ctr = atomic_read (& global.s_" << vn << "_lock_skip_count);";
1407 o->newline() << "if (ctr) _stp_warn (\"Skipped due to global '%s' lock timeout: %d\\n\", "
1408 << lex_cast_qstring(vn) << ", ctr);";
1409 }
1410 o->newline() << "ctr = atomic_read (& skipped_count_lowstack);";
1411 o->newline() << "if (ctr) _stp_warn (\"Skipped due to low stack: %d\\n\", ctr);";
1412 o->newline() << "ctr = atomic_read (& skipped_count_reentrant);";
1413 o->newline() << "if (ctr) _stp_warn (\"Skipped due to reentrancy: %d\\n\", ctr);";
1414 o->newline() << "ctr = atomic_read (& skipped_count_uprobe_reg);";
1415 o->newline() << "if (ctr) _stp_warn (\"Skipped due to uprobe register failure: %d\\n\", ctr);";
1416 o->newline() << "ctr = atomic_read (& skipped_count_uprobe_unreg);";
1417 o->newline() << "if (ctr) _stp_warn (\"Skipped due to uprobe unregister failure: %d\\n\", ctr);";
1418 o->newline(-1) << "}";
1419 o->newline () << "#endif";
1420 o->newline() << "_stp_print_flush();";
1421 o->newline(-1) << "}";
1422 o->newline(-1) << "}\n";
1423 }
1424
1425
1426 void
1427 c_unparser::emit_function (functiondecl* v)
1428 {
1429 o->newline() << "static void function_" << c_varname (v->name)
1430 << " (struct context* __restrict__ c) {";
1431 o->indent(1);
1432 this->current_probe = 0;
1433 this->current_function = v;
1434 this->tmpvar_counter = 0;
1435 this->action_counter = 0;
1436
1437 o->newline()
1438 << "struct function_" << c_varname (v->name) << "_locals * "
1439 << " __restrict__ l =";
1440 o->newline(1)
1441 << "& c->locals[c->nesting+1].function_" << c_varname (v->name) // NB: nesting+1
1442 << ";";
1443 o->newline(-1) << "(void) l;"; // make sure "l" is marked used
1444 o->newline() << "#define CONTEXT c";
1445 o->newline() << "#define THIS l";
1446 o->newline() << "if (0) goto out;"; // make sure out: is marked used
1447
1448 // set this, in case embedded-c code sets last_error but doesn't otherwise identify itself
1449 o->newline() << "c->last_stmt = " << lex_cast_qstring(*v->tok) << ";";
1450
1451 // check/increment nesting level
1452 o->newline() << "if (unlikely (c->nesting+2 >= MAXNESTING)) {";
1453 o->newline(1) << "c->last_error = \"MAXNESTING exceeded\";";
1454 o->newline() << "return;";
1455 o->newline(-1) << "} else {";
1456 o->newline(1) << "c->nesting ++;";
1457 o->newline(-1) << "}";
1458
1459 // initialize locals
1460 // XXX: optimization: use memset instead
1461 for (unsigned i=0; i<v->locals.size(); i++)
1462 {
1463 if (v->locals[i]->index_types.size() > 0) // array?
1464 throw semantic_error ("array locals not supported, missing global declaration?",
1465 v->locals[i]->tok);
1466
1467 o->newline() << getvar (v->locals[i]).init();
1468 }
1469
1470 // initialize return value, if any
1471 if (v->type != pe_unknown)
1472 {
1473 var retvalue = var(true, v->type, "__retvalue");
1474 o->newline() << retvalue.init();
1475 }
1476
1477 o->newline() << "#define return goto out"; // redirect embedded-C return
1478 this->probe_or_function_needs_deref_fault_handler = false;
1479 v->body->visit (this);
1480 o->newline() << "#undef return";
1481
1482 this->current_function = 0;
1483
1484 record_actions(0, true);
1485
1486 if (this->probe_or_function_needs_deref_fault_handler) {
1487 // Emit this handler only if the body included a
1488 // print/printf/etc. using a string or memory buffer!
1489 o->newline() << "CATCH_DEREF_FAULT ();";
1490 }
1491
1492 o->newline(-1) << "out:";
1493 o->newline(1) << ";";
1494
1495 // Function prologue: this is why we redirect the "return" above.
1496 // Decrement nesting level.
1497 o->newline() << "c->nesting --;";
1498
1499 o->newline() << "#undef CONTEXT";
1500 o->newline() << "#undef THIS";
1501 o->newline(-1) << "}\n";
1502 }
1503
1504
1505 #define DUPMETHOD_CALL 0
1506 #define DUPMETHOD_ALIAS 0
1507 #define DUPMETHOD_RENAME 1
1508
1509 void
1510 c_unparser::emit_probe (derived_probe* v)
1511 {
1512 this->current_function = 0;
1513 this->current_probe = v;
1514 this->tmpvar_counter = 0;
1515 this->action_counter = 0;
1516
1517 // If we about to emit a probe that is exactly the same as another
1518 // probe previously emitted, make the second probe just call the
1519 // first one.
1520 //
1521 // Notice we're using the probe body itself instead of the emitted C
1522 // probe body to compare probes. We need to do this because the
1523 // emitted C probe body has stuff in it like:
1524 // c->last_stmt = "identifier 'printf' at foo.stp:<line>:<column>";
1525 //
1526 // which would make comparisons impossible.
1527 //
1528 // --------------------------------------------------------------------------
1529 // NB: see also c_unparser:emit_common_header(), which deliberately but sadly
1530 // duplicates this calculation.
1531 // --------------------------------------------------------------------------
1532 //
1533 ostringstream oss;
1534
1535 // NB: statp is just for avoiding designation as duplicate. It need not be C.
1536 // NB: This code *could* be enclosed in an "if (session->timing)". That would
1537 // recognize more duplicate probe handlers, but then the generated code could
1538 // be very different with or without -t.
1539 oss << "c->statp = & time_" << v->basest()->name << ";" << endl;
1540
1541 v->print_dupe_stamp (oss);
1542 v->body->print(oss);
1543
1544 // Since the generated C changes based on whether or not the probe
1545 // needs locks around global variables, this needs to be reflected
1546 // here. We don't want to treat as duplicate the handlers of
1547 // begin/end and normal probes that differ only in need_global_locks.
1548 oss << "# needs_global_locks: " << v->needs_global_locks () << endl;
1549
1550 // If an identical probe has already been emitted, just call that
1551 // one.
1552 if (probe_contents.count(oss.str()) != 0)
1553 {
1554 string dupe = probe_contents[oss.str()];
1555
1556 // NB: Elision of context variable structs is a separate
1557 // operation which has already taken place by now.
1558 if (session->verbose > 1)
1559 clog << v->name << " elided, duplicates " << dupe << endl;
1560
1561 #if DUPMETHOD_CALL
1562 // This one emits a direct call to the first copy.
1563 o->newline();
1564 o->newline() << "static void " << v->name << " (struct context * __restrict__ c) ";
1565 o->newline() << "{ " << dupe << " (c); }";
1566 #elif DUPMETHOD_ALIAS
1567 // This one defines a function alias, arranging gcc to emit
1568 // several equivalent symbols for the same function body.
1569 // For some reason, on gcc 4.1, this is twice as slow as
1570 // the CALL option.
1571 o->newline();
1572 o->newline() << "static void " << v->name << " (struct context * __restrict__ c) ";
1573 o->line() << "__attribute__ ((alias (\"" << dupe << "\")));";
1574 #elif DUPMETHOD_RENAME
1575 // This one is sneaky. It emits nothing for duplicate probe
1576 // handlers. It instead redirects subsequent references to the
1577 // probe handler function to the first copy, *by name*.
1578 v->name = dupe;
1579 #else
1580 #error "Unknown duplicate elimination method"
1581 #endif
1582 }
1583 else // This probe is unique. Remember it and output it.
1584 {
1585 this->probe_or_function_needs_deref_fault_handler = false;
1586
1587 o->newline();
1588 o->newline() << "#ifdef STP_TIMING";
1589 o->newline() << "static __cacheline_aligned Stat " << "time_" << v->basest()->name << ";";
1590 o->newline() << "#endif";
1591 o->newline();
1592 o->newline() << "static void " << v->name << " (struct context * __restrict__ c) ";
1593 o->line () << "{";
1594 o->indent (1);
1595
1596 probe_contents[oss.str()] = v->name;
1597
1598 // initialize frame pointer
1599 o->newline() << "struct " << v->name << "_locals * __restrict__ l =";
1600 o->newline(1) << "& c->locals[0]." << v->name << ";";
1601 o->newline(-1) << "(void) l;"; // make sure "l" is marked used
1602
1603 o->newline() << "#ifdef STP_TIMING";
1604 o->newline() << "c->statp = & time_" << v->basest()->name << ";";
1605 o->newline() << "#endif";
1606
1607 // emit probe local initialization block
1608 v->emit_probe_local_init(o);
1609
1610 // emit all read/write locks for global variables
1611 varuse_collecting_visitor vut;
1612 if (v->needs_global_locks ())
1613 {
1614 v->body->visit (& vut);
1615 emit_locks (vut);
1616 }
1617
1618 // initialize locals
1619 for (unsigned j=0; j<v->locals.size(); j++)
1620 {
1621 if (v->locals[j]->index_types.size() > 0) // array?
1622 throw semantic_error ("array locals not supported, missing global declaration?",
1623 v->locals[j]->tok);
1624 else if (v->locals[j]->type == pe_long)
1625 o->newline() << "l->" << c_varname (v->locals[j]->name)
1626 << " = 0;";
1627 else if (v->locals[j]->type == pe_string)
1628 o->newline() << "l->" << c_varname (v->locals[j]->name)
1629 << "[0] = '\\0';";
1630 else
1631 throw semantic_error ("unsupported local variable type",
1632 v->locals[j]->tok);
1633 }
1634
1635 v->initialize_probe_context_vars (o);
1636
1637 v->body->visit (this);
1638
1639 record_actions(0, true);
1640
1641 if (this->probe_or_function_needs_deref_fault_handler) {
1642 // Emit this handler only if the body included a
1643 // print/printf/etc. using a string or memory buffer!
1644 o->newline() << "CATCH_DEREF_FAULT ();";
1645 }
1646
1647 o->newline(-1) << "out:";
1648 // NB: no need to uninitialize locals, except if arrays/stats can
1649 // someday be local
1650
1651 // XXX: do this flush only if the body included a
1652 // print/printf/etc. routine!
1653 o->newline(1) << "_stp_print_flush();";
1654
1655 if (v->needs_global_locks ())
1656 emit_unlocks (vut);
1657
1658 o->newline(-1) << "}\n";
1659 }
1660
1661
1662 this->current_probe = 0;
1663 }
1664
1665
1666 void
1667 c_unparser::emit_locks(const varuse_collecting_visitor& vut)
1668 {
1669 o->newline() << "{";
1670 o->newline(1) << "unsigned numtrylock = 0;";
1671 o->newline() << "(void) numtrylock;";
1672
1673 string last_locked_var;
1674 for (unsigned i = 0; i < session->globals.size(); i++)
1675 {
1676 vardecl* v = session->globals[i];
1677 bool read_p = vut.read.find(v) != vut.read.end();
1678 bool write_p = vut.written.find(v) != vut.written.end();
1679 if (!read_p && !write_p) continue;
1680
1681 if (v->type == pe_stats) // read and write locks are flipped
1682 // Specifically, a "<<<" to a stats object is considered a
1683 // "shared-lock" operation, since it's implicitly done
1684 // per-cpu. But a "@op(x)" extraction is an "exclusive-lock"
1685 // one, as is a (sorted or unsorted) foreach, so those cases
1686 // are excluded by the w & !r condition below.
1687 {
1688 if (write_p && !read_p) { read_p = true; write_p = false; }
1689 else if (read_p && !write_p) { read_p = false; write_p = true; }
1690 }
1691
1692 // We don't need to read lock "read-mostly" global variables. A
1693 // "read-mostly" global variable is only written to within
1694 // probes that don't need global variable locking (such as
1695 // begin/end probes). If vcv_needs_global_locks doesn't mark
1696 // the global as written to, then we don't have to lock it
1697 // here to read it safely.
1698 if (read_p && !write_p)
1699 {
1700 if (vcv_needs_global_locks.written.find(v)
1701 == vcv_needs_global_locks.written.end())
1702 continue;
1703 }
1704
1705 string lockcall =
1706 string (write_p ? "write" : "read") +
1707 "_trylock (& global.s_" + v->name + "_lock)";
1708
1709 o->newline() << "while (! " << lockcall
1710 << "&& (++numtrylock < MAXTRYLOCK))";
1711 o->newline(1) << "ndelay (TRYLOCKDELAY);";
1712 o->newline(-1) << "if (unlikely (numtrylock >= MAXTRYLOCK)) {";
1713 o->newline(1) << "atomic_inc (& skipped_count);";
1714 o->newline() << "#ifdef STP_TIMING";
1715 o->newline() << "atomic_inc (& global.s_" << c_varname (v->name) << "_lock_skip_count);";
1716 o->newline() << "#endif";
1717 // The following works even if i==0. Note that using
1718 // globals[i-1]->name is wrong since that global may not have
1719 // been lockworthy by this probe.
1720 o->newline() << "goto unlock_" << last_locked_var << ";";
1721 o->newline(-1) << "}";
1722
1723 last_locked_var = v->name;
1724 }
1725
1726 o->newline() << "if (0) goto unlock_;";
1727
1728 o->newline(-1) << "}";
1729 }
1730
1731
1732 void
1733 c_unparser::emit_unlocks(const varuse_collecting_visitor& vut)
1734 {
1735 unsigned numvars = 0;
1736
1737 if (session->verbose>1)
1738 clog << current_probe->name << " locks ";
1739
1740 for (int i = session->globals.size()-1; i>=0; i--) // in reverse order!
1741 {
1742 vardecl* v = session->globals[i];
1743 bool read_p = vut.read.find(v) != vut.read.end();
1744 bool write_p = vut.written.find(v) != vut.written.end();
1745 if (!read_p && !write_p) continue;
1746
1747 // Duplicate lock flipping logic from above
1748 if (v->type == pe_stats)
1749 {
1750 if (write_p && !read_p) { read_p = true; write_p = false; }
1751 else if (read_p && !write_p) { read_p = false; write_p = true; }
1752 }
1753
1754 // Duplicate "read-mostly" global variable logic from above.
1755 if (read_p && !write_p)
1756 {
1757 if (vcv_needs_global_locks.written.find(v)
1758 == vcv_needs_global_locks.written.end())
1759 continue;
1760 }
1761
1762 numvars ++;
1763 o->newline(-1) << "unlock_" << v->name << ":";
1764 o->indent(1);
1765
1766 if (session->verbose>1)
1767 clog << v->name << "[" << (read_p ? "r" : "")
1768 << (write_p ? "w" : "") << "] ";
1769
1770 if (write_p) // emit write lock
1771 o->newline() << "write_unlock (& global.s_" << v->name << "_lock);";
1772 else // (read_p && !write_p) : emit read lock
1773 o->newline() << "read_unlock (& global.s_" << v->name << "_lock);";
1774
1775 // fall through to next variable; thus the reverse ordering
1776 }
1777
1778 // emit plain "unlock" label, used if the very first lock failed.
1779 o->newline(-1) << "unlock_: ;";
1780 o->indent(1);
1781
1782 if (numvars) // is there a chance that any lock attempt failed?
1783 {
1784 // Formerly, we checked skipped_count > MAXSKIPPED here, and set
1785 // SYSTEMTAP_SESSION_ERROR if so. But now, this check is shared
1786 // via common_probe_entryfn_epilogue().
1787
1788 if (session->verbose>1)
1789 clog << endl;
1790 }
1791 else if (session->verbose>1)
1792 clog << "nothing" << endl;
1793 }
1794
1795
1796 void
1797 c_unparser::collect_map_index_types(vector<vardecl *> const & vars,
1798 set< pair<vector<exp_type>, exp_type> > & types)
1799 {
1800 for (unsigned i = 0; i < vars.size(); ++i)
1801 {
1802 vardecl *v = vars[i];
1803 if (v->arity > 0)
1804 {
1805 types.insert(make_pair(v->index_types, v->type));
1806 }
1807 }
1808 }
1809
1810 string
1811 mapvar::value_typename(exp_type e)
1812 {
1813 switch (e)
1814 {
1815 case pe_long:
1816 return "INT64";
1817 case pe_string:
1818 return "STRING";
1819 case pe_stats:
1820 return "STAT";
1821 default:
1822 throw semantic_error("array type is neither string nor long");
1823 }
1824 return "";
1825 }
1826
1827 string
1828 mapvar::key_typename(exp_type e)
1829 {
1830 switch (e)
1831 {
1832 case pe_long:
1833 return "INT64";
1834 case pe_string:
1835 return "STRING";
1836 default:
1837 throw semantic_error("array key is neither string nor long");
1838 }
1839 return "";
1840 }
1841
1842 string
1843 mapvar::shortname(exp_type e)
1844 {
1845 switch (e)
1846 {
1847 case pe_long:
1848 return "i";
1849 case pe_string:
1850 return "s";
1851 default:
1852 throw semantic_error("array type is neither string nor long");
1853 }
1854 return "";
1855 }
1856
1857
1858 void
1859 c_unparser::emit_map_type_instantiations ()
1860 {
1861 set< pair<vector<exp_type>, exp_type> > types;
1862
1863 collect_map_index_types(session->globals, types);
1864
1865 for (unsigned i = 0; i < session->probes.size(); ++i)
1866 collect_map_index_types(session->probes[i]->locals, types);
1867
1868 for (map<string,functiondecl*>::iterator it = session->functions.begin(); it != session->functions.end(); it++)
1869 collect_map_index_types(it->second->locals, types);
1870
1871 if (!types.empty())
1872 o->newline() << "#include \"alloc.c\"";
1873
1874 for (set< pair<vector<exp_type>, exp_type> >::const_iterator i = types.begin();
1875 i != types.end(); ++i)
1876 {
1877 o->newline() << "#define VALUE_TYPE " << mapvar::value_typename(i->second);
1878 for (unsigned j = 0; j < i->first.size(); ++j)
1879 {
1880 string ktype = mapvar::key_typename(i->first.at(j));
1881 o->newline() << "#define KEY" << (j+1) << "_TYPE " << ktype;
1882 }
1883 if (i->second == pe_stats)
1884 o->newline() << "#include \"pmap-gen.c\"";
1885 else
1886 o->newline() << "#include \"map-gen.c\"";
1887 o->newline() << "#undef VALUE_TYPE";
1888 for (unsigned j = 0; j < i->first.size(); ++j)
1889 {
1890 o->newline() << "#undef KEY" << (j+1) << "_TYPE";
1891 }
1892
1893 /* FIXME
1894 * For pmaps, we also need to include map-gen.c, because we might be accessing
1895 * the aggregated map. The better way to handle this is for pmap-gen.c to make
1896 * this include, but that's impossible with the way they are set up now.
1897 */
1898 if (i->second == pe_stats)
1899 {
1900 o->newline() << "#define VALUE_TYPE " << mapvar::value_typename(i->second);
1901 for (unsigned j = 0; j < i->first.size(); ++j)
1902 {
1903 string ktype = mapvar::key_typename(i->first.at(j));
1904 o->newline() << "#define KEY" << (j+1) << "_TYPE " << ktype;
1905 }
1906 o->newline() << "#include \"map-gen.c\"";
1907 o->newline() << "#undef VALUE_TYPE";
1908 for (unsigned j = 0; j < i->first.size(); ++j)
1909 {
1910 o->newline() << "#undef KEY" << (j+1) << "_TYPE";
1911 }
1912 }
1913 }
1914
1915 if (!types.empty())
1916 o->newline() << "#include \"map.c\"";
1917
1918 };
1919
1920
1921 string
1922 c_unparser::c_typename (exp_type e)
1923 {
1924 switch (e)
1925 {
1926 case pe_long: return string("int64_t");
1927 case pe_string: return string("string_t");
1928 case pe_stats: return string("Stat");
1929 case pe_unknown:
1930 default:
1931 throw semantic_error ("cannot expand unknown type");
1932 }
1933 }
1934
1935
1936 string
1937 c_unparser::c_varname (const string& e)
1938 {
1939 // XXX: safeify, uniquefy, given name
1940 return e;
1941 }
1942
1943
1944 string
1945 c_unparser::c_expression (expression *e)
1946 {
1947 // We want to evaluate expression 'e' and return its value as a
1948 // string. In the case of expressions that are just numeric
1949 // constants, if we just print the value into a string, it won't
1950 // have the same value as being visited by c_unparser. For
1951 // instance, a numeric constant evaluated using print() would return
1952 // "5", while c_unparser::visit_literal_number() would
1953 // return "((int64_t)5LL)". String constants evaluated using
1954 // print() would just return the string, while
1955 // c_unparser::visit_literal_string() would return the string with
1956 // escaped double quote characters. So, we need to "visit" the
1957 // expression.
1958
1959 // However, we have to be careful of side effects. Currently this
1960 // code is only being used for evaluating literal numbers and
1961 // strings, which currently have no side effects. Until needed
1962 // otherwise, limit the use of this function to literal numbers and
1963 // strings.
1964 if (e->tok->type != tok_number && e->tok->type != tok_string)
1965 throw semantic_error("unsupported c_expression token type");
1966
1967 // Create a fake output stream so we can grab the string output.
1968 ostringstream oss;
1969 translator_output tmp_o(oss);
1970
1971 // Temporarily swap out the real translator_output stream with our
1972 // fake one.
1973 translator_output *saved_o = o;
1974 o = &tmp_o;
1975
1976 // Visit the expression then restore the original output stream
1977 e->visit (this);
1978 o = saved_o;
1979
1980 return (oss.str());
1981 }
1982
1983
1984 void
1985 c_unparser::c_assign (var& lvalue, const string& rvalue, const token *tok)
1986 {
1987 switch (lvalue.type())
1988 {
1989 case pe_string:
1990 c_strcpy(lvalue.value(), rvalue);
1991 break;
1992 case pe_long:
1993 o->newline() << lvalue << " = " << rvalue << ";";
1994 break;
1995 default:
1996 throw semantic_error ("unknown lvalue type in assignment", tok);
1997 }
1998 }
1999
2000 void
2001 c_unparser::c_assign (const string& lvalue, expression* rvalue,
2002 const string& msg)
2003 {
2004 if (rvalue->type == pe_long)
2005 {
2006 o->newline() << lvalue << " = ";
2007 rvalue->visit (this);
2008 o->line() << ";";
2009 }
2010 else if (rvalue->type == pe_string)
2011 {
2012 c_strcpy (lvalue, rvalue);
2013 }
2014 else
2015 {
2016 string fullmsg = msg + " type unsupported";
2017 throw semantic_error (fullmsg, rvalue->tok);
2018 }
2019 }
2020
2021
2022 void
2023 c_unparser::c_assign (const string& lvalue, const string& rvalue,
2024 exp_type type, const string& msg, const token* tok)
2025 {
2026 if (type == pe_long)
2027 {
2028 o->newline() << lvalue << " = " << rvalue << ";";
2029 }
2030 else if (type == pe_string)
2031 {
2032 c_strcpy (lvalue, rvalue);
2033 }
2034 else
2035 {
2036 string fullmsg = msg + " type unsupported";
2037 throw semantic_error (fullmsg, tok);
2038 }
2039 }
2040
2041
2042 void
2043 c_unparser_assignment::c_assignop(tmpvar & res,
2044 var const & lval,
2045 tmpvar const & rval,
2046 token const * tok)
2047 {
2048 // This is common code used by scalar and array-element assignments.
2049 // It assumes an operator-and-assignment (defined by the 'pre' and
2050 // 'op' fields of c_unparser_assignment) is taking place between the
2051 // following set of variables:
2052 //
2053 // res: the result of evaluating the expression, a temporary
2054 // lval: the lvalue of the expression, which may be damaged
2055 // rval: the rvalue of the expression, which is a temporary or constant
2056
2057 // we'd like to work with a local tmpvar so we can overwrite it in
2058 // some optimized cases
2059
2060 translator_output* o = parent->o;
2061
2062 if (res.type() == pe_string)
2063 {
2064 if (post)
2065 throw semantic_error ("post assignment on strings not supported",
2066 tok);
2067 if (op == "=")
2068 {
2069 parent->c_strcpy (lval.value(), rval.value());
2070 // no need for second copy
2071 res = rval;
2072 }
2073 else if (op == ".=")
2074 {
2075 parent->c_strcat (lval.value(), rval.value());
2076 res = lval;
2077 }
2078 else
2079 throw semantic_error ("string assignment operator " +
2080 op + " unsupported", tok);
2081 }
2082 else if (op == "<<<")
2083 {
2084 assert(lval.type() == pe_stats);
2085 assert(rval.type() == pe_long);
2086 assert(res.type() == pe_long);
2087 o->newline() << res << " = " << rval << ";";
2088 o->newline() << "_stp_stat_add (" << lval << ", " << res << ");";
2089 }
2090 else if (res.type() == pe_long)
2091 {
2092 // a lot of operators come through this "gate":
2093 // - vanilla assignment "="
2094 // - stats aggregation "<<<"
2095 // - modify-accumulate "+=" and many friends
2096 // - pre/post-crement "++"/"--"
2097 // - "/" and "%" operators, but these need special handling in kernel
2098
2099 // compute the modify portion of a modify-accumulate
2100 string macop;
2101 unsigned oplen = op.size();
2102 if (op == "=")
2103 macop = "*error*"; // special shortcuts below
2104 else if (op == "++" || op == "+=")
2105 macop = "+=";
2106 else if (op == "--" || op == "-=")
2107 macop = "-=";
2108 else if (oplen > 1 && op[oplen-1] == '=') // for *=, <<=, etc...
2109 macop = op;
2110 else
2111 // internal error
2112 throw semantic_error ("unknown macop for assignment", tok);
2113
2114 if (post)
2115 {
2116 if (macop == "/" || macop == "%" || op == "=")
2117 throw semantic_error ("invalid post-mode operator", tok);
2118
2119 o->newline() << res << " = " << lval << ";";
2120
2121 if (macop == "+=" || macop == "-=")
2122 o->newline() << lval << " " << macop << " " << rval << ";";
2123 else
2124 o->newline() << lval << " = " << res << " " << macop << " " << rval << ";";
2125 }
2126 else
2127 {
2128 if (op == "=") // shortcut simple assignment
2129 {
2130 o->newline() << lval << " = " << rval << ";";
2131 res = rval;
2132 }
2133 else
2134 {
2135 if (macop == "/=" || macop == "%=")
2136 {
2137 o->newline() << "if (unlikely(!" << rval << ")) {";
2138 o->newline(1) << "c->last_error = \"division by 0\";";
2139 o->newline() << "goto out;";
2140 o->newline(-1) << "}";
2141 o->newline() << lval << " = "
2142 << ((macop == "/=") ? "_stp_div64" : "_stp_mod64")
2143 << " (NULL, " << lval << ", " << rval << ");";
2144 }
2145 else
2146 o->newline() << lval << " " << macop << " " << rval << ";";
2147 res = lval;
2148 }
2149 }
2150 }
2151 else
2152 throw semantic_error ("assignment type not yet implemented", tok);
2153 }
2154
2155
2156 void
2157 c_unparser::c_declare(exp_type ty, const string &name)
2158 {
2159 o->newline() << c_typename (ty) << " " << c_varname (name) << ";";
2160 }
2161
2162
2163 void
2164 c_unparser::c_declare_static(exp_type ty, const string &name)
2165 {
2166 o->newline() << "static " << c_typename (ty) << " " << c_varname (name) << ";";
2167 }
2168
2169
2170 void
2171 c_unparser::c_strcpy (const string& lvalue, const string& rvalue)
2172 {
2173 o->newline() << "strlcpy ("
2174 << lvalue << ", "
2175 << rvalue << ", MAXSTRINGLEN);";
2176 }
2177
2178
2179 void
2180 c_unparser::c_strcpy (const string& lvalue, expression* rvalue)
2181 {
2182 o->newline() << "strlcpy (" << lvalue << ", ";
2183 rvalue->visit (this);
2184 o->line() << ", MAXSTRINGLEN);";
2185 }
2186
2187
2188 void
2189 c_unparser::c_strcat (const string& lvalue, const string& rvalue)
2190 {
2191 o->newline() << "strlcat ("
2192 << lvalue << ", "
2193 << rvalue << ", MAXSTRINGLEN);";
2194 }
2195
2196
2197 void
2198 c_unparser::c_strcat (const string& lvalue, expression* rvalue)
2199 {
2200 o->newline() << "strlcat (" << lvalue << ", ";
2201 rvalue->visit (this);
2202 o->line() << ", MAXSTRINGLEN);";
2203 }
2204
2205
2206 bool
2207 c_unparser::is_local(vardecl const *r, token const *tok)
2208 {
2209 if (current_probe)
2210 {
2211 for (unsigned i=0; i<current_probe->locals.size(); i++)
2212 {
2213 if (current_probe->locals[i] == r)
2214 return true;
2215 }
2216 }
2217 else if (current_function)
2218 {
2219 for (unsigned i=0; i<current_function->locals.size(); i++)
2220 {
2221 if (current_function->locals[i] == r)
2222 return true;
2223 }
2224
2225 for (unsigned i=0; i<current_function->formal_args.size(); i++)
2226 {
2227 if (current_function->formal_args[i] == r)
2228 return true;
2229 }
2230 }
2231
2232 for (unsigned i=0; i<session->globals.size(); i++)
2233 {
2234 if (session->globals[i] == r)
2235 return false;
2236 }
2237
2238 if (tok)
2239 throw semantic_error ("unresolved symbol", tok);
2240 else
2241 throw semantic_error ("unresolved symbol: " + r->name);
2242 }
2243
2244
2245 tmpvar
2246 c_unparser::gensym(exp_type ty)
2247 {
2248 return tmpvar (ty, tmpvar_counter);
2249 }
2250
2251 aggvar
2252 c_unparser::gensym_aggregate()
2253 {
2254 return aggvar (tmpvar_counter);
2255 }
2256
2257
2258 var
2259 c_unparser::getvar(vardecl *v, token const *tok)
2260 {
2261 bool loc = is_local (v, tok);
2262 if (loc)
2263 return var (loc, v->type, v->name);
2264 else
2265 {
2266 statistic_decl sd;
2267 std::map<std::string, statistic_decl>::const_iterator i;
2268 i = session->stat_decls.find(v->name);
2269 if (i != session->stat_decls.end())
2270 sd = i->second;
2271 return var (loc, v->type, sd, v->name);
2272 }
2273 }
2274
2275
2276 mapvar
2277 c_unparser::getmap(vardecl *v, token const *tok)
2278 {
2279 if (v->arity < 1)
2280 throw semantic_error("attempt to use scalar where map expected", tok);
2281 statistic_decl sd;
2282 std::map<std::string, statistic_decl>::const_iterator i;
2283 i = session->stat_decls.find(v->name);
2284 if (i != session->stat_decls.end())
2285 sd = i->second;
2286 return mapvar (is_local (v, tok), v->type, sd,
2287 v->name, v->index_types, v->maxsize);
2288 }
2289
2290
2291 itervar
2292 c_unparser::getiter(symbol *s)
2293 {
2294 return itervar (s, tmpvar_counter);
2295 }
2296
2297
2298 // Queue up some actions to remove from actionremaining. Set update=true at
2299 // the end of basic blocks to actually update actionremaining and check it
2300 // against MAXACTION.
2301 void
2302 c_unparser::record_actions (unsigned actions, bool update)
2303 {
2304 action_counter += actions;
2305
2306 // Update if needed, or after queueing up a few actions, in case of very
2307 // large code sequences.
2308 if ((update && action_counter > 0) || action_counter >= 10/*<-arbitrary*/)
2309 {
2310 o->newline() << "c->actionremaining -= " << action_counter << ";";
2311 o->newline() << "if (unlikely (c->actionremaining <= 0)) {";
2312 o->newline(1) << "c->last_error = \"MAXACTION exceeded\";";
2313 o->newline() << "goto out;";
2314 o->newline(-1) << "}";
2315 action_counter = 0;
2316 }
2317 }
2318
2319
2320 void
2321 c_unparser::visit_block (block *s)
2322 {
2323 o->newline() << "{";
2324 o->indent (1);
2325
2326 for (unsigned i=0; i<s->statements.size(); i++)
2327 {
2328 try
2329 {
2330 s->statements[i]->visit (this);
2331 o->newline();
2332 }
2333 catch (const semantic_error& e)
2334 {
2335 session->print_error (e);
2336 }
2337 }
2338 o->newline(-1) << "}";
2339 }
2340
2341
2342 void
2343 c_unparser::visit_embeddedcode (embeddedcode *s)
2344 {
2345 o->newline() << "{";
2346 o->newline(1) << s->code;
2347 o->newline(-1) << "}";
2348 }
2349
2350
2351 void
2352 c_unparser::visit_null_statement (null_statement *)
2353 {
2354 o->newline() << "/* null */;";
2355 }
2356
2357
2358 void
2359 c_unparser::visit_expr_statement (expr_statement *s)
2360 {
2361 o->newline() << "(void) ";
2362 s->value->visit (this);
2363 o->line() << ";";
2364 record_actions(1);
2365 }
2366
2367
2368 void
2369 c_unparser::visit_if_statement (if_statement *s)
2370 {
2371 record_actions(1, true);
2372 o->newline() << "if (";
2373 o->indent (1);
2374 s->condition->visit (this);
2375 o->indent (-1);
2376 o->line() << ") {";
2377 o->indent (1);
2378 s->thenblock->visit (this);
2379 record_actions(0, true);
2380 o->newline(-1) << "}";
2381 if (s->elseblock)
2382 {
2383 o->newline() << "else {";
2384 o->indent (1);
2385 s->elseblock->visit (this);
2386 record_actions(0, true);
2387 o->newline(-1) << "}";
2388 }
2389 }
2390
2391
2392 void
2393 c_tmpcounter::visit_block (block *s)
2394 {
2395 // Key insight: individual statements of a block can reuse
2396 // temporary variable slots, since temporaries don't survive
2397 // statement boundaries. So we use gcc's anonymous union/struct
2398 // facility to explicitly overlay the temporaries.
2399 parent->o->newline() << "union {";
2400 parent->o->indent(1);
2401 for (unsigned i=0; i<s->statements.size(); i++)
2402 {
2403 // To avoid lots of empty structs inside the union, remember
2404 // where we are now. Then, output the struct start and remember
2405 // that positon. If when we get done with the statement we
2406 // haven't moved, then we don't really need the struct. To get
2407 // rid of the struct start we output, we'll seek back to where
2408 // we were before we output the struct.
2409 std::ostream::pos_type before_struct_pos = parent->o->tellp();
2410 parent->o->newline() << "struct {";
2411 parent->o->indent(1);
2412 std::ostream::pos_type after_struct_pos = parent->o->tellp();
2413 s->statements[i]->visit (this);
2414 parent->o->indent(-1);
2415 if (after_struct_pos == parent->o->tellp())
2416 parent->o->seekp(before_struct_pos);
2417 else
2418 parent->o->newline() << "};";
2419 }
2420 parent->o->newline(-1) << "};";
2421 }
2422
2423 void
2424 c_tmpcounter::visit_for_loop (for_loop *s)
2425 {
2426 if (s->init) s->init->visit (this);
2427 s->cond->visit (this);
2428 s->block->visit (this);
2429 if (s->incr) s->incr->visit (this);
2430 }
2431
2432
2433 void
2434 c_unparser::visit_for_loop (for_loop *s)
2435 {
2436 string ctr = stringify (label_counter++);
2437 string toplabel = "top_" + ctr;
2438 string contlabel = "continue_" + ctr;
2439 string breaklabel = "break_" + ctr;
2440
2441 // initialization
2442 if (s->init) s->init->visit (this);
2443 record_actions(1, true);
2444
2445 // condition
2446 o->newline(-1) << toplabel << ":";
2447
2448 // Emit an explicit action here to cover the act of iteration.
2449 // Equivalently, it can stand for the evaluation of the condition
2450 // expression.
2451 o->indent(1);
2452 record_actions(1);
2453
2454 o->newline() << "if (! (";
2455 if (s->cond->type != pe_long)
2456 throw semantic_error ("expected numeric type", s->cond->tok);
2457 s->cond->visit (this);
2458 o->line() << ")) goto " << breaklabel << ";";
2459
2460 // body
2461 loop_break_labels.push_back (breaklabel);
2462 loop_continue_labels.push_back (contlabel);
2463 s->block->visit (this);
2464 record_actions(0, true);
2465 loop_break_labels.pop_back ();
2466 loop_continue_labels.pop_back ();
2467
2468 // iteration
2469 o->newline(-1) << contlabel << ":";
2470 o->indent(1);
2471 if (s->incr) s->incr->visit (this);
2472 o->newline() << "goto " << toplabel << ";";
2473
2474 // exit
2475 o->newline(-1) << breaklabel << ":";
2476 o->newline(1) << "; /* dummy statement */";
2477 }
2478
2479
2480 struct arrayindex_downcaster
2481 : public traversing_visitor
2482 {
2483 arrayindex *& arr;
2484
2485 arrayindex_downcaster (arrayindex *& arr)
2486 : arr(arr)
2487 {}
2488
2489 void visit_arrayindex (arrayindex* e)
2490 {
2491 arr = e;
2492 }
2493 };
2494
2495
2496 static bool
2497 expression_is_arrayindex (expression *e,
2498 arrayindex *& hist)
2499 {
2500 arrayindex *h = NULL;
2501 arrayindex_downcaster d(h);
2502 e->visit (&d);
2503 if (static_cast<void*>(h) == static_cast<void*>(e))
2504 {
2505 hist = h;
2506 return true;
2507 }
2508 return false;
2509 }
2510
2511
2512 void
2513 c_tmpcounter::visit_foreach_loop (foreach_loop *s)
2514 {
2515 symbol *array;
2516 hist_op *hist;
2517 classify_indexable (s->base, array, hist);
2518
2519 if (array)
2520 {
2521 itervar iv = parent->getiter (array);
2522 parent->o->newline() << iv.declare();
2523 }
2524 else
2525 {
2526 // See commentary in c_tmpcounter::visit_arrayindex for
2527 // discussion of tmpvars required to look into @hist_op(...)
2528 // expressions.
2529
2530 // First make sure we have exactly one pe_long variable to use as
2531 // our bucket index.
2532
2533 if (s->indexes.size() != 1 || s->indexes[0]->referent->type != pe_long)
2534 throw semantic_error("Invalid indexing of histogram", s->tok);
2535
2536 // Then declare what we need to form the aggregate we're
2537 // iterating over, and all the tmpvars needed by our call to
2538 // load_aggregate().
2539
2540 aggvar agg = parent->gensym_aggregate ();
2541 agg.declare(*(this->parent));
2542
2543 symbol *sym = get_symbol_within_expression (hist->stat);
2544 var v = parent->getvar(sym->referent, sym->tok);
2545 if (sym->referent->arity != 0)
2546 {
2547 arrayindex *arr = NULL;
2548 if (!expression_is_arrayindex (hist->stat, arr))
2549 throw semantic_error("expected arrayindex expression in iterated hist_op", s->tok);
2550
2551 for (unsigned i=0; i<sym->referent->index_types.size(); i++)
2552 {
2553 tmpvar ix = parent->gensym (sym->referent->index_types[i]);
2554 ix.declare (*parent);
2555 arr->indexes[i]->visit(this);
2556 }
2557 }
2558 }
2559
2560 // Create a temporary for the loop limit counter and the limit
2561 // expression result.
2562 if (s->limit)
2563 {
2564 tmpvar res_limit = parent->gensym (pe_long);
2565 res_limit.declare(*parent);
2566
2567 s->limit->visit (this);
2568
2569 tmpvar limitv = parent->gensym (pe_long);
2570 limitv.declare(*parent);
2571 }
2572
2573 s->block->visit (this);
2574 }
2575
2576 void
2577 c_unparser::visit_foreach_loop (foreach_loop *s)
2578 {
2579 symbol *array;
2580 hist_op *hist;
2581 classify_indexable (s->base, array, hist);
2582
2583 if (array)
2584 {
2585 mapvar mv = getmap (array->referent, s->tok);
2586 itervar iv = getiter (array);
2587 vector<var> keys;
2588
2589 string ctr = stringify (label_counter++);
2590 string toplabel = "top_" + ctr;
2591 string contlabel = "continue_" + ctr;
2592 string breaklabel = "break_" + ctr;
2593
2594 // NB: structure parallels for_loop
2595
2596 // initialization
2597
2598 tmpvar *res_limit = NULL;
2599 if (s->limit)
2600 {
2601 // Evaluate the limit expression once.
2602 res_limit = new tmpvar(gensym(pe_long));
2603 c_assign (res_limit->value(), s->limit, "foreach limit");
2604 }
2605
2606 // aggregate array if required
2607 if (mv.is_parallel())
2608 {
2609 o->newline() << "if (unlikely(NULL == " << mv.calculate_aggregate() << ")) {";
2610 o->newline(1) << "c->last_error = \"aggregation overflow in " << mv << "\";";
2611 o->newline() << "goto out;";
2612 o->newline(-1) << "}";
2613
2614 // sort array if desired
2615 if (s->sort_direction)
2616 {
2617 int sort_column;
2618
2619 // If the user wanted us to sort by value, we'll sort by
2620 // @count instead for aggregates. '-5' tells the
2621 // runtime to sort by count.
2622 if (s->sort_column == 0)
2623 sort_column = -5;
2624 else
2625 sort_column = s->sort_column;
2626
2627 o->newline() << "else"; // only sort if aggregation was ok
2628 if (s->limit)
2629 {
2630 o->newline(1) << "_stp_map_sortn ("
2631 << mv.fetch_existing_aggregate() << ", "
2632 << *res_limit << ", " << sort_column << ", "
2633 << - s->sort_direction << ");";
2634 }
2635 else
2636 {
2637 o->newline(1) << "_stp_map_sort ("
2638 << mv.fetch_existing_aggregate() << ", "
2639 << sort_column << ", "
2640 << - s->sort_direction << ");";
2641 }
2642 o->indent(-1);
2643 }
2644 }
2645 else
2646 {
2647 // sort array if desired
2648 if (s->sort_direction)
2649 {
2650 if (s->limit)
2651 {
2652 o->newline() << "_stp_map_sortn (" << mv.value() << ", "
2653 << *res_limit << ", " << s->sort_column << ", "
2654 << - s->sort_direction << ");";
2655 }
2656 else
2657 {
2658 o->newline() << "_stp_map_sort (" << mv.value() << ", "
2659 << s->sort_column << ", "
2660 << - s->sort_direction << ");";
2661 }
2662 }
2663 }
2664
2665 // NB: sort direction sense is opposite in runtime, thus the negation
2666
2667 if (mv.is_parallel())
2668 aggregations_active.insert(mv.value());
2669 o->newline() << iv << " = " << iv.start (mv) << ";";
2670
2671 tmpvar *limitv = NULL;
2672 if (s->limit)
2673 {
2674 // Create the loop limit variable here and initialize it.
2675 limitv = new tmpvar(gensym (pe_long));
2676 o->newline() << *limitv << " = 0LL;";
2677 }
2678
2679 record_actions(1, true);
2680
2681 // condition
2682 o->newline(-1) << toplabel << ":";
2683
2684 // Emit an explicit action here to cover the act of iteration.
2685 // Equivalently, it can stand for the evaluation of the
2686 // condition expression.
2687 o->indent(1);
2688 record_actions(1);
2689
2690 o->newline() << "if (! (" << iv << ")) goto " << breaklabel << ";";
2691
2692 // body
2693 loop_break_labels.push_back (breaklabel);
2694 loop_continue_labels.push_back (contlabel);
2695 o->newline() << "{";
2696 o->indent (1);
2697
2698 if (s->limit)
2699 {
2700 // If we've been through LIMIT loop iterations, quit.
2701 o->newline() << "if (" << *limitv << "++ >= " << *res_limit
2702 << ") goto " << breaklabel << ";";
2703
2704 // We're done with limitv and res_limit.
2705 delete limitv;
2706 delete res_limit;
2707 }
2708
2709 for (unsigned i = 0; i < s->indexes.size(); ++i)
2710 {
2711 // copy the iter values into the specified locals
2712 var v = getvar (s->indexes[i]->referent);
2713 c_assign (v, iv.get_key (v.type(), i), s->tok);
2714 }
2715 s->block->visit (this);
2716 record_actions(0, true);
2717 o->newline(-1) << "}";
2718 loop_break_labels.pop_back ();
2719 loop_continue_labels.pop_back ();
2720
2721 // iteration
2722 o->newline(-1) << contlabel << ":";
2723 o->newline(1) << iv << " = " << iv.next (mv) << ";";
2724 o->newline() << "goto " << toplabel << ";";
2725
2726 // exit
2727 o->newline(-1) << breaklabel << ":";
2728 o->newline(1) << "; /* dummy statement */";
2729
2730 if (mv.is_parallel())
2731 aggregations_active.erase(mv.value());
2732 }
2733 else
2734 {
2735 // Iterating over buckets in a histogram.
2736 assert(s->indexes.size() == 1);
2737 assert(s->indexes[0]->referent->type == pe_long);
2738 var bucketvar = getvar (s->indexes[0]->referent);
2739
2740 aggvar agg = gensym_aggregate ();
2741 load_aggregate(hist->stat, agg);
2742
2743 symbol *sym = get_symbol_within_expression (hist->stat);
2744 var v = getvar(sym->referent, sym->tok);
2745 v.assert_hist_compatible(*hist);
2746
2747 tmpvar *res_limit = NULL;
2748 tmpvar *limitv = NULL;
2749 if (s->limit)
2750 {
2751 // Evaluate the limit expression once.
2752 res_limit = new tmpvar(gensym(pe_long));
2753 c_assign (res_limit->value(), s->limit, "foreach limit");
2754
2755 // Create the loop limit variable here and initialize it.
2756 limitv = new tmpvar(gensym (pe_long));
2757 o->newline() << *limitv << " = 0LL;";
2758 }
2759
2760 // XXX: break / continue don't work here yet
2761 record_actions(1, true);
2762 o->newline() << "for (" << bucketvar << " = 0; "
2763 << bucketvar << " < " << v.buckets() << "; "
2764 << bucketvar << "++) { ";
2765 o->newline(1);
2766
2767 if (s->limit)
2768 {
2769 // If we've been through LIMIT loop iterations, quit.
2770 o->newline() << "if (" << *limitv << "++ >= " << *res_limit
2771 << ") break;";
2772
2773 // We're done with limitv and res_limit.
2774 delete limitv;
2775 delete res_limit;
2776 }
2777
2778 s->block->visit (this);
2779 record_actions(1, true);
2780 o->newline(-1) << "}";
2781 }
2782 }
2783
2784
2785 void
2786 c_unparser::visit_return_statement (return_statement* s)
2787 {
2788 if (current_function == 0)
2789 throw semantic_error ("cannot 'return' from probe", s->tok);
2790
2791 if (s->value->type != current_function->type)
2792 throw semantic_error ("return type mismatch", current_function->tok,
2793 "vs", s->tok);
2794
2795 c_assign ("l->__retvalue", s->value, "return value");
2796 record_actions(1, true);
2797 o->newline() << "goto out;";
2798 }
2799
2800
2801 void
2802 c_unparser::visit_next_statement (next_statement* s)
2803 {
2804 if (current_probe == 0)
2805 throw semantic_error ("cannot 'next' from function", s->tok);
2806
2807 record_actions(1, true);
2808 o->newline() << "goto out;";
2809 }
2810
2811
2812 struct delete_statement_operand_tmp_visitor:
2813 public traversing_visitor
2814 {
2815 c_tmpcounter *parent;
2816 delete_statement_operand_tmp_visitor (c_tmpcounter *p):
2817 parent (p)
2818 {}
2819 //void visit_symbol (symbol* e);
2820 void visit_arrayindex (arrayindex* e);
2821 };
2822
2823
2824 struct delete_statement_operand_visitor:
2825 public throwing_visitor
2826 {
2827 c_unparser *parent;
2828 delete_statement_operand_visitor (c_unparser *p):
2829 throwing_visitor ("invalid operand of delete expression"),
2830 parent (p)
2831 {}
2832 void visit_symbol (symbol* e);
2833 void visit_arrayindex (arrayindex* e);
2834 };
2835
2836 void
2837 delete_statement_operand_visitor::visit_symbol (symbol* e)
2838 {
2839 assert (e->referent != 0);
2840 if (e->referent->arity > 0)
2841 {
2842 mapvar mvar = parent->getmap(e->referent, e->tok);
2843 /* NB: Memory deallocation/allocation operations
2844 are not generally safe.
2845 parent->o->newline() << mvar.fini ();
2846 parent->o->newline() << mvar.init ();
2847 */
2848 if (mvar.is_parallel())
2849 parent->o->newline() << "_stp_pmap_clear (" << mvar.value() << ");";
2850 else
2851 parent->o->newline() << "_stp_map_clear (" << mvar.value() << ");";
2852 }
2853 else
2854 {
2855 var v = parent->getvar(e->referent, e->tok);
2856 switch (e->type)
2857 {
2858 case pe_stats:
2859 parent->o->newline() << "_stp_stat_clear (" << v.value() << ");";
2860 break;
2861 case pe_long:
2862 parent->o->newline() << v.value() << " = 0;";
2863 break;
2864 case pe_string:
2865 parent->o->newline() << v.value() << "[0] = '\\0';";
2866 break;
2867 case pe_unknown:
2868 default:
2869 throw semantic_error("Cannot delete unknown expression type", e->tok);
2870 }
2871 }
2872 }
2873
2874 void
2875 delete_statement_operand_tmp_visitor::visit_arrayindex (arrayindex* e)
2876 {
2877 symbol *array;
2878 hist_op *hist;
2879 classify_indexable (e->base, array, hist);
2880
2881 if (array)
2882 {
2883 assert (array->referent != 0);
2884 vardecl* r = array->referent;
2885
2886 // One temporary per index dimension.
2887 for (unsigned i=0; i<r->index_types.size(); i++)
2888 {
2889 tmpvar ix = parent->parent->gensym (r->index_types[i]);
2890 ix.declare (*(parent->parent));
2891 e->indexes[i]->visit(parent);
2892 }
2893 }
2894 else
2895 {
2896 throw semantic_error("cannot delete histogram bucket entries\n", e->tok);
2897 }
2898 }
2899
2900 void
2901 delete_statement_operand_visitor::visit_arrayindex (arrayindex* e)
2902 {
2903 symbol *array;
2904 hist_op *hist;
2905 classify_indexable (e->base, array, hist);
2906
2907 if (array)
2908 {
2909 vector<tmpvar> idx;
2910 parent->load_map_indices (e, idx);
2911
2912 {
2913 mapvar mvar = parent->getmap (array->referent, e->tok);
2914 parent->o->newline() << mvar.del (idx) << ";";
2915 }
2916 }
2917 else
2918 {
2919 throw semantic_error("cannot delete histogram bucket entries\n", e->tok);
2920 }
2921 }
2922
2923
2924 void
2925 c_tmpcounter::visit_delete_statement (delete_statement* s)
2926 {
2927 delete_statement_operand_tmp_visitor dv (this);
2928 s->value->visit (&dv);
2929 }
2930
2931
2932 void
2933 c_unparser::visit_delete_statement (delete_statement* s)
2934 {
2935 delete_statement_operand_visitor dv (this);
2936 s->value->visit (&dv);
2937 record_actions(1);
2938 }
2939
2940
2941 void
2942 c_unparser::visit_break_statement (break_statement* s)
2943 {
2944 if (loop_break_labels.size() == 0)
2945 throw semantic_error ("cannot 'break' outside loop", s->tok);
2946
2947 record_actions(1, true);
2948 string label = loop_break_labels[loop_break_labels.size()-1];
2949 o->newline() << "goto " << label << ";";
2950 }
2951
2952
2953 void
2954 c_unparser::visit_continue_statement (continue_statement* s)
2955 {
2956 if (loop_continue_labels.size() == 0)
2957 throw semantic_error ("cannot 'continue' outside loop", s->tok);
2958
2959 record_actions(1, true);
2960 string label = loop_continue_labels[loop_continue_labels.size()-1];
2961 o->newline() << "goto " << label << ";";
2962 }
2963
2964
2965
2966 void
2967 c_unparser::visit_literal_string (literal_string* e)
2968 {
2969 const string& v = e->value;
2970 o->line() << '"';
2971 for (unsigned i=0; i<v.size(); i++)
2972 // NB: The backslash character is specifically passed through as is.
2973 // This is because our parser treats "\" as an ordinary character, not
2974 // an escape sequence, leaving it to the C compiler (and this function)
2975 // to treat it as such. If we were to escape it, there would be no way
2976 // of generating C-level escapes from script code.
2977 // See also print_format::components_to_string and lex_cast_qstring
2978 if (v[i] == '"') // or other escapeworthy characters?
2979 o->line() << '\\' << '"';
2980 else
2981 o->line() << v[i];
2982 o->line() << '"';
2983 }
2984
2985
2986 void
2987 c_unparser::visit_literal_number (literal_number* e)
2988 {
2989 // This looks ugly, but tries to be warning-free on 32- and 64-bit
2990 // hosts.
2991 // NB: this needs to be signed!
2992 if (e->value == -9223372036854775807LL-1) // PR 5023
2993 o->line() << "((int64_t)" << (unsigned long long) e->value << "ULL)";
2994 else
2995 o->line() << "((int64_t)" << e->value << "LL)";
2996 }
2997
2998
2999 void
3000 c_tmpcounter::visit_binary_expression (binary_expression* e)
3001 {
3002 if (e->op == "/" || e->op == "%")
3003 {
3004 tmpvar left = parent->gensym (pe_long);
3005 tmpvar right = parent->gensym (pe_long);
3006 if (e->left->tok->type != tok_number)
3007 left.declare (*parent);
3008 if (e->right->tok->type != tok_number)
3009 right.declare (*parent);
3010 }
3011
3012 e->left->visit (this);
3013 e->right->visit (this);
3014 }
3015
3016
3017 void
3018 c_unparser::visit_binary_expression (binary_expression* e)
3019 {
3020 if (e->type != pe_long ||
3021 e->left->type != pe_long ||
3022 e->right->type != pe_long)
3023 throw semantic_error ("expected numeric types", e->tok);
3024
3025 if (e->op == "+" ||
3026 e->op == "-" ||
3027 e->op == "*" ||
3028 e->op == "&" ||
3029 e->op == "|" ||
3030 e->op == "^")
3031 {
3032 o->line() << "((";
3033 e->left->visit (this);
3034 o->line() << ") " << e->op << " (";
3035 e->right->visit (this);
3036 o->line() << "))";
3037 }
3038 else if (e->op == ">>" ||
3039 e->op == "<<")
3040 {
3041 o->line() << "((";
3042 e->left->visit (this);
3043 o->line() << ") " << e->op << "max(min(";
3044 e->right->visit (this);
3045 o->line() << ", (int64_t)64LL), (int64_t)0LL))"; // between 0 and 64
3046 }
3047 else if (e->op == "/" ||
3048 e->op == "%")
3049 {
3050 // % and / need a division-by-zero check; and thus two temporaries
3051 // for proper evaluation order
3052 tmpvar left = gensym (pe_long);
3053 tmpvar right = gensym (pe_long);
3054
3055 o->line() << "({";
3056 o->indent(1);
3057
3058 if (e->left->tok->type == tok_number)
3059 left.override(c_expression(e->left));
3060 else
3061 {
3062 o->newline() << left << " = ";
3063 e->left->visit (this);
3064 o->line() << ";";
3065 }
3066
3067 if (e->right->tok->type == tok_number)
3068 right.override(c_expression(e->right));
3069 else
3070 {
3071 o->newline() << right << " = ";
3072 e->right->visit (this);
3073 o->line() << ";";
3074 }
3075
3076 o->newline() << "if (unlikely(!" << right << ")) {";
3077 o->newline(1) << "c->last_error = \"division by 0\";";
3078 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3079 o->newline() << "goto out;";
3080 o->newline(-1) << "}";
3081 o->newline() << ((e->op == "/") ? "_stp_div64" : "_stp_mod64")
3082 << " (NULL, " << left << ", " << right << ");";
3083
3084 o->newline(-1) << "})";
3085 }
3086 else
3087 throw semantic_error ("operator not yet implemented", e->tok);
3088 }
3089
3090
3091 void
3092 c_unparser::visit_unary_expression (unary_expression* e)
3093 {
3094 if (e->type != pe_long ||
3095 e->operand->type != pe_long)
3096 throw semantic_error ("expected numeric types", e->tok);
3097
3098 if (e->op == "-")
3099 {
3100 // NB: Subtraction is special, since negative literals in the
3101 // script language show up as unary negations over positive
3102 // literals here. This makes it "exciting" for emitting pure
3103 // C since: - 0x8000_0000_0000_0000 ==> - (- 9223372036854775808)
3104 // This would constitute a signed overflow, which gcc warns on
3105 // unless -ftrapv/-J are in CFLAGS - which they're not.
3106
3107 o->line() << "(int64_t)(0 " << e->op << " (uint64_t)(";
3108 e->operand->visit (this);
3109 o->line() << "))";
3110 }
3111 else
3112 {
3113 o->line() << "(" << e->op << " (";
3114 e->operand->visit (this);
3115 o->line() << "))";
3116 }
3117 }
3118
3119 void
3120 c_unparser::visit_logical_or_expr (logical_or_expr* e)
3121 {
3122 if (e->type != pe_long ||
3123 e->left->type != pe_long ||
3124 e->right->type != pe_long)
3125 throw semantic_error ("expected numeric types", e->tok);
3126
3127 o->line() << "((";
3128 e->left->visit (this);
3129 o->line() << ") " << e->op << " (";
3130 e->right->visit (this);
3131 o->line() << "))";
3132 }
3133
3134
3135 void
3136 c_unparser::visit_logical_and_expr (logical_and_expr* e)
3137 {
3138 if (e->type != pe_long ||
3139 e->left->type != pe_long ||
3140 e->right->type != pe_long)
3141 throw semantic_error ("expected numeric types", e->tok);
3142
3143 o->line() << "((";
3144 e->left->visit (this);
3145 o->line() << ") " << e->op << " (";
3146 e->right->visit (this);
3147 o->line() << "))";
3148 }
3149
3150
3151 void
3152 c_tmpcounter::visit_array_in (array_in* e)
3153 {
3154 symbol *array;
3155 hist_op *hist;
3156 classify_indexable (e->operand->base, array, hist);
3157
3158 if (array)
3159 {
3160 assert (array->referent != 0);
3161 vardecl* r = array->referent;
3162
3163 // One temporary per index dimension.
3164 for (unsigned i=0; i<r->index_types.size(); i++)
3165 {
3166 tmpvar ix = parent->gensym (r->index_types[i]);
3167 ix.declare (*parent);
3168 e->operand->indexes[i]->visit(this);
3169 }
3170
3171 // A boolean result.
3172 tmpvar res = parent->gensym (e->type);
3173 res.declare (*parent);
3174 }
3175 else
3176 {
3177 // By definition:
3178 //
3179 // 'foo in @hist_op(...)' is true iff
3180 // '@hist_op(...)[foo]' is nonzero
3181 //
3182 // so we just delegate to the latter call, since int64_t is also
3183 // our boolean type.
3184 e->operand->visit(this);
3185 }
3186 }
3187
3188
3189 void
3190 c_unparser::visit_array_in (array_in* e)
3191 {
3192 symbol *array;
3193 hist_op *hist;
3194 classify_indexable (e->operand->base, array, hist);
3195
3196 if (array)
3197 {
3198 stmt_expr block(*this);
3199
3200 vector<tmpvar> idx;
3201 load_map_indices (e->operand, idx);
3202 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3203
3204 tmpvar res = gensym (pe_long);
3205 mapvar mvar = getmap (array->referent, e->tok);
3206 c_assign (res, mvar.exists(idx), e->tok);
3207
3208 o->newline() << res << ";";
3209 }
3210 else
3211 {
3212 // By definition:
3213 //
3214 // 'foo in @hist_op(...)' is true iff
3215 // '@hist_op(...)[foo]' is nonzero
3216 //
3217 // so we just delegate to the latter call, since int64_t is also
3218 // our boolean type.
3219 e->operand->visit(this);
3220 }
3221 }
3222
3223
3224 void
3225 c_unparser::visit_comparison (comparison* e)
3226 {
3227 o->line() << "(";
3228
3229 if (e->left->type == pe_string)
3230 {
3231 if (e->right->type != pe_string)
3232 throw semantic_error ("expected string types", e->tok);
3233
3234 o->line() << "strncmp (";
3235 e->left->visit (this);
3236 o->line() << ", ";
3237 e->right->visit (this);
3238 o->line() << ", MAXSTRINGLEN";
3239 o->line() << ") " << e->op << " 0";
3240 }
3241 else if (e->left->type == pe_long)
3242 {
3243 if (e->right->type != pe_long)
3244 throw semantic_error ("expected numeric types", e->tok);
3245
3246 o->line() << "((";
3247 e->left->visit (this);
3248 o->line() << ") " << e->op << " (";
3249 e->right->visit (this);
3250 o->line() << "))";
3251 }
3252 else
3253 throw semantic_error ("unexpected type", e->left->tok);
3254
3255 o->line() << ")";
3256 }
3257
3258
3259 void
3260 c_tmpcounter::visit_concatenation (concatenation* e)
3261 {
3262 tmpvar t = parent->gensym (e->type);
3263 t.declare (*parent);
3264 e->left->visit (this);
3265 e->right->visit (this);
3266 }
3267
3268
3269 void
3270 c_unparser::visit_concatenation (concatenation* e)
3271 {
3272 if (e->op != ".")
3273 throw semantic_error ("unexpected concatenation operator", e->tok);
3274
3275 if (e->type != pe_string ||
3276 e->left->type != pe_string ||
3277 e->right->type != pe_string)
3278 throw semantic_error ("expected string types", e->tok);
3279
3280 tmpvar t = gensym (e->type);
3281
3282 o->line() << "({ ";
3283 o->indent(1);
3284 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3285 c_assign (t.value(), e->left, "assignment");
3286 c_strcat (t.value(), e->right);
3287 o->newline() << t << ";";
3288 o->newline(-1) << "})";
3289 }
3290
3291
3292 void
3293 c_unparser::visit_ternary_expression (ternary_expression* e)
3294 {
3295 if (e->cond->type != pe_long)
3296 throw semantic_error ("expected numeric condition", e->cond->tok);
3297
3298 if (e->truevalue->type != e->falsevalue->type ||
3299 e->type != e->truevalue->type ||
3300 (e->truevalue->type != pe_long && e->truevalue->type != pe_string))
3301 throw semantic_error ("expected matching types", e->tok);
3302
3303 o->line() << "((";
3304 e->cond->visit (this);
3305 o->line() << ") ? (";
3306 e->truevalue->visit (this);
3307 o->line() << ") : (";
3308 e->falsevalue->visit (this);
3309 o->line() << "))";
3310 }
3311
3312
3313 void
3314 c_tmpcounter::visit_assignment (assignment *e)
3315 {
3316 c_tmpcounter_assignment tav (this, e->op, e->right);
3317 e->left->visit (& tav);
3318 }
3319
3320
3321 void
3322 c_unparser::visit_assignment (assignment* e)
3323 {
3324 if (e->op == "<<<")
3325 {
3326 if (e->type != pe_long)
3327 throw semantic_error ("non-number <<< expression", e->tok);
3328
3329 if (e->left->type != pe_stats)
3330 throw semantic_error ("non-stats left operand to <<< expression", e->left->tok);
3331
3332 if (e->right->type != pe_long)
3333 throw semantic_error ("non-number right operand to <<< expression", e->right->tok);
3334
3335 }
3336 else
3337 {
3338 if (e->type != e->left->type)
3339 throw semantic_error ("type mismatch", e->tok,
3340 "vs", e->left->tok);
3341 if (e->right->type != e->left->type)
3342 throw semantic_error ("type mismatch", e->right->tok,
3343 "vs", e->left->tok);
3344 }
3345
3346 c_unparser_assignment tav (this, e->op, e->right);
3347 e->left->visit (& tav);
3348 }
3349
3350
3351 void
3352 c_tmpcounter::visit_pre_crement (pre_crement* e)
3353 {
3354 c_tmpcounter_assignment tav (this, e->op, 0);
3355 e->operand->visit (& tav);
3356 }
3357
3358
3359 void
3360 c_unparser::visit_pre_crement (pre_crement* e)
3361 {
3362 if (e->type != pe_long ||
3363 e->type != e->operand->type)
3364 throw semantic_error ("expected numeric type", e->tok);
3365
3366 c_unparser_assignment tav (this, e->op, false);
3367 e->operand->visit (& tav);
3368 }
3369
3370
3371 void
3372 c_tmpcounter::visit_post_crement (post_crement* e)
3373 {
3374 c_tmpcounter_assignment tav (this, e->op, 0, true);
3375 e->operand->visit (& tav);
3376 }
3377
3378
3379 void
3380 c_unparser::visit_post_crement (post_crement* e)
3381 {
3382 if (e->type != pe_long ||
3383 e->type != e->operand->type)
3384 throw semantic_error ("expected numeric type", e->tok);
3385
3386 c_unparser_assignment tav (this, e->op, true);
3387 e->operand->visit (& tav);
3388 }
3389
3390
3391 void
3392 c_unparser::visit_symbol (symbol* e)
3393 {
3394 assert (e->referent != 0);
3395 vardecl* r = e->referent;
3396
3397 if (r->index_types.size() != 0)
3398 throw semantic_error ("invalid reference to array", e->tok);
3399
3400 var v = getvar(r, e->tok);
3401 o->line() << v;
3402 }
3403
3404
3405 void
3406 c_tmpcounter_assignment::prepare_rvalue (tmpvar & rval)
3407 {
3408 if (rvalue)
3409 {
3410 // literal number and strings don't need any temporaries declared
3411 if (rvalue->tok->type != tok_number && rvalue->tok->type != tok_string)
3412 rval.declare (*(parent->parent));
3413
3414 rvalue->visit (parent);
3415 }
3416 }
3417
3418 void
3419 c_tmpcounter_assignment::c_assignop(tmpvar & res)
3420 {
3421 if (res.type() == pe_string)
3422 {
3423 // string assignment doesn't need any temporaries declared
3424 }
3425 else if (op == "<<<")
3426 res.declare (*(parent->parent));
3427 else if (res.type() == pe_long)
3428 {
3429 // Only the 'post' operators ('x++') need a temporary declared.
3430 if (post)
3431 res.declare (*(parent->parent));
3432 }
3433 }
3434
3435 // Assignment expansion is tricky.
3436 //
3437 // Because assignments are nestable expressions, we have
3438 // to emit C constructs that are nestable expressions too.
3439 // We have to evaluate the given expressions the proper number of times,
3440 // including array indices.
3441 // We have to lock the lvalue (if global) against concurrent modification,
3442 // especially with modify-assignment operations (+=, ++).
3443 // We have to check the rvalue (for division-by-zero checks).
3444
3445 // In the normal "pre=false" case, for (A op B) emit:
3446 // ({ tmp = B; check(B); lock(A); res = A op tmp; A = res; unlock(A); res; })
3447 // In the "pre=true" case, emit instead:
3448 // ({ tmp = B; check(B); lock(A); res = A; A = res op tmp; unlock(A); res; })
3449 //
3450 // (op is the plain operator portion of a combined calculate/assignment:
3451 // "+" for "+=", and so on. It is in the "macop" variable below.)
3452 //
3453 // For array assignments, additional temporaries are used for each
3454 // index, which are expanded before the "tmp=B" expression, in order
3455 // to consistently order evaluation of lhs before rhs.
3456 //
3457
3458 void
3459 c_tmpcounter_assignment::visit_symbol (symbol *e)
3460 {
3461 exp_type ty = rvalue ? rvalue->type : e->type;
3462 tmpvar rval = parent->parent->gensym (ty);
3463 tmpvar res = parent->parent->gensym (ty);
3464
3465 prepare_rvalue(rval);
3466
3467 c_assignop (res);
3468 }
3469
3470
3471 void
3472 c_unparser_assignment::prepare_rvalue (string const & op,
3473 tmpvar & rval,
3474 token const * tok)
3475 {
3476 if (rvalue)
3477 {
3478 if (rvalue->tok->type == tok_number || rvalue->tok->type == tok_string)
3479 // Instead of assigning the numeric or string constant to a
3480 // temporary, then assigning the temporary to the final, let's
3481 // just override the temporary with the constant.
3482 rval.override(parent->c_expression(rvalue));
3483 else
3484 parent->c_assign (rval.value(), rvalue, "assignment");
3485 }
3486 else
3487 {
3488 if (op == "++" || op == "--")
3489 // Here is part of the conversion proccess of turning "x++" to
3490 // "x += 1".
3491 rval.override("1");
3492 else
3493 throw semantic_error ("need rvalue for assignment", tok);
3494 }
3495 }
3496
3497 void
3498 c_unparser_assignment::visit_symbol (symbol *e)
3499 {
3500 stmt_expr block(*parent);
3501
3502 assert (e->referent != 0);
3503 if (e->referent->index_types.size() != 0)
3504 throw semantic_error ("unexpected reference to array", e->tok);
3505
3506 // parent->o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3507 exp_type ty = rvalue ? rvalue->type : e->type;
3508 tmpvar rval = parent->gensym (ty);
3509 tmpvar res = parent->gensym (ty);
3510
3511 prepare_rvalue (op, rval, e->tok);
3512
3513 var lvar = parent->getvar (e->referent, e->tok);
3514 c_assignop (res, lvar, rval, e->tok);
3515
3516 parent->o->newline() << res << ";";
3517 }
3518
3519
3520 void
3521 c_unparser::visit_target_symbol (target_symbol* e)
3522 {
3523 if (!e->probe_context_var.empty())
3524 o->line() << "l->" << e->probe_context_var;
3525 else
3526 throw semantic_error("cannot translate general cast expression", e->tok);
3527 }
3528
3529
3530 void
3531 c_unparser::visit_cast_op (cast_op* e)
3532 {
3533 throw semantic_error("cannot translate general cast expression", e->tok);
3534 }
3535
3536
3537 void
3538 c_tmpcounter::load_map_indices(arrayindex *e)
3539 {
3540 symbol *array;
3541 hist_op *hist;
3542 classify_indexable (e->base, array, hist);
3543
3544 if (array)
3545 {
3546 assert (array->referent != 0);
3547 vardecl* r = array->referent;
3548
3549 // One temporary per index dimension, except in the case of
3550 // number or string constants.
3551 for (unsigned i=0; i<r->index_types.size(); i++)
3552 {
3553 tmpvar ix = parent->gensym (r->index_types[i]);
3554 if (e->indexes[i]->tok->type == tok_number
3555 || e->indexes[i]->tok->type == tok_string)
3556 {
3557 // Do nothing
3558 }
3559 else
3560 ix.declare (*parent);
3561 e->indexes[i]->visit(this);
3562 }
3563 }
3564 }
3565
3566
3567 void
3568 c_unparser::load_map_indices(arrayindex *e,
3569 vector<tmpvar> & idx)
3570 {
3571 symbol *array;
3572 hist_op *hist;
3573 classify_indexable (e->base, array, hist);
3574
3575 if (array)
3576 {
3577 idx.clear();
3578
3579 assert (array->referent != 0);
3580 vardecl* r = array->referent;
3581
3582 if (r->index_types.size() == 0 ||
3583 r->index_types.size() != e->indexes.size())
3584 throw semantic_error ("invalid array reference", e->tok);
3585
3586 for (unsigned i=0; i<r->index_types.size(); i++)
3587 {
3588 if (r->index_types[i] != e->indexes[i]->type)
3589 throw semantic_error ("array index type mismatch", e->indexes[i]->tok);
3590
3591 tmpvar ix = gensym (r->index_types[i]);
3592 if (e->indexes[i]->tok->type == tok_number
3593 || e->indexes[i]->tok->type == tok_string)
3594 // Instead of assigning the numeric or string constant to a
3595 // temporary, then using the temporary, let's just
3596 // override the temporary with the constant.
3597 ix.override(c_expression(e->indexes[i]));
3598 else
3599 {
3600 // o->newline() << "c->last_stmt = "
3601 // << lex_cast_qstring(*e->indexes[i]->tok) << ";";
3602 c_assign (ix.value(), e->indexes[i], "array index copy");
3603 }
3604 idx.push_back (ix);
3605 }
3606 }
3607 else
3608 {
3609 assert (e->indexes.size() == 1);
3610 assert (e->indexes[0]->type == pe_long);
3611 tmpvar ix = gensym (pe_long);
3612 // o->newline() << "c->last_stmt = "
3613 // << lex_cast_qstring(*e->indexes[0]->tok) << ";";
3614 c_assign (ix.value(), e->indexes[0], "array index copy");
3615 idx.push_back(ix);
3616 }
3617 }
3618
3619
3620 void
3621 c_unparser::load_aggregate (expression *e, aggvar & agg, bool pre_agg)
3622 {
3623 symbol *sym = get_symbol_within_expression (e);
3624
3625 if (sym->referent->type != pe_stats)
3626 throw semantic_error ("unexpected aggregate of non-statistic", sym->tok);
3627
3628 var v = getvar(sym->referent, e->tok);
3629
3630 if (sym->referent->arity == 0)
3631 {
3632 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*sym->tok) << ";";
3633 o->newline() << agg << " = _stp_stat_get (" << v << ", 0);";
3634 }
3635 else
3636 {
3637 arrayindex *arr = NULL;
3638 if (!expression_is_arrayindex (e, arr))
3639 throw semantic_error("unexpected aggregate of non-arrayindex", e->tok);
3640
3641 vector<tmpvar> idx;
3642 load_map_indices (arr, idx);
3643 mapvar mvar = getmap (sym->referent, sym->tok);
3644 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*sym->tok) << ";";
3645 o->newline() << agg << " = " << mvar.get(idx, pre_agg) << ";";
3646 }
3647 }
3648
3649
3650 string
3651 c_unparser::histogram_index_check(var & base, tmpvar & idx) const
3652 {
3653 return "((" + idx.value() + " >= 0)"
3654 + " && (" + idx.value() + " < " + base.buckets() + "))";
3655 }
3656
3657
3658 void
3659 c_tmpcounter::visit_arrayindex (arrayindex *e)
3660 {
3661 symbol *array;
3662 hist_op *hist;
3663 classify_indexable (e->base, array, hist);
3664
3665 if (array)
3666 {
3667 load_map_indices(e);
3668
3669 // The index-expression result.
3670 tmpvar res = parent->gensym (e->type);
3671 res.declare (*parent);
3672 }
3673 else
3674 {
3675
3676 assert(hist);
3677
3678 // Note: this is a slightly tricker-than-it-looks allocation of
3679 // temporaries. The reason is that we're in the branch handling
3680 // histogram-indexing, and the histogram might be build over an
3681 // indexable entity itself. For example if we have:
3682 //
3683 // global foo
3684 // ...
3685 // foo[getpid(), geteuid()] <<< 1
3686 // ...
3687 // print @log_hist(foo[pid, euid])[bucket]
3688 //
3689 // We are looking at the @log_hist(...)[bucket] expression, so
3690 // allocating one tmpvar for calculating bucket (the "index" of
3691 // this arrayindex expression), and one tmpvar for storing the
3692 // result in, just as normal.
3693 //
3694 // But we are *also* going to call load_aggregate on foo, which
3695 // will itself require tmpvars for each of its indices. Since
3696 // this is not handled by delving into the subexpression (it
3697 // would be if hist were first-class in the type system, but
3698 // it's not) we we allocate all the tmpvars used in such a
3699 // subexpression up here: first our own aggvar, then our index
3700 // (bucket) tmpvar, then all the index tmpvars of our
3701 // pe_stat-valued subexpression, then our result.
3702
3703
3704 // First all the stuff related to indexing into the histogram
3705
3706 if (e->indexes.size() != 1)
3707 throw semantic_error("Invalid indexing of histogram", e->tok);
3708 tmpvar ix = parent->gensym (pe_long);
3709 ix.declare (*parent);
3710 e->indexes[0]->visit(this);
3711 tmpvar res = parent->gensym (pe_long);
3712 res.declare (*parent);
3713
3714 // Then the aggregate, and all the tmpvars needed by our call to
3715 // load_aggregate().
3716
3717 aggvar agg = parent->gensym_aggregate ();
3718 agg.declare(*(this->parent));
3719
3720 symbol *sym = get_symbol_within_expression (hist->stat);
3721 var v = parent->getvar(sym->referent, sym->tok);
3722 if (sym->referent->arity != 0)
3723 {
3724 arrayindex *arr = NULL;
3725 if (!expression_is_arrayindex (hist->stat, arr))
3726 throw semantic_error("expected arrayindex expression in indexed hist_op", e->tok);
3727
3728 for (unsigned i=0; i<sym->referent->index_types.size(); i++)
3729 {
3730 tmpvar ix = parent->gensym (sym->referent->index_types[i]);
3731 ix.declare (*parent);
3732 arr->indexes[i]->visit(this);
3733 }
3734 }
3735 }
3736 }
3737
3738
3739 void
3740 c_unparser::visit_arrayindex (arrayindex* e)
3741 {
3742 symbol *array;
3743 hist_op *hist;
3744 classify_indexable (e->base, array, hist);
3745
3746 if (array)
3747 {
3748 // Visiting an statistic-valued array in a non-lvalue context is prohibited.
3749 if (array->referent->type == pe_stats)
3750 throw semantic_error ("statistic-valued array in rvalue context", e->tok);
3751
3752 stmt_expr block(*this);
3753
3754 // NB: Do not adjust the order of the next few lines; the tmpvar
3755 // allocation order must remain the same between
3756 // c_unparser::visit_arrayindex and c_tmpcounter::visit_arrayindex
3757
3758 vector<tmpvar> idx;
3759 load_map_indices (e, idx);
3760 tmpvar res = gensym (e->type);
3761
3762 mapvar mvar = getmap (array->referent, e->tok);
3763 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3764 c_assign (res, mvar.get(idx), e->tok);
3765
3766 o->newline() << res << ";";
3767 }
3768 else
3769 {
3770 // See commentary in c_tmpcounter::visit_arrayindex
3771
3772 assert(hist);
3773 stmt_expr block(*this);
3774
3775 // NB: Do not adjust the order of the next few lines; the tmpvar
3776 // allocation order must remain the same between
3777 // c_unparser::visit_arrayindex and c_tmpcounter::visit_arrayindex
3778
3779 vector<tmpvar> idx;
3780 load_map_indices (e, idx);
3781 tmpvar res = gensym (e->type);
3782
3783 aggvar agg = gensym_aggregate ();
3784
3785 // These should have faulted during elaboration if not true.
3786 assert(idx.size() == 1);
3787 assert(idx[0].type() == pe_long);
3788
3789 symbol *sym = get_symbol_within_expression (hist->stat);
3790
3791 var *v;
3792 if (sym->referent->arity < 1)
3793 v = new var(getvar(sym->referent, e->tok));
3794 else
3795 v = new mapvar(getmap(sym->referent, e->tok));
3796
3797 v->assert_hist_compatible(*hist);
3798
3799 if (aggregations_active.count(v->value()))
3800 load_aggregate(hist->stat, agg, true);
3801 else
3802 load_aggregate(hist->stat, agg, false);
3803
3804 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3805
3806 // PR 2142+2610: empty aggregates
3807 o->newline() << "if (unlikely (" << agg.value() << " == NULL)"
3808 << " || " << agg.value() << "->count == 0) {";
3809 o->newline(1) << "c->last_error = \"empty aggregate\";";
3810 o->newline() << "goto out;";
3811 o->newline(-1) << "} else {";
3812 o->newline(1) << "if (" << histogram_index_check(*v, idx[0]) << ")";
3813 o->newline(1) << res << " = " << agg << "->histogram[" << idx[0] << "];";
3814 o->newline(-1) << "else {";
3815 o->newline(1) << "c->last_error = \"histogram index out of range\";";
3816 o->newline() << "goto out;";
3817 o->newline(-1) << "}";
3818
3819 o->newline(-1) << "}";
3820 o->newline() << res << ";";
3821
3822 delete v;
3823 }
3824 }
3825
3826
3827 void
3828 c_tmpcounter_assignment::visit_arrayindex (arrayindex *e)
3829 {
3830 symbol *array;
3831 hist_op *hist;
3832 classify_indexable (e->base, array, hist);
3833
3834 if (array)
3835 {
3836 parent->load_map_indices(e);
3837
3838 // The expression rval, lval, and result.
3839 exp_type ty = rvalue ? rvalue->type : e->type;
3840 tmpvar rval = parent->parent->gensym (ty);
3841 tmpvar lval = parent->parent->gensym (ty);
3842 tmpvar res = parent->parent->gensym (ty);
3843
3844 prepare_rvalue(rval);
3845 lval.declare (*(parent->parent));
3846
3847 if (op == "<<<")
3848 res.declare (*(parent->parent));
3849 else
3850 c_assignop(res);
3851 }
3852 else
3853 {
3854 throw semantic_error("cannot assign to histogram buckets", e->tok);
3855 }
3856 }
3857
3858
3859 void
3860 c_unparser_assignment::visit_arrayindex (arrayindex *e)
3861 {
3862 symbol *array;
3863 hist_op *hist;
3864 classify_indexable (e->base, array, hist);
3865
3866 if (array)
3867 {
3868
3869 stmt_expr block(*parent);
3870
3871 translator_output *o = parent->o;
3872
3873 if (array->referent->index_types.size() == 0)
3874 throw semantic_error ("unexpected reference to scalar", e->tok);
3875
3876 // nb: Do not adjust the order of the next few lines; the tmpvar
3877 // allocation order must remain the same between
3878 // c_unparser_assignment::visit_arrayindex and
3879 // c_tmpcounter_assignment::visit_arrayindex
3880
3881 vector<tmpvar> idx;
3882 parent->load_map_indices (e, idx);
3883 exp_type ty = rvalue ? rvalue->type : e->type;
3884 tmpvar rvar = parent->gensym (ty);
3885 tmpvar lvar = parent->gensym (ty);
3886 tmpvar res = parent->gensym (ty);
3887
3888 // NB: because these expressions are nestable, emit this construct
3889 // thusly:
3890 // ({ tmp0=(idx0); ... tmpN=(idxN); rvar=(rhs); lvar; res;
3891 // lock (array);
3892 // lvar = get (array,idx0...N); // if necessary
3893 // assignop (res, lvar, rvar);
3894 // set (array, idx0...N, lvar);
3895 // unlock (array);
3896 // res; })
3897 //
3898 // we store all indices in temporary variables to avoid nasty
3899 // reentrancy issues that pop up with nested expressions:
3900 // e.g. ++a[a[c]=5] could deadlock
3901 //
3902 //
3903 // There is an exception to the above form: if we're doign a <<< assigment to
3904 // a statistic-valued map, there's a special form we follow:
3905 //
3906 // ({ tmp0=(idx0); ... tmpN=(idxN); rvar=(rhs);
3907 // *no need to* lock (array);
3908 // _stp_map_add_stat (array, idx0...N, rvar);
3909 // *no need to* unlock (array);
3910 // rvar; })
3911 //
3912 // To simplify variable-allocation rules, we assign rvar to lvar and
3913 // res in this block as well, even though they are technically
3914 // superfluous.
3915
3916 prepare_rvalue (op, rvar, e->tok);
3917
3918 if (op == "<<<")
3919 {
3920 assert (e->type == pe_stats);
3921 assert (rvalue->type == pe_long);
3922
3923 mapvar mvar = parent->getmap (array->referent, e->tok);
3924 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3925 o->newline() << mvar.add (idx, rvar) << ";";
3926 res = rvar;
3927 // no need for these dummy assignments
3928 // o->newline() << lvar << " = " << rvar << ";";
3929 // o->newline() << res << " = " << rvar << ";";
3930 }
3931 else
3932 {
3933 mapvar mvar = parent->getmap (array->referent, e->tok);
3934 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3935 if (op != "=") // don't bother fetch slot if we will just overwrite it
3936 parent->c_assign (lvar, mvar.get(idx), e->tok);
3937 c_assignop (res, lvar, rvar, e->tok);
3938 o->newline() << mvar.set (idx, lvar) << ";";
3939 }
3940
3941 o->newline() << res << ";";
3942 }
3943 else
3944 {
3945 throw semantic_error("cannot assign to histogram buckets", e->tok);
3946 }
3947 }
3948
3949
3950 void
3951 c_tmpcounter::visit_functioncall (functioncall *e)
3952 {
3953 assert (e->referent != 0);
3954 functiondecl* r = e->referent;
3955 // one temporary per argument, unless literal numbers or strings
3956 for (unsigned i=0; i<r->formal_args.size(); i++)
3957 {
3958 tmpvar t = parent->gensym (r->formal_args[i]->type);
3959 if (e->args[i]->tok->type != tok_number
3960 && e->args[i]->tok->type != tok_string)
3961 t.declare (*parent);
3962 e->args[i]->visit (this);
3963 }
3964 }
3965
3966
3967 void
3968 c_unparser::visit_functioncall (functioncall* e)
3969 {
3970 assert (e->referent != 0);
3971 functiondecl* r = e->referent;
3972
3973 if (r->formal_args.size() != e->args.size())
3974 throw semantic_error ("invalid length argument list", e->tok);
3975
3976 stmt_expr block(*this);
3977
3978 // NB: we store all actual arguments in temporary variables,
3979 // to avoid colliding sharing of context variables with
3980 // nested function calls: f(f(f(1)))
3981
3982 // compute actual arguments
3983 vector<tmpvar> tmp;
3984
3985 for (unsigned i=0; i<e->args.size(); i++)
3986 {
3987 tmpvar t = gensym(e->args[i]->type);
3988
3989 if (r->formal_args[i]->type != e->args[i]->type)
3990 throw semantic_error ("function argument type mismatch",
3991 e->args[i]->tok, "vs", r->formal_args[i]->tok);
3992
3993 if (e->args[i]->tok->type == tok_number
3994 || e->args[i]->tok->type == tok_string)
3995 t.override(c_expression(e->args[i]));
3996 else
3997 {
3998 // o->newline() << "c->last_stmt = "
3999 // << lex_cast_qstring(*e->args[i]->tok) << ";";
4000 c_assign (t.value(), e->args[i],
4001 "function actual argument evaluation");
4002 }
4003 tmp.push_back(t);
4004 }
4005
4006 // copy in actual arguments
4007 for (unsigned i=0; i<e->args.size(); i++)
4008 {
4009 if (r->formal_args[i]->type != e->args[i]->type)
4010 throw semantic_error ("function argument type mismatch",
4011 e->args[i]->tok, "vs", r->formal_args[i]->tok);
4012
4013 c_assign ("c->locals[c->nesting+1].function_" +
4014 c_varname (r->name) + "." +
4015 c_varname (r->formal_args[i]->name),
4016 tmp[i].value(),
4017 e->args[i]->type,
4018 "function actual argument copy",
4019 e->args[i]->tok);
4020 }
4021
4022 // call function
4023 o->newline() << "function_" << c_varname (r->name) << " (c);";
4024 o->newline() << "if (unlikely(c->last_error)) goto out;";
4025
4026 // return result from retvalue slot
4027 if (r->type == pe_unknown)
4028 // If we passed typechecking, then nothing will use this return value
4029 o->newline() << "(void) 0;";
4030 else
4031 o->newline() << "c->locals[c->nesting+1]"
4032 << ".function_" << c_varname (r->name)
4033 << ".__retvalue;";
4034 }
4035
4036 void
4037 c_tmpcounter::visit_print_format (print_format* e)
4038 {
4039 if (e->hist)
4040 {
4041 symbol *sym = get_symbol_within_expression (e->hist->stat);
4042 var v = parent->getvar(sym->referent, sym->tok);
4043 aggvar agg = parent->gensym_aggregate ();
4044
4045 agg.declare(*(this->parent));
4046
4047 if (sym->referent->arity != 0)
4048 {
4049 // One temporary per index dimension.
4050 for (unsigned i=0; i<sym->referent->index_types.size(); i++)
4051 {
4052 arrayindex *arr = NULL;
4053 if (!expression_is_arrayindex (e->hist->stat, arr))
4054 throw semantic_error("expected arrayindex expression in printed hist_op", e->tok);
4055
4056 tmpvar ix = parent->gensym (sym->referent->index_types[i]);
4057 ix.declare (*parent);
4058 arr->indexes[i]->visit(this);
4059 }
4060 }
4061 }
4062 else
4063 {
4064 // One temporary per argument
4065 for (unsigned i=0; i < e->args.size(); i++)
4066 {
4067 tmpvar t = parent->gensym (e->args[i]->type);
4068 if (e->args[i]->type == pe_unknown)
4069 {
4070 throw semantic_error("unknown type of arg to print operator",
4071 e->args[i]->tok);
4072 }
4073
4074 if (e->args[i]->tok->type != tok_number
4075 && e->args[i]->tok->type != tok_string)
4076 t.declare (*parent);
4077 e->args[i]->visit (this);
4078 }
4079
4080 // And the result
4081 exp_type ty = e->print_to_stream ? pe_long : pe_string;
4082 tmpvar res = parent->gensym (ty);
4083 if (ty == pe_string)
4084 res.declare (*parent);
4085 }
4086 }
4087
4088
4089 void
4090 c_unparser::visit_print_format (print_format* e)
4091 {
4092 // Print formats can contain a general argument list *or* a special
4093 // type of argument which gets its own processing: a single,
4094 // non-format-string'ed, histogram-type stat_op expression.
4095
4096 if (e->hist)
4097 {
4098 stmt_expr block(*this);
4099 symbol *sym = get_symbol_within_expression (e->hist->stat);
4100 aggvar agg = gensym_aggregate ();
4101
4102 var *v;
4103 if (sym->referent->arity < 1)
4104 v = new var(getvar(sym->referent, e->tok));
4105 else
4106 v = new mapvar(getmap(sym->referent, e->tok));
4107
4108 v->assert_hist_compatible(*e->hist);
4109
4110 {
4111 if (aggregations_active.count(v->value()))
4112 load_aggregate(e->hist->stat, agg, true);
4113 else
4114 load_aggregate(e->hist->stat, agg, false);
4115
4116 // PR 2142+2610: empty aggregates
4117 o->newline() << "if (unlikely (" << agg.value() << " == NULL)"
4118 << " || " << agg.value() << "->count == 0) {";
4119 o->newline(1) << "c->last_error = \"empty aggregate\";";
4120 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
4121 o->newline() << "goto out;";
4122 o->newline(-1) << "} else";
4123 o->newline(1) << "_stp_stat_print_histogram (" << v->hist() << ", " << agg.value() << ");";
4124 o->indent(-1);
4125 }
4126
4127 delete v;
4128 }
4129 else
4130 {
4131 stmt_expr block(*this);
4132
4133 // Compute actual arguments
4134 vector<tmpvar> tmp;
4135
4136 for (unsigned i=0; i<e->args.size(); i++)
4137 {
4138 tmpvar t = gensym(e->args[i]->type);
4139 tmp.push_back(t);
4140
4141 // o->newline() << "c->last_stmt = "
4142 // << lex_cast_qstring(*e->args[i]->tok) << ";";
4143
4144 // If we've got a numeric or string constant, instead of
4145 // assigning the numeric or string constant to a temporary,
4146 // then passing the temporary to _stp_printf/_stp_snprintf,
4147 // let's just override the temporary with the constant.
4148 if (e->args[i]->tok->type == tok_number
4149 || e->args[i]->tok->type == tok_string)
4150 tmp[i].override(c_expression(e->args[i]));
4151 else
4152 c_assign (t.value(), e->args[i],
4153 "print format actual argument evaluation");
4154 }
4155
4156 std::vector<print_format::format_component> components;
4157
4158 if (e->print_with_format)
4159 {
4160 components = e->components;
4161 }
4162 else
4163 {
4164 // Synthesize a print-format string if the user didn't
4165 // provide one; the synthetic string simply contains one
4166 // directive for each argument.
4167 for (unsigned i = 0; i < e->args.size(); ++i)
4168 {
4169 if (i > 0 && e->print_with_delim)
4170 components.push_back (e->delimiter);
4171 print_format::format_component curr;
4172 curr.clear();
4173 switch (e->args[i]->type)
4174 {
4175 case pe_unknown:
4176 throw semantic_error("cannot print unknown expression type", e->args[i]->tok);
4177 case pe_stats:
4178 throw semantic_error("cannot print a raw stats object", e->args[i]->tok);
4179 case pe_long:
4180 curr.type = print_format::conv_signed_decimal;
4181 break;
4182 case pe_string:
4183 curr.type = print_format::conv_string;
4184 break;
4185 }
4186 components.push_back (curr);
4187 }
4188
4189 if (e->print_with_newline)
4190 {
4191 print_format::format_component curr;
4192 curr.clear();
4193 curr.type = print_format::conv_literal;
4194 curr.literal_string = "\\n";
4195 components.push_back (curr);
4196 }
4197 }
4198
4199 // Allocate the result
4200 exp_type ty = e->print_to_stream ? pe_long : pe_string;
4201 tmpvar res = gensym (ty);
4202 int use_print = 0;
4203
4204 string format_string = print_format::components_to_string(components);
4205 if ((tmp.size() == 0 && format_string.find("%%") == std::string::npos)
4206 || (tmp.size() == 1 && format_string == "%s"))
4207 use_print = 1;
4208 else if (tmp.size() == 1
4209 && e->args[0]->tok->type == tok_string
4210 && format_string == "%s\\n")
4211 {
4212 use_print = 1;
4213 tmp[0].override(tmp[0].value() + "\"\\n\"");
4214 components[0].type = print_format::conv_literal;
4215 }
4216
4217 // Make the [s]printf call...
4218
4219 // Generate code to check that any pointer arguments are actually accessible. */
4220 int arg_ix = 0;
4221 for (unsigned i = 0; i < components.size(); ++i) {
4222 if (components[i].type == print_format::conv_literal)
4223 continue;
4224
4225 /* Take note of the width and precision arguments, if any. */
4226 int width_ix = -1, prec_ix= -1;
4227 if (components[i].widthtype == print_format::width_dynamic)
4228 width_ix = arg_ix++;
4229 if (components[i].prectype == print_format::prec_dynamic)
4230 prec_ix = arg_ix++;
4231
4232 /* Generate a noop call to deref_buffer for %m. */
4233 if (components[i].type == print_format::conv_memory
4234 || components[i].type == print_format::conv_memory_hex) {
4235 this->probe_or_function_needs_deref_fault_handler = true;
4236 o->newline() << "deref_buffer (0, " << tmp[arg_ix].value() << ", ";
4237 if (prec_ix == -1)
4238 if (width_ix != -1)
4239 prec_ix = width_ix;
4240 if (prec_ix != -1)
4241 o->line() << tmp[prec_ix].value();
4242 else
4243 o->line() << "1";
4244 o->line() << ");";
4245 }
4246
4247 ++arg_ix;
4248 }
4249
4250 if (e->print_to_stream)
4251 {
4252 if (e->print_char)
4253 {
4254 o->newline() << "_stp_print_char (";
4255 if (tmp.size())
4256 o->line() << tmp[0].value() << ");";
4257 else
4258 o->line() << '"' << format_string << "\");";
4259 return;
4260 }
4261 if (use_print)
4262 {
4263 o->newline() << "_stp_print (";
4264 if (tmp.size())
4265 o->line() << tmp[0].value() << ");";
4266 else
4267 o->line() << '"' << format_string << "\");";
4268 return;
4269 }
4270
4271 // We'll just hardcode the result of 0 instead of using the
4272 // temporary.
4273 res.override("((int64_t)0LL)");
4274 o->newline() << "_stp_printf (";
4275 }
4276 else
4277 o->newline() << "_stp_snprintf (" << res.value() << ", MAXSTRINGLEN, ";
4278
4279 o->line() << '"' << format_string << '"';
4280
4281 /* Generate the actual arguments. Make sure that they match the expected type of the
4282 format specifier. */
4283 arg_ix = 0;
4284 for (unsigned i = 0; i < components.size(); ++i) {
4285 if (components[i].type == print_format::conv_literal)
4286 continue;
4287
4288 /* Cast the width and precision arguments, if any, to 'int'. */
4289 if (components[i].widthtype == print_format::width_dynamic)
4290 o->line() << ", (int)" << tmp[arg_ix++].value();
4291 if (components[i].prectype == print_format::prec_dynamic)
4292 o->line() << ", (int)" << tmp[arg_ix++].value();
4293
4294 /* The type of the %m argument is 'char*'. */
4295 if (components[i].type == print_format::conv_memory
4296 || components[i].type == print_format::conv_memory_hex)
4297 o->line() << ", (char*)(uintptr_t)" << tmp[arg_ix++].value();
4298 /* The type of the %c argument is 'int'. */
4299 else if (components[i].type == print_format::conv_char)
4300 o->line() << ", (int)" << tmp[arg_ix++].value();
4301 else if (arg_ix < (int) tmp.size())
4302 o->line() << ", " << tmp[arg_ix++].value();
4303 }
4304
4305 o->line() << ");";
4306 o->newline() << res.value() << ";";
4307 }
4308 }
4309
4310
4311 void
4312 c_tmpcounter::visit_stat_op (stat_op* e)
4313 {
4314 symbol *sym = get_symbol_within_expression (e->stat);
4315 var v = parent->getvar(sym->referent, e->tok);
4316 aggvar agg = parent->gensym_aggregate ();
4317 tmpvar res = parent->gensym (pe_long);
4318
4319 agg.declare(*(this->parent));
4320 res.declare(*(this->parent));
4321
4322 if (sym->referent->arity != 0)
4323 {
4324 // One temporary per index dimension.
4325 for (unsigned i=0; i<sym->referent->index_types.size(); i++)
4326 {
4327 // Sorry about this, but with no dynamic_cast<> and no
4328 // constructor patterns, this is how things work.
4329 arrayindex *arr = NULL;
4330 if (!expression_is_arrayindex (e->stat, arr))
4331 throw semantic_error("expected arrayindex expression in stat_op of array", e->tok);
4332
4333 tmpvar ix = parent->gensym (sym->referent->index_types[i]);
4334 ix.declare (*parent);
4335 arr->indexes[i]->visit(this);
4336 }
4337 }
4338 }
4339
4340 void
4341 c_unparser::visit_stat_op (stat_op* e)
4342 {
4343 // Stat ops can be *applied* to two types of expression:
4344 //
4345 // 1. An arrayindex expression on a pe_stats-valued array.
4346 //
4347 // 2. A symbol of type pe_stats.
4348
4349 // FIXME: classify the expression the stat_op is being applied to,
4350 // call appropriate stp_get_stat() / stp_pmap_get_stat() helper,
4351 // then reach into resultant struct stat_data.
4352
4353 // FIXME: also note that summarizing anything is expensive, and we
4354 // really ought to pass a timeout handler into the summary routine,
4355 // check its response, possibly exit if it ran out of cycles.
4356
4357 {
4358 stmt_expr block(*this);
4359 symbol *sym = get_symbol_within_expression (e->stat);
4360 aggvar agg = gensym_aggregate ();
4361 tmpvar res = gensym (pe_long);
4362 var v = getvar(sym->referent, e->tok);
4363 {
4364 if (aggregations_active.count(v.value()))
4365 load_aggregate(e->stat, agg, true);
4366 else
4367 load_aggregate(e->stat, agg, false);
4368
4369 // PR 2142+2610: empty aggregates
4370 if (e->ctype == sc_count)
4371 {
4372 o->newline() << "if (unlikely (" << agg.value() << " == NULL))";
4373 o->indent(1);
4374 c_assign(res, "0", e->tok);
4375 o->indent(-1);
4376 }
4377 else
4378 {
4379 o->newline() << "if (unlikely (" << agg.value() << " == NULL)"
4380 << " || " << agg.value() << "->count == 0) {";
4381 o->newline(1) << "c->last_error = \"empty aggregate\";";
4382 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
4383 o->newline() << "goto out;";
4384 o->newline(-1) << "}";
4385 }
4386 o->newline() << "else";
4387 o->indent(1);
4388 switch (e->ctype)
4389 {
4390 case sc_average:
4391 c_assign(res, ("_stp_div64(NULL, " + agg.value() + "->sum, "
4392 + agg.value() + "->count)"),
4393 e->tok);
4394 break;
4395 case sc_count:
4396 c_assign(res, agg.value() + "->count", e->tok);
4397 break;
4398 case sc_sum:
4399 c_assign(res, agg.value() + "->sum", e->tok);
4400 break;
4401 case sc_min:
4402 c_assign(res, agg.value() + "->min", e->tok);
4403 break;
4404 case sc_max:
4405 c_assign(res, agg.value() + "->max", e->tok);
4406 break;
4407 }
4408 o->indent(-1);
4409 }
4410 o->newline() << res << ";";
4411 }
4412 }
4413
4414
4415 void
4416 c_unparser::visit_hist_op (hist_op*)
4417 {
4418 // Hist ops can only occur in a limited set of circumstances:
4419 //
4420 // 1. Inside an arrayindex expression, as the base referent. See
4421 // c_unparser::visit_arrayindex for handling of this case.
4422 //
4423 // 2. Inside a foreach statement, as the base referent. See
4424 // c_unparser::visit_foreach_loop for handling this case.
4425 //
4426 // 3. Inside a print_format expression, as the sole argument. See
4427 // c_unparser::visit_print_format for handling this case.
4428 //
4429 // Note that none of these cases involves the c_unparser ever
4430 // visiting this node. We should not get here.
4431
4432 assert(false);
4433 }
4434
4435
4436
4437 struct unwindsym_dump_context
4438 {
4439 systemtap_session& session;
4440 ostream& output;
4441 unsigned stp_module_index;
4442 set<string> undone_unwindsym_modules;
4443 };
4444
4445
4446 // Get the .debug_frame section for the given module.
4447 // l will be set to the length of the size of the unwind data if found.
4448 static void *get_unwind_data (Dwfl_Module *m, size_t *l)
4449 {
4450 Dwarf_Addr bias = 0;
4451 Dwarf *dw;
4452 GElf_Ehdr *ehdr, ehdr_mem;
4453 GElf_Shdr *shdr, shdr_mem;
4454 Elf_Scn *scn = NULL;
4455 Elf_Data *data = NULL;
4456
4457 dw = dwfl_module_getdwarf(m, &bias);
4458 if (dw != NULL)
4459 {
4460 Elf *elf = dwarf_getelf(dw);
4461 ehdr = gelf_getehdr(elf, &ehdr_mem);
4462 while ((scn = elf_nextscn(elf, scn)))
4463 {
4464 shdr = gelf_getshdr(scn, &shdr_mem);
4465 if (strcmp(elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name),
4466 ".debug_frame") == 0)
4467 {
4468 data = elf_rawdata(scn, NULL);
4469 break;
4470 }
4471 }
4472 }
4473
4474 if (data != NULL)
4475 {
4476 *l = data->d_size;
4477 return data->d_buf;
4478 }
4479
4480 return NULL;
4481 }
4482
4483 static int
4484 dump_unwindsyms (Dwfl_Module *m,
4485 void **userdata __attribute__ ((unused)),
4486 const char *name,
4487 Dwarf_Addr base,
4488 void *arg)
4489 {
4490 unwindsym_dump_context* c = (unwindsym_dump_context*) arg;
4491 assert (c);
4492 unsigned stpmod_idx = c->stp_module_index;
4493
4494 string modname = name;
4495
4496 if (pending_interrupts)
4497 return DWARF_CB_ABORT;
4498
4499 // skip modules/files we're not actually interested in
4500 if (c->session.unwindsym_modules.find(modname) == c->session.unwindsym_modules.end())
4501 return DWARF_CB_OK;
4502
4503 c->stp_module_index ++;
4504
4505 if (c->session.verbose > 1)
4506 clog << "dump_unwindsyms " << name
4507 << " index=" << stpmod_idx
4508 << " base=0x" << hex << base << dec << endl;
4509
4510 // We want to extract several bits of information:
4511 //
4512 // - parts of the program-header that map the file's physical offsets to the text section
4513 // - section table: just a list of section (relocation) base addresses
4514 // - symbol table of the text-like sections, with all addresses relativized to each base
4515 // - the contents of .debug_frame section, for unwinding purposes
4516 //
4517 // In the future, we'll also care about data symbols.
4518
4519 int syments = dwfl_module_getsymtab(m);
4520 dwfl_assert ("Getting symbol table for " + modname, syments >= 0);
4521
4522 //extract build-id from debuginfo file
4523 int build_id_len = 0;
4524 unsigned char *build_id_bits;
4525 GElf_Addr build_id_vaddr;
4526
4527 if ((build_id_len=dwfl_module_build_id(m,
4528 (const unsigned char **)&build_id_bits,
4529 &build_id_vaddr)) > 0)
4530 {
4531 // Enable workaround for elfutils dwfl bug.
4532 // see https://bugzilla.redhat.com/show_bug.cgi?id=465872
4533 // and http://sourceware.org/ml/systemtap/2008-q4/msg00579.html
4534 #ifdef _ELFUTILS_PREREQ
4535 #if _ELFUTILS_PREREQ(0,138)
4536 // Let's standardize to the buggy "end of build-id bits" behavior.
4537 build_id_vaddr += build_id_len;
4538 #endif
4539 #if !_ELFUTILS_PREREQ(0,141)
4540 #define NEED_ELFUTILS_BUILDID_WORKAROUND
4541 #endif
4542 #else
4543 #define NEED_ELFUTILS_BUILDID_WORKAROUND
4544 #endif
4545
4546 // And check for another workaround needed.
4547 // see https://bugzilla.redhat.com/show_bug.cgi?id=489439
4548 // and http://sourceware.org/ml/systemtap/2009-q1/msg00513.html
4549 #ifdef NEED_ELFUTILS_BUILDID_WORKAROUND
4550 if (build_id_vaddr < base && dwfl_module_relocations (m) == 1)
4551 {
4552 GElf_Addr main_bias;
4553 dwfl_module_getelf (m, &main_bias);
4554 build_id_vaddr += main_bias;
4555 }
4556 #endif
4557 if (c->session.verbose > 1)
4558 {
4559 clog << "Found build-id in " << name
4560 << ", length " << build_id_len;
4561 clog << ", end at 0x" << hex << build_id_vaddr
4562 << dec << endl;
4563 }
4564 }
4565
4566 // Get the canonical path of the main file for comparison at runtime.
4567 // When given directly by the user through -d or in case of the kernel
4568 // name and path might differ. path should be used for matching.
4569 // Use end as sanity check when resolving symbol addresses and to
4570 // calculate size for .dynamic and .absolute sections.
4571 const char *mainfile;
4572 Dwarf_Addr start, end;
4573 dwfl_module_info (m, NULL, &start, &end, NULL, NULL, &mainfile, NULL);
4574
4575 // Look up the relocation basis for symbols
4576 int n = dwfl_module_relocations (m);
4577
4578 dwfl_assert ("dwfl_module_relocations", n >= 0);
4579
4580
4581 // XXX: unfortunate duplication with tapsets.cxx:emit_address()
4582
4583 typedef map<Dwarf_Addr,const char*> addrmap_t; // NB: plain map, sorted by address
4584 vector<pair<string,unsigned> > seclist; // encountered relocation bases
4585 // (section names and sizes)
4586 map<unsigned, addrmap_t> addrmap; // per-relocation-base sorted addrmap
4587
4588 Dwarf_Addr extra_offset = 0;
4589
4590 for (int i = 0; i < syments; ++i)
4591 {
4592 GElf_Sym sym;
4593 GElf_Word shndxp;
4594 const char *name = dwfl_module_getsym(m, i, &sym, &shndxp);
4595 if (name)
4596 {
4597 // NB: Yey, we found the kernel's _stext value.
4598 // Sess.sym_stext may be unset (0) at this point, since
4599 // there may have been no kernel probes set. We could
4600 // use tapsets.cxx:lookup_symbol_address(), but then
4601 // we're already iterating over the same data here...
4602 if (modname == "kernel" && !strcmp(name, "_stext"))
4603 {
4604 int ki;
4605 extra_offset = sym.st_value;
4606 ki = dwfl_module_relocate_address (m, &extra_offset);
4607 dwfl_assert ("dwfl_module_relocate_address extra_offset",
4608 ki >= 0);
4609 // Sadly dwfl_module_relocate_address is broken on
4610 // elfutils < 0.138, so we need to adjust for the module
4611 // base address outself. (see also below).
4612 extra_offset = sym.st_value - base;
4613 if (c->session.verbose > 2)
4614 clog << "Found kernel _stext extra offset 0x" << hex << extra_offset << dec << endl;
4615 }
4616
4617 // We are only interested in "real" symbols.
4618 // We omit symbols that have suspicious addresses (before base,
4619 // or after end).
4620 if ((GELF_ST_TYPE (sym.st_info) == STT_FUNC ||
4621 GELF_ST_TYPE (sym.st_info) == STT_OBJECT) // PR10000: also need .data
4622 && !(sym.st_shndx == SHN_UNDEF // Value undefined,
4623 || shndxp == (GElf_Word) -1 // in a non-allocated section,
4624 || sym.st_value >= end // beyond current module,
4625 || sym.st_value < base)) // before first section.
4626 {
4627 Dwarf_Addr sym_addr = sym.st_value;
4628 Dwarf_Addr save_addr = sym_addr;
4629 const char *secname = NULL;
4630
4631 if (n > 0) // only try to relocate if there exist relocation bases
4632 {
4633 int ki = dwfl_module_relocate_address (m, &sym_addr);
4634 dwfl_assert ("dwfl_module_relocate_address", ki >= 0);
4635 secname = dwfl_module_relocation_info (m, ki, NULL);
4636
4637 // For ET_DYN files (secname == "") we do ignore the
4638 // dwfl_module_relocate_address adjustment. libdwfl
4639 // up to 0.137 would substract the wrong bias. So we do
4640 // it ourself, it is always just the module base address
4641 // in this case.
4642 if (ki == 0 && secname != NULL && secname[0] == '\0')
4643 sym_addr = save_addr - base;
4644 }
4645
4646 if (n == 1 && modname == "kernel")
4647 {
4648 // This is a symbol within a (possibly relocatable)
4649 // kernel image.
4650
4651 // We only need the function symbols to identify kernel-mode
4652 // PC's, so we omit undefined or "fake" absolute addresses.
4653 // These fake absolute addresses occur in some older i386
4654 // kernels to indicate they are vDSO symbols, not real
4655 // functions in the kernel. We also omit symbols that have
4656 if (GELF_ST_TYPE (sym.st_info) == STT_FUNC
4657 && sym.st_shndx == SHN_ABS)
4658 continue;
4659
4660 secname = "_stext";
4661 // NB: don't subtract session.sym_stext, which could be inconveniently NULL.
4662 // Instead, sym_addr will get compensated later via extra_offset.
4663 }
4664 else if (n > 0)
4665 {
4666 assert (secname != NULL);
4667 // secname adequately set
4668
4669 // NB: it may be an empty string for ET_DYN objects
4670 // like shared libraries, as their relocation base
4671 // is implicit.
4672 if (secname[0] == '\0')
4673 secname = ".dynamic";
4674 }
4675 else
4676 {
4677 assert (n == 0);
4678 // sym_addr is absolute, as it must be since there are no relocation bases
4679 secname = ".absolute"; // sentinel
4680 }
4681
4682 // Compute our section number
4683 unsigned secidx;
4684 for (secidx=0; secidx<seclist.size(); secidx++)
4685 if (seclist[secidx].first==secname) break;
4686
4687 if (secidx == seclist.size()) // new section name
4688 {
4689 // absolute, dynamic or kernel have just one relocation
4690 // section, which covers the whole module address range.
4691 unsigned size;
4692 if (secidx == 0
4693 && (n == 0
4694 || (n == 1
4695 && (strcmp(secname, ".dynamic") == 0
4696 || strcmp(secname, "_stext") == 0))))
4697 size = end - start;
4698 else
4699 {
4700 Dwarf_Addr b;
4701 Elf_Scn *scn;
4702 GElf_Shdr *shdr, shdr_mem;
4703 scn = dwfl_module_address_section (m, &save_addr, &b);
4704 assert (scn != NULL);
4705 shdr = gelf_getshdr(scn, &shdr_mem);
4706 size = shdr->sh_size;
4707 }
4708 seclist.push_back (make_pair(secname,size));
4709 }
4710
4711 (addrmap[secidx])[sym_addr] = name;
4712 }
4713 }
4714 }
4715
4716 // Add unwind data to be included if it exists for this module.
4717 size_t len = 0;
4718 void *unwind = get_unwind_data (m, &len);
4719 if (unwind != NULL)
4720 {
4721 c->output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
4722 c->output << "static uint8_t _stp_module_" << stpmod_idx
4723 << "_unwind_data[] = \n";
4724 c->output << " {";
4725 for (size_t i = 0; i < len; i++)
4726 {
4727 int h = ((uint8_t *)unwind)[i];
4728 c->output << "0x" << hex << h << dec << ",";
4729 if ((i + 1) % 16 == 0)
4730 c->output << "\n" << " ";
4731 }
4732 c->output << "};\n";
4733 c->output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA */\n";
4734 }
4735 else
4736 {
4737 // There would be only a small benefit to warning. A user
4738 // likely can't do anything about this; backtraces for the
4739 // affected module would just get all icky heuristicy.
4740 // So only report in verbose mode.
4741 if (c->session.verbose > 2)
4742 c->session.print_warning ("No unwind data for " + modname
4743 + ", " + dwfl_errmsg (-1));
4744 }
4745
4746 for (unsigned secidx = 0; secidx < seclist.size(); secidx++)
4747 {
4748 c->output << "static struct _stp_symbol "
4749 << "_stp_module_" << stpmod_idx<< "_symbols_" << secidx << "[] = {\n";
4750
4751 // Only include symbols if they will be used
4752 c->output << "#ifdef STP_NEED_SYMBOL_DATA\n";
4753
4754 // We write out a *sorted* symbol table, so the runtime doesn't have to sort them later.
4755 for (addrmap_t::iterator it = addrmap[secidx].begin(); it != addrmap[secidx].end(); it++)
4756 {
4757 if (it->first < extra_offset)
4758 continue; // skip symbols that occur before our chosen base address
4759
4760 c->output << " { 0x" << hex << it->first-extra_offset << dec
4761 << ", " << lex_cast_qstring (it->second) << " },\n";
4762 }
4763
4764 c->output << "#endif /* STP_NEED_SYMBOL_DATA */\n";
4765
4766 c->output << "};\n";
4767 }
4768
4769 c->output << "static struct _stp_section _stp_module_" << stpmod_idx<< "_sections[] = {\n";
4770 // For the kernel, executables (ET_EXEC) or shared libraries (ET_DYN)
4771 // there is just one section that covers the whole address space of
4772 // the module. For kernel modules (ET_REL) there can be multiple
4773 // sections that get relocated separately.
4774 for (unsigned secidx = 0; secidx < seclist.size(); secidx++)
4775 {
4776 c->output << "{\n"
4777 << ".name = " << lex_cast_qstring(seclist[secidx].first) << ",\n"
4778 << ".size = 0x" << hex << seclist[secidx].second << dec << ",\n"
4779 << ".symbols = _stp_module_" << stpmod_idx << "_symbols_" << secidx << ",\n"
4780 << ".num_symbols = " << addrmap[secidx].size() << "\n"
4781 << "},\n";
4782 }
4783 c->output << "};\n";
4784
4785 c->output << "static struct _stp_module _stp_module_" << stpmod_idx << " = {\n";
4786 c->output << ".name = " << lex_cast_qstring (modname) << ", \n";
4787
4788 mainfile = canonicalize_file_name(mainfile);
4789 c->output << ".path = " << lex_cast_qstring (mainfile) << ",\n";
4790
4791 c->output << ".dwarf_module_base = 0x" << hex << base << dec << ", \n";
4792
4793 if (unwind != NULL)
4794 {
4795 c->output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
4796 c->output << ".unwind_data = "
4797 << "_stp_module_" << stpmod_idx << "_unwind_data, \n";
4798 c->output << ".unwind_data_len = " << len << ", \n";
4799 c->output << "#else\n";
4800 }
4801
4802 c->output << ".unwind_data = NULL,\n";
4803 c->output << ".unwind_data_len = 0,\n";
4804
4805 if (unwind != NULL)
4806 c->output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA*/\n";
4807
4808 c->output << ".unwind_hdr = NULL,\n";
4809 c->output << ".unwind_hdr_len = 0,\n";
4810 c->output << ".unwind_is_ehframe = 0,\n";
4811
4812 c->output << ".sections = _stp_module_" << stpmod_idx << "_sections" << ",\n";
4813 c->output << ".num_sections = sizeof(_stp_module_" << stpmod_idx << "_sections)/"
4814 << "sizeof(struct _stp_section),\n";
4815
4816 if (build_id_len > 0) {
4817 c->output << ".build_id_bits = \"" ;
4818 for (int j=0; j<build_id_len;j++)
4819 c->output << "\\x" << hex
4820 << (unsigned short) *(build_id_bits+j) << dec;
4821
4822 c->output << "\",\n";
4823 c->output << ".build_id_len = " << build_id_len << ",\n";
4824
4825 /* XXX: kernel data boot-time relocation works differently from text.
4826 This hack disables relocation altogether, but that's not necessarily
4827 correct either. We may instead need a relocation basis different
4828 from _stext, such as __start_notes. */
4829 if (modname == "kernel")
4830 c->output << ".build_id_offset = 0x" << hex << build_id_vaddr
4831 << dec << ",\n";
4832 else
4833 c->output << ".build_id_offset = 0x" << hex
4834 << build_id_vaddr - base
4835 << dec << ",\n";
4836 } else
4837 c->output << ".build_id_len = 0,\n";
4838
4839 //initialize the note section representing unloaded
4840 c->output << ".notes_sect = 0,\n";
4841
4842 c->output << "};\n\n";
4843
4844 c->undone_unwindsym_modules.erase (modname);
4845
4846 return DWARF_CB_OK;
4847 }
4848
4849
4850 // Emit symbol table & unwind data, plus any calls needed to register
4851 // them with the runtime.
4852 void emit_symbol_data_done (unwindsym_dump_context*, systemtap_session&);
4853
4854 void
4855 emit_symbol_data (systemtap_session& s)
4856 {
4857 string symfile = "stap-symbols.h";
4858
4859 s.op->newline() << "#include " << lex_cast_qstring (symfile);
4860
4861 ofstream kallsyms_out ((s.tmpdir + "/" + symfile).c_str());
4862
4863 unwindsym_dump_context ctx = { s, kallsyms_out, 0, s.unwindsym_modules };
4864
4865 // Micro optimization, mainly to speed up tiny regression tests
4866 // using just begin probe.
4867 if (s.unwindsym_modules.size () == 0)
4868 {
4869 emit_symbol_data_done(&ctx, s);
4870 return;
4871 }
4872
4873 // XXX: copied from tapsets.cxx dwflpp::, sadly
4874 static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build";
4875 static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
4876 static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr);
4877
4878 // ---- step 1: process any kernel modules listed
4879 static const Dwfl_Callbacks kernel_callbacks =
4880 {
4881 dwfl_linux_kernel_find_elf,
4882 dwfl_standard_find_debuginfo,
4883 dwfl_offline_section_address,
4884 (char **) & debuginfo_path
4885 };
4886
4887 Dwfl *dwfl = dwfl_begin (&kernel_callbacks);
4888 if (!dwfl)
4889 throw semantic_error ("cannot open dwfl");
4890 dwfl_report_begin (dwfl);
4891
4892 // We have a problem with -r REVISION vs -r BUILDDIR here. If
4893 // we're running against a fedora/rhel style kernel-debuginfo
4894 // tree, s.kernel_build_tree is not the place where the unstripped
4895 // vmlinux will be installed. Rather, it's over yonder at
4896 // /usr/lib/debug/lib/modules/$REVISION/. It seems that there is
4897 // no way to set the dwfl_callback.debuginfo_path and always
4898 // passs the plain kernel_release here. So instead we have to
4899 // hard-code this magic here.
4900 string elfutils_kernel_path;
4901 if (s.kernel_build_tree == string("/lib/modules/" + s.kernel_release + "/build"))
4902 elfutils_kernel_path = s.kernel_release;
4903 else
4904 elfutils_kernel_path = s.kernel_build_tree;
4905
4906 int rc = dwfl_linux_kernel_report_offline (dwfl,
4907 elfutils_kernel_path.c_str(),
4908 NULL /* XXX: filtering callback */);
4909 dwfl_report_end (dwfl, NULL, NULL);
4910 if (rc == 0) // tolerate missing data; will warn user about it anyway
4911 {
4912 ptrdiff_t off = 0;
4913 do
4914 {
4915 if (pending_interrupts) return;
4916 if (ctx.undone_unwindsym_modules.empty()) break;
4917 off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0);
4918 }
4919 while (off > 0);
4920 dwfl_assert("dwfl_getmodules", off == 0);
4921 }
4922 dwfl_end(dwfl);
4923
4924
4925 // ---- step 2: process any user modules (files) listed
4926 // XXX: see dwflpp::setup_user.
4927 static const Dwfl_Callbacks user_callbacks =
4928 {
4929 NULL, /* dwfl_linux_kernel_find_elf, */
4930 dwfl_standard_find_debuginfo,
4931 NULL, /* ET_REL not supported for user space, only ET_EXEC and ET_DYN.
4932 dwfl_offline_section_address, */
4933 (char **) & debuginfo_path
4934 };
4935
4936 for (std::set<std::string>::iterator it = s.unwindsym_modules.begin();
4937 it != s.unwindsym_modules.end();
4938 it++)
4939 {
4940 string modname = *it;
4941 assert (modname.length() != 0);
4942 if (modname[0] != '/') continue; // user-space files must be full paths
4943 Dwfl *dwfl = dwfl_begin (&user_callbacks);
4944 if (!dwfl)
4945 throw semantic_error ("cannot create dwfl for " + modname);
4946
4947 dwfl_report_begin (dwfl);
4948 Dwfl_Module* mod = dwfl_report_offline (dwfl, modname.c_str(), modname.c_str(), -1);
4949 dwfl_report_end (dwfl, NULL, NULL);
4950 if (mod != 0) // tolerate missing data; will warn below
4951 {
4952 ptrdiff_t off = 0;
4953 do
4954 {
4955 if (pending_interrupts) return;
4956 if (ctx.undone_unwindsym_modules.empty()) break;
4957 off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0);
4958 }
4959 while (off > 0);
4960 dwfl_assert("dwfl_getmodules", off == 0);
4961 }
4962 dwfl_end(dwfl);
4963 }
4964
4965 emit_symbol_data_done (&ctx, s);
4966 }
4967
4968 void
4969 emit_symbol_data_done (unwindsym_dump_context *ctx, systemtap_session& s)
4970 {
4971 // Print out a definition of the runtime's _stp_modules[] globals.
4972 ctx->output << "\n";
4973 ctx->output << "static struct _stp_module *_stp_modules [] = {\n";
4974 for (unsigned i=0; i<ctx->stp_module_index; i++)
4975 {
4976 ctx->output << "& _stp_module_" << i << ",\n";
4977 }
4978 ctx->output << "};\n";
4979 ctx->output << "static unsigned _stp_num_modules = " << ctx->stp_module_index << ";\n";
4980
4981 // Some nonexistent modules may have been identified with "-d". Note them.
4982 for (set<string>::iterator it = ctx->undone_unwindsym_modules.begin();
4983 it != ctx->undone_unwindsym_modules.end();
4984 it ++)
4985 {
4986 s.print_warning ("missing unwind/symbol data for module '" + (*it) + "'");
4987 }
4988 }
4989
4990
4991 int
4992 translate_pass (systemtap_session& s)
4993 {
4994 int rc = 0;
4995
4996 s.op = new translator_output (s.translated_source);
4997 c_unparser cup (& s);
4998 s.up = & cup;
4999
5000 try
5001 {
5002 // This is at the very top of the file.
5003
5004 s.op->newline() << "#ifndef MAXNESTING";
5005 s.op->newline() << "#define MAXNESTING 10";
5006 s.op->newline() << "#endif";
5007 s.op->newline() << "#ifndef MAXSTRINGLEN";
5008 s.op->newline() << "#define MAXSTRINGLEN 128";
5009 s.op->newline() << "#endif";
5010 s.op->newline() << "#ifndef MAXACTION";
5011 s.op->newline() << "#define MAXACTION 1000";
5012 s.op->newline() << "#endif";
5013 s.op->newline() << "#ifndef MAXACTION_INTERRUPTIBLE";
5014 s.op->newline() << "#define MAXACTION_INTERRUPTIBLE (MAXACTION * 10)";
5015 s.op->newline() << "#endif";
5016 s.op->newline() << "#ifndef MAXTRYLOCK";
5017 s.op->newline() << "#define MAXTRYLOCK MAXACTION";
5018 s.op->newline() << "#endif";
5019 s.op->newline() << "#ifndef TRYLOCKDELAY";
5020 s.op->newline() << "#define TRYLOCKDELAY 100";
5021 s.op->newline() << "#endif";
5022 s.op->newline() << "#ifndef MAXMAPENTRIES";
5023 s.op->newline() << "#define MAXMAPENTRIES 2048";
5024 s.op->newline() << "#endif";
5025 s.op->newline() << "#ifndef MAXERRORS";
5026 s.op->newline() << "#define MAXERRORS 0";
5027 s.op->newline() << "#endif";
5028 s.op->newline() << "#ifndef MAXSKIPPED";
5029 s.op->newline() << "#define MAXSKIPPED 100";
5030 s.op->newline() << "#endif";
5031 s.op->newline() << "#ifndef MINSTACKSPACE";
5032 s.op->newline() << "#define MINSTACKSPACE 1024";
5033 s.op->newline() << "#endif";
5034 s.op->newline() << "#ifndef INTERRUPTIBLE";
5035 s.op->newline() << "#define INTERRUPTIBLE 1";
5036 s.op->newline() << "#endif";
5037
5038 // Overload processing
5039 s.op->newline() << "#ifndef STP_OVERLOAD_INTERVAL";
5040 s.op->newline() << "#define STP_OVERLOAD_INTERVAL 1000000000LL";
5041 s.op->newline() << "#endif";
5042 s.op->newline() << "#ifndef STP_OVERLOAD_THRESHOLD";
5043 s.op->newline() << "#define STP_OVERLOAD_THRESHOLD 500000000LL";
5044 s.op->newline() << "#endif";
5045 // We allow the user to completely turn overload processing off
5046 // (as opposed to tuning it by overriding the values above) by
5047 // running: stap -DSTP_NO_OVERLOAD {other options}
5048 s.op->newline() << "#ifndef STP_NO_OVERLOAD";
5049 s.op->newline() << "#define STP_OVERLOAD";
5050 s.op->newline() << "#endif";
5051
5052 s.op->newline() << "#define STP_SKIP_BADVARS " << (s.skip_badvars ? 1 : 0);
5053
5054 if (s.bulk_mode)
5055 s.op->newline() << "#define STP_BULKMODE";
5056
5057 if (s.timing)
5058 s.op->newline() << "#define STP_TIMING";
5059
5060 if (s.perfmon)
5061 s.op->newline() << "#define STP_PERFMON";
5062
5063 s.op->newline() << "#include \"runtime.h\"";
5064 s.op->newline() << "#include \"stack.c\"";
5065 s.op->newline() << "#include \"stat.c\"";
5066 s.op->newline() << "#include <linux/string.h>";
5067 s.op->newline() << "#include <linux/timer.h>";
5068 s.op->newline() << "#include <linux/sched.h>";
5069 s.op->newline() << "#include <linux/delay.h>";
5070 s.op->newline() << "#include <linux/profile.h>";
5071 s.op->newline() << "#include <linux/random.h>";
5072 // s.op->newline() << "#include <linux/utsrelease.h>"; // newer kernels only
5073 s.op->newline() << "#include <linux/vermagic.h>";
5074 s.op->newline() << "#include <linux/utsname.h>";
5075 s.op->newline() << "#include <linux/version.h>";
5076 // s.op->newline() << "#include <linux/compile.h>";
5077 s.op->newline() << "#include \"loc2c-runtime.h\" ";
5078
5079 // XXX: old 2.6 kernel hack
5080 s.op->newline() << "#ifndef read_trylock";
5081 s.op->newline() << "#define read_trylock(x) ({ read_lock(x); 1; })";
5082 s.op->newline() << "#endif";
5083
5084 s.up->emit_common_header (); // context etc.
5085
5086 for (unsigned i=0; i<s.embeds.size(); i++)
5087 {
5088 s.op->newline() << s.embeds[i]->code << "\n";
5089 }
5090
5091 if (s.globals.size()>0) {
5092 s.op->newline() << "static struct {";
5093 s.op->indent(1);
5094 for (unsigned i=0; i<s.globals.size(); i++)
5095 {
5096 s.up->emit_global (s.globals[i]);
5097 }
5098 s.op->newline(-1) << "} global = {";
5099 s.op->newline(1);
5100 for (unsigned i=0; i<s.globals.size(); i++)
5101 {
5102 if (pending_interrupts) return 1;
5103 s.up->emit_global_init (s.globals[i]);
5104 }
5105 s.op->newline(-1) << "};";
5106 s.op->assert_0_indent();
5107 }
5108
5109 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
5110 {
5111 if (pending_interrupts) return 1;
5112 s.op->newline();
5113 s.up->emit_functionsig (it->second);
5114 }
5115 s.op->assert_0_indent();
5116
5117 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
5118 {
5119 if (pending_interrupts) return 1;
5120 s.op->newline();
5121 s.up->emit_function (it->second);
5122 }
5123 s.op->assert_0_indent();
5124
5125 // Run a varuse_collecting_visitor over probes that need global
5126 // variable locks. We'll use this information later in
5127 // emit_locks()/emit_unlocks().
5128 for (unsigned i=0; i<s.probes.size(); i++)
5129 {
5130 if (pending_interrupts) return 1;
5131 if (s.probes[i]->needs_global_locks())
5132 s.probes[i]->body->visit (&cup.vcv_needs_global_locks);
5133 }
5134 s.op->assert_0_indent();
5135
5136 for (unsigned i=0; i<s.probes.size(); i++)
5137 {
5138 if (pending_interrupts) return 1;
5139 s.up->emit_probe (s.probes[i]);
5140 }
5141 s.op->assert_0_indent();
5142
5143 s.op->newline();
5144 s.up->emit_unprivileged_user_check ();
5145 s.op->assert_0_indent();
5146 s.op->newline();
5147 s.up->emit_module_init ();
5148 s.op->assert_0_indent();
5149 s.op->newline();
5150 s.up->emit_module_exit ();
5151 s.op->assert_0_indent();
5152 s.op->newline();
5153
5154 // XXX impedance mismatch
5155 s.op->newline() << "static int probe_start (void) {";
5156 s.op->newline(1) << "return systemtap_module_init () ? -1 : 0;";
5157 s.op->newline(-1) << "}";
5158 s.op->newline();
5159 s.op->newline() << "static void probe_exit (void) {";
5160 s.op->newline(1) << "systemtap_module_exit ();";
5161 s.op->newline(-1) << "}";
5162 s.op->assert_0_indent();
5163
5164 for (unsigned i=0; i<s.globals.size(); i++)
5165 {
5166 s.op->newline();
5167 s.up->emit_global_param (s.globals[i]);
5168 }
5169 s.op->assert_0_indent();
5170
5171 emit_symbol_data (s);
5172
5173 s.op->newline() << "MODULE_DESCRIPTION(\"systemtap-generated probe\");";
5174 s.op->newline() << "MODULE_LICENSE(\"GPL\");";
5175 s.op->assert_0_indent();
5176 }
5177 catch (const semantic_error& e)
5178 {
5179 s.print_error (e);
5180 }
5181
5182 s.op->line() << "\n";
5183
5184 delete s.op;
5185 s.op = 0;
5186 s.up = 0;
5187
5188 return rc + s.num_errors();
5189 }
5190
5191 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.317016 seconds and 5 git commands to generate.