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