]> sourceware.org Git - systemtap.git/blame - translate.cxx
Fix rawhide compile problems in aux_syscalls.stp.
[systemtap.git] / translate.cxx
CommitLineData
f3c26ea5 1// translation pass
27cc9ab5 2// Copyright (C) 2005-2014 Red Hat Inc.
12363146 3// Copyright (C) 2005-2008 Intel Corporation.
77123275 4// Copyright (C) 2010 Novell Corporation.
69c68955
FCE
5//
6// This file is part of systemtap, and is free software. You can
7// redistribute it and/or modify it under the terms of the GNU General
8// Public License (GPL); either version 2, or (at your option) any
9// later version.
2b066ec1
FCE
10
11#include "config.h"
12#include "staptree.h"
13#include "elaborate.h"
14#include "translate.h"
dc38c0ae 15#include "session.h"
b20febf3 16#include "tapsets.h"
72dbc915 17#include "util.h"
f5973d67 18#include "dwarf_wrappers.h"
3db9c843 19#include "setupdwfl.h"
18da5887 20#include "task_finder.h"
ea15e536 21#include "runtime/k_syms.h"
6bbcd339 22#include "dwflpp.h"
60cf5fae 23#include "stapregex.h"
a3e980f9 24#include "stringtable.h"
d2548fe7 25
3b579393 26#include <cstdlib>
2b066ec1 27#include <iostream>
f8220a7b 28#include <set>
ce10591c 29#include <sstream>
f8220a7b 30#include <string>
29e64872 31#include <cassert>
1b94bf6d 32#include <cstring>
ef06c938 33#include <cerrno>
2b066ec1 34
c4a94c1a 35extern "C" {
9424498b 36#include <dwarf.h>
c4a94c1a 37#include <elfutils/libdwfl.h>
9424498b 38#include <elfutils/libdw.h>
18da5887 39#include <ftw.h>
1e41115c
LB
40#define __STDC_FORMAT_MACROS
41#include <inttypes.h>
c4a94c1a
FCE
42}
43
c42e2d2e
MW
44// Max unwind table size (debug or eh) per module. Somewhat arbitrary
45// limit (a bit more than twice the .debug_frame size of my local
17c0b69c
FCE
46// vmlinux for 2.6.31.4-83.fc12.x86_64).
47// A larger value was recently found in a libxul.so build.
86058b0f
JS
48// ... and yet again in libxul.so, PR15162
49#define MAX_UNWIND_TABLE_SIZE (16 * 1024 * 1024)
c42e2d2e 50
b5f561be
LB
51#define STAP_T_01 _("\"Array overflow, check ")
52#define STAP_T_02 _("\"MAXNESTING exceeded\";")
53#define STAP_T_03 _("\"division by 0\";")
54#define STAP_T_04 _("\"MAXACTION exceeded\";")
55#define STAP_T_05 _("\"aggregation overflow in ")
56#define STAP_T_06 _("\"empty aggregate\";")
57#define STAP_T_07 _("\"histogram index out of range\";")
a3e980f9 58
2b066ec1
FCE
59using namespace std;
60
b9aa5bb4 61class var;
313b2f74 62struct tmpvar;
07c17d67 63struct aggvar;
313b2f74 64struct mapvar;
b9aa5bb4 65class itervar;
ce10591c 66
d6d4dc4b
JS
67// A null-sink output stream, similar to /dev/null
68// (no buffer -> badbit -> quietly suppressed output)
69static ostream nullstream(NULL);
70static translator_output null_o(nullstream);
71
4383d78c 72struct c_unparser: public unparser, public visitor
2b066ec1
FCE
73{
74 systemtap_session* session;
75 translator_output* o;
76
77 derived_probe* current_probe;
2b066ec1 78 functiondecl* current_function;
296c059b
JS
79
80 const functioncall* assigned_functioncall;
81 const string* assigned_functioncall_retval;
82
4383d78c 83 unsigned tmpvar_counter;
f3c26ea5 84 unsigned label_counter;
9d0808b4 85 unsigned action_counter;
ad534e14 86 bool already_checked_action_count;
2b066ec1 87
3be43eac
DS
88 varuse_collecting_visitor vcv_needs_global_locks;
89
1341a03c 90 map<string, probe*> probe_contents;
88bbd60d 91
5b1fa53b
JS
92 map<pair<bool, string>, string> compiled_printfs;
93
d6d4dc4b
JS
94 c_unparser (systemtap_session* ss, translator_output* op=NULL):
95 session (ss), o (op ?: ss->op), current_probe(0), current_function (0),
296c059b 96 assigned_functioncall (0), assigned_functioncall_retval (0),
74fe61bc 97 tmpvar_counter (0), label_counter (0), action_counter(0),
ad534e14 98 already_checked_action_count(false), vcv_needs_global_locks (*ss) {}
4383d78c 99 ~c_unparser () {}
2b066ec1 100
d6d4dc4b
JS
101 // The main c_unparser doesn't write declarations as it traverses,
102 // but the c_tmpcounter subclass will.
103 virtual void var_declare(string const&, var const&) {}
104
105 // If we've seen a dupe, return it; else remember this and return NULL.
106 probe *get_probe_dupe (derived_probe *dp);
107
313b2f74 108 void emit_map_type_instantiations ();
2b066ec1
FCE
109 void emit_common_header ();
110 void emit_global (vardecl* v);
4a6d3dfa 111 void emit_global_init (vardecl* v);
bd268288 112 void emit_global_init_type (vardecl *v);
16c1c808 113 void emit_global_param (vardecl* v);
bd268288 114 void emit_global_init_setters ();
2b066ec1 115 void emit_functionsig (functiondecl* v);
be66b6e1
DS
116 void emit_kernel_module_init ();
117 void emit_kernel_module_exit ();
2b066ec1 118 void emit_module_init ();
a60923e9 119 void emit_module_refresh ();
2b066ec1
FCE
120 void emit_module_exit ();
121 void emit_function (functiondecl* v);
29bb0bbc 122 void emit_lock_decls (const varuse_collecting_visitor& v);
3f3f4dd0 123 void emit_locks ();
c1d5f3f6 124 void emit_probe (derived_probe* v);
05a072cf 125 void emit_probe_condition_update(derived_probe* v);
3f3f4dd0 126 void emit_unlocks ();
2b066ec1 127
5b1fa53b
JS
128 void emit_compiled_printfs ();
129 void emit_compiled_printf_locals ();
130 void declare_compiled_printf (bool print_to_stream, const string& format);
d6d4dc4b
JS
131 virtual const string& get_compiled_printf (bool print_to_stream,
132 const string& format);
5b1fa53b 133
13a9593f
FCE
134 // for use by stats (pmap) foreach
135 set<string> aggregations_active;
136
bdc82277
JS
137 // values immediately available in foreach_loop iterations
138 map<string, string> foreach_loop_values;
d6d4dc4b 139 void visit_foreach_loop_value (foreach_loop* s, const string& value="");
bdc82277
JS
140 bool get_foreach_loop_value (arrayindex* ai, string& value);
141
f3c26ea5
FCE
142 // for use by looping constructs
143 vector<string> loop_break_labels;
144 vector<string> loop_continue_labels;
2b066ec1
FCE
145
146 string c_typename (exp_type e);
49b68a33 147 virtual string c_localname (const string& e, bool mangle_oldstyle = false);
0386bbcf
SM
148 virtual string c_globalname (const string &e);
149 virtual string c_funcname (const string &e);
313b2f74 150
0386bbcf
SM
151 string c_arg_define (const string& e);
152 string c_arg_undef (const string& e);
153
0af18f5a
FL
154 string map_keytypes(vardecl* v);
155 void c_global_write_def(vardecl* v);
156 void c_global_read_def(vardecl* v);
157 void c_global_write_undef(vardecl* v);
158 void c_global_read_undef(vardecl* v);
159
54dfabe9 160 void c_assign (var& lvalue, const string& rvalue, const token* tok);
b2d74f03
JS
161 void c_assign (tmpvar& lvalue, expression* rvalue, const char* msg);
162 void c_assign (const string& lvalue, expression* rvalue, const char* msg);
ce10591c 163 void c_assign (const string& lvalue, const string& rvalue, exp_type type,
b2d74f03 164 const char* msg, const token* tok);
2b066ec1 165
0386bbcf
SM
166 void c_declare(exp_type ty, const string &ident);
167 void c_declare_static(exp_type ty, const string &ident);
313b2f74
GH
168
169 void c_strcat (const string& lvalue, const string& rvalue);
170 void c_strcat (const string& lvalue, expression* rvalue);
171
172 void c_strcpy (const string& lvalue, const string& rvalue);
173 void c_strcpy (const string& lvalue, expression* rvalue);
174
54dfabe9 175 bool is_local (vardecl const* r, token const* tok);
313b2f74
GH
176
177 tmpvar gensym(exp_type ty);
07c17d67
GH
178 aggvar gensym_aggregate();
179
54dfabe9 180 var getvar(vardecl* v, token const* tok = NULL);
d02548c0 181 itervar getiter(symbol* s);
54dfabe9 182 mapvar getmap(vardecl* v, token const* tok = NULL);
313b2f74 183
54dfabe9 184 void load_map_indices(arrayindex* e,
313b2f74
GH
185 vector<tmpvar> & idx);
186
c4782e01 187 var* load_aggregate (expression *e, aggvar & agg);
1bbeef03 188 string histogram_index_check(var & vase, tmpvar & idx) const;
a4636912 189
54dfabe9 190 void collect_map_index_types(vector<vardecl* > const & vars,
d23a2349 191 set< pair<vector<exp_type>, exp_type> > & types);
313b2f74 192
54975cd8 193 void record_actions (unsigned actions, const token* tok, bool update=false);
5e309481 194
54dfabe9 195 void visit_block (block* s);
f4fe2e93 196 void visit_try_block (try_block* s);
54dfabe9
FCE
197 void visit_embeddedcode (embeddedcode* s);
198 void visit_null_statement (null_statement* s);
199 void visit_expr_statement (expr_statement* s);
2b066ec1
FCE
200 void visit_if_statement (if_statement* s);
201 void visit_for_loop (for_loop* s);
69c68955 202 void visit_foreach_loop (foreach_loop* s);
2b066ec1
FCE
203 void visit_return_statement (return_statement* s);
204 void visit_delete_statement (delete_statement* s);
f3c26ea5
FCE
205 void visit_next_statement (next_statement* s);
206 void visit_break_statement (break_statement* s);
207 void visit_continue_statement (continue_statement* s);
2b066ec1
FCE
208 void visit_literal_string (literal_string* e);
209 void visit_literal_number (literal_number* e);
7d902887 210 void visit_embedded_expr (embedded_expr* e);
2b066ec1
FCE
211 void visit_binary_expression (binary_expression* e);
212 void visit_unary_expression (unary_expression* e);
213 void visit_pre_crement (pre_crement* e);
214 void visit_post_crement (post_crement* e);
215 void visit_logical_or_expr (logical_or_expr* e);
216 void visit_logical_and_expr (logical_and_expr* e);
217 void visit_array_in (array_in* e);
93daaca8 218 void visit_regex_query (regex_query* e);
2b066ec1
FCE
219 void visit_comparison (comparison* e);
220 void visit_concatenation (concatenation* e);
2b066ec1
FCE
221 void visit_ternary_expression (ternary_expression* e);
222 void visit_assignment (assignment* e);
223 void visit_symbol (symbol* e);
d7f3e0c5 224 void visit_target_symbol (target_symbol* e);
2b066ec1
FCE
225 void visit_arrayindex (arrayindex* e);
226 void visit_functioncall (functioncall* e);
d02548c0
GH
227 void visit_print_format (print_format* e);
228 void visit_stat_op (stat_op* e);
229 void visit_hist_op (hist_op* e);
9b5af295 230 void visit_cast_op (cast_op* e);
251707c8 231 void visit_autocast_op (autocast_op* e);
bd1fcbad 232 void visit_atvar_op (atvar_op* e);
30263a73 233 void visit_defined_op (defined_op* e);
8cc799a5 234 void visit_entry_op (entry_op* e);
3689db05 235 void visit_perf_op (perf_op* e);
7d1e27af
JS
236
237 // start/close statements with multiple independent child visits
238 virtual void start_compound_statement (const char*, statement*) { }
239 virtual void close_compound_statement (const char*, statement*) { }
240
241 // wrap one child visit of a compound statement
242 virtual void wrap_compound_visit (expression *e) { if (e) e->visit (this); }
243 virtual void wrap_compound_visit (statement *s) { if (s) s->visit (this); }
2b066ec1
FCE
244};
245
313b2f74 246// A shadow visitor, meant to generate temporary variable declarations
d6d4dc4b
JS
247// for function or probe bodies. The output is discarded, but we now do
248// real work in var_declare().
29d86764 249struct c_tmpcounter cxx_final: public c_unparser
313b2f74
GH
250{
251 c_unparser* parent;
d6d4dc4b
JS
252 set<string> declared_vars;
253
dff50e09 254 c_tmpcounter (c_unparser* p):
d6d4dc4b
JS
255 c_unparser(p->session, &null_o), parent (p)
256 { }
313b2f74 257
d6d4dc4b
JS
258 // When vars are created *and used* (i.e. not overridden tmpvars) they call
259 // var_declare(), which will forward to the parent c_unparser for output;
260 void var_declare(string const&, var const& v) cxx_override;
11b52b73 261
d6d4dc4b
JS
262 void emit_function (functiondecl* fd);
263 void emit_probe (derived_probe* dp);
264
265 const string& get_compiled_printf (bool print_to_stream,
266 const string& format) cxx_override;
11b52b73 267
7d1e27af
JS
268 void start_compound_statement (const char*, statement*) cxx_override;
269 void close_compound_statement (const char*, statement*) cxx_override;
395146b5 270
7d1e27af
JS
271 void wrap_compound_visit (expression *e) cxx_override;
272 void wrap_compound_visit (statement *s) cxx_override;
395146b5 273
395146b5
AJ
274 void start_struct_def (std::ostream::pos_type &before,
275 std::ostream::pos_type &after, const token* tok);
276 void close_struct_def (std::ostream::pos_type before,
277 std::ostream::pos_type after);
313b2f74
GH
278};
279
dff50e09 280struct c_unparser_assignment:
313b2f74
GH
281 public throwing_visitor
282{
283 c_unparser* parent;
47d349b1 284 interned_string op;
313b2f74 285 expression* rvalue;
78110925 286 bool post; // true == value saved before modify operator
47d349b1 287 c_unparser_assignment (c_unparser* p, interned_string o, expression* e):
313b2f74 288 throwing_visitor ("invalid lvalue type"),
78110925 289 parent (p), op (o), rvalue (e), post (false) {}
47d349b1 290 c_unparser_assignment (c_unparser* p, interned_string o, bool pp):
313b2f74 291 throwing_visitor ("invalid lvalue type"),
78110925 292 parent (p), op (o), rvalue (0), post (pp) {}
313b2f74 293
47d349b1 294 void prepare_rvalue (interned_string op,
11b52b73 295 tmpvar & rval,
54dfabe9 296 token const* tok);
313b2f74 297
dff50e09
FCE
298 void c_assignop(tmpvar & res,
299 var const & lvar,
313b2f74 300 tmpvar const & tmp,
54dfabe9 301 token const* tok);
313b2f74
GH
302
303 // only symbols and arrayindex nodes are possible lvalues
54dfabe9
FCE
304 void visit_symbol (symbol* e);
305 void visit_arrayindex (arrayindex* e);
313b2f74
GH
306};
307
308
313b2f74
GH
309ostream & operator<<(ostream & o, var const & v);
310
07c17d67
GH
311
312/*
313 Some clarification on the runtime structures involved in statistics:
dff50e09 314
07c17d67
GH
315 The basic type for collecting statistics in the runtime is struct
316 stat_data. This contains the count, min, max, sum, and possibly
317 histogram fields.
dff50e09 318
07c17d67 319 There are two places struct stat_data shows up.
dff50e09 320
07c17d67
GH
321 1. If you declare a statistic variable of any sort, you want to make
322 a struct _Stat. A struct _Stat* is also called a Stat. Struct _Stat
323 contains a per-CPU array of struct stat_data values, as well as a
324 struct stat_data which it aggregates into. Writes into a Struct
325 _Stat go into the per-CPU struct stat. Reads involve write-locking
326 the struct _Stat, aggregating into its aggregate struct stat_data,
327 unlocking, read-locking the struct _Stat, then reading values out of
328 the aggregate and unlocking.
329
330 2. If you declare a statistic-valued map, you want to make a
331 pmap. This is a per-CPU array of maps, each of which holds struct
332 stat_data values, as well as an aggregate *map*. Writes into a pmap
333 go into the per-CPU map. Reads involve write-locking the pmap,
334 aggregating into its aggregate map, unlocking, read-locking the
335 pmap, then reading values out of its aggregate (which is a normal
336 map) and unlocking.
337
338 Because, at the moment, the runtime does not support the concept of
339 a statistic which collects multiple histogram types, we may need to
340 instantiate one pmap or struct _Stat for each histogram variation
dff50e09 341 the user wants to track.
07c17d67
GH
342 */
343
313b2f74
GH
344class var
345{
07c17d67
GH
346
347protected:
0386bbcf
SM
348 // Required for accurate mangling:
349 c_unparser *u;
350
313b2f74
GH
351 bool local;
352 exp_type ty;
57b73400 353 statistic_decl sd;
313b2f74 354 string name;
0386bbcf 355 bool do_mangle;
313b2f74 356
d6d4dc4b
JS
357private:
358 mutable bool declaration_needed;
359
313b2f74
GH
360public:
361
0386bbcf
SM
362 var(c_unparser *u, bool local, exp_type ty,
363 statistic_decl const & sd, string const & name)
d6d4dc4b
JS
364 : u(u), local(local), ty(ty), sd(sd), name(name),
365 do_mangle(true), declaration_needed(false)
57b73400
GH
366 {}
367
0386bbcf 368 var(c_unparser *u, bool local, exp_type ty, string const & name)
d6d4dc4b
JS
369 : u(u), local(local), ty(ty), name(name),
370 do_mangle(true), declaration_needed(false)
0386bbcf
SM
371 {}
372
373 var(c_unparser *u, bool local, exp_type ty,
374 string const & name, bool do_mangle)
d6d4dc4b
JS
375 : u(u), local(local), ty(ty), name(name),
376 do_mangle(do_mangle), declaration_needed(false)
377 {}
378
379 var(c_unparser *u, bool local, exp_type ty, unsigned & counter)
380 : u(u), local(local), ty(ty), name("__tmp" + lex_cast(counter++)),
381 do_mangle(false), declaration_needed(true)
313b2f74
GH
382 {}
383
1820694f
JS
384 virtual ~var() {}
385
313b2f74
GH
386 bool is_local() const
387 {
388 return local;
389 }
390
57b73400
GH
391 statistic_decl const & sdecl() const
392 {
393 return sd;
394 }
395
a4636912
GH
396 void assert_hist_compatible(hist_op const & hop)
397 {
398 // Semantic checks in elaborate should have caught this if it was
399 // false. This is just a double-check.
400 switch (sd.type)
401 {
402 case statistic_decl::linear:
403 assert(hop.htype == hist_linear);
404 assert(hop.params.size() == 3);
405 assert(hop.params[0] == sd.linear_low);
406 assert(hop.params[1] == sd.linear_high);
407 assert(hop.params[2] == sd.linear_step);
408 break;
409 case statistic_decl::logarithmic:
410 assert(hop.htype == hist_log);
e38723d2 411 assert(hop.params.size() == 0);
a4636912
GH
412 break;
413 case statistic_decl::none:
414 assert(false);
415 }
416 }
417
313b2f74
GH
418 exp_type type() const
419 {
420 return ty;
421 }
422
0386bbcf
SM
423 string c_name() const
424 {
425 if (!do_mangle)
426 return name;
427 else if (local)
428 return u->c_localname(name);
429 else
430 return u->c_globalname(name);
431 }
432
11b52b73 433 string value() const
313b2f74 434 {
d6d4dc4b
JS
435 if (declaration_needed)
436 {
437 u->var_declare (name, *this);
438 declaration_needed = false;
439 }
440
313b2f74 441 if (local)
0386bbcf 442 return "l->" + c_name();
313b2f74 443 else
63438a79 444 return "global(" + c_name() + ")";
313b2f74
GH
445 }
446
1820694f 447 virtual string hist() const
a4636912
GH
448 {
449 assert (ty == pe_stats);
1bbeef03 450 assert (sd.type != statistic_decl::none);
11b52b73 451 return "(&(" + value() + "->hist))";
1bbeef03
GH
452 }
453
1820694f 454 virtual string buckets() const
1bbeef03
GH
455 {
456 assert (ty == pe_stats);
457 assert (sd.type != statistic_decl::none);
11b52b73 458 return "(" + value() + "->hist.buckets)";
a4636912
GH
459 }
460
67c0a579 461 string init() const
313b2f74
GH
462 {
463 switch (type())
464 {
465 case pe_string:
16c1c808
FCE
466 if (! local)
467 return ""; // module_param
468 else
63438a79 469 return value() + "[0] = '\\0';";
313b2f74 470 case pe_long:
213bee8f 471 if (! local)
9ba8c134 472 return ""; // module_param
213bee8f 473 else
11b52b73 474 return value() + " = 0;";
57b73400 475 case pe_stats:
133467ef
FCE
476 {
477 // See also mapvar::init().
dff50e09 478
63438a79 479 if (local)
dc09353a 480 throw SEMANTIC_ERROR(_F("unsupported local stats init for %s", value().c_str()));
63438a79
JS
481
482 string prefix = "global_set(" + c_name() + ", _stp_stat_init (";
133467ef 483 // Check for errors during allocation.
11b52b73 484 string suffix = "if (" + value () + " == NULL) rc = -ENOMEM;";
dff50e09 485
133467ef
FCE
486 switch (sd.type)
487 {
488 case statistic_decl::none:
489 prefix += "HIST_NONE";
490 break;
dff50e09 491
133467ef
FCE
492 case statistic_decl::linear:
493 prefix += string("HIST_LINEAR")
aca66a36
JS
494 + ", " + lex_cast(sd.linear_low)
495 + ", " + lex_cast(sd.linear_high)
496 + ", " + lex_cast(sd.linear_step);
133467ef 497 break;
dff50e09 498
133467ef 499 case statistic_decl::logarithmic:
e38723d2 500 prefix += string("HIST_LOG");
133467ef 501 break;
dff50e09 502
133467ef 503 default:
dc09353a 504 throw SEMANTIC_ERROR(_F("unsupported stats type for %s", value().c_str()));
133467ef 505 }
dff50e09 506
63438a79 507 prefix = prefix + ")); ";
133467ef
FCE
508 return string (prefix + suffix);
509 }
dff50e09 510
313b2f74 511 default:
dc09353a 512 throw SEMANTIC_ERROR(_F("unsupported initializer for %s", value().c_str()));
313b2f74
GH
513 }
514 }
515
85278e66
DB
516 string fini () const
517 {
518 switch (type())
519 {
520 case pe_string:
521 case pe_long:
522 return ""; // no action required
523 case pe_stats:
524 return "_stp_stat_del (" + value () + ");";
525 default:
dc09353a 526 throw SEMANTIC_ERROR(_F("unsupported deallocator for %s", value().c_str()));
85278e66
DB
527 }
528 }
529
d6d4dc4b 530 virtual void declare(c_unparser &c) const
313b2f74 531 {
0386bbcf 532 c.c_declare(ty, c_name());
313b2f74
GH
533 }
534};
535
536ostream & operator<<(ostream & o, var const & v)
537{
11b52b73 538 return o << v.value();
313b2f74
GH
539}
540
d6d4dc4b
JS
541void
542c_tmpcounter::var_declare (string const& name, var const& v)
543{
544 if (declared_vars.insert(name).second)
545 v.declare (*parent);
546}
547
313b2f74
GH
548struct stmt_expr
549{
550 c_unparser & c;
dff50e09 551 stmt_expr(c_unparser & c) : c(c)
313b2f74 552 {
1bbeef03 553 c.o->newline() << "({";
313b2f74
GH
554 c.o->indent(1);
555 }
556 ~stmt_expr()
557 {
bb788f9f 558 c.o->newline(-1) << "})";
313b2f74
GH
559 }
560};
561
bb788f9f 562
313b2f74
GH
563struct tmpvar
564 : public var
565{
11b52b73
DS
566protected:
567 bool overridden;
568 string override_value;
569
570public:
0386bbcf 571 tmpvar(c_unparser *u, exp_type ty, unsigned & counter)
d6d4dc4b 572 : var(u, true, ty, counter),
0386bbcf 573 overridden(false)
11b52b73
DS
574 {}
575
576 tmpvar(const var& source)
577 : var(source), overridden(false)
313b2f74 578 {}
11b52b73
DS
579
580 void override(const string &value)
581 {
582 overridden = true;
583 override_value = value;
584 }
585
b2d74f03
JS
586 bool is_overridden()
587 {
588 return overridden;
589 }
590
11b52b73
DS
591 string value() const
592 {
593 if (overridden)
594 return override_value;
595 else
596 return var::value();
dff50e09 597 }
313b2f74
GH
598};
599
11b52b73
DS
600ostream & operator<<(ostream & o, tmpvar const & v)
601{
602 return o << v.value();
603}
604
07c17d67
GH
605struct aggvar
606 : public var
607{
0386bbcf 608 aggvar(c_unparser *u, unsigned & counter)
d6d4dc4b 609 : var(u, true, pe_stats, counter)
07c17d67
GH
610 {}
611
612 string init() const
613 {
614 assert (type() == pe_stats);
11b52b73 615 return value() + " = NULL;";
07c17d67
GH
616 }
617
d6d4dc4b 618 void declare(c_unparser &c) const cxx_override
07c17d67
GH
619 {
620 assert (type() == pe_stats);
621 c.o->newline() << "struct stat_data *" << name << ";";
622 }
bdc82277
JS
623
624 string get_hist (var& index) const
625 {
626 return "(" + value() + "->histogram[" + index.value() + "])";
627 }
07c17d67
GH
628};
629
313b2f74
GH
630struct mapvar
631 : public var
632{
633 vector<exp_type> index_types;
ef474d24 634 int maxsize;
74e6cc92 635 bool wrap;
0386bbcf
SM
636 mapvar (c_unparser *u,
637 bool local, exp_type ty,
57b73400 638 statistic_decl const & sd,
dff50e09 639 string const & name,
ef474d24 640 vector<exp_type> const & index_types,
74e6cc92 641 int maxsize, bool wrap)
0386bbcf 642 : var (u, local, ty, sd, name),
ef474d24 643 index_types (index_types),
74e6cc92 644 maxsize (maxsize), wrap(wrap)
313b2f74 645 {}
dff50e09 646
313b2f74
GH
647 static string shortname(exp_type e);
648 static string key_typename(exp_type e);
649 static string value_typename(exp_type e);
650
d23a2349 651 string keysym () const
d98d459c 652 {
d23a2349
GH
653 string result;
654 vector<exp_type> tmp = index_types;
655 tmp.push_back (type ());
656 for (unsigned i = 0; i < tmp.size(); ++i)
657 {
658 switch (tmp[i])
659 {
660 case pe_long:
661 result += 'i';
662 break;
663 case pe_string:
664 result += 's';
665 break;
666 case pe_stats:
667 result += 'x';
668 break;
669 default:
dc09353a 670 throw SEMANTIC_ERROR(_("unknown type of map"));
d23a2349
GH
671 break;
672 }
673 }
674 return result;
51bf37c3
GH
675 }
676
2473ac1b 677 string function_keysym(string const & fname, bool pre_agg=false) const
313b2f74 678 {
57eedf94 679 string mtype = (is_parallel() && !pre_agg) ? "pmap" : "map";
2473ac1b
JS
680 string result = "_stp_" + mtype + "_" + fname + "_" + keysym();
681 return result;
682 }
683
684 string call_prefix (string const & fname, vector<tmpvar> const & indices, bool pre_agg=false) const
685 {
686 string result = function_keysym(fname, pre_agg) + " (";
11b52b73 687 result += pre_agg? fetch_existing_aggregate() : value();
313b2f74
GH
688 for (unsigned i = 0; i < indices.size(); ++i)
689 {
690 if (indices[i].type() != index_types[i])
dc09353a 691 throw SEMANTIC_ERROR(_("index type mismatch"));
313b2f74 692 result += ", ";
11b52b73 693 result += indices[i].value();
313b2f74 694 }
d23a2349 695
313b2f74
GH
696 return result;
697 }
698
07c17d67
GH
699 bool is_parallel() const
700 {
701 return type() == pe_stats;
702 }
703
704 string calculate_aggregate() const
705 {
706 if (!is_parallel())
dc09353a 707 throw SEMANTIC_ERROR(_("aggregating non-parallel map type"));
dff50e09 708
2473ac1b 709 return function_keysym("agg") + " (" + value() + ")";
07c17d67
GH
710 }
711
712 string fetch_existing_aggregate() const
713 {
714 if (!is_parallel())
dc09353a 715 throw SEMANTIC_ERROR(_("fetching aggregate of non-parallel map type"));
dff50e09 716
11b52b73 717 return "_stp_pmap_get_agg(" + value() + ")";
07c17d67 718 }
d23a2349
GH
719
720 string del (vector<tmpvar> const & indices) const
e7ae4442
MH
721 {
722 return (call_prefix("del", indices) + ")");
d23a2349
GH
723 }
724
725 string exists (vector<tmpvar> const & indices) const
726 {
77d3caaf
MH
727 if (type() == pe_long || type() == pe_string)
728 return (call_prefix("exists", indices) + ")");
729 else if (type() == pe_stats)
4c82f679
DS
730 return ("((uintptr_t)" + call_prefix("get", indices)
731 + ") != (uintptr_t) 0)");
732 else
dc09353a 733 throw SEMANTIC_ERROR(_("checking existence of an unsupported map type"));
d23a2349
GH
734 }
735
57eedf94 736 string get (vector<tmpvar> const & indices, bool pre_agg=false) const
313b2f74 737 {
aab2b35f
FCE
738 // see also itervar::get_key
739 if (type() == pe_string)
740 // impedance matching: NULL -> empty strings
57eedf94 741 return ("({ char *v = " + call_prefix("get", indices, pre_agg) + ");"
d23a2349 742 + "if (!v) v = \"\"; v; })");
07c17d67 743 else if (type() == pe_long || type() == pe_stats)
57eedf94 744 return call_prefix("get", indices, pre_agg) + ")";
57b73400 745 else
dc09353a 746 throw SEMANTIC_ERROR(_("getting a value from an unsupported map type"));
313b2f74
GH
747 }
748
d23a2349 749 string add (vector<tmpvar> const & indices, tmpvar const & val) const
313b2f74 750 {
ef474d24
JS
751 string res = "{ int rc = ";
752
aab2b35f 753 // impedance matching: empty strings -> NULL
d23a2349 754 if (type() == pe_stats)
11b52b73 755 res += (call_prefix("add", indices) + ", " + val.value() + ")");
57b73400 756 else
dc09353a 757 throw SEMANTIC_ERROR(_("adding a value of an unsupported map type"));
ef474d24 758
b5f561be
LB
759 res += "; if (unlikely(rc)) { c->last_error = ";
760 res += STAP_T_01 +
aca66a36
JS
761 lex_cast(maxsize > 0 ?
762 "size limit (" + lex_cast(maxsize) + ")" : "MAXMAPENTRIES")
12363146 763 + "\"; goto out; }}";
ef474d24
JS
764
765 return res;
313b2f74
GH
766 }
767
d23a2349 768 string set (vector<tmpvar> const & indices, tmpvar const & val) const
313b2f74 769 {
2288c6bb
ET
770 string res = "{ int rc = ";
771
d23a2349
GH
772 // impedance matching: empty strings -> NULL
773 if (type() == pe_string)
dff50e09 774 res += (call_prefix("set", indices)
11b52b73 775 + ", (" + val.value() + "[0] ? " + val.value() + " : NULL))");
d23a2349 776 else if (type() == pe_long)
11b52b73 777 res += (call_prefix("set", indices) + ", " + val.value() + ")");
d23a2349 778 else
dc09353a 779 throw SEMANTIC_ERROR(_("setting a value of an unsupported map type"));
2288c6bb 780
b5f561be
LB
781 res += "; if (unlikely(rc)) { c->last_error = ";
782 res += STAP_T_01 +
aca66a36
JS
783 lex_cast(maxsize > 0 ?
784 "size limit (" + lex_cast(maxsize) + ")" : "MAXMAPENTRIES")
12363146 785 + "\"; goto out; }}";
2288c6bb
ET
786
787 return res;
313b2f74 788 }
1820694f
JS
789
790 string hist() const
791 {
792 assert (ty == pe_stats);
793 assert (sd.type != statistic_decl::none);
794 return "(&(" + fetch_existing_aggregate() + "->hist))";
795 }
796
797 string buckets() const
798 {
799 assert (ty == pe_stats);
800 assert (sd.type != statistic_decl::none);
801 return "(" + fetch_existing_aggregate() + "->hist.buckets)";
802 }
dff50e09 803
313b2f74
GH
804 string init () const
805 {
63438a79 806 if (local)
dc09353a 807 throw SEMANTIC_ERROR(_F("unsupported local map init for %s", value().c_str()));
63438a79
JS
808
809 string prefix = "global_set(" + c_name() + ", ";
810 prefix += function_keysym("new") + " ("
db0a4028
DS
811 + (maxsize > 0 ? lex_cast(maxsize) : "MAXMAPENTRIES")
812 + ((wrap == true) ? ", 1" : ", 0");
d23a2349 813
133467ef
FCE
814 // See also var::init().
815
3a02f9bf 816 // Check for errors during allocation.
11b52b73 817 string suffix = "if (" + value () + " == NULL) rc = -ENOMEM;";
3a02f9bf 818
57b73400
GH
819 if (type() == pe_stats)
820 {
821 switch (sdecl().type)
822 {
823 case statistic_decl::none:
3a02f9bf 824 prefix = prefix + ", HIST_NONE";
57b73400
GH
825 break;
826
827 case statistic_decl::linear:
828 // FIXME: check for "reasonable" values in linear stats
dff50e09 829 prefix = prefix + ", HIST_LINEAR"
aca66a36
JS
830 + ", " + lex_cast(sdecl().linear_low)
831 + ", " + lex_cast(sdecl().linear_high)
832 + ", " + lex_cast(sdecl().linear_step);
57b73400
GH
833 break;
834
835 case statistic_decl::logarithmic:
e38723d2 836 prefix = prefix + ", HIST_LOG";
57b73400
GH
837 break;
838 }
839 }
840
63438a79 841 prefix = prefix + ")); ";
b20febf3 842 return (prefix + suffix);
313b2f74
GH
843 }
844
845 string fini () const
846 {
b20febf3
FCE
847 // NB: fini() is safe to call even for globals that have not
848 // successfully initialized (that is to say, on NULL pointers),
849 // because the runtime specifically tolerates that in its _del
850 // functions.
851
b68e0c9e 852 if (is_parallel())
11b52b73 853 return "_stp_pmap_del (" + value() + ");";
b68e0c9e 854 else
11b52b73 855 return "_stp_map_del (" + value() + ");";
b68e0c9e 856 }
313b2f74
GH
857};
858
07c17d67 859
67c0a579 860class itervar
d6d4dc4b 861 : public var
67c0a579 862{
67c0a579
GH
863public:
864
d6d4dc4b
JS
865 itervar (c_unparser *u, symbol* e, unsigned & counter)
866 : var(u, true, e->referent->type, counter)
67c0a579 867 {
d6d4dc4b 868 if (type() == pe_unknown)
dc09353a 869 throw SEMANTIC_ERROR(_("iterating over unknown reference type"), e->tok);
67c0a579 870 }
dff50e09 871
d6d4dc4b 872 void declare(c_unparser &c) const cxx_override
67c0a579 873 {
d6d4dc4b 874 c.o->newline() << "struct map_node *" << name << ";";
67c0a579 875 }
dff50e09 876
67c0a579
GH
877 string start (mapvar const & mv) const
878 {
07c17d67
GH
879 string res;
880
d6d4dc4b 881 if (mv.type() != type())
dc09353a 882 throw SEMANTIC_ERROR(_("inconsistent iterator type in itervar::start()"));
dff50e09 883
07c17d67
GH
884 if (mv.is_parallel())
885 return "_stp_map_start (" + mv.fetch_existing_aggregate() + ")";
886 else
11b52b73 887 return "_stp_map_start (" + mv.value() + ")";
67c0a579
GH
888 }
889
890 string next (mapvar const & mv) const
891 {
d6d4dc4b 892 if (mv.type() != type())
dc09353a 893 throw SEMANTIC_ERROR(_("inconsistent iterator type in itervar::next()"));
67c0a579 894
40687c55 895 if (mv.is_parallel())
11b52b73 896 return "_stp_map_iter (" + mv.fetch_existing_aggregate() + ", " + value() + ")";
40687c55 897 else
11b52b73 898 return "_stp_map_iter (" + mv.value() + ", " + value() + ")";
67c0a579
GH
899 }
900
3a7fec94
AJ
901 // Cannot handle deleting and iterating on pmaps
902 string del_next (mapvar const & mv) const
a98c930b 903 {
d6d4dc4b 904 if (mv.type() != type())
a98c930b
AJ
905 throw SEMANTIC_ERROR(_("inconsistent iterator type in itervar::next()"));
906
907 if (mv.is_parallel())
3a7fec94 908 throw SEMANTIC_ERROR(_("deleting a value of an unsupported map type"));
a98c930b
AJ
909 else
910 return "_stp_map_iterdel (" + mv.value() + ", " + value() + ")";
911 }
912
2473ac1b 913 string get_key (mapvar const& mv, exp_type ty, unsigned i) const
67c0a579 914 {
aab2b35f
FCE
915 // bug translator/1175: runtime uses base index 1 for the first dimension
916 // see also mapval::get
67c0a579
GH
917 switch (ty)
918 {
919 case pe_long:
3cb9c91e 920 return mv.function_keysym("key_get_int64", true)
2473ac1b 921 + " (" + value() + ", " + lex_cast(i+1) + ")";
67c0a579 922 case pe_string:
aab2b35f 923 // impedance matching: NULL -> empty strings
3cb9c91e 924 return "(" + mv.function_keysym("key_get_str", true)
2473ac1b 925 + " (" + value() + ", " + lex_cast(i+1) + ") ?: \"\")";
67c0a579 926 default:
dc09353a 927 throw SEMANTIC_ERROR(_("illegal key type"));
67c0a579
GH
928 }
929 }
bdc82277 930
1841d2dd 931 string get_value (mapvar const& mv, exp_type ty) const
bdc82277 932 {
d6d4dc4b 933 if (ty != type())
dc09353a 934 throw SEMANTIC_ERROR(_("inconsistent iterator value in itervar::get_value()"));
bdc82277
JS
935
936 switch (ty)
937 {
938 case pe_long:
1841d2dd 939 return mv.function_keysym("get_int64", true) + " ("+ value() + ")";
bdc82277
JS
940 case pe_string:
941 // impedance matching: NULL -> empty strings
1841d2dd 942 return "(" + mv.function_keysym("get_str", true) + " ("+ value() + ") ?: \"\")";
bdc82277 943 case pe_stats:
1841d2dd 944 return mv.function_keysym("get_stat_data", true) + " ("+ value() + ")";
bdc82277 945 default:
dc09353a 946 throw SEMANTIC_ERROR(_("illegal value type"));
bdc82277
JS
947 }
948 }
67c0a579
GH
949};
950
951ostream & operator<<(ostream & o, itervar const & v)
952{
11b52b73 953 return o << v.value();
67c0a579 954}
2b066ec1 955
2b066ec1
FCE
956// ------------------------------------------------------------------------
957
60cf5fae 958// translator_output moved to translator-output.cxx
f8220a7b 959
313b2f74 960// ------------------------------------------------------------------------
4383d78c 961
b9086437 962struct unmodified_fnargs_checker : public embedded_tags_visitor
befa891f
AJ
963{
964 bool embedded_seen; // excludes code with pure and unmodified-args
b9086437 965 unmodified_fnargs_checker (): embedded_tags_visitor(true), embedded_seen(false) {}
befa891f 966
befa891f
AJ
967 void visit_embeddedcode (embeddedcode *e)
968 {
b9086437 969 embedded_tags_visitor::visit_embeddedcode(e);
da1bd8fa 970 // set embedded_seen to true if it does not contain /* unmodified-fnargs */
2451f2f1 971 embedded_seen = (embedded_seen || !tagged_p("/* unmodified-fnargs */"));
befa891f
AJ
972 }
973};
974
975bool
976is_unmodified_string_fnarg (systemtap_session* sess, functiondecl* fd, vardecl* v)
977{
b9086437
AJ
978 if (sess->unoptimized || v->type != pe_string)
979 return false;
980
981 // check that there is no embedded code that might modify the fn args
982 unmodified_fnargs_checker ecv;
983 fd->body->visit(& ecv);
984 if (ecv.embedded_seen)
985 return false;
986
987 varuse_collecting_visitor vut (*sess);
988 vut.current_function = fd;
989 fd->body->visit(& vut);
990 return (find(vut.written.begin(), vut.written.end(), v) == vut.written.end());
befa891f
AJ
991}
992
d6d4dc4b
JS
993// If we've seen a dupe, return it; else remember this and return NULL.
994probe *
995c_unparser::get_probe_dupe (derived_probe *dp)
996{
997 if (session->unoptimized)
998 return NULL;
999
1000 // Notice we're using the probe body itself instead of the emitted C
1001 // probe body to compare probes. We need to do this because the
1002 // emitted C probe body has stuff in it like:
1003 // c->last_stmt = "identifier 'printf' at foo.stp:<line>:<column>";
1004 //
1005 // which would make comparisons impossible.
1006
1007 ostringstream oss;
1008
1009 dp->print_dupe_stamp (oss);
1010 dp->body->print(oss);
1011
1012 // Since the generated C changes based on whether or not the probe
1013 // needs locks around global variables, this needs to be reflected
1014 // here. We don't want to treat as duplicate the handlers of
1015 // begin/end and normal probes that differ only in need_global_locks.
1016 oss << "# needs_global_locks: " << dp->needs_global_locks () << endl;
1017
1018 // NB: dependent probe conditions *could* be listed here, but don't need to
1019 // be. That's because they're only dependent on the probe body, which is
1020 // already "hashed" in above.
1021
1022 pair<map<string, probe*>::iterator, bool> const& inserted =
1023 probe_contents.insert(make_pair(oss.str(), dp));
1024
1025 if (inserted.second)
1026 return NULL; // it's new!
1027
1028 // Already seen it; here's the old one:
1029 return inserted.first->second;
1030}
1031
2b066ec1 1032void
4383d78c 1033c_unparser::emit_common_header ()
2b066ec1 1034{
d6d4dc4b
JS
1035 c_tmpcounter ct (this);
1036
342d3f96 1037 o->newline();
97cd9334 1038
a34a9fe0
MW
1039 // Per CPU context for probes. Includes common shared state held for
1040 // all probes (defined in common_probe_context), the probe locals (union)
1041 // and the function locals (union).
2b066ec1 1042 o->newline() << "struct context {";
18e5ffd4 1043
a34a9fe0
MW
1044 // Common state held shared by probes.
1045 o->newline(1) << "#include \"common_probe_context.h\"";
18e5ffd4
FCE
1046
1047 // PR10516: probe locals
2b066ec1
FCE
1048 o->newline() << "union {";
1049 o->indent(1);
2b066ec1
FCE
1050
1051 for (unsigned i=0; i<session->probes.size(); i++)
d6d4dc4b 1052 ct.emit_probe (session->probes[i]);
57478609 1053
18e5ffd4
FCE
1054 o->newline(-1) << "} probe_locals;";
1055
1056 // PR10516: function locals
1057 o->newline() << "union {";
1058 o->indent(1);
2b066ec1 1059
d6d4dc4b
JS
1060 for (map<string,functiondecl*>::iterator it = session->functions.begin();
1061 it != session->functions.end(); it++)
1062 ct.emit_function (it->second);
9b1b0d7e 1063
a7ed0d3e
FCE
1064 o->newline(-1) << "} locals [MAXNESTING+1];";
1065
1066 // NB: The +1 above for extra room for outgoing arguments of next nested function.
1067 // If MAXNESTING is set too small, the args will be written, but the MAXNESTING
1068 // check done at c_unparser::emit_function will reject.
1069 //
1070 // This policy wastes memory (one row of locals[] that cannot really
1071 // be used), but trades that for smaller code (not having to check
1072 // c->nesting against MAXNESTING at every call site).
1073
1074 // Try to catch a crazy user dude passing in -DMAXNESTING=-1, leading to a [0]-sized
1075 // locals[] array.
1076 o->newline() << "#if MAXNESTING < 0";
1077 o->newline() << "#error \"MAXNESTING must be positive\"";
1078 o->newline() << "#endif";
1079
5b1fa53b
JS
1080 // Use a separate union for compiled-printf locals, no nesting required.
1081 emit_compiled_printf_locals ();
1082
c08bf9de
JS
1083 o->newline(-1) << "};\n"; // end of struct context
1084
1085 o->newline() << "#include \"runtime_context.h\"";
1086
313b2f74 1087 emit_map_type_instantiations ();
57b73400 1088
5b1fa53b
JS
1089 emit_compiled_printfs();
1090
4bf3d59d
JL
1091 if (!session->runtime_usermode_p())
1092 {
1093 // Updated in probe handlers to signal that a module refresh is needed.
1094 // Checked and cleared by common epilogue after scheduling refresh work.
6092ee9e 1095 o->newline( 0) << "static atomic_t need_module_refresh = ATOMIC_INIT(0);";
4bf3d59d
JL
1096
1097 // We will use a workqueue to schedule module_refresh work when we need
1098 // to enable/disable probes.
1099 o->newline( 0) << "#include <linux/workqueue.h>";
1100 o->newline( 0) << "static struct work_struct module_refresher_work;";
1101 o->newline( 0) << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)";
1102 o->newline( 0) << "static void module_refresher(void *data) {";
1103 o->newline( 0) << "#else";
1104 o->newline( 0) << "static void module_refresher(struct work_struct *work) {";
1105 o->newline( 0) << "#endif";
1106 o->newline( 1) << "systemtap_module_refresh(NULL);";
1107 o->newline(-1) << "}";
0d10ad2d 1108
4619bb71 1109 o->newline( 0) << "#ifdef STP_ON_THE_FLY_TIMER_ENABLE";
566b515c 1110 o->newline( 0) << "#include \"timer.h\"";
0d10ad2d
JL
1111 o->newline( 0) << "static struct hrtimer module_refresh_timer;";
1112
406ca289
JL
1113 o->newline( 0) << "#ifndef STP_ON_THE_FLY_INTERVAL";
1114 o->newline( 0) << "#define STP_ON_THE_FLY_INTERVAL (100*1000*1000)"; // default to 100 ms
1115 o->newline( 0) << "#endif";
1116
566b515c 1117 o->newline( 0) << "hrtimer_return_t module_refresh_timer_cb(struct hrtimer *timer) {";
0d10ad2d 1118 o->newline(+1) << "if (atomic_cmpxchg(&need_module_refresh, 1, 0) == 1)";
df6c01e7
FCE
1119 // NB: one might like to invoke systemtap_module_refresh(NULL) directly from
1120 // here ... however hrtimers are called from an unsleepable context, so no can do.
0d10ad2d
JL
1121 o->newline(+1) << "schedule_work(&module_refresher_work);";
1122 o->newline(-1) << "hrtimer_set_expires(timer,";
1123 o->newline( 0) << " ktime_add(hrtimer_get_expires(timer),";
406ca289 1124 o->newline( 0) << " ktime_set(0, STP_ON_THE_FLY_INTERVAL))); ";
0d10ad2d
JL
1125 o->newline( 0) << "return HRTIMER_RESTART;";
1126 o->newline(-1) << "}";
f161bd74 1127 o->newline( 0) << "#endif /* STP_ON_THE_FLY_TIMER_ENABLE */";
4bf3d59d 1128 }
fc422d2b 1129
8cef7c70 1130 o->newline(0) << "#include \"namespaces.h\"";
ba7276fa
JL
1131
1132 o->newline();
2b066ec1
FCE
1133}
1134
1135
5b1fa53b
JS
1136void
1137c_unparser::declare_compiled_printf (bool print_to_stream, const string& format)
1138{
1139 pair<bool, string> index (print_to_stream, format);
1140 map<pair<bool, string>, string>::iterator it = compiled_printfs.find(index);
1141 if (it == compiled_printfs.end())
1142 compiled_printfs[index] = (print_to_stream ? "stp_printf_" : "stp_sprintf_")
1143 + lex_cast(compiled_printfs.size() + 1);
1144}
1145
1146const string&
1147c_unparser::get_compiled_printf (bool print_to_stream, const string& format)
1148{
1149 map<pair<bool, string>, string>::iterator it =
1150 compiled_printfs.find(make_pair(print_to_stream, format));
1151 if (it == compiled_printfs.end())
dc09353a 1152 throw SEMANTIC_ERROR (_("internal error translating printf"));
5b1fa53b
JS
1153 return it->second;
1154}
1155
d6d4dc4b
JS
1156const string&
1157c_tmpcounter::get_compiled_printf (bool print_to_stream, const string& format)
1158{
1159 parent->declare_compiled_printf (print_to_stream, format);
1160 return parent->get_compiled_printf (print_to_stream, format);
1161}
1162
5b1fa53b
JS
1163void
1164c_unparser::emit_compiled_printf_locals ()
1165{
0da35eae 1166 o->newline() << "#ifndef STP_LEGACY_PRINT";
5b1fa53b
JS
1167 o->newline() << "union {";
1168 o->indent(1);
1169 map<pair<bool, string>, string>::iterator it;
1170 for (it = compiled_printfs.begin(); it != compiled_printfs.end(); ++it)
1171 {
1172 bool print_to_stream = it->first.first;
1173 const string& format_string = it->first.second;
1174 const string& name = it->second;
1175 vector<print_format::format_component> components =
1176 print_format::string_to_components(format_string);
1177
1178 o->newline() << "struct " << name << "_locals {";
1179 o->indent(1);
1180
1181 size_t arg_ix = 0;
1182 vector<print_format::format_component>::const_iterator c;
1183 for (c = components.begin(); c != components.end(); ++c)
1184 {
1185 if (c->type == print_format::conv_literal)
1186 continue;
1187
1188 // Take note of the width and precision arguments, if any.
1189 if (c->widthtype == print_format::width_dynamic)
1190 o->newline() << "int64_t arg" << arg_ix++ << ";";
1191 if (c->prectype == print_format::prec_dynamic)
1192 o->newline() << "int64_t arg" << arg_ix++ << ";";
1193
1194 // Output the actual argument.
1195 switch (c->type)
1196 {
1197 case print_format::conv_pointer:
1198 case print_format::conv_number:
1199 case print_format::conv_char:
1200 case print_format::conv_memory:
1201 case print_format::conv_memory_hex:
1202 case print_format::conv_binary:
1203 o->newline() << "int64_t arg" << arg_ix++ << ";";
1204 break;
1205
1206 case print_format::conv_string:
1207 // NB: Since we know incoming strings are immutable, we can use
1208 // const char* rather than a private char[] copy. This is a
1209 // special case of the sort of optimizations desired in PR11528.
1210 o->newline() << "const char* arg" << arg_ix++ << ";";
1211 break;
1212
1213 default:
1214 assert(false); // XXX
1215 break;
1216 }
1217 }
1218
1219
1220 if (!print_to_stream)
1221 o->newline() << "char * __retvalue;";
1222
1223 o->newline(-1) << "} " << name << ";";
1224 }
1225 o->newline(-1) << "} printf_locals;";
0da35eae 1226 o->newline() << "#endif // STP_LEGACY_PRINT";
5b1fa53b
JS
1227}
1228
1229void
1230c_unparser::emit_compiled_printfs ()
1231{
0da35eae 1232 o->newline() << "#ifndef STP_LEGACY_PRINT";
5b1fa53b
JS
1233 map<pair<bool, string>, string>::iterator it;
1234 for (it = compiled_printfs.begin(); it != compiled_printfs.end(); ++it)
1235 {
1236 bool print_to_stream = it->first.first;
1237 const string& format_string = it->first.second;
1238 const string& name = it->second;
1239 vector<print_format::format_component> components =
1240 print_format::string_to_components(format_string);
1241
1242 o->newline();
1243
1244 // Might be nice to output the format string in a comment, but we'd have
1245 // to be extra careful about format strings not escaping the comment...
8f122660 1246 o->newline() << "static void " << name
5b1fa53b
JS
1247 << " (struct context* __restrict__ c) {";
1248 o->newline(1) << "struct " << name << "_locals * __restrict__ l = "
1249 << "& c->printf_locals." << name << ";";
1250 o->newline() << "char *str = NULL, *end = NULL;";
8f122660
FCE
1251 o->newline() << "const char *src;";
1252 o->newline() << "int width;";
1253 o->newline() << "int precision;";
1254 o->newline() << "unsigned long ptr_value;";
1255 o->newline() << "int num_bytes;";
1256
1257 o->newline() << "(void) width;";
1258 o->newline() << "(void) precision;";
1259 o->newline() << "(void) ptr_value;";
1260 o->newline() << "(void) num_bytes;";
5b1fa53b
JS
1261
1262 if (print_to_stream)
1263 {
1264 // Compute the buffer size needed for these arguments.
1265 size_t arg_ix = 0;
8f122660 1266 o->newline() << "num_bytes = 0;";
5b1fa53b
JS
1267 vector<print_format::format_component>::const_iterator c;
1268 for (c = components.begin(); c != components.end(); ++c)
1269 {
1270 if (c->type == print_format::conv_literal)
1271 {
1272 literal_string ls(c->literal_string);
1273 o->newline() << "num_bytes += sizeof(";
1274 visit_literal_string(&ls);
1275 o->line() << ") - 1;"; // don't count the '\0'
1276 continue;
1277 }
1278
8f122660 1279 o->newline() << "width = ";
5b1fa53b
JS
1280 if (c->widthtype == print_format::width_dynamic)
1281 o->line() << "clamp_t(int, l->arg" << arg_ix++
1282 << ", 0, STP_BUFFER_SIZE);";
1283 else if (c->widthtype == print_format::width_static)
1284 o->line() << "clamp_t(int, " << c->width
1285 << ", 0, STP_BUFFER_SIZE);";
1286 else
1287 o->line() << "-1;";
1288
8f122660 1289 o->newline() << "precision = ";
5b1fa53b
JS
1290 if (c->prectype == print_format::prec_dynamic)
1291 o->line() << "clamp_t(int, l->arg" << arg_ix++
1292 << ", 0, STP_BUFFER_SIZE);";
1293 else if (c->prectype == print_format::prec_static)
1294 o->line() << "clamp_t(int, " << c->precision
1295 << ", 0, STP_BUFFER_SIZE);";
1296 else
1297 o->line() << "-1;";
1298
1299 string value = "l->arg" + lex_cast(arg_ix++);
1300 switch (c->type)
1301 {
1302 case print_format::conv_pointer:
1303 // NB: stap < 1.3 had odd %p behavior... see _stp_vsnprintf
1304 if (strverscmp(session->compatible.c_str(), "1.3") < 0)
1305 {
8f122660 1306 o->newline() << "ptr_value = " << value << ";";
5b1fa53b
JS
1307 o->newline() << "if (width == -1)";
1308 o->newline(1) << "width = 2 + 2 * sizeof(void*);";
1309 o->newline(-1) << "precision = width - 2;";
1310 if (!c->test_flag(print_format::fmt_flag_left))
1311 o->newline() << "precision = min_t(int, precision, 2 * sizeof(void*));";
1312 o->newline() << "num_bytes += number_size(ptr_value, "
1313 << c->base << ", width, precision, " << c->flags << ");";
1314 break;
1315 }
1316 // else fall-through to conv_number
1317 case print_format::conv_number:
1318 o->newline() << "num_bytes += number_size(" << value << ", "
1319 << c->base << ", width, precision, " << c->flags << ");";
1320 break;
1321
1322 case print_format::conv_char:
5650ca76
JS
1323 o->newline() << "num_bytes += _stp_vsprint_char_size("
1324 << value << ", width, " << c->flags << ");";
5b1fa53b
JS
1325 break;
1326
1327 case print_format::conv_string:
1328 o->newline() << "num_bytes += _stp_vsprint_memory_size("
1329 << value << ", width, precision, 's', "
1330 << c->flags << ");";
1331 break;
1332
1333 case print_format::conv_memory:
1334 case print_format::conv_memory_hex:
1335 o->newline() << "num_bytes += _stp_vsprint_memory_size("
1336 << "(const char*)(intptr_t)" << value
1337 << ", width, precision, '"
1338 << ((c->type == print_format::conv_memory) ? "m" : "M")
1339 << "', " << c->flags << ");";
1340 break;
1341
1342 case print_format::conv_binary:
1343 o->newline() << "num_bytes += _stp_vsprint_binary_size("
1344 << value << ", width, precision);";
1345 break;
1346
1347 default:
1348 assert(false); // XXX
1349 break;
1350 }
5b1fa53b
JS
1351 }
1352
1353 o->newline() << "num_bytes = clamp(num_bytes, 0, STP_BUFFER_SIZE);";
1354 o->newline() << "str = (char*)_stp_reserve_bytes(num_bytes);";
1355 o->newline() << "end = str ? str + num_bytes - 1 : 0;";
5b1fa53b
JS
1356 }
1357 else // !print_to_stream
1358 {
1359 // String results are a known buffer and size;
1360 o->newline() << "str = l->__retvalue;";
1361 o->newline() << "end = str + MAXSTRINGLEN - 1;";
1362 }
1363
1364 o->newline() << "if (str && str <= end) {";
1365 o->indent(1);
1366
1367 // Generate code to print the actual arguments.
1368 size_t arg_ix = 0;
1369 vector<print_format::format_component>::const_iterator c;
1370 for (c = components.begin(); c != components.end(); ++c)
1371 {
1372 if (c->type == print_format::conv_literal)
1373 {
1374 literal_string ls(c->literal_string);
8f122660 1375 o->newline() << "src = ";
5b1fa53b
JS
1376 visit_literal_string(&ls);
1377 o->line() << ";";
1378 o->newline() << "while (*src && str <= end)";
1379 o->newline(1) << "*str++ = *src++;";
8f122660 1380 o->indent(-1);
5b1fa53b
JS
1381 continue;
1382 }
1383
8f122660 1384 o->newline() << "width = ";
5b1fa53b
JS
1385 if (c->widthtype == print_format::width_dynamic)
1386 o->line() << "clamp_t(int, l->arg" << arg_ix++
1387 << ", 0, end - str + 1);";
1388 else if (c->widthtype == print_format::width_static)
1389 o->line() << "clamp_t(int, " << c->width
1390 << ", 0, end - str + 1);";
1391 else
1392 o->line() << "-1;";
1393
8f122660 1394 o->newline() << "precision = ";
5b1fa53b
JS
1395 if (c->prectype == print_format::prec_dynamic)
1396 o->line() << "clamp_t(int, l->arg" << arg_ix++
1397 << ", 0, end - str + 1);";
1398 else if (c->prectype == print_format::prec_static)
1399 o->line() << "clamp_t(int, " << c->precision
1400 << ", 0, end - str + 1);";
1401 else
1402 o->line() << "-1;";
1403
1404 string value = "l->arg" + lex_cast(arg_ix++);
1405 switch (c->type)
1406 {
1407 case print_format::conv_pointer:
1408 // NB: stap < 1.3 had odd %p behavior... see _stp_vsnprintf
1409 if (strverscmp(session->compatible.c_str(), "1.3") < 0)
1410 {
8f122660 1411 o->newline() << "ptr_value = " << value << ";";
5b1fa53b
JS
1412 o->newline() << "if (width == -1)";
1413 o->newline(1) << "width = 2 + 2 * sizeof(void*);";
1414 o->newline(-1) << "precision = width - 2;";
1415 if (!c->test_flag(print_format::fmt_flag_left))
1416 o->newline() << "precision = min_t(int, precision, 2 * sizeof(void*));";
1417 o->newline() << "str = number(str, end, ptr_value, "
1418 << c->base << ", width, precision, " << c->flags << ");";
1419 break;
1420 }
1421 // else fall-through to conv_number
1422 case print_format::conv_number:
1423 o->newline() << "str = number(str, end, " << value << ", "
1424 << c->base << ", width, precision, " << c->flags << ");";
1425 break;
1426
1427 case print_format::conv_char:
5650ca76
JS
1428 o->newline() << "str = _stp_vsprint_char(str, end, "
1429 << value << ", width, " << c->flags << ");";
5b1fa53b
JS
1430 break;
1431
1432 case print_format::conv_string:
1433 o->newline() << "str = _stp_vsprint_memory(str, end, "
1434 << value << ", width, precision, 's', "
1435 << c->flags << ");";
1436 break;
1437
1438 case print_format::conv_memory:
1439 case print_format::conv_memory_hex:
1440 o->newline() << "str = _stp_vsprint_memory(str, end, "
1441 << "(const char*)(intptr_t)" << value
1442 << ", width, precision, '"
1443 << ((c->type == print_format::conv_memory) ? "m" : "M")
1444 << "', " << c->flags << ");";
2ec6b38c
DS
1445 o->newline() << "if (unlikely(str == NULL)) {";
1446 o->indent(1);
1447 if (print_to_stream)
1448 o->newline() << "_stp_unreserve_bytes(num_bytes);";
1449 o->newline() << "return;";
1450 o->newline(-1) << "}";
5b1fa53b
JS
1451 break;
1452
1453 case print_format::conv_binary:
1454 o->newline() << "str = _stp_vsprint_binary(str, end, "
1455 << value << ", width, precision, "
1456 << c->flags << ");";
1457 break;
1458
1459 default:
1460 assert(false); // XXX
1461 break;
1462 }
5b1fa53b
JS
1463 }
1464
1465 if (!print_to_stream)
1466 {
1467 o->newline() << "if (str <= end)";
1468 o->newline(1) << "*str = '\\0';";
1469 o->newline(-1) << "else";
1470 o->newline(1) << "*end = '\\0';";
1471 o->indent(-1);
1472 }
1473
1474 o->newline(-1) << "}";
1475
1476 o->newline(-1) << "}";
1477 }
0da35eae 1478 o->newline() << "#endif // STP_LEGACY_PRINT";
5b1fa53b
JS
1479}
1480
1481
16c1c808
FCE
1482void
1483c_unparser::emit_global_param (vardecl *v)
1484{
6b15a04a
JS
1485 // Only true globals can be params, not private variables.
1486 if (!v->name.starts_with("__global_")) return;
1487
1488 string global = c_globalname (v->name);
1489 interned_string param = v->name.substr(sizeof("__global_") - 1);
16c1c808 1490
bd268288
SM
1491 // For dyninst, use the emit_global_init_* functionality instead.
1492 assert (!session->runtime_usermode_p());
71db462b 1493
16c1c808
FCE
1494 // NB: systemtap globals can collide with linux macros,
1495 // e.g. VM_FAULT_MAJOR. We want the parameter name anyway. This
1496 // #undef is spit out at the end of the C file, so that removing the
1497 // definition won't affect any other embedded-C or generated code.
1498 // XXX: better not have a global variable named module_param_named etc.!
eba95df1 1499 o->newline() << "#undef " << param; // avoid colliding with non-mangled name
16c1c808
FCE
1500
1501 // Emit module_params for this global, if its type is convenient.
1502 if (v->arity == 0 && v->type == pe_long)
1503 {
6b15a04a
JS
1504 o->newline() << "module_param_named (" << param << ", "
1505 << "global(" << global << "), int64_t, 0);";
16c1c808
FCE
1506 }
1507 else if (v->arity == 0 && v->type == pe_string)
1508 {
1509 // NB: no special copying is needed.
6b15a04a
JS
1510 o->newline() << "module_param_string (" << param << ", "
1511 << "global(" << global << "), MAXSTRINGLEN, 0);";
16c1c808
FCE
1512 }
1513}
1514
1515
bd268288
SM
1516void
1517c_unparser::emit_global_init_setters ()
1518{
1519 // Hack for dyninst module params: setter function forms a little
1520 // linear lookup table ditty to find a global variable by name.
1521 o->newline() << "int stp_global_setter (const char *name, const char *value) {";
1522 o->newline(1);
1523 for (unsigned i=0; i<session->globals.size(); i++)
1524 {
1525 vardecl* v = session->globals[i];
1526 if (v->arity > 0) continue;
1527 if (v->type != pe_string && v->type != pe_long) continue;
1528
6b15a04a
JS
1529 // Only true globals can be params, not private variables.
1530 if (!v->name.starts_with("__global_")) continue;
1531
1532 string global = c_globalname (v->name);
1533 interned_string param = v->name.substr(sizeof("__global_") - 1);
1534
bd268288 1535 // Do not mangle v->name for the comparison!
6b15a04a 1536 o->line() << "if (0 == strcmp(name,\"" << param << "\"))" << " {";
bd268288
SM
1537
1538 o->indent(1);
1539 if (v->type == pe_string)
1540 {
6b15a04a 1541 c_assign("stp_global_init." + global, "value", pe_string, "BUG: global module param", v->tok);
bd268288
SM
1542 o->newline() << "return 0;";
1543 }
1544 else
1545 {
6b15a04a 1546 o->newline() << "return set_int64_t(value, &stp_global_init." << global << ");";
bd268288
SM
1547 }
1548
1549 o->newline(-1) << "} else ";
1550 }
ac033e87
DS
1551
1552 // Call the runtime function that handles session attributes, like
1553 // log_level, etc.
1554 o->line() << "return stp_session_attribute_setter(name, value);";
bd268288
SM
1555 o->newline(-1) << "}";
1556 o->newline();
1557}
1558
1559
2b066ec1 1560void
4383d78c 1561c_unparser::emit_global (vardecl *v)
2b066ec1 1562{
0386bbcf 1563 string vn = c_globalname (v->name);
213bee8f 1564
63438a79
JS
1565 string type;
1566 if (v->arity > 0)
1567 type = (v->type == pe_stats) ? "PMAP" : "MAP";
4a6d3dfa 1568 else
63438a79
JS
1569 type = c_typename (v->type);
1570
1571 if (session->runtime_usermode_p())
1572 {
1573 // In stapdyn mode, the stat/map/pmap pointers are stored as offptr_t in
1574 // shared memory. However, we can keep a little type safety by emitting
1575 // FOO_typed and using typeof(FOO_typed) in the global() macros.
1576 bool offptr_p = (v->type == pe_stats) || (v->arity > 0);
1577 string stored_type = offptr_p ? "offptr_t" : type;
1578
1579 // NB: The casted_type is in the unused side of a __builtin_choose_expr
1580 // for non-offptr types, so it doesn't matter what we put for them, as
1581 // long as it passes syntax long enough for gcc to choose the other expr.
1582 string casted_type = offptr_p ? type : "void*";
1583
1584 o->newline() << "union {";
1585 o->newline(1) << casted_type << " " << vn << "_typed;";
1586 o->newline() << stored_type << " " << vn << ";";
1587 o->newline(-1) << "};";
1588 }
1589 else
1590 o->newline() << type << " " << vn << ";";
1591
0386bbcf 1592 o->newline() << "rwlock_t " << vn << "_lock;";
d9582a60 1593 o->newline() << "#ifdef STP_TIMING";
0386bbcf 1594 o->newline() << "atomic_t " << vn << "_lock_skip_count;";
1751e667 1595 o->newline() << "#endif\n";
4a6d3dfa
FCE
1596}
1597
1598
1599void
1600c_unparser::emit_global_init (vardecl *v)
1601{
63438a79
JS
1602 // We can only statically initialize some scalars.
1603 if (v->arity == 0 && v->init)
9ba8c134 1604 {
63438a79
JS
1605 o->newline() << "." << c_globalname (v->name) << " = ";
1606 v->init->visit(this);
1607 o->line() << ",";
b68e0c9e 1608 }
bd268288
SM
1609 else if (v->arity == 0 && session->runtime_usermode_p())
1610 {
1611 // For dyninst: always try to put a default value into the initial
1612 // static structure, so we don't have to guess if it was customized.
1613 if (v->type == pe_long)
1614 o->newline() << "." << c_globalname (v->name) << " = 0,";
1615 else if (v->type == pe_string)
1616 o->newline() << "." << c_globalname (v->name) << " = { '\\0' },"; // XXX: ""
1617 }
63438a79 1618 // The lock and lock_skip_count are handled in emit_module_init.
2b066ec1
FCE
1619}
1620
1621
bd268288
SM
1622void
1623c_unparser::emit_global_init_type (vardecl *v)
1624{
1625 // We can only statically initialize some scalars.
1626 if (v->arity == 0) // ... although we still allow !v->init here.
1627 {
1628 o->newline() << c_typename(v->type) << " " << c_globalname(v->name) << ";";
1629 }
1630}
1631
1632
2b066ec1 1633void
4383d78c 1634c_unparser::emit_functionsig (functiondecl* v)
2b066ec1 1635{
acb811fc 1636 o->newline() << "static void " << c_funcname(v->name)
9a604fac 1637 << " (struct context * __restrict__ c);";
2b066ec1
FCE
1638}
1639
1640
be66b6e1
DS
1641void
1642c_unparser::emit_kernel_module_init ()
1643{
1644 if (session->runtime_usermode_p())
1645 return;
1646
1647 o->newline();
1648 o->newline() << "static int systemtap_kernel_module_init (void) {";
1649 o->newline(1) << "int rc = 0;";
1650 o->newline() << "int i=0, j=0;"; // for derived_probe_group use
1651
1652 vector<derived_probe_group*> g = all_session_groups (*session);
1653 for (unsigned i=0; i<g.size(); i++)
1654 {
1655 g[i]->emit_kernel_module_init (*session);
1656
1657 o->newline() << "if (rc) {";
1658 o->indent(1);
1659 if (i>0)
1660 {
1661 for (int j=i-1; j>=0; j--)
1662 g[j]->emit_kernel_module_exit (*session);
1663 }
1664 o->newline() << "goto out;";
1665 o->newline(-1) << "}";
1666 }
1667 o->newline(-1) << "out:";
1668 o->indent(1);
1669 o->newline() << "return rc;";
1670 o->newline(-1) << "}\n";
1671 o->assert_0_indent();
1672}
1673
1674
1675void
1676c_unparser::emit_kernel_module_exit ()
1677{
1678 if (session->runtime_usermode_p())
1679 return;
1680
1681 o->newline();
1682 o->newline() << "static void systemtap_kernel_module_exit (void) {";
1683 o->newline(1) << "int i=0, j=0;"; // for derived_probe_group use
1684
1685 // We're processing the derived_probe_group list in reverse order.
1686 // This ensures that probe groups get unregistered in reverse order
1687 // of the way they were registered.
1688 vector<derived_probe_group*> g = all_session_groups (*session);
1689 for (vector<derived_probe_group*>::reverse_iterator i = g.rbegin();
1690 i != g.rend(); i++)
1691 {
1692 (*i)->emit_kernel_module_exit (*session);
1693 }
1694 o->newline(-1) << "}\n";
1695 o->assert_0_indent();
1696}
1697
1698
2b066ec1 1699void
4383d78c 1700c_unparser::emit_module_init ()
2b066ec1 1701{
b20febf3
FCE
1702 vector<derived_probe_group*> g = all_session_groups (*session);
1703 for (unsigned i=0; i<g.size(); i++)
dac77b80
FCE
1704 {
1705 g[i]->emit_module_decls (*session);
1706 o->assert_0_indent();
1707 }
dff50e09 1708
3ef9830a
JS
1709 o->newline() << "#ifdef STAP_NEED_TRACEPOINTS";
1710 o->newline() << "#include \"linux/stp_tracepoint.c\"";
1711 o->newline() << "#endif";
1712
db22e55f 1713 o->newline();
4c2732a1 1714 o->newline() << "static int systemtap_module_init (void) {";
bfb3d2d2 1715 o->newline(1) << "int rc = 0;";
4a0ae64c 1716 o->newline() << "int cpu;";
b20febf3 1717 o->newline() << "int i=0, j=0;"; // for derived_probe_group use
2508b230 1718 o->newline() << "const char *probe_point = \"\";";
bfb3d2d2 1719
4441e344 1720 // NB: This block of initialization only makes sense in kernel
ac3af990 1721 if (! session->runtime_usermode_p())
71db462b
DS
1722 {
1723 // XXX Plus, most of this code is completely static, so it probably should
1724 // move into the runtime, where kernel/dyninst is more easily separated.
1725
1726 // Compare actual and targeted kernel releases/machines. Sometimes
1727 // one may install the incorrect debuginfo or -devel RPM, and try to
1728 // run a probe compiled for a different version. Catch this early,
1729 // just in case modversions didn't.
1730 o->newline() << "{";
2c867c94 1731 o->newline() << "#ifndef STP_NO_VERREL_CHECK";
71db462b
DS
1732 o->newline(1) << "const char* release = UTS_RELEASE;";
1733 o->newline() << "#ifdef STAPCONF_GENERATED_COMPILE";
1734 o->newline() << "const char* version = UTS_VERSION;";
1735 o->newline() << "#endif";
1736
1737 // NB: This UTS_RELEASE compile-time macro directly checks only that
1738 // the compile-time kbuild tree matches the compile-time debuginfo/etc.
1739 // It does not check the run time kernel value. However, this is
1740 // probably OK since the kbuild modversions system aims to prevent
1741 // mismatches between kbuild and runtime versions at module-loading time.
1742
1743 // o->newline() << "const char* machine = UTS_MACHINE;";
1744 // NB: We could compare UTS_MACHINE too, but on x86 it lies
1745 // (UTS_MACHINE=i386, but uname -m is i686). Sheesh.
1746
1747 o->newline() << "if (strcmp (release, "
1748 << lex_cast_qstring (session->kernel_release) << ")) {";
1749 o->newline(1) << "_stp_error (\"module release mismatch (%s vs %s)\", "
1750 << "release, "
1751 << lex_cast_qstring (session->kernel_release)
1752 << ");";
1753 o->newline() << "rc = -EINVAL;";
1754 o->newline(-1) << "}";
f2013cc9 1755
71db462b
DS
1756 o->newline() << "#ifdef STAPCONF_GENERATED_COMPILE";
1757 o->newline() << "if (strcmp (utsname()->version, version)) {";
1758 o->newline(1) << "_stp_error (\"module version mismatch (%s vs %s), release %s\", "
1759 << "version, "
1760 << "utsname()->version, "
1761 << "release"
1762 << ");";
1763 o->newline() << "rc = -EINVAL;";
1764 o->newline(-1) << "}";
1765 o->newline() << "#endif";
2c867c94 1766 o->newline() << "#endif";
71db462b
DS
1767
1768 // perform buildid-based checking if able
1769 o->newline() << "if (_stp_module_check()) rc = -EINVAL;";
1770
1771 // Perform checking on the user's credentials vs those required to load/run this module.
1772 o->newline() << "if (_stp_privilege_credentials == 0) {";
1773 o->newline(1) << "if (STP_PRIVILEGE_CONTAINS(STP_PRIVILEGE, STP_PR_STAPDEV) ||";
1774 o->newline() << " STP_PRIVILEGE_CONTAINS(STP_PRIVILEGE, STP_PR_STAPUSR)) {";
1775 o->newline(1) << "_stp_privilege_credentials = STP_PRIVILEGE;";
1776 o->newline() << "#ifdef DEBUG_PRIVILEGE";
1777 o->newline(1) << "_dbug(\"User's privilege credentials default to %s\\n\",";
1778 o->newline() << " privilege_to_text(_stp_privilege_credentials));";
1779 o->newline(-1) << "#endif";
1780 o->newline(-1) << "}";
1781 o->newline() << "else {";
1782 o->newline(1) << "_stp_error (\"Unable to verify that you have the required privilege credentials to run this module (%s required). You must use staprun version 1.7 or higher.\",";
1783 o->newline() << " privilege_to_text(STP_PRIVILEGE));";
1784 o->newline() << "rc = -EINVAL;";
1785 o->newline(-1) << "}";
1786 o->newline(-1) << "}";
1787 o->newline() << "else {";
1788 o->newline(1) << "#ifdef DEBUG_PRIVILEGE";
1789 o->newline(1) << "_dbug(\"User's privilege credentials provided as %s\\n\",";
1790 o->newline() << " privilege_to_text(_stp_privilege_credentials));";
1791 o->newline(-1) << "#endif";
1792 o->newline() << "if (! STP_PRIVILEGE_CONTAINS(_stp_privilege_credentials, STP_PRIVILEGE)) {";
1793 o->newline(1) << "_stp_error (\"Your privilege credentials (%s) are insufficient to run this module (%s required).\",";
1794 o->newline () << " privilege_to_text(_stp_privilege_credentials), privilege_to_text(STP_PRIVILEGE));";
1795 o->newline() << "rc = -EINVAL;";
1796 o->newline(-1) << "}";
1797 o->newline(-1) << "}";
faf38cd9 1798
71db462b 1799 o->newline(-1) << "}";
4441e344 1800
71db462b
DS
1801 o->newline() << "if (rc) goto out;";
1802 }
90ce056f 1803
065d5567
JS
1804 // Now that kernel version and permissions are correct,
1805 // initialize the global session states before anything else.
1806 o->newline() << "rc = stp_session_init();";
1807 o->newline() << "if (rc) {";
1808 o->newline(1) << "_stp_error (\"couldn't initialize the main session (rc %d)\", rc);";
1809 o->newline() << "goto out;";
1810 o->newline(-1) << "}";
1811
29e2616a
JS
1812 // initialize gettimeofday (if needed)
1813 o->newline() << "#ifdef STAP_NEED_GETTIMEOFDAY";
1814 o->newline() << "rc = _stp_init_time();"; // Kick off the Big Bang.
1815 o->newline() << "if (rc) {";
1816 o->newline(1) << "_stp_error (\"couldn't initialize gettimeofday\");";
1817 o->newline() << "goto out;";
1818 o->newline(-1) << "}";
1819 o->newline() << "#endif";
1820
3ef9830a
JS
1821 // initialize tracepoints (if needed)
1822 o->newline() << "#ifdef STAP_NEED_TRACEPOINTS";
1823 o->newline() << "rc = stp_tracepoint_init();";
1824 o->newline() << "if (rc) {";
1825 o->newline(1) << "_stp_error (\"couldn't initialize tracepoints\");";
1826 o->newline() << "goto out;";
1827 o->newline(-1) << "}";
1828 o->newline() << "#endif";
1829
89ba3085 1830 // NB: we don't need per-_stp_module task_finders, since a single common one
a057c85c 1831 // set up in runtime/sym.c's _stp_sym_init() will scan through all _stp_modules. XXX - check this!
438cd7ed 1832 o->newline() << "(void) probe_point;";
b20febf3
FCE
1833 o->newline() << "(void) i;";
1834 o->newline() << "(void) j;";
065d5567 1835 o->newline() << "atomic_set (session_state(), STAP_SESSION_STARTING);";
bfb3d2d2
FCE
1836 // This signals any other probes that may be invoked in the next little
1837 // while to abort right away. Currently running probes are allowed to
1838 // terminate. These may set STAP_SESSION_ERROR!
bb2e3076 1839
1d0e697d
DS
1840 // Allocate context structures.
1841 o->newline() << "rc = _stp_runtime_contexts_alloc();";
1842 o->newline() << "if (rc != 0)";
1843 o->newline(1) << "goto out;";
1844 o->indent(-1);
dff50e09 1845
bb2e3076
FCE
1846 for (unsigned i=0; i<session->globals.size(); i++)
1847 {
dff50e09 1848 vardecl* v = session->globals[i];
313b2f74
GH
1849 if (v->index_types.size() > 0)
1850 o->newline() << getmap (v).init();
bd268288
SM
1851 else if (session->runtime_usermode_p() && v->arity == 0
1852 && (v->type == pe_long || v->type == pe_string))
1853 c_assign(getvar (v).value(), "stp_global_init." + c_globalname(v->name), v->type, "BUG: global initialization", v->tok);
bb2e3076 1854 else
313b2f74 1855 o->newline() << getvar (v).init();
b20febf3
FCE
1856 // NB: in case of failure of allocation, "rc" will be set to non-zero.
1857 // Allocation can in general continue.
1858
1859 o->newline() << "if (rc) {";
ae87121a 1860 o->newline(1) << "_stp_error (\"global variable '" << v->name << "' allocation failed\");";
b20febf3
FCE
1861 o->newline() << "goto out;";
1862 o->newline(-1) << "}";
1863
63438a79
JS
1864 o->newline() << "global_lock_init(" << c_globalname (v->name) << ");";
1865 o->newline() << "#ifdef STP_TIMING";
1866 o->newline() << "atomic_set(global_skipped(" << c_globalname (v->name) << "), 0);";
1867 o->newline() << "#endif";
bb2e3076
FCE
1868 }
1869
cbc32000
MH
1870 // Print a message to the kernel log about this module. This is
1871 // intended to help debug problems with systemtap modules.
1d0e697d
DS
1872 if (! session->runtime_usermode_p())
1873 o->newline() << "_stp_print_kernel_info("
1874 << "\"" << VERSION
1875 << "/" << dwfl_version (NULL) << "\""
1876 << ", (num_online_cpus() * sizeof(struct context))"
1877 << ", " << session->probes.size()
1878 << ");";
8ca891c4
DS
1879 // In dyninst mode, we need to know when all the globals have been
1880 // allocated and we're ready to run probe registration.
1881 else
1882 {
1883 o->newline() << "rc = stp_session_init_finished();";
1884 o->newline() << "if (rc) goto out;";
1885 }
cbc32000 1886
4bf3d59d
JL
1887 if (!session->runtime_usermode_p())
1888 {
1889 // Initialize workqueue needed for on-the-fly arming/disarming
1890 o->newline() << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)";
1891 o->newline() << "INIT_WORK(&module_refresher_work, module_refresher, NULL);";
1892 o->newline() << "#else";
1893 o->newline() << "INIT_WORK(&module_refresher_work, module_refresher);";
1894 o->newline() << "#endif";
1895 }
ba7276fa 1896
65aeaea0
FCE
1897 // Run all probe registrations. This actually runs begin probes.
1898
1899 for (unsigned i=0; i<g.size(); i++)
1900 {
1901 g[i]->emit_module_init (*session);
1902 // NB: this gives O(N**2) amount of code, but luckily there
1903 // are only seven or eight derived_probe_groups, so it's ok.
1904 o->newline() << "if (rc) {";
b0f614a0
DS
1905 // If a probe types's emit_module_init() wants to handle error
1906 // messages itself, it should set probe_point to NULL,
1907 o->newline(1) << "if (probe_point)";
65aeaea0 1908 o->newline(1) << "_stp_error (\"probe %s registration error (rc %d)\", probe_point, rc);";
b0f614a0 1909 o->indent(-1);
65aeaea0
FCE
1910 // NB: we need to be in the error state so timers can shutdown cleanly,
1911 // and so end probes don't run. OTOH, error probes can run.
065d5567 1912 o->newline() << "atomic_set (session_state(), STAP_SESSION_ERROR);";
65aeaea0
FCE
1913 if (i>0)
1914 for (int j=i-1; j>=0; j--)
1915 g[j]->emit_module_exit (*session);
1916 o->newline() << "goto out;";
1917 o->newline(-1) << "}";
1918 }
1919
b20febf3 1920 // All registrations were successful. Consider the system started.
065d5567 1921 o->newline() << "if (atomic_read (session_state()) == STAP_SESSION_STARTING)";
dff50e09 1922 // NB: only other valid state value is ERROR, in which case we don't
065d5567 1923 o->newline(1) << "atomic_set (session_state(), STAP_SESSION_RUNNING);";
0d10ad2d 1924 o->newline(-1);
f346b8b3
DS
1925
1926 // Run all post-session starting code.
1927 for (unsigned i=0; i<g.size(); i++)
1928 {
1929 g[i]->emit_module_post_init (*session);
1930 }
0d10ad2d
JL
1931
1932 if (!session->runtime_usermode_p())
1933 {
4619bb71
JL
1934 o->newline() << "#ifdef STP_ON_THE_FLY_TIMER_ENABLE";
1935
0d10ad2d
JL
1936 // Initialize hrtimer needed for on-the-fly arming/disarming
1937 o->newline() << "hrtimer_init(&module_refresh_timer, CLOCK_MONOTONIC,";
1938 o->newline() << " HRTIMER_MODE_REL);";
1939 o->newline() << "module_refresh_timer.function = &module_refresh_timer_cb;";
32fb33bd
JL
1940
1941 // We check here if it's worth it to start the timer at all. We only need
1942 // the background timer if there is a probe which doesn't support directy
1943 // scheduling work (otf_safe_context() == false), but yet does affect the
1944 // condition of at least one probe which supports on-the-fly operations.
1945 {
1946 // for each derived probe...
1947 bool start_timer = false;
1948 for (unsigned i=0; i<session->probes.size() && !start_timer; i++)
1949 {
1950 // if it isn't safe in this probe type to directly schedule work,
1951 // and this probe could affect other probes...
1952 if (session->probes[i]->group
1953 && !session->probes[i]->group->otf_safe_context(*session)
1954 && !session->probes[i]->probes_with_affected_conditions.empty())
1955 {
1956 // and if any of those possible probes support on-the-fly operations,
1957 // then we'll need the timer
1958 for (set<derived_probe*>::const_iterator
1959 it = session->probes[i]->probes_with_affected_conditions.begin();
1960 it != session->probes[i]->probes_with_affected_conditions.end()
1961 && !start_timer; ++it)
1962 {
1963 if ((*it)->group->otf_supported(*session))
1964 start_timer = true;
1965 }
1966 }
1967 }
1968
1969 if (start_timer)
1970 {
1971 o->newline() << "hrtimer_start(&module_refresh_timer,";
1972 o->newline() << " ktime_set(0, STP_ON_THE_FLY_INTERVAL),";
1973 o->newline() << " HRTIMER_MODE_REL);";
1974 }
1975 }
4619bb71
JL
1976
1977 o->newline() << "#endif /* STP_ON_THE_FLY_TIMER_ENABLE */";
0d10ad2d
JL
1978 }
1979
1980 o->newline() << "return 0;";
b20febf3
FCE
1981
1982 // Error handling path; by now all partially registered probe groups
1983 // have been unregistered.
1984 o->newline(-1) << "out:";
1985 o->indent(1);
fe3d01fa 1986
ff007aa3
FCE
1987 // If any registrations failed, we will need to deregister the globals,
1988 // as this is our only chance.
1989 for (unsigned i=0; i<session->globals.size(); i++)
1990 {
dff50e09 1991 vardecl* v = session->globals[i];
ff007aa3
FCE
1992 if (v->index_types.size() > 0)
1993 o->newline() << getmap (v).fini();
85278e66
DB
1994 else
1995 o->newline() << getvar (v).fini();
ff007aa3
FCE
1996 }
1997
bc9a523d 1998 // For any partially registered/unregistered kernel facilities.
065d5567 1999 o->newline() << "atomic_set (session_state(), STAP_SESSION_STOPPED);";
b9197b0f 2000 o->newline() << "stp_synchronize_sched();";
bc9a523d 2001
3ef9830a
JS
2002 // In case tracepoints were started, they need to be cleaned up
2003 o->newline() << "#ifdef STAP_NEED_TRACEPOINTS";
2004 o->newline() << " stp_tracepoint_exit();";
2005 o->newline() << "#endif";
2006
cc76db23
JS
2007 // In case gettimeofday was started, it needs to be stopped
2008 o->newline() << "#ifdef STAP_NEED_GETTIMEOFDAY";
2009 o->newline() << " _stp_kill_time();"; // An error is no cause to hurry...
2010 o->newline() << "#endif";
2011
2012 // Free up the context memory after an error too
1d0e697d 2013 o->newline() << "_stp_runtime_contexts_free();";
cc76db23 2014
b20febf3 2015 o->newline() << "return rc;";
db22e55f 2016 o->newline(-1) << "}\n";
2b066ec1
FCE
2017}
2018
2019
a60923e9
FCE
2020void
2021c_unparser::emit_module_refresh ()
2022{
19d62b5b 2023 o->newline() << "static void systemtap_module_refresh (const char *modname) {";
9c91d9d5
JL
2024 o->newline(1) << "int state;";
2025 o->newline() << "int i=0, j=0;"; // for derived_probe_group use
2026
35878a75
JL
2027 if (!session->runtime_usermode_p())
2028 {
4bf3d59d 2029 o->newline() << "#if defined(STP_TIMING)";
35878a75
JL
2030 o->newline() << "cycles_t cycles_atstart = get_cycles();";
2031 o->newline() << "#endif";
2032 }
2033
9c91d9d5
JL
2034 // Ensure we're only doing the refreshing one at a time. NB: it's important
2035 // that we get the lock prior to checking the session_state, in case whoever
2036 // is holding the lock (e.g. systemtap_module_exit()) changes it.
4bf3d59d
JL
2037 if (!session->runtime_usermode_p())
2038 o->newline() << "mutex_lock(&module_refresh_mutex);";
ae91e3d5
FCE
2039
2040 /* If we're not in STARTING/RUNNING state, don't try doing any work.
2041 PR16766 */
9c91d9d5 2042 o->newline() << "state = atomic_read (session_state());";
7caa63eb 2043 o->newline() << "if (state != STAP_SESSION_RUNNING && state != STAP_SESSION_STARTING && state != STAP_SESSION_ERROR) {";
ae91e3d5 2044 // cannot _stp_warn etc. since we're not in probe context
53d72bca 2045 o->newline(1) << "#if defined(__KERNEL__)";
e6f437ad
DS
2046 o->newline() << "if (state != STAP_SESSION_STOPPING)";
2047 o->newline(1) << "printk (KERN_ERR \"stap module notifier triggered in unexpected state %d\\n\", state);";
2048 o->indent(-1);
53d72bca 2049 o->newline() << "#endif";
9c91d9d5 2050
4bf3d59d
JL
2051 if (!session->runtime_usermode_p())
2052 o->newline() << "mutex_unlock(&module_refresh_mutex);";
9c91d9d5 2053
ae91e3d5
FCE
2054 o->newline() << "return;";
2055 o->newline(-1) << "}";
2056
a60923e9
FCE
2057 o->newline() << "(void) i;";
2058 o->newline() << "(void) j;";
ae91e3d5 2059
a60923e9
FCE
2060 vector<derived_probe_group*> g = all_session_groups (*session);
2061 for (unsigned i=0; i<g.size(); i++)
2062 {
2063 g[i]->emit_module_refresh (*session);
2064 }
9c91d9d5 2065
35878a75
JL
2066 if (!session->runtime_usermode_p())
2067 {
2068 // see also common_probe_entryfn_epilogue()
4bf3d59d 2069 o->newline() << "#if defined(STP_TIMING)";
35878a75
JL
2070 o->newline() << "if (likely(g_refresh_timing)) {";
2071 o->newline(1) << "cycles_t cycles_atend = get_cycles ();";
2072 o->newline() << "int32_t cycles_elapsed = ((int32_t)cycles_atend > (int32_t)cycles_atstart)";
2073 o->newline(1) << "? ((int32_t)cycles_atend - (int32_t)cycles_atstart)";
2074 o->newline() << ": (~(int32_t)0) - (int32_t)cycles_atstart + (int32_t)cycles_atend + 1;";
2075 o->indent(-1);
2076 o->newline() << "_stp_stat_add(g_refresh_timing, cycles_elapsed);";
2077 o->newline(-1) << "}";
2078 o->newline() << "#endif";
2079 }
2080
4bf3d59d
JL
2081 if (!session->runtime_usermode_p())
2082 o->newline() << "mutex_unlock(&module_refresh_mutex);";
9c91d9d5 2083
a60923e9
FCE
2084 o->newline(-1) << "}\n";
2085}
2086
2087
2b066ec1 2088void
4383d78c 2089c_unparser::emit_module_exit ()
2b066ec1 2090{
4c2732a1 2091 o->newline() << "static void systemtap_module_exit (void) {";
bfb3d2d2 2092 // rc?
71db462b 2093 o->newline(1) << "int i=0, j=0;"; // for derived_probe_group use
b20febf3
FCE
2094 o->newline() << "(void) i;";
2095 o->newline() << "(void) j;";
ff007aa3
FCE
2096 // If we aborted startup, then everything has been cleaned up already, and
2097 // module_exit shouldn't even have been called. But since it might be, let's
2098 // beat a hasty retreat to avoid double uninitialization.
065d5567 2099 o->newline() << "if (atomic_read (session_state()) == STAP_SESSION_STARTING)";
ff007aa3
FCE
2100 o->newline(1) << "return;";
2101 o->indent(-1);
dff50e09 2102
065d5567 2103 o->newline() << "if (atomic_read (session_state()) == STAP_SESSION_RUNNING)";
dff50e09 2104 // NB: only other valid state value is ERROR, in which case we don't
065d5567 2105 o->newline(1) << "atomic_set (session_state(), STAP_SESSION_STOPPING);";
bfb3d2d2
FCE
2106 o->indent(-1);
2107 // This signals any other probes that may be invoked in the next little
2108 // while to abort right away. Currently running probes are allowed to
2109 // terminate. These may set STAP_SESSION_ERROR!
2110
0d10ad2d 2111 if (!session->runtime_usermode_p())
4619bb71
JL
2112 {
2113 o->newline() << "#ifdef STP_ON_THE_FLY_TIMER_ENABLE";
2114 o->newline() << "hrtimer_cancel(&module_refresh_timer);";
2115 o->newline() << "#endif";
2116 }
0d10ad2d 2117
df6c01e7
FCE
2118 // cargo cult prologue ... hope to flush any pending workqueue items too
2119 o->newline() << "stp_synchronize_sched();";
2120
9c91d9d5 2121 // Get the lock before exiting to ensure there's no one in module_refresh
df6c01e7
FCE
2122 // NB: this should't be able to happen, because both the module_refresh_timer
2123 // and the workqueue ought to have been shut down by now.
4bf3d59d
JL
2124 if (!session->runtime_usermode_p())
2125 o->newline() << "mutex_lock(&module_refresh_mutex);";
ba7276fa 2126
ce5cddc5
FCE
2127 // We're processing the derived_probe_group list in reverse
2128 // order. This ensures that probes get unregistered in reverse
2129 // order of the way they were registered.
2130 vector<derived_probe_group*> g = all_session_groups (*session);
2131 for (vector<derived_probe_group*>::reverse_iterator i = g.rbegin();
2132 i != g.rend(); i++)
2133 (*i)->emit_module_exit (*session); // NB: runs "end" probes
2134
4bf3d59d
JL
2135 if (!session->runtime_usermode_p())
2136 o->newline() << "mutex_unlock(&module_refresh_mutex);";
9c91d9d5 2137
ce5cddc5
FCE
2138 // But some other probes may have launched too during unregistration.
2139 // Let's wait a while to make sure they're all done, done, done.
2140
224e23be 2141 // cargo cult prologue
b9197b0f 2142 o->newline() << "stp_synchronize_sched();";
224e23be 2143
bfb3d2d2
FCE
2144 // NB: systemtap_module_exit is assumed to be called from ordinary
2145 // user context, say during module unload. Among other things, this
2146 // means we can sleep a while.
1d0e697d 2147 o->newline() << "_stp_runtime_context_wait();";
a36378d7 2148
224e23be 2149 // cargo cult epilogue
065d5567 2150 o->newline() << "atomic_set (session_state(), STAP_SESSION_STOPPED);";
b9197b0f 2151 o->newline() << "stp_synchronize_sched();";
8d59b39f 2152
bfb3d2d2 2153 // XXX: might like to have an escape hatch, in case some probe is
cc9ee605 2154 // genuinely stuck somehow
bfb3d2d2 2155
313b2f74
GH
2156 for (unsigned i=0; i<session->globals.size(); i++)
2157 {
dff50e09 2158 vardecl* v = session->globals[i];
313b2f74
GH
2159 if (v->index_types.size() > 0)
2160 o->newline() << getmap (v).fini();
85278e66
DB
2161 else
2162 o->newline() << getvar (v).fini();
313b2f74 2163 }
ded98b33 2164
8ca891c4
DS
2165 // We're finished with the contexts if we're not in dyninst
2166 // mode. The dyninst mode needs the contexts, since print buffers
2167 // are stored there.
2168 if (!session->runtime_usermode_p())
2169 {
2170 o->newline() << "_stp_runtime_contexts_free();";
2171 }
2172 else
2173 {
2174 o->newline() << "struct context* __restrict__ c;";
2175 o->newline() << "c = _stp_runtime_entryfn_get_context();";
2176 }
ded98b33 2177
3ef9830a
JS
2178 // teardown tracepoints (if needed)
2179 o->newline() << "#ifdef STAP_NEED_TRACEPOINTS";
2180 o->newline() << " stp_tracepoint_exit();";
2181 o->newline() << "#endif";
2182
b9527ce5
FCE
2183 // teardown gettimeofday (if needed)
2184 o->newline() << "#ifdef STAP_NEED_GETTIMEOFDAY";
2185 o->newline() << " _stp_kill_time();"; // Go to a beach. Drink a beer.
2186 o->newline() << "#endif";
2187
c114ce7f
FCE
2188 // NB: PR13386 points out that _stp_printf may be called from contexts
2189 // without already active preempt disabling, which breaks various uses
2190 // of smp_processor_id(). So we temporary block preemption around this
2191 // whole printing block. XXX: get_cpu() / put_cpu() may work just as well.
2192 o->newline() << "preempt_disable();";
2193
653e6a9a
JS
2194 // print per probe point timing/alibi statistics
2195 o->newline() << "#if defined(STP_TIMING) || defined(STP_ALIBI)";
26e63673
JS
2196 o->newline() << "_stp_printf(\"----- probe hit report: \\n\");";
2197 o->newline() << "for (i = 0; i < ARRAY_SIZE(stap_probes); ++i) {";
7c3e97f4 2198 o->newline(1) << "const struct stap_probe *const p = &stap_probes[i];";
653e6a9a 2199 o->newline() << "#ifdef STP_ALIBI";
7c3e97f4 2200 o->newline() << "int alibi = atomic_read(probe_alibi(i));";
653e6a9a 2201 o->newline() << "if (alibi)";
ea260cbc
FCE
2202 o->newline(1) << "_stp_printf (\"%s, (%s), hits: %d,%s, index: %d\\n\",";
2203 o->newline(2) << "p->pp, p->location, alibi, p->derivation, i);";
653e6a9a
JS
2204 o->newline(-3) << "#endif"; // STP_ALIBI
2205 o->newline() << "#ifdef STP_TIMING";
7c3e97f4
JS
2206 o->newline() << "if (likely (probe_timing(i))) {"; // NB: check for null stat object
2207 o->newline(1) << "struct stat_data *stats = _stp_stat_get (probe_timing(i), 0);";
26e63673
JS
2208 o->newline() << "if (stats->count) {";
2209 o->newline(1) << "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);";
f887a8c9
DS
2210 o->newline() << "_stp_printf (\"%s, (%s), hits: %lld, "
2211 << (!session->runtime_usermode_p() ? "cycles" : "nsecs")
ea260cbc 2212 << ": %lldmin/%lldavg/%lldmax,%s, index: %d\\n\",";
26e63673
JS
2213 o->newline(2) << "p->pp, p->location, (long long) stats->count,";
2214 o->newline() << "(long long) stats->min, (long long) avg, (long long) stats->max,";
ea260cbc 2215 o->newline() << "p->derivation, i);";
26e63673 2216 o->newline(-3) << "}";
7c3e97f4 2217 o->newline() << "_stp_stat_del (probe_timing(i));";
26e63673 2218 o->newline(-1) << "}";
653e6a9a 2219 o->newline() << "#endif"; // STP_TIMING
26e63673 2220 o->newline(-1) << "}";
35878a75
JL
2221
2222 if (!session->runtime_usermode_p())
2223 {
4bf3d59d 2224 o->newline() << "#if defined(STP_TIMING)";
35878a75
JL
2225 o->newline() << "_stp_printf(\"----- refresh report:\\n\");";
2226 o->newline() << "if (likely (g_refresh_timing)) {";
2227 o->newline(1) << "struct stat_data *stats = _stp_stat_get (g_refresh_timing, 0);";
2228 o->newline() << "if (stats->count) {";
2229 o->newline(1) << "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);";
2230 o->newline() << "_stp_printf (\"hits: %lld, cycles: %lldmin/%lldavg/%lldmax\\n\",";
2231 o->newline(2) << "(long long) stats->count, (long long) stats->min, ";
2232 o->newline() << "(long long) avg, (long long) stats->max);";
2233 o->newline(-3) << "}";
2234 o->newline() << "_stp_stat_del (g_refresh_timing);";
2235 o->newline(-1) << "}";
4bf3d59d 2236 o->newline() << "#endif"; // STP_TIMING
35878a75
JL
2237 }
2238
26e63673
JS
2239 o->newline() << "_stp_print_flush();";
2240 o->newline() << "#endif";
dbb68664 2241
9c736061 2242 // print final error/skipped counts if non-zero
065d5567
JS
2243 o->newline() << "if (atomic_read (skipped_count()) || "
2244 << "atomic_read (error_count()) || "
2245 << "atomic_read (skipped_count_reentrant())) {"; // PR9967
802e6327 2246 o->newline(1) << "_stp_warn (\"Number of errors: %d, "
9a604fac 2247 << "skipped probes: %d\\n\", "
065d5567
JS
2248 << "(int) atomic_read (error_count()), "
2249 << "(int) atomic_read (skipped_count()));";
d9582a60
FCE
2250 o->newline() << "#ifdef STP_TIMING";
2251 o->newline() << "{";
2252 o->newline(1) << "int ctr;";
2253 for (unsigned i=0; i<session->globals.size(); i++)
2254 {
0386bbcf
SM
2255 string orig_vn = session->globals[i]->name;
2256 string vn = c_globalname (orig_vn);
63438a79 2257 o->newline() << "ctr = atomic_read (global_skipped(" << vn << "));";
b3c3ca7c 2258 o->newline() << "if (ctr) _stp_warn (\"Skipped due to global '%s' lock timeout: %d\\n\", "
0386bbcf 2259 << lex_cast_qstring(orig_vn) << ", ctr);";
d9582a60 2260 }
065d5567 2261 o->newline() << "ctr = atomic_read (skipped_count_lowstack());";
b3c3ca7c 2262 o->newline() << "if (ctr) _stp_warn (\"Skipped due to low stack: %d\\n\", ctr);";
065d5567 2263 o->newline() << "ctr = atomic_read (skipped_count_reentrant());";
b3c3ca7c 2264 o->newline() << "if (ctr) _stp_warn (\"Skipped due to reentrancy: %d\\n\", ctr);";
065d5567 2265 o->newline() << "ctr = atomic_read (skipped_count_uprobe_reg());";
73209876 2266 o->newline() << "if (ctr) _stp_warn (\"Skipped due to uprobe register failure: %d\\n\", ctr);";
065d5567 2267 o->newline() << "ctr = atomic_read (skipped_count_uprobe_unreg());";
73209876 2268 o->newline() << "if (ctr) _stp_warn (\"Skipped due to uprobe unregister failure: %d\\n\", ctr);";
d9582a60
FCE
2269 o->newline(-1) << "}";
2270 o->newline () << "#endif";
e65b03c1
MH
2271 o->newline() << "_stp_print_flush();";
2272 o->newline(-1) << "}";
c114ce7f
FCE
2273
2274 // NB: PR13386 needs to restore preemption-blocking counts
2275 o->newline() << "preempt_enable_no_resched();";
2276
fee09ad5 2277 // In dyninst mode, now we're done with the contexts, transport, everything!
8ca891c4
DS
2278 if (session->runtime_usermode_p())
2279 {
e481ab2e 2280 o->newline() << "_stp_runtime_entryfn_put_context(c);";
fee09ad5 2281 o->newline() << "_stp_dyninst_transport_shutdown();";
8ca891c4
DS
2282 o->newline() << "_stp_runtime_contexts_free();";
2283 }
2284
db22e55f 2285 o->newline(-1) << "}\n";
2b066ec1
FCE
2286}
2287
1bf6fd2c
AJ
2288struct max_action_info: public functioncall_traversing_visitor
2289{
2290 max_action_info(systemtap_session& s): sess(s), statement_count(0) {}
2291
2292 systemtap_session& sess;
2293 unsigned statement_count;
2294 static const unsigned max_statement_count = ~0;
2295
2296 void add_stmt_count (unsigned val)
2297 {
2298 statement_count = (statement_count > max_statement_count - val) ? max_statement_count : statement_count + val;
2299 }
2300 void add_max_stmt_count () { statement_count = max_statement_count; }
765e6976 2301 bool statement_count_finite() { return statement_count < max_statement_count; }
1bf6fd2c 2302
dabd71bb
MW
2303 void visit_for_loop (for_loop*) { add_max_stmt_count(); }
2304 void visit_foreach_loop (foreach_loop*) { add_max_stmt_count(); }
1bf6fd2c
AJ
2305 void visit_expr_statement (expr_statement *stmt)
2306 {
2307 add_stmt_count(1);
2308 traversing_visitor::visit_expr_statement(stmt); // which will trigger visit_functioncall, if applicable
2309 }
2310 void visit_if_statement (if_statement *stmt)
2311 {
2312 add_stmt_count(1);
2313 stmt->condition->visit(this);
2314
13133f2c 2315 // Create new visitors for the two forks. Copy the nested[] set
1bf6fd2c
AJ
2316 // to prevent infinite recursion for a function f () { if (a) f() }
2317 max_action_info tmp_visitor_then (*this);
2318 max_action_info tmp_visitor_else (*this);
2319 stmt->thenblock->visit(& tmp_visitor_then);
2320 if (stmt->elseblock)
2321 {
2322 stmt->elseblock->visit(& tmp_visitor_else);
2323 }
2324
2325 // Simply overwrite our copy of statement_count, since these
2326 // visitor copies already included our starting count.
2327 statement_count = max(tmp_visitor_then.statement_count, tmp_visitor_else.statement_count);
2328 }
2329
dabd71bb 2330 void note_recursive_functioncall (functioncall *) { add_max_stmt_count(); }
1bf6fd2c 2331
dabd71bb
MW
2332 void visit_null_statement (null_statement *) { add_stmt_count(1); }
2333 void visit_return_statement (return_statement *) { add_stmt_count(1); }
2334 void visit_delete_statement (delete_statement *) { add_stmt_count(1); }
2335 void visit_next_statement (next_statement *) { add_stmt_count(1); }
2336 void visit_break_statement (break_statement *) { add_stmt_count(1); }
2337 void visit_continue_statement (continue_statement *) { add_stmt_count(1); }
1bf6fd2c 2338};
2b066ec1
FCE
2339
2340void
d6d4dc4b 2341c_tmpcounter::emit_function (functiondecl* fd)
2b066ec1 2342{
d6d4dc4b
JS
2343 this->current_probe = 0;
2344 this->current_function = fd;
2345 this->tmpvar_counter = 0;
2346 this->action_counter = 0;
2347 this->already_checked_action_count = false;
2348 declared_vars.clear();
2349
2350 translator_output *o = parent->o;
2351
2352 // indent the dummy output as if we were already in a block
2353 this->o->indent (1);
2354
2355 o->newline() << "struct " << c_funcname (fd->name) << "_locals {";
2b066ec1 2356 o->indent(1);
d6d4dc4b
JS
2357
2358 for (unsigned j=0; j<fd->locals.size(); j++)
2359 {
2360 vardecl* v = fd->locals[j];
2361 try
2362 {
2363 if (fd->mangle_oldstyle)
2364 {
2365 // PR14524: retain old way of referring to the locals
2366 o->newline() << "union { "
2367 << c_typename (v->type) << " "
2368 << c_localname (v->name) << "; "
2369 << c_typename (v->type) << " "
2370 << c_localname (v->name, true) << "; };";
2371 }
2372 else
2373 {
2374 o->newline() << c_typename (v->type) << " "
2375 << c_localname (v->name) << ";";
2376 }
2377 } catch (const semantic_error& e) {
2378 semantic_error e2 (e);
2379 if (e2.tok1 == 0) e2.tok1 = v->tok;
2380 throw e2;
2381 }
2382 }
2383
2384 for (unsigned j=0; j<fd->formal_args.size(); j++)
2385 {
2386 vardecl* v = fd->formal_args[j];
2387 try
2388 {
2389 v->char_ptr_arg = (is_unmodified_string_fnarg (session, fd, v));
2390
2391 if (v->char_ptr_arg && session->verbose > 2)
2392 clog << _F("variable %s for function %s will be passed by reference (char *)",
5eb6ecb1
DS
2393 v->name.to_string().c_str(),
2394 fd->unmangled_name.to_string().c_str()) << endl;
d6d4dc4b
JS
2395
2396 if (fd->mangle_oldstyle)
2397 {
2398 // PR14524: retain old way of referring to the locals
2399 o->newline() << "union { "
2400 << (v->char_ptr_arg ? "const char *" : c_typename (v->type))
2401 << " " << c_localname (v->name) << "; "
2402 << (v->char_ptr_arg ? "const char *" : c_typename (v->type))
2403 << " " << c_localname (v->name, true) << "; };";
2404 }
2405 else
2406 {
2407 o->newline() << (v->char_ptr_arg ? "const char *" : c_typename (v->type))
2408 << " " << c_localname (v->name) << ";";
2409 }
2410 } catch (const semantic_error& e) {
2411 semantic_error e2 (e);
2412 if (e2.tok1 == 0) e2.tok1 = v->tok;
2413 throw e2;
2414 }
2415 }
2416
2417 fd->body->visit (this);
2418
2419 if (fd->type == pe_unknown)
2420 o->newline() << "/* no return value */";
2421 else
2422 {
2423 bool as_charp = !session->unoptimized && fd->type == pe_string;
2424 if (as_charp && session->verbose > 2)
2425 clog << _F("return value for function %s will be passed by reference (char *)",
5eb6ecb1 2426 fd->unmangled_name.to_string().c_str()) << endl;
d6d4dc4b
JS
2427 o->newline() << (as_charp ? "char *" : c_typename (fd->type))
2428 << " __retvalue;";
2429 }
2430 o->newline(-1) << "} " << c_funcname (fd->name) << ";";
2431
2432 // finish dummy indentation
2433 this->o->indent (-1);
2434 this->o->assert_0_indent ();
2435
2436 declared_vars.clear();
2437 this->current_function = 0;
2438 this->already_checked_action_count = false;
2439}
2440
2441void
2442c_unparser::emit_function (functiondecl* v)
2443{
2b066ec1 2444 this->current_probe = 0;
2b066ec1 2445 this->current_function = v;
ce10591c 2446 this->tmpvar_counter = 0;
9d0808b4 2447 this->action_counter = 0;
ad534e14 2448 this->already_checked_action_count = false;
4383d78c 2449
d6d4dc4b
JS
2450 o->newline() << "static void " << c_funcname (v->name)
2451 << " (struct context* __restrict__ c) {";
2452 o->indent(1);
2453
f4fe2e93 2454 o->newline() << "__label__ out;";
4383d78c 2455 o->newline()
0386bbcf 2456 << "struct " << c_funcname (v->name) << "_locals * "
f4fe2e93 2457 << " __restrict__ l = "
0386bbcf 2458 << "& c->locals[c->nesting+1]." << c_funcname (v->name) // NB: nesting+1
3d3887df 2459 << ";";
f4fe2e93 2460 o->newline() << "(void) l;"; // make sure "l" is marked used
3a20432b 2461 o->newline() << "#define CONTEXT c";
54dfabe9 2462 o->newline() << "#define THIS l";
0386bbcf
SM
2463 for (unsigned i = 0; i < v->formal_args.size(); i++) {
2464 o->newline() << c_arg_define(v->formal_args[i]->name); // #define STAP_ARG_foo ...
2465 }
2466 for (unsigned i = 0; i < v->locals.size(); i++) {
2467 o->newline() << c_arg_define(v->locals[i]->name); // #define STAP_ARG_foo ...
2468 }
a9bbc498
SM
2469 // define STAP_RETVALUE only if the function is non-void
2470 if (v->type != pe_unknown)
2471 o->newline() << "#define STAP_RETVALUE THIS->__retvalue";
4383d78c 2472
dff50e09 2473 // set this, in case embedded-c code sets last_error but doesn't otherwise identify itself
6120441d
FL
2474 if (v->tok)
2475 o->newline() << "c->last_stmt = " << lex_cast_qstring(*v->tok) << ";";
0301cfe7 2476
60ba482c 2477 // check/increment nesting level
a7ed0d3e
FCE
2478 // NB: incoming c->nesting level will be -1 (if we're called directly from a probe),
2479 // or 0...N (if we're called from another function). Incoming parameters are already
2480 // stored in c->locals[c->nesting+1]. See also ::emit_common_header() for more.
2481
101a2bb8 2482 o->newline() << "if (unlikely (c->nesting+1 >= MAXNESTING)) {";
b5f561be
LB
2483 o->newline(1) << "c->last_error = ";
2484 o->line() << STAP_T_02;
60ba482c
FCE
2485 o->newline() << "return;";
2486 o->newline(-1) << "} else {";
2487 o->newline(1) << "c->nesting ++;";
2488 o->newline(-1) << "}";
2489
4383d78c 2490 // initialize locals
3a20432b 2491 // XXX: optimization: use memset instead
4383d78c
FCE
2492 for (unsigned i=0; i<v->locals.size(); i++)
2493 {
2494 if (v->locals[i]->index_types.size() > 0) // array?
dc09353a 2495 throw SEMANTIC_ERROR (_("array locals not supported, missing global declaration?"),
9f36b77f 2496 v->locals[i]->tok);
313b2f74
GH
2497
2498 o->newline() << getvar (v->locals[i]).init();
4383d78c
FCE
2499 }
2500
2501 // initialize return value, if any
31966088
FCE
2502 if (v->type != pe_unknown)
2503 {
0386bbcf 2504 var retvalue = var(this, true, v->type, "__retvalue", false); // not mangled
31966088
FCE
2505 o->newline() << retvalue.init();
2506 }
4383d78c 2507
27cc9ab5
FCE
2508 switch (v->type)
2509 {
2510 case pe_long:
2511 o->newline() << "#define STAP_RETURN(v) do { STAP_RETVALUE = (int64_t) (v); "
2512 "goto out; } while(0)";
2513 break;
2514
2515 case pe_string:
2516 o->newline() <<
66b920f0 2517 "#define STAP_RETURN(v) do { strlcpy(STAP_RETVALUE, (v), MAXSTRINGLEN); "
27cc9ab5
FCE
2518 "goto out; } while(0)";
2519 break;
2520
2521 default:
2522 o->newline() << "#define STAP_RETURN() do { goto out; } while(0)";
2523 break;
2524 }
2525
68cdd41e 2526 o->newline() << "#define STAP_PRINTF(fmt, ...) do { _stp_printf(fmt, ##__VA_ARGS__); } while (0)";
bbbf5f8c 2527 o->newline() << "#define STAP_ERROR(...) do { snprintf(CONTEXT->error_buffer, MAXSTRINGLEN, __VA_ARGS__); CONTEXT->last_error = CONTEXT->error_buffer; goto out; } while (0)";
60ba482c 2528 o->newline() << "#define return goto out"; // redirect embedded-C return
1bf6fd2c
AJ
2529
2530 max_action_info mai (*session);
2531 v->body->visit (&mai);
2532
3021c2e8 2533 if (mai.statement_count_finite() && !session->suppress_time_limits
1497f0cc 2534 && !session->unoptimized) // this is a finite-statement-count function
1bf6fd2c
AJ
2535 {
2536 o->newline() << "if (c->actionremaining < " << mai.statement_count
7650d3de 2537 << ") { c->last_error = " << STAP_T_04 << "goto out; }";
1bf6fd2c
AJ
2538 this->already_checked_action_count = true;
2539 }
2540
2b066ec1 2541 v->body->visit (this);
60ba482c 2542 o->newline() << "#undef return";
68cdd41e 2543 o->newline() << "#undef STAP_PRINTF";
27cc9ab5
FCE
2544 o->newline() << "#undef STAP_ERROR";
2545 o->newline() << "#undef STAP_RETURN";
0d155048 2546
2b066ec1
FCE
2547 this->current_function = 0;
2548
54975cd8 2549 record_actions(0, v->body->tok, true);
9d0808b4 2550
2b066ec1 2551 o->newline(-1) << "out:";
f4fe2e93 2552 o->newline(1) << "if (0) goto out;"; // make sure out: is marked used
2b066ec1 2553
60ba482c
FCE
2554 // Function prologue: this is why we redirect the "return" above.
2555 // Decrement nesting level.
2556 o->newline() << "c->nesting --;";
ec03bd4b 2557
3a20432b 2558 o->newline() << "#undef CONTEXT";
54dfabe9 2559 o->newline() << "#undef THIS";
0386bbcf
SM
2560 for (unsigned i = 0; i < v->formal_args.size(); i++) {
2561 o->newline() << c_arg_undef(v->formal_args[i]->name); // #undef STAP_ARG_foo
2562 }
2563 for (unsigned i = 0; i < v->locals.size(); i++) {
2564 o->newline() << c_arg_undef(v->locals[i]->name); // #undef STAP_ARG_foo
2565 }
2566 o->newline() << "#undef STAP_RETVALUE";
db22e55f 2567 o->newline(-1) << "}\n";
2b066ec1 2568
d6d4dc4b
JS
2569 this->current_function = 0;
2570 this->already_checked_action_count = false;
2571}
2572
2573void
2574c_tmpcounter::emit_probe (derived_probe* dp)
2575{
2576 this->current_function = 0;
2577 this->current_probe = dp;
2578 this->tmpvar_counter = 0;
2579 this->action_counter = 0;
2580 this->already_checked_action_count = false;
2581 declared_vars.clear();
2582
2583 if (get_probe_dupe (dp) == NULL)
2584 {
2585 translator_output *o = parent->o;
2586
2587 // indent the dummy output as if we were already in a block
2588 this->o->indent (1);
2589
2590 o->newline() << "struct " << dp->name() << "_locals {";
2591 o->indent(1);
2592 for (unsigned j=0; j<dp->locals.size(); j++)
2593 {
2594 vardecl* v = dp->locals[j];
2595 try
2596 {
2597 o->newline() << c_typename (v->type) << " "
2598 << c_localname (v->name) << ";";
2599 } catch (const semantic_error& e) {
2600 semantic_error e2 (e);
2601 if (e2.tok1 == 0) e2.tok1 = v->tok;
2602 throw e2;
2603 }
2604 }
2605
2606 dp->body->visit (this);
2607
2608 // finish by visiting conditions of affected probes to match
2609 // c_unparser::emit_probe()
2610 if (!dp->probes_with_affected_conditions.empty())
2611 {
2612 for (set<derived_probe*>::const_iterator
2613 it = dp->probes_with_affected_conditions.begin();
2614 it != dp->probes_with_affected_conditions.end(); ++it)
2615 (*it)->sole_location()->condition->visit(this);
2616 }
2617
2618 o->newline(-1) << "} " << dp->name() << ";";
2619
2620 // finish dummy indentation
2621 this->o->indent (-1);
2622 this->o->assert_0_indent ();
2623 }
2624
2625 declared_vars.clear();
2626 this->current_probe = 0;
1bf6fd2c
AJ
2627 this->already_checked_action_count = false;
2628}
2b066ec1 2629
b20febf3
FCE
2630#define DUPMETHOD_CALL 0
2631#define DUPMETHOD_ALIAS 0
2632#define DUPMETHOD_RENAME 1
2633
d6d4dc4b 2634
2b066ec1 2635void
c1d5f3f6 2636c_unparser::emit_probe (derived_probe* v)
2b066ec1 2637{
3066c15c
FCE
2638 this->current_function = 0;
2639 this->current_probe = v;
3066c15c 2640 this->tmpvar_counter = 0;
9d0808b4 2641 this->action_counter = 0;
ad534e14 2642 this->already_checked_action_count = false;
3066c15c 2643
88bbd60d
DS
2644 // If we about to emit a probe that is exactly the same as another
2645 // probe previously emitted, make the second probe just call the
2646 // first one.
d6d4dc4b
JS
2647 probe *dupe = get_probe_dupe (v);
2648 if (dupe != NULL)
2b066ec1 2649 {
b20febf3
FCE
2650 // NB: Elision of context variable structs is a separate
2651 // operation which has already taken place by now.
2652 if (session->verbose > 1)
7371cd19 2653 clog << _F("%s elided, duplicates %s\n",
1341a03c 2654 v->name().c_str(), dupe->name().c_str());
b20febf3
FCE
2655
2656#if DUPMETHOD_CALL
2657 // This one emits a direct call to the first copy.
2658 o->newline();
1341a03c 2659 o->newline() << "static void " << v->name() << " (struct context * __restrict__ c) ";
d6d4dc4b 2660 o->newline() << "{ " << dupe->name() << " (c); }";
b20febf3
FCE
2661#elif DUPMETHOD_ALIAS
2662 // This one defines a function alias, arranging gcc to emit
2663 // several equivalent symbols for the same function body.
2664 // For some reason, on gcc 4.1, this is twice as slow as
2665 // the CALL option.
2666 o->newline();
1341a03c 2667 o->newline() << "static void " << v->name() << " (struct context * __restrict__ c) ";
d6d4dc4b 2668 o->line() << "__attribute__ ((alias (\"" << dupe->name() << "\")));";
b20febf3
FCE
2669#elif DUPMETHOD_RENAME
2670 // This one is sneaky. It emits nothing for duplicate probe
2671 // handlers. It instead redirects subsequent references to the
2672 // probe handler function to the first copy, *by name*.
1341a03c 2673 v->id = dupe->id;
b20febf3 2674#else
3866fc1d 2675#error "Unknown duplicate elimination method"
b20febf3 2676#endif
2b066ec1 2677 }
b20febf3 2678 else // This probe is unique. Remember it and output it.
88bbd60d 2679 {
b20febf3 2680 o->newline();
1341a03c 2681 o->newline() << "static void " << v->name() << " (struct context * __restrict__ c) ";
b20febf3
FCE
2682 o->line () << "{";
2683 o->indent (1);
2684
f4fe2e93
FCE
2685 o->newline() << "__label__ out;";
2686
29bb0bbc 2687 // emit static read/write lock decls for global variables
29bb0bbc
JS
2688 if (v->needs_global_locks ())
2689 {
3f3f4dd0
JS
2690 varuse_collecting_visitor vut(*session);
2691 v->body->visit (& vut);
be855773
JL
2692
2693 // also visit any probe conditions which this current probe might
2694 // evaluate so that read locks are emitted as necessary: e.g. suppose
2695 // probe X if (a || b) {...} probe Y {a = ...} probe Z {b = ...}
2696 // then Y and Z will already write-lock a and b respectively, but they
2697 // also need a read-lock on b and a respectively, since they will read
2698 // them when evaluating the new cond_enabled field (see c_unparser::
2699 // emit_probe_condition_update()).
2700 for (set<derived_probe*>::const_iterator
2701 it = v->probes_with_affected_conditions.begin();
2702 it != v->probes_with_affected_conditions.end(); ++it)
2703 {
2704 assert((*it)->sole_location()->condition != NULL);
2705 (*it)->sole_location()->condition->visit (& vut);
2706 }
2707
3f3f4dd0
JS
2708 emit_lock_decls (vut);
2709 }
29bb0bbc 2710
88bbd60d 2711 // initialize frame pointer
1341a03c
JS
2712 o->newline() << "struct " << v->name() << "_locals * __restrict__ l = "
2713 << "& c->probe_locals." << v->name() << ";";
f4fe2e93 2714 o->newline() << "(void) l;"; // make sure "l" is marked used
dff50e09 2715
2865d17a 2716 // Emit runtime safety net for unprivileged mode.
4441e344 2717 // NB: In usermode, the system restricts our privilege for us.
ac3af990 2718 if (!session->runtime_usermode_p())
4441e344 2719 v->emit_privilege_assertion (o);
2865d17a 2720
9020300d 2721 // emit probe local initialization block
3689db05
SC
2722
2723 v->emit_probe_local_init(*this->session, o);
9020300d 2724
88bbd60d 2725 // emit all read/write locks for global variables
90f98cc3 2726 if (v->needs_global_locks ())
3f3f4dd0 2727 emit_locks ();
88bbd60d
DS
2728
2729 // initialize locals
2730 for (unsigned j=0; j<v->locals.size(); j++)
2731 {
69aa668e 2732 if (v->locals[j]->synthetic)
a45664f4 2733 continue;
88bbd60d 2734 if (v->locals[j]->index_types.size() > 0) // array?
dc09353a 2735 throw SEMANTIC_ERROR (_("array locals not supported, missing global declaration?"),
9f36b77f 2736 v->locals[j]->tok);
88bbd60d 2737 else if (v->locals[j]->type == pe_long)
0386bbcf 2738 o->newline() << "l->" << c_localname (v->locals[j]->name)
88bbd60d
DS
2739 << " = 0;";
2740 else if (v->locals[j]->type == pe_string)
0386bbcf 2741 o->newline() << "l->" << c_localname (v->locals[j]->name)
88bbd60d
DS
2742 << "[0] = '\\0';";
2743 else
dc09353a 2744 throw SEMANTIC_ERROR (_("unsupported local variable type"),
88bbd60d
DS
2745 v->locals[j]->tok);
2746 }
2c384610
DS
2747
2748 v->initialize_probe_context_vars (o);
5d23847d 2749
ad534e14
AJ
2750 max_action_info mai (*session);
2751 v->body->visit (&mai);
2752 if (session->verbose > 1)
7371cd19 2753 clog << _F("%d statements for probe %s", mai.statement_count,
1341a03c 2754 v->name().c_str()) << endl;
ad534e14 2755
3021c2e8 2756 if (mai.statement_count_finite() && !session->suppress_time_limits
1497f0cc 2757 && !session->unoptimized) // this is a finite-statement-count probe
ad534e14 2758 {
2e19a3c1 2759 o->newline() << "if (c->actionremaining < " << mai.statement_count
7650d3de 2760 << ") { c->last_error = " << STAP_T_04 << " goto out; }";
ad534e14
AJ
2761 this->already_checked_action_count = true;
2762 }
2763
1bf6fd2c 2764
88bbd60d 2765 v->body->visit (this);
2b066ec1 2766
54975cd8 2767 record_actions(0, v->body->tok, true);
9d0808b4 2768
88bbd60d 2769 o->newline(-1) << "out:";
5d23847d 2770 // NB: no need to uninitialize locals, except if arrays/stats can
dff50e09 2771 // someday be local
4a6d3dfa 2772
c1969f1b 2773 o->indent(1);
05a072cf
JL
2774
2775 if (!v->probes_with_affected_conditions.empty())
2776 {
05a072cf
JL
2777 for (set<derived_probe*>::const_iterator
2778 it = v->probes_with_affected_conditions.begin();
2779 it != v->probes_with_affected_conditions.end(); ++it)
2780 emit_probe_condition_update(*it);
05a072cf
JL
2781 }
2782
90f98cc3 2783 if (v->needs_global_locks ())
3f3f4dd0 2784 emit_unlocks ();
b20febf3 2785
c1969f1b
DS
2786 // XXX: do this flush only if the body included a
2787 // print/printf/etc. routine!
2788 o->newline() << "_stp_print_flush();";
b20febf3 2789 o->newline(-1) << "}\n";
88bbd60d 2790 }
3066c15c 2791
3066c15c 2792 this->current_probe = 0;
8f8d261a 2793 this->already_checked_action_count = false;
2b066ec1
FCE
2794}
2795
05a072cf
JL
2796// Updates the cond_enabled field and sets need_module_refresh if it was
2797// changed.
2798void
2799c_unparser::emit_probe_condition_update(derived_probe* v)
2800{
2801 unsigned i = v->session_index;
2802 assert(i < session->probes.size());
2803
2804 expression *cond = v->sole_location()->condition;
2805 assert(cond);
2806
2807 string cond_enabled = "stap_probes[" + lex_cast(i) + "].cond_enabled";
2808
be855773
JL
2809 // Concurrency note: we're safe modifying cond_enabled here since we emit
2810 // locks not only for globals we write to, but also for globals read in other
2811 // probes' whose conditions we visit below (see in c_unparser::emit_probe). So
2812 // we can be assured we're the only ones modifying cond_enabled.
d02d9b1c 2813
05a072cf 2814 o->newline() << "if (" << cond_enabled << " != ";
d02d9b1c 2815 o->line() << "!!"; // NB: turn general integer into boolean 1 or 0
05a072cf
JL
2816 v->sole_location()->condition->visit(this);
2817 o->line() << ") {";
d02d9b1c 2818 o->newline(1) << cond_enabled << " ^= 1;"; // toggle it
ca6d3b0f 2819
4bf3d59d
JL
2820 // don't bother refreshing if on-the-fly not supported
2821 if (!session->runtime_usermode_p()
ca6d3b0f 2822 && v->group && v->group->otf_supported(*session))
6092ee9e 2823 o->newline() << "atomic_set(&need_module_refresh, 1);";
ca6d3b0f 2824
05a072cf
JL
2825 o->newline(-1) << "}";
2826}
2b066ec1 2827
dff50e09 2828void
29bb0bbc 2829c_unparser::emit_lock_decls(const varuse_collecting_visitor& vut)
3066c15c 2830{
29bb0bbc
JS
2831 unsigned numvars = 0;
2832
2833 if (session->verbose > 1)
a8f84c45
JL
2834 clog << "probe " << current_probe->session_index << " "
2835 "('" << *current_probe->sole_location() << "') locks";
29bb0bbc 2836
63438a79
JS
2837 // We can only make this static in kernel mode. In stapdyn mode,
2838 // the globals and their locks are in shared memory.
2839 o->newline();
2840 if (!session->runtime_usermode_p())
2841 o->line() << "static ";
2842 o->line() << "const struct stp_probe_lock locks[] = {";
29bb0bbc 2843 o->indent(1);
3066c15c 2844
3066c15c
FCE
2845 for (unsigned i = 0; i < session->globals.size(); i++)
2846 {
2847 vardecl* v = session->globals[i];
3f3f4dd0
JS
2848 bool read_p = vut.read.count(v) > 0;
2849 bool write_p = vut.written.count(v) > 0;
3066c15c
FCE
2850 if (!read_p && !write_p) continue;
2851
3f3f4dd0 2852 bool written_p;
3066c15c
FCE
2853 if (v->type == pe_stats) // read and write locks are flipped
2854 // Specifically, a "<<<" to a stats object is considered a
2855 // "shared-lock" operation, since it's implicitly done
2856 // per-cpu. But a "@op(x)" extraction is an "exclusive-lock"
2857 // one, as is a (sorted or unsorted) foreach, so those cases
2858 // are excluded by the w & !r condition below.
2859 {
2860 if (write_p && !read_p) { read_p = true; write_p = false; }
2861 else if (read_p && !write_p) { read_p = false; write_p = true; }
3f3f4dd0 2862 written_p = vcv_needs_global_locks.read.count(v) > 0;
3066c15c 2863 }
3f3f4dd0
JS
2864 else
2865 written_p = vcv_needs_global_locks.written.count(v) > 0;
3066c15c 2866
3be43eac
DS
2867 // We don't need to read lock "read-mostly" global variables. A
2868 // "read-mostly" global variable is only written to within
2869 // probes that don't need global variable locking (such as
2870 // begin/end probes). If vcv_needs_global_locks doesn't mark
2871 // the global as written to, then we don't have to lock it
2872 // here to read it safely.
3f3f4dd0
JS
2873 if (!written_p && read_p && !write_p)
2874 continue;
3be43eac 2875
29bb0bbc 2876 o->newline() << "{";
63438a79 2877 o->newline(1) << ".lock = global_lock(" + c_globalname(v->name) + "),";
29bb0bbc 2878 o->newline() << ".write_p = " << (write_p ? 1 : 0) << ",";
d9582a60 2879 o->newline() << "#ifdef STP_TIMING";
63438a79 2880 o->newline() << ".skipped = global_skipped(" << c_globalname (v->name) << "),";
d9582a60 2881 o->newline() << "#endif";
29bb0bbc 2882 o->newline(-1) << "},";
3066c15c 2883
29bb0bbc
JS
2884 numvars ++;
2885 if (session->verbose > 1)
a8f84c45
JL
2886 clog << " " << v->name << "[" << (read_p ? "r" : "")
2887 << (write_p ? "w" : "") << "]";
3066c15c
FCE
2888 }
2889
29bb0bbc 2890 o->newline(-1) << "};";
438cd7ed 2891
29bb0bbc
JS
2892 if (session->verbose > 1)
2893 {
2894 if (!numvars)
a8f84c45 2895 clog << _(" nothing");
29bb0bbc
JS
2896 clog << endl;
2897 }
3066c15c
FCE
2898}
2899
2900
dff50e09 2901void
3f3f4dd0 2902c_unparser::emit_locks()
3066c15c 2903{
29bb0bbc
JS
2904 o->newline() << "if (!stp_lock_probe(locks, ARRAY_SIZE(locks)))";
2905 o->newline(1) << "return;";
2906 o->indent(-1);
2907}
dff50e09 2908
3066c15c 2909
29bb0bbc 2910void
3f3f4dd0 2911c_unparser::emit_unlocks()
29bb0bbc
JS
2912{
2913 o->newline() << "stp_unlock_probe(locks, ARRAY_SIZE(locks));";
3066c15c
FCE
2914}
2915
2916
dff50e09 2917void
313b2f74 2918c_unparser::collect_map_index_types(vector<vardecl *> const & vars,
d23a2349 2919 set< pair<vector<exp_type>, exp_type> > & types)
313b2f74
GH
2920{
2921 for (unsigned i = 0; i < vars.size(); ++i)
2922 {
2923 vardecl *v = vars[i];
2924 if (v->arity > 0)
2925 {
d23a2349 2926 types.insert(make_pair(v->index_types, v->type));
313b2f74
GH
2927 }
2928 }
2929}
2930
2931string
2932mapvar::value_typename(exp_type e)
2933{
2934 switch (e)
2935 {
2936 case pe_long:
2937 return "INT64";
313b2f74
GH
2938 case pe_string:
2939 return "STRING";
313b2f74
GH
2940 case pe_stats:
2941 return "STAT";
313b2f74 2942 default:
dc09353a 2943 throw SEMANTIC_ERROR(_("array type is neither string nor long"));
03ad4de1 2944 }
313b2f74
GH
2945}
2946
2947string
2948mapvar::key_typename(exp_type e)
2949{
2950 switch (e)
2951 {
2952 case pe_long:
2953 return "INT64";
313b2f74
GH
2954 case pe_string:
2955 return "STRING";
313b2f74 2956 default:
dc09353a 2957 throw SEMANTIC_ERROR(_("array key is neither string nor long"));
dff50e09 2958 }
313b2f74
GH
2959}
2960
2961string
2962mapvar::shortname(exp_type e)
2963{
2964 switch (e)
2965 {
2966 case pe_long:
d23a2349 2967 return "i";
313b2f74 2968 case pe_string:
d23a2349 2969 return "s";
313b2f74 2970 default:
dc09353a 2971 throw SEMANTIC_ERROR(_("array type is neither string nor long"));
dff50e09 2972 }
313b2f74
GH
2973}
2974
0af18f5a
FL
2975string
2976c_unparser::map_keytypes(vardecl* v)
2977{
2978 string result;
2979 vector<exp_type> types = v->index_types;
2980 types.push_back (v->type);
2981 for (unsigned i = 0; i < types.size(); ++i)
2982 {
2983 switch (types[i])
2984 {
2985 case pe_long:
2986 result += 'i';
2987 break;
2988 case pe_string:
2989 result += 's';
2990 break;
2991 case pe_stats:
2992 result += 'x';
2993 break;
2994 default:
2995 throw SEMANTIC_ERROR(_("unknown type of map"));
2996 break;
2997 }
2998 }
2999 return result;
3000}
313b2f74
GH
3001
3002void
3003c_unparser::emit_map_type_instantiations ()
3004{
d23a2349 3005 set< pair<vector<exp_type>, exp_type> > types;
dff50e09 3006
d23a2349 3007 collect_map_index_types(session->globals, types);
313b2f74
GH
3008
3009 for (unsigned i = 0; i < session->probes.size(); ++i)
d23a2349 3010 collect_map_index_types(session->probes[i]->locals, types);
313b2f74 3011
f76427a2
FCE
3012 for (map<string,functiondecl*>::iterator it = session->functions.begin(); it != session->functions.end(); it++)
3013 collect_map_index_types(it->second->locals, types);
313b2f74 3014
07c17d67
GH
3015 if (!types.empty())
3016 o->newline() << "#include \"alloc.c\"";
3017
d23a2349
GH
3018 for (set< pair<vector<exp_type>, exp_type> >::const_iterator i = types.begin();
3019 i != types.end(); ++i)
313b2f74 3020 {
d23a2349
GH
3021 o->newline() << "#define VALUE_TYPE " << mapvar::value_typename(i->second);
3022 for (unsigned j = 0; j < i->first.size(); ++j)
313b2f74 3023 {
d23a2349 3024 string ktype = mapvar::key_typename(i->first.at(j));
313b2f74
GH
3025 o->newline() << "#define KEY" << (j+1) << "_TYPE " << ktype;
3026 }
3cb9c91e 3027 /* For statistics, flag map-gen to pull in nested pmap-gen too. */
07c17d67 3028 if (i->second == pe_stats)
3cb9c91e
JS
3029 o->newline() << "#define MAP_DO_PMAP 1";
3030 o->newline() << "#include \"map-gen.c\"";
3031 o->newline() << "#undef MAP_DO_PMAP";
d23a2349
GH
3032 o->newline() << "#undef VALUE_TYPE";
3033 for (unsigned j = 0; j < i->first.size(); ++j)
313b2f74
GH
3034 {
3035 o->newline() << "#undef KEY" << (j+1) << "_TYPE";
dff50e09 3036 }
313b2f74
GH
3037 }
3038
d23a2349 3039 if (!types.empty())
313b2f74 3040 o->newline() << "#include \"map.c\"";
07c17d67 3041
313b2f74
GH
3042};
3043
3044
2b066ec1 3045string
4383d78c 3046c_unparser::c_typename (exp_type e)
2b066ec1
FCE
3047{
3048 switch (e)
3049 {
3a20432b 3050 case pe_long: return string("int64_t");
dff50e09 3051 case pe_string: return string("string_t");
57b73400 3052 case pe_stats: return string("Stat");
dff50e09 3053 case pe_unknown:
2b066ec1 3054 default:
dc09353a 3055 throw SEMANTIC_ERROR (_("cannot expand unknown type"));
2b066ec1
FCE
3056 }
3057}
3058
3059
05e1f292
SM
3060// XXX: the below is just for the sake of example; it's possibly
3061// better to expose the hash function in hash.cxx
3062
3063// unsigned int
3064// do_hash (const char *e)
3065// {
3066// unsigned int foo = 0;
3067// while (*e) {
3068// foo *= 101; foo += *e; e++;
3069// }
3070// return foo;
3071// }
0386bbcf
SM
3072
3073
3074string
49b68a33 3075c_unparser::c_localname (const string& e, bool mangle_oldstyle)
0386bbcf 3076{
49b68a33 3077 if (strverscmp(session->compatible.c_str(), "1.8") < 0 || mangle_oldstyle)
0386bbcf
SM
3078 return e; // old mangling behaviour
3079 else
05e1f292
SM
3080// XXX: we may wish to invent and/or test other mangling schemes, e.g.:
3081// return "l_" + e + "_" + lex_cast(do_hash(e.c_str()));
0386bbcf
SM
3082 return "l_" + e;
3083}
3084
3085
3086string
3087c_unparser::c_globalname (const string& e)
3088{
acb811fc
SM
3089 // XXX uncomment to test custom mangling:
3090 // return "s_" + e + "_" + lex_cast(do_hash(e.c_str()));
0386bbcf
SM
3091 return "s_" + e;
3092}
3093
3094
3095string
3096c_unparser::c_funcname (const string& e)
3097{
acb811fc
SM
3098 // XXX uncomment to test custom mangling:
3099 // return "function_" + e + "_" + lex_cast(do_hash(e.c_str()));
0386bbcf
SM
3100 return "function_" + e;
3101}
3102
3103
3104string
3105c_unparser::c_arg_define (const string& e)
3106{
9e1830b9 3107 return "#define STAP_ARG_" + e + " THIS->" + c_localname(e);
0386bbcf
SM
3108}
3109
3110
313b2f74 3111string
0386bbcf 3112c_unparser::c_arg_undef (const string& e)
313b2f74 3113{
0386bbcf 3114 return "#undef STAP_ARG_" + e;
313b2f74
GH
3115}
3116
0af18f5a
FL
3117void
3118c_unparser::c_global_write_def(vardecl* v)
3119{
3120 if (v->arity > 0)
3121 {
8e95959e 3122 o->newline() << "#define STAP_GLOBAL_SET_" << v->unmangled_name << "(...) "
0af18f5a
FL
3123 << "({int rc = _stp_map_set_" << map_keytypes(v)
3124 << "(global(" << c_globalname(v->name) << "), __VA_ARGS__); "
3125 << "if (unlikely(rc)) { c->last_error = " << STAP_T_01
3126 << lex_cast(v->maxsize > 0 ? "size limit (" + lex_cast(v->maxsize)
3127 + ")" : "MAXMAPENTRIES") + "\"; goto out; } rc;})";
3128 }
3129 else
3130 {
8e95959e 3131 o->newline() << "#define STAP_GLOBAL_SET_" << v->unmangled_name << "(val) ";
0af18f5a
FL
3132 if (v->type == pe_string)
3133 o->line() << "strlcpy(global(" << c_globalname(v->name) << "), val, MAXSTRINGLEN)";
3134 else if (v->type == pe_long)
3135 o->line() << "global_set(" << c_globalname(v->name) << ", val)";
3136 }
3137}
3138
3139void
3140c_unparser::c_global_read_def(vardecl* v)
3141{
3142 if (v->arity > 0)
3143 {
8e95959e 3144 o->newline() << "#define STAP_GLOBAL_GET_" << v->unmangled_name << "(...) "
0af18f5a
FL
3145 << "_stp_map_get_" << map_keytypes(v)
3146 << "(global(" << c_globalname(v->name) << "), __VA_ARGS__)";
3147 }
3148 else
3149 {
8e95959e 3150 o->newline() << "#define STAP_GLOBAL_GET_" << v->unmangled_name << "() "
0af18f5a
FL
3151 << "global(" << c_globalname(v->name) << ")";
3152 }
3153}
3154
3155void
3156c_unparser::c_global_write_undef(vardecl* v)
3157{
8e95959e 3158 o->newline() << "#undef STAP_GLOBAL_SET_" << v->unmangled_name;
0af18f5a
FL
3159}
3160
3161void
3162c_unparser::c_global_read_undef(vardecl* v)
3163{
8e95959e 3164 o->newline() << "#undef STAP_GLOBAL_GET_" << v->unmangled_name;
0af18f5a 3165}
11b52b73 3166
dff50e09 3167void
67c0a579 3168c_unparser::c_assign (var& lvalue, const string& rvalue, const token *tok)
dff50e09 3169{
67c0a579
GH
3170 switch (lvalue.type())
3171 {
3172 case pe_string:
11b52b73 3173 c_strcpy(lvalue.value(), rvalue);
67c0a579
GH
3174 break;
3175 case pe_long:
3176 o->newline() << lvalue << " = " << rvalue << ";";
3177 break;
3178 default:
dc09353a 3179 throw SEMANTIC_ERROR (_("unknown lvalue type in assignment"), tok);
67c0a579
GH
3180 }
3181}
313b2f74 3182
412c6fe4 3183
b2d74f03
JS
3184void
3185c_unparser::c_assign(tmpvar& t, expression *e, const char* msg)
3186{
3187 // We don't really need a tmpvar if the expression is a literal.
3188 // (NB: determined by the expression itself, not tok->type!)
3189
3190 if (dynamic_cast<literal*>(e))
3191 {
3192 // We need to use the visitors to get proper C values, like
3193 // "((int64_t)5LL)" for numbers and escaped characters in strings.
3194
3195 // Create a fake output stream so we can grab the string output.
3196 ostringstream oss;
3197 translator_output tmp_o(oss);
3198
3199 // Temporarily swap out the real translator_output stream with our
3200 // fake one.
3201 translator_output *saved_o = o;
3202 o = &tmp_o;
3203
3204 // Visit the expression then restore the original output stream
3205 e->visit (this);
3206 o = saved_o;
3207
3208 // All instances of this tmpvar will use the literal value.
3209 t.override (oss.str());
3210 }
3211 else
3212 c_assign (t.value(), e, msg);
3213}
3214
f281029c 3215struct expression_is_functioncall : public nop_visitor
412c6fe4 3216{
412c6fe4 3217 functioncall* fncall;
f281029c
JS
3218 expression_is_functioncall ()
3219 : fncall(NULL) {}
412c6fe4 3220
412c6fe4
AJ
3221 void visit_functioncall (functioncall* e)
3222 {
3223 fncall = e;
3224 }
3225};
3226
313b2f74
GH
3227void
3228c_unparser::c_assign (const string& lvalue, expression* rvalue,
b2d74f03 3229 const char* msg)
313b2f74
GH
3230{
3231 if (rvalue->type == pe_long)
3232 {
3233 o->newline() << lvalue << " = ";
3234 rvalue->visit (this);
3235 o->line() << ";";
3236 }
3237 else if (rvalue->type == pe_string)
3238 {
f281029c 3239 expression_is_functioncall eif;
412c6fe4
AJ
3240 rvalue->visit(& eif);
3241 if (!session->unoptimized && eif.fncall)
cfaa0635 3242 {
296c059b
JS
3243 const functioncall* saved_fncall = assigned_functioncall;
3244 const string* saved_retval = assigned_functioncall_retval;
3245
cfaa0635 3246 // let the functioncall know that the return value is being saved/used
6c22bc26
AJ
3247 // and keep track of the lvalue, so that the retval assignment can
3248 // happen in ::visit_functioncall, to avoid complications with nesting.
296c059b
JS
3249 assigned_functioncall = eif.fncall;
3250 assigned_functioncall_retval = &lvalue;
412c6fe4 3251 eif.fncall->visit (this);
cfaa0635 3252 o->line() << ";";
296c059b
JS
3253
3254 assigned_functioncall = saved_fncall;
3255 assigned_functioncall_retval = saved_retval;
cfaa0635
AJ
3256 }
3257 else
3258 {
3259 // will call rvalue->visit()
3260 c_strcpy (lvalue, rvalue);
3261 }
313b2f74
GH
3262 }
3263 else
3264 {
b2d74f03 3265 string fullmsg = string(msg) + _(" type unsupported");
dc09353a 3266 throw SEMANTIC_ERROR (fullmsg, rvalue->tok);
313b2f74
GH
3267 }
3268}
3269
3270
3271void
3272c_unparser::c_assign (const string& lvalue, const string& rvalue,
b2d74f03 3273 exp_type type, const char* msg, const token* tok)
313b2f74
GH
3274{
3275 if (type == pe_long)
3276 {
3277 o->newline() << lvalue << " = " << rvalue << ";";
3278 }
3279 else if (type == pe_string)
3280 {
3281 c_strcpy (lvalue, rvalue);
3282 }
3283 else
3284 {
b2d74f03 3285 string fullmsg = string(msg) + _(" type unsupported");
dc09353a 3286 throw SEMANTIC_ERROR (fullmsg, tok);
313b2f74
GH
3287 }
3288}
3289
3290
dff50e09
FCE
3291void
3292c_unparser_assignment::c_assignop(tmpvar & res,
3293 var const & lval,
313b2f74
GH
3294 tmpvar const & rval,
3295 token const * tok)
3296{
3297 // This is common code used by scalar and array-element assignments.
3298 // It assumes an operator-and-assignment (defined by the 'pre' and
3299 // 'op' fields of c_unparser_assignment) is taking place between the
3300 // following set of variables:
3301 //
11b52b73 3302 // res: the result of evaluating the expression, a temporary
313b2f74 3303 // lval: the lvalue of the expression, which may be damaged
11b52b73 3304 // rval: the rvalue of the expression, which is a temporary or constant
313b2f74 3305
dff50e09 3306 // we'd like to work with a local tmpvar so we can overwrite it in
313b2f74 3307 // some optimized cases
67c0a579 3308
313b2f74
GH
3309 translator_output* o = parent->o;
3310
3311 if (res.type() == pe_string)
3312 {
78110925 3313 if (post)
dc09353a 3314 throw SEMANTIC_ERROR (_("post assignment on strings not supported"),
313b2f74
GH
3315 tok);
3316 if (op == "=")
3317 {
11b52b73 3318 parent->c_strcpy (lval.value(), rval.value());
313b2f74
GH
3319 // no need for second copy
3320 res = rval;
b5f561be 3321 }
313b2f74
GH
3322 else if (op == ".=")
3323 {
11b52b73
DS
3324 parent->c_strcat (lval.value(), rval.value());
3325 res = lval;
313b2f74
GH
3326 }
3327 else
7371cd19
JS
3328 throw SEMANTIC_ERROR (_F("string assignment operator %s unsupported",
3329 op.to_string().c_str()), tok);
313b2f74 3330 }
57b73400
GH
3331 else if (op == "<<<")
3332 {
3333 assert(lval.type() == pe_stats);
3334 assert(rval.type() == pe_long);
3335 assert(res.type() == pe_long);
0f1a1dda
FCE
3336 o->newline() << "_stp_stat_add (" << lval << ", " << rval << ");";
3337 res = rval;
57b73400 3338 }
313b2f74
GH
3339 else if (res.type() == pe_long)
3340 {
3341 // a lot of operators come through this "gate":
3342 // - vanilla assignment "="
3343 // - stats aggregation "<<<"
3344 // - modify-accumulate "+=" and many friends
3345 // - pre/post-crement "++"/"--"
3a20432b 3346 // - "/" and "%" operators, but these need special handling in kernel
313b2f74
GH
3347
3348 // compute the modify portion of a modify-accumulate
3349 string macop;
3350 unsigned oplen = op.size();
3351 if (op == "=")
3a20432b 3352 macop = "*error*"; // special shortcuts below
11b52b73 3353 else if (op == "++" || op == "+=")
53362f0e 3354 macop = "+=";
11b52b73
DS
3355 else if (op == "--" || op == "-=")
3356 macop = "-=";
53362f0e 3357 else if (oplen > 1 && op[oplen-1] == '=') // for *=, <<=, etc...
47d349b1 3358 macop = op;
313b2f74
GH
3359 else
3360 // internal error
dc09353a 3361 throw SEMANTIC_ERROR (_("unknown macop for assignment"), tok);
3a20432b 3362
78110925 3363 if (post)
313b2f74 3364 {
3a20432b 3365 if (macop == "/" || macop == "%" || op == "=")
dc09353a 3366 throw SEMANTIC_ERROR (_("invalid post-mode operator"), tok);
3a20432b 3367
313b2f74 3368 o->newline() << res << " = " << lval << ";";
11b52b73
DS
3369
3370 if (macop == "+=" || macop == "-=")
3371 o->newline() << lval << " " << macop << " " << rval << ";";
3372 else
3373 o->newline() << lval << " = " << res << " " << macop << " " << rval << ";";
313b2f74
GH
3374 }
3375 else
3376 {
3a20432b 3377 if (op == "=") // shortcut simple assignment
11b52b73 3378 {
53362f0e
DS
3379 o->newline() << lval << " = " << rval << ";";
3380 res = rval;
11b52b73 3381 }
12363146
JS
3382 else
3383 {
3384 if (macop == "/=" || macop == "%=")
3385 {
3386 o->newline() << "if (unlikely(!" << rval << ")) {";
b5f561be
LB
3387 o->newline(1) << "c->last_error = ";
3388 o->line() << STAP_T_03;
54975cd8 3389 o->newline() << "c->last_stmt = " << lex_cast_qstring(*rvalue->tok) << ";";
12363146
JS
3390 o->newline() << "goto out;";
3391 o->newline(-1) << "}";
3392 o->newline() << lval << " = "
3393 << ((macop == "/=") ? "_stp_div64" : "_stp_mod64")
3394 << " (NULL, " << lval << ", " << rval << ");";
3395 }
53362f0e
DS
3396 else
3397 o->newline() << lval << " " << macop << " " << rval << ";";
3398 res = lval;
12363146 3399 }
313b2f74
GH
3400 }
3401 }
3402 else
dc09353a 3403 throw SEMANTIC_ERROR (_("assignment type not yet implemented"), tok);
313b2f74
GH
3404}
3405
3406
dff50e09 3407void
0386bbcf 3408c_unparser::c_declare(exp_type ty, const string &ident)
313b2f74 3409{
0386bbcf 3410 o->newline() << c_typename (ty) << " " << ident << ";";
313b2f74
GH
3411}
3412
3413
dff50e09 3414void
0386bbcf 3415c_unparser::c_declare_static(exp_type ty, const string &ident)
313b2f74 3416{
0386bbcf 3417 o->newline() << "static " << c_typename (ty) << " " << ident << ";";
313b2f74
GH
3418}
3419
3420
dff50e09
FCE
3421void
3422c_unparser::c_strcpy (const string& lvalue, const string& rvalue)
313b2f74 3423{
dff50e09
FCE
3424 o->newline() << "strlcpy ("
3425 << lvalue << ", "
313b2f74
GH
3426 << rvalue << ", MAXSTRINGLEN);";
3427}
3428
3429
dff50e09
FCE
3430void
3431c_unparser::c_strcpy (const string& lvalue, expression* rvalue)
2b066ec1 3432{
7d46afb8 3433 o->newline() << "strlcpy (" << lvalue << ", ";
313b2f74
GH
3434 rvalue->visit (this);
3435 o->line() << ", MAXSTRINGLEN);";
2b066ec1
FCE
3436}
3437
3438
dff50e09
FCE
3439void
3440c_unparser::c_strcat (const string& lvalue, const string& rvalue)
ce10591c 3441{
dff50e09
FCE
3442 o->newline() << "strlcat ("
3443 << lvalue << ", "
7d46afb8 3444 << rvalue << ", MAXSTRINGLEN);";
ce10591c
FCE
3445}
3446
3447
dff50e09
FCE
3448void
3449c_unparser::c_strcat (const string& lvalue, expression* rvalue)
ce10591c 3450{
7d46afb8 3451 o->newline() << "strlcat (" << lvalue << ", ";
313b2f74
GH
3452 rvalue->visit (this);
3453 o->line() << ", MAXSTRINGLEN);";
3454}
3455
3456
3457bool
3458c_unparser::is_local(vardecl const *r, token const *tok)
dff50e09 3459{
313b2f74 3460 if (current_probe)
ce10591c 3461 {
313b2f74
GH
3462 for (unsigned i=0; i<current_probe->locals.size(); i++)
3463 {
3464 if (current_probe->locals[i] == r)
3465 return true;
3466 }
ce10591c 3467 }
313b2f74 3468 else if (current_function)
ce10591c 3469 {
313b2f74
GH
3470 for (unsigned i=0; i<current_function->locals.size(); i++)
3471 {
3472 if (current_function->locals[i] == r)
3473 return true;
3474 }
3475
3476 for (unsigned i=0; i<current_function->formal_args.size(); i++)
3477 {
3478 if (current_function->formal_args[i] == r)
3479 return true;
3480 }
ce10591c 3481 }
313b2f74
GH
3482
3483 for (unsigned i=0; i<session->globals.size(); i++)
ce10591c 3484 {
313b2f74
GH
3485 if (session->globals[i] == r)
3486 return false;
ce10591c 3487 }
dff50e09 3488
313b2f74 3489 if (tok)
dc09353a 3490 throw SEMANTIC_ERROR (_("unresolved symbol"), tok);
313b2f74 3491 else
47d349b1 3492 throw SEMANTIC_ERROR (_("unresolved symbol: ") + (string)r->name);
313b2f74
GH
3493}
3494
3495
dff50e09
FCE
3496tmpvar
3497c_unparser::gensym(exp_type ty)
3498{
0386bbcf 3499 return tmpvar (this, ty, tmpvar_counter);
ce10591c
FCE
3500}
3501
dff50e09
FCE
3502aggvar
3503c_unparser::gensym_aggregate()
3504{
0386bbcf 3505 return aggvar (this, tmpvar_counter);
07c17d67
GH
3506}
3507
ce10591c 3508
dff50e09
FCE
3509var
3510c_unparser::getvar(vardecl *v, token const *tok)
3511{
57b73400 3512 bool loc = is_local (v, tok);
dff50e09 3513 if (loc)
0386bbcf 3514 return var (this, loc, v->type, v->name);
57b73400
GH
3515 else
3516 {
3517 statistic_decl sd;
47d349b1 3518 std::map<interned_string, statistic_decl>::const_iterator i;
57b73400
GH
3519 i = session->stat_decls.find(v->name);
3520 if (i != session->stat_decls.end())
3521 sd = i->second;
0386bbcf 3522 return var (this, loc, v->type, sd, v->name);
57b73400 3523 }
313b2f74
GH
3524}
3525
3526
dff50e09
FCE
3527mapvar
3528c_unparser::getmap(vardecl *v, token const *tok)
3529{
d98d459c 3530 if (v->arity < 1)
dc09353a 3531 throw SEMANTIC_ERROR(_("attempt to use scalar where map expected"), tok);
57b73400 3532 statistic_decl sd;
47d349b1 3533 std::map<interned_string, statistic_decl>::const_iterator i;
57b73400
GH
3534 i = session->stat_decls.find(v->name);
3535 if (i != session->stat_decls.end())
3536 sd = i->second;
0386bbcf 3537 return mapvar (this, is_local (v, tok), v->type, sd,
74e6cc92 3538 v->name, v->index_types, v->maxsize, v->wrap);
313b2f74
GH
3539}
3540
4383d78c 3541
dff50e09 3542itervar
d02548c0 3543c_unparser::getiter(symbol *s)
dff50e09 3544{
d6d4dc4b 3545 return itervar (this, s, tmpvar_counter);
67c0a579
GH
3546}
3547
3548
9d0808b4
JS
3549// Queue up some actions to remove from actionremaining. Set update=true at
3550// the end of basic blocks to actually update actionremaining and check it
3551// against MAXACTION.
5e309481 3552void
54975cd8 3553c_unparser::record_actions (unsigned actions, const token* tok, bool update)
5e309481 3554{
9d0808b4 3555 action_counter += actions;
a7c9924b 3556
9d0808b4
JS
3557 // Update if needed, or after queueing up a few actions, in case of very
3558 // large code sequences.
ad534e14
AJ
3559 if (((update && action_counter > 0) || action_counter >= 10/*<-arbitrary*/)
3560 && !session->suppress_time_limits && !already_checked_action_count)
5e309481 3561 {
ad534e14 3562
9d0808b4 3563 o->newline() << "c->actionremaining -= " << action_counter << ";";
29fdb4e4 3564 o->newline() << "if (unlikely (c->actionremaining <= 0)) {";
b5f561be
LB
3565 o->newline(1) << "c->last_error = ";
3566 o->line() << STAP_T_04;
63ea4244
JS
3567
3568 // XXX it really ought to be illegal for anything to be missing a token,
3569 // but until we're sure of that, we need to defend against NULL.
3570 if (tok)
3571 o->newline() << "c->last_stmt = " << lex_cast_qstring(*tok) << ";";
3572
12363146 3573 o->newline() << "goto out;";
5e309481 3574 o->newline(-1) << "}";
9d0808b4 3575 action_counter = 0;
5e309481
FCE
3576 }
3577}
3578
3579
2b066ec1 3580void
4383d78c 3581c_unparser::visit_block (block *s)
2b066ec1 3582{
d6d4dc4b
JS
3583 // Key insight: individual statements of a block can reuse
3584 // temporary variable slots, since temporaries don't survive
3585 // statement boundaries. So we use gcc's anonymous union/struct
3586 // facility to explicitly overlay the temporaries.
7d1e27af 3587 start_compound_statement ("block_statement", s);
d6d4dc4b 3588
2b066ec1
FCE
3589 o->newline() << "{";
3590 o->indent (1);
a7c9924b 3591
2b066ec1
FCE
3592 for (unsigned i=0; i<s->statements.size(); i++)
3593 {
3594 try
3595 {
7d1e27af 3596 wrap_compound_visit (s->statements[i]);
2b066ec1
FCE
3597 o->newline();
3598 }
3599 catch (const semantic_error& e)
3600 {
3601 session->print_error (e);
3602 }
3603 }
3604 o->newline(-1) << "}";
2b066ec1 3605
7d1e27af
JS
3606 close_compound_statement ("block_statement", s);
3607}
2b066ec1 3608
d74a7874 3609
f4fe2e93
FCE
3610void c_unparser::visit_try_block (try_block *s)
3611{
0940fad9
JS
3612 record_actions(0, s->tok, true); // flush prior actions
3613
7d1e27af
JS
3614 start_compound_statement ("try_block", s);
3615
f4fe2e93 3616 o->newline() << "{";
0940fad9 3617 o->newline(1) << "__label__ normal_fallthrough;";
f4fe2e93
FCE
3618 o->newline(1) << "{";
3619 o->newline() << "__label__ out;";
3620
3621 assert (!session->unoptimized || s->try_block); // dead_stmtexpr_remover would zap it
3622 if (s->try_block)
54975cd8 3623 {
7d1e27af 3624 wrap_compound_visit (s->try_block);
54975cd8
JS
3625 record_actions(0, s->try_block->tok, true); // flush accumulated actions
3626 }
0940fad9 3627 o->newline() << "goto normal_fallthrough;";
54975cd8 3628
f4fe2e93
FCE
3629 o->newline() << "if (0) goto out;"; // to prevent 'unused label' warnings
3630 o->newline() << "out:";
0940fad9
JS
3631 o->newline() << ";"; // to have _some_ statement
3632
3633 // Close the scope of the above nested 'out' label, to make sure
3634 // that the catch block, should it encounter errors, does not resolve
3635 // a 'goto out;' to the above label, causing infinite looping.
3636 o->newline(-1) << "}";
3637
3638 o->newline() << "if (likely(c->last_error == NULL)) goto out;";
3639
f4fe2e93
FCE
3640 if (s->catch_error_var)
3641 {
3642 var cev(getvar(s->catch_error_var->referent, s->catch_error_var->tok));
3643 c_strcpy (cev.value(), "c->last_error");
3644 }
3645 o->newline() << "c->last_error = NULL;";
3646
f4fe2e93 3647 // Prevent the catch{} handler from even starting if MAXACTIONS have
54975cd8
JS
3648 // already been used up. Add one for the act of catching too.
3649 record_actions(1, s->tok, true);
3650
f4fe2e93 3651 if (s->catch_block)
54975cd8 3652 {
7d1e27af 3653 wrap_compound_visit (s->catch_block);
54975cd8
JS
3654 record_actions(0, s->catch_block->tok, true); // flush accumulated actions
3655 }
3656
0940fad9 3657 o->newline() << "normal_fallthrough:";
f4fe2e93
FCE
3658 o->newline() << ";"; // to have _some_ statement
3659 o->newline(-1) << "}";
7d1e27af
JS
3660
3661 close_compound_statement ("try_block", s);
f4fe2e93
FCE
3662}
3663
3664
54dfabe9
FCE
3665void
3666c_unparser::visit_embeddedcode (embeddedcode *s)
3667{
2363d2a5
DB
3668 // Automatically add a call to assert_is_myproc to any code tagged with
3669 // /* myproc-unprivileged */
3670 if (s->code.find ("/* myproc-unprivileged */") != string::npos)
3671 o->newline() << "assert_is_myproc();";
5e309481 3672 o->newline() << "{";
0af18f5a
FL
3673
3674 vector<vardecl*> read_defs;
3675 vector<vardecl*> write_defs;
3676 for (unsigned i = 0; i < session->globals.size(); i++)
3677 {
3678 vardecl* v = session->globals[i];
8e95959e 3679 string name = v->unmangled_name;
0af18f5a
FL
3680 if (s->code.find("/* pragma:read:" + name + " */") != string::npos)
3681 {
3682 c_global_read_def(v);
3683 read_defs.push_back(v);
3684 }
3685 if (s->code.find("/* pragma:write:" + name + " */") != string::npos)
3686 {
3687 c_global_write_def(v);
3688 write_defs.push_back(v);
3689 }
3690 }
3691
5e309481 3692 o->newline(1) << s->code;
0af18f5a
FL
3693 o->indent(-1);
3694
3695 for (vector<vardecl*>::const_iterator it = read_defs.begin(); it != read_defs.end(); ++it)
3696 c_global_read_undef(*it);
3697 for (vector<vardecl*>::const_iterator it = write_defs.begin(); it != write_defs.end(); ++it)
3698 c_global_write_undef(*it);
3699
3700 o->newline() << "}";
54dfabe9
FCE
3701}
3702
3703
2b066ec1 3704void
78f6bba6 3705c_unparser::visit_null_statement (null_statement *)
2b066ec1 3706{
2b066ec1
FCE
3707 o->newline() << "/* null */;";
3708}
3709
3710
3711void
4383d78c 3712c_unparser::visit_expr_statement (expr_statement *s)
2b066ec1 3713{
2b066ec1
FCE
3714 o->newline() << "(void) ";
3715 s->value->visit (this);
3716 o->line() << ";";
54975cd8 3717 record_actions(1, s->tok);
2b066ec1
FCE
3718}
3719
3720
395146b5 3721void
7d1e27af 3722c_tmpcounter::wrap_compound_visit (statement *s)
395146b5 3723{
d6d4dc4b
JS
3724 if (!s) return;
3725
395146b5
AJ
3726 std::ostream::pos_type before_struct_pos;
3727 std::ostream::pos_type after_struct_pos;
3728
3729 start_struct_def(before_struct_pos, after_struct_pos, s->tok);
7d1e27af 3730 c_unparser::wrap_compound_visit (s);
395146b5
AJ
3731 close_struct_def(before_struct_pos, after_struct_pos);
3732}
3733
3734void
7d1e27af 3735c_tmpcounter::wrap_compound_visit (expression *e)
395146b5 3736{
d6d4dc4b
JS
3737 if (!e) return;
3738
395146b5
AJ
3739 std::ostream::pos_type before_struct_pos;
3740 std::ostream::pos_type after_struct_pos;
3741
3742 start_struct_def(before_struct_pos, after_struct_pos, e->tok);
7d1e27af 3743 c_unparser::wrap_compound_visit (e);
395146b5
AJ
3744 close_struct_def(before_struct_pos, after_struct_pos);
3745}
3746
3747void
3748c_tmpcounter::start_struct_def (std::ostream::pos_type &before,
3749 std::ostream::pos_type &after, const token* tok)
3750{
3751 // To avoid lots of empty structs, remember where we are now. Then,
3752 // output the struct start and remember that positon. If when we get
3753 // done with the statement we haven't moved, then we don't really need
3754 // the struct. To get rid of the struct start we output, we'll seek back
3755 // to where we were before we output the struct (done in ::close_struct_def).
d6d4dc4b
JS
3756 translator_output *o = parent->o;
3757 before = o->tellp();
3758 o->newline() << "struct { /* source: " << tok->location.file->name
3759 << ":" << lex_cast(tok->location.line) << " */";
3760 o->indent(1);
3761 after = o->tellp();
395146b5
AJ
3762}
3763
3764void
3765c_tmpcounter::close_struct_def (std::ostream::pos_type before,
3766 std::ostream::pos_type after)
3767{
3768 // meant to be used with ::start_struct_def. remove the struct if empty.
d6d4dc4b
JS
3769 translator_output *o = parent->o;
3770 o->indent(-1);
3771 if (after == o->tellp())
3772 o->seekp(before);
395146b5 3773 else
d6d4dc4b 3774 o->newline() << "};";
395146b5
AJ
3775}
3776
d74a7874 3777void
7d1e27af 3778c_tmpcounter::start_compound_statement (const char* tag, statement *s)
d74a7874 3779{
7d1e27af 3780 const source_loc& loc = s->tok->location;
d6d4dc4b
JS
3781 translator_output *o = parent->o;
3782 o->newline() << "union { /* " << tag << ": "
7d1e27af
JS
3783 << loc.file->name << ":"
3784 << lex_cast(loc.line) << " */";
d6d4dc4b
JS
3785 o->indent(1);
3786}
d74a7874 3787
d6d4dc4b 3788void
7d1e27af 3789c_tmpcounter::close_compound_statement (const char*, statement *)
d6d4dc4b
JS
3790{
3791 translator_output *o = parent->o;
3792 o->newline(-1) << "};";
d74a7874
AJ
3793}
3794
d74a7874 3795
2b066ec1 3796void
4383d78c 3797c_unparser::visit_if_statement (if_statement *s)
2b066ec1 3798{
54975cd8 3799 record_actions(1, s->tok, true);
7d1e27af
JS
3800
3801 start_compound_statement ("if_statement", s);
3802
2b066ec1
FCE
3803 o->newline() << "if (";
3804 o->indent (1);
7d1e27af 3805 wrap_compound_visit (s->condition);
2b066ec1
FCE
3806 o->indent (-1);
3807 o->line() << ") {";
3808 o->indent (1);
7d1e27af 3809 wrap_compound_visit (s->thenblock);
54975cd8 3810 record_actions(0, s->thenblock->tok, true);
2b066ec1
FCE
3811 o->newline(-1) << "}";
3812 if (s->elseblock)
3813 {
3814 o->newline() << "else {";
3815 o->indent (1);
7d1e27af 3816 wrap_compound_visit (s->elseblock);
54975cd8 3817 record_actions(0, s->elseblock->tok, true);
2b066ec1
FCE
3818 o->newline(-1) << "}";
3819 }
2b066ec1 3820
7d1e27af 3821 close_compound_statement ("if_statement", s);
bb788f9f
FCE
3822}
3823
3824
2b066ec1 3825void
4383d78c 3826c_unparser::visit_for_loop (for_loop *s)
2b066ec1 3827{
aca66a36 3828 string ctr = lex_cast (label_counter++);
bb788f9f 3829 string toplabel = "top_" + ctr;
f3c26ea5
FCE
3830 string contlabel = "continue_" + ctr;
3831 string breaklabel = "break_" + ctr;
3832
7d1e27af
JS
3833 start_compound_statement ("for_loop", s);
3834
bb788f9f 3835 // initialization
7d1e27af 3836 wrap_compound_visit (s->init);
54975cd8 3837 record_actions(1, s->tok, true);
f3c26ea5 3838
bb788f9f
FCE
3839 // condition
3840 o->newline(-1) << toplabel << ":";
a7c9924b 3841
29fdb4e4
DS
3842 // Emit an explicit action here to cover the act of iteration.
3843 // Equivalently, it can stand for the evaluation of the condition
3844 // expression.
a7c9924b 3845 o->indent(1);
54975cd8 3846 record_actions(1, s->tok);
a7c9924b
FCE
3847
3848 o->newline() << "if (! (";
f3c26ea5 3849 if (s->cond->type != pe_long)
dc09353a 3850 throw SEMANTIC_ERROR (_("expected numeric type"), s->cond->tok);
7d1e27af 3851 wrap_compound_visit (s->cond);
f3c26ea5
FCE
3852 o->line() << ")) goto " << breaklabel << ";";
3853
bb788f9f 3854 // body
f3c26ea5
FCE
3855 loop_break_labels.push_back (breaklabel);
3856 loop_continue_labels.push_back (contlabel);
7d1e27af 3857 wrap_compound_visit (s->block);
54975cd8 3858 record_actions(0, s->block->tok, true);
f3c26ea5
FCE
3859 loop_break_labels.pop_back ();
3860 loop_continue_labels.pop_back ();
3861
bb788f9f
FCE
3862 // iteration
3863 o->newline(-1) << contlabel << ":";
3864 o->indent(1);
7d1e27af 3865 wrap_compound_visit (s->incr);
bb788f9f 3866 o->newline() << "goto " << toplabel << ";";
f3c26ea5 3867
bb788f9f
FCE
3868 // exit
3869 o->newline(-1) << breaklabel << ":";
3870 o->newline(1) << "; /* dummy statement */";
7d1e27af
JS
3871
3872 close_compound_statement ("for_loop", s);
2b066ec1
FCE
3873}
3874
3875
71572ba8
GH
3876struct arrayindex_downcaster
3877 : public traversing_visitor
3878{
3879 arrayindex *& arr;
dff50e09 3880
71572ba8 3881 arrayindex_downcaster (arrayindex *& arr)
dff50e09 3882 : arr(arr)
71572ba8
GH
3883 {}
3884
3885 void visit_arrayindex (arrayindex* e)
3886 {
3887 arr = e;
3888 }
3889};
3890
3891
3892static bool
dff50e09 3893expression_is_arrayindex (expression *e,
71572ba8
GH
3894 arrayindex *& hist)
3895{
3896 arrayindex *h = NULL;
3897 arrayindex_downcaster d(h);
3898 e->visit (&d);
3899 if (static_cast<void*>(h) == static_cast<void*>(e))
3900 {
3901 hist = h;
3902 return true;
3903 }
3904 return false;
3905}
3906
3907
bdc82277
JS
3908// Look for opportunities to used a saved value at the beginning of the loop
3909void
d6d4dc4b 3910c_unparser::visit_foreach_loop_value (foreach_loop* s, const string& value)
bdc82277
JS
3911{
3912 bool stable_value = false;
3913
3914 // There are three possible cases that we might easily retrieve the value:
3915 // 1. foreach ([keys] in any_array_type)
3916 // 2. foreach (idx in @hist_*(stat))
3917 // 3. foreach (idx in @hist_*(stat[keys]))
3918 //
3919 // For 1 and 2, we just need to check that the keys/idx are const throughout
3920 // the loop. For 3, we'd have to check also that the arbitrary keys
3921 // expressions indexing the stat are const -- much harder, so I'm punting
3922 // that case for now.
3923
3924 symbol *array;
3925 hist_op *hist;
3926 classify_indexable (s->base, array, hist);
3927
3928 if (!(hist && get_symbol_within_expression(hist->stat)->referent->arity > 0))
3929 {
3930 set<vardecl*> indexes;
3931 for (unsigned i=0; i < s->indexes.size(); ++i)
3932 indexes.insert(s->indexes[i]->referent);
3933
3934 varuse_collecting_visitor v(*session);
3935 s->block->visit (&v);
3936 v.embedded_seen = false; // reset because we only care about the indexes
3937 if (v.side_effect_free_wrt(indexes))
3938 stable_value = true;
3939 }
3940
3941 if (stable_value)
3942 {
3943 // Rather than trying to compare arrayindexes to this foreach_loop
3944 // manually, we just create a fake arrayindex that would match the
3945 // foreach_loop, render it as a string, and later render encountered
3946 // arrayindexes as strings and compare.
3947 arrayindex ai;
3948 ai.base = s->base;
3949 for (unsigned i=0; i < s->indexes.size(); ++i)
3950 ai.indexes.push_back(s->indexes[i]);
3951 string loopai = lex_cast(ai);
3952 foreach_loop_values[loopai] = value;
d6d4dc4b 3953 s->block->visit (this);
bdc82277
JS
3954 foreach_loop_values.erase(loopai);
3955 }
3956 else
d6d4dc4b 3957 s->block->visit (this);
bdc82277
JS
3958}
3959
3960
3961bool
3962c_unparser::get_foreach_loop_value (arrayindex* ai, string& value)
3963{
3964 if (!ai)
3965 return false;
3966 map<string,string>::iterator it = foreach_loop_values.find(lex_cast(*ai));
3967 if (it == foreach_loop_values.end())
3968 return false;
3969 value = it->second;
3970 return true;
3971}
3972
3973
69c68955
FCE
3974void
3975c_unparser::visit_foreach_loop (foreach_loop *s)
3976{
dff50e09 3977 symbol *array;
d02548c0
GH
3978 hist_op *hist;
3979 classify_indexable (s->base, array, hist);
5e309481 3980
8e00730c
JS
3981 string ctr = lex_cast (label_counter++);
3982 string toplabel = "top_" + ctr;
3983 string contlabel = "continue_" + ctr;
3984 string breaklabel = "break_" + ctr;
3985
d02548c0 3986 if (array)
1a0e4851 3987 {
d02548c0 3988 mapvar mv = getmap (array->referent, s->tok);
d02548c0 3989 vector<var> keys;
dff50e09 3990
d02548c0 3991 // NB: structure parallels for_loop
dff50e09 3992
d02548c0 3993 // initialization
07c17d67 3994
27f21e8c
DS
3995 tmpvar *res_limit = NULL;
3996 if (s->limit)
3997 {
3998 // Evaluate the limit expression once.
3999 res_limit = new tmpvar(gensym(pe_long));
43ff5962 4000 c_assign (*res_limit, s->limit, "foreach limit");
27f21e8c 4001 }
dff50e09 4002
07c17d67
GH
4003 // aggregate array if required
4004 if (mv.is_parallel())
d02548c0 4005 {
12363146 4006 o->newline() << "if (unlikely(NULL == " << mv.calculate_aggregate() << ")) {";
b5f561be
LB
4007 o->newline(1) << "c->last_error = ";
4008 o->line() << STAP_T_05 << mv << "\";";
54975cd8 4009 o->newline() << "c->last_stmt = " << lex_cast_qstring(*s->tok) << ";";
12363146
JS
4010 o->newline() << "goto out;";
4011 o->newline(-1) << "}";
ea7f4e8d 4012
07c17d67 4013 // sort array if desired
27f21e8c
DS
4014 if (s->sort_direction)
4015 {
fd5689dc 4016 string sort_column;
6a59236b
DS
4017
4018 // If the user wanted us to sort by value, we'll sort by
fd5689dc
FCE
4019 // @count or selected function instead for aggregates.
4020 // See runtime/map.c
6a59236b 4021 if (s->sort_column == 0)
fd5689dc
FCE
4022 switch (s->sort_aggr) {
4023 default: case sc_none: case sc_count: sort_column = "SORT_COUNT"; break;
4024 case sc_sum: sort_column = "SORT_SUM"; break;
4025 case sc_min: sort_column = "SORT_MIN"; break;
4026 case sc_max: sort_column = "SORT_MAX"; break;
4027 case sc_average: sort_column = "SORT_AVG"; break;
4028 }
6a59236b 4029 else
fd5689dc 4030 sort_column = lex_cast(s->sort_column);
6a59236b 4031
27f21e8c
DS
4032 o->newline() << "else"; // only sort if aggregation was ok
4033 if (s->limit)
4034 {
3cb9c91e 4035 o->newline(1) << mv.function_keysym("sortn", true) <<" ("
27f21e8c 4036 << mv.fetch_existing_aggregate() << ", "
6a59236b 4037 << *res_limit << ", " << sort_column << ", "
27f21e8c
DS
4038 << - s->sort_direction << ");";
4039 }
4040 else
4041 {
3cb9c91e 4042 o->newline(1) << mv.function_keysym("sort", true) <<" ("
27f21e8c 4043 << mv.fetch_existing_aggregate() << ", "
6a59236b 4044 << sort_column << ", "
27f21e8c
DS
4045 << - s->sort_direction << ");";
4046 }
4047 o->indent(-1);
4048 }
4049 }
07c17d67 4050 else
dff50e09 4051 {
07c17d67
GH
4052 // sort array if desired
4053 if (s->sort_direction)
4054 {
27f21e8c
DS
4055 if (s->limit)
4056 {
2473ac1b
JS
4057 o->newline() << mv.function_keysym("sortn") <<" ("
4058 << mv.value() << ", "
27f21e8c
DS
4059 << *res_limit << ", " << s->sort_column << ", "
4060 << - s->sort_direction << ");";
4061 }
4062 else
4063 {
2473ac1b
JS
4064 o->newline() << mv.function_keysym("sort") <<" ("
4065 << mv.value() << ", "
27f21e8c
DS
4066 << s->sort_column << ", "
4067 << - s->sort_direction << ");";
4068 }
07c17d67 4069 }
d02548c0 4070 }
07c17d67 4071
d02548c0 4072 // NB: sort direction sense is opposite in runtime, thus the negation
dff50e09 4073
27f21e8c
DS
4074 tmpvar *limitv = NULL;
4075 if (s->limit)
4076 {
4077 // Create the loop limit variable here and initialize it.
4078 limitv = new tmpvar(gensym (pe_long));
4079 o->newline() << *limitv << " = 0LL;";
4080 }
4081
c56fc632
JL
4082 if (mv.is_parallel())
4083 aggregations_active.insert(mv.value());
4084
4085 itervar iv = getiter (array);
4086 o->newline() << iv << " = " << iv.start (mv) << ";";
4087
05f0fc64
AJ
4088 vector<tmpvar *> array_slice_vars;
4089 // store the the variables corresponding to the index of the array slice
4090 // as temporary variables
4091 if (!s->array_slice.empty())
4092 for (unsigned i = 0; i < s->array_slice.size(); ++i)
4093 {
45af9d1b 4094 if (s->array_slice[i])
05f0fc64
AJ
4095 {
4096 tmpvar *asvar = new tmpvar(gensym(s->array_slice[i]->type));
43ff5962 4097 c_assign(*asvar, s->array_slice[i], "array slice index");
05f0fc64
AJ
4098 array_slice_vars.push_back(asvar);
4099 }
45af9d1b
AJ
4100 else
4101 array_slice_vars.push_back(NULL);
05f0fc64
AJ
4102 }
4103
54975cd8 4104 record_actions(1, s->tok, true);
9d0808b4 4105
d02548c0
GH
4106 // condition
4107 o->newline(-1) << toplabel << ":";
a7c9924b 4108
29fdb4e4
DS
4109 // Emit an explicit action here to cover the act of iteration.
4110 // Equivalently, it can stand for the evaluation of the
a7c9924b
FCE
4111 // condition expression.
4112 o->indent(1);
54975cd8 4113 record_actions(1, s->tok);
a7c9924b
FCE
4114
4115 o->newline() << "if (! (" << iv << ")) goto " << breaklabel << ";";
dff50e09 4116
d02548c0
GH
4117 // body
4118 loop_break_labels.push_back (breaklabel);
4119 loop_continue_labels.push_back (contlabel);
4120 o->newline() << "{";
4121 o->indent (1);
27f21e8c
DS
4122
4123 if (s->limit)
4124 {
4125 // If we've been through LIMIT loop iterations, quit.
4126 o->newline() << "if (" << *limitv << "++ >= " << *res_limit
4127 << ") goto " << breaklabel << ";";
4128
4129 // We're done with limitv and res_limit.
4130 delete limitv;
4131 delete res_limit;
4132 }
4133
d02548c0
GH
4134 for (unsigned i = 0; i < s->indexes.size(); ++i)
4135 {
4136 // copy the iter values into the specified locals
4137 var v = getvar (s->indexes[i]->referent);
2473ac1b 4138 c_assign (v, iv.get_key (mv, v.type(), i), s->tok);
d02548c0 4139 }
c261711d 4140
3040bf3a
AJ
4141 // in the case that the user specified something like
4142 // foreach ([a,b] in foo[*, 123]), need to check that it iterates over
4143 // the specified values, ie b is alwasy going to be 123
4144 if (!s->array_slice.empty())
4145 {
4146 //add in the beginning portion of the if statement
ad02fd4f 4147 o->newline() << "if (0"; // in case all are wildcards
3040bf3a 4148 for (unsigned i = 0; i < s->array_slice.size(); ++i)
05f0fc64 4149
3040bf3a 4150 // only output a comparsion if the expression is not "*".
45af9d1b 4151 if (s->array_slice[i])
3040bf3a
AJ
4152 {
4153 o->line() << " || ";
4154 if (s->indexes[i]->type == pe_string)
4155 {
4156 if (s->array_slice[i]->type != pe_string)
4157 throw SEMANTIC_ERROR (_("expected string types"), s->tok);
05f0fc64
AJ
4158 o->line() << "strncmp(" << getvar (s->indexes[i]->referent)
4159 << ", " << *array_slice_vars[i];
3040bf3a
AJ
4160 o->line() << ", MAXSTRINGLEN) !=0";
4161 }
4162 else if (s->indexes[i]->type == pe_long)
4163 {
4164 if (s->array_slice[i]->type != pe_long)
4165 throw SEMANTIC_ERROR (_("expected numeric types"), s->tok);
05f0fc64
AJ
4166 o->line() << getvar (s->indexes[i]->referent) << " != "
4167 << *array_slice_vars[i];
3040bf3a
AJ
4168 }
4169 else
4170 {
05f0fc64 4171 throw SEMANTIC_ERROR (_("unexpected type"), s->tok);
3040bf3a
AJ
4172 }
4173 }
4174 o->line() << ") goto " << contlabel << ";"; // end of the if statment
4175 }
4176
c261711d
JS
4177 if (s->value)
4178 {
4179 var v = getvar (s->value->referent);
1841d2dd 4180 c_assign (v, iv.get_value (mv, v.type()), s->tok);
c261711d
JS
4181 }
4182
d6d4dc4b 4183 visit_foreach_loop_value(s, iv.get_value(mv, array->type));
54975cd8 4184 record_actions(0, s->block->tok, true);
d02548c0
GH
4185 o->newline(-1) << "}";
4186 loop_break_labels.pop_back ();
4187 loop_continue_labels.pop_back ();
dff50e09 4188
d02548c0
GH
4189 // iteration
4190 o->newline(-1) << contlabel << ":";
4191 o->newline(1) << iv << " = " << iv.next (mv) << ";";
4192 o->newline() << "goto " << toplabel << ";";
dff50e09 4193
d02548c0
GH
4194 // exit
4195 o->newline(-1) << breaklabel << ":";
4196 o->newline(1) << "; /* dummy statement */";
57eedf94
JS
4197
4198 if (mv.is_parallel())
11b52b73 4199 aggregations_active.erase(mv.value());
1a0e4851 4200 }
d02548c0 4201 else
67c0a579 4202 {
71572ba8 4203 // Iterating over buckets in a histogram.
d6d4dc4b
JS
4204
4205 // First make sure we have exactly one pe_long variable to use as
4206 // our bucket index.
4207 if (s->indexes.size() != 1 || s->indexes[0]->referent->type != pe_long)
4208 throw SEMANTIC_ERROR(_("Invalid indexing of histogram"), s->tok);
e76c6d65 4209
27f21e8c
DS
4210 tmpvar *res_limit = NULL;
4211 tmpvar *limitv = NULL;
4212 if (s->limit)
4213 {
4214 // Evaluate the limit expression once.
4215 res_limit = new tmpvar(gensym(pe_long));
43ff5962 4216 c_assign (*res_limit, s->limit, "foreach limit");
27f21e8c
DS
4217
4218 // Create the loop limit variable here and initialize it.
4219 limitv = new tmpvar(gensym (pe_long));
4220 o->newline() << *limitv << " = 0LL;";
4221 }
dff50e09 4222
c56fc632
JL
4223 var bucketvar = getvar (s->indexes[0]->referent);
4224
4225 aggvar agg = gensym_aggregate ();
4226
4227 var *v = load_aggregate(hist->stat, agg);
4228 v->assert_hist_compatible(*hist);
4229
54975cd8 4230 record_actions(1, s->tok, true);
dff50e09 4231 o->newline() << "for (" << bucketvar << " = 0; "
e76c6d65 4232 << bucketvar << " < " << v->buckets() << "; "
71572ba8
GH
4233 << bucketvar << "++) { ";
4234 o->newline(1);
8e00730c
JS
4235 loop_break_labels.push_back (breaklabel);
4236 loop_continue_labels.push_back (contlabel);
27f21e8c
DS
4237
4238 if (s->limit)
4239 {
4240 // If we've been through LIMIT loop iterations, quit.
4241 o->newline() << "if (" << *limitv << "++ >= " << *res_limit
4242 << ") break;";
4243
4244 // We're done with limitv and res_limit.
4245 delete limitv;
4246 delete res_limit;
4247 }
4248
c261711d
JS
4249 if (s->value)
4250 {
4251 var v = getvar (s->value->referent);
4252 c_assign (v, agg.get_hist (bucketvar), s->tok);
4253 }
4254
d6d4dc4b 4255 visit_foreach_loop_value(s, agg.get_hist(bucketvar));
54975cd8 4256 record_actions(1, s->block->tok, true);
8e00730c
JS
4257
4258 o->newline(-1) << contlabel << ":";
4259 o->newline(1) << "continue;";
4260 o->newline(-1) << breaklabel << ":";
4261 o->newline(1) << "break;";
71572ba8 4262 o->newline(-1) << "}";
8e00730c
JS
4263 loop_break_labels.pop_back ();
4264 loop_continue_labels.pop_back ();
e76c6d65
JS
4265
4266 delete v;
67c0a579 4267 }
69c68955
FCE
4268}
4269
4270
2b066ec1 4271void
4383d78c 4272c_unparser::visit_return_statement (return_statement* s)
2b066ec1 4273{
2b066ec1 4274 if (current_function == 0)
dc09353a 4275 throw SEMANTIC_ERROR (_("cannot 'return' from probe"), s->tok);
2b066ec1
FCE
4276
4277 if (s->value->type != current_function->type)
dc09353a 4278 throw SEMANTIC_ERROR (_("return type mismatch"), current_function->tok,
e26c2f83 4279 s->tok);
2b066ec1 4280
ce10591c 4281 c_assign ("l->__retvalue", s->value, "return value");
54975cd8 4282 record_actions(1, s->tok, true);
12363146 4283 o->newline() << "goto out;";
2b066ec1
FCE
4284}
4285
4286
f3c26ea5
FCE
4287void
4288c_unparser::visit_next_statement (next_statement* s)
4289{
4290 if (current_probe == 0)
dc09353a 4291 throw SEMANTIC_ERROR (_("cannot 'next' from function"), s->tok);
f3c26ea5 4292
54975cd8 4293 record_actions(1, s->tok, true);
12363146 4294 o->newline() << "goto out;";
f3c26ea5
FCE
4295}
4296
4297
d98d459c
GH
4298struct delete_statement_operand_visitor:
4299 public throwing_visitor
4300{
4301 c_unparser *parent;
4302 delete_statement_operand_visitor (c_unparser *p):
1e41115c 4303 throwing_visitor (_("invalid operand of delete expression")),
d98d459c
GH
4304 parent (p)
4305 {}
4306 void visit_symbol (symbol* e);
4307 void visit_arrayindex (arrayindex* e);
4308};
4309
dff50e09 4310void
d98d459c
GH
4311delete_statement_operand_visitor::visit_symbol (symbol* e)
4312{
d6d4dc4b 4313 translator_output* o = parent->o;
ed238a16 4314 assert (e->referent != 0);
45c2b487
JS
4315 if (e->referent->arity > 0)
4316 {
dff50e09 4317 mapvar mvar = parent->getmap(e->referent, e->tok);
13a9593f
FCE
4318 /* NB: Memory deallocation/allocation operations
4319 are not generally safe.
d6d4dc4b
JS
4320 o->newline() << mvar.fini ();
4321 o->newline() << mvar.init ();
45c2b487
JS
4322 */
4323 if (mvar.is_parallel())
d6d4dc4b 4324 o->newline() << "_stp_pmap_clear (" << mvar.value() << ");";
45c2b487 4325 else
d6d4dc4b 4326 o->newline() << "_stp_map_clear (" << mvar.value() << ");";
45c2b487
JS
4327 }
4328 else
4329 {
dff50e09 4330 var v = parent->getvar(e->referent, e->tok);
45c2b487
JS
4331 switch (e->type)
4332 {
4333 case pe_stats:
d6d4dc4b 4334 o->newline() << "_stp_stat_clear (" << v.value() << ");";
45c2b487
JS
4335 break;
4336 case pe_long:
d6d4dc4b 4337 o->newline() << v.value() << " = 0;";
45c2b487
JS
4338 break;
4339 case pe_string:
d6d4dc4b 4340 o->newline() << v.value() << "[0] = '\\0';";
45c2b487
JS
4341 break;
4342 case pe_unknown:
4343 default:
dc09353a 4344 throw SEMANTIC_ERROR(_("Cannot delete unknown expression type"), e->tok);
45c2b487
JS
4345 }
4346 }
4347}
4348
dff50e09 4349void
d98d459c
GH
4350delete_statement_operand_visitor::visit_arrayindex (arrayindex* e)
4351{
dff50e09 4352 symbol *array;
d02548c0
GH
4353 hist_op *hist;
4354 classify_indexable (e->base, array, hist);
d6d4dc4b 4355 translator_output* o = parent->o;
bb788f9f 4356
d02548c0
GH
4357 if (array)
4358 {
a98c930b
AJ
4359 bool array_slice = false;
4360 for (unsigned i = 0; i < e->indexes.size(); i ++)
45af9d1b 4361 if (e->indexes[i] == NULL)
a98c930b
AJ
4362 {
4363 array_slice = true;
4364 break;
4365 }
dff50e09 4366
a98c930b
AJ
4367 if (!array_slice) // delete a single element
4368 {
4369 vector<tmpvar> idx;
4370 parent->load_map_indices (e, idx);
4371 mapvar mvar = parent->getmap (array->referent, e->tok);
d6d4dc4b 4372 o->newline() << mvar.del (idx) << ";";
a98c930b
AJ
4373 }
4374 else // delete elements if they match the array slice.
4375 {
3a7fec94
AJ
4376 vardecl* r = array->referent;
4377 mapvar mvar = parent->getmap (r, e->tok);
4378 itervar iv = parent->getiter(array);
4379
a98c930b
AJ
4380 // create tmpvars for the array indexes, storing NULL where there is
4381 // no specific value that the index should be
4382 vector<tmpvar *> array_slice_vars;
3a7fec94 4383 vector<tmpvar> idx; // for the indexes if the variable is a pmap
a98c930b
AJ
4384 for (unsigned i=0; i<e->indexes.size(); i++)
4385 {
45af9d1b 4386 if (e->indexes[i])
a98c930b 4387 {
45af9d1b 4388 tmpvar *asvar = new tmpvar(parent->gensym(e->indexes[i]->type));
43ff5962 4389 parent->c_assign (*asvar, e->indexes[i], "tmp var");
a98c930b 4390 array_slice_vars.push_back(asvar);
3a7fec94
AJ
4391 if (mvar.is_parallel())
4392 idx.push_back(*asvar);
a98c930b 4393 }
45af9d1b 4394 else
3a7fec94
AJ
4395 {
4396 array_slice_vars.push_back(NULL);
4397 if (mvar.is_parallel())
4398 {
4399 tmpvar *asvar = new tmpvar(parent->gensym(r->index_types[i]));
4400 idx.push_back(*asvar);
4401 }
4402 }
a98c930b
AJ
4403 }
4404
3a7fec94
AJ
4405 if (mvar.is_parallel())
4406 {
d6d4dc4b
JS
4407 o->newline() << "if (unlikely(NULL == "
4408 << mvar.calculate_aggregate() << ")) {";
4409 o->newline(1) << "c->last_error = ";
4410 o->line() << STAP_T_05 << mvar << "\";";
4411 o->newline() << "c->last_stmt = "
4412 << lex_cast_qstring(*e->tok) << ";";
4413 o->newline() << "goto out;";
4414 o->newline(-1) << "}";
3a7fec94 4415 }
a98c930b
AJ
4416
4417 // iterate through the map, deleting elements that match the array slice
4418 string ctr = lex_cast (parent->label_counter++);
4419 string toplabel = "top_" + ctr;
4420 string breaklabel = "break_" + ctr;
4421
d6d4dc4b
JS
4422 o->newline() << iv << " = " << iv.start(mvar) << ";";
4423 o->newline() << toplabel << ":";
a98c930b 4424
d6d4dc4b
JS
4425 o->newline(1) << "if (!(" << iv << ")){";
4426 o->newline(1) << "goto " << breaklabel << ";}";
a98c930b
AJ
4427
4428 // insert the comparison for keys that aren't wildcards
d6d4dc4b 4429 o->newline(-1) << "if (1"; // in case all are wildcards
a98c930b
AJ
4430 for (unsigned i=0; i<array_slice_vars.size(); i++)
4431 if (array_slice_vars[i] != NULL)
4432 {
4433 if (array_slice_vars[i]->type() == pe_long)
d6d4dc4b
JS
4434 o->line() << " && " << *array_slice_vars[i] << " == "
4435 << iv.get_key(mvar, array_slice_vars[i]->type(), i);
a98c930b 4436 else if (array_slice_vars[i]->type() == pe_string)
d6d4dc4b
JS
4437 o->line() << " && strncmp(" << *array_slice_vars[i] << ", "
4438 << iv.get_key(mvar, array_slice_vars[i]->type(), i)
4439 << ", MAXSTRINGLEN) == 0";
a98c930b
AJ
4440 else
4441 throw SEMANTIC_ERROR (_("unexpected type"), e->tok);
4442 }
3a7fec94 4443
d6d4dc4b 4444 o->line() << ") {";
3a7fec94 4445
a98c930b 4446 // conditional is true, so delete item and go to the next item
3a7fec94
AJ
4447 if (mvar.is_parallel())
4448 {
d6d4dc4b 4449 o->indent(1);
3a7fec94
AJ
4450 // fills in the wildcards with the current iteration's (map) indexes
4451 for (unsigned i = 0; i<array_slice_vars.size(); i++)
4452 if (array_slice_vars[i] == NULL)
4453 parent->c_assign (idx[i].value(),
4454 iv.get_key(mvar, r->index_types[i], i),
4455 r->index_types[i], "tmpvar", e->tok);
d6d4dc4b
JS
4456 o->newline() << iv << " = " << iv.next(mvar) << ";";
4457 o->newline() << mvar.del(idx) << ";";
3a7fec94
AJ
4458 }
4459 else
d6d4dc4b 4460 o->newline(1) << iv << " = " << iv.del_next(mvar) << ";";
a98c930b 4461
d6d4dc4b
JS
4462 o->newline(-1) << "} else";
4463 o->newline(1) << iv << " = " << iv.next(mvar) << ";";
a98c930b 4464
d6d4dc4b 4465 o->newline(-1) << "goto " << toplabel << ";";
a98c930b 4466
d6d4dc4b
JS
4467 o->newline(-1) << breaklabel<< ":";
4468 o->newline(1) << "; /* dummy statement */";
4469 o->indent(-1);
a98c930b 4470 }
d02548c0
GH
4471 }
4472 else
4473 {
dc09353a 4474 throw SEMANTIC_ERROR(_("cannot delete histogram bucket entries\n"), e->tok);
d02548c0 4475 }
d98d459c
GH
4476}
4477
4478
2b066ec1 4479void
4383d78c 4480c_unparser::visit_delete_statement (delete_statement* s)
2b066ec1 4481{
d98d459c
GH
4482 delete_statement_operand_visitor dv (this);
4483 s->value->visit (&dv);
54975cd8 4484 record_actions(1, s->tok);
2b066ec1
FCE
4485}
4486
f3c26ea5
FCE
4487
4488void
4489c_unparser::visit_break_statement (break_statement* s)
4490{
f6abaa09 4491 if (loop_break_labels.empty())
dc09353a 4492 throw SEMANTIC_ERROR (_("cannot 'break' outside loop"), s->tok);
f3c26ea5 4493
54975cd8 4494 record_actions(1, s->tok, true);
f6abaa09 4495 o->newline() << "goto " << loop_break_labels.back() << ";";
f3c26ea5
FCE
4496}
4497
4498
4499void
4500c_unparser::visit_continue_statement (continue_statement* s)
4501{
f6abaa09 4502 if (loop_continue_labels.empty())
dc09353a 4503 throw SEMANTIC_ERROR (_("cannot 'continue' outside loop"), s->tok);
f3c26ea5 4504
54975cd8 4505 record_actions(1, s->tok, true);
f6abaa09 4506 o->newline() << "goto " << loop_continue_labels.back() << ";";
f3c26ea5
FCE
4507}
4508
4509
4510
2b066ec1 4511void
4383d78c 4512c_unparser::visit_literal_string (literal_string* e)
2b066ec1 4513{
47d349b1 4514 interned_string v = e->value;
f86db5a7
FCE
4515 o->line() << '"';
4516 for (unsigned i=0; i<v.size(); i++)
72dbc915
FCE
4517 // NB: The backslash character is specifically passed through as is.
4518 // This is because our parser treats "\" as an ordinary character, not
4519 // an escape sequence, leaving it to the C compiler (and this function)
4520 // to treat it as such. If we were to escape it, there would be no way
4521 // of generating C-level escapes from script code.
c4bb5be2 4522 // See also print_format::components_to_string and lex_cast_qstring
f86db5a7
FCE
4523 if (v[i] == '"') // or other escapeworthy characters?
4524 o->line() << '\\' << '"';
4525 else
4526 o->line() << v[i];
4527 o->line() << '"';
2b066ec1
FCE
4528}
4529
f3c26ea5 4530
2b066ec1 4531void
4383d78c 4532c_unparser::visit_literal_number (literal_number* e)
2b066ec1 4533{
3a20432b
FCE
4534 // This looks ugly, but tries to be warning-free on 32- and 64-bit
4535 // hosts.
ba4a90fd 4536 // NB: this needs to be signed!
0a08ca99
FCE
4537 if (e->value == -9223372036854775807LL-1) // PR 5023
4538 o->line() << "((int64_t)" << (unsigned long long) e->value << "ULL)";
4539 else
4540 o->line() << "((int64_t)" << e->value << "LL)";
2b066ec1
FCE
4541}
4542
3d3887df 4543
7d902887
FCE
4544void
4545c_unparser::visit_embedded_expr (embedded_expr* e)
4546{
0af18f5a
FL
4547 bool has_defines = false;
4548 vector<vardecl*> read_defs;
4549 vector<vardecl*> write_defs;
4550 for (unsigned i = 0; i < session->globals.size(); i++)
4551 {
4552 vardecl* v = session->globals[i];
8e95959e 4553 string name = v->unmangled_name;
0af18f5a
FL
4554 if (e->code.find("/* pragma:read:" + name + " */") != string::npos)
4555 {
4556 has_defines = true;
4557 c_global_read_def(v);
4558 read_defs.push_back(v);
4559 }
4560 if (e->code.find("/* pragma:write:" + name + " */") != string::npos)
4561 {
4562 has_defines = true;
4563 c_global_write_def(v);
4564 write_defs.push_back(v);
4565 }
4566 }
4567
4568 if (has_defines)
4569 o->newline();
4570
2363d2a5
DB
4571 o->line() << "(";
4572
4573 // Automatically add a call to assert_is_myproc to any code tagged with
4574 // /* myproc-unprivileged */
4575 if (e->code.find ("/* myproc-unprivileged */") != string::npos)
58b666e3 4576 o->line() << "({ assert_is_myproc(); }), ";
2363d2a5 4577
7d902887
FCE
4578 if (e->type == pe_long)
4579 o->line() << "((int64_t) (" << e->code << "))";
4580 else if (e->type == pe_string)
4581 o->line() << "((const char *) (" << e->code << "))";
4582 else
dc09353a 4583 throw SEMANTIC_ERROR (_("expected numeric or string type"), e->tok);
2363d2a5
DB
4584
4585 o->line() << ")";
0af18f5a
FL
4586
4587 for (vector<vardecl*>::const_iterator it = read_defs.begin(); it != read_defs.end(); ++it)
4588 c_global_read_undef(*it);
4589 for (vector<vardecl*>::const_iterator it = write_defs.begin(); it != write_defs.end(); ++it)
4590 c_global_write_undef(*it);
4591
4592 if (has_defines)
4593 o->newline();
7d902887
FCE
4594}
4595
4596
2b066ec1 4597void
4383d78c 4598c_unparser::visit_binary_expression (binary_expression* e)
2b066ec1 4599{
bb2e3076
FCE
4600 if (e->type != pe_long ||
4601 e->left->type != pe_long ||
4602 e->right->type != pe_long)
dc09353a 4603 throw SEMANTIC_ERROR (_("expected numeric types"), e->tok);
dff50e09 4604
3d3887df
FCE
4605 if (e->op == "+" ||
4606 e->op == "-" ||
4607 e->op == "*" ||
bb2e3076
FCE
4608 e->op == "&" ||
4609 e->op == "|" ||
79cd1b27 4610 e->op == "^")
3d3887df 4611 {
bb2e3076
FCE
4612 o->line() << "((";
4613 e->left->visit (this);
4614 o->line() << ") " << e->op << " (";
4615 e->right->visit (this);
4616 o->line() << "))";
4617 }
79cd1b27
ET
4618 else if (e->op == ">>" ||
4619 e->op == "<<")
4620 {
4621 o->line() << "((";
4622 e->left->visit (this);
4623 o->line() << ") " << e->op << "max(min(";
4624 e->right->visit (this);
4625 o->line() << ", (int64_t)64LL), (int64_t)0LL))"; // between 0 and 64
4626 }
bb2e3076
FCE
4627 else if (e->op == "/" ||
4628 e->op == "%")
4629 {
4630 // % and / need a division-by-zero check; and thus two temporaries
4631 // for proper evaluation order
313b2f74
GH
4632 tmpvar left = gensym (pe_long);
4633 tmpvar right = gensym (pe_long);
4634
bb2e3076 4635 o->line() << "({";
99613db7 4636 o->indent(1);
bb2e3076 4637
b2d74f03
JS
4638 c_assign (left, e->left, "division");
4639 c_assign (right, e->right, "division");
bb2e3076 4640
12363146 4641 o->newline() << "if (unlikely(!" << right << ")) {";
b5f561be
LB
4642 o->newline(1) << "c->last_error = ";
4643 o->line() << STAP_T_03;
12363146
JS
4644 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
4645 o->newline() << "goto out;";
4646 o->newline(-1) << "}";
3a20432b 4647 o->newline() << ((e->op == "/") ? "_stp_div64" : "_stp_mod64")
12363146 4648 << " (NULL, " << left << ", " << right << ");";
bb2e3076 4649
bb2e3076 4650 o->newline(-1) << "})";
3d3887df 4651 }
3d3887df 4652 else
dc09353a 4653 throw SEMANTIC_ERROR (_("operator not yet implemented"), e->tok);
2b066ec1
FCE
4654}
4655
553d27a5 4656
2b066ec1 4657void
4383d78c 4658c_unparser::visit_unary_expression (unary_expression* e)
2b066ec1 4659{
553d27a5
FCE
4660 if (e->type != pe_long ||
4661 e->operand->type != pe_long)
dc09353a 4662 throw SEMANTIC_ERROR (_("expected numeric types"), e->tok);
553d27a5 4663
0a08ca99
FCE
4664 if (e->op == "-")
4665 {
4666 // NB: Subtraction is special, since negative literals in the
4667 // script language show up as unary negations over positive
4668 // literals here. This makes it "exciting" for emitting pure
4669 // C since: - 0x8000_0000_0000_0000 ==> - (- 9223372036854775808)
4670 // This would constitute a signed overflow, which gcc warns on
4671 // unless -ftrapv/-J are in CFLAGS - which they're not.
4672
4673 o->line() << "(int64_t)(0 " << e->op << " (uint64_t)(";
4674 e->operand->visit (this);
4675 o->line() << "))";
4676 }
4677 else
4678 {
4679 o->line() << "(" << e->op << " (";
4680 e->operand->visit (this);
4681 o->line() << "))";
4682 }
2b066ec1
FCE
4683}
4684
4685void
4383d78c 4686c_unparser::visit_logical_or_expr (logical_or_expr* e)
2b066ec1 4687{
553d27a5
FCE
4688 if (e->type != pe_long ||
4689 e->left->type != pe_long ||
4690 e->right->type != pe_long)
dc09353a 4691 throw SEMANTIC_ERROR (_("expected numeric types"), e->tok);
553d27a5 4692
bb2e3076 4693 o->line() << "((";
553d27a5
FCE
4694 e->left->visit (this);
4695 o->line() << ") " << e->op << " (";
4696 e->right->visit (this);
bb2e3076 4697 o->line() << "))";
2b066ec1
FCE
4698}
4699
553d27a5 4700
2b066ec1 4701void
4383d78c 4702c_unparser::visit_logical_and_expr (logical_and_expr* e)
2b066ec1 4703{
553d27a5
FCE
4704 if (e->type != pe_long ||
4705 e->left->type != pe_long ||
4706 e->right->type != pe_long)
dc09353a 4707 throw SEMANTIC_ERROR (_("expected numeric types"), e->tok);
553d27a5 4708
bb2e3076 4709 o->line() << "((";
553d27a5
FCE
4710 e->left->visit (this);
4711 o->line() << ") " << e->op << " (";
4712 e->right->visit (this);
bb2e3076 4713 o->line() << "))";
2b066ec1
FCE
4714}
4715
553d27a5 4716
2b066ec1 4717void
4383d78c 4718c_unparser::visit_array_in (array_in* e)
2b066ec1 4719{
dff50e09 4720 symbol *array;
d02548c0
GH
4721 hist_op *hist;
4722 classify_indexable (e->operand->base, array, hist);
dff50e09 4723
d02548c0
GH
4724 if (array)
4725 {
dff50e09
FCE
4726 stmt_expr block(*this);
4727
e225e273 4728 tmpvar res = gensym (pe_long);
d02548c0 4729 vector<tmpvar> idx;
dff50e09 4730
e225e273
AJ
4731 // determine if the array index contains an asterisk
4732 bool array_slice = false;
4733 for (unsigned i = 0; i < e->operand->indexes.size(); i ++)
45af9d1b 4734 if (e->operand->indexes[i] == NULL)
e225e273
AJ
4735 {
4736 array_slice = true;
4737 break;
4738 }
4739
4740 if (!array_slice) // checking for membership of a specific element
4741 {
4742 load_map_indices (e->operand, idx);
4743 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
4744
4745 mapvar mvar = getmap (array->referent, e->tok);
4746 c_assign (res, mvar.exists(idx), e->tok);
4747
4748 o->newline() << res << ";";
4749 }
4750 else
4751 {
4752 // create tmpvars for the array indexes, storing NULL where there is
4753 // no specific value that the index should be
4754 vector<tmpvar *> array_slice_vars;
4755 for (unsigned i=0; i<e->operand->indexes.size(); i++)
4756 {
45af9d1b 4757 if (e->operand->indexes[i])
e225e273 4758 {
45af9d1b 4759 tmpvar *asvar = new tmpvar(gensym(e->operand->indexes[i]->type));
43ff5962 4760 c_assign (*asvar, e->operand->indexes[i], "tmp var");
e225e273
AJ
4761 array_slice_vars.push_back(asvar);
4762 }
45af9d1b
AJ
4763 else
4764 array_slice_vars.push_back(NULL);
e225e273
AJ
4765 }
4766
4767 mapvar mvar = getmap (array->referent, e->operand->tok);
4768 itervar iv = getiter(array);
4769 vector<tmpvar> idx;
4770
5306eb13
JS
4771 // we may not need to aggregate if we're already in a foreach
4772 bool pre_agg = (aggregations_active.count(mvar.value()) > 0);
4773 if (mvar.is_parallel() && !pre_agg)
4774 {
4775 o->newline() << "if (unlikely(NULL == "
4776 << mvar.calculate_aggregate() << ")) {";
4777 o->newline(1) << "c->last_error = ";
4778 o->line() << STAP_T_05 << mvar << "\";";
4779 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
4780 o->newline() << "goto out;";
4781 o->newline(-1) << "}";
4782 }
4783
e225e273
AJ
4784 string ctr = lex_cast (label_counter++);
4785 string toplabel = "top_" + ctr;
4786 string contlabel = "continue_" + ctr;
4787 string breaklabel = "break_" + ctr;
4788
4789 o->newline() << iv << " = " << iv.start(mvar) << ";";
4790 c_assign (res, "0", e->tok); // set the default to 0
4791
4792 o->newline() << toplabel << ":";
4793
4794 o->newline(1) << "if (!(" << iv << "))";
4795 o->newline(1) << "goto " << breaklabel << ";";
4796
4797 // generate code for comparing the keys to the index slice
ad02fd4f 4798 o->newline(-1) << "if (1"; // in case all are wildcards
e225e273
AJ
4799 for (unsigned i=0; i<array_slice_vars.size(); i++)
4800 {
4801 if (array_slice_vars[i] != NULL)
4802 {
4803 if (array_slice_vars[i]->type() == pe_long)
4804 o->line() << " && " << *array_slice_vars[i] << " == "
4805 << iv.get_key(mvar, array_slice_vars[i]->type(), i);
4806 else if (array_slice_vars[i]->type() == pe_string)
4807 o->line() << " && strncmp(" << *array_slice_vars[i] << ", "
4808 << iv.get_key(mvar, array_slice_vars[i]->type(), i)
4809 << ", MAXSTRINGLEN) == 0";
4810 else
4811 throw SEMANTIC_ERROR (_("unexpected type"), e->tok);
4812 }
4813 }
4814 o->line() << "){";
4815 o->indent(1);
4816 // conditional is true, so set res and go to break
4817 c_assign (res, "1", e->tok);
4818 o->newline() << "goto " << breaklabel << ";";
4819 o->newline(-1) << "}";
4820
4821 // else, keep iterating
4822 o->newline() << iv << " = " << iv.next(mvar) << ";";
4823 o->newline() << "goto " << toplabel << ";";
4824
4825 o->newline(-1) << breaklabel<< ":";
4826 o->newline(1) << "; /* dummy statement */";
4827 o->newline(-1) << res << ";";
4828 }
51bf37c3 4829
d02548c0
GH
4830 }
4831 else
4832 {
460b2038
GH
4833 // By definition:
4834 //
4835 // 'foo in @hist_op(...)' is true iff
4836 // '@hist_op(...)[foo]' is nonzero
4837 //
4838 // so we just delegate to the latter call, since int64_t is also
4839 // our boolean type.
4840 e->operand->visit(this);
d02548c0 4841 }
2b066ec1
FCE
4842}
4843
93daaca8
SM
4844void
4845c_unparser::visit_regex_query (regex_query* e)
4846{
d2548fe7 4847 o->line() << "(";
93daaca8 4848 o->indent(1);
d2548fe7
SM
4849 o->newline();
4850 if (e->op == "!~") o->line() << "!";
47d349b1 4851 stapdfa *dfa = session->dfas[e->right->value];
d2548fe7 4852 dfa->emit_matchop_start (o);
93daaca8 4853 e->left->visit(this);
d2548fe7
SM
4854 dfa->emit_matchop_end (o);
4855 o->newline(-1) << ")";
93daaca8 4856}
4383d78c 4857
2b066ec1 4858void
4383d78c 4859c_unparser::visit_comparison (comparison* e)
2b066ec1 4860{
553d27a5
FCE
4861 o->line() << "(";
4862
4863 if (e->left->type == pe_string)
4864 {
26de79f7 4865 if (e->right->type != pe_string)
dc09353a 4866 throw SEMANTIC_ERROR (_("expected string types"), e->tok);
553d27a5 4867
c12bdeab
JS
4868 o->line() << "({";
4869 o->indent(1);
4870
4871 tmpvar left = gensym (pe_string);
b2d74f03 4872 c_assign (left, e->left, "assignment");
c12bdeab
JS
4873
4874 o->newline() << "strncmp (" << left << ", ";
553d27a5 4875 e->right->visit (this);
c12bdeab
JS
4876 o->line() << ", MAXSTRINGLEN) " << e->op << " 0;";
4877 o->newline(-1) << "})";
553d27a5
FCE
4878 }
4879 else if (e->left->type == pe_long)
4880 {
26de79f7 4881 if (e->right->type != pe_long)
dc09353a 4882 throw SEMANTIC_ERROR (_("expected numeric types"), e->tok);
553d27a5 4883
bb2e3076 4884 o->line() << "((";
553d27a5
FCE
4885 e->left->visit (this);
4886 o->line() << ") " << e->op << " (";
4887 e->right->visit (this);
bb2e3076 4888 o->line() << "))";
553d27a5
FCE
4889 }
4890 else
dc09353a 4891 throw SEMANTIC_ERROR (_("unexpected type"), e->left->tok);
553d27a5
FCE
4892
4893 o->line() << ")";
2b066ec1
FCE
4894}
4895
4383d78c 4896
2b066ec1 4897void
4383d78c 4898c_unparser::visit_concatenation (concatenation* e)
2b066ec1 4899{
3d3887df 4900 if (e->op != ".")
dc09353a 4901 throw SEMANTIC_ERROR (_("unexpected concatenation operator"), e->tok);
3d3887df
FCE
4902
4903 if (e->type != pe_string ||
4904 e->left->type != pe_string ||
4905 e->right->type != pe_string)
dc09353a 4906 throw SEMANTIC_ERROR (_("expected string types"), e->tok);
3d3887df 4907
313b2f74 4908 tmpvar t = gensym (e->type);
dff50e09 4909
3d3887df
FCE
4910 o->line() << "({ ";
4911 o->indent(1);
99613db7 4912 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
11b52b73
DS
4913 c_assign (t.value(), e->left, "assignment");
4914 c_strcat (t.value(), e->right);
313b2f74 4915 o->newline() << t << ";";
3d3887df 4916 o->newline(-1) << "})";
2b066ec1
FCE
4917}
4918
4383d78c 4919
2b066ec1 4920void
4383d78c 4921c_unparser::visit_ternary_expression (ternary_expression* e)
2b066ec1 4922{
553d27a5 4923 if (e->cond->type != pe_long)
dc09353a 4924 throw SEMANTIC_ERROR (_("expected numeric condition"), e->cond->tok);
553d27a5
FCE
4925
4926 if (e->truevalue->type != e->falsevalue->type ||
4927 e->type != e->truevalue->type ||
4928 (e->truevalue->type != pe_long && e->truevalue->type != pe_string))
dc09353a 4929 throw SEMANTIC_ERROR (_("expected matching types"), e->tok);
553d27a5
FCE
4930
4931 o->line() << "((";
4932 e->cond->visit (this);
4933 o->line() << ") ? (";
4934 e->truevalue->visit (this);
4935 o->line() << ") : (";
4936 e->falsevalue->visit (this);
4937 o->line() << "))";
2b066ec1
FCE
4938}
4939
4940
2b066ec1 4941void
4383d78c 4942c_unparser::visit_assignment (assignment* e)
2b066ec1 4943{
57b73400
GH
4944 if (e->op == "<<<")
4945 {
4946 if (e->type != pe_long)
dc09353a 4947 throw SEMANTIC_ERROR (_("non-number <<< expression"), e->tok);
57b73400
GH
4948
4949 if (e->left->type != pe_stats)
dc09353a 4950 throw SEMANTIC_ERROR (_("non-stats left operand to <<< expression"), e->left->tok);
57b73400
GH
4951
4952 if (e->right->type != pe_long)
dc09353a 4953 throw SEMANTIC_ERROR (_("non-number right operand to <<< expression"), e->right->tok);
dff50e09 4954
57b73400
GH
4955 }
4956 else
4957 {
4958 if (e->type != e->left->type)
dc09353a 4959 throw SEMANTIC_ERROR (_("type mismatch"), e->tok, e->left->tok);
57b73400 4960 if (e->right->type != e->left->type)
dc09353a 4961 throw SEMANTIC_ERROR (_("type mismatch"), e->right->tok, e->left->tok);
57b73400 4962 }
2b066ec1 4963
bb2e3076
FCE
4964 c_unparser_assignment tav (this, e->op, e->right);
4965 e->left->visit (& tav);
4966}
4967
4968
bb2e3076
FCE
4969void
4970c_unparser::visit_pre_crement (pre_crement* e)
4971{
4972 if (e->type != pe_long ||
4973 e->type != e->operand->type)
dc09353a 4974 throw SEMANTIC_ERROR (_("expected numeric type"), e->tok);
bb2e3076 4975
78110925 4976 c_unparser_assignment tav (this, e->op, false);
bb2e3076
FCE
4977 e->operand->visit (& tav);
4978}
4979
4980
bb2e3076
FCE
4981void
4982c_unparser::visit_post_crement (post_crement* e)
4983{
4984 if (e->type != pe_long ||
4985 e->type != e->operand->type)
dc09353a 4986 throw SEMANTIC_ERROR (_("expected numeric type"), e->tok);
bb2e3076 4987
78110925 4988 c_unparser_assignment tav (this, e->op, true);
bb2e3076 4989 e->operand->visit (& tav);
2b066ec1
FCE
4990}
4991
4992
4993void
4383d78c 4994c_unparser::visit_symbol (symbol* e)
2b066ec1 4995{
ed238a16 4996 assert (e->referent != 0);
2b066ec1
FCE
4997 vardecl* r = e->referent;
4998
4999 if (r->index_types.size() != 0)
dc09353a 5000 throw SEMANTIC_ERROR (_("invalid reference to array"), e->tok);
2b066ec1 5001
313b2f74
GH
5002 var v = getvar(r, e->tok);
5003 o->line() << v;
2b066ec1
FCE
5004}
5005
5006
bb2e3076
FCE
5007// Assignment expansion is tricky.
5008//
5009// Because assignments are nestable expressions, we have
5010// to emit C constructs that are nestable expressions too.
5011// We have to evaluate the given expressions the proper number of times,
5012// including array indices.
5013// We have to lock the lvalue (if global) against concurrent modification,
5014// especially with modify-assignment operations (+=, ++).
5015// We have to check the rvalue (for division-by-zero checks).
5016
5017// In the normal "pre=false" case, for (A op B) emit:
5018// ({ tmp = B; check(B); lock(A); res = A op tmp; A = res; unlock(A); res; })
5019// In the "pre=true" case, emit instead:
5020// ({ tmp = B; check(B); lock(A); res = A; A = res op tmp; unlock(A); res; })
5021//
5022// (op is the plain operator portion of a combined calculate/assignment:
5023// "+" for "+=", and so on. It is in the "macop" variable below.)
5024//
5025// For array assignments, additional temporaries are used for each
5026// index, which are expanded before the "tmp=B" expression, in order
5027// to consistently order evaluation of lhs before rhs.
5028//
5029
4383d78c 5030void
47d349b1 5031c_unparser_assignment::prepare_rvalue (interned_string op,
11b52b73 5032 tmpvar & rval,
313b2f74 5033 token const * tok)
2b066ec1 5034{
bb2e3076 5035 if (rvalue)
b2d74f03 5036 parent->c_assign (rval, rvalue, "assignment");
bb2e3076
FCE
5037 else
5038 {
5039 if (op == "++" || op == "--")
11b52b73
DS
5040 // Here is part of the conversion proccess of turning "x++" to
5041 // "x += 1".
5042 rval.override("1");
bb2e3076 5043 else
dc09353a 5044 throw SEMANTIC_ERROR (_("need rvalue for assignment"), tok);
bb2e3076 5045 }
313b2f74 5046}
ce10591c 5047
313b2f74
GH
5048void
5049c_unparser_assignment::visit_symbol (symbol *e)
5050{
5051 stmt_expr block(*parent);
d6d4dc4b 5052 translator_output* o = parent->o;
bb2e3076 5053
ed238a16 5054 assert (e->referent != 0);
313b2f74 5055 if (e->referent->index_types.size() != 0)
dc09353a 5056 throw SEMANTIC_ERROR (_("unexpected reference to array"), e->tok);
bb2e3076 5057
d6d4dc4b 5058 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
57b73400
GH
5059 exp_type ty = rvalue ? rvalue->type : e->type;
5060 tmpvar rval = parent->gensym (ty);
5061 tmpvar res = parent->gensym (ty);
bb2e3076 5062
313b2f74 5063 prepare_rvalue (op, rval, e->tok);
2b066ec1 5064
13a9593f 5065 var lvar = parent->getvar (e->referent, e->tok);
dff50e09 5066 c_assignop (res, lvar, rval, e->tok);
bb2e3076 5067
d6d4dc4b 5068 o->newline() << res << ";";
2b066ec1
FCE
5069}
5070
5071
dff50e09 5072void
d7f3e0c5
GH
5073c_unparser::visit_target_symbol (target_symbol* e)
5074{
dc09353a 5075 throw SEMANTIC_ERROR(_("cannot translate general target-symbol expression"), e->tok);
d7f3e0c5
GH
5076}
5077
5078
bd1fcbad
YZ
5079void
5080c_unparser::visit_atvar_op (atvar_op* e)
5081{
dc09353a 5082 throw SEMANTIC_ERROR(_("cannot translate general @var expression"), e->tok);
bd1fcbad
YZ
5083}
5084
5085
9b5af295
JS
5086void
5087c_unparser::visit_cast_op (cast_op* e)
5088{
dc09353a 5089 throw SEMANTIC_ERROR(_("cannot translate general @cast expression"), e->tok);
30263a73
FCE
5090}
5091
5092
251707c8
JS
5093void
5094c_unparser::visit_autocast_op (autocast_op* e)
5095{
5096 throw SEMANTIC_ERROR(_("cannot translate general dereference expression"), e->tok);
5097}
5098
5099
30263a73
FCE
5100void
5101c_unparser::visit_defined_op (defined_op* e)
5102{
dc09353a 5103 throw SEMANTIC_ERROR(_("cannot translate general @defined expression"), e->tok);
9b5af295
JS
5104}
5105
5106
8cc799a5
JS
5107void
5108c_unparser::visit_entry_op (entry_op* e)
5109{
dc09353a 5110 throw SEMANTIC_ERROR(_("cannot translate general @entry expression"), e->tok);
8cc799a5
JS
5111}
5112
5113
3689db05
SC
5114void
5115c_unparser::visit_perf_op (perf_op* e)
5116{
dc09353a 5117 throw SEMANTIC_ERROR(_("cannot translate general @perf expression"), e->tok);
3689db05
SC
5118}
5119
5120
4383d78c 5121void
313b2f74
GH
5122c_unparser::load_map_indices(arrayindex *e,
5123 vector<tmpvar> & idx)
2b066ec1 5124{
dff50e09 5125 symbol *array;
d02548c0
GH
5126 hist_op *hist;
5127 classify_indexable (e->base, array, hist);
313b2f74 5128
d02548c0 5129 if (array)
313b2f74 5130 {
d02548c0 5131 idx.clear();
dff50e09 5132
ed238a16 5133 assert (array->referent != 0);
d02548c0 5134 vardecl* r = array->referent;
dff50e09 5135
d02548c0
GH
5136 if (r->index_types.size() == 0 ||
5137 r->index_types.size() != e->indexes.size())
dc09353a 5138 throw SEMANTIC_ERROR (_("invalid array reference"), e->tok);
dff50e09 5139
d02548c0
GH
5140 for (unsigned i=0; i<r->index_types.size(); i++)
5141 {
5142 if (r->index_types[i] != e->indexes[i]->type)
dc09353a 5143 throw SEMANTIC_ERROR (_("array index type mismatch"), e->indexes[i]->tok);
dff50e09 5144
d02548c0 5145 tmpvar ix = gensym (r->index_types[i]);
b2d74f03 5146 c_assign (ix, e->indexes[i], "array index copy");
d02548c0
GH
5147 idx.push_back (ix);
5148 }
313b2f74 5149 }
d02548c0
GH
5150 else
5151 {
1bbeef03
GH
5152 assert (e->indexes.size() == 1);
5153 assert (e->indexes[0]->type == pe_long);
5154 tmpvar ix = gensym (pe_long);
b2d74f03 5155 c_assign (ix, e->indexes[0], "array index copy");
1bbeef03 5156 idx.push_back(ix);
dff50e09 5157 }
313b2f74 5158}
bb2e3076 5159
2b066ec1 5160
c4782e01
JS
5161var*
5162c_unparser::load_aggregate (expression *e, aggvar & agg)
a4636912
GH
5163{
5164 symbol *sym = get_symbol_within_expression (e);
dff50e09 5165
a4636912 5166 if (sym->referent->type != pe_stats)
dc09353a 5167 throw SEMANTIC_ERROR (_("unexpected aggregate of non-statistic"), sym->tok);
dff50e09 5168
c4782e01 5169 var *v;
a4636912
GH
5170 if (sym->referent->arity == 0)
5171 {
c4782e01 5172 v = new var(getvar(sym->referent, sym->tok));
99613db7 5173 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*sym->tok) << ";";
c4782e01 5174 o->newline() << agg << " = _stp_stat_get (" << *v << ", 0);";
a4636912
GH
5175 }
5176 else
5177 {
c4782e01
JS
5178 mapvar *mv = new mapvar(getmap(sym->referent, sym->tok));
5179 v = mv;
5180
a4636912
GH
5181 arrayindex *arr = NULL;
5182 if (!expression_is_arrayindex (e, arr))
dc09353a 5183 throw SEMANTIC_ERROR(_("unexpected aggregate of non-arrayindex"), e->tok);
dff50e09 5184
bdc82277
JS
5185 // If we have a foreach_loop value, we don't need to index the map
5186 string agg_value;
5187 if (get_foreach_loop_value(arr, agg_value))
5188 o->newline() << agg << " = " << agg_value << ";";
5189 else
5190 {
5191 vector<tmpvar> idx;
5192 load_map_indices (arr, idx);
bdc82277 5193 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*sym->tok) << ";";
c4782e01
JS
5194 bool pre_agg = (aggregations_active.count(mv->value()) > 0);
5195 o->newline() << agg << " = " << mv->get(idx, pre_agg) << ";";
bdc82277 5196 }
a4636912 5197 }
c4782e01
JS
5198
5199 return v;
a4636912
GH
5200}
5201
1bbeef03 5202
dff50e09 5203string
1bbeef03
GH
5204c_unparser::histogram_index_check(var & base, tmpvar & idx) const
5205{
11b52b73 5206 return "((" + idx.value() + " >= 0)"
dff50e09 5207 + " && (" + idx.value() + " < " + base.buckets() + "))";
1bbeef03
GH
5208}
5209
5210
313b2f74 5211void
d6d4dc4b 5212c_unparser::visit_arrayindex (arrayindex* e)
313b2f74 5213{
d6d4dc4b 5214 // If we have a foreach_loop value, use it and call it a day!
bdc82277 5215 string ai_value;
d6d4dc4b
JS
5216 if (get_foreach_loop_value(e, ai_value))
5217 {
5218 o->line() << ai_value;
5219 return;
5220 }
bdc82277 5221
dff50e09 5222 symbol *array;
d02548c0
GH
5223 hist_op *hist;
5224 classify_indexable (e->base, array, hist);
5225
5226 if (array)
5227 {
d6d4dc4b
JS
5228 // Visiting an statistic-valued array in a non-lvalue context is prohibited.
5229 if (array->referent->type == pe_stats)
5230 throw SEMANTIC_ERROR (_("statistic-valued array in rvalue context"), e->tok);
dff50e09 5231
d6d4dc4b 5232 stmt_expr block(*this);
dff50e09 5233
d6d4dc4b
JS
5234 vector<tmpvar> idx;
5235 load_map_indices (e, idx);
5236 tmpvar res = gensym (e->type);
5237
5238 mapvar mvar = getmap (array->referent, e->tok);
5239 // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
5240 c_assign (res, mvar.get(idx), e->tok);
5241
5242 o->newline() << res << ";";
1bbeef03
GH
5243 }
5244 else
5245 {
1bbeef03
GH
5246 // Note: this is a slightly tricker-than-it-looks allocation of
5247 // temporaries. The reason is that we're in the branch handling
5248 // histogram-indexing, and the histogram might be build over an
5249 // indexable entity itself. For example if we have:
dff50e09 5250 //
1bbeef03
GH
5251 // global foo
5252 // ...
5253 // foo[getpid(), geteuid()] <<< 1
5254 // ...
5255 // print @log_hist(foo[pid, euid])[bucket]
dff50e09 5256 //
1bbeef03
GH
5257 // We are looking at the @log_hist(...)[bucket] expression, so
5258 // allocating one tmpvar for calculating bucket (the "index" of
5259 // this arrayindex expression), and one tmpvar for storing the
5260 // result in, just as normal.
dff50e09 5261 //
1bbeef03
GH
5262 // But we are *also* going to call load_aggregate on foo, which
5263 // will itself require tmpvars for each of its indices. Since
5264 // this is not handled by delving into the subexpression (it
5265 // would be if hist were first-class in the type system, but
5266 // it's not) we we allocate all the tmpvars used in such a
5267 // subexpression up here: first our own aggvar, then our index
5268 // (bucket) tmpvar, then all the index tmpvars of our
5269 // pe_stat-valued subexpression, then our result.
5270
1bbeef03 5271 assert(hist);
dff50e09 5272 stmt_expr block(*this);
1bbeef03 5273
d6d4dc4b 5274 aggvar agg = gensym_aggregate ();
dff50e09 5275
1bbeef03
GH
5276 vector<tmpvar> idx;
5277 load_map_indices (e, idx);
5278 tmpvar res = gensym (e->type);
dff50e09 5279
1bbeef03 5280 // These should have faulted during elaboration if not true.
d6d4dc4b
JS
5281 if (idx.size() != 1 || idx[0].type() != pe_long)
5282 throw SEMANTIC_ERROR(_("Invalid indexing of histogram"), e->tok);
1bbeef03 5283
c4782e01 5284 var *v = load_aggregate(hist->stat, agg);
1820694f 5285 v->assert_hist_compatible(*hist);
1bbeef03 5286
5db2fa89 5287 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
1bbeef03 5288
35ba8b83 5289 // PR 2142+2610: empty aggregates
11b52b73 5290 o->newline() << "if (unlikely (" << agg.value() << " == NULL)"
12363146 5291 << " || " << agg.value() << "->count == 0) {";
b5f561be
LB
5292 o->newline(1) << "c->last_error = ";
5293 o->line() << STAP_T_06;
12363146
JS
5294 o->newline() << "goto out;";
5295 o->newline(-1) << "} else {";
35ba8b83 5296 o->newline(1) << "if (" << histogram_index_check(*v, idx[0]) << ")";
5db2fa89 5297 o->newline(1) << res << " = " << agg << "->histogram[" << idx[0] << "];";
12363146 5298 o->newline(-1) << "else {";
b5f561be
LB
5299 o->newline(1) << "c->last_error = ";
5300 o->line() << STAP_T_07;
12363146
JS
5301 o->newline() << "goto out;";
5302 o->newline(-1) << "}";
1820694f 5303
5db2fa89 5304 o->newline(-1) << "}";
12363146 5305 o->newline() << res << ";";
dff50e09 5306
35ba8b83 5307 delete v;
d02548c0 5308 }
313b2f74 5309}
4383d78c 5310
bb2e3076 5311
4383d78c
FCE
5312void
5313c_unparser_assignment::visit_arrayindex (arrayindex *e)
2b066ec1 5314{
dff50e09 5315 symbol *array;
d02548c0
GH
5316 hist_op *hist;
5317 classify_indexable (e->base, array, hist);
313b2f74 5318
d02548c0
GH
5319 if (array)
5320 {
313b2f74 5321
dff50e09 5322 stmt_expr block(*parent);
313b2f74 5323
d02548c0 5324 translator_output *o = parent->o;
57b73400 5325
d02548c0 5326 if (array->referent->index_types.size() == 0)
dc09353a 5327 throw SEMANTIC_ERROR (_("unexpected reference to scalar"), e->tok);
57b73400 5328
d02548c0
GH
5329 vector<tmpvar> idx;
5330 parent->load_map_indices (e, idx);
5331 exp_type ty = rvalue ? rvalue->type : e->type;
5332 tmpvar rvar = parent->gensym (ty);
5333 tmpvar lvar = parent->gensym (ty);
5334 tmpvar res = parent->gensym (ty);
dff50e09 5335
d02548c0
GH
5336 // NB: because these expressions are nestable, emit this construct
5337 // thusly:
5338 // ({ tmp0=(idx0); ... tmpN=(idxN); rvar=(rhs); lvar; res;
5339 // lock (array);
5340 // lvar = get (array,idx0...N); // if necessary
5341 // assignop (res, lvar, rvar);
5342 // set (array, idx0...N, lvar);
5343 // unlock (array);
5344 // res; })
5345 //
5346 // we store all indices in temporary variables to avoid nasty
5347 // reentrancy issues that pop up with nested expressions:
5348 // e.g. ++a[a[c]=5] could deadlock
5349 //
5350 //
dff50e09 5351 // There is an exception to the above form: if we're doign a <<< assigment to
d02548c0
GH
5352 // a statistic-valued map, there's a special form we follow:
5353 //
c01d3d3d 5354 // ({ tmp0=(idx0); ... tmpN=(idxN); rvar=(rhs);
8616e84e 5355 // *no need to* lock (array);
d02548c0 5356 // _stp_map_add_stat (array, idx0...N, rvar);
8616e84e 5357 // *no need to* unlock (array);
d02548c0
GH
5358 // rvar; })
5359 //
5360 // To simplify variable-allocation rules, we assign rvar to lvar and
5361 // res in this block as well, even though they are technically
5362 // superfluous.
5363
5364 prepare_rvalue (op, rvar, e->tok);
5365
5366 if (op == "<<<")
5367 {
5368 assert (e->type == pe_stats);
5369 assert (rvalue->type == pe_long);
5370
5371 mapvar mvar = parent->getmap (array->referent, e->tok);
cd1db1dd 5372 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
d02548c0 5373 o->newline() << mvar.add (idx, rvar) << ";";
c01d3d3d
FCE
5374 res = rvar;
5375 // no need for these dummy assignments
5376 // o->newline() << lvar << " = " << rvar << ";";
5377 // o->newline() << res << " = " << rvar << ";";
d02548c0
GH
5378 }
5379 else
13a9593f 5380 {
d02548c0 5381 mapvar mvar = parent->getmap (array->referent, e->tok);
cd1db1dd 5382 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
d02548c0
GH
5383 if (op != "=") // don't bother fetch slot if we will just overwrite it
5384 parent->c_assign (lvar, mvar.get(idx), e->tok);
dff50e09 5385 c_assignop (res, lvar, rvar, e->tok);
d02548c0
GH
5386 o->newline() << mvar.set (idx, lvar) << ";";
5387 }
57b73400 5388
d02548c0 5389 o->newline() << res << ";";
dff50e09 5390 }
57b73400 5391 else
d02548c0 5392 {
dc09353a 5393 throw SEMANTIC_ERROR(_("cannot assign to histogram buckets"), e->tok);
57b73400 5394 }
2b066ec1
FCE
5395}
5396
5397
4383d78c
FCE
5398void
5399c_unparser::visit_functioncall (functioncall* e)
2b066ec1 5400{
ed238a16 5401 assert (e->referent != 0);
2b066ec1
FCE
5402 functiondecl* r = e->referent;
5403
5404 if (r->formal_args.size() != e->args.size())
dc09353a 5405 throw SEMANTIC_ERROR (_("invalid length argument list"), e->tok);
2b066ec1 5406
dff50e09 5407 stmt_expr block(*this);
2b066ec1
FCE
5408
5409 // NB: we store all actual arguments in temporary variables,
5410 // to avoid colliding sharing of context variables with
5411 // nested function calls: f(f(f(1)))
5412
69c68955 5413 // compute actual arguments
313b2f74 5414 vector<tmpvar> tmp;
4383d78c 5415
2b066ec1
FCE
5416 for (unsigned i=0; i<e->args.size(); i++)
5417 {
313b2f74 5418 tmpvar t = gensym(e->args[i]->type);
4383d78c 5419
2b066ec1 5420 if (r->formal_args[i]->type != e->args[i]->type)
dc09353a 5421 throw SEMANTIC_ERROR (_("function argument type mismatch"),
e26c2f83 5422 e->args[i]->tok, r->formal_args[i]->tok);
ce10591c 5423
e92d43e9 5424 symbol *sym_out;
b2d74f03
JS
5425 if (r->formal_args[i]->char_ptr_arg && e->args[i]->is_symbol(sym_out)
5426 && is_local(sym_out->referent, sym_out->tok))
5427 t.override(getvar(sym_out->referent, sym_out->tok).value());
94603dab 5428 else
b2d74f03
JS
5429 c_assign (t, e->args[i],
5430 _("function actual argument evaluation"));
94603dab 5431 tmp.push_back(t);
2b066ec1
FCE
5432 }
5433
4383d78c 5434 // copy in actual arguments
2b066ec1
FCE
5435 for (unsigned i=0; i<e->args.size(); i++)
5436 {
5437 if (r->formal_args[i]->type != e->args[i]->type)
dc09353a 5438 throw SEMANTIC_ERROR (_("function argument type mismatch"),
e26c2f83 5439 e->args[i]->tok, r->formal_args[i]->tok);
ce10591c 5440
e92d43e9
AJ
5441 if (r->formal_args[i]->char_ptr_arg)
5442 o->newline() << "c->locals[c->nesting+1]." + c_funcname (r->name) + "."
5443 + c_localname (r->formal_args[i]->name) << " = "
5444 << tmp[i].value() << ";";
5445 else
5446 c_assign ("c->locals[c->nesting+1]." +
5447 c_funcname (r->name) + "." +
5448 c_localname (r->formal_args[i]->name),
5449 tmp[i].value(),
5450 e->args[i]->type,
5451 "function actual argument copy",
5452 e->args[i]->tok);
2b066ec1
FCE
5453 }
5454
6c22bc26
AJ
5455 // store the return value after the function arguments have been worked out
5456 // to avoid problems that may occure with nesting.
296c059b
JS
5457 tmpvar tmp_ret = gensym (e->type);
5458
5459 // optimized string returns need a local storage pointer.
5460 bool pointer_ret = (e->type == pe_string && !session->unoptimized);
5461 if (pointer_ret)
5462 {
5463 if (e == assigned_functioncall)
5464 tmp_ret.override (*assigned_functioncall_retval);
5465 o->newline() << "c->locals[c->nesting+1]." << c_funcname(r->name)
5466 << ".__retvalue = &" << tmp_ret.value() << "[0];";
5467 }
6c22bc26 5468
2b066ec1 5469 // call function
0386bbcf 5470 o->newline() << c_funcname (r->name) << " (c);";
12363146 5471 o->newline() << "if (unlikely(c->last_error)) goto out;";
bb788f9f 5472
765e6976
AJ
5473 if (!already_checked_action_count && !session->suppress_time_limits
5474 && !session->unoptimized)
5475 {
5476 max_action_info mai (*session);
5477 e->referent->body->visit(&mai);
5478 // if an unoptimized function/probe called an optimized function, then
5479 // increase the counter, since the subtraction isn't done within an
5480 // optimized function
5481 if(mai.statement_count_finite())
5482 record_actions (mai.statement_count, e->tok, true);
5483 }
0c5ef9de
FCE
5484
5485 // return result from retvalue slot NB: this must be last, for the
5486 // enclosing statement-expression ({ ... }) to carry this value.
f281029c
JS
5487 if (r->type == pe_unknown || tmp_ret.is_overridden())
5488 // If we passed typechecking with pe_unknown, or if we directly assigned
5489 // the functioncall retval, then nothing will use this return value
0c5ef9de 5490 o->newline() << "(void) 0;";
296c059b 5491 else if (!pointer_ret)
0c5ef9de
FCE
5492 o->newline() << "c->locals[c->nesting+1]"
5493 << "." << c_funcname (r->name)
5494 << ".__retvalue;";
f281029c 5495 else
cfaa0635 5496 o->newline() << tmp_ret.value() << ";";
0c5ef9de 5497
2b066ec1
FCE
5498}
5499
5b1fa53b 5500
d6fa4974
JS
5501// returns true if it should print directly to a stream
5502static bool
5b1fa53b
JS
5503preprocess_print_format(print_format* e, vector<tmpvar>& tmp,
5504 vector<print_format::format_component>& components,
5505 string& format_string)
5506{
5b1fa53b
JS
5507 if (e->print_with_format)
5508 {
5509 format_string = e->raw_components;
5510 components = e->components;
5511 }
5512 else
5513 {
5514 string delim;
5515 if (e->print_with_delim)
5516 {
5517 stringstream escaped_delim;
d70e3afe 5518 interned_string dstr = e->delimiter;
47d349b1 5519 for (interned_string::const_iterator i = dstr.begin();
5b1fa53b
JS
5520 i != dstr.end(); ++i)
5521 {
5522 if (*i == '%')
5523 escaped_delim << '%';
5524 escaped_delim << *i;
5525 }
5526 delim = escaped_delim.str();
5527 }
5528
5529 // Synthesize a print-format string if the user didn't
5530 // provide one; the synthetic string simply contains one
5531 // directive for each argument.
5532 stringstream format;
5533 for (unsigned i = 0; i < e->args.size(); ++i)
5534 {
5535 if (i > 0 && e->print_with_delim)
5536 format << delim;
5537 switch (e->args[i]->type)
5538 {
5539 default:
5540 case pe_unknown:
dc09353a 5541 throw SEMANTIC_ERROR(_("cannot print unknown expression type"), e->args[i]->tok);
5b1fa53b 5542 case pe_stats:
dc09353a 5543 throw SEMANTIC_ERROR(_("cannot print a raw stats object"), e->args[i]->tok);
5b1fa53b
JS
5544 case pe_long:
5545 format << "%d";
5546 break;
5547 case pe_string:
5548 format << "%s";
5549 break;
5550 }
5551 }
5552 if (e->print_with_newline)
5553 format << "\\n";
5554
5555 format_string = format.str();
5556 components = print_format::string_to_components(format_string);
5557 }
5558
5559
d6fa4974
JS
5560 // optimize simple string prints
5561 if (e->print_to_stream && tmp.size() <= 1
5562 && format_string.find("%%") == string::npos)
5b1fa53b 5563 {
d6fa4974
JS
5564 // just a plain format string itself, or
5565 // simply formatting a string verbatim.
5566 if (tmp.empty() || format_string == "%s")
5567 return true;
5568
5569 // just a string without formatting plus newline, and it's been
5570 // overridden with a literal, then we can token-paste the newline.
5571 // TODO could allow any prefix and suffix around "%s", C-escaped.
b2d74f03 5572 if (tmp[0].is_overridden() && format_string == "%s\\n")
d6fa4974
JS
5573 {
5574 tmp[0].override(tmp[0].value() + "\"\\n\"");
5575 return true;
5576 }
5b1fa53b
JS
5577 }
5578
d6fa4974 5579 return false;
5b1fa53b
JS
5580}
5581
d02548c0 5582
dff50e09 5583void
d02548c0
GH
5584c_unparser::visit_print_format (print_format* e)
5585{
5586 // Print formats can contain a general argument list *or* a special
5587 // type of argument which gets its own processing: a single,
5588 // non-format-string'ed, histogram-type stat_op expression.
5589
a4636912 5590 if (e->hist)
d02548c0 5591 {
dff50e09 5592 stmt_expr block(*this);
a4636912 5593 aggvar agg = gensym_aggregate ();
a4636912 5594
c4782e01 5595 var *v = load_aggregate(e->hist->stat, agg);
1820694f
JS
5596 v->assert_hist_compatible(*e->hist);
5597
5598 {
35ba8b83 5599 // PR 2142+2610: empty aggregates
11b52b73 5600 o->newline() << "if (unlikely (" << agg.value() << " == NULL)"
99613db7 5601 << " || " << agg.value() << "->count == 0) {";
b5f561be
LB
5602 o->newline(1) << "c->last_error = ";
5603 o->line() << STAP_T_06;
99613db7 5604 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
12363146 5605 o->newline() << "goto out;";
99613db7 5606 o->newline(-1) << "} else";
b15c465c
PP
5607 if (e->print_to_stream)
5608 {
5609 o->newline(1) << "_stp_stat_print_histogram (" << v->hist() << ", " << agg.value() << ");";
5610 o->indent(-1);
5611 }
5612 else
5613 {
5614 exp_type ty = pe_string;
5615 tmpvar res = gensym (ty);
5616 o->newline(1) << "_stp_stat_print_histogram_buf (" << res.value() << ", MAXSTRINGLEN, " << v->hist() << ", " << agg.value() << ");";
5617 o->newline(-1) << res.value() << ";";
5618 }
1820694f
JS
5619 }
5620
5621 delete v;
d02548c0
GH
5622 }
5623 else
5624 {
dff50e09 5625 stmt_expr block(*this);
d02548c0 5626
8f805d33
JS
5627 // PR10750: Enforce a reasonable limit on # of varargs
5628 // 32 varargs leads to max 256 bytes on the stack
5629 if (e->args.size() > 32)
dc09353a 5630 throw SEMANTIC_ERROR(_NF("additional argument to print", "too many arguments to print (%zu)",
52c2652f 5631 e->args.size(), e->args.size()), e->tok);
8f805d33 5632
d02548c0
GH
5633 // Compute actual arguments
5634 vector<tmpvar> tmp;
dff50e09 5635
d02548c0
GH
5636 for (unsigned i=0; i<e->args.size(); i++)
5637 {
5638 tmpvar t = gensym(e->args[i]->type);
b2d74f03
JS
5639 c_assign (t, e->args[i],
5640 "print format actual argument evaluation");
d02548c0 5641 tmp.push_back(t);
d02548c0
GH
5642 }
5643
d02548c0
GH
5644 // Allocate the result
5645 exp_type ty = e->print_to_stream ? pe_long : pe_string;
dff50e09 5646 tmpvar res = gensym (ty);
5b1fa53b
JS
5647
5648 // Munge so we can find our compiled printf
5649 vector<print_format::format_component> components;
1386d8fc 5650 string format_string, format_string_out;
d6fa4974 5651 bool use_print = preprocess_print_format(e, tmp, components, format_string);
1386d8fc 5652 format_string_out = print_format::components_to_string(components);
d02548c0 5653
12363146 5654 // Make the [s]printf call...
ec03bd4b 5655
0da35eae 5656 // Generate code to check that any pointer arguments are actually accessible.
929eb962 5657 size_t arg_ix = 0;
ec03bd4b
DB
5658 for (unsigned i = 0; i < components.size(); ++i) {
5659 if (components[i].type == print_format::conv_literal)
5660 continue;
5661
5662 /* Take note of the width and precision arguments, if any. */
5663 int width_ix = -1, prec_ix= -1;
5664 if (components[i].widthtype == print_format::width_dynamic)
5665 width_ix = arg_ix++;
5666 if (components[i].prectype == print_format::prec_dynamic)
5667 prec_ix = arg_ix++;
5668
5d8a0aea
FCE
5669 (void) width_ix; /* XXX: notused */
5670
63db23df 5671 /* %m and %M need special care for digging into memory. */
30c94a80 5672 if (components[i].type == print_format::conv_memory
63db23df
JS
5673 || components[i].type == print_format::conv_memory_hex)
5674 {
5675 string mem_size;
54975cd8 5676 const token* prec_tok = e->tok;
63db23df 5677 if (prec_ix != -1)
54975cd8
JS
5678 {
5679 mem_size = tmp[prec_ix].value();
5680 prec_tok = e->args[prec_ix]->tok;
5681 }
63db23df
JS
5682 else if (components[i].prectype == print_format::prec_static &&
5683 components[i].precision > 0)
5684 mem_size = lex_cast(components[i].precision) + "LL";
5685 else
5686 mem_size = "1LL";
5687
5688 /* Limit how much can be printed at a time. (see also PR10490) */
2ec6b38c 5689 o->newline() << "c->last_stmt = " << lex_cast_qstring(*prec_tok) << ";";
63db23df
JS
5690 o->newline() << "if (" << mem_size << " > 1024) {";
5691 o->newline(1) << "snprintf(c->error_buffer, sizeof(c->error_buffer), "
060b2633 5692 << "\"%lld is too many bytes for a memory dump\", (long long)"
63db23df
JS
5693 << mem_size << ");";
5694 o->newline() << "c->last_error = c->error_buffer;";
5695 o->newline() << "goto out;";
5696 o->newline(-1) << "}";
63db23df 5697 }
ec03bd4b
DB
5698
5699 ++arg_ix;
5700 }
5701
929eb962 5702 // Shortcuts for cases that aren't formatted at all
d02548c0 5703 if (e->print_to_stream)
f5334f06 5704 {
32784362
MH
5705 if (e->print_char)
5706 {
5707 o->newline() << "_stp_print_char (";
5708 if (tmp.size())
5709 o->line() << tmp[0].value() << ");";
5710 else
1386d8fc 5711 o->line() << '"' << format_string_out << "\");";
dff50e09 5712 return;
32784362
MH
5713 }
5714 if (use_print)
5715 {
5716 o->newline() << "_stp_print (";
5717 if (tmp.size())
5718 o->line() << tmp[0].value() << ");";
5719 else
1386d8fc 5720 o->line() << '"' << format_string_out << "\");";
32784362
MH
5721 return;
5722 }
929eb962
JS
5723 }
5724
0da35eae
JS
5725 // The default it to use the new compiled-printf, but one can fall back
5726 // to the old code with -DSTP_LEGACY_PRINT if desired.
5727 o->newline() << "#ifndef STP_LEGACY_PRINT";
5728 o->indent(1);
5729
5b1fa53b
JS
5730 // Copy all arguments to the compiled-printf's space, then call it
5731 const string& compiled_printf =
5732 get_compiled_printf (e->print_to_stream, format_string);
5733 for (unsigned i = 0; i < tmp.size(); ++i)
5734 o->newline() << "c->printf_locals." << compiled_printf
5735 << ".arg" << i << " = " << tmp[i].value() << ";";
929eb962 5736 if (e->print_to_stream)
5b1fa53b
JS
5737 // We'll just hardcode the result of 0 instead of using the
5738 // temporary.
5739 res.override("((int64_t)0LL)");
5740 else
5741 o->newline() << "c->printf_locals." << compiled_printf
5742 << ".__retvalue = " << res.value() << ";";
5743 o->newline() << compiled_printf << " (c);";
0da35eae
JS
5744
5745 o->newline(-1) << "#else // STP_LEGACY_PRINT";
5746 o->indent(1);
5747
5748 // Generate the legacy call that goes through _stp_vsnprintf.
5749 if (e->print_to_stream)
5750 o->newline() << "_stp_printf (";
5751 else
5752 o->newline() << "_stp_snprintf (" << res.value() << ", MAXSTRINGLEN, ";
1386d8fc 5753 o->line() << '"' << format_string_out << '"';
0da35eae
JS
5754
5755 // Make sure arguments match the expected type of the format specifier.
5756 arg_ix = 0;
5757 for (unsigned i = 0; i < components.size(); ++i)
5758 {
5759 if (components[i].type == print_format::conv_literal)
5760 continue;
5761
5762 /* Cast the width and precision arguments, if any, to 'int'. */
5763 if (components[i].widthtype == print_format::width_dynamic)
5764 o->line() << ", (int)" << tmp[arg_ix++].value();
5765 if (components[i].prectype == print_format::prec_dynamic)
5766 o->line() << ", (int)" << tmp[arg_ix++].value();
5767
5768 /* The type of the %m argument is 'char*'. */
5769 if (components[i].type == print_format::conv_memory
5770 || components[i].type == print_format::conv_memory_hex)
5771 o->line() << ", (char*)(uintptr_t)" << tmp[arg_ix++].value();
5772 /* The type of the %c argument is 'int'. */
5773 else if (components[i].type == print_format::conv_char)
5774 o->line() << ", (int)" << tmp[arg_ix++].value();
5775 else if (arg_ix < tmp.size())
5776 o->line() << ", " << tmp[arg_ix++].value();
5777 }
5778 o->line() << ");";
5779 o->newline(-1) << "#endif // STP_LEGACY_PRINT";
bcc1790f 5780 o->newline() << "if (unlikely(c->last_error)) goto out;";
11b52b73 5781 o->newline() << res.value() << ";";
d02548c0
GH
5782 }
5783}
5784
dff50e09 5785void
d02548c0
GH
5786c_unparser::visit_stat_op (stat_op* e)
5787{
d02548c0
GH
5788 // Stat ops can be *applied* to two types of expression:
5789 //
dff50e09 5790 // 1. An arrayindex expression on a pe_stats-valued array.
d02548c0 5791 //
dff50e09 5792 // 2. A symbol of type pe_stats.
d02548c0
GH
5793
5794 // FIXME: classify the expression the stat_op is being applied to,
5795 // call appropriate stp_get_stat() / stp_pmap_get_stat() helper,
5796 // then reach into resultant struct stat_data.
5797
07c17d67
GH
5798 // FIXME: also note that summarizing anything is expensive, and we
5799 // really ought to pass a timeout handler into the summary routine,
5800 // check its response, possibly exit if it ran out of cycles.
dff50e09 5801
07c17d67 5802 {
a4636912 5803 stmt_expr block(*this);
07c17d67 5804 aggvar agg = gensym_aggregate ();
dff50e09 5805 tmpvar res = gensym (pe_long);
c4782e01 5806 var *v = load_aggregate(e->stat, agg);
07c17d67 5807 {
35ba8b83 5808 // PR 2142+2610: empty aggregates
cb034dff
JS
5809 if ((e->ctype == sc_count) ||
5810 (e->ctype == sc_sum &&
5811 strverscmp(session->compatible.c_str(), "1.5") >= 0))
35ba8b83 5812 {
11b52b73 5813 o->newline() << "if (unlikely (" << agg.value() << " == NULL))";
35ba8b83
FCE
5814 o->indent(1);
5815 c_assign(res, "0", e->tok);
5816 o->indent(-1);
5817 }
5db2fa89 5818 else
35ba8b83 5819 {
11b52b73 5820 o->newline() << "if (unlikely (" << agg.value() << " == NULL)"
12363146 5821 << " || " << agg.value() << "->count == 0) {";
b5f561be
LB
5822 o->newline(1) << "c->last_error = ";
5823 o->line() << STAP_T_06;
12363146
JS
5824 o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
5825 o->newline() << "goto out;";
5826 o->newline(-1) << "}";
35ba8b83
FCE
5827 }
5828 o->newline() << "else";
5db2fa89 5829 o->indent(1);
07c17d67 5830 switch (e->ctype)
35ba8b83
FCE
5831 {
5832 case sc_average:
12363146 5833 c_assign(res, ("_stp_div64(NULL, " + agg.value() + "->sum, "
11b52b73 5834 + agg.value() + "->count)"),
35ba8b83
FCE
5835 e->tok);
5836 break;
5837 case sc_count:
11b52b73 5838 c_assign(res, agg.value() + "->count", e->tok);
35ba8b83
FCE
5839 break;
5840 case sc_sum:
11b52b73 5841 c_assign(res, agg.value() + "->sum", e->tok);
35ba8b83
FCE
5842 break;
5843 case sc_min:
11b52b73 5844 c_assign(res, agg.value() + "->min", e->tok);
35ba8b83
FCE
5845 break;
5846 case sc_max:
11b52b73 5847 c_assign(res, agg.value() + "->max", e->tok);
35ba8b83 5848 break;
fd5689dc
FCE
5849 case sc_none:
5850 assert (0); // should not happen, as sc_none is only used in foreach sorts
35ba8b83
FCE
5851 }
5852 o->indent(-1);
dff50e09 5853 }
07c17d67 5854 o->newline() << res << ";";
c4782e01 5855 delete v;
07c17d67 5856 }
d02548c0
GH
5857}
5858
5859
dff50e09 5860void
78f6bba6 5861c_unparser::visit_hist_op (hist_op*)
d02548c0 5862{
07c17d67
GH
5863 // Hist ops can only occur in a limited set of circumstances:
5864 //
5865 // 1. Inside an arrayindex expression, as the base referent. See
5866 // c_unparser::visit_arrayindex for handling of this case.
5867 //
5868 // 2. Inside a foreach statement, as the base referent. See
5869 // c_unparser::visit_foreach_loop for handling this case.
5870 //
5871 // 3. Inside a print_format expression, as the sole argument. See
5872 // c_unparser::visit_print_format for handling this case.
5873 //
5874 // Note that none of these cases involves the c_unparser ever
5875 // visiting this node. We should not get here.
5876
d02548c0
GH
5877 assert(false);
5878}
2b066ec1 5879
fa670082 5880
c9970555 5881typedef map<Dwarf_Addr,const char*> addrmap_t; // NB: plain map, sorted by address
fa670082 5882
f5973d67 5883struct unwindsym_dump_context
fa670082 5884{
f5973d67
FCE
5885 systemtap_session& session;
5886 ostream& output;
1b94bf6d 5887 unsigned stp_module_index;
c9970555
MW
5888
5889 int build_id_len;
5890 unsigned char *build_id_bits;
5891 GElf_Addr build_id_vaddr;
5892
129de9ef 5893 unsigned long stp_kretprobe_trampoline_addr;
c9970555
MW
5894 Dwarf_Addr stext_offset;
5895
5896 vector<pair<string,unsigned> > seclist; // encountered relocation bases
5897 // (section names and sizes)
5898 map<unsigned, addrmap_t> addrmap; // per-relocation-base sorted addrmap
5899
5900 void *debug_frame;
5901 size_t debug_len;
5902 void *debug_frame_hdr;
5903 size_t debug_frame_hdr_len;
5904 Dwarf_Addr debug_frame_off;
5905 void *eh_frame;
5906 void *eh_frame_hdr;
5907 size_t eh_len;
5908 size_t eh_frame_hdr_len;
5909 Dwarf_Addr eh_addr;
5910 Dwarf_Addr eh_frame_hdr_addr;
ee533a58
AJ
5911 void *debug_line;
5912 size_t debug_line_len;
c9970555 5913
4464a6bb 5914 set<string> undone_unwindsym_modules;
f5973d67
FCE
5915};
5916
9424498b
MW
5917static void create_debug_frame_hdr (const unsigned char e_ident[],
5918 Elf_Data *debug_frame,
5919 void **debug_frame_hdr,
5920 size_t *debug_frame_hdr_len,
4d83bd9b 5921 Dwarf_Addr *debug_frame_off,
9424498b 5922 systemtap_session& session,
4d83bd9b 5923 Dwfl_Module *mod)
9424498b
MW
5924{
5925 *debug_frame_hdr = NULL;
5926 *debug_frame_hdr_len = 0;
5927
5928 int cies = 0;
5929 set< pair<Dwarf_Addr, Dwarf_Off> > fdes;
5930 set< pair<Dwarf_Addr, Dwarf_Off> >::iterator it;
5931
5932 // In the .debug_frame the FDE encoding is always DW_EH_PE_absptr.
5933 // So there is no need to read the CIEs. And the size is either 4
5934 // or 8, depending on the elf class from e_ident.
5935 int size = (e_ident[EI_CLASS] == ELFCLASS32) ? 4 : 8;
5936 int res = 0;
5937 Dwarf_Off off = 0;
5938 Dwarf_CFI_Entry entry;
5939
822a6a3d 5940 while (res != 1)
9424498b
MW
5941 {
5942 Dwarf_Off next_off;
5943 res = dwarf_next_cfi (e_ident, debug_frame, false, off, &next_off,
5944 &entry);
5945 if (res == 0)
5946 {
5947 if (entry.CIE_id == DW_CIE_ID_64)
5948 cies++; // We can just ignore the CIEs.
5949 else
5950 {
5951 Dwarf_Addr addr;
5952 if (size == 4)
5953 addr = (*((uint32_t *) entry.fde.start));
5954 else
5955 addr = (*((uint64_t *) entry.fde.start));
5956 fdes.insert(pair<Dwarf_Addr, Dwarf_Off>(addr, off));
5957 }
5958 }
5959 else if (res > 0)
5960 ; // Great, all done.
5961 else
5962 {
5963 // Warn, but continue, backtracing will be slow...
5964 if (session.verbose > 2 && ! session.suppress_warnings)
4d83bd9b
MW
5965 {
5966 const char *modname = dwfl_module_info (mod, NULL,
5967 NULL, NULL, NULL,
5968 NULL, NULL, NULL);
5969 session.print_warning("Problem creating debug frame hdr for "
5970 + lex_cast_qstring(modname)
5971 + ", " + dwarf_errmsg (-1));
5972 }
9424498b
MW
5973 return;
5974 }
5975 off = next_off;
5976 }
5977
4d83bd9b
MW
5978 if (fdes.size() > 0)
5979 {
5980 it = fdes.begin();
5981 Dwarf_Addr first_addr = (*it).first;
5982 int res = dwfl_module_relocate_address (mod, &first_addr);
e1c3b13a 5983 DWFL_ASSERT ("create_debug_frame_hdr, dwfl_module_relocate_address",
4d83bd9b
MW
5984 res >= 0);
5985 *debug_frame_off = (*it).first - first_addr;
5986 }
5987
9424498b
MW
5988 size_t total_size = 4 + (2 * size) + (2 * size * fdes.size());
5989 uint8_t *hdr = (uint8_t *) malloc(total_size);
5990 *debug_frame_hdr = hdr;
5991 *debug_frame_hdr_len = total_size;
5992
5993 hdr[0] = 1; // version
5994 hdr[1] = DW_EH_PE_absptr; // ptr encoding
5995 hdr[2] = (size == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8; // count encoding
5996 hdr[3] = DW_EH_PE_absptr; // table encoding
5997 if (size == 4)
5998 {
5999 uint32_t *table = (uint32_t *)(hdr + 4);
6000 *table++ = (uint32_t) 0; // eh_frame_ptr, unused
6001 *table++ = (uint32_t) fdes.size();
6002 for (it = fdes.begin(); it != fdes.end(); it++)
6003 {
6004 *table++ = (*it).first;
6005 *table++ = (*it).second;
6006 }
6007 }
6008 else
6009 {
6010 uint64_t *table = (uint64_t *)(hdr + 4);
6011 *table++ = (uint64_t) 0; // eh_frame_ptr, unused
6012 *table++ = (uint64_t) fdes.size();
6013 for (it = fdes.begin(); it != fdes.end(); it++)
6014 {
6015 *table++ = (*it).first;
6016 *table++ = (*it).second;
6017 }
6018 }
6019}
6020
081b45d1
MW
6021static set<string> vdso_paths;
6022
4285dc9a
MW
6023// Get the .debug_frame end .eh_frame sections for the given module.
6024// Also returns the lenght of both sections when found, plus the section
9424498b
MW
6025// address (offset) of the eh_frame data. If a debug_frame is found, a
6026// synthesized debug_frame_hdr is also returned.
4285dc9a
MW
6027static void get_unwind_data (Dwfl_Module *m,
6028 void **debug_frame, void **eh_frame,
6029 size_t *debug_len, size_t *eh_len,
0f33053e 6030 Dwarf_Addr *eh_addr,
9424498b
MW
6031 void **eh_frame_hdr, size_t *eh_frame_hdr_len,
6032 void **debug_frame_hdr,
6033 size_t *debug_frame_hdr_len,
4d83bd9b 6034 Dwarf_Addr *debug_frame_off,
9424498b 6035 Dwarf_Addr *eh_frame_hdr_addr,
c9970555 6036 systemtap_session& session)
61a80584 6037{
c65358e8 6038 Dwarf_Addr start, bias = 0;
61a80584
MW
6039 GElf_Ehdr *ehdr, ehdr_mem;
6040 GElf_Shdr *shdr, shdr_mem;
4285dc9a 6041 Elf_Scn *scn;
6b65ca81 6042 Elf_Data *data = NULL;
4285dc9a
MW
6043 Elf *elf;
6044
6045 // fetch .eh_frame info preferably from main elf file.
e9068f4d 6046 dwfl_module_info (m, NULL, &start, NULL, NULL, NULL, NULL, NULL);
4285dc9a
MW
6047 elf = dwfl_module_getelf(m, &bias);
6048 ehdr = gelf_getehdr(elf, &ehdr_mem);
081b45d1 6049
4285dc9a 6050 scn = NULL;
ef187c96
CM
6051 bool eh_frame_seen = false;
6052 bool eh_frame_hdr_seen = false;
4285dc9a 6053 while ((scn = elf_nextscn(elf, scn)))
61a80584 6054 {
4285dc9a 6055 shdr = gelf_getshdr(scn, &shdr_mem);
0f33053e 6056 const char* scn_name = elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name);
9cc3e70c
MW
6057 if (!eh_frame_seen
6058 && strcmp(scn_name, ".eh_frame") == 0
6059 && shdr->sh_type == SHT_PROGBITS)
61a80584 6060 {
4285dc9a
MW
6061 data = elf_rawdata(scn, NULL);
6062 *eh_frame = data->d_buf;
6063 *eh_len = data->d_size;
c65358e8 6064 // For ".dynamic" sections we want the offset, not absolute addr.
c3999423
MW
6065 // Note we don't trust dwfl_module_relocations() for ET_EXEC.
6066 if (ehdr->e_type != ET_EXEC && dwfl_module_relocations (m) > 0)
c65358e8
MW
6067 *eh_addr = shdr->sh_addr - start + bias;
6068 else
6069 *eh_addr = shdr->sh_addr;
0f33053e 6070 eh_frame_seen = true;
61a80584 6071 }
9cc3e70c
MW
6072 else if (!eh_frame_hdr_seen
6073 && strcmp(scn_name, ".eh_frame_hdr") == 0
6074 && shdr->sh_type == SHT_PROGBITS)
0f33053e
TM
6075 {
6076 data = elf_rawdata(scn, NULL);
6077 *eh_frame_hdr = data->d_buf;
6078 *eh_frame_hdr_len = data->d_size;
c3999423 6079 if (ehdr->e_type != ET_EXEC && dwfl_module_relocations (m) > 0)
0f33053e
TM
6080 *eh_frame_hdr_addr = shdr->sh_addr - start + bias;
6081 else
6082 *eh_frame_hdr_addr = shdr->sh_addr;
6083 eh_frame_hdr_seen = true;
6084 }
6085 if (eh_frame_seen && eh_frame_hdr_seen)
6086 break;
61a80584
MW
6087 }
6088
4285dc9a
MW
6089 // fetch .debug_frame info preferably from dwarf debuginfo file.
6090 elf = (dwarf_getelf (dwfl_module_getdwarf (m, &bias))
6091 ?: dwfl_module_getelf (m, &bias));
6092 ehdr = gelf_getehdr(elf, &ehdr_mem);
6093 scn = NULL;
6094 while ((scn = elf_nextscn(elf, scn)))
61a80584 6095 {
4285dc9a
MW
6096 shdr = gelf_getshdr(scn, &shdr_mem);
6097 if (strcmp(elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name),
6098 ".debug_frame") == 0)
6099 {
6100 data = elf_rawdata(scn, NULL);
6101 *debug_frame = data->d_buf;
6102 *debug_len = data->d_size;
6103 break;
6104 }
61a80584 6105 }
9424498b
MW
6106
6107 if (*debug_frame != NULL && *debug_len > 0)
6108 create_debug_frame_hdr (ehdr->e_ident, data,
6109 debug_frame_hdr, debug_frame_hdr_len,
c9970555 6110 debug_frame_off, session, m);
61a80584
MW
6111}
6112
fa670082 6113static int
c9970555
MW
6114dump_build_id (Dwfl_Module *m,
6115 unwindsym_dump_context *c,
dabd71bb 6116 const char *name, Dwarf_Addr)
fa670082 6117{
f5973d67
FCE
6118 string modname = name;
6119
29495972
WH
6120 //extract build-id from debuginfo file
6121 int build_id_len = 0;
6122 unsigned char *build_id_bits;
6123 GElf_Addr build_id_vaddr;
6124
6125 if ((build_id_len=dwfl_module_build_id(m,
6126 (const unsigned char **)&build_id_bits,
6127 &build_id_vaddr)) > 0)
6128 {
155bb07a 6129 if (modname != "kernel")
77123275
FCE
6130 {
6131 Dwarf_Addr reloc_vaddr = build_id_vaddr;
6132 const char *secname;
6133 int i;
71fa1fe3 6134
77123275 6135 i = dwfl_module_relocate_address (m, &reloc_vaddr);
e1c3b13a 6136 DWFL_ASSERT ("dwfl_module_relocate_address reloc_vaddr", i >= 0);
71fa1fe3 6137
77123275 6138 secname = dwfl_module_relocation_info (m, i, NULL);
71fa1fe3 6139
77123275 6140 // assert same section name as in runtime/transport/symbols.c
1f6e8810
FCE
6141 // NB: this is applicable only to module("...") probes.
6142 // process("...") ones may have relocation bases like '.dynamic',
6143 // and so we'll have to store not just a generic offset but
6144 // the relocation section/symbol name too: just like we do
155bb07a
SC
6145 // for probe PC addresses themselves. We want to set build_id_vaddr for
6146 // user modules even though they will not have a secname.
6147
6148 if (modname[0] != '/')
6149 if (!secname || strcmp(secname, ".note.gnu.build-id"))
dc09353a 6150 throw SEMANTIC_ERROR (_("unexpected build-id reloc section ") +
155bb07a 6151 string(secname ?: "null"));
77123275
FCE
6152
6153 build_id_vaddr = reloc_vaddr;
6154 }
71fa1fe3 6155
1bb61ae1
MW
6156 if (c->session.verbose > 1)
6157 {
2a97f50b 6158 clog << _F("Found build-id in %s, length %d, start at %#" PRIx64,
1e41115c 6159 name, build_id_len, build_id_vaddr) << endl;
1bb61ae1 6160 }
c9970555
MW
6161
6162 c->build_id_len = build_id_len;
6163 c->build_id_vaddr = build_id_vaddr;
6164 c->build_id_bits = build_id_bits;
29495972
WH
6165 }
6166
c9970555
MW
6167 return DWARF_CB_OK;
6168}
6169
6170static int
59218439
MW
6171dump_section_list (Dwfl_Module *m,
6172 unwindsym_dump_context *c,
dabd71bb 6173 const char *name, Dwarf_Addr)
59218439
MW
6174{
6175 // Depending on ELF section names normally means you are doing it WRONG.
6176 // Sadly it seems we do need it for the kernel modules. Which are ET_REL
6177 // files, which are "dynamically loaded" by the kernel. We keep a section
6178 // list for them to know which symbol corresponds to which section.
6179 //
6180 // Luckily for the kernel, normal executables (ET_EXEC) or shared
6181 // libraries (ET_DYN) we don't need it. We just have one "section",
6182 // which we will just give the arbitrary names "_stext", ".absolute"
6183 // or ".dynamic"
c9970555 6184
59218439 6185 string modname = name;
c9970555 6186
59218439
MW
6187 // Use start and end as to calculate size for _stext, .dynamic and
6188 // .absolute sections.
60ad8eba 6189 Dwarf_Addr start, end;
c9970555 6190 dwfl_module_info (m, NULL, &start, &end, NULL, NULL, NULL, NULL);
d6377d44 6191
1b94bf6d
FCE
6192 // Look up the relocation basis for symbols
6193 int n = dwfl_module_relocations (m);
e1c3b13a 6194 DWFL_ASSERT ("dwfl_module_relocations", n >= 0);
59218439
MW
6195
6196 if (n == 0)
6197 {
6198 // ET_EXEC, no relocations.
6199 string secname = ".absolute";
6200 unsigned size = end - start;
6201 c->seclist.push_back (make_pair (secname, size));
6202 return DWARF_CB_OK;
6203 }
6204 else if (n == 1)
6205 {
6206 // kernel or shared library (ET_DYN).
6207 string secname;
6208 secname = (modname == "kernel") ? "_stext" : ".dynamic";
6209 unsigned size = end - start;
6210 c->seclist.push_back (make_pair (secname, size));
6211 return DWARF_CB_OK;
6212 }
6213 else if (n > 1)
6214 {
6215 // ET_REL, kernel module.
6216 string secname;
6217 unsigned size;
6218 Dwarf_Addr bias;
6219 GElf_Ehdr *ehdr, ehdr_mem;
6220 GElf_Shdr *shdr, shdr_mem;
6221 Elf *elf = dwfl_module_getelf(m, &bias);
6222 ehdr = gelf_getehdr(elf, &ehdr_mem);
6223 Elf_Scn *scn = NULL;
6224 while ((scn = elf_nextscn(elf, scn)))
6225 {
6226 // Just the "normal" sections with program bits please.
6227 shdr = gelf_getshdr(scn, &shdr_mem);
6228 if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS)
6229 && (shdr->sh_flags & SHF_ALLOC))
6230 {
6231 size = shdr->sh_size;
6232 const char* scn_name = elf_strptr(elf, ehdr->e_shstrndx,
6233 shdr->sh_name);
6234 secname = scn_name;
6235 c->seclist.push_back (make_pair (secname, size));
6236 }
6237 }
6238
6239 return DWARF_CB_OK;
6240 }
6241
6242 // Impossible... dflw_assert above will have triggered.
6243 return DWARF_CB_ABORT;
6244}
6245
51816238
AJ
6246static void find_debug_frame_offset (Dwfl_Module *m,
6247 unwindsym_dump_context *c)
6248{
6249 Dwarf_Addr start, bias = 0;
6250 GElf_Ehdr *ehdr, ehdr_mem;
6251 GElf_Shdr *shdr, shdr_mem;
6252 Elf_Scn *scn = NULL;
6253 Elf_Data *data = NULL;
6254 Elf *elf;
6255
6256 dwfl_module_info (m, NULL, &start, NULL, NULL, NULL, NULL, NULL);
6257
6258 // fetch .debug_frame info preferably from dwarf debuginfo file.
6259 elf = (dwarf_getelf (dwfl_module_getdwarf (m, &bias))
6260 ?: dwfl_module_getelf (m, &bias));
6261 ehdr = gelf_getehdr(elf, &ehdr_mem);
6262
6263 while ((scn = elf_nextscn(elf, scn)))
6264 {
6265 shdr = gelf_getshdr(scn, &shdr_mem);
6266 if (strcmp(elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name),
6267 ".debug_frame") == 0)
6268 {
6269 data = elf_rawdata(scn, NULL);
6270 break;
6271 }
6272 }
6273
6274 if (!data) // need this check since dwarf_next_cfi() doesn't do it
6275 return;
6276
6277 // In the .debug_frame the FDE encoding is always DW_EH_PE_absptr.
6278 // So there is no need to read the CIEs. And the size is either 4
6279 // or 8, depending on the elf class from e_ident.
6280 int size = (ehdr->e_ident[EI_CLASS] == ELFCLASS32) ? 4 : 8;
6281 int res = 0;
6282 Dwarf_Off off = 0;
6283 Dwarf_CFI_Entry entry;
6284
6285 while (res != 1)
6286 {
6287 Dwarf_Off next_off;
6288 res = dwarf_next_cfi (ehdr->e_ident, data, false, off, &next_off, &entry);
6289 if (res == 0)
6290 {
6291 if (entry.CIE_id != DW_CIE_ID_64) // ignore CIEs
6292 {
6293 Dwarf_Addr addr;
6294 if (size == 4)
6295 addr = (*((uint32_t *) entry.fde.start));
6296 else
6297 addr = (*((uint64_t *) entry.fde.start));
6298 Dwarf_Addr first_addr = addr;
6299 int res = dwfl_module_relocate_address (m, &first_addr);
6300 DWFL_ASSERT ("find_debug_frame_offset, dwfl_module_relocate_address",
6301 res >= 0);
6302 c->debug_frame_off = addr - first_addr;
6303 }
6304 }
6305 else if (res < 1)
6306 return;
6307 off = next_off;
6308 }
6309}
6310
b8c579fb
AJ
6311static int
6312dump_line_tables_check (void *data, size_t data_len)
6313{
6314 uint64_t unit_length = 0, header_length = 0;
6315 uint16_t version = 0;
b4bbee91 6316 uint8_t *ptr = (uint8_t *)data, *endunitptr, opcode_base = 0;
b8c579fb
AJ
6317 unsigned length = 4;
6318
b4bbee91
AJ
6319 while (ptr < ((uint8_t *)data + data_len))
6320 {
5160c6f2 6321 if (ptr + 4 > (uint8_t *)data + data_len)
b8c579fb 6322 return DWARF_CB_ABORT;
b8c579fb 6323
b4bbee91 6324 unit_length = *((uint32_t *) ptr);
b4bbee91
AJ
6325 ptr += 4;
6326 if (unit_length == 0xffffffff)
6327 {
992b2254 6328 if (ptr + 8 > (uint8_t *)data + data_len)
b4bbee91
AJ
6329 return DWARF_CB_ABORT;
6330 length = 8;
6331 unit_length = *((uint64_t *) ptr);
6332 ptr += 8;
6333 }
b8c579fb 6334
992b2254 6335 if ((ptr + unit_length > (uint8_t *)data + data_len) || unit_length <= 2)
b4bbee91 6336 return DWARF_CB_ABORT;
b8c579fb 6337
b4bbee91 6338 endunitptr = ptr + unit_length;
b8c579fb 6339
b4bbee91
AJ
6340 version = *((uint16_t *)ptr);
6341 ptr += 2;
b8c579fb 6342
b4bbee91
AJ
6343 if (unit_length <= (2 + length))
6344 return DWARF_CB_ABORT;
b8c579fb 6345
b4bbee91
AJ
6346 if (length == 4)
6347 {
6348 header_length = *((uint32_t *) ptr);
6349 ptr += 4;
6350 }
6351 else
6352 {
6353 header_length = *((uint64_t *) ptr);
6354 ptr += 8;
6355 }
b8c579fb 6356
b4bbee91
AJ
6357 // safety check for the next few jumps
6358 if (header_length <= ((version >= 4 ? 5 : 4) + 2)
6359 || (unit_length - (2 + length) < header_length))
6360 return DWARF_CB_ABORT;
6361
6362 // skip past min instr length, max ops per instr, and line base
6363 if (version >= 4)
6364 ptr += 3;
6365 else
6366 ptr += 2;
b8c579fb 6367
b4bbee91
AJ
6368 // check that the line range is not 0
6369 if (*ptr == 0)
6370 return DWARF_CB_ABORT;
6371 ptr++;
b8c579fb 6372
b4bbee91
AJ
6373 // check that the header accomodates the std opcode lens section
6374 opcode_base = *((uint8_t *) ptr);
6375 if (header_length <= (uint64_t) (opcode_base + (version >= 4 ? 7 : 6)))
6376 return DWARF_CB_ABORT;
b8c579fb 6377
b4bbee91
AJ
6378 // the initial checks stop here, before the directory table
6379 ptr = endunitptr;
6380 }
b8c579fb
AJ
6381 return DWARF_CB_OK;
6382}
6383
ee533a58
AJ
6384static void
6385dump_line_tables (Dwfl_Module *m, unwindsym_dump_context *c,
dabd71bb 6386 const char *, Dwarf_Addr)
ee533a58
AJ
6387{
6388 Elf* elf;
6389 Elf_Scn* scn = NULL;
6390 Elf_Data* data;
6391 GElf_Ehdr *ehdr, ehdr_mem;
6392 GElf_Shdr* shdr, shdr_mem;
6393 Dwarf_Addr bias, start;
6394
6395 dwfl_module_info (m, NULL, &start, NULL, NULL, NULL, NULL, NULL);
6396
6397 elf = dwfl_module_getelf (m, &bias);
6398 if (elf == NULL)
6399 return;
6400
6401 // we do not have the index for debug_line, so we can't use elf_getscn()
6402 // instead, we need to seach through the sections for the correct one as in
6403 // get_unwind_data()
6404 ehdr = gelf_getehdr(elf, &ehdr_mem);
6405 while ((scn = elf_nextscn(elf, scn)))
6406 {
6407 shdr = gelf_getshdr(scn, &shdr_mem);
6408 if (strcmp(elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name),
6409 ".debug_line") == 0)
6410 {
6411 data = elf_rawdata(scn, NULL);
b8c579fb
AJ
6412 if (dump_line_tables_check(data->d_buf, data->d_size) == DWARF_CB_ABORT)
6413 return;
ee533a58
AJ
6414 c->debug_line = data->d_buf;
6415 c->debug_line_len = data->d_size;
6416 break;
6417 }
6418 }
51816238
AJ
6419
6420 // still need to get some kind of information about the sec_load_offset for
6421 // kernel addresses if there is no unwind data
6422 if (c->debug_line_len > 0 && !c->session.need_unwind)
6423 find_debug_frame_offset (m, c);
ee533a58
AJ
6424}
6425
15c110ee
MW
6426/* Some architectures create special local symbols that are not
6427 interesting. */
6428static int
6429skippable_arch_symbol (GElf_Half e_machine, const char *name, GElf_Sym *sym)
6430{
6431 /* Filter out ARM mapping symbols */
6432 if (e_machine == EM_ARM
6433 && GELF_ST_TYPE (sym->st_info) == STT_NOTYPE
6434 && (! strcmp(name, "$a") || ! strcmp(name, "$t")
6435 || ! strcmp(name, "$t.x") || ! strcmp(name, "$d")
6436 || ! strcmp(name, "$v") || ! strcmp(name, "$d.realdata")))
6437 return 1;
6438
6439 return 0;
6440}
6441
59218439
MW
6442static int
6443dump_symbol_tables (Dwfl_Module *m,
6444 unwindsym_dump_context *c,
6445 const char *modname, Dwarf_Addr base)
6446{
6447 // Use end as sanity check when resolving symbol addresses.
6448 Dwarf_Addr end;
6449 dwfl_module_info (m, NULL, NULL, &end, NULL, NULL, NULL, NULL);
2c9438e3 6450
59218439 6451 int syments = dwfl_module_getsymtab(m);
e1c3b13a 6452 DWFL_ASSERT (_F("Getting symbol table for %s", modname), syments >= 0);
59218439
MW
6453
6454 // Look up the relocation basis for symbols
6455 int n = dwfl_module_relocations (m);
e1c3b13a 6456 DWFL_ASSERT ("dwfl_module_relocations", n >= 0);
1b94bf6d 6457
a09fc5a4
MW
6458 /* Needed on ppc64, for function descriptors. */
6459 Dwarf_Addr elf_bias;
6460 GElf_Ehdr *ehdr, ehdr_mem;
6461 Elf *elf;
6462 elf = dwfl_module_getelf(m, &elf_bias);
6463 ehdr = gelf_getehdr(elf, &ehdr_mem);
6464
1b94bf6d
FCE
6465 // XXX: unfortunate duplication with tapsets.cxx:emit_address()
6466
59218439 6467 // extra_offset is for the special kernel case.
1b94bf6d 6468 Dwarf_Addr extra_offset = 0;
59218439
MW
6469 Dwarf_Addr kretprobe_trampoline_addr = (unsigned long) -1;
6470 int is_kernel = !strcmp(modname, "kernel");
dff50e09 6471
59218439
MW
6472 /* Set to bail early if we are just examining the kernel
6473 and don't need anything more. */
6474 int done = 0;
6475 for (int i = 0; i < syments && !done; ++i)
fa670082 6476 {
ebc08b50
FCE
6477 if (pending_interrupts)
6478 return DWARF_CB_ABORT;
6479
fa670082 6480 GElf_Sym sym;
d6377d44 6481 GElf_Word shndxp;
ebc08b50 6482
d6377d44 6483 const char *name = dwfl_module_getsym(m, i, &sym, &shndxp);
f5973d67 6484 if (name)
dff50e09 6485 {
59218439
MW
6486 Dwarf_Addr sym_addr = sym.st_value;
6487
6488 // We always need two special values from the kernel.
6489 // _stext for extra_offset and kretprobe_trampoline_holder
6490 // for the unwinder.
6491 if (is_kernel)
6492 {
6493 // NB: Yey, we found the kernel's _stext value.
6494 // Sess.sym_stext may be unset (0) at this point, since
6495 // there may have been no kernel probes set. We could
6496 // use tapsets.cxx:lookup_symbol_address(), but then
6497 // we're already iterating over the same data here...
ea15e536 6498 if (! strcmp(name, KERNEL_RELOC_SYMBOL))
59218439
MW
6499 {
6500 int ki;
6501 extra_offset = sym_addr;
6502 ki = dwfl_module_relocate_address (m, &extra_offset);
e1c3b13a 6503 DWFL_ASSERT ("dwfl_module_relocate_address extra_offset",
59218439
MW
6504 ki >= 0);
6505
6506 if (c->session.verbose > 2)
6507 clog << _F("Found kernel _stext extra offset %#" PRIx64,
6508 extra_offset) << endl;
6509
6510 if (! c->session.need_symbols
6511 && (kretprobe_trampoline_addr != (unsigned long) -1
6512 || ! c->session.need_unwind))
6513 done = 1;
6514 }
6515 else if (kretprobe_trampoline_addr == (unsigned long) -1
6516 && c->session.need_unwind
6517 && ! strcmp(name, "kretprobe_trampoline_holder"))
6518 {
6519 int ki;
6520 kretprobe_trampoline_addr = sym_addr;
6521 ki = dwfl_module_relocate_address(m,
6522 &kretprobe_trampoline_addr);
e1c3b13a 6523 DWFL_ASSERT ("dwfl_module_relocate_address, kretprobe_trampoline_addr", ki >= 0);
59218439
MW
6524
6525 if (! c->session.need_symbols
6526 && extra_offset != 0)
6527 done = 1;
6528 }
1b94bf6d
FCE
6529 }
6530
d6377d44 6531 // We are only interested in "real" symbols.
a09fc5a4
MW
6532 // We omit symbols that have suspicious addresses
6533 // (before base, or after end).
59218439 6534 if (!done && c->session.need_symbols
15c110ee 6535 && ! skippable_arch_symbol(ehdr->e_machine, name, &sym)
59218439 6536 && (GELF_ST_TYPE (sym.st_info) == STT_FUNC
a09fc5a4 6537 || (GELF_ST_TYPE (sym.st_info) == STT_NOTYPE
17e446b2
MW
6538 && (ehdr->e_type == ET_REL // PR10206 ppc fn-desc in .opd
6539 || is_kernel)) // kernel entry functions are NOTYPE
cd0ae7e5 6540 || GELF_ST_TYPE (sym.st_info) == STT_OBJECT) // PR10000: .data
d6377d44
MW
6541 && !(sym.st_shndx == SHN_UNDEF // Value undefined,
6542 || shndxp == (GElf_Word) -1 // in a non-allocated section,
59218439
MW
6543 || sym_addr >= end // beyond current module,
6544 || sym_addr < base)) // before first section.
37ddf6e5 6545 {
2c9438e3 6546 const char *secname = NULL;
59218439 6547 unsigned secidx = 0; /* Most things have just one section. */
a09fc5a4
MW
6548 Dwarf_Addr func_desc_addr = 0; /* Function descriptor */
6549
6550 /* PPC64 uses function descriptors.
6551 Note: for kernel ET_REL modules we rely on finding the
6552 .function symbols instead of going through the opd function
6553 descriptors. */
6554 if (ehdr->e_machine == EM_PPC64
6555 && GELF_ST_TYPE (sym.st_info) == STT_FUNC
6556 && ehdr->e_type != ET_REL)
6557 {
6558 Elf64_Addr opd_addr;
6559 Dwarf_Addr opd_bias;
6560 Elf_Scn *opd;
6561
6562 func_desc_addr = sym_addr;
6563
6564 opd = dwfl_module_address_section (m, &sym_addr, &opd_bias);
e1c3b13a 6565 DWFL_ASSERT ("dwfl_module_address_section opd", opd != NULL);
a09fc5a4
MW
6566
6567 Elf_Data *opd_data = elf_rawdata (opd, NULL);
6568 assert(opd_data != NULL);
6569
6570 Elf_Data opd_in, opd_out;
6571 opd_out.d_buf = &opd_addr;
6572 opd_in.d_buf = (char *) opd_data->d_buf + sym_addr;
6573 opd_out.d_size = opd_in.d_size = sizeof (Elf64_Addr);
6574 opd_out.d_type = opd_in.d_type = ELF_T_ADDR;
6575 if (elf64_xlatetom (&opd_out, &opd_in,
6576 ehdr->e_ident[EI_DATA]) == NULL)
6577 throw runtime_error ("elf64_xlatetom failed");
6578
6579 // So the real address of the function is...
6580 sym_addr = opd_addr + opd_bias;
6581 }
1b94bf6d 6582
2c9438e3 6583 if (n > 0) // only try to relocate if there exist relocation bases
1b94bf6d 6584 {
94687c8d 6585 int ki = dwfl_module_relocate_address (m, &sym_addr);
e1c3b13a 6586 DWFL_ASSERT ("dwfl_module_relocate_address sym_addr", ki >= 0);
94687c8d 6587 secname = dwfl_module_relocation_info (m, ki, NULL);
a09fc5a4
MW
6588
6589 if (func_desc_addr != 0)
6590 dwfl_module_relocate_address (m, &func_desc_addr);
7774095b 6591 }
2c9438e3 6592
59218439 6593 if (n == 1 && is_kernel)
1b94bf6d 6594 {
6f8b6801
FCE
6595 // This is a symbol within a (possibly relocatable)
6596 // kernel image.
3f6b6682 6597
d6377d44
MW
6598 // We only need the function symbols to identify kernel-mode
6599 // PC's, so we omit undefined or "fake" absolute addresses.
6600 // These fake absolute addresses occur in some older i386
6601 // kernels to indicate they are vDSO symbols, not real
6602 // functions in the kernel. We also omit symbols that have
6603 if (GELF_ST_TYPE (sym.st_info) == STT_FUNC
6604 && sym.st_shndx == SHN_ABS)
6605 continue;
6606
7795c7e7 6607 secname = "_stext";
59218439
MW
6608 // NB: don't subtract session.sym_stext, which could be
6609 // inconveniently NULL. Instead, sym_addr will get
6610 // compensated later via extra_offset.
1b94bf6d 6611 }
7795c7e7 6612 else if (n > 0)
1b94bf6d 6613 {
7795c7e7 6614 assert (secname != NULL);
f76427a2 6615 // secname adequately set
17c128f2
FCE
6616
6617 // NB: it may be an empty string for ET_DYN objects
6618 // like shared libraries, as their relocation base
6619 // is implicit.
6620 if (secname[0] == '\0')
59218439
MW
6621 secname = ".dynamic";
6622 else
6623 {
6624 // Compute our section number
6625 for (secidx = 0; secidx < c->seclist.size(); secidx++)
6626 if (c->seclist[secidx].first==secname)
6627 break;
6628
6629 if (secidx == c->seclist.size()) // whoa! We messed up...
6630 {
6631 string m = _F("%s has unknown section %s for sym %s",
6632 modname, secname, name);
6633 throw runtime_error(m);
6634 }
6635 }
1b94bf6d 6636 }
dff50e09 6637 else
2c9438e3 6638 {
7795c7e7 6639 assert (n == 0);
59218439
MW
6640 // sym_addr is absolute, as it must be since there are
6641 // no relocation bases
dff50e09 6642 secname = ".absolute"; // sentinel
2c9438e3 6643 }
37ddf6e5 6644
59218439 6645 (c->addrmap[secidx])[sym_addr] = name;
a09fc5a4
MW
6646 /* If we have a function descriptor, register that address
6647 under the same name */
6648 if (func_desc_addr != 0)
6649 (c->addrmap[secidx])[func_desc_addr] = name;
37ddf6e5 6650 }
f5973d67 6651 }
fa670082 6652 }
1b94bf6d 6653
59218439
MW
6654 if (is_kernel)
6655 {
6656 c->stext_offset = extra_offset;
6657 // Must be relative to actual kernel load address.
6658 if (kretprobe_trampoline_addr != (unsigned long) -1)
6659 c->stp_kretprobe_trampoline_addr = (kretprobe_trampoline_addr
6660 - extra_offset);
6661 }
129de9ef 6662
c9970555
MW
6663 return DWARF_CB_OK;
6664}
5738a982 6665
c9970555
MW
6666static int
6667dump_unwind_tables (Dwfl_Module *m,
6668 unwindsym_dump_context *c,
dabd71bb 6669 const char *, Dwarf_Addr)
c9970555
MW
6670{
6671 // Add unwind data to be included if it exists for this module.
59218439
MW
6672 get_unwind_data (m, &c->debug_frame, &c->eh_frame,
6673 &c->debug_len, &c->eh_len,
6674 &c->eh_addr, &c->eh_frame_hdr, &c->eh_frame_hdr_len,
6675 &c->debug_frame_hdr, &c->debug_frame_hdr_len,
6676 &c->debug_frame_off, &c->eh_frame_hdr_addr,
6677 c->session);
c9970555
MW
6678 return DWARF_CB_OK;
6679}
6680
4472fb4d
JS
6681static void
6682dump_unwindsym_cxt_table(systemtap_session& session, ostream& output,
6683 const string& modname, unsigned modindex,
6684 const string& secname, unsigned secindex,
6685 const string& table, void*& data, size_t& len)
6686{
6687 if (data == NULL || len == 0)
6688 return;
6689
6690 if (len > MAX_UNWIND_TABLE_SIZE)
6691 {
6692 if (secname.empty())
6693 session.print_warning (_F("skipping module %s %s table (too big: %zi > %zi)",
6694 modname.c_str(), table.c_str(),
6695 len, (size_t)MAX_UNWIND_TABLE_SIZE));
6696 else
6697 session.print_warning (_F("skipping module %s, section %s %s table (too big: %zi > %zi)",
6698 modname.c_str(), secname.c_str(), table.c_str(),
6699 len, (size_t)MAX_UNWIND_TABLE_SIZE));
6700 data = NULL;
6701 len = 0;
6702 return;
6703 }
6704
ee533a58
AJ
6705 // if it is the debug_line data, do not need the unwind flags to be defined
6706 if(table == "debug_line")
6707 output << "#if defined(STP_NEED_LINE_DATA)\n";
6708 else
6709 output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
4472fb4d
JS
6710 output << "static uint8_t _stp_module_" << modindex << "_" << table;
6711 if (!secname.empty())
6712 output << "_" << secindex;
6713 output << "[] = \n";
6714 output << " {";
6715 for (size_t i = 0; i < len; i++)
6716 {
6717 int h = ((uint8_t *)data)[i];
6718 output << h << ","; // decimal is less wordy than hex
6719 if ((i + 1) % 16 == 0)
6720 output << "\n" << " ";
6721 }
6722 output << "};\n";
ee533a58
AJ
6723 if (table == "debug_line")
6724 output << "#endif /* STP_NEED_LINE_DATA */\n";
6725 else
6726 output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA */\n";
4472fb4d
JS
6727}
6728
c9970555
MW
6729static int
6730dump_unwindsym_cxt (Dwfl_Module *m,
6731 unwindsym_dump_context *c,
6732 const char *name, Dwarf_Addr base)
6733{
6734 string modname = name;
6735 unsigned stpmod_idx = c->stp_module_index;
6736 void *debug_frame = c->debug_frame;
6737 size_t debug_len = c->debug_len;
6738 void *debug_frame_hdr = c->debug_frame_hdr;
6739 size_t debug_frame_hdr_len = c->debug_frame_hdr_len;
6740 Dwarf_Addr debug_frame_off = c->debug_frame_off;
6741 void *eh_frame = c->eh_frame;
6742 void *eh_frame_hdr = c->eh_frame_hdr;
6743 size_t eh_len = c->eh_len;
6744 size_t eh_frame_hdr_len = c->eh_frame_hdr_len;
6745 Dwarf_Addr eh_addr = c->eh_addr;
6746 Dwarf_Addr eh_frame_hdr_addr = c->eh_frame_hdr_addr;
ee533a58
AJ
6747 void *debug_line = c->debug_line;
6748 size_t debug_line_len = c->debug_line_len;
5738a982 6749
4472fb4d
JS
6750 dump_unwindsym_cxt_table(c->session, c->output, modname, stpmod_idx, "", 0,
6751 "debug_frame", debug_frame, debug_len);
4285dc9a 6752
4472fb4d
JS
6753 dump_unwindsym_cxt_table(c->session, c->output, modname, stpmod_idx, "", 0,
6754 "eh_frame", eh_frame, eh_len);
6755
6756 dump_unwindsym_cxt_table(c->session, c->output, modname, stpmod_idx, "", 0,
6757 "eh_frame_hdr", eh_frame_hdr, eh_frame_hdr_len);
4285dc9a 6758
ee533a58
AJ
6759 dump_unwindsym_cxt_table(c->session, c->output, modname, stpmod_idx, "", 0,
6760 "debug_line", debug_line, debug_line_len);
6761
5738a982 6762 if (c->session.need_unwind && debug_frame == NULL && eh_frame == NULL)
61a80584 6763 {
41a6bdc9
FCE
6764 // There would be only a small benefit to warning. A user
6765 // likely can't do anything about this; backtraces for the
6766 // affected module would just get all icky heuristicy.
d6377d44 6767 // So only report in verbose mode.
2713ea24 6768 if (c->session.verbose > 2)
d6377d44
MW
6769 c->session.print_warning ("No unwind data for " + modname
6770 + ", " + dwfl_errmsg (-1));
61a80584
MW
6771 }
6772
ee533a58
AJ
6773 if (c->session.need_lines && debug_line == NULL)
6774 {
6775 if (c->session.verbose > 2)
6776 c->session.print_warning ("No debug line data for " + modname + ", " +
6777 dwfl_errmsg (-1));
6778 }
6779
c9970555 6780 for (unsigned secidx = 0; secidx < c->seclist.size(); secidx++)
1b94bf6d 6781 {
4c2732a1 6782 c->output << "static struct _stp_symbol "
1751e667 6783 << "_stp_module_" << stpmod_idx<< "_symbols_" << secidx << "[] = {\n";
1b94bf6d 6784
c9970555
MW
6785 string secname = c->seclist[secidx].first;
6786 Dwarf_Addr extra_offset;
6787 extra_offset = (secname == "_stext") ? c->stext_offset : 0;
6788
82762adc 6789 // Only include symbols if they will be used
8af41ec2
MW
6790 if (c->session.need_symbols)
6791 {
8af41ec2
MW
6792 // We write out a *sorted* symbol table, so the runtime doesn't
6793 // have to sort them later.
c9970555
MW
6794 for (addrmap_t::iterator it = c->addrmap[secidx].begin();
6795 it != c->addrmap[secidx].end(); it++)
8af41ec2
MW
6796 {
6797 // skip symbols that occur before our chosen base address
6798 if (it->first < extra_offset)
6799 continue;
82762adc 6800
8af41ec2
MW
6801 c->output << " { 0x" << hex << it->first-extra_offset << dec
6802 << ", " << lex_cast_qstring (it->second) << " },\n";
bb12c3df
FCE
6803 // XXX: these literal strings all suffer ELF relocation bloat too.
6804 // See if the tapsets.cxx:dwarf_derived_probe_group::emit_module_decls
6805 // CALCIT hack could work here.
8af41ec2
MW
6806 }
6807 }
82762adc 6808
1751e667 6809 c->output << "};\n";
4d83bd9b
MW
6810
6811 /* For now output debug_frame index only in "magic" sections. */
4d83bd9b
MW
6812 if (secname == ".dynamic" || secname == ".absolute"
6813 || secname == ".text" || secname == "_stext")
6814 {
4472fb4d
JS
6815 dump_unwindsym_cxt_table(c->session, c->output, modname, stpmod_idx, secname, secidx,
6816 "debug_frame_hdr", debug_frame_hdr, debug_frame_hdr_len);
4d83bd9b 6817 }
7795c7e7
FCE
6818 }
6819
1751e667 6820 c->output << "static struct _stp_section _stp_module_" << stpmod_idx<< "_sections[] = {\n";
60ad8eba
MW
6821 // For the kernel, executables (ET_EXEC) or shared libraries (ET_DYN)
6822 // there is just one section that covers the whole address space of
6823 // the module. For kernel modules (ET_REL) there can be multiple
6824 // sections that get relocated separately.
c9970555 6825 for (unsigned secidx = 0; secidx < c->seclist.size(); secidx++)
7795c7e7 6826 {
1751e667 6827 c->output << "{\n"
c9970555
MW
6828 << ".name = " << lex_cast_qstring(c->seclist[secidx].first) << ",\n"
6829 << ".size = 0x" << hex << c->seclist[secidx].second << dec << ",\n"
1751e667 6830 << ".symbols = _stp_module_" << stpmod_idx << "_symbols_" << secidx << ",\n"
c9970555 6831 << ".num_symbols = " << c->addrmap[secidx].size() << ",\n";
4d83bd9b
MW
6832
6833 /* For now output debug_frame index only in "magic" sections. */
c9970555 6834 string secname = c->seclist[secidx].first;
4d83bd9b
MW
6835 if (debug_frame_hdr && (secname == ".dynamic" || secname == ".absolute"
6836 || secname == ".text" || secname == "_stext"))
6837 {
6838 c->output << "#if defined(STP_USE_DWARF_UNWINDER)"
6839 << " && defined(STP_NEED_UNWIND_DATA)\n";
6840
6841 c->output << ".debug_hdr = "
6842 << "_stp_module_" << stpmod_idx
6843 << "_debug_frame_hdr_" << secidx << ",\n";
6844 c->output << ".debug_hdr_len = " << debug_frame_hdr_len << ", \n";
6845
6846 Dwarf_Addr dwbias = 0;
6847 dwfl_module_getdwarf (m, &dwbias);
6848 c->output << ".sec_load_offset = 0x"
6849 << hex << debug_frame_off - dwbias << dec << "\n";
6850
6851 c->output << "#else\n";
6852 c->output << ".debug_hdr = NULL,\n";
6853 c->output << ".debug_hdr_len = 0,\n";
6854 c->output << ".sec_load_offset = 0\n";
6855 c->output << "#endif /* STP_USE_DWARF_UNWINDER"
6856 << " && STP_NEED_UNWIND_DATA */\n";
6857
6858 }
6859 else
6860 {
6861 c->output << ".debug_hdr = NULL,\n";
6862 c->output << ".debug_hdr_len = 0,\n";
51816238
AJ
6863 if (c->session.need_lines && secname == ".text")
6864 {
6865 c->output << "#if defined(STP_NEED_LINE_DATA)\n";
6866 Dwarf_Addr dwbias = 0;
6867 dwfl_module_getdwarf (m, &dwbias);
6868 c->output << ".sec_load_offset = 0x"
6869 << hex << debug_frame_off - dwbias << dec << "\n";
6870 c->output << "#else\n";
6871 }
4d83bd9b 6872 c->output << ".sec_load_offset = 0\n";
51816238
AJ
6873 if (c->session.need_lines && secname == ".text")
6874 c->output << "#endif /* STP_NEED_LINE_DATA */\n";
4d83bd9b
MW
6875 }
6876
6877 c->output << "},\n";
1b94bf6d 6878 }
1751e667 6879 c->output << "};\n";
1b94bf6d 6880
c9970555
MW
6881 // Get the canonical path of the main file for comparison at runtime.
6882 // When given directly by the user through -d or in case of the kernel
6883 // name and path might differ. path should be used for matching.
6884 const char *mainfile;
6885 dwfl_module_info (m, NULL, NULL, NULL, NULL, NULL, &mainfile, NULL);
6886
496fec26 6887 // For user space modules store canonical path.
c92a217d 6888 // For kernel modules just the name itself.
5bca76a8 6889 string mainpath = resolve_path(mainfile);
496fec26 6890 string mainname;
4766b1e6 6891 if (is_user_module(modname)) // userspace
496fec26 6892 mainname = lex_cast_qstring (path_remove_sysroot(c->session,mainpath));
c92a217d 6893 else
4766b1e6
JL
6894 { // kernel module
6895
6896 // If the module name is the full path to the ko, then we have to retrieve
6897 // the actual name by which the module will be known inside the kernel.
6898 // Otherwise, section relocations would be mismatched.
6899 if (is_fully_resolved(modname, c->session.sysroot, c->session.sysenv))
6900 mainname = lex_cast_qstring (modname_from_path(modname));
6901 else
6902 mainname = lex_cast_qstring (modname);
6903 }
671ceda8 6904
1751e667 6905 c->output << "static struct _stp_module _stp_module_" << stpmod_idx << " = {\n";
496fec26 6906 c->output << ".name = " << mainname.c_str() << ",\n";
65e2141c 6907 c->output << ".path = " << lex_cast_qstring (path_remove_sysroot(c->session,mainpath)) << ",\n";
4d83bd9b
MW
6908 c->output << ".eh_frame_addr = 0x" << hex << eh_addr << dec << ", \n";
6909 c->output << ".unwind_hdr_addr = 0x" << hex << eh_frame_hdr_addr
6910 << dec << ", \n";
4285dc9a
MW
6911
6912 if (debug_frame != NULL)
6913 {
6914 c->output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
6915 c->output << ".debug_frame = "
6916 << "_stp_module_" << stpmod_idx << "_debug_frame, \n";
6917 c->output << ".debug_frame_len = " << debug_len << ", \n";
6918 c->output << "#else\n";
6919 }
6920
6921 c->output << ".debug_frame = NULL,\n";
6922 c->output << ".debug_frame_len = 0,\n";
6923
6924 if (debug_frame != NULL)
6925 c->output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA*/\n";
61a80584 6926
4285dc9a 6927 if (eh_frame != NULL)
61a80584 6928 {
1751e667 6929 c->output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
4285dc9a
MW
6930 c->output << ".eh_frame = "
6931 << "_stp_module_" << stpmod_idx << "_eh_frame, \n";
6932 c->output << ".eh_frame_len = " << eh_len << ", \n";
0f33053e
TM
6933 if (eh_frame_hdr)
6934 {
6935 c->output << ".unwind_hdr = "
6936 << "_stp_module_" << stpmod_idx << "_eh_frame_hdr, \n";
6937 c->output << ".unwind_hdr_len = " << eh_frame_hdr_len << ", \n";
6938 }
6939 else
6940 {
6941 c->output << ".unwind_hdr = NULL,\n";
6942 c->output << ".unwind_hdr_len = 0,\n";
6943 }
1751e667 6944 c->output << "#else\n";
61a80584
MW
6945 }
6946
4285dc9a
MW
6947 c->output << ".eh_frame = NULL,\n";
6948 c->output << ".eh_frame_len = 0,\n";
1751e667
FCE
6949 c->output << ".unwind_hdr = NULL,\n";
6950 c->output << ".unwind_hdr_len = 0,\n";
0f33053e
TM
6951 if (eh_frame != NULL)
6952 c->output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA*/\n";
ee533a58
AJ
6953
6954 if (debug_line != NULL)
6955 {
ca6031ac 6956 c->output << "#if defined(STP_NEED_LINE_DATA)\n";
ee533a58
AJ
6957 c->output << ".debug_line = "
6958 << "_stp_module_" << stpmod_idx << "_debug_line, \n";
6959 c->output << ".debug_line_len = " << debug_line_len << ", \n";
ca6031ac 6960 c->output << "#else\n";
ee533a58 6961 }
ca6031ac
AJ
6962
6963 c->output << ".debug_line = NULL,\n";
6964 c->output << ".debug_line_len = 0,\n";
6965
6966 if (debug_line != NULL)
6967 c->output << "#endif /* STP_NEED_LINE_DATA */\n";
ee533a58 6968
1751e667 6969 c->output << ".sections = _stp_module_" << stpmod_idx << "_sections" << ",\n";
7795c7e7 6970 c->output << ".num_sections = sizeof(_stp_module_" << stpmod_idx << "_sections)/"
1751e667 6971 << "sizeof(struct _stp_section),\n";
dff50e09 6972
66f65c4f
EM
6973 /* Don't save build-id if it is located before _stext.
6974 * This probably means that build-id will not be loaded at all and
d1d13a8b
SC
6975 * happens for example with ARM kernel. Allow user space modules since the
6976 * check fails for a shared object.
66f65c4f
EM
6977 *
6978 * See also:
306dd4f8 6979 * http://sourceware.org/ml/systemtap/2009-q4/msg00574.html
66f65c4f 6980 */
c9970555
MW
6981 if (c->build_id_len > 0
6982 && (modname != "kernel" || (c->build_id_vaddr > base + c->stext_offset))) {
3a894f7e 6983 c->output << ".build_id_bits = (unsigned char *)\"" ;
c9970555 6984 for (int j=0; j<c->build_id_len;j++)
1751e667 6985 c->output << "\\x" << hex
c9970555 6986 << (unsigned short) *(c->build_id_bits+j) << dec;
3f6b6682 6987
1751e667 6988 c->output << "\",\n";
c9970555 6989 c->output << ".build_id_len = " << c->build_id_len << ",\n";
3f6b6682 6990
1751e667 6991 /* XXX: kernel data boot-time relocation works differently from text.
201e18a8
EM
6992 This hack assumes that offset between _stext and build id
6993 stays constant after relocation, but that's not necessarily
1751e667
FCE
6994 correct either. We may instead need a relocation basis different
6995 from _stext, such as __start_notes. */
6996 if (modname == "kernel")
c9970555 6997 c->output << ".build_id_offset = 0x" << hex << c->build_id_vaddr - (base + c->stext_offset)
1751e667 6998 << dec << ",\n";
155bb07a 6999 // ET_DYN: task finder gives the load address. ET_EXEC: this is absolute address
1751e667
FCE
7000 else
7001 c->output << ".build_id_offset = 0x" << hex
c9970555 7002 << c->build_id_vaddr /* - base */
1751e667 7003 << dec << ",\n";
29495972 7004 } else
1751e667 7005 c->output << ".build_id_len = 0,\n";
3f6b6682 7006
29495972 7007 //initialize the note section representing unloaded
1751e667 7008 c->output << ".notes_sect = 0,\n";
29495972 7009
1751e667 7010 c->output << "};\n\n";
37ddf6e5 7011
4464a6bb
FCE
7012 c->undone_unwindsym_modules.erase (modname);
7013
e7899657 7014 // release various malloc'd tables
bd2a3e38 7015 // if (eh_frame_hdr) free (eh_frame_hdr); -- nope, this one comes from the elf image in memory
e7899657
FCE
7016 if (debug_frame_hdr) free (debug_frame_hdr);
7017
fa670082
MH
7018 return DWARF_CB_OK;
7019}
7020
7b65c066
FL
7021static void dump_kallsyms(unwindsym_dump_context *c)
7022{
7023 ifstream kallsyms("/proc/kallsyms");
7024 unsigned stpmod_idx = c->stp_module_index;
7025 string line;
7026 unsigned size = 0;
7027 Dwarf_Addr start = 0;
7028 Dwarf_Addr end = 0;
7029 Dwarf_Addr prev = 0;
7030
7031 c->output << "static struct _stp_symbol "
7032 << "_stp_module_" << stpmod_idx << "_symbols_" << 0 << "[] = {\n";
7033
7034 while (getline(kallsyms, line))
7035 {
7036 Dwarf_Addr addr;
7037 string name;
7038 string module;
7039 char type;
7040 istringstream iss(line);
7041
7042 iss >> hex >> addr >> type >> name >> module;
7043
7044 if (name == KERNEL_RELOC_SYMBOL)
7045 start = addr;
7046 else if (name == "_end" || module != "")
7047 {
7048 end = prev;
7049 break;
7050 }
7051
7052 if (!start || addr == 0 || prev == addr)
7053 continue;
7054
7055 c->output << " { 0x" << hex << addr - start << dec
7056 << ", " << lex_cast_qstring(name) << " },\n";
7057
7058 size++;
7059 prev = addr;
7060 }
7061
7062 c->output << "};\n";
7063 c->output << "static struct _stp_section _stp_module_" << stpmod_idx << "_sections[] = {\n";
7064 c->output << "{\n"
7065 << ".name = " << lex_cast_qstring(KERNEL_RELOC_SYMBOL) << ",\n"
7066 << ".size = 0x" << hex << end - start << dec << ",\n"
7067 << ".symbols = _stp_module_" << stpmod_idx << "_symbols_" << 0 << ",\n"
7068 << ".num_symbols = " << size << ",\n";
7069 c->output << "},\n";
7070 c->output << "};\n";
7071 c->output << "static struct _stp_module _stp_module_" << stpmod_idx << " = {\n";
7072 c->output << ".name = " << lex_cast_qstring("kernel") << ",\n";
7073 c->output << ".sections = _stp_module_" << stpmod_idx << "_sections" << ",\n";
7074 c->output << ".num_sections = sizeof(_stp_module_" << stpmod_idx << "_sections)/"
7075 << "sizeof(struct _stp_section),\n";
7076 c->output << "};\n\n";
7077
7078 c->undone_unwindsym_modules.erase("kernel");
7079 c->stp_module_index++;
7080}
7081
c9970555
MW
7082static int
7083dump_unwindsyms (Dwfl_Module *m,
7084 void **userdata __attribute__ ((unused)),
7085 const char *name,
7086 Dwarf_Addr base,
7087 void *arg)
7088{
7089 if (pending_interrupts)
7090 return DWARF_CB_ABORT;
7091
7092 unwindsym_dump_context *c = (unwindsym_dump_context*) arg;
7093 assert (c);
7094
7095 // skip modules/files we're not actually interested in
7096 string modname = name;
7097 if (c->session.unwindsym_modules.find(modname)
7098 == c->session.unwindsym_modules.end())
7099 return DWARF_CB_OK;
7100
7101 if (c->session.verbose > 1)
7102 clog << "dump_unwindsyms " << name
7103 << " index=" << c->stp_module_index
7104 << " base=0x" << hex << base << dec << endl;
7105
7106 // We want to extract several bits of information:
7107 //
7108 // - parts of the program-header that map the file's physical offsets to the text section
7109 // - section table: just a list of section (relocation) base addresses
7110 // - symbol table of the text-like sections, with all addresses relativized to each base
7111 // - the contents of .debug_frame and/or .eh_frame section, for unwinding purposes
7112
7113 int res = DWARF_CB_OK;
7114
7115 c->build_id_len = 0;
7116 c->build_id_vaddr = 0;
7117 c->build_id_bits = NULL;
7118 res = dump_build_id (m, c, name, base);
c9970555
MW
7119
7120 c->seclist.clear();
59218439
MW
7121 if (res == DWARF_CB_OK)
7122 res = dump_section_list(m, c, name, base);
7123
7124 // We always need to check the symbols of the kernel if we use it,
7125 // for the extra_offset (also used for build_ids) and possibly
7126 // stp_kretprobe_trampoline_addr for the dwarf unwinder.
c9970555 7127 c->addrmap.clear();
59218439
MW
7128 if (res == DWARF_CB_OK
7129 && (c->session.need_symbols || ! strcmp(name, "kernel")))
7130 res = dump_symbol_tables (m, c, name, base);
c9970555
MW
7131
7132 c->debug_frame = NULL;
7133 c->debug_len = 0;
7134 c->debug_frame_hdr = NULL;
7135 c->debug_frame_hdr_len = 0;
7136 c->debug_frame_off = 0;
7137 c->eh_frame = NULL;
7138 c->eh_frame_hdr = NULL;
7139 c->eh_len = 0;
7140 c->eh_frame_hdr_len = 0;
7141 c->eh_addr = 0;
7142 c->eh_frame_hdr_addr = 0;
59218439
MW
7143 if (res == DWARF_CB_OK && c->session.need_unwind)
7144 res = dump_unwind_tables (m, c, name, base);
c9970555 7145
ee533a58
AJ
7146 c->debug_line = NULL;
7147 c->debug_line_len = 0;
7148 if (res == DWARF_CB_OK && c->session.need_lines)
7149 // we dont set res = dump_line_tables() because unwindsym stuff should still
7150 // get dumped to the output even if gathering debug_line data fails
7151 (void) dump_line_tables (m, c, name, base);
7152
c9970555 7153 /* And finally dump everything collected in the output. */
59218439
MW
7154 if (res == DWARF_CB_OK)
7155 res = dump_unwindsym_cxt (m, c, name, base);
7156
7157 if (res == DWARF_CB_OK)
7158 c->stp_module_index++;
7159
c9970555
MW
7160 return res;
7161}
7162
1a0dbc5a 7163
1b94bf6d
FCE
7164// Emit symbol table & unwind data, plus any calls needed to register
7165// them with the runtime.
62d950bb 7166void emit_symbol_data_done (unwindsym_dump_context*, systemtap_session&);
1b94bf6d 7167
ef06c938 7168
6bbcd339 7169void
bbbc7241 7170add_unwindsym_iol_callback (set<string> *added, const char *data)
6bbcd339 7171{
6bbcd339
SC
7172 added->insert (string (data));
7173}
7174
7175
7176static int
7177query_module (Dwfl_Module *mod,
7178 void **,
822a6a3d
FCE
7179 const char *,
7180 Dwarf_Addr,
06de3a04 7181 struct dwflpp *dwflpp)
6bbcd339 7182{
06de3a04 7183 dwflpp->focus_on_module(mod, NULL);
6bbcd339
SC
7184 return DWARF_CB_OK;
7185}
7186
7187
ef06c938
FCE
7188void
7189add_unwindsym_ldd (systemtap_session &s)
7190{
7191 std::set<std::string> added;
7192
ef06c938
FCE
7193 for (std::set<std::string>::iterator it = s.unwindsym_modules.begin();
7194 it != s.unwindsym_modules.end();
7195 it++)
7196 {
7197 string modname = *it;
7198 assert (modname.length() != 0);
7199 if (! is_user_module (modname)) continue;
7200
2d590ebe
JS
7201 dwflpp mod_dwflpp (s, modname, false);
7202 mod_dwflpp.iterate_over_modules(&query_module, &mod_dwflpp);
7203 if (mod_dwflpp.module) // existing binary
0ce08aaa 7204 {
2d590ebe
JS
7205 assert (mod_dwflpp.module_name != "");
7206 mod_dwflpp.iterate_over_libraries (&add_unwindsym_iol_callback, &added);
0ce08aaa 7207 }
ef06c938 7208 }
6bbcd339 7209
ef06c938
FCE
7210 s.unwindsym_modules.insert (added.begin(), added.end());
7211}
7212
822a6a3d 7213static int find_vdso(const char *path, const struct stat *, int type)
18da5887
MW
7214{
7215 if (type == FTW_F)
7216 {
b3131710
DS
7217 /* Assume that if the path's basename starts with 'vdso' and
7218 * ends with '.so', it is the vdso.
7219 *
7220 * Note that this logic should match up with the logic in the
7221 * _stp_vma_match_vdso() function in runtime/vma.c. */
18da5887
MW
7222 const char *name = strrchr(path, '/');
7223 if (name)
7224 {
b3131710
DS
7225 const char *ext;
7226
18da5887 7227 name++;
b3131710 7228 ext = strrchr(name, '.');
18da5887
MW
7229 if (ext
7230 && strncmp("vdso", name, 4) == 0
7231 && strcmp(".so", ext) == 0)
7232 vdso_paths.insert(path);
7233 }
7234 }
7235 return 0;
7236}
7237
7238void
7239add_unwindsym_vdso (systemtap_session &s)
7240{
7241 // This is to disambiguate between -r REVISION vs -r BUILDDIR.
7242 // See also dwflsetup.c (setup_dwfl_kernel). In case of only
7243 // having the BUILDDIR we need to do a deep search (the specific
7244 // arch name dir in the kernel build tree is unknown).
7245 string vdso_dir;
05fb3e0c 7246 if (s.kernel_build_tree == string(s.sysroot + "/lib/modules/"
18da5887
MW
7247 + s.kernel_release
7248 + "/build"))
05fb3e0c 7249 vdso_dir = s.sysroot + "/lib/modules/" + s.kernel_release + "/vdso";
18da5887
MW
7250 else
7251 vdso_dir = s.kernel_build_tree + "/arch/";
7252
7253 if (s.verbose > 1)
1e41115c 7254 clog << _("Searching for vdso candidates: ") << vdso_dir << endl;
18da5887
MW
7255
7256 ftw(vdso_dir.c_str(), find_vdso, 1);
7257
7258 for (set<string>::iterator it = vdso_paths.begin();
7259 it != vdso_paths.end();
7260 it++)
7261 {
7262 s.unwindsym_modules.insert(*it);
7263 if (s.verbose > 1)
1e41115c 7264 clog << _("vdso candidate: ") << *it << endl;
18da5887
MW
7265 }
7266}
ef06c938 7267
d13bcfd8
JS
7268static void
7269prepare_symbol_data (systemtap_session& s)
fa670082 7270{
ef06c938
FCE
7271 // step 0: run ldd on any user modules if requested
7272 if (s.unwindsym_ldd)
7273 add_unwindsym_ldd (s);
18da5887
MW
7274 // step 0.5: add vdso(s) when vma tracker was requested
7275 if (vma_tracker_enabled (s))
7276 add_unwindsym_vdso (s);
ef06c938 7277 // NB: do this before the ctx.unwindsym_modules copy is taken
d13bcfd8
JS
7278}
7279
7280void
7281emit_symbol_data (systemtap_session& s)
7282{
7283 string symfile = "stap-symbols.h";
7284
7285 s.op->newline() << "#include " << lex_cast_qstring (symfile);
7286
7287 ofstream kallsyms_out ((s.tmpdir + "/" + symfile).c_str());
ef06c938 7288
c9970555
MW
7289 vector<pair<string,unsigned> > seclist;
7290 map<unsigned, addrmap_t> addrmap;
7291 unwindsym_dump_context ctx = { s, kallsyms_out,
7292 0, /* module index */
7293 0, NULL, 0, /* build_id len, bits, vaddr */
47caa991 7294 ~0UL, /* stp_kretprobe_trampoline_addr */
c9970555
MW
7295 0, /* stext_offset */
7296 seclist, addrmap,
7297 NULL, /* debug_frame */
7298 0, /* debug_len */
7299 NULL, /* debug_frame_hdr */
7300 0, /* debug_frame_hdr_len */
7301 0, /* debug_frame_off */
7302 NULL, /* eh_frame */
7303 NULL, /* eh_frame_hdr */
7304 0, /* eh_len */
7305 0, /* eh_frame_hdr_len */
7306 0, /* eh_addr */
7307 0, /* eh_frame_hdr_addr */
ee533a58
AJ
7308 NULL, /* debug_line */
7309 0, /* debug_line_len */
c9970555 7310 s.unwindsym_modules };
f5973d67 7311
62d950bb
MW
7312 // Micro optimization, mainly to speed up tiny regression tests
7313 // using just begin probe.
7314 if (s.unwindsym_modules.size () == 0)
7315 {
7316 emit_symbol_data_done(&ctx, s);
7317 return;
7318 }
7319
f5973d67 7320 // ---- step 1: process any kernel modules listed
3db9c843
MW
7321 set<string> offline_search_modules;
7322 unsigned count;
ae2552da
FCE
7323 for (set<string>::iterator it = s.unwindsym_modules.begin();
7324 it != s.unwindsym_modules.end();
7325 it++)
7326 {
7327 string foo = *it;
5f8ca04f
MW
7328 if (! is_user_module (foo)) /* Omit user-space, since we're only
7329 using this for kernel space
7330 offline searches. */
ae2552da
FCE
7331 offline_search_modules.insert (foo);
7332 }
ccf2c922 7333 Dwfl *dwfl = setup_dwfl_kernel (offline_search_modules, &count, s);
73562400
FCE
7334 /* NB: It's not an error to find a few fewer modules than requested.
7335 There might be third-party modules loaded (e.g. uprobes). */
e1c3b13a 7336 /* DWFL_ASSERT("all kernel modules found",
73562400 7337 count >= offline_search_modules.size()); */
ae2552da 7338
ae2552da
FCE
7339 ptrdiff_t off = 0;
7340 do
f5973d67 7341 {
e19ebcf7 7342 assert_no_interrupts();
ae2552da 7343 if (ctx.undone_unwindsym_modules.empty()) break;
68983551 7344 off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, off);
f5973d67 7345 }
ae2552da 7346 while (off > 0);
e1c3b13a 7347 DWFL_ASSERT("dwfl_getmodules", off == 0);
ccf2c922 7348 dwfl_end(dwfl);
f5973d67
FCE
7349
7350 // ---- step 2: process any user modules (files) listed
f5973d67
FCE
7351 for (std::set<std::string>::iterator it = s.unwindsym_modules.begin();
7352 it != s.unwindsym_modules.end();
7353 it++)
7354 {
7355 string modname = *it;
7356 assert (modname.length() != 0);
5f8ca04f 7357 if (! is_user_module (modname)) continue;
ccf2c922 7358 Dwfl *dwfl = setup_dwfl_user (modname);
5f8ca04f 7359 if (dwfl != NULL) // tolerate missing data; will warn below
f5973d67 7360 {
4464a6bb
FCE
7361 ptrdiff_t off = 0;
7362 do
7363 {
e19ebcf7 7364 assert_no_interrupts();
c87193cf 7365 if (ctx.undone_unwindsym_modules.empty()) break;
68983551 7366 off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, off);
4464a6bb 7367 }
5d6b0142 7368 while (off > 0);
e1c3b13a 7369 DWFL_ASSERT("dwfl_getmodules", off == 0);
f5973d67 7370 }
ccf2c922 7371 dwfl_end(dwfl);
f5973d67 7372 }
1b94bf6d 7373
7b65c066
FL
7374 // Use /proc/kallsyms if debuginfo not found.
7375 if (ctx.undone_unwindsym_modules.find("kernel") != ctx.undone_unwindsym_modules.end())
7376 dump_kallsyms(&ctx);
7377
62d950bb
MW
7378 emit_symbol_data_done (&ctx, s);
7379}
1b94bf6d 7380
8dca3463
LB
7381void
7382self_unwind_declarations(unwindsym_dump_context *ctx)
7383{
7384 ctx->output << "static uint8_t _stp_module_self_eh_frame [] = {0,};\n";
7385 ctx->output << "static struct _stp_symbol _stp_module_self_symbols_0[] = {{0},};\n";
7386 ctx->output << "static struct _stp_symbol _stp_module_self_symbols_1[] = {{0},};\n";
7387 ctx->output << "static struct _stp_section _stp_module_self_sections[] = {\n";
7388 ctx->output << "{.name = \".symtab\", .symbols = _stp_module_self_symbols_0, .num_symbols = 0},\n";
7389 ctx->output << "{.name = \".text\", .symbols = _stp_module_self_symbols_1, .num_symbols = 0},\n";
7390 ctx->output << "};\n";
7391 ctx->output << "static struct _stp_module _stp_module_self = {\n";
7392 ctx->output << ".name = \"stap_self_tmp_value\",\n";
7393 ctx->output << ".path = \"stap_self_tmp_value\",\n";
7394 ctx->output << ".num_sections = 2,\n";
7395 ctx->output << ".sections = _stp_module_self_sections,\n";
7396 ctx->output << ".eh_frame = _stp_module_self_eh_frame,\n";
7397 ctx->output << ".eh_frame_len = 0,\n";
7398 ctx->output << ".unwind_hdr_addr = 0x0,\n";
7399 ctx->output << ".unwind_hdr = NULL,\n";
7400 ctx->output << ".unwind_hdr_len = 0,\n";
7401 ctx->output << ".debug_frame = NULL,\n";
7402 ctx->output << ".debug_frame_len = 0,\n";
ee533a58
AJ
7403 ctx->output << ".debug_line = NULL,\n";
7404 ctx->output << ".debug_line_len = 0,\n";
8dca3463
LB
7405 ctx->output << "};\n";
7406}
7407
62d950bb
MW
7408void
7409emit_symbol_data_done (unwindsym_dump_context *ctx, systemtap_session& s)
7410{
80d74c6b
FCE
7411 // Add a .eh_frame terminator dummy object file, much like
7412 // libgcc/crtstuff.c's EH_FRAME_SECTION_NAME closer. We need this in
7413 // order for runtime/sym.c
7414 translator_output *T_800 = s.op_create_auxiliary(true);
7415 T_800->newline() << "__extension__ unsigned int T_800 []"; // assumed 32-bits wide
7416 T_800->newline(1) << "__attribute__((used, section(\".eh_frame\"), aligned(4)))";
7417 T_800->newline() << "= { 0 };";
7418 T_800->newline(-1);
7419 T_800->assert_0_indent (); // flush to disk
7420
1b94bf6d 7421 // Print out a definition of the runtime's _stp_modules[] globals.
62d950bb 7422 ctx->output << "\n";
8dca3463
LB
7423 self_unwind_declarations(ctx);
7424 ctx->output << "static struct _stp_module *_stp_modules [] = {\n";
62d950bb 7425 for (unsigned i=0; i<ctx->stp_module_index; i++)
1b94bf6d 7426 {
62d950bb 7427 ctx->output << "& _stp_module_" << i << ",\n";
1b94bf6d 7428 }
3222365c 7429 ctx->output << "& _stp_module_self,\n";
62d950bb 7430 ctx->output << "};\n";
89815df7 7431 ctx->output << "static const unsigned _stp_num_modules = ARRAY_SIZE(_stp_modules);\n";
4464a6bb 7432
3f6b6682
RM
7433 ctx->output << "static unsigned long _stp_kretprobe_trampoline = ";
7434 // Special case for -1, which is invalid in hex if host width > target width.
7435 if (ctx->stp_kretprobe_trampoline_addr == (unsigned long) -1)
7436 ctx->output << "-1;\n";
7437 else
7438 ctx->output << "0x" << hex << ctx->stp_kretprobe_trampoline_addr << dec
7439 << ";\n";
4464a6bb
FCE
7440
7441 // Some nonexistent modules may have been identified with "-d". Note them.
83ca3872
MW
7442 if (! s.suppress_warnings)
7443 for (set<string>::iterator it = ctx->undone_unwindsym_modules.begin();
7444 it != ctx->undone_unwindsym_modules.end();
7445 it ++)
1e41115c 7446 s.print_warning (_("missing unwind/symbol data for module '")
83ca3872 7447 + (*it) + "'");
33f88a80
FCE
7448}
7449
a7ed0d3e
FCE
7450struct recursion_info: public traversing_visitor
7451{
7452 recursion_info (systemtap_session& s): sess(s), nesting_max(0), recursive(false) {}
7453 systemtap_session& sess;
7454 unsigned nesting_max;
7455 bool recursive;
7456 std::vector <functiondecl *> current_nesting;
7457
7458 void visit_functioncall (functioncall* e) {
7459 traversing_visitor::visit_functioncall (e); // for arguments
7460
7461 // check for nesting level
7462 unsigned nesting_depth = current_nesting.size() + 1;
7463 if (nesting_max < nesting_depth)
7464 {
7465 if (sess.verbose > 3)
1e41115c 7466 clog << _F("identified max-nested function: %s (%d)",
7371cd19 7467 e->referent->name.to_string().c_str(), nesting_depth) << endl;
a7ed0d3e
FCE
7468 nesting_max = nesting_depth;
7469 }
7470
7471 // check for (direct or mutual) recursion
7472 for (unsigned j=0; j<current_nesting.size(); j++)
7473 if (current_nesting[j] == e->referent)
7474 {
7475 recursive = true;
7476 if (sess.verbose > 3)
7371cd19
JS
7477 clog << _F("identified recursive function: %s",
7478 e->referent->name.to_string().c_str()) << endl;
a7ed0d3e
FCE
7479 return;
7480 }
7481
7482 // non-recursive traversal
7483 current_nesting.push_back (e->referent);
7484 e->referent->body->visit (this);
7485 current_nesting.pop_back ();
7486 }
7487};
7488
7489
b5f561be
LB
7490void translate_runtime(systemtap_session& s)
7491{
7492 s.op->newline() << "#define STAP_MSG_RUNTIME_H_01 "
7493 << lex_cast_qstring(_("myproc-unprivileged tapset function called "
7494 "without is_myproc checking for pid %d (euid %d)"));
7495
7496 s.op->newline() << "#define STAP_MSG_LOC2C_01 "
6003d4bc 7497 << lex_cast_qstring(_("read fault [man error::fault] at 0x%p (%s)"));
b5f561be 7498 s.op->newline() << "#define STAP_MSG_LOC2C_02 "
6003d4bc 7499 << lex_cast_qstring(_("write fault [man error::fault] at 0x%p (%s)"));
fa2e3415
MW
7500 s.op->newline() << "#define STAP_MSG_LOC2C_03 "
7501 << lex_cast_qstring(_("divide by zero in DWARF operand (%s)"));
b5f561be 7502}
cfa5d9e0
FCE
7503
7504
d13bcfd8
JS
7505int
7506prepare_translate_pass (systemtap_session& s)
7507{
cfa5d9e0
FCE
7508 int rc = 0;
7509 try
7510 {
7511 prepare_symbol_data (s);
7512 }
7513 catch (const semantic_error& e)
7514 {
7515 s.print_error (e);
7516 rc = 1;
7517 }
7518
7519 return rc;
d13bcfd8 7520}
a7ed0d3e
FCE
7521
7522
2b066ec1
FCE
7523int
7524translate_pass (systemtap_session& s)
7525{
7526 int rc = 0;
7527
f4b28491 7528 s.op = new translator_output (s.translated_source);
a4b9c3b3 7529 // additional outputs might be found in s.auxiliary_outputs
4383d78c
FCE
7530 c_unparser cup (& s);
7531 s.up = & cup;
b5f561be 7532 translate_runtime(s);
2b066ec1
FCE
7533
7534 try
7535 {
176e25af
JS
7536 int64_t major=0, minor=0;
7537 try
7538 {
7539 vector<string> versions;
7540 tokenize (s.compatible, versions, ".");
7541 if (versions.size() >= 1)
7542 major = lex_cast<int64_t> (versions[0]);
7543 if (versions.size() >= 2)
7544 minor = lex_cast<int64_t> (versions[1]);
7545 if (versions.size() >= 3 && s.verbose > 1)
1e41115c 7546 clog << _F("ignoring extra parts of compat version: %s", s.compatible.c_str()) << endl;
176e25af
JS
7547 }
7548 catch (const runtime_error)
7549 {
dc09353a 7550 throw SEMANTIC_ERROR(_F("parse error in compatibility version: %s", s.compatible.c_str()));
176e25af
JS
7551 }
7552 if (major < 0 || major > 255 || minor < 0 || minor > 255)
dc09353a 7553 throw SEMANTIC_ERROR(_F("compatibility version out of range: %s", s.compatible.c_str()));
176e25af
JS
7554 s.op->newline() << "#define STAP_VERSION(a, b) ( ((a) << 8) + (b) )";
7555 s.op->newline() << "#ifndef STAP_COMPAT_VERSION";
7556 s.op->newline() << "#define STAP_COMPAT_VERSION STAP_VERSION("
7557 << major << ", " << minor << ")";
7558 s.op->newline() << "#endif";
7559
a7ed0d3e
FCE
7560 recursion_info ri (s);
7561
7562 // NB: we start our traversal from the s.functions[] rather than the probes.
7563 // We assume that each function is called at least once, or else it would have
7564 // been elided already.
7565 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
7566 {
7567 functiondecl *fd = it->second;
7568 fd->body->visit (& ri);
7569 }
7570
7571 if (s.verbose > 1)
1e41115c
LB
7572 clog << _F("function recursion-analysis: max-nesting %d %s", ri.nesting_max,
7573 (ri.recursive ? _(" recursive") : _(" non-recursive"))) << endl;
a7ed0d3e
FCE
7574 unsigned nesting = ri.nesting_max + 1; /* to account for initial probe->function call */
7575 if (ri.recursive) nesting += 10;
dff50e09 7576
a7ed0d3e 7577 // This is at the very top of the file.
a34a9fe0 7578 // All "static" defines (not dependend on session state).
f2013cc9 7579 s.op->newline() << "#include \"runtime_defines.h\"";
3689db05
SC
7580 if (s.perf_derived_probes)
7581 s.op->newline() << "#define _HAVE_PERF_ 1";
7582 s.op->newline() << "#include \"linux/perf_read.h\"";
a34a9fe0 7583
9a1917ff 7584 // Generated macros describing the privilege level required to load/run this module.
f2013cc9 7585 s.op->newline() << "#define STP_PR_STAPUSR 0x" << hex << pr_stapusr << dec;
f6be7c06 7586 s.op->newline() << "#define STP_PR_STAPSYS 0x" << hex << pr_stapsys << dec;
f2013cc9
DB
7587 s.op->newline() << "#define STP_PR_STAPDEV 0x" << hex << pr_stapdev << dec;
7588 s.op->newline() << "#define STP_PRIVILEGE 0x" << hex << s.privilege << dec;
a34a9fe0 7589
f2013cc9 7590 // Generate a section containing a mask of the privilege levels required to load/run this
9a1917ff 7591 // module.
f2013cc9 7592 s.op->newline() << "int stp_required_privilege "
bb4470ca 7593 << "__attribute__ ((section (\"" << STAP_PRIVILEGE_SECTION <<"\")))"
f2013cc9 7594 << " = STP_PRIVILEGE;";
9a1917ff 7595
ed10c639 7596 s.op->newline() << "#ifndef MAXNESTING";
a7ed0d3e 7597 s.op->newline() << "#define MAXNESTING " << nesting;
ed10c639 7598 s.op->newline() << "#endif";
1eed9afc 7599
e5fcd199
SM
7600 // Generated macros specifying how much storage is required for
7601 // regexp subexpressions:
7602 s.op->newline() << "#define STAPREGEX_MAX_STATE" << s.dfa_maxstate;
7603 s.op->newline() << "#define STAPREGEX_MAX_TAG" << s.dfa_maxtag;
7604
dcfd7fed
FCE
7605 s.op->newline() << "#define STP_SKIP_BADVARS " << (s.skip_badvars ? 1 : 0);
7606
f12b2552 7607 if (s.bulk_mode)
e65b03c1 7608 s.op->newline() << "#define STP_BULKMODE";
dff50e09 7609
f6429b94 7610 if (s.timing || s.monitor)
08badca8
MW
7611 s.op->newline() << "#define STP_TIMING";
7612
7613 if (s.need_unwind)
7614 s.op->newline() << "#define STP_NEED_UNWIND_DATA 1";
4b17d6af 7615
ee533a58
AJ
7616 if (s.need_lines)
7617 s.op->newline() << "#define STP_NEED_LINE_DATA 1";
7618
7c3e97f4
JS
7619 // Emit the total number of probes (not regarding merged probe handlers)
7620 s.op->newline() << "#define STP_PROBE_COUNT " << s.probes.size();
7621
ba7276fa 7622 // Emit systemtap_module_refresh() prototype so we can reference it
19d62b5b 7623 s.op->newline() << "static void systemtap_module_refresh (const char* modname);";
ba7276fa 7624
320e1ecb
DS
7625 // Be sure to include runtime.h before any real code.
7626 s.op->newline() << "#include \"runtime.h\"";
7627
4bf3d59d
JL
7628 if (!s.runtime_usermode_p())
7629 {
4619bb71
JL
7630 // When on-the-fly [dis]arming is used, module_refresh can be called from
7631 // both the module notifier, as well as when probes need to be
7632 // armed/disarmed. We need to protect it to ensure it's only run one at a
7633 // time.
4bf3d59d
JL
7634 s.op->newline() << "#include <linux/mutex.h>";
7635 s.op->newline() << "static DEFINE_MUTEX(module_refresh_mutex);";
4619bb71
JL
7636
7637 // For some probes, on-the-fly support is provided through a
7638 // background timer (module_refresh_timer). We need to disable that
7639 // part if hrtimers are not supported.
7640 s.op->newline() << "#include <linux/version.h>";
7641 s.op->newline() << "#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)";
7642 s.op->newline() << "#define STP_ON_THE_FLY_TIMER_ENABLE";
7643 s.op->newline() << "#endif";
4bf3d59d 7644 }
9c91d9d5 7645
f58e7aa8 7646 // Emit embeds ahead of time, in case they affect context layout
54dfabe9
FCE
7647 for (unsigned i=0; i<s.embeds.size(); i++)
7648 {
db22e55f 7649 s.op->newline() << s.embeds[i]->code << "\n";
54dfabe9
FCE
7650 }
7651
f58e7aa8
FCE
7652 s.up->emit_common_header (); // context etc.
7653
1f88b7b7
MW
7654 if (s.need_unwind)
7655 s.op->newline() << "#include \"stack.c\"";
7656
63438a79
JS
7657 if (s.globals.size()>0)
7658 {
7659 s.op->newline() << "struct stp_globals {";
7660 s.op->indent(1);
7661 for (unsigned i=0; i<s.globals.size(); i++)
7662 {
7663 s.up->emit_global (s.globals[i]);
7664 }
7665 s.op->newline(-1) << "};";
7666
7667 // We only need to statically initialize globals in kernel modules,
7668 // where module parameters may want to override the script's value. In
bd268288
SM
7669 // stapdyn, the globals are actually part of the dynamic shared memory,
7670 // and the static structure is merely used as a source of default values.
7671 s.op->newline();
7672 if (!s.runtime_usermode_p ())
7673 s.op->newline() << "static struct stp_globals stp_global = {";
7674 else
7675 {
7676 s.op->newline() << "static struct {";
7677 s.op->indent(1);
7678 for (unsigned i=0; i<s.globals.size(); i++)
7679 {
7680 assert_no_interrupts();
7681 s.up->emit_global_init_type (s.globals[i]);
7682 }
7683 s.op->newline(-1) << "} stp_global_init = {";
7684 }
7685 s.op->newline(1);
7686 for (unsigned i=0; i<s.globals.size(); i++)
63438a79 7687 {
bd268288
SM
7688 assert_no_interrupts();
7689 s.up->emit_global_init (s.globals[i]);
63438a79 7690 }
bd268288 7691 s.op->newline(-1) << "};";
63438a79
JS
7692
7693 s.op->assert_0_indent();
7694 }
2caba859
DS
7695 else
7696 // stp_runtime_session wants to incorporate globals, but it
7697 // can be empty
63438a79
JS
7698 s.op->newline() << "struct stp_globals {};";
7699
7700 // Common (static atomic) state of the stap session.
8b2f930e 7701 s.op->newline();
63438a79
JS
7702 s.op->newline() << "#include \"common_session_state.h\"";
7703
f58e7aa8
FCE
7704 s.op->newline() << "#include \"probe_lock.h\" ";
7705
63438a79
JS
7706 s.op->newline() << "#ifdef STAP_NEED_GETTIMEOFDAY";
7707 s.op->newline() << "#include \"time.c\""; // Don't we all need more?
7708 s.op->newline() << "#endif";
f4b28491 7709
d2548fe7
SM
7710 for (map<string,stapdfa*>::iterator it = s.dfas.begin(); it != s.dfas.end(); it++)
7711 {
7712 assert_no_interrupts();
7713 s.op->newline();
5a14b9b8
SM
7714 try
7715 {
7716 it->second->emit_declaration (s.op);
7717 }
7718 catch (const semantic_error &e)
7719 {
60cf5fae 7720 s.print_error(e);
5a14b9b8 7721 }
d2548fe7
SM
7722 }
7723 s.op->assert_0_indent();
7724
f76427a2 7725 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
8a43522c 7726 {
e19ebcf7 7727 assert_no_interrupts();
8a43522c 7728 s.op->newline();
f76427a2 7729 s.up->emit_functionsig (it->second);
8a43522c 7730 }
1384b663 7731 s.op->assert_0_indent();
f4b28491 7732
f4b28491 7733
faea5e16
JS
7734 // Let's find some stats for the embedded pp strings. Maybe they
7735 // are small and uniform enough to justify putting char[MAX]'s into
7736 // the array instead of relocated char*'s.
26e63673
JS
7737 size_t pp_max = 0, pn_max = 0, location_max = 0, derivation_max = 0;
7738 size_t pp_tot = 0, pn_tot = 0, location_tot = 0, derivation_tot = 0;
faea5e16
JS
7739 for (unsigned i=0; i<s.probes.size(); i++)
7740 {
7741 derived_probe* p = s.probes[i];
7742#define DOIT(var,expr) do { \
7743 size_t var##_size = (expr) + 1; \
7744 var##_max = max (var##_max, var##_size); \
7745 var##_tot += var##_size; } while (0)
7746 DOIT(pp, lex_cast_qstring(*p->sole_location()).size());
d48df0cf 7747 DOIT(pn, lex_cast_qstring(*p->script_location()).size());
26e63673
JS
7748 DOIT(location, lex_cast_qstring(p->tok->location).size());
7749 DOIT(derivation, lex_cast_qstring(p->derived_locations()).size());
faea5e16
JS
7750#undef DOIT
7751 }
7752
7753 // Decide whether it's worthwhile to use char[] or char* by comparing
7754 // the amount of average waste (max - avg) to the relocation data size
7755 // (3 native long words).
7756#define CALCIT(var) \
1af06529
FCE
7757 if (s.verbose > 2) \
7758 clog << "adapt " << #var << ":" << var##_max << "max - " << var##_tot << "/" << s.probes.size() << "tot =>"; \
faea5e16
JS
7759 if ((var##_max-(var##_tot/s.probes.size())) < (3 * sizeof(void*))) \
7760 { \
7761 s.op->newline() << "const char " << #var << "[" << var##_max << "];"; \
7762 if (s.verbose > 2) \
1af06529 7763 clog << "[]" << endl; \
faea5e16
JS
7764 } \
7765 else \
7766 { \
7767 s.op->newline() << "const char * const " << #var << ";"; \
7768 if (s.verbose > 2) \
1af06529 7769 clog << "*" << endl; \
faea5e16
JS
7770 }
7771
8b2f930e 7772 s.op->newline();
7c3e97f4 7773 s.op->newline() << "struct stap_probe {";
100354e5 7774 s.op->newline(1) << "const size_t index;";
7c3e97f4 7775 s.op->newline() << "void (* const ph) (struct context*);";
d02d9b1c 7776 s.op->newline() << "unsigned cond_enabled:1;"; // just one bit required
653e6a9a 7777 s.op->newline() << "#if defined(STP_TIMING) || defined(STP_ALIBI)";
26e63673
JS
7778 CALCIT(location);
7779 CALCIT(derivation);
7780 s.op->newline() << "#define STAP_PROBE_INIT_TIMING(L, D) "
7781 << ".location=(L), .derivation=(D),";
994aac0e 7782 s.op->newline() << "#else";
26e63673 7783 s.op->newline() << "#define STAP_PROBE_INIT_TIMING(L, D)";
994aac0e 7784 s.op->newline() << "#endif";
faea5e16 7785 CALCIT(pp);
d48df0cf
JS
7786 s.op->newline() << "#ifdef STP_NEED_PROBE_NAME";
7787 CALCIT(pn);
994aac0e 7788 s.op->newline() << "#define STAP_PROBE_INIT_NAME(PN) .pn=(PN),";
2d767770 7789 s.op->newline() << "#else";
994aac0e 7790 s.op->newline() << "#define STAP_PROBE_INIT_NAME(PN)";
2d767770 7791 s.op->newline() << "#endif";
7c3e97f4 7792 s.op->newline() << "#define STAP_PROBE_INIT(I, PH, PP, PN, L, D) "
61d88614 7793 << "{ .index=(I), .ph=(PH), .cond_enabled=1, .pp=(PP), "
994aac0e 7794 << "STAP_PROBE_INIT_NAME(PN) "
26e63673 7795 << "STAP_PROBE_INIT_TIMING(L, D) "
994aac0e 7796 << "}";
3ef65016
JL
7797 s.op->newline(-1) << "} static stap_probes[];";
7798 s.op->assert_0_indent();
7799#undef CALCIT
7800
7801 // Run a varuse_collecting_visitor over probes that need global
7802 // variable locks. We'll use this information later in
7803 // emit_locks()/emit_unlocks().
7804 for (unsigned i=0; i<s.probes.size(); i++)
7805 {
7806 assert_no_interrupts();
05a072cf 7807 s.probes[i]->session_index = i;
3ef65016
JL
7808 if (s.probes[i]->needs_global_locks())
7809 s.probes[i]->body->visit (&cup.vcv_needs_global_locks);
7810 }
7811 s.op->assert_0_indent();
7812
7813 for (unsigned i=0; i<s.probes.size(); i++)
7814 {
7815 assert_no_interrupts();
7816 s.up->emit_probe (s.probes[i]);
7817 }
7818 s.op->assert_0_indent();
7819
7820 s.op->newline() << "static struct stap_probe stap_probes[] = {";
26e63673
JS
7821 s.op->indent(1);
7822 for (unsigned i=0; i<s.probes.size(); ++i)
7823 {
7824 derived_probe* p = s.probes[i];
1341a03c 7825 s.op->newline() << "STAP_PROBE_INIT(" << i << ", &" << p->name() << ", "
26e63673
JS
7826 << lex_cast_qstring (*p->sole_location()) << ", "
7827 << lex_cast_qstring (*p->script_location()) << ", "
7828 << lex_cast_qstring (p->tok->location) << ", "
7829 << lex_cast_qstring (p->derived_locations()) << "),";
7830 }
faea5e16 7831 s.op->newline(-1) << "};";
faea5e16 7832
f4d70a33
JS
7833 if (s.runtime_usermode_p())
7834 {
7835 s.op->newline() << "static const char* stp_probe_point(size_t index) {";
7836 s.op->newline(1) << "if (index < ARRAY_SIZE(stap_probes))";
7837 s.op->newline(1) << "return stap_probes[index].pp;";
7838 s.op->newline(-1) << "return NULL;";
7839 s.op->newline(-1) << "}";
7840 s.op->assert_0_indent();
7841 }
7842
6120441d
FL
7843 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
7844 {
7845 assert_no_interrupts();
7846 s.op->newline();
7847 s.up->emit_function (it->second);
7848 }
7849
3ef65016 7850 s.op->assert_0_indent();
bfb3d2d2 7851 s.op->newline();
2b066ec1 7852 s.up->emit_module_init ();
1384b663 7853 s.op->assert_0_indent();
bfb3d2d2 7854 s.op->newline();
a60923e9
FCE
7855 s.up->emit_module_refresh ();
7856 s.op->assert_0_indent();
7857 s.op->newline();
2b066ec1 7858 s.up->emit_module_exit ();
1384b663 7859 s.op->assert_0_indent();
be66b6e1
DS
7860 s.up->emit_kernel_module_init ();
7861 s.op->assert_0_indent();
7862 s.up->emit_kernel_module_exit ();
7863 s.op->assert_0_indent();
f4b28491 7864 s.op->newline();
f4b28491 7865
ed35c8ac
FCE
7866 emit_symbol_data (s);
7867
7868 s.op->newline() << "MODULE_DESCRIPTION(\"systemtap-generated probe\");";
7869 s.op->newline() << "MODULE_LICENSE(\"GPL\");";
633e5ca7
FCE
7870
7871 for (unsigned i = 0; i < s.modinfos.size(); i++)
7872 {
7873 const string& mi = s.modinfos[i];
7874 size_t loc = mi.find('=');
7875 string tag = mi.substr (0, loc);
7876 string value = mi.substr (loc+1);
7877 s.op->newline() << "MODULE_INFO(" << tag << "," << lex_cast_qstring(value) << ");";
7878 }
7879
ed35c8ac
FCE
7880 s.op->assert_0_indent();
7881
bd268288
SM
7882 if (s.runtime_usermode_p())
7883 s.up->emit_global_init_setters();
7884 else
7885 // PR10298: attempt to avoid collisions with symbols
7886 for (unsigned i=0; i<s.globals.size(); i++)
7887 {
7888 s.op->newline();
7889 s.up->emit_global_param (s.globals[i]);
7890 }
1384b663 7891 s.op->assert_0_indent();
2b066ec1
FCE
7892 }
7893 catch (const semantic_error& e)
7894 {
7895 s.print_error (e);
7896 }
7897
db22e55f 7898 s.op->line() << "\n";
33f88a80 7899
f4b28491
FCE
7900 delete s.op;
7901 s.op = 0;
4383d78c 7902 s.up = 0;
33f88a80 7903
7e41d3dc 7904 return rc + s.num_errors();
2b066ec1 7905}
73267b89
JS
7906
7907/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 1.866791 seconds and 5 git commands to generate.