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