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