2 // Copyright (C) 2005-2009 Red Hat Inc.
3 // Copyright (C) 2005-2008 Intel Corporation.
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
12 #include "elaborate.h"
13 #include "translate.h"
17 #include "dwarf_wrappers.h"
28 #include <elfutils/libdwfl.h>
29 #ifdef HAVE_ELFUTILS_VERSION_H
30 #include <elfutils/version.h>
42 struct c_unparser
: public unparser
, public visitor
44 systemtap_session
* session
;
47 derived_probe
* current_probe
;
48 functiondecl
* current_function
;
49 unsigned tmpvar_counter
;
50 unsigned label_counter
;
51 unsigned action_counter
;
52 bool probe_or_function_needs_deref_fault_handler
;
54 varuse_collecting_visitor vcv_needs_global_locks
;
56 map
<string
, string
> probe_contents
;
58 c_unparser (systemtap_session
* ss
):
59 session (ss
), o (ss
->op
), current_probe(0), current_function (0),
60 tmpvar_counter (0), label_counter (0) {}
63 void emit_map_type_instantiations ();
64 void emit_common_header ();
65 void emit_global (vardecl
* v
);
66 void emit_global_init (vardecl
* v
);
67 void emit_global_param (vardecl
* v
);
68 void emit_functionsig (functiondecl
* v
);
69 void emit_module_init ();
70 void emit_module_exit ();
71 void emit_function (functiondecl
* v
);
72 void emit_locks (const varuse_collecting_visitor
& v
);
73 void emit_probe (derived_probe
* v
);
74 void emit_unlocks (const varuse_collecting_visitor
& v
);
76 // for use by stats (pmap) foreach
77 set
<string
> aggregations_active
;
79 // for use by looping constructs
80 vector
<string
> loop_break_labels
;
81 vector
<string
> loop_continue_labels
;
83 string
c_typename (exp_type e
);
84 string
c_varname (const string
& e
);
85 string
c_expression (expression
* e
);
87 void c_assign (var
& lvalue
, const string
& rvalue
, const token
* tok
);
88 void c_assign (const string
& lvalue
, expression
* rvalue
, const string
& msg
);
89 void c_assign (const string
& lvalue
, const string
& rvalue
, exp_type type
,
90 const string
& msg
, const token
* tok
);
92 void c_declare(exp_type ty
, const string
&name
);
93 void c_declare_static(exp_type ty
, const string
&name
);
95 void c_strcat (const string
& lvalue
, const string
& rvalue
);
96 void c_strcat (const string
& lvalue
, expression
* rvalue
);
98 void c_strcpy (const string
& lvalue
, const string
& rvalue
);
99 void c_strcpy (const string
& lvalue
, expression
* rvalue
);
101 bool is_local (vardecl
const* r
, token
const* tok
);
103 tmpvar
gensym(exp_type ty
);
104 aggvar
gensym_aggregate();
106 var
getvar(vardecl
* v
, token
const* tok
= NULL
);
107 itervar
getiter(symbol
* s
);
108 mapvar
getmap(vardecl
* v
, token
const* tok
= NULL
);
110 void load_map_indices(arrayindex
* e
,
111 vector
<tmpvar
> & idx
);
113 void load_aggregate (expression
*e
, aggvar
& agg
, bool pre_agg
=false);
114 string
histogram_index_check(var
& vase
, tmpvar
& idx
) const;
116 void collect_map_index_types(vector
<vardecl
* > const & vars
,
117 set
< pair
<vector
<exp_type
>, exp_type
> > & types
);
119 void record_actions (unsigned actions
, bool update
=false);
121 void visit_block (block
* s
);
122 void visit_embeddedcode (embeddedcode
* s
);
123 void visit_null_statement (null_statement
* s
);
124 void visit_expr_statement (expr_statement
* s
);
125 void visit_if_statement (if_statement
* s
);
126 void visit_for_loop (for_loop
* s
);
127 void visit_foreach_loop (foreach_loop
* s
);
128 void visit_return_statement (return_statement
* s
);
129 void visit_delete_statement (delete_statement
* s
);
130 void visit_next_statement (next_statement
* s
);
131 void visit_break_statement (break_statement
* s
);
132 void visit_continue_statement (continue_statement
* s
);
133 void visit_literal_string (literal_string
* e
);
134 void visit_literal_number (literal_number
* e
);
135 void visit_binary_expression (binary_expression
* e
);
136 void visit_unary_expression (unary_expression
* e
);
137 void visit_pre_crement (pre_crement
* e
);
138 void visit_post_crement (post_crement
* e
);
139 void visit_logical_or_expr (logical_or_expr
* e
);
140 void visit_logical_and_expr (logical_and_expr
* e
);
141 void visit_array_in (array_in
* e
);
142 void visit_comparison (comparison
* e
);
143 void visit_concatenation (concatenation
* e
);
144 void visit_ternary_expression (ternary_expression
* e
);
145 void visit_assignment (assignment
* e
);
146 void visit_symbol (symbol
* e
);
147 void visit_target_symbol (target_symbol
* e
);
148 void visit_arrayindex (arrayindex
* e
);
149 void visit_functioncall (functioncall
* e
);
150 void visit_print_format (print_format
* e
);
151 void visit_stat_op (stat_op
* e
);
152 void visit_hist_op (hist_op
* e
);
153 void visit_cast_op (cast_op
* e
);
156 // A shadow visitor, meant to generate temporary variable declarations
157 // for function or probe bodies. Member functions should exactly match
158 // the corresponding c_unparser logic and traversal sequence,
159 // to ensure interlocking naming and declaration of temp variables.
161 public traversing_visitor
164 c_tmpcounter (c_unparser
* p
):
167 parent
->tmpvar_counter
= 0;
170 void load_map_indices(arrayindex
* e
);
172 void visit_block (block
*s
);
173 void visit_for_loop (for_loop
* s
);
174 void visit_foreach_loop (foreach_loop
* s
);
175 // void visit_return_statement (return_statement* s);
176 void visit_delete_statement (delete_statement
* s
);
177 void visit_binary_expression (binary_expression
* e
);
178 // void visit_unary_expression (unary_expression* e);
179 void visit_pre_crement (pre_crement
* e
);
180 void visit_post_crement (post_crement
* e
);
181 // void visit_logical_or_expr (logical_or_expr* e);
182 // void visit_logical_and_expr (logical_and_expr* e);
183 void visit_array_in (array_in
* e
);
184 // void visit_comparison (comparison* e);
185 void visit_concatenation (concatenation
* e
);
186 // void visit_ternary_expression (ternary_expression* e);
187 void visit_assignment (assignment
* e
);
188 void visit_arrayindex (arrayindex
* e
);
189 void visit_functioncall (functioncall
* e
);
190 void visit_print_format (print_format
* e
);
191 void visit_stat_op (stat_op
* e
);
194 struct c_unparser_assignment
:
195 public throwing_visitor
200 bool post
; // true == value saved before modify operator
201 c_unparser_assignment (c_unparser
* p
, const string
& o
, expression
* e
):
202 throwing_visitor ("invalid lvalue type"),
203 parent (p
), op (o
), rvalue (e
), post (false) {}
204 c_unparser_assignment (c_unparser
* p
, const string
& o
, bool pp
):
205 throwing_visitor ("invalid lvalue type"),
206 parent (p
), op (o
), rvalue (0), post (pp
) {}
208 void prepare_rvalue (string
const & op
,
212 void c_assignop(tmpvar
& res
,
217 // only symbols and arrayindex nodes are possible lvalues
218 void visit_symbol (symbol
* e
);
219 void visit_arrayindex (arrayindex
* e
);
223 struct c_tmpcounter_assignment
:
224 public traversing_visitor
225 // leave throwing for illegal lvalues to the c_unparser_assignment instance
227 c_tmpcounter
* parent
;
230 bool post
; // true == value saved before modify operator
231 c_tmpcounter_assignment (c_tmpcounter
* p
, const string
& o
, expression
* e
, bool pp
= false):
232 parent (p
), op (o
), rvalue (e
), post (pp
) {}
234 void prepare_rvalue (tmpvar
& rval
);
236 void c_assignop(tmpvar
& res
);
238 // only symbols and arrayindex nodes are possible lvalues
239 void visit_symbol (symbol
* e
);
240 void visit_arrayindex (arrayindex
* e
);
244 ostream
& operator<<(ostream
& o
, var
const & v
);
248 Some clarification on the runtime structures involved in statistics:
250 The basic type for collecting statistics in the runtime is struct
251 stat_data. This contains the count, min, max, sum, and possibly
254 There are two places struct stat_data shows up.
256 1. If you declare a statistic variable of any sort, you want to make
257 a struct _Stat. A struct _Stat* is also called a Stat. Struct _Stat
258 contains a per-CPU array of struct stat_data values, as well as a
259 struct stat_data which it aggregates into. Writes into a Struct
260 _Stat go into the per-CPU struct stat. Reads involve write-locking
261 the struct _Stat, aggregating into its aggregate struct stat_data,
262 unlocking, read-locking the struct _Stat, then reading values out of
263 the aggregate and unlocking.
265 2. If you declare a statistic-valued map, you want to make a
266 pmap. This is a per-CPU array of maps, each of which holds struct
267 stat_data values, as well as an aggregate *map*. Writes into a pmap
268 go into the per-CPU map. Reads involve write-locking the pmap,
269 aggregating into its aggregate map, unlocking, read-locking the
270 pmap, then reading values out of its aggregate (which is a normal
273 Because, at the moment, the runtime does not support the concept of
274 a statistic which collects multiple histogram types, we may need to
275 instantiate one pmap or struct _Stat for each histogram variation
276 the user wants to track.
290 var(bool local
, exp_type ty
, statistic_decl
const & sd
, string
const & name
)
291 : local(local
), ty(ty
), sd(sd
), name(name
)
294 var(bool local
, exp_type ty
, string
const & name
)
295 : local(local
), ty(ty
), name(name
)
300 bool is_local() const
305 statistic_decl
const & sdecl() const
310 void assert_hist_compatible(hist_op
const & hop
)
312 // Semantic checks in elaborate should have caught this if it was
313 // false. This is just a double-check.
316 case statistic_decl::linear
:
317 assert(hop
.htype
== hist_linear
);
318 assert(hop
.params
.size() == 3);
319 assert(hop
.params
[0] == sd
.linear_low
);
320 assert(hop
.params
[1] == sd
.linear_high
);
321 assert(hop
.params
[2] == sd
.linear_step
);
323 case statistic_decl::logarithmic
:
324 assert(hop
.htype
== hist_log
);
325 assert(hop
.params
.size() == 0);
327 case statistic_decl::none
:
332 exp_type
type() const
342 return "global.s_" + name
;
345 virtual string
hist() const
347 assert (ty
== pe_stats
);
348 assert (sd
.type
!= statistic_decl::none
);
349 return "(&(" + value() + "->hist))";
352 virtual string
buckets() const
354 assert (ty
== pe_stats
);
355 assert (sd
.type
!= statistic_decl::none
);
356 return "(" + value() + "->hist.buckets)";
365 return ""; // module_param
367 return value() + "[0] = '\\0';";
370 return ""; // module_param
372 return value() + " = 0;";
375 // See also mapvar::init().
377 string prefix
= value() + " = _stp_stat_init (";
378 // Check for errors during allocation.
379 string suffix
= "if (" + value () + " == NULL) rc = -ENOMEM;";
383 case statistic_decl::none
:
384 prefix
+= "HIST_NONE";
387 case statistic_decl::linear
:
388 prefix
+= string("HIST_LINEAR")
389 + ", " + stringify(sd
.linear_low
)
390 + ", " + stringify(sd
.linear_high
)
391 + ", " + stringify(sd
.linear_step
);
394 case statistic_decl::logarithmic
:
395 prefix
+= string("HIST_LOG");
399 throw semantic_error("unsupported stats type for " + value());
402 prefix
= prefix
+ "); ";
403 return string (prefix
+ suffix
);
407 throw semantic_error("unsupported initializer for " + value());
417 return ""; // no action required
419 return "_stp_stat_del (" + value () + ");";
421 throw semantic_error("unsupported deallocator for " + value());
425 void declare(c_unparser
&c
) const
427 c
.c_declare(ty
, name
);
431 ostream
& operator<<(ostream
& o
, var
const & v
)
433 return o
<< v
.value();
439 stmt_expr(c_unparser
& c
) : c(c
)
441 c
.o
->newline() << "({";
446 c
.o
->newline(-1) << "})";
456 string override_value
;
461 : var(true, ty
, ("__tmp" + stringify(counter
++))), overridden(false)
464 tmpvar(const var
& source
)
465 : var(source
), overridden(false)
468 void override(const string
&value
)
471 override_value
= value
;
477 return override_value
;
483 ostream
& operator<<(ostream
& o
, tmpvar
const & v
)
485 return o
<< v
.value();
491 aggvar(unsigned & counter
)
492 : var(true, pe_stats
, ("__tmp" + stringify(counter
++)))
497 assert (type() == pe_stats
);
498 return value() + " = NULL;";
501 void declare(c_unparser
&c
) const
503 assert (type() == pe_stats
);
504 c
.o
->newline() << "struct stat_data *" << name
<< ";";
511 vector
<exp_type
> index_types
;
513 mapvar (bool local
, exp_type ty
,
514 statistic_decl
const & sd
,
516 vector
<exp_type
> const & index_types
,
518 : var (local
, ty
, sd
, name
),
519 index_types (index_types
),
523 static string
shortname(exp_type e
);
524 static string
key_typename(exp_type e
);
525 static string
value_typename(exp_type e
);
527 string
keysym () const
530 vector
<exp_type
> tmp
= index_types
;
531 tmp
.push_back (type ());
532 for (unsigned i
= 0; i
< tmp
.size(); ++i
)
546 throw semantic_error("unknown type of map");
553 string
call_prefix (string
const & fname
, vector
<tmpvar
> const & indices
, bool pre_agg
=false) const
555 string mtype
= (is_parallel() && !pre_agg
) ? "pmap" : "map";
556 string result
= "_stp_" + mtype
+ "_" + fname
+ "_" + keysym() + " (";
557 result
+= pre_agg
? fetch_existing_aggregate() : value();
558 for (unsigned i
= 0; i
< indices
.size(); ++i
)
560 if (indices
[i
].type() != index_types
[i
])
561 throw semantic_error("index type mismatch");
563 result
+= indices
[i
].value();
569 bool is_parallel() const
571 return type() == pe_stats
;
574 string
calculate_aggregate() const
577 throw semantic_error("aggregating non-parallel map type");
579 return "_stp_pmap_agg (" + value() + ")";
582 string
fetch_existing_aggregate() const
585 throw semantic_error("fetching aggregate of non-parallel map type");
587 return "_stp_pmap_get_agg(" + value() + ")";
590 string
del (vector
<tmpvar
> const & indices
) const
592 return (call_prefix("del", indices
) + ")");
595 string
exists (vector
<tmpvar
> const & indices
) const
597 if (type() == pe_long
|| type() == pe_string
)
598 return (call_prefix("exists", indices
) + ")");
599 else if (type() == pe_stats
)
600 return ("((uintptr_t)" + call_prefix("get", indices
)
601 + ") != (uintptr_t) 0)");
603 throw semantic_error("checking existence of an unsupported map type");
606 string
get (vector
<tmpvar
> const & indices
, bool pre_agg
=false) const
608 // see also itervar::get_key
609 if (type() == pe_string
)
610 // impedance matching: NULL -> empty strings
611 return ("({ char *v = " + call_prefix("get", indices
, pre_agg
) + ");"
612 + "if (!v) v = \"\"; v; })");
613 else if (type() == pe_long
|| type() == pe_stats
)
614 return call_prefix("get", indices
, pre_agg
) + ")";
616 throw semantic_error("getting a value from an unsupported map type");
619 string
add (vector
<tmpvar
> const & indices
, tmpvar
const & val
) const
621 string res
= "{ int rc = ";
623 // impedance matching: empty strings -> NULL
624 if (type() == pe_stats
)
625 res
+= (call_prefix("add", indices
) + ", " + val
.value() + ")");
627 throw semantic_error("adding a value of an unsupported map type");
629 res
+= "; if (unlikely(rc)) { c->last_error = \"Array overflow, check " +
630 stringify(maxsize
> 0 ?
631 "size limit (" + stringify(maxsize
) + ")" : "MAXMAPENTRIES")
632 + "\"; goto out; }}";
637 string
set (vector
<tmpvar
> const & indices
, tmpvar
const & val
) const
639 string res
= "{ int rc = ";
641 // impedance matching: empty strings -> NULL
642 if (type() == pe_string
)
643 res
+= (call_prefix("set", indices
)
644 + ", (" + val
.value() + "[0] ? " + val
.value() + " : NULL))");
645 else if (type() == pe_long
)
646 res
+= (call_prefix("set", indices
) + ", " + val
.value() + ")");
648 throw semantic_error("setting a value of an unsupported map type");
650 res
+= "; if (unlikely(rc)) { c->last_error = \"Array overflow, check " +
651 stringify(maxsize
> 0 ?
652 "size limit (" + stringify(maxsize
) + ")" : "MAXMAPENTRIES")
653 + "\"; goto out; }}";
660 assert (ty
== pe_stats
);
661 assert (sd
.type
!= statistic_decl::none
);
662 return "(&(" + fetch_existing_aggregate() + "->hist))";
665 string
buckets() const
667 assert (ty
== pe_stats
);
668 assert (sd
.type
!= statistic_decl::none
);
669 return "(" + fetch_existing_aggregate() + "->hist.buckets)";
674 string mtype
= is_parallel() ? "pmap" : "map";
675 string prefix
= value() + " = _stp_" + mtype
+ "_new_" + keysym() + " (" +
676 (maxsize
> 0 ? stringify(maxsize
) : "MAXMAPENTRIES") ;
678 // See also var::init().
680 // Check for errors during allocation.
681 string suffix
= "if (" + value () + " == NULL) rc = -ENOMEM;";
683 if (type() == pe_stats
)
685 switch (sdecl().type
)
687 case statistic_decl::none
:
688 prefix
= prefix
+ ", HIST_NONE";
691 case statistic_decl::linear
:
692 // FIXME: check for "reasonable" values in linear stats
693 prefix
= prefix
+ ", HIST_LINEAR"
694 + ", " + stringify(sdecl().linear_low
)
695 + ", " + stringify(sdecl().linear_high
)
696 + ", " + stringify(sdecl().linear_step
);
699 case statistic_decl::logarithmic
:
700 prefix
= prefix
+ ", HIST_LOG";
705 prefix
= prefix
+ "); ";
706 return (prefix
+ suffix
);
711 // NB: fini() is safe to call even for globals that have not
712 // successfully initialized (that is to say, on NULL pointers),
713 // because the runtime specifically tolerates that in its _del
717 return "_stp_pmap_del (" + value() + ");";
719 return "_stp_map_del (" + value() + ");";
726 exp_type referent_ty
;
731 itervar (symbol
* e
, unsigned & counter
)
732 : referent_ty(e
->referent
->type
),
733 name("__tmp" + stringify(counter
++))
735 if (referent_ty
== pe_unknown
)
736 throw semantic_error("iterating over unknown reference type", e
->tok
);
739 string
declare () const
741 return "struct map_node *" + name
+ ";";
744 string
start (mapvar
const & mv
) const
748 if (mv
.type() != referent_ty
)
749 throw semantic_error("inconsistent iterator type in itervar::start()");
751 if (mv
.is_parallel())
752 return "_stp_map_start (" + mv
.fetch_existing_aggregate() + ")";
754 return "_stp_map_start (" + mv
.value() + ")";
757 string
next (mapvar
const & mv
) const
759 if (mv
.type() != referent_ty
)
760 throw semantic_error("inconsistent iterator type in itervar::next()");
762 if (mv
.is_parallel())
763 return "_stp_map_iter (" + mv
.fetch_existing_aggregate() + ", " + value() + ")";
765 return "_stp_map_iter (" + mv
.value() + ", " + value() + ")";
768 string
value () const
773 string
get_key (exp_type ty
, unsigned i
) const
775 // bug translator/1175: runtime uses base index 1 for the first dimension
776 // see also mapval::get
780 return "_stp_key_get_int64 ("+ value() + ", " + stringify(i
+1) + ")";
782 // impedance matching: NULL -> empty strings
783 return "({ char *v = "
784 "_stp_key_get_str ("+ value() + ", " + stringify(i
+1) + "); "
785 "if (! v) v = \"\"; "
788 throw semantic_error("illegal key type");
793 ostream
& operator<<(ostream
& o
, itervar
const & v
)
795 return o
<< v
.value();
798 // ------------------------------------------------------------------------
801 translator_output::translator_output (ostream
& f
):
802 buf(0), o2 (0), o (f
), tablevel (0)
807 translator_output::translator_output (const string
& filename
, size_t bufsize
):
808 buf (new char[bufsize
]),
809 o2 (new ofstream (filename
.c_str ())),
813 o2
->rdbuf()->pubsetbuf(buf
, bufsize
);
817 translator_output::~translator_output ()
825 translator_output::newline (int indent
)
827 if (! (indent
> 0 || tablevel
>= (unsigned)-indent
)) o
.flush ();
828 assert (indent
> 0 || tablevel
>= (unsigned)-indent
);
832 for (unsigned i
=0; i
<tablevel
; i
++)
839 translator_output::indent (int indent
)
841 if (! (indent
> 0 || tablevel
>= (unsigned)-indent
)) o
.flush ();
842 assert (indent
> 0 || tablevel
>= (unsigned)-indent
);
848 translator_output::line ()
854 // ------------------------------------------------------------------------
857 c_unparser::emit_common_header ()
860 o
->newline() << "typedef char string_t[MAXSTRINGLEN];";
862 o
->newline() << "#define STAP_SESSION_STARTING 0";
863 o
->newline() << "#define STAP_SESSION_RUNNING 1";
864 o
->newline() << "#define STAP_SESSION_ERROR 2";
865 o
->newline() << "#define STAP_SESSION_STOPPING 3";
866 o
->newline() << "#define STAP_SESSION_STOPPED 4";
867 o
->newline() << "static atomic_t session_state = ATOMIC_INIT (STAP_SESSION_STARTING);";
868 o
->newline() << "static atomic_t error_count = ATOMIC_INIT (0);";
869 o
->newline() << "static atomic_t skipped_count = ATOMIC_INIT (0);";
870 o
->newline() << "static atomic_t skipped_count_lowstack = ATOMIC_INIT (0);";
871 o
->newline() << "static atomic_t skipped_count_reentrant = ATOMIC_INIT (0);";
872 o
->newline() << "static atomic_t skipped_count_uprobe_reg = ATOMIC_INIT (0);";
873 o
->newline() << "static atomic_t skipped_count_uprobe_unreg = ATOMIC_INIT (0);";
875 o
->newline() << "struct context {";
876 o
->newline(1) << "atomic_t busy;";
877 o
->newline() << "const char *probe_point;";
878 o
->newline() << "int actionremaining;";
879 o
->newline() << "unsigned nesting;";
880 o
->newline() << "string_t error_buffer;";
881 o
->newline() << "const char *last_error;";
882 // NB: last_error is used as a health flag within a probe.
883 // While it's 0, execution continues
884 // When it's "something", probe code unwinds, _stp_error's, sets error state
885 o
->newline() << "const char *last_stmt;";
886 o
->newline() << "struct pt_regs *regs;";
887 o
->newline() << "unsigned long *unwaddr;";
888 // unwaddr is caching unwound address in each probe handler on ia64.
889 o
->newline() << "struct kretprobe_instance *pi;";
890 o
->newline() << "int regparm;";
891 o
->newline() << "va_list *mark_va_list;";
892 o
->newline() << "const char * marker_name;";
893 o
->newline() << "const char * marker_format;";
894 o
->newline() << "void *data;";
895 o
->newline() << "#ifdef STP_TIMING";
896 o
->newline() << "Stat *statp;";
897 o
->newline() << "#endif";
898 o
->newline() << "#ifdef STP_OVERLOAD";
899 o
->newline() << "cycles_t cycles_base;";
900 o
->newline() << "cycles_t cycles_sum;";
901 o
->newline() << "#endif";
902 o
->newline() << "union {";
905 // To elide context variables for probe handler functions that
906 // themselves are about to get duplicate-eliminated, we XXX
907 // duplicate the parse-tree-hash method from ::emit_probe().
908 map
<string
, string
> tmp_probe_contents
;
909 // The reason we don't use c_unparser::probe_contents itself
910 // for this is that we don't want to muck up the data for
911 // that later routine.
913 for (unsigned i
=0; i
<session
->probes
.size(); i
++)
915 derived_probe
* dp
= session
->probes
[i
];
917 // NB: see c_unparser::emit_probe() for original copy of duplicate-hashing logic.
919 oss
<< "c->statp = & time_" << dp
->basest()->name
<< ";" << endl
; // -t anti-dupe
920 oss
<< "# needs_global_locks: " << dp
->needs_global_locks () << endl
;
921 dp
->print_dupe_stamp (oss
);
922 dp
->body
->print(oss
);
923 // NB: dependent probe conditions *could* be listed here, but don't need to be.
924 // That's because they're only dependent on the probe body, which is already
925 // "hashed" in above.
928 if (tmp_probe_contents
.count(oss
.str()) == 0) // unique
930 tmp_probe_contents
[oss
.str()] = dp
->name
; // save it
932 // XXX: probe locals need not be recursion-nested, only function locals
934 o
->newline() << "struct " << dp
->name
<< "_locals {";
936 for (unsigned j
=0; j
<dp
->locals
.size(); j
++)
938 vardecl
* v
= dp
->locals
[j
];
941 o
->newline() << c_typename (v
->type
) << " "
942 << c_varname (v
->name
) << ";";
943 } catch (const semantic_error
& e
) {
944 semantic_error
e2 (e
);
945 if (e2
.tok1
== 0) e2
.tok1
= v
->tok
;
950 // NB: This part is finicky. The logic here must
952 c_tmpcounter
ct (this);
953 dp
->emit_probe_context_vars (o
);
954 dp
->body
->visit (& ct
);
956 o
->newline(-1) << "} " << dp
->name
<< ";";
960 for (map
<string
,functiondecl
*>::iterator it
= session
->functions
.begin(); it
!= session
->functions
.end(); it
++)
962 functiondecl
* fd
= it
->second
;
964 << "struct function_" << c_varname (fd
->name
) << "_locals {";
966 for (unsigned j
=0; j
<fd
->locals
.size(); j
++)
968 vardecl
* v
= fd
->locals
[j
];
971 o
->newline() << c_typename (v
->type
) << " "
972 << c_varname (v
->name
) << ";";
973 } catch (const semantic_error
& e
) {
974 semantic_error
e2 (e
);
975 if (e2
.tok1
== 0) e2
.tok1
= v
->tok
;
979 for (unsigned j
=0; j
<fd
->formal_args
.size(); j
++)
981 vardecl
* v
= fd
->formal_args
[j
];
984 o
->newline() << c_typename (v
->type
) << " "
985 << c_varname (v
->name
) << ";";
986 } catch (const semantic_error
& e
) {
987 semantic_error
e2 (e
);
988 if (e2
.tok1
== 0) e2
.tok1
= v
->tok
;
992 c_tmpcounter
ct (this);
993 fd
->body
->visit (& ct
);
994 if (fd
->type
== pe_unknown
)
995 o
->newline() << "/* no return value */";
998 o
->newline() << c_typename (fd
->type
) << " __retvalue;";
1000 o
->newline(-1) << "} function_" << c_varname (fd
->name
) << ";";
1002 o
->newline(-1) << "} locals [MAXNESTING];";
1003 o
->newline(-1) << "};\n";
1004 o
->newline() << "static void *contexts = NULL; /* alloc_percpu */\n";
1006 emit_map_type_instantiations ();
1008 if (!session
->stat_decls
.empty())
1009 o
->newline() << "#include \"stat.c\"\n";
1016 c_unparser::emit_global_param (vardecl
*v
)
1018 string vn
= c_varname (v
->name
);
1020 // NB: systemtap globals can collide with linux macros,
1021 // e.g. VM_FAULT_MAJOR. We want the parameter name anyway. This
1022 // #undef is spit out at the end of the C file, so that removing the
1023 // definition won't affect any other embedded-C or generated code.
1024 // XXX: better not have a global variable named module_param_named etc.!
1025 o
->newline() << "#undef " << vn
;
1027 // Emit module_params for this global, if its type is convenient.
1028 if (v
->arity
== 0 && v
->type
== pe_long
)
1030 o
->newline() << "module_param_named (" << vn
<< ", "
1031 << "global.s_" << vn
<< ", int64_t, 0);";
1033 else if (v
->arity
== 0 && v
->type
== pe_string
)
1035 // NB: no special copying is needed.
1036 o
->newline() << "module_param_string (" << vn
<< ", "
1037 << "global.s_" << vn
1038 << ", MAXSTRINGLEN, 0);";
1044 c_unparser::emit_global (vardecl
*v
)
1046 string vn
= c_varname (v
->name
);
1049 o
->newline() << c_typename (v
->type
) << " s_" << vn
<< ";";
1050 else if (v
->type
== pe_stats
)
1051 o
->newline() << "PMAP s_" << vn
<< ";";
1053 o
->newline() << "MAP s_" << vn
<< ";";
1054 o
->newline() << "rwlock_t s_" << vn
<< "_lock;";
1055 o
->newline() << "#ifdef STP_TIMING";
1056 o
->newline() << "atomic_t s_" << vn
<< "_lock_skip_count;";
1057 o
->newline() << "#endif\n";
1062 c_unparser::emit_global_init (vardecl
*v
)
1064 string vn
= c_varname (v
->name
);
1066 if (v
->arity
== 0) // can only statically initialize some scalars
1070 o
->newline() << ".s_" << vn
<< " = ";
1071 v
->init
->visit(this);
1075 o
->newline() << "#ifdef STP_TIMING";
1076 o
->newline() << ".s_" << vn
<< "_lock_skip_count = ATOMIC_INIT(0),";
1077 o
->newline() << "#endif";
1083 c_unparser::emit_functionsig (functiondecl
* v
)
1085 o
->newline() << "static void function_" << v
->name
1086 << " (struct context * __restrict__ c);";
1092 c_unparser::emit_module_init ()
1094 vector
<derived_probe_group
*> g
= all_session_groups (*session
);
1095 for (unsigned i
=0; i
<g
.size(); i
++)
1096 g
[i
]->emit_module_decls (*session
);
1099 o
->newline() << "static int systemtap_module_init (void) {";
1100 o
->newline(1) << "int rc = 0;";
1101 o
->newline() << "int i=0, j=0;"; // for derived_probe_group use
1102 o
->newline() << "const char *probe_point = \"\";";
1104 // Compare actual and targeted kernel releases/machines. Sometimes
1105 // one may install the incorrect debuginfo or -devel RPM, and try to
1106 // run a probe compiled for a different version. Catch this early,
1107 // just in case modversions didn't.
1108 o
->newline() << "{";
1109 o
->newline(1) << "const char* release = UTS_RELEASE;";
1111 // NB: This UTS_RELEASE compile-time macro directly checks only that
1112 // the compile-time kbuild tree matches the compile-time debuginfo/etc.
1113 // It does not check the run time kernel value. However, this is
1114 // probably OK since the kbuild modversions system aims to prevent
1115 // mismatches between kbuild and runtime versions at module-loading time.
1117 // o->newline() << "const char* machine = UTS_MACHINE;";
1118 // NB: We could compare UTS_MACHINE too, but on x86 it lies
1119 // (UTS_MACHINE=i386, but uname -m is i686). Sheesh.
1121 o
->newline() << "if (strcmp (release, "
1122 << lex_cast_qstring (session
->kernel_release
) << ")) {";
1123 o
->newline(1) << "_stp_error (\"module release mismatch (%s vs %s)\", "
1125 << lex_cast_qstring (session
->kernel_release
)
1127 o
->newline() << "rc = -EINVAL;";
1128 o
->newline(-1) << "}";
1130 // perform buildid-based checking if able
1131 o
->newline() << "if (_stp_module_check()) rc = -EINVAL;";
1133 o
->newline(-1) << "}";
1134 o
->newline() << "if (rc) goto out;";
1136 o
->newline() << "(void) probe_point;";
1137 o
->newline() << "(void) i;";
1138 o
->newline() << "(void) j;";
1139 o
->newline() << "atomic_set (&session_state, STAP_SESSION_STARTING);";
1140 // This signals any other probes that may be invoked in the next little
1141 // while to abort right away. Currently running probes are allowed to
1142 // terminate. These may set STAP_SESSION_ERROR!
1145 o
->newline() << "if (sizeof (struct context) <= 131072)";
1146 o
->newline(1) << "contexts = alloc_percpu (struct context);";
1147 o
->newline(-1) << "if (contexts == NULL) {";
1148 o
->newline(1) << "_stp_error (\"percpu context (size %lu) allocation failed\", sizeof (struct context));";
1149 o
->newline() << "rc = -ENOMEM;";
1150 o
->newline() << "goto out;";
1151 o
->newline(-1) << "}";
1153 for (unsigned i
=0; i
<session
->globals
.size(); i
++)
1155 vardecl
* v
= session
->globals
[i
];
1156 if (v
->index_types
.size() > 0)
1157 o
->newline() << getmap (v
).init();
1159 o
->newline() << getvar (v
).init();
1160 // NB: in case of failure of allocation, "rc" will be set to non-zero.
1161 // Allocation can in general continue.
1163 o
->newline() << "if (rc) {";
1164 o
->newline(1) << "_stp_error (\"global variable " << v
->name
<< " allocation failed\");";
1165 o
->newline() << "goto out;";
1166 o
->newline(-1) << "}";
1168 o
->newline() << "rwlock_init (& global.s_" << c_varname (v
->name
) << "_lock);";
1171 // initialize each Stat used for timing information
1172 o
->newline() << "#ifdef STP_TIMING";
1173 set
<string
> basest_names
;
1174 for (unsigned i
=0; i
<session
->probes
.size(); i
++)
1176 string nm
= session
->probes
[i
]->basest()->name
;
1177 if (basest_names
.find(nm
) == basest_names
.end())
1179 o
->newline() << "time_" << nm
<< " = _stp_stat_init (HIST_NONE);";
1180 // NB: we don't check for null return here, but instead at
1181 // passage to probe handlers and at final printing.
1182 basest_names
.insert (nm
);
1185 o
->newline() << "#endif";
1187 // Print a message to the kernel log about this module. This is
1188 // intended to help debug problems with systemtap modules.
1190 o
->newline() << "_stp_print_kernel_info("
1192 << "/" << dwfl_version (NULL
) << "\""
1193 << ", (num_online_cpus() * sizeof(struct context))"
1194 << ", " << session
->probes
.size()
1197 // Run all probe registrations. This actually runs begin probes.
1199 for (unsigned i
=0; i
<g
.size(); i
++)
1201 g
[i
]->emit_module_init (*session
);
1202 // NB: this gives O(N**2) amount of code, but luckily there
1203 // are only seven or eight derived_probe_groups, so it's ok.
1204 o
->newline() << "if (rc) {";
1205 o
->newline(1) << "_stp_error (\"probe %s registration error (rc %d)\", probe_point, rc);";
1206 // NB: we need to be in the error state so timers can shutdown cleanly,
1207 // and so end probes don't run. OTOH, error probes can run.
1208 o
->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);";
1210 for (int j
=i
-1; j
>=0; j
--)
1211 g
[j
]->emit_module_exit (*session
);
1212 o
->newline() << "goto out;";
1213 o
->newline(-1) << "}";
1216 // All registrations were successful. Consider the system started.
1217 o
->newline() << "if (atomic_read (&session_state) == STAP_SESSION_STARTING)";
1218 // NB: only other valid state value is ERROR, in which case we don't
1219 o
->newline(1) << "atomic_set (&session_state, STAP_SESSION_RUNNING);";
1220 o
->newline(-1) << "return 0;";
1222 // Error handling path; by now all partially registered probe groups
1223 // have been unregistered.
1224 o
->newline(-1) << "out:";
1227 // If any registrations failed, we will need to deregister the globals,
1228 // as this is our only chance.
1229 for (unsigned i
=0; i
<session
->globals
.size(); i
++)
1231 vardecl
* v
= session
->globals
[i
];
1232 if (v
->index_types
.size() > 0)
1233 o
->newline() << getmap (v
).fini();
1235 o
->newline() << getvar (v
).fini();
1238 // For any partially registered/unregistered kernel facilities.
1239 o
->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
1240 o
->newline() << "synchronize_sched();";
1241 o
->newline() << "#endif";
1243 o
->newline() << "return rc;";
1244 o
->newline(-1) << "}\n";
1249 c_unparser::emit_module_exit ()
1251 o
->newline() << "static void systemtap_module_exit (void) {";
1253 o
->newline(1) << "int holdon;";
1254 o
->newline() << "int i=0, j=0;"; // for derived_probe_group use
1256 o
->newline() << "(void) i;";
1257 o
->newline() << "(void) j;";
1258 // If we aborted startup, then everything has been cleaned up already, and
1259 // module_exit shouldn't even have been called. But since it might be, let's
1260 // beat a hasty retreat to avoid double uninitialization.
1261 o
->newline() << "if (atomic_read (&session_state) == STAP_SESSION_STARTING)";
1262 o
->newline(1) << "return;";
1265 o
->newline() << "if (atomic_read (&session_state) == STAP_SESSION_RUNNING)";
1266 // NB: only other valid state value is ERROR, in which case we don't
1267 o
->newline(1) << "atomic_set (&session_state, STAP_SESSION_STOPPING);";
1269 // This signals any other probes that may be invoked in the next little
1270 // while to abort right away. Currently running probes are allowed to
1271 // terminate. These may set STAP_SESSION_ERROR!
1273 // We're processing the derived_probe_group list in reverse
1274 // order. This ensures that probes get unregistered in reverse
1275 // order of the way they were registered.
1276 vector
<derived_probe_group
*> g
= all_session_groups (*session
);
1277 for (vector
<derived_probe_group
*>::reverse_iterator i
= g
.rbegin();
1279 (*i
)->emit_module_exit (*session
); // NB: runs "end" probes
1281 // But some other probes may have launched too during unregistration.
1282 // Let's wait a while to make sure they're all done, done, done.
1284 // cargo cult prologue
1285 o
->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
1286 o
->newline() << "synchronize_sched();";
1287 o
->newline() << "#endif";
1289 // NB: systemtap_module_exit is assumed to be called from ordinary
1290 // user context, say during module unload. Among other things, this
1291 // means we can sleep a while.
1292 o
->newline() << "do {";
1293 o
->newline(1) << "int i;";
1294 o
->newline() << "holdon = 0;";
1295 o
->newline() << "for (i=0; i < NR_CPUS; i++)";
1296 o
->newline(1) << "if (cpu_possible (i) && "
1297 << "atomic_read (& ((struct context *)per_cpu_ptr(contexts, i))->busy)) "
1299 // NB: we run at least one of these during the shutdown sequence:
1300 o
->newline () << "yield ();"; // aka schedule() and then some
1301 o
->newline(-2) << "} while (holdon);";
1303 // cargo cult epilogue
1304 o
->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
1305 o
->newline() << "synchronize_sched();";
1306 o
->newline() << "#endif";
1308 // XXX: might like to have an escape hatch, in case some probe is
1309 // genuinely stuck somehow
1311 for (unsigned i
=0; i
<session
->globals
.size(); i
++)
1313 vardecl
* v
= session
->globals
[i
];
1314 if (v
->index_types
.size() > 0)
1315 o
->newline() << getmap (v
).fini();
1317 o
->newline() << getvar (v
).fini();
1320 o
->newline() << "free_percpu (contexts);";
1322 // print probe timing statistics
1324 o
->newline() << "#ifdef STP_TIMING";
1325 o
->newline() << "{";
1327 set
<string
> basest_names
;
1328 for (unsigned i
=0; i
<session
->probes
.size(); i
++)
1330 probe
* p
= session
->probes
[i
]->basest();
1331 string nm
= p
->name
;
1332 if (basest_names
.find(nm
) == basest_names
.end())
1334 basest_names
.insert (nm
);
1335 // NB: check for null stat object
1336 o
->newline() << "if (likely (time_" << p
->name
<< ")) {";
1337 o
->newline(1) << "const char *probe_point = "
1338 << lex_cast_qstring (* p
->locations
[0])
1339 << (p
->locations
.size() > 1 ? "\"+\"" : "")
1340 << (p
->locations
.size() > 1 ? lex_cast_qstring(p
->locations
.size()-1) : "")
1342 o
->newline() << "const char *decl_location = "
1343 << lex_cast_qstring (p
->tok
->location
)
1345 o
->newline() << "struct stat_data *stats = _stp_stat_get (time_"
1348 o
->newline() << "if (stats->count) {";
1349 o
->newline(1) << "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);";
1350 o
->newline() << "_stp_printf (\"probe %s (%s), hits: %lld, cycles: %lldmin/%lldavg/%lldmax\\n\",";
1351 o
->newline() << "probe_point, decl_location, (long long) stats->count, (long long) stats->min, (long long) avg, (long long) stats->max);";
1352 o
->newline(-1) << "}";
1353 o
->newline() << "_stp_stat_del (time_" << p
->name
<< ");";
1354 o
->newline(-1) << "}";
1357 o
->newline() << "_stp_print_flush();";
1358 o
->newline(-1) << "}";
1359 o
->newline() << "#endif";
1362 // print final error/skipped counts if non-zero
1363 o
->newline() << "if (atomic_read (& skipped_count) || "
1364 << "atomic_read (& error_count) || "
1365 << "atomic_read (& skipped_count_reentrant)) {"; // PR9967
1366 o
->newline(1) << "_stp_warn (\"Number of errors: %d, "
1367 << "skipped probes: %d\\n\", "
1368 << "(int) atomic_read (& error_count), "
1369 << "(int) atomic_read (& skipped_count));";
1370 o
->newline() << "#ifdef STP_TIMING";
1371 o
->newline() << "{";
1372 o
->newline(1) << "int ctr;";
1373 for (unsigned i
=0; i
<session
->globals
.size(); i
++)
1375 string vn
= c_varname (session
->globals
[i
]->name
);
1376 o
->newline() << "ctr = atomic_read (& global.s_" << vn
<< "_lock_skip_count);";
1377 o
->newline() << "if (ctr) _stp_warn (\"Skipped due to global '%s' lock timeout: %d\\n\", "
1378 << lex_cast_qstring(vn
) << ", ctr);";
1380 o
->newline() << "ctr = atomic_read (& skipped_count_lowstack);";
1381 o
->newline() << "if (ctr) _stp_warn (\"Skipped due to low stack: %d\\n\", ctr);";
1382 o
->newline() << "ctr = atomic_read (& skipped_count_reentrant);";
1383 o
->newline() << "if (ctr) _stp_warn (\"Skipped due to reentrancy: %d\\n\", ctr);";
1384 o
->newline() << "ctr = atomic_read (& skipped_count_uprobe_reg);";
1385 o
->newline() << "if (ctr) _stp_warn (\"Skipped due to uprobe register failure: %d\\n\", ctr);";
1386 o
->newline() << "ctr = atomic_read (& skipped_count_uprobe_unreg);";
1387 o
->newline() << "if (ctr) _stp_warn (\"Skipped due to uprobe unregister failure: %d\\n\", ctr);";
1388 o
->newline(-1) << "}";
1389 o
->newline () << "#endif";
1390 o
->newline() << "_stp_print_flush();";
1391 o
->newline(-1) << "}";
1392 o
->newline(-1) << "}\n";
1397 c_unparser::emit_function (functiondecl
* v
)
1399 o
->newline() << "static void function_" << c_varname (v
->name
)
1400 << " (struct context* __restrict__ c) {";
1402 this->current_probe
= 0;
1403 this->current_function
= v
;
1404 this->tmpvar_counter
= 0;
1405 this->action_counter
= 0;
1408 << "struct function_" << c_varname (v
->name
) << "_locals * "
1409 << " __restrict__ l =";
1411 << "& c->locals[c->nesting+1].function_" << c_varname (v
->name
) // NB: nesting+1
1413 o
->newline(-1) << "(void) l;"; // make sure "l" is marked used
1414 o
->newline() << "#define CONTEXT c";
1415 o
->newline() << "#define THIS l";
1416 o
->newline() << "if (0) goto out;"; // make sure out: is marked used
1418 // set this, in case embedded-c code sets last_error but doesn't otherwise identify itself
1419 o
->newline() << "c->last_stmt = " << lex_cast_qstring(*v
->tok
) << ";";
1421 // check/increment nesting level
1422 o
->newline() << "if (unlikely (c->nesting+2 >= MAXNESTING)) {";
1423 o
->newline(1) << "c->last_error = \"MAXNESTING exceeded\";";
1424 o
->newline() << "return;";
1425 o
->newline(-1) << "} else {";
1426 o
->newline(1) << "c->nesting ++;";
1427 o
->newline(-1) << "}";
1429 // initialize locals
1430 // XXX: optimization: use memset instead
1431 for (unsigned i
=0; i
<v
->locals
.size(); i
++)
1433 if (v
->locals
[i
]->index_types
.size() > 0) // array?
1434 throw semantic_error ("array locals not supported, missing global declaration?",
1437 o
->newline() << getvar (v
->locals
[i
]).init();
1440 // initialize return value, if any
1441 if (v
->type
!= pe_unknown
)
1443 var retvalue
= var(true, v
->type
, "__retvalue");
1444 o
->newline() << retvalue
.init();
1447 o
->newline() << "#define return goto out"; // redirect embedded-C return
1448 this->probe_or_function_needs_deref_fault_handler
= false;
1449 v
->body
->visit (this);
1450 o
->newline() << "#undef return";
1452 this->current_function
= 0;
1454 record_actions(0, true);
1456 if (this->probe_or_function_needs_deref_fault_handler
) {
1457 // Emit this handler only if the body included a
1458 // print/printf/etc. using a string or memory buffer!
1459 o
->newline() << "CATCH_DEREF_FAULT ();";
1462 o
->newline(-1) << "out:";
1463 o
->newline(1) << ";";
1465 // Function prologue: this is why we redirect the "return" above.
1466 // Decrement nesting level.
1467 o
->newline() << "c->nesting --;";
1469 o
->newline() << "#undef CONTEXT";
1470 o
->newline() << "#undef THIS";
1471 o
->newline(-1) << "}\n";
1475 #define DUPMETHOD_CALL 0
1476 #define DUPMETHOD_ALIAS 0
1477 #define DUPMETHOD_RENAME 1
1480 c_unparser::emit_probe (derived_probe
* v
)
1482 this->current_function
= 0;
1483 this->current_probe
= v
;
1484 this->tmpvar_counter
= 0;
1485 this->action_counter
= 0;
1487 // If we about to emit a probe that is exactly the same as another
1488 // probe previously emitted, make the second probe just call the
1491 // Notice we're using the probe body itself instead of the emitted C
1492 // probe body to compare probes. We need to do this because the
1493 // emitted C probe body has stuff in it like:
1494 // c->last_stmt = "identifier 'printf' at foo.stp:<line>:<column>";
1496 // which would make comparisons impossible.
1498 // --------------------------------------------------------------------------
1499 // NB: see also c_unparser:emit_common_header(), which deliberately but sadly
1500 // duplicates this calculation.
1501 // --------------------------------------------------------------------------
1505 // NB: statp is just for avoiding designation as duplicate. It need not be C.
1506 // NB: This code *could* be enclosed in an "if (session->timing)". That would
1507 // recognize more duplicate probe handlers, but then the generated code could
1508 // be very different with or without -t.
1509 oss
<< "c->statp = & time_" << v
->basest()->name
<< ";" << endl
;
1511 v
->print_dupe_stamp (oss
);
1512 v
->body
->print(oss
);
1514 // Since the generated C changes based on whether or not the probe
1515 // needs locks around global variables, this needs to be reflected
1516 // here. We don't want to treat as duplicate the handlers of
1517 // begin/end and normal probes that differ only in need_global_locks.
1518 oss
<< "# needs_global_locks: " << v
->needs_global_locks () << endl
;
1520 // If an identical probe has already been emitted, just call that
1522 if (probe_contents
.count(oss
.str()) != 0)
1524 string dupe
= probe_contents
[oss
.str()];
1526 // NB: Elision of context variable structs is a separate
1527 // operation which has already taken place by now.
1528 if (session
->verbose
> 1)
1529 clog
<< v
->name
<< " elided, duplicates " << dupe
<< endl
;
1532 // This one emits a direct call to the first copy.
1534 o
->newline() << "static void " << v
->name
<< " (struct context * __restrict__ c) ";
1535 o
->newline() << "{ " << dupe
<< " (c); }";
1536 #elif DUPMETHOD_ALIAS
1537 // This one defines a function alias, arranging gcc to emit
1538 // several equivalent symbols for the same function body.
1539 // For some reason, on gcc 4.1, this is twice as slow as
1542 o
->newline() << "static void " << v
->name
<< " (struct context * __restrict__ c) ";
1543 o
->line() << "__attribute__ ((alias (\"" << dupe
<< "\")));";
1544 #elif DUPMETHOD_RENAME
1545 // This one is sneaky. It emits nothing for duplicate probe
1546 // handlers. It instead redirects subsequent references to the
1547 // probe handler function to the first copy, *by name*.
1550 #error "Unknown duplicate elimination method"
1553 else // This probe is unique. Remember it and output it.
1555 this->probe_or_function_needs_deref_fault_handler
= false;
1558 o
->newline() << "#ifdef STP_TIMING";
1559 o
->newline() << "static __cacheline_aligned Stat " << "time_" << v
->basest()->name
<< ";";
1560 o
->newline() << "#endif";
1562 o
->newline() << "static void " << v
->name
<< " (struct context * __restrict__ c) ";
1566 probe_contents
[oss
.str()] = v
->name
;
1568 // initialize frame pointer
1569 o
->newline() << "struct " << v
->name
<< "_locals * __restrict__ l =";
1570 o
->newline(1) << "& c->locals[0]." << v
->name
<< ";";
1571 o
->newline(-1) << "(void) l;"; // make sure "l" is marked used
1573 o
->newline() << "#ifdef STP_TIMING";
1574 o
->newline() << "c->statp = & time_" << v
->basest()->name
<< ";";
1575 o
->newline() << "#endif";
1577 // emit probe local initialization block
1578 v
->emit_probe_local_init(o
);
1580 // emit all read/write locks for global variables
1581 varuse_collecting_visitor vut
;
1582 if (v
->needs_global_locks ())
1584 v
->body
->visit (& vut
);
1588 // initialize locals
1589 for (unsigned j
=0; j
<v
->locals
.size(); j
++)
1591 if (v
->locals
[j
]->index_types
.size() > 0) // array?
1592 throw semantic_error ("array locals not supported, missing global declaration?",
1594 else if (v
->locals
[j
]->type
== pe_long
)
1595 o
->newline() << "l->" << c_varname (v
->locals
[j
]->name
)
1597 else if (v
->locals
[j
]->type
== pe_string
)
1598 o
->newline() << "l->" << c_varname (v
->locals
[j
]->name
)
1601 throw semantic_error ("unsupported local variable type",
1605 v
->initialize_probe_context_vars (o
);
1607 v
->body
->visit (this);
1609 record_actions(0, true);
1611 if (this->probe_or_function_needs_deref_fault_handler
) {
1612 // Emit this handler only if the body included a
1613 // print/printf/etc. using a string or memory buffer!
1614 o
->newline() << "CATCH_DEREF_FAULT ();";
1617 o
->newline(-1) << "out:";
1618 // NB: no need to uninitialize locals, except if arrays/stats can
1621 // XXX: do this flush only if the body included a
1622 // print/printf/etc. routine!
1623 o
->newline(1) << "_stp_print_flush();";
1625 if (v
->needs_global_locks ())
1628 o
->newline(-1) << "}\n";
1632 this->current_probe
= 0;
1637 c_unparser::emit_locks(const varuse_collecting_visitor
& vut
)
1639 o
->newline() << "{";
1640 o
->newline(1) << "unsigned numtrylock = 0;";
1641 o
->newline() << "(void) numtrylock;";
1643 string last_locked_var
;
1644 for (unsigned i
= 0; i
< session
->globals
.size(); i
++)
1646 vardecl
* v
= session
->globals
[i
];
1647 bool read_p
= vut
.read
.find(v
) != vut
.read
.end();
1648 bool write_p
= vut
.written
.find(v
) != vut
.written
.end();
1649 if (!read_p
&& !write_p
) continue;
1651 if (v
->type
== pe_stats
) // read and write locks are flipped
1652 // Specifically, a "<<<" to a stats object is considered a
1653 // "shared-lock" operation, since it's implicitly done
1654 // per-cpu. But a "@op(x)" extraction is an "exclusive-lock"
1655 // one, as is a (sorted or unsorted) foreach, so those cases
1656 // are excluded by the w & !r condition below.
1658 if (write_p
&& !read_p
) { read_p
= true; write_p
= false; }
1659 else if (read_p
&& !write_p
) { read_p
= false; write_p
= true; }
1662 // We don't need to read lock "read-mostly" global variables. A
1663 // "read-mostly" global variable is only written to within
1664 // probes that don't need global variable locking (such as
1665 // begin/end probes). If vcv_needs_global_locks doesn't mark
1666 // the global as written to, then we don't have to lock it
1667 // here to read it safely.
1668 if (read_p
&& !write_p
)
1670 if (vcv_needs_global_locks
.written
.find(v
)
1671 == vcv_needs_global_locks
.written
.end())
1676 string (write_p
? "write" : "read") +
1677 "_trylock (& global.s_" + v
->name
+ "_lock)";
1679 o
->newline() << "while (! " << lockcall
1680 << "&& (++numtrylock < MAXTRYLOCK))";
1681 o
->newline(1) << "ndelay (TRYLOCKDELAY);";
1682 o
->newline(-1) << "if (unlikely (numtrylock >= MAXTRYLOCK)) {";
1683 o
->newline(1) << "atomic_inc (& skipped_count);";
1684 o
->newline() << "#ifdef STP_TIMING";
1685 o
->newline() << "atomic_inc (& global.s_" << c_varname (v
->name
) << "_lock_skip_count);";
1686 o
->newline() << "#endif";
1687 // The following works even if i==0. Note that using
1688 // globals[i-1]->name is wrong since that global may not have
1689 // been lockworthy by this probe.
1690 o
->newline() << "goto unlock_" << last_locked_var
<< ";";
1691 o
->newline(-1) << "}";
1693 last_locked_var
= v
->name
;
1696 o
->newline() << "if (0) goto unlock_;";
1698 o
->newline(-1) << "}";
1703 c_unparser::emit_unlocks(const varuse_collecting_visitor
& vut
)
1705 unsigned numvars
= 0;
1707 if (session
->verbose
>1)
1708 clog
<< current_probe
->name
<< " locks ";
1710 for (int i
= session
->globals
.size()-1; i
>=0; i
--) // in reverse order!
1712 vardecl
* v
= session
->globals
[i
];
1713 bool read_p
= vut
.read
.find(v
) != vut
.read
.end();
1714 bool write_p
= vut
.written
.find(v
) != vut
.written
.end();
1715 if (!read_p
&& !write_p
) continue;
1717 // Duplicate lock flipping logic from above
1718 if (v
->type
== pe_stats
)
1720 if (write_p
&& !read_p
) { read_p
= true; write_p
= false; }
1721 else if (read_p
&& !write_p
) { read_p
= false; write_p
= true; }
1724 // Duplicate "read-mostly" global variable logic from above.
1725 if (read_p
&& !write_p
)
1727 if (vcv_needs_global_locks
.written
.find(v
)
1728 == vcv_needs_global_locks
.written
.end())
1733 o
->newline(-1) << "unlock_" << v
->name
<< ":";
1736 if (session
->verbose
>1)
1737 clog
<< v
->name
<< "[" << (read_p
? "r" : "")
1738 << (write_p
? "w" : "") << "] ";
1740 if (write_p
) // emit write lock
1741 o
->newline() << "write_unlock (& global.s_" << v
->name
<< "_lock);";
1742 else // (read_p && !write_p) : emit read lock
1743 o
->newline() << "read_unlock (& global.s_" << v
->name
<< "_lock);";
1745 // fall through to next variable; thus the reverse ordering
1748 // emit plain "unlock" label, used if the very first lock failed.
1749 o
->newline(-1) << "unlock_: ;";
1752 if (numvars
) // is there a chance that any lock attempt failed?
1754 // Formerly, we checked skipped_count > MAXSKIPPED here, and set
1755 // SYSTEMTAP_SESSION_ERROR if so. But now, this check is shared
1756 // via common_probe_entryfn_epilogue().
1758 if (session
->verbose
>1)
1761 else if (session
->verbose
>1)
1762 clog
<< "nothing" << endl
;
1767 c_unparser::collect_map_index_types(vector
<vardecl
*> const & vars
,
1768 set
< pair
<vector
<exp_type
>, exp_type
> > & types
)
1770 for (unsigned i
= 0; i
< vars
.size(); ++i
)
1772 vardecl
*v
= vars
[i
];
1775 types
.insert(make_pair(v
->index_types
, v
->type
));
1781 mapvar::value_typename(exp_type e
)
1792 throw semantic_error("array type is neither string nor long");
1798 mapvar::key_typename(exp_type e
)
1807 throw semantic_error("array key is neither string nor long");
1813 mapvar::shortname(exp_type e
)
1822 throw semantic_error("array type is neither string nor long");
1829 c_unparser::emit_map_type_instantiations ()
1831 set
< pair
<vector
<exp_type
>, exp_type
> > types
;
1833 collect_map_index_types(session
->globals
, types
);
1835 for (unsigned i
= 0; i
< session
->probes
.size(); ++i
)
1836 collect_map_index_types(session
->probes
[i
]->locals
, types
);
1838 for (map
<string
,functiondecl
*>::iterator it
= session
->functions
.begin(); it
!= session
->functions
.end(); it
++)
1839 collect_map_index_types(it
->second
->locals
, types
);
1842 o
->newline() << "#include \"alloc.c\"";
1844 for (set
< pair
<vector
<exp_type
>, exp_type
> >::const_iterator i
= types
.begin();
1845 i
!= types
.end(); ++i
)
1847 o
->newline() << "#define VALUE_TYPE " << mapvar::value_typename(i
->second
);
1848 for (unsigned j
= 0; j
< i
->first
.size(); ++j
)
1850 string ktype
= mapvar::key_typename(i
->first
.at(j
));
1851 o
->newline() << "#define KEY" << (j
+1) << "_TYPE " << ktype
;
1853 if (i
->second
== pe_stats
)
1854 o
->newline() << "#include \"pmap-gen.c\"";
1856 o
->newline() << "#include \"map-gen.c\"";
1857 o
->newline() << "#undef VALUE_TYPE";
1858 for (unsigned j
= 0; j
< i
->first
.size(); ++j
)
1860 o
->newline() << "#undef KEY" << (j
+1) << "_TYPE";
1864 * For pmaps, we also need to include map-gen.c, because we might be accessing
1865 * the aggregated map. The better way to handle this is for pmap-gen.c to make
1866 * this include, but that's impossible with the way they are set up now.
1868 if (i
->second
== pe_stats
)
1870 o
->newline() << "#define VALUE_TYPE " << mapvar::value_typename(i
->second
);
1871 for (unsigned j
= 0; j
< i
->first
.size(); ++j
)
1873 string ktype
= mapvar::key_typename(i
->first
.at(j
));
1874 o
->newline() << "#define KEY" << (j
+1) << "_TYPE " << ktype
;
1876 o
->newline() << "#include \"map-gen.c\"";
1877 o
->newline() << "#undef VALUE_TYPE";
1878 for (unsigned j
= 0; j
< i
->first
.size(); ++j
)
1880 o
->newline() << "#undef KEY" << (j
+1) << "_TYPE";
1886 o
->newline() << "#include \"map.c\"";
1892 c_unparser::c_typename (exp_type e
)
1896 case pe_long
: return string("int64_t");
1897 case pe_string
: return string("string_t");
1898 case pe_stats
: return string("Stat");
1901 throw semantic_error ("cannot expand unknown type");
1907 c_unparser::c_varname (const string
& e
)
1909 // XXX: safeify, uniquefy, given name
1915 c_unparser::c_expression (expression
*e
)
1917 // We want to evaluate expression 'e' and return its value as a
1918 // string. In the case of expressions that are just numeric
1919 // constants, if we just print the value into a string, it won't
1920 // have the same value as being visited by c_unparser. For
1921 // instance, a numeric constant evaluated using print() would return
1922 // "5", while c_unparser::visit_literal_number() would
1923 // return "((int64_t)5LL)". String constants evaluated using
1924 // print() would just return the string, while
1925 // c_unparser::visit_literal_string() would return the string with
1926 // escaped double quote characters. So, we need to "visit" the
1929 // However, we have to be careful of side effects. Currently this
1930 // code is only being used for evaluating literal numbers and
1931 // strings, which currently have no side effects. Until needed
1932 // otherwise, limit the use of this function to literal numbers and
1934 if (e
->tok
->type
!= tok_number
&& e
->tok
->type
!= tok_string
)
1935 throw semantic_error("unsupported c_expression token type");
1937 // Create a fake output stream so we can grab the string output.
1939 translator_output
tmp_o(oss
);
1941 // Temporarily swap out the real translator_output stream with our
1943 translator_output
*saved_o
= o
;
1946 // Visit the expression then restore the original output stream
1955 c_unparser::c_assign (var
& lvalue
, const string
& rvalue
, const token
*tok
)
1957 switch (lvalue
.type())
1960 c_strcpy(lvalue
.value(), rvalue
);
1963 o
->newline() << lvalue
<< " = " << rvalue
<< ";";
1966 throw semantic_error ("unknown lvalue type in assignment", tok
);
1971 c_unparser::c_assign (const string
& lvalue
, expression
* rvalue
,
1974 if (rvalue
->type
== pe_long
)
1976 o
->newline() << lvalue
<< " = ";
1977 rvalue
->visit (this);
1980 else if (rvalue
->type
== pe_string
)
1982 c_strcpy (lvalue
, rvalue
);
1986 string fullmsg
= msg
+ " type unsupported";
1987 throw semantic_error (fullmsg
, rvalue
->tok
);
1993 c_unparser::c_assign (const string
& lvalue
, const string
& rvalue
,
1994 exp_type type
, const string
& msg
, const token
* tok
)
1996 if (type
== pe_long
)
1998 o
->newline() << lvalue
<< " = " << rvalue
<< ";";
2000 else if (type
== pe_string
)
2002 c_strcpy (lvalue
, rvalue
);
2006 string fullmsg
= msg
+ " type unsupported";
2007 throw semantic_error (fullmsg
, tok
);
2013 c_unparser_assignment::c_assignop(tmpvar
& res
,
2015 tmpvar
const & rval
,
2018 // This is common code used by scalar and array-element assignments.
2019 // It assumes an operator-and-assignment (defined by the 'pre' and
2020 // 'op' fields of c_unparser_assignment) is taking place between the
2021 // following set of variables:
2023 // res: the result of evaluating the expression, a temporary
2024 // lval: the lvalue of the expression, which may be damaged
2025 // rval: the rvalue of the expression, which is a temporary or constant
2027 // we'd like to work with a local tmpvar so we can overwrite it in
2028 // some optimized cases
2030 translator_output
* o
= parent
->o
;
2032 if (res
.type() == pe_string
)
2035 throw semantic_error ("post assignment on strings not supported",
2039 parent
->c_strcpy (lval
.value(), rval
.value());
2040 // no need for second copy
2043 else if (op
== ".=")
2045 parent
->c_strcat (lval
.value(), rval
.value());
2049 throw semantic_error ("string assignment operator " +
2050 op
+ " unsupported", tok
);
2052 else if (op
== "<<<")
2054 assert(lval
.type() == pe_stats
);
2055 assert(rval
.type() == pe_long
);
2056 assert(res
.type() == pe_long
);
2057 o
->newline() << res
<< " = " << rval
<< ";";
2058 o
->newline() << "_stp_stat_add (" << lval
<< ", " << res
<< ");";
2060 else if (res
.type() == pe_long
)
2062 // a lot of operators come through this "gate":
2063 // - vanilla assignment "="
2064 // - stats aggregation "<<<"
2065 // - modify-accumulate "+=" and many friends
2066 // - pre/post-crement "++"/"--"
2067 // - "/" and "%" operators, but these need special handling in kernel
2069 // compute the modify portion of a modify-accumulate
2071 unsigned oplen
= op
.size();
2073 macop
= "*error*"; // special shortcuts below
2074 else if (op
== "++" || op
== "+=")
2076 else if (op
== "--" || op
== "-=")
2078 else if (oplen
> 1 && op
[oplen
-1] == '=') // for *=, <<=, etc...
2082 throw semantic_error ("unknown macop for assignment", tok
);
2086 if (macop
== "/" || macop
== "%" || op
== "=")
2087 throw semantic_error ("invalid post-mode operator", tok
);
2089 o
->newline() << res
<< " = " << lval
<< ";";
2091 if (macop
== "+=" || macop
== "-=")
2092 o
->newline() << lval
<< " " << macop
<< " " << rval
<< ";";
2094 o
->newline() << lval
<< " = " << res
<< " " << macop
<< " " << rval
<< ";";
2098 if (op
== "=") // shortcut simple assignment
2100 o
->newline() << lval
<< " = " << rval
<< ";";
2105 if (macop
== "/=" || macop
== "%=")
2107 o
->newline() << "if (unlikely(!" << rval
<< ")) {";
2108 o
->newline(1) << "c->last_error = \"division by 0\";";
2109 o
->newline() << "goto out;";
2110 o
->newline(-1) << "}";
2111 o
->newline() << lval
<< " = "
2112 << ((macop
== "/=") ? "_stp_div64" : "_stp_mod64")
2113 << " (NULL, " << lval
<< ", " << rval
<< ");";
2116 o
->newline() << lval
<< " " << macop
<< " " << rval
<< ";";
2122 throw semantic_error ("assignment type not yet implemented", tok
);
2127 c_unparser::c_declare(exp_type ty
, const string
&name
)
2129 o
->newline() << c_typename (ty
) << " " << c_varname (name
) << ";";
2134 c_unparser::c_declare_static(exp_type ty
, const string
&name
)
2136 o
->newline() << "static " << c_typename (ty
) << " " << c_varname (name
) << ";";
2141 c_unparser::c_strcpy (const string
& lvalue
, const string
& rvalue
)
2143 o
->newline() << "strlcpy ("
2145 << rvalue
<< ", MAXSTRINGLEN);";
2150 c_unparser::c_strcpy (const string
& lvalue
, expression
* rvalue
)
2152 o
->newline() << "strlcpy (" << lvalue
<< ", ";
2153 rvalue
->visit (this);
2154 o
->line() << ", MAXSTRINGLEN);";
2159 c_unparser::c_strcat (const string
& lvalue
, const string
& rvalue
)
2161 o
->newline() << "strlcat ("
2163 << rvalue
<< ", MAXSTRINGLEN);";
2168 c_unparser::c_strcat (const string
& lvalue
, expression
* rvalue
)
2170 o
->newline() << "strlcat (" << lvalue
<< ", ";
2171 rvalue
->visit (this);
2172 o
->line() << ", MAXSTRINGLEN);";
2177 c_unparser::is_local(vardecl
const *r
, token
const *tok
)
2181 for (unsigned i
=0; i
<current_probe
->locals
.size(); i
++)
2183 if (current_probe
->locals
[i
] == r
)
2187 else if (current_function
)
2189 for (unsigned i
=0; i
<current_function
->locals
.size(); i
++)
2191 if (current_function
->locals
[i
] == r
)
2195 for (unsigned i
=0; i
<current_function
->formal_args
.size(); i
++)
2197 if (current_function
->formal_args
[i
] == r
)
2202 for (unsigned i
=0; i
<session
->globals
.size(); i
++)
2204 if (session
->globals
[i
] == r
)
2209 throw semantic_error ("unresolved symbol", tok
);
2211 throw semantic_error ("unresolved symbol: " + r
->name
);
2216 c_unparser::gensym(exp_type ty
)
2218 return tmpvar (ty
, tmpvar_counter
);
2222 c_unparser::gensym_aggregate()
2224 return aggvar (tmpvar_counter
);
2229 c_unparser::getvar(vardecl
*v
, token
const *tok
)
2231 bool loc
= is_local (v
, tok
);
2233 return var (loc
, v
->type
, v
->name
);
2237 std::map
<std::string
, statistic_decl
>::const_iterator i
;
2238 i
= session
->stat_decls
.find(v
->name
);
2239 if (i
!= session
->stat_decls
.end())
2241 return var (loc
, v
->type
, sd
, v
->name
);
2247 c_unparser::getmap(vardecl
*v
, token
const *tok
)
2250 throw semantic_error("attempt to use scalar where map expected", tok
);
2252 std::map
<std::string
, statistic_decl
>::const_iterator i
;
2253 i
= session
->stat_decls
.find(v
->name
);
2254 if (i
!= session
->stat_decls
.end())
2256 return mapvar (is_local (v
, tok
), v
->type
, sd
,
2257 v
->name
, v
->index_types
, v
->maxsize
);
2262 c_unparser::getiter(symbol
*s
)
2264 return itervar (s
, tmpvar_counter
);
2268 // Queue up some actions to remove from actionremaining. Set update=true at
2269 // the end of basic blocks to actually update actionremaining and check it
2270 // against MAXACTION.
2272 c_unparser::record_actions (unsigned actions
, bool update
)
2274 action_counter
+= actions
;
2276 // Update if needed, or after queueing up a few actions, in case of very
2277 // large code sequences.
2278 if ((update
&& action_counter
> 0) || action_counter
>= 10/*<-arbitrary*/)
2280 o
->newline() << "c->actionremaining -= " << action_counter
<< ";";
2281 o
->newline() << "if (unlikely (c->actionremaining <= 0)) {";
2282 o
->newline(1) << "c->last_error = \"MAXACTION exceeded\";";
2283 o
->newline() << "goto out;";
2284 o
->newline(-1) << "}";
2291 c_unparser::visit_block (block
*s
)
2293 o
->newline() << "{";
2296 for (unsigned i
=0; i
<s
->statements
.size(); i
++)
2300 s
->statements
[i
]->visit (this);
2303 catch (const semantic_error
& e
)
2305 session
->print_error (e
);
2308 o
->newline(-1) << "}";
2313 c_unparser::visit_embeddedcode (embeddedcode
*s
)
2315 o
->newline() << "{";
2316 o
->newline(1) << s
->code
;
2317 o
->newline(-1) << "}";
2322 c_unparser::visit_null_statement (null_statement
*)
2324 o
->newline() << "/* null */;";
2329 c_unparser::visit_expr_statement (expr_statement
*s
)
2331 o
->newline() << "(void) ";
2332 s
->value
->visit (this);
2339 c_unparser::visit_if_statement (if_statement
*s
)
2341 record_actions(1, true);
2342 o
->newline() << "if (";
2344 s
->condition
->visit (this);
2348 s
->thenblock
->visit (this);
2349 record_actions(0, true);
2350 o
->newline(-1) << "}";
2353 o
->newline() << "else {";
2355 s
->elseblock
->visit (this);
2356 record_actions(0, true);
2357 o
->newline(-1) << "}";
2363 c_tmpcounter::visit_block (block
*s
)
2365 // Key insight: individual statements of a block can reuse
2366 // temporary variable slots, since temporaries don't survive
2367 // statement boundaries. So we use gcc's anonymous union/struct
2368 // facility to explicitly overlay the temporaries.
2369 parent
->o
->newline() << "union {";
2370 parent
->o
->indent(1);
2371 for (unsigned i
=0; i
<s
->statements
.size(); i
++)
2373 // To avoid lots of empty structs inside the union, remember
2374 // where we are now. Then, output the struct start and remember
2375 // that positon. If when we get done with the statement we
2376 // haven't moved, then we don't really need the struct. To get
2377 // rid of the struct start we output, we'll seek back to where
2378 // we were before we output the struct.
2379 std::ostream::pos_type before_struct_pos
= parent
->o
->tellp();
2380 parent
->o
->newline() << "struct {";
2381 parent
->o
->indent(1);
2382 std::ostream::pos_type after_struct_pos
= parent
->o
->tellp();
2383 s
->statements
[i
]->visit (this);
2384 parent
->o
->indent(-1);
2385 if (after_struct_pos
== parent
->o
->tellp())
2386 parent
->o
->seekp(before_struct_pos
);
2388 parent
->o
->newline() << "};";
2390 parent
->o
->newline(-1) << "};";
2394 c_tmpcounter::visit_for_loop (for_loop
*s
)
2396 if (s
->init
) s
->init
->visit (this);
2397 s
->cond
->visit (this);
2398 s
->block
->visit (this);
2399 if (s
->incr
) s
->incr
->visit (this);
2404 c_unparser::visit_for_loop (for_loop
*s
)
2406 string ctr
= stringify (label_counter
++);
2407 string toplabel
= "top_" + ctr
;
2408 string contlabel
= "continue_" + ctr
;
2409 string breaklabel
= "break_" + ctr
;
2412 if (s
->init
) s
->init
->visit (this);
2413 record_actions(1, true);
2416 o
->newline(-1) << toplabel
<< ":";
2418 // Emit an explicit action here to cover the act of iteration.
2419 // Equivalently, it can stand for the evaluation of the condition
2424 o
->newline() << "if (! (";
2425 if (s
->cond
->type
!= pe_long
)
2426 throw semantic_error ("expected numeric type", s
->cond
->tok
);
2427 s
->cond
->visit (this);
2428 o
->line() << ")) goto " << breaklabel
<< ";";
2431 loop_break_labels
.push_back (breaklabel
);
2432 loop_continue_labels
.push_back (contlabel
);
2433 s
->block
->visit (this);
2434 record_actions(0, true);
2435 loop_break_labels
.pop_back ();
2436 loop_continue_labels
.pop_back ();
2439 o
->newline(-1) << contlabel
<< ":";
2441 if (s
->incr
) s
->incr
->visit (this);
2442 o
->newline() << "goto " << toplabel
<< ";";
2445 o
->newline(-1) << breaklabel
<< ":";
2446 o
->newline(1) << "; /* dummy statement */";
2450 struct arrayindex_downcaster
2451 : public traversing_visitor
2455 arrayindex_downcaster (arrayindex
*& arr
)
2459 void visit_arrayindex (arrayindex
* e
)
2467 expression_is_arrayindex (expression
*e
,
2470 arrayindex
*h
= NULL
;
2471 arrayindex_downcaster
d(h
);
2473 if (static_cast<void*>(h
) == static_cast<void*>(e
))
2483 c_tmpcounter::visit_foreach_loop (foreach_loop
*s
)
2487 classify_indexable (s
->base
, array
, hist
);
2491 itervar iv
= parent
->getiter (array
);
2492 parent
->o
->newline() << iv
.declare();
2496 // See commentary in c_tmpcounter::visit_arrayindex for
2497 // discussion of tmpvars required to look into @hist_op(...)
2500 // First make sure we have exactly one pe_long variable to use as
2501 // our bucket index.
2503 if (s
->indexes
.size() != 1 || s
->indexes
[0]->referent
->type
!= pe_long
)
2504 throw semantic_error("Invalid indexing of histogram", s
->tok
);
2506 // Then declare what we need to form the aggregate we're
2507 // iterating over, and all the tmpvars needed by our call to
2508 // load_aggregate().
2510 aggvar agg
= parent
->gensym_aggregate ();
2511 agg
.declare(*(this->parent
));
2513 symbol
*sym
= get_symbol_within_expression (hist
->stat
);
2514 var v
= parent
->getvar(sym
->referent
, sym
->tok
);
2515 if (sym
->referent
->arity
!= 0)
2517 arrayindex
*arr
= NULL
;
2518 if (!expression_is_arrayindex (hist
->stat
, arr
))
2519 throw semantic_error("expected arrayindex expression in iterated hist_op", s
->tok
);
2521 for (unsigned i
=0; i
<sym
->referent
->index_types
.size(); i
++)
2523 tmpvar ix
= parent
->gensym (sym
->referent
->index_types
[i
]);
2524 ix
.declare (*parent
);
2525 arr
->indexes
[i
]->visit(this);
2530 // Create a temporary for the loop limit counter and the limit
2531 // expression result.
2534 tmpvar res_limit
= parent
->gensym (pe_long
);
2535 res_limit
.declare(*parent
);
2537 s
->limit
->visit (this);
2539 tmpvar limitv
= parent
->gensym (pe_long
);
2540 limitv
.declare(*parent
);
2543 s
->block
->visit (this);
2547 c_unparser::visit_foreach_loop (foreach_loop
*s
)
2551 classify_indexable (s
->base
, array
, hist
);
2555 mapvar mv
= getmap (array
->referent
, s
->tok
);
2556 itervar iv
= getiter (array
);
2559 string ctr
= stringify (label_counter
++);
2560 string toplabel
= "top_" + ctr
;
2561 string contlabel
= "continue_" + ctr
;
2562 string breaklabel
= "break_" + ctr
;
2564 // NB: structure parallels for_loop
2568 tmpvar
*res_limit
= NULL
;
2571 // Evaluate the limit expression once.
2572 res_limit
= new tmpvar(gensym(pe_long
));
2573 c_assign (res_limit
->value(), s
->limit
, "foreach limit");
2576 // aggregate array if required
2577 if (mv
.is_parallel())
2579 o
->newline() << "if (unlikely(NULL == " << mv
.calculate_aggregate() << ")) {";
2580 o
->newline(1) << "c->last_error = \"aggregation overflow in " << mv
<< "\";";
2581 o
->newline() << "goto out;";
2582 o
->newline(-1) << "}";
2584 // sort array if desired
2585 if (s
->sort_direction
)
2589 // If the user wanted us to sort by value, we'll sort by
2590 // @count instead for aggregates. '-5' tells the
2591 // runtime to sort by count.
2592 if (s
->sort_column
== 0)
2595 sort_column
= s
->sort_column
;
2597 o
->newline() << "else"; // only sort if aggregation was ok
2600 o
->newline(1) << "_stp_map_sortn ("
2601 << mv
.fetch_existing_aggregate() << ", "
2602 << *res_limit
<< ", " << sort_column
<< ", "
2603 << - s
->sort_direction
<< ");";
2607 o
->newline(1) << "_stp_map_sort ("
2608 << mv
.fetch_existing_aggregate() << ", "
2609 << sort_column
<< ", "
2610 << - s
->sort_direction
<< ");";
2617 // sort array if desired
2618 if (s
->sort_direction
)
2622 o
->newline() << "_stp_map_sortn (" << mv
.value() << ", "
2623 << *res_limit
<< ", " << s
->sort_column
<< ", "
2624 << - s
->sort_direction
<< ");";
2628 o
->newline() << "_stp_map_sort (" << mv
.value() << ", "
2629 << s
->sort_column
<< ", "
2630 << - s
->sort_direction
<< ");";
2635 // NB: sort direction sense is opposite in runtime, thus the negation
2637 if (mv
.is_parallel())
2638 aggregations_active
.insert(mv
.value());
2639 o
->newline() << iv
<< " = " << iv
.start (mv
) << ";";
2641 tmpvar
*limitv
= NULL
;
2644 // Create the loop limit variable here and initialize it.
2645 limitv
= new tmpvar(gensym (pe_long
));
2646 o
->newline() << *limitv
<< " = 0LL;";
2649 record_actions(1, true);
2652 o
->newline(-1) << toplabel
<< ":";
2654 // Emit an explicit action here to cover the act of iteration.
2655 // Equivalently, it can stand for the evaluation of the
2656 // condition expression.
2660 o
->newline() << "if (! (" << iv
<< ")) goto " << breaklabel
<< ";";
2663 loop_break_labels
.push_back (breaklabel
);
2664 loop_continue_labels
.push_back (contlabel
);
2665 o
->newline() << "{";
2670 // If we've been through LIMIT loop iterations, quit.
2671 o
->newline() << "if (" << *limitv
<< "++ >= " << *res_limit
2672 << ") goto " << breaklabel
<< ";";
2674 // We're done with limitv and res_limit.
2679 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
2681 // copy the iter values into the specified locals
2682 var v
= getvar (s
->indexes
[i
]->referent
);
2683 c_assign (v
, iv
.get_key (v
.type(), i
), s
->tok
);
2685 s
->block
->visit (this);
2686 record_actions(0, true);
2687 o
->newline(-1) << "}";
2688 loop_break_labels
.pop_back ();
2689 loop_continue_labels
.pop_back ();
2692 o
->newline(-1) << contlabel
<< ":";
2693 o
->newline(1) << iv
<< " = " << iv
.next (mv
) << ";";
2694 o
->newline() << "goto " << toplabel
<< ";";
2697 o
->newline(-1) << breaklabel
<< ":";
2698 o
->newline(1) << "; /* dummy statement */";
2700 if (mv
.is_parallel())
2701 aggregations_active
.erase(mv
.value());
2705 // Iterating over buckets in a histogram.
2706 assert(s
->indexes
.size() == 1);
2707 assert(s
->indexes
[0]->referent
->type
== pe_long
);
2708 var bucketvar
= getvar (s
->indexes
[0]->referent
);
2710 aggvar agg
= gensym_aggregate ();
2711 load_aggregate(hist
->stat
, agg
);
2713 symbol
*sym
= get_symbol_within_expression (hist
->stat
);
2714 var v
= getvar(sym
->referent
, sym
->tok
);
2715 v
.assert_hist_compatible(*hist
);
2717 tmpvar
*res_limit
= NULL
;
2718 tmpvar
*limitv
= NULL
;
2721 // Evaluate the limit expression once.
2722 res_limit
= new tmpvar(gensym(pe_long
));
2723 c_assign (res_limit
->value(), s
->limit
, "foreach limit");
2725 // Create the loop limit variable here and initialize it.
2726 limitv
= new tmpvar(gensym (pe_long
));
2727 o
->newline() << *limitv
<< " = 0LL;";
2730 // XXX: break / continue don't work here yet
2731 record_actions(1, true);
2732 o
->newline() << "for (" << bucketvar
<< " = 0; "
2733 << bucketvar
<< " < " << v
.buckets() << "; "
2734 << bucketvar
<< "++) { ";
2739 // If we've been through LIMIT loop iterations, quit.
2740 o
->newline() << "if (" << *limitv
<< "++ >= " << *res_limit
2743 // We're done with limitv and res_limit.
2748 s
->block
->visit (this);
2749 record_actions(1, true);
2750 o
->newline(-1) << "}";
2756 c_unparser::visit_return_statement (return_statement
* s
)
2758 if (current_function
== 0)
2759 throw semantic_error ("cannot 'return' from probe", s
->tok
);
2761 if (s
->value
->type
!= current_function
->type
)
2762 throw semantic_error ("return type mismatch", current_function
->tok
,
2765 c_assign ("l->__retvalue", s
->value
, "return value");
2766 record_actions(1, true);
2767 o
->newline() << "goto out;";
2772 c_unparser::visit_next_statement (next_statement
* s
)
2774 if (current_probe
== 0)
2775 throw semantic_error ("cannot 'next' from function", s
->tok
);
2777 record_actions(1, true);
2778 o
->newline() << "goto out;";
2782 struct delete_statement_operand_tmp_visitor
:
2783 public traversing_visitor
2785 c_tmpcounter
*parent
;
2786 delete_statement_operand_tmp_visitor (c_tmpcounter
*p
):
2789 //void visit_symbol (symbol* e);
2790 void visit_arrayindex (arrayindex
* e
);
2794 struct delete_statement_operand_visitor
:
2795 public throwing_visitor
2798 delete_statement_operand_visitor (c_unparser
*p
):
2799 throwing_visitor ("invalid operand of delete expression"),
2802 void visit_symbol (symbol
* e
);
2803 void visit_arrayindex (arrayindex
* e
);
2807 delete_statement_operand_visitor::visit_symbol (symbol
* e
)
2809 assert (e
->referent
!= 0);
2810 if (e
->referent
->arity
> 0)
2812 mapvar mvar
= parent
->getmap(e
->referent
, e
->tok
);
2813 /* NB: Memory deallocation/allocation operations
2814 are not generally safe.
2815 parent->o->newline() << mvar.fini ();
2816 parent->o->newline() << mvar.init ();
2818 if (mvar
.is_parallel())
2819 parent
->o
->newline() << "_stp_pmap_clear (" << mvar
.value() << ");";
2821 parent
->o
->newline() << "_stp_map_clear (" << mvar
.value() << ");";
2825 var v
= parent
->getvar(e
->referent
, e
->tok
);
2829 parent
->o
->newline() << "_stp_stat_clear (" << v
.value() << ");";
2832 parent
->o
->newline() << v
.value() << " = 0;";
2835 parent
->o
->newline() << v
.value() << "[0] = '\\0';";
2839 throw semantic_error("Cannot delete unknown expression type", e
->tok
);
2845 delete_statement_operand_tmp_visitor::visit_arrayindex (arrayindex
* e
)
2849 classify_indexable (e
->base
, array
, hist
);
2853 assert (array
->referent
!= 0);
2854 vardecl
* r
= array
->referent
;
2856 // One temporary per index dimension.
2857 for (unsigned i
=0; i
<r
->index_types
.size(); i
++)
2859 tmpvar ix
= parent
->parent
->gensym (r
->index_types
[i
]);
2860 ix
.declare (*(parent
->parent
));
2861 e
->indexes
[i
]->visit(parent
);
2866 throw semantic_error("cannot delete histogram bucket entries\n", e
->tok
);
2871 delete_statement_operand_visitor::visit_arrayindex (arrayindex
* e
)
2875 classify_indexable (e
->base
, array
, hist
);
2880 parent
->load_map_indices (e
, idx
);
2883 mapvar mvar
= parent
->getmap (array
->referent
, e
->tok
);
2884 parent
->o
->newline() << mvar
.del (idx
) << ";";
2889 throw semantic_error("cannot delete histogram bucket entries\n", e
->tok
);
2895 c_tmpcounter::visit_delete_statement (delete_statement
* s
)
2897 delete_statement_operand_tmp_visitor
dv (this);
2898 s
->value
->visit (&dv
);
2903 c_unparser::visit_delete_statement (delete_statement
* s
)
2905 delete_statement_operand_visitor
dv (this);
2906 s
->value
->visit (&dv
);
2912 c_unparser::visit_break_statement (break_statement
* s
)
2914 if (loop_break_labels
.size() == 0)
2915 throw semantic_error ("cannot 'break' outside loop", s
->tok
);
2917 record_actions(1, true);
2918 string label
= loop_break_labels
[loop_break_labels
.size()-1];
2919 o
->newline() << "goto " << label
<< ";";
2924 c_unparser::visit_continue_statement (continue_statement
* s
)
2926 if (loop_continue_labels
.size() == 0)
2927 throw semantic_error ("cannot 'continue' outside loop", s
->tok
);
2929 record_actions(1, true);
2930 string label
= loop_continue_labels
[loop_continue_labels
.size()-1];
2931 o
->newline() << "goto " << label
<< ";";
2937 c_unparser::visit_literal_string (literal_string
* e
)
2939 const string
& v
= e
->value
;
2941 for (unsigned i
=0; i
<v
.size(); i
++)
2942 // NB: The backslash character is specifically passed through as is.
2943 // This is because our parser treats "\" as an ordinary character, not
2944 // an escape sequence, leaving it to the C compiler (and this function)
2945 // to treat it as such. If we were to escape it, there would be no way
2946 // of generating C-level escapes from script code.
2947 // See also print_format::components_to_string and lex_cast_qstring
2948 if (v
[i
] == '"') // or other escapeworthy characters?
2949 o
->line() << '\\' << '"';
2957 c_unparser::visit_literal_number (literal_number
* e
)
2959 // This looks ugly, but tries to be warning-free on 32- and 64-bit
2961 // NB: this needs to be signed!
2962 if (e
->value
== -9223372036854775807LL-1) // PR 5023
2963 o
->line() << "((int64_t)" << (unsigned long long) e
->value
<< "ULL)";
2965 o
->line() << "((int64_t)" << e
->value
<< "LL)";
2970 c_tmpcounter::visit_binary_expression (binary_expression
* e
)
2972 if (e
->op
== "/" || e
->op
== "%")
2974 tmpvar left
= parent
->gensym (pe_long
);
2975 tmpvar right
= parent
->gensym (pe_long
);
2976 if (e
->left
->tok
->type
!= tok_number
)
2977 left
.declare (*parent
);
2978 if (e
->right
->tok
->type
!= tok_number
)
2979 right
.declare (*parent
);
2982 e
->left
->visit (this);
2983 e
->right
->visit (this);
2988 c_unparser::visit_binary_expression (binary_expression
* e
)
2990 if (e
->type
!= pe_long
||
2991 e
->left
->type
!= pe_long
||
2992 e
->right
->type
!= pe_long
)
2993 throw semantic_error ("expected numeric types", e
->tok
);
3003 e
->left
->visit (this);
3004 o
->line() << ") " << e
->op
<< " (";
3005 e
->right
->visit (this);
3008 else if (e
->op
== ">>" ||
3012 e
->left
->visit (this);
3013 o
->line() << ") " << e
->op
<< "max(min(";
3014 e
->right
->visit (this);
3015 o
->line() << ", (int64_t)64LL), (int64_t)0LL))"; // between 0 and 64
3017 else if (e
->op
== "/" ||
3020 // % and / need a division-by-zero check; and thus two temporaries
3021 // for proper evaluation order
3022 tmpvar left
= gensym (pe_long
);
3023 tmpvar right
= gensym (pe_long
);
3028 if (e
->left
->tok
->type
== tok_number
)
3029 left
.override(c_expression(e
->left
));
3032 o
->newline() << left
<< " = ";
3033 e
->left
->visit (this);
3037 if (e
->right
->tok
->type
== tok_number
)
3038 right
.override(c_expression(e
->right
));
3041 o
->newline() << right
<< " = ";
3042 e
->right
->visit (this);
3046 o
->newline() << "if (unlikely(!" << right
<< ")) {";
3047 o
->newline(1) << "c->last_error = \"division by 0\";";
3048 o
->newline() << "c->last_stmt = " << lex_cast_qstring(*e
->tok
) << ";";
3049 o
->newline() << "goto out;";
3050 o
->newline(-1) << "}";
3051 o
->newline() << ((e
->op
== "/") ? "_stp_div64" : "_stp_mod64")
3052 << " (NULL, " << left
<< ", " << right
<< ");";
3054 o
->newline(-1) << "})";
3057 throw semantic_error ("operator not yet implemented", e
->tok
);
3062 c_unparser::visit_unary_expression (unary_expression
* e
)
3064 if (e
->type
!= pe_long
||
3065 e
->operand
->type
!= pe_long
)
3066 throw semantic_error ("expected numeric types", e
->tok
);
3070 // NB: Subtraction is special, since negative literals in the
3071 // script language show up as unary negations over positive
3072 // literals here. This makes it "exciting" for emitting pure
3073 // C since: - 0x8000_0000_0000_0000 ==> - (- 9223372036854775808)
3074 // This would constitute a signed overflow, which gcc warns on
3075 // unless -ftrapv/-J are in CFLAGS - which they're not.
3077 o
->line() << "(int64_t)(0 " << e
->op
<< " (uint64_t)(";
3078 e
->operand
->visit (this);
3083 o
->line() << "(" << e
->op
<< " (";
3084 e
->operand
->visit (this);
3090 c_unparser::visit_logical_or_expr (logical_or_expr
* e
)
3092 if (e
->type
!= pe_long
||
3093 e
->left
->type
!= pe_long
||
3094 e
->right
->type
!= pe_long
)
3095 throw semantic_error ("expected numeric types", e
->tok
);
3098 e
->left
->visit (this);
3099 o
->line() << ") " << e
->op
<< " (";
3100 e
->right
->visit (this);
3106 c_unparser::visit_logical_and_expr (logical_and_expr
* e
)
3108 if (e
->type
!= pe_long
||
3109 e
->left
->type
!= pe_long
||
3110 e
->right
->type
!= pe_long
)
3111 throw semantic_error ("expected numeric types", e
->tok
);
3114 e
->left
->visit (this);
3115 o
->line() << ") " << e
->op
<< " (";
3116 e
->right
->visit (this);
3122 c_tmpcounter::visit_array_in (array_in
* e
)
3126 classify_indexable (e
->operand
->base
, array
, hist
);
3130 assert (array
->referent
!= 0);
3131 vardecl
* r
= array
->referent
;
3133 // One temporary per index dimension.
3134 for (unsigned i
=0; i
<r
->index_types
.size(); i
++)
3136 tmpvar ix
= parent
->gensym (r
->index_types
[i
]);
3137 ix
.declare (*parent
);
3138 e
->operand
->indexes
[i
]->visit(this);
3141 // A boolean result.
3142 tmpvar res
= parent
->gensym (e
->type
);
3143 res
.declare (*parent
);
3149 // 'foo in @hist_op(...)' is true iff
3150 // '@hist_op(...)[foo]' is nonzero
3152 // so we just delegate to the latter call, since int64_t is also
3153 // our boolean type.
3154 e
->operand
->visit(this);
3160 c_unparser::visit_array_in (array_in
* e
)
3164 classify_indexable (e
->operand
->base
, array
, hist
);
3168 stmt_expr
block(*this);
3171 load_map_indices (e
->operand
, idx
);
3172 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3174 tmpvar res
= gensym (pe_long
);
3175 mapvar mvar
= getmap (array
->referent
, e
->tok
);
3176 c_assign (res
, mvar
.exists(idx
), e
->tok
);
3178 o
->newline() << res
<< ";";
3184 // 'foo in @hist_op(...)' is true iff
3185 // '@hist_op(...)[foo]' is nonzero
3187 // so we just delegate to the latter call, since int64_t is also
3188 // our boolean type.
3189 e
->operand
->visit(this);
3195 c_unparser::visit_comparison (comparison
* e
)
3199 if (e
->left
->type
== pe_string
)
3201 if (e
->right
->type
!= pe_string
)
3202 throw semantic_error ("expected string types", e
->tok
);
3204 o
->line() << "strncmp (";
3205 e
->left
->visit (this);
3207 e
->right
->visit (this);
3208 o
->line() << ", MAXSTRINGLEN";
3209 o
->line() << ") " << e
->op
<< " 0";
3211 else if (e
->left
->type
== pe_long
)
3213 if (e
->right
->type
!= pe_long
)
3214 throw semantic_error ("expected numeric types", e
->tok
);
3217 e
->left
->visit (this);
3218 o
->line() << ") " << e
->op
<< " (";
3219 e
->right
->visit (this);
3223 throw semantic_error ("unexpected type", e
->left
->tok
);
3230 c_tmpcounter::visit_concatenation (concatenation
* e
)
3232 tmpvar t
= parent
->gensym (e
->type
);
3233 t
.declare (*parent
);
3234 e
->left
->visit (this);
3235 e
->right
->visit (this);
3240 c_unparser::visit_concatenation (concatenation
* e
)
3243 throw semantic_error ("unexpected concatenation operator", e
->tok
);
3245 if (e
->type
!= pe_string
||
3246 e
->left
->type
!= pe_string
||
3247 e
->right
->type
!= pe_string
)
3248 throw semantic_error ("expected string types", e
->tok
);
3250 tmpvar t
= gensym (e
->type
);
3254 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3255 c_assign (t
.value(), e
->left
, "assignment");
3256 c_strcat (t
.value(), e
->right
);
3257 o
->newline() << t
<< ";";
3258 o
->newline(-1) << "})";
3263 c_unparser::visit_ternary_expression (ternary_expression
* e
)
3265 if (e
->cond
->type
!= pe_long
)
3266 throw semantic_error ("expected numeric condition", e
->cond
->tok
);
3268 if (e
->truevalue
->type
!= e
->falsevalue
->type
||
3269 e
->type
!= e
->truevalue
->type
||
3270 (e
->truevalue
->type
!= pe_long
&& e
->truevalue
->type
!= pe_string
))
3271 throw semantic_error ("expected matching types", e
->tok
);
3274 e
->cond
->visit (this);
3275 o
->line() << ") ? (";
3276 e
->truevalue
->visit (this);
3277 o
->line() << ") : (";
3278 e
->falsevalue
->visit (this);
3284 c_tmpcounter::visit_assignment (assignment
*e
)
3286 c_tmpcounter_assignment
tav (this, e
->op
, e
->right
);
3287 e
->left
->visit (& tav
);
3292 c_unparser::visit_assignment (assignment
* e
)
3296 if (e
->type
!= pe_long
)
3297 throw semantic_error ("non-number <<< expression", e
->tok
);
3299 if (e
->left
->type
!= pe_stats
)
3300 throw semantic_error ("non-stats left operand to <<< expression", e
->left
->tok
);
3302 if (e
->right
->type
!= pe_long
)
3303 throw semantic_error ("non-number right operand to <<< expression", e
->right
->tok
);
3308 if (e
->type
!= e
->left
->type
)
3309 throw semantic_error ("type mismatch", e
->tok
,
3310 "vs", e
->left
->tok
);
3311 if (e
->right
->type
!= e
->left
->type
)
3312 throw semantic_error ("type mismatch", e
->right
->tok
,
3313 "vs", e
->left
->tok
);
3316 c_unparser_assignment
tav (this, e
->op
, e
->right
);
3317 e
->left
->visit (& tav
);
3322 c_tmpcounter::visit_pre_crement (pre_crement
* e
)
3324 c_tmpcounter_assignment
tav (this, e
->op
, 0);
3325 e
->operand
->visit (& tav
);
3330 c_unparser::visit_pre_crement (pre_crement
* e
)
3332 if (e
->type
!= pe_long
||
3333 e
->type
!= e
->operand
->type
)
3334 throw semantic_error ("expected numeric type", e
->tok
);
3336 c_unparser_assignment
tav (this, e
->op
, false);
3337 e
->operand
->visit (& tav
);
3342 c_tmpcounter::visit_post_crement (post_crement
* e
)
3344 c_tmpcounter_assignment
tav (this, e
->op
, 0, true);
3345 e
->operand
->visit (& tav
);
3350 c_unparser::visit_post_crement (post_crement
* e
)
3352 if (e
->type
!= pe_long
||
3353 e
->type
!= e
->operand
->type
)
3354 throw semantic_error ("expected numeric type", e
->tok
);
3356 c_unparser_assignment
tav (this, e
->op
, true);
3357 e
->operand
->visit (& tav
);
3362 c_unparser::visit_symbol (symbol
* e
)
3364 assert (e
->referent
!= 0);
3365 vardecl
* r
= e
->referent
;
3367 if (r
->index_types
.size() != 0)
3368 throw semantic_error ("invalid reference to array", e
->tok
);
3370 var v
= getvar(r
, e
->tok
);
3376 c_tmpcounter_assignment::prepare_rvalue (tmpvar
& rval
)
3380 // literal number and strings don't need any temporaries declared
3381 if (rvalue
->tok
->type
!= tok_number
&& rvalue
->tok
->type
!= tok_string
)
3382 rval
.declare (*(parent
->parent
));
3384 rvalue
->visit (parent
);
3389 c_tmpcounter_assignment::c_assignop(tmpvar
& res
)
3391 if (res
.type() == pe_string
)
3393 // string assignment doesn't need any temporaries declared
3395 else if (op
== "<<<")
3396 res
.declare (*(parent
->parent
));
3397 else if (res
.type() == pe_long
)
3399 // Only the 'post' operators ('x++') need a temporary declared.
3401 res
.declare (*(parent
->parent
));
3405 // Assignment expansion is tricky.
3407 // Because assignments are nestable expressions, we have
3408 // to emit C constructs that are nestable expressions too.
3409 // We have to evaluate the given expressions the proper number of times,
3410 // including array indices.
3411 // We have to lock the lvalue (if global) against concurrent modification,
3412 // especially with modify-assignment operations (+=, ++).
3413 // We have to check the rvalue (for division-by-zero checks).
3415 // In the normal "pre=false" case, for (A op B) emit:
3416 // ({ tmp = B; check(B); lock(A); res = A op tmp; A = res; unlock(A); res; })
3417 // In the "pre=true" case, emit instead:
3418 // ({ tmp = B; check(B); lock(A); res = A; A = res op tmp; unlock(A); res; })
3420 // (op is the plain operator portion of a combined calculate/assignment:
3421 // "+" for "+=", and so on. It is in the "macop" variable below.)
3423 // For array assignments, additional temporaries are used for each
3424 // index, which are expanded before the "tmp=B" expression, in order
3425 // to consistently order evaluation of lhs before rhs.
3429 c_tmpcounter_assignment::visit_symbol (symbol
*e
)
3431 exp_type ty
= rvalue
? rvalue
->type
: e
->type
;
3432 tmpvar rval
= parent
->parent
->gensym (ty
);
3433 tmpvar res
= parent
->parent
->gensym (ty
);
3435 prepare_rvalue(rval
);
3442 c_unparser_assignment::prepare_rvalue (string
const & op
,
3448 if (rvalue
->tok
->type
== tok_number
|| rvalue
->tok
->type
== tok_string
)
3449 // Instead of assigning the numeric or string constant to a
3450 // temporary, then assigning the temporary to the final, let's
3451 // just override the temporary with the constant.
3452 rval
.override(parent
->c_expression(rvalue
));
3454 parent
->c_assign (rval
.value(), rvalue
, "assignment");
3458 if (op
== "++" || op
== "--")
3459 // Here is part of the conversion proccess of turning "x++" to
3463 throw semantic_error ("need rvalue for assignment", tok
);
3468 c_unparser_assignment::visit_symbol (symbol
*e
)
3470 stmt_expr
block(*parent
);
3472 assert (e
->referent
!= 0);
3473 if (e
->referent
->index_types
.size() != 0)
3474 throw semantic_error ("unexpected reference to array", e
->tok
);
3476 // parent->o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3477 exp_type ty
= rvalue
? rvalue
->type
: e
->type
;
3478 tmpvar rval
= parent
->gensym (ty
);
3479 tmpvar res
= parent
->gensym (ty
);
3481 prepare_rvalue (op
, rval
, e
->tok
);
3483 var lvar
= parent
->getvar (e
->referent
, e
->tok
);
3484 c_assignop (res
, lvar
, rval
, e
->tok
);
3486 parent
->o
->newline() << res
<< ";";
3491 c_unparser::visit_target_symbol (target_symbol
* e
)
3493 if (!e
->probe_context_var
.empty())
3494 o
->line() << "l->" << e
->probe_context_var
;
3496 throw semantic_error("cannot translate general cast expression", e
->tok
);
3501 c_unparser::visit_cast_op (cast_op
* e
)
3503 throw semantic_error("cannot translate general cast expression", e
->tok
);
3508 c_tmpcounter::load_map_indices(arrayindex
*e
)
3512 classify_indexable (e
->base
, array
, hist
);
3516 assert (array
->referent
!= 0);
3517 vardecl
* r
= array
->referent
;
3519 // One temporary per index dimension, except in the case of
3520 // number or string constants.
3521 for (unsigned i
=0; i
<r
->index_types
.size(); i
++)
3523 tmpvar ix
= parent
->gensym (r
->index_types
[i
]);
3524 if (e
->indexes
[i
]->tok
->type
== tok_number
3525 || e
->indexes
[i
]->tok
->type
== tok_string
)
3530 ix
.declare (*parent
);
3531 e
->indexes
[i
]->visit(this);
3538 c_unparser::load_map_indices(arrayindex
*e
,
3539 vector
<tmpvar
> & idx
)
3543 classify_indexable (e
->base
, array
, hist
);
3549 assert (array
->referent
!= 0);
3550 vardecl
* r
= array
->referent
;
3552 if (r
->index_types
.size() == 0 ||
3553 r
->index_types
.size() != e
->indexes
.size())
3554 throw semantic_error ("invalid array reference", e
->tok
);
3556 for (unsigned i
=0; i
<r
->index_types
.size(); i
++)
3558 if (r
->index_types
[i
] != e
->indexes
[i
]->type
)
3559 throw semantic_error ("array index type mismatch", e
->indexes
[i
]->tok
);
3561 tmpvar ix
= gensym (r
->index_types
[i
]);
3562 if (e
->indexes
[i
]->tok
->type
== tok_number
3563 || e
->indexes
[i
]->tok
->type
== tok_string
)
3564 // Instead of assigning the numeric or string constant to a
3565 // temporary, then using the temporary, let's just
3566 // override the temporary with the constant.
3567 ix
.override(c_expression(e
->indexes
[i
]));
3570 // o->newline() << "c->last_stmt = "
3571 // << lex_cast_qstring(*e->indexes[i]->tok) << ";";
3572 c_assign (ix
.value(), e
->indexes
[i
], "array index copy");
3579 assert (e
->indexes
.size() == 1);
3580 assert (e
->indexes
[0]->type
== pe_long
);
3581 tmpvar ix
= gensym (pe_long
);
3582 // o->newline() << "c->last_stmt = "
3583 // << lex_cast_qstring(*e->indexes[0]->tok) << ";";
3584 c_assign (ix
.value(), e
->indexes
[0], "array index copy");
3591 c_unparser::load_aggregate (expression
*e
, aggvar
& agg
, bool pre_agg
)
3593 symbol
*sym
= get_symbol_within_expression (e
);
3595 if (sym
->referent
->type
!= pe_stats
)
3596 throw semantic_error ("unexpected aggregate of non-statistic", sym
->tok
);
3598 var v
= getvar(sym
->referent
, e
->tok
);
3600 if (sym
->referent
->arity
== 0)
3602 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*sym->tok) << ";";
3603 o
->newline() << agg
<< " = _stp_stat_get (" << v
<< ", 0);";
3607 arrayindex
*arr
= NULL
;
3608 if (!expression_is_arrayindex (e
, arr
))
3609 throw semantic_error("unexpected aggregate of non-arrayindex", e
->tok
);
3612 load_map_indices (arr
, idx
);
3613 mapvar mvar
= getmap (sym
->referent
, sym
->tok
);
3614 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*sym->tok) << ";";
3615 o
->newline() << agg
<< " = " << mvar
.get(idx
, pre_agg
) << ";";
3621 c_unparser::histogram_index_check(var
& base
, tmpvar
& idx
) const
3623 return "((" + idx
.value() + " >= 0)"
3624 + " && (" + idx
.value() + " < " + base
.buckets() + "))";
3629 c_tmpcounter::visit_arrayindex (arrayindex
*e
)
3633 classify_indexable (e
->base
, array
, hist
);
3637 load_map_indices(e
);
3639 // The index-expression result.
3640 tmpvar res
= parent
->gensym (e
->type
);
3641 res
.declare (*parent
);
3648 // Note: this is a slightly tricker-than-it-looks allocation of
3649 // temporaries. The reason is that we're in the branch handling
3650 // histogram-indexing, and the histogram might be build over an
3651 // indexable entity itself. For example if we have:
3655 // foo[getpid(), geteuid()] <<< 1
3657 // print @log_hist(foo[pid, euid])[bucket]
3659 // We are looking at the @log_hist(...)[bucket] expression, so
3660 // allocating one tmpvar for calculating bucket (the "index" of
3661 // this arrayindex expression), and one tmpvar for storing the
3662 // result in, just as normal.
3664 // But we are *also* going to call load_aggregate on foo, which
3665 // will itself require tmpvars for each of its indices. Since
3666 // this is not handled by delving into the subexpression (it
3667 // would be if hist were first-class in the type system, but
3668 // it's not) we we allocate all the tmpvars used in such a
3669 // subexpression up here: first our own aggvar, then our index
3670 // (bucket) tmpvar, then all the index tmpvars of our
3671 // pe_stat-valued subexpression, then our result.
3674 // First all the stuff related to indexing into the histogram
3676 if (e
->indexes
.size() != 1)
3677 throw semantic_error("Invalid indexing of histogram", e
->tok
);
3678 tmpvar ix
= parent
->gensym (pe_long
);
3679 ix
.declare (*parent
);
3680 e
->indexes
[0]->visit(this);
3681 tmpvar res
= parent
->gensym (pe_long
);
3682 res
.declare (*parent
);
3684 // Then the aggregate, and all the tmpvars needed by our call to
3685 // load_aggregate().
3687 aggvar agg
= parent
->gensym_aggregate ();
3688 agg
.declare(*(this->parent
));
3690 symbol
*sym
= get_symbol_within_expression (hist
->stat
);
3691 var v
= parent
->getvar(sym
->referent
, sym
->tok
);
3692 if (sym
->referent
->arity
!= 0)
3694 arrayindex
*arr
= NULL
;
3695 if (!expression_is_arrayindex (hist
->stat
, arr
))
3696 throw semantic_error("expected arrayindex expression in indexed hist_op", e
->tok
);
3698 for (unsigned i
=0; i
<sym
->referent
->index_types
.size(); i
++)
3700 tmpvar ix
= parent
->gensym (sym
->referent
->index_types
[i
]);
3701 ix
.declare (*parent
);
3702 arr
->indexes
[i
]->visit(this);
3710 c_unparser::visit_arrayindex (arrayindex
* e
)
3714 classify_indexable (e
->base
, array
, hist
);
3718 // Visiting an statistic-valued array in a non-lvalue context is prohibited.
3719 if (array
->referent
->type
== pe_stats
)
3720 throw semantic_error ("statistic-valued array in rvalue context", e
->tok
);
3722 stmt_expr
block(*this);
3724 // NB: Do not adjust the order of the next few lines; the tmpvar
3725 // allocation order must remain the same between
3726 // c_unparser::visit_arrayindex and c_tmpcounter::visit_arrayindex
3729 load_map_indices (e
, idx
);
3730 tmpvar res
= gensym (e
->type
);
3732 mapvar mvar
= getmap (array
->referent
, e
->tok
);
3733 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
3734 c_assign (res
, mvar
.get(idx
), e
->tok
);
3736 o
->newline() << res
<< ";";
3740 // See commentary in c_tmpcounter::visit_arrayindex
3743 stmt_expr
block(*this);
3745 // NB: Do not adjust the order of the next few lines; the tmpvar
3746 // allocation order must remain the same between
3747 // c_unparser::visit_arrayindex and c_tmpcounter::visit_arrayindex
3750 load_map_indices (e
, idx
);
3751 tmpvar res
= gensym (e
->type
);
3753 aggvar agg
= gensym_aggregate ();
3755 // These should have faulted during elaboration if not true.
3756 assert(idx
.size() == 1);
3757 assert(idx
[0].type() == pe_long
);
3759 symbol
*sym
= get_symbol_within_expression (hist
->stat
);
3762 if (sym
->referent
->arity
< 1)
3763 v
= new var(getvar(sym
->referent
, e
->tok
));
3765 v
= new mapvar(getmap(sym
->referent
, e
->tok
));
3767 v
->assert_hist_compatible(*hist
);
3769 if (aggregations_active
.count(v
->value()))
3770 load_aggregate(hist
->stat
, agg
, true);
3772 load_aggregate(hist
->stat
, agg
, false);
3774 o
->newline() << "c->last_stmt = " << lex_cast_qstring(*e
->tok
) << ";";
3776 // PR 2142+2610: empty aggregates
3777 o
->newline() << "if (unlikely (" << agg
.value() << " == NULL)"
3778 << " || " << agg
.value() << "->count == 0) {";
3779 o
->newline(1) << "c->last_error = \"empty aggregate\";";
3780 o
->newline() << "goto out;";
3781 o
->newline(-1) << "} else {";
3782 o
->newline(1) << "if (" << histogram_index_check(*v
, idx
[0]) << ")";
3783 o
->newline(1) << res
<< " = " << agg
<< "->histogram[" << idx
[0] << "];";
3784 o
->newline(-1) << "else {";
3785 o
->newline(1) << "c->last_error = \"histogram index out of range\";";
3786 o
->newline() << "goto out;";
3787 o
->newline(-1) << "}";
3789 o
->newline(-1) << "}";
3790 o
->newline() << res
<< ";";
3798 c_tmpcounter_assignment::visit_arrayindex (arrayindex
*e
)
3802 classify_indexable (e
->base
, array
, hist
);
3806 parent
->load_map_indices(e
);
3808 // The expression rval, lval, and result.
3809 exp_type ty
= rvalue
? rvalue
->type
: e
->type
;
3810 tmpvar rval
= parent
->parent
->gensym (ty
);
3811 tmpvar lval
= parent
->parent
->gensym (ty
);
3812 tmpvar res
= parent
->parent
->gensym (ty
);
3814 prepare_rvalue(rval
);
3815 lval
.declare (*(parent
->parent
));
3818 res
.declare (*(parent
->parent
));
3824 throw semantic_error("cannot assign to histogram buckets", e
->tok
);
3830 c_unparser_assignment::visit_arrayindex (arrayindex
*e
)
3834 classify_indexable (e
->base
, array
, hist
);
3839 stmt_expr
block(*parent
);
3841 translator_output
*o
= parent
->o
;
3843 if (array
->referent
->index_types
.size() == 0)
3844 throw semantic_error ("unexpected reference to scalar", e
->tok
);
3846 // nb: Do not adjust the order of the next few lines; the tmpvar
3847 // allocation order must remain the same between
3848 // c_unparser_assignment::visit_arrayindex and
3849 // c_tmpcounter_assignment::visit_arrayindex
3852 parent
->load_map_indices (e
, idx
);
3853 exp_type ty
= rvalue
? rvalue
->type
: e
->type
;
3854 tmpvar rvar
= parent
->gensym (ty
);
3855 tmpvar lvar
= parent
->gensym (ty
);
3856 tmpvar res
= parent
->gensym (ty
);
3858 // NB: because these expressions are nestable, emit this construct
3860 // ({ tmp0=(idx0); ... tmpN=(idxN); rvar=(rhs); lvar; res;
3862 // lvar = get (array,idx0...N); // if necessary
3863 // assignop (res, lvar, rvar);
3864 // set (array, idx0...N, lvar);
3868 // we store all indices in temporary variables to avoid nasty
3869 // reentrancy issues that pop up with nested expressions:
3870 // e.g. ++a[a[c]=5] could deadlock
3873 // There is an exception to the above form: if we're doign a <<< assigment to
3874 // a statistic-valued map, there's a special form we follow:
3876 // ({ tmp0=(idx0); ... tmpN=(idxN); rvar=(rhs);
3877 // *no need to* lock (array);
3878 // _stp_map_add_stat (array, idx0...N, rvar);
3879 // *no need to* unlock (array);
3882 // To simplify variable-allocation rules, we assign rvar to lvar and
3883 // res in this block as well, even though they are technically
3886 prepare_rvalue (op
, rvar
, e
->tok
);
3890 assert (e
->type
== pe_stats
);
3891 assert (rvalue
->type
== pe_long
);
3893 mapvar mvar
= parent
->getmap (array
->referent
, e
->tok
);
3894 o
->newline() << "c->last_stmt = " << lex_cast_qstring(*e
->tok
) << ";";
3895 o
->newline() << mvar
.add (idx
, rvar
) << ";";
3897 // no need for these dummy assignments
3898 // o->newline() << lvar << " = " << rvar << ";";
3899 // o->newline() << res << " = " << rvar << ";";
3903 mapvar mvar
= parent
->getmap (array
->referent
, e
->tok
);
3904 o
->newline() << "c->last_stmt = " << lex_cast_qstring(*e
->tok
) << ";";
3905 if (op
!= "=") // don't bother fetch slot if we will just overwrite it
3906 parent
->c_assign (lvar
, mvar
.get(idx
), e
->tok
);
3907 c_assignop (res
, lvar
, rvar
, e
->tok
);
3908 o
->newline() << mvar
.set (idx
, lvar
) << ";";
3911 o
->newline() << res
<< ";";
3915 throw semantic_error("cannot assign to histogram buckets", e
->tok
);
3921 c_tmpcounter::visit_functioncall (functioncall
*e
)
3923 assert (e
->referent
!= 0);
3924 functiondecl
* r
= e
->referent
;
3925 // one temporary per argument, unless literal numbers or strings
3926 for (unsigned i
=0; i
<r
->formal_args
.size(); i
++)
3928 tmpvar t
= parent
->gensym (r
->formal_args
[i
]->type
);
3929 if (e
->args
[i
]->tok
->type
!= tok_number
3930 && e
->args
[i
]->tok
->type
!= tok_string
)
3931 t
.declare (*parent
);
3932 e
->args
[i
]->visit (this);
3938 c_unparser::visit_functioncall (functioncall
* e
)
3940 assert (e
->referent
!= 0);
3941 functiondecl
* r
= e
->referent
;
3943 if (r
->formal_args
.size() != e
->args
.size())
3944 throw semantic_error ("invalid length argument list", e
->tok
);
3946 stmt_expr
block(*this);
3948 // NB: we store all actual arguments in temporary variables,
3949 // to avoid colliding sharing of context variables with
3950 // nested function calls: f(f(f(1)))
3952 // compute actual arguments
3955 for (unsigned i
=0; i
<e
->args
.size(); i
++)
3957 tmpvar t
= gensym(e
->args
[i
]->type
);
3959 if (r
->formal_args
[i
]->type
!= e
->args
[i
]->type
)
3960 throw semantic_error ("function argument type mismatch",
3961 e
->args
[i
]->tok
, "vs", r
->formal_args
[i
]->tok
);
3963 if (e
->args
[i
]->tok
->type
== tok_number
3964 || e
->args
[i
]->tok
->type
== tok_string
)
3965 t
.override(c_expression(e
->args
[i
]));
3968 // o->newline() << "c->last_stmt = "
3969 // << lex_cast_qstring(*e->args[i]->tok) << ";";
3970 c_assign (t
.value(), e
->args
[i
],
3971 "function actual argument evaluation");
3976 // copy in actual arguments
3977 for (unsigned i
=0; i
<e
->args
.size(); i
++)
3979 if (r
->formal_args
[i
]->type
!= e
->args
[i
]->type
)
3980 throw semantic_error ("function argument type mismatch",
3981 e
->args
[i
]->tok
, "vs", r
->formal_args
[i
]->tok
);
3983 c_assign ("c->locals[c->nesting+1].function_" +
3984 c_varname (r
->name
) + "." +
3985 c_varname (r
->formal_args
[i
]->name
),
3988 "function actual argument copy",
3993 o
->newline() << "function_" << c_varname (r
->name
) << " (c);";
3994 o
->newline() << "if (unlikely(c->last_error)) goto out;";
3996 // return result from retvalue slot
3997 if (r
->type
== pe_unknown
)
3998 // If we passed typechecking, then nothing will use this return value
3999 o
->newline() << "(void) 0;";
4001 o
->newline() << "c->locals[c->nesting+1]"
4002 << ".function_" << c_varname (r
->name
)
4007 c_tmpcounter::visit_print_format (print_format
* e
)
4011 symbol
*sym
= get_symbol_within_expression (e
->hist
->stat
);
4012 var v
= parent
->getvar(sym
->referent
, sym
->tok
);
4013 aggvar agg
= parent
->gensym_aggregate ();
4015 agg
.declare(*(this->parent
));
4017 if (sym
->referent
->arity
!= 0)
4019 // One temporary per index dimension.
4020 for (unsigned i
=0; i
<sym
->referent
->index_types
.size(); i
++)
4022 arrayindex
*arr
= NULL
;
4023 if (!expression_is_arrayindex (e
->hist
->stat
, arr
))
4024 throw semantic_error("expected arrayindex expression in printed hist_op", e
->tok
);
4026 tmpvar ix
= parent
->gensym (sym
->referent
->index_types
[i
]);
4027 ix
.declare (*parent
);
4028 arr
->indexes
[i
]->visit(this);
4034 // One temporary per argument
4035 for (unsigned i
=0; i
< e
->args
.size(); i
++)
4037 tmpvar t
= parent
->gensym (e
->args
[i
]->type
);
4038 if (e
->args
[i
]->type
== pe_unknown
)
4040 throw semantic_error("unknown type of arg to print operator",
4044 if (e
->args
[i
]->tok
->type
!= tok_number
4045 && e
->args
[i
]->tok
->type
!= tok_string
)
4046 t
.declare (*parent
);
4047 e
->args
[i
]->visit (this);
4051 exp_type ty
= e
->print_to_stream
? pe_long
: pe_string
;
4052 tmpvar res
= parent
->gensym (ty
);
4053 if (ty
== pe_string
)
4054 res
.declare (*parent
);
4060 c_unparser::visit_print_format (print_format
* e
)
4062 // Print formats can contain a general argument list *or* a special
4063 // type of argument which gets its own processing: a single,
4064 // non-format-string'ed, histogram-type stat_op expression.
4068 stmt_expr
block(*this);
4069 symbol
*sym
= get_symbol_within_expression (e
->hist
->stat
);
4070 aggvar agg
= gensym_aggregate ();
4073 if (sym
->referent
->arity
< 1)
4074 v
= new var(getvar(sym
->referent
, e
->tok
));
4076 v
= new mapvar(getmap(sym
->referent
, e
->tok
));
4078 v
->assert_hist_compatible(*e
->hist
);
4081 if (aggregations_active
.count(v
->value()))
4082 load_aggregate(e
->hist
->stat
, agg
, true);
4084 load_aggregate(e
->hist
->stat
, agg
, false);
4086 // PR 2142+2610: empty aggregates
4087 o
->newline() << "if (unlikely (" << agg
.value() << " == NULL)"
4088 << " || " << agg
.value() << "->count == 0) {";
4089 o
->newline(1) << "c->last_error = \"empty aggregate\";";
4090 o
->newline() << "c->last_stmt = " << lex_cast_qstring(*e
->tok
) << ";";
4091 o
->newline() << "goto out;";
4092 o
->newline(-1) << "} else";
4093 o
->newline(1) << "_stp_stat_print_histogram (" << v
->hist() << ", " << agg
.value() << ");";
4101 stmt_expr
block(*this);
4103 // Compute actual arguments
4106 for (unsigned i
=0; i
<e
->args
.size(); i
++)
4108 tmpvar t
= gensym(e
->args
[i
]->type
);
4111 // o->newline() << "c->last_stmt = "
4112 // << lex_cast_qstring(*e->args[i]->tok) << ";";
4114 // If we've got a numeric or string constant, instead of
4115 // assigning the numeric or string constant to a temporary,
4116 // then passing the temporary to _stp_printf/_stp_snprintf,
4117 // let's just override the temporary with the constant.
4118 if (e
->args
[i
]->tok
->type
== tok_number
4119 || e
->args
[i
]->tok
->type
== tok_string
)
4120 tmp
[i
].override(c_expression(e
->args
[i
]));
4122 c_assign (t
.value(), e
->args
[i
],
4123 "print format actual argument evaluation");
4126 std::vector
<print_format::format_component
> components
;
4128 if (e
->print_with_format
)
4130 components
= e
->components
;
4134 // Synthesize a print-format string if the user didn't
4135 // provide one; the synthetic string simply contains one
4136 // directive for each argument.
4137 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
4139 if (i
> 0 && e
->print_with_delim
)
4140 components
.push_back (e
->delimiter
);
4141 print_format::format_component curr
;
4143 switch (e
->args
[i
]->type
)
4146 throw semantic_error("cannot print unknown expression type", e
->args
[i
]->tok
);
4148 throw semantic_error("cannot print a raw stats object", e
->args
[i
]->tok
);
4150 curr
.type
= print_format::conv_signed_decimal
;
4153 curr
.type
= print_format::conv_string
;
4156 components
.push_back (curr
);
4159 if (e
->print_with_newline
)
4161 print_format::format_component curr
;
4163 curr
.type
= print_format::conv_literal
;
4164 curr
.literal_string
= "\\n";
4165 components
.push_back (curr
);
4169 // Allocate the result
4170 exp_type ty
= e
->print_to_stream
? pe_long
: pe_string
;
4171 tmpvar res
= gensym (ty
);
4174 string format_string
= print_format::components_to_string(components
);
4175 if (tmp
.size() == 0 || (tmp
.size() == 1 && format_string
== "%s"))
4177 else if (tmp
.size() == 1
4178 && e
->args
[0]->tok
->type
== tok_string
4179 && format_string
== "%s\\n")
4182 tmp
[0].override(tmp
[0].value() + "\"\\n\"");
4183 components
[0].type
= print_format::conv_literal
;
4186 // Make the [s]printf call...
4188 // Generate code to check that any pointer arguments are actually accessible. */
4190 for (unsigned i
= 0; i
< components
.size(); ++i
) {
4191 if (components
[i
].type
== print_format::conv_literal
)
4194 /* Take note of the width and precision arguments, if any. */
4195 int width_ix
= -1, prec_ix
= -1;
4196 if (components
[i
].widthtype
== print_format::width_dynamic
)
4197 width_ix
= arg_ix
++;
4198 if (components
[i
].prectype
== print_format::prec_dynamic
)
4201 /* Generate a noop call to deref_buffer for %m. */
4202 if (components
[i
].type
== print_format::conv_memory
4203 || components
[i
].type
== print_format::conv_memory_hex
) {
4204 this->probe_or_function_needs_deref_fault_handler
= true;
4205 o
->newline() << "deref_buffer (0, " << tmp
[arg_ix
].value() << ", ";
4210 o
->line() << tmp
[prec_ix
].value();
4219 if (e
->print_to_stream
)
4223 o
->newline() << "_stp_print_char (";
4225 o
->line() << tmp
[0].value() << ");";
4227 o
->line() << '"' << format_string
<< "\");";
4232 o
->newline() << "_stp_print (";
4234 o
->line() << tmp
[0].value() << ");";
4236 o
->line() << '"' << format_string
<< "\");";
4240 // We'll just hardcode the result of 0 instead of using the
4242 res
.override("((int64_t)0LL)");
4243 o
->newline() << "_stp_printf (";
4246 o
->newline() << "_stp_snprintf (" << res
.value() << ", MAXSTRINGLEN, ";
4248 o
->line() << '"' << format_string
<< '"';
4250 /* Generate the actual arguments. Make sure that they match the expected type of the
4251 format specifier. */
4253 for (unsigned i
= 0; i
< components
.size(); ++i
) {
4254 if (components
[i
].type
== print_format::conv_literal
)
4257 /* Cast the width and precision arguments, if any, to 'int'. */
4258 if (components
[i
].widthtype
== print_format::width_dynamic
)
4259 o
->line() << ", (int)" << tmp
[arg_ix
++].value();
4260 if (components
[i
].prectype
== print_format::prec_dynamic
)
4261 o
->line() << ", (int)" << tmp
[arg_ix
++].value();
4263 /* The type of the %m argument is 'char*'. */
4264 if (components
[i
].type
== print_format::conv_memory
4265 || components
[i
].type
== print_format::conv_memory_hex
)
4266 o
->line() << ", (char*)(uintptr_t)" << tmp
[arg_ix
++].value();
4267 /* The type of the %c argument is 'int'. */
4268 else if (components
[i
].type
== print_format::conv_char
)
4269 o
->line() << ", (int)" << tmp
[arg_ix
++].value();
4270 else if (arg_ix
< (int) tmp
.size())
4271 o
->line() << ", " << tmp
[arg_ix
++].value();
4275 o
->newline() << res
.value() << ";";
4281 c_tmpcounter::visit_stat_op (stat_op
* e
)
4283 symbol
*sym
= get_symbol_within_expression (e
->stat
);
4284 var v
= parent
->getvar(sym
->referent
, e
->tok
);
4285 aggvar agg
= parent
->gensym_aggregate ();
4286 tmpvar res
= parent
->gensym (pe_long
);
4288 agg
.declare(*(this->parent
));
4289 res
.declare(*(this->parent
));
4291 if (sym
->referent
->arity
!= 0)
4293 // One temporary per index dimension.
4294 for (unsigned i
=0; i
<sym
->referent
->index_types
.size(); i
++)
4296 // Sorry about this, but with no dynamic_cast<> and no
4297 // constructor patterns, this is how things work.
4298 arrayindex
*arr
= NULL
;
4299 if (!expression_is_arrayindex (e
->stat
, arr
))
4300 throw semantic_error("expected arrayindex expression in stat_op of array", e
->tok
);
4302 tmpvar ix
= parent
->gensym (sym
->referent
->index_types
[i
]);
4303 ix
.declare (*parent
);
4304 arr
->indexes
[i
]->visit(this);
4310 c_unparser::visit_stat_op (stat_op
* e
)
4312 // Stat ops can be *applied* to two types of expression:
4314 // 1. An arrayindex expression on a pe_stats-valued array.
4316 // 2. A symbol of type pe_stats.
4318 // FIXME: classify the expression the stat_op is being applied to,
4319 // call appropriate stp_get_stat() / stp_pmap_get_stat() helper,
4320 // then reach into resultant struct stat_data.
4322 // FIXME: also note that summarizing anything is expensive, and we
4323 // really ought to pass a timeout handler into the summary routine,
4324 // check its response, possibly exit if it ran out of cycles.
4327 stmt_expr
block(*this);
4328 symbol
*sym
= get_symbol_within_expression (e
->stat
);
4329 aggvar agg
= gensym_aggregate ();
4330 tmpvar res
= gensym (pe_long
);
4331 var v
= getvar(sym
->referent
, e
->tok
);
4333 if (aggregations_active
.count(v
.value()))
4334 load_aggregate(e
->stat
, agg
, true);
4336 load_aggregate(e
->stat
, agg
, false);
4338 // PR 2142+2610: empty aggregates
4339 if (e
->ctype
== sc_count
)
4341 o
->newline() << "if (unlikely (" << agg
.value() << " == NULL))";
4343 c_assign(res
, "0", e
->tok
);
4348 o
->newline() << "if (unlikely (" << agg
.value() << " == NULL)"
4349 << " || " << agg
.value() << "->count == 0) {";
4350 o
->newline(1) << "c->last_error = \"empty aggregate\";";
4351 o
->newline() << "c->last_stmt = " << lex_cast_qstring(*e
->tok
) << ";";
4352 o
->newline() << "goto out;";
4353 o
->newline(-1) << "}";
4355 o
->newline() << "else";
4360 c_assign(res
, ("_stp_div64(NULL, " + agg
.value() + "->sum, "
4361 + agg
.value() + "->count)"),
4365 c_assign(res
, agg
.value() + "->count", e
->tok
);
4368 c_assign(res
, agg
.value() + "->sum", e
->tok
);
4371 c_assign(res
, agg
.value() + "->min", e
->tok
);
4374 c_assign(res
, agg
.value() + "->max", e
->tok
);
4379 o
->newline() << res
<< ";";
4385 c_unparser::visit_hist_op (hist_op
*)
4387 // Hist ops can only occur in a limited set of circumstances:
4389 // 1. Inside an arrayindex expression, as the base referent. See
4390 // c_unparser::visit_arrayindex for handling of this case.
4392 // 2. Inside a foreach statement, as the base referent. See
4393 // c_unparser::visit_foreach_loop for handling this case.
4395 // 3. Inside a print_format expression, as the sole argument. See
4396 // c_unparser::visit_print_format for handling this case.
4398 // Note that none of these cases involves the c_unparser ever
4399 // visiting this node. We should not get here.
4406 struct unwindsym_dump_context
4408 systemtap_session
& session
;
4410 unsigned stp_module_index
;
4411 set
<string
> undone_unwindsym_modules
;
4415 // Get the .debug_frame section for the given module.
4416 // l will be set to the length of the size of the unwind data if found.
4417 static void *get_unwind_data (Dwfl_Module
*m
, size_t *l
)
4419 Dwarf_Addr bias
= 0;
4421 GElf_Ehdr
*ehdr
, ehdr_mem
;
4422 GElf_Shdr
*shdr
, shdr_mem
;
4423 Elf_Scn
*scn
= NULL
;
4424 Elf_Data
*data
= NULL
;
4426 dw
= dwfl_module_getdwarf(m
, &bias
);
4429 Elf
*elf
= dwarf_getelf(dw
);
4430 ehdr
= gelf_getehdr(elf
, &ehdr_mem
);
4431 while ((scn
= elf_nextscn(elf
, scn
)))
4433 shdr
= gelf_getshdr(scn
, &shdr_mem
);
4434 if (strcmp(elf_strptr(elf
, ehdr
->e_shstrndx
, shdr
->sh_name
),
4435 ".debug_frame") == 0)
4437 data
= elf_rawdata(scn
, NULL
);
4453 dump_unwindsyms (Dwfl_Module
*m
,
4454 void **userdata
__attribute__ ((unused
)),
4459 unwindsym_dump_context
* c
= (unwindsym_dump_context
*) arg
;
4461 unsigned stpmod_idx
= c
->stp_module_index
;
4463 string modname
= name
;
4465 if (pending_interrupts
)
4466 return DWARF_CB_ABORT
;
4468 // skip modules/files we're not actually interested in
4469 if (c
->session
.unwindsym_modules
.find(modname
) == c
->session
.unwindsym_modules
.end())
4472 c
->stp_module_index
++;
4474 if (c
->session
.verbose
> 1)
4475 clog
<< "dump_unwindsyms " << name
4476 << " index=" << stpmod_idx
4477 << " base=0x" << hex
<< base
<< dec
<< endl
;
4479 // We want to extract several bits of information:
4481 // - parts of the program-header that map the file's physical offsets to the text section
4482 // - section table: just a list of section (relocation) base addresses
4483 // - symbol table of the text-like sections, with all addresses relativized to each base
4484 // - the contents of .debug_frame section, for unwinding purposes
4486 // In the future, we'll also care about data symbols.
4488 int syments
= dwfl_module_getsymtab(m
);
4489 dwfl_assert ("Getting symbol table for " + modname
, syments
>= 0);
4491 //extract build-id from debuginfo file
4492 int build_id_len
= 0;
4493 unsigned char *build_id_bits
;
4494 GElf_Addr build_id_vaddr
;
4496 if ((build_id_len
=dwfl_module_build_id(m
,
4497 (const unsigned char **)&build_id_bits
,
4498 &build_id_vaddr
)) > 0)
4500 // Enable workaround for elfutils dwfl bug.
4501 // see https://bugzilla.redhat.com/show_bug.cgi?id=465872
4502 // and http://sourceware.org/ml/systemtap/2008-q4/msg00579.html
4503 #ifdef _ELFUTILS_PREREQ
4504 #if _ELFUTILS_PREREQ(0,138)
4505 // Let's standardize to the buggy "end of build-id bits" behavior.
4506 build_id_vaddr
+= build_id_len
;
4508 #if !_ELFUTILS_PREREQ(0,141)
4509 #define NEED_ELFUTILS_BUILDID_WORKAROUND
4512 #define NEED_ELFUTILS_BUILDID_WORKAROUND
4515 // And check for another workaround needed.
4516 // see https://bugzilla.redhat.com/show_bug.cgi?id=489439
4517 // and http://sourceware.org/ml/systemtap/2009-q1/msg00513.html
4518 #ifdef NEED_ELFUTILS_BUILDID_WORKAROUND
4519 if (build_id_vaddr
< base
&& dwfl_module_relocations (m
) == 1)
4521 GElf_Addr main_bias
;
4522 dwfl_module_getelf (m
, &main_bias
);
4523 build_id_vaddr
+= main_bias
;
4526 if (c
->session
.verbose
> 1)
4528 clog
<< "Found build-id in " << name
4529 << ", length " << build_id_len
;
4530 clog
<< ", end at 0x" << hex
<< build_id_vaddr
4535 // Get the canonical path of the main file for comparison at runtime.
4536 // When given directly by the user through -d or in case of the kernel
4537 // name and path might differ. path should be used for matching.
4538 // Use end as sanity check when resolving symbol addresses and to
4539 // calculate size for .dynamic and .absolute sections.
4540 const char *mainfile
;
4541 Dwarf_Addr start
, end
;
4542 dwfl_module_info (m
, NULL
, &start
, &end
, NULL
, NULL
, &mainfile
, NULL
);
4544 // Look up the relocation basis for symbols
4545 int n
= dwfl_module_relocations (m
);
4547 dwfl_assert ("dwfl_module_relocations", n
>= 0);
4550 // XXX: unfortunate duplication with tapsets.cxx:emit_address()
4552 typedef map
<Dwarf_Addr
,const char*> addrmap_t
; // NB: plain map, sorted by address
4553 vector
<pair
<string
,unsigned> > seclist
; // encountered relocation bases
4554 // (section names and sizes)
4555 map
<unsigned, addrmap_t
> addrmap
; // per-relocation-base sorted addrmap
4557 Dwarf_Addr extra_offset
= 0;
4559 for (int i
= 0; i
< syments
; ++i
)
4563 const char *name
= dwfl_module_getsym(m
, i
, &sym
, &shndxp
);
4566 // NB: Yey, we found the kernel's _stext value.
4567 // Sess.sym_stext may be unset (0) at this point, since
4568 // there may have been no kernel probes set. We could
4569 // use tapsets.cxx:lookup_symbol_address(), but then
4570 // we're already iterating over the same data here...
4571 if (modname
== "kernel" && !strcmp(name
, "_stext"))
4574 extra_offset
= sym
.st_value
;
4575 ki
= dwfl_module_relocate_address (m
, &extra_offset
);
4576 dwfl_assert ("dwfl_module_relocate_address extra_offset",
4578 // Sadly dwfl_module_relocate_address is broken on
4579 // elfutils < 0.138, so we need to adjust for the module
4580 // base address outself. (see also below).
4581 extra_offset
= sym
.st_value
- base
;
4582 if (c
->session
.verbose
> 2)
4583 clog
<< "Found kernel _stext extra offset 0x" << hex
<< extra_offset
<< dec
<< endl
;
4586 // We are only interested in "real" symbols.
4587 // We omit symbols that have suspicious addresses (before base,
4589 if ((GELF_ST_TYPE (sym
.st_info
) == STT_FUNC
||
4590 GELF_ST_TYPE (sym
.st_info
) == STT_OBJECT
) // PR10000: also need .data
4591 && !(sym
.st_shndx
== SHN_UNDEF
// Value undefined,
4592 || shndxp
== (GElf_Word
) -1 // in a non-allocated section,
4593 || sym
.st_value
>= end
// beyond current module,
4594 || sym
.st_value
< base
)) // before first section.
4596 Dwarf_Addr sym_addr
= sym
.st_value
;
4597 Dwarf_Addr save_addr
= sym_addr
;
4598 const char *secname
= NULL
;
4600 if (n
> 0) // only try to relocate if there exist relocation bases
4602 int ki
= dwfl_module_relocate_address (m
, &sym_addr
);
4603 dwfl_assert ("dwfl_module_relocate_address", ki
>= 0);
4604 secname
= dwfl_module_relocation_info (m
, ki
, NULL
);
4606 // For ET_DYN files (secname == "") we do ignore the
4607 // dwfl_module_relocate_address adjustment. libdwfl
4608 // up to 0.137 would substract the wrong bias. So we do
4609 // it ourself, it is always just the module base address
4611 if (ki
== 0 && secname
!= NULL
&& secname
[0] == '\0')
4612 sym_addr
= save_addr
- base
;
4615 if (n
== 1 && modname
== "kernel")
4617 // This is a symbol within a (possibly relocatable)
4620 // We only need the function symbols to identify kernel-mode
4621 // PC's, so we omit undefined or "fake" absolute addresses.
4622 // These fake absolute addresses occur in some older i386
4623 // kernels to indicate they are vDSO symbols, not real
4624 // functions in the kernel. We also omit symbols that have
4625 if (GELF_ST_TYPE (sym
.st_info
) == STT_FUNC
4626 && sym
.st_shndx
== SHN_ABS
)
4630 // NB: don't subtract session.sym_stext, which could be inconveniently NULL.
4631 // Instead, sym_addr will get compensated later via extra_offset.
4635 assert (secname
!= NULL
);
4636 // secname adequately set
4638 // NB: it may be an empty string for ET_DYN objects
4639 // like shared libraries, as their relocation base
4641 if (secname
[0] == '\0')
4642 secname
= ".dynamic";
4647 // sym_addr is absolute, as it must be since there are no relocation bases
4648 secname
= ".absolute"; // sentinel
4651 // Compute our section number
4653 for (secidx
=0; secidx
<seclist
.size(); secidx
++)
4654 if (seclist
[secidx
].first
==secname
) break;
4656 if (secidx
== seclist
.size()) // new section name
4658 // absolute, dynamic or kernel have just one relocation
4659 // section, which covers the whole module address range.
4664 && (strcmp(secname
, ".dynamic") == 0
4665 || strcmp(secname
, "_stext") == 0))))
4671 GElf_Shdr
*shdr
, shdr_mem
;
4672 scn
= dwfl_module_address_section (m
, &save_addr
, &b
);
4673 assert (scn
!= NULL
);
4674 shdr
= gelf_getshdr(scn
, &shdr_mem
);
4675 size
= shdr
->sh_size
;
4677 seclist
.push_back (make_pair(secname
,size
));
4680 (addrmap
[secidx
])[sym_addr
] = name
;
4685 // Add unwind data to be included if it exists for this module.
4687 void *unwind
= get_unwind_data (m
, &len
);
4690 c
->output
<< "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
4691 c
->output
<< "static uint8_t _stp_module_" << stpmod_idx
4692 << "_unwind_data[] = \n";
4694 for (size_t i
= 0; i
< len
; i
++)
4696 int h
= ((uint8_t *)unwind
)[i
];
4697 c
->output
<< "0x" << hex
<< h
<< dec
<< ",";
4698 if ((i
+ 1) % 16 == 0)
4699 c
->output
<< "\n" << " ";
4701 c
->output
<< "};\n";
4702 c
->output
<< "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA */\n";
4706 // There would be only a small benefit to warning. A user
4707 // likely can't do anything about this; backtraces for the
4708 // affected module would just get all icky heuristicy.
4709 // So only report in verbose mode.
4710 if (c
->session
.verbose
> 2)
4711 c
->session
.print_warning ("No unwind data for " + modname
4712 + ", " + dwfl_errmsg (-1));
4715 for (unsigned secidx
= 0; secidx
< seclist
.size(); secidx
++)
4717 c
->output
<< "static struct _stp_symbol "
4718 << "_stp_module_" << stpmod_idx
<< "_symbols_" << secidx
<< "[] = {\n";
4720 // Only include symbols if they will be used
4721 c
->output
<< "#ifdef STP_NEED_SYMBOL_DATA\n";
4723 // We write out a *sorted* symbol table, so the runtime doesn't have to sort them later.
4724 for (addrmap_t::iterator it
= addrmap
[secidx
].begin(); it
!= addrmap
[secidx
].end(); it
++)
4726 if (it
->first
< extra_offset
)
4727 continue; // skip symbols that occur before our chosen base address
4729 c
->output
<< " { 0x" << hex
<< it
->first
-extra_offset
<< dec
4730 << ", " << lex_cast_qstring (it
->second
) << " },\n";
4733 c
->output
<< "#endif /* STP_NEED_SYMBOL_DATA */\n";
4735 c
->output
<< "};\n";
4738 c
->output
<< "static struct _stp_section _stp_module_" << stpmod_idx
<< "_sections[] = {\n";
4739 // For the kernel, executables (ET_EXEC) or shared libraries (ET_DYN)
4740 // there is just one section that covers the whole address space of
4741 // the module. For kernel modules (ET_REL) there can be multiple
4742 // sections that get relocated separately.
4743 for (unsigned secidx
= 0; secidx
< seclist
.size(); secidx
++)
4746 << ".name = " << lex_cast_qstring(seclist
[secidx
].first
) << ",\n"
4747 << ".size = 0x" << hex
<< seclist
[secidx
].second
<< dec
<< ",\n"
4748 << ".symbols = _stp_module_" << stpmod_idx
<< "_symbols_" << secidx
<< ",\n"
4749 << ".num_symbols = " << addrmap
[secidx
].size() << "\n"
4752 c
->output
<< "};\n";
4754 c
->output
<< "static struct _stp_module _stp_module_" << stpmod_idx
<< " = {\n";
4755 c
->output
<< ".name = " << lex_cast_qstring (modname
) << ", \n";
4757 mainfile
= canonicalize_file_name(mainfile
);
4758 c
->output
<< ".path = " << lex_cast_qstring (mainfile
) << ",\n";
4760 c
->output
<< ".dwarf_module_base = 0x" << hex
<< base
<< dec
<< ", \n";
4764 c
->output
<< "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
4765 c
->output
<< ".unwind_data = "
4766 << "_stp_module_" << stpmod_idx
<< "_unwind_data, \n";
4767 c
->output
<< ".unwind_data_len = " << len
<< ", \n";
4768 c
->output
<< "#else\n";
4771 c
->output
<< ".unwind_data = NULL,\n";
4772 c
->output
<< ".unwind_data_len = 0,\n";
4775 c
->output
<< "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA*/\n";
4777 c
->output
<< ".unwind_hdr = NULL,\n";
4778 c
->output
<< ".unwind_hdr_len = 0,\n";
4779 c
->output
<< ".unwind_is_ehframe = 0,\n";
4781 c
->output
<< ".sections = _stp_module_" << stpmod_idx
<< "_sections" << ",\n";
4782 c
->output
<< ".num_sections = sizeof(_stp_module_" << stpmod_idx
<< "_sections)/"
4783 << "sizeof(struct _stp_section),\n";
4785 if (build_id_len
> 0) {
4786 c
->output
<< ".build_id_bits = \"" ;
4787 for (int j
=0; j
<build_id_len
;j
++)
4788 c
->output
<< "\\x" << hex
4789 << (unsigned short) *(build_id_bits
+j
) << dec
;
4791 c
->output
<< "\",\n";
4792 c
->output
<< ".build_id_len = " << build_id_len
<< ",\n";
4794 /* XXX: kernel data boot-time relocation works differently from text.
4795 This hack disables relocation altogether, but that's not necessarily
4796 correct either. We may instead need a relocation basis different
4797 from _stext, such as __start_notes. */
4798 if (modname
== "kernel")
4799 c
->output
<< ".build_id_offset = 0x" << hex
<< build_id_vaddr
4802 c
->output
<< ".build_id_offset = 0x" << hex
4803 << build_id_vaddr
- base
4806 c
->output
<< ".build_id_len = 0,\n";
4808 //initialize the note section representing unloaded
4809 c
->output
<< ".notes_sect = 0,\n";
4811 c
->output
<< "};\n\n";
4813 c
->undone_unwindsym_modules
.erase (modname
);
4819 // Emit symbol table & unwind data, plus any calls needed to register
4820 // them with the runtime.
4821 void emit_symbol_data_done (unwindsym_dump_context
*, systemtap_session
&);
4824 emit_symbol_data (systemtap_session
& s
)
4826 string symfile
= "stap-symbols.h";
4828 s
.op
->newline() << "#include " << lex_cast_qstring (symfile
);
4830 ofstream
kallsyms_out ((s
.tmpdir
+ "/" + symfile
).c_str());
4832 unwindsym_dump_context ctx
= { s
, kallsyms_out
, 0, s
.unwindsym_modules
};
4834 // Micro optimization, mainly to speed up tiny regression tests
4835 // using just begin probe.
4836 if (s
.unwindsym_modules
.size () == 0)
4838 emit_symbol_data_done(&ctx
, s
);
4842 // XXX: copied from tapsets.cxx dwflpp::, sadly
4843 static const char *debuginfo_path_arr
= "+:.debug:/usr/lib/debug:build";
4844 static const char *debuginfo_env_arr
= getenv("SYSTEMTAP_DEBUGINFO_PATH");
4845 static const char *debuginfo_path
= (debuginfo_env_arr
?: debuginfo_path_arr
);
4847 // ---- step 1: process any kernel modules listed
4848 static const Dwfl_Callbacks kernel_callbacks
=
4850 dwfl_linux_kernel_find_elf
,
4851 dwfl_standard_find_debuginfo
,
4852 dwfl_offline_section_address
,
4853 (char **) & debuginfo_path
4856 Dwfl
*dwfl
= dwfl_begin (&kernel_callbacks
);
4858 throw semantic_error ("cannot open dwfl");
4859 dwfl_report_begin (dwfl
);
4861 // We have a problem with -r REVISION vs -r BUILDDIR here. If
4862 // we're running against a fedora/rhel style kernel-debuginfo
4863 // tree, s.kernel_build_tree is not the place where the unstripped
4864 // vmlinux will be installed. Rather, it's over yonder at
4865 // /usr/lib/debug/lib/modules/$REVISION/. It seems that there is
4866 // no way to set the dwfl_callback.debuginfo_path and always
4867 // passs the plain kernel_release here. So instead we have to
4868 // hard-code this magic here.
4869 string elfutils_kernel_path
;
4870 if (s
.kernel_build_tree
== string("/lib/modules/" + s
.kernel_release
+ "/build"))
4871 elfutils_kernel_path
= s
.kernel_release
;
4873 elfutils_kernel_path
= s
.kernel_build_tree
;
4875 int rc
= dwfl_linux_kernel_report_offline (dwfl
,
4876 elfutils_kernel_path
.c_str(),
4877 NULL
/* XXX: filtering callback */);
4878 dwfl_report_end (dwfl
, NULL
, NULL
);
4879 if (rc
== 0) // tolerate missing data; will warn user about it anyway
4884 if (pending_interrupts
) return;
4885 if (ctx
.undone_unwindsym_modules
.empty()) break;
4886 off
= dwfl_getmodules (dwfl
, &dump_unwindsyms
, (void *) &ctx
, 0);
4889 dwfl_assert("dwfl_getmodules", off
== 0);
4894 // ---- step 2: process any user modules (files) listed
4895 // XXX: see dwflpp::setup_user.
4896 static const Dwfl_Callbacks user_callbacks
=
4898 NULL
, /* dwfl_linux_kernel_find_elf, */
4899 dwfl_standard_find_debuginfo
,
4900 NULL
, /* ET_REL not supported for user space, only ET_EXEC and ET_DYN.
4901 dwfl_offline_section_address, */
4902 (char **) & debuginfo_path
4905 for (std::set
<std::string
>::iterator it
= s
.unwindsym_modules
.begin();
4906 it
!= s
.unwindsym_modules
.end();
4909 string modname
= *it
;
4910 assert (modname
.length() != 0);
4911 if (modname
[0] != '/') continue; // user-space files must be full paths
4912 Dwfl
*dwfl
= dwfl_begin (&user_callbacks
);
4914 throw semantic_error ("cannot create dwfl for " + modname
);
4916 dwfl_report_begin (dwfl
);
4917 Dwfl_Module
* mod
= dwfl_report_offline (dwfl
, modname
.c_str(), modname
.c_str(), -1);
4918 dwfl_report_end (dwfl
, NULL
, NULL
);
4919 if (mod
!= 0) // tolerate missing data; will warn below
4924 if (pending_interrupts
) return;
4925 if (ctx
.undone_unwindsym_modules
.empty()) break;
4926 off
= dwfl_getmodules (dwfl
, &dump_unwindsyms
, (void *) &ctx
, 0);
4929 dwfl_assert("dwfl_getmodules", off
== 0);
4934 emit_symbol_data_done (&ctx
, s
);
4938 emit_symbol_data_done (unwindsym_dump_context
*ctx
, systemtap_session
& s
)
4940 // Print out a definition of the runtime's _stp_modules[] globals.
4941 ctx
->output
<< "\n";
4942 ctx
->output
<< "static struct _stp_module *_stp_modules [] = {\n";
4943 for (unsigned i
=0; i
<ctx
->stp_module_index
; i
++)
4945 ctx
->output
<< "& _stp_module_" << i
<< ",\n";
4947 ctx
->output
<< "};\n";
4948 ctx
->output
<< "static unsigned _stp_num_modules = " << ctx
->stp_module_index
<< ";\n";
4950 // Some nonexistent modules may have been identified with "-d". Note them.
4951 for (set
<string
>::iterator it
= ctx
->undone_unwindsym_modules
.begin();
4952 it
!= ctx
->undone_unwindsym_modules
.end();
4955 s
.print_warning ("missing unwind/symbol data for module '" + (*it
) + "'");
4961 translate_pass (systemtap_session
& s
)
4965 s
.op
= new translator_output (s
.translated_source
);
4966 c_unparser
cup (& s
);
4971 // This is at the very top of the file.
4973 s
.op
->newline() << "#ifndef MAXNESTING";
4974 s
.op
->newline() << "#define MAXNESTING 10";
4975 s
.op
->newline() << "#endif";
4976 s
.op
->newline() << "#ifndef MAXSTRINGLEN";
4977 s
.op
->newline() << "#define MAXSTRINGLEN 128";
4978 s
.op
->newline() << "#endif";
4979 s
.op
->newline() << "#ifndef MAXACTION";
4980 s
.op
->newline() << "#define MAXACTION 1000";
4981 s
.op
->newline() << "#endif";
4982 s
.op
->newline() << "#ifndef MAXACTION_INTERRUPTIBLE";
4983 s
.op
->newline() << "#define MAXACTION_INTERRUPTIBLE (MAXACTION * 10)";
4984 s
.op
->newline() << "#endif";
4985 s
.op
->newline() << "#ifndef MAXTRYLOCK";
4986 s
.op
->newline() << "#define MAXTRYLOCK MAXACTION";
4987 s
.op
->newline() << "#endif";
4988 s
.op
->newline() << "#ifndef TRYLOCKDELAY";
4989 s
.op
->newline() << "#define TRYLOCKDELAY 100";
4990 s
.op
->newline() << "#endif";
4991 s
.op
->newline() << "#ifndef MAXMAPENTRIES";
4992 s
.op
->newline() << "#define MAXMAPENTRIES 2048";
4993 s
.op
->newline() << "#endif";
4994 s
.op
->newline() << "#ifndef MAXERRORS";
4995 s
.op
->newline() << "#define MAXERRORS 0";
4996 s
.op
->newline() << "#endif";
4997 s
.op
->newline() << "#ifndef MAXSKIPPED";
4998 s
.op
->newline() << "#define MAXSKIPPED 100";
4999 s
.op
->newline() << "#endif";
5000 s
.op
->newline() << "#ifndef MINSTACKSPACE";
5001 s
.op
->newline() << "#define MINSTACKSPACE 1024";
5002 s
.op
->newline() << "#endif";
5003 s
.op
->newline() << "#ifndef INTERRUPTIBLE";
5004 s
.op
->newline() << "#define INTERRUPTIBLE 1";
5005 s
.op
->newline() << "#endif";
5007 // Overload processing
5008 s
.op
->newline() << "#ifndef STP_OVERLOAD_INTERVAL";
5009 s
.op
->newline() << "#define STP_OVERLOAD_INTERVAL 1000000000LL";
5010 s
.op
->newline() << "#endif";
5011 s
.op
->newline() << "#ifndef STP_OVERLOAD_THRESHOLD";
5012 s
.op
->newline() << "#define STP_OVERLOAD_THRESHOLD 500000000LL";
5013 s
.op
->newline() << "#endif";
5014 // We allow the user to completely turn overload processing off
5015 // (as opposed to tuning it by overriding the values above) by
5016 // running: stap -DSTP_NO_OVERLOAD {other options}
5017 s
.op
->newline() << "#ifndef STP_NO_OVERLOAD";
5018 s
.op
->newline() << "#define STP_OVERLOAD";
5019 s
.op
->newline() << "#endif";
5021 s
.op
->newline() << "#define STP_SKIP_BADVARS " << (s
.skip_badvars
? 1 : 0);
5024 s
.op
->newline() << "#define STP_BULKMODE";
5027 s
.op
->newline() << "#define STP_TIMING";
5030 s
.op
->newline() << "#define STP_PERFMON";
5032 s
.op
->newline() << "#include \"runtime.h\"";
5033 s
.op
->newline() << "#include \"stack.c\"";
5034 s
.op
->newline() << "#include \"stat.c\"";
5035 s
.op
->newline() << "#include <linux/string.h>";
5036 s
.op
->newline() << "#include <linux/timer.h>";
5037 s
.op
->newline() << "#include <linux/sched.h>";
5038 s
.op
->newline() << "#include <linux/delay.h>";
5039 s
.op
->newline() << "#include <linux/profile.h>";
5040 s
.op
->newline() << "#include <linux/random.h>";
5041 // s.op->newline() << "#include <linux/utsrelease.h>"; // newer kernels only
5042 s
.op
->newline() << "#include <linux/vermagic.h>";
5043 s
.op
->newline() << "#include <linux/utsname.h>";
5044 s
.op
->newline() << "#include <linux/version.h>";
5045 // s.op->newline() << "#include <linux/compile.h>";
5046 s
.op
->newline() << "#include \"loc2c-runtime.h\" ";
5048 // XXX: old 2.6 kernel hack
5049 s
.op
->newline() << "#ifndef read_trylock";
5050 s
.op
->newline() << "#define read_trylock(x) ({ read_lock(x); 1; })";
5051 s
.op
->newline() << "#endif";
5053 s
.up
->emit_common_header (); // context etc.
5055 for (unsigned i
=0; i
<s
.embeds
.size(); i
++)
5057 s
.op
->newline() << s
.embeds
[i
]->code
<< "\n";
5060 if (s
.globals
.size()>0) {
5061 s
.op
->newline() << "static struct {";
5063 for (unsigned i
=0; i
<s
.globals
.size(); i
++)
5065 s
.up
->emit_global (s
.globals
[i
]);
5067 s
.op
->newline(-1) << "} global = {";
5069 for (unsigned i
=0; i
<s
.globals
.size(); i
++)
5071 if (pending_interrupts
) return 1;
5072 s
.up
->emit_global_init (s
.globals
[i
]);
5074 s
.op
->newline(-1) << "};";
5075 s
.op
->assert_0_indent();
5078 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
5080 if (pending_interrupts
) return 1;
5082 s
.up
->emit_functionsig (it
->second
);
5084 s
.op
->assert_0_indent();
5086 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
5088 if (pending_interrupts
) return 1;
5090 s
.up
->emit_function (it
->second
);
5092 s
.op
->assert_0_indent();
5094 // Run a varuse_collecting_visitor over probes that need global
5095 // variable locks. We'll use this information later in
5096 // emit_locks()/emit_unlocks().
5097 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
5099 if (pending_interrupts
) return 1;
5100 if (s
.probes
[i
]->needs_global_locks())
5101 s
.probes
[i
]->body
->visit (&cup
.vcv_needs_global_locks
);
5103 s
.op
->assert_0_indent();
5105 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
5107 if (pending_interrupts
) return 1;
5108 s
.up
->emit_probe (s
.probes
[i
]);
5110 s
.op
->assert_0_indent();
5113 s
.up
->emit_module_init ();
5114 s
.op
->assert_0_indent();
5116 s
.up
->emit_module_exit ();
5117 s
.op
->assert_0_indent();
5120 // XXX impedance mismatch
5121 s
.op
->newline() << "static int probe_start (void) {";
5122 s
.op
->newline(1) << "return systemtap_module_init () ? -1 : 0;";
5123 s
.op
->newline(-1) << "}";
5125 s
.op
->newline() << "static void probe_exit (void) {";
5126 s
.op
->newline(1) << "systemtap_module_exit ();";
5127 s
.op
->newline(-1) << "}";
5128 s
.op
->assert_0_indent();
5130 for (unsigned i
=0; i
<s
.globals
.size(); i
++)
5133 s
.up
->emit_global_param (s
.globals
[i
]);
5135 s
.op
->assert_0_indent();
5137 emit_symbol_data (s
);
5139 s
.op
->newline() << "MODULE_DESCRIPTION(\"systemtap-generated probe\");";
5140 s
.op
->newline() << "MODULE_LICENSE(\"GPL\");";
5141 s
.op
->assert_0_indent();
5143 catch (const semantic_error
& e
)
5148 s
.op
->line() << "\n";
5154 return rc
+ s
.num_errors();
5157 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */