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