]> sourceware.org Git - systemtap.git/blame - tapsets.cxx
2006-09-27 Martin Hunt <hunt@redhat.com>
[systemtap.git] / tapsets.cxx
CommitLineData
56e12059 1// tapset resolution
9a604fac 2// Copyright (C) 2005, 2006 Red Hat Inc.
77a5c1f9 3// Copyright (C) 2005, 2006 Intel Corporation.
56e12059
FCE
4//
5// This file is part of systemtap, and is free software. You can
6// redistribute it and/or modify it under the terms of the GNU General
7// Public License (GPL); either version 2, or (at your option) any
8// later version.
9
10#include "config.h"
11#include "staptree.h"
12#include "elaborate.h"
b55bc428 13#include "tapsets.h"
56e12059 14#include "translate.h"
dc38c0ae 15#include "session.h"
bd2b1e68
GH
16
17#include <deque>
56e12059 18#include <iostream>
bd2b1e68 19#include <map>
ec4373ff 20#include <set>
56e12059 21#include <sstream>
bd2b1e68 22#include <stdexcept>
b55bc428 23#include <vector>
e36387d7 24#include <cstdarg>
29e64872 25#include <cassert>
bd2b1e68
GH
26
27extern "C" {
df8fadee 28#include <fcntl.h>
bd2b1e68 29#include <elfutils/libdwfl.h>
7a053d3b 30#include <elfutils/libdw.h>
77de5e9e
GH
31#include <dwarf.h>
32#include <elf.h>
33#include <obstack.h>
30a279be
FCE
34#include <regex.h>
35#include <fnmatch.h>
4b1ad75e 36
30a279be 37#include "loc2c.h"
4b1ad75e
RM
38#define __STDC_FORMAT_MACROS
39#include <inttypes.h>
bd2b1e68 40}
77de5e9e 41
56e12059 42
47dd066d
WC
43#ifdef PERFMON
44#include <perfmon/pfmlib.h>
45#include <perfmon/perfmon.h>
46#endif
47
48
56e12059
FCE
49using namespace std;
50
cc9ee605
FCE
51
52// XXX: should standardize to these functions throughout translator
53
54template <typename OUT, typename IN> inline OUT
55lex_cast(IN const & in)
56{
57 stringstream ss;
58 OUT out;
59 if (!(ss << in && ss >> out))
60 throw runtime_error("bad lexical cast");
61 return out;
62}
63
64template <typename OUT, typename IN> inline OUT
65lex_cast_hex(IN const & in)
66{
67 stringstream ss;
68 OUT out;
69 if (!(ss << hex << showbase << in && ss >> out))
70 throw runtime_error("bad lexical cast");
71 return out;
72}
73
74
75// return as quoted string, with at least '"' backslash-escaped
76template <typename IN> inline string
77lex_cast_qstring(IN const & in)
78{
79 stringstream ss;
80 string out, out2;
499cf740 81 if (!(ss << in))
cc9ee605 82 throw runtime_error("bad lexical cast");
499cf740 83 out = ss.str();
cc9ee605
FCE
84 out2 += '"';
85 for (unsigned i=0; i<out.length(); i++)
86 {
87 if (out[i] == '"') // XXX others?
88 out2 += '\\';
89 out2 += out[i];
90 }
91 out2 += '"';
92 return out2;
93}
94
95
46b84a80
DS
96static void
97emit_probe_timing(derived_probe* p, translator_output* o)
98{
99 static set<string> basest_names;
100
101 string nm = p->basest()->name;
102 if (basest_names.find(nm) == basest_names.end())
103 {
104 basest_names.insert (nm);
105
106 o->newline() << "#ifdef STP_TIMING";
107 o->newline() << "{";
108 o->newline(1) << "const char *probe_point = "
109 << lex_cast_qstring (*p->basest()->locations[0])
110 << ";";
111 o->newline() << "const char *decl_location = "
112 << lex_cast_qstring (p->basest()->tok->location)
113 << ";";
114 o->newline() << "struct stat_data *stats = _stp_stat_get (time_"
115 << p->basest()->name
116 << ", 0);";
117 o->newline() << "const char *error;";
118 o->newline() << "if (stats->count) {";
119 o->newline(1) << "int64_t avg = _stp_div64 (&error, stats->sum, stats->count);";
120 o->newline() << "_stp_printf (\"probe %s (%s), %lld hits taking %lldmin/%lldavg/%lldmax cycles.\\n\",";
121 o->newline() << "probe_point, decl_location, (long long) stats->count, (long long) stats->min, (long long) avg, (long long) stats->max);";
122 o->newline() << "_stp_print_flush();";
123 o->newline(-1) << "}";
124 o->newline(-1) << "}";
125 o->newline() << "#endif";
126 }
127}
128
129
9a604fac
FCE
130// ------------------------------------------------------------------------
131
132void
a44a0785 133derived_probe::emit_common_header (translator_output* o)
9a604fac 134{
47dd066d
WC
135
136#ifdef PERFMON
137 o->newline() << "static struct pfarg_ctx _pfm_context;";
138 o->newline() << "static void *_pfm_desc;";
139 o->newline() << "static struct pfarg_pmc *_pfm_pmc_x;";
140 o->newline() << "static int _pfm_num_pmc_x;";
141 o->newline() << "static struct pfarg_pmd *_pfm_pmd_x;";
142 o->newline() << "static int _pfm_num_pmd_x;";
143#endif
144
a44a0785
FCE
145 o->newline();
146 o->newline() << "static struct context* common_probe_prologue (int state) {";
147 o->newline(1);
03d569d3 148 o->newline() << "struct context* c;";
a44a0785
FCE
149 o->newline() << "if (atomic_read (&session_state) != state)";
150 o->newline(1) << "return NULL;";
9a604fac 151
a44a0785 152 o->newline() << "c = per_cpu_ptr (contexts, smp_processor_id());";
9a604fac 153 o->newline(-1) << "if (unlikely (atomic_inc_return (&c->busy) != 1)) {";
9a604fac
FCE
154 o->newline(1) << "if (atomic_inc_return (& skipped_count) > MAXSKIPPED) {";
155 o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
156 // NB: We don't assume that we can safely call stp_error etc. in such
157 // a reentrant context. But this is OK:
158 o->newline() << "_stp_exit ();";
159 o->newline(-1) << "}";
9a604fac 160 o->newline() << "atomic_dec (& c->busy);";
a44a0785 161 o->newline() << "return NULL;";
9a604fac
FCE
162 o->newline(-1) << "}";
163 o->newline();
164 o->newline() << "c->last_error = 0;";
9a604fac
FCE
165 o->newline() << "c->nesting = 0;";
166 o->newline() << "c->regs = 0;";
167 o->newline() << "c->actioncount = 0;";
a44a0785
FCE
168 o->newline() << "return c;";
169 o->newline(-1) << "}";
170 o->newline();
9a604fac 171
a44a0785
FCE
172
173 o->newline() << "static void common_probe_epilogue (struct context* c) {";
174 o->newline(1) ;
9a604fac
FCE
175 o->newline() << "if (unlikely (c->last_error && c->last_error[0])) {";
176 o->newline(1) << "if (c->last_stmt != NULL)";
177 o->newline(1) << "_stp_softerror (\"%s near %s\", c->last_error, c->last_stmt);";
178 o->newline(-1) << "else";
179 o->newline(1) << "_stp_softerror (\"%s\", c->last_error);";
180 o->indent(-1);
181 o->newline() << "atomic_inc (& error_count);";
9a604fac
FCE
182 o->newline() << "if (atomic_read (& error_count) > MAXERRORS) {";
183 o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
184 o->newline() << "_stp_exit ();";
185 o->newline(-1) << "}";
9a604fac 186 o->newline(-1) << "}";
e38d6504 187
9a604fac 188 o->newline() << "atomic_dec (&c->busy);";
a44a0785
FCE
189 o->newline(-1) << "}";
190}
191
192
193void
194derived_probe::emit_probe_prologue (translator_output* o,
195 const std::string& statereq)
196{
197 o->newline() << "struct context* c;";
198 o->newline() << "unsigned long flags;";
199
e38d6504 200 // NB: this cycles_t stuff might go into the common header block above
a44a0785
FCE
201 o->newline() << "#ifdef STP_TIMING";
202 o->newline() << "cycles_t cycles_atstart;";
203 o->newline() << "#endif";
204 o->newline() << "local_irq_save (flags);";
205 o->newline() << "#ifdef STP_TIMING";
206 o->newline() << "cycles_atstart = get_cycles ();";
207 o->newline() << "#endif";
208 o->newline() << "c = common_probe_prologue (" << statereq << ");";
209 o->newline() << "if (c == NULL) goto probe_epilogue;";
210 o->newline() << "c->probe_point = probe_point;";
211}
212
213void
214derived_probe::emit_probe_epilogue (translator_output* o)
215{
216 o->newline() << "common_probe_epilogue (c);";
217
213bee8f 218 o->newline(-1) << "probe_epilogue:";
4b17d6af
WC
219 o->newline(1) << "#ifdef STP_TIMING";
220 o->newline() << "{";
221 o->newline(1) << "cycles_t cycles_atend = get_cycles ();";
a44a0785
FCE
222
223 // XXX: get_cycles() may return fewer significant digits than
224 // cycles_t can carry. On some machines, cycles_t is 64 bits wide
225 // but get_cycles() is only 52. So we should investigate truncating
226 // these get_cycles() return values to some reasonable smaller
227 // number of bits, perhaps 32 or even 24.
228
4b17d6af
WC
229 o->newline() << "int64_t cycles_elapsed = (cycles_atend > cycles_atstart)";
230 o->newline(1) << "? (int64_t) (cycles_atend - cycles_atstart)";
231 o->newline() << ": (int64_t) (~(cycles_t)0) - cycles_atstart + cycles_atend + 1;";
c1d5f3f6 232 o->newline() << "_stp_stat_add(time_" << basest()->name << ",cycles_elapsed);";
4b17d6af
WC
233 o->indent(-1);
234 o->newline(-1) << "}";
235 o->newline() << "#endif";
236 o->newline() << "local_irq_restore (flags);";
9a604fac
FCE
237}
238
239
240
b55bc428
FCE
241// ------------------------------------------------------------------------
242// begin/end probes are run right during registration / deregistration
56e12059
FCE
243// ------------------------------------------------------------------------
244
b55bc428
FCE
245struct be_derived_probe: public derived_probe
246{
247 bool begin;
248 be_derived_probe (probe* p, bool b): derived_probe (p), begin (b) {}
249 be_derived_probe (probe* p, probe_point* l, bool b):
250 derived_probe (p, l), begin (b) {}
56e12059 251
dc38c0ae
DS
252 void register_probe (systemtap_session& s);
253
46b84a80
DS
254 void emit_registrations_start (translator_output* o, unsigned index=0);
255 void emit_registrations_end (translator_output* o, unsigned index) {}
35d4ab18
FCE
256 void emit_deregistrations (translator_output* o);
257 void emit_probe_entries (translator_output* o);
b55bc428
FCE
258};
259
98afd80e 260
dc38c0ae
DS
261struct be_derived_probe_group: public derived_probe_group
262{
263private:
264 vector<be_derived_probe*> probes;
265
266public:
267 virtual void register_probe(be_derived_probe* p) { probes.push_back (p); }
268 virtual size_t size () { return probes.size (); }
269
270 virtual void emit_probes (translator_output* op, unparser* up);
46b84a80 271 virtual void emit_module_init (translator_output* o);
dc38c0ae
DS
272};
273
274
98afd80e 275struct be_builder: public derived_probe_builder
b55bc428
FCE
276{
277 bool begin;
278 be_builder(bool b) : begin(b) {}
5227f1ea 279 virtual void build(systemtap_session & sess,
7a053d3b 280 probe * base,
20c6c071
GH
281 probe_point * location,
282 std::map<std::string, literal *> const & parameters,
20c6c071 283 vector<derived_probe *> & finished_results)
b55bc428 284 {
20c6c071 285 finished_results.push_back(new be_derived_probe(base, location, begin));
b55bc428 286 }
b55bc428 287};
56e12059
FCE
288
289
dc38c0ae
DS
290void
291be_derived_probe::register_probe(systemtap_session& s)
292{
293 s.probes.register_probe(this);
294}
295
296
7a053d3b 297void
46b84a80
DS
298be_derived_probe::emit_registrations_start (translator_output* o,
299 unsigned index)
56e12059
FCE
300{
301 if (begin)
302 for (unsigned i=0; i<locations.size(); i++)
35d4ab18 303 o->newline() << "enter_" << name << "_" << i << " ();";
56e12059
FCE
304}
305
306
7a053d3b 307void
35d4ab18 308be_derived_probe::emit_deregistrations (translator_output* o)
56e12059 309{
bfb3d2d2 310 if (!begin)
56e12059 311 for (unsigned i=0; i<locations.size(); i++)
35d4ab18 312 o->newline() << "enter_" << name << "_" << i << " ();";
56e12059
FCE
313}
314
315
316void
35d4ab18 317be_derived_probe::emit_probe_entries (translator_output* o)
56e12059 318{
4b17d6af 319 o->newline() << "#ifdef STP_TIMING";
c1d5f3f6 320 o->newline() << "static __cacheline_aligned Stat " << "time_" << basest()->name << ";";
4b17d6af
WC
321 o->newline() << "#endif";
322
56e12059
FCE
323 for (unsigned i=0; i<locations.size(); i++)
324 {
325 probe_point *l = locations[i];
326 o->newline() << "/* location " << i << ": " << *l << " */";
ffd1346f 327 o->newline() << "static void enter_" << name << "_" << i << " (void) {";
bfb3d2d2 328
7a053d3b 329 // While begin/end probes are executed single-threaded, we
bfb3d2d2 330 // still code defensively and use a per-cpu context.
9a604fac 331 o->indent(1);
cc9ee605 332 o->newline() << "const char* probe_point = "
9a604fac
FCE
333 << lex_cast_qstring(*l) << ";";
334 emit_probe_prologue (o,
335 (begin ?
336 "STAP_SESSION_STARTING" :
337 "STAP_SESSION_STOPPING"));
bfb3d2d2 338
56e12059 339 // NB: locals are initialized by probe function itself
35d4ab18 340 o->newline() << name << " (c);";
bfb3d2d2 341
9a604fac 342 emit_probe_epilogue (o);
bfb3d2d2 343
db22e55f 344 o->newline(-1) << "}\n";
56e12059
FCE
345 }
346}
347
348
dc38c0ae
DS
349void
350be_derived_probe_group::emit_probes (translator_output* op, unparser* up)
351{
352 for (unsigned i=0; i < probes.size(); i++)
353 {
354 op->newline ();
355 up->emit_probe (probes[i]);
356 }
357}
358
46b84a80
DS
359void
360be_derived_probe_group::emit_module_init (translator_output* o)
361{
362 if (probes.size () == 0)
363 return;
364
365 // Output the be probes create function
366 o->newline() << "static int register_be_probes (void) {";
367 o->indent(1);
368
369 for (unsigned i=0; i < probes.size (); i++)
370 probes[i]->emit_registrations_start (o);
371
372 o->newline() << "return 0;";
373 o->newline(-1) << "}\n";
374
375 // Output the be probes destroy function
376 o->newline() << "static void unregister_be_probes (void) {";
377 o->indent(1);
378
379 for (unsigned i=0; i < probes.size (); i++)
380 {
381 probes[i]->emit_deregistrations (o);
382 emit_probe_timing(probes[i], o);
383 }
384
385 o->newline(-1) << "}\n";
386}
387
dc38c0ae 388
6e3347a9
FCE
389// ------------------------------------------------------------------------
390// never probes are never run
391// ------------------------------------------------------------------------
392
393struct never_derived_probe: public derived_probe
394{
395 never_derived_probe (probe* p): derived_probe (p) {}
396 never_derived_probe (probe* p, probe_point* l): derived_probe (p, l) {}
397
dc38c0ae
DS
398 void register_probe (systemtap_session& s);
399
46b84a80
DS
400 void emit_registrations_start (translator_output* o, unsigned index) {}
401 void emit_registrations_end (translator_output* o, unsigned index) {}
402 void emit_deregistrations (translator_output* o) {}
403 void emit_probe_entries (translator_output* o) {}
6e3347a9
FCE
404};
405
406
dc38c0ae
DS
407struct never_derived_probe_group: public derived_probe_group
408{
409private:
410 vector<never_derived_probe*> probes;
411
412public:
413 virtual void register_probe(never_derived_probe* p) { probes.push_back (p); }
414 virtual size_t size () { return probes.size (); }
415
46b84a80
DS
416 virtual void emit_probes (translator_output* op, unparser* up) {}
417 virtual void emit_module_init (translator_output* o) {}
dc38c0ae
DS
418};
419
420
421void
422never_derived_probe::register_probe(systemtap_session& s)
423{
424 s.probes.register_probe(this);
425}
426
427
6e3347a9
FCE
428struct never_builder: public derived_probe_builder
429{
430 never_builder() {}
431 virtual void build(systemtap_session & sess,
432 probe * base,
433 probe_point * location,
434 std::map<std::string, literal *> const & parameters,
435 vector<derived_probe *> & finished_results)
436 {
437 finished_results.push_back(new never_derived_probe(base, location));
438 }
439};
440
441
56e12059 442// ------------------------------------------------------------------------
bd2b1e68 443// Dwarf derived probes.
b55bc428 444// ------------------------------------------------------------------------
bd2b1e68 445
c239d28c
GH
446static string TOK_PROCESS("process");
447static string TOK_KERNEL("kernel");
448static string TOK_MODULE("module");
449
450static string TOK_FUNCTION("function");
54efe513 451static string TOK_INLINE("inline");
c239d28c
GH
452static string TOK_RETURN("return");
453static string TOK_CALLEES("callees");
454
455static string TOK_STATEMENT("statement");
456static string TOK_LABEL("label");
457static string TOK_RELATIVE("relative");
458
59ff2773 459
59ff2773 460
59ff2773 461
20e4a32c 462struct
7e1279ea
FCE
463func_info
464{
20e4a32c 465 func_info()
b6581717
GH
466 : decl_file(NULL), decl_line(-1), prologue_end(0)
467 {
468 memset(&die, 0, sizeof(die));
469 }
7e1279ea 470 string name;
4cd232e4
GH
471 char const * decl_file;
472 int decl_line;
7e1279ea
FCE
473 Dwarf_Die die;
474 Dwarf_Addr prologue_end;
475};
476
477struct
478inline_instance_info
479{
20e4a32c 480 inline_instance_info()
b6581717
GH
481 : decl_file(NULL), decl_line(-1)
482 {
483 memset(&die, 0, sizeof(die));
484 }
7e1279ea 485 string name;
4cd232e4
GH
486 char const * decl_file;
487 int decl_line;
7e1279ea
FCE
488 Dwarf_Die die;
489};
490
c8959a29
GH
491class
492symbol_cache
493{
494 // For each module, we keep a multimap from function names to
495 // (cudie, funcdie*) pairs. The first time we pass over a module,
496 // we build up this multimap as an index. Our iteration over the
497 // module's CUs and functions is then driven by the function or
498 // statement pattern string we're scanning for.
499 struct entry
500 {
501 Dwarf_Die cu;
502 Dwarf_Die function;
503 };
504 typedef multimap<string, entry> index;
505 map<Dwarf *, index*> indices;
506 index *curr_index;
507 Dwarf_Die * cu_die;
508 void make_entry_for_function(Dwarf_Die *func_die);
509 static int function_callback(Dwarf_Die * func, void * arg);
510 void index_module(Dwarf * mod);
e38d6504 511public:
c8959a29
GH
512 void select_die_subsets(Dwarf * mod,
513 string const & pattern,
514 set<Dwarf_Die> & cus,
515 multimap<Dwarf_Die, Dwarf_Die> & funcs);
516};
517
518void
519symbol_cache::make_entry_for_function(Dwarf_Die *func_die)
520{
521 entry e;
522 assert(this->cu_die);
523 assert(this->curr_index);
524 e.cu = *(this->cu_die);
525 e.function = *(func_die);
526 char const * fname = dwarf_diename(func_die);
527 if (fname)
528 curr_index->insert(make_pair(string(fname), e));
529}
530
531int
532symbol_cache::function_callback(Dwarf_Die * func, void * arg)
533{
534 symbol_cache *sym = static_cast<symbol_cache*>(arg);
535 sym->make_entry_for_function(func);
536 return DWARF_CB_OK;
537}
538
539void
540symbol_cache::index_module(Dwarf *module_dwarf)
541{
542 Dwarf_Off off = 0;
543 size_t cuhl = 0;
544 Dwarf_Off noff = 0;
545 this->cu_die = NULL;
546 while (dwarf_nextcu (module_dwarf, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
547 {
548 Dwarf_Die die_mem;
549 this->cu_die = dwarf_offdie (module_dwarf, off + cuhl, &die_mem);
550 dwarf_getfuncs (this->cu_die, function_callback, this, 0);
551 off = noff;
552 }
553 this->cu_die = NULL;
554}
555
556inline bool
e38d6504 557operator<(Dwarf_Die const & a,
c8959a29
GH
558 Dwarf_Die const & b)
559{
560 return (a.addr < b.addr)
561 || ((a.addr == b.addr) && (a.cu < b.cu))
562 || ((a.addr == b.addr) && (a.cu == b.cu) && (a.abbrev < b.abbrev));
563}
564
565inline bool
e38d6504 566operator==(Dwarf_Die const & a,
c8959a29
GH
567 Dwarf_Die const & b)
568{
569 return !((a < b) || (b < a));
570}
571
e38d6504 572void
c8959a29
GH
573symbol_cache::select_die_subsets(Dwarf *mod,
574 string const & pattern,
575 set<Dwarf_Die> & cus,
576 multimap<Dwarf_Die, Dwarf_Die> & funcs)
577{
578 cus.clear();
579 funcs.clear();
580 index *ix = NULL;
581
582 // First find the index for this module. If there's no index, build
583 // one.
584 map<Dwarf *, index*>::const_iterator i = indices.find(mod);
585 if (i == indices.end())
586 {
587 this->curr_index = new index;
e38d6504 588 index_module(mod);
c8959a29
GH
589 indices.insert(make_pair(mod, this->curr_index));
590 ix = this->curr_index;
591 this->curr_index = NULL;
592 this->cu_die = NULL;
593 }
594 else
595 ix = i->second;
596
597 assert(ix);
598
599 // Now stem the pattern such that we have a minimal non-wildcard
600 // prefix to search in the multimap for. We will use the full pattern
601 // to narrow this set further.
602 string stem;
603 for (string::const_iterator i = pattern.begin();
604 i != pattern.end(); ++i)
605 {
606 if (*i == '?' || *i == '*' || *i == '[' || *i == ']')
607 break;
608 stem += *i;
609 }
610
611 // Now perform a lower-bound on the multimap, refine that result
612 // set, and copy the CU and function DIEs into the parameter sets.
613 index::const_iterator j = stem.empty() ? ix->begin() : ix->lower_bound(stem);
e38d6504 614 while (j != ix->end() &&
c8959a29
GH
615 (stem.empty() || j->first.compare(0, stem.size(), stem) == 0))
616 {
617 if (fnmatch(pattern.c_str(), j->first.c_str(), 0) == 0)
618 {
619 cus.insert(j->second.cu);
620 funcs.insert(make_pair(j->second.cu, j->second.function));
621 }
e38d6504 622 ++j;
c8959a29
GH
623 }
624}
e38d6504 625
c8959a29
GH
626
627
7e1279ea
FCE
628static int
629query_cu (Dwarf_Die * cudie, void * arg);
59ff2773
FCE
630
631
bd2b1e68
GH
632// Helper for dealing with selected portions of libdwfl in a more readable
633// fashion, and with specific cleanup / checking / logging options.
634
91eefb1c
GH
635static const char *
636dwarf_diename_integrate (Dwarf_Die *die)
637{
638 Dwarf_Attribute attr_mem;
639 return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
640}
641
bd2b1e68
GH
642struct
643dwflpp
644{
5227f1ea 645 systemtap_session & sess;
bd2b1e68
GH
646 Dwfl * dwfl;
647
c8959a29
GH
648 symbol_cache cache;
649
bd2b1e68
GH
650 // These are "current" values we focus on.
651 Dwfl_Module * module;
652 Dwarf * module_dwarf;
653 Dwarf_Addr module_bias;
50e0d793
GH
654
655 // These describe the current module's PC address range
656 Dwarf_Addr module_start;
657 Dwarf_Addr module_end;
658
bd2b1e68 659 Dwarf_Die * cu;
20e4a32c 660 Dwarf_Die * function;
bd2b1e68 661
c8959a29
GH
662 set<Dwarf_Die> pattern_limited_cus;
663 multimap<Dwarf_Die, Dwarf_Die> pattern_limited_funcs;
664
bd2b1e68
GH
665 string module_name;
666 string cu_name;
667 string function_name;
668
50e0d793 669
7a053d3b 670 string const default_name(char const * in,
bd2b1e68
GH
671 char const * type)
672 {
7a053d3b 673 if (in)
bd2b1e68 674 return in;
a229fcd7 675 return string("");
bd2b1e68
GH
676 }
677
50e0d793 678
8d695876 679 void get_module_dwarf(bool required = false)
5227f1ea
GH
680 {
681 if (!module_dwarf)
682 module_dwarf = dwfl_module_getdwarf(module, &module_bias);
7e1279ea 683
0ce64fb8
FCE
684 if (!module_dwarf)
685 {
686 string msg = "cannot find ";
687 if (module_name == "")
688 msg += "kernel";
689 else
690 msg += string("module ") + module_name;
691 msg += " debuginfo";
692
693 int i = dwfl_errno();
694 if (i)
695 msg += string(": ") + dwfl_errmsg (i);
696
697 if (required)
698 throw semantic_error (msg);
699 else
db22e55f 700 cerr << "WARNING: " << msg << "\n";
0ce64fb8 701 }
5227f1ea
GH
702 }
703
c8959a29
GH
704 void limit_search_to_function_pattern(string const & pattern)
705 {
8d695876 706 get_module_dwarf(false);
e38d6504
RM
707 cache.select_die_subsets(module_dwarf, pattern,
708 pattern_limited_cus,
c8959a29
GH
709 pattern_limited_funcs);
710 }
50e0d793 711
bd2b1e68
GH
712 void focus_on_module(Dwfl_Module * m)
713 {
714 assert(m);
715 module = m;
7a053d3b 716 module_name = default_name(dwfl_module_info(module, NULL,
50e0d793 717 &module_start, &module_end,
bd2b1e68
GH
718 NULL, NULL,
719 NULL, NULL),
720 "module");
50e0d793
GH
721
722 // Reset existing pointers and names
723
724 module_dwarf = NULL;
725
c8959a29
GH
726 pattern_limited_cus.clear();
727 pattern_limited_funcs.clear();
e38d6504 728
a229fcd7 729 cu_name.clear();
50e0d793
GH
730 cu = NULL;
731
a229fcd7 732 function_name.clear();
50e0d793 733 function = NULL;
bd2b1e68
GH
734 }
735
50e0d793 736
bd2b1e68
GH
737 void focus_on_cu(Dwarf_Die * c)
738 {
739 assert(c);
50e0d793
GH
740 assert(module);
741
bd2b1e68 742 cu = c;
50e0d793
GH
743 cu_name = default_name(dwarf_diename(c), "CU");
744
745 // Reset existing pointers and names
a229fcd7 746 function_name.clear();
50e0d793 747 function = NULL;
bd2b1e68
GH
748 }
749
50e0d793 750
20e4a32c 751 void focus_on_function(Dwarf_Die * f)
bd2b1e68
GH
752 {
753 assert(f);
50e0d793
GH
754 assert(module);
755 assert(cu);
756
bd2b1e68 757 function = f;
20e4a32c 758 function_name = default_name(dwarf_diename(function),
bd2b1e68 759 "function");
bd2b1e68
GH
760 }
761
50e0d793 762
bd2b1e68
GH
763 void focus_on_module_containing_global_address(Dwarf_Addr a)
764 {
765 assert(dwfl);
50e0d793 766 cu = NULL;
0ce64fb8
FCE
767 Dwfl_Module* mod = dwfl_addrmodule(dwfl, a);
768 if (mod) // address could be wildly out of range
769 focus_on_module(mod);
bd2b1e68
GH
770 }
771
50e0d793 772
7e1279ea 773 void query_cu_containing_global_address(Dwarf_Addr a, void *arg)
bd2b1e68 774 {
bd2b1e68 775 Dwarf_Addr bias;
50e0d793 776 assert(dwfl);
5227f1ea 777 get_module_dwarf();
ab55a5ae
FCE
778 Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias);
779 if (cudie) // address could be wildly out of range
780 query_cu (cudie, arg);
bd2b1e68
GH
781 assert(bias == module_bias);
782 }
783
50e0d793 784
7e1279ea 785 void query_cu_containing_module_address(Dwarf_Addr a, void *arg)
bd2b1e68 786 {
7e1279ea 787 query_cu_containing_global_address(module_address_to_global(a), arg);
bd2b1e68
GH
788 }
789
50e0d793 790
bd2b1e68
GH
791 Dwarf_Addr module_address_to_global(Dwarf_Addr a)
792 {
50e0d793 793 assert(dwfl);
bd2b1e68 794 assert(module);
5227f1ea 795 get_module_dwarf();
c239d28c
GH
796 if (module_name == TOK_KERNEL)
797 return a;
50e0d793 798 return a + module_start;
bd2b1e68
GH
799 }
800
50e0d793 801
bd2b1e68
GH
802 Dwarf_Addr global_address_to_module(Dwarf_Addr a)
803 {
804 assert(module);
5227f1ea 805 get_module_dwarf();
bd2b1e68
GH
806 return a - module_bias;
807 }
808
809
810 bool module_name_matches(string pattern)
811 {
812 assert(module);
813 bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
b0ee93c4 814 if (t && sess.verbose>2)
bd2b1e68 815 clog << "pattern '" << pattern << "' "
24cb178f 816 << "matches "
db22e55f 817 << "module '" << module_name << "'" << "\n";
bd2b1e68
GH
818 return t;
819 }
820
50e0d793 821
bd2b1e68
GH
822 bool function_name_matches(string pattern)
823 {
824 assert(function);
825 bool t = (fnmatch(pattern.c_str(), function_name.c_str(), 0) == 0);
b0ee93c4 826 if (t && sess.verbose>2)
bd2b1e68 827 clog << "pattern '" << pattern << "' "
24cb178f 828 << "matches "
db22e55f 829 << "function '" << function_name << "'" << "\n";
bd2b1e68
GH
830 return t;
831 }
832
50e0d793 833
bd2b1e68
GH
834 bool cu_name_matches(string pattern)
835 {
836 assert(cu);
837 bool t = (fnmatch(pattern.c_str(), cu_name.c_str(), 0) == 0);
b0ee93c4 838 if (t && sess.verbose>2)
bd2b1e68 839 clog << "pattern '" << pattern << "' "
24cb178f 840 << "matches "
db22e55f 841 << "CU '" << cu_name << "'" << "\n";
bd2b1e68
GH
842 return t;
843 }
844
50e0d793 845
b40af7ee
DS
846 // NB: "rc == 0" means OK in this case
847 void dwfl_assert(string desc, int rc, string extra_msg = "")
bd2b1e68 848 {
7e1279ea 849 string msg = "libdwfl failure (" + desc + "): ";
d8067b24
FCE
850 if (rc < 0) msg += dwfl_errmsg (rc);
851 else if (rc > 0) msg += strerror (rc);
bd2b1e68 852 if (rc != 0)
b40af7ee
DS
853 {
854 if (extra_msg.length() > 0)
855 msg += "\n" + extra_msg;
856 throw semantic_error (msg);
857 }
bd2b1e68
GH
858 }
859
7e1279ea
FCE
860 void dwarf_assert(string desc, int rc) // NB: "rc == 0" means OK in this case
861 {
862 string msg = "libdw failure (" + desc + "): ";
863 if (rc < 0) msg += dwarf_errmsg (rc);
864 else if (rc > 0) msg += strerror (rc);
865 if (rc != 0)
866 throw semantic_error (msg);
867 }
868
50e0d793 869
5227f1ea 870 dwflpp(systemtap_session & sess)
bd2b1e68 871 :
5227f1ea 872 sess(sess),
bd2b1e68
GH
873 dwfl(NULL),
874 module(NULL),
875 module_dwarf(NULL),
876 module_bias(0),
50e0d793
GH
877 module_start(0),
878 module_end(0),
bd2b1e68
GH
879 cu(NULL),
880 function(NULL)
881 {}
7a053d3b 882
50e0d793 883
bd2b1e68
GH
884 void setup(bool kernel)
885 {
b5d77020 886 // XXX: this is where the session -R parameter could come in
c72dc86c
JS
887 static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug";
888 static char *debuginfo_path = debuginfo_path_arr;
b5d77020 889
bd2b1e68
GH
890 static const Dwfl_Callbacks proc_callbacks =
891 {
892 dwfl_linux_proc_find_elf,
893 dwfl_standard_find_debuginfo,
894 NULL,
b5d77020 895 & debuginfo_path
bd2b1e68 896 };
7a053d3b 897
bd2b1e68
GH
898 static const Dwfl_Callbacks kernel_callbacks =
899 {
900 dwfl_linux_kernel_find_elf,
901 dwfl_standard_find_debuginfo,
902 dwfl_linux_kernel_module_section_address,
b5d77020 903 & debuginfo_path
bd2b1e68
GH
904 };
905
906 if (kernel)
907 {
7e1279ea 908 dwfl = dwfl_begin (&kernel_callbacks);
bd2b1e68 909 if (!dwfl)
7e1279ea
FCE
910 throw semantic_error ("cannot open dwfl");
911 dwfl_report_begin (dwfl);
d8067b24
FCE
912 // XXX: if we have only kernel.* probe points, we shouldn't waste time
913 // looking for module debug-info (and vice versa).
20e4a32c 914 dwfl_assert ("dwfl_linux_kernel_report_kernel",
b40af7ee
DS
915 dwfl_linux_kernel_report_kernel (dwfl),
916 "Ensure kernel debuginfo is installed");
20e4a32c 917 dwfl_assert ("dwfl_linux_kernel_report_modules",
b40af7ee
DS
918 dwfl_linux_kernel_report_modules (dwfl),
919 "Ensure kernel debuginfo is installed");
bd2b1e68
GH
920 }
921 else
922 {
7e1279ea
FCE
923 dwfl = dwfl_begin (&proc_callbacks);
924 dwfl_report_begin (dwfl);
bd2b1e68 925 if (!dwfl)
7e1279ea 926 throw semantic_error ("cannot open dwfl");
bd2b1e68
GH
927 // XXX: Find pids or processes, do userspace stuff.
928 }
929
7e1279ea 930 dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL));
bd2b1e68
GH
931 }
932
933 void iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
934 const char *, Dwarf_Addr,
77de5e9e 935 void *),
bd2b1e68
GH
936 void * data)
937 {
bd2b1e68
GH
938 ptrdiff_t off = 0;
939 do
940 {
77de5e9e 941 off = dwfl_getmodules (dwfl, callback, data, off);
bd2b1e68
GH
942 }
943 while (off > 0);
7e1279ea 944 dwfl_assert("dwfl_getmodules", off);
bd2b1e68
GH
945 }
946
7e1279ea 947
7a053d3b 948 void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
bd2b1e68
GH
949 void * data)
950 {
0ce64fb8 951 get_module_dwarf(false);
5227f1ea 952
bd2b1e68 953 if (!module_dwarf)
0ce64fb8 954 return;
bd2b1e68 955
c8959a29
GH
956 for (set<Dwarf_Die>::const_iterator i = pattern_limited_cus.begin();
957 i != pattern_limited_cus.end(); ++i)
7a053d3b 958 {
c8959a29
GH
959 Dwarf_Die die = *i;
960 if (callback (&die, data) != DWARF_CB_OK)
bd2b1e68 961 break;
bd2b1e68
GH
962 }
963 }
964
bd2b1e68 965
7e1279ea 966 bool func_is_inline()
bd2b1e68 967 {
7e1279ea
FCE
968 assert (function);
969 return dwarf_func_inline (function) != 0;
bd2b1e68
GH
970 }
971
7e1279ea
FCE
972 void iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg),
973 void * data)
bd2b1e68 974 {
7e1279ea
FCE
975 assert (function);
976 assert (func_is_inline ());
20e4a32c 977 dwarf_assert ("dwarf_func_inline_instances",
7e1279ea 978 dwarf_func_inline_instances (function, callback, data));
4fa7b22b 979 }
bd2b1e68 980
50e0d793 981
20e4a32c 982 void iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg),
7e1279ea 983 void * data)
4fa7b22b 984 {
7e1279ea
FCE
985 assert (module);
986 assert (cu);
c8959a29
GH
987 multimap<Dwarf_Die, Dwarf_Die>::const_iterator i = pattern_limited_funcs.lower_bound(*cu);
988 while (i != pattern_limited_funcs.end() && (i->first == *cu))
989 {
990 Dwarf_Die func_die = i->second;
991 if (callback (&func_die, data) != DWARF_CB_OK)
992 break;
993
994 ++i;
995 }
7e1279ea 996 }
c239d28c 997
d9b516ca 998
897820ca
GH
999 bool has_single_line_record (char const * srcfile, int lineno)
1000 {
1001 if (lineno < 0)
1002 return false;
1003
1004 Dwarf_Line **srcsp = NULL;
1005 size_t nsrcs = 0;
1006
1007 dwarf_assert ("dwarf_getsrc_file",
20e4a32c 1008 dwarf_getsrc_file (module_dwarf,
897820ca
GH
1009 srcfile, lineno, 0,
1010 &srcsp, &nsrcs));
20e4a32c 1011
897820ca
GH
1012 return nsrcs == 1;
1013 }
1014
7e1279ea 1015 void iterate_over_srcfile_lines (char const * srcfile,
20e4a32c 1016 int lineno,
897820ca 1017 bool need_single_match,
20e4a32c 1018 void (* callback) (Dwarf_Line * line, void * arg),
7e1279ea
FCE
1019 void *data)
1020 {
6315bd76
GH
1021 Dwarf_Line **srcsp = NULL;
1022 size_t nsrcs = 0;
bb788f9f 1023
7e1279ea 1024 get_module_dwarf();
bb788f9f 1025
7e1279ea 1026 dwarf_assert ("dwarf_getsrc_file",
20e4a32c 1027 dwarf_getsrc_file (module_dwarf,
7e1279ea
FCE
1028 srcfile, lineno, 0,
1029 &srcsp, &nsrcs));
20e4a32c 1030
114ffac2 1031 if (need_single_match && nsrcs > 1)
897820ca
GH
1032 {
1033 // We wanted a single line record (a unique address for the
1034 // line) and we got a bunch of line records. We're going to
1035 // skip this probe (throw an exception) but before we throw
1036 // we're going to look around a bit to see if there's a low or
1037 // high line number nearby which *doesn't* have this problem,
1038 // so we can give the user some advice.
1039
1040 int lo_try = -1;
1041 int hi_try = -1;
114ffac2 1042 for (size_t i = 1; i < 6; ++i)
897820ca
GH
1043 {
1044 if (lo_try == -1 && has_single_line_record(srcfile, lineno - i))
1045 lo_try = lineno - i;
1046
1047 if (hi_try == -1 && has_single_line_record(srcfile, lineno + i))
1048 hi_try = lineno + i;
1049 }
1050
1051 string advice = "";
1052 if (lo_try > 0 || hi_try > 0)
20e4a32c
RM
1053 advice = " (try "
1054 + (lo_try > 0
897820ca
GH
1055 ? (string(srcfile) + ":" + lex_cast<string>(lo_try))
1056 : string(""))
1057 + (lo_try > 0 && hi_try > 0 ? " or " : "")
20e4a32c 1058 + (hi_try > 0
897820ca
GH
1059 ? (string(srcfile) + ":"+ lex_cast<string>(hi_try))
1060 : string(""))
1061 + ")";
1062
20e4a32c
RM
1063 throw semantic_error("multiple addresses for "
1064 + string(srcfile)
897820ca
GH
1065 + ":"
1066 + lex_cast<string>(lineno)
1067 + advice);
1068 }
1069
20e4a32c 1070 try
bb788f9f 1071 {
6315bd76
GH
1072 for (size_t i = 0; i < nsrcs; ++i)
1073 {
1074 callback (srcsp[i], data);
1075 }
bb788f9f 1076 }
6315bd76
GH
1077 catch (...)
1078 {
1079 free (srcsp);
1080 throw;
20e4a32c 1081 }
6315bd76 1082 free (srcsp);
50e0d793
GH
1083 }
1084
1085
7e1279ea
FCE
1086 void collect_srcfiles_matching (string const & pattern,
1087 set<char const *> & filtered_srcfiles)
50e0d793 1088 {
7e1279ea
FCE
1089 assert (module);
1090 assert (cu);
bb788f9f 1091
7e1279ea
FCE
1092 size_t nfiles;
1093 Dwarf_Files *srcfiles;
bb788f9f 1094
20e4a32c 1095 dwarf_assert ("dwarf_getsrcfiles",
7e1279ea
FCE
1096 dwarf_getsrcfiles (cu, &srcfiles, &nfiles));
1097 {
1098 for (size_t i = 0; i < nfiles; ++i)
50e0d793 1099 {
7e1279ea
FCE
1100 char const * fname = dwarf_filesrc (srcfiles, i, NULL, NULL);
1101 if (fnmatch (pattern.c_str(), fname, 0) == 0)
50e0d793 1102 {
7e1279ea 1103 filtered_srcfiles.insert (fname);
b0ee93c4 1104 if (sess.verbose>2)
db22e55f 1105 clog << "selected source file '" << fname << "'\n";
50e0d793
GH
1106 }
1107 }
7e1279ea 1108 }
20e4a32c 1109 }
50e0d793 1110
7e1279ea 1111 void resolve_prologue_endings (map<Dwarf_Addr, func_info> & funcs)
7d71e1d5
FCE
1112 {
1113 // This heuristic attempts to pick the first address that has a
34ca7d84
FCE
1114 // source line distinct from the function declaration's. In a
1115 // perfect world, this would be the first statement *past* the
1116 // prologue.
1117
7d71e1d5
FCE
1118 assert(module);
1119 assert(cu);
1120
456aa31c
FCE
1121 size_t nlines = 0;
1122 Dwarf_Lines *lines = NULL;
7d71e1d5 1123
dc223023
FCE
1124 /* trouble cases:
1125 malloc do_symlink in init/initramfs.c tail-recursive/tiny then no-prologue
1126 sys_get?id in kernel/timer.c no-prologue
1127 sys_exit_group tail-recursive
1128 {do_,}sys_open extra-long-prologue (gcc 3.4)
1129 cpu_to_logical_apicid NULL-decl_file
1130 */
1131
1132 // Fetch all srcline records, sorted by address.
20e4a32c
RM
1133 dwarf_assert ("dwarf_getsrclines",
1134 dwarf_getsrclines(cu, &lines, &nlines));
dc223023 1135 // XXX: free lines[] later, but how?
7d71e1d5 1136
dc223023 1137 for(map<Dwarf_Addr,func_info>::iterator it = funcs.begin(); it != funcs.end(); it++)
7d71e1d5 1138 {
dc223023
FCE
1139#if 0 /* someday */
1140 Dwarf_Addr* bkpts = 0;
1141 int n = dwarf_entry_breakpoints (& it->second.die, & bkpts);
1142 // ...
1143 free (bkpts);
1144#endif
20e4a32c 1145
dc223023
FCE
1146 Dwarf_Addr entrypc = it->first;
1147 Dwarf_Addr highpc; // NB: highpc is exclusive: [entrypc,highpc)
1148 func_info* func = &it->second;
e38d6504 1149 dwfl_assert ("dwarf_highpc", dwarf_highpc (& func->die,
dc223023
FCE
1150 & highpc));
1151
1152 if (func->decl_file == 0) func->decl_file = "";
e38d6504 1153
dc223023
FCE
1154 unsigned entrypc_srcline_idx = 0;
1155 Dwarf_Line* entrypc_srcline = 0;
1156 // open-code binary search for exact match
1157 {
1158 unsigned l = 0, h = nlines;
1159 while (l < h)
1160 {
1161 entrypc_srcline_idx = (l + h) / 2;
1162 Dwarf_Addr addr;
1163 Dwarf_Line *lr = dwarf_onesrcline(lines, entrypc_srcline_idx);
1164 dwarf_lineaddr (lr, &addr);
1165 if (addr == entrypc) { entrypc_srcline = lr; break; }
1166 else if (l + 1 == h) { break; } // ran off bottom of tree
1167 else if (addr < entrypc) { l = entrypc_srcline_idx; }
1168 else { h = entrypc_srcline_idx; }
e38d6504 1169 }
dc223023 1170 }
e38d6504
RM
1171 if (entrypc_srcline == 0)
1172 throw semantic_error ("missing entrypc dwarf line record for function '"
dc223023
FCE
1173 + func->name + "'");
1174
1175 if (sess.verbose>2)
1176 clog << "prologue searching function '" << func->name << "'"
5fe3e97f 1177 << " 0x" << hex << entrypc << "-0x" << highpc << dec
dc223023
FCE
1178 << "@" << func->decl_file << ":" << func->decl_line
1179 << "\n";
1180
1181 // Now we go searching for the first line record that has a
1182 // file/line different from the one in the declaration.
1183 // Normally, this will be the next one. BUT:
1184 //
1185 // We may have to skip a few because some old compilers plop
1186 // in dummy line records for longer prologues. If we go too
1187 // far (addr >= highpc), we take the previous one. Or, it may
1188 // be the first one, if the function had no prologue, and thus
1189 // the entrypc maps to a statement in the body rather than the
1190 // declaration.
1191
1192 unsigned postprologue_srcline_idx = entrypc_srcline_idx;
1193 bool ranoff_end = false;
35f5f091 1194 while (postprologue_srcline_idx < nlines)
7d71e1d5 1195 {
dc223023
FCE
1196 Dwarf_Addr postprologue_addr;
1197 Dwarf_Line *lr = dwarf_onesrcline(lines, postprologue_srcline_idx);
1198 dwarf_lineaddr (lr, &postprologue_addr);
1199 const char* postprologue_file = dwarf_linesrc (lr, NULL, NULL);
1200 int postprologue_lineno;
7d71e1d5 1201 dwfl_assert ("dwarf_lineno",
dc223023 1202 dwarf_lineno (lr, & postprologue_lineno));
456aa31c 1203
b0ee93c4 1204 if (sess.verbose>2)
dc223023
FCE
1205 clog << "checking line record 0x" << hex << postprologue_addr << dec
1206 << "@" << postprologue_file << ":" << postprologue_lineno << "\n";
1207
1208 if (postprologue_addr >= highpc)
e38d6504
RM
1209 {
1210 ranoff_end = true;
1211 postprologue_srcline_idx --;
dc223023
FCE
1212 continue;
1213 }
1214 if (ranoff_end ||
1215 (strcmp (postprologue_file, func->decl_file) || // We have a winner!
1216 (postprologue_lineno != func->decl_line)))
1217 {
1218 func->prologue_end = postprologue_addr;
1219
1220 if (sess.verbose>2)
1221 {
1222 clog << "prologue found function '" << func->name << "'";
1223 // Add a little classification datum
1224 if (postprologue_srcline_idx == entrypc_srcline_idx) clog << " (naked)";
1225 if (ranoff_end) clog << " (tail-call?)";
1226 clog << " = 0x" << hex << postprologue_addr << dec << "\n";
1227 }
1228
1229 break;
1230 }
e38d6504 1231
dc223023
FCE
1232 // Let's try the next srcline.
1233 postprologue_srcline_idx ++;
1234 } // loop over srclines
7d71e1d5 1235
dc223023
FCE
1236 // if (strlen(func->decl_file) == 0) func->decl_file = NULL;
1237
1238 } // loop over functions
bd2b1e68
GH
1239 }
1240
7e1279ea
FCE
1241
1242 bool function_entrypc (Dwarf_Addr * addr)
1243 {
1244 assert (function);
20e4a32c 1245 return (dwarf_entrypc (function, addr) == 0);
7e1279ea
FCE
1246 }
1247
1248
1249 bool die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr)
1250 {
1251 Dwarf_Attribute attr_mem;
1252 Dwarf_Attribute *attr = dwarf_attr (die, DW_AT_entry_pc, &attr_mem);
1253 if (attr != NULL)
1254 return (dwarf_formaddr (attr, addr) == 0);
1255
1256 return ( dwarf_lowpc (die, addr) == 0);
1257 }
1258
4cd232e4
GH
1259 void function_die (Dwarf_Die *d)
1260 {
1261 assert (function);
20e4a32c 1262 *d = *function;
4cd232e4 1263 }
7e1279ea 1264
4cd232e4 1265 void function_file (char const ** c)
7e1279ea
FCE
1266 {
1267 assert (function);
4cd232e4 1268 assert (c);
20e4a32c 1269 *c = dwarf_decl_file (function);
7e1279ea
FCE
1270 }
1271
4cd232e4 1272 void function_line (int *linep)
7e1279ea
FCE
1273 {
1274 assert (function);
20e4a32c 1275 dwarf_decl_line (function, linep);
7e1279ea
FCE
1276 }
1277
1278 bool die_has_pc (Dwarf_Die * die, Dwarf_Addr pc)
1279 {
1280 int res = dwarf_haspc (die, pc);
1281 if (res == -1)
1282 dwarf_assert ("dwarf_haspc", res);
1283 return res == 1;
1284 }
1285
1286
e36387d7
RM
1287 static void loc2c_error (void *arg, const char *fmt, ...)
1288 {
1289 char *msg = NULL;
1290 va_list ap;
1291 va_start (ap, fmt);
1292 vasprintf (&msg, fmt, ap);
1293 va_end (ap);
1294 throw semantic_error (msg);
1295 }
bd2b1e68 1296
e38d6504
RM
1297 void emit_address (struct obstack *pool, Dwarf_Addr address)
1298 {
1299 // For now what we actually use is just a hard-wired constant.
1300 obstack_printf (pool, "%#" PRIx64 "UL", address);
1301
1302 // Turn this address into a section-relative offset if it should be one.
1303 // We emit a comment approximating the variable+offset expression that
1304 // relocatable module probing code will need to have.
1305 Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
1306 dwfl_assert ("dwfl_addrmodule", mod == NULL);
1307 int n = dwfl_module_relocations (mod);
1308 dwfl_assert ("dwfl_module_relocations", n < 0);
1309 if (n > 0)
1310 {
1311 int i = dwfl_module_relocate_address (mod, &address);
1312 dwfl_assert ("dwfl_module_relocate_address", i < 0);
1313 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
1314 NULL, NULL, NULL, NULL);
1315 dwfl_assert ("dwfl_module_info", modname == NULL);
1316 const char *secname = dwfl_module_relocation_info (mod, i, NULL);
1317 dwfl_assert ("dwfl_module_relocation_info", secname == NULL);
1318 if (n > 1 || secname[0] != '\0')
1319 // This gives us the module name, and section name within the
1320 // module, for a kernel module (or other ET_REL module object).
1321 obstack_printf (pool, " /* %s(%s)+%#" PRIx64 " */",
1322 modname, secname, address);
1323 else
1324 // This would happen for a Dwfl_Module that's a user-level DSO.
1325 obstack_printf (pool, " /* %s+%#" PRIx64 " */",
1326 modname, address);
1327 }
1328 }
7e1279ea 1329
4b1ad75e
RM
1330 static void loc2c_emit_address (void *arg, struct obstack *pool,
1331 Dwarf_Addr address)
1332 {
1333 dwflpp *dwfl = (dwflpp *) arg;
e38d6504 1334 dwfl->emit_address (pool, address);
4b1ad75e
RM
1335 }
1336
e57b735a
GH
1337 Dwarf_Attribute *
1338 find_variable_and_frame_base (Dwarf_Die *scope_die,
20e4a32c 1339 Dwarf_Addr pc,
91eefb1c 1340 string const & local,
e57b735a
GH
1341 Dwarf_Die *vardie,
1342 Dwarf_Attribute *fb_attr_mem)
77de5e9e 1343 {
77de5e9e 1344 Dwarf_Die *scopes;
bcc12710 1345 int nscopes = 0;
e57b735a
GH
1346 Dwarf_Attribute *fb_attr = NULL;
1347
1348 assert (cu);
bcc12710
FCE
1349
1350 if (scope_die)
1351 nscopes = dwarf_getscopes_die (scope_die, &scopes);
1352 else
1353 nscopes = dwarf_getscopes (cu, pc, &scopes);
77de5e9e 1354
77de5e9e
GH
1355 if (nscopes == 0)
1356 {
7a053d3b 1357 throw semantic_error ("unable to find any scopes containing "
59ff2773 1358 + lex_cast_hex<string>(pc)
77de5e9e
GH
1359 + " while searching for local '" + local + "'");
1360 }
7a053d3b 1361
77de5e9e 1362 int declaring_scope = dwarf_getscopevar (scopes, nscopes,
7a053d3b
RM
1363 local.c_str(),
1364 0, NULL, 0, 0,
e57b735a 1365 vardie);
77de5e9e
GH
1366 if (declaring_scope < 0)
1367 {
1368 throw semantic_error ("unable to find local '" + local + "'"
59ff2773 1369 + " near pc " + lex_cast_hex<string>(pc));
77de5e9e 1370 }
7a053d3b 1371
77de5e9e
GH
1372 for (int inner = 0; inner < nscopes; ++inner)
1373 {
1374 switch (dwarf_tag (&scopes[inner]))
1375 {
1376 default:
1377 continue;
1378 case DW_TAG_subprogram:
1379 case DW_TAG_entry_point:
1380 case DW_TAG_inlined_subroutine: /* XXX */
1381 if (inner >= declaring_scope)
1382 fb_attr = dwarf_attr_integrate (&scopes[inner],
1383 DW_AT_frame_base,
e57b735a 1384 fb_attr_mem);
77de5e9e
GH
1385 break;
1386 }
1387 }
e57b735a
GH
1388 return fb_attr;
1389 }
77de5e9e 1390
77de5e9e 1391
d1531387
RM
1392 struct location *
1393 translate_location(struct obstack *pool,
1394 Dwarf_Attribute *attr, Dwarf_Addr pc,
1395 Dwarf_Attribute *fb_attr,
1396 struct location **tail)
1397 {
1398 Dwarf_Op *expr;
1399 size_t len;
1400
1401 switch (dwarf_getlocation_addr (attr, pc - module_bias, &expr, &len, 1))
1402 {
1403 case 1: /* Should always happen. */
1404 if (len > 0)
1405 break;
1406 /* Fall through. */
1407
1408 case 0: /* Shouldn't happen. */
1409 throw semantic_error ("not accessible at this address");
1410
1411 default: /* Shouldn't happen. */
1412 case -1:
1413 throw semantic_error (string ("dwarf_getlocation_addr failed") +
1414 string (dwarf_errmsg (-1)));
1415 }
1416
1417 return c_translate_location (pool, &loc2c_error, this,
1418 &loc2c_emit_address,
1419 1, module_bias,
1420 pc, expr, len, tail, fb_attr);
1421 }
1422
e57b735a
GH
1423 Dwarf_Die *
1424 translate_components(struct obstack *pool,
20e4a32c
RM
1425 struct location **tail,
1426 Dwarf_Addr pc,
e57b735a
GH
1427 vector<pair<target_symbol::component_type,
1428 std::string> > const & components,
1429 Dwarf_Die *vardie,
1430 Dwarf_Die *die_mem,
1431 Dwarf_Attribute *attr_mem)
1432 {
1433 Dwarf_Die *die = vardie;
d9b516ca
RM
1434 unsigned i = 0;
1435 while (i < components.size())
1436 {
e57b735a 1437 die = dwarf_formref_die (attr_mem, die_mem);
d9b516ca
RM
1438 const int typetag = dwarf_tag (die);
1439 switch (typetag)
1440 {
1441 case DW_TAG_typedef:
fdfbe4f7
GH
1442 case DW_TAG_const_type:
1443 case DW_TAG_volatile_type:
d9b516ca
RM
1444 /* Just iterate on the referent type. */
1445 break;
91eefb1c 1446
d9b516ca
RM
1447 case DW_TAG_pointer_type:
1448 if (components[i].first == target_symbol::comp_literal_array_index)
1449 goto subscript;
91eefb1c 1450
e57b735a 1451 c_translate_pointer (pool, 1, module_bias, die, tail);
d9b516ca 1452 break;
91eefb1c 1453
d9b516ca
RM
1454 case DW_TAG_array_type:
1455 if (components[i].first == target_symbol::comp_literal_array_index)
1456 {
1457 subscript:
e57b735a 1458 c_translate_array (pool, 1, module_bias, die, tail,
d9b516ca
RM
1459 NULL, lex_cast<Dwarf_Word>(components[i].second));
1460 ++i;
1461 }
1462 else
1463 throw semantic_error("bad field '"
1464 + components[i].second
1465 + "' for array type");
1466 break;
91eefb1c 1467
d9b516ca
RM
1468 case DW_TAG_structure_type:
1469 case DW_TAG_union_type:
e57b735a 1470 switch (dwarf_child (die, die_mem))
d9b516ca
RM
1471 {
1472 case 1: /* No children. */
1473 throw semantic_error ("empty struct "
1474 + string (dwarf_diename_integrate (die) ?: "<anonymous>"));
1475 break;
1476 case -1: /* Error. */
1477 default: /* Shouldn't happen */
1478 throw semantic_error (string (typetag == DW_TAG_union_type ? "union" : "struct")
1479 + string (dwarf_diename_integrate (die) ?: "<anonymous>")
1480 + string (dwarf_errmsg (-1)));
1481 break;
1482
1483 case 0:
1484 break;
1485 }
1486
1487 while (dwarf_tag (die) != DW_TAG_member
1488 || ({ const char *member = dwarf_diename_integrate (die);
1489 member == NULL || string(member) != components[i].second; }))
e57b735a 1490 if (dwarf_siblingof (die, die_mem) != 0)
d9b516ca
RM
1491 throw semantic_error ("field name " + components[i].second + " not found");
1492
1493 if (dwarf_attr_integrate (die, DW_AT_data_member_location,
e57b735a 1494 attr_mem) == NULL)
d9b516ca
RM
1495 {
1496 /* Union members don't usually have a location,
1497 but just use the containing union's location. */
1498 if (typetag != DW_TAG_union_type)
1499 throw semantic_error ("no location for field "
1500 + components[i].second
1501 + " :" + string(dwarf_errmsg (-1)));
1502 }
1503 else
d1531387 1504 translate_location (pool, attr_mem, pc, NULL, tail);
d9b516ca
RM
1505 ++i;
1506 break;
1507
1508 case DW_TAG_base_type:
1509 throw semantic_error ("field "
1510 + components[i].second
1511 + " vs base type "
1512 + string(dwarf_diename_integrate (die) ?: "<anonymous type>"));
1513 break;
1514 case -1:
1515 throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)));
1516 break;
1517
1518 default:
1519 throw semantic_error (string(dwarf_diename_integrate (die) ?: "<anonymous type>")
1520 + ": unexpected type tag "
1521 + lex_cast<string>(dwarf_tag (die)));
1522 break;
1523 }
1524
1525 /* Now iterate on the type in DIE's attribute. */
e57b735a 1526 if (dwarf_attr_integrate (die, DW_AT_type, attr_mem) == NULL)
d9b516ca
RM
1527 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
1528 }
e57b735a
GH
1529 return die;
1530 }
91eefb1c 1531
d9b516ca 1532
e57b735a
GH
1533 Dwarf_Die *
1534 resolve_unqualified_inner_typedie (Dwarf_Die *typedie_mem,
1535 Dwarf_Attribute *attr_mem)
1536 {
1537 ;
d9b516ca 1538 Dwarf_Die *typedie;
e57b735a 1539 int typetag = 0;
d9b516ca 1540 while (1)
20e4a32c 1541 {
e57b735a 1542 typedie = dwarf_formref_die (attr_mem, typedie_mem);
d9b516ca 1543 if (typedie == NULL)
e57b735a 1544 throw semantic_error ("cannot get type: " + string(dwarf_errmsg (-1)));
d9b516ca 1545 typetag = dwarf_tag (typedie);
20e4a32c 1546 if (typetag != DW_TAG_typedef &&
fdfbe4f7
GH
1547 typetag != DW_TAG_const_type &&
1548 typetag != DW_TAG_volatile_type)
91eefb1c 1549 break;
e57b735a
GH
1550 if (dwarf_attr_integrate (typedie, DW_AT_type, attr_mem) == NULL)
1551 throw semantic_error ("cannot get type of pointee: " + string(dwarf_errmsg (-1)));
d9b516ca 1552 }
e57b735a
GH
1553 return typedie;
1554 }
91eefb1c 1555
91eefb1c 1556
20e4a32c 1557 void
e57b735a
GH
1558 translate_final_fetch_or_store (struct obstack *pool,
1559 struct location **tail,
1560 Dwarf_Addr module_bias,
1561 Dwarf_Die *die,
1562 Dwarf_Attribute *attr_mem,
1563 bool lvalue,
1564 string & prelude,
1565 string & postlude,
1566 exp_type & ty)
1567 {
1568 /* First boil away any qualifiers associated with the type DIE of
1569 the final location to be accessed. */
fdfbe4f7 1570
e57b735a
GH
1571 Dwarf_Die typedie_mem;
1572 Dwarf_Die *typedie;
1573 int typetag;
1574
1575 typedie = resolve_unqualified_inner_typedie (&typedie_mem, attr_mem);
1576 typetag = dwarf_tag (typedie);
1577
1578 /* Then switch behavior depending on the type of fetch/store we
1579 want, and the type and pointer-ness of the final location. */
20e4a32c 1580
fdfbe4f7
GH
1581 switch (typetag)
1582 {
fdfbe4f7 1583 default:
66d284f4
FCE
1584 throw semantic_error ("unsupported type tag "
1585 + lex_cast<string>(typetag));
fdfbe4f7 1586 break;
66d284f4 1587
e7a012f0 1588 case DW_TAG_enumeration_type:
fdfbe4f7
GH
1589 case DW_TAG_base_type:
1590 ty = pe_long;
e57b735a
GH
1591 if (lvalue)
1592 c_translate_store (pool, 1, module_bias, die, typedie, tail,
1593 "THIS->value");
20e4a32c 1594 else
e57b735a
GH
1595 c_translate_fetch (pool, 1, module_bias, die, typedie, tail,
1596 "THIS->__retvalue");
fdfbe4f7
GH
1597 break;
1598
1599 case DW_TAG_array_type:
1600 case DW_TAG_pointer_type:
e57b735a
GH
1601
1602 if (lvalue)
1603 throw semantic_error ("cannot store into target pointer value");
1604
fdfbe4f7
GH
1605 {
1606 Dwarf_Die pointee_typedie_mem;
1607 Dwarf_Die *pointee_typedie;
1608 Dwarf_Word pointee_encoding;
246b383e 1609 Dwarf_Word pointee_byte_size = 0;
fdfbe4f7 1610
e57b735a
GH
1611 pointee_typedie = resolve_unqualified_inner_typedie (&pointee_typedie_mem, attr_mem);
1612
1613 if (dwarf_attr_integrate (pointee_typedie, DW_AT_byte_size, attr_mem))
1614 dwarf_formudata (attr_mem, &pointee_byte_size);
20e4a32c
RM
1615
1616 dwarf_formudata (dwarf_attr_integrate (pointee_typedie, DW_AT_encoding, attr_mem),
fdfbe4f7
GH
1617 &pointee_encoding);
1618
f9eba66e
FCE
1619 // We have the pointer: cast it to an integral type via &(*(...))
1620
1621 // NB: per bug #1187, at one point char*-like types were
1622 // automagically converted here to systemtap string values.
1623 // For several reasons, this was taken back out, leaving
1624 // pointer-to-string "conversion" (copying) to tapset functions.
1625
1626 ty = pe_long;
1627 if (typetag == DW_TAG_array_type)
e57b735a 1628 c_translate_array (pool, 1, module_bias, typedie, tail, NULL, 0);
fdfbe4f7 1629 else
e57b735a 1630 c_translate_pointer (pool, 1, module_bias, typedie, tail);
20e4a32c 1631 c_translate_addressof (pool, 1, module_bias, NULL, pointee_typedie, tail,
f9eba66e 1632 "THIS->__retvalue");
fdfbe4f7 1633 }
20e4a32c 1634 break;
fdfbe4f7 1635 }
20e4a32c 1636 }
e57b735a 1637
e19fda4e
DS
1638 string
1639 express_as_string (string prelude,
1640 string postlude,
1641 struct location *head)
1642 {
1643 size_t bufsz = 1024;
1644 char *buf = static_cast<char*>(malloc(bufsz));
1645 assert(buf);
1646
1647 FILE *memstream = open_memstream (&buf, &bufsz);
1648 assert(memstream);
1649
1650 fprintf(memstream, "{\n");
1651 fprintf(memstream, prelude.c_str());
1652 bool deref = c_emit_location (memstream, head, 1);
1653 fprintf(memstream, postlude.c_str());
1654 fprintf(memstream, " goto out;\n");
1655
1656 // dummy use of deref_fault label, to disable warning if deref() not used
1657 fprintf(memstream, "if (0) goto deref_fault;\n");
1658
1659 // XXX: deref flag not reliable; emit fault label unconditionally
1660 // XXX: print the faulting address, like the user_string/kernel_string
1661 // tapset functions do
1662 if (deref) ;
1663 fprintf(memstream,
1664 "deref_fault:\n"
1665 " c->last_error = \"pointer dereference fault\";\n"
1666 " goto out;\n");
1667 fprintf(memstream, "}\n");
1668
1669 fclose (memstream);
1670 string result(buf);
1671 free (buf);
1672 return result;
1673 }
e57b735a 1674
20e4a32c 1675 string
e57b735a 1676 literal_stmt_for_local (Dwarf_Die *scope_die,
20e4a32c 1677 Dwarf_Addr pc,
e57b735a
GH
1678 string const & local,
1679 vector<pair<target_symbol::component_type,
1680 std::string> > const & components,
1681 bool lvalue,
1682 exp_type & ty)
1683 {
1684 Dwarf_Die vardie;
1685 Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
1686
20e4a32c 1687 fb_attr = find_variable_and_frame_base (scope_die, pc, local,
e57b735a
GH
1688 &vardie, &fb_attr_mem);
1689
b0ee93c4 1690 if (sess.verbose>2)
e57b735a
GH
1691 clog << "finding location for local '" << local
1692 << "' near address " << hex << pc
1693 << ", module bias " << module_bias << dec
db22e55f 1694 << "\n";
e57b735a
GH
1695
1696 Dwarf_Attribute attr_mem;
1697 if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
1698 {
1699 throw semantic_error("failed to retrieve location "
20e4a32c
RM
1700 "attribute for local '" + local
1701 + "' (dieoffset: "
1702 + lex_cast_hex<string>(dwarf_dieoffset (&vardie))
e57b735a
GH
1703 + ")");
1704 }
1705
1706#define obstack_chunk_alloc malloc
1707#define obstack_chunk_free free
1708
1709 struct obstack pool;
1710 obstack_init (&pool);
1711 struct location *tail = NULL;
1712
1713 /* Given $foo->bar->baz[NN], translate the location of foo. */
1714
d1531387
RM
1715 struct location *head = translate_location (&pool,
1716 &attr_mem, pc, fb_attr, &tail);
e57b735a
GH
1717
1718 if (dwarf_attr_integrate (&vardie, DW_AT_type, &attr_mem) == NULL)
1719 throw semantic_error("failed to retrieve type "
1720 "attribute for local '" + local + "'");
1721
1722
1723 /* Translate the ->bar->baz[NN] parts. */
1724
1725 Dwarf_Die die_mem, *die = NULL;
20e4a32c 1726 die = translate_components (&pool, &tail, pc, components,
e57b735a
GH
1727 &vardie, &die_mem, &attr_mem);
1728
20e4a32c
RM
1729 /* Translate the assignment part, either
1730 x = $foo->bar->baz[NN]
1731 or
e57b735a
GH
1732 $foo->bar->baz[NN] = x
1733 */
1734
1735 string prelude, postlude;
20e4a32c 1736 translate_final_fetch_or_store (&pool, &tail, module_bias,
e57b735a
GH
1737 die, &attr_mem, lvalue,
1738 prelude, postlude, ty);
1739
1740 /* Write the translation to a string. */
e19fda4e
DS
1741 return express_as_string(prelude, postlude, head);
1742 }
20e4a32c 1743
20e4a32c 1744
e19fda4e
DS
1745 string
1746 literal_stmt_for_return (Dwarf_Die *scope_die,
1747 Dwarf_Addr pc,
1748 vector<pair<target_symbol::component_type,
1749 std::string> > const & components,
1750 bool lvalue,
1751 exp_type & ty)
1752 {
1753 if (sess.verbose>2)
1754 clog << "literal_stmt_for_return: finding return value for "
1755 << dwarf_diename (scope_die)
1756 << "("
1757 << dwarf_diename (cu)
1758 << ")\n";
7a053d3b 1759
e19fda4e
DS
1760 struct obstack pool;
1761 obstack_init (&pool);
1762 struct location *tail = NULL;
7a053d3b 1763
e19fda4e
DS
1764 /* Given $return->bar->baz[NN], translate the location of return. */
1765 const Dwarf_Op *locops;
1766 int nlocops = dwfl_module_return_value_location (module, scope_die,
1767 &locops);
1768 if (nlocops < 0)
1769 {
1770 throw semantic_error("failed to retrieve return value location");
1771 }
1772 // the function has no return value (e.g. "void" in C)
1773 else if (nlocops == 0)
1774 {
1775 throw semantic_error("function has no return value");
1776 }
a781f401 1777
e19fda4e
DS
1778 struct location *head = c_translate_location (&pool, &loc2c_error, this,
1779 &loc2c_emit_address,
1780 1, module_bias,
1781 pc, locops, nlocops,
1782 &tail, NULL);
7a053d3b 1783
e19fda4e 1784 /* Translate the ->bar->baz[NN] parts. */
7a053d3b 1785
e19fda4e
DS
1786 Dwarf_Attribute attr_mem;
1787 Dwarf_Attribute *attr = dwarf_attr (scope_die, DW_AT_type, &attr_mem);
1788
1789 Dwarf_Die vardie_mem;
1790 Dwarf_Die *vardie = dwarf_formref_die (attr, &vardie_mem);
1791
1792 Dwarf_Die die_mem, *die = NULL;
1793 die = translate_components (&pool, &tail, pc, components,
1794 vardie, &die_mem, &attr_mem);
1795
1796 /* Translate the assignment part, either
1797 x = $return->bar->baz[NN]
1798 or
1799 $return->bar->baz[NN] = x
1800 */
1801
1802 string prelude, postlude;
1803 translate_final_fetch_or_store (&pool, &tail, module_bias,
1804 die, &attr_mem, lvalue,
1805 prelude, postlude, ty);
1806
1807 /* Write the translation to a string. */
1808 return express_as_string(prelude, postlude, head);
1809 }
7a053d3b 1810
77de5e9e 1811
bd2b1e68
GH
1812 ~dwflpp()
1813 {
1814 if (dwfl)
1815 dwfl_end(dwfl);
1816 }
1817};
1818
20c6c071 1819
7a053d3b 1820enum
bd2b1e68 1821function_spec_type
7a053d3b 1822 {
bd2b1e68
GH
1823 function_alone,
1824 function_and_file,
7a053d3b 1825 function_file_and_line
bd2b1e68
GH
1826 };
1827
ec4373ff 1828
bd2b1e68 1829struct dwarf_builder;
77de5e9e
GH
1830struct dwarf_query;
1831
2930abc7 1832
bd2b1e68 1833struct dwarf_derived_probe : public derived_probe
b55bc428 1834{
2930abc7
FCE
1835 dwarf_derived_probe (Dwarf_Die *scope_die,
1836 Dwarf_Addr addr,
1837 dwarf_query & q);
20e4a32c 1838
2930abc7
FCE
1839 vector<Dwarf_Addr> probe_points;
1840 bool has_return;
1841
dc38c0ae
DS
1842 void register_probe (systemtap_session& s);
1843
2930abc7 1844 void add_probe_point(string const & funcname,
4cd232e4
GH
1845 char const * filename,
1846 int line,
1847 Dwarf_Addr addr,
1848 dwarf_query & q);
d9b516ca 1849
bd2b1e68 1850 // Pattern registration helpers.
7a053d3b 1851 static void register_relative_variants(match_node * root,
bd2b1e68 1852 dwarf_builder * dw);
7a053d3b 1853 static void register_statement_variants(match_node * root,
bd2b1e68 1854 dwarf_builder * dw);
fd6602a0
FCE
1855 static void register_function_variants(match_node * root,
1856 dwarf_builder * dw);
54efe513
GH
1857 static void register_inline_variants(match_node * root,
1858 dwarf_builder * dw);
7a053d3b 1859 static void register_function_and_statement_variants(match_node * root,
bd2b1e68 1860 dwarf_builder * dw);
20c6c071 1861 static void register_patterns(match_node * root);
7a053d3b 1862
46b84a80
DS
1863 virtual void emit_registrations_start (translator_output* o, unsigned index);
1864 virtual void emit_registrations_end (translator_output * o, unsigned index);
35d4ab18
FCE
1865 virtual void emit_deregistrations (translator_output * o);
1866 virtual void emit_probe_entries (translator_output * o);
20c6c071
GH
1867};
1868
dc38c0ae
DS
1869
1870struct dwarf_derived_probe_group: public derived_probe_group
1871{
1872private:
1873 vector<dwarf_derived_probe*> probes;
1874
1875public:
1876 virtual void register_probe(dwarf_derived_probe* p) { probes.push_back (p); }
1877 virtual size_t size () { return probes.size (); }
1878
1879 virtual void emit_probes (translator_output* op, unparser* up);
46b84a80 1880 virtual void emit_module_init (translator_output* o);
dc38c0ae
DS
1881};
1882
1883
20c6c071 1884// Helper struct to thread through the dwfl callbacks.
7a053d3b 1885struct
20c6c071
GH
1886dwarf_query
1887{
5227f1ea
GH
1888 dwarf_query(systemtap_session & sess,
1889 probe * base_probe,
20c6c071
GH
1890 probe_point * base_loc,
1891 dwflpp & dw,
1892 map<string, literal *> const & params,
1893 vector<derived_probe *> & results);
bd2b1e68 1894
5227f1ea
GH
1895 systemtap_session & sess;
1896
bd2b1e68 1897 // Parameter extractors.
7a053d3b 1898 static bool has_null_param(map<string, literal *> const & params,
bd2b1e68 1899 string const & k);
7a053d3b 1900 static bool get_string_param(map<string, literal *> const & params,
bd2b1e68 1901 string const & k, string & v);
7a053d3b 1902 static bool get_number_param(map<string, literal *> const & params,
bd2b1e68 1903 string const & k, long & v);
c239d28c
GH
1904 static bool get_number_param(map<string, literal *> const & params,
1905 string const & k, Dwarf_Addr & v);
b55bc428 1906
77de5e9e
GH
1907 string pt_regs_member_for_regnum(uint8_t dwarf_regnum);
1908
2930abc7 1909 // Result vector and flavour-sorting mechanism.
20c6c071 1910 vector<derived_probe *> & results;
2930abc7
FCE
1911 bool probe_has_no_target_variables;
1912 map<string, dwarf_derived_probe *> probe_flavours;
1913 void add_probe_point(string const & funcname,
1914 char const * filename,
1915 int line,
1916 Dwarf_Die *scope_die,
1917 Dwarf_Addr addr);
20c6c071 1918
0daad364
JS
1919 set<string> blacklisted_probes;
1920 set<string> blacklisted_return_probes;
1921 void build_blacklist();
1922
36f9dd1d
FCE
1923 bool blacklisted_p(string const & funcname,
1924 char const * filename,
1925 int line,
1926 Dwarf_Die *scope_die,
1927 Dwarf_Addr addr);
1928
2930abc7 1929 // Extracted parameters.
20c6c071
GH
1930 bool has_kernel;
1931 bool has_process;
1932 bool has_module;
7a053d3b
RM
1933 string process_val;
1934 string module_val;
1935 string function_val;
20c6c071 1936
54efe513 1937 bool has_inline_str;
20c6c071
GH
1938 bool has_function_str;
1939 bool has_statement_str;
54efe513 1940 bool has_inline_num;
20c6c071
GH
1941 bool has_function_num;
1942 bool has_statement_num;
7a053d3b
RM
1943 string statement_str_val;
1944 string function_str_val;
54efe513 1945 string inline_str_val;
c239d28c
GH
1946 Dwarf_Addr statement_num_val;
1947 Dwarf_Addr function_num_val;
54efe513 1948 Dwarf_Addr inline_num_val;
20c6c071
GH
1949
1950 bool has_callees;
7a053d3b 1951 long callee_val;
20c6c071
GH
1952
1953 bool has_return;
1954
1955 bool has_label;
1956 string label_val;
1957
1958 bool has_relative;
1959 long relative_val;
1960
1961 function_spec_type parse_function_spec(string & spec);
1962 function_spec_type spec_type;
1963 string function;
1964 string file;
1965 int line;
1966
7e1279ea
FCE
1967 set<char const *> filtered_srcfiles;
1968
1969 // Map official entrypc -> func_info object
1970 map<Dwarf_Addr, inline_instance_info> filtered_inlines;
1971 map<Dwarf_Addr, func_info> filtered_functions;
1972 bool choose_next_line;
1973 Dwarf_Addr entrypc_for_next_line;
1974
20c6c071
GH
1975 probe * base_probe;
1976 probe_point * base_loc;
1977 dwflpp & dw;
b55bc428
FCE
1978};
1979
98afd80e
FCE
1980
1981struct dwarf_builder: public derived_probe_builder
b55bc428 1982{
e38d6504
RM
1983 dwflpp *kern_dw;
1984 dwflpp *user_dw;
1985 dwarf_builder()
1986 : kern_dw(NULL), user_dw(NULL)
c8959a29 1987 {}
e38d6504
RM
1988 ~dwarf_builder()
1989 {
1990 if (kern_dw)
c8959a29 1991 delete kern_dw;
e38d6504 1992 if (user_dw)
c8959a29
GH
1993 delete user_dw;
1994 }
5227f1ea 1995 virtual void build(systemtap_session & sess,
7a053d3b 1996 probe * base,
20c6c071
GH
1997 probe_point * location,
1998 std::map<std::string, literal *> const & parameters,
20c6c071 1999 vector<derived_probe *> & finished_results);
b55bc428
FCE
2000};
2001
7a053d3b
RM
2002bool
2003dwarf_query::has_null_param(map<string, literal *> const & params,
20c6c071 2004 string const & k)
bd2b1e68
GH
2005{
2006 map<string, literal *>::const_iterator i = params.find(k);
2007 if (i != params.end() && i->second == NULL)
2008 return true;
2009 return false;
2010}
2011
7a053d3b
RM
2012bool
2013dwarf_query::get_string_param(map<string, literal *> const & params,
20c6c071 2014 string const & k, string & v)
bd2b1e68 2015{
98afd80e 2016 return derived_probe_builder::get_param (params, k, v);
bd2b1e68
GH
2017}
2018
7a053d3b
RM
2019bool
2020dwarf_query::get_number_param(map<string, literal *> const & params,
20c6c071 2021 string const & k, long & v)
bd2b1e68 2022{
98afd80e
FCE
2023 int64_t value;
2024 bool present = derived_probe_builder::get_param (params, k, value);
2025 v = (long) value;
2026 return present;
bd2b1e68
GH
2027}
2028
c239d28c
GH
2029bool
2030dwarf_query::get_number_param(map<string, literal *> const & params,
2031 string const & k, Dwarf_Addr & v)
2032{
98afd80e
FCE
2033 int64_t value;
2034 bool present = derived_probe_builder::get_param (params, k, value);
2035 v = (Dwarf_Addr) value;
2036 return present;
c239d28c
GH
2037}
2038
77de5e9e 2039
5227f1ea
GH
2040dwarf_query::dwarf_query(systemtap_session & sess,
2041 probe * base_probe,
20c6c071
GH
2042 probe_point * base_loc,
2043 dwflpp & dw,
2044 map<string, literal *> const & params,
2045 vector<derived_probe *> & results)
5227f1ea
GH
2046 : sess(sess),
2047 results(results),
2930abc7 2048 probe_has_no_target_variables(false),
7a053d3b 2049 base_probe(base_probe),
20c6c071
GH
2050 base_loc(base_loc),
2051 dw(dw)
bd2b1e68 2052{
20c6c071 2053
bd2b1e68
GH
2054 // Reduce the query to more reasonable semantic values (booleans,
2055 // extracted strings, numbers, etc).
2056
2057 has_kernel = has_null_param(params, TOK_KERNEL);
2058 has_module = get_string_param(params, TOK_MODULE, module_val);
2059 has_process = get_string_param(params, TOK_PROCESS, process_val);
2060
2061 has_function_str = get_string_param(params, TOK_FUNCTION, function_str_val);
2062 has_function_num = get_number_param(params, TOK_FUNCTION, function_num_val);
2063
54efe513
GH
2064 has_inline_str = get_string_param(params, TOK_INLINE, inline_str_val);
2065 has_inline_num = get_number_param(params, TOK_INLINE, inline_num_val);
2066
bd2b1e68
GH
2067 has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val);
2068 has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val);
2069
2070 callee_val = 1;
7a053d3b 2071 has_callees = (has_null_param(params, TOK_CALLEES) ||
bd2b1e68
GH
2072 get_number_param(params, TOK_CALLEES, callee_val));
2073
2074 has_return = has_null_param(params, TOK_RETURN);
2075
2076 has_label = get_string_param(params, TOK_LABEL, label_val);
2077 has_relative = get_number_param(params, TOK_RELATIVE, relative_val);
7a053d3b 2078
bd2b1e68
GH
2079 if (has_function_str)
2080 spec_type = parse_function_spec(function_str_val);
54efe513
GH
2081 else if (has_inline_str)
2082 spec_type = parse_function_spec(inline_str_val);
bd2b1e68
GH
2083 else if (has_statement_str)
2084 spec_type = parse_function_spec(statement_str_val);
0daad364
JS
2085
2086 build_blacklist();
2087}
2088
2089
2090void
2091dwarf_query::build_blacklist()
2092{
2093 // FIXME: it would be nice if these blacklisted functions were pulled in
2094 // dynamically, instead of being statically defined here.
2095
2096 // Most of these are marked __kprobes in newer kernels. We list them here so
2097 // the translator can block them on older kernels that don't have the
2098 // __kprobes function decorator.
2099 blacklisted_probes.insert("default_do_nmi");
2100 blacklisted_probes.insert("__die");
2101 blacklisted_probes.insert("die_nmi");
2102 blacklisted_probes.insert("do_debug");
2103 blacklisted_probes.insert("do_general_protection");
2104 blacklisted_probes.insert("do_int3");
2105 blacklisted_probes.insert("do_IRQ");
2106 blacklisted_probes.insert("do_page_fault");
2107 blacklisted_probes.insert("do_sparc64_fault");
2108 blacklisted_probes.insert("do_trap");
2109 blacklisted_probes.insert("dummy_nmi_callback");
2110 blacklisted_probes.insert("flush_icache_range");
2111 blacklisted_probes.insert("ia64_bad_break");
2112 blacklisted_probes.insert("ia64_do_page_fault");
2113 blacklisted_probes.insert("ia64_fault");
2114 blacklisted_probes.insert("io_check_error");
2115 blacklisted_probes.insert("mem_parity_error");
2116 blacklisted_probes.insert("nmi_watchdog_tick");
2117 blacklisted_probes.insert("notifier_call_chain");
2118 blacklisted_probes.insert("oops_begin");
2119 blacklisted_probes.insert("oops_end");
2120 blacklisted_probes.insert("program_check_exception");
2121 blacklisted_probes.insert("single_step_exception");
2122 blacklisted_probes.insert("sync_regs");
2123 blacklisted_probes.insert("unhandled_fault");
2124 blacklisted_probes.insert("unknown_nmi_error");
2125
2126 // __switch_to is only disallowed on x86_64
2127 if (sess.architecture == "x86_64")
2128 blacklisted_probes.insert("__switch_to");
2129
2130 // These functions don't return, so return probes would never be recovered
2131 blacklisted_return_probes.insert("do_exit");
2132 blacklisted_return_probes.insert("sys_exit");
2133 blacklisted_return_probes.insert("sys_exit_group");
7a053d3b 2134}
bd2b1e68
GH
2135
2136
bd2b1e68 2137function_spec_type
20c6c071 2138dwarf_query::parse_function_spec(string & spec)
bd2b1e68
GH
2139{
2140 string::const_iterator i = spec.begin(), e = spec.end();
7a053d3b 2141
bd2b1e68
GH
2142 function.clear();
2143 file.clear();
2144 line = 0;
2145
2146 while (i != e && *i != '@')
2147 {
2148 if (*i == ':')
2149 goto bad;
2150 function += *i++;
2151 }
2152
2153 if (i == e)
2154 {
b0ee93c4 2155 if (sess.verbose>2)
7a053d3b
RM
2156 clog << "parsed '" << spec
2157 << "' -> func '" << function
db22e55f 2158 << "'\n";
bd2b1e68
GH
2159 return function_alone;
2160 }
2161
2162 if (i++ == e)
2163 goto bad;
2164
2165 while (i != e && *i != ':')
2166 file += *i++;
7a053d3b 2167
bd2b1e68
GH
2168 if (i == e)
2169 {
b0ee93c4 2170 if (sess.verbose>2)
7a053d3b
RM
2171 clog << "parsed '" << spec
2172 << "' -> func '"<< function
2173 << "', file '" << file
db22e55f 2174 << "'\n";
bd2b1e68
GH
2175 return function_and_file;
2176 }
2177
2178 if (i++ == e)
2179 goto bad;
2180
2181 try
2182 {
2183 line = lex_cast<int>(string(i, e));
b0ee93c4 2184 if (sess.verbose>2)
7a053d3b
RM
2185 clog << "parsed '" << spec
2186 << "' -> func '"<< function
2187 << "', file '" << file
db22e55f 2188 << "', line " << line << "\n";
bd2b1e68
GH
2189 return function_file_and_line;
2190 }
2191 catch (runtime_error & exn)
2192 {
2193 goto bad;
2194 }
2195
2196 bad:
7a053d3b 2197 throw semantic_error("malformed specification '" + spec + "'",
20c6c071 2198 base_probe->tok);
bd2b1e68
GH
2199}
2200
2201
7e1279ea 2202
2930abc7
FCE
2203// Our goal here is to calculate a "flavour", a string which
2204// characterizes the way in which this probe body depends on target
2205// variables. The flavour is used to separate instances of a dwarf
2206// probe which have different contextual bindings for the target
2207// variables which occur within the probe body. If two die/addr
2208// combinations have the same flavour string, they will be directed
2209// into the same probe function.
2210
2211struct
2212target_variable_flavour_calculating_visitor
2213 : public traversing_visitor
2214{
2215 string flavour;
2216
2217 dwarf_query & q;
2218 Dwarf_Die *scope_die;
2219 Dwarf_Addr addr;
2220
20e4a32c
RM
2221 target_variable_flavour_calculating_visitor(dwarf_query & q,
2222 Dwarf_Die *sd,
2930abc7
FCE
2223 Dwarf_Addr a)
2224 : q(q), scope_die(sd), addr(a)
2225 {}
2226 void visit_target_symbol (target_symbol* e);
2227};
2228
2229void
2230target_variable_flavour_calculating_visitor::visit_target_symbol (target_symbol *e)
2231{
2232 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
2233
cbfbbf69
FCE
2234 // NB: if for whatever reason this variable does not resolve,
2235 // or is illegally used (write in non-guru mode for instance),
35d4ab18 2236 // just pretend that it's OK anyway. dwarf_var_expanding_copy_visitor
cbfbbf69 2237 // will take care of throwing the appropriate exception.
e38d6504 2238
cbfbbf69
FCE
2239 bool lvalue = is_active_lvalue(e);
2240 flavour += lvalue ? 'w' : 'r';
2241 exp_type ty;
2242 string expr;
e38d6504 2243 try
20e4a32c 2244 {
e19fda4e
DS
2245 if (q.has_return && e->base_name == "$return")
2246 expr = q.dw.literal_stmt_for_return (scope_die,
2247 addr,
2248 e->components,
2249 lvalue,
2250 ty);
2251 else
2252 expr = q.dw.literal_stmt_for_local(scope_die,
2253 addr,
2254 e->base_name.substr(1),
2255 e->components,
2256 lvalue,
2257 ty);
2930abc7 2258 }
9b48ce88 2259 catch (const semantic_error& x)
2930abc7 2260 {
9b48ce88
FCE
2261 e->saved_conversion_error = new semantic_error (x);
2262 e->saved_conversion_error->tok1 = e->tok;
cbfbbf69 2263 ty = pe_unknown;
2930abc7 2264 }
e38d6504 2265
cbfbbf69
FCE
2266 switch (ty)
2267 {
2268 case pe_unknown:
2269 flavour += 'U';
2270 break;
2271 case pe_long:
2272 flavour += 'L';
2273 break;
2274 case pe_string:
2275 flavour += 'S';
2276 break;
2277 case pe_stats:
2278 flavour += 'T';
2279 break;
2280 }
2281 flavour += lex_cast<string>(expr.size());
2282 flavour += '{';
2283 flavour += expr;
2284 flavour += '}';
2930abc7
FCE
2285}
2286
703621ae 2287
20e4a32c 2288
36f9dd1d
FCE
2289bool
2290dwarf_query::blacklisted_p(string const & funcname,
2291 char const * filename,
2292 int line,
2293 Dwarf_Die *scope_die,
2294 Dwarf_Addr addr)
2295{
fd64709f 2296 // Check whether the given address points into an .init/.exit section,
703621ae
FCE
2297 // which will have been unmapped by the kernel by the time we get to
2298 // insert the probe. In this case, just ignore this call.
ae6f054a 2299 if (dwfl_module_relocations (dw.module) > 0)
703621ae 2300 {
ae6f054a
RM
2301 // This is a relocatable module; libdwfl has noted its sections.
2302 Dwarf_Addr rel_addr = addr;
2303 int idx = dwfl_module_relocate_address (dw.module, &rel_addr);
2304 const char *name = dwfl_module_relocation_info (dw.module, idx, NULL);
fd64709f
JS
2305 if (name && ((strncmp (name, ".init.", 6) == 0) ||
2306 (strncmp (name, ".exit.", 6) == 0)))
ae6f054a 2307 {
b0ee93c4 2308 if (sess.verbose>1)
ae6f054a
RM
2309 clog << "skipping function '" << funcname << "' base 0x"
2310 << hex << addr << dec << " is within section '"
db22e55f 2311 << name << "'\n";
36f9dd1d 2312 return true;
ae6f054a
RM
2313 }
2314 }
2315 else
2316 {
2317 Dwarf_Addr baseaddr;
2318 Elf* elf = dwfl_module_getelf (dw.module, & baseaddr);
2319 Dwarf_Addr rel_addr = addr - baseaddr;
2320 if (elf)
2321 {
2322 // Iterate through section headers to find which one
2323 // contains the given rel_addr.
2324 Elf_Scn* scn = 0;
2325 size_t shstrndx;
2326 dw.dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
2327 while ((scn = elf_nextscn (elf, scn)) != NULL)
2328 {
2329 GElf_Shdr shdr_mem;
2330 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2331 if (! shdr) continue; // XXX error?
2332
2333 // check for address inclusion
2334 GElf_Addr start = shdr->sh_addr;
2335 GElf_Addr end = start + shdr->sh_size;
2336 if (! (rel_addr >= start && rel_addr < end))
2337 continue;
2338
2339 // check for section name
2340 const char* name = elf_strptr (elf, shstrndx, shdr->sh_name);
fd64709f
JS
2341 if (name && ((strncmp (name, ".init.", 6) == 0) ||
2342 (strncmp (name, ".exit.", 6) == 0)))
ae6f054a 2343 {
b0ee93c4 2344 if (sess.verbose>1)
ae6f054a
RM
2345 clog << "skipping function '" << funcname << "' base 0x"
2346 << hex << addr << dec << " is within section '"
db22e55f 2347 << name << "'\n";
36f9dd1d 2348 return true;
ae6f054a
RM
2349 }
2350 }
2351 }
703621ae
FCE
2352 }
2353
36f9dd1d
FCE
2354 // Check probe point against blacklist. XXX: This has to be
2355 // properly generalized, perhaps via a table populated from script
2356 // files. A "noprobe kernel.function("...")" construct might do
2357 // the trick.
4893e4b2
FCE
2358 if (filename == 0) filename = ""; // possibly 0
2359 string filename_s = filename; // is passed as const char*
0daad364
JS
2360 if (blacklisted_probes.count(funcname) > 0 ||
2361 (has_return && blacklisted_return_probes.count(funcname) > 0) ||
36f9dd1d 2362 filename_s == "kernel/kprobes.c" ||
0daad364 2363 0 == fnmatch ("arch/*/kernel/kprobes.c", filename, 0))
36f9dd1d 2364 {
b0ee93c4 2365 if (sess.verbose>1)
36f9dd1d 2366 clog << "skipping function '" << funcname << "' file '"
db22e55f 2367 << filename << "' is blacklisted\n";
36f9dd1d
FCE
2368 return true;
2369 }
2370
2371 // This probe point is not blacklisted.
2372 return false;
2373}
2374
2375
2376void
2377dwarf_query::add_probe_point(string const & funcname,
2378 char const * filename,
2379 int line,
2380 Dwarf_Die *scope_die,
2381 Dwarf_Addr addr)
2382{
2383 dwarf_derived_probe *probe = NULL;
2384
2385 if (blacklisted_p (funcname, filename, line, scope_die, addr))
2386 return;
2387
2930abc7
FCE
2388 if (probe_has_no_target_variables)
2389 {
2390 assert(probe_flavours.size() == 1);
2391 probe = probe_flavours.begin()->second;
2392 }
2393 else
2394 {
20e4a32c 2395
2930abc7
FCE
2396 target_variable_flavour_calculating_visitor flav(*this, scope_die, addr);
2397 base_probe->body->visit(&flav);
20e4a32c
RM
2398
2399 map<string, dwarf_derived_probe *>::iterator i
2930abc7 2400 = probe_flavours.find(flav.flavour);
20e4a32c 2401
2930abc7
FCE
2402 if (i != probe_flavours.end())
2403 probe = i->second;
2404 else
2405 {
2406 probe = new dwarf_derived_probe(scope_die, addr, *this);
2407 probe_flavours.insert(make_pair(flav.flavour, probe));
2408 results.push_back(probe);
2409 }
20e4a32c 2410
2930abc7
FCE
2411 // Cache result in degenerate case to avoid recomputing.
2412 if (flav.flavour.empty())
2413 probe_has_no_target_variables = true;
2414 }
2415
7f9f3386
FCE
2416 if (sess.verbose > 1)
2417 {
2418 clog << "probe " << funcname << "@" << filename << ":" << line
2419 << " pc=0x" << hex << addr << dec << endl;
2420 }
2421
2930abc7
FCE
2422 probe->add_probe_point(funcname, filename, line, addr, *this);
2423}
2424
2425
2426
2427
7e1279ea
FCE
2428 // The critical determining factor when interpreting a pattern
2429 // string is, perhaps surprisingly: "presence of a lineno". The
2430 // presence of a lineno changes the search strategy completely.
2431 //
2432 // Compare the two cases:
2433 //
2434 // 1. {statement,function}(foo@file.c:lineno)
2435 // - find the files matching file.c
2436 // - in each file, find the functions matching foo
2437 // - query the file for line records matching lineno
2438 // - iterate over the line records,
20e4a32c
RM
2439 // - and iterate over the functions,
2440 // - if(haspc(function.DIE, line.addr))
7e1279ea
FCE
2441 // - if looking for statements: probe(lineno.addr)
2442 // - if looking for functions: probe(function.{entrypc,return,etc.})
20e4a32c 2443 //
7e1279ea
FCE
2444 // 2. {statement,function}(foo@file.c)
2445 // - find the files matching file.c
2446 // - in each file, find the functions matching foo
2447 // - probe(function.{entrypc,return,etc.})
2448 //
2449 // Thus the first decision we make is based on the presence of a
2450 // lineno, and we enter entirely different sets of callbacks
2451 // depending on that decision.
2452
2453
bd2b1e68 2454static void
4cd232e4 2455query_statement (string const & func,
20e4a32c 2456 char const * file,
4cd232e4 2457 int line,
bcc12710 2458 Dwarf_Die *scope_die,
20e4a32c 2459 Dwarf_Addr stmt_addr,
4cd232e4 2460 dwarf_query * q)
bd2b1e68 2461{
39bcd429
FCE
2462 try
2463 {
2464 // XXX: implement
2465 if (q->has_relative)
2466 throw semantic_error("incomplete: do not know how to interpret .relative",
2467 q->base_probe->tok);
d9b516ca 2468
2930abc7 2469 q->add_probe_point(func, file, line, scope_die, stmt_addr);
39bcd429
FCE
2470 }
2471 catch (const semantic_error& e)
2472 {
2473 q->sess.print_error (e);
2474 }
bd2b1e68
GH
2475}
2476
7e1279ea
FCE
2477static void
2478query_inline_instance_info (Dwarf_Addr entrypc,
bcc12710 2479 inline_instance_info & ii,
7e1279ea
FCE
2480 dwarf_query * q)
2481{
b6581717 2482 try
7e1279ea 2483 {
b6581717
GH
2484 if (q->has_return)
2485 {
2486 throw semantic_error ("cannot probe .return of inline function '" + ii.name + "'");
2487 }
2488 else
2489 {
b0ee93c4 2490 if (q->sess.verbose>2)
20e4a32c
RM
2491 clog << "querying entrypc "
2492 << hex << entrypc << dec
db22e55f 2493 << " of instance of inline '" << ii.name << "'\n";
20e4a32c 2494 query_statement (ii.name, ii.decl_file, ii.decl_line,
b6581717
GH
2495 &ii.die, entrypc, q);
2496 }
7e1279ea 2497 }
b6581717 2498 catch (semantic_error &e)
7e1279ea 2499 {
b6581717 2500 q->sess.print_error (e);
7e1279ea
FCE
2501 }
2502}
2503
2504static void
2505query_func_info (Dwarf_Addr entrypc,
bcc12710 2506 func_info & fi,
7e1279ea
FCE
2507 dwarf_query * q)
2508{
b6581717 2509 try
7e1279ea 2510 {
b6581717
GH
2511 if (q->has_return)
2512 {
2513 // NB. dwarf_derived_probe::emit_registrations will emit a
2514 // kretprobe based on the entrypc in this case.
20e4a32c 2515 query_statement (fi.name, fi.decl_file, fi.decl_line,
b6581717
GH
2516 &fi.die, entrypc, q);
2517 }
2518 else
2519 {
1c9db4fd
AK
2520#ifdef __ia64__
2521 // In IA64 platform function probe point is set at its
2522 // entry point rather than prologue end pointer
20e4a32c 2523 query_statement (fi.name, fi.decl_file, fi.decl_line,
1c9db4fd
AK
2524 &fi.die, entrypc, q);
2525
2526#else
20e4a32c 2527 if (fi.prologue_end == 0)
b6581717
GH
2528 throw semantic_error("could not find prologue-end "
2529 "for probed function '" + fi.name + "'");
20e4a32c 2530 query_statement (fi.name, fi.decl_file, fi.decl_line,
b6581717 2531 &fi.die, fi.prologue_end, q);
1c9db4fd 2532#endif
b6581717 2533 }
7e1279ea 2534 }
b6581717 2535 catch (semantic_error &e)
7e1279ea 2536 {
b6581717 2537 q->sess.print_error (e);
7e1279ea
FCE
2538 }
2539}
2540
2541
2542static void
2543query_srcfile_line (Dwarf_Line * line, void * arg)
2544{
2545 dwarf_query * q = static_cast<dwarf_query *>(arg);
2546
2547 Dwarf_Addr addr;
2548 dwarf_lineaddr(line, &addr);
4cd232e4 2549
7e1279ea
FCE
2550 for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
2551 i != q->filtered_functions.end(); ++i)
2552 {
2553 if (q->dw.die_has_pc (&(i->second.die), addr))
2554 {
b0ee93c4 2555 if (q->sess.verbose>3)
db22e55f 2556 clog << "function DIE lands on srcfile\n";
4cd232e4 2557 if (q->has_statement_str)
20e4a32c 2558 query_statement (i->second.name, i->second.decl_file,
bcc12710 2559 q->line, NULL, addr, q);
4cd232e4
GH
2560 else
2561 query_func_info (i->first, i->second, q);
7e1279ea 2562 }
20e4a32c
RM
2563 }
2564
2565 for (map<Dwarf_Addr, inline_instance_info>::iterator i
897820ca
GH
2566 = q->filtered_inlines.begin();
2567 i != q->filtered_inlines.end(); ++i)
2568 {
2569 if (q->dw.die_has_pc (&(i->second.die), addr))
7e1279ea 2570 {
b0ee93c4 2571 if (q->sess.verbose>3)
db22e55f 2572 clog << "inline instance DIE lands on srcfile\n";
897820ca 2573 if (q->has_statement_str)
20e4a32c 2574 query_statement (i->second.name, i->second.decl_file,
897820ca
GH
2575 q->line, NULL, addr, q);
2576 else
2577 query_inline_instance_info (i->first, i->second, q);
2578 }
20e4a32c 2579 }
7e1279ea
FCE
2580}
2581
2582
4fa7b22b 2583static int
7e1279ea 2584query_dwarf_inline_instance (Dwarf_Die * die, void * arg)
4fa7b22b
GH
2585{
2586 dwarf_query * q = static_cast<dwarf_query *>(arg);
7e1279ea 2587 assert (!q->has_statement_num);
bd2b1e68 2588
39bcd429 2589 try
7a053d3b 2590 {
bb788f9f 2591
7e1279ea
FCE
2592 bool record_this_inline = false;
2593
b0ee93c4 2594 if (q->sess.verbose>2)
db22e55f 2595 clog << "examining inline instance of " << q->dw.function_name << "\n";
7e1279ea 2596
54efe513 2597 if (q->has_inline_str || q->has_statement_str)
7e1279ea 2598 record_this_inline = true;
54efe513
GH
2599
2600 else if (q->has_inline_num)
7e1279ea 2601 {
54efe513 2602 Dwarf_Addr query_addr = q->inline_num_val;
20e4a32c 2603
7e1279ea
FCE
2604 if (q->has_module)
2605 query_addr = q->dw.module_address_to_global(query_addr);
20e4a32c 2606
7e1279ea 2607 if (q->dw.die_has_pc (die, query_addr))
20e4a32c 2608 record_this_inline = true;
7e1279ea
FCE
2609 }
2610
2611 if (record_this_inline)
2612 {
b0ee93c4 2613 if (q->sess.verbose>2)
db22e55f
FCE
2614 clog << "selected inline instance of " << q->dw.function_name
2615 << "\n";
7e1279ea
FCE
2616
2617 Dwarf_Addr entrypc;
2618 if (q->dw.die_entrypc (die, &entrypc))
2619 {
2620 inline_instance_info inl;
2621 inl.die = *die;
2622 inl.name = q->dw.function_name;
4cd232e4
GH
2623 q->dw.function_file (&inl.decl_file);
2624 q->dw.function_line (&inl.decl_line);
7e1279ea
FCE
2625 q->filtered_inlines[entrypc] = inl;
2626 }
2627 }
2628 return DWARF_CB_OK;
2629 }
2630 catch (const semantic_error& e)
2631 {
2632 q->sess.print_error (e);
2633 return DWARF_CB_ABORT;
2634 }
2635}
bb788f9f 2636
7e1279ea 2637static int
20e4a32c 2638query_dwarf_func (Dwarf_Die * func, void * arg)
7e1279ea
FCE
2639{
2640 dwarf_query * q = static_cast<dwarf_query *>(arg);
2641 assert (!q->has_statement_num);
bb788f9f 2642
7e1279ea
FCE
2643 try
2644 {
2645 // XXX: implement
2646 if (q->has_callees)
2647 throw semantic_error ("incomplete: do not know how to interpret .callees",
2648 q->base_probe->tok);
20e4a32c 2649
7e1279ea
FCE
2650 if (q->has_label)
2651 throw semantic_error ("incomplete: do not know how to interpret .label",
2652 q->base_probe->tok);
2653
2654 q->dw.focus_on_function (func);
2655
20e4a32c 2656 if (q->dw.func_is_inline ()
54efe513 2657 && (((q->has_statement_str || q->has_inline_str)
7e1279ea 2658 && q->dw.function_name_matches(q->function))
54efe513 2659 || q->has_inline_num))
7e1279ea 2660 {
b0ee93c4 2661 if (q->sess.verbose>3)
db22e55f
FCE
2662 clog << "checking instances of inline " << q->dw.function_name
2663 << "\n";
7e1279ea
FCE
2664 q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, arg);
2665 }
54efe513 2666 else if (!q->dw.func_is_inline ())
20e4a32c 2667 {
7e1279ea
FCE
2668 bool record_this_function = false;
2669
2670 if ((q->has_statement_str || q->has_function_str)
2671 && q->dw.function_name_matches(q->function))
2672 {
2673 record_this_function = true;
2674 }
2675 else if (q->has_function_num)
2676 {
2677 Dwarf_Addr query_addr = q->function_num_val;
20e4a32c 2678
7e1279ea
FCE
2679 if (q->has_module)
2680 query_addr = q->dw.module_address_to_global(query_addr);
2681
2682 Dwarf_Die d;
2683 q->dw.function_die (&d);
20e4a32c 2684
7e1279ea
FCE
2685 if (q->dw.die_has_pc (&d, query_addr))
2686 record_this_function = true;
2687 }
2688
2689 if (record_this_function)
2690 {
b0ee93c4 2691 if (q->sess.verbose>2)
db22e55f 2692 clog << "selected function " << q->dw.function_name << "\n";
7e1279ea
FCE
2693
2694 Dwarf_Addr entrypc;
2695 if (q->dw.function_entrypc (&entrypc))
2696 {
2697 func_info func;
2698 q->dw.function_die (&func.die);
2699 func.name = q->dw.function_name;
4cd232e4
GH
2700 q->dw.function_file (&func.decl_file);
2701 q->dw.function_line (&func.decl_line);
7e1279ea
FCE
2702 q->filtered_functions[entrypc] = func;
2703 }
20e4a32c
RM
2704 else
2705 throw semantic_error("no entrypc found for function '"
2706 + q->dw.function_name + "'");
7e1279ea
FCE
2707 }
2708 }
39bcd429 2709 return DWARF_CB_OK;
bd2b1e68 2710 }
39bcd429 2711 catch (const semantic_error& e)
bd2b1e68 2712 {
39bcd429
FCE
2713 q->sess.print_error (e);
2714 return DWARF_CB_ABORT;
bd2b1e68 2715 }
bd2b1e68
GH
2716}
2717
2718static int
2719query_cu (Dwarf_Die * cudie, void * arg)
2720{
20c6c071 2721 dwarf_query * q = static_cast<dwarf_query *>(arg);
7a053d3b 2722
39bcd429 2723 try
bd2b1e68 2724 {
7e1279ea 2725 q->dw.focus_on_cu (cudie);
b5d77020 2726
b0ee93c4 2727 if (false && q->sess.verbose>2)
b5d77020 2728 clog << "focused on CU '" << q->dw.cu_name
db22e55f 2729 << "', in module '" << q->dw.module_name << "'\n";
d9b516ca 2730
20e4a32c 2731 if (q->has_statement_str
54efe513
GH
2732 || q->has_inline_str || q->has_inline_num
2733 || q->has_function_str || q->has_function_num)
7e1279ea
FCE
2734 {
2735 q->filtered_srcfiles.clear();
2736 q->filtered_functions.clear();
2737 q->filtered_inlines.clear();
2738
2739 // In this path, we find "abstract functions", record
2740 // information about them, and then (depending on lineno
2741 // matching) possibly emit one or more of the function's
2742 // associated addresses. Unfortunately the control of this
2743 // cannot easily be turned inside out.
2744
54efe513 2745 if ((q->has_statement_str || q->has_function_str || q->has_inline_str)
7e1279ea
FCE
2746 && (q->spec_type != function_alone))
2747 {
2748 // If we have a pattern string with a filename, we need
2749 // to elaborate the srcfile mask in question first.
2750 q->dw.collect_srcfiles_matching (q->file, q->filtered_srcfiles);
2751
2752 // If we have a file pattern and *no* srcfile matches, there's
2753 // no need to look further into this CU, so skip.
2754 if (q->filtered_srcfiles.empty())
2755 return DWARF_CB_OK;
2756 }
2757
2758 // Pick up [entrypc, name, DIE] tuples for all the functions
2759 // matching the query, and fill in the prologue endings of them
2760 // all in a single pass.
2761 q->dw.iterate_over_functions (query_dwarf_func, q);
dc223023
FCE
2762 if (! q->filtered_functions.empty())
2763 q->dw.resolve_prologue_endings (q->filtered_functions);
7e1279ea 2764
54efe513 2765 if ((q->has_statement_str || q->has_function_str || q->has_inline_str)
7e1279ea
FCE
2766 && (q->spec_type == function_file_and_line))
2767 {
2768 // If we have a pattern string with target *line*, we
20e4a32c 2769 // have to look at lines in all the matched srcfiles.
7e1279ea
FCE
2770 for (set<char const *>::const_iterator i = q->filtered_srcfiles.begin();
2771 i != q->filtered_srcfiles.end(); ++i)
897820ca
GH
2772 q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
2773 query_srcfile_line, q);
7e1279ea
FCE
2774 }
2775 else
2776 {
54efe513
GH
2777 // Otherwise, simply probe all resolved functions (if
2778 // we're scanning functions)
2779 if (q->has_statement_str || q->has_function_str || q->has_function_num)
2780 for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
2781 i != q->filtered_functions.end(); ++i)
2782 query_func_info (i->first, i->second, q);
20e4a32c 2783
54efe513
GH
2784 // Or all inline instances (if we're scanning inlines)
2785 if (q->has_statement_str || q->has_inline_str || q->has_inline_num)
20e4a32c 2786 for (map<Dwarf_Addr, inline_instance_info>::iterator i
54efe513
GH
2787 = q->filtered_inlines.begin(); i != q->filtered_inlines.end(); ++i)
2788 query_inline_instance_info (i->first, i->second, q);
7e1279ea
FCE
2789
2790 }
2791 }
39bcd429
FCE
2792 else
2793 {
7e1279ea
FCE
2794 // Otherwise we have a statement number, and we can just
2795 // query it directly within this module.
2796
2797 assert (q->has_statement_num);
2798 Dwarf_Addr query_addr = q->statement_num_val;
2799 if (q->has_module)
2800 query_addr = q->dw.module_address_to_global(query_addr);
2801
bcc12710 2802 query_statement ("", "", -1, NULL, query_addr, q);
39bcd429
FCE
2803 }
2804 return DWARF_CB_OK;
bd2b1e68 2805 }
39bcd429 2806 catch (const semantic_error& e)
bd2b1e68 2807 {
39bcd429
FCE
2808 q->sess.print_error (e);
2809 return DWARF_CB_ABORT;
bd2b1e68 2810 }
bd2b1e68
GH
2811}
2812
0ce64fb8
FCE
2813
2814static int
2815query_kernel_exists (Dwfl_Module *mod __attribute__ ((unused)),
2816 void **userdata __attribute__ ((unused)),
2817 const char *name,
2818 Dwarf_Addr base __attribute__ ((unused)),
2819 void *arg)
2820{
2821 int *flagp = (int *) arg;
2822 if (TOK_KERNEL == name)
2823 *flagp = 1;
2824 return DWARF_CB_OK;
2825}
2826
2827
bd2b1e68
GH
2828static int
2829query_module (Dwfl_Module *mod __attribute__ ((unused)),
2830 void **userdata __attribute__ ((unused)),
2831 const char *name, Dwarf_Addr base,
bd2b1e68
GH
2832 void *arg __attribute__ ((unused)))
2833{
20c6c071 2834 dwarf_query * q = static_cast<dwarf_query *>(arg);
bd2b1e68 2835
39bcd429 2836 try
e38d6504 2837 {
39bcd429 2838 q->dw.focus_on_module(mod);
d9b516ca 2839
39bcd429
FCE
2840 // If we have enough information in the pattern to skip a module and
2841 // the module does not match that information, return early.
d9b516ca 2842
39bcd429
FCE
2843 if (q->has_kernel && !q->dw.module_name_matches(TOK_KERNEL))
2844 return DWARF_CB_OK;
d9b516ca 2845
39bcd429
FCE
2846 if (q->has_module && !q->dw.module_name_matches(q->module_val))
2847 return DWARF_CB_OK;
b5d77020 2848
b0ee93c4 2849 if (q->sess.verbose>2)
0ce64fb8
FCE
2850 clog << "focused on module '" << q->dw.module_name
2851 << "' = [" << hex << q->dw.module_start
2852 << "-" << q->dw.module_end
db22e55f 2853 << ", bias " << q->dw.module_bias << "]" << dec << "\n";
b5d77020 2854
54efe513 2855 if (q->has_inline_num || q->has_function_num || q->has_statement_num)
39bcd429
FCE
2856 {
2857 // If we have module("foo").function(0xbeef) or
2858 // module("foo").statement(0xbeef), the address is relative
2859 // to the start of the module, so we seek the function
2860 // number plus the module's bias.
7e1279ea 2861
39bcd429
FCE
2862 Dwarf_Addr addr;
2863 if (q->has_function_num)
2864 addr = q->function_num_val;
54efe513
GH
2865 else if (q->has_inline_num)
2866 addr = q->inline_num_val;
39bcd429
FCE
2867 else
2868 addr = q->statement_num_val;
d9b516ca 2869
7e1279ea
FCE
2870 // NB: We should not have kernel.* here; global addresses
2871 // should have bypassed query_module in dwarf_builder::build
2872 // and gone directly to query_cu.
d9b516ca 2873
7e1279ea
FCE
2874 assert (!q->has_kernel);
2875 assert (q->has_module);
2876 q->dw.query_cu_containing_module_address(addr, q);
39bcd429 2877 }
50e0d793 2878 else
39bcd429
FCE
2879 {
2880 // Otherwise if we have a function("foo") or statement("foo")
2881 // specifier, we have to scan over all the CUs looking for
7e1279ea 2882 // the function(s) in question
e38d6504 2883
c8959a29 2884 q->dw.limit_search_to_function_pattern(q->function);
7e1279ea 2885
54efe513 2886 assert(q->has_function_str || q->has_inline_str || q->has_statement_str);
39bcd429 2887 q->dw.iterate_over_cus(&query_cu, q);
d9b516ca 2888
7e1279ea
FCE
2889 // If we just processed the module "kernel", and the user asked for
2890 // the kernel pattern, there's no need to iterate over any further
2891 // modules
20e4a32c 2892
7e1279ea
FCE
2893 if (q->has_kernel && q->dw.module_name_matches(TOK_KERNEL))
2894 return DWARF_CB_ABORT;
2895 }
bb788f9f 2896
39bcd429 2897 return DWARF_CB_OK;
7a053d3b 2898 }
39bcd429 2899 catch (const semantic_error& e)
bd2b1e68 2900 {
39bcd429
FCE
2901 q->sess.print_error (e);
2902 return DWARF_CB_ABORT;
bd2b1e68 2903 }
bd2b1e68
GH
2904}
2905
2930abc7 2906
35d4ab18 2907struct var_expanding_copy_visitor: public deep_copy_visitor
77de5e9e 2908{
77de5e9e 2909 static unsigned tick;
e57b735a 2910 stack<functioncall**> target_symbol_setter_functioncalls;
77de5e9e 2911
35d4ab18
FCE
2912 var_expanding_copy_visitor() {}
2913 void visit_assignment (assignment* e);
2914};
2915
2916
2917struct dwarf_var_expanding_copy_visitor: public var_expanding_copy_visitor
2918{
77de5e9e 2919 dwarf_query & q;
bcc12710 2920 Dwarf_Die *scope_die;
77de5e9e
GH
2921 Dwarf_Addr addr;
2922
35d4ab18
FCE
2923 dwarf_var_expanding_copy_visitor(dwarf_query & q, Dwarf_Die *sd, Dwarf_Addr a):
2924 q(q), scope_die(sd), addr(a) {}
d7f3e0c5 2925 void visit_target_symbol (target_symbol* e);
77de5e9e
GH
2926};
2927
2928
35d4ab18 2929
77de5e9e
GH
2930unsigned var_expanding_copy_visitor::tick = 0;
2931
77de5e9e 2932void
e57b735a 2933var_expanding_copy_visitor::visit_assignment (assignment* e)
77de5e9e 2934{
e57b735a
GH
2935 // Our job would normally be to require() the left and right sides
2936 // into a new assignment. What we're doing is slightly trickier:
2937 // we're pushing a functioncall** onto a stack, and if our left
2938 // child sets the functioncall* for that value, we're going to
2939 // assume our left child was a target symbol -- transformed into a
2940 // set_target_foo(value) call, and it wants to take our right child
2941 // as the argument "value".
2942 //
2943 // This is why some people claim that languages with
2944 // constructor-decomposing case expressions have a leg up on
2945 // visitors.
2946
2947 functioncall *fcall = NULL;
2948 expression *new_left, *new_right;
d9b516ca 2949
e57b735a
GH
2950 target_symbol_setter_functioncalls.push (&fcall);
2951 require<expression*> (this, &new_left, e->left);
2952 target_symbol_setter_functioncalls.pop ();
2953 require<expression*> (this, &new_right, e->right);
2954
2955 if (fcall != NULL)
77de5e9e 2956 {
e57b735a
GH
2957 // Our left child is informing us that it was a target variable
2958 // and it has been replaced with a set_target_foo() function
2959 // call; we are going to provide that function call -- with the
2960 // right child spliced in as sole argument -- in place of
2961 // ourselves, in the deep copy we're in the middle of making.
2962
2963 // FIXME: for the time being, we only support plan $foo = bar,
2964 // not += or any other op= variant. This is fixable, but a bit
2965 // ugly.
2966 if (e->op != "=")
2967 throw semantic_error ("Operator-assign expressions on target "
2968 "variables not implemented", e->tok);
2969
2970 assert (new_left == fcall);
2971 fcall->args.push_back (new_right);
2972 provide <expression*> (this, fcall);
77de5e9e 2973 }
e57b735a
GH
2974 else
2975 {
2976 assignment* n = new assignment;
2977 n->op = e->op;
2978 n->tok = e->tok;
2979 n->left = new_left;
2980 n->right = new_right;
2981 provide <assignment*> (this, n);
2982 }
2983}
d9b516ca 2984
d7f3e0c5 2985
e57b735a 2986void
35d4ab18 2987dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
e57b735a
GH
2988{
2989 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
2990
2991 // Synthesize a function.
d7f3e0c5 2992 functiondecl *fdecl = new functiondecl;
7b99c7d3 2993 fdecl->tok = e->tok;
d7f3e0c5 2994 embeddedcode *ec = new embeddedcode;
5e309481 2995 ec->tok = e->tok;
e57b735a 2996 bool lvalue = is_active_lvalue(e);
e8fbc5e8
GH
2997
2998 if (lvalue && !q.sess.guru_mode)
2fae2e30 2999 throw semantic_error("write to target variable not permitted", e->tok);
e8fbc5e8 3000
1b07c728 3001 string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get")
20e4a32c 3002 + "_" + e->base_name.substr(1)
e57b735a
GH
3003 + "_" + lex_cast<string>(tick++));
3004
e19fda4e 3005 if (q.has_return && e->base_name != "$return")
2fae2e30
FCE
3006 throw semantic_error ("target variables not available to .return probes");
3007
66d284f4 3008 try
e57b735a 3009 {
e19fda4e
DS
3010 if (q.has_return && e->base_name == "$return")
3011 {
3012 ec->code = q.dw.literal_stmt_for_return (scope_die,
3013 addr,
3014 e->components,
3015 lvalue,
3016 fdecl->type);
3017 }
3018 else
3019 {
3020 ec->code = q.dw.literal_stmt_for_local (scope_die,
3021 addr,
3022 e->base_name.substr(1),
3023 e->components,
3024 lvalue,
3025 fdecl->type);
3026 }
3027
1b07c728
FCE
3028 if (! lvalue)
3029 ec->code += "/* pure */";
66d284f4
FCE
3030 }
3031 catch (const semantic_error& er)
3032 {
cbfbbf69
FCE
3033 // We suppress this error message, and pass the unresolved
3034 // target_symbol to the next pass. We hope that this value ends
3035 // up not being referenced after all, so it can be optimized out
3036 // quietly.
3037 provide <target_symbol*> (this, e);
1cde5ba5
JS
3038 delete fdecl;
3039 delete ec;
cbfbbf69 3040 return;
66d284f4 3041 }
e57b735a 3042
d7f3e0c5
GH
3043 fdecl->name = fname;
3044 fdecl->body = ec;
e57b735a
GH
3045 if (lvalue)
3046 {
3047 // Modify the fdecl so it carries a single pe_long formal
3048 // argument called "value".
3049
3050 // FIXME: For the time being we only support setting target
3051 // variables which have base types; these are 'pe_long' in
3052 // stap's type vocabulary. Strings and pointers might be
3053 // reasonable, some day, but not today.
3054
3055 vardecl *v = new vardecl;
3056 v->type = pe_long;
3057 v->name = "value";
3058 v->tok = e->tok;
3059 fdecl->formal_args.push_back(v);
3060 }
d7f3e0c5 3061 q.sess.functions.push_back(fdecl);
d9b516ca 3062
e57b735a 3063 // Synthesize a functioncall.
d7f3e0c5
GH
3064 functioncall* n = new functioncall;
3065 n->tok = e->tok;
3066 n->function = fname;
35d4ab18 3067 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
e57b735a
GH
3068
3069 if (lvalue)
3070 {
3071 // Provide the functioncall to our parent, so that it can be
3072 // used to substitute for the assignment node immediately above
3073 // us.
3074 assert(!target_symbol_setter_functioncalls.empty());
3075 *(target_symbol_setter_functioncalls.top()) = n;
3076 }
3077
d9b516ca 3078 provide <functioncall*> (this, n);
77de5e9e
GH
3079}
3080
3081
dc38c0ae
DS
3082void
3083dwarf_derived_probe::register_probe(systemtap_session& s)
3084{
3085 s.probes.register_probe(this);
3086}
3087
3088
2930abc7
FCE
3089void
3090dwarf_derived_probe::add_probe_point(string const & funcname,
3091 char const * filename,
3092 int line,
3093 Dwarf_Addr addr,
3094 dwarf_query & q)
bd2b1e68 3095{
4cd232e4 3096 string module_name(q.dw.module_name);
df8fadee 3097
2930abc7
FCE
3098 // "Adding a probe point" means two things:
3099 //
3100 //
3101 // 1. Adding an addr to the probe-point vector
3102
3103 probe_points.push_back(addr);
3104
3105 // 2. Extending the "locations" vector
3106
a229fcd7
GH
3107 vector<probe_point::component*> comps;
3108 comps.push_back
3109 (module_name == TOK_KERNEL
3110 ? new probe_point::component(TOK_KERNEL)
db520b00 3111 : new probe_point::component(TOK_MODULE, new literal_string(module_name)));
b5d77020 3112
db520b00
FCE
3113 string fn_or_stmt;
3114 if (q.has_function_str || q.has_function_num)
3115 fn_or_stmt = "function";
2508b230 3116 else if (q.has_inline_str || q.has_inline_num)
54efe513 3117 fn_or_stmt = "inline";
db520b00
FCE
3118 else
3119 fn_or_stmt = "statement";
a229fcd7 3120
54efe513 3121 if (q.has_function_str || q.has_inline_str || q.has_statement_str)
db520b00 3122 {
4cd232e4
GH
3123 string retro_name = funcname;
3124 if (filename && !string (filename).empty())
3125 retro_name += ("@" + string (filename));
3126 if (line != -1)
3127 retro_name += (":" + lex_cast<string> (line));
db520b00
FCE
3128 comps.push_back
3129 (new probe_point::component
3130 (fn_or_stmt, new literal_string (retro_name)));
3131 }
54efe513 3132 else if (q.has_function_num || q.has_inline_num || q.has_statement_num)
db520b00
FCE
3133 {
3134 Dwarf_Addr retro_addr;
3135 if (q.has_function_num)
3136 retro_addr = q.function_num_val;
54efe513
GH
3137 else if (q.has_inline_num)
3138 retro_addr = q.inline_num_val;
db520b00
FCE
3139 else
3140 retro_addr = q.statement_num_val;
3141
3142 comps.push_back (new probe_point::component
3143 (fn_or_stmt,
3144 new literal_number(retro_addr))); // XXX: should be hex if possible
a229fcd7
GH
3145 }
3146
db520b00 3147 if (has_return)
a229fcd7 3148 comps.push_back
db520b00 3149 (new probe_point::component(TOK_RETURN));
d9b516ca 3150
a229fcd7
GH
3151 assert(q.base_probe->locations.size() > 0);
3152 locations.push_back(new probe_point(comps, q.base_probe->locations[0]->tok));
2930abc7
FCE
3153}
3154
3155dwarf_derived_probe::dwarf_derived_probe (Dwarf_Die *scope_die,
3156 Dwarf_Addr addr,
3157 dwarf_query & q)
c1d5f3f6 3158 : derived_probe (q.base_probe, 0 /* location-less */),
2930abc7
FCE
3159 has_return (q.has_return)
3160{
3161 string module_name(q.dw.module_name);
3162
3163 // Lock the kernel module in memory.
3164 if (module_name != TOK_KERNEL)
3165 {
3166 // XXX: There is a race window here, between the time that libdw
3167 // opened up this same file for its relocation duties, and now.
3168 int fd = q.sess.module_fds[module_name];
3169 if (fd == 0)
3170 {
3171 string sys_module = "/sys/module/" + module_name + "/sections/.text";
3172 fd = open (sys_module.c_str(), O_RDONLY);
3173 if (fd < 0)
3174 throw semantic_error ("error opening module refcount-bumping file.");
3175 q.sess.module_fds[module_name] = fd;
3176 }
3177 }
a229fcd7
GH
3178
3179 // Now make a local-variable-expanded copy of the probe body
35d4ab18 3180 dwarf_var_expanding_copy_visitor v (q, scope_die, addr);
77de5e9e
GH
3181 require <block*> (&v, &(this->body), q.base_probe->body);
3182 this->tok = q.base_probe->tok;
bd2b1e68
GH
3183}
3184
7a053d3b 3185void
20c6c071 3186dwarf_derived_probe::register_relative_variants(match_node * root,
bd2b1e68
GH
3187 dwarf_builder * dw)
3188{
3189 // Here we match 2 forms:
3190 //
3191 // .
3192 // .relative(NN)
3193
20c6c071
GH
3194 root->bind(dw);
3195 root->bind_num(TOK_RELATIVE)->bind(dw);
bd2b1e68
GH
3196}
3197
7a053d3b 3198void
20c6c071 3199dwarf_derived_probe::register_statement_variants(match_node * root,
bd2b1e68
GH
3200 dwarf_builder * dw)
3201{
3202 // Here we match 3 forms:
3203 //
3204 // .
3205 // .return
3206 // .label("foo")
7a053d3b 3207
bd2b1e68 3208 register_relative_variants(root, dw);
20c6c071 3209 register_relative_variants(root->bind_str(TOK_LABEL), dw);
bd2b1e68
GH
3210}
3211
54efe513
GH
3212void
3213dwarf_derived_probe::register_inline_variants(match_node * root,
3214 dwarf_builder * dw)
3215{
3216 // Here we match 4 forms:
3217 //
3218 // .
3219 // .callees
3220 // .callees(N)
3221 //
3222 // The last form permits N-level callee resolving without any
3223 // recursive .callees.callees.callees... pattern-matching on our part.
3224
3225 root->bind(dw);
3226 root->bind(TOK_CALLEES)->bind(dw);
3227 root->bind_num(TOK_CALLEES)->bind(dw);
3228}
3229
7a053d3b 3230void
fd6602a0 3231dwarf_derived_probe::register_function_variants(match_node * root,
bd2b1e68
GH
3232 dwarf_builder * dw)
3233{
a229fcd7 3234 // Here we match 4 forms:
bd2b1e68
GH
3235 //
3236 // .
fd6602a0 3237 // .return
bd2b1e68
GH
3238 // .callees
3239 // .callees(N)
3240 //
3241 // The last form permits N-level callee resolving without any
3242 // recursive .callees.callees.callees... pattern-matching on our part.
3243
fd6602a0
FCE
3244 root->bind(dw);
3245 root->bind(TOK_RETURN)->bind(dw);
3246 root->bind(TOK_CALLEES)->bind(dw);
3247 root->bind_num(TOK_CALLEES)->bind(dw);
bd2b1e68
GH
3248}
3249
7a053d3b 3250void
20c6c071 3251dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
bd2b1e68
GH
3252 dwarf_builder * dw)
3253{
3254 // Here we match 4 forms:
3255 //
3256 // .function("foo")
3257 // .function(0xdeadbeef)
54efe513
GH
3258 // .inline("foo")
3259 // .inline(0xdeadbeef)
bd2b1e68
GH
3260 // .statement("foo")
3261 // .statement(0xdeadbeef)
3262
fd6602a0
FCE
3263 register_function_variants(root->bind_str(TOK_FUNCTION), dw);
3264 register_function_variants(root->bind_num(TOK_FUNCTION), dw);
54efe513
GH
3265 register_inline_variants(root->bind_str(TOK_INLINE), dw);
3266 register_inline_variants(root->bind_num(TOK_INLINE), dw);
20c6c071
GH
3267 register_statement_variants(root->bind_str(TOK_STATEMENT), dw);
3268 register_statement_variants(root->bind_num(TOK_STATEMENT), dw);
bd2b1e68
GH
3269}
3270
3271void
20c6c071 3272dwarf_derived_probe::register_patterns(match_node * root)
bd2b1e68
GH
3273{
3274 dwarf_builder *dw = new dwarf_builder();
3275
3276 // Here we match 3 forms:
3277 //
3278 // .kernel
3279 // .module("foo")
3280 // .process("foo")
3281
20c6c071
GH
3282 register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
3283 register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
ab55a5ae 3284 // register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
bd2b1e68
GH
3285}
3286
2930abc7 3287
7a053d3b 3288void
46b84a80
DS
3289dwarf_derived_probe::emit_registrations_start (translator_output* o,
3290 unsigned index)
ec4373ff 3291{
35d4ab18 3292 string func_name = "enter_" + name;
46b84a80
DS
3293 string index_var = "i_" + lex_cast<string>(index);
3294 o->newline();
3295 o->newline() << "probe_point = dwarf_kprobe_" << name
3296 << "_location_names[0];";
3297 o->newline() << "for (" << index_var << " = 0; " << index_var << " < "
3298 << probe_points.size() << "; " << index_var << "++) {";
2930abc7 3299 o->indent(1);
46b84a80
DS
3300 string probe_name = string("dwarf_kprobe_") + name + string("[")
3301 + index_var + string("]");
2930abc7 3302
1472a4e1
FCE
3303#if 0
3304 // XXX: triggers false negatives on RHEL4U2 kernel
3305 // emit address verification code
3306 o->newline() << "void *addr = " << probe_name;
3307 if (has_return)
3308 o->line() << ".kp.addr;";
3309 else
3310 o->line() << ".addr;";
3311 o->newline() << "rc = ! virt_addr_valid (addr);";
3312#endif
3313
59ff2773
FCE
3314 if (has_return)
3315 {
ff007aa3 3316 o->newline() << "#ifdef ARCH_SUPPORTS_KRETPROBES";
2930abc7 3317 o->newline() << probe_name << ".handler = &" << func_name << ";";
da4e78db 3318 o->newline() << probe_name << ".maxactive = max(10, 4 * NR_CPUS);";
2930abc7
FCE
3319 // XXX: pending PR 1289
3320 // o->newline() << probe_name << ".kp_fault_handler = &stap_kprobe_fault_handler;";
1472a4e1 3321 o->newline() << "rc = rc || register_kretprobe (&(" << probe_name << "));";
ff007aa3
FCE
3322 o->newline() << "#else";
3323 o->newline() << "rc = 1;";
3324 o->newline() << "#endif";
ec4373ff 3325 }
20c6c071 3326 else
bd2b1e68 3327 {
2930abc7
FCE
3328 o->newline() << probe_name << ".pre_handler = &" << func_name << ";";
3329 // XXX: pending PR 1289
3330 // o->newline() << probe_name << ".kp_fault_handler = &stap_kprobe_fault_handler;";
1472a4e1 3331 o->newline() << "rc = rc || register_kprobe (&(" << probe_name << "));";
bd2b1e68 3332 }
2930abc7 3333
2508b230 3334 o->newline() << "if (unlikely (rc)) {";
e38d6504 3335 o->newline(1) << "probe_point = " << string("dwarf_kprobe_") + name
46b84a80 3336 + string("_location_names[") << index_var << "];";
2508b230
FCE
3337 o->newline() << "break;";
3338 o->newline(-1) << "}";
2930abc7
FCE
3339 o->newline(-1) << "}";
3340
46b84a80
DS
3341 // if one failed, must goto code (output by emit_registrations_end)
3342 // that will roll back completed registations for this probe
3343 o->newline() << "if (unlikely (rc))";
3344 o->newline(1) << "goto unwind_dwarf_" << index << ";";
3345 o->indent(-1);
3346}
3347
3348
3349void
3350dwarf_derived_probe::emit_registrations_end (translator_output* o,
3351 unsigned index)
3352{
3353 string index_var = "i_" + lex_cast<string>(index);
3354 string probe_name = string("dwarf_kprobe_") + name + string("[")
3355 + index_var + string("]");
3356
2930abc7 3357 // if one failed, must roll back completed registations for this probe
46b84a80
DS
3358 o->newline(-1) << "unwind_dwarf_" << index << ":";
3359 o->newline(1) << "while (--" << index_var << " >= 0)";
2930abc7
FCE
3360 o->indent(1);
3361 if (has_return)
ff007aa3
FCE
3362 {
3363 o->newline() << "#ifdef ARCH_SUPPORTS_KRETPROBES";
3364 o->newline() << "unregister_kretprobe (&(" << probe_name << "));";
3365 o->newline() << "#else";
3366 o->newline() << ";";
3367 o->newline() << "#endif";
3368 }
2930abc7
FCE
3369 else
3370 o->newline() << "unregister_kprobe (&(" << probe_name << "));";
46b84a80 3371 o->indent(-1);
b55bc428
FCE
3372}
3373
2930abc7 3374
7a053d3b 3375void
35d4ab18 3376dwarf_derived_probe::emit_deregistrations (translator_output* o)
b55bc428 3377{
35d4ab18 3378 string probe_name = string("dwarf_kprobe_") + name + string("[i]");
46b84a80 3379 o->newline() << "for (i = 0; i < " << probe_points.size() << "; i++) {";
2930abc7 3380 o->indent(1);
46b84a80 3381
fd6602a0 3382 if (has_return)
ff007aa3
FCE
3383 {
3384 o->newline() << "#ifdef ARCH_SUPPORTS_KRETPROBES";
9a604fac 3385 o->newline() << "atomic_add ("
46b84a80
DS
3386 << probe_name << ".kp.nmissed,"
3387 << "& skipped_count);";
9a604fac 3388 o->newline() << "atomic_add ("
46b84a80
DS
3389 << probe_name << ".nmissed,"
3390 << "& skipped_count);";
af9ea5ee 3391 o->newline() << "unregister_kretprobe (&(" << probe_name << "));";
ff007aa3
FCE
3392 o->newline() << "#else";
3393 o->newline() << ";";
3394 o->newline() << "#endif";
3395 }
fd6602a0 3396 else
9a604fac 3397 {
9a604fac 3398 o->newline() << "atomic_add ("
46b84a80
DS
3399 << probe_name << ".nmissed,"
3400 << "& skipped_count);";
af9ea5ee 3401 o->newline() << "unregister_kprobe (&(" << probe_name << "));";
9a604fac
FCE
3402 }
3403
af9ea5ee 3404 o->newline(-1) << "}";
ec4373ff
GH
3405}
3406
7a053d3b 3407void
35d4ab18 3408dwarf_derived_probe::emit_probe_entries (translator_output* o)
ec4373ff 3409{
499cf740
FCE
3410 static unsigned already_emitted_fault_handler = 0;
3411
3412 if (! already_emitted_fault_handler)
3413 {
3414 o->newline() << "int stap_kprobe_fault_handler (struct kprobe* kp, "
3415 << "struct pt_regs* regs, int trapnr) {";
ded98b33 3416 o->newline(1) << "struct context* c = per_cpu_ptr (contexts, smp_processor_id());";
b1f3e72e
MH
3417 o->newline() << "_stp_warn (\"systemtap probe fault\\n\");";
3418 o->newline() << "_stp_warn (\"cpu %d, probe %s, near %s\\n\", ";
499cf740
FCE
3419 o->newline(1) << "smp_processor_id(), ";
3420 o->newline() << "c->probe_point ? c->probe_point : \"unknown\", ";
3421 o->newline() << "c->last_stmt ? c->last_stmt : \"unknown\");";
3422 o->newline() << "c->last_error = \"probe faulted\";";
3423 o->newline(-1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
3424
3425 o->newline() << "return 0;"; // defer to kernel fault handler
3426 // NB: We might prefer to use "return 1" instead, to consider
3427 // the fault "handled". But we may get into an infinite loop
3428 // of traps if the faulting instruction is simply restarted.
3429
3430 o->newline(-1) << "}";
3431 already_emitted_fault_handler ++;
3432 }
3433
2930abc7
FCE
3434
3435 // Emit arrays of probes and location names.
3436
35d4ab18
FCE
3437 string probe_array = string("dwarf_kprobe_") + name;
3438 string string_array = probe_array + "_location_names";
2930abc7
FCE
3439
3440 assert(locations.size() == probe_points.size());
3441
3442 if (has_return)
ff007aa3
FCE
3443 {
3444 o->newline() << "#ifdef ARCH_SUPPORTS_KRETPROBES";
2930abc7
FCE
3445 o->newline() << "static struct kretprobe "
3446 << probe_array
3447 << "[" << probe_points.size() << "]"
3448 << "= {";
ff007aa3 3449 }
2930abc7
FCE
3450 else
3451 o->newline() << "static struct kprobe "
3452 << probe_array
3453 << "[" << probe_points.size() << "]"
3454 << "= {";
3455
3456 o->indent(1);
3457 for (vector<Dwarf_Addr>::const_iterator i = probe_points.begin();
20e4a32c 3458 i != probe_points.end();
2930abc7
FCE
3459 ++i)
3460 {
3461 if (i != probe_points.begin())
3462 o->line() << ",";
3463 if (has_return)
3464 o->newline() << "{.kp.addr= (void *) 0x" << hex << *i << dec << "}";
3465 else
3466 o->newline() << "{.addr= (void *) 0x" << hex << *i << dec << "}";
3467 }
3468 o->newline(-1) << "};";
3469
ff007aa3
FCE
3470 if (has_return)
3471 o->newline() << "#endif /* ARCH_SUPPORTS_KRETPROBES */";
3472
2930abc7
FCE
3473 o->newline();
3474
3475 // This is somewhat gross, but it should work: we allocate a
3476 // *parallel* array of strings containing the location of each
3477 // probe. You can calculate which kprobe or kretprobe you're in by
3478 // taking the difference of the struct kprobe pointer and the base
3479 // of the kprobe array and dividing by the size of the struct kprobe
3480 // (or kretprobe), then you can use this index into the string table
20e4a32c 3481 // here to work out the *name* of the probe you're in.
2930abc7
FCE
3482 //
3483 // Sorry.
3484
3485 assert(probe_points.size() == locations.size());
3486
ffd1346f 3487 o->newline() << "static char const * "
2930abc7
FCE
3488 << string_array
3489 << "[" << locations.size() << "] = {";
3490 o->indent(1);
20e4a32c 3491 for (vector<probe_point*>::const_iterator i = locations.begin();
2930abc7
FCE
3492 i != locations.end(); ++i)
3493 {
3494 if (i != locations.begin())
3495 o->line() << ",";
3496 o->newline() << lex_cast_qstring(*(*i));
3497 }
20e4a32c
RM
3498 o->newline(-1) << "};";
3499
4b17d6af
WC
3500 o->newline();
3501 o->newline() << "#ifdef STP_TIMING";
c1d5f3f6 3502 o->newline() << "static __cacheline_aligned Stat " << "time_" << basest()->name << ";";
4b17d6af 3503 o->newline() << "#endif";
2930abc7 3504
7a053d3b 3505 // Construct a single entry function, and a struct kprobe pointing into
20c6c071 3506 // the entry function. The entry function will call the probe function.
20c6c071 3507 o->newline();
ff007aa3
FCE
3508 if (has_return)
3509 o->newline() << "#ifdef ARCH_SUPPORTS_KRETPROBES";
3d49c615 3510 o->newline() << "static int ";
35d4ab18 3511 o->newline() << "enter_" << name << " (";
9e6edd10 3512 if (has_return)
2930abc7 3513 o->line() << "struct kretprobe_instance *probe_instance";
9e6edd10 3514 else
2930abc7 3515 o->line() << "struct kprobe *probe_instance";
9e6edd10 3516 o->line() << ", struct pt_regs *regs) {";
9a604fac 3517 o->indent(1);
2930abc7
FCE
3518
3519 // Calculate the name of the current probe by finding its index in the probe array.
3520 if (has_return)
20e4a32c
RM
3521 o->newline() << "const char* probe_point = "
3522 << string_array
2930abc7
FCE
3523 << "[ (probe_instance->rp - &(" << probe_array << "[0]))];";
3524 else
20e4a32c
RM
3525 o->newline() << "const char* probe_point = "
3526 << string_array
2930abc7 3527 << "[ (probe_instance - &(" << probe_array << "[0]))];";
9a604fac 3528 emit_probe_prologue (o, "STAP_SESSION_RUNNING");
3d49c615 3529 o->newline() << "c->regs = regs;";
5e309481 3530
ec4373ff 3531 // NB: locals are initialized by probe function itself
35d4ab18 3532 o->newline() << name << " (c);";
bfb3d2d2 3533
9a604fac 3534 emit_probe_epilogue (o);
20e4a32c 3535
3d49c615 3536 o->newline() << "return 0;";
db22e55f 3537 o->newline(-1) << "}\n";
ff007aa3
FCE
3538 if (has_return)
3539 o->newline() << "#endif /* ARCH_SUPPORTS_KRETPROBES */";
ec4373ff 3540
20c6c071 3541 o->newline();
20c6c071 3542}
ec4373ff 3543
20c6c071 3544
dc38c0ae
DS
3545void
3546dwarf_derived_probe_group::emit_probes (translator_output* op, unparser* up)
3547{
3548 for (unsigned i=0; i < probes.size(); i++)
3549 {
3550 op->newline ();
3551 up->emit_probe (probes[i]);
3552 }
3553}
3554
3555
46b84a80
DS
3556void
3557dwarf_derived_probe_group::emit_module_init (translator_output* o)
3558{
3559 if (probes.size () == 0)
3560 return;
3561
3562 // Output the dwarf probes create function
3563 o->newline() << "static int register_dwarf_probes (void) {";
3564 o->indent(1);
3565 o->newline() << "int rc = 0;";
3566 o->newline() << "const char *probe_point;";
3567
3568 for (unsigned i=0; i < probes.size (); i++)
3569 o->newline() << "int i_" << i << ";";
3570
3571 for (unsigned i=0; i < probes.size (); i++)
3572 probes[i]->emit_registrations_start (o, i);
3573
3574 o->newline() << "goto out;";
3575 o->newline();
3576
3577 for (int i=probes.size() - 1; i >= 0; i--)
3578 probes[i]->emit_registrations_end (o, i);
3579
3580 o->newline();
3581
3582 o->newline() << "if (unlikely (rc)) {";
3583 // In case it's just a lower-layer (kprobes) error that set rc but
3584 // not session_state, do that here to prevent any other BEGIN probe
3585 // from attempting to run.
3586 o->newline(1) << "atomic_set (&session_state, STAP_SESSION_ERROR);";
3587 o->newline() << "_stp_error (\"dwarf probe %s registration failed, rc=%d\\n\", probe_point, rc);";
3588 o->newline(-1) << "}\n";
3589
3590 o->newline(-1) << "out:";
3591 o->newline(1) << "return rc;";
3592 o->newline(-1) << "}\n";
3593
3594 // Output the dwarf probes destroy function
3595 o->newline() << "static void unregister_dwarf_probes (void) {";
3596 o->newline(1) << "int i;";
3597
3598 for (unsigned i=0; i < probes.size (); i++)
3599 {
3600 probes[i]->emit_deregistrations (o);
3601 emit_probe_timing(probes[i], o);
3602 }
3603
3604 o->newline(-1) << "}\n";
3605}
3606
3607
20c6c071 3608void
5227f1ea 3609dwarf_builder::build(systemtap_session & sess,
7a053d3b 3610 probe * base,
20c6c071
GH
3611 probe_point * location,
3612 std::map<std::string, literal *> const & parameters,
20c6c071
GH
3613 vector<derived_probe *> & finished_results)
3614{
c8959a29
GH
3615 dwflpp *dw = NULL;
3616
3617 string dummy;
3618 bool has_kernel = dwarf_query::has_null_param(parameters, TOK_KERNEL);
3619 bool has_module = dwarf_query::get_string_param(parameters, TOK_MODULE, dummy);
3620
3621 if (has_kernel || has_module)
3622 {
3623 if (!kern_dw)
3624 {
3625 kern_dw = new dwflpp(sess);
3626 assert(kern_dw);
3627 kern_dw->setup(true);
3628 }
3629 dw = kern_dw;
3630 }
3631 else
3632 {
3633 if (!user_dw)
3634 {
3635 user_dw = new dwflpp(sess);
3636 assert(user_dw);
3637 user_dw->setup(false);
3638 }
3639 dw = user_dw;
3640 }
3641 assert(dw);
20c6c071 3642
c8959a29 3643 dwarf_query q(sess, base, location, *dw, parameters, finished_results);
20c6c071 3644
20c6c071 3645
20e4a32c 3646 if (q.has_kernel &&
54efe513 3647 (q.has_function_num || q.has_inline_num || q.has_statement_num))
20c6c071 3648 {
50e0d793
GH
3649 // If we have kernel.function(0xbeef), or
3650 // kernel.statement(0xbeef) the address is global (relative to
3651 // the kernel) and we can seek directly to the module and cudie
3652 // in question.
54efe513
GH
3653 Dwarf_Addr a;
3654 if (q.has_function_num)
3655 a = q.function_num_val;
3656 else if (q.has_inline_num)
3657 a = q.inline_num_val;
20e4a32c 3658 else
54efe513 3659 a = q.statement_num_val;
c8959a29
GH
3660 dw->focus_on_module_containing_global_address(a);
3661 dw->query_cu_containing_global_address(a, &q);
20c6c071 3662 }
7a053d3b 3663 else
20c6c071 3664 {
0ce64fb8 3665 // Otherwise we have module("*bar*"), kernel.statement("foo"), or
20c6c071
GH
3666 // kernel.function("foo"); in these cases we need to scan all
3667 // the modules.
7a053d3b 3668 assert((q.has_kernel && q.has_function_str) ||
54efe513 3669 (q.has_kernel && q.has_inline_str) ||
20c6c071
GH
3670 (q.has_kernel && q.has_statement_str) ||
3671 (q.has_module));
0ce64fb8
FCE
3672 if (q.has_kernel)
3673 {
3674 int flag = 0;
c8959a29 3675 dw->iterate_over_modules(&query_kernel_exists, &flag);
0ce64fb8
FCE
3676 if (! flag)
3677 throw semantic_error ("cannot find kernel debuginfo");
3678 }
3679
c8959a29 3680 dw->iterate_over_modules(&query_module, &q);
20c6c071 3681 }
b55bc428
FCE
3682}
3683
3684
98afd80e
FCE
3685
3686// ------------------------------------------------------------------------
3687// timer derived probes
3688// ------------------------------------------------------------------------
3689
3690
3691struct timer_derived_probe: public derived_probe
3692{
3693 int64_t interval, randomize;
422d1ceb 3694 bool time_is_msecs;
98afd80e 3695
422d1ceb 3696 timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r, bool ms=false);
98afd80e 3697
dc38c0ae
DS
3698 virtual void register_probe (systemtap_session& s);
3699
46b84a80
DS
3700 virtual void emit_registrations_start (translator_output* o, unsigned index);
3701 virtual void emit_registrations_end (translator_output * o, unsigned index);
35d4ab18
FCE
3702 virtual void emit_deregistrations (translator_output * o);
3703 virtual void emit_probe_entries (translator_output * o);
98afd80e
FCE
3704};
3705
3706
422d1ceb
FCE
3707timer_derived_probe::timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r, bool ms):
3708 derived_probe (p, l), interval (i), randomize (r), time_is_msecs(ms)
98afd80e
FCE
3709{
3710 if (interval <= 0 || interval > 1000000) // make i and r fit into plain ints
3711 throw semantic_error ("invalid interval for jiffies timer");
3712 // randomize = 0 means no randomization
3713 if (randomize < 0 || randomize > interval)
3714 throw semantic_error ("invalid randomize for jiffies timer");
3715
3716 if (locations.size() != 1)
3717 throw semantic_error ("expect single probe point");
3718 // so we don't have to loop over them in the other functions
3719}
3720
3721
dc38c0ae
DS
3722void
3723timer_derived_probe::register_probe(systemtap_session& s)
3724{
3725 s.probes.register_probe(this);
3726}
3727
3728
98afd80e 3729void
46b84a80
DS
3730timer_derived_probe::emit_registrations_start (translator_output* o,
3731 unsigned index)
98afd80e 3732{
46b84a80
DS
3733 o->newline();
3734 o->newline() << "probe_point = \"" << *locations[0] << "\";";
35d4ab18
FCE
3735 o->newline() << "init_timer (& timer_" << name << ");";
3736 o->newline() << "timer_" << name << ".expires = jiffies + ";
422d1ceb
FCE
3737 if (time_is_msecs)
3738 o->line() << "msecs_to_jiffies(";
3739 o->line() << interval;
3740 if (randomize)
3741 o->line() << " + _stp_random_pm(" << randomize << ")";
3742 if (time_is_msecs)
3743 o->line() << ")";
3744 o->line() << ";";
35d4ab18
FCE
3745 o->newline() << "timer_" << name << ".function = & enter_" << name << ";";
3746 o->newline() << "add_timer (& timer_" << name << ");";
46b84a80
DS
3747
3748 // if one failed, must goto code (output by emit_registrations_end)
3749 // that will roll back completed registations for this probe
3750 o->newline() << "if (unlikely (rc))";
3751 if (index == 0)
3752 o->newline(1) << "goto timer_error;";
3753 else
3754 o->newline(1) << "goto unwind_timer_" << index - 1 << ";";
3755 o->indent(-1);
3756}
3757
3758
3759void
3760timer_derived_probe::emit_registrations_end (translator_output* o,
3761 unsigned index)
3762{
3763 // if one failed, must roll back completed registations for this probe
3764 o->newline(-1) << "unwind_timer_" << index << ":";
3765 o->newline(1) << "del_timer_sync (& timer_" << name << ");";
98afd80e
FCE
3766}
3767
3768
3769void
35d4ab18 3770timer_derived_probe::emit_deregistrations (translator_output* o)
98afd80e 3771{
35d4ab18 3772 o->newline() << "del_timer_sync (& timer_" << name << ");";
98afd80e
FCE
3773}
3774
3775
3776void
35d4ab18 3777timer_derived_probe::emit_probe_entries (translator_output* o)
98afd80e 3778{
35d4ab18 3779 o->newline() << "static struct timer_list timer_" << name << ";";
98afd80e 3780
ffd1346f 3781 o->newline() << "static void enter_" << name << " (unsigned long val) {";
9a604fac 3782 o->indent(1);
cc9ee605
FCE
3783 o->newline() << "const char* probe_point = "
3784 << lex_cast_qstring(*locations[0]) << ";";
9a604fac 3785 emit_probe_prologue (o, "STAP_SESSION_RUNNING");
98afd80e 3786
9a604fac 3787 o->newline() << "(void) val;";
35d4ab18 3788 o->newline() << "mod_timer (& timer_" << name << ", jiffies + ";
422d1ceb
FCE
3789 if (time_is_msecs)
3790 o->line() << "msecs_to_jiffies(";
3791 o->line() << interval;
98afd80e
FCE
3792 if (randomize)
3793 o->line() << " + _stp_random_pm(" << randomize << ")";
422d1ceb
FCE
3794 if (time_is_msecs)
3795 o->line() << ")";
98afd80e 3796 o->line() << ");";
20e4a32c 3797
98afd80e 3798 // NB: locals are initialized by probe function itself
35d4ab18 3799 o->newline() << name << " (c);";
20e4a32c 3800
9a604fac 3801 emit_probe_epilogue (o);
db22e55f 3802 o->newline(-1) << "}\n";
98afd80e
FCE
3803}
3804
3805
dc38c0ae
DS
3806struct timer_derived_probe_group: public derived_probe_group
3807{
3808private:
3809 vector<timer_derived_probe*> probes;
3810
3811public:
3812 virtual void register_probe(timer_derived_probe* p) { probes.push_back (p); }
3813 virtual size_t size () { return probes.size (); }
3814
3815 virtual void emit_probes (translator_output* op, unparser* up);
46b84a80 3816 virtual void emit_module_init (translator_output* o);
dc38c0ae
DS
3817};
3818
3819
3820void
3821timer_derived_probe_group::emit_probes (translator_output* op, unparser* up)
3822{
3823 for (unsigned i=0; i < probes.size(); i++)
3824 {
3825 op->newline ();
3826 up->emit_probe (probes[i]);
3827 }
3828}
3829
3830
46b84a80
DS
3831void
3832timer_derived_probe_group::emit_module_init (translator_output* o)
3833{
3834 if (probes.size () == 0)
3835 return;
3836
3837 // Output the timer probes create function
3838 o->newline() << "static int register_timer_probes (void) {";
3839 o->indent(1);
3840 o->newline() << "int rc = 0;";
3841 o->newline() << "const char *probe_point;";
3842
3843 for (unsigned i=0; i < probes.size (); i++)
3844 o->newline() << "int i_" << i << ";";
3845
3846 for (unsigned i=0; i < probes.size (); i++)
3847 probes[i]->emit_registrations_start (o, i);
3848
3849 o->newline() << "goto out;";
3850 o->newline();
3851
3852 for (int i=probes.size() - 2; i >= 0; i--)
3853 probes[i]->emit_registrations_end (o, i);
3854
3855 o->newline();
3856
3857 o->newline(-1) << "timer_error:";
3858 o->newline(1) << "if (unlikely (rc)) {";
3859 // In case it's just a lower-layer (kprobes) error that set rc but
3860 // not session_state, do that here to prevent any other BEGIN probe
3861 // from attempting to run.
3862 o->newline(1) << "atomic_set (&session_state, STAP_SESSION_ERROR);";
3863 o->newline() << "_stp_error (\"timer probe %s registration failed, rc=%d\\n\", probe_point, rc);";
3864 o->newline(-1) << "}\n";
3865
3866 o->newline(-1) << "out:";
3867 o->newline(1) << "return rc;";
3868 o->newline(-1) << "}\n";
3869
3870 // Output the timer probes destroy function
3871 o->newline() << "static void unregister_timer_probes (void) {";
3872 o->indent(1);
3873
3874 for (unsigned i=0; i < probes.size (); i++)
3875 {
3876 probes[i]->emit_deregistrations (o);
3877 emit_probe_timing(probes[i], o);
3878 }
3879
3880 o->newline(-1) << "}\n";
3881}
3882
3883
98afd80e
FCE
3884struct timer_builder: public derived_probe_builder
3885{
422d1ceb
FCE
3886 bool time_is_msecs;
3887 timer_builder(bool ms=false): time_is_msecs(ms) {}
98afd80e
FCE
3888 virtual void build(systemtap_session & sess,
3889 probe * base,
3890 probe_point * location,
3891 std::map<std::string, literal *> const & parameters,
98afd80e
FCE
3892 vector<derived_probe *> & finished_results)
3893 {
3894 int64_t jn, rn;
3895 bool jn_p, rn_p;
3896
422d1ceb 3897 jn_p = get_param (parameters, time_is_msecs ? "ms" : "jiffies", jn);
98afd80e 3898 rn_p = get_param (parameters, "randomize", rn);
20e4a32c 3899
98afd80e 3900 finished_results.push_back(new timer_derived_probe(base, location,
422d1ceb
FCE
3901 jn, rn_p ? rn : 0,
3902 time_is_msecs));
98afd80e
FCE
3903 }
3904};
3905
3906
39e57ce0
FCE
3907// ------------------------------------------------------------------------
3908// profile derived probes
3909// ------------------------------------------------------------------------
3910// On kernels < 2.6.10, this uses the register_profile_notifier API to
3911// generate the timed events for profiling; on kernels >= 2.6.10 this
3912// uses the register_timer_hook API. The latter doesn't currently allow
3913// simultaneous users, so insertion will fail if the profiler is busy.
3914// (Conflicting users may include OProfile, other SystemTap probes, etc.)
3915
3916
3917struct profile_derived_probe: public derived_probe
3918{
6dce2125
JS
3919 // kernels < 2.6.10: use register_profile_notifier API
3920 // kernels >= 2.6.10: use register_timer_hook API
3921 bool using_rpn;
3922
3923 profile_derived_probe (systemtap_session &s, probe* p, probe_point* l);
39e57ce0 3924
dc38c0ae
DS
3925 void register_probe (systemtap_session& s);
3926
46b84a80
DS
3927 virtual void emit_registrations_start (translator_output* o, unsigned index);
3928 virtual void emit_registrations_end (translator_output * o, unsigned index);
35d4ab18
FCE
3929 virtual void emit_deregistrations (translator_output * o);
3930 virtual void emit_probe_entries (translator_output * o);
39e57ce0
FCE
3931};
3932
3933
6dce2125
JS
3934profile_derived_probe::profile_derived_probe (systemtap_session &s, probe* p, probe_point* l):
3935 derived_probe(p, l)
39e57ce0 3936{
6dce2125 3937 string target_kernel_v;
39e57ce0 3938
6dce2125 3939 // cut off any release code suffix
77a5c1f9
JS
3940 string::size_type dash_index = s.kernel_release.find ('-');
3941 if (dash_index > 0 && dash_index != string::npos)
3942 target_kernel_v = s.kernel_release.substr (0, dash_index);
6dce2125
JS
3943 else
3944 target_kernel_v = s.kernel_release;
39e57ce0 3945
6dce2125 3946 using_rpn = (strverscmp(target_kernel_v.c_str(), "2.6.10") < 0);
39e57ce0
FCE
3947}
3948
3949
dc38c0ae
DS
3950void
3951profile_derived_probe::register_probe(systemtap_session& s)
3952{
3953 s.probes.register_probe(this);
3954}
3955
3956
39e57ce0 3957void
46b84a80
DS
3958profile_derived_probe::emit_registrations_start (translator_output* o,
3959 unsigned index)
39e57ce0 3960{
46b84a80
DS
3961 o->newline();
3962 o->newline() << "probe_point = \"" << *locations[0] << "\";";
6dce2125 3963 if (using_rpn)
35d4ab18 3964 o->newline() << "rc = register_profile_notifier(& profile_" << name << ");";
6dce2125 3965 else
35d4ab18 3966 o->newline() << "rc = register_timer_hook(enter_" << name << ");";
46b84a80
DS
3967
3968 // if one failed, must goto code (output by emit_registrations_end)
3969 // that will roll back completed registations for other probes of
3970 // this type.
3971 o->newline() << "if (unlikely (rc))";
3972 if (index == 0)
3973 o->newline(1) << "goto profile_error;";
3974 else
3975 o->newline(1) << "goto unwind_profile_" << index - 1 << ";";
3976 o->indent(-1);
3977}
3978
3979
3980void
3981profile_derived_probe::emit_registrations_end (translator_output* o,
3982 unsigned index)
3983{
3984 // if one failed, must roll back completed registations for this
3985 // type of probe
3986 o->newline(-1) << "unwind_profile_" << index << ":";
3987 o->indent(1);
3988 emit_deregistrations (o);
6dce2125 3989}
39e57ce0 3990
39e57ce0 3991
6dce2125 3992void
35d4ab18 3993profile_derived_probe::emit_deregistrations (translator_output* o)
6dce2125
JS
3994{
3995 if (using_rpn)
35d4ab18 3996 o->newline() << "unregister_profile_notifier(& profile_" << name << ");";
6dce2125 3997 else
35d4ab18 3998 o->newline() << "unregister_timer_hook(enter_" << name << ");";
39e57ce0
FCE
3999}
4000
4001
4002void
35d4ab18 4003profile_derived_probe::emit_probe_entries (translator_output* o)
39e57ce0 4004{
6dce2125 4005 if (using_rpn) {
35d4ab18 4006 o->newline() << "static int enter_" << name
6dce2125 4007 << " (struct notifier_block *self, unsigned long val, void *data);";
35d4ab18
FCE
4008 o->newline() << "static struct notifier_block profile_" << name << " = {";
4009 o->newline(1) << ".notifier_call = enter_" << name << ",";
6dce2125 4010 o->newline(-1) << "};";
35d4ab18 4011 o->newline() << "int enter_" << name
6dce2125
JS
4012 << " (struct notifier_block *self, unsigned long val, void *data) {";
4013 o->newline(1) << "struct pt_regs *regs = (struct pt_regs *)data;";
4014 o->indent(-1);
4015 } else {
35d4ab18
FCE
4016 o->newline() << "static int enter_" << name << " (struct pt_regs *regs);";
4017 o->newline() << "int enter_" << name << " (struct pt_regs *regs) {";
6dce2125 4018 }
39e57ce0 4019
9a604fac 4020 o->indent(1);
39e57ce0
FCE
4021 o->newline() << "const char* probe_point = "
4022 << lex_cast_qstring(*locations[0]) << ";";
9a604fac 4023 emit_probe_prologue (o, "STAP_SESSION_RUNNING");
a7978f80 4024 o->newline() << "c->regs = regs;";
39e57ce0 4025
6dce2125
JS
4026 if (using_rpn) {
4027 o->newline() << "(void) self;";
4028 o->newline() << "(void) val;";
4029 }
4030
35d4ab18 4031 o->newline() << name << " (c);";
39e57ce0 4032
9a604fac 4033 emit_probe_epilogue (o);
39e57ce0 4034 o->newline() << "return 0;";
db22e55f 4035 o->newline(-1) << "}\n";
39e57ce0
FCE
4036}
4037
4038
dc38c0ae
DS
4039struct profile_derived_probe_group: public derived_probe_group
4040{
4041private:
4042 vector<profile_derived_probe*> probes;
4043
4044public:
4045 virtual void register_probe(profile_derived_probe* p) {
4046 probes.push_back (p); }
4047 virtual size_t size () { return probes.size (); }
4048
4049 virtual void emit_probes (translator_output* op, unparser* up);
46b84a80 4050 virtual void emit_module_init (translator_output* o);
dc38c0ae
DS
4051};
4052
4053
4054void
4055profile_derived_probe_group::emit_probes (translator_output* op, unparser* up)
4056{
4057 for (unsigned i=0; i < probes.size(); i++)
4058 {
4059 op->newline ();
4060 up->emit_probe (probes[i]);
4061 }
4062}
4063
4064
46b84a80
DS
4065void
4066profile_derived_probe_group::emit_module_init (translator_output* o)
4067{
4068 if (probes.size () == 0)
4069 return;
4070
4071 // Output the profile probes create function
4072 o->newline() << "static int register_profile_probes (void) {";
4073 o->indent(1);
4074 o->newline() << "int rc = 0;";
4075 o->newline() << "const char *probe_point;";
4076
4077 for (unsigned i=0; i < probes.size (); i++)
4078 probes[i]->emit_registrations_start (o, i);
4079
4080 o->newline() << "goto out;";
4081 o->newline();
4082
4083 for (int i=probes.size() - 2; i >= 0; i--)
4084 probes[i]->emit_registrations_end (o, i);
4085
4086 o->newline();
4087
4088 o->newline(-1) << "profile_error:";
4089 o->newline(1) << "if (unlikely (rc)) {";
4090 // In case it's just a lower-layer (kprobes) error that set rc but
4091 // not session_state, do that here to prevent any other BEGIN probe
4092 // from attempting to run.
4093 o->newline(1) << "atomic_set (&session_state, STAP_SESSION_ERROR);";
4094 o->newline() << "_stp_error (\"profile probe %s registration failed, rc=%d\\n\", probe_point, rc);";
4095 o->newline(-1) << "}\n";
4096
4097 o->newline(-1) << "out:";
4098 o->newline(1) << "return rc;";
4099 o->newline(-1) << "}\n";
4100
4101 // Output the profile probes destroy function
4102 o->newline() << "static void unregister_profile_probes (void) {";
4103 o->indent(1);
4104
4105 for (unsigned i=0; i < probes.size (); i++)
4106 {
4107 probes[i]->emit_deregistrations (o);
4108 emit_probe_timing(probes[i], o);
4109 }
4110
4111 o->newline(-1) << "}\n";
4112}
4113
4114
39e57ce0
FCE
4115struct profile_builder: public derived_probe_builder
4116{
4117 profile_builder() {}
4118 virtual void build(systemtap_session & sess,
4119 probe * base,
4120 probe_point * location,
4121 std::map<std::string, literal *> const & parameters,
4122 vector<derived_probe *> & finished_results)
4123 {
6dce2125 4124 finished_results.push_back(new profile_derived_probe(sess, base, location));
39e57ce0
FCE
4125 }
4126};
4127
4128
30a279be
FCE
4129// ------------------------------------------------------------------------
4130// statically inserted macro-based derived probes
4131// ------------------------------------------------------------------------
4132
4133
4134struct mark_derived_probe: public derived_probe
4135{
4136 mark_derived_probe (systemtap_session &s,
35d4ab18
FCE
4137 const string& probe_name, const string& probe_sig,
4138 uintptr_t address, const string& module,
4139 probe* base_probe);
30a279be 4140
35d4ab18 4141 systemtap_session& sess;
30a279be
FCE
4142 string probe_name, probe_sig;
4143 uintptr_t address;
4144 string module;
4145 string probe_sig_expanded;
4146
dc38c0ae
DS
4147 void register_probe (systemtap_session& s);
4148
46b84a80
DS
4149 void emit_registrations_start (translator_output * o, unsigned index);
4150 void emit_registrations_end (translator_output * o, unsigned index);
35d4ab18
FCE
4151 void emit_deregistrations (translator_output * o);
4152 void emit_probe_entries (translator_output * o);
4153 void emit_probe_context_vars (translator_output* o);
30a279be
FCE
4154};
4155
4156
35d4ab18
FCE
4157struct mark_var_expanding_copy_visitor: public var_expanding_copy_visitor
4158{
4159 mark_var_expanding_copy_visitor(systemtap_session& s,
4160 const string& ms, const string& pn):
4161 sess (s), mark_signature (ms), probe_name (pn) {}
4162 systemtap_session& sess;
4163 string mark_signature;
4164 string probe_name;
4165
4166 void visit_target_symbol (target_symbol* e);
4167};
4168
4169
4170void
4171mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
4172{
4173 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
4174
4175 if (e->base_name.substr(0,4) != "$arg")
4176 throw semantic_error ("invalid target symbol for marker, $argN expected", e->tok);
4177 string argnum_s = e->base_name.substr(4,e->base_name.length()-4);
4178 int argnum = atoi (argnum_s.c_str());
4179 if (argnum < 1 || argnum > (int) mark_signature.size())
4180 throw semantic_error ("invalid marker argument number", e->tok);
4181
4182 char argtype = mark_signature[argnum-1];
4183
4184 // Synthesize a function.
4185 functiondecl *fdecl = new functiondecl;
4186 fdecl->tok = e->tok;
4187 embeddedcode *ec = new embeddedcode;
4188 ec->tok = e->tok;
35d4ab18 4189
1b07c728
FCE
4190 if (is_active_lvalue (e))
4191 throw semantic_error("write to marker parameter not permitted", e->tok);
35d4ab18 4192
1b07c728
FCE
4193 string fname = string("_mark_tvar_get")
4194 + "_" + e->base_name.substr(1)
4195 + "_" + lex_cast<string>(tick++);
35d4ab18 4196
1b07c728
FCE
4197 ec->code = string("THIS->__retvalue = CONTEXT->locals[0].")
4198 + probe_name + string(".__mark_arg")
4199 + lex_cast<string>(argnum) + string (";");
4200 ec->code += "/* pure */";
35d4ab18
FCE
4201 fdecl->name = fname;
4202 fdecl->body = ec;
4203 fdecl->type = (argtype == 'N' ? pe_long :
4204 argtype == 'S' ? pe_string :
4205 pe_unknown); // cannot happen
4206 sess.functions.push_back(fdecl);
4207
4208 // Synthesize a functioncall.
4209 functioncall* n = new functioncall;
4210 n->tok = e->tok;
4211 n->function = fname;
4212 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
4213 provide <functioncall*> (this, n);
4214}
4215
4216
4217
30a279be 4218mark_derived_probe::mark_derived_probe (systemtap_session &s,
35d4ab18
FCE
4219 const string& p_n,
4220 const string& p_s,
4221 uintptr_t a,
4222 const string& m,
4223 probe* base):
4224 derived_probe (base, 0), sess (s), probe_name (p_n), probe_sig (p_s),
30a279be
FCE
4225 address (a), module (m)
4226{
4227 // create synthetic probe point
4228 probe_point* pp = new probe_point;
4229
4230 probe_point::component* c;
4231 if (module == "") c = new probe_point::component ("kernel");
4232 else c = new probe_point::component ("module",
4233 new literal_string (module));
4234 pp->components.push_back (c);
dc223023 4235 c = new probe_point::component ("mark",
30a279be
FCE
4236 new literal_string (probe_name));
4237 pp->components.push_back (c);
4238 this->locations.push_back (pp);
4239
4240 // expand the signature string
4241 for (unsigned i=0; i<probe_sig.length(); i++)
4242 {
4243 if (i > 0)
4244 probe_sig_expanded += ", ";
e38d6504 4245 switch (probe_sig[i])
30a279be
FCE
4246 {
4247 case 'N': probe_sig_expanded += "int64_t"; break;
4248 case 'S': probe_sig_expanded += "const char *"; break;
e38d6504 4249 default:
30a279be
FCE
4250 throw semantic_error ("unsupported probe signature " + probe_sig,
4251 this->tok);
4252 }
e38d6504 4253 probe_sig_expanded += " arg" + lex_cast<string>(i+1); // arg1 ...
30a279be 4254 }
35d4ab18
FCE
4255
4256 // Now make a local-variable-expanded copy of the probe body
4257 mark_var_expanding_copy_visitor v (sess, probe_sig, name);
4258 require <block*> (&v, &(this->body), base->body);
4259
4260 if (sess.verbose > 1)
4261 clog << "marker-based " << name << " address=0x" << hex << address << dec
4262 << " signature=" << probe_sig << endl;
30a279be
FCE
4263}
4264
4265
dc38c0ae
DS
4266void
4267mark_derived_probe::register_probe(systemtap_session& s)
4268{
4269 s.probes.register_probe(this);
4270}
4271
4272
30a279be 4273void
35d4ab18
FCE
4274mark_derived_probe::emit_probe_context_vars (translator_output* o)
4275{
4276 // Save incoming arguments
4277 for (unsigned i=0; i<probe_sig.length(); i++)
4278 {
4279 string localname = "__mark_arg" + lex_cast<string>(i+1);
e38d6504 4280 switch (probe_sig[i])
35d4ab18
FCE
4281 {
4282 case 'S': o->newline() << "string_t " << localname << ";"; break;
4283 case 'N': o->newline() << "int64_t " << localname << ";"; break;
4284 }
4285 }
4286}
4287
4288
4289void
4290mark_derived_probe::emit_probe_entries (translator_output* o)
30a279be
FCE
4291{
4292 assert (this->locations.size() == 1);
4293
ffd1346f 4294 o->newline() << "static void enter_" << name << " (" << probe_sig_expanded << ")";
30a279be
FCE
4295 o->newline() << "{";
4296 o->newline(1) << "const char* probe_point = "
4297 << lex_cast_qstring(* this->locations[0]) << ";";
4298 emit_probe_prologue (o, "STAP_SESSION_RUNNING");
4299
35d4ab18
FCE
4300 // Save incoming arguments
4301 for (unsigned k=0; k<probe_sig.length(); k++)
4302 {
4303 string locals = "c->locals[0]." + name;
4304 string localname = locals + ".__mark_arg" + lex_cast<string>(k+1);
4305 string argname = "arg" + lex_cast<string>(k+1);
e38d6504 4306 switch (probe_sig[k])
35d4ab18
FCE
4307 {
4308 case 'S': o->newline() << "strlcpy (" << localname << ", " << argname
4309 << ", MAXSTRINGLEN);"; break;
e38d6504 4310 // XXX: dupe with c_unparser::c_strcpy
35d4ab18
FCE
4311 case 'N': o->newline() << localname << " = " << argname << ";"; break;
4312 }
4313 }
30a279be
FCE
4314
4315 // NB: locals are initialized by probe function itself
35d4ab18 4316 o->newline() << name << " (c);";
30a279be
FCE
4317
4318 emit_probe_epilogue (o);
4319 o->newline(-1) << "}";
4320}
4321
4322
4323void
46b84a80
DS
4324mark_derived_probe::emit_registrations_start (translator_output* o,
4325 unsigned index)
30a279be
FCE
4326{
4327 assert (this->locations.size() == 1);
4328
4329 o->newline() << "{";
4330 o->newline(1) << "void (**fn) (" << probe_sig_expanded << ") = (void *)"
4331 << address << "UL;";
4332
4a5e8a70
FCE
4333 o->newline() << "#if __HAVE_ARCH_CMPXCHG";
4334 o->newline() << "unsigned long *fnpp = (unsigned long *) (void *) fn;";
35d4ab18 4335 o->newline() << "unsigned long fnp = (unsigned long) (void *) & enter_" << name << ";";
4a5e8a70
FCE
4336 o->newline() << "unsigned long oldval = cmpxchg (fnpp, 0, fnp);";
4337 o->newline() << "if (oldval != 0) rc = 1;"; // XXX: could retry a few times
4338 o->newline() << "#else";
dc223023 4339 // XXX: need proper synchronization for concurrent registration attempts
35d4ab18 4340 o->newline() << "if (*fn == 0) *fn = & enter_" << name << ";";
4a5e8a70 4341 o->newline() << "#endif";
30a279be 4342 o->newline() << "mb ();";
35d4ab18 4343 o->newline() << "if (*fn != & enter_" << name << ") rc = 1;";
30a279be
FCE
4344
4345 o->newline(-1) << "}";
e38d6504 4346
46b84a80
DS
4347
4348 // if one failed, must goto code (output by emit_registrations_end)
4349 // that will roll back completed registations for this probe
4350 o->newline() << "if (unlikely (rc)) {";
4351 o->newline(1) << "probe_point = "
4352 << lex_cast_qstring (*this->locations[0]) << ";";
4353 if (index == 0)
4354 o->newline() << "goto mark_error;";
4355 else
4356 o->newline() << "goto unwind_mark_" << index - 1 << ";";
4357 o->newline(-1) << "}";
4358}
4359
4360
4361void
4362mark_derived_probe::emit_registrations_end (translator_output* o,
4363 unsigned index)
4364{
4365 // if one failed, must roll back completed registations for this probe
4366 o->newline(-1) << "unwind_mark_" << index << ":";
4367 o->indent(1);
4368 emit_deregistrations (o);
30a279be
FCE
4369}
4370
35d4ab18 4371
30a279be 4372void
35d4ab18 4373mark_derived_probe::emit_deregistrations (translator_output * o)
30a279be
FCE
4374{
4375 assert (this->locations.size() == 1);
4376
4377 o->newline() << "{";
4378 o->newline(1) << "void (**fn) (" << probe_sig_expanded << ") = (void *)"
4379 << address << "UL;";
4a5e8a70
FCE
4380 o->newline() << "#if __HAVE_ARCH_CMPXCHG";
4381 o->newline() << "unsigned long *fnpp = (unsigned long *) (void *) fn;";
35d4ab18 4382 o->newline() << "unsigned long fnp = (unsigned long) (void *) & enter_" << name << ";";
4a5e8a70
FCE
4383 o->newline() << "unsigned long oldval = cmpxchg (fnpp, fnp, 0);";
4384 o->newline() << "if (oldval != fnp) ;"; // XXX: should not happen
4385 o->newline() << "#else";
30a279be 4386 o->newline(0) << "*fn = 0;";
4a5e8a70 4387 o->newline() << "#endif";
30a279be
FCE
4388 o->newline(-1) << "}";
4389}
4390
4391
dc38c0ae
DS
4392struct mark_derived_probe_group: public derived_probe_group
4393{
4394private:
4395 vector<mark_derived_probe*> probes;
4396
4397public:
4398 virtual void register_probe(mark_derived_probe* p) { probes.push_back (p); }
4399 virtual size_t size () { return probes.size (); }
4400
4401 virtual void emit_probes (translator_output* op, unparser* up);
46b84a80 4402 virtual void emit_module_init (translator_output* o);
dc38c0ae
DS
4403};
4404
4405
4406void
4407mark_derived_probe_group::emit_probes (translator_output* op, unparser* up)
4408{
4409 for (unsigned i=0; i < probes.size(); i++)
4410 {
4411 op->newline ();
4412 up->emit_probe (probes[i]);
4413 }
4414}
4415
30a279be 4416
46b84a80
DS
4417void
4418mark_derived_probe_group::emit_module_init (translator_output* o)
4419{
4420 if (probes.size () == 0)
4421 return;
4422
4423 // Output the mark probes create function
4424 o->newline() << "static int register_mark_probes (void) {";
4425 o->indent(1);
4426 o->newline() << "int rc = 0;";
4427 o->newline() << "const char *probe_point;";
4428
4429 for (unsigned i=0; i < probes.size (); i++)
4430 probes[i]->emit_registrations_start (o, i);
4431
4432 o->newline() << "goto out;";
4433 o->newline();
4434
4435 for (int i=probes.size() - 2; i >= 0; i--)
4436 probes[i]->emit_registrations_end (o, i);
4437
4438 o->newline();
4439
4440 o->newline(-1) << "mark_error:";
4441 o->newline(1) << "if (unlikely (rc)) {";
4442 // In case it's just a lower-layer (kprobes) error that set rc but
4443 // not session_state, do that here to prevent any other BEGIN probe
4444 // from attempting to run.
4445 o->newline(1) << "atomic_set (&session_state, STAP_SESSION_ERROR);";
4446 o->newline() << "_stp_error (\"mark probe %s registration failed, rc=%d\\n\", probe_point, rc);";
4447 o->newline(-1) << "}\n";
4448
4449 o->newline(-1) << "out:";
4450 o->newline(1) << "return rc;";
4451 o->newline(-1) << "}\n";
4452
4453 // Output the mark probes destroy function
4454 o->newline() << "static void unregister_mark_probes (void) {";
4455 o->indent(1);
4456
4457 for (unsigned i=0; i < probes.size (); i++)
4458 {
4459 probes[i]->emit_deregistrations (o);
4460 emit_probe_timing(probes[i], o);
4461 }
4462
4463 o->newline(-1) << "}\n";
4464}
4465
4466
30a279be
FCE
4467struct symboltable_extract
4468{
4469 uintptr_t address;
4470 string symbol;
4471 string module;
4472};
4473
4474
4475#define PROBE_SYMBOL_PREFIX "__systemtap_mark_"
4476
4477
4478struct mark_builder: public derived_probe_builder
4479{
4480private:
4481 static const vector<symboltable_extract>* get_symbols (systemtap_session&);
4482
4483public:
4484 mark_builder() {}
4485 void build(systemtap_session & sess,
4486 probe * base,
4487 probe_point * location,
4488 std::map<std::string, literal *> const & parameters,
4489 vector<derived_probe *> & finished_results);
4490};
4491
4492
4493// Until elfutils makes this straightforward, we kludge.
4494// See also translate.cxx:emit_symbol_data().
4495
4496const vector<symboltable_extract>*
4497mark_builder::get_symbols (systemtap_session& sess)
4498{
4499 static vector<symboltable_extract>* syms = 0;
4500 if (syms) return syms; // already computed
4501
4502 syms = new vector<symboltable_extract>;
4503
4504 // Process /proc/kallsyms - contains reliable module symbols
4505 ifstream kallsyms ("/proc/kallsyms");
4506 while (! kallsyms.eof())
4507 {
4508 string addr, type, sym, module;
4509 kallsyms >> addr >> type >> sym;
4510 kallsyms >> ws;
4511 if (kallsyms.peek() == '[')
4512 {
4513 string bracketed;
4514 kallsyms >> bracketed;
4515 module = bracketed.substr (1, bracketed.length()-2);
4516 }
4517 else // kernel symbols come from /boot/System.map*
4518 continue;
4519
4520 if (type == "b" || type == "d") // static data/bss
4521 {
4522 symboltable_extract e;
4523 e.address = strtoul (addr.c_str(), 0, 16);
4524 e.symbol = sym;
4525 e.module = module;
4526 syms->push_back (e);
4527 }
4528 }
4529 kallsyms.close ();
4530
4531 // grab them kernel symbols
4532 string smname = "/boot/System.map-";
4533 smname += sess.kernel_release;
4534 ifstream systemmap (smname.c_str());
4535 while (! systemmap.eof())
4536 {
4537 string addr, type, sym, module;
4538 systemmap >> addr >> type >> sym;
4539 module = "";
4540
4541 if (type == "b" || type == "d") // static data/bss
4542 {
4543 symboltable_extract e;
4544 e.address = strtoul (addr.c_str(), 0, 16);
4545 e.symbol = sym;
4546 e.module = module;
4547 syms->push_back (e);
4548 }
4549 }
4550 systemmap.close ();
4551
4552 return syms;
4553}
4554
4555
4556void
4557mark_builder::build(systemtap_session & sess,
4558 probe * base,
4559 probe_point * location,
4560 std::map<std::string, literal *> const & parameters,
4561 vector<derived_probe *> & finished_results)
4562{
4563 const vector<symboltable_extract>* syms = get_symbols (sess);
4564
4565 string param_module;
4566 bool has_module = get_param (parameters, "module", param_module);
4567 bool has_kernel = (parameters.find("kernel") != parameters.end());
4568
4569 if (! (has_module ^ has_kernel))
35d4ab18 4570 throw semantic_error ("need kernel or module() component", location->tok);
30a279be
FCE
4571
4572 string param_probe;
4573 bool has_probe = get_param (parameters, "mark", param_probe);
4574 if (! has_probe)
4575 throw semantic_error ("need mark() component", location->tok);
4576
4577 string symbol_regex = PROBE_SYMBOL_PREFIX "([a-zA-Z0-9_]+)_([NS]*)\\.[0-9]+";
4578 // ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^ ^^^^^^
4579 // common prefix probe name types suffix
4580 regex_t symbol_regex_t;
4581 int rc = regcomp (& symbol_regex_t, symbol_regex.c_str(), REG_EXTENDED);
4582 if (rc)
4583 throw semantic_error ("regcomp '" + symbol_regex + "' failed");
4584
4585 // cout << "searching for " << symbol_regex << endl;
4586
4587 for (unsigned i=0; i<syms->size(); i++)
4588 {
4589 regmatch_t match[3];
4590 const symboltable_extract& ext = syms->at(i);
4591 const char* symstr = ext.symbol.c_str();
4592
4593 rc = regexec (& symbol_regex_t, symstr, 3, match, 0);
4594 if (! rc) // match
4595 {
4596#if 0
4597 cout << "match in " << symstr << ":"
4598 << "[" << match[0].rm_so << "-" << match[0].rm_eo << "],"
4599 << "[" << match[1].rm_so << "-" << match[1].rm_eo << "],"
4600 << "[" << match[2].rm_so << "-" << match[2].rm_eo << "]"
4601 << endl;
4602#endif
4603
4604 string probe_name = string (symstr + match[1].rm_so,
4605 (match[1].rm_eo - match[1].rm_so));
4606 string probe_sig = string (symstr + match[2].rm_so,
4607 (match[2].rm_eo - match[2].rm_so));
4608
4609 // Below, "rc" has negative polarity: zero iff matching
e38d6504 4610 rc = (has_module
30a279be
FCE
4611 ? fnmatch (param_module.c_str(), ext.module.c_str(), 0)
4612 : (ext.module != "")); // kernel.*
4613 rc |= fnmatch (param_probe.c_str(), probe_name.c_str(), 0);
e38d6504 4614
30a279be
FCE
4615 if (! rc)
4616 {
4617 // cout << "match (" << probe_name << "):" << probe_sig << endl;
4618
e38d6504 4619 derived_probe *dp
30a279be
FCE
4620 = new mark_derived_probe (sess,
4621 probe_name, probe_sig,
4622 ext.address,
4623 ext.module,
4624 base);
4625 finished_results.push_back (dp);
4626 }
4627 }
4628 }
4629
4630 // cout << "done" << endl;
4631
4632 // It's not a big deal if this is skipped due to an exception.
4633 regfree (& symbol_regex_t);
4634}
4635
4636
56894e91
JS
4637// ------------------------------------------------------------------------
4638// hrtimer derived probes
4639// ------------------------------------------------------------------------
4640// This is a new timer interface that provides more flexibility in specifying
4641// intervals, and uses the hrtimer APIs when available for greater precision.
4642// As of 2.6.16, these APIs don't have the needed EXPORT_SYMBOL_GPL, so we
4643// can't make use of them yet.
4644//
4645// There are two classes defined below:
4646// * hrtimer_derived_probe: creates a probe point based on the hrtimer APIs.
4647// * hrtimer_builder: parses the user's time-spec into a 64-bit nanosecond
4648// value, and calls the appropriate derived_probe.
4649
4650
4651struct hrtimer_derived_probe: public derived_probe
4652{
4653 // set a (generous) maximum of one day in ns
4654 static const int64_t max_ns_interval = 1000000000LL * 60LL * 60LL * 24LL;
4655
4656 // 100us seems like a reasonable minimum
4657 static const int64_t min_ns_interval = 100000LL;
4658
4659 int64_t interval, randomize;
4660
4661 hrtimer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r):
4662 derived_probe (p, l), interval (i), randomize (r)
4663 {
4664 if ((i < min_ns_interval) || (i > max_ns_interval))
4665 throw semantic_error("interval value out of range");
4666
4667 // randomize = 0 means no randomization
4668 if ((r < 0) || (r > i))
4669 throw semantic_error("randomization value out of range");
4670
4671 if (locations.size() != 1)
4672 throw semantic_error ("expect single probe point");
4673 // so we don't have to loop over them in the other functions
4674 }
4675
dc38c0ae
DS
4676 void register_probe (systemtap_session& s);
4677
56894e91
JS
4678 virtual void emit_interval (translator_output * o);
4679
46b84a80
DS
4680 virtual void emit_registrations_start (translator_output * o,
4681 unsigned index);
4682 virtual void emit_registrations_end (translator_output * o,
4683 unsigned index);
35d4ab18
FCE
4684 virtual void emit_deregistrations (translator_output * o);
4685 virtual void emit_probe_entries (translator_output * o);
56894e91
JS
4686};
4687
4688
dc38c0ae
DS
4689void
4690hrtimer_derived_probe::register_probe(systemtap_session& s)
4691{
4692 s.probes.register_probe(this);
4693}
4694
4695
56894e91
JS
4696void
4697hrtimer_derived_probe::emit_interval (translator_output* o)
4698{
4699 o->line() << "({";
ffb0b3ad 4700 o->newline(1) << "unsigned long nsecs;";
56894e91
JS
4701 o->newline() << "int64_t i = " << interval << "LL;";
4702 if (randomize != 0)
e38d6504 4703 {
56894e91
JS
4704 o->newline() << "int64_t r;";
4705 o->newline() << "get_random_bytes(&r, sizeof(r));";
4706 o->newline() << "r &= ((uint64_t)1 << (8*sizeof(r) - 1)) - 1;";
4707 o->newline() << "r = _stp_mod64(NULL, r, " << (2*randomize + 1) << "LL);";
4708 o->newline() << "r -= " << randomize << "LL;";
4709 o->newline() << "i += r;";
4710 o->newline() << "if (unlikely(i < " << min_ns_interval << "LL))";
4711 o->newline(1) << "i = " << min_ns_interval << "LL;";
4712 o->indent(-1);
4713 }
ffb0b3ad
JS
4714 o->newline() << "nsecs = do_div(i, NSEC_PER_SEC);";
4715 o->newline() << "ktime_set(i, nsecs);";
56894e91
JS
4716 o->newline(-1) << "})";
4717}
4718
4719
4720void
46b84a80
DS
4721hrtimer_derived_probe::emit_registrations_start (translator_output* o,
4722 unsigned index)
56894e91 4723{
35d4ab18 4724 o->newline() << "hrtimer_init (& timer_" << name
56894e91 4725 << ", CLOCK_MONOTONIC, HRTIMER_REL);";
35d4ab18
FCE
4726 o->newline() << "timer_" << name << ".function = enter_" << name << ";";
4727 o->newline() << "hrtimer_start (& timer_" << name << ", ";
56894e91
JS
4728 emit_interval(o);
4729 o->line() << ", HRTIMER_REL);";
4730}
4731
4732
46b84a80
DS
4733void
4734hrtimer_derived_probe::emit_registrations_end (translator_output* o,
4735 unsigned index)
4736{
4737 // nothing to do here...
4738}
4739
4740
56894e91 4741void
35d4ab18 4742hrtimer_derived_probe::emit_deregistrations (translator_output* o)
56894e91 4743{
35d4ab18 4744 o->newline() << "hrtimer_cancel (& timer_" << name << ");";
56894e91
JS
4745}
4746
4747
4748void
35d4ab18 4749hrtimer_derived_probe::emit_probe_entries (translator_output* o)
56894e91 4750{
a68f81a2 4751 o->newline() << "static int enter_" << name << " (struct hrtimer *);";
35d4ab18 4752 o->newline() << "static struct hrtimer timer_" << name << ";";
56894e91 4753
a68f81a2 4754 o->newline() << "int enter_" << name << " (struct hrtimer *timer) {";
56894e91
JS
4755 o->indent(1);
4756 o->newline() << "const char* probe_point = "
4757 << lex_cast_qstring(*locations[0]) << ";";
4758 emit_probe_prologue (o, "STAP_SESSION_RUNNING");
4759
a68f81a2 4760 o->newline() << "(void) timer;";
56894e91 4761
ffb0b3ad 4762 o->newline() << "hrtimer_start (& timer_" << name << ", ";
56894e91 4763 emit_interval(o);
ffb0b3ad 4764 o->line() << ", HRTIMER_REL);";
56894e91
JS
4765
4766 // NB: locals are initialized by probe function itself
35d4ab18 4767 o->newline() << name << " (c);";
56894e91
JS
4768
4769 emit_probe_epilogue (o);
a68f81a2
JS
4770
4771 // Return NORESTART, because we already requeued the timer above
4772 o->newline() << "return HRTIMER_NORESTART;";
56894e91
JS
4773 o->newline(-1) << "}\n";
4774}
4775
4776
dc38c0ae
DS
4777struct hrtimer_derived_probe_group: public derived_probe_group
4778{
4779private:
4780 vector<hrtimer_derived_probe*> probes;
4781
4782public:
4783 virtual void register_probe(hrtimer_derived_probe* p) { probes.push_back (p); }
4784 virtual size_t size () { return probes.size (); }
4785
4786 virtual void emit_probes (translator_output* op, unparser* up);
46b84a80 4787 virtual void emit_module_init (translator_output* o);
dc38c0ae
DS
4788};
4789
4790
4791void
4792hrtimer_derived_probe_group::emit_probes (translator_output* op, unparser* up)
4793{
4794 for (unsigned i=0; i < probes.size(); i++)
4795 {
4796 op->newline ();
4797 up->emit_probe (probes[i]);
4798 }
4799}
4800
4801
46b84a80
DS
4802void
4803hrtimer_derived_probe_group::emit_module_init (translator_output* o)
4804{
4805 if (probes.size () == 0)
4806 return;
4807
4808 // Output the hrtimer probes create function
4809 o->newline() << "static int register_hrtimer_probes (void) {";
4810 o->indent(1);
4811
4812 for (unsigned i=0; i < probes.size (); i++)
4813 {
4814 probes[i]->emit_registrations_start (o, i);
4815 o->newline ();
4816 }
4817
4818 o->newline() << "return 0;";
4819 o->newline(-1) << "}\n";
4820
4821 // Output the hrtimer probes destroy function
4822 o->newline() << "static void unregister_hrtimer_probes (void) {";
4823 o->indent(1);
4824
4825 for (unsigned i=0; i < probes.size (); i++)
4826 {
4827 probes[i]->emit_deregistrations (o);
4828 emit_probe_timing(probes[i], o);
4829 }
4830
4831 o->newline(-1) << "}\n";
4832}
4833
56894e91
JS
4834struct hrtimer_builder: public derived_probe_builder
4835{
4836 hrtimer_builder() {}
4837 static int64_t convert_to_ns(const string &time);
4838 virtual void build(systemtap_session & sess,
4839 probe * base,
4840 probe_point * location,
4841 std::map<std::string, literal *> const & parameters,
4842 vector<derived_probe *> & finished_results)
4843 {
4844 string interval, randomize;
4845 int64_t i_ns, r_ns;
4846
4847 if (!get_param (parameters, "hrtimer", interval))
4848 throw semantic_error("timer requires an interval");
4849 i_ns = convert_to_ns(interval);
4850 if (sess.verbose > 1)
4851 clog << "parsed timer interval '" << interval
4852 << "' to " << i_ns << " ns. "<< endl;
4853
4854 if (get_param (parameters, "randomize", randomize))
4855 {
4856 r_ns = convert_to_ns(randomize);
4857 if (sess.verbose > 1)
4858 clog << "parsed timer randomization '" << randomize
4859 << "' to " << r_ns << " ns. "<< endl;
4860 }
4861 else
4862 r_ns = 0;
4863
4864 string target_kernel_v;
4865
a68f81a2
JS
4866 // cut off any release code suffix
4867 string::size_type dash_index = sess.kernel_release.find ('-');
4868 if (dash_index > 0 && dash_index != string::npos)
4869 target_kernel_v = sess.kernel_release.substr (0, dash_index);
4870 else
4871 target_kernel_v = sess.kernel_release;
4872
4873 // hrtimers are only exported starting in 2.6.17
4874 if (strverscmp(target_kernel_v.c_str(), "2.6.17") >= 0)
56894e91
JS
4875 finished_results.push_back(
4876 new hrtimer_derived_probe(base, location, i_ns, r_ns));
4877 else
4878 {
4879 int64_t i_ms = (i_ns + 999999) / 1000000;
4880 int64_t r_ms = (r_ns + 999999) / 1000000;
4881
4882 if (sess.verbose > 2)
4883 {
4884 clog << "rounded timer interval from "
4885 << i_ns << " ns to " << i_ms <<" ms. "<< endl;
4886 clog << "rounded timer randomization from "
4887 << i_ns << " ns to " << i_ms <<" ms. "<< endl;
4888 }
e38d6504 4889
56894e91
JS
4890 finished_results.push_back(
4891 new timer_derived_probe(base, location, i_ms, r_ms, true));
4892 }
4893 }
4894};
4895
4896
4897int64_t
4898hrtimer_builder::convert_to_ns(const string &time)
4899{
4900 int64_t ns;
4901 int64_t num;
4902 string unit;
4903 istringstream iss(time);
4904
4905 iss >> num >> unit;
4906 if (iss.fail() || num==0) goto bad_time;
4907
4908 if ((unit == "hz") || (unit == "hertz"))
4909 {
4910 ns = 1000000000/num;
4911 iss >> unit;
4912 if (!iss.fail()) goto bad_time;
4913 return ns;
4914 }
4915
4916 ns = 0;
4917 do
4918 {
4919 if ((unit == "ns") || (unit == "nsec"))
4920 goto unit_parsed;
4921
4922 num *= 1000;
4923 if ((unit == "us") || (unit == "usec"))
4924 goto unit_parsed;
4925
4926 num *= 1000;
4927 if ((unit == "ms") || (unit == "msec"))
4928 goto unit_parsed;
4929
4930 num *= 1000;
4931 if ((unit == "s") || (unit == "sec"))
4932 goto unit_parsed;
4933
4934 num *= 60;
4935 if ((unit == "m") || (unit == "min"))
4936 goto unit_parsed;
4937
4938 num *= 60;
4939 if ((unit == "h") || (unit == "hour"))
4940 goto unit_parsed;
4941
4942 goto bad_time;
4943
4944unit_parsed:
4945 ns += num;
4946
4947 iss >> num;
4948 if (iss.fail()) break;
4949 iss >> unit;
4950 if (iss.fail() || num==0) goto bad_time;
4951 }
4952 while (1);
4953
4954 return ns;
4955
4956bad_time:
4957 throw semantic_error("bad time parameter: '" + time + "'");
4958}
4959
4960
47dd066d
WC
4961// ------------------------------------------------------------------------
4962// perfmon derived probes
4963// ------------------------------------------------------------------------
4964// This is a new interface to the perfmon hw.
4965//
4966
4967
4968struct perfmon_var_expanding_copy_visitor: public var_expanding_copy_visitor
4969{
4970 systemtap_session & sess;
4971 unsigned counter_number;
4972 perfmon_var_expanding_copy_visitor(systemtap_session & s, unsigned c):
4973 sess(s), counter_number(c) {}
4974 void visit_target_symbol (target_symbol* e);
4975};
4976
4977
4978void
4979perfmon_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
4980{
4981 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
4982
4983 // Synthesize a function.
4984 functiondecl *fdecl = new functiondecl;
4985 fdecl->tok = e->tok;
4986 embeddedcode *ec = new embeddedcode;
4987 ec->tok = e->tok;
4988 bool lvalue = is_active_lvalue(e);
4989
4990 if (lvalue )
4991 throw semantic_error("writes to $counter not permitted");
4992
4993 string fname = string("_perfmon_tvar_get")
4994 + "_" + e->base_name.substr(1)
4995 + "_" + lex_cast<string>(counter_number);
4996
4997 if (e->base_name != "$counter")
4998 throw semantic_error ("target variables not available to perfmon probes");
4999
5000 ec->code = "THIS->__retvalue = _pfm_pmd_x[" +
5001 lex_cast<string>(counter_number) + "].reg_num;";
5002 ec->code += "/* pure */";
5003 fdecl->name = fname;
5004 fdecl->body = ec;
5005 fdecl->type = pe_long;
5006 sess.functions.push_back(fdecl);
5007
5008 // Synthesize a functioncall.
5009 functioncall* n = new functioncall;
5010 n->tok = e->tok;
5011 n->function = fname;
5012 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
5013
5014 provide <functioncall*> (this, n);
5015}
5016
5017
5018enum perfmon_mode
5019{
5020 perfmon_count,
5021 perfmon_sample
5022};
5023
5024
5025struct perfmon_derived_probe: public derived_probe
5026{
5027protected:
5028 static unsigned probes_allocated;
5029
5030public:
5031 systemtap_session & sess;
5032 string event;
5033 perfmon_mode mode;
5034
5035 perfmon_derived_probe (probe* p, probe_point* l, systemtap_session &s,
5036 string e, perfmon_mode m);
5037 virtual void register_probe (systemtap_session& s);
5038 virtual void emit_registrations_start (translator_output* o, unsigned index);
5039 virtual void emit_registrations_end (translator_output * o, unsigned index);
5040 virtual void emit_deregistrations (translator_output * o);
5041 virtual void emit_probe_entries (translator_output * o);
5042};
5043
5044
5045struct perfmon_derived_probe_group: public derived_probe_group
5046{
5047private:
5048 vector<perfmon_derived_probe*> probes;
5049
5050public:
5051 virtual void register_probe(perfmon_derived_probe* p)
5052 { probes.push_back (p); }
5053 virtual size_t size () { return probes.size (); }
5054 virtual void emit_probes (translator_output* op, unparser* up);
5055 virtual void emit_module_init (translator_output* o);
5056};
5057
5058
5059struct perfmon_builder: public derived_probe_builder
5060{
5061 perfmon_builder() {}
5062 virtual void build(systemtap_session & sess,
5063 probe * base,
5064 probe_point * location,
5065 std::map<std::string, literal *> const & parameters,
5066 vector<derived_probe *> & finished_results)
5067 {
5068 string event;
5069 if (!get_param (parameters, "counter", event))
5070 throw semantic_error("perfmon requires an event");
5071
5072 sess.perfmon++;
5073
5074 // XXX: need to revise when doing sampling
5075 finished_results.push_back(new perfmon_derived_probe(base, location,
5076 sess, event,
5077 perfmon_count));
5078 }
5079};
5080
5081unsigned perfmon_derived_probe::probes_allocated;
5082
5083perfmon_derived_probe::perfmon_derived_probe (probe* p, probe_point* l,
5084 systemtap_session &s,
5085 string e, perfmon_mode m)
5086 : derived_probe (p, l), sess(s), event(e), mode(m)
5087{
5088 ++probes_allocated;
5089
5090 // Now make a local-variable-expanded copy of the probe body
5091 perfmon_var_expanding_copy_visitor v (sess, probes_allocated-1);
5092 require <block*> (&v, &(this->body), base->body);
5093
5094 if (sess.verbose > 1)
5095 clog << "perfmon-based probe" << endl;
5096}
5097
5098
5099void
5100perfmon_derived_probe::register_probe (systemtap_session& s)
5101{
5102 s.probes.register_probe(this);
5103}
5104
5105
5106void
5107perfmon_derived_probe::emit_registrations_start (translator_output* o,
5108 unsigned index)
5109{
5110 for (unsigned i=0; i<locations.size(); i++)
5111 o->newline() << "enter_" << name << "_" << i << " ();";
5112}
5113
5114
5115void
5116perfmon_derived_probe::emit_registrations_end (translator_output * o,
5117 unsigned index)
5118{
5119}
5120
5121
5122void
5123perfmon_derived_probe::emit_deregistrations (translator_output * o)
5124{
5125}
5126
5127
5128void
5129perfmon_derived_probe::emit_probe_entries (translator_output * o)
5130{
5131 o->newline() << "#ifdef STP_TIMING";
5132 o->newline() << "static __cacheline_aligned Stat " << "time_" << basest()->name << ";";
5133 o->newline() << "#endif";
5134
5135 for (unsigned i=0; i<locations.size(); i++)
5136 {
5137 probe_point *l = locations[i];
5138 o->newline() << "/* location " << i << ": " << *l << " */";
5139 o->newline() << "static void enter_" << name << "_" << i << " (void) {";
5140
5141 o->indent(1);
5142 o->newline() << "const char* probe_point = "
5143 << lex_cast_qstring(*l) << ";";
5144 emit_probe_prologue (o,
5145 (mode == perfmon_count ?
5146 "STAP_SESSION_STARTING" :
5147 "STAP_SESSION_RUNNING"));
5148
5149 // NB: locals are initialized by probe function itself
5150 o->newline() << name << " (c);";
5151
5152 emit_probe_epilogue (o);
5153
5154 o->newline(-1) << "}\n";
5155 }
5156}
5157
5158
5159#ifdef PERFMON
5160void no_pfm_event_error (string s)
5161{
5162 string msg(string("Cannot find event:" + s));
5163 throw semantic_error(msg);
5164}
5165
5166
5167void no_pfm_mask_error (string s)
5168{
5169 string msg(string("Cannot find mask:" + s));
5170 throw semantic_error(msg);
5171}
5172
5173
5174void
5175split(const string& s, vector<string>& v, const string & separator)
5176{
5177 string::size_type last_pos = s.find_first_not_of(separator, 0);
5178 string::size_type pos = s.find_first_of(separator, last_pos);
5179
5180 while (string::npos != pos || string::npos != last_pos) {
5181 v.push_back(s.substr(last_pos, pos - last_pos));
5182 last_pos = s.find_first_not_of(separator, pos);
5183 pos = s.find_first_of(separator, last_pos);
5184 }
5185}
5186
5187
5188void
5189perfmon_derived_probe_group::emit_probes (translator_output* op, unparser* up)
5190{
5191 for (unsigned i=0; i < probes.size(); i++)
5192 {
5193 op->newline ();
5194 up->emit_probe (probes[i]);
5195 }
5196}
5197
5198
5199void
5200perfmon_derived_probe_group::emit_module_init (translator_output* o)
5201{
5202 int ret;
5203 pfmlib_input_param_t inp;
5204 pfmlib_output_param_t outp;
5205 pfarg_pmd_t pd[PFMLIB_MAX_PMDS];
5206 pfarg_pmc_t pc[PFMLIB_MAX_PMCS];
5207 pfarg_ctx_t ctx;
5208 pfarg_load_t load_args;
5209 pfmlib_options_t pfmlib_options;
5210 unsigned int max_counters;
5211
5212 if ( probes.size() == 0)
5213 return;
5214 ret = pfm_initialize();
5215 if (ret != PFMLIB_SUCCESS)
5216 throw semantic_error("Unable to generate performance monitoring events (no libpfm)");
5217
5218 pfm_get_num_counters(&max_counters);
5219
5220 memset(&pfmlib_options, 0, sizeof(pfmlib_options));
5221 pfmlib_options.pfm_debug = 0; /* set to 1 for debug */
5222 pfmlib_options.pfm_verbose = 0; /* set to 1 for debug */
5223 pfm_set_options(&pfmlib_options);
5224
5225 memset(pd, 0, sizeof(pd));
5226 memset(pc, 0, sizeof(pc));
5227 memset(&ctx, 0, sizeof(ctx));
5228 memset(&load_args, 0, sizeof(load_args));
5229
5230 /*
5231 * prepare parameters to library.
5232 */
5233 memset(&inp,0, sizeof(inp));
5234 memset(&outp,0, sizeof(outp));
5235
5236 /* figure out the events */
5237 for (unsigned i=0; i<probes.size(); ++i)
5238 {
5239 if (probes[i]->event == "cycles") {
5240 if (pfm_get_cycle_event( &inp.pfp_events[i].event) != PFMLIB_SUCCESS)
5241 no_pfm_event_error(probes[i]->event);
5242 } else if (probes[i]->event == "instructions") {
5243 if (pfm_get_inst_retired_event( &inp.pfp_events[i].event) !=
5244 PFMLIB_SUCCESS)
5245 no_pfm_event_error(probes[i]->event);
5246 } else {
5247 unsigned int event_id = 0;
5248 unsigned int mask_id = 0;
5249 vector<string> event_spec;
5250 split(probes[i]->event, event_spec, ":");
5251 int num = event_spec.size();
5252 int masks = num - 1;
5253
5254 if (num == 0)
5255 throw semantic_error("No events found");
5256
5257 /* setup event */
5258 if (pfm_find_event(event_spec[0].c_str(), &event_id) != PFMLIB_SUCCESS)
5259 no_pfm_event_error(event_spec[0]);
5260 inp.pfp_events[i].event = event_id;
5261
5262 /* set up masks */
5263 if (masks > PFMLIB_MAX_MASKS_PER_EVENT)
5264 throw semantic_error("Too many unit masks specified");
5265
5266 for (int j=0; j < masks; j++) {
5267 if (pfm_find_event_mask(event_id, event_spec[j+1].c_str(),
5268 &mask_id) != PFMLIB_SUCCESS)
5269 no_pfm_mask_error(string(event_spec[j+1]));
5270 inp.pfp_events[i].unit_masks[j] = mask_id;
5271 }
5272 inp.pfp_events[i].num_masks = masks;
5273 }
5274 }
5275
5276 /* number of counters in use */
5277 inp.pfp_event_count = probes.size();
5278
5279 // XXX: no elimination of duplicated counters
5280 if (inp.pfp_event_count>max_counters)
5281 throw semantic_error("Too many performance monitoring events.");
5282
5283 /* count events both in kernel and user-space */
5284 inp.pfp_dfl_plm = PFM_PLM0 | PFM_PLM3;
5285
5286 /* XXX: some cases a perfmon register might be used of watch dog
5287 this code doesn't handle that case */
5288
5289 /* figure out the pmcs for the events */
5290 if ((ret=pfm_dispatch_events(&inp, NULL, &outp, NULL)) != PFMLIB_SUCCESS)
5291 throw semantic_error("Cannot configure events");
5292
5293 for (unsigned i=0; i < outp.pfp_pmc_count; i++) {
5294 pc[i].reg_num = outp.pfp_pmcs[i].reg_num;
5295 pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
5296 }
5297
5298 /*
5299 * There could be more pmc settings than pmd.
5300 * Figure out the actual pmds to use.
5301 */
5302 for (unsigned i=0, j=0; i < inp.pfp_event_count; i++) {
5303 pd[i].reg_num = outp.pfp_pmcs[j].reg_pmd_num;
5304 for(; j < outp.pfp_pmc_count; j++)
5305 if (outp.pfp_pmcs[j].reg_evt_idx != i) break;
5306 }
5307
5308 // Output the be probes create function
5309 o->newline() << "static int register_perfmon_probes (void) {";
5310 o->newline(1) << "int rc = 0;";
5311
5312 o->newline() << "/* data for perfmon */";
5313 o->newline() << "static int _pfm_num_pmc = " << outp.pfp_pmc_count << ";";
5314 o->newline() << "static struct pfarg_pmc _pfm_pmc[" << outp.pfp_pmc_count
5315 << "] = {";
5316 /* output the needed bits for pmc here */
5317 for (unsigned i=0; i < outp.pfp_pmc_count; i++) {
5318 o->newline() << "{.reg_num=" << pc[i].reg_num << ", "
5319 << ".reg_value=" << lex_cast_hex<string>(pc[i].reg_value)
5320 << "},";
5321 }
5322
5323 o->newline() << "};";
5324 o->newline() << "static int _pfm_num_pmd = " << inp.pfp_event_count << ";";
5325 o->newline() << "static struct pfarg_pmd _pfm_pmd[" << inp.pfp_event_count
5326 << "] = {";
5327 /* output the needed bits for pmd here */
5328 for (unsigned i=0; i < inp.pfp_event_count; i++) {
5329 o->newline() << "{.reg_num=" << pd[i].reg_num << ", "
5330 << ".reg_value=" << pd[i].reg_value << "},";
5331 }
5332 o->newline() << "};";
5333 o->newline();
5334
5335 o->newline() << "_pfm_pmc_x=_pfm_pmc;";
5336 o->newline() << "_pfm_num_pmc_x=_pfm_num_pmc;";
5337 o->newline() << "_pfm_pmd_x=_pfm_pmd;";
5338 o->newline() << "_pfm_num_pmd_x=_pfm_num_pmd;";
5339
5340 // call all the function bodies associated with perfcounters
5341 for (unsigned i=0; i < probes.size (); i++)
5342 probes[i]->emit_registrations_start (o,i);
5343
5344 /* generate call to turn on instrumentation */
5345 o->newline() << "_pfm_context.ctx_flags |= PFM_FL_SYSTEM_WIDE;";
5346 o->newline() << "rc = rc || _stp_perfmon_setup(&_pfm_desc, &_pfm_context,";
5347 o->newline(1) << "_pfm_pmc, _pfm_num_pmc,";
5348 o->newline() << "_pfm_pmd, _pfm_num_pmd);";
5349 o->newline(-1);
5350
5351 o->newline() << "return rc;";
5352 o->newline(-1) << "}\n";
5353
5354 // Output the be probes destroy function
5355 o->newline() << "static void unregister_perfmon_probes (void) {";
5356 o->newline(1) << "_stp_perfmon_shutdown(_pfm_desc);";
5357 o->newline(-1) << "}\n";
5358}
5359#else
5360void
5361perfmon_derived_probe_group::emit_probes (translator_output* op, unparser* up)
5362{
5363}
5364
5365
5366void
5367perfmon_derived_probe_group::emit_module_init (translator_output* o)
5368{
47dd066d
WC
5369}
5370#endif /* PERFMON */
5371
b55bc428 5372// ------------------------------------------------------------------------
bd2b1e68 5373// Standard tapset registry.
b55bc428
FCE
5374// ------------------------------------------------------------------------
5375
7a053d3b 5376void
f8220a7b 5377register_standard_tapsets(systemtap_session & s)
b55bc428 5378{
f8220a7b
GH
5379 s.pattern_root->bind("begin")->bind(new be_builder(true));
5380 s.pattern_root->bind("end")->bind(new be_builder(false));
30a279be 5381
6e3347a9
FCE
5382 s.pattern_root->bind("never")->bind(new never_builder());
5383
98afd80e
FCE
5384 s.pattern_root->bind("timer")->bind_num("jiffies")->bind(new timer_builder());
5385 s.pattern_root->bind("timer")->bind_num("jiffies")->bind_num("randomize")->bind(new timer_builder());
422d1ceb
FCE
5386 s.pattern_root->bind("timer")->bind_num("ms")->bind(new timer_builder(true));
5387 s.pattern_root->bind("timer")->bind_num("ms")->bind_num("randomize")->bind(new timer_builder(true));
39e57ce0 5388 s.pattern_root->bind("timer")->bind("profile")->bind(new profile_builder());
56894e91
JS
5389 s.pattern_root->bind_str("hrtimer")->bind(new hrtimer_builder());
5390 s.pattern_root->bind_str("hrtimer")->bind_str("randomize")->bind(new hrtimer_builder());
47dd066d 5391 s.pattern_root->bind("perfmon")->bind_str("counter")->bind(new perfmon_builder());
b98a8d73 5392
30a279be 5393 // dwarf-based kernel/module parts
f8220a7b 5394 dwarf_derived_probe::register_patterns(s.pattern_root);
30a279be
FCE
5395
5396 // marker-based kernel/module parts
5397 s.pattern_root->bind("kernel")->bind_str("mark")->bind(new mark_builder());
5398 s.pattern_root->bind_str("module")->bind_str("mark")->bind(new mark_builder());
b55bc428 5399}
dc38c0ae
DS
5400
5401
5402derived_probe_group_container::derived_probe_group_container ():
5403 be_probe_group(new be_derived_probe_group),
5404 dwarf_probe_group(new dwarf_derived_probe_group),
5405 hrtimer_probe_group(new hrtimer_derived_probe_group),
5406 mark_probe_group(new mark_derived_probe_group),
5407 never_probe_group(new never_derived_probe_group),
5408 profile_probe_group(new profile_derived_probe_group),
47dd066d
WC
5409 timer_probe_group(new timer_derived_probe_group),
5410 perfmon_probe_group(new perfmon_derived_probe_group)
dc38c0ae
DS
5411{
5412}
5413
5414
5415derived_probe_group_container::~derived_probe_group_container ()
5416{
5417 delete be_probe_group;
5418 delete dwarf_probe_group;
5419 delete hrtimer_probe_group;
5420 delete mark_probe_group;
5421 delete never_probe_group;
5422 delete profile_probe_group;
5423 delete timer_probe_group;
47dd066d 5424 delete perfmon_probe_group;
dc38c0ae
DS
5425}
5426
5427
5428void
5429derived_probe_group_container::register_probe(be_derived_probe* p)
5430{
5431 probes.push_back (p);
5432 be_probe_group->register_probe(p);
5433}
5434
5435
5436void
5437derived_probe_group_container::register_probe(dwarf_derived_probe* p)
5438{
5439 probes.push_back (p);
5440 dwarf_probe_group->register_probe(p);
5441}
5442
5443
5444void
5445derived_probe_group_container::register_probe(hrtimer_derived_probe* p)
5446{
5447 probes.push_back (p);
5448 hrtimer_probe_group->register_probe(p);
5449}
5450
5451
5452void
5453derived_probe_group_container::register_probe(mark_derived_probe* p)
5454{
5455 probes.push_back (p);
5456 mark_probe_group->register_probe(p);
5457}
5458
5459
5460void
5461derived_probe_group_container::register_probe(never_derived_probe* p)
5462{
5463 probes.push_back (p);
5464 never_probe_group->register_probe(p);
5465}
5466
5467
5468void
5469derived_probe_group_container::register_probe(profile_derived_probe* p)
5470{
5471 probes.push_back (p);
5472 profile_probe_group->register_probe(p);
5473}
5474
5475
5476void
5477derived_probe_group_container::register_probe(timer_derived_probe* p)
5478{
5479 probes.push_back (p);
5480 timer_probe_group->register_probe(p);
5481}
5482
5483
47dd066d
WC
5484void
5485derived_probe_group_container::register_probe(perfmon_derived_probe* p)
5486{
5487 probes.push_back (p);
5488 perfmon_probe_group->register_probe(p);
5489}
5490
5491
dc38c0ae
DS
5492void
5493derived_probe_group_container::emit_probes (translator_output* op,
5494 unparser* up)
5495{
5496 // Sanity check.
5497 size_t groups_size = be_probe_group->size ()
5498 + dwarf_probe_group->size ()
5499 + hrtimer_probe_group->size ()
5500 + mark_probe_group->size ()
5501 + never_probe_group->size ()
5502 + profile_probe_group->size ()
47dd066d
WC
5503 + timer_probe_group->size ()
5504 + perfmon_probe_group->size ();
dc38c0ae
DS
5505 if (probes.size () != groups_size)
5506 {
5507 cerr << "There are " << probes.size () << " total probes, and "
5508 << groups_size << " grouped probes\n";
5509
5510 throw runtime_error("internal probe mismatch");
5511 }
5512
5513 // Let each probe group emit its probes.
5514 be_probe_group->emit_probes (op, up);
5515 dwarf_probe_group->emit_probes (op, up);
5516 hrtimer_probe_group->emit_probes (op, up);
5517 mark_probe_group->emit_probes (op, up);
5518 never_probe_group->emit_probes (op, up);
5519 profile_probe_group->emit_probes (op, up);
5520 timer_probe_group->emit_probes (op, up);
47dd066d 5521 perfmon_probe_group->emit_probes (op, up);
dc38c0ae 5522}
46b84a80
DS
5523
5524
5525void
5526derived_probe_group_container::emit_module_init (translator_output* o)
5527{
5528 // Let each probe group emit its module init logic.
5529 be_probe_group->emit_module_init (o);
5530 dwarf_probe_group->emit_module_init (o);
5531 hrtimer_probe_group->emit_module_init (o);
5532 mark_probe_group->emit_module_init (o);
5533 never_probe_group->emit_module_init (o);
5534 profile_probe_group->emit_module_init (o);
5535 timer_probe_group->emit_module_init (o);
47dd066d 5536 perfmon_probe_group->emit_module_init(o);
46b84a80
DS
5537}
5538
5539
47dd066d 5540#define PERFMON_ERROR_LABEL "unregister_perfmon"
46b84a80
DS
5541#define BE_ERROR_LABEL "unregister_be"
5542#define DWARF_ERROR_LABEL "unregister_dwarf"
5543#define HRTIMER_ERROR_LABEL "unregister_hrtimer"
5544#define MARK_ERROR_LABEL "unregister_mark"
5545#define PROFILE_ERROR_LABEL "unregister_profile"
5546#define TIMER_ERROR_LABEL "unregister_timer"
5547
5548void
5549derived_probe_group_container::emit_module_init_call (translator_output* o)
5550{
5551 int i = 0;
5552 const char *error_label = "";
5553
47dd066d
WC
5554 if (perfmon_probe_group->size () > 0)
5555 {
5556 o->newline() << "rc = register_perfmon_probes ();";
5557 o->newline() << "if (rc)";
5558 o->indent(1);
5559 // We need to deregister any already probes set up - this is
5560 // essential for kprobes.
5561 o->newline() << "goto out;";
5562 o->indent(-1);
5563 i++;
5564 error_label = PERFMON_ERROR_LABEL;
5565 }
5566
46b84a80
DS
5567 if (be_probe_group->size () > 0)
5568 {
5569 o->newline() << "rc = register_be_probes ();";
5570 o->newline() << "if (rc)";
5571 o->indent(1);
5572 // We need to deregister any already probes set up - this is
5573 // essential for kprobes.
5574 o->newline() << "goto out;";
5575 o->indent(-1);
5576 i++;
5577 error_label = BE_ERROR_LABEL;
5578 }
5579
5580 if (dwarf_probe_group->size () > 0)
5581 {
5582 o->newline() << "rc = register_dwarf_probes ();";
5583 o->newline() << "if (rc)";
5584 o->indent(1);
5585 // We need to deregister any already probes set up - this is
5586 // essential for kprobes.
5587 if (i > 0)
5588 o->newline() << "goto " << error_label << ";";
5589 else
5590 o->newline() << "goto out;";
5591 o->indent(-1);
5592 i++;
5593 error_label = DWARF_ERROR_LABEL;
5594 }
5595
5596 if (hrtimer_probe_group->size () > 0)
5597 {
5598 o->newline() << "rc = register_hrtimer_probes ();";
5599 o->newline() << "if (rc)";
5600 o->indent(1);
5601 // We need to deregister any already probes set up - this is
5602 // essential for kprobes.
5603 if (i > 0)
5604 o->newline() << "goto " << error_label << ";";
5605 else
5606 o->newline() << "goto out;";
5607 o->indent(-1);
5608 i++;
5609 error_label = HRTIMER_ERROR_LABEL;
5610 }
5611
5612 if (mark_probe_group->size () > 0)
5613 {
5614 o->newline() << "rc = register_mark_probes ();";
5615 o->newline() << "if (rc)";
5616 o->indent(1);
5617 // We need to deregister any already probes set up - this is
5618 // essential for kprobes.
5619 if (i > 0)
5620 o->newline() << "goto " << error_label << ";";
5621 else
5622 o->newline() << "goto out;";
5623 o->indent(-1);
5624 i++;
5625 error_label = MARK_ERROR_LABEL;
5626 }
5627
5628 // We don't need to bother with the never_probe_group.
5629
5630 if (profile_probe_group->size () > 0)
5631 {
5632 o->newline() << "rc = register_profile_probes ();";
5633 o->newline() << "if (rc)";
5634 o->indent(1);
5635 // We need to deregister any already probes set up - this is
5636 // essential for kprobes.
5637 if (i > 0)
5638 o->newline() << "goto " << error_label << ";";
5639 else
5640 o->newline() << "goto out;";
5641 o->indent(-1);
5642 i++;
5643 error_label = PROFILE_ERROR_LABEL;
5644 }
5645
5646 if (timer_probe_group->size () > 0)
5647 {
5648 o->newline() << "rc = register_timer_probes ();";
5649 o->newline() << "if (rc)";
5650 o->indent(1);
5651 // We need to deregister any already probes set up - this is
5652 // essential for kprobes.
5653 if (i > 0)
5654 o->newline() << "goto " << error_label << ";";
5655 else
5656 o->newline() << "goto out;";
5657 o->indent(-1);
5658 i++;
5659 error_label = TIMER_ERROR_LABEL;
5660 }
5661
5662 // BEGIN probes would have all been run by now. One of them may
5663 // have triggered a STAP_SESSION_ERROR (which would incidentally
5664 // block later BEGIN ones). If so, let that indication stay, and
5665 // otherwise act like probe insertion was a success.
5666 o->newline() << "if (atomic_read (&session_state) == STAP_SESSION_STARTING)";
5667 o->newline(1) << "atomic_set (&session_state, STAP_SESSION_RUNNING);";
5668 o->newline(-1) << "goto out;";
5669
5670 // Recovery code for partially successful registration (rc != 0)
5671 // XXX: Do we need to delay here to ensure any triggered probes have
5672 // terminated? Probably not much, as they should all test for
5673 // SESSION_STARTING state right at the top and return. ("begin"
5674 // probes don't count, as they return synchronously.)
5675 o->newline();
5676
5677 if (i > 0 && timer_probe_group->size () > 0)
5678 {
5679 o->newline(-1) << TIMER_ERROR_LABEL << ":";
5680 o->newline(1) << "unregister_timer_probes();";
5681 i--;
5682 }
5683 if (i > 0 && profile_probe_group->size () > 0)
5684 {
5685 o->newline(-1) << PROFILE_ERROR_LABEL << ":";
5686 o->newline(1) << "unregister_profile_probes();";
5687 i--;
5688 }
5689
5690 // We don't need to bother with the never_probe_group.
5691
5692 if (i > 0 && mark_probe_group->size () > 0)
5693 {
5694 o->newline(-1) << MARK_ERROR_LABEL << ":";
5695 o->newline(1) << "unregister_mark_probes();";
5696 i--;
5697 }
5698 if (i > 0 && hrtimer_probe_group->size () > 0)
5699 {
5700 o->newline(-1) << HRTIMER_ERROR_LABEL << ":";
5701 o->newline(1) << "unregister_hrtimer_probes();";
5702 i--;
5703 }
5704 if (i > 0 && dwarf_probe_group->size () > 0)
5705 {
5706 o->newline(-1) << DWARF_ERROR_LABEL << ":";
5707 o->newline(1) << "unregister_dwarf_probes();";
5708 i--;
5709 }
5710 if (i > 0 && be_probe_group->size () > 0)
5711 {
5712 o->newline(-1) << BE_ERROR_LABEL << ":";
5713 o->newline(1) << "unregister_be_probes();";
5714 i--;
5715 }
47dd066d
WC
5716 if (i > 0 && perfmon_probe_group->size () > 0)
5717 {
5718 o->newline(-1) << PERFMON_ERROR_LABEL << ":";
5719 o->newline(1) << "unregister_perfmon_probes();";
5720 i--;
5721 }
46b84a80
DS
5722}
5723
5724
5725void
5726derived_probe_group_container::emit_module_exit (translator_output* o)
5727{
5728 if (be_probe_group->size () > 0)
5729 o->newline() << "unregister_be_probes ();";
5730
5731 if (dwarf_probe_group->size () > 0)
5732 o->newline() << "unregister_dwarf_probes ();";
5733
5734 if (hrtimer_probe_group->size () > 0)
5735 o->newline() << "unregister_hrtimer_probes ();";
5736
5737 if (mark_probe_group->size () > 0)
5738 o->newline() << "unregister_mark_probes ();";
5739
5740 // We don't need to bother with the never_probe_group.
5741
5742 if (profile_probe_group->size () > 0)
5743 o->newline() << "unregister_profile_probes ();";
5744
5745 if (timer_probe_group->size () > 0)
5746 o->newline() << "unregister_timer_probes ();";
47dd066d
WC
5747
5748 if (perfmon_probe_group->size () > 0)
5749 o->newline() << "unregister_perfmon_probes ();";
46b84a80 5750}
This page took 0.735908 seconds and 5 git commands to generate.