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