]> sourceware.org Git - systemtap.git/blame - tapsets.cxx
Add test and doc for kernel.statement relative line number.
[systemtap.git] / tapsets.cxx
CommitLineData
56e12059 1// tapset resolution
0f16be72 2// Copyright (C) 2005-2008 Red Hat Inc.
aa30ccd3 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 17
3b579393
FCE
18#include <cstdlib>
19#include <algorithm>
bd2b1e68 20#include <deque>
56e12059 21#include <iostream>
bd2b1e68 22#include <map>
3bf6ac45
TM
23#ifdef HAVE_TR1_UNORDERED_MAP
24#include <tr1/unordered_map>
25#else
2171f774 26#include <ext/hash_map>
3bf6ac45 27#endif
ec4373ff 28#include <set>
56e12059 29#include <sstream>
bd2b1e68 30#include <stdexcept>
b55bc428 31#include <vector>
e36387d7 32#include <cstdarg>
29e64872 33#include <cassert>
1969b5bc 34#include <iomanip>
f781f849 35#include <cerrno>
bd2b1e68
GH
36
37extern "C" {
df8fadee 38#include <fcntl.h>
bd2b1e68 39#include <elfutils/libdwfl.h>
7a053d3b 40#include <elfutils/libdw.h>
c931ec8a 41#include <elfutils/libebl.h>
77de5e9e
GH
42#include <dwarf.h>
43#include <elf.h>
44#include <obstack.h>
30a279be 45#include <regex.h>
b20febf3 46#include <glob.h>
30a279be 47#include <fnmatch.h>
5f0a03a6 48#include <stdio.h>
4b1ad75e 49
30a279be 50#include "loc2c.h"
4b1ad75e
RM
51#define __STDC_FORMAT_MACROS
52#include <inttypes.h>
bd2b1e68 53}
77de5e9e 54
56e12059 55
47dd066d
WC
56#ifdef PERFMON
57#include <perfmon/pfmlib.h>
58#include <perfmon/perfmon.h>
59#endif
60
56e12059 61using namespace std;
2171f774 62using namespace __gnu_cxx;
56e12059 63
cc9ee605 64
b20febf3
FCE
65// ------------------------------------------------------------------------
66// Generic derived_probe_group: contains an ordinary vector of the
67// given type. It provides only the enrollment function.
68
69template <class DP> struct generic_dpg: public derived_probe_group
70{
71protected:
72 vector <DP*> probes;
73public:
74 generic_dpg () {}
75 void enroll (DP* probe) { probes.push_back (probe); }
76};
46b84a80
DS
77
78
b20febf3
FCE
79
80// ------------------------------------------------------------------------
65aeaea0 81// begin/end/error probes are run right during registration / deregistration
9a604fac
FCE
82// ------------------------------------------------------------------------
83
12b21830
DS
84static string TOK_BEGIN("begin");
85static string TOK_END("end");
86static string TOK_ERROR("error");
87
65aeaea0
FCE
88enum be_t { BEGIN, END, ERROR };
89
b20febf3
FCE
90struct be_derived_probe: public derived_probe
91{
65aeaea0 92 be_t type;
16e8f21f
JS
93 int64_t priority;
94
65aeaea0
FCE
95 be_derived_probe (probe* p, probe_point* l, be_t t, int64_t pr):
96 derived_probe (p, l), type (t), priority (pr) {}
b20febf3
FCE
97
98 void join_group (systemtap_session& s);
16e8f21f
JS
99
100 static inline bool comp(be_derived_probe const *a,
101 be_derived_probe const *b)
65aeaea0
FCE
102 {
103 // This allows the BEGIN/END/ERROR probes to intermingle.
104 // But that's OK - they're always treversed with a nested
105 // "if (type==FOO)" conditional.
4baf0e53 106 return a->priority < b->priority;
65aeaea0 107 }
90f98cc3
DS
108
109 bool needs_global_locks () { return false; }
110 // begin/end probes don't need locks around global variables, since
111 // they aren't run concurrently with any other probes
b20febf3
FCE
112};
113
114
115struct be_derived_probe_group: public generic_dpg<be_derived_probe>
116{
117public:
118 void emit_module_decls (systemtap_session& s);
119 void emit_module_init (systemtap_session& s);
120 void emit_module_exit (systemtap_session& s);
121};
122
123
124struct be_builder: public derived_probe_builder
125{
65aeaea0
FCE
126 be_t type;
127
128 be_builder(be_t t) : type(t) {}
129
78f6bba6 130 virtual void build(systemtap_session &,
b20febf3
FCE
131 probe * base,
132 probe_point * location,
133 std::map<std::string, literal *> const & parameters,
134 vector<derived_probe *> & finished_results)
135 {
16e8f21f 136 int64_t priority;
12b21830
DS
137 if ((type == BEGIN && !get_param(parameters, TOK_BEGIN, priority)) ||
138 (type == END && !get_param(parameters, TOK_END, priority)) ||
139 (type == ERROR && !get_param(parameters, TOK_ERROR, priority)))
16e8f21f
JS
140 priority = 0;
141 finished_results.push_back(
65aeaea0 142 new be_derived_probe(base, location, type, priority));
b20febf3
FCE
143 }
144};
145
146
9a604fac 147void
b20febf3 148be_derived_probe::join_group (systemtap_session& s)
9a604fac 149{
b20febf3
FCE
150 if (! s.be_derived_probes)
151 s.be_derived_probes = new be_derived_probe_group ();
152 s.be_derived_probes->enroll (this);
153}
47dd066d 154
b20febf3
FCE
155
156// ------------------------------------------------------------------------
157void
a58d79d0 158common_probe_entryfn_prologue (translator_output* o, string statestr,
29fdb4e4 159 bool overload_processing = true,
37ebca01 160 bool interruptible = false)
b20febf3 161{
72d18b98 162 o->newline() << "struct context* __restrict__ c;";
29fdb4e4
DS
163 if (! interruptible)
164 o->newline() << "unsigned long flags;";
b20febf3 165
a58d79d0
DS
166 if (overload_processing)
167 o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
168 else
169 o->newline() << "#ifdef STP_TIMING";
170 o->newline() << "cycles_t cycles_atstart = get_cycles ();";
b20febf3 171 o->newline() << "#endif";
b20febf3
FCE
172
173#if 0 /* XXX: PERFMON */
47dd066d
WC
174 o->newline() << "static struct pfarg_ctx _pfm_context;";
175 o->newline() << "static void *_pfm_desc;";
176 o->newline() << "static struct pfarg_pmc *_pfm_pmc_x;";
177 o->newline() << "static int _pfm_num_pmc_x;";
178 o->newline() << "static struct pfarg_pmd *_pfm_pmd_x;";
179 o->newline() << "static int _pfm_num_pmd_x;";
180#endif
181
29fdb4e4
DS
182 if (! interruptible)
183 o->newline() << "local_irq_save (flags);";
184 else
185 o->newline() << "preempt_disable ();";
b20febf3 186
c931ec8a 187 // Check for enough free enough stack space
d05a1d00 188 o->newline() << "if (unlikely ((((unsigned long) (& c)) & (THREAD_SIZE-1))"; // free space
a63401b1 189 o->newline(1) << "< (MINSTACKSPACE + sizeof (struct thread_info)))) {"; // needed space
d05a1d00
FCE
190 // XXX: may need porting to platforms where task_struct is not at bottom of kernel stack
191 // NB: see also CONFIG_DEBUG_STACKOVERFLOW
192 o->newline() << "if (unlikely (atomic_inc_return (& skipped_count) > MAXSKIPPED)) {";
c931ec8a
FCE
193 o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
194 o->newline() << "_stp_exit ();";
195 o->newline(-1) << "}";
196 o->newline() << "goto probe_epilogue;";
197 o->newline(-1) << "}";
198
b20febf3
FCE
199 o->newline() << "if (atomic_read (&session_state) != " << statestr << ")";
200 o->newline(1) << "goto probe_epilogue;";
201 o->indent(-1);
9a604fac 202
a44a0785 203 o->newline() << "c = per_cpu_ptr (contexts, smp_processor_id());";
b20febf3 204 o->newline() << "if (unlikely (atomic_inc_return (&c->busy) != 1)) {";
9a604fac
FCE
205 o->newline(1) << "if (atomic_inc_return (& skipped_count) > MAXSKIPPED) {";
206 o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
207 // NB: We don't assume that we can safely call stp_error etc. in such
208 // a reentrant context. But this is OK:
209 o->newline() << "_stp_exit ();";
210 o->newline(-1) << "}";
9a604fac 211 o->newline() << "atomic_dec (& c->busy);";
b20febf3 212 o->newline() << "goto probe_epilogue;";
9a604fac
FCE
213 o->newline(-1) << "}";
214 o->newline();
1e00cfb1 215 o->newline() << "c->last_stmt = 0;";
9a604fac 216 o->newline() << "c->last_error = 0;";
9a604fac
FCE
217 o->newline() << "c->nesting = 0;";
218 o->newline() << "c->regs = 0;";
b916df9c
MH
219 o->newline() << "c->unwaddr = 0;";
220 // reset unwound address cache
fcff848e 221 o->newline() << "c->pi = 0;";
9addf322 222 o->newline() << "c->regparm = 0;";
b20febf3 223 o->newline() << "c->probe_point = 0;";
29fdb4e4
DS
224 if (! interruptible)
225 o->newline() << "c->actionremaining = MAXACTION;";
226 else
227 o->newline() << "c->actionremaining = MAXACTION_INTERRUPTIBLE;";
dbb68664
FCE
228 o->newline() << "#ifdef STP_TIMING";
229 o->newline() << "c->statp = 0;";
230 o->newline() << "#endif";
9915575b
FCE
231 // NB: The following would actually be incorrect.
232 // That's because cycles_sum/cycles_base values are supposed to survive
233 // between consecutive probes. Periodically (STP_OVERLOAD_INTERVAL
234 // cycles), the values will be reset.
235 /*
f0e6dc63
FCE
236 o->newline() << "#ifdef STP_OVERLOAD";
237 o->newline() << "c->cycles_sum = 0;";
238 o->newline() << "c->cycles_base = 0;";
239 o->newline() << "#endif";
9915575b 240 */
b20febf3 241}
9a604fac 242
a44a0785 243
b20febf3 244void
a58d79d0 245common_probe_entryfn_epilogue (translator_output* o,
29fdb4e4 246 bool overload_processing = true,
37ebca01 247 bool interruptible = false)
b20febf3 248{
a58d79d0
DS
249 if (overload_processing)
250 o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
251 else
252 o->newline() << "#ifdef STP_TIMING";
dbb68664 253 o->newline() << "{";
a58d79d0
DS
254 o->newline(1) << "cycles_t cycles_atend = get_cycles ();";
255 // NB: we truncate cycles counts to 32 bits. Perhaps it should be
256 // fewer, if the hardware counter rolls over really quickly. We
257 // handle 32-bit wraparound here.
258 o->newline() << "int32_t cycles_elapsed = ((int32_t)cycles_atend > (int32_t)cycles_atstart)";
259 o->newline(1) << "? ((int32_t)cycles_atend - (int32_t)cycles_atstart)";
260 o->newline() << ": (~(int32_t)0) - (int32_t)cycles_atstart + (int32_t)cycles_atend + 1;";
261 o->indent(-1);
dbb68664 262
a58d79d0 263 o->newline() << "#ifdef STP_TIMING";
dbb68664 264 o->newline() << "if (likely (c->statp)) _stp_stat_add(*c->statp, cycles_elapsed);";
a58d79d0
DS
265 o->newline() << "#endif";
266
267 if (overload_processing)
268 {
269 o->newline() << "#ifdef STP_OVERLOAD";
270 o->newline() << "{";
271 // If the cycle count has wrapped (cycles_atend > cycles_base),
272 // let's go ahead and pretend the interval has been reached.
273 // This should reset cycles_base and cycles_sum.
274 o->newline(1) << "cycles_t interval = (cycles_atend > c->cycles_base)";
275 o->newline(1) << "? (cycles_atend - c->cycles_base)";
276 o->newline() << ": (STP_OVERLOAD_INTERVAL + 1);";
277 o->newline(-1) << "c->cycles_sum += cycles_elapsed;";
278
279 // If we've spent more than STP_OVERLOAD_THRESHOLD cycles in a
280 // probe during the last STP_OVERLOAD_INTERVAL cycles, the probe
281 // has overloaded the system and we need to quit.
282 o->newline() << "if (interval > STP_OVERLOAD_INTERVAL) {";
283 o->newline(1) << "if (c->cycles_sum > STP_OVERLOAD_THRESHOLD) {";
284 o->newline(1) << "_stp_error (\"probe overhead exceeded threshold\");";
285 o->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);";
551e9f14 286 o->newline() << "atomic_inc (&error_count);";
a58d79d0
DS
287 o->newline(-1) << "}";
288
289 o->newline() << "c->cycles_base = cycles_atend;";
290 o->newline() << "c->cycles_sum = 0;";
291 o->newline(-1) << "}";
292 o->newline(-1) << "}";
293 o->newline() << "#endif";
294 }
295
dbb68664
FCE
296 o->newline(-1) << "}";
297 o->newline() << "#endif";
298
9a604fac
FCE
299 o->newline() << "if (unlikely (c->last_error && c->last_error[0])) {";
300 o->newline(1) << "if (c->last_stmt != NULL)";
301 o->newline(1) << "_stp_softerror (\"%s near %s\", c->last_error, c->last_stmt);";
302 o->newline(-1) << "else";
303 o->newline(1) << "_stp_softerror (\"%s\", c->last_error);";
304 o->indent(-1);
305 o->newline() << "atomic_inc (& error_count);";
9a604fac
FCE
306 o->newline() << "if (atomic_read (& error_count) > MAXERRORS) {";
307 o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
308 o->newline() << "_stp_exit ();";
309 o->newline(-1) << "}";
9a604fac 310 o->newline(-1) << "}";
9a604fac 311 o->newline() << "atomic_dec (&c->busy);";
a44a0785 312
b20febf3
FCE
313 o->newline(-1) << "probe_epilogue:"; // context is free
314 o->indent(1);
a44a0785 315
29fdb4e4
DS
316 if (! interruptible)
317 o->newline() << "local_irq_restore (flags);";
318 else
319 o->newline() << "preempt_enable_no_resched ();";
9a604fac
FCE
320}
321
322
56e12059
FCE
323// ------------------------------------------------------------------------
324
56e12059 325void
b20febf3
FCE
326be_derived_probe_group::emit_module_decls (systemtap_session& s)
327{
328 if (probes.empty()) return;
329
330 s.op->newline() << "/* ---- begin/end probes ---- */";
65aeaea0 331 s.op->newline() << "void enter_begin_probe (void (*fn)(struct context*), const char* pp) {";
b20febf3 332 s.op->indent(1);
29fdb4e4 333 common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false, true);
65aeaea0 334 s.op->newline() << "c->probe_point = pp;";
b20febf3 335 s.op->newline() << "(*fn) (c);";
29fdb4e4 336 common_probe_entryfn_epilogue (s.op, false, true);
b20febf3 337 s.op->newline(-1) << "}";
65aeaea0
FCE
338
339 s.op->newline() << "void enter_end_probe (void (*fn)(struct context*), const char* pp) {";
b20febf3 340 s.op->indent(1);
29fdb4e4 341 common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false, true);
65aeaea0
FCE
342 s.op->newline() << "c->probe_point = pp;";
343 s.op->newline() << "(*fn) (c);";
344 common_probe_entryfn_epilogue (s.op, false, true);
345 s.op->newline(-1) << "}";
346
347 s.op->newline() << "void enter_error_probe (void (*fn)(struct context*), const char* pp) {";
348 s.op->indent(1);
349 common_probe_entryfn_prologue (s.op, "STAP_SESSION_ERROR", false, true);
350 s.op->newline() << "c->probe_point = pp;";
b20febf3 351 s.op->newline() << "(*fn) (c);";
29fdb4e4 352 common_probe_entryfn_epilogue (s.op, false, true);
b20febf3 353 s.op->newline(-1) << "}";
65aeaea0
FCE
354
355 s.op->newline() << "struct stap_be_probe {";
356 s.op->newline(1) << "void (*ph)(struct context*);";
357 s.op->newline() << "const char* pp;";
358 s.op->newline() << "int type;";
359 s.op->newline(-1) << "} stap_be_probes[] = {";
360 s.op->indent(1);
361
362 // NB: We emit the table in sorted order here, so we don't have to
363 // store the priority numbers as integers and sort at run time.
364
365 sort(probes.begin(), probes.end(), be_derived_probe::comp);
366
367 for (unsigned i=0; i < probes.size(); i++)
368 {
4baf0e53
RM
369 s.op->newline () << "{";
370 s.op->line() << " .pp="
65aeaea0
FCE
371 << lex_cast_qstring (*probes[i]->sole_location()) << ",";
372 s.op->line() << " .ph=&" << probes[i]->name << ",";
373 s.op->line() << " .type=" << probes[i]->type;
374 s.op->line() << " },";
375 }
376 s.op->newline(-1) << "};";
56e12059
FCE
377}
378
dc38c0ae 379void
b20febf3 380be_derived_probe_group::emit_module_init (systemtap_session& s)
dc38c0ae 381{
b8da0ad1
FCE
382 if (probes.empty()) return;
383
65aeaea0
FCE
384 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
385 s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
386 s.op->newline() << "if (stp->type != " << BEGIN << ") continue;";
387 s.op->newline() << "enter_begin_probe (stp->ph, stp->pp);";
388 s.op->newline() << "/* rc = 0; */";
389 // NB: begin probes that cause errors do not constitute registration
390 // failures. An error message will probably get printed and if
391 // MAXERRORS was left at 1, we'll get an stp_exit. The
392 // error-handling probes will be run during the ordinary
393 // unregistration phase.
394 s.op->newline(-1) << "}";
dc38c0ae
DS
395}
396
46b84a80 397void
b20febf3 398be_derived_probe_group::emit_module_exit (systemtap_session& s)
46b84a80 399{
b8da0ad1
FCE
400 if (probes.empty()) return;
401
65aeaea0
FCE
402 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
403 s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
404 s.op->newline() << "if (stp->type != " << END << ") continue;";
405 s.op->newline() << "enter_end_probe (stp->ph, stp->pp);";
406 s.op->newline(-1) << "}";
407
408 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
409 s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
410 s.op->newline() << "if (stp->type != " << ERROR << ") continue;";
411 s.op->newline() << "enter_error_probe (stp->ph, stp->pp);";
412 s.op->newline(-1) << "}";
46b84a80
DS
413}
414
dc38c0ae 415
b20febf3 416
6e3347a9
FCE
417// ------------------------------------------------------------------------
418// never probes are never run
419// ------------------------------------------------------------------------
420
12b21830
DS
421static string TOK_NEVER("never");
422
6e3347a9
FCE
423struct never_derived_probe: public derived_probe
424{
425 never_derived_probe (probe* p): derived_probe (p) {}
426 never_derived_probe (probe* p, probe_point* l): derived_probe (p, l) {}
78f6bba6 427 void join_group (systemtap_session&) { /* thus no probe_group */ }
dc38c0ae
DS
428};
429
430
6e3347a9
FCE
431struct never_builder: public derived_probe_builder
432{
433 never_builder() {}
78f6bba6 434 virtual void build(systemtap_session &,
6e3347a9
FCE
435 probe * base,
436 probe_point * location,
78f6bba6 437 std::map<std::string, literal *> const &,
6e3347a9
FCE
438 vector<derived_probe *> & finished_results)
439 {
440 finished_results.push_back(new never_derived_probe(base, location));
441 }
442};
443
444
b20febf3 445
56e12059 446// ------------------------------------------------------------------------
b20febf3 447// Dwarf derived probes. "We apologize for the inconvience."
b55bc428 448// ------------------------------------------------------------------------
bd2b1e68 449
c239d28c
GH
450static string TOK_KERNEL("kernel");
451static string TOK_MODULE("module");
c239d28c 452static string TOK_FUNCTION("function");
54efe513 453static string TOK_INLINE("inline");
b8da0ad1 454static string TOK_CALL("call");
c239d28c 455static string TOK_RETURN("return");
c9bad430 456static string TOK_MAXACTIVE("maxactive");
c239d28c 457static string TOK_STATEMENT("statement");
37ebca01 458static string TOK_ABSOLUTE("absolute");
888af770 459static string TOK_PROCESS("process");
59ff2773 460
5f0a03a6
JK
461// Can we handle this query with just symbol-table info?
462enum dbinfo_reqt
463{
464 dbr_unknown,
465 dbr_none, // kernel.statement(NUM).absolute
466 dbr_need_symtab, // can get by with symbol table if there's no dwarf
467 dbr_need_dwarf
468};
469
470enum info_status
471{
472 info_unknown,
473 info_present,
474 info_absent
475};
b8da0ad1 476
20e4a32c 477struct
7e1279ea
FCE
478func_info
479{
20e4a32c 480 func_info()
ab91b232 481 : decl_file(NULL), decl_line(-1), addr(0), prologue_end(0), weak(false)
b6581717
GH
482 {
483 memset(&die, 0, sizeof(die));
484 }
7e1279ea 485 string name;
4cd232e4
GH
486 char const * decl_file;
487 int decl_line;
7e1279ea 488 Dwarf_Die die;
5f0a03a6 489 Dwarf_Addr addr;
7e1279ea 490 Dwarf_Addr prologue_end;
ab91b232 491 bool weak;
7e1279ea
FCE
492};
493
494struct
495inline_instance_info
496{
20e4a32c 497 inline_instance_info()
b6581717
GH
498 : decl_file(NULL), decl_line(-1)
499 {
500 memset(&die, 0, sizeof(die));
501 }
7e1279ea 502 string name;
4cd232e4
GH
503 char const * decl_file;
504 int decl_line;
7e1279ea
FCE
505 Dwarf_Die die;
506};
507
c8959a29 508
5f0a03a6
JK
509struct dwarf_query; // forward decls
510struct dwflpp;
511struct symbol_table;
512
513struct
514module_info
515{
516 Dwfl_Module* mod;
517 const char* name;
518 string elf_path;
519 Dwarf_Addr addr;
520 Dwarf_Addr bias;
521 symbol_table *sym_table;
522 info_status dwarf_status; // module has dwarf info?
523 info_status symtab_status; // symbol table cached?
524
525 void get_symtab(dwarf_query *q);
526
527 module_info(const char *name) :
528 mod(NULL),
529 name(name),
530 addr(0),
531 bias(0),
532 sym_table(NULL),
533 dwarf_status(info_unknown),
534 symtab_status(info_unknown)
535 {}
536
537 ~module_info();
538};
539
540struct
541module_cache
542{
543 map<string, module_info*> cache;
544 bool paths_collected;
545 bool dwarf_collected;
546
547 module_cache() : paths_collected(false), dwarf_collected(false) {}
548};
549typedef struct module_cache module_cache_t;
550
3bf6ac45
TM
551#ifdef HAVE_TR1_UNORDERED_MAP
552typedef tr1::unordered_map<string,Dwarf_Die> cu_function_cache_t;
553typedef tr1::unordered_map<string,cu_function_cache_t*> mod_cu_function_cache_t; // module:cu -> function -> die
554#else
2171f774
FCE
555struct stringhash {
556 size_t operator() (const string& s) const { hash<const char*> h; return h(s.c_str()); }
557};
558
559typedef hash_map<string,Dwarf_Die,stringhash> cu_function_cache_t;
560typedef hash_map<string,cu_function_cache_t*,stringhash> mod_cu_function_cache_t; // module:cu -> function -> die
3bf6ac45 561#endif
5f0a03a6
JK
562
563struct
564symbol_table
565{
566 module_info *mod_info; // associated module
567 map<string, func_info*> map_by_name;
568 vector<func_info*> list_by_addr;
569
ab91b232
JK
570 void add_symbol(const char *name, bool weak, Dwarf_Addr addr,
571 Dwarf_Addr *high_addr);
5f0a03a6
JK
572 enum info_status read_symbols(FILE *f, const string& path);
573 enum info_status read_from_elf_file(const string& path);
574 enum info_status read_from_text_file(const string& path);
575 enum info_status get_from_elf();
576 void mark_dwarf_redundancies(dwflpp *dw);
ab91b232 577 void purge_syscall_stubs();
5f0a03a6
JK
578 func_info *lookup_symbol(const string& name);
579 Dwarf_Addr lookup_symbol_address(const string& name);
580 func_info *get_func_containing_address(Dwarf_Addr addr);
581 int get_index_for_address(Dwarf_Addr addr);
582
583 symbol_table(module_info *mi) : mod_info(mi) {}
584 ~symbol_table();
585};
586
587static bool null_die(Dwarf_Die *die)
588{
589 static Dwarf_Die null = { 0 };
590 return (!die || !memcmp(die, &null, sizeof(null)));
591}
592
7e1279ea
FCE
593static int
594query_cu (Dwarf_Die * cudie, void * arg);
59ff2773
FCE
595
596
bd2b1e68
GH
597// Helper for dealing with selected portions of libdwfl in a more readable
598// fashion, and with specific cleanup / checking / logging options.
599
91eefb1c
GH
600static const char *
601dwarf_diename_integrate (Dwarf_Die *die)
602{
603 Dwarf_Attribute attr_mem;
604 return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
605}
606
b20febf3 607struct dwflpp
bd2b1e68 608{
5227f1ea 609 systemtap_session & sess;
bd2b1e68
GH
610 Dwfl * dwfl;
611
612 // These are "current" values we focus on.
613 Dwfl_Module * module;
614 Dwarf * module_dwarf;
615 Dwarf_Addr module_bias;
5f0a03a6 616 module_info * mod_info;
50e0d793
GH
617
618 // These describe the current module's PC address range
619 Dwarf_Addr module_start;
620 Dwarf_Addr module_end;
621
bd2b1e68 622 Dwarf_Die * cu;
20e4a32c 623 Dwarf_Die * function;
bd2b1e68
GH
624
625 string module_name;
626 string cu_name;
627 string function_name;
628
7a053d3b 629 string const default_name(char const * in,
78f6bba6 630 char const *)
bd2b1e68 631 {
7a053d3b 632 if (in)
bd2b1e68 633 return in;
a229fcd7 634 return string("");
bd2b1e68
GH
635 }
636
50e0d793 637
5f0a03a6 638 void get_module_dwarf(bool required = false, bool report = true)
5227f1ea 639 {
5f0a03a6 640 if (!module_dwarf && mod_info->dwarf_status != info_absent)
0ce64fb8 641 {
5f0a03a6
JK
642 if (!sess.ignore_dwarf)
643 module_dwarf = dwfl_module_getdwarf(module, &module_bias);
644 mod_info->dwarf_status = (module_dwarf ? info_present : info_absent);
645 }
0ce64fb8 646
5f0a03a6
JK
647 if (!module_dwarf && report)
648 {
649 string msg = "cannot find ";
650 if (module_name == "")
651 msg += "kernel";
652 else
653 msg += string("module ") + module_name;
654 msg += " debuginfo";
655
656 int i = dwfl_errno();
657 if (i)
658 msg += string(": ") + dwfl_errmsg (i);
659
660 if (required)
661 throw semantic_error (msg);
662 else
663 cerr << "WARNING: " << msg << "\n";
0ce64fb8 664 }
5227f1ea
GH
665 }
666
5f0a03a6 667 void focus_on_module(Dwfl_Module * m, module_info * mi)
bd2b1e68 668 {
bd2b1e68 669 module = m;
5f0a03a6
JK
670 mod_info = mi;
671 if (m)
672 {
673 module_name = default_name(dwfl_module_info(module, NULL,
50e0d793 674 &module_start, &module_end,
bd2b1e68
GH
675 NULL, NULL,
676 NULL, NULL),
677 "module");
5f0a03a6
JK
678 }
679 else
680 {
681 assert(mi && mi->name && mi->name == TOK_KERNEL);
682 module_name = mi->name;
683 module_start = 0;
684 module_end = 0;
685 module_bias = mi->bias;
686 }
50e0d793
GH
687
688 // Reset existing pointers and names
689
690 module_dwarf = NULL;
691
a229fcd7 692 cu_name.clear();
50e0d793
GH
693 cu = NULL;
694
a229fcd7 695 function_name.clear();
50e0d793 696 function = NULL;
bd2b1e68
GH
697 }
698
50e0d793 699
bd2b1e68
GH
700 void focus_on_cu(Dwarf_Die * c)
701 {
702 assert(c);
50e0d793
GH
703 assert(module);
704
bd2b1e68 705 cu = c;
50e0d793
GH
706 cu_name = default_name(dwarf_diename(c), "CU");
707
708 // Reset existing pointers and names
a229fcd7 709 function_name.clear();
50e0d793 710 function = NULL;
bd2b1e68
GH
711 }
712
50e0d793 713
20e4a32c 714 void focus_on_function(Dwarf_Die * f)
bd2b1e68
GH
715 {
716 assert(f);
50e0d793
GH
717 assert(module);
718 assert(cu);
719
bd2b1e68 720 function = f;
20e4a32c 721 function_name = default_name(dwarf_diename(function),
bd2b1e68 722 "function");
bd2b1e68
GH
723 }
724
50e0d793 725
bd2b1e68
GH
726 void focus_on_module_containing_global_address(Dwarf_Addr a)
727 {
728 assert(dwfl);
50e0d793 729 cu = NULL;
0ce64fb8
FCE
730 Dwfl_Module* mod = dwfl_addrmodule(dwfl, a);
731 if (mod) // address could be wildly out of range
5f0a03a6 732 focus_on_module(mod, NULL);
bd2b1e68
GH
733 }
734
50e0d793 735
7e1279ea 736 void query_cu_containing_global_address(Dwarf_Addr a, void *arg)
bd2b1e68 737 {
bd2b1e68 738 Dwarf_Addr bias;
50e0d793 739 assert(dwfl);
5227f1ea 740 get_module_dwarf();
ab55a5ae
FCE
741 Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias);
742 if (cudie) // address could be wildly out of range
743 query_cu (cudie, arg);
bd2b1e68
GH
744 assert(bias == module_bias);
745 }
746
50e0d793 747
7e1279ea 748 void query_cu_containing_module_address(Dwarf_Addr a, void *arg)
bd2b1e68 749 {
7e1279ea 750 query_cu_containing_global_address(module_address_to_global(a), arg);
bd2b1e68
GH
751 }
752
50e0d793 753
bd2b1e68
GH
754 Dwarf_Addr module_address_to_global(Dwarf_Addr a)
755 {
50e0d793 756 assert(dwfl);
bd2b1e68 757 assert(module);
5227f1ea 758 get_module_dwarf();
c239d28c
GH
759 if (module_name == TOK_KERNEL)
760 return a;
50e0d793 761 return a + module_start;
bd2b1e68
GH
762 }
763
50e0d793 764
bd2b1e68
GH
765 Dwarf_Addr global_address_to_module(Dwarf_Addr a)
766 {
767 assert(module);
5227f1ea 768 get_module_dwarf();
bd2b1e68
GH
769 return a - module_bias;
770 }
771
772
773 bool module_name_matches(string pattern)
774 {
bd2b1e68 775 bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
b8da0ad1 776 if (t && sess.verbose>3)
bd2b1e68 777 clog << "pattern '" << pattern << "' "
24cb178f 778 << "matches "
db22e55f 779 << "module '" << module_name << "'" << "\n";
bd2b1e68
GH
780 return t;
781 }
5f0a03a6
JK
782 bool name_has_wildcard(string pattern)
783 {
784 return (pattern.find('*') != string::npos ||
785 pattern.find('?') != string::npos ||
786 pattern.find('[') != string::npos);
787 }
b8da0ad1
FCE
788 bool module_name_final_match(string pattern)
789 {
790 // Assume module_name_matches(). Can there be any more matches?
791 // Not unless the pattern is a wildcard, since module names are
792 // presumed unique.
5f0a03a6 793 return !name_has_wildcard(pattern);
b8da0ad1 794 }
bd2b1e68 795
50e0d793 796
5f0a03a6 797 bool function_name_matches_pattern(string name, string pattern)
bd2b1e68 798 {
5f0a03a6 799 bool t = (fnmatch(pattern.c_str(), name.c_str(), 0) == 0);
b8da0ad1 800 if (t && sess.verbose>3)
bd2b1e68 801 clog << "pattern '" << pattern << "' "
24cb178f 802 << "matches "
5f0a03a6 803 << "function '" << name << "'" << "\n";
bd2b1e68
GH
804 return t;
805 }
5f0a03a6
JK
806 bool function_name_matches(string pattern)
807 {
808 assert(function);
809 return function_name_matches_pattern(function_name, pattern);
810 }
275f40a6
FCE
811 bool function_name_final_match(string pattern)
812 {
813 return module_name_final_match (pattern);
814 }
bd2b1e68 815
50e0d793 816
bd2b1e68
GH
817 bool cu_name_matches(string pattern)
818 {
819 assert(cu);
820 bool t = (fnmatch(pattern.c_str(), cu_name.c_str(), 0) == 0);
b8da0ad1 821 if (t && sess.verbose>3)
bd2b1e68 822 clog << "pattern '" << pattern << "' "
24cb178f 823 << "matches "
db22e55f 824 << "CU '" << cu_name << "'" << "\n";
bd2b1e68
GH
825 return t;
826 }
827
50e0d793 828
b40af7ee 829 // NB: "rc == 0" means OK in this case
c931ec8a 830 static void dwfl_assert(string desc, int rc, string extra_msg = "")
bd2b1e68 831 {
7e1279ea 832 string msg = "libdwfl failure (" + desc + "): ";
d8067b24
FCE
833 if (rc < 0) msg += dwfl_errmsg (rc);
834 else if (rc > 0) msg += strerror (rc);
bd2b1e68 835 if (rc != 0)
b40af7ee
DS
836 {
837 if (extra_msg.length() > 0)
838 msg += "\n" + extra_msg;
839 throw semantic_error (msg);
840 }
bd2b1e68
GH
841 }
842
7e1279ea
FCE
843 void dwarf_assert(string desc, int rc) // NB: "rc == 0" means OK in this case
844 {
845 string msg = "libdw failure (" + desc + "): ";
846 if (rc < 0) msg += dwarf_errmsg (rc);
847 else if (rc > 0) msg += strerror (rc);
848 if (rc != 0)
849 throw semantic_error (msg);
850 }
851
5f0a03a6
JK
852 // static so pathname_caching_callback() can access them
853 static module_cache_t module_cache;
854 static bool ignore_vmlinux;
50e0d793 855
5f0a03a6
JK
856
857 dwflpp(systemtap_session & session)
bd2b1e68 858 :
5f0a03a6 859 sess(session),
bd2b1e68
GH
860 dwfl(NULL),
861 module(NULL),
862 module_dwarf(NULL),
863 module_bias(0),
5f0a03a6 864 mod_info(NULL),
50e0d793
GH
865 module_start(0),
866 module_end(0),
bd2b1e68
GH
867 cu(NULL),
868 function(NULL)
5f0a03a6
JK
869 {
870 ignore_vmlinux = sess.ignore_vmlinux;
871 }
7a053d3b 872
5f0a03a6
JK
873 // Called by dwfl_linux_kernel_report_offline(). We may not have
874 // dwarf info for the kernel and/or modules, so remember this
875 // module's pathname in case we need to extract elf info from it.
876 // (Currently, we get all the elf info we need via elfutils -- if the
877 // elf file exists -- so remembering the pathname isn't strictly needed.
878 // But we still need to handle the case where there's no vmlinux.)
879 static int pathname_caching_callback(const char *name, const char *path)
880 {
881 module_info *mi = new module_info(name);
882 module_cache.cache[name] = mi;
883
884 if (ignore_vmlinux && path && name == TOK_KERNEL)
885 {
886 // report_kernel() in elfutils found vmlinux, but pretend it didn't.
887 // Given a non-null path, returning 1 means keep reporting modules.
888 mi->dwarf_status = info_absent;
889 return 1;
890 }
891 else if (path)
892 {
893 mi->elf_path = path;
894 return 1;
895 }
896
897 // No vmlinux. Here returning 0 to report_kernel() means go ahead
898 // and keep reporting modules.
899 assert(name == TOK_KERNEL);
900 mi->dwarf_status = info_absent;
901 return 0;
902 }
50e0d793 903
1969b5bc 904 void setup(bool kernel, bool debuginfo_needed = true)
bd2b1e68 905 {
b5d77020 906 // XXX: this is where the session -R parameter could come in
12603f28 907 static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug:build";
25114db1
FCE
908 static char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
909
910 static char *debuginfo_path = (debuginfo_env_arr ?
911 debuginfo_env_arr : debuginfo_path_arr);
921d6103
SD
912 static const char *debug_path = (debuginfo_env_arr ?
913 debuginfo_env_arr : sess.kernel_release.c_str());
b5d77020 914
bd2b1e68
GH
915 static const Dwfl_Callbacks proc_callbacks =
916 {
917 dwfl_linux_proc_find_elf,
918 dwfl_standard_find_debuginfo,
919 NULL,
b5d77020 920 & debuginfo_path
bd2b1e68 921 };
7a053d3b 922
bd2b1e68
GH
923 static const Dwfl_Callbacks kernel_callbacks =
924 {
925 dwfl_linux_kernel_find_elf,
926 dwfl_standard_find_debuginfo,
b20febf3 927 dwfl_offline_section_address,
b5d77020 928 & debuginfo_path
bd2b1e68
GH
929 };
930
931 if (kernel)
932 {
7e1279ea 933 dwfl = dwfl_begin (&kernel_callbacks);
bd2b1e68 934 if (!dwfl)
7e1279ea
FCE
935 throw semantic_error ("cannot open dwfl");
936 dwfl_report_begin (dwfl);
b20febf3 937
5f0a03a6
JK
938 int (*callback)(const char *name, const char *path);
939 if (sess.consult_symtab && !module_cache.paths_collected)
940 {
941 callback = pathname_caching_callback;
942 module_cache.paths_collected = true;
943 }
944 else
945 callback = NULL;
1969b5bc 946 int rc = dwfl_linux_kernel_report_offline (dwfl,
921d6103 947 debug_path,
1969b5bc 948 /* selection predicate */
5f0a03a6 949 callback);
1969b5bc 950 if (debuginfo_needed)
464c2dcb
FCE
951 dwfl_assert (string("missing kernel ") +
952 sess.kernel_release +
953 string(" ") +
954 sess.architecture +
4baf0e53 955 string(" debuginfo"),
464c2dcb 956 rc);
b20febf3
FCE
957
958 // XXX: it would be nice if we could do a single
959 // ..._report_offline call for an entire systemtap script, so
960 // that a selection predicate would filter out modules outside
961 // the union of all the requested wildcards. But we build
962 // derived_probes one-by-one and we don't have lookahead.
963
964 // XXX: a special case: if we have only kernel.* probe points,
965 // we shouldn't waste time looking for module debug-info (and
966 // vice versa).
967
968 // NB: the result of an _offline call is the assignment of
969 // virtualized addresses to relocatable objects such as
970 // modules. These have to be converted to real addresses at
971 // run time. See the dwarf_derived_probe ctor and its caller.
bd2b1e68
GH
972 }
973 else
974 {
7e1279ea
FCE
975 dwfl = dwfl_begin (&proc_callbacks);
976 dwfl_report_begin (dwfl);
bd2b1e68 977 if (!dwfl)
7e1279ea 978 throw semantic_error ("cannot open dwfl");
b20febf3
FCE
979
980 throw semantic_error ("user-space probes not yet implemented");
bd2b1e68
GH
981 // XXX: Find pids or processes, do userspace stuff.
982 }
983
7e1279ea 984 dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL));
bd2b1e68
GH
985 }
986
b8da0ad1
FCE
987
988
989 // -----------------------------------------------------------------
990
4baf0e53 991 static int module_caching_callback(Dwfl_Module * mod,
b8da0ad1
FCE
992 void **,
993 const char *name,
994 Dwarf_Addr addr,
995 void *param)
b20febf3 996 {
5f0a03a6
JK
997 module_cache_t *cache = static_cast<module_cache_t*>(param);
998 module_info *mi = NULL;
999
1000 if (ignore_vmlinux && name == TOK_KERNEL)
1001 // This wouldn't be called for vmlinux if vmlinux weren't there.
1002 return DWARF_CB_OK;
1003
1004 if (cache->paths_collected)
1005 mi = cache->cache[name];
1006 if (!mi)
1007 {
1008 mi = new module_info(name);
1009 cache->cache[name] = mi;
1010 }
1011 mi->mod = mod;
1012 mi->addr = addr;
b8da0ad1 1013 return DWARF_CB_OK;
b20febf3
FCE
1014 }
1015
5f0a03a6 1016 void cache_modules_dwarf()
bd2b1e68 1017 {
5f0a03a6 1018 if (!module_cache.dwarf_collected)
bd2b1e68 1019 {
b8da0ad1
FCE
1020 ptrdiff_t off = 0;
1021 do
1022 {
49abf162 1023 if (pending_interrupts) return;
b8da0ad1
FCE
1024 off = dwfl_getmodules (dwfl, module_caching_callback,
1025 & module_cache, off);
1026 }
1027 while (off > 0);
1028 dwfl_assert("dwfl_getmodules", off);
5f0a03a6 1029 module_cache.dwarf_collected = true;
b8da0ad1 1030 }
5f0a03a6 1031 }
b8da0ad1 1032
5f0a03a6
JK
1033 void iterate_over_modules(int (* callback)(Dwfl_Module *, module_info *,
1034 const char *, Dwarf_Addr,
1035 void *),
1036 void * data)
1037 {
1038 cache_modules_dwarf();
1039
1040 map<string, module_info*>::iterator i;
1041 for (i = module_cache.cache.begin(); i != module_cache.cache.end(); i++)
b8da0ad1 1042 {
49abf162 1043 if (pending_interrupts) return;
5f0a03a6
JK
1044 module_info *mi = i->second;
1045 int rc = callback (mi->mod, mi, mi->name, mi->addr, data);
b8da0ad1 1046 if (rc != DWARF_CB_OK) break;
bd2b1e68 1047 }
bd2b1e68
GH
1048 }
1049
5f0a03a6
JK
1050 // Defined after dwarf_query
1051 void query_modules(dwarf_query *q);
7e1279ea 1052
b8da0ad1
FCE
1053
1054 // -----------------------------------------------------------------
1055
1056 typedef map<Dwarf*, vector<Dwarf_Die>*> module_cu_cache_t;
1057 module_cu_cache_t module_cu_cache;
1058
7a053d3b 1059 void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
bd2b1e68
GH
1060 void * data)
1061 {
0ce64fb8 1062 get_module_dwarf(false);
b8da0ad1
FCE
1063 Dwarf *dw = module_dwarf;
1064 if (!dw) return;
5227f1ea 1065
b8da0ad1
FCE
1066 vector<Dwarf_Die>* v = module_cu_cache[dw];
1067 if (v == 0)
1068 {
1069 v = new vector<Dwarf_Die>;
1070 module_cu_cache[dw] = v;
bd2b1e68 1071
b8da0ad1
FCE
1072 Dwarf_Off off = 0;
1073 size_t cuhl;
1074 Dwarf_Off noff;
1075 while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
1076 {
49abf162 1077 if (pending_interrupts) return;
b8da0ad1
FCE
1078 Dwarf_Die die_mem;
1079 Dwarf_Die *die;
1080 die = dwarf_offdie (dw, off + cuhl, &die_mem);
1081 v->push_back (*die); /* copy */
1082 off = noff;
1083 }
1084 }
1085
1086 for (unsigned i = 0; i < v->size(); i++)
7a053d3b 1087 {
49abf162 1088 if (pending_interrupts) return;
b8da0ad1
FCE
1089 Dwarf_Die die = v->at(i);
1090 int rc = (*callback)(& die, data);
1091 if (rc != DWARF_CB_OK) break;
bd2b1e68
GH
1092 }
1093 }
1094
bd2b1e68 1095
b8da0ad1
FCE
1096 // -----------------------------------------------------------------
1097
7e1279ea 1098 bool func_is_inline()
bd2b1e68 1099 {
7e1279ea
FCE
1100 assert (function);
1101 return dwarf_func_inline (function) != 0;
bd2b1e68
GH
1102 }
1103
b8da0ad1
FCE
1104
1105 typedef map<string, vector<Dwarf_Die>*> cu_inl_function_cache_t;
1106 cu_inl_function_cache_t cu_inl_function_cache;
1107
1108 static int cu_inl_function_caching_callback (Dwarf_Die* func, void *arg)
1109 {
1110 vector<Dwarf_Die>* v = static_cast<vector<Dwarf_Die>*>(arg);
1111 v->push_back (* func);
1112 return DWARF_CB_OK;
1113 }
1114
7e1279ea
FCE
1115 void iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg),
1116 void * data)
bd2b1e68 1117 {
7e1279ea
FCE
1118 assert (function);
1119 assert (func_is_inline ());
b8da0ad1
FCE
1120
1121 string key = module_name + ":" + cu_name + ":" + function_name;
1122 vector<Dwarf_Die>* v = cu_inl_function_cache[key];
1123 if (v == 0)
1124 {
1125 v = new vector<Dwarf_Die>;
1126 cu_inl_function_cache[key] = v;
1127 dwarf_func_inline_instances (function, cu_inl_function_caching_callback, v);
1128 }
1129
1130 for (unsigned i=0; i<v->size(); i++)
1131 {
1132 Dwarf_Die die = v->at(i);
1133 int rc = (*callback)(& die, data);
1134 if (rc != DWARF_CB_OK) break;
1135 }
4fa7b22b 1136 }
bd2b1e68 1137
50e0d793 1138
b8da0ad1
FCE
1139 // -----------------------------------------------------------------
1140
6561773f 1141 mod_cu_function_cache_t cu_function_cache;
b8da0ad1
FCE
1142
1143 static int cu_function_caching_callback (Dwarf_Die* func, void *arg)
1144 {
6561773f
FCE
1145 cu_function_cache_t* v = static_cast<cu_function_cache_t*>(arg);
1146 string function_name = dwarf_diename(func);
1147 (*v)[function_name] = * func;
b8da0ad1
FCE
1148 return DWARF_CB_OK;
1149 }
1150
5f0a03a6 1151 int iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg),
6561773f 1152 void * data);
d9b516ca 1153
fedd4090 1154 bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno);
897820ca 1155
7e1279ea 1156 void iterate_over_srcfile_lines (char const * srcfile,
20e4a32c 1157 int lineno,
897820ca 1158 bool need_single_match,
0c8b7d37 1159 bool line_type_relative,
20e4a32c 1160 void (* callback) (Dwarf_Line * line, void * arg),
7e1279ea
FCE
1161 void *data)
1162 {
6315bd76
GH
1163 Dwarf_Line **srcsp = NULL;
1164 size_t nsrcs = 0;
fedd4090 1165 dwarf_query * q = static_cast<dwarf_query *>(data);
bb788f9f 1166
7e1279ea 1167 get_module_dwarf();
bb788f9f 1168
0c8b7d37
SC
1169 if (line_type_relative)
1170 {
1171 Dwarf_Addr addr;
1172 Dwarf_Line *line;
1173 int line_number;
1174
1175 dwarf_assert ("dwarf_entrypc", dwarf_entrypc (this->function, &addr));
1176 line = dwarf_getsrc_die (this->cu, addr);
1177 dwarf_assert ("dwarf_getsrc_die", line == NULL);
1178 dwarf_assert ("dwarf_lineno", dwarf_lineno (line, &line_number));
1179 lineno += line_number;
1180 }
1181
7e1279ea 1182 dwarf_assert ("dwarf_getsrc_file",
20e4a32c 1183 dwarf_getsrc_file (module_dwarf,
7e1279ea
FCE
1184 srcfile, lineno, 0,
1185 &srcsp, &nsrcs));
fedd4090
FCE
1186
1187 // NB: Formerly, we used to filter, because:
20e4a32c 1188
847bf07f
FCE
1189 // dwarf_getsrc_file gets one *near hits* for line numbers, not
1190 // exact matches. For example, an existing file but a nonexistent
1191 // line number will be rounded up to the next definition in that
1192 // file. This may be similar to the GDB breakpoint algorithm, but
1193 // we don't want to be so fuzzy in systemtap land. So we filter.
1194
fedd4090
FCE
1195 // But we now see the error of our ways, and skip this filtering.
1196
847bf07f
FCE
1197 // XXX: the code also fails to match e.g. inline function
1198 // definitions when the srcfile is a header file rather than the
1199 // CU name.
1200
1201 size_t remaining_nsrcs = nsrcs;
fedd4090 1202#if 0
847bf07f
FCE
1203 for (size_t i = 0; i < nsrcs; ++i)
1204 {
1205 int l_no;
1206 Dwarf_Line* l = srcsp[i];
1207 dwarf_assert ("dwarf_lineno", dwarf_lineno (l, & l_no));
1208 if (l_no != lineno)
1209 {
1210 if (sess.verbose > 3)
18face2b 1211 clog << "skipping line number mismatch "
4baf0e53 1212 << "(" << l_no << " vs " << lineno << ")"
847bf07f
FCE
1213 << " in file '" << srcfile << "'"
1214 << "\n";
1215 srcsp[i] = 0;
1216 remaining_nsrcs --;
1217 }
1218 }
fedd4090 1219#endif
847bf07f
FCE
1220
1221 if (need_single_match && remaining_nsrcs > 1)
897820ca
GH
1222 {
1223 // We wanted a single line record (a unique address for the
1224 // line) and we got a bunch of line records. We're going to
1225 // skip this probe (throw an exception) but before we throw
1226 // we're going to look around a bit to see if there's a low or
1227 // high line number nearby which *doesn't* have this problem,
1228 // so we can give the user some advice.
1229
1230 int lo_try = -1;
1231 int hi_try = -1;
114ffac2 1232 for (size_t i = 1; i < 6; ++i)
897820ca 1233 {
fedd4090 1234 if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i))
897820ca
GH
1235 lo_try = lineno - i;
1236
fedd4090 1237 if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i))
897820ca
GH
1238 hi_try = lineno + i;
1239 }
1240
fedd4090
FCE
1241 stringstream advice;
1242 advice << "multiple addresses for " << srcfile << ":" << lineno;
897820ca 1243 if (lo_try > 0 || hi_try > 0)
fedd4090
FCE
1244 {
1245 advice << " (try ";
1246 if (lo_try > 0)
1247 advice << srcfile << ":" << lo_try;
1248 if (lo_try > 0 && hi_try > 0)
1249 advice << " or ";
1250 if (hi_try > 0)
1251 advice << srcfile << ":" << hi_try;
1252 advice << ")";
1253 }
1254 throw semantic_error (advice.str());
897820ca
GH
1255 }
1256
20e4a32c 1257 try
bb788f9f 1258 {
6315bd76
GH
1259 for (size_t i = 0; i < nsrcs; ++i)
1260 {
49abf162 1261 if (pending_interrupts) return;
847bf07f
FCE
1262 if (srcsp [i]) // skip over mismatched lines
1263 callback (srcsp[i], data);
6315bd76 1264 }
bb788f9f 1265 }
6315bd76
GH
1266 catch (...)
1267 {
1268 free (srcsp);
1269 throw;
20e4a32c 1270 }
6315bd76 1271 free (srcsp);
50e0d793
GH
1272 }
1273
1274
7e1279ea
FCE
1275 void collect_srcfiles_matching (string const & pattern,
1276 set<char const *> & filtered_srcfiles)
50e0d793 1277 {
7e1279ea
FCE
1278 assert (module);
1279 assert (cu);
bb788f9f 1280
7e1279ea
FCE
1281 size_t nfiles;
1282 Dwarf_Files *srcfiles;
bb788f9f 1283
20e4a32c 1284 dwarf_assert ("dwarf_getsrcfiles",
7e1279ea
FCE
1285 dwarf_getsrcfiles (cu, &srcfiles, &nfiles));
1286 {
1287 for (size_t i = 0; i < nfiles; ++i)
50e0d793 1288 {
7e1279ea
FCE
1289 char const * fname = dwarf_filesrc (srcfiles, i, NULL, NULL);
1290 if (fnmatch (pattern.c_str(), fname, 0) == 0)
50e0d793 1291 {
7e1279ea 1292 filtered_srcfiles.insert (fname);
b0ee93c4 1293 if (sess.verbose>2)
db22e55f 1294 clog << "selected source file '" << fname << "'\n";
50e0d793
GH
1295 }
1296 }
7e1279ea 1297 }
20e4a32c 1298 }
50e0d793 1299
7e1279ea 1300 void resolve_prologue_endings (map<Dwarf_Addr, func_info> & funcs)
7d71e1d5
FCE
1301 {
1302 // This heuristic attempts to pick the first address that has a
34ca7d84
FCE
1303 // source line distinct from the function declaration's. In a
1304 // perfect world, this would be the first statement *past* the
1305 // prologue.
1306
7d71e1d5
FCE
1307 assert(module);
1308 assert(cu);
1309
456aa31c
FCE
1310 size_t nlines = 0;
1311 Dwarf_Lines *lines = NULL;
7d71e1d5 1312
dc223023
FCE
1313 /* trouble cases:
1314 malloc do_symlink in init/initramfs.c tail-recursive/tiny then no-prologue
1315 sys_get?id in kernel/timer.c no-prologue
1316 sys_exit_group tail-recursive
1317 {do_,}sys_open extra-long-prologue (gcc 3.4)
1318 cpu_to_logical_apicid NULL-decl_file
1319 */
1320
1321 // Fetch all srcline records, sorted by address.
20e4a32c
RM
1322 dwarf_assert ("dwarf_getsrclines",
1323 dwarf_getsrclines(cu, &lines, &nlines));
dc223023 1324 // XXX: free lines[] later, but how?
7d71e1d5 1325
dc223023 1326 for(map<Dwarf_Addr,func_info>::iterator it = funcs.begin(); it != funcs.end(); it++)
7d71e1d5 1327 {
dc223023
FCE
1328#if 0 /* someday */
1329 Dwarf_Addr* bkpts = 0;
1330 int n = dwarf_entry_breakpoints (& it->second.die, & bkpts);
1331 // ...
1332 free (bkpts);
1333#endif
20e4a32c 1334
dc223023
FCE
1335 Dwarf_Addr entrypc = it->first;
1336 Dwarf_Addr highpc; // NB: highpc is exclusive: [entrypc,highpc)
1337 func_info* func = &it->second;
e38d6504 1338 dwfl_assert ("dwarf_highpc", dwarf_highpc (& func->die,
dc223023
FCE
1339 & highpc));
1340
1341 if (func->decl_file == 0) func->decl_file = "";
e38d6504 1342
dc223023
FCE
1343 unsigned entrypc_srcline_idx = 0;
1344 Dwarf_Line* entrypc_srcline = 0;
1345 // open-code binary search for exact match
1346 {
1347 unsigned l = 0, h = nlines;
1348 while (l < h)
1349 {
1350 entrypc_srcline_idx = (l + h) / 2;
1351 Dwarf_Addr addr;
1352 Dwarf_Line *lr = dwarf_onesrcline(lines, entrypc_srcline_idx);
1353 dwarf_lineaddr (lr, &addr);
1354 if (addr == entrypc) { entrypc_srcline = lr; break; }
1355 else if (l + 1 == h) { break; } // ran off bottom of tree
1356 else if (addr < entrypc) { l = entrypc_srcline_idx; }
1357 else { h = entrypc_srcline_idx; }
e38d6504 1358 }
dc223023 1359 }
e38d6504
RM
1360 if (entrypc_srcline == 0)
1361 throw semantic_error ("missing entrypc dwarf line record for function '"
dc223023
FCE
1362 + func->name + "'");
1363
1364 if (sess.verbose>2)
1365 clog << "prologue searching function '" << func->name << "'"
5fe3e97f 1366 << " 0x" << hex << entrypc << "-0x" << highpc << dec
dc223023
FCE
1367 << "@" << func->decl_file << ":" << func->decl_line
1368 << "\n";
1369
1370 // Now we go searching for the first line record that has a
1371 // file/line different from the one in the declaration.
1372 // Normally, this will be the next one. BUT:
1373 //
1374 // We may have to skip a few because some old compilers plop
1375 // in dummy line records for longer prologues. If we go too
1376 // far (addr >= highpc), we take the previous one. Or, it may
1377 // be the first one, if the function had no prologue, and thus
1378 // the entrypc maps to a statement in the body rather than the
1379 // declaration.
1380
1381 unsigned postprologue_srcline_idx = entrypc_srcline_idx;
1382 bool ranoff_end = false;
35f5f091 1383 while (postprologue_srcline_idx < nlines)
7d71e1d5 1384 {
dc223023
FCE
1385 Dwarf_Addr postprologue_addr;
1386 Dwarf_Line *lr = dwarf_onesrcline(lines, postprologue_srcline_idx);
1387 dwarf_lineaddr (lr, &postprologue_addr);
1388 const char* postprologue_file = dwarf_linesrc (lr, NULL, NULL);
1389 int postprologue_lineno;
7d71e1d5 1390 dwfl_assert ("dwarf_lineno",
dc223023 1391 dwarf_lineno (lr, & postprologue_lineno));
456aa31c 1392
b0ee93c4 1393 if (sess.verbose>2)
dc223023
FCE
1394 clog << "checking line record 0x" << hex << postprologue_addr << dec
1395 << "@" << postprologue_file << ":" << postprologue_lineno << "\n";
1396
1397 if (postprologue_addr >= highpc)
e38d6504
RM
1398 {
1399 ranoff_end = true;
1400 postprologue_srcline_idx --;
dc223023
FCE
1401 continue;
1402 }
1403 if (ranoff_end ||
1404 (strcmp (postprologue_file, func->decl_file) || // We have a winner!
1405 (postprologue_lineno != func->decl_line)))
1406 {
1407 func->prologue_end = postprologue_addr;
1408
1409 if (sess.verbose>2)
1410 {
1411 clog << "prologue found function '" << func->name << "'";
1412 // Add a little classification datum
1413 if (postprologue_srcline_idx == entrypc_srcline_idx) clog << " (naked)";
1414 if (ranoff_end) clog << " (tail-call?)";
1415 clog << " = 0x" << hex << postprologue_addr << dec << "\n";
1416 }
1417
1418 break;
1419 }
e38d6504 1420
dc223023
FCE
1421 // Let's try the next srcline.
1422 postprologue_srcline_idx ++;
1423 } // loop over srclines
7d71e1d5 1424
dc223023
FCE
1425 // if (strlen(func->decl_file) == 0) func->decl_file = NULL;
1426
1427 } // loop over functions
b20febf3
FCE
1428
1429 // XXX: how to free lines?
bd2b1e68
GH
1430 }
1431
7e1279ea
FCE
1432
1433 bool function_entrypc (Dwarf_Addr * addr)
1434 {
1435 assert (function);
20e4a32c 1436 return (dwarf_entrypc (function, addr) == 0);
b8da0ad1 1437 // XXX: see also _lowpc ?
7e1279ea
FCE
1438 }
1439
1440
1441 bool die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr)
1442 {
5bc4ac10
FCE
1443 int rc = 0;
1444 string lookup_method;
7e1279ea 1445
5bc4ac10
FCE
1446 * addr = 0;
1447
1448 lookup_method = "dwarf_entrypc";
1449 rc = dwarf_entrypc (die, addr);
1450
4baf0e53 1451 if (rc)
5bc4ac10
FCE
1452 {
1453 lookup_method = "dwarf_lowpc";
1454 rc = dwarf_lowpc (die, addr);
1455 }
1456
1457 if (rc)
1458 {
1459 lookup_method = "dwarf_ranges";
1460
1461 Dwarf_Addr base;
1462 Dwarf_Addr begin;
1463 Dwarf_Addr end;
1464 ptrdiff_t offset = dwarf_ranges (die, 0, &base, &begin, &end);
1465 if (offset < 0) rc = -1;
1466 else if (offset > 0)
1467 {
1468 * addr = begin;
1469 rc = 0;
1470
1471 // Now we need to check that there are no more ranges
1472 // associated with this function, which could conceivably
1473 // happen if a function is inlined, then pieces of it are
1474 // split amongst different conditional branches. It's not
1475 // obvious which of them to favour. As a heuristic, we
1476 // pick the beginning of the first range, and ignore the
1477 // others (but with a warning).
1478
1479 unsigned extra = 0;
1480 while ((offset = dwarf_ranges (die, offset, &base, &begin, &end)) > 0)
1481 extra ++;
1482 if (extra)
1483 lookup_method += ", ignored " + lex_cast<string>(extra) + " more";
1484 }
1485 }
4baf0e53 1486
5bc4ac10
FCE
1487 if (sess.verbose > 2)
1488 clog << "entry-pc lookup (" << lookup_method << ") = 0x" << hex << *addr << dec
4baf0e53 1489 << " (rc " << rc << ")"
5bc4ac10
FCE
1490 << endl;
1491 return (rc == 0);
7e1279ea
FCE
1492 }
1493
4cd232e4
GH
1494 void function_die (Dwarf_Die *d)
1495 {
1496 assert (function);
20e4a32c 1497 *d = *function;
4cd232e4 1498 }
7e1279ea 1499
4cd232e4 1500 void function_file (char const ** c)
7e1279ea
FCE
1501 {
1502 assert (function);
4cd232e4 1503 assert (c);
20e4a32c 1504 *c = dwarf_decl_file (function);
7e1279ea
FCE
1505 }
1506
4cd232e4 1507 void function_line (int *linep)
7e1279ea
FCE
1508 {
1509 assert (function);
20e4a32c 1510 dwarf_decl_line (function, linep);
7e1279ea
FCE
1511 }
1512
1513 bool die_has_pc (Dwarf_Die * die, Dwarf_Addr pc)
1514 {
1515 int res = dwarf_haspc (die, pc);
1516 if (res == -1)
1517 dwarf_assert ("dwarf_haspc", res);
1518 return res == 1;
1519 }
1520
1521
78f6bba6 1522 static void loc2c_error (void *, const char *fmt, ...)
e36387d7 1523 {
78f6bba6
FCE
1524 const char *msg = "?";
1525 char *tmp = NULL;
5ce20b7a 1526 int rc;
e36387d7
RM
1527 va_list ap;
1528 va_start (ap, fmt);
78f6bba6
FCE
1529 rc = vasprintf (& tmp, fmt, ap);
1530 if (rc < 0)
1531 msg = "?";
1532 else
1533 msg = tmp;
e36387d7
RM
1534 va_end (ap);
1535 throw semantic_error (msg);
1536 }
bd2b1e68 1537
e664cf5b
FCE
1538 // This function generates code used for addressing computations of
1539 // target variables.
e38d6504
RM
1540 void emit_address (struct obstack *pool, Dwarf_Addr address)
1541 {
e664cf5b
FCE
1542 #if 0
1543 // The easy but incorrect way is to just print a hard-wired
1544 // constant.
e38d6504 1545 obstack_printf (pool, "%#" PRIx64 "UL", address);
e664cf5b 1546 #endif
e38d6504
RM
1547
1548 // Turn this address into a section-relative offset if it should be one.
1549 // We emit a comment approximating the variable+offset expression that
1550 // relocatable module probing code will need to have.
1551 Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
1552 dwfl_assert ("dwfl_addrmodule", mod == NULL);
1553 int n = dwfl_module_relocations (mod);
1554 dwfl_assert ("dwfl_module_relocations", n < 0);
d64e82b1
SD
1555 int i = dwfl_module_relocate_address (mod, &address);
1556 dwfl_assert ("dwfl_module_relocate_address", i < 0);
1557 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
1558 NULL, NULL, NULL, NULL);
1559 dwfl_assert ("dwfl_module_info", modname == NULL);
1560 const char *secname = dwfl_module_relocation_info (mod, i, NULL);
1561
1562 if (n > 0 && !(n == 1 && secname == NULL))
1563 {
e38d6504
RM
1564 dwfl_assert ("dwfl_module_relocation_info", secname == NULL);
1565 if (n > 1 || secname[0] != '\0')
7e41d3dc
FCE
1566 {
1567 // This gives us the module name, and section name within the
1568 // module, for a kernel module (or other ET_REL module object).
1569 obstack_printf (pool, "({ static unsigned long addr = 0; ");
1570 obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
1571 modname, secname, address);
1572 obstack_printf (pool, "addr; })");
1573 }
4baf0e53 1574 else if (n == 1 && module_name == TOK_KERNEL && secname[0] == '\0')
21beacc9
FCE
1575 {
1576 // elfutils' way of telling us that this is a relocatable kernel address, which we
1577 // need to treat the same way here as dwarf_query::add_probe_point does: _stext.
1578 address -= sess.sym_stext;
1579 secname = "_stext";
1580 obstack_printf (pool, "({ static unsigned long addr = 0; ");
1581 obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
1582 modname, secname, address);
1583 obstack_printf (pool, "addr; })");
1584 }
e38d6504 1585 else
e664cf5b
FCE
1586 {
1587 throw semantic_error ("cannot relocate user-space dso (?) address");
1588#if 0
1589 // This would happen for a Dwfl_Module that's a user-level DSO.
1590 obstack_printf (pool, " /* %s+%#" PRIx64 " */",
1591 modname, address);
1592#endif
1593 }
e38d6504 1594 }
e664cf5b
FCE
1595 else
1596 obstack_printf (pool, "%#" PRIx64 "UL", address); // assume as constant
e38d6504 1597 }
7e1279ea 1598
4b1ad75e
RM
1599 static void loc2c_emit_address (void *arg, struct obstack *pool,
1600 Dwarf_Addr address)
1601 {
1602 dwflpp *dwfl = (dwflpp *) arg;
e38d6504 1603 dwfl->emit_address (pool, address);
4b1ad75e
RM
1604 }
1605
82e72903
DS
1606 void print_locals(Dwarf_Die *die, ostream &o)
1607 {
1608 // Try to get the first child of die.
1609 bool local_found = false;
1610 Dwarf_Die child;
1611 if (dwarf_child (die, &child) == 0)
1612 {
1613 do
1614 {
1615 // Output each sibling's name (that is a variable or
1616 // parameter) to 'o'.
1617 switch (dwarf_tag (&child))
1618 {
1619 case DW_TAG_variable:
1620 case DW_TAG_formal_parameter:
1621 o << " " << dwarf_diename (&child);
1622 local_found = true;
1623 break;
1624 default:
1625 break;
1626 }
1627 }
1628 while (dwarf_siblingof (&child, &child) == 0);
1629 }
1630
1631 if (! local_found)
1632 o << " (none found)";
1633 }
1634
e57b735a
GH
1635 Dwarf_Attribute *
1636 find_variable_and_frame_base (Dwarf_Die *scope_die,
20e4a32c 1637 Dwarf_Addr pc,
91eefb1c 1638 string const & local,
e57b735a
GH
1639 Dwarf_Die *vardie,
1640 Dwarf_Attribute *fb_attr_mem)
77de5e9e 1641 {
77de5e9e 1642 Dwarf_Die *scopes;
bcc12710 1643 int nscopes = 0;
e57b735a
GH
1644 Dwarf_Attribute *fb_attr = NULL;
1645
1646 assert (cu);
bcc12710
FCE
1647
1648 if (scope_die)
1649 nscopes = dwarf_getscopes_die (scope_die, &scopes);
1650 else
1651 nscopes = dwarf_getscopes (cu, pc, &scopes);
77de5e9e 1652
77de5e9e
GH
1653 if (nscopes == 0)
1654 {
7a053d3b 1655 throw semantic_error ("unable to find any scopes containing "
59ff2773 1656 + lex_cast_hex<string>(pc)
77de5e9e
GH
1657 + " while searching for local '" + local + "'");
1658 }
7a053d3b 1659
77de5e9e 1660 int declaring_scope = dwarf_getscopevar (scopes, nscopes,
7a053d3b
RM
1661 local.c_str(),
1662 0, NULL, 0, 0,
e57b735a 1663 vardie);
77de5e9e
GH
1664 if (declaring_scope < 0)
1665 {
82e72903
DS
1666 stringstream alternatives;
1667 print_locals (scopes, alternatives);
77de5e9e 1668 throw semantic_error ("unable to find local '" + local + "'"
82e72903
DS
1669 + " near pc " + lex_cast_hex<string>(pc)
1670 + " (alternatives:" + alternatives.str ()
1671 + ")");
77de5e9e 1672 }
7a053d3b 1673
77de5e9e
GH
1674 for (int inner = 0; inner < nscopes; ++inner)
1675 {
1676 switch (dwarf_tag (&scopes[inner]))
1677 {
1678 default:
1679 continue;
1680 case DW_TAG_subprogram:
1681 case DW_TAG_entry_point:
1682 case DW_TAG_inlined_subroutine: /* XXX */
1683 if (inner >= declaring_scope)
1684 fb_attr = dwarf_attr_integrate (&scopes[inner],
1685 DW_AT_frame_base,
e57b735a 1686 fb_attr_mem);
77de5e9e
GH
1687 break;
1688 }
1689 }
e57b735a
GH
1690 return fb_attr;
1691 }
77de5e9e 1692
77de5e9e 1693
d1531387
RM
1694 struct location *
1695 translate_location(struct obstack *pool,
1696 Dwarf_Attribute *attr, Dwarf_Addr pc,
1697 Dwarf_Attribute *fb_attr,
1698 struct location **tail)
1699 {
1700 Dwarf_Op *expr;
1701 size_t len;
1702
1703 switch (dwarf_getlocation_addr (attr, pc - module_bias, &expr, &len, 1))
1704 {
1705 case 1: /* Should always happen. */
1706 if (len > 0)
1707 break;
1708 /* Fall through. */
1709
1710 case 0: /* Shouldn't happen. */
1711 throw semantic_error ("not accessible at this address");
1712
1713 default: /* Shouldn't happen. */
1714 case -1:
1715 throw semantic_error (string ("dwarf_getlocation_addr failed") +
1716 string (dwarf_errmsg (-1)));
1717 }
1718
1719 return c_translate_location (pool, &loc2c_error, this,
1720 &loc2c_emit_address,
1721 1, module_bias,
1722 pc, expr, len, tail, fb_attr);
1723 }
1724
82e72903
DS
1725 void
1726 print_members(Dwarf_Die *vardie, ostream &o)
1727 {
1728 const int typetag = dwarf_tag (vardie);
1729
1730 if (typetag != DW_TAG_structure_type && typetag != DW_TAG_union_type)
1731 {
1732 o << " Error: "
1733 << (dwarf_diename_integrate (vardie) ?: "<anonymous>")
1734 << " isn't a struct/union";
1735 return;
1736 }
1737
1738 // Try to get the first child of vardie.
1739 Dwarf_Die die_mem;
1740 Dwarf_Die *die = &die_mem;
1741 switch (dwarf_child (vardie, die))
1742 {
1743 case 1: // No children.
1744 o << ((typetag == DW_TAG_union_type) ? " union " : " struct ")
1745 << (dwarf_diename_integrate (die) ?: "<anonymous>")
1746 << " is empty";
1747 break;
1748
1749 case -1: // Error.
1750 default: // Shouldn't happen.
1751 o << ((typetag == DW_TAG_union_type) ? " union " : " struct ")
1752 << (dwarf_diename_integrate (die) ?: "<anonymous>")
1753 << ": " << dwarf_errmsg (-1);
1754 break;
1755
1756 case 0: // Success.
1757 break;
1758 }
1759
1760 // Output each sibling's name to 'o'.
1761 while (dwarf_tag (die) == DW_TAG_member)
1762 {
1763 const char *member = (dwarf_diename_integrate (die) ?: "<anonymous>");
4baf0e53 1764
82e72903
DS
1765 o << " " << member;
1766
1767 if (dwarf_siblingof (die, &die_mem) != 0)
1768 break;
1769 }
1770 }
1771
e57b735a
GH
1772 Dwarf_Die *
1773 translate_components(struct obstack *pool,
20e4a32c
RM
1774 struct location **tail,
1775 Dwarf_Addr pc,
e57b735a
GH
1776 vector<pair<target_symbol::component_type,
1777 std::string> > const & components,
1778 Dwarf_Die *vardie,
1779 Dwarf_Die *die_mem,
1780 Dwarf_Attribute *attr_mem)
1781 {
1782 Dwarf_Die *die = vardie;
82e72903 1783 Dwarf_Die struct_die;
d9b516ca
RM
1784 unsigned i = 0;
1785 while (i < components.size())
1786 {
0301cfe7
FCE
1787 /* XXX: This would be desirable, but we don't get the target_symbol token,
1788 and printing that gives us the file:line number too early anyway. */
1789#if 0
1790 // Emit a marker to note which field is being access-attempted, to give
1791 // better error messages if deref() fails.
1792 string piece = string(...target_symbol token...) + string ("#") + stringify(components[i].second);
1793 obstack_printf (pool, "c->last_stmt = %s;", lex_cast_qstring(piece).c_str());
1794#endif
1795
e57b735a 1796 die = dwarf_formref_die (attr_mem, die_mem);
d9b516ca
RM
1797 const int typetag = dwarf_tag (die);
1798 switch (typetag)
1799 {
1800 case DW_TAG_typedef:
fdfbe4f7
GH
1801 case DW_TAG_const_type:
1802 case DW_TAG_volatile_type:
d9b516ca
RM
1803 /* Just iterate on the referent type. */
1804 break;
91eefb1c 1805
d9b516ca
RM
1806 case DW_TAG_pointer_type:
1807 if (components[i].first == target_symbol::comp_literal_array_index)
2302c47e
FCE
1808 throw semantic_error ("cannot index pointer");
1809 // XXX: of course, we should support this the same way C does,
b0be9bdb 1810 // by explicit pointer arithmetic etc. PR4166.
91eefb1c 1811
e57b735a 1812 c_translate_pointer (pool, 1, module_bias, die, tail);
d9b516ca 1813 break;
91eefb1c 1814
d9b516ca
RM
1815 case DW_TAG_array_type:
1816 if (components[i].first == target_symbol::comp_literal_array_index)
1817 {
e57b735a 1818 c_translate_array (pool, 1, module_bias, die, tail,
d9b516ca
RM
1819 NULL, lex_cast<Dwarf_Word>(components[i].second));
1820 ++i;
1821 }
1822 else
1823 throw semantic_error("bad field '"
1824 + components[i].second
1825 + "' for array type");
1826 break;
91eefb1c 1827
d9b516ca
RM
1828 case DW_TAG_structure_type:
1829 case DW_TAG_union_type:
82e72903 1830 struct_die = *die;
e57b735a 1831 switch (dwarf_child (die, die_mem))
d9b516ca
RM
1832 {
1833 case 1: /* No children. */
1834 throw semantic_error ("empty struct "
1835 + string (dwarf_diename_integrate (die) ?: "<anonymous>"));
1836 break;
1837 case -1: /* Error. */
1838 default: /* Shouldn't happen */
1839 throw semantic_error (string (typetag == DW_TAG_union_type ? "union" : "struct")
1840 + string (dwarf_diename_integrate (die) ?: "<anonymous>")
1841 + string (dwarf_errmsg (-1)));
1842 break;
1843
1844 case 0:
1845 break;
1846 }
1847
1848 while (dwarf_tag (die) != DW_TAG_member
1849 || ({ const char *member = dwarf_diename_integrate (die);
1850 member == NULL || string(member) != components[i].second; }))
e57b735a 1851 if (dwarf_siblingof (die, die_mem) != 0)
82e72903
DS
1852 {
1853 stringstream alternatives;
1854 print_members (&struct_die, alternatives);
1855 throw semantic_error ("field '" + components[i].second
1856 + "' not found (alternatives:"
1857 + alternatives.str () + ")");
1858 }
d9b516ca
RM
1859
1860 if (dwarf_attr_integrate (die, DW_AT_data_member_location,
e57b735a 1861 attr_mem) == NULL)
d9b516ca
RM
1862 {
1863 /* Union members don't usually have a location,
1864 but just use the containing union's location. */
1865 if (typetag != DW_TAG_union_type)
9f36b77f 1866 throw semantic_error ("no location for field '"
d9b516ca 1867 + components[i].second
9f36b77f 1868 + "' :" + string(dwarf_errmsg (-1)));
d9b516ca
RM
1869 }
1870 else
d1531387 1871 translate_location (pool, attr_mem, pc, NULL, tail);
d9b516ca
RM
1872 ++i;
1873 break;
1874
1875 case DW_TAG_base_type:
9f36b77f 1876 throw semantic_error ("field '"
d9b516ca 1877 + components[i].second
9f36b77f 1878 + "' vs. base type "
d9b516ca
RM
1879 + string(dwarf_diename_integrate (die) ?: "<anonymous type>"));
1880 break;
1881 case -1:
1882 throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)));
1883 break;
1884
1885 default:
1886 throw semantic_error (string(dwarf_diename_integrate (die) ?: "<anonymous type>")
1887 + ": unexpected type tag "
1888 + lex_cast<string>(dwarf_tag (die)));
1889 break;
1890 }
1891
1892 /* Now iterate on the type in DIE's attribute. */
e57b735a 1893 if (dwarf_attr_integrate (die, DW_AT_type, attr_mem) == NULL)
d9b516ca
RM
1894 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
1895 }
e57b735a
GH
1896 return die;
1897 }
91eefb1c 1898
d9b516ca 1899
e57b735a
GH
1900 Dwarf_Die *
1901 resolve_unqualified_inner_typedie (Dwarf_Die *typedie_mem,
1902 Dwarf_Attribute *attr_mem)
1903 {
1904 ;
d9b516ca 1905 Dwarf_Die *typedie;
e57b735a 1906 int typetag = 0;
d9b516ca 1907 while (1)
20e4a32c 1908 {
e57b735a 1909 typedie = dwarf_formref_die (attr_mem, typedie_mem);
d9b516ca 1910 if (typedie == NULL)
e57b735a 1911 throw semantic_error ("cannot get type: " + string(dwarf_errmsg (-1)));
d9b516ca 1912 typetag = dwarf_tag (typedie);
20e4a32c 1913 if (typetag != DW_TAG_typedef &&
fdfbe4f7
GH
1914 typetag != DW_TAG_const_type &&
1915 typetag != DW_TAG_volatile_type)
91eefb1c 1916 break;
e57b735a
GH
1917 if (dwarf_attr_integrate (typedie, DW_AT_type, attr_mem) == NULL)
1918 throw semantic_error ("cannot get type of pointee: " + string(dwarf_errmsg (-1)));
d9b516ca 1919 }
e57b735a
GH
1920 return typedie;
1921 }
91eefb1c 1922
91eefb1c 1923
20e4a32c 1924 void
e57b735a
GH
1925 translate_final_fetch_or_store (struct obstack *pool,
1926 struct location **tail,
1927 Dwarf_Addr module_bias,
1928 Dwarf_Die *die,
1929 Dwarf_Attribute *attr_mem,
1930 bool lvalue,
b8da0ad1
FCE
1931 string &,
1932 string &,
e57b735a
GH
1933 exp_type & ty)
1934 {
1935 /* First boil away any qualifiers associated with the type DIE of
1936 the final location to be accessed. */
fdfbe4f7 1937
e57b735a
GH
1938 Dwarf_Die typedie_mem;
1939 Dwarf_Die *typedie;
1940 int typetag;
022b623f
DS
1941 char const *dname;
1942 string diestr;
e57b735a
GH
1943
1944 typedie = resolve_unqualified_inner_typedie (&typedie_mem, attr_mem);
1945 typetag = dwarf_tag (typedie);
1946
1947 /* Then switch behavior depending on the type of fetch/store we
1948 want, and the type and pointer-ness of the final location. */
20e4a32c 1949
fdfbe4f7
GH
1950 switch (typetag)
1951 {
fdfbe4f7 1952 default:
022b623f
DS
1953 dname = dwarf_diename(die);
1954 diestr = (dname != NULL) ? dname : "<unknown>";
66d284f4 1955 throw semantic_error ("unsupported type tag "
022b623f
DS
1956 + lex_cast<string>(typetag)
1957 + " for " + diestr);
1958 break;
1959
1960 case DW_TAG_structure_type:
1961 case DW_TAG_union_type:
1962 dname = dwarf_diename(die);
1963 diestr = (dname != NULL) ? dname : "<unknown>";
1964 throw semantic_error ("struct/union '" + diestr
1965 + "' is being accessed instead of a member of the struct/union");
fdfbe4f7 1966 break;
66d284f4 1967
e7a012f0 1968 case DW_TAG_enumeration_type:
fdfbe4f7
GH
1969 case DW_TAG_base_type:
1970 ty = pe_long;
e57b735a
GH
1971 if (lvalue)
1972 c_translate_store (pool, 1, module_bias, die, typedie, tail,
1973 "THIS->value");
20e4a32c 1974 else
e57b735a
GH
1975 c_translate_fetch (pool, 1, module_bias, die, typedie, tail,
1976 "THIS->__retvalue");
fdfbe4f7
GH
1977 break;
1978
1979 case DW_TAG_array_type:
1980 case DW_TAG_pointer_type:
e57b735a 1981
b0be9bdb 1982 {
fdfbe4f7
GH
1983 Dwarf_Die pointee_typedie_mem;
1984 Dwarf_Die *pointee_typedie;
1985 Dwarf_Word pointee_encoding;
246b383e 1986 Dwarf_Word pointee_byte_size = 0;
fdfbe4f7 1987
e57b735a
GH
1988 pointee_typedie = resolve_unqualified_inner_typedie (&pointee_typedie_mem, attr_mem);
1989
1990 if (dwarf_attr_integrate (pointee_typedie, DW_AT_byte_size, attr_mem))
1991 dwarf_formudata (attr_mem, &pointee_byte_size);
20e4a32c
RM
1992
1993 dwarf_formudata (dwarf_attr_integrate (pointee_typedie, DW_AT_encoding, attr_mem),
fdfbe4f7
GH
1994 &pointee_encoding);
1995
b0be9bdb
FCE
1996 if (lvalue)
1997 {
1998 ty = pe_long;
1999 if (typetag == DW_TAG_array_type)
2000 throw semantic_error ("cannot write to array address");
2001 assert (typetag == DW_TAG_pointer_type);
2002 c_translate_pointer_store (pool, 1, module_bias, typedie, tail,
2003 "THIS->value");
2004 }
2005 else
2006 {
2007 // We have the pointer: cast it to an integral type via &(*(...))
2008
2009 // NB: per bug #1187, at one point char*-like types were
2010 // automagically converted here to systemtap string values.
2011 // For several reasons, this was taken back out, leaving
2012 // pointer-to-string "conversion" (copying) to tapset functions.
2013
2014 ty = pe_long;
2015 if (typetag == DW_TAG_array_type)
2016 c_translate_array (pool, 1, module_bias, typedie, tail, NULL, 0);
2017 else
2018 c_translate_pointer (pool, 1, module_bias, typedie, tail);
2019 c_translate_addressof (pool, 1, module_bias, NULL, pointee_typedie, tail,
2020 "THIS->__retvalue");
2021 }
2022 }
20e4a32c 2023 break;
fdfbe4f7 2024 }
20e4a32c 2025 }
e57b735a 2026
e19fda4e
DS
2027 string
2028 express_as_string (string prelude,
2029 string postlude,
2030 struct location *head)
2031 {
2032 size_t bufsz = 1024;
2033 char *buf = static_cast<char*>(malloc(bufsz));
2034 assert(buf);
2035
2036 FILE *memstream = open_memstream (&buf, &bufsz);
2037 assert(memstream);
2038
2039 fprintf(memstream, "{\n");
2040 fprintf(memstream, prelude.c_str());
2041 bool deref = c_emit_location (memstream, head, 1);
2042 fprintf(memstream, postlude.c_str());
2043 fprintf(memstream, " goto out;\n");
2044
2045 // dummy use of deref_fault label, to disable warning if deref() not used
2046 fprintf(memstream, "if (0) goto deref_fault;\n");
2047
2048 // XXX: deref flag not reliable; emit fault label unconditionally
78f6bba6 2049 (void) deref;
e19fda4e
DS
2050 fprintf(memstream,
2051 "deref_fault:\n"
e19fda4e
DS
2052 " goto out;\n");
2053 fprintf(memstream, "}\n");
2054
2055 fclose (memstream);
2056 string result(buf);
2057 free (buf);
2058 return result;
2059 }
e57b735a 2060
20e4a32c 2061 string
e57b735a 2062 literal_stmt_for_local (Dwarf_Die *scope_die,
20e4a32c 2063 Dwarf_Addr pc,
e57b735a
GH
2064 string const & local,
2065 vector<pair<target_symbol::component_type,
2066 std::string> > const & components,
2067 bool lvalue,
2068 exp_type & ty)
2069 {
2070 Dwarf_Die vardie;
2071 Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
2072
20e4a32c 2073 fb_attr = find_variable_and_frame_base (scope_die, pc, local,
e57b735a
GH
2074 &vardie, &fb_attr_mem);
2075
b0ee93c4 2076 if (sess.verbose>2)
e57b735a
GH
2077 clog << "finding location for local '" << local
2078 << "' near address " << hex << pc
2079 << ", module bias " << module_bias << dec
db22e55f 2080 << "\n";
e57b735a
GH
2081
2082 Dwarf_Attribute attr_mem;
2083 if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
2084 {
2085 throw semantic_error("failed to retrieve location "
20e4a32c
RM
2086 "attribute for local '" + local
2087 + "' (dieoffset: "
2088 + lex_cast_hex<string>(dwarf_dieoffset (&vardie))
e57b735a
GH
2089 + ")");
2090 }
2091
2092#define obstack_chunk_alloc malloc
2093#define obstack_chunk_free free
2094
2095 struct obstack pool;
2096 obstack_init (&pool);
2097 struct location *tail = NULL;
2098
2099 /* Given $foo->bar->baz[NN], translate the location of foo. */
2100
d1531387
RM
2101 struct location *head = translate_location (&pool,
2102 &attr_mem, pc, fb_attr, &tail);
e57b735a
GH
2103
2104 if (dwarf_attr_integrate (&vardie, DW_AT_type, &attr_mem) == NULL)
2105 throw semantic_error("failed to retrieve type "
2106 "attribute for local '" + local + "'");
2107
2108
2109 /* Translate the ->bar->baz[NN] parts. */
2110
2111 Dwarf_Die die_mem, *die = NULL;
20e4a32c 2112 die = translate_components (&pool, &tail, pc, components,
e57b735a
GH
2113 &vardie, &die_mem, &attr_mem);
2114
20e4a32c
RM
2115 /* Translate the assignment part, either
2116 x = $foo->bar->baz[NN]
2117 or
e57b735a
GH
2118 $foo->bar->baz[NN] = x
2119 */
2120
2121 string prelude, postlude;
20e4a32c 2122 translate_final_fetch_or_store (&pool, &tail, module_bias,
e57b735a
GH
2123 die, &attr_mem, lvalue,
2124 prelude, postlude, ty);
2125
2126 /* Write the translation to a string. */
e19fda4e
DS
2127 return express_as_string(prelude, postlude, head);
2128 }
20e4a32c 2129
20e4a32c 2130
e19fda4e
DS
2131 string
2132 literal_stmt_for_return (Dwarf_Die *scope_die,
2133 Dwarf_Addr pc,
2134 vector<pair<target_symbol::component_type,
2135 std::string> > const & components,
2136 bool lvalue,
2137 exp_type & ty)
2138 {
2139 if (sess.verbose>2)
2140 clog << "literal_stmt_for_return: finding return value for "
2141 << dwarf_diename (scope_die)
2142 << "("
2143 << dwarf_diename (cu)
2144 << ")\n";
7a053d3b 2145
e19fda4e
DS
2146 struct obstack pool;
2147 obstack_init (&pool);
2148 struct location *tail = NULL;
7a053d3b 2149
e19fda4e
DS
2150 /* Given $return->bar->baz[NN], translate the location of return. */
2151 const Dwarf_Op *locops;
2152 int nlocops = dwfl_module_return_value_location (module, scope_die,
2153 &locops);
2154 if (nlocops < 0)
2155 {
2156 throw semantic_error("failed to retrieve return value location");
2157 }
2158 // the function has no return value (e.g. "void" in C)
2159 else if (nlocops == 0)
2160 {
2161 throw semantic_error("function has no return value");
2162 }
a781f401 2163
e19fda4e
DS
2164 struct location *head = c_translate_location (&pool, &loc2c_error, this,
2165 &loc2c_emit_address,
2166 1, module_bias,
2167 pc, locops, nlocops,
2168 &tail, NULL);
7a053d3b 2169
e19fda4e 2170 /* Translate the ->bar->baz[NN] parts. */
7a053d3b 2171
e19fda4e
DS
2172 Dwarf_Attribute attr_mem;
2173 Dwarf_Attribute *attr = dwarf_attr (scope_die, DW_AT_type, &attr_mem);
2174
2175 Dwarf_Die vardie_mem;
2176 Dwarf_Die *vardie = dwarf_formref_die (attr, &vardie_mem);
2177
2178 Dwarf_Die die_mem, *die = NULL;
2179 die = translate_components (&pool, &tail, pc, components,
2180 vardie, &die_mem, &attr_mem);
2181
2182 /* Translate the assignment part, either
2183 x = $return->bar->baz[NN]
2184 or
2185 $return->bar->baz[NN] = x
2186 */
2187
2188 string prelude, postlude;
2189 translate_final_fetch_or_store (&pool, &tail, module_bias,
2190 die, &attr_mem, lvalue,
2191 prelude, postlude, ty);
2192
2193 /* Write the translation to a string. */
2194 return express_as_string(prelude, postlude, head);
2195 }
7a053d3b 2196
77de5e9e 2197
bd2b1e68
GH
2198 ~dwflpp()
2199 {
2200 if (dwfl)
2201 dwfl_end(dwfl);
2202 }
2203};
2204
5f0a03a6
JK
2205module_cache_t dwflpp::module_cache;
2206bool dwflpp::ignore_vmlinux = false;
2207
20c6c071 2208
7a053d3b 2209enum
bd2b1e68 2210function_spec_type
7a053d3b 2211 {
bd2b1e68
GH
2212 function_alone,
2213 function_and_file,
7a053d3b 2214 function_file_and_line
bd2b1e68
GH
2215 };
2216
ec4373ff 2217
bd2b1e68 2218struct dwarf_builder;
77de5e9e 2219
2930abc7 2220
b20febf3
FCE
2221// XXX: This class is a candidate for subclassing to separate
2222// the relocation vs non-relocation variants. Likewise for
2223// kprobe vs kretprobe variants.
2224
2225struct dwarf_derived_probe: public derived_probe
b55bc428 2226{
b20febf3
FCE
2227 dwarf_derived_probe (const string& function,
2228 const string& filename,
2229 int line,
2230 const string& module,
2231 const string& section,
2232 Dwarf_Addr dwfl_addr,
2930abc7 2233 Dwarf_Addr addr,
b20febf3
FCE
2234 dwarf_query & q,
2235 Dwarf_Die* scope_die);
20e4a32c 2236
b20febf3
FCE
2237 string module;
2238 string section;
2239 Dwarf_Addr addr;
2930abc7 2240 bool has_return;
c9bad430
DS
2241 bool has_maxactive;
2242 long maxactive_val;
2930abc7 2243
b8da0ad1
FCE
2244 void printsig (std::ostream &o) const;
2245
b20febf3 2246 void join_group (systemtap_session& s);
d9b516ca 2247
bd2b1e68 2248 // Pattern registration helpers.
7a053d3b 2249 static void register_statement_variants(match_node * root,
bd2b1e68 2250 dwarf_builder * dw);
fd6602a0
FCE
2251 static void register_function_variants(match_node * root,
2252 dwarf_builder * dw);
7a053d3b 2253 static void register_function_and_statement_variants(match_node * root,
bd2b1e68 2254 dwarf_builder * dw);
20c6c071 2255 static void register_patterns(match_node * root);
20c6c071
GH
2256};
2257
dc38c0ae
DS
2258
2259struct dwarf_derived_probe_group: public derived_probe_group
2260{
2261private:
b20febf3
FCE
2262 multimap<string,dwarf_derived_probe*> probes_by_module;
2263 typedef multimap<string,dwarf_derived_probe*>::iterator p_b_m_iterator;
dc38c0ae
DS
2264
2265public:
b20febf3
FCE
2266 void enroll (dwarf_derived_probe* probe);
2267 void emit_module_decls (systemtap_session& s);
2268 void emit_module_init (systemtap_session& s);
2269 void emit_module_exit (systemtap_session& s);
dc38c0ae
DS
2270};
2271
2272
20c6c071 2273// Helper struct to thread through the dwfl callbacks.
2c384610 2274struct base_query
20c6c071 2275{
2c384610
DS
2276 base_query(systemtap_session & sess,
2277 probe * base_probe,
2278 probe_point * base_loc,
2279 dwflpp & dw,
2280 map<string, literal *> const & params,
2281 vector<derived_probe *> & results);
2282 virtual ~base_query() {}
bd2b1e68 2283
5227f1ea 2284 systemtap_session & sess;
2c384610
DS
2285 probe * base_probe;
2286 probe_point * base_loc;
2287 dwflpp & dw;
2288 vector<derived_probe *> & results;
5227f1ea 2289
bd2b1e68 2290 // Parameter extractors.
7a053d3b 2291 static bool has_null_param(map<string, literal *> const & params,
888af770 2292 string const & k);
7a053d3b 2293 static bool get_string_param(map<string, literal *> const & params,
bd2b1e68 2294 string const & k, string & v);
7a053d3b 2295 static bool get_number_param(map<string, literal *> const & params,
bd2b1e68 2296 string const & k, long & v);
c239d28c
GH
2297 static bool get_number_param(map<string, literal *> const & params,
2298 string const & k, Dwarf_Addr & v);
b55bc428 2299
2c384610
DS
2300 // Extracted parameters.
2301 bool has_kernel;
2302 string module_val; // has_kernel => module_val = "kernel"
2303
2304 virtual void handle_query_module() = 0;
2305};
2306
2307
2308base_query::base_query(systemtap_session & sess,
2309 probe * base_probe,
2310 probe_point * base_loc,
2311 dwflpp & dw,
2312 map<string, literal *> const & params,
2313 vector<derived_probe *> & results)
2314 : sess(sess), base_probe(base_probe), base_loc(base_loc), dw(dw),
2315 results(results)
2316{
2317 has_kernel = has_null_param(params, TOK_KERNEL);
2318 if (has_kernel)
2319 module_val = "kernel";
4baf0e53 2320 else
2c384610
DS
2321 {
2322 bool has_module = get_string_param(params, TOK_MODULE, module_val);
2323 assert (has_module); // no other options are possible by construction
ced347a9 2324 (void) has_module;
2c384610
DS
2325 }
2326}
2327
2328bool
2329base_query::has_null_param(map<string, literal *> const & params,
2330 string const & k)
2331{
888af770 2332 return derived_probe_builder::has_null_param(params, k);
2c384610
DS
2333}
2334
2335
2336bool
2337base_query::get_string_param(map<string, literal *> const & params,
2338 string const & k, string & v)
2339{
2340 return derived_probe_builder::get_param (params, k, v);
2341}
2342
2343
2344bool
2345base_query::get_number_param(map<string, literal *> const & params,
2346 string const & k, long & v)
2347{
2348 int64_t value;
2349 bool present = derived_probe_builder::get_param (params, k, value);
2350 v = (long) value;
2351 return present;
2352}
2353
2354
2355bool
2356base_query::get_number_param(map<string, literal *> const & params,
2357 string const & k, Dwarf_Addr & v)
2358{
2359 int64_t value;
2360 bool present = derived_probe_builder::get_param (params, k, value);
2361 v = (Dwarf_Addr) value;
2362 return present;
2363}
2364
2365
0c8b7d37
SC
2366enum line_t { ABSOLUTE, RELATIVE };
2367
2c384610
DS
2368struct dwarf_query : public base_query
2369{
2370 dwarf_query(systemtap_session & sess,
2371 probe * base_probe,
2372 probe_point * base_loc,
2373 dwflpp & dw,
2374 map<string, literal *> const & params,
2375 vector<derived_probe *> & results);
2376
2377 virtual void handle_query_module();
5f0a03a6
JK
2378 void query_module_dwarf();
2379 void query_module_symtab();
2c384610 2380
2930abc7
FCE
2381 void add_probe_point(string const & funcname,
2382 char const * filename,
2383 int line,
2384 Dwarf_Die *scope_die,
2385 Dwarf_Addr addr);
d64e82b1 2386 string get_blacklist_section(Dwarf_Addr addr);
20c6c071 2387
a7301475
FCE
2388 regex_t blacklist_func; // function/statement probes
2389 regex_t blacklist_func_ret; // only for .return probes
2390 regex_t blacklist_file; // file name
0daad364
JS
2391 void build_blacklist();
2392
b20febf3
FCE
2393 bool blacklisted_p(const string& funcname,
2394 const string& filename,
36f9dd1d 2395 int line,
b20febf3
FCE
2396 const string& module,
2397 const string& section,
36f9dd1d
FCE
2398 Dwarf_Addr addr);
2399
2930abc7 2400 // Extracted parameters.
7a053d3b 2401 string function_val;
20c6c071
GH
2402
2403 bool has_function_str;
2404 bool has_statement_str;
2405 bool has_function_num;
2406 bool has_statement_num;
7a053d3b
RM
2407 string statement_str_val;
2408 string function_str_val;
c239d28c
GH
2409 Dwarf_Addr statement_num_val;
2410 Dwarf_Addr function_num_val;
20c6c071 2411
b8da0ad1
FCE
2412 bool has_call;
2413 bool has_inline;
20c6c071
GH
2414 bool has_return;
2415
c9bad430
DS
2416 bool has_maxactive;
2417 long maxactive_val;
2418
20c6c071
GH
2419 bool has_label;
2420 string label_val;
2421
2422 bool has_relative;
2423 long relative_val;
2424
37ebca01
FCE
2425 bool has_absolute;
2426
5f0a03a6
JK
2427 enum dbinfo_reqt dbinfo_reqt;
2428 enum dbinfo_reqt assess_dbinfo_reqt();
2429
20c6c071
GH
2430 function_spec_type parse_function_spec(string & spec);
2431 function_spec_type spec_type;
2432 string function;
2433 string file;
0c8b7d37 2434 line_t line_type;
20c6c071 2435 int line;
5f0a03a6 2436 bool query_done; // Found exact match
20c6c071 2437
7e1279ea
FCE
2438 set<char const *> filtered_srcfiles;
2439
2440 // Map official entrypc -> func_info object
2441 map<Dwarf_Addr, inline_instance_info> filtered_inlines;
2442 map<Dwarf_Addr, func_info> filtered_functions;
2443 bool choose_next_line;
2444 Dwarf_Addr entrypc_for_next_line;
b55bc428
FCE
2445};
2446
98afd80e 2447
fedd4090
FCE
2448// This little test routine represents an unfortunate breakdown in
2449// abstraction between dwflpp (putatively, a layer right on top of
2450// elfutils), and dwarf_query (interpreting a systemtap probe point).
2451// It arises because we sometimes try to fix up slightly-off
2452// .statement() probes (something we find out in fairly low-level).
2453//
2454// An alternative would be to put some more intellgence into query_cu(),
4baf0e53 2455// and have it print additional suggestions after finding that
fedd4090
FCE
2456// q->dw.iterate_over_srcfile_lines resulted in no new finished_results.
2457
2458bool
2459dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int lineno)
2460{
2461 if (lineno < 0)
2462 return false;
2463
2464 Dwarf_Line **srcsp = NULL;
2465 size_t nsrcs = 0;
2466
2467 dwarf_assert ("dwarf_getsrc_file",
2468 dwarf_getsrc_file (module_dwarf,
2469 srcfile, lineno, 0,
2470 &srcsp, &nsrcs));
2471
4baf0e53 2472 if (nsrcs != 1)
fedd4090
FCE
2473 {
2474 if (sess.verbose>4)
2475 clog << "alternative line " << lineno << " rejected: nsrcs=" << nsrcs << endl;
2476 return false;
2477 }
2478
2479 // We also try to filter out lines that leave the selected
2480 // functions (if any).
2481
2482 Dwarf_Line *line = srcsp[0];
2483 Dwarf_Addr addr;
2484 dwarf_lineaddr (line, &addr);
2485
2486 for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
2487 i != q->filtered_functions.end(); ++i)
2488 {
2489 if (q->dw.die_has_pc (&(i->second.die), addr))
2490 {
2491 if (q->sess.verbose>4)
2492 clog << "alternative line " << lineno << " accepted: fn=" << i->second.name << endl;
2493 return true;
2494 }
2495 }
2496
2497 for (map<Dwarf_Addr, inline_instance_info>::iterator i = q->filtered_inlines.begin();
2498 i != q->filtered_inlines.end(); ++i)
2499 {
2500 if (q->dw.die_has_pc (&(i->second.die), addr))
2501 {
2502 if (sess.verbose>4)
2503 clog << "alternative line " << lineno << " accepted: ifn=" << i->second.name << endl;
2504 return true;
2505 }
2506 }
2507
2508 if (sess.verbose>4)
2509 clog << "alternative line " << lineno << " rejected: leaves selected fns" << endl;
2510 return false;
2511 }
2512
2513
6561773f
FCE
2514int
2515dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg),
2516 void * data)
2517{
2518 int rc = DWARF_CB_OK;
2519 assert (module);
2520 assert (cu);
2521 dwarf_query * q = static_cast<dwarf_query *>(data);
2522
2523 string key = module_name + ":" + cu_name;
2524 cu_function_cache_t *v = cu_function_cache[key];
2525 if (v == 0)
2526 {
2527 v = new cu_function_cache_t;
2528 cu_function_cache[key] = v;
2529 dwarf_getfuncs (cu, cu_function_caching_callback, v, 0);
2530 if (q->sess.verbose > 4)
2531 clog << "function cache " << key << " size " << v->size() << endl;
2532 }
2533
2534 string subkey = q->function;
2535 if (v->find(subkey) != v->end())
2536 {
2171f774 2537 Dwarf_Die die = v->find(subkey)->second;
6561773f
FCE
2538 if (q->sess.verbose > 4)
2539 clog << "function cache " << key << " hit " << subkey << endl;
2540 return (*callback)(& die, data);
2541 }
2542 else if (name_has_wildcard (subkey))
2543 {
2544 for (cu_function_cache_t::iterator it = v->begin(); it != v->end(); it++)
2545 {
2546 string func_name = it->first;
2547 Dwarf_Die die = it->second;
2548 if (function_name_matches_pattern (func_name, subkey))
2549 {
2550 if (q->sess.verbose > 4)
2551 clog << "function cache " << key << " match " << func_name << " vs " << subkey << endl;
2552
2553 rc = (*callback)(& die, data);
2554 if (rc != DWARF_CB_OK) break;
2555 }
2556 }
2557 }
cf314c0f
WH
2558 else if (q->has_statement_num) // searching all for kernel.statement
2559 {
2560 for (cu_function_cache_t::iterator it = v->begin(); it != v->end(); it++)
2561 {
2562 Dwarf_Die die = it->second;
2563 rc = (*callback)(& die, data);
2564 if (rc != DWARF_CB_OK) break;
2565 }
2566 }
6561773f
FCE
2567 else // not a wildcard and no match in this CU
2568 {
2569 // do nothing
2570 }
2571 return rc;
2572}
2573
2574
fedd4090 2575
98afd80e 2576struct dwarf_builder: public derived_probe_builder
b55bc428 2577{
e38d6504 2578 dwflpp *kern_dw;
b8da0ad1 2579 dwarf_builder(): kern_dw(0) {}
aa30ccd3
FCE
2580
2581 void build_no_more (systemtap_session &s)
2582 {
2583 if (kern_dw)
2584 {
2585 if (s.verbose > 3)
2586 clog << "dwarf_builder releasing dwflpp" << endl;
2587 delete kern_dw;
2588 kern_dw = 0;
2589 }
2590 }
2591
e38d6504
RM
2592 ~dwarf_builder()
2593 {
b8da0ad1
FCE
2594 // XXX: in practice, NOTREACHED
2595 delete kern_dw;
c8959a29 2596 }
aa30ccd3 2597
5227f1ea 2598 virtual void build(systemtap_session & sess,
7a053d3b 2599 probe * base,
20c6c071
GH
2600 probe_point * location,
2601 std::map<std::string, literal *> const & parameters,
20c6c071 2602 vector<derived_probe *> & finished_results);
b55bc428
FCE
2603};
2604
888af770 2605
5227f1ea
GH
2606dwarf_query::dwarf_query(systemtap_session & sess,
2607 probe * base_probe,
20c6c071
GH
2608 probe_point * base_loc,
2609 dwflpp & dw,
2610 map<string, literal *> const & params,
2611 vector<derived_probe *> & results)
2c384610 2612 : base_query(sess, base_probe, base_loc, dw, params, results)
bd2b1e68
GH
2613{
2614 // Reduce the query to more reasonable semantic values (booleans,
2615 // extracted strings, numbers, etc).
bd2b1e68
GH
2616 has_function_str = get_string_param(params, TOK_FUNCTION, function_str_val);
2617 has_function_num = get_number_param(params, TOK_FUNCTION, function_num_val);
2618
2619 has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val);
2620 has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val);
2621
b8da0ad1
FCE
2622 has_call = has_null_param(params, TOK_CALL);
2623 has_inline = has_null_param(params, TOK_INLINE);
bd2b1e68 2624 has_return = has_null_param(params, TOK_RETURN);
c9bad430 2625 has_maxactive = get_number_param(params, TOK_MAXACTIVE, maxactive_val);
37ebca01
FCE
2626 has_absolute = has_null_param(params, TOK_ABSOLUTE);
2627
bd2b1e68
GH
2628 if (has_function_str)
2629 spec_type = parse_function_spec(function_str_val);
2630 else if (has_statement_str)
2631 spec_type = parse_function_spec(statement_str_val);
0daad364 2632
b8da0ad1 2633 build_blacklist(); // XXX: why not reuse amongst dwarf_query instances?
5f0a03a6
JK
2634 dbinfo_reqt = assess_dbinfo_reqt();
2635 query_done = false;
0daad364
JS
2636}
2637
2638
2c384610 2639void
5f0a03a6 2640dwarf_query::query_module_dwarf()
2c384610
DS
2641{
2642 if (has_function_num || has_statement_num)
2643 {
2644 // If we have module("foo").function(0xbeef) or
2645 // module("foo").statement(0xbeef), the address is relative
2646 // to the start of the module, so we seek the function
2647 // number plus the module's bias.
2648
2649 Dwarf_Addr addr;
2650 if (has_function_num)
2651 addr = function_num_val;
2652 else
2653 addr = statement_num_val;
4baf0e53 2654
2c384610
DS
2655 // NB: we don't need to add the module base address or bias
2656 // value here (for reasons that may be coincidental).
2657 dw.query_cu_containing_module_address(addr, this);
2658 }
2659 else
2660 {
2661 // Otherwise if we have a function("foo") or statement("foo")
2662 // specifier, we have to scan over all the CUs looking for
2663 // the function(s) in question
2664 assert(has_function_str || has_statement_str);
2665 dw.iterate_over_cus(&query_cu, this);
2666 }
2667}
2668
5f0a03a6
JK
2669static void query_func_info (Dwarf_Addr entrypc, func_info & fi,
2670 dwarf_query * q);
2671
2672void
2673dwarf_query::query_module_symtab()
2674{
2675 // Get the symbol table if it's necessary, sufficient, and not already got.
2676 if (dbinfo_reqt == dbr_need_dwarf)
2677 return;
2678
2679 module_info *mi = dw.mod_info;
2680 if (dbinfo_reqt == dbr_need_symtab)
2681 {
2682 if (mi->symtab_status == info_unknown)
2683 mi->get_symtab(this);
2684 if (mi->symtab_status == info_absent)
2685 return;
2686 }
2687
2688 func_info *fi = NULL;
2689 symbol_table *sym_table = mi->sym_table;
2690
2691 if (has_function_str)
2692 {
2693 // Per dwarf_query::assess_dbinfo_reqt()...
2694 assert(spec_type == function_alone);
2695 if (dw.name_has_wildcard(function_str_val))
2696 {
2697 // Until we augment the blacklist sufficently...
2698 if (function_str_val.find_first_not_of("*?") == string::npos)
2699 {
2700 // e.g., kernel.function("*")
2701 cerr << "Error: Pattern '"
2702 << function_str_val
2703 << "' matches every instruction address in the symbol table,"
2704 << endl
2705 << "some of which aren't even functions."
2706 << " Please be more precise."
2707 << endl;
2708 return;
2709 }
2710
2711 size_t i;
2712 size_t nsyms = sym_table->list_by_addr.size();
2713 for (i = 0; i < nsyms; i++)
2714 {
2715 fi = sym_table->list_by_addr.at(i);
2716 if (!null_die(&fi->die))
2717 continue; // already handled in query_module_dwarf()
2718 if (dw.function_name_matches_pattern(fi->name, function_str_val))
2719 query_func_info(fi->addr, *fi, this);
2720 }
2721 }
2722 else
2723 {
2724 fi = sym_table->lookup_symbol(function_str_val);
2725 if (fi && null_die(&fi->die))
2726 query_func_info(fi->addr, *fi, this);
2727 }
2728 }
2729 else
2730 {
2731 assert(has_function_num || has_statement_num);
2732 // Find the "function" in which the indicated address resides.
2733 Dwarf_Addr addr =
2734 (has_function_num ? function_num_val : statement_num_val);
2735 fi = sym_table->get_func_containing_address(addr);
2736 if (!fi)
2737 {
2738 cerr << "Warning: address "
2739 << hex << addr << dec
2740 << " out of range for module "
2741 << dw.module_name;
2742 return;
2743 }
2744 if (!null_die(&fi->die))
2745 {
2746 // addr looks like it's in the compilation unit containing
2747 // the indicated function, but query_module_dwarf() didn't
2748 // match addr to any compilation unit, so addr must be
2749 // above that cu's address range.
2750 cerr << "Warning: address "
2751 << hex << addr << dec
2752 << " maps to no known compilation unit in module "
2753 << dw.module_name;
2754 return;
2755 }
2756 query_func_info(fi->addr, *fi, this);
2757 }
2758}
2759
2760void
2761dwarf_query::handle_query_module()
2762{
2763 dw.get_module_dwarf(false,
2764 (dbinfo_reqt == dbr_need_dwarf || !sess.consult_symtab));
2765 if (dw.mod_info->dwarf_status == info_present)
2766 query_module_dwarf();
2767 // Consult the symbol table if we haven't found all we're looking for.
2768 // asm functions can show up in the symbol table but not in dwarf.
2769 if (sess.consult_symtab && !query_done)
2770 query_module_symtab();
2771}
2772
2c384610 2773
0daad364
JS
2774void
2775dwarf_query::build_blacklist()
2776{
a7301475
FCE
2777 // We build up the regexps in these strings
2778
2779 // Add ^ anchors at the front; $ will be added just before regcomp.
2780
a7301475
FCE
2781 string blfn = "^(";
2782 string blfn_ret = "^(";
2783 string blfile = "^(";
2784
e4c58386 2785 blfile += "kernel/kprobes.c"; // first alternative, no "|"
a7301475
FCE
2786 blfile += "|arch/.*/kernel/kprobes.c";
2787
2788 // XXX: it would be nice if these blacklisted functions were pulled
2789 // in dynamically, instead of being statically defined here.
49f426d9
FCE
2790 // Perhaps it could be populated from script files. A "noprobe
2791 // kernel.function("...")" construct might do the trick.
0daad364 2792
b20febf3 2793 // Most of these are marked __kprobes in newer kernels. We list
a7301475
FCE
2794 // them here (anyway) so the translator can block them on older
2795 // kernels that don't have the __kprobes function decorator. This
2796 // also allows detection of problems at translate- rather than
2797 // run-time.
2798
e4c58386 2799 blfn += "atomic_notifier_call_chain"; // first blfn; no "|"
a7301475
FCE
2800 blfn += "|default_do_nmi";
2801 blfn += "|__die";
2802 blfn += "|die_nmi";
2803 blfn += "|do_debug";
2804 blfn += "|do_general_protection";
2805 blfn += "|do_int3";
2806 blfn += "|do_IRQ";
2807 blfn += "|do_page_fault";
2808 blfn += "|do_sparc64_fault";
2809 blfn += "|do_trap";
2810 blfn += "|dummy_nmi_callback";
2811 blfn += "|flush_icache_range";
2812 blfn += "|ia64_bad_break";
2813 blfn += "|ia64_do_page_fault";
2814 blfn += "|ia64_fault";
2815 blfn += "|io_check_error";
2816 blfn += "|mem_parity_error";
2817 blfn += "|nmi_watchdog_tick";
2818 blfn += "|notifier_call_chain";
2819 blfn += "|oops_begin";
2820 blfn += "|oops_end";
2821 blfn += "|program_check_exception";
2822 blfn += "|single_step_exception";
2823 blfn += "|sync_regs";
2824 blfn += "|unhandled_fault";
2825 blfn += "|unknown_nmi_error";
2826
2827 // Lots of locks
2828 blfn += "|.*raw_.*lock.*";
2829 blfn += "|.*read_.*lock.*";
2830 blfn += "|.*write_.*lock.*";
2831 blfn += "|.*spin_.*lock.*";
2832 blfn += "|.*rwlock_.*lock.*";
2833 blfn += "|.*rwsem_.*lock.*";
2834 blfn += "|.*mutex_.*lock.*";
2835 blfn += "|raw_.*";
2836 blfn += "|.*seq_.*lock.*";
2837
a11f4bae 2838 // atomic functions
2ca12712
JS
2839 blfn += "|atomic_.*";
2840 blfn += "|atomic64_.*";
a11f4bae
SD
2841
2842 // few other problematic cases
2843 blfn += "|get_bh";
2844 blfn += "|put_bh";
2845
a7301475
FCE
2846 // Experimental
2847 blfn += "|.*apic.*|.*APIC.*";
2848 blfn += "|.*softirq.*";
2849 blfn += "|.*IRQ.*";
2850 blfn += "|.*_intr.*";
2851 blfn += "|__delay";
2852 blfn += "|.*kernel_text.*";
2853 blfn += "|get_current";
2854 blfn += "|current_.*";
2855 blfn += "|.*exception_tables.*";
2856 blfn += "|.*setup_rt_frame.*";
c931ec8a 2857
a8c9be6f 2858 // PR 5759, CONFIG_PREEMPT kernels
a7301475
FCE
2859 blfn += "|.*preempt_count.*";
2860 blfn += "|preempt_schedule";
a8c9be6f 2861
e4c58386
FCE
2862 // These functions don't return, so return probes would never be recovered
2863 blfn_ret += "do_exit"; // no "|"
2864 blfn_ret += "|sys_exit";
2865 blfn_ret += "|sys_exit_group";
2866
a721fbcf
MH
2867 // __switch_to changes "current" on x86_64 and i686, so return probes
2868 // would cause kernel panic, and it is marked as "__kprobes" on x86_64
0daad364 2869 if (sess.architecture == "x86_64")
a7301475 2870 blfn += "|__switch_to";
a721fbcf 2871 if (sess.architecture == "i686")
a7301475 2872 blfn_ret += "|__switch_to";
0daad364 2873
a7301475
FCE
2874 blfn += ")$";
2875 blfn_ret += ")$";
2876 blfile += ")$";
2877
e4c58386
FCE
2878 if (sess.verbose > 2)
2879 {
2880 clog << "blacklist regexps:" << endl;
2881 clog << "blfn: " << blfn << endl;
2882 clog << "blfn_ret: " << blfn_ret << endl;
2883 clog << "blfile: " << blfile << endl;
2884 }
2885
a7301475
FCE
2886 int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED);
2887 if (rc) throw semantic_error ("blacklist_func regcomp failed");
2888 rc = regcomp (& blacklist_func_ret, blfn_ret.c_str(), REG_NOSUB|REG_EXTENDED);
2889 if (rc) throw semantic_error ("blacklist_func_ret regcomp failed");
2890 rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED);
2891 if (rc) throw semantic_error ("blacklist_file regcomp failed");
7a053d3b 2892}
bd2b1e68
GH
2893
2894
bd2b1e68 2895function_spec_type
20c6c071 2896dwarf_query::parse_function_spec(string & spec)
bd2b1e68
GH
2897{
2898 string::const_iterator i = spec.begin(), e = spec.end();
7a053d3b 2899
bd2b1e68
GH
2900 function.clear();
2901 file.clear();
2902 line = 0;
2903
2904 while (i != e && *i != '@')
2905 {
0c8b7d37 2906 if (*i == ':' || *i == '+')
bd2b1e68
GH
2907 goto bad;
2908 function += *i++;
2909 }
2910
2911 if (i == e)
2912 {
b0ee93c4 2913 if (sess.verbose>2)
7a053d3b
RM
2914 clog << "parsed '" << spec
2915 << "' -> func '" << function
db22e55f 2916 << "'\n";
bd2b1e68
GH
2917 return function_alone;
2918 }
2919
2920 if (i++ == e)
2921 goto bad;
2922
0c8b7d37 2923 while (i != e && *i != ':' && *i != '+')
bd2b1e68 2924 file += *i++;
0c8b7d37
SC
2925 if (*i == ':')
2926 line_type = ABSOLUTE;
2927 else if (*i == '+')
2928 line_type = RELATIVE;
7a053d3b 2929
bd2b1e68
GH
2930 if (i == e)
2931 {
b0ee93c4 2932 if (sess.verbose>2)
7a053d3b
RM
2933 clog << "parsed '" << spec
2934 << "' -> func '"<< function
2935 << "', file '" << file
db22e55f 2936 << "'\n";
bd2b1e68
GH
2937 return function_and_file;
2938 }
2939
2940 if (i++ == e)
2941 goto bad;
2942
2943 try
2944 {
2945 line = lex_cast<int>(string(i, e));
b0ee93c4 2946 if (sess.verbose>2)
7a053d3b
RM
2947 clog << "parsed '" << spec
2948 << "' -> func '"<< function
2949 << "', file '" << file
db22e55f 2950 << "', line " << line << "\n";
bd2b1e68
GH
2951 return function_file_and_line;
2952 }
2953 catch (runtime_error & exn)
2954 {
2955 goto bad;
2956 }
2957
2958 bad:
7a053d3b 2959 throw semantic_error("malformed specification '" + spec + "'",
20c6c071 2960 base_probe->tok);
bd2b1e68
GH
2961}
2962
2963
b20febf3 2964// Forward declaration.
5f0a03a6 2965static int query_kernel_module (Dwfl_Module *, module_info *, const char *,
b20febf3 2966 Dwarf_Addr, void *);
7e1279ea 2967
2930abc7 2968
b8da0ad1 2969// XXX: pull this into dwflpp
b20febf3
FCE
2970static bool
2971in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr)
2930abc7 2972{
84048984 2973 if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0)
1d3a40b6
DS
2974 {
2975 // If the probe point address is anywhere in the __kprobes
2976 // address range, we can't use this probe point.
84048984 2977 if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end)
1d3a40b6
DS
2978 return true;
2979 }
2980 return false;
2981}
2982
20e4a32c 2983
36f9dd1d 2984bool
b20febf3
FCE
2985dwarf_query::blacklisted_p(const string& funcname,
2986 const string& filename,
78f6bba6 2987 int,
b20febf3
FCE
2988 const string& module,
2989 const string& section,
36f9dd1d
FCE
2990 Dwarf_Addr addr)
2991{
b20febf3 2992 if (section.substr(0, 6) == string(".init.") ||
f90f9261
SD
2993 section.substr(0, 6) == string(".exit.") ||
2994 section.substr(0, 9) == string(".devinit.") ||
2995 section.substr(0, 9) == string(".devexit.") ||
2996 section.substr(0, 9) == string(".cpuinit.") ||
2997 section.substr(0, 9) == string(".cpuexit.") ||
2998 section.substr(0, 9) == string(".meminit.") ||
2999 section.substr(0, 9) == string(".memexit."))
703621ae 3000 {
b8da0ad1
FCE
3001 // NB: module .exit. routines could be probed in theory:
3002 // if the exit handler in "struct module" is diverted,
3003 // first inserting the kprobes
3004 // then allowing the exit code to run
3005 // then removing these kprobes
b20febf3
FCE
3006 if (sess.verbose>1)
3007 clog << " skipping - init/exit";
3008 return true;
703621ae
FCE
3009 }
3010
1d3a40b6 3011 // Check for function marked '__kprobes'.
b20febf3 3012 if (module == TOK_KERNEL && in_kprobes_function(sess, addr))
1d3a40b6
DS
3013 {
3014 if (sess.verbose>1)
b20febf3 3015 clog << " skipping - __kprobes";
1d3a40b6
DS
3016 return true;
3017 }
4baf0e53 3018
a7301475
FCE
3019 // Check probe point against blacklist.
3020 int goodfn = regexec (&blacklist_func, funcname.c_str(), 0, NULL, 0);
3021 if (has_return)
3022 goodfn = goodfn && regexec (&blacklist_func_ret, funcname.c_str(), 0, NULL, 0);
3023 int goodfile = regexec (&blacklist_file, filename.c_str(), 0, NULL, 0);
3024
3025 if (! (goodfn && goodfile))
36f9dd1d 3026 {
b0ee93c4 3027 if (sess.verbose>1)
b20febf3 3028 clog << " skipping - blacklisted";
36f9dd1d
FCE
3029 return true;
3030 }
3031
3032 // This probe point is not blacklisted.
3033 return false;
3034}
3035
d64e82b1
SD
3036string dwarf_query::get_blacklist_section(Dwarf_Addr addr)
3037{
d64e82b1 3038 string blacklist_section;
f9331b29
RM
3039 Dwarf_Addr bias;
3040 // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
3041 // because dwfl_module_getelf can force costly section relocations
3042 // we don't really need, while either will do for this purpose.
3043 Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (dw.module, &bias))
3044 ?: dwfl_module_getelf (dw.module, &bias));
3045
3046 Dwarf_Addr offset = addr - bias;
d64e82b1
SD
3047 if (elf)
3048 {
3049 Elf_Scn* scn = 0;
3050 size_t shstrndx;
3051 dw.dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
3052 while ((scn = elf_nextscn (elf, scn)) != NULL)
3053 {
3054 GElf_Shdr shdr_mem;
3055 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3056 if (! shdr) continue; // XXX error?
3057
f9331b29
RM
3058 if (!(shdr->sh_flags & SHF_ALLOC))
3059 continue;
3060
d64e82b1
SD
3061 GElf_Addr start = shdr->sh_addr;
3062 GElf_Addr end = start + shdr->sh_size;
3063 if (! (offset >= start && offset < end))
3064 continue;
3065
3066 blacklist_section = elf_strptr (elf, shstrndx, shdr->sh_name);
3067 break;
3068 }
3069 }
3070 return blacklist_section;
3071}
36f9dd1d 3072
b20febf3 3073
36f9dd1d 3074void
b20febf3
FCE
3075dwarf_query::add_probe_point(const string& funcname,
3076 const char* filename,
36f9dd1d 3077 int line,
b20febf3 3078 Dwarf_Die* scope_die,
36f9dd1d
FCE
3079 Dwarf_Addr addr)
3080{
3081 dwarf_derived_probe *probe = NULL;
b20febf3
FCE
3082 string reloc_section; // base section for relocation purposes
3083 Dwarf_Addr reloc_addr = addr; // relocated
3084 string blacklist_section; // linking section for blacklist purposes
3085 const string& module = dw.module_name; // "kernel" or other
36f9dd1d 3086
37ebca01
FCE
3087 assert (! has_absolute); // already handled in dwarf_builder::build()
3088
5f0a03a6
JK
3089 if (!dw.module)
3090 {
3091 assert(module == TOK_KERNEL);
3092 reloc_section = "";
3093 blacklist_section = "";
3094 }
3095 else if (dwfl_module_relocations (dw.module) > 0)
2930abc7 3096 {
b20febf3
FCE
3097 // This is arelocatable module; libdwfl already knows its
3098 // sections, so we can relativize addr.
3099 int idx = dwfl_module_relocate_address (dw.module, &reloc_addr);
3100 const char* r_s = dwfl_module_relocation_info (dw.module, idx, NULL);
3101 if (r_s)
3102 reloc_section = r_s;
3103 blacklist_section = reloc_section;
d64e82b1
SD
3104
3105 if(reloc_section == "" && dwfl_module_relocations (dw.module) == 1)
3106 blacklist_section = this->get_blacklist_section(addr);
2930abc7
FCE
3107 }
3108 else
3109 {
d64e82b1 3110 blacklist_section = this->get_blacklist_section(addr);
b20febf3 3111 reloc_section = "";
2930abc7
FCE
3112 }
3113
7f9f3386
FCE
3114 if (sess.verbose > 1)
3115 {
b20febf3
FCE
3116 clog << "probe " << funcname << "@" << filename << ":" << line;
3117 if (string(module) == TOK_KERNEL)
3118 clog << " kernel";
3119 else
3120 clog << " module=" << module;
3121 if (reloc_section != "") clog << " reloc=" << reloc_section;
3122 if (blacklist_section != "") clog << " section=" << blacklist_section;
3123 clog << " pc=0x" << hex << addr << dec;
7f9f3386 3124 }
4baf0e53 3125
b20febf3
FCE
3126 bool bad = blacklisted_p (funcname, filename, line, module, blacklist_section, addr);
3127 if (sess.verbose > 1)
3128 clog << endl;
7f9f3386 3129
84048984
FCE
3130 if (module == TOK_KERNEL)
3131 {
3132 // PR 4224: adapt to relocatable kernel by subtracting the _stext address here.
3133 reloc_addr = addr - sess.sym_stext;
37ebca01 3134 reloc_section = "_stext"; // a message to runtime's _stp_module_relocate
84048984
FCE
3135 }
3136
b20febf3
FCE
3137 if (! bad)
3138 {
4baf0e53 3139 probe = new dwarf_derived_probe(funcname, filename, line,
b20febf3
FCE
3140 module, reloc_section, addr, reloc_addr, *this, scope_die);
3141 results.push_back(probe);
3142 }
2930abc7
FCE
3143}
3144
5f0a03a6
JK
3145enum dbinfo_reqt
3146dwarf_query::assess_dbinfo_reqt()
3147{
3148 if (has_absolute)
3149 {
3150 // kernel.statement(NUM).absolute
3151 return dbr_none;
3152 }
3153 if (has_inline)
3154 {
3155 // kernel.function("f").inline or module("m").function("f").inline
3156 return dbr_need_dwarf;
3157 }
3158 if (has_function_str && spec_type == function_alone)
3159 {
3160 // kernel.function("f") or module("m").function("f")
3161 return dbr_need_symtab;
3162 }
3163 if (has_statement_num)
3164 {
3165 // kernel.statement(NUM) or module("m").statement(NUM)
3166 // Technically, all we need is the module offset (or _stext, for
3167 // the kernel). But for that we need either the ELF file or (for
3168 // _stext) the symbol table. In either case, the symbol table
3169 // is available, and that allows us to map the NUM (address)
3170 // to a function, which is goodness.
3171 return dbr_need_symtab;
3172 }
3173 if (has_function_num)
3174 {
3175 // kernel.function(NUM) or module("m").function(NUM)
3176 // Need the symbol table so we can back up from NUM to the
3177 // start of the function.
3178 return dbr_need_symtab;
3179 }
3180 // Symbol table tells us nothing about source files or line numbers.
3181 return dbr_need_dwarf;
3182}
2930abc7
FCE
3183
3184
3185
b8da0ad1
FCE
3186// The critical determining factor when interpreting a pattern
3187// string is, perhaps surprisingly: "presence of a lineno". The
3188// presence of a lineno changes the search strategy completely.
3189//
3190// Compare the two cases:
3191//
3192// 1. {statement,function}(foo@file.c:lineno)
3193// - find the files matching file.c
3194// - in each file, find the functions matching foo
3195// - query the file for line records matching lineno
3196// - iterate over the line records,
3197// - and iterate over the functions,
3198// - if(haspc(function.DIE, line.addr))
3199// - if looking for statements: probe(lineno.addr)
3200// - if looking for functions: probe(function.{entrypc,return,etc.})
3201//
3202// 2. {statement,function}(foo@file.c)
3203// - find the files matching file.c
3204// - in each file, find the functions matching foo
3205// - probe(function.{entrypc,return,etc.})
3206//
3207// Thus the first decision we make is based on the presence of a
3208// lineno, and we enter entirely different sets of callbacks
3209// depending on that decision.
3210//
3211// Note that the first case is a generalization fo the second, in that
3212// we could theoretically search through line records for matching
3213// file names (a "table scan" in rdbms lingo). Luckily, file names
3214// are already cached elsewhere, so we can do an "index scan" as an
3215// optimization.
7e1279ea 3216
bd2b1e68 3217static void
4cd232e4 3218query_statement (string const & func,
20e4a32c 3219 char const * file,
4cd232e4 3220 int line,
bcc12710 3221 Dwarf_Die *scope_die,
20e4a32c 3222 Dwarf_Addr stmt_addr,
4cd232e4 3223 dwarf_query * q)
bd2b1e68 3224{
39bcd429
FCE
3225 try
3226 {
a9b2f3a5
FCE
3227 q->add_probe_point(func, file ? file : "?",
3228 line, scope_die, stmt_addr);
39bcd429
FCE
3229 }
3230 catch (const semantic_error& e)
3231 {
3232 q->sess.print_error (e);
3233 }
bd2b1e68
GH
3234}
3235
7e1279ea
FCE
3236static void
3237query_inline_instance_info (Dwarf_Addr entrypc,
bcc12710 3238 inline_instance_info & ii,
7e1279ea
FCE
3239 dwarf_query * q)
3240{
b6581717 3241 try
7e1279ea 3242 {
b6581717
GH
3243 if (q->has_return)
3244 {
3245 throw semantic_error ("cannot probe .return of inline function '" + ii.name + "'");
3246 }
3247 else
3248 {
b0ee93c4 3249 if (q->sess.verbose>2)
20e4a32c
RM
3250 clog << "querying entrypc "
3251 << hex << entrypc << dec
db22e55f 3252 << " of instance of inline '" << ii.name << "'\n";
20e4a32c 3253 query_statement (ii.name, ii.decl_file, ii.decl_line,
b6581717
GH
3254 &ii.die, entrypc, q);
3255 }
7e1279ea 3256 }
b6581717 3257 catch (semantic_error &e)
7e1279ea 3258 {
b6581717 3259 q->sess.print_error (e);
7e1279ea
FCE
3260 }
3261}
3262
3263static void
3264query_func_info (Dwarf_Addr entrypc,
bcc12710 3265 func_info & fi,
7e1279ea
FCE
3266 dwarf_query * q)
3267{
b6581717 3268 try
7e1279ea 3269 {
b6581717
GH
3270 if (q->has_return)
3271 {
3272 // NB. dwarf_derived_probe::emit_registrations will emit a
3273 // kretprobe based on the entrypc in this case.
20e4a32c 3274 query_statement (fi.name, fi.decl_file, fi.decl_line,
b6581717
GH
3275 &fi.die, entrypc, q);
3276 }
3277 else
3278 {
e4c58386
FCE
3279 if (q->sess.prologue_searching
3280 && !q->has_statement_str && !q->has_statement_num) // PR 2608
44f75386
FCE
3281 {
3282 if (fi.prologue_end == 0)
3283 throw semantic_error("could not find prologue-end "
3284 "for probed function '" + fi.name + "'");
3285 query_statement (fi.name, fi.decl_file, fi.decl_line,
3286 &fi.die, fi.prologue_end, q);
3287 }
3288 else
3289 {
3290 query_statement (fi.name, fi.decl_file, fi.decl_line,
3291 &fi.die, entrypc, q);
3292 }
b6581717 3293 }
7e1279ea 3294 }
b6581717 3295 catch (semantic_error &e)
7e1279ea 3296 {
b6581717 3297 q->sess.print_error (e);
7e1279ea
FCE
3298 }
3299}
3300
3301
3302static void
3303query_srcfile_line (Dwarf_Line * line, void * arg)
3304{
3305 dwarf_query * q = static_cast<dwarf_query *>(arg);
3306
3307 Dwarf_Addr addr;
3308 dwarf_lineaddr(line, &addr);
4cd232e4 3309
847bf07f
FCE
3310 int lineno;
3311 dwarf_lineno (line, &lineno);
3312
7e1279ea
FCE
3313 for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
3314 i != q->filtered_functions.end(); ++i)
3315 {
3316 if (q->dw.die_has_pc (&(i->second.die), addr))
3317 {
b0ee93c4 3318 if (q->sess.verbose>3)
db22e55f 3319 clog << "function DIE lands on srcfile\n";
4cd232e4 3320 if (q->has_statement_str)
20e4a32c 3321 query_statement (i->second.name, i->second.decl_file,
847bf07f 3322 lineno, // NB: not q->line !
fedd4090 3323 &(i->second.die), addr, q);
4cd232e4
GH
3324 else
3325 query_func_info (i->first, i->second, q);
7e1279ea 3326 }
20e4a32c
RM
3327 }
3328
3329 for (map<Dwarf_Addr, inline_instance_info>::iterator i
897820ca
GH
3330 = q->filtered_inlines.begin();
3331 i != q->filtered_inlines.end(); ++i)
3332 {
3333 if (q->dw.die_has_pc (&(i->second.die), addr))
7e1279ea 3334 {
b0ee93c4 3335 if (q->sess.verbose>3)
db22e55f 3336 clog << "inline instance DIE lands on srcfile\n";
897820ca 3337 if (q->has_statement_str)
20e4a32c 3338 query_statement (i->second.name, i->second.decl_file,
fedd4090 3339 q->line, &(i->second.die), addr, q);
897820ca
GH
3340 else
3341 query_inline_instance_info (i->first, i->second, q);
3342 }
20e4a32c 3343 }
7e1279ea
FCE
3344}
3345
3346
4fa7b22b 3347static int
7e1279ea 3348query_dwarf_inline_instance (Dwarf_Die * die, void * arg)
4fa7b22b
GH
3349{
3350 dwarf_query * q = static_cast<dwarf_query *>(arg);
7e1279ea 3351 assert (!q->has_statement_num);
bd2b1e68 3352
39bcd429 3353 try
7a053d3b 3354 {
b0ee93c4 3355 if (q->sess.verbose>2)
db22e55f 3356 clog << "examining inline instance of " << q->dw.function_name << "\n";
7e1279ea 3357
4baf0e53 3358 if ((q->has_function_str && ! q->has_call)
b8da0ad1 3359 || q->has_statement_str)
7e1279ea 3360 {
b0ee93c4 3361 if (q->sess.verbose>2)
db22e55f
FCE
3362 clog << "selected inline instance of " << q->dw.function_name
3363 << "\n";
7e1279ea
FCE
3364
3365 Dwarf_Addr entrypc;
3366 if (q->dw.die_entrypc (die, &entrypc))
3367 {
3368 inline_instance_info inl;
3369 inl.die = *die;
3370 inl.name = q->dw.function_name;
4cd232e4
GH
3371 q->dw.function_file (&inl.decl_file);
3372 q->dw.function_line (&inl.decl_line);
7e1279ea
FCE
3373 q->filtered_inlines[entrypc] = inl;
3374 }
3375 }
3376 return DWARF_CB_OK;
3377 }
3378 catch (const semantic_error& e)
3379 {
3380 q->sess.print_error (e);
3381 return DWARF_CB_ABORT;
3382 }
3383}
bb788f9f 3384
7e1279ea 3385static int
20e4a32c 3386query_dwarf_func (Dwarf_Die * func, void * arg)
7e1279ea
FCE
3387{
3388 dwarf_query * q = static_cast<dwarf_query *>(arg);
bb788f9f 3389
7e1279ea
FCE
3390 try
3391 {
7e1279ea
FCE
3392 q->dw.focus_on_function (func);
3393
20e4a32c 3394 if (q->dw.func_is_inline ()
b8da0ad1
FCE
3395 && (! q->has_call) && (! q->has_return)
3396 && (((q->has_statement_str || q->has_function_str)
3397 && q->dw.function_name_matches(q->function))))
7e1279ea 3398 {
b0ee93c4 3399 if (q->sess.verbose>3)
db22e55f
FCE
3400 clog << "checking instances of inline " << q->dw.function_name
3401 << "\n";
7e1279ea 3402 q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, arg);
275f40a6
FCE
3403
3404 if (q->dw.function_name_final_match (q->function))
3405 return DWARF_CB_ABORT;
7e1279ea 3406 }
396afcee 3407 else if (!q->dw.func_is_inline () && (! q->has_inline))
20e4a32c 3408 {
7e1279ea
FCE
3409 bool record_this_function = false;
3410
3411 if ((q->has_statement_str || q->has_function_str)
3412 && q->dw.function_name_matches(q->function))
3413 {
3414 record_this_function = true;
3415 }
e4c58386 3416 else if (q->has_function_num || q->has_statement_num)
7e1279ea 3417 {
e4c58386
FCE
3418 Dwarf_Addr query_addr =
3419 q->dw.module_address_to_global(q->has_function_num ? q->function_num_val :
3420 q->has_statement_num ? q->statement_num_val :
3421 (assert(0) , 0));
7e1279ea
FCE
3422 Dwarf_Die d;
3423 q->dw.function_die (&d);
20e4a32c 3424
7e1279ea
FCE
3425 if (q->dw.die_has_pc (&d, query_addr))
3426 record_this_function = true;
3427 }
3428
3429 if (record_this_function)
3430 {
b0ee93c4 3431 if (q->sess.verbose>2)
db22e55f 3432 clog << "selected function " << q->dw.function_name << "\n";
7e1279ea 3433
e4c58386
FCE
3434 func_info func;
3435 q->dw.function_die (&func.die);
3436 func.name = q->dw.function_name;
3437 q->dw.function_file (&func.decl_file);
3438 q->dw.function_line (&func.decl_line);
3439
3440 if (q->has_function_num || q->has_function_str || q->has_statement_str)
3441 {
3442 Dwarf_Addr entrypc;
3443 if (q->dw.function_entrypc (&entrypc))
3444 q->filtered_functions[entrypc] = func;
3445 else
3446 throw semantic_error("no entrypc found for function '"
3447 + q->dw.function_name + "'");
3448 }
3449 else if (q->has_statement_num)
3450 {
3451 Dwarf_Addr probepc = q->statement_num_val;
3452 q->filtered_functions[probepc] = func;
275f40a6
FCE
3453 if (q->dw.function_name_final_match (q->function))
3454 return DWARF_CB_ABORT;
e4c58386
FCE
3455 }
3456 else
3457 assert(0);
3458
3459 if (q->dw.function_name_final_match (q->function))
3460 return DWARF_CB_ABORT;
7e1279ea
FCE
3461 }
3462 }
39bcd429 3463 return DWARF_CB_OK;
bd2b1e68 3464 }
39bcd429 3465 catch (const semantic_error& e)
bd2b1e68 3466 {
39bcd429
FCE
3467 q->sess.print_error (e);
3468 return DWARF_CB_ABORT;
bd2b1e68 3469 }
bd2b1e68
GH
3470}
3471
3472static int
3473query_cu (Dwarf_Die * cudie, void * arg)
3474{
20c6c071 3475 dwarf_query * q = static_cast<dwarf_query *>(arg);
49abf162 3476 if (pending_interrupts) return DWARF_CB_ABORT;
7a053d3b 3477
39bcd429 3478 try
bd2b1e68 3479 {
7e1279ea 3480 q->dw.focus_on_cu (cudie);
b5d77020 3481
b0ee93c4 3482 if (false && q->sess.verbose>2)
b5d77020 3483 clog << "focused on CU '" << q->dw.cu_name
db22e55f 3484 << "', in module '" << q->dw.module_name << "'\n";
d9b516ca 3485
e4c58386 3486 if (q->has_statement_str || q->has_statement_num
54efe513 3487 || q->has_function_str || q->has_function_num)
7e1279ea
FCE
3488 {
3489 q->filtered_srcfiles.clear();
3490 q->filtered_functions.clear();
3491 q->filtered_inlines.clear();
3492
3493 // In this path, we find "abstract functions", record
3494 // information about them, and then (depending on lineno
3495 // matching) possibly emit one or more of the function's
3496 // associated addresses. Unfortunately the control of this
3497 // cannot easily be turned inside out.
3498
b8da0ad1 3499 if ((q->has_statement_str || q->has_function_str)
7e1279ea
FCE
3500 && (q->spec_type != function_alone))
3501 {
3502 // If we have a pattern string with a filename, we need
3503 // to elaborate the srcfile mask in question first.
3504 q->dw.collect_srcfiles_matching (q->file, q->filtered_srcfiles);
3505
3506 // If we have a file pattern and *no* srcfile matches, there's
3507 // no need to look further into this CU, so skip.
3508 if (q->filtered_srcfiles.empty())
3509 return DWARF_CB_OK;
3510 }
3511
3512 // Pick up [entrypc, name, DIE] tuples for all the functions
3513 // matching the query, and fill in the prologue endings of them
3514 // all in a single pass.
5f0a03a6
JK
3515 int rc = q->dw.iterate_over_functions (query_dwarf_func, q);
3516 if (rc != DWARF_CB_OK)
3517 q->query_done = true;
44f75386 3518
e4c58386
FCE
3519 if (q->sess.prologue_searching
3520 && !q->has_statement_str && !q->has_statement_num) // PR 2608
44f75386
FCE
3521 if (! q->filtered_functions.empty())
3522 q->dw.resolve_prologue_endings (q->filtered_functions);
7e1279ea 3523
b8da0ad1 3524 if ((q->has_statement_str || q->has_function_str)
7e1279ea
FCE
3525 && (q->spec_type == function_file_and_line))
3526 {
3527 // If we have a pattern string with target *line*, we
20e4a32c 3528 // have to look at lines in all the matched srcfiles.
7e1279ea
FCE
3529 for (set<char const *>::const_iterator i = q->filtered_srcfiles.begin();
3530 i != q->filtered_srcfiles.end(); ++i)
897820ca 3531 q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
0c8b7d37 3532 q->line_type, query_srcfile_line, q);
7e1279ea
FCE
3533 }
3534 else
3535 {
e4c58386
FCE
3536 // Otherwise, simply probe all resolved functions.
3537 for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
3538 i != q->filtered_functions.end(); ++i)
3539 query_func_info (i->first, i->second, q);
3540
3541 // And all inline instances (if we're not excluding inlines with ".call")
3542 if (! q->has_call)
20e4a32c 3543 for (map<Dwarf_Addr, inline_instance_info>::iterator i
54efe513
GH
3544 = q->filtered_inlines.begin(); i != q->filtered_inlines.end(); ++i)
3545 query_inline_instance_info (i->first, i->second, q);
7e1279ea
FCE
3546 }
3547 }
39bcd429
FCE
3548 else
3549 {
e4c58386
FCE
3550 // Before PR 5787, we used to have this:
3551#if 0
7e1279ea
FCE
3552 // Otherwise we have a statement number, and we can just
3553 // query it directly within this module.
7e1279ea
FCE
3554 assert (q->has_statement_num);
3555 Dwarf_Addr query_addr = q->statement_num_val;
b8da0ad1 3556 query_addr = q->dw.module_address_to_global(query_addr);
7e1279ea 3557
bcc12710 3558 query_statement ("", "", -1, NULL, query_addr, q);
e4c58386
FCE
3559#endif
3560 // But now, we traverse CUs/functions even for
3561 // statement_num's, for blacklist sensitivity and $var
3562 // resolution purposes.
3563
3564 assert (0); // NOTREACHED
39bcd429
FCE
3565 }
3566 return DWARF_CB_OK;
bd2b1e68 3567 }
39bcd429 3568 catch (const semantic_error& e)
bd2b1e68 3569 {
39bcd429
FCE
3570 q->sess.print_error (e);
3571 return DWARF_CB_ABORT;
bd2b1e68 3572 }
bd2b1e68
GH
3573}
3574
0ce64fb8 3575
1d3a40b6
DS
3576static int
3577query_kernel_module (Dwfl_Module *mod,
5f0a03a6 3578 module_info *,
1d3a40b6 3579 const char *name,
b8da0ad1 3580 Dwarf_Addr,
1d3a40b6
DS
3581 void *arg)
3582{
3583 if (TOK_KERNEL == name)
3584 {
3585 Dwfl_Module **m = (Dwfl_Module **)arg;
3586
3587 *m = mod;
3588 return DWARF_CB_ABORT;
3589 }
3590 return DWARF_CB_OK;
3591}
3592
5f0a03a6
JK
3593static void
3594validate_module_elf (Dwfl_Module *mod, const char *name, base_query *q)
3595{
3596 // Validate the machine code in this elf file against the
3597 // session machine. This is important, in case the wrong kind
3598 // of debuginfo is being automagically processed by elfutils.
3599 // While we can tell i686 apart from x86-64, unfortunately
3600 // we can't help confusing i586 vs i686 (both EM_386).
3601
3602 Dwarf_Addr bias;
3603 // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
3604 // because dwfl_module_getelf can force costly section relocations
3605 // we don't really need, while either will do for this purpose.
3606 Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
3607 ?: dwfl_module_getelf (mod, &bias));
3608
3609 GElf_Ehdr ehdr_mem;
3610 GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
3611 if (em == 0) { q->dw.dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
3612 int elf_machine = em->e_machine;
3613 const char* debug_filename = "";
3614 const char* main_filename = "";
3615 (void) dwfl_module_info (mod, NULL, NULL,
3616 NULL, NULL, NULL,
3617 & main_filename,
3618 & debug_filename);
3619 const string& sess_machine = q->sess.architecture;
3620 string expect_machine;
3621
3622 switch (elf_machine)
3623 {
3624 case EM_386: expect_machine = "i?86"; break; // accept e.g. i586
3625 case EM_X86_64: expect_machine = "x86_64"; break;
3626 case EM_PPC: expect_machine = "ppc"; break;
3627 case EM_PPC64: expect_machine = "ppc64"; break;
3628 case EM_S390: expect_machine = "s390x"; break;
3629 case EM_IA_64: expect_machine = "ia64"; break;
3630 case EM_ARM: expect_machine = "armv*"; break;
3631 // XXX: fill in some more of these
3632 default: expect_machine = "?"; break;
3633 }
3634
3635 if (! debug_filename) debug_filename = main_filename;
3636 if (! debug_filename) debug_filename = name;
3637
3638 if (fnmatch (expect_machine.c_str(), sess_machine.c_str(), 0) != 0)
3639 {
3640 stringstream msg;
3641 msg << "ELF machine " << expect_machine << " (code " << elf_machine
3642 << ") mismatch with target " << sess_machine
3643 << " in '" << debug_filename << "'";
3644 throw semantic_error(msg.str ());
3645 }
3646
3647 if (q->sess.verbose>2)
3648 clog << "focused on module '" << q->dw.module_name
3649 << " = [0x" << hex << q->dw.module_start
3650 << "-0x" << q->dw.module_end
3651 << ", bias 0x" << q->dw.module_bias << "]" << dec
3652 << " file " << debug_filename
3653 << " ELF machine " << expect_machine
3654 << " (code " << elf_machine << ")"
3655 << "\n";
3656}
1d3a40b6 3657
bd2b1e68 3658static int
b8da0ad1 3659query_module (Dwfl_Module *mod,
5f0a03a6 3660 module_info *mi,
b8da0ad1
FCE
3661 const char *name,
3662 Dwarf_Addr,
3663 void *arg)
bd2b1e68 3664{
2c384610 3665 base_query * q = static_cast<base_query *>(arg);
bd2b1e68 3666
39bcd429 3667 try
e38d6504 3668 {
5f0a03a6 3669 q->dw.focus_on_module(mod, mi);
d9b516ca 3670
39bcd429
FCE
3671 // If we have enough information in the pattern to skip a module and
3672 // the module does not match that information, return early.
b8da0ad1 3673 if (!q->dw.module_name_matches(q->module_val))
39bcd429 3674 return DWARF_CB_OK;
0cbbf9d1
FCE
3675
3676 // Don't allow module("*kernel*") type expressions to match the
3677 // elfutils module "kernel", which we refer to in the probe
3678 // point syntax exclusively as "kernel.*".
3679 if (q->dw.module_name == TOK_KERNEL && ! q->has_kernel)
3680 return DWARF_CB_OK;
b5d77020 3681
5f0a03a6
JK
3682 if (mod)
3683 validate_module_elf(mod, name, q);
3684 else
c931ec8a 3685 {
5f0a03a6
JK
3686 assert(q->has_kernel); // and no vmlinux to examine
3687 if (q->sess.verbose>2)
3688 cerr << "focused on module '" << q->dw.module_name << "'\n";
c931ec8a
FCE
3689 }
3690
2c384610 3691 q->handle_query_module();
bb788f9f 3692
b8da0ad1
FCE
3693 // If we know that there will be no more matches, abort early.
3694 if (q->dw.module_name_final_match(q->module_val))
3695 return DWARF_CB_ABORT;
3696 else
3697 return DWARF_CB_OK;
7a053d3b 3698 }
39bcd429 3699 catch (const semantic_error& e)
bd2b1e68 3700 {
39bcd429
FCE
3701 q->sess.print_error (e);
3702 return DWARF_CB_ABORT;
bd2b1e68 3703 }
bd2b1e68
GH
3704}
3705
5f0a03a6
JK
3706void
3707dwflpp::query_modules(dwarf_query *q)
3708{
3709 string name = q->module_val;
3710 if (name_has_wildcard(name))
3711 iterate_over_modules(&query_module, q);
3712 else
3713 {
3714 cache_modules_dwarf();
3715
3716 map<string, module_info*>::iterator i = module_cache.cache.find(name);
3717 if (i != module_cache.cache.end())
3718 {
3719 module_info *mi = i->second;
3720 query_module(mi->mod, mi, name.c_str(), mi->addr, q);
3721 }
3722 }
3723}
2930abc7 3724
35d4ab18 3725struct var_expanding_copy_visitor: public deep_copy_visitor
77de5e9e 3726{
77de5e9e 3727 static unsigned tick;
e57b735a 3728 stack<functioncall**> target_symbol_setter_functioncalls;
77de5e9e 3729
35d4ab18
FCE
3730 var_expanding_copy_visitor() {}
3731 void visit_assignment (assignment* e);
3732};
3733
3734
3735struct dwarf_var_expanding_copy_visitor: public var_expanding_copy_visitor
3736{
77de5e9e 3737 dwarf_query & q;
bcc12710 3738 Dwarf_Die *scope_die;
77de5e9e 3739 Dwarf_Addr addr;
8c819921 3740 block *add_block;
8fc05e57 3741 probe *add_probe;
cd5b28b2 3742 std::map<std::string, symbol *> return_ts_map;
77de5e9e 3743
35d4ab18 3744 dwarf_var_expanding_copy_visitor(dwarf_query & q, Dwarf_Die *sd, Dwarf_Addr a):
8fc05e57 3745 q(q), scope_die(sd), addr(a), add_block(NULL), add_probe(NULL) {}
d7f3e0c5 3746 void visit_target_symbol (target_symbol* e);
77de5e9e
GH
3747};
3748
3749
35d4ab18 3750
77de5e9e
GH
3751unsigned var_expanding_copy_visitor::tick = 0;
3752
77de5e9e 3753void
e57b735a 3754var_expanding_copy_visitor::visit_assignment (assignment* e)
77de5e9e 3755{
e57b735a
GH
3756 // Our job would normally be to require() the left and right sides
3757 // into a new assignment. What we're doing is slightly trickier:
3758 // we're pushing a functioncall** onto a stack, and if our left
3759 // child sets the functioncall* for that value, we're going to
3760 // assume our left child was a target symbol -- transformed into a
3761 // set_target_foo(value) call, and it wants to take our right child
3762 // as the argument "value".
3763 //
3764 // This is why some people claim that languages with
3765 // constructor-decomposing case expressions have a leg up on
3766 // visitors.
3767
3768 functioncall *fcall = NULL;
3769 expression *new_left, *new_right;
d9b516ca 3770
e57b735a
GH
3771 target_symbol_setter_functioncalls.push (&fcall);
3772 require<expression*> (this, &new_left, e->left);
3773 target_symbol_setter_functioncalls.pop ();
3774 require<expression*> (this, &new_right, e->right);
3775
3776 if (fcall != NULL)
77de5e9e 3777 {
e57b735a
GH
3778 // Our left child is informing us that it was a target variable
3779 // and it has been replaced with a set_target_foo() function
3780 // call; we are going to provide that function call -- with the
3781 // right child spliced in as sole argument -- in place of
3782 // ourselves, in the deep copy we're in the middle of making.
3783
3784 // FIXME: for the time being, we only support plan $foo = bar,
3785 // not += or any other op= variant. This is fixable, but a bit
3786 // ugly.
3787 if (e->op != "=")
3788 throw semantic_error ("Operator-assign expressions on target "
3789 "variables not implemented", e->tok);
3790
3791 assert (new_left == fcall);
3792 fcall->args.push_back (new_right);
3793 provide <expression*> (this, fcall);
77de5e9e 3794 }
e57b735a
GH
3795 else
3796 {
3797 assignment* n = new assignment;
3798 n->op = e->op;
3799 n->tok = e->tok;
3800 n->left = new_left;
3801 n->right = new_right;
3802 provide <assignment*> (this, n);
3803 }
3804}
d9b516ca 3805
d7f3e0c5 3806
e57b735a 3807void
35d4ab18 3808dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
e57b735a
GH
3809{
3810 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
3811
cf2a1f85
DS
3812 bool lvalue = is_active_lvalue(e);
3813 if (lvalue && !q.sess.guru_mode)
3814 throw semantic_error("write to target variable not permitted", e->tok);
3815
3816 if (q.has_return && e->base_name != "$return")
85ecf79a
DS
3817 {
3818 if (lvalue)
3819 throw semantic_error("write to target variable not permitted in .return probes", e->tok);
3820
cd5b28b2
DS
3821 // Get the full name of the target symbol.
3822 stringstream ts_name_stream;
3823 e->print(ts_name_stream);
3824 string ts_name = ts_name_stream.str();
3825
3826 // Check and make sure we haven't already seen this target
3827 // variable in this return probe. If we have, just return our
3828 // last replacement.
3829 map<string, symbol *>::iterator i = return_ts_map.find(ts_name);
3830 if (i != return_ts_map.end())
3831 {
3832 provide <symbol*> (this, i->second);
3833 return;
3834 }
3835
85ecf79a
DS
3836 // We've got to do several things here to handle target
3837 // variables in return probes.
3838
5e600bd6
DS
3839 // (1) Synthesize two global arrays. One is the cache of the
3840 // target variable and the other contains a thread specific
3841 // nesting level counter. The arrays will look like
3842 // this:
85ecf79a
DS
3843 //
3844 // _dwarf_tvar_{name}_{num}
85ecf79a
DS
3845 // _dwarf_tvar_{name}_{num}_ctr
3846
3847 string aname = (string("_dwarf_tvar_")
3848 + e->base_name.substr(1)
3849 + "_" + lex_cast<string>(tick++));
3850 vardecl* vd = new vardecl;
3851 vd->name = aname;
3852 vd->tok = e->tok;
3853 q.sess.globals.push_back (vd);
3854
3855 string ctrname = aname + "_ctr";
3856 vd = new vardecl;
3857 vd->name = ctrname;
3858 vd->tok = e->tok;
3859 q.sess.globals.push_back (vd);
3860
8c819921
DS
3861 // (2) Create a new code block we're going to insert at the
3862 // beginning of this probe to get the cached value into a
3863 // temporary variable. We'll replace the target variable
3864 // reference with the temporary variable reference. The code
3865 // will look like this:
3866 //
3867 // _dwarf_tvar_tid = tid()
3868 // _dwarf_tvar_{name}_{num}_tmp
3869 // = _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
3870 // _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
3871 // delete _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
3872 // _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]--]
46392da3
DS
3873 // if (! _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid])
3874 // delete _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]
8c819921
DS
3875
3876 // (2a) Synthesize the tid temporary expression, which will look
85ecf79a
DS
3877 // like this:
3878 //
8c819921
DS
3879 // _dwarf_tvar_tid = tid()
3880 symbol* tidsym = new symbol;
3881 tidsym->name = string("_dwarf_tvar_tid");
3882 tidsym->tok = e->tok;
85ecf79a 3883
8c819921
DS
3884 if (add_block == NULL)
3885 {
8fc05e57
DS
3886 add_block = new block;
3887 add_block->tok = e->tok;
3888
3889 // Synthesize a functioncall to grab the thread id.
3890 functioncall* fc = new functioncall;
3891 fc->tok = e->tok;
3892 fc->function = string("tid");
3893
3894 // Assign the tid to '_dwarf_tvar_tid'.
3895 assignment* a = new assignment;
3896 a->tok = e->tok;
3897 a->op = "=";
3898 a->left = tidsym;
3899 a->right = fc;
3900
3901 expr_statement* es = new expr_statement;
3902 es->tok = e->tok;
3903 es->value = a;
3904 add_block->statements.push_back (es);
8c819921
DS
3905 }
3906
3907 // (2b) Synthesize an array reference and assign it to a
3908 // temporary variable (that we'll use as replacement for the
3909 // target variable reference). It will look like this:
3910 //
3911 // _dwarf_tvar_{name}_{num}_tmp
3912 // = _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
3913 // _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
3914
8fc05e57
DS
3915 arrayindex* ai_tvar_base = new arrayindex;
3916 ai_tvar_base->tok = e->tok;
85ecf79a
DS
3917
3918 symbol* sym = new symbol;
3919 sym->name = aname;
3920 sym->tok = e->tok;
8fc05e57 3921 ai_tvar_base->base = sym;
8c819921 3922
8fc05e57 3923 ai_tvar_base->indexes.push_back(tidsym);
85ecf79a 3924
8c819921
DS
3925 // We need to create a copy of the array index in its current
3926 // state so we can have 2 variants of it (the original and one
3927 // that post-decrements the second index).
8fc05e57
DS
3928 arrayindex* ai_tvar = new arrayindex;
3929 arrayindex* ai_tvar_postdec = new arrayindex;
3930 *ai_tvar = *ai_tvar_base;
3931 *ai_tvar_postdec = *ai_tvar_base;
85ecf79a 3932
8c819921
DS
3933 // Synthesize the
3934 // "_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]" used as the
85ecf79a 3935 // second index into the array.
8c819921
DS
3936 arrayindex* ai_ctr = new arrayindex;
3937 ai_ctr->tok = e->tok;
5e600bd6 3938
85ecf79a
DS
3939 sym = new symbol;
3940 sym->name = ctrname;
3941 sym->tok = e->tok;
8c819921
DS
3942 ai_ctr->base = sym;
3943 ai_ctr->indexes.push_back(tidsym);
3944 ai_tvar->indexes.push_back(ai_ctr);
3945
3946 symbol* tmpsym = new symbol;
3947 tmpsym->name = aname + "_tmp";
3948 tmpsym->tok = e->tok;
3949
3950 assignment* a = new assignment;
3951 a->tok = e->tok;
3952 a->op = "=";
3953 a->left = tmpsym;
3954 a->right = ai_tvar;
3955
3956 expr_statement* es = new expr_statement;
3957 es->tok = e->tok;
3958 es->value = a;
3959
3960 add_block->statements.push_back (es);
3961
3962 // (2c) Add a post-decrement to the second array index and
3963 // delete the array value. It will look like this:
3964 //
3965 // delete _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
3966 // _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]--]
5e600bd6 3967
85ecf79a
DS
3968 post_crement* pc = new post_crement;
3969 pc->tok = e->tok;
3970 pc->op = "--";
8c819921 3971 pc->operand = ai_ctr;
8fc05e57 3972 ai_tvar_postdec->indexes.push_back(pc);
8c819921
DS
3973
3974 delete_statement* ds = new delete_statement;
3975 ds->tok = e->tok;
8fc05e57 3976 ds->value = ai_tvar_postdec;
8c819921
DS
3977
3978 add_block->statements.push_back (ds);
85ecf79a 3979
46392da3
DS
3980 // (2d) Delete the counter value if it is 0. It will look like
3981 // this:
3982 // if (! _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid])
3983 // delete _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]
4baf0e53 3984
46392da3
DS
3985 ds = new delete_statement;
3986 ds->tok = e->tok;
3987 ds->value = ai_ctr;
3988
3989 unary_expression *ue = new unary_expression;
3990 ue->tok = e->tok;
3991 ue->op = "!";
3992 ue->operand = ai_ctr;
3993
3994 if_statement *ifs = new if_statement;
3995 ifs->tok = e->tok;
3996 ifs->condition = ue;
3997 ifs->thenblock = ds;
3998 ifs->elseblock = NULL;
4baf0e53 3999
46392da3
DS
4000 add_block->statements.push_back (ifs);
4001
85ecf79a 4002 // (3) We need an entry probe that saves the value for us in the
8fc05e57
DS
4003 // global array we created. Create the entry probe, which will
4004 // look like this:
85ecf79a 4005 //
85ecf79a 4006 // probe kernel.function("{function}") {
8fc05e57
DS
4007 // _dwarf_tvar_tid = tid()
4008 // _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
4009 // ++_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
85ecf79a
DS
4010 // = ${param}
4011 // }
4012
8fc05e57 4013 if (add_probe == NULL)
85ecf79a 4014 {
8fc05e57
DS
4015 add_probe = new probe;
4016 add_probe->tok = e->tok;
4017
4018 // We need the name of the current probe point, minus the
4019 // ".return" (or anything after it, such as ".maxactive(N)").
4020 // Create a new probe point, copying all the components,
4021 // stopping when we see the ".return" component.
4022 probe_point* pp = new probe_point;
4023 for (unsigned c = 0; c < q.base_loc->components.size(); c++)
4024 {
4025 if (q.base_loc->components[c]->functor == "return")
4026 break;
4027 else
4028 pp->components.push_back(q.base_loc->components[c]);
4029 }
4030 pp->tok = e->tok;
4031 pp->optional = q.base_loc->optional;
4032 add_probe->locations.push_back(pp);
4033
4034 add_probe->body = new block;
4035 add_probe->body->tok = e->tok;
4036
4037 // Synthesize a functioncall to grab the thread id.
4038 functioncall* fc = new functioncall;
4039 fc->tok = e->tok;
4040 fc->function = string("tid");
4041
4042 // Assign the tid to '_dwarf_tvar_tid'.
4043 assignment* a = new assignment;
4044 a->tok = e->tok;
4045 a->op = "=";
4046 a->left = tidsym;
4047 a->right = fc;
4048
4049 expr_statement* es = new expr_statement;
4050 es->tok = e->tok;
4051 es->value = a;
ba6f838d 4052 add_probe->body = new block(add_probe->body, es);
8fc05e57
DS
4053
4054 vardecl* vd = new vardecl;
4055 vd->tok = e->tok;
4056 vd->name = tidsym->name;
4057 vd->type = pe_long;
4058 vd->set_arity(0);
4059 add_probe->locals.push_back(vd);
85ecf79a 4060 }
8fc05e57
DS
4061
4062 // Save the value, like this:
4063 // _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
4064 // ++_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
4065 // = ${param}
4066 arrayindex* ai_tvar_preinc = new arrayindex;
4067 *ai_tvar_preinc = *ai_tvar_base;
4baf0e53 4068
8fc05e57
DS
4069 pre_crement* preinc = new pre_crement;
4070 preinc->tok = e->tok;
4071 preinc->op = "++";
4072 preinc->operand = ai_ctr;
4073 ai_tvar_preinc->indexes.push_back(preinc);
4baf0e53 4074
8fc05e57
DS
4075 a = new assignment;
4076 a->tok = e->tok;
4077 a->op = "=";
4078 a->left = ai_tvar_preinc;
4079 a->right = e;
4080
4081 es = new expr_statement;
4082 es->tok = e->tok;
4083 es->value = a;
4084
ba6f838d 4085 add_probe->body = new block(add_probe->body, es);
85ecf79a 4086
8c819921
DS
4087 // (4) Provide the '_dwarf_tvar_{name}_{num}_tmp' variable to
4088 // our parent so it can be used as a substitute for the target
4089 // symbol.
4090 provide <symbol*> (this, tmpsym);
cd5b28b2
DS
4091
4092 // (5) Remember this replacement since we might be able to reuse
4093 // it later if the same return probe references this target
4094 // symbol again.
4095 return_ts_map[ts_name] = tmpsym;
85ecf79a
DS
4096 return;
4097 }
cf2a1f85 4098
e57b735a 4099 // Synthesize a function.
d7f3e0c5 4100 functiondecl *fdecl = new functiondecl;
7b99c7d3 4101 fdecl->tok = e->tok;
d7f3e0c5 4102 embeddedcode *ec = new embeddedcode;
5e309481 4103 ec->tok = e->tok;
e8fbc5e8 4104
1b07c728 4105 string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get")
20e4a32c 4106 + "_" + e->base_name.substr(1)
e57b735a
GH
4107 + "_" + lex_cast<string>(tick++));
4108
66d284f4 4109 try
e57b735a 4110 {
e19fda4e
DS
4111 if (q.has_return && e->base_name == "$return")
4112 {
4113 ec->code = q.dw.literal_stmt_for_return (scope_die,
4114 addr,
4115 e->components,
4116 lvalue,
4117 fdecl->type);
4118 }
4119 else
4120 {
4121 ec->code = q.dw.literal_stmt_for_local (scope_die,
4122 addr,
4123 e->base_name.substr(1),
4124 e->components,
4125 lvalue,
4126 fdecl->type);
4127 }
4128
1b07c728
FCE
4129 if (! lvalue)
4130 ec->code += "/* pure */";
66d284f4
FCE
4131 }
4132 catch (const semantic_error& er)
4133 {
cbfbbf69
FCE
4134 // We suppress this error message, and pass the unresolved
4135 // target_symbol to the next pass. We hope that this value ends
4136 // up not being referenced after all, so it can be optimized out
4137 // quietly.
4138 provide <target_symbol*> (this, e);
9f36b77f
FCE
4139 semantic_error* saveme = new semantic_error (er); // copy it
4140 saveme->tok1 = e->tok; // XXX: token not passed to q.dw code generation routines
7e41d3dc
FCE
4141 // NB: we can have multiple errors, since a $target variable
4142 // may be expanded in several different contexts:
4143 // function ("*") { $var }
4144 saveme->chain = e->saved_conversion_error;
9f36b77f 4145 e->saved_conversion_error = saveme;
1cde5ba5
JS
4146 delete fdecl;
4147 delete ec;
cbfbbf69 4148 return;
66d284f4 4149 }
e57b735a 4150
d7f3e0c5
GH
4151 fdecl->name = fname;
4152 fdecl->body = ec;
e57b735a
GH
4153 if (lvalue)
4154 {
4155 // Modify the fdecl so it carries a single pe_long formal
4156 // argument called "value".
4157
4158 // FIXME: For the time being we only support setting target
4159 // variables which have base types; these are 'pe_long' in
4160 // stap's type vocabulary. Strings and pointers might be
4161 // reasonable, some day, but not today.
4162
4163 vardecl *v = new vardecl;
4164 v->type = pe_long;
4165 v->name = "value";
4166 v->tok = e->tok;
4167 fdecl->formal_args.push_back(v);
4168 }
d7f3e0c5 4169 q.sess.functions.push_back(fdecl);
d9b516ca 4170
e57b735a 4171 // Synthesize a functioncall.
d7f3e0c5
GH
4172 functioncall* n = new functioncall;
4173 n->tok = e->tok;
4174 n->function = fname;
35d4ab18 4175 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
e57b735a
GH
4176
4177 if (lvalue)
4178 {
4179 // Provide the functioncall to our parent, so that it can be
4180 // used to substitute for the assignment node immediately above
4181 // us.
4182 assert(!target_symbol_setter_functioncalls.empty());
4183 *(target_symbol_setter_functioncalls.top()) = n;
4184 }
4185
d9b516ca 4186 provide <functioncall*> (this, n);
77de5e9e
GH
4187}
4188
4189
b8da0ad1
FCE
4190void
4191dwarf_derived_probe::printsig (ostream& o) const
4192{
4193 // Instead of just printing the plain locations, we add a PC value
4194 // as a comment as a way of telling e.g. apart multiple inlined
4195 // function instances. This is distinct from the verbose/clog
4196 // output, since this part goes into the cache hash calculations.
4197 sole_location()->print (o);
4198 o << " /* pc=0x" << hex << addr << dec << " */";
4199 printsig_nested (o);
4200}
4201
4202
4203
dc38c0ae 4204void
b20febf3
FCE
4205dwarf_derived_probe::join_group (systemtap_session& s)
4206{
4207 if (! s.dwarf_derived_probes)
4208 s.dwarf_derived_probes = new dwarf_derived_probe_group ();
4209 s.dwarf_derived_probes->enroll (this);
4210}
4211
4212
4213dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
4214 const string& filename,
4215 int line,
4216 // module & section speficy a relocation
4217 // base for <addr>, unless section==""
4218 // (equivalently module=="kernel")
4219 const string& module,
4220 const string& section,
4221 // NB: dwfl_addr is the virtualized
4222 // address for this symbol.
4223 Dwarf_Addr dwfl_addr,
4224 // addr is the section-offset for
4225 // actual relocation.
4226 Dwarf_Addr addr,
4227 dwarf_query& q,
37ebca01 4228 Dwarf_Die* scope_die /* may be null */)
1939ea32 4229 : derived_probe (q.base_probe, new probe_point(*q.base_loc) /* .components soon rewritten */ ),
b20febf3 4230 module (module), section (section), addr (addr),
c9bad430
DS
4231 has_return (q.has_return),
4232 has_maxactive (q.has_maxactive),
4233 maxactive_val (q.maxactive_val)
bd2b1e68 4234{
b20febf3 4235 // Assert relocation invariants
4baf0e53 4236 if (section == "" && dwfl_addr != addr) // addr should be absolute
84048984
FCE
4237 throw semantic_error ("missing relocation base against", q.base_loc->tok);
4238 if (section != "" && dwfl_addr == addr) // addr should be an offset
b20febf3 4239 throw semantic_error ("inconsistent relocation address", q.base_loc->tok);
df8fadee 4240
b20febf3 4241 this->tok = q.base_probe->tok;
2930abc7 4242
21beacc9
FCE
4243 // XXX: hack for strange g++/gcc's
4244#ifndef USHRT_MAX
4245#define USHRT_MAX 32767
4246#endif
4247
606fd9c8
FCE
4248 // Range limit maxactive() value
4249 if (q.has_maxactive && (q.maxactive_val < 0 || q.maxactive_val > USHRT_MAX))
4250 throw semantic_error ("maxactive value out of range [0,"
4251 + lex_cast<string>(USHRT_MAX) + "]",
4252 q.base_loc->tok);
4253
37ebca01 4254 // Make a target-variable-expanded copy of the probe body
5f0a03a6 4255 if (!null_die(scope_die))
8fc05e57 4256 {
37ebca01 4257 dwarf_var_expanding_copy_visitor v (q, scope_die, dwfl_addr);
ba6f838d 4258 require <statement*> (&v, &(this->body), this->body);
37ebca01
FCE
4259
4260 // If during target-variable-expanding the probe, we added a new block
4261 // of code, add it to the start of the probe.
4262 if (v.add_block)
ba6f838d 4263 this->body = new block(v.add_block, this->body);
4baf0e53 4264
37ebca01
FCE
4265 // If when target-variable-expanding the probe, we added a new
4266 // probe, add it in a new file to the list of files to be processed.
4267 if (v.add_probe)
4268 {
4269 stapfile *f = new stapfile;
4270 f->probes.push_back(v.add_probe);
4271 q.sess.files.push_back(f);
4272 }
8fc05e57 4273 }
37ebca01 4274 // else - null scope_die - $target variables will produce an error during translate phase
8fc05e57 4275
5d23847d 4276 // Reset the sole element of the "locations" vector as a
b20febf3
FCE
4277 // "reverse-engineered" form of the incoming (q.base_loc) probe
4278 // point. This allows a user to see what function / file / line
4279 // number any particular match of the wildcards.
2930abc7 4280
a229fcd7
GH
4281 vector<probe_point::component*> comps;
4282 comps.push_back
b20febf3 4283 (module == TOK_KERNEL
a229fcd7 4284 ? new probe_point::component(TOK_KERNEL)
b20febf3 4285 : new probe_point::component(TOK_MODULE, new literal_string(module)));
b5d77020 4286
db520b00
FCE
4287 string fn_or_stmt;
4288 if (q.has_function_str || q.has_function_num)
4289 fn_or_stmt = "function";
4290 else
4291 fn_or_stmt = "statement";
a229fcd7 4292
b8da0ad1 4293 if (q.has_function_str || q.has_statement_str)
db520b00 4294 {
4cd232e4 4295 string retro_name = funcname;
b20febf3 4296 if (filename != "")
4cd232e4
GH
4297 retro_name += ("@" + string (filename));
4298 if (line != -1)
4299 retro_name += (":" + lex_cast<string> (line));
db520b00
FCE
4300 comps.push_back
4301 (new probe_point::component
4302 (fn_or_stmt, new literal_string (retro_name)));
4303 }
b8da0ad1 4304 else if (q.has_function_num || q.has_statement_num)
db520b00
FCE
4305 {
4306 Dwarf_Addr retro_addr;
4307 if (q.has_function_num)
4308 retro_addr = q.function_num_val;
4309 else
4310 retro_addr = q.statement_num_val;
db520b00
FCE
4311 comps.push_back (new probe_point::component
4312 (fn_or_stmt,
4313 new literal_number(retro_addr))); // XXX: should be hex if possible
37ebca01
FCE
4314
4315 if (q.has_absolute)
4316 comps.push_back (new probe_point::component (TOK_ABSOLUTE));
a229fcd7
GH
4317 }
4318
b8da0ad1
FCE
4319 if (q.has_call)
4320 comps.push_back (new probe_point::component(TOK_CALL));
4321 if (q.has_inline)
4322 comps.push_back (new probe_point::component(TOK_INLINE));
db520b00 4323 if (has_return)
b8da0ad1
FCE
4324 comps.push_back (new probe_point::component(TOK_RETURN));
4325 if (has_maxactive)
4326 comps.push_back (new probe_point::component
4327 (TOK_MAXACTIVE, new literal_number(maxactive_val)));
d9b516ca 4328
5d23847d
FCE
4329 // Overwrite it.
4330 this->sole_location()->components = comps;
2930abc7
FCE
4331}
4332
bd2b1e68 4333
7a053d3b 4334void
20c6c071 4335dwarf_derived_probe::register_statement_variants(match_node * root,
bd2b1e68
GH
4336 dwarf_builder * dw)
4337{
54efe513 4338 root->bind(dw);
54efe513
GH
4339}
4340
7a053d3b 4341void
fd6602a0 4342dwarf_derived_probe::register_function_variants(match_node * root,
c9bad430 4343 dwarf_builder * dw)
bd2b1e68 4344{
fd6602a0 4345 root->bind(dw);
b8da0ad1
FCE
4346 root->bind(TOK_INLINE)->bind(dw);
4347 root->bind(TOK_CALL)->bind(dw);
fd6602a0 4348 root->bind(TOK_RETURN)->bind(dw);
c9bad430 4349 root->bind(TOK_RETURN)->bind_num(TOK_MAXACTIVE)->bind(dw);
bd2b1e68
GH
4350}
4351
7a053d3b 4352void
20c6c071 4353dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
bd2b1e68
GH
4354 dwarf_builder * dw)
4355{
4356 // Here we match 4 forms:
4357 //
4358 // .function("foo")
4359 // .function(0xdeadbeef)
4360 // .statement("foo")
4361 // .statement(0xdeadbeef)
4362
fd6602a0
FCE
4363 register_function_variants(root->bind_str(TOK_FUNCTION), dw);
4364 register_function_variants(root->bind_num(TOK_FUNCTION), dw);
20c6c071
GH
4365 register_statement_variants(root->bind_str(TOK_STATEMENT), dw);
4366 register_statement_variants(root->bind_num(TOK_STATEMENT), dw);
bd2b1e68
GH
4367}
4368
4369void
20c6c071 4370dwarf_derived_probe::register_patterns(match_node * root)
bd2b1e68
GH
4371{
4372 dwarf_builder *dw = new dwarf_builder();
4373
20c6c071
GH
4374 register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
4375 register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
37ebca01
FCE
4376 root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(dw);
4377
ab55a5ae 4378 // register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
bd2b1e68
GH
4379}
4380
2930abc7 4381
b20febf3 4382// ------------------------------------------------------------------------
46b84a80
DS
4383
4384void
b20febf3 4385dwarf_derived_probe_group::enroll (dwarf_derived_probe* p)
46b84a80 4386{
b20febf3 4387 probes_by_module.insert (make_pair (p->module, p));
b8da0ad1
FCE
4388
4389 // XXX: probes put at the same address should all share a
4390 // single kprobe/kretprobe, and have their handlers executed
4391 // sequentially.
b55bc428
FCE
4392}
4393
2930abc7 4394
7a053d3b 4395void
775d51e5 4396dwarf_derived_probe_group::emit_module_decls (systemtap_session& s)
ec4373ff 4397{
b20febf3 4398 if (probes_by_module.empty()) return;
2930abc7 4399
775d51e5
DS
4400 s.op->newline() << "/* ---- dwarf probes ---- */";
4401
4402 // Warn of misconfigured kernels
f41595cc
FCE
4403 s.op->newline() << "#if ! defined(CONFIG_KPROBES)";
4404 s.op->newline() << "#error \"Need CONFIG_KPROBES!\"";
4405 s.op->newline() << "#endif";
775d51e5 4406 s.op->newline();
f41595cc 4407
b20febf3
FCE
4408 // Forward declare the master entry functions
4409 s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
4410 s.op->line() << " struct pt_regs *regs);";
4411 s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
4412 s.op->line() << " struct pt_regs *regs);";
4413
42cb22bd
MH
4414 // Emit an array of kprobe/kretprobe pointers
4415 s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
4416 s.op->newline() << "static void * stap_unreg_kprobes[" << probes_by_module.size() << "];";
4417 s.op->newline() << "#endif";
4418
b20febf3 4419 // Emit the actual probe list.
606fd9c8
FCE
4420
4421 // NB: we used to plop a union { struct kprobe; struct kretprobe } into
4422 // struct stap_dwarf_probe, but it being initialized data makes it add
4423 // hundreds of bytes of padding per stap_dwarf_probe. (PR5673)
4424 s.op->newline() << "struct stap_dwarf_kprobe {";
b20febf3 4425 s.op->newline(1) << "union { struct kprobe kp; struct kretprobe krp; } u;";
606fd9c8
FCE
4426 s.op->newline(-1) << "} stap_dwarf_kprobes[" << probes_by_module.size() << "];";
4427 // NB: bss!
4428
4429 s.op->newline() << "struct stap_dwarf_probe {";
b0986e7a
DS
4430 s.op->newline(1) << "const unsigned return_p:1;";
4431 s.op->newline() << "const unsigned maxactive_p:1;";
b20febf3 4432 s.op->newline() << "unsigned registered_p:1;";
b0986e7a 4433 s.op->newline() << "const unsigned short maxactive_val;";
606fd9c8
FCE
4434
4435 // Let's find some stats for the three embedded strings. Maybe they
4436 // are small and uniform enough to justify putting char[MAX]'s into
4437 // the array instead of relocated char*'s.
4438 size_t module_name_max = 0, section_name_max = 0, pp_name_max = 0;
4439 size_t module_name_tot = 0, section_name_tot = 0, pp_name_tot = 0;
4440 size_t all_name_cnt = probes_by_module.size(); // for average
4441 for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
4442 {
4443 dwarf_derived_probe* p = it->second;
4444#define DOIT(var,expr) do { \
4445 size_t var##_size = (expr) + 1; \
4446 var##_max = max (var##_max, var##_size); \
4447 var##_tot += var##_size; } while (0)
4448 DOIT(module_name, p->module.size());
4449 DOIT(section_name, p->section.size());
4450 DOIT(pp_name, lex_cast_qstring(*p->sole_location()).size());
4451#undef DOIT
4452 }
4453
4454 // Decide whether it's worthwhile to use char[] or char* by comparing
4455 // the amount of average waste (max - avg) to the relocation data size
4456 // (3 native long words).
4457#define CALCIT(var) \
4458 if ((var##_name_max-(var##_name_tot/all_name_cnt)) < (3 * sizeof(void*))) \
4459 { \
4460 s.op->newline() << "const char " << #var << "[" << var##_name_max << "];"; \
4461 if (s.verbose > 2) clog << "stap_dwarf_probe " << #var \
4462 << "[" << var##_name_max << "]" << endl; \
4463 } \
4464 else \
4465 { \
b0986e7a 4466 s.op->newline() << "const char * const " << #var << ";"; \
606fd9c8
FCE
4467 if (s.verbose > 2) clog << "stap_dwarf_probe *" << #var << endl; \
4468 }
4469
4470 CALCIT(module);
4471 CALCIT(section);
4472 CALCIT(pp);
4473
b0986e7a
DS
4474 s.op->newline() << "const unsigned long address;";
4475 s.op->newline() << "void (* const ph) (struct context*);";
b20febf3
FCE
4476 s.op->newline(-1) << "} stap_dwarf_probes[] = {";
4477 s.op->indent(1);
4478
4479 for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
2930abc7 4480 {
b20febf3
FCE
4481 dwarf_derived_probe* p = it->second;
4482 s.op->newline() << "{";
4483 if (p->has_return)
4484 s.op->line() << " .return_p=1,";
c9bad430 4485 if (p->has_maxactive)
606fd9c8
FCE
4486 {
4487 s.op->line() << " .maxactive_p=1,";
4488 assert (p->maxactive_val >= 0 && p->maxactive_val <= USHRT_MAX);
4489 s.op->line() << " .maxactive_val=" << p->maxactive_val << ",";
4490 }
b20febf3 4491 s.op->line() << " .address=0x" << hex << p->addr << dec << "UL,";
84048984
FCE
4492 s.op->line() << " .module=\"" << p->module << "\",";
4493 s.op->line() << " .section=\"" << p->section << "\",";
b20febf3
FCE
4494 s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
4495 s.op->line() << " .ph=&" << p->name;
4496 s.op->line() << " },";
2930abc7 4497 }
2930abc7 4498
b20febf3
FCE
4499 s.op->newline(-1) << "};";
4500
4501 // Emit the kprobes callback function
4502 s.op->newline();
4503 s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
4504 s.op->line() << " struct pt_regs *regs) {";
606fd9c8
FCE
4505 // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
4506 s.op->newline(1) << "int kprobe_idx = ((uintptr_t)inst-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);";
4507 // Check that the index is plausible
4508 s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes[";
4509 s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
4510 s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
4511 // XXX: it would be nice to give a more verbose error though; BUG_ON later?
4512 s.op->line() << "];";
b20febf3
FCE
4513 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
4514 s.op->newline() << "c->probe_point = sdp->pp;";
4515 s.op->newline() << "c->regs = regs;";
4516 s.op->newline() << "(*sdp->ph) (c);";
4517 common_probe_entryfn_epilogue (s.op);
4518 s.op->newline() << "return 0;";
4519 s.op->newline(-1) << "}";
4520
4521 // Same for kretprobes
4522 s.op->newline();
4523 s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
4524 s.op->line() << " struct pt_regs *regs) {";
4525 s.op->newline(1) << "struct kretprobe *krp = inst->rp;";
606fd9c8
FCE
4526
4527 // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
a36378d7 4528 s.op->newline() << "int kprobe_idx = ((uintptr_t)krp-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);";
606fd9c8
FCE
4529 // Check that the index is plausible
4530 s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes[";
4531 s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
4532 s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
4533 // XXX: it would be nice to give a more verbose error though; BUG_ON later?
4534 s.op->line() << "];";
4535
b20febf3
FCE
4536 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
4537 s.op->newline() << "c->probe_point = sdp->pp;";
4538 s.op->newline() << "c->regs = regs;";
4539 s.op->newline() << "c->pi = inst;"; // for assisting runtime's backtrace logic
4540 s.op->newline() << "(*sdp->ph) (c);";
4541 common_probe_entryfn_epilogue (s.op);
4542 s.op->newline() << "return 0;";
4543 s.op->newline(-1) << "}";
20c6c071 4544}
ec4373ff 4545
20c6c071 4546
dc38c0ae 4547void
b20febf3
FCE
4548dwarf_derived_probe_group::emit_module_init (systemtap_session& s)
4549{
4550 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
4551 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
a36378d7 4552 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
f1bad60c 4553 s.op->newline() << "unsigned long relocated_addr = _stp_module_relocate (sdp->module, sdp->section, sdp->address);";
b20febf3 4554 s.op->newline() << "if (relocated_addr == 0) continue;"; // quietly; assume module is absent
6f313a73 4555 s.op->newline() << "probe_point = sdp->pp;";
b20febf3 4556 s.op->newline() << "if (sdp->return_p) {";
606fd9c8 4557 s.op->newline(1) << "kp->u.krp.kp.addr = (void *) relocated_addr;";
c9bad430 4558 s.op->newline() << "if (sdp->maxactive_p) {";
606fd9c8 4559 s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;";
c9bad430 4560 s.op->newline(-1) << "} else {";
606fd9c8 4561 s.op->newline(1) << "kp->u.krp.maxactive = max(10, 4*NR_CPUS);";
c9bad430 4562 s.op->newline(-1) << "}";
606fd9c8
FCE
4563 s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;";
4564 s.op->newline() << "rc = register_kretprobe (& kp->u.krp);";
b20febf3 4565 s.op->newline(-1) << "} else {";
606fd9c8
FCE
4566 s.op->newline(1) << "kp->u.kp.addr = (void *) relocated_addr;";
4567 s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe_probe;";
4568 s.op->newline() << "rc = register_kprobe (& kp->u.kp);";
b20febf3 4569 s.op->newline(-1) << "}";
c48cb0cc
FCE
4570 s.op->newline() << "if (rc) {";
4571 s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
b20febf3 4572 s.op->newline(1) << "struct stap_dwarf_probe *sdp2 = & stap_dwarf_probes[j];";
606fd9c8
FCE
4573 s.op->newline() << "struct stap_dwarf_kprobe *kp2 = & stap_dwarf_kprobes[j];";
4574 s.op->newline() << "if (sdp2->return_p) unregister_kretprobe (&kp2->u.krp);";
4575 s.op->newline() << "else unregister_kprobe (&kp2->u.kp);";
c48cb0cc
FCE
4576 // NB: we don't have to clear sdp2->registered_p, since the module_exit code is
4577 // not run for this early-abort case.
4578 s.op->newline(-1) << "}";
4579 s.op->newline() << "break;"; // don't attempt to register any more probes
b20febf3
FCE
4580 s.op->newline(-1) << "}";
4581 s.op->newline() << "else sdp->registered_p = 1;";
4582 s.op->newline(-1) << "}"; // for loop
dc38c0ae
DS
4583}
4584
4585
46b84a80 4586void
b20febf3 4587dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
46b84a80 4588{
42cb22bd
MH
4589 //Unregister kprobes by batch interfaces.
4590 s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
4591 s.op->newline() << "j = 0;";
4592 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
4593 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
4594 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
4595 s.op->newline() << "if (! sdp->registered_p) continue;";
4596 s.op->newline() << "if (!sdp->return_p)";
4597 s.op->newline(1) << "stap_unreg_kprobes[j++] = &kp->u.kp;";
4598 s.op->newline(-2) << "}";
4599 s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);";
4600 s.op->newline() << "j = 0;";
4601 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
4602 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
4603 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
4604 s.op->newline() << "if (! sdp->registered_p) continue;";
4605 s.op->newline() << "if (sdp->return_p)";
4606 s.op->newline(1) << "stap_unreg_kprobes[j++] = &kp->u.krp;";
4607 s.op->newline(-2) << "}";
4608 s.op->newline() << "unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, j);";
4609 s.op->newline() << "#endif";
4610
b20febf3
FCE
4611 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
4612 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
a36378d7 4613 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
b20febf3
FCE
4614 s.op->newline() << "if (! sdp->registered_p) continue;";
4615 s.op->newline() << "if (sdp->return_p) {";
42cb22bd 4616 s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
606fd9c8 4617 s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);";
42cb22bd 4618 s.op->newline() << "#endif";
606fd9c8
FCE
4619 s.op->newline() << "atomic_add (kp->u.krp.nmissed, & skipped_count);";
4620 s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, & skipped_count);";
557fb7a8 4621 s.op->newline(-1) << "} else {";
42cb22bd 4622 s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
606fd9c8 4623 s.op->newline(1) << "unregister_kprobe (&kp->u.kp);";
42cb22bd 4624 s.op->newline() << "#endif";
606fd9c8 4625 s.op->newline() << "atomic_add (kp->u.kp.nmissed, & skipped_count);";
b20febf3
FCE
4626 s.op->newline(-1) << "}";
4627 s.op->newline() << "sdp->registered_p = 0;";
4628 s.op->newline(-1) << "}";
46b84a80
DS
4629}
4630
4631
84048984
FCE
4632
4633static Dwarf_Addr
4634lookup_symbol_address (Dwfl_Module *m, const char* wanted)
4635{
4636 int syments = dwfl_module_getsymtab(m);
4637 assert(syments);
4638 for (int i = 1; i < syments; ++i)
4639 {
4640 GElf_Sym sym;
4641 const char *name = dwfl_module_getsym(m, i, &sym, NULL);
4642 if (name != NULL && strcmp(name, wanted) == 0)
4643 return sym.st_value;
4644 }
4645
4646 return 0;
4647}
4648
4649
4650
4651
20c6c071 4652void
5227f1ea 4653dwarf_builder::build(systemtap_session & sess,
7a053d3b 4654 probe * base,
20c6c071
GH
4655 probe_point * location,
4656 std::map<std::string, literal *> const & parameters,
20c6c071
GH
4657 vector<derived_probe *> & finished_results)
4658{
b20febf3
FCE
4659 // NB: the kernel/user dwlfpp objects are long-lived.
4660 // XXX: but they should be per-session, as this builder object
4661 // may be reused if we try to cross-instrument multiple targets.
84048984 4662
b8da0ad1
FCE
4663 if (!kern_dw)
4664 {
4665 kern_dw = new dwflpp(sess);
4666 assert(kern_dw);
4667 kern_dw->setup(true);
4668 }
84048984 4669
b8da0ad1
FCE
4670 Dwfl_Module* km = 0;
4671 kern_dw->iterate_over_modules(&query_kernel_module, &km);
4672 if (km)
4673 {
6561773f
FCE
4674 if (! sess.sym_kprobes_text_start)
4675 sess.sym_kprobes_text_start = lookup_symbol_address (km, "__kprobes_text_start");
4676 if (! sess.sym_kprobes_text_end)
4677 sess.sym_kprobes_text_end = lookup_symbol_address (km, "__kprobes_text_end");
4678 if (! sess.sym_stext)
4679 sess.sym_stext = lookup_symbol_address (km, "_stext");
4680
b8da0ad1 4681 if (sess.verbose > 2)
84048984 4682 {
b8da0ad1
FCE
4683 clog << "control symbols:"
4684 // abbreviate the names - they're for our debugging only anyway
4685 << " kts: 0x" << hex << sess.sym_kprobes_text_start
4686 << " kte: 0x" << sess.sym_kprobes_text_end
4687 << " stext: 0x" << sess.sym_stext
4688 << dec << endl;
84048984 4689 }
c8959a29 4690 }
20c6c071 4691
b8da0ad1 4692 dwflpp* dw = kern_dw;
c8959a29 4693 dwarf_query q(sess, base, location, *dw, parameters, finished_results);
20c6c071 4694
37ebca01
FCE
4695 if (q.has_absolute)
4696 {
4baf0e53 4697 // assert guru mode for absolute probes
37ebca01
FCE
4698 if (! q.base_probe->privileged)
4699 {
4700 throw semantic_error ("absolute statement probe in unprivileged script", q.base_probe->tok);
4701 }
4702
4703 // For kernel.statement(NUM).absolute probe points, we bypass
4704 // all the debuginfo stuff: We just wire up a
4705 // dwarf_derived_probe right here and now.
4baf0e53 4706 dwarf_derived_probe* p =
b8da0ad1
FCE
4707 new dwarf_derived_probe ("", "", 0, "kernel", "",
4708 q.statement_num_val, q.statement_num_val,
4709 q, 0);
37ebca01
FCE
4710 finished_results.push_back (p);
4711 return;
4712 }
4713
5f0a03a6
JK
4714 // dw->iterate_over_modules(&query_module, &q);
4715 dw->query_modules(&q);
4716}
4717
4718symbol_table::~symbol_table()
4719{
4720 // map::clear() and vector::clear() don't call destructors for
4721 // pointers, only for objects.
4722 int i;
4723 int nsym = (int) list_by_addr.size();
4724 for (i = 0; i < nsym; i++)
4725 delete list_by_addr.at(i);
4726 list_by_addr.clear();
4727 map_by_name.clear();
4728}
4729
4730void
ab91b232
JK
4731symbol_table::add_symbol(const char *name, bool weak, Dwarf_Addr addr,
4732 Dwarf_Addr *high_addr)
5f0a03a6 4733{
ab91b232
JK
4734#ifdef __powerpc__
4735 // Map ".sys_foo" to "sys_foo".
4736 if (name[0] == '.')
4737 name++;
4738#endif
5f0a03a6
JK
4739 func_info *fi = new func_info();
4740 fi->addr = addr;
4741 fi->name = name;
ab91b232 4742 fi->weak = weak;
5f0a03a6
JK
4743 map_by_name[fi->name] = fi;
4744 // TODO: Use a multimap in case there are multiple static
4745 // functions with the same name?
4746 if (addr >= *high_addr)
4747 {
4748 list_by_addr.push_back(fi);
4749 *high_addr = addr;
4750 }
4751 else
4752 {
4753 // Symbols aren't in numerical order. FWIW, sort(1) doesn't
4754 // handle hex numbers without the leading 0x.
4755 int index = get_index_for_address(fi->addr);
4756 list_by_addr.insert(list_by_addr.begin()+(index+1), fi);
4757 }
4758}
4759
4760enum info_status
4761symbol_table::read_symbols(FILE *f, const string& path)
4762{
4763 // Based on do_kernel_symbols() in runtime/staprun/symbols.c
4764 int ret;
4765 char *name, *mod;
4766 char type;
4767 unsigned long long addr;
4768 Dwarf_Addr high_addr = 0;
4769 int line = 0;
4770
4771 // %as (non-POSIX) mallocs space for the string and stores its address.
4772 while ((ret = fscanf(f, "%llx %c %as [%as", &addr, &type, &name, &mod)) > 0)
4773 {
4774 line++;
4775 if (ret < 3)
4776 {
4777 cerr << "Symbol table error: Line "
4778 << line
4779 << " of symbol list from "
4780 << path
4781 << " is not in correct format: address type name [module]";
4782 // Caller should delete symbol_table object.
4783 return info_absent;
4784 }
4785 if (ret > 3)
4786 {
4787 // Modules are loaded above the kernel, so if we're getting
4788 // modules, we're done.
4789 free(name);
4790 free(mod);
4791 goto done;
4792 }
ab91b232
JK
4793 if (type == 'T' || type == 't' || type == 'W')
4794 add_symbol(name, (type == 'W'), (Dwarf_Addr) addr, &high_addr);
5f0a03a6
JK
4795 free(name);
4796 }
4797
4798done:
4799 if (list_by_addr.size() < 1)
4800 {
4801 cerr << "Symbol table error: "
4802 << path << " contains no function symbols." << endl;
4803 return info_absent;
4804 }
4805 return info_present;
4806}
4807
4808// NB: This currently unused. We use get_from_elf() instead because
4809// that gives us raw addresses -- which we need for modules -- whereas
4810// nm provides the address relative to the beginning of the section.
4811enum info_status
4812symbol_table::read_from_elf_file(const string &path)
4813{
4814 FILE *f;
4815 string cmd = string("/usr/bin/nm -n --defined-only ") + path;
4816 f = popen(cmd.c_str(), "r");
4817 if (!f)
4818 {
4819 // nm failures are detected by pclose, not popen.
4820 cerr << "Internal error reading symbol table from "
4821 << path << " -- " << strerror (errno);
4822 return info_absent;
4823 }
4824 enum info_status status = read_symbols(f, path);
4825 if (pclose(f) != 0)
4826 {
4827 if (status == info_present)
4828 cerr << "Warning: nm cannot read symbol table from " << path;
4829 return info_absent;
4830 }
4831 return status;
4832}
4833
4834enum info_status
4835symbol_table::read_from_text_file(const string& path)
4836{
4837 FILE *f = fopen(path.c_str(), "r");
4838 if (!f)
4839 {
4840 cerr << "Warning: cannot read symbol table from "
4841 << path << " -- " << strerror (errno);
4842 return info_absent;
4843 }
4844 enum info_status status = read_symbols(f, path);
4845 (void) fclose(f);
4846 return status;
4847}
4848
4849enum info_status
4850symbol_table::get_from_elf()
4851{
4852 Dwarf_Addr high_addr = 0;
4853 Dwfl_Module *mod = mod_info->mod;
4854 int syments = dwfl_module_getsymtab(mod);
4855 assert(syments);
4856 for (int i = 1; i < syments; ++i)
4857 {
4858 GElf_Sym sym;
ab91b232
JK
4859 GElf_Word section;
4860 const char *name = dwfl_module_getsym(mod, i, &sym, &section);
4861 if (name && GELF_ST_TYPE(sym.st_info) == STT_FUNC && section != SHN_UNDEF)
4862 add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
4863 sym.st_value, &high_addr);
5f0a03a6
JK
4864 }
4865 return info_present;
4866}
4867
4868void
4869symbol_table::mark_dwarf_redundancies(dwflpp *dw)
4870{
4871 // dwflpp.cu_function_cache maps each module_name:cu_name to a
4872 // vector of Dwarf_Dies, one per function.
4873 string module_prefix = string(mod_info->name) + ":";
4874
6561773f 4875 mod_cu_function_cache_t::iterator cu;
5f0a03a6 4876 for (cu = dw->cu_function_cache.begin();
6561773f 4877 cu != dw->cu_function_cache.end(); cu++)
5f0a03a6
JK
4878 {
4879 string key = cu->first;
4880 if (key.find(module_prefix) == 0)
4881 {
4882 // Found a compilation unit in the module of interest.
4883 // Mark all its functions in the symbol table.
6561773f 4884 cu_function_cache_t* v = cu->second;
5f0a03a6 4885 assert(v);
6561773f 4886 for (cu_function_cache_t::iterator fc = v->begin(); fc != v->end(); fc++)
5f0a03a6 4887 {
6561773f
FCE
4888 Dwarf_Die func = fc->second;
4889 string func_name = fc->first; // == dwarf_diename(&func);
5f0a03a6
JK
4890 // map_by_name[func_name]->die = func;
4891 map<string, func_info*>::iterator i = map_by_name.find(func_name);
4892 // Func names can show up in the dwarf but not the symtab (!).
4893 if (i != map_by_name.end())
4894 {
4895 func_info *fi = i->second;
4896 fi->die = func;
4897 }
4898 }
4899 }
4900 }
4901}
4902
4903func_info *
4904symbol_table::get_func_containing_address(Dwarf_Addr addr)
4905{
4906 int index = get_index_for_address(addr);
4907 if (index < 0)
4908 return NULL;
4909 return list_by_addr.at(index);
4910}
4911
4912// Find the index in list_by_addr of the last element whose address
4913// is <= addr. Returns -1 if addr is less than the first address in
4914// list_by_addr.
4915int
4916symbol_table::get_index_for_address(Dwarf_Addr addr)
4917{
4918 // binary search from runtime/sym.c
4919 int begin = 0;
4920 int mid;
4921 int end = list_by_addr.size();
4922
4923 if (end == 0 || addr < list_by_addr.at(0)->addr)
4924 return -1;
4925 do
4926 {
4927 mid = (begin + end) / 2;
4928 if (addr < list_by_addr.at(mid)->addr)
4929 end = mid;
4930 else
4931 begin = mid;
4932 }
4933 while (begin + 1 < end);
4934 return begin;
4935}
4936
4937func_info *
4938symbol_table::lookup_symbol(const string& name)
4939{
4940 map<string, func_info*>::iterator i = map_by_name.find(name);
4941 if (i == map_by_name.end())
4942 return NULL;
4943 return i->second;
4944}
4945
4946Dwarf_Addr
4947symbol_table::lookup_symbol_address(const string& name)
4948{
4949 func_info *fi = lookup_symbol(name);
4950 if (fi)
4951 return fi->addr;
4952 return 0;
4953}
4954
ab91b232
JK
4955// This is the kernel symbol table. The kernel macro cond_syscall creates
4956// a weak symbol for each system call and maps it to sys_ni_syscall.
4957// For system calls not implemented elsewhere, this weak symbol shows up
4958// in the kernel symbol table. Following the precedent of dwarfful stap,
4959// we refuse to consider such symbols. Here we delete them from our
4960// symbol table.
4961// TODO: Consider generalizing this and/or making it part of blacklist
4962// processing.
4963void
4964symbol_table::purge_syscall_stubs()
4965{
4966 Dwarf_Addr stub_addr = lookup_symbol_address("sys_ni_syscall");
4967 if (stub_addr == 0)
4968 return;
4969 for (size_t i = 0; i < list_by_addr.size(); i++)
4970 {
4971 func_info *fi = list_by_addr.at(i);
4972 if (fi->weak && fi->addr == stub_addr && fi->name != "sys_ni_syscall")
4973 {
4974 list_by_addr.erase(list_by_addr.begin()+i);
4975 map_by_name.erase(fi->name);
4976 delete fi;
4977 i--;
4978 }
4979 }
4980}
4981
5f0a03a6
JK
4982void
4983module_info::get_symtab(dwarf_query *q)
4984{
4985 systemtap_session &sess = q->sess;
4986
4987 sym_table = new symbol_table(this);
4988 if (!elf_path.empty())
4989 {
4990 if (name == TOK_KERNEL && !sess.kernel_symtab_path.empty())
4991 cerr << "Warning: reading symbol table from "
4992 << elf_path
4993 << " -- ignoring "
4994 << sess.kernel_symtab_path
4995 << endl ;;
4996 symtab_status = sym_table->get_from_elf();
4997 }
4998 else
4999 {
5000 assert(name == TOK_KERNEL);
5001 if (sess.kernel_symtab_path.empty())
5002 {
5003 symtab_status = info_absent;
5004 cerr << "Error: Cannot find vmlinux."
5005 << " Consider using --kmap instead of --kelf."
5006 << endl;;
5007 }
5008 else
5009 {
5010 symtab_status =
5011 sym_table->read_from_text_file(sess.kernel_symtab_path);
5012 if (symtab_status == info_present)
5013 {
5014 sess.sym_kprobes_text_start =
5015 sym_table->lookup_symbol_address("__kprobes_text_start");
5016 sess.sym_kprobes_text_end =
5017 sym_table->lookup_symbol_address("__kprobes_text_end");
5018 sess.sym_stext = sym_table->lookup_symbol_address("_stext");
5019 bias = sym_table->lookup_symbol_address("_text");
5020 }
5021 }
5022 }
5023 if (symtab_status == info_absent)
5024 {
5025 delete sym_table;
5026 sym_table = NULL;
5027 return;
5028 }
5029
5030 // If we have dwarf for the same module, mark the redundant symtab
5031 // entries.
5032 //
5033 // In dwarf_query::handle_query_module(), the call to query_module_dwarf()
5034 // precedes the call to query_module_symtab(). So we should never read
5035 // a module's symbol table without first having tried to get its dwarf.
5036 sym_table->mark_dwarf_redundancies(&q->dw);
ab91b232
JK
5037
5038 if (name == TOK_KERNEL)
5039 sym_table->purge_syscall_stubs();
5f0a03a6
JK
5040}
5041
5042module_info::~module_info()
5043{
5044 if (sym_table)
5045 delete sym_table;
b55bc428
FCE
5046}
5047
5048
98afd80e 5049
935447c8
DS
5050// ------------------------------------------------------------------------
5051// task_finder derived 'probes': These don't really exist. The whole
5052// purpose of the task_finder_derived_probe_group is to make sure that
5053// stap_start_task_finder()/stap_stop_task_finder() get called only
5054// once and in the right place.
5055// ------------------------------------------------------------------------
5056
5057struct task_finder_derived_probe: public derived_probe
5058{
c295b10e
FCE
5059 // Dummy constructor for gcc 3.4 compatibility
5060 task_finder_derived_probe (): derived_probe (0) { assert(0); }
935447c8
DS
5061};
5062
5063
5064struct task_finder_derived_probe_group: public generic_dpg<task_finder_derived_probe>
5065{
5066public:
5067 static void create_session_group (systemtap_session& s);
5068
5069 void emit_module_decls (systemtap_session& ) { }
5070 void emit_module_init (systemtap_session& s);
5071 void emit_module_exit (systemtap_session& s);
5072};
5073
5074
5075void
5076task_finder_derived_probe_group::create_session_group (systemtap_session& s)
5077{
5078 if (! s.task_finder_derived_probes)
5079 {
5080 s.task_finder_derived_probes = new task_finder_derived_probe_group();
5081
5082 // Make sure we've got the stuff we need early in the output code.
5083 embeddedcode *ec = new embeddedcode;
5084 ec->tok = NULL;
5085 ec->code = string("#if ! defined(CONFIG_UTRACE)\n")
5086 + string("#error \"Need CONFIG_UTRACE!\"\n")
5087 + string("#endif\n")
5088 + string("#include <linux/utrace.h>\n")
5089 + string("#include <linux/mount.h>\n")
5090 + string("#include \"task_finder.c\"\n");
5091
5092 s.embeds.push_back(ec);
5093 }
5094}
5095
5096
5097void
5098task_finder_derived_probe_group::emit_module_init (systemtap_session& s)
5099{
5100 s.op->newline();
5101 s.op->newline() << "/* ---- task finder ---- */";
5102 s.op->newline() << "rc = stap_start_task_finder();";
5103
5104 s.op->newline() << "if (rc) {";
5105 s.op->indent(1);
5106 s.op->newline() << "stap_stop_task_finder();";
5107 s.op->newline(-1) << "}";
5108}
5109
5110
5111void
5112task_finder_derived_probe_group::emit_module_exit (systemtap_session& s)
5113{
5114 s.op->newline();
5115 s.op->newline() << "/* ---- task finder ---- */";
5116 s.op->newline() << "stap_stop_task_finder();";
5117}
5118
5119
5120// ------------------------------------------------------------------------
5121// utrace user-space probes
5122// ------------------------------------------------------------------------
5123
eff6ac72 5124static string TOK_THREAD("thread");
12b21830
DS
5125static string TOK_SYSCALL("syscall");
5126
eff6ac72
DS
5127// Note that these flags don't match up exactly with UTRACE_EVENT
5128// flags (and that's OK).
935447c8
DS
5129enum utrace_derived_probe_flags {
5130 UDPF_NONE,
eff6ac72
DS
5131 UDPF_BEGIN, // process begin
5132 UDPF_END, // process end
5133 UDPF_THREAD_BEGIN, // thread begin
5134 UDPF_THREAD_END, // thread end
5135 UDPF_SYSCALL, // syscall entry
5136 UDPF_SYSCALL_RETURN, // syscall exit
935447c8
DS
5137 UDPF_NFLAGS
5138};
5139
5140struct utrace_derived_probe: public derived_probe
5141{
5142 bool has_path;
5143 string path;
5144 int64_t pid;
5145 enum utrace_derived_probe_flags flags;
5146 bool target_symbol_seen;
5147
5148 utrace_derived_probe (systemtap_session &s, probe* p, probe_point* l,
5149 bool hp, string &pn, int64_t pd,
5150 enum utrace_derived_probe_flags f);
5151 void join_group (systemtap_session& s);
5152};
5153
5154
5155struct utrace_derived_probe_group: public generic_dpg<utrace_derived_probe>
5156{
5157private:
5158 map<string, vector<utrace_derived_probe*> > probes_by_path;
5159 typedef map<string, vector<utrace_derived_probe*> >::iterator p_b_path_iterator;
5160 map<int64_t, vector<utrace_derived_probe*> > probes_by_pid;
5161 typedef map<int64_t, vector<utrace_derived_probe*> >::iterator p_b_pid_iterator;
5162 unsigned num_probes;
5163 bool flags_seen[UDPF_NFLAGS];
5164
5165 void emit_probe_decl (systemtap_session& s, utrace_derived_probe *p);
5166
5167public:
5168 utrace_derived_probe_group(): num_probes(0), flags_seen() { }
5169
5170 void enroll (utrace_derived_probe* probe);
5171 void emit_module_decls (systemtap_session& s);
5172 void emit_module_init (systemtap_session& s);
5173 void emit_module_exit (systemtap_session& s);
5174};
5175
5176
5177struct utrace_var_expanding_copy_visitor: public var_expanding_copy_visitor
5178{
5179 utrace_var_expanding_copy_visitor(systemtap_session& s, const string& pn,
5180 enum utrace_derived_probe_flags f):
5181 sess (s), probe_name (pn), flags (f), target_symbol_seen (false) {}
5182
5183 systemtap_session& sess;
5184 string probe_name;
5185 enum utrace_derived_probe_flags flags;
5186 bool target_symbol_seen;
5187
5188 void visit_target_symbol (target_symbol* e);
5189};
5190
5191
5192utrace_derived_probe::utrace_derived_probe (systemtap_session &s,
5193 probe* p, probe_point* l,
5194 bool hp, string &pn, int64_t pd,
5195 enum utrace_derived_probe_flags f):
5196 derived_probe(p, l), has_path(hp), path(pn), pid(pd), flags(f),
5197 target_symbol_seen(false)
5198{
5199 // Make a local-variable-expanded copy of the probe body
5200 utrace_var_expanding_copy_visitor v (s, name, flags);
ba6f838d 5201 require <statement*> (&v, &(this->body), base->body);
935447c8
DS
5202 target_symbol_seen = v.target_symbol_seen;
5203}
5204
5205
5206void
5207utrace_derived_probe::join_group (systemtap_session& s)
5208{
5209 if (! s.utrace_derived_probes)
14cdaa0b 5210 {
935447c8 5211 s.utrace_derived_probes = new utrace_derived_probe_group ();
14cdaa0b 5212 }
935447c8
DS
5213 s.utrace_derived_probes->enroll (this);
5214
5215 task_finder_derived_probe_group::create_session_group (s);
5216}
5217
5218
5219void
5220utrace_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
5221{
5222 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
5223
eff6ac72 5224 if (flags != UDPF_SYSCALL && flags != UDPF_SYSCALL_RETURN)
935447c8
DS
5225 throw semantic_error ("only \"process(PATH_OR_PID).syscall\" and \"process(PATH_OR_PID).syscall.return\" probes support target symbols",
5226 e->tok);
5227
5228 if (e->base_name != "$syscall")
5229 throw semantic_error ("invalid target symbol for utrace probe, $syscall expected",
5230 e->tok);
5231
5232 if (e->components.size() > 0)
5233 {
5234 switch (e->components[0].first)
5235 {
5236 case target_symbol::comp_literal_array_index:
5237 throw semantic_error("utrace target variable '$syscall' may not be used as array",
5238 e->tok);
5239 break;
5240 case target_symbol::comp_struct_member:
5241 throw semantic_error("utrace target variable '$syscall' may not be used as a structure",
5242 e->tok);
5243 break;
5244 default:
5245 throw semantic_error ("invalid use of utrace target variable '$syscall'",
5246 e->tok);
5247 break;
5248 }
5249 }
5250
5251 bool lvalue = is_active_lvalue(e);
5252 if (lvalue)
5253 throw semantic_error("utrace $syscall variable is read-only", e->tok);
5254
5255 // Remember that we've seen a target variable.
5256 target_symbol_seen = true;
5257
14cdaa0b
DS
5258 // We're going to substitute '_stp_arg(0)' for the '$syscall'
5259 // reference.
5260
5261 // First, synthesize the '0' argument. We can't use 'e->tok' as the
5262 // token, since the token's type gets checked during pass 3. So,
5263 // we'll synthesize a new token.
5264 literal_number* arg = new literal_number(0);
5265 token* arg_tok = new token;
5266 arg_tok->type = tok_number;
5267 arg_tok->location = e->tok->location;
5268 arg_tok->content = e->tok->content;
5269 arg->tok = arg_tok;
5270
5271 // Synthesize a functioncall with our argument.
935447c8
DS
5272 functioncall* n = new functioncall;
5273 n->tok = e->tok;
14cdaa0b
DS
5274 n->function = "_stp_arg";
5275 n->args.push_back(arg);
935447c8
DS
5276 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
5277
5278 provide <functioncall*> (this, n);
5279}
5280
5281
5282struct utrace_builder: public derived_probe_builder
5283{
5284 utrace_builder() {}
5285 virtual void build(systemtap_session & sess,
5286 probe * base,
5287 probe_point * location,
5288 std::map<std::string, literal *> const & parameters,
5289 vector<derived_probe *> & finished_results)
5290 {
5291 string path;
5292 int64_t pid;
5293
5294 bool has_path = get_param (parameters, TOK_PROCESS, path);
5295 bool has_pid = get_param (parameters, TOK_PROCESS, pid);
5296 enum utrace_derived_probe_flags flags = UDPF_NONE;
5297 assert (has_path || has_pid);
5298
eff6ac72
DS
5299 if (has_null_param (parameters, TOK_THREAD))
5300 {
5301 if (has_null_param (parameters, TOK_BEGIN))
5302 flags = UDPF_THREAD_BEGIN;
5303 else if (has_null_param (parameters, TOK_END))
5304 flags = UDPF_THREAD_END;
5305 }
12b21830 5306 else if (has_null_param (parameters, TOK_SYSCALL))
935447c8
DS
5307 {
5308 if (has_null_param (parameters, TOK_RETURN))
eff6ac72 5309 flags = UDPF_SYSCALL_RETURN;
935447c8 5310 else
eff6ac72 5311 flags = UDPF_SYSCALL;
935447c8 5312 }
eff6ac72
DS
5313 else if (has_null_param (parameters, TOK_BEGIN))
5314 flags = UDPF_BEGIN;
5315 else if (has_null_param (parameters, TOK_END))
5316 flags = UDPF_END;
935447c8 5317
0744f531
DS
5318 // If we have a path, we need to validate it.
5319 if (has_path)
5320 {
5321 string::size_type start_pos, end_pos;
5322 string component;
5323
5324 // Make sure it starts with '/'.
5325 if (path[0] != '/')
5326 throw semantic_error ("process path must start with a '/'",
5327 location->tok);
5328
5329 start_pos = 1; // get past the initial '/'
5330 while ((end_pos = path.find('/', start_pos)) != string::npos)
5331 {
5332 component = path.substr(start_pos, end_pos - start_pos);
5333 // Make sure it isn't empty.
5334 if (component.size() == 0)
5335 throw semantic_error ("process path component cannot be empty",
5336 location->tok);
5337 // Make sure it isn't relative.
5338 else if (component == "." || component == "..")
5339 throw semantic_error ("process path cannot be relative (and contain '.' or '..')", location->tok);
5340
5341 start_pos = end_pos + 1;
5342 }
5343 component = path.substr(start_pos);
5344 // Make sure it doesn't end with '/'.
5345 if (component.size() == 0)
5346 throw semantic_error ("process path cannot end with a '/'", location->tok);
5347 // Make sure it isn't relative.
5348 else if (component == "." || component == "..")
5349 throw semantic_error ("process path cannot be relative (and contain '.' or '..')", location->tok);
5350 }
5351
935447c8
DS
5352 finished_results.push_back(new utrace_derived_probe(sess, base, location,
5353 has_path, path, pid,
5354 flags));
5355 }
5356};
5357
5358
5359void
5360utrace_derived_probe_group::enroll (utrace_derived_probe* p)
5361{
5362 if (p->has_path)
5363 probes_by_path[p->path].push_back(p);
5364 else
5365 probes_by_pid[p->pid].push_back(p);
5366 num_probes++;
5367 flags_seen[p->flags] = true;
5368
5369 // XXX: multiple exec probes (for instance) for the same path (or
5370 // pid) should all share a utrace report function, and have their
5371 // handlers executed sequentially.
5372}
5373
5374
5375void
5376utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
5377 utrace_derived_probe *p)
5378{
5379 s.op->newline() << "{";
5380 s.op->line() << " .tgt={";
5381
5382 if (p->has_path)
5383 {
5384 s.op->line() << " .pathname=\"" << p->path << "\",";
5385 s.op->line() << " .pid=0,";
5386 }
5387 else
5388 {
5389 s.op->line() << " .pathname=NULL,";
5390 s.op->line() << " .pid=" << p->pid << ",";
5391 }
5392
5393 s.op->line() << " .callback=&_stp_utrace_probe_cb,";
5394 s.op->line() << " },";
5395 s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
5396 s.op->line() << " .ph=&" << p->name << ",";
5397
5398 // Handle flags
5399 switch (p->flags)
5400 {
eff6ac72
DS
5401 // Look in _stp_utrace_probe_cb for description of why quiesce is
5402 // used here.
5403 case UDPF_BEGIN: // process begin
5404 s.op->line() << " .flags=(UDPF_BEGIN),";
5405 s.op->line() << " .ops={ .report_quiesce=stap_utrace_probe_quiesce },";
5406 s.op->line() << " .events=(UTRACE_ACTION_QUIESCE|UTRACE_EVENT(QUIESCE)),";
935447c8 5407 break;
eff6ac72
DS
5408 case UDPF_THREAD_BEGIN: // thread begin
5409 s.op->line() << " .flags=(UDPF_THREAD_BEGIN),";
5410 s.op->line() << " .ops={ .report_quiesce=stap_utrace_probe_quiesce },";
5411 s.op->line() << " .events=(UTRACE_ACTION_QUIESCE|UTRACE_EVENT(QUIESCE)),";
159cb109 5412 break;
eff6ac72
DS
5413
5414 // Notice we're not setting up a .ops/.report_death handler for
5415 // either UDPF_END or UDPF_THREAD_END. Instead, we'll just call
5416 // the probe directly when we get notified.
5417 case UDPF_END: // process end
5418 s.op->line() << " .flags=(UDPF_END),";
935447c8 5419 break;
eff6ac72
DS
5420 case UDPF_THREAD_END: // thread end
5421 s.op->line() << " .flags=(UDPF_THREAD_END),";
5422 break;
5423
5424 // For UDPF_SYSCALL/UDPF_SYSCALL_RETURN probes, the .report_death
5425 // handler isn't strictly necessary. However, it helps to keep
5426 // our attaches/detaches symmetrical.
5427 case UDPF_SYSCALL:
5428 s.op->line() << " .flags=(UDPF_SYSCALL),";
8c392b1a 5429 s.op->line() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
eff6ac72 5430 s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH)),";
935447c8 5431 break;
eff6ac72
DS
5432 case UDPF_SYSCALL_RETURN:
5433 s.op->line() << " .flags=(UDPF_SYSCALL_RETURN),";
8c392b1a 5434 s.op->line() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
eff6ac72 5435 s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH)),";
935447c8
DS
5436 break;
5437 default:
5438 throw semantic_error ("bad utrace probe flag");
5439 break;
5440 }
5441 s.op->line() << " .engine_attached=0,";
5442 s.op->line() << " },";
5443}
5444
5445
5446void
5447utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
5448{
5449 if (probes_by_path.empty() && probes_by_pid.empty())
5450 return;
5451
5452 s.op->newline();
5453 s.op->newline() << "/* ---- utrace probes ---- */";
eff6ac72
DS
5454 s.op->newline() << "enum utrace_derived_probe_flags {";
5455 s.op->indent(1);
5456 s.op->newline() << "UDPF_NONE,";
5457 s.op->newline() << "UDPF_BEGIN,";
5458 s.op->newline() << "UDPF_END,";
5459 s.op->newline() << "UDPF_THREAD_BEGIN,";
5460 s.op->newline() << "UDPF_THREAD_END,";
5461 s.op->newline() << "UDPF_SYSCALL,";
5462 s.op->newline() << "UDPF_SYSCALL_RETURN,";
5463 s.op->newline() << "UDPF_NFLAGS";
5464 s.op->newline(-1) << "};";
5465
935447c8
DS
5466 s.op->newline() << "struct stap_utrace_probe {";
5467 s.op->indent(1);
5468 s.op->newline() << "struct stap_task_finder_target tgt;";
5469 s.op->newline() << "const char *pp;";
5470 s.op->newline() << "void (*ph) (struct context*);";
eff6ac72 5471 s.op->newline() << "enum utrace_derived_probe_flags flags;";
935447c8 5472 s.op->newline() << "struct utrace_engine_ops ops;";
eff6ac72 5473 s.op->newline() << "unsigned long events;";
935447c8
DS
5474 s.op->newline() << "int engine_attached;";
5475 s.op->newline(-1) << "};";
5476
eff6ac72
DS
5477
5478 // Output handler function for UDPF_BEGIN and UDPF_THREAD_BEGIN
5479 if (flags_seen[UDPF_BEGIN] || flags_seen[UDPF_THREAD_BEGIN])
5480 {
5481 s.op->newline() << "static u32 stap_utrace_probe_quiesce(struct utrace_attached_engine *engine, struct task_struct *tsk) {";
5482 s.op->indent(1);
5483 s.op->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;";
5484
5485 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
5486 s.op->newline() << "c->probe_point = p->pp;";
5487
5488 // call probe function
5489 s.op->newline() << "(*p->ph) (c);";
5490 common_probe_entryfn_epilogue (s.op);
5491
5492 // UTRACE_ACTION_NEWSTATE not needed here to clear quiesce since
5493 // we're detaching - utrace automatically restarts the thread.
5494 s.op->newline() << "debug_task_finder_detach();";
5495 s.op->newline() << "return UTRACE_ACTION_DETACH;";
5496 s.op->newline(-1) << "}";
5497 }
5498
5499 // Output handler function for UDPF_END and UDPF_THREAD_END
5500 if (flags_seen[UDPF_END] || flags_seen[UDPF_THREAD_END])
159cb109 5501 {
935447c8
DS
5502 s.op->newline() << "static void stap_utrace_probe_handler(struct task_struct *tsk, struct stap_utrace_probe *p) {";
5503 s.op->indent(1);
5504
5505 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
5506 s.op->newline() << "c->probe_point = p->pp;";
5507
5508 // call probe function
5509 s.op->newline() << "(*p->ph) (c);";
5510 common_probe_entryfn_epilogue (s.op);
5511
5512 s.op->newline() << "return;";
5513 s.op->newline(-1) << "}";
159cb109 5514 }
935447c8
DS
5515
5516 // Output handler function for SYSCALL_ENTRY and SYSCALL_EXIT events
eff6ac72 5517 if (flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
935447c8
DS
5518 {
5519 s.op->newline() << "static u32 stap_utrace_probe_syscall(struct utrace_attached_engine *engine, struct task_struct *tsk, struct pt_regs *regs) {";
5520 s.op->indent(1);
5521 s.op->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;";
5522
5523 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
5524 s.op->newline() << "c->probe_point = p->pp;";
5525 s.op->newline() << "c->regs = regs;";
5526
5527 // call probe function
5528 s.op->newline() << "(*p->ph) (c);";
5529 common_probe_entryfn_epilogue (s.op);
5530
5531 s.op->newline() << "return UTRACE_ACTION_RESUME;";
5532 s.op->newline(-1) << "}";
5533 }
5534
eff6ac72 5535 // Output task_finder callback routine that gets called for all
935447c8 5536 // utrace probe types.
eff6ac72 5537 s.op->newline() << "static int _stp_utrace_probe_cb(struct task_struct *tsk, int register_p, int process_p, struct stap_task_finder_target *tgt) {";
935447c8
DS
5538 s.op->indent(1);
5539 s.op->newline() << "int rc = 0;";
5540 s.op->newline() << "struct stap_utrace_probe *p = container_of(tgt, struct stap_utrace_probe, tgt);";
5541 s.op->newline() << "struct utrace_attached_engine *engine;";
5542
935447c8
DS
5543 s.op->newline() << "if (register_p) {";
5544 s.op->indent(1);
5545
0744f531 5546 s.op->newline() << "switch (p->flags) {";
935447c8 5547 s.op->indent(1);
eff6ac72
DS
5548
5549 // When receiving a UTRACE_EVENT(CLONE) event, we can't call the
5550 // begin/thread.begin probe directly. So, we'll just attach an
5551 // engine that waits for the thread to quiesce. When the thread
5552 // quiesces, then call the probe.
5553 if (flags_seen[UDPF_BEGIN])
5554 {
5555 s.op->newline() << "case UDPF_BEGIN:";
37e24fbe 5556 s.op->indent(1);
eff6ac72 5557 s.op->newline() << "if (process_p) {";
37e24fbe 5558 s.op->indent(1);
eff6ac72
DS
5559 s.op->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
5560 s.op->newline() << "if (rc == 0) {";
5561 s.op->indent(1);
5562 s.op->newline() << "p->engine_attached = 1;";
5563 s.op->newline(-1) << "}";
37e24fbe
DS
5564 s.op->newline(-1) << "}";
5565 s.op->newline() << "break;";
5566 s.op->indent(-1);
eff6ac72
DS
5567 }
5568 if (flags_seen[UDPF_THREAD_BEGIN])
5569 {
5570 s.op->newline() << "case UDPF_THREAD_BEGIN:";
0744f531 5571 s.op->indent(1);
eff6ac72 5572 s.op->newline() << "if (! process_p) {";
cfac4b1f 5573 s.op->indent(1);
eff6ac72
DS
5574 s.op->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
5575 s.op->newline() << "if (rc == 0) {";
5576 s.op->indent(1);
5577 s.op->newline() << "p->engine_attached = 1;";
5578 s.op->newline(-1) << "}";
cfac4b1f 5579 s.op->newline(-1) << "}";
0744f531
DS
5580 s.op->newline() << "break;";
5581 s.op->indent(-1);
eff6ac72
DS
5582 }
5583
5584 // For end/thread_end probes, do nothing at registration time.
5585 // We'll handle these in the 'register_p == 0' case.
5586 if (flags_seen[UDPF_END] || flags_seen[UDPF_THREAD_END])
0744f531 5587 {
eff6ac72
DS
5588 s.op->newline() << "case UDPF_END:";
5589 s.op->newline() << "case UDPF_THREAD_END:";
0744f531
DS
5590 s.op->indent(1);
5591 s.op->newline() << "break;";
5592 s.op->indent(-1);
5593 }
eff6ac72 5594
37e24fbe 5595 // Attach an engine for SYSCALL_ENTRY and SYSCALL_EXIT events.
eff6ac72 5596 if (flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
0744f531 5597 {
eff6ac72
DS
5598 s.op->newline() << "case UDPF_SYSCALL:";
5599 s.op->newline() << "case UDPF_SYSCALL_RETURN:";
0744f531 5600 s.op->indent(1);
eff6ac72
DS
5601 s.op->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
5602 s.op->newline() << "if (rc == 0) {";
0744f531 5603 s.op->indent(1);
0744f531
DS
5604 s.op->newline() << "p->engine_attached = 1;";
5605 s.op->newline(-1) << "}";
5606 s.op->newline() << "break;";
5607 s.op->indent(-1);
5608 }
eff6ac72
DS
5609
5610 s.op->newline() << "default:";
5611 s.op->indent(1);
5612 s.op->newline() << "_stp_error(\"unhandled flag value %d at %s:%d\", p->flags, __FUNCTION__, __LINE__);";
5613 s.op->newline() << "break;";
5614 s.op->indent(-1);
935447c8
DS
5615 s.op->newline(-1) << "}";
5616 s.op->newline(-1) << "}";
eff6ac72 5617
935447c8 5618 // Since this engine could be attached to multiple threads, don't
eff6ac72 5619 // call stap_utrace_detach_ops() here.
0744f531 5620 s.op->newline() << "else {";
935447c8 5621 s.op->indent(1);
37e24fbe
DS
5622 s.op->newline() << "switch (p->flags) {";
5623 s.op->indent(1);
0744f531 5624 // For death probes, go ahead and call the probe directly.
eff6ac72 5625 if (flags_seen[UDPF_END])
0744f531 5626 {
eff6ac72 5627 s.op->newline() << "case UDPF_END:";
37e24fbe 5628 s.op->indent(1);
eff6ac72 5629 s.op->newline() << "if (process_p) {";
0744f531 5630 s.op->indent(1);
0744f531
DS
5631 s.op->newline() << "stap_utrace_probe_handler(tsk, p);";
5632 s.op->newline(-1) << "}";
37e24fbe
DS
5633 s.op->newline() << "break;";
5634 s.op->indent(-1);
0744f531 5635 }
eff6ac72 5636 if (flags_seen[UDPF_THREAD_END])
37e24fbe 5637 {
eff6ac72 5638 s.op->newline() << "case UDPF_THREAD_END:";
37e24fbe 5639 s.op->indent(1);
eff6ac72
DS
5640 s.op->newline() << "if (! process_p) {";
5641 s.op->indent(1);
5642 s.op->newline() << "stap_utrace_probe_handler(tsk, p);";
5643 s.op->newline(-1) << "}";
5644 s.op->newline() << "break;";
5645 s.op->indent(-1);
5646 }
5647
5648 // For begin/thread_begin probes, at deregistration time we'll try
5649 // to detach. This will only be necessary if the new thread/process
5650 // got killed before the probe got run in the UTRACE_EVENT(QUIESCE)
5651 // handler.
5652 if (flags_seen[UDPF_BEGIN] || flags_seen[UDPF_THREAD_BEGIN]
5653 || flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
5654 {
5655 s.op->newline() << "case UDPF_BEGIN:";
5656 s.op->newline() << "case UDPF_THREAD_BEGIN:";
5657 s.op->newline() << "case UDPF_SYSCALL:";
5658 s.op->newline() << "case UDPF_SYSCALL_RETURN:";
37e24fbe
DS
5659 s.op->indent(1);
5660 s.op->newline() << "engine = utrace_attach(tsk, UTRACE_ATTACH_MATCH_OPS, &p->ops, 0);";
5661 s.op->newline() << "if (! IS_ERR(engine) && engine != NULL) {";
5662 s.op->indent(1);
5663 s.op->newline() << "utrace_detach(tsk, engine);";
eff6ac72
DS
5664 s.op->newline() << "debug_task_finder_detach();";
5665
37e24fbe
DS
5666 s.op->newline(-1) << "}";
5667 s.op->newline() << "break;";
5668 s.op->indent(-1);
5669 }
eff6ac72
DS
5670
5671 s.op->newline() << "default:";
5672 s.op->indent(1);
5673 s.op->newline() << "_stp_error(\"unhandled flag value %d at %s:%d\", p->flags, __FUNCTION__, __LINE__);";
5674 s.op->newline() << "break;";
5675 s.op->indent(-1);
37e24fbe 5676 s.op->newline(-1) << "}";
935447c8
DS
5677 s.op->newline(-1) << "}";
5678 s.op->newline() << "return rc;";
5679 s.op->newline(-1) << "}";
5680
5681 s.op->newline() << "struct stap_utrace_probe stap_utrace_probes[] = {";
5682 s.op->indent(1);
5683
5684 // Set up 'process(PATH)' probes
5685 if (! probes_by_path.empty())
5686 {
5687 for (p_b_path_iterator it = probes_by_path.begin();
5688 it != probes_by_path.end(); it++)
5689 {
5690 for (unsigned i = 0; i < it->second.size(); i++)
5691 {
5692 utrace_derived_probe *p = it->second[i];
5693 emit_probe_decl(s, p);
5694 }
5695 }
5696 }
5697
5698 // Set up 'process(PID)' probes
5699 if (! probes_by_pid.empty())
5700 {
5701 for (p_b_pid_iterator it = probes_by_pid.begin();
5702 it != probes_by_pid.end(); it++)
5703 {
5704 for (unsigned i = 0; i < it->second.size(); i++)
5705 {
5706 utrace_derived_probe *p = it->second[i];
5707 emit_probe_decl(s, p);
5708 }
5709 }
5710 }
5711 s.op->newline(-1) << "};";
5712}
5713
5714
5715void
5716utrace_derived_probe_group::emit_module_init (systemtap_session& s)
5717{
5718 if (probes_by_path.empty() && probes_by_pid.empty())
5719 return;
5720
5721 s.op->newline();
5722 s.op->newline() << "/* ---- utrace probes ---- */";
5723
5724 s.op->newline() << "for (i=0; i<" << num_probes << "; i++) {";
5725 s.op->indent(1);
5726 s.op->newline() << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
5727 s.op->newline() << "rc = stap_register_task_finder_target(&p->tgt);";
5728 s.op->newline(-1) << "}";
5729
5730 // rollback all utrace probes
5731 s.op->newline() << "if (rc) {";
5732 s.op->indent(1);
5733 s.op->newline() << "for (j=i-1; j>=0; j--) {";
5734 s.op->indent(1);
5735 s.op->newline() << "struct stap_utrace_probe *p = &stap_utrace_probes[j];";
5736
5737 s.op->newline() << "if (p->engine_attached) {";
5738 s.op->indent(1);
5739 s.op->newline() << "stap_utrace_detach_ops(&p->ops);";
5740 s.op->newline(-1) << "}";
5741 s.op->newline(-1) << "}";
5742
5743 s.op->newline(-1) << "}";
5744}
5745
5746
5747void
5748utrace_derived_probe_group::emit_module_exit (systemtap_session& s)
5749{
5750 if (probes_by_path.empty() && probes_by_pid.empty()) return;
5751
5752 s.op->newline();
5753 s.op->newline() << "/* ---- utrace probes ---- */";
5754 s.op->newline() << "for (i=0; i<" << num_probes << "; i++) {";
5755 s.op->indent(1);
5756 s.op->newline() << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
5757
5758 s.op->newline() << "if (p->engine_attached) {";
5759 s.op->indent(1);
5760 s.op->newline() << "stap_utrace_detach_ops(&p->ops);";
5761 s.op->newline(-1) << "}";
5762 s.op->newline(-1) << "}";
5763}
5764
5765
888af770
FCE
5766// ------------------------------------------------------------------------
5767// user-space probes
5768// ------------------------------------------------------------------------
5769
5770struct uprobe_derived_probe: public derived_probe
5771{
5772 uint64_t process, address;
5773 bool return_p;
5774 uprobe_derived_probe (systemtap_session &s, probe* p, probe_point* l,
5775 uint64_t, uint64_t, bool);
5776 void join_group (systemtap_session& s);
5777};
5778
5779
5780struct uprobe_derived_probe_group: public generic_dpg<uprobe_derived_probe>
5781{
5782public:
5783 void emit_module_decls (systemtap_session& s);
5784 void emit_module_init (systemtap_session& s);
5785 void emit_module_exit (systemtap_session& s);
5786};
5787
5788
4baf0e53 5789uprobe_derived_probe::uprobe_derived_probe (systemtap_session &s,
888af770
FCE
5790 probe* p, probe_point* l,
5791 uint64_t pp, uint64_t aa, bool rr):
5792 derived_probe(p, l), process(pp), address(aa), return_p (rr)
4baf0e53 5793{
6274464e 5794 s.need_uprobes = true;
888af770
FCE
5795}
5796
5797
5798void
5799uprobe_derived_probe::join_group (systemtap_session& s)
5800{
5801 if (! s.uprobe_derived_probes)
5802 s.uprobe_derived_probes = new uprobe_derived_probe_group ();
5803 s.uprobe_derived_probes->enroll (this);
5804}
5805
5806
5807struct uprobe_builder: public derived_probe_builder
5808{
5809 uprobe_builder() {}
5810 virtual void build(systemtap_session & sess,
5811 probe * base,
5812 probe_point * location,
5813 std::map<std::string, literal *> const & parameters,
5814 vector<derived_probe *> & finished_results)
5815 {
5816 int64_t process, address;
5817
5818 bool b1 = get_param (parameters, TOK_PROCESS, process);
ced347a9 5819 (void) b1;
888af770 5820 bool b2 = get_param (parameters, TOK_STATEMENT, address);
ced347a9 5821 (void) b2;
888af770
FCE
5822 bool rr = has_null_param (parameters, TOK_RETURN);
5823 assert (b1 && b2); // by pattern_root construction
4baf0e53 5824
888af770
FCE
5825 finished_results.push_back(new uprobe_derived_probe(sess, base, location,
5826 process, address, rr));
5827 }
5828};
5829
5830
5831void
775d51e5 5832uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
888af770
FCE
5833{
5834 if (probes.empty()) return;
775d51e5 5835 s.op->newline() << "/* ---- user probes ---- */";
4baf0e53 5836
c480bf3d 5837 // If uprobes isn't in the kernel, pull it in from the runtime.
6274464e 5838 s.op->newline() << "#if defined(CONFIG_UPROBES) || defined(CONFIG_UPROBES_MODULE)";
888af770 5839 s.op->newline() << "#include <linux/uprobes.h>";
c480bf3d 5840 s.op->newline() << "#else";
6274464e 5841 s.op->newline() << "#include \"uprobes/uprobes.h\"";
c480bf3d 5842 s.op->newline() << "#endif";
888af770
FCE
5843
5844 s.op->newline() << "struct stap_uprobe {";
5845 s.op->newline(1) << "union { struct uprobe up; struct uretprobe urp; };";
5846 s.op->newline() << "unsigned registered_p:1;";
5847 s.op->newline() << "unsigned return_p:1;";
5848 s.op->newline() << "unsigned long process;";
5849 s.op->newline() << "unsigned long address;";
5850 s.op->newline() << "const char *pp;";
5851 s.op->newline() << "void (*ph) (struct context*);";
5852 s.op->newline(-1) << "} stap_uprobes [] = {";
5853 s.op->indent(1);
5854 for (unsigned i =0; i<probes.size(); i++)
5855 {
5856 uprobe_derived_probe* p = probes[i];
5857 s.op->newline() << "{";
5858 s.op->line() << " .address=0x" << hex << p->address << dec << "UL,";
5859 s.op->line() << " .process=" << p->process << ",";
5860 s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
5861 s.op->line() << " .ph=&" << p->name << ",";
5862 if (p->return_p) s.op->line() << " .return_p=1,";
5863 s.op->line() << " },";
5864 }
5865 s.op->newline(-1) << "};";
5866
5867 s.op->newline();
5868 s.op->newline() << "void enter_uprobe_probe (struct uprobe *inst, struct pt_regs *regs) {";
5869 s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst, struct stap_uprobe, up);";
5870 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
5871 s.op->newline() << "c->probe_point = sup->pp;";
5872 s.op->newline() << "c->regs = regs;";
5873 s.op->newline() << "(*sup->ph) (c);";
5874 common_probe_entryfn_epilogue (s.op);
5875 s.op->newline(-1) << "}";
5876
5877 s.op->newline() << "void enter_uretprobe_probe (struct uretprobe_instance *inst, struct pt_regs *regs) {";
5878 s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst->rp, struct stap_uprobe, urp);";
5879 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
5880 s.op->newline() << "c->probe_point = sup->pp;";
5881 // XXX: kretprobes saves "c->pi = inst;" too
5882 s.op->newline() << "c->regs = regs;";
5883 s.op->newline() << "(*sup->ph) (c);";
5884 common_probe_entryfn_epilogue (s.op);
5885 s.op->newline(-1) << "}";
5886}
5887
5888
5889void
5890uprobe_derived_probe_group::emit_module_init (systemtap_session& s)
5891{
5892 if (probes.empty()) return;
5893 s.op->newline() << "/* ---- user probes ---- */";
5894
5895 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
5896 s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
5897 s.op->newline() << "probe_point = sup->pp;";
5898 s.op->newline() << "if (sup->return_p) {";
5899 s.op->newline(1) << "sup->urp.u.pid = sup->process;";
5900 s.op->newline() << "sup->urp.u.vaddr = sup->address;";
5901 s.op->newline() << "sup->urp.handler = &enter_uretprobe_probe;";
5902 s.op->newline() << "rc = register_uretprobe (& sup->urp);";
5903 s.op->newline(-1) << "} else {";
5904 s.op->newline(1) << "sup->up.pid = sup->process;";
5905 s.op->newline() << "sup->up.vaddr = sup->address;";
5906 s.op->newline() << "sup->up.handler = &enter_uprobe_probe;";
5907 s.op->newline() << "rc = register_uprobe (& sup->up);";
5908 s.op->newline(-1) << "}";
5909 s.op->newline() << "if (rc) {";
5910 s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
5911 s.op->newline(1) << "struct stap_uprobe *sup2 = & stap_uprobes[j];";
5912 s.op->newline() << "if (sup2->return_p) unregister_uretprobe (&sup2->urp);";
5913 s.op->newline() << "else unregister_uprobe (&sup2->up);";
5914 // NB: we don't have to clear sup2->registered_p, since the module_exit code is
5915 // not run for this early-abort case.
5916 s.op->newline(-1) << "}";
5917 s.op->newline() << "break;"; // don't attempt to register any more probes
5918 s.op->newline(-1) << "}";
5919 s.op->newline() << "else sup->registered_p = 1;";
5920 s.op->newline(-1) << "}";
5921}
5922
5923
5924void
5925uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
5926{
5927 if (probes.empty()) return;
5928 s.op->newline() << "/* ---- user probes ---- */";
5929
5930 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
5931 s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
5932 s.op->newline() << "if (! sup->registered_p) continue;";
5933 // s.op->newline() << "atomic_add (sdp->u.krp.nmissed, & skipped_count);";
5934 // s.op->newline() << "atomic_add (sdp->u.krp.kp.nmissed, & skipped_count);";
5935 s.op->newline() << "if (sup->return_p) unregister_uretprobe (&sup->urp);";
5936 s.op->newline() << "else unregister_uprobe (&sup->up);";
5937 s.op->newline() << "sup->registered_p = 0;";
5938 s.op->newline(-1) << "}";
5939}
5940
5941
5942
98afd80e
FCE
5943// ------------------------------------------------------------------------
5944// timer derived probes
5945// ------------------------------------------------------------------------
5946
5947
12b21830
DS
5948static string TOK_TIMER("timer");
5949
98afd80e
FCE
5950struct timer_derived_probe: public derived_probe
5951{
5952 int64_t interval, randomize;
b20febf3 5953 bool time_is_msecs; // NB: hrtimers get ms-based probes on modern kernels instead
422d1ceb 5954 timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r, bool ms=false);
b20febf3
FCE
5955 virtual void join_group (systemtap_session& s);
5956};
98afd80e 5957
dc38c0ae 5958
b20febf3
FCE
5959struct timer_derived_probe_group: public generic_dpg<timer_derived_probe>
5960{
d006ef4f 5961 void emit_interval (translator_output* o);
b20febf3
FCE
5962public:
5963 void emit_module_decls (systemtap_session& s);
5964 void emit_module_init (systemtap_session& s);
5965 void emit_module_exit (systemtap_session& s);
98afd80e
FCE
5966};
5967
5968
422d1ceb
FCE
5969timer_derived_probe::timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r, bool ms):
5970 derived_probe (p, l), interval (i), randomize (r), time_is_msecs(ms)
98afd80e
FCE
5971{
5972 if (interval <= 0 || interval > 1000000) // make i and r fit into plain ints
5973 throw semantic_error ("invalid interval for jiffies timer");
5974 // randomize = 0 means no randomization
5975 if (randomize < 0 || randomize > interval)
5976 throw semantic_error ("invalid randomize for jiffies timer");
5977
5978 if (locations.size() != 1)
5979 throw semantic_error ("expect single probe point");
5980 // so we don't have to loop over them in the other functions
5981}
5982
5983
dc38c0ae 5984void
b20febf3 5985timer_derived_probe::join_group (systemtap_session& s)
dc38c0ae 5986{
b20febf3
FCE
5987 if (! s.timer_derived_probes)
5988 s.timer_derived_probes = new timer_derived_probe_group ();
5989 s.timer_derived_probes->enroll (this);
dc38c0ae
DS
5990}
5991
5992
d006ef4f
JS
5993void
5994timer_derived_probe_group::emit_interval (translator_output* o)
5995{
5996 o->line() << "({";
5997 o->newline(1) << "unsigned i = stp->intrv;";
5998 o->newline() << "if (stp->rnd != 0)";
5999 o->newline(1) << "i += _stp_random_pm(stp->rnd);";
6000 o->newline(-1) << "stp->ms ? msecs_to_jiffies(i) : i;";
6001 o->newline(-1) << "})";
6002}
6003
6004
98afd80e 6005void
b20febf3 6006timer_derived_probe_group::emit_module_decls (systemtap_session& s)
98afd80e 6007{
b20febf3 6008 if (probes.empty()) return;
46b84a80 6009
b20febf3 6010 s.op->newline() << "/* ---- timer probes ---- */";
46b84a80 6011
b20febf3
FCE
6012 s.op->newline() << "struct stap_timer_probe {";
6013 s.op->newline(1) << "struct timer_list timer_list;";
6014 s.op->newline() << "const char *pp;";
6015 s.op->newline() << "void (*ph) (struct context*);";
6016 s.op->newline() << "unsigned intrv, ms, rnd;";
6017 s.op->newline(-1) << "} stap_timer_probes [" << probes.size() << "] = {";
6018 s.op->indent(1);
6019 for (unsigned i=0; i < probes.size(); i++)
6020 {
4baf0e53
RM
6021 s.op->newline () << "{";
6022 s.op->line() << " .pp="
b20febf3
FCE
6023 << lex_cast_qstring (*probes[i]->sole_location()) << ",";
6024 s.op->line() << " .ph=&" << probes[i]->name << ",";
6025 s.op->line() << " .intrv=" << probes[i]->interval << ",";
6026 s.op->line() << " .ms=" << probes[i]->time_is_msecs << ",";
6027 s.op->line() << " .rnd=" << probes[i]->randomize;
6028 s.op->line() << " },";
6029 }
6030 s.op->newline(-1) << "};";
6031 s.op->newline();
98afd80e 6032
b20febf3
FCE
6033 s.op->newline() << "static void enter_timer_probe (unsigned long val) {";
6034 s.op->newline(1) << "struct stap_timer_probe* stp = & stap_timer_probes [val];";
e0d86324
JS
6035 s.op->newline() << "if ((atomic_read (&session_state) == STAP_SESSION_STARTING) ||";
6036 s.op->newline() << " (atomic_read (&session_state) == STAP_SESSION_RUNNING))";
6037 s.op->newline(1) << "mod_timer (& stp->timer_list, jiffies + ";
d006ef4f
JS
6038 emit_interval (s.op);
6039 s.op->line() << ");";
e0d86324
JS
6040 s.op->newline(-1) << "{";
6041 s.op->indent(1);
6042 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
6043 s.op->newline() << "c->probe_point = stp->pp;";
b20febf3
FCE
6044 s.op->newline() << "(*stp->ph) (c);";
6045 common_probe_entryfn_epilogue (s.op);
6046 s.op->newline(-1) << "}";
e0d86324 6047 s.op->newline(-1) << "}";
98afd80e
FCE
6048}
6049
6050
6051void
b20febf3 6052timer_derived_probe_group::emit_module_init (systemtap_session& s)
dc38c0ae 6053{
b20febf3 6054 if (probes.empty()) return;
dc38c0ae 6055
b20febf3
FCE
6056 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
6057 s.op->newline(1) << "struct stap_timer_probe* stp = & stap_timer_probes [i];";
6f313a73 6058 s.op->newline() << "probe_point = stp->pp;";
b20febf3
FCE
6059 s.op->newline() << "init_timer (& stp->timer_list);";
6060 s.op->newline() << "stp->timer_list.function = & enter_timer_probe;";
6061 s.op->newline() << "stp->timer_list.data = i;"; // NB: important!
6062 // copy timer renew calculations from above :-(
d006ef4f
JS
6063 s.op->newline() << "stp->timer_list.expires = jiffies + ";
6064 emit_interval (s.op);
6065 s.op->line() << ";";
6066 s.op->newline() << "add_timer (& stp->timer_list);";
b20febf3
FCE
6067 // note: no partial failure rollback is needed: add_timer cannot fail.
6068 s.op->newline(-1) << "}"; // for loop
dc38c0ae
DS
6069}
6070
6071
46b84a80 6072void
b20febf3 6073timer_derived_probe_group::emit_module_exit (systemtap_session& s)
46b84a80 6074{
b20febf3 6075 if (probes.empty()) return;
46b84a80 6076
b20febf3
FCE
6077 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)";
6078 s.op->newline(1) << "del_timer_sync (& stap_timer_probes[i].timer_list);";
6079 s.op->indent(-1);
46b84a80
DS
6080}
6081
6082
b20febf3 6083
39e57ce0
FCE
6084// ------------------------------------------------------------------------
6085// profile derived probes
6086// ------------------------------------------------------------------------
6087// On kernels < 2.6.10, this uses the register_profile_notifier API to
6088// generate the timed events for profiling; on kernels >= 2.6.10 this
6089// uses the register_timer_hook API. The latter doesn't currently allow
6090// simultaneous users, so insertion will fail if the profiler is busy.
6091// (Conflicting users may include OProfile, other SystemTap probes, etc.)
6092
6093
6094struct profile_derived_probe: public derived_probe
6095{
6dce2125 6096 profile_derived_probe (systemtap_session &s, probe* p, probe_point* l);
b20febf3
FCE
6097 void join_group (systemtap_session& s);
6098};
39e57ce0 6099
dc38c0ae 6100
b20febf3
FCE
6101struct profile_derived_probe_group: public generic_dpg<profile_derived_probe>
6102{
6103public:
6104 void emit_module_decls (systemtap_session& s);
6105 void emit_module_init (systemtap_session& s);
6106 void emit_module_exit (systemtap_session& s);
39e57ce0
FCE
6107};
6108
6109
78f6bba6 6110profile_derived_probe::profile_derived_probe (systemtap_session &, probe* p, probe_point* l):
6dce2125 6111 derived_probe(p, l)
4baf0e53 6112{
39e57ce0
FCE
6113}
6114
6115
dc38c0ae 6116void
b20febf3 6117profile_derived_probe::join_group (systemtap_session& s)
dc38c0ae 6118{
b20febf3
FCE
6119 if (! s.profile_derived_probes)
6120 s.profile_derived_probes = new profile_derived_probe_group ();
6121 s.profile_derived_probes->enroll (this);
dc38c0ae
DS
6122}
6123
6124
b20febf3 6125struct profile_builder: public derived_probe_builder
39e57ce0 6126{
b20febf3
FCE
6127 profile_builder() {}
6128 virtual void build(systemtap_session & sess,
6129 probe * base,
6130 probe_point * location,
78f6bba6 6131 std::map<std::string, literal *> const &,
b20febf3
FCE
6132 vector<derived_probe *> & finished_results)
6133 {
6134 finished_results.push_back(new profile_derived_probe(sess, base, location));
6135 }
6136};
46b84a80 6137
39e57ce0 6138
b20febf3
FCE
6139// timer.profile probe handlers are hooked up in an entertaining way
6140// to the underlying kernel facility. The fact that 2.6.11+ era
6141// "register_timer_hook" API allows only one consumer *system-wide*
6142// will give a hint. We will have a single entry function (and thus
6143// trivial registration / unregistration), and it will call all probe
6144// handler functions in sequence.
39e57ce0 6145
6dce2125 6146void
b20febf3 6147profile_derived_probe_group::emit_module_decls (systemtap_session& s)
6dce2125 6148{
b20febf3 6149 if (probes.empty()) return;
39e57ce0 6150
b20febf3
FCE
6151 // kernels < 2.6.10: use register_profile_notifier API
6152 // kernels >= 2.6.10: use register_timer_hook API
6153 s.op->newline() << "/* ---- profile probes ---- */";
39e57ce0 6154
b20febf3
FCE
6155 // This function calls all the profiling probe handlers in sequence.
6156 // The only tricky thing is that the context will be reused amongst
6157 // them. While a simple sequence of calls to the individual probe
6158 // handlers is unlikely to go terribly wrong (with c->last_error
6159 // being set causing an early return), but for extra assurance, we
6160 // open-code the same logic here.
39e57ce0 6161
b20febf3
FCE
6162 s.op->newline() << "static void enter_all_profile_probes (struct pt_regs *regs) {";
6163 s.op->indent(1);
6164 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
6165 s.op->newline() << "c->probe_point = \"timer.profile\";"; // NB: hard-coded for convenience
29b0069b 6166 s.op->newline() << "c->regs = regs;";
39e57ce0 6167
b20febf3
FCE
6168 for (unsigned i=0; i<probes.size(); i++)
6169 {
6170 if (i > 0)
6171 {
4baf0e53 6172 // Some lightweight inter-probe context resetting
6f313a73 6173 // XXX: not quite right: MAXERRORS not respected
29fdb4e4 6174 s.op->newline() << "c->actionremaining = MAXACTION;";
b20febf3
FCE
6175 }
6176 s.op->newline() << "if (c->last_error == NULL) " << probes[i]->name << " (c);";
6177 }
6178 common_probe_entryfn_epilogue (s.op);
6179 s.op->newline(-1) << "}";
6180
6181 s.op->newline() << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)"; // == using_rpn of yore
6182
6183 s.op->newline() << "int enter_profile_probes (struct notifier_block *self,"
6184 << " unsigned long val, void *data) {";
6185 s.op->newline(1) << "(void) self; (void) val;";
6186 s.op->newline() << "enter_all_profile_probes ((struct pt_regs *) data);";
6187 s.op->newline() << "return 0;";
6188 s.op->newline(-1) << "}";
6189 s.op->newline() << "struct notifier_block stap_profile_notifier = {"
6190 << " .notifier_call = & enter_profile_probes };";
4baf0e53 6191
b20febf3 6192 s.op->newline() << "#else";
6dce2125 6193
b20febf3
FCE
6194 s.op->newline() << "int enter_profile_probes (struct pt_regs *regs) {";
6195 s.op->newline(1) << "enter_all_profile_probes (regs);";
6196 s.op->newline() << "return 0;";
6197 s.op->newline(-1) << "}";
39e57ce0 6198
b20febf3 6199 s.op->newline() << "#endif";
39e57ce0
FCE
6200}
6201
6202
dc38c0ae 6203void
b20febf3 6204profile_derived_probe_group::emit_module_init (systemtap_session& s)
dc38c0ae 6205{
b20febf3
FCE
6206 if (probes.empty()) return;
6207
6f313a73 6208 s.op->newline() << "probe_point = \"timer.profile\";"; // NB: hard-coded for convenience
b20febf3
FCE
6209 s.op->newline() << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)"; // == using_rpn of yore
6210 s.op->newline() << "rc = register_profile_notifier (& stap_profile_notifier);";
6211 s.op->newline() << "#else";
6212 s.op->newline() << "rc = register_timer_hook (& enter_profile_probes);";
6213 s.op->newline() << "#endif";
dc38c0ae
DS
6214}
6215
6216
46b84a80 6217void
b20febf3 6218profile_derived_probe_group::emit_module_exit (systemtap_session& s)
46b84a80 6219{
b20febf3 6220 if (probes.empty()) return;
46b84a80 6221
b20febf3
FCE
6222 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)";
6223 s.op->newline(1) << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)"; // == using_rpn of yore
6224 s.op->newline() << "unregister_profile_notifier (& stap_profile_notifier);";
6225 s.op->newline() << "#else";
6226 s.op->newline() << "unregister_timer_hook (& enter_profile_probes);";
6227 s.op->newline() << "#endif";
6228 s.op->indent(-1);
46b84a80
DS
6229}
6230
ce82316f 6231
342d3f96 6232
604eef3b
MH
6233// ------------------------------------------------------------------------
6234// procfs file derived probes
6235// ------------------------------------------------------------------------
6236
ce82316f 6237
12b21830
DS
6238static string TOK_PROCFS("procfs");
6239static string TOK_READ("read");
6240static string TOK_WRITE("write");
6241
604eef3b
MH
6242struct procfs_derived_probe: public derived_probe
6243{
6244 string path;
6245 bool write;
87ebf4cb
DS
6246 bool target_symbol_seen;
6247
604eef3b
MH
6248 procfs_derived_probe (systemtap_session &, probe* p, probe_point* l, string ps, bool w);
6249 void join_group (systemtap_session& s);
6250};
6251
6252
87ebf4cb
DS
6253struct procfs_probe_set
6254{
6255 procfs_derived_probe* read_probe;
6256 procfs_derived_probe* write_probe;
6257
6258 procfs_probe_set () : read_probe (NULL), write_probe (NULL) {}
6259};
6260
6261
604eef3b
MH
6262struct procfs_derived_probe_group: public generic_dpg<procfs_derived_probe>
6263{
87ebf4cb
DS
6264private:
6265 map<string, procfs_probe_set*> probes_by_path;
6266 typedef map<string, procfs_probe_set*>::iterator p_b_p_iterator;
6267 bool has_read_probes;
6268 bool has_write_probes;
6269
604eef3b 6270public:
87ebf4cb
DS
6271 procfs_derived_probe_group () :
6272 has_read_probes(false), has_write_probes(false) {}
6273
6274 void enroll (procfs_derived_probe* probe);
604eef3b
MH
6275 void emit_module_decls (systemtap_session& s);
6276 void emit_module_init (systemtap_session& s);
6277 void emit_module_exit (systemtap_session& s);
6278};
6279
6280
87ebf4cb
DS
6281struct procfs_var_expanding_copy_visitor: public var_expanding_copy_visitor
6282{
6283 procfs_var_expanding_copy_visitor(systemtap_session& s, const string& pn,
6284 string path, bool write_probe):
6285 sess (s), probe_name (pn), path (path), write_probe (write_probe),
6286 target_symbol_seen (false) {}
6287
6288 systemtap_session& sess;
6289 string probe_name;
6290 string path;
6291 bool write_probe;
6292 bool target_symbol_seen;
6293
6294 void visit_target_symbol (target_symbol* e);
6295};
6296
6297
6298procfs_derived_probe::procfs_derived_probe (systemtap_session &s, probe* p,
6299 probe_point* l, string ps, bool w):
6300 derived_probe(p, l), path(ps), write(w), target_symbol_seen(false)
604eef3b 6301{
87ebf4cb
DS
6302 // Make a local-variable-expanded copy of the probe body
6303 procfs_var_expanding_copy_visitor v (s, name, path, write);
ba6f838d 6304 require <statement*> (&v, &(this->body), base->body);
87ebf4cb 6305 target_symbol_seen = v.target_symbol_seen;
604eef3b
MH
6306}
6307
6308
6309void
6310procfs_derived_probe::join_group (systemtap_session& s)
6311{
6312 if (! s.procfs_derived_probes)
6313 s.procfs_derived_probes = new procfs_derived_probe_group ();
6314 s.procfs_derived_probes->enroll (this);
6315}
6316
ce82316f 6317
604eef3b 6318void
87ebf4cb 6319procfs_derived_probe_group::enroll (procfs_derived_probe* p)
604eef3b 6320{
87ebf4cb 6321 procfs_probe_set *pset;
ce82316f 6322
87ebf4cb
DS
6323 if (probes_by_path.count(p->path) == 0)
6324 {
6325 pset = new procfs_probe_set;
6326 probes_by_path[p->path] = pset;
6327 }
6328 else
6329 {
6330 pset = probes_by_path[p->path];
6331
6332 // You can only specify 1 read and 1 write probe.
6333 if (p->write && pset->write_probe != NULL)
6334 throw semantic_error("only one write procfs probe can exist for procfs path \"" + p->path + "\"");
6335 else if (! p->write && pset->read_probe != NULL)
6336 throw semantic_error("only one read procfs probe can exist for procfs path \"" + p->path + "\"");
5d23847d
FCE
6337
6338 // XXX: multiple writes should be acceptable
87ebf4cb
DS
6339 }
6340
6341 if (p->write)
6342 {
6343 pset->write_probe = p;
6344 has_write_probes = true;
6345 }
6346 else
6347 {
6348 pset->read_probe = p;
6349 has_read_probes = true;
6350 }
604eef3b
MH
6351}
6352
ce82316f 6353
604eef3b 6354void
87ebf4cb 6355procfs_derived_probe_group::emit_module_decls (systemtap_session& s)
604eef3b 6356{
87ebf4cb 6357 if (probes_by_path.empty())
ce82316f 6358 return;
604eef3b 6359
87ebf4cb
DS
6360 s.op->newline() << "/* ---- procfs probes ---- */";
6361
6362 // Emit the procfs probe data list
6363 s.op->newline() << "struct stap_procfs_probe {";
6364 s.op->newline(1)<< "const char *path;";
6365 s.op->newline() << "const char *read_pp;";
6366 s.op->newline() << "void (*read_ph) (struct context*);";
6367 s.op->newline() << "const char *write_pp;";
6368 s.op->newline() << "void (*write_ph) (struct context*);";
6369 s.op->newline(-1) << "} stap_procfs_probes[] = {";
6370 s.op->indent(1);
6371
6372 for (p_b_p_iterator it = probes_by_path.begin(); it != probes_by_path.end();
6373 it++)
6374 {
6375 procfs_probe_set *pset = it->second;
6376
6377 s.op->newline() << "{";
6378 s.op->line() << " .path=" << lex_cast_qstring (it->first) << ",";
6379
6380 if (pset->read_probe != NULL)
6381 {
6382 s.op->line() << " .read_pp="
6383 << lex_cast_qstring (*pset->read_probe->sole_location())
6384 << ",";
6385 s.op->line() << " .read_ph=&" << pset->read_probe->name << ",";
6386 }
6387 else
ce82316f 6388 {
87ebf4cb
DS
6389 s.op->line() << " .read_pp=NULL,";
6390 s.op->line() << " .read_ph=NULL,";
604eef3b 6391 }
ce82316f 6392
87ebf4cb
DS
6393 if (pset->write_probe != NULL)
6394 {
6395 s.op->line() << " .write_pp="
6396 << lex_cast_qstring (*pset->write_probe->sole_location())
6397 << ",";
6398 s.op->line() << " .write_ph=&" << pset->write_probe->name;
6399 }
ce82316f 6400 else
87ebf4cb
DS
6401 {
6402 s.op->line() << " .write_pp=NULL,";
6403 s.op->line() << " .write_ph=NULL";
6404 }
6405 s.op->line() << " },";
6406 }
6407 s.op->newline(-1) << "};";
6408
6409 if (has_read_probes)
6410 {
6411 // Output routine to fill in 'page' with our data.
6412 s.op->newline();
6413
6414 s.op->newline() << "static int _stp_procfs_read(char *page, char **start, off_t off, int count, int *eof, void *data) {";
6415
6416 s.op->newline(1) << "struct stap_procfs_probe *spp = (struct stap_procfs_probe *)data;";
6417 s.op->newline() << "int bytes = 0;";
6418 s.op->newline() << "string_t strdata = {'\\0'};";
6419
87ebf4cb 6420 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
87ebf4cb
DS
6421 s.op->newline() << "c->probe_point = spp->read_pp;";
6422
6423 s.op->newline() << "if (c->data == NULL)";
6424 s.op->newline(1) << "c->data = &strdata;";
007f0f1c
DS
6425 s.op->newline(-1) << "else {";
6426
6427 s.op->newline(1) << "if (unlikely (atomic_inc_return (& skipped_count) > MAXSKIPPED)) {";
6428 s.op->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
6429 s.op->newline() << "_stp_exit ();";
6430 s.op->newline(-1) << "}";
6431 s.op->newline() << "atomic_dec (& c->busy);";
6432 s.op->newline() << "goto probe_epilogue;";
6433 s.op->newline(-1) << "}";
87ebf4cb
DS
6434
6435 // call probe function (which copies data into strdata)
007f0f1c 6436 s.op->newline() << "(*spp->read_ph) (c);";
87ebf4cb
DS
6437
6438 // copy string data into 'page'
6439 s.op->newline() << "c->data = NULL;";
007f0f1c 6440 s.op->newline() << "bytes = strnlen(strdata, MAXSTRINGLEN - 1);";
87ebf4cb
DS
6441 s.op->newline() << "if (off >= bytes)";
6442 s.op->newline(1) << "*eof = 1;";
6443 s.op->newline(-1) << "else {";
6444 s.op->newline(1) << "bytes -= off;";
6445 s.op->newline() << "if (bytes > count)";
6446 s.op->newline(1) << "bytes = count;";
6447 s.op->newline(-1) << "memcpy(page, strdata + off, bytes);";
6448 s.op->newline() << "*start = page;";
6449 s.op->newline(-1) << "}";
6450
87ebf4cb 6451 common_probe_entryfn_epilogue (s.op);
87ebf4cb
DS
6452 s.op->newline() << "return bytes;";
6453
6454 s.op->newline(-1) << "}";
6455 }
6456 if (has_write_probes)
6457 {
6458 s.op->newline() << "static int _stp_procfs_write(struct file *file, const char *buffer, unsigned long count, void *data) {";
6459
6460 s.op->newline(1) << "struct stap_procfs_probe *spp = (struct stap_procfs_probe *)data;";
007f0f1c
DS
6461 s.op->newline() << "string_t strdata = {'\\0'};";
6462
6463 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
6464 s.op->newline() << "c->probe_point = spp->write_pp;";
87ebf4cb 6465
007f0f1c
DS
6466 s.op->newline() << "if (count > (MAXSTRINGLEN - 1))";
6467 s.op->newline(1) << "count = MAXSTRINGLEN - 1;";
6468 s.op->newline(-1) << "_stp_copy_from_user(strdata, buffer, count);";
6469
6470 s.op->newline() << "if (c->data == NULL)";
6471 s.op->newline(1) << "c->data = &strdata;";
6472 s.op->newline(-1) << "else {";
6473
6474 s.op->newline(1) << "if (unlikely (atomic_inc_return (& skipped_count) > MAXSKIPPED)) {";
6475 s.op->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
6476 s.op->newline() << "_stp_exit ();";
6477 s.op->newline(-1) << "}";
6478 s.op->newline() << "atomic_dec (& c->busy);";
6479 s.op->newline() << "goto probe_epilogue;";
6480 s.op->newline(-1) << "}";
6481
6482 // call probe function (which copies data out of strdata)
6483 s.op->newline() << "(*spp->write_ph) (c);";
6484
6485 s.op->newline() << "c->data = NULL;";
6486 common_probe_entryfn_epilogue (s.op);
6487
6488 s.op->newline() << "return count;";
87ebf4cb 6489 s.op->newline(-1) << "}";
604eef3b 6490 }
87ebf4cb
DS
6491}
6492
6493
6494void
6495procfs_derived_probe_group::emit_module_init (systemtap_session& s)
6496{
6497 if (probes_by_path.empty())
6498 return;
6499
6500 s.op->newline() << "for (i = 0; i < " << probes_by_path.size() << "; i++) {";
6501 s.op->newline(1) << "struct stap_procfs_probe *spp = &stap_procfs_probes[i];";
6502
6503 s.op->newline() << "if (spp->read_pp)";
6504 s.op->newline(1) << "probe_point = spp->read_pp;";
6505 s.op->newline(-1) << "else";
6506 s.op->newline(1) << "probe_point = spp->write_pp;";
6507
6508 s.op->newline(-1) << "rc = _stp_create_procfs(spp->path, i);";
6509
6510 s.op->newline() << "if (rc) {";
6511 s.op->newline(1) << "_stp_close_procfs();";
6512 s.op->newline() << "break;";
6513 s.op->newline(-1) << "}";
6514
4baf0e53 6515 if (has_read_probes)
bcf31db4
DS
6516 {
6517 s.op->newline() << "if (spp->read_pp)";
6518 s.op->newline(1) << "_stp_procfs_files[i]->read_proc = &_stp_procfs_read;";
6519 s.op->newline(-1) << "else";
6520 s.op->newline(1) << "_stp_procfs_files[i]->read_proc = NULL;";
6521 s.op->indent(-1);
6522 }
6523 else
6524 s.op->newline() << "_stp_procfs_files[i]->read_proc = NULL;";
87ebf4cb 6525
bcf31db4
DS
6526 if (has_write_probes)
6527 {
cf8dc3c7 6528 s.op->newline() << "if (spp->write_pp)";
bcf31db4
DS
6529 s.op->newline(1) << "_stp_procfs_files[i]->write_proc = &_stp_procfs_write;";
6530 s.op->newline(-1) << "else";
6531 s.op->newline(1) << "_stp_procfs_files[i]->write_proc = NULL;";
6532 s.op->indent(-1);
6533 }
6534 else
6535 s.op->newline() << "_stp_procfs_files[i]->write_proc = NULL;";
87ebf4cb 6536
bcf31db4 6537 s.op->newline() << "_stp_procfs_files[i]->data = spp;";
87ebf4cb 6538 s.op->newline(-1) << "}"; // for loop
604eef3b
MH
6539}
6540
ce82316f 6541
604eef3b
MH
6542void
6543procfs_derived_probe_group::emit_module_exit (systemtap_session& s)
6544{
87ebf4cb
DS
6545 if (probes_by_path.empty())
6546 return;
6547
4baf0e53 6548 s.op->newline() << "_stp_close_procfs();";
604eef3b
MH
6549}
6550
ce82316f 6551
87ebf4cb
DS
6552void
6553procfs_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
6554{
87ebf4cb
DS
6555 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
6556
6557 if (e->base_name != "$value")
6558 throw semantic_error ("invalid target symbol for procfs probe, $value expected",
6559 e->tok);
6560
4ec2f7d0
DS
6561 if (e->components.size() > 0)
6562 {
6563 switch (e->components[0].first)
6564 {
6565 case target_symbol::comp_literal_array_index:
6566 throw semantic_error("procfs target variable '$value' may not be used as array",
6567 e->tok);
6568 break;
6569 case target_symbol::comp_struct_member:
6570 throw semantic_error("procfs target variable '$value' may not be used as a structure",
6571 e->tok);
6572 break;
6573 default:
6574 throw semantic_error ("invalid use of procfs target variable '$value'",
6575 e->tok);
6576 break;
6577 }
6578 }
6579
87ebf4cb
DS
6580 bool lvalue = is_active_lvalue(e);
6581 if (write_probe && lvalue)
6582 throw semantic_error("procfs $value variable is read-only in a procfs write probe", e->tok);
cf8dc3c7
DS
6583 else if (! write_probe && ! lvalue)
6584 throw semantic_error("procfs $value variable cannot be read in a procfs read probe", e->tok);
87ebf4cb
DS
6585
6586 // Remember that we've seen a target variable.
6587 target_symbol_seen = true;
6588
6589 // Synthesize a function.
6590 functiondecl *fdecl = new functiondecl;
6591 fdecl->tok = e->tok;
6592 embeddedcode *ec = new embeddedcode;
6593 ec->tok = e->tok;
6594
6595 string fname = (string(lvalue ? "_procfs_value_set" : "_procfs_value_get")
6596 + "_" + lex_cast<string>(tick++));
6597 string locvalue = "CONTEXT->data";
6598
6599 if (! lvalue)
007f0f1c
DS
6600 ec->code = string("strlcpy (THIS->__retvalue, ") + locvalue
6601 + string(", MAXSTRINGLEN); /* pure */");
87ebf4cb
DS
6602 else
6603 ec->code = string("strlcpy (") + locvalue
6604 + string(", THIS->value, MAXSTRINGLEN);");
6605
6606 fdecl->name = fname;
6607 fdecl->body = ec;
6608 fdecl->type = pe_string;
6609
6610 if (lvalue)
6611 {
6612 // Modify the fdecl so it carries a single pe_string formal
6613 // argument called "value".
6614
6615 vardecl *v = new vardecl;
6616 v->type = pe_string;
6617 v->name = "value";
6618 v->tok = e->tok;
6619 fdecl->formal_args.push_back(v);
6620 }
6621 sess.functions.push_back(fdecl);
6622
6623 // Synthesize a functioncall.
6624 functioncall* n = new functioncall;
6625 n->tok = e->tok;
6626 n->function = fname;
6627 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
6628
6629 if (lvalue)
6630 {
6631 // Provide the functioncall to our parent, so that it can be
6632 // used to substitute for the assignment node immediately above
6633 // us.
6634 assert(!target_symbol_setter_functioncalls.empty());
6635 *(target_symbol_setter_functioncalls.top()) = n;
6636 }
6637
6638 provide <functioncall*> (this, n);
6639}
6640
6641
604eef3b
MH
6642struct procfs_builder: public derived_probe_builder
6643{
ce82316f 6644 procfs_builder() {}
604eef3b
MH
6645 virtual void build(systemtap_session & sess,
6646 probe * base,
6647 probe_point * location,
ce82316f
DS
6648 std::map<std::string, literal *> const & parameters,
6649 vector<derived_probe *> & finished_results);
604eef3b 6650};
39e57ce0 6651
ce82316f
DS
6652
6653void
6654procfs_builder::build(systemtap_session & sess,
6655 probe * base,
6656 probe_point * location,
6657 std::map<std::string, literal *> const & parameters,
6658 vector<derived_probe *> & finished_results)
6659{
6660 string path;
12b21830
DS
6661 bool has_procfs = get_param(parameters, TOK_PROCFS, path);
6662 bool has_read = (parameters.find(TOK_READ) != parameters.end());
6663 bool has_write = (parameters.find(TOK_WRITE) != parameters.end());
ce82316f 6664
87ebf4cb
DS
6665 // If no procfs path, default to "command". The runtime will do
6666 // this for us, but if we don't do it here, we'll think the
6667 // following 2 probes are attached to different paths:
6668 //
6669 // probe procfs("command").read {}"
6670 // probe procfs.write {}
4baf0e53 6671
ce82316f
DS
6672 if (! has_procfs)
6673 path = "command";
227cacb9
DS
6674 // If we have a path, we need to validate it.
6675 else
6676 {
6677 string::size_type start_pos, end_pos;
6678 string component;
6679 start_pos = 0;
6680 while ((end_pos = path.find('/', start_pos)) != string::npos)
6681 {
6682 // Make sure it doesn't start with '/'.
6683 if (end_pos == 0)
6684 throw semantic_error ("procfs path cannot start with a '/'",
6685 location->tok);
6686
6687 component = path.substr(start_pos, end_pos - start_pos);
6688 // Make sure it isn't empty.
6689 if (component.size() == 0)
6690 throw semantic_error ("procfs path component cannot be empty",
6691 location->tok);
6692 // Make sure it isn't relative.
6693 else if (component == "." || component == "..")
6694 throw semantic_error ("procfs path cannot be relative (and contain '.' or '..')", location->tok);
6695
6696 start_pos = end_pos + 1;
6697 }
6698 component = path.substr(start_pos);
6699 // Make sure it doesn't end with '/'.
6700 if (component.size() == 0)
6701 throw semantic_error ("procfs path cannot end with a '/'", location->tok);
6702 // Make sure it isn't relative.
6703 else if (component == "." || component == "..")
6704 throw semantic_error ("procfs path cannot be relative (and contain '.' or '..')", location->tok);
6705 }
ce82316f
DS
6706
6707 if (!(has_read ^ has_write))
6708 throw semantic_error ("need read/write component", location->tok);
6709
6710 finished_results.push_back(new procfs_derived_probe(sess, base, location,
6711 path, has_write));
6712}
6713
6714
342d3f96 6715
30a279be
FCE
6716// ------------------------------------------------------------------------
6717// statically inserted macro-based derived probes
6718// ------------------------------------------------------------------------
6719
12b21830
DS
6720static string TOK_MARK("mark");
6721static string TOK_FORMAT("format");
30a279be 6722
2c384610
DS
6723struct mark_arg
6724{
6725 bool str;
6726 string c_type;
6727 exp_type stp_type;
6728};
6729
30a279be
FCE
6730struct mark_derived_probe: public derived_probe
6731{
6732 mark_derived_probe (systemtap_session &s,
eb973c2a 6733 const string& probe_name, const string& probe_format,
5d23847d 6734 probe* base_probe, probe_point* location);
30a279be 6735
35d4ab18 6736 systemtap_session& sess;
eb973c2a 6737 string probe_name, probe_format;
2c384610
DS
6738 vector <struct mark_arg *> mark_args;
6739 bool target_symbol_seen;
30a279be 6740
b20febf3 6741 void join_group (systemtap_session& s);
35d4ab18 6742 void emit_probe_context_vars (translator_output* o);
2c384610
DS
6743 void initialize_probe_context_vars (translator_output* o);
6744
eb973c2a 6745 void parse_probe_format ();
30a279be
FCE
6746};
6747
6748
b20febf3
FCE
6749struct mark_derived_probe_group: public generic_dpg<mark_derived_probe>
6750{
6751public:
2c384610
DS
6752 void emit_module_decls (systemtap_session& s);
6753 void emit_module_init (systemtap_session& s);
6754 void emit_module_exit (systemtap_session& s);
b20febf3
FCE
6755};
6756
6757
35d4ab18
FCE
6758struct mark_var_expanding_copy_visitor: public var_expanding_copy_visitor
6759{
6760 mark_var_expanding_copy_visitor(systemtap_session& s,
2c384610
DS
6761 const string& pn,
6762 vector <struct mark_arg *> &mark_args):
6763 sess (s), probe_name (pn), mark_args (mark_args),
6764 target_symbol_seen (false) {}
35d4ab18 6765 systemtap_session& sess;
35d4ab18 6766 string probe_name;
2c384610
DS
6767 vector <struct mark_arg *> &mark_args;
6768 bool target_symbol_seen;
35d4ab18
FCE
6769
6770 void visit_target_symbol (target_symbol* e);
0a63c36f
DS
6771 void visit_target_symbol_arg (target_symbol* e);
6772 void visit_target_symbol_format (target_symbol* e);
35d4ab18
FCE
6773};
6774
6775
1969b5bc
DS
6776void
6777hex_dump(unsigned char *data, size_t len)
2c384610 6778{
1969b5bc
DS
6779 // Dump data
6780 size_t idx = 0;
6781 while (idx < len)
6782 {
6783 string char_rep;
6784
6785 clog << " 0x" << setfill('0') << setw(8) << hex << internal << idx;
6786
6787 for (int i = 0; i < 4; i++)
6788 {
6789 clog << " ";
6790 size_t limit = idx + 4;
6791 while (idx < len && idx < limit)
6792 {
6793 clog << setfill('0') << setw(2)
6794 << ((unsigned) *((unsigned char *)data + idx));
6795 if (isprint(*((char *)data + idx)))
6796 char_rep += *((char *)data + idx);
6797 else
6798 char_rep += '.';
6799 idx++;
6800 }
6801 while (idx < limit)
6802 {
6803 clog << " ";
6804 idx++;
6805 }
6806 }
6807 clog << " " << char_rep << dec << setfill(' ') << endl;
6808 }
6809}
6810
2c384610 6811
35d4ab18 6812void
0a63c36f 6813mark_var_expanding_copy_visitor::visit_target_symbol_arg (target_symbol* e)
35d4ab18 6814{
35d4ab18
FCE
6815 string argnum_s = e->base_name.substr(4,e->base_name.length()-4);
6816 int argnum = atoi (argnum_s.c_str());
2c384610
DS
6817
6818 if (argnum < 1 || argnum > (int)mark_args.size())
35d4ab18
FCE
6819 throw semantic_error ("invalid marker argument number", e->tok);
6820
2c384610
DS
6821 if (is_active_lvalue (e))
6822 throw semantic_error("write to marker parameter not permitted", e->tok);
6823
6f93ef37
DS
6824 if (e->components.size() > 0)
6825 {
6826 switch (e->components[0].first)
6827 {
6828 case target_symbol::comp_literal_array_index:
6829 throw semantic_error("marker argument may not be used as array",
6830 e->tok);
6831 break;
6832 case target_symbol::comp_struct_member:
6833 throw semantic_error("marker argument may not be used as a structure",
6834 e->tok);
6835 break;
6836 default:
6837 throw semantic_error ("invalid marker argument use", e->tok);
6838 break;
6839 }
6840 }
4baf0e53 6841
2c384610
DS
6842 // Remember that we've seen a target variable.
6843 target_symbol_seen = true;
35d4ab18
FCE
6844
6845 // Synthesize a function.
6846 functiondecl *fdecl = new functiondecl;
6847 fdecl->tok = e->tok;
6848 embeddedcode *ec = new embeddedcode;
6849 ec->tok = e->tok;
35d4ab18 6850
1b07c728
FCE
6851 string fname = string("_mark_tvar_get")
6852 + "_" + e->base_name.substr(1)
6853 + "_" + lex_cast<string>(tick++);
35d4ab18 6854
2c384610
DS
6855 if (mark_args[argnum-1]->stp_type == pe_long)
6856 ec->code = string("THIS->__retvalue = CONTEXT->locals[0].")
6857 + probe_name + string(".__mark_arg")
6858 + lex_cast<string>(argnum) + string (";");
6859 else
6860 ec->code = string("strlcpy (THIS->__retvalue, CONTEXT->locals[0].")
6861 + probe_name + string(".__mark_arg")
6862 + lex_cast<string>(argnum) + string (", MAXSTRINGLEN);");
1b07c728 6863 ec->code += "/* pure */";
35d4ab18
FCE
6864 fdecl->name = fname;
6865 fdecl->body = ec;
2c384610 6866 fdecl->type = mark_args[argnum-1]->stp_type;
35d4ab18
FCE
6867 sess.functions.push_back(fdecl);
6868
6869 // Synthesize a functioncall.
6870 functioncall* n = new functioncall;
6871 n->tok = e->tok;
6872 n->function = fname;
6873 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
6874 provide <functioncall*> (this, n);
6875}
6876
6877
0a63c36f
DS
6878void
6879mark_var_expanding_copy_visitor::visit_target_symbol_format (target_symbol* e)
6880{
6881 static bool function_synthesized = false;
6882
6883 if (is_active_lvalue (e))
6884 throw semantic_error("write to marker format not permitted", e->tok);
6885
6886 if (e->components.size() > 0)
6887 {
6888 switch (e->components[0].first)
6889 {
6890 case target_symbol::comp_literal_array_index:
6891 throw semantic_error("marker format may not be used as array",
6892 e->tok);
6893 break;
6894 case target_symbol::comp_struct_member:
6895 throw semantic_error("marker format may not be used as a structure",
6896 e->tok);
6897 break;
6898 default:
6899 throw semantic_error ("invalid marker format use", e->tok);
6900 break;
6901 }
6902 }
4baf0e53 6903
0a63c36f
DS
6904 string fname = string("_mark_format_get");
6905
6906 // Synthesize a function (if not already synthesized).
6907 if (! function_synthesized)
6908 {
6909 function_synthesized = true;
6910 functiondecl *fdecl = new functiondecl;
6911 fdecl->tok = e->tok;
6912 embeddedcode *ec = new embeddedcode;
6913 ec->tok = e->tok;
6914
6915 ec->code = string("strlcpy (THIS->__retvalue, CONTEXT->data, MAXSTRINGLEN); /* pure */");
6916 fdecl->name = fname;
6917 fdecl->body = ec;
6918 fdecl->type = pe_string;
6919 sess.functions.push_back(fdecl);
6920 }
6921
6922 // Synthesize a functioncall.
6923 functioncall* n = new functioncall;
6924 n->tok = e->tok;
6925 n->function = fname;
6926 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
6927 provide <functioncall*> (this, n);
6928}
6929
6930void
6931mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
6932{
6933 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
6934
6935 if (e->base_name.substr(0,4) == "$arg")
6936 visit_target_symbol_arg (e);
6937 else if (e->base_name == "$format")
6938 visit_target_symbol_format (e);
6939 else
6940 throw semantic_error ("invalid target symbol for marker, $argN or $format expected",
6941 e->tok);
6942}
6943
6944
35d4ab18 6945
30a279be 6946mark_derived_probe::mark_derived_probe (systemtap_session &s,
35d4ab18 6947 const string& p_n,
eb973c2a 6948 const string& p_f,
5d23847d 6949 probe* base, probe_point* loc):
a10fa7f5 6950 derived_probe (base, new probe_point(*loc) /* .components soon rewritten */),
eb973c2a 6951 sess (s), probe_name (p_n), probe_format (p_f),
f781f849 6952 target_symbol_seen (false)
30a279be 6953{
5d23847d
FCE
6954 // create synthetic probe point name; preserve condition
6955 vector<probe_point::component*> comps;
12b21830
DS
6956 comps.push_back (new probe_point::component (TOK_KERNEL));
6957 comps.push_back (new probe_point::component (TOK_MARK, new literal_string (probe_name)));
6958 comps.push_back (new probe_point::component (TOK_FORMAT, new literal_string (probe_format)));
5d23847d 6959 this->sole_location()->components = comps;
cbbe8080 6960
eb973c2a
DS
6961 // expand the marker format
6962 parse_probe_format();
35d4ab18
FCE
6963
6964 // Now make a local-variable-expanded copy of the probe body
2c384610 6965 mark_var_expanding_copy_visitor v (sess, name, mark_args);
ba6f838d 6966 require <statement*> (&v, &(this->body), base->body);
2c384610 6967 target_symbol_seen = v.target_symbol_seen;
35d4ab18 6968
1969b5bc 6969 if (sess.verbose > 2)
eb973c2a
DS
6970 clog << "marker-based " << name << " mark=" << probe_name
6971 << " fmt='" << probe_format << "'" << endl;
30a279be
FCE
6972}
6973
6974
2c384610
DS
6975static int
6976skip_atoi(const char **s)
dc38c0ae 6977{
2c384610
DS
6978 int i = 0;
6979 while (isdigit(**s))
6980 i = i * 10 + *((*s)++) - '0';
6981 return i;
dc38c0ae
DS
6982}
6983
6984
30a279be 6985void
eb973c2a 6986mark_derived_probe::parse_probe_format()
35d4ab18 6987{
eb973c2a 6988 const char *fmt = probe_format.c_str();
2c384610
DS
6989 int qualifier; // 'h', 'l', or 'L' for integer fields
6990 mark_arg *arg;
6991
6992 for (; *fmt ; ++fmt)
35d4ab18 6993 {
2c384610 6994 if (*fmt != '%')
35d4ab18 6995 {
2c384610
DS
6996 /* Skip text */
6997 continue;
6998 }
35d4ab18 6999
2c384610
DS
7000repeat:
7001 ++fmt;
35d4ab18 7002
2c384610
DS
7003 // skip conversion flags (if present)
7004 switch (*fmt)
7005 {
7006 case '-':
7007 case '+':
7008 case ' ':
7009 case '#':
7010 case '0':
7011 goto repeat;
7012 }
30a279be 7013
2c384610
DS
7014 // skip minimum field witdh (if present)
7015 if (isdigit(*fmt))
7016 skip_atoi(&fmt);
30a279be 7017
2c384610
DS
7018 // skip precision (if present)
7019 if (*fmt == '.')
35d4ab18 7020 {
2c384610
DS
7021 ++fmt;
7022 if (isdigit(*fmt))
7023 skip_atoi(&fmt);
7024 }
30a279be 7025
2c384610
DS
7026 // get the conversion qualifier (if present)
7027 qualifier = -1;
7028 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')
7029 {
7030 qualifier = *fmt;
7031 ++fmt;
7032 if (qualifier == 'l' && *fmt == 'l')
7033 {
7034 qualifier = 'L';
7035 ++fmt;
7036 }
7037 }
30a279be 7038
2c384610
DS
7039 // get the conversion type
7040 switch (*fmt)
7041 {
7042 case 'c':
7043 arg = new mark_arg;
7044 arg->str = false;
7045 arg->c_type = "int";
7046 arg->stp_type = pe_long;
7047 mark_args.push_back(arg);
7048 continue;
7049
7050 case 's':
7051 arg = new mark_arg;
7052 arg->str = true;
7053 arg->c_type = "char *";
7054 arg->stp_type = pe_string;
7055 mark_args.push_back(arg);
7056 continue;
7057
7058 case 'p':
7059 arg = new mark_arg;
7060 arg->str = false;
38c963a9
DS
7061 // This should really be 'void *'. But, then we'll get a
7062 // compile error when we assign the void pointer to an
7063 // integer without a cast. So, we use 'long' instead, since
7064 // it should have the same size as 'void *'.
7065 arg->c_type = "long";
2c384610
DS
7066 arg->stp_type = pe_long;
7067 mark_args.push_back(arg);
7068 continue;
7069
7070 case '%':
7071 continue;
7072
7073 case 'o':
7074 case 'X':
7075 case 'x':
7076 case 'd':
7077 case 'i':
7078 case 'u':
7079 // fall through...
7080 break;
30a279be 7081
2c384610
DS
7082 default:
7083 if (!*fmt)
7084 --fmt;
7085 continue;
7086 }
30a279be 7087
2c384610
DS
7088 arg = new mark_arg;
7089 arg->str = false;
7090 arg->stp_type = pe_long;
7091 switch (qualifier)
7092 {
7093 case 'L':
7094 arg->c_type = "long long";
7095 break;
30a279be 7096
2c384610
DS
7097 case 'l':
7098 arg->c_type = "long";
7099 break;
e38d6504 7100
2c384610
DS
7101 case 'h':
7102 arg->c_type = "short";
7103 break;
46b84a80 7104
2c384610
DS
7105 default:
7106 arg->c_type = "int";
7107 break;
7108 }
7109 mark_args.push_back(arg);
7110 }
46b84a80
DS
7111}
7112
f781f849 7113
46b84a80 7114void
2c384610 7115mark_derived_probe::join_group (systemtap_session& s)
46b84a80 7116{
2c384610 7117 if (! s.mark_derived_probes)
775d51e5
DS
7118 {
7119 s.mark_derived_probes = new mark_derived_probe_group ();
7120
7121 // Make sure <linux/marker.h> is included early.
7122 embeddedcode *ec = new embeddedcode;
7123 ec->tok = NULL;
7124 ec->code = string("#if ! defined(CONFIG_MARKERS)\n")
7125 + string("#error \"Need CONFIG_MARKERS!\"\n")
7126 + string("#endif\n")
7127 + string("#include <linux/marker.h>\n");
7128
7129 s.embeds.push_back(ec);
7130 }
2c384610 7131 s.mark_derived_probes->enroll (this);
30a279be
FCE
7132}
7133
35d4ab18 7134
30a279be 7135void
2c384610 7136mark_derived_probe::emit_probe_context_vars (translator_output* o)
30a279be 7137{
2c384610
DS
7138 // If we haven't seen a target symbol for this probe, quit.
7139 if (! target_symbol_seen)
7140 return;
30a279be 7141
2c384610
DS
7142 for (unsigned i = 0; i < mark_args.size(); i++)
7143 {
7144 string localname = "__mark_arg" + lex_cast<string>(i+1);
7145 switch (mark_args[i]->stp_type)
7146 {
7147 case pe_long:
7148 o->newline() << "int64_t " << localname << ";";
7149 break;
7150 case pe_string:
7151 o->newline() << "string_t " << localname << ";";
7152 break;
7153 default:
7154 throw semantic_error ("cannot expand unknown type");
7155 break;
7156 }
7157 }
30a279be
FCE
7158}
7159
7160
dc38c0ae 7161void
2c384610 7162mark_derived_probe::initialize_probe_context_vars (translator_output* o)
dc38c0ae 7163{
2c384610
DS
7164 // If we haven't seen a target symbol for this probe, quit.
7165 if (! target_symbol_seen)
7166 return;
7167
d09fee57 7168 bool deref_fault_needed = false;
2c384610 7169 for (unsigned i = 0; i < mark_args.size(); i++)
dc38c0ae 7170 {
2c384610
DS
7171 string localname = "l->__mark_arg" + lex_cast<string>(i+1);
7172 switch (mark_args[i]->stp_type)
7173 {
7174 case pe_long:
3b0c565c 7175 o->newline() << localname << " = va_arg(*c->mark_va_list, "
2c384610
DS
7176 << mark_args[i]->c_type << ");";
7177 break;
7178
7179 case pe_string:
7180 // We're assuming that this is a kernel string (this code is
7181 // basically the guts of kernel_string), not a user string.
7182 o->newline() << "{ " << mark_args[i]->c_type
3b0c565c 7183 << " tmp_str = va_arg(*c->mark_va_list, "
2c384610
DS
7184 << mark_args[i]->c_type << ");";
7185 o->newline() << "deref_string (" << localname
d09fee57
DS
7186 << ", tmp_str, MAXSTRINGLEN); }";
7187 deref_fault_needed = true;
2c384610
DS
7188 break;
7189
7190 default:
7191 throw semantic_error ("cannot expand unknown type");
7192 break;
7193 }
dc38c0ae 7194 }
d09fee57
DS
7195 if (deref_fault_needed)
7196 // Need to report errors?
7197 o->newline() << "deref_fault: ;";
dc38c0ae
DS
7198}
7199
30a279be 7200
342d3f96
DS
7201void
7202mark_derived_probe_group::emit_module_decls (systemtap_session& s)
7203{
7204 if (probes.empty())
7205 return;
7206
7207 s.op->newline() << "/* ---- marker probes ---- */";
46b84a80 7208
2c384610 7209 s.op->newline() << "struct stap_marker_probe {";
0a63c36f
DS
7210 s.op->newline(1) << "const char * const name;";
7211 s.op->newline() << "const char * const format;";
7212 s.op->newline() << "const char * const pp;";
7213 s.op->newline() << "void (* const ph) (struct context *);";
46b84a80 7214
2c384610
DS
7215 s.op->newline(-1) << "} stap_marker_probes [" << probes.size() << "] = {";
7216 s.op->indent(1);
7217 for (unsigned i=0; i < probes.size(); i++)
46b84a80 7218 {
4baf0e53 7219 s.op->newline () << "{";
2c384610
DS
7220 s.op->line() << " .name=" << lex_cast_qstring(probes[i]->probe_name)
7221 << ",";
eb973c2a 7222 s.op->line() << " .format=" << lex_cast_qstring(probes[i]->probe_format)
2c384610
DS
7223 << ",";
7224 s.op->line() << " .pp=" << lex_cast_qstring (*probes[i]->sole_location())
7225 << ",";
7226 s.op->line() << " .ph=&" << probes[i]->name;
7227 s.op->line() << " },";
46b84a80 7228 }
2c384610
DS
7229 s.op->newline(-1) << "};";
7230 s.op->newline();
4baf0e53 7231
2c384610
DS
7232
7233 // Emit the marker callback function
7234 s.op->newline();
3b0c565c
DS
7235 s.op->newline() << "static void enter_marker_probe (void *probe_data, void *call_data, const char *fmt, va_list *args) {";
7236 s.op->newline(1) << "struct stap_marker_probe *smp = (struct stap_marker_probe *)probe_data;";
2c384610
DS
7237 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
7238 s.op->newline() << "c->probe_point = smp->pp;";
0a63c36f 7239 s.op->newline() << "c->data = (char *)smp->format;";
2c384610 7240
3b0c565c 7241 s.op->newline() << "c->mark_va_list = args;";
2c384610 7242 s.op->newline() << "(*smp->ph) (c);";
3b0c565c 7243 s.op->newline() << "c->mark_va_list = NULL;";
0a63c36f
DS
7244 s.op->newline() << "c->data = NULL;";
7245
2c384610
DS
7246 common_probe_entryfn_epilogue (s.op);
7247 s.op->newline(-1) << "}";
46b84a80 7248
2c384610 7249 return;
46b84a80
DS
7250}
7251
7252
2c384610
DS
7253void
7254mark_derived_probe_group::emit_module_init (systemtap_session &s)
30a279be 7255{
2c384610
DS
7256 if (probes.size () == 0)
7257 return;
30a279be 7258
2c384610
DS
7259 s.op->newline() << "/* init marker probes */";
7260 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
7261 s.op->newline(1) << "struct stap_marker_probe *smp = &stap_marker_probes[i];";
7262 s.op->newline() << "probe_point = smp->pp;";
38c963a9 7263 s.op->newline() << "rc = marker_probe_register(smp->name, smp->format, enter_marker_probe, smp);";
3b0c565c 7264 s.op->newline() << "if (rc) {";
2c384610
DS
7265 s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
7266 s.op->newline(1) << "struct stap_marker_probe *smp2 = &stap_marker_probes[j];";
3b0c565c 7267 s.op->newline() << "marker_probe_unregister(smp2->name, enter_marker_probe, smp2);";
2c384610
DS
7268 s.op->newline(-1) << "}";
7269 s.op->newline() << "break;"; // don't attempt to register any more probes
7270 s.op->newline(-1) << "}";
7271 s.op->newline(-1) << "}"; // for loop
7272}
7273
7274
7275void
7276mark_derived_probe_group::emit_module_exit (systemtap_session& s)
7277{
7278 if (probes.empty())
7279 return;
7280
7281 s.op->newline() << "/* deregister marker probes */";
7282 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
7283 s.op->newline(1) << "struct stap_marker_probe *smp = &stap_marker_probes[i];";
3b0c565c 7284 s.op->newline() << "marker_probe_unregister(smp->name, enter_marker_probe, smp);";
2c384610
DS
7285 s.op->newline(-1) << "}"; // for loop
7286}
30a279be
FCE
7287
7288
7289struct mark_builder: public derived_probe_builder
7290{
7291private:
f781f849 7292 bool cache_initialized;
eb973c2a
DS
7293 typedef multimap<string, string> mark_cache_t;
7294 typedef multimap<string, string>::const_iterator mark_cache_const_iterator_t;
7295 typedef pair<mark_cache_const_iterator_t, mark_cache_const_iterator_t>
7296 mark_cache_const_iterator_pair_t;
7297 mark_cache_t mark_cache;
30a279be
FCE
7298
7299public:
f781f849 7300 mark_builder(): cache_initialized(false) {}
2c384610
DS
7301
7302 void build_no_more (systemtap_session &s)
7303 {
f781f849 7304 if (! mark_cache.empty())
2c384610
DS
7305 {
7306 if (s.verbose > 3)
f781f849
DS
7307 clog << "mark_builder releasing cache" << endl;
7308 mark_cache.clear();
2c384610
DS
7309 }
7310 }
7311
30a279be
FCE
7312 void build(systemtap_session & sess,
7313 probe * base,
7314 probe_point * location,
7315 std::map<std::string, literal *> const & parameters,
7316 vector<derived_probe *> & finished_results);
7317};
7318
7319
30a279be
FCE
7320void
7321mark_builder::build(systemtap_session & sess,
2c384610 7322 probe * base,
cbbe8080 7323 probe_point *loc,
2c384610
DS
7324 std::map<std::string, literal *> const & parameters,
7325 vector<derived_probe *> & finished_results)
30a279be 7326{
f781f849 7327 string mark_str_val;
12b21830 7328 bool has_mark_str = get_param (parameters, TOK_MARK, mark_str_val);
eb973c2a 7329 string mark_format_val;
12b21830 7330 bool has_mark_format = get_param (parameters, TOK_FORMAT, mark_format_val);
f781f849 7331 assert (has_mark_str);
ced347a9 7332 (void) has_mark_str;
30a279be 7333
f781f849
DS
7334 if (! cache_initialized)
7335 {
7336 cache_initialized = true;
7337 string module_markers_path = "/lib/modules/" + sess.kernel_release
7338 + "/build/Module.markers";
30a279be 7339
f781f849
DS
7340 ifstream module_markers;
7341 module_markers.open(module_markers_path.c_str(), ifstream::in);
7342 if (! module_markers)
7343 {
7344 if (sess.verbose>3)
7345 clog << module_markers_path << " cannot be opened: "
7346 << strerror(errno) << endl;
7347 return;
7348 }
30a279be 7349
f781f849
DS
7350 string name, module, format;
7351 do
7352 {
7353 module_markers >> name >> module;
7354 getline(module_markers, format);
7355
7356 // trim leading whitespace
7357 string::size_type notwhite = format.find_first_not_of(" \t");
7358 format.erase(0, notwhite);
7359
a53c9645
DS
7360 // If the format is empty, make sure we add back a space
7361 // character, which is what MARK_NOARGS expands to.
7362 if (format.length() == 0)
7363 format = " ";
7364
f781f849
DS
7365 if (sess.verbose>3)
7366 clog << "'" << name << "' '" << module << "' '" << format
7367 << "'" << endl;
4baf0e53 7368
eb973c2a
DS
7369 if (mark_cache.count(name) > 0)
7370 {
7371 // If we have 2 markers with the same we've got 2 cases:
7372 // different format strings or duplicate format strings.
7373 // If an existing marker in the cache doesn't have the
7374 // same format string, add this marker.
7375 mark_cache_const_iterator_pair_t ret;
7376 mark_cache_const_iterator_t it;
7377 bool matching_format_string = false;
7378
7379 ret = mark_cache.equal_range(name);
7380 for (it = ret.first; it != ret.second; ++it)
7381 {
7382 if (format == it->second)
7383 {
7384 matching_format_string = true;
7385 break;
7386 }
7387 }
7388
7389 if (! matching_format_string)
7390 mark_cache.insert(pair<string,string>(name, format));
7391 }
7392 else
7393 mark_cache.insert(pair<string,string>(name, format));
f781f849
DS
7394 }
7395 while (! module_markers.eof());
7396 module_markers.close();
30a279be
FCE
7397 }
7398
f781f849 7399 // Search marker list for matching markers
eb973c2a 7400 for (mark_cache_const_iterator_t it = mark_cache.begin();
f781f849
DS
7401 it != mark_cache.end(); it++)
7402 {
7403 // Below, "rc" has negative polarity: zero iff matching.
7404 int rc = fnmatch(mark_str_val.c_str(), it->first.c_str(), 0);
7405 if (! rc)
7406 {
eb973c2a
DS
7407 bool add_result = true;
7408
7409 // Match format strings (if the user specified one)
7410 if (has_mark_format && fnmatch(mark_format_val.c_str(),
7411 it->second.c_str(), 0))
7412 add_result = false;
7413
7414 if (add_result)
7415 {
7416 derived_probe *dp
7417 = new mark_derived_probe (sess,
7418 it->first, it->second,
7419 base, loc);
7420 finished_results.push_back (dp);
7421 }
f781f849
DS
7422 }
7423 }
30a279be
FCE
7424}
7425
7426
342d3f96 7427
56894e91
JS
7428// ------------------------------------------------------------------------
7429// hrtimer derived probes
7430// ------------------------------------------------------------------------
7431// This is a new timer interface that provides more flexibility in specifying
7432// intervals, and uses the hrtimer APIs when available for greater precision.
39014506
JS
7433// While hrtimers were added in 2.6.16, the API's weren't exported until
7434// 2.6.17, so we must check this kernel version before attempting to use
7435// hrtimers.
56894e91 7436//
56894e91 7437// * hrtimer_derived_probe: creates a probe point based on the hrtimer APIs.
56894e91
JS
7438
7439
7440struct hrtimer_derived_probe: public derived_probe
7441{
7442 // set a (generous) maximum of one day in ns
7443 static const int64_t max_ns_interval = 1000000000LL * 60LL * 60LL * 24LL;
7444
7445 // 100us seems like a reasonable minimum
7446 static const int64_t min_ns_interval = 100000LL;
7447
7448 int64_t interval, randomize;
7449
7450 hrtimer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r):
7451 derived_probe (p, l), interval (i), randomize (r)
7452 {
7453 if ((i < min_ns_interval) || (i > max_ns_interval))
7454 throw semantic_error("interval value out of range");
7455
7456 // randomize = 0 means no randomization
7457 if ((r < 0) || (r > i))
7458 throw semantic_error("randomization value out of range");
56894e91
JS
7459 }
7460
b20febf3
FCE
7461 void join_group (systemtap_session& s);
7462};
dc38c0ae 7463
56894e91 7464
b20febf3
FCE
7465struct hrtimer_derived_probe_group: public generic_dpg<hrtimer_derived_probe>
7466{
7467 void emit_interval (translator_output* o);
7468public:
7469 void emit_module_decls (systemtap_session& s);
7470 void emit_module_init (systemtap_session& s);
7471 void emit_module_exit (systemtap_session& s);
56894e91
JS
7472};
7473
7474
dc38c0ae 7475void
b20febf3 7476hrtimer_derived_probe::join_group (systemtap_session& s)
dc38c0ae 7477{
b20febf3
FCE
7478 if (! s.hrtimer_derived_probes)
7479 s.hrtimer_derived_probes = new hrtimer_derived_probe_group ();
7480 s.hrtimer_derived_probes->enroll (this);
dc38c0ae
DS
7481}
7482
7483
56894e91 7484void
b20febf3 7485hrtimer_derived_probe_group::emit_interval (translator_output* o)
56894e91
JS
7486{
7487 o->line() << "({";
ffb0b3ad 7488 o->newline(1) << "unsigned long nsecs;";
b20febf3
FCE
7489 o->newline() << "int64_t i = stp->intrv;";
7490 o->newline() << "if (stp->rnd != 0) {";
7491 // XXX: why not use stp_random_pm instead of this?
7492 o->newline(1) << "int64_t r;";
7493 o->newline() << "get_random_bytes(&r, sizeof(r));";
7494 // ensure that r is positive
7495 o->newline() << "r &= ((uint64_t)1 << (8*sizeof(r) - 1)) - 1;";
7496 o->newline() << "r = _stp_mod64(NULL, r, (2*stp->rnd+1));";
7497 o->newline() << "r -= stp->rnd;";
7498 o->newline() << "i += r;";
7499 o->newline(-1) << "}";
7500 o->newline() << "if (unlikely(i < stap_hrtimer_resolution))";
7501 o->newline(1) << "i = stap_hrtimer_resolution;";
197a4d62 7502 o->indent(-1);
ffb0b3ad
JS
7503 o->newline() << "nsecs = do_div(i, NSEC_PER_SEC);";
7504 o->newline() << "ktime_set(i, nsecs);";
56894e91
JS
7505 o->newline(-1) << "})";
7506}
7507
7508
7509void
b20febf3 7510hrtimer_derived_probe_group::emit_module_decls (systemtap_session& s)
46b84a80 7511{
b20febf3 7512 if (probes.empty()) return;
46b84a80 7513
b20febf3 7514 s.op->newline() << "/* ---- hrtimer probes ---- */";
46b84a80 7515
b20febf3
FCE
7516 s.op->newline() << "unsigned long stap_hrtimer_resolution;"; // init later
7517 s.op->newline() << "struct stap_hrtimer_probe {";
7518 s.op->newline(1) << "struct hrtimer hrtimer;";
7519 s.op->newline() << "const char *pp;";
7520 s.op->newline() << "void (*ph) (struct context*);";
7521 s.op->newline() << "int64_t intrv, rnd;";
7522 s.op->newline(-1) << "} stap_hrtimer_probes [" << probes.size() << "] = {";
7523 s.op->indent(1);
7524 for (unsigned i=0; i < probes.size(); i++)
7525 {
4baf0e53 7526 s.op->newline () << "{";
b20febf3
FCE
7527 s.op->line() << " .pp=" << lex_cast_qstring (*probes[i]->sole_location()) << ",";
7528 s.op->line() << " .ph=&" << probes[i]->name << ",";
7529 s.op->line() << " .intrv=" << probes[i]->interval << "LL,";
7530 s.op->line() << " .rnd=" << probes[i]->randomize << "LL";
7531 s.op->line() << " },";
7532 }
7533 s.op->newline(-1) << "};";
7534 s.op->newline();
7535
255e4c68
FCE
7536 // autoconf: adapt to HRTIMER_REL -> HRTIMER_MODE_REL renaming near 2.6.21
7537 s.op->newline() << "#ifdef STAPCONF_HRTIMER_REL";
7538 s.op->newline() << "#define HRTIMER_MODE_REL HRTIMER_REL";
7539 s.op->newline() << "#endif";
4baf0e53 7540
5dbd55d7 7541 // The function signature changed in 2.6.21.
255e4c68
FCE
7542 s.op->newline() << "#ifdef STAPCONF_HRTIMER_REL";
7543 s.op->newline() << "static int ";
7544 s.op->newline() << "#else";
7545 s.op->newline() << "static enum hrtimer_restart ";
7546 s.op->newline() << "#endif";
7547 s.op->newline() << "enter_hrtimer_probe (struct hrtimer *timer) {";
5dbd55d7 7548
4baf0e53 7549 s.op->newline(1) << "int rc = HRTIMER_NORESTART;";
e0d86324
JS
7550 s.op->newline() << "struct stap_hrtimer_probe *stp = container_of(timer, struct stap_hrtimer_probe, hrtimer);";
7551 s.op->newline() << "if ((atomic_read (&session_state) == STAP_SESSION_STARTING) ||";
7552 s.op->newline() << " (atomic_read (&session_state) == STAP_SESSION_RUNNING)) {";
b20febf3 7553 // Compute next trigger time
e0d86324 7554 s.op->newline(1) << "timer->expires = ktime_add (timer->expires,";
b20febf3
FCE
7555 emit_interval (s.op);
7556 s.op->line() << ");";
4baf0e53 7557 s.op->newline() << "rc = HRTIMER_RESTART;";
e0d86324
JS
7558 s.op->newline(-1) << "}";
7559 s.op->newline() << "{";
7560 s.op->indent(1);
7561 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
7562 s.op->newline() << "c->probe_point = stp->pp;";
b20febf3
FCE
7563 s.op->newline() << "(*stp->ph) (c);";
7564 common_probe_entryfn_epilogue (s.op);
e0d86324
JS
7565 s.op->newline(-1) << "}";
7566 s.op->newline() << "return rc;";
b20febf3 7567 s.op->newline(-1) << "}";
56894e91
JS
7568}
7569
7570
7571void
b20febf3 7572hrtimer_derived_probe_group::emit_module_init (systemtap_session& s)
56894e91 7573{
b20febf3 7574 if (probes.empty()) return;
56894e91 7575
b20febf3
FCE
7576 s.op->newline() << "{";
7577 s.op->newline(1) << "struct timespec res;";
7578 s.op->newline() << "hrtimer_get_res (CLOCK_MONOTONIC, &res);";
7579 s.op->newline() << "stap_hrtimer_resolution = timespec_to_ns (&res);";
7580 s.op->newline(-1) << "}";
a68f81a2 7581
b20febf3
FCE
7582 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
7583 s.op->newline(1) << "struct stap_hrtimer_probe* stp = & stap_hrtimer_probes [i];";
6f313a73 7584 s.op->newline() << "probe_point = stp->pp;";
255e4c68 7585 s.op->newline() << "hrtimer_init (& stp->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);";
b20febf3
FCE
7586 s.op->newline() << "stp->hrtimer.function = & enter_hrtimer_probe;";
7587 // There is no hrtimer field to identify *this* (i-th) probe handler
7588 // callback. So instead we'll deduce it at entry time.
7589 s.op->newline() << "(void) hrtimer_start (& stp->hrtimer, ";
7590 emit_interval (s.op);
255e4c68 7591 s.op->line() << ", HRTIMER_MODE_REL);";
b20febf3
FCE
7592 // Note: no partial failure rollback is needed: hrtimer_start only
7593 // "fails" if the timer was already active, which cannot be.
7594 s.op->newline(-1) << "}"; // for loop
56894e91
JS
7595}
7596
7597
dc38c0ae 7598void
b20febf3 7599hrtimer_derived_probe_group::emit_module_exit (systemtap_session& s)
dc38c0ae 7600{
b20febf3 7601 if (probes.empty()) return;
197a4d62 7602
b20febf3
FCE
7603 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)";
7604 s.op->newline(1) << "hrtimer_cancel (& stap_hrtimer_probes[i].hrtimer);";
7605 s.op->indent(-1);
dc38c0ae
DS
7606}
7607
7608
56894e91 7609
197a4d62
JS
7610struct timer_builder: public derived_probe_builder
7611{
7612 virtual void build(systemtap_session & sess,
7613 probe * base, probe_point * location,
7614 std::map<std::string, literal *> const & parameters,
7615 vector<derived_probe *> & finished_results);
e38d6504 7616
197a4d62 7617 static void register_patterns(match_node *root);
56894e91
JS
7618};
7619
197a4d62
JS
7620void
7621timer_builder::build(systemtap_session & sess,
7622 probe * base,
7623 probe_point * location,
7624 std::map<std::string, literal *> const & parameters,
7625 vector<derived_probe *> & finished_results)
56894e91 7626{
197a4d62 7627 int64_t period, rand=0;
56894e91 7628
197a4d62
JS
7629 if (!get_param(parameters, "randomize", rand))
7630 rand = 0;
56894e91 7631
197a4d62 7632 if (get_param(parameters, "jiffies", period))
56894e91 7633 {
197a4d62
JS
7634 // always use basic timers for jiffies
7635 finished_results.push_back(
7636 new timer_derived_probe(base, location, period, rand, false));
7637 return;
56894e91 7638 }
197a4d62 7639 else if (get_param(parameters, "hz", period))
56894e91 7640 {
197a4d62
JS
7641 if (period <= 0)
7642 throw semantic_error ("frequency must be greater than 0");
7643 period = (1000000000 + period - 1)/period;
7644 }
7645 else if (get_param(parameters, "s", period)
7646 || get_param(parameters, "sec", period))
7647 {
7648 period *= 1000000000;
7649 rand *= 1000000000;
7650 }
7651 else if (get_param(parameters, "ms", period)
7652 || get_param(parameters, "msec", period))
7653 {
7654 period *= 1000000;
7655 rand *= 1000000;
7656 }
7657 else if (get_param(parameters, "us", period)
7658 || get_param(parameters, "usec", period))
7659 {
7660 period *= 1000;
7661 rand *= 1000;
7662 }
7663 else if (get_param(parameters, "ns", period)
7664 || get_param(parameters, "nsec", period))
7665 {
7666 // ok
7667 }
7668 else
7669 throw semantic_error ("unrecognized timer variant");
56894e91 7670
b20febf3
FCE
7671 // Redirect wallclock-time based probes to hrtimer code on recent
7672 // enough kernels.
197a4d62
JS
7673 if (strverscmp(sess.kernel_base_release.c_str(), "2.6.17") < 0)
7674 {
7675 // hrtimers didn't exist, so use the old-school timers
7676 period = (period + 1000000 - 1)/1000000;
7677 rand = (rand + 1000000 - 1)/1000000;
56894e91 7678
197a4d62
JS
7679 finished_results.push_back(
7680 new timer_derived_probe(base, location, period, rand, true));
7681 }
7682 else
7683 finished_results.push_back(
7684 new hrtimer_derived_probe(base, location, period, rand));
7685}
56894e91 7686
197a4d62
JS
7687void
7688timer_builder::register_patterns(match_node *root)
7689{
7690 derived_probe_builder *builder = new timer_builder();
56894e91 7691
12b21830 7692 root = root->bind(TOK_TIMER);
56894e91 7693
197a4d62
JS
7694 root->bind_num("s")->bind(builder);
7695 root->bind_num("s")->bind_num("randomize")->bind(builder);
7696 root->bind_num("sec")->bind(builder);
7697 root->bind_num("sec")->bind_num("randomize")->bind(builder);
56894e91 7698
197a4d62
JS
7699 root->bind_num("ms")->bind(builder);
7700 root->bind_num("ms")->bind_num("randomize")->bind(builder);
7701 root->bind_num("msec")->bind(builder);
7702 root->bind_num("msec")->bind_num("randomize")->bind(builder);
56894e91 7703
197a4d62
JS
7704 root->bind_num("us")->bind(builder);
7705 root->bind_num("us")->bind_num("randomize")->bind(builder);
7706 root->bind_num("usec")->bind(builder);
7707 root->bind_num("usec")->bind_num("randomize")->bind(builder);
56894e91 7708
197a4d62
JS
7709 root->bind_num("ns")->bind(builder);
7710 root->bind_num("ns")->bind_num("randomize")->bind(builder);
7711 root->bind_num("nsec")->bind(builder);
7712 root->bind_num("nsec")->bind_num("randomize")->bind(builder);
56894e91 7713
197a4d62
JS
7714 root->bind_num("jiffies")->bind(builder);
7715 root->bind_num("jiffies")->bind_num("randomize")->bind(builder);
4baf0e53 7716
197a4d62 7717 root->bind_num("hz")->bind(builder);
56894e91
JS
7718}
7719
7720
342d3f96 7721
47dd066d
WC
7722// ------------------------------------------------------------------------
7723// perfmon derived probes
7724// ------------------------------------------------------------------------
7725// This is a new interface to the perfmon hw.
7726//
7727
7728
7729struct perfmon_var_expanding_copy_visitor: public var_expanding_copy_visitor
7730{
7731 systemtap_session & sess;
7732 unsigned counter_number;
7733 perfmon_var_expanding_copy_visitor(systemtap_session & s, unsigned c):
7734 sess(s), counter_number(c) {}
7735 void visit_target_symbol (target_symbol* e);
7736};
7737
7738
7739void
7740perfmon_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
7741{
7742 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
7743
7744 // Synthesize a function.
7745 functiondecl *fdecl = new functiondecl;
7746 fdecl->tok = e->tok;
7747 embeddedcode *ec = new embeddedcode;
7748 ec->tok = e->tok;
7749 bool lvalue = is_active_lvalue(e);
7750
7751 if (lvalue )
7752 throw semantic_error("writes to $counter not permitted");
7753
7754 string fname = string("_perfmon_tvar_get")
7755 + "_" + e->base_name.substr(1)
7756 + "_" + lex_cast<string>(counter_number);
7757
7758 if (e->base_name != "$counter")
7759 throw semantic_error ("target variables not available to perfmon probes");
7760
af304783
DS
7761 if (e->components.size() > 0)
7762 {
7763 switch (e->components[0].first)
7764 {
7765 case target_symbol::comp_literal_array_index:
7766 throw semantic_error("perfmon probe '$counter' variable may not be used as array",
7767 e->tok);
7768 break;
7769 case target_symbol::comp_struct_member:
7770 throw semantic_error("perfmon probe '$counter' variable may not be used as a structure",
7771 e->tok);
7772 break;
7773 default:
7774 throw semantic_error ("invalid use of perfmon probe '$counter' variable",
7775 e->tok);
7776 break;
7777 }
7778 }
7779
4baf0e53 7780 ec->code = "THIS->__retvalue = _pfm_pmd_x[" +
47dd066d
WC
7781 lex_cast<string>(counter_number) + "].reg_num;";
7782 ec->code += "/* pure */";
7783 fdecl->name = fname;
7784 fdecl->body = ec;
7785 fdecl->type = pe_long;
7786 sess.functions.push_back(fdecl);
7787
7788 // Synthesize a functioncall.
7789 functioncall* n = new functioncall;
7790 n->tok = e->tok;
7791 n->function = fname;
7792 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
7793
7794 provide <functioncall*> (this, n);
7795}
7796
7797
7798enum perfmon_mode
7799{
7800 perfmon_count,
7801 perfmon_sample
7802};
7803
7804
7805struct perfmon_derived_probe: public derived_probe
7806{
7807protected:
7808 static unsigned probes_allocated;
7809
7810public:
7811 systemtap_session & sess;
7812 string event;
7813 perfmon_mode mode;
7814
7815 perfmon_derived_probe (probe* p, probe_point* l, systemtap_session &s,
7816 string e, perfmon_mode m);
b20febf3 7817 virtual void join_group (systemtap_session& s);
47dd066d
WC
7818};
7819
7820
b20febf3 7821struct perfmon_derived_probe_group: public generic_dpg<perfmon_derived_probe>
47dd066d 7822{
47dd066d 7823public:
78f6bba6
FCE
7824 void emit_module_decls (systemtap_session&) {}
7825 void emit_module_init (systemtap_session&) {}
7826 void emit_module_exit (systemtap_session&) {}
47dd066d
WC
7827};
7828
7829
7830struct perfmon_builder: public derived_probe_builder
7831{
7832 perfmon_builder() {}
7833 virtual void build(systemtap_session & sess,
7834 probe * base,
7835 probe_point * location,
7836 std::map<std::string, literal *> const & parameters,
7837 vector<derived_probe *> & finished_results)
7838 {
7839 string event;
7840 if (!get_param (parameters, "counter", event))
7841 throw semantic_error("perfmon requires an event");
7842
7843 sess.perfmon++;
7844
4baf0e53 7845 // XXX: need to revise when doing sampling
47dd066d
WC
7846 finished_results.push_back(new perfmon_derived_probe(base, location,
7847 sess, event,
7848 perfmon_count));
7849 }
7850};
7851
b20febf3 7852
47dd066d
WC
7853unsigned perfmon_derived_probe::probes_allocated;
7854
7855perfmon_derived_probe::perfmon_derived_probe (probe* p, probe_point* l,
7856 systemtap_session &s,
7857 string e, perfmon_mode m)
7858 : derived_probe (p, l), sess(s), event(e), mode(m)
7859{
7860 ++probes_allocated;
7861
7862 // Now make a local-variable-expanded copy of the probe body
7863 perfmon_var_expanding_copy_visitor v (sess, probes_allocated-1);
ba6f838d 7864 require <statement*> (&v, &(this->body), base->body);
47dd066d
WC
7865
7866 if (sess.verbose > 1)
7867 clog << "perfmon-based probe" << endl;
7868}
7869
7870
7871void
b20febf3 7872perfmon_derived_probe::join_group (systemtap_session& s)
47dd066d 7873{
b20febf3
FCE
7874 throw semantic_error ("incomplete", this->tok);
7875
7876 if (! s.perfmon_derived_probes)
7877 s.perfmon_derived_probes = new perfmon_derived_probe_group ();
7878 s.perfmon_derived_probes->enroll (this);
47dd066d
WC
7879}
7880
7881
b20febf3 7882#if 0
47dd066d
WC
7883void
7884perfmon_derived_probe::emit_registrations_start (translator_output* o,
7885 unsigned index)
7886{
7887 for (unsigned i=0; i<locations.size(); i++)
7888 o->newline() << "enter_" << name << "_" << i << " ();";
7889}
7890
7891
7892void
7893perfmon_derived_probe::emit_registrations_end (translator_output * o,
7894 unsigned index)
7895{
7896}
7897
7898
7899void
7900perfmon_derived_probe::emit_deregistrations (translator_output * o)
7901{
7902}
7903
7904
7905void
7906perfmon_derived_probe::emit_probe_entries (translator_output * o)
7907{
7908 o->newline() << "#ifdef STP_TIMING";
dbb68664 7909 // NB: This variable may be multiply (but identically) defined.
47dd066d
WC
7910 o->newline() << "static __cacheline_aligned Stat " << "time_" << basest()->name << ";";
7911 o->newline() << "#endif";
7912
7913 for (unsigned i=0; i<locations.size(); i++)
7914 {
7915 probe_point *l = locations[i];
7916 o->newline() << "/* location " << i << ": " << *l << " */";
7917 o->newline() << "static void enter_" << name << "_" << i << " (void) {";
7918
7919 o->indent(1);
7920 o->newline() << "const char* probe_point = "
7921 << lex_cast_qstring(*l) << ";";
7922 emit_probe_prologue (o,
7923 (mode == perfmon_count ?
7924 "STAP_SESSION_STARTING" :
7925 "STAP_SESSION_RUNNING"));
7926
7927 // NB: locals are initialized by probe function itself
7928 o->newline() << name << " (c);";
7929
7930 emit_probe_epilogue (o);
7931
7932 o->newline(-1) << "}\n";
7933 }
7934}
b20febf3 7935#endif
47dd066d
WC
7936
7937
b20febf3 7938#if 0
47dd066d
WC
7939void no_pfm_event_error (string s)
7940{
7941 string msg(string("Cannot find event:" + s));
7942 throw semantic_error(msg);
7943}
7944
7945
7946void no_pfm_mask_error (string s)
7947{
7948 string msg(string("Cannot find mask:" + s));
7949 throw semantic_error(msg);
7950}
7951
7952
7953void
7954split(const string& s, vector<string>& v, const string & separator)
7955{
7956 string::size_type last_pos = s.find_first_not_of(separator, 0);
7957 string::size_type pos = s.find_first_of(separator, last_pos);
7958
7959 while (string::npos != pos || string::npos != last_pos) {
7960 v.push_back(s.substr(last_pos, pos - last_pos));
7961 last_pos = s.find_first_not_of(separator, pos);
7962 pos = s.find_first_of(separator, last_pos);
7963 }
7964}
7965
7966
7967void
7968perfmon_derived_probe_group::emit_probes (translator_output* op, unparser* up)
7969{
7970 for (unsigned i=0; i < probes.size(); i++)
7971 {
7972 op->newline ();
7973 up->emit_probe (probes[i]);
7974 }
7975}
7976
7977
7978void
7979perfmon_derived_probe_group::emit_module_init (translator_output* o)
7980{
7981 int ret;
7982 pfmlib_input_param_t inp;
7983 pfmlib_output_param_t outp;
7984 pfarg_pmd_t pd[PFMLIB_MAX_PMDS];
7985 pfarg_pmc_t pc[PFMLIB_MAX_PMCS];
7986 pfarg_ctx_t ctx;
7987 pfarg_load_t load_args;
7988 pfmlib_options_t pfmlib_options;
7989 unsigned int max_counters;
7990
7991 if ( probes.size() == 0)
7992 return;
7993 ret = pfm_initialize();
7994 if (ret != PFMLIB_SUCCESS)
7995 throw semantic_error("Unable to generate performance monitoring events (no libpfm)");
7996
7997 pfm_get_num_counters(&max_counters);
7998
7999 memset(&pfmlib_options, 0, sizeof(pfmlib_options));
8000 pfmlib_options.pfm_debug = 0; /* set to 1 for debug */
8001 pfmlib_options.pfm_verbose = 0; /* set to 1 for debug */
8002 pfm_set_options(&pfmlib_options);
8003
8004 memset(pd, 0, sizeof(pd));
8005 memset(pc, 0, sizeof(pc));
8006 memset(&ctx, 0, sizeof(ctx));
8007 memset(&load_args, 0, sizeof(load_args));
8008
8009 /*
8010 * prepare parameters to library.
8011 */
8012 memset(&inp,0, sizeof(inp));
8013 memset(&outp,0, sizeof(outp));
8014
8015 /* figure out the events */
8016 for (unsigned i=0; i<probes.size(); ++i)
8017 {
8018 if (probes[i]->event == "cycles") {
8019 if (pfm_get_cycle_event( &inp.pfp_events[i].event) != PFMLIB_SUCCESS)
8020 no_pfm_event_error(probes[i]->event);
8021 } else if (probes[i]->event == "instructions") {
8022 if (pfm_get_inst_retired_event( &inp.pfp_events[i].event) !=
8023 PFMLIB_SUCCESS)
8024 no_pfm_event_error(probes[i]->event);
8025 } else {
8026 unsigned int event_id = 0;
8027 unsigned int mask_id = 0;
8028 vector<string> event_spec;
8029 split(probes[i]->event, event_spec, ":");
8030 int num = event_spec.size();
8031 int masks = num - 1;
8032
8033 if (num == 0)
8034 throw semantic_error("No events found");
8035
8036 /* setup event */
8037 if (pfm_find_event(event_spec[0].c_str(), &event_id) != PFMLIB_SUCCESS)
8038 no_pfm_event_error(event_spec[0]);
8039 inp.pfp_events[i].event = event_id;
8040
8041 /* set up masks */
8042 if (masks > PFMLIB_MAX_MASKS_PER_EVENT)
8043 throw semantic_error("Too many unit masks specified");
8044
8045 for (int j=0; j < masks; j++) {
8046 if (pfm_find_event_mask(event_id, event_spec[j+1].c_str(),
8047 &mask_id) != PFMLIB_SUCCESS)
8048 no_pfm_mask_error(string(event_spec[j+1]));
8049 inp.pfp_events[i].unit_masks[j] = mask_id;
8050 }
8051 inp.pfp_events[i].num_masks = masks;
8052 }
8053 }
8054
8055 /* number of counters in use */
8056 inp.pfp_event_count = probes.size();
8057
8058 // XXX: no elimination of duplicated counters
8059 if (inp.pfp_event_count>max_counters)
8060 throw semantic_error("Too many performance monitoring events.");
8061
8062 /* count events both in kernel and user-space */
8063 inp.pfp_dfl_plm = PFM_PLM0 | PFM_PLM3;
8064
4baf0e53 8065 /* XXX: some cases a perfmon register might be used of watch dog
47dd066d
WC
8066 this code doesn't handle that case */
8067
8068 /* figure out the pmcs for the events */
8069 if ((ret=pfm_dispatch_events(&inp, NULL, &outp, NULL)) != PFMLIB_SUCCESS)
8070 throw semantic_error("Cannot configure events");
8071
8072 for (unsigned i=0; i < outp.pfp_pmc_count; i++) {
8073 pc[i].reg_num = outp.pfp_pmcs[i].reg_num;
8074 pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
8075 }
8076
8077 /*
8078 * There could be more pmc settings than pmd.
8079 * Figure out the actual pmds to use.
8080 */
8081 for (unsigned i=0, j=0; i < inp.pfp_event_count; i++) {
8082 pd[i].reg_num = outp.pfp_pmcs[j].reg_pmd_num;
8083 for(; j < outp.pfp_pmc_count; j++)
8084 if (outp.pfp_pmcs[j].reg_evt_idx != i) break;
8085 }
8086
8087 // Output the be probes create function
8088 o->newline() << "static int register_perfmon_probes (void) {";
8089 o->newline(1) << "int rc = 0;";
8090
8091 o->newline() << "/* data for perfmon */";
8092 o->newline() << "static int _pfm_num_pmc = " << outp.pfp_pmc_count << ";";
8093 o->newline() << "static struct pfarg_pmc _pfm_pmc[" << outp.pfp_pmc_count
8094 << "] = {";
8095 /* output the needed bits for pmc here */
8096 for (unsigned i=0; i < outp.pfp_pmc_count; i++) {
8097 o->newline() << "{.reg_num=" << pc[i].reg_num << ", "
8098 << ".reg_value=" << lex_cast_hex<string>(pc[i].reg_value)
8099 << "},";
8100 }
8101
8102 o->newline() << "};";
8103 o->newline() << "static int _pfm_num_pmd = " << inp.pfp_event_count << ";";
8104 o->newline() << "static struct pfarg_pmd _pfm_pmd[" << inp.pfp_event_count
8105 << "] = {";
8106 /* output the needed bits for pmd here */
8107 for (unsigned i=0; i < inp.pfp_event_count; i++) {
8108 o->newline() << "{.reg_num=" << pd[i].reg_num << ", "
8109 << ".reg_value=" << pd[i].reg_value << "},";
8110 }
8111 o->newline() << "};";
8112 o->newline();
8113
8114 o->newline() << "_pfm_pmc_x=_pfm_pmc;";
8115 o->newline() << "_pfm_num_pmc_x=_pfm_num_pmc;";
8116 o->newline() << "_pfm_pmd_x=_pfm_pmd;";
8117 o->newline() << "_pfm_num_pmd_x=_pfm_num_pmd;";
8118
8119 // call all the function bodies associated with perfcounters
8120 for (unsigned i=0; i < probes.size (); i++)
8121 probes[i]->emit_registrations_start (o,i);
8122
8123 /* generate call to turn on instrumentation */
8124 o->newline() << "_pfm_context.ctx_flags |= PFM_FL_SYSTEM_WIDE;";
8125 o->newline() << "rc = rc || _stp_perfmon_setup(&_pfm_desc, &_pfm_context,";
8126 o->newline(1) << "_pfm_pmc, _pfm_num_pmc,";
8127 o->newline() << "_pfm_pmd, _pfm_num_pmd);";
8128 o->newline(-1);
8129
8130 o->newline() << "return rc;";
8131 o->newline(-1) << "}\n";
8132
8133 // Output the be probes destroy function
8134 o->newline() << "static void unregister_perfmon_probes (void) {";
8135 o->newline(1) << "_stp_perfmon_shutdown(_pfm_desc);";
8136 o->newline(-1) << "}\n";
8137}
b20febf3 8138#endif
47dd066d 8139
47dd066d 8140
b55bc428 8141// ------------------------------------------------------------------------
bd2b1e68 8142// Standard tapset registry.
b55bc428
FCE
8143// ------------------------------------------------------------------------
8144
7a053d3b 8145void
f8220a7b 8146register_standard_tapsets(systemtap_session & s)
b55bc428 8147{
12b21830
DS
8148 s.pattern_root->bind(TOK_BEGIN)->bind(new be_builder(BEGIN));
8149 s.pattern_root->bind_num(TOK_BEGIN)->bind(new be_builder(BEGIN));
8150 s.pattern_root->bind(TOK_END)->bind(new be_builder(END));
8151 s.pattern_root->bind_num(TOK_END)->bind(new be_builder(END));
8152 s.pattern_root->bind(TOK_ERROR)->bind(new be_builder(ERROR));
8153 s.pattern_root->bind_num(TOK_ERROR)->bind(new be_builder(ERROR));
16e8f21f 8154
12b21830 8155 s.pattern_root->bind(TOK_NEVER)->bind(new never_builder());
6e3347a9 8156
197a4d62 8157 timer_builder::register_patterns(s.pattern_root);
12b21830
DS
8158 s.pattern_root->bind(TOK_TIMER)->bind("profile")->bind(new profile_builder());
8159 s.pattern_root->bind("perfmon")->bind_str("counter")
8160 ->bind(new perfmon_builder());
b98a8d73 8161
30a279be 8162 // dwarf-based kernel/module parts
f8220a7b 8163 dwarf_derived_probe::register_patterns(s.pattern_root);
30a279be 8164
888af770
FCE
8165 // XXX: user-space starter set
8166 s.pattern_root->bind_num(TOK_PROCESS)
8167 ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)
8168 ->bind(new uprobe_builder ());
8169 s.pattern_root->bind_num(TOK_PROCESS)
8170 ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(TOK_RETURN)
8171 ->bind(new uprobe_builder ());
8172
935447c8 8173 // utrace user-space probes
eff6ac72
DS
8174 s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_BEGIN)
8175 ->bind(new utrace_builder ());
8176 s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_BEGIN)
8177 ->bind(new utrace_builder ());
8178 s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_END)
935447c8 8179 ->bind(new utrace_builder ());
eff6ac72 8180 s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_END)
935447c8 8181 ->bind(new utrace_builder ());
eff6ac72 8182 s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_THREAD)->bind(TOK_BEGIN)
159cb109 8183 ->bind(new utrace_builder ());
eff6ac72
DS
8184 s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_THREAD)->bind(TOK_BEGIN)
8185 ->bind(new utrace_builder ());
8186 s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_THREAD)->bind(TOK_END)
8187 ->bind(new utrace_builder ());
8188 s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_THREAD)->bind(TOK_END)
159cb109 8189 ->bind(new utrace_builder ());
12b21830 8190 s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_SYSCALL)
935447c8 8191 ->bind(new utrace_builder ());
12b21830 8192 s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_SYSCALL)
935447c8 8193 ->bind(new utrace_builder ());
12b21830 8194 s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_SYSCALL)->bind(TOK_RETURN)
935447c8 8195 ->bind(new utrace_builder ());
12b21830 8196 s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_SYSCALL)->bind(TOK_RETURN)
935447c8 8197 ->bind(new utrace_builder ());
935447c8 8198
f781f849 8199 // marker-based parts
12b21830
DS
8200 s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_MARK)
8201 ->bind(new mark_builder());
8202 s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_MARK)->bind_str(TOK_FORMAT)
eb973c2a 8203 ->bind(new mark_builder());
f781f849 8204
ce82316f 8205 // procfs parts
12b21830
DS
8206 s.pattern_root->bind(TOK_PROCFS)->bind(TOK_READ)->bind(new procfs_builder());
8207 s.pattern_root->bind_str(TOK_PROCFS)->bind(TOK_READ)
8208 ->bind(new procfs_builder());
8209 s.pattern_root->bind(TOK_PROCFS)->bind(TOK_WRITE)->bind(new procfs_builder());
8210 s.pattern_root->bind_str(TOK_PROCFS)->bind(TOK_WRITE)
8211 ->bind(new procfs_builder());
b55bc428 8212}
dc38c0ae
DS
8213
8214
b20febf3
FCE
8215vector<derived_probe_group*>
8216all_session_groups(systemtap_session& s)
dc38c0ae 8217{
b20febf3
FCE
8218 vector<derived_probe_group*> g;
8219#define DOONE(x) if (s. x##_derived_probes) g.push_back (s. x##_derived_probes)
ab655cf8
DS
8220
8221 // Note that order *is* important here. We want to make sure we
8222 // register (actually run) begin probes before any other probe type
8223 // is run. Similarly, when unregistering probes, we want to
8224 // unregister (actually run) end probes after every other probe type
8225 // has be unregistered. To do the latter,
8226 // c_unparser::emit_module_exit() will run this list backwards.
b20febf3
FCE
8227 DOONE(be);
8228 DOONE(dwarf);
888af770 8229 DOONE(uprobe);
b20febf3
FCE
8230 DOONE(timer);
8231 DOONE(profile);
8232 DOONE(mark);
8233 DOONE(hrtimer);
8234 DOONE(perfmon);
ce82316f 8235 DOONE(procfs);
935447c8
DS
8236
8237 // Another "order is important" item. We want to make sure we
8238 // "register" the dummy task_finder probe group after all probe
8239 // groups that use the task_finder.
8240 DOONE(utrace);
8241 DOONE(task_finder);
b20febf3
FCE
8242#undef DOONE
8243 return g;
46b84a80 8244}
This page took 1.225537 seconds and 5 git commands to generate.