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