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