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