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