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