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